comparison python/pavement.py @ 614:5e09583275a4

Merged Nicolas/trafficintelligence into default
author Mohamed Gomaa <eng.m.gom3a@gmail.com>
date Fri, 05 Dec 2014 12:13:53 -0500
parents 7978b286fcfa
children 3058e00887bc
comparison
equal deleted inserted replaced
598:11f96bd08552 614:5e09583275a4
1 #! /usr/bin/env python
2 '''Tools for processing and analyzing pavement marking data'''
3
4 import utils
5
6 import numpy as np
7
8 __metaclass__ = type
9
10 paintTypes = {0: "Non-existant",
11 1: "Eau",
12 2: "Epoxy",
13 3: "Alkyde",
14 4: "Autre"}
15
16 durabilities = {1: 98, #96 to 100
17 2: 85, #75 to 96
18 3: 62, #50 to 75
19 4: 32, #15 to 50
20 5: 7 #0 to 15
21 }
22
23 roadFunctionalClasses = {40: "Collectrice",
24 20: "Nationale",
25 30: "Regionale",
26 10: "Autoroute",
27 60: "Acces ressources",
28 51: "Local 1",
29 52: "Local 2",
30 53: "Local 3",
31 15: "Aut (PRN)",
32 25: "Nat (PRN)",
33 70: "Acces isolees",
34 99: "Autres"}
35
36 def caracteristiques(rtss, maintenanceLevel, rtssWeatherStation, fmr, paintType):
37 '''Computes characteristic data for the RTSS (class rtss)
38 maintenanceLevel = pylab.csv2rec('C:\Users\Alexandre\Desktop\Projet_maitrise_recherche\BDD_access\\analyse_donnees_deneigement\\exigence_circuits.txt', delimiter = ';')
39 rtssWeatherStation = pylab.csv2rec('C:\Users\Alexandre\Desktop\Projet_maitrise_recherche\stations_environnement_canada\\rtssWeatherStation\juste_pour_rtss_avec_donnees_entretien_hiv\\rtssWeatherStation_EC3.txt', delimiter = ',')
40 fmr = pylab.csv2rec('C:\Users\Alexandre\Desktop\Projet_maitrise_recherche\BDD_access\\analyse_donnees_deneigement\\fmr.txt', delimiter = ';')
41 paintType = pylab.csv2rec('C:\Users\Alexandre\Desktop\Projet_maitrise_recherche\BDD_access\\analyse_donnees_deneigement\\type_peinture.txt', delimiter = ';')
42 '''
43 # determination exigence deneigement
44 if rtss.id in maintenanceLevel['rtss_debut']:
45 for i in range(len(maintenanceLevel)):
46 if maintenanceLevel['rtss_debut'][i] == rtss.id:
47 exigence = maintenanceLevel['exigence'][i]
48 else:
49 exigence = ''
50
51 # determination x/y
52 if rtss.id in rtssWeatherStation['rtss']:
53 for i in range(len(rtssWeatherStation)):
54 if rtssWeatherStation['rtss'][i] == rtss.id:
55 x_moy = rtssWeatherStation['x_moy'][i]
56 y_moy = rtssWeatherStation['y_moy'][i]
57 else:
58 x_moy, y_moy = '',''
59
60 # determination info fmr
61 age_revtm, classe_fonct, type_revtm, milieu, djma, pourc_camions, vit_max = [], [], [], [], [], [], []
62 if rtss.id in fmr['rtss_debut']:
63 for i in range(len(fmr)):
64 if fmr['rtss_debut'][i] == rtss.id:
65 age_revtm.append(fmr['age_revtm'][i])
66 classe_fonct.append(fmr['des_clasf_fonct'][i])
67 type_revtm.append(fmr['des_type_revtm'][i])
68 milieu.append(fmr['des_cod_mil'][i])
69 djma.append(fmr['val_djma'][i])
70 pourc_camions.append(fmr['val_pourc_camns'][i])
71 vit_max.append(fmr['val_limt_vitss'][i])
72 age_revtm = utils.mostCommon(age_revtm)
73 classe_fonct = utils.mostCommon(classe_fonct)
74 type_revtm = utils.mostCommon(type_revtm)
75 milieu = utils.mostCommon(milieu)
76 djma = utils.mostCommon(djma)
77 vit_max = utils.mostCommon(vit_max)
78 if vit_max < 0:
79 vit_max = ''
80 pourc_camions = utils.mostCommon(pourc_camions)
81 if pourc_camions == "" or pourc_camions < 0:
82 djma_camions = ""
83 else:
84 djma_camions = pourc_camions*djma/100
85 else:
86 age_revtm, classe_fonct, type_revtm, milieu, djma, djma_camions, vit_max = '','','','','','',''
87
88 # determination type peinture
89 peinture_rd, peinture_rg, peinture_cl = [], [], []
90 peinture_lrd, peinture_lrg, peinture_lc = 0,0,0
91 if rtss.id in paintType['rtss_debut_orig']:
92 for i in range(len(paintType)):
93 if paintType['rtss_debut_orig'][i] == rtss.id:
94 peinture_rd.append((paintType['peinture_rd'][i]))
95 peinture_rg.append((paintType['peinture_rg'][i]))
96 peinture_cl.append((paintType['peinture_cl'][i]))
97 peinture_lrd = utils.mostCommon(peinture_rd)
98 peinture_lrg = utils.mostCommon(peinture_rg)
99 peinture_lc = utils.mostCommon(peinture_cl)
100 else:
101 peinture_lrd, peinture_lrg, peinture_lc = '','',''
102
103 return (exigence, x_moy, y_moy, age_revtm, classe_fonct, type_revtm, milieu, djma, djma_camions, vit_max, peinture_lrd, peinture_lrg, peinture_lc)
104
105 def winterMaintenanceIndicators(data, startDate, endDate, circuitReference, snowThreshold):
106 '''Computes several winter maintenance indicators
107 data = entretien_hivernal = pylab.csv2rec('C:\Users\Alexandre\Documents\Cours\Poly\Projet\mesures_entretien_hivernal\mesures_deneigement.txt', delimiter = ',')'''
108 import datetime
109 somme_eau, somme_neige, somme_abrasif, somme_sel, somme_lc, somme_lrg, somme_lrd, compteur_premiere_neige, compteur_somme_abrasif = 0,0,0,0,0,0,0,0,0
110
111 if circuitReference in data['ref_circuit']:
112 for i in range(len(data)):
113 if data['ref_circuit'][i] == circuitReference and (data['date'][i] + datetime.timedelta(days = 6)) <= endDate and (data['date'][i] + datetime.timedelta(days = 6)) > startDate:
114 compteur_premiere_neige += float(data['premiere_neige'][i])
115 somme_neige += float(data['neige'][i])
116 somme_eau += float(data['eau'][i])
117 somme_abrasif += float(data['abrasif'][i])
118 somme_sel += float(data['sel'][i])
119 somme_lc += float(data['lc'][i])
120 somme_lrg += float(data['lrg'][i])
121 somme_lrd += float(data['lrd'][i])
122 compteur_somme_abrasif += float(data['autre_abrasif_binaire'][i])
123 if compteur_premiere_neige >= 1:
124 premiere_neige = 1
125 else:
126 premiere_neige = 0
127 if compteur_somme_abrasif >= 1:
128 autres_abrasifs = 1
129 else:
130 autres_abrasifs = 0
131 if somme_neige < snowThreshold:
132 neigeMTQ_sup_seuil = 0
133 else:
134 neigeMTQ_sup_seuil = 1
135 else:
136 somme_eau, somme_neige, somme_abrasif, somme_sel, somme_lc, somme_lrg, somme_lrd, premiere_neige, autres_abrasifs, neigeMTQ_sup_seuil = '','','','','','','','','',''
137
138 return (somme_eau, somme_neige, neigeMTQ_sup_seuil, somme_abrasif, somme_sel, somme_lc, somme_lrg, somme_lrd, premiere_neige, autres_abrasifs)
139
140 def weatherIndicators(data, startDate, endDate, snowThreshold, weatherDatatype, minProportionMeasures = 0.):
141 '''Computes the indicators from Environment Canada files
142 (loaded as a recarray using csv2rec in data),
143 between start and end dates (datetime.datetime objects)
144
145 weatherDataType is to indicate Environnement Canada data ('ec') or else MTQ
146 minProportionMeasures is proportion of measures necessary to consider the indicators'''
147 from matplotlib.mlab import find
148 nbre_jours_T_negatif,nbre_jours_gel_degel,pluie_tot,neige_tot,ecart_type_T = 0,0,0,0,0
149 compteur,nbre_jours_gel_consecutifs=0,0
150 tmoys = []
151 seuils_T = [20,15,10,5]
152 deltas_T = [0,0,0,0]
153 startIndex = find(data['date'] == startDate)
154 nDays = int((endDate - startDate).days)+1
155 if len(startIndex) > 0 and startIndex+nDays <= len(data):
156 startIndex = startIndex[0]
157 for i in range(startIndex, startIndex+nDays):
158 if not np.isnan(data['tmax'][i]):
159 tmax = data['tmax'][i]
160 else:
161 tmax = None
162 if not np.isnan(data['tmin'][i]):
163 tmin = data['tmin'][i]
164 else:
165 tmin = None
166 if weatherDatatype == 'ec':
167 if data['pluie_tot'][i] != None and not np.isnan(data['pluie_tot'][i]):
168 pluie_tot += data['pluie_tot'][i]
169 if data['neige_tot'][i] != None and not np.isnan(data['neige_tot'][i]):
170 neige_tot += data['neige_tot'][i]
171 if tmax != None:
172 if tmax < 0:
173 nbre_jours_T_negatif += 1
174 if tmax != None and tmin != None:
175 if tmax > 0 and tmin < 0:
176 nbre_jours_gel_degel += 1
177 for l in range(len(seuils_T)):
178 if tmax - tmin >=seuils_T[l]:
179 deltas_T[l] += 1
180 if not np.isnan(data['tmoy'][i]):
181 tmoys.append(data['tmoy'][i])
182 if tmax != None:
183 if tmax < 0:
184 compteur += 1
185 elif tmax >= 0 and compteur >= nbre_jours_gel_consecutifs:
186 nbre_jours_gel_consecutifs = compteur
187 compteur = 0
188 else:
189 compteur = 0
190 nbre_jours_gel_consecutifs = max(nbre_jours_gel_consecutifs,compteur)
191 if len(tmoys) > 0 and float(len(tmoys))/nDays >= minProportionMeasures:
192 if tmoys != []:
193 ecart_type_T = np.std(tmoys)
194 else:
195 ecart_type = None
196 if neige_tot < snowThreshold:
197 neigeEC_sup_seuil = 0
198 else:
199 neigeEC_sup_seuil = 1
200 return (nbre_jours_T_negatif,nbre_jours_gel_degel, deltas_T, nbre_jours_gel_consecutifs, pluie_tot, neige_tot, neigeEC_sup_seuil, ecart_type_T)
201 else:
202 return [None]*2+[[None]*len(seuils_T)]+[None]*5
203
204 def mtqWeatherIndicators(data, startDate, endDate,tmax,tmin,tmoy):
205 print("Deprecated, use weatherIndicators")
206 from matplotlib.mlab import find
207 nbre_jours_T_negatif,nbre_jours_gel_degel,ecart_type_T = 0,0,0
208 compteur,nbre_jours_gel_consecutifs=0,0
209 tmoys = []
210 seuils_T = [20,15,10,5]
211 deltas_T = [0,0,0,0]
212 startIndex = find(data['date'] == startDate)
213 nDays = (endDate - startDate).days+1
214 for i in range(startIndex, startIndex+nDays):
215 if tmax[i] < 0:
216 nbre_jours_T_negatif += 1
217 if tmax[i] > 0 and tmin[i] < 0:
218 nbre_jours_gel_degel += 1
219 for l in range(len(seuils_T)):
220 if tmax[i] - tmin[i] >=seuils_T[l]:
221 deltas_T[l] += 1
222 tmoys.append(tmoy[i])
223 if tmax[i] < 0:
224 compteur += 1
225 elif tmax[i] >= 0 and compteur >= nbre_jours_gel_consecutifs:
226 nbre_jours_gel_consecutifs = compteur
227 compteur = 0
228 else:
229 compteur = 0
230 nbre_jours_gel_consecutifs = max(nbre_jours_gel_consecutifs,compteur)
231 if tmoys != []:
232 ecart_type_T = np.std(tmoys)
233 else:
234 ecart_type = None
235
236 return (nbre_jours_T_negatif,nbre_jours_gel_degel, deltas_T, nbre_jours_gel_consecutifs, ecart_type_T)
237
238 class RTSS:
239 '''class for data related to a RTSS:
240 - agregating pavement marking measurements
241 - RTSS characteristics from FMR: pavement type, age, AADT, truck AADT
242 - winter maintenance level from V155
243
244 If divided highway, the RTSS ends with G or D and are distinct: there is no ambiguity
245 - retroreflectivity types: there are CB, RJ and RB
246 If undivided, ending with C
247 - durability is fine: ETAT_MARQG_RG ETAT_MARQG_CL ETAT_MARQG_RD (+SG/SD, but recent)
248 - retroreflectivity: CJ is center line, RB and SB are left/right if DEBUT-FIN>0 or <0
249 '''
250
251 def __init__(self, _id, name, data):
252 self.id = _id
253 self.name = name
254 self.data = data
255
256 class MarkingTest:
257 '''class for a test site for a given product
258
259 including the series of measurements over the years'''
260
261 def __init__(self, _id, paintingDate, paintingType, color, data):
262 self.id = _id
263 self.paintingDate = paintingDate
264 self.paintingType = paintingType
265 self.color = color
266 self.data = data
267 self.nMeasures = len(data)
268
269 def getSite(self):
270 return int(self.id[:2])
271
272 def getTestAttributes(self):
273 return [self.paintingType, self.color, self.paintingDate.year]
274
275 def plot(self, measure, options = 'o', dayRatio = 1., **kwargs):
276 from matplotlib.pyplot import plot
277 plot(self.data['jours']/float(dayRatio),
278 self.data[measure], options, **kwargs)
279
280 def getMarkingMeasures(self, dataLabel):
281 nonZeroIndices = ~np.isnan(self.data[dataLabel])
282 return self.data[nonZeroIndices]['jours'], self.data[nonZeroIndices][dataLabel]
283
284 def plotMarkingMeasures(self, measure, options = 'o', dayRatio = 1., **kwargs):
285 for i in range(1,7):
286 self.plot('{}_{}'.format(measure, i), options, dayRatio, **kwargs)
287
288 def computeMarkingMeasureVariations(self, dataLabel, lanePositions, weatherData, snowThreshold, weatherDataType = 'ec', minProportionMeasures = 0.):
289 '''Computes for each successive measurement
290 lanePositions = None
291 measure variation, initial measure, time duration, weather indicators
292
293 TODO if measurements per lane, add a variable for lane position (position1 to 6)
294 lanePositions = list of integers (range(1,7))
295 measure variation, initial measure, time duration, lane position1, weather indicators
296 measure variation, initial measure, time duration, lane position2, weather indicators
297 ...'''
298 variationData = []
299 if lanePositions == None:
300 nonZeroIndices = ~np.isnan(self.data[dataLabel])
301 days = self.data[nonZeroIndices]['jours']
302 dates = self.data[nonZeroIndices]['date_mesure']
303 measures = self.data[nonZeroIndices][dataLabel]
304 for i in range(1, len(dates)):
305 nDaysTNegative, nDaysThawFreeze, deltaTemp, nConsecutiveFrozenDays, totalRain, totalSnow, snowAboveThreshold, stdevTemp = weatherIndicators(weatherData, dates[i-1], dates[i], snowThreshold, weatherDataType, minProportionMeasures)
306 if dates[i-1].year+1 == dates[i].year:
307 winter = 1
308 if days[i-1]<365:
309 firstWinter = 1
310 else:
311 winter = 0
312 firstWinter = 0
313 variationData.append([measures[i-1]-measures[i], measures[i-1], days[i]-days[i-1], days[i-1], winter, firstWinter, nDaysTNegative, nDaysThawFreeze] + deltaTemp + [nConsecutiveFrozenDays, totalRain, totalSnow, snowAboveThreshold, stdevTemp])
314 return variationData