# VISSIM secondary development (Python) & big job summary 2

### Write in front

The previous section has summarized all the basic knowledge of secondary development used this time. In this section, we mainly introduce the reading, drawing and analysis of. att files in this paper.

In this part, we will introduce this part. Because the content of this part is highly specialized, it is written separately from the previous secondary development part for the reference of students in need.

### Example. att file

The header will introduce the meaning of data bytes. Here, you need to point out that the first column is the number of simulation runs.

### Requirement 1: draw contour diagram according to simulation results

#development environment matplotlib 3.3.4 numpy 1.19.5 pandas 1.2.4

coutour map refers to the contour map, which is directly on the code

import pandas as pd import numpy as np import matplotlib.pyplot as plt S=8 #Set the number of simulations that need to be read df1=pd.read_csv('file.att',sep=';',skiprows=21)#The data separator in att is ";", Then you need to skip the previous part that does not need to be converted to df. #To read data, you need to skip the previous unnecessary rows #%% # df2=df1.sort_values(by=['DATACOLLECTIONMEASUREMENT', 'TIMEINT']) dfn1=df1[df1['$DATACOLLECTIONMEASUREMENTEVALUATION:SIMRUN'].isin([S])]#In fact, it will be more convenient to change clomun earlier. Select to include only the results of this eighth run T=int(672*5/8)#This is the number of rows of coil valid data in the non ramp section, because there will be many unnecessary statistical values, which may need to be changed by yourself #%% dfn=dfn1[dfn1['DATACOLLECTIONMEASUREMENT'].isin([1,2,4,7,9])]#The section to be analyzed is selected here pre_df=dfn[['TIMEINT','DATACOLLECTIONMEASUREMENT','SPEED(ALL)']].iloc[:T,:]#Here we mainly select the columns to be analyzed pre_df1=pre_df[['SPEED(ALL)']]#Finally, it was found that only one column was needed pre_df1.index = range(T)#index is renumbered for convenience #The following is to convert the above column of data for i in range(84): if i ==0: A= pre_df1.iloc[0:5,0] C=pd.DataFrame(A) C.index = range(len(C)) else: B=pd.DataFrame(pre_df1.iloc[i*5:i*5+5,0]) B.index = range(len(B)) C=pd.concat([C,B],axis=1,join='inner')#Establish a 9 * 64 df as the input of contour drawing t=C.shape[1]#The following is the drawing of contour map C=C.iloc[::-1,:] x=np.linspace(0,t-1,t) y=np.linspace(37,41,5) X,Y=np.meshgrid(x,y) #The above three sentences are to establish the grid of contour map plt.figure() plt.contourf(X,Y,np.array(C),7,cmap=plt.cm.RdYlGn,levels=np.linspace(0,90,50)) #To draw the contour map, the middle needs to be in the form of matrix, and meet the requirements of x columns and y rows plt.colorbar()#Display color bar plt.xticks(range(0,84,12),['6:00','7:00','8:00','9:00','10:00','11:00','12:00'])#Change abscissa and ordinate plt.yticks([37,38,39,40,41],['NHNX41','NHNX40','NHNX39','NHNX38','NHNX37']) # plt.savefig('C:\\Users\\13968\\Desktop\\0819-'+str(S)+'.jpg', dpi=1000) plt.show()

Among them, the code levels=np.linspace(0,90,50) is mainly used to control the drawing effect, where 0,90 is the color range of the control display ordinate (corresponding color), and 50 is the trend of color transition. You can refer to the methods in the following links for selection. And the use of color plates can be referred to. Of course, the official documents are also very clear~

Some students may also have the need to draw the contour of the real scene. Because the methods are the same, it will not be discussed here. The main thing is to build the drawing speed space-time matrix C. you can try it yourself. The df transmission in the middle of this part is a little chaotic. At present, it seems that it is good to achieve results

The final drawing effect is as follows ~ is it OK

### Requirement 2: Analysis Based on results

The result analysis is mainly based on these two literatures

Bottleneck Identification and Calibration for Corridor Management Planning

Calibration of a micro-traffic simulation model with respect to the spatial-temporal evolution of expressway on-ramp bottlenecks

evaluating indicator | meaning | requirement |
---|---|---|

C1(Bottleneck Area Matching) | Matching degree of actual and Simulation in bottleneck range (time and space) | >0.75 |

C2(Actual Speed Matching) | Reflect range matching and actual speed matching | >0.70 |

GEH | It is proposed by Geoffrey E. Havers to compare the matching degree of two groups of traffic data | <5 |

Velocity relative error | <15% |

Let's also briefly list the formulas. C1 and Devs have some other forms, but there is little difference. For details, please refer to the previously recommended literature~

D
e
v
s
=
∣
S
r
−
S
s
j
S
r
\\Devs= \frac { | S _ { r } - S _ { s } j } { S _ { r } }
Devs=Sr∣Sr−Ssj

G H = ( E − v ) 2 ( E + v ) / 2 \sqrt { G H } = \sqrt { \frac { ( E - v ) ^ { 2 } } { ( E + v ) / 2 } } GH =(E+v)/2(E−v)2

C 1 = ∑ i = 1 N { ( ∑ t = 1 T [ B S s ( i , t ) A B S r ( i , t ) ] ) ⋅ ( x i + 1 − x i ) } ∑ i = 1 N ( ∑ t = 1 T [ B S s ( i , t ) V B S r ( i , t ) ] ) ⋅ ( x i + 1 − x i ) } \\C_1=\frac{\sum _ { i = 1 } ^ { N } \{ ( \sum _ { t = 1 } ^ { T } [ B S _ { s } ( i , t ) A B S _ { r } ( i , t ) ] ) \cdot ( x _ { i } + 1 - x _ { i } ) \}}{\sum _ { i = 1 } ^ { N } ( \sum _ { t = 1 } ^ { T } [ B S _ { s } ( i , t ) V B S _ { r } ( i , t ) ] ) \cdot ( x _ { i } + 1 - x _ { i } ) \}} C1=∑i=1N(∑t=1T[BSs(i,t)VBSr(i,t)])⋅(xi+1−xi)}∑i=1N{(∑t=1T[BSs(i,t)ABSr(i,t)])⋅(xi+1−xi)}

