Mercurial > hg > nsaunier > traffic-intelligence
comparison python/indicators.py @ 708:a37c565f4b68
merged dev
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Wed, 22 Jul 2015 14:17:44 -0400 |
| parents | 5ee22bf7e4d5 |
| children | b75d0c258ca9 |
comparison
equal
deleted
inserted
replaced
| 707:7efa36b9bcfd | 708:a37c565f4b68 |
|---|---|
| 1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
| 2 '''Class for indicators, temporal indicators, and safety indicators''' | 2 '''Class for indicators, temporal indicators, and safety indicators''' |
| 3 | 3 |
| 4 import moving | 4 import moving |
| 5 #import matplotlib.nxutils as nx | |
| 6 from matplotlib.pyplot import plot, ylim | |
| 7 from matplotlib.pylab import find | |
| 8 from numpy import array, arange, mean, floor, mean | |
| 5 | 9 |
| 6 | 10 |
| 7 # need for a class representing the indicators, their units, how to print them in graphs... | 11 # need for a class representing the indicators, their units, how to print them in graphs... |
| 8 class TemporalIndicator(object): | 12 class TemporalIndicator(object): |
| 9 '''Class for temporal indicators | 13 '''Class for temporal indicators |
| 13 * a dict, for the values at specific time instants | 17 * a dict, for the values at specific time instants |
| 14 * or a list with a time interval object if continuous measurements | 18 * or a list with a time interval object if continuous measurements |
| 15 | 19 |
| 16 it should have more information like name, unit''' | 20 it should have more information like name, unit''' |
| 17 | 21 |
| 18 def __init__(self, name, values, timeInterval=None, maxValue = None): | 22 def __init__(self, name, values, timeInterval = None, maxValue = None): |
| 19 self.name = name | 23 self.name = name |
| 20 if timeInterval: | 24 if timeInterval is None: |
| 25 self.values = values | |
| 26 instants = sorted(self.values.keys()) | |
| 27 if len(instants) > 0: | |
| 28 self.timeInterval = moving.TimeInterval(instants[0], instants[-1]) | |
| 29 else: | |
| 30 self.timeInterval = moving.TimeInterval() | |
| 31 else: | |
| 21 assert len(values) == timeInterval.length() | 32 assert len(values) == timeInterval.length() |
| 22 self.timeInterval = timeInterval | 33 self.timeInterval = timeInterval |
| 23 self.values = {} | 34 self.values = {} |
| 24 for i in xrange(int(round(self.timeInterval.length()))): | 35 for i in xrange(int(round(self.timeInterval.length()))): |
| 25 self.values[self.timeInterval[i]] = values[i] | 36 self.values[self.timeInterval[i]] = values[i] |
| 26 else: | |
| 27 self.values = values | |
| 28 instants = sorted(self.values.keys()) | |
| 29 if instants: | |
| 30 self.timeInterval = moving.TimeInterval(instants[0], instants[-1]) | |
| 31 else: | |
| 32 self.timeInterval = moving.TimeInterval() | |
| 33 self.maxValue = maxValue | 37 self.maxValue = maxValue |
| 34 | 38 |
| 35 def __len__(self): | 39 def __len__(self): |
| 36 return len(self.values) | 40 return len(self.values) |
| 37 | 41 |
| 72 | 76 |
| 73 def getValues(self): | 77 def getValues(self): |
| 74 return [self.__getitem__(t) for t in self.timeInterval] | 78 return [self.__getitem__(t) for t in self.timeInterval] |
| 75 | 79 |
| 76 def plot(self, options = '', xfactor = 1., yfactor = 1., timeShift = 0, **kwargs): | 80 def plot(self, options = '', xfactor = 1., yfactor = 1., timeShift = 0, **kwargs): |
| 77 from matplotlib.pylab import plot,ylim | |
| 78 if self.getTimeInterval().length() == 1: | 81 if self.getTimeInterval().length() == 1: |
| 79 marker = 'o' | 82 marker = 'o' |
| 80 else: | 83 else: |
| 81 marker = '' | 84 marker = '' |
| 82 time = sorted(self.values.keys()) | 85 time = sorted(self.values.keys()) |
| 139 def __init__(self, name, values, timeInterval=None, mostSevereIsMax=True, maxValue = None): | 142 def __init__(self, name, values, timeInterval=None, mostSevereIsMax=True, maxValue = None): |
| 140 TemporalIndicator.__init__(self, name, values, timeInterval, maxValue) | 143 TemporalIndicator.__init__(self, name, values, timeInterval, maxValue) |
| 141 self.mostSevereIsMax = mostSevereIsMax | 144 self.mostSevereIsMax = mostSevereIsMax |
| 142 | 145 |
| 143 def getMostSevereValue(self, minNInstants=1): # TODO use np.percentile | 146 def getMostSevereValue(self, minNInstants=1): # TODO use np.percentile |
| 144 from matplotlib.mlab import find | |
| 145 from numpy.core.multiarray import array | |
| 146 from numpy.core.fromnumeric import mean | |
| 147 values = array(self.values.values()) | 147 values = array(self.values.values()) |
| 148 indices = range(len(values)) | 148 indices = range(len(values)) |
| 149 if len(indices) >= minNInstants: | 149 if len(indices) >= minNInstants: |
| 150 values = sorted(values[indices], reverse = self.mostSevereIsMax) # inverted if most severe is max -> take the first values | 150 values = sorted(values[indices], reverse = self.mostSevereIsMax) # inverted if most severe is max -> take the first values |
| 151 return mean(values[:minNInstants]) | 151 return mean(values[:minNInstants]) |
| 152 else: | 152 else: |
| 153 return None | 153 return None |
| 154 | 154 |
| 155 def getInstantOfMostSevereValue(self): | |
| 156 '''Returns the instant at which the indicator reaches its most severe value''' | |
| 157 if self.mostSevereIsMax: | |
| 158 return max(self.values, key=self.values.get) | |
| 159 else: | |
| 160 return min(self.values, key=self.values.get) | |
| 161 | |
| 155 # functions to aggregate discretized maps of indicators | 162 # functions to aggregate discretized maps of indicators |
| 156 # TODO add values in the cells between the positions (similar to discretizing vector graphics to bitmap) | 163 # TODO add values in the cells between the positions (similar to discretizing vector graphics to bitmap) |
| 157 | 164 |
| 158 def indicatorMap(indicatorValues, trajectory, squareSize): | 165 def indicatorMap(indicatorValues, trajectory, squareSize): |
| 159 '''Returns a dictionary | 166 '''Returns a dictionary |
| 161 in which the trajectory positions are located | 168 in which the trajectory positions are located |
| 162 at which the indicator values are attached | 169 at which the indicator values are attached |
| 163 | 170 |
| 164 ex: speeds and trajectory''' | 171 ex: speeds and trajectory''' |
| 165 | 172 |
| 166 from numpy import floor, mean | |
| 167 assert len(indicatorValues) == trajectory.length() | 173 assert len(indicatorValues) == trajectory.length() |
| 168 indicatorMap = {} | 174 indicatorMap = {} |
| 169 for k in xrange(trajectory.length()): | 175 for k in xrange(trajectory.length()): |
| 170 p = trajectory[k] | 176 p = trajectory[k] |
| 171 i = floor(p.x/squareSize) | 177 i = floor(p.x/squareSize) |
| 176 indicatorMap[(i,j)] = [indicatorValues[k]] | 182 indicatorMap[(i,j)] = [indicatorValues[k]] |
| 177 for k in indicatorMap.keys(): | 183 for k in indicatorMap.keys(): |
| 178 indicatorMap[k] = mean(indicatorMap[k]) | 184 indicatorMap[k] = mean(indicatorMap[k]) |
| 179 return indicatorMap | 185 return indicatorMap |
| 180 | 186 |
| 181 def indicatorMapFromPolygon(value, polygon, squareSize): | 187 # def indicatorMapFromPolygon(value, polygon, squareSize): |
| 182 '''Fills an indicator map with the value within the polygon | 188 # '''Fills an indicator map with the value within the polygon |
| 183 (array of Nx2 coordinates of the polygon vertices)''' | 189 # (array of Nx2 coordinates of the polygon vertices)''' |
| 184 import matplotlib.nxutils as nx | 190 # points = [] |
| 185 from numpy.core.multiarray import array, arange | 191 # for x in arange(min(polygon[:,0])+squareSize/2, max(polygon[:,0]), squareSize): |
| 186 from numpy import floor | 192 # for y in arange(min(polygon[:,1])+squareSize/2, max(polygon[:,1]), squareSize): |
| 187 | 193 # points.append([x,y]) |
| 188 points = [] | 194 # inside = nx.points_inside_poly(array(points), polygon) |
| 189 for x in arange(min(polygon[:,0])+squareSize/2, max(polygon[:,0]), squareSize): | 195 # indicatorMap = {} |
| 190 for y in arange(min(polygon[:,1])+squareSize/2, max(polygon[:,1]), squareSize): | 196 # for i in xrange(len(inside)): |
| 191 points.append([x,y]) | 197 # if inside[i]: |
| 192 inside = nx.points_inside_poly(array(points), polygon) | 198 # indicatorMap[(floor(points[i][0]/squareSize), floor(points[i][1]/squareSize))] = 0 |
| 193 indicatorMap = {} | 199 # return indicatorMap |
| 194 for i in xrange(len(inside)): | |
| 195 if inside[i]: | |
| 196 indicatorMap[(floor(points[i][0]/squareSize), floor(points[i][1]/squareSize))] = 0 | |
| 197 return indicatorMap | |
| 198 | 200 |
| 199 def indicatorMapFromAxis(value, limits, squareSize): | 201 def indicatorMapFromAxis(value, limits, squareSize): |
| 200 '''axis = [xmin, xmax, ymin, ymax] ''' | 202 '''axis = [xmin, xmax, ymin, ymax] ''' |
| 201 from numpy.core.multiarray import arange | |
| 202 from numpy import floor | |
| 203 indicatorMap = {} | 203 indicatorMap = {} |
| 204 for x in arange(limits[0], limits[1], squareSize): | 204 for x in arange(limits[0], limits[1], squareSize): |
| 205 for y in arange(limits[2], limits[3], squareSize): | 205 for y in arange(limits[2], limits[3], squareSize): |
| 206 indicatorMap[(floor(x/squareSize), floor(y/squareSize))] = value | 206 indicatorMap[(floor(x/squareSize), floor(y/squareSize))] = value |
| 207 return indicatorMap | 207 return indicatorMap |
| 208 | 208 |
| 209 def combineIndicatorMaps(maps, squareSize, combinationFunction): | 209 def combineIndicatorMaps(maps, squareSize, combinationFunction): |
| 210 '''Puts many indicator maps together | 210 '''Puts many indicator maps together |
| 211 (averaging the values in each cell | 211 (averaging the values in each cell |
| 212 if more than one maps has a value)''' | 212 if more than one maps has a value)''' |
| 213 #from numpy import mean | |
| 214 indicatorMap = {} | 213 indicatorMap = {} |
| 215 for m in maps: | 214 for m in maps: |
| 216 for k,v in m.iteritems(): | 215 for k,v in m.iteritems(): |
| 217 if indicatorMap.has_key(k): | 216 if indicatorMap.has_key(k): |
| 218 indicatorMap[k].append(v) | 217 indicatorMap[k].append(v) |
