Mercurial > hg > nsaunier > 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 |