C 2 = 2 ∑ i = 1 N ∑ i = 1 T { [ B S s ( i , t ) V B S r ( i , t ) ] ⋅ ∣ S s ( i , t ) − S r ( i , t ) ∣ ) ⋅ ( x i + 1 − x i ) } ∑ i = 1 N ∑ t = 1 T { [ B S s ( i , t ) V B S r ( i , t ) ] ⋅ ( S s ( i , t ) + S r ( i , t ) ) ) ⋅ ( x i + 1 − x i ) } \\C_2=\frac{2 \sum _ { i = 1 } ^ { N } \sum _ { i = 1 } ^ { T } \{[ B S _ { s } ( i , t ) V B S _ { r } ( i , t ) ] \cdot| S _ { s } ( i , t ) - S _ { r } ( i , t ) | ) \cdot ( x _ { i } + 1 - x _ { i } ) \}}{\sum _ { i = 1 } ^ { N } \sum _ { t = 1 } ^ { T } \{ [ B S _ { s } ( i , t ) V B S _ { r } ( i , t ) ] \cdot ( S _ { s } ( i , t ) + S _ { r } ( i , t ) ) ) \cdot ( x _ { i } + 1 - x _ { i } ) \}} C2=∑i=1N∑t=1T{[BSs(i,t)VBSr(i,t)]⋅(Ss(i,t)+Sr(i,t)))⋅(xi+1−xi)}2∑i=1N∑i=1T{[BSs(i,t)VBSr(i,t)]⋅∣Ss(i,t)−Sr(i,t)∣)⋅(xi+1−xi)}

This part of the code is a good brother xjt read my blog today_ CSDN blog provide

#The file import part has been explained earlier and will not be repeated here. It mainly introduces its functional modules #Calculate the BS matrix (45 represents the threshold, which can be adjusted by itself, and the index can be adjusted by itself according to the matrix) BS_wn[f'speed_{data}'] = BS_wn[f'speed_{data}'].apply(lambda x: 0 if x >= 45 else 1) #Here, the Dataframe type read by pandas is directly used for operation. Other types can also be operated as long as the index corresponds to #Correct the BS matrix for fear of errors, which is not brought in here and has little impact on the results BS_s_1 = BS_wn.values #Convert it into matrix form and traverse the historical data of a coil for judgment for spa_ii in range(1,BS_s_1.shape[1]): for tt_3 in range(BS_s_1.shape[0]): if BS_s_1[tt_3][spa_ii] == 0: #It mainly focuses on whether the setting of the bottleneck area is reasonable. Therefore, the abnormal value of the unreasonable bottleneck area setting is 0, so all 0 (non bottleneck area positions) are found for tt_4 in range(tt_3-3,tt_3): data_listwn = [] if tt_4 <0: pass else: for tt_5 in range(tt_4,tt_4+5): if tt_5 == tt_3 or tt_5 >=len(BS_s_1.shape[0])-1: #Spatial location index maximum pass else: data_listwn.append(BS_s_1[tt_5][spa_ii]) if data_listwn == [1, 1, 1, 1]: BS_s_1[tt_3][spa_ii] = 1 #Refer to the formula for the meaning of each parameter of the index #Calculate C1 def Ca_C1(Bs_s, Bs_r): C1_up = np.sum(np.logical_and(Bs_s,Bs_r)) C1_down = np.sum(Bs_s+Bs_r) C1 = 2*C1_up/C1_down return C1 # Calculate C2 index: def Ca_C2(Bs_s1, Bs_r1, S_s, S_r): Bs_or = np.logical_or(Bs_s1,Bs_r1) S_abs = np.abs(S_r-S_s) S_add =S_r+S_s C2_up = np.sum(np.multiply(Bs_or, S_abs)) C2_down = np.sum(np.multiply(Bs_or,S_add)) C2 =1 - 2*C2_up/C2_down return C2 # Calculate GEH def Ca_GEH(V_ss,V_r): Geh_up = np.multiply((V_ss-V_r), (V_ss-V_r)) Geh_down = (V_ss+V_r)/2 Geh = np.sqrt(Geh_up/Geh_down) return np.percentile(Geh, 0.85) #Returns the 85th percentile value #Calculate the relative deviation of speed def Ca_DevS(S_s1, S_r1): S_abs = np.abs(S_r1-S_s1) idxnonzeros = np.where(S_r1 != 0) Devs = S_abs[idxnonzeros]/S_r1[idxnonzeros] Devs_re = Devs[np.where(Devs <= np.percentile(Devs, 0.85))] #It can be calculated after excluding the larger value of 15%, or it can not be eliminated Devs_avr = np.average(Devs_re) return Devs_avr

By calculating these indexes and combining with the first article of this column, the calibration parameters can be calibrated~

Of course, these works are based on the pre detailed inspection, such as software inspection - modeling inspection - Animation inspection. After qualitative analysis, the methods introduced here are used for quantitative analysis. So as to obtain the best parameter combination, complete the calibration of the model, and have a deeper understanding of traffic phenomena and micro behavior.

The first in this series: VISSIM secondary development (Python) & big job summary 1_tu_qing's blog - CSDN blog Welcome your attention