Mercurial Hosting > traffic-intelligence
comparison python/indicators.py @ 244:5027c174ab90
moved indicators to new file, added ExtrapolatedTrajectory class to extrapolation file
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Tue, 17 Jul 2012 00:15:42 -0400 |
parents | |
children | 8f0ed138d373 |
comparison
equal
deleted
inserted
replaced
243:e0988a8ace0c | 244:5027c174ab90 |
---|---|
1 #! /usr/bin/env python | |
2 '''Class for indicators, temporal indicators, and safety indicators''' | |
3 | |
4 __metaclass__ = type | |
5 | |
6 # need for a class representing the indicators, their units, how to print them in graphs... | |
7 class TemporalIndicator: | |
8 '''Class for temporal indicators | |
9 i.e. indicators that take a value at specific instants | |
10 | |
11 values should be | |
12 * a dict, for the values at specific time instants | |
13 * or a list with a time interval object if continuous measurements | |
14 | |
15 it should have more information like name, unit''' | |
16 | |
17 def __init__(self, name, values, timeInterval=None): | |
18 self.name = name | |
19 self.isCosine = name.find('Cosine') | |
20 self.values = values | |
21 self.timeInterval = timeInterval | |
22 if timeInterval: | |
23 assert len(values) == timeInterval.length() | |
24 | |
25 def empty(self): | |
26 return len(self.values) == 0 | |
27 | |
28 def __getitem__(self, i): | |
29 if self.timeInterval: | |
30 if self.timeInterval.contains(i): | |
31 return self.values[i-self.timeInterval.first] | |
32 else: | |
33 if i in self.values.keys(): | |
34 return self.values[i] | |
35 return None # default | |
36 | |
37 def __iter__(self): | |
38 self.iterInstantNum = 0 # index in the interval or keys of the dict | |
39 return self | |
40 | |
41 def next(self): | |
42 if self.iterInstantNum >= len(self.values):#(self.timeInterval and self.iterInstantNum>=self.timeInterval.length())\ | |
43 # or (self.iterInstantNum >= self.values) | |
44 raise StopIteration | |
45 else: | |
46 self.iterInstantNum += 1 | |
47 if self.timeInterval: | |
48 return self.values[self.iterInstantNum-1] | |
49 else: | |
50 return self.values.values()[self.iterInstantNum-1] | |
51 | |
52 def getTimeInterval(self): | |
53 if not self.timeInterval and type(self.values)==dict: | |
54 instants = self.values.keys() | |
55 if instants: | |
56 self.timeInterval = TimeInterval(instants[0], instants[-1]) | |
57 else: | |
58 self.timeInterval = TimeInterval() | |
59 return self.timeInterval | |
60 | |
61 def getValues(self): | |
62 if self.timeInterval: | |
63 return self.values | |
64 else: | |
65 return self.values.values() | |
66 | |
67 def getAngleValues(self): | |
68 '''if the indicator is a function of an angle, | |
69 transform it to an angle (eg cos) | |
70 (no transformation otherwise)''' | |
71 from numpy import arccos | |
72 values = self.getValues() | |
73 if self.isCosine >= 0: | |
74 return [arccos(c) for c in values] | |
75 else: | |
76 return values | |
77 | |
78 class SeverityIndicator(TemporalIndicator): | |
79 '''Class for severity indicators | |
80 field mostSevereIsMax is True | |
81 if the most severe value taken by the indicator is the maximum''' | |
82 | |
83 def __init__(self, name, values, timeInterval=None, mostSevereIsMax=True, ignoredValue = None): | |
84 TemporalIndicator.__init__(self, name, values, timeInterval) | |
85 self.mostSevereIsMax = mostSevereIsMax | |
86 self.ignoredValue = ignoredValue | |
87 | |
88 def getMostSevereValue(self, minNInstants=1): | |
89 from matplotlib.mlab import find | |
90 from numpy.core.multiarray import array | |
91 from numpy.core.fromnumeric import mean | |
92 values = array(self.values.values()) | |
93 if self.ignoredValue: | |
94 indices = find(values != self.ignoredValue) | |
95 else: | |
96 indices = range(len(values)) | |
97 if len(indices) >= minNInstants: | |
98 values = sorted(values[indices], reverse = self.mostSevereIsMax) # inverted if most severe is max -> take the first values | |
99 return mean(values[:minNInstants]) | |
100 else: | |
101 return None | |
102 | |
103 # functions to aggregate discretized maps of indicators | |
104 # TODO add values in the cells between the positions (similar to discretizing vector graphics to bitmap) | |
105 | |
106 def indicatorMap(indicatorValues, trajectory, squareSize): | |
107 '''Returns a dictionary | |
108 with keys for the indices of the cells (squares) | |
109 in which the trajectory positions are located | |
110 at which the indicator values are attached | |
111 | |
112 ex: speeds and trajectory''' | |
113 | |
114 from numpy import floor, mean | |
115 assert len(indicatorValues) == trajectory.length() | |
116 indicatorMap = {} | |
117 for k in xrange(trajectory.length()): | |
118 p = trajectory[k] | |
119 i = floor(p.x/squareSize) | |
120 j = floor(p.y/squareSize) | |
121 if indicatorMap.has_key((i,j)): | |
122 indicatorMap[(i,j)].append(indicatorValues[k]) | |
123 else: | |
124 indicatorMap[(i,j)] = [indicatorValues[k]] | |
125 for k in indicatorMap.keys(): | |
126 indicatorMap[k] = mean(indicatorMap[k]) | |
127 return indicatorMap | |
128 | |
129 def indicatorMapFromPolygon(value, polygon, squareSize): | |
130 '''Fills an indicator map with the value within the polygon | |
131 (array of Nx2 coordinates of the polygon vertices)''' | |
132 import matplotlib.nxutils as nx | |
133 from numpy.core.multiarray import array, arange | |
134 from numpy import floor | |
135 | |
136 points = [] | |
137 for x in arange(min(polygon[:,0])+squareSize/2, max(polygon[:,0]), squareSize): | |
138 for y in arange(min(polygon[:,1])+squareSize/2, max(polygon[:,1]), squareSize): | |
139 points.append([x,y]) | |
140 inside = nx.points_inside_poly(array(points), polygon) | |
141 indicatorMap = {} | |
142 for i in xrange(len(inside)): | |
143 if inside[i]: | |
144 indicatorMap[(floor(points[i][0]/squareSize), floor(points[i][1]/squareSize))] = 0 | |
145 return indicatorMap | |
146 | |
147 def indicatorMapFromAxis(value, limits, squareSize): | |
148 '''axis = [xmin, xmax, ymin, ymax] ''' | |
149 from numpy.core.multiarray import arange | |
150 from numpy import floor | |
151 indicatorMap = {} | |
152 for x in arange(limits[0], limits[1], squareSize): | |
153 for y in arange(limits[2], limits[3], squareSize): | |
154 indicatorMap[(floor(x/squareSize), floor(y/squareSize))] = value | |
155 return indicatorMap | |
156 | |
157 def combineIndicatorMaps(maps, squareSize, combinationFunction): | |
158 '''Puts many indicator maps together | |
159 (averaging the values in each cell | |
160 if more than one maps has a value)''' | |
161 #from numpy import mean | |
162 indicatorMap = {} | |
163 for m in maps: | |
164 for k,v in m.iteritems(): | |
165 if indicatorMap.has_key(k): | |
166 indicatorMap[k].append(v) | |
167 else: | |
168 indicatorMap[k] = [v] | |
169 for k in indicatorMap.keys(): | |
170 indicatorMap[k] = combinationFunction(indicatorMap[k]) | |
171 return indicatorMap |