Mercurial Hosting > traffic-intelligence
comparison python/utils.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 | c5406edbcf12 |
children | 0954aaf28231 |
comparison
equal
deleted
inserted
replaced
598:11f96bd08552 | 614:5e09583275a4 |
---|---|
1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
2 ''' Generic utilities.''' | 2 ''' Generic utilities.''' |
3 | 3 |
4 #from numpy import * | 4 #from numpy import * |
5 #from pylab import * | 5 #from pylab import * |
6 from datetime import time, datetime | |
7 from math import sqrt | |
6 | 8 |
7 __metaclass__ = type | 9 __metaclass__ = type |
8 | 10 |
9 commentChar = '#' | 11 datetimeFormat = "%Y-%m-%d %H:%M:%S" |
10 | |
11 delimiterChar = '%'; | |
12 | 12 |
13 ######################### | 13 ######################### |
14 # Enumerations | 14 # Enumerations |
15 ######################### | 15 ######################### |
16 | 16 |
20 for i,x in enumerate(l): | 20 for i,x in enumerate(l): |
21 result[x] = i | 21 result[x] = i |
22 return result | 22 return result |
23 | 23 |
24 ######################### | 24 ######################### |
25 # CLI utils | |
26 ######################### | |
27 | |
28 def parseCLIOptions(helpMessage, options, cliArgs, optionalOptions=[]): | |
29 ''' Simple function to handle similar argument parsing | |
30 Returns the dictionary of options and their values | |
31 | |
32 * cliArgs are most likely directly sys.argv | |
33 (only the elements after the first one are considered) | |
34 | |
35 * options should be a list of strings for getopt options, | |
36 eg ['frame=','correspondences=','video='] | |
37 A value must be provided for each option, or the program quits''' | |
38 import sys, getopt | |
39 from numpy.core.fromnumeric import all | |
40 optionValues, args = getopt.getopt(cliArgs[1:], 'h', ['help']+options+optionalOptions) | |
41 optionValues = dict(optionValues) | |
42 | |
43 if '--help' in optionValues.keys() or '-h' in optionValues.keys(): | |
44 print(helpMessage+ | |
45 '\n - Compulsory options: '+' '.join([opt.replace('=','') for opt in options])+ | |
46 '\n - Non-compulsory options: '+' '.join([opt.replace('=','') for opt in optionalOptions])) | |
47 sys.exit() | |
48 | |
49 missingArgument = [('--'+opt.replace('=','') in optionValues.keys()) for opt in options] | |
50 if not all(missingArgument): | |
51 print('Missing argument') | |
52 print(optionValues) | |
53 sys.exit() | |
54 | |
55 return optionValues | |
56 | |
57 ######################### | |
58 # simple statistics | 25 # simple statistics |
59 ######################### | 26 ######################### |
60 | 27 |
61 def confidenceInterval(mean, stdev, nSamples, percentConfidence, printLatex = False): | 28 def sampleSize(stdev, tolerance, percentConfidence, printLatex = False): |
62 from math import sqrt | |
63 from scipy.stats.distributions import norm | 29 from scipy.stats.distributions import norm |
64 k = round(norm.ppf(0.5+percentConfidence/200., 0, 1)*100)/100. # 1.-(100-percentConfidence)/200. | 30 k = round(norm.ppf(0.5+percentConfidence/200., 0, 1)*100)/100. # 1.-(100-percentConfidence)/200. |
31 if printLatex: | |
32 print('${0}^2\\frac{{{1}^2}}{{{2}^2}}$'.format(k, stdev, tolerance)) | |
33 return (k*stdev/tolerance)**2 | |
34 | |
35 def confidenceInterval(mean, stdev, nSamples, percentConfidence, trueStd = True, printLatex = False): | |
36 '''if trueStd, use normal distribution, otherwise, Student | |
37 | |
38 Use otherwise t.interval or norm.interval | |
39 ex: norm.interval(0.95, loc = 0., scale = 2.3/sqrt(11)) | |
40 t.interval(0.95, 10, loc=1.2, scale = 2.3/sqrt(nSamples)) | |
41 loc is mean, scale is sigma/sqrt(n) (for Student, 10 is df)''' | |
42 from math import sqrt | |
43 from scipy.stats.distributions import norm, t | |
44 if trueStd: | |
45 k = round(norm.ppf(0.5+percentConfidence/200., 0, 1)*100)/100. # 1.-(100-percentConfidence)/200. | |
46 else: # use Student | |
47 k = round(t.ppf(0.5+percentConfidence/200., nSamples-1)*100)/100. | |
65 e = k*stdev/sqrt(nSamples) | 48 e = k*stdev/sqrt(nSamples) |
66 if printLatex: | 49 if printLatex: |
67 print('${0} \pm {1}\\frac{{{2}}}{{\sqrt{{{3}}}}}$'.format(mean, k, stdev, nSamples)) | 50 print('${0} \pm {1}\\frac{{{2}}}{{\sqrt{{{3}}}}}$'.format(mean, k, stdev, nSamples)) |
68 return mean-e, mean+e | 51 return mean-e, mean+e |
69 | 52 |
76 | 59 |
77 class EmpiricalDistribution: | 60 class EmpiricalDistribution: |
78 def nSamples(self): | 61 def nSamples(self): |
79 return sum(self.counts) | 62 return sum(self.counts) |
80 | 63 |
81 def cumulativeDensityFunction(sample): | 64 def cumulativeDensityFunction(sample, normalized = False): |
82 '''Returns the cumulative density function of the sample of a random variable''' | 65 '''Returns the cumulative density function of the sample of a random variable''' |
83 from numpy.core.multiarray import array | 66 from numpy import arange, cumsum |
84 from numpy.lib.function_base import unique | 67 xaxis = sorted(sample) |
85 from numpy.core.fromnumeric import sum | 68 counts = arange(1,len(sample)+1) # dtype = float |
86 a = array(sample) | 69 if normalized: |
87 a.sort() | 70 counts /= float(len(sample)) |
88 xaxis = unique(a) | |
89 counts = [sum(a <= x) for x in xaxis] | |
90 return xaxis, counts | 71 return xaxis, counts |
91 | 72 |
92 class EmpiricalDiscreteDistribution(EmpiricalDistribution): | 73 class EmpiricalDiscreteDistribution(EmpiricalDistribution): |
93 '''Class to represent a sample of a distribution for a discrete random variable | 74 '''Class to represent a sample of a distribution for a discrete random variable |
94 ''' | 75 ''' |
172 | 153 |
173 ######################### | 154 ######################### |
174 # maths section | 155 # maths section |
175 ######################### | 156 ######################### |
176 | 157 |
177 def LCSS(l1, l2, threshold, distance, delta = float('inf')): | 158 # def kernelSmoothing(sampleX, X, Y, weightFunc, halfwidth): |
178 '''returns the longest common subsequence similarity | 159 # '''Returns a smoothed weighted version of Y at the predefined values of sampleX |
179 based on the threshold on distance between two elements of lists l1, l2 | 160 # Sum_x weight(sample_x,x) * y(x)''' |
180 ''' | 161 # from numpy import zeros, array |
181 from numpy import zeros, int as npint | 162 # smoothed = zeros(len(sampleX)) |
182 m = len(l1) | 163 # for i,x in enumerate(sampleX): |
183 n = len(l2) | 164 # weights = array([weightFunc(x,xx, halfwidth) for xx in X]) |
184 similarity = zeros((m+1,n+1), dtype = npint) | 165 # if sum(weights)>0: |
185 for i in xrange(1,m+1): | 166 # smoothed[i] = sum(weights*Y)/sum(weights) |
186 for j in xrange(max(1,i-delta),min(n+1,i+delta)): | 167 # else: |
187 if distance(l1[i-1], l2[j-1])<=threshold: | 168 # smoothed[i] = 0 |
188 similarity[i][j] = similarity[i-1][j-1]+1 | 169 # return smoothed |
189 else: | 170 |
190 similarity[i][j] = max(similarity[i-1][j], similarity[i][j-1]) | 171 def kernelSmoothing(x, X, Y, weightFunc, halfwidth): |
191 return similarity[-1][-1] | 172 '''Returns the smoothed estimate of (X,Y) at x |
192 | 173 Sum_x weight(sample_x,x) * y(x)''' |
193 def framesToTime(nFrames, frameRate, initialTime = (0.,0.,0.)): | 174 from numpy import zeros, array |
194 'returns hour, minutes and seconds' | 175 weights = array([weightFunc(x,observedx, halfwidth) for observedx in X]) |
176 if sum(weights)>0: | |
177 return sum(weights*Y)/sum(weights) | |
178 else: | |
179 return 0 | |
180 | |
181 def uniform(center, x, halfwidth): | |
182 if abs(center-x)<halfwidth: | |
183 return 1. | |
184 else: | |
185 return 0. | |
186 | |
187 def gaussian(center, x, halfwidth): | |
188 from numpy import exp | |
189 return exp(-((center-x)/halfwidth)**2/2) | |
190 | |
191 def epanechnikov(center, x, halfwidth): | |
192 diff = abs(center-x) | |
193 if diff<halfwidth: | |
194 return 1.-(diff/halfwidth)**2 | |
195 else: | |
196 return 0. | |
197 | |
198 def triangular(center, x, halfwidth): | |
199 diff = abs(center-x) | |
200 if diff<halfwidth: | |
201 return 1.-abs(diff/halfwidth) | |
202 else: | |
203 return 0. | |
204 | |
205 def medianSmoothing(x, X, Y, halfwidth): | |
206 '''Returns the media of Y's corresponding to X's in the interval [x-halfwidth, x+halfwidth]''' | |
207 from numpy import median | |
208 return median([y for observedx, y in zip(X,Y) if abs(x-observedx)<halfwidth]) | |
209 | |
210 def argmaxDict(d): | |
211 return max(d, key=d.get) | |
212 | |
213 def framesToTime(nFrames, frameRate, initialTime = time()): | |
214 '''returns a datetime.time for the time in hour, minutes and seconds | |
215 initialTime is a datetime.time''' | |
195 from math import floor | 216 from math import floor |
196 from datetime import time | 217 seconds = int(floor(float(nFrames)/float(frameRate))+initialTime.hour*3600+initialTime.minute*60+initialTime.second) |
197 seconds = int(floor(float(nFrames)/float(frameRate))+initialTime[0]*3600+initialTime[1]*60+initialTime[2]) | |
198 h = int(floor(seconds/3600.)) | 218 h = int(floor(seconds/3600.)) |
199 seconds = seconds - h*3600 | 219 seconds = seconds - h*3600 |
200 m = int(floor(seconds/60)) | 220 m = int(floor(seconds/60)) |
201 seconds = seconds - m*60 | 221 seconds = seconds - m*60 |
202 return time(h, m, seconds) | 222 return time(h, m, seconds) |
223 | |
224 def timeToFrames(t, frameRate): | |
225 return frameRate*(t.hour*3600+t.minute*60+t.second) | |
203 | 226 |
204 def sortXY(X,Y): | 227 def sortXY(X,Y): |
205 'returns the sorted (x, Y(x)) sorted on X' | 228 'returns the sorted (x, Y(x)) sorted on X' |
206 D = {} | 229 D = {} |
207 for x, y in zip(X,Y): | 230 for x, y in zip(X,Y): |
215 from math import ceil,pow | 238 from math import ceil,pow |
216 tens = pow(10,nDecimals) | 239 tens = pow(10,nDecimals) |
217 return ceil(v*tens)/tens | 240 return ceil(v*tens)/tens |
218 | 241 |
219 def inBetween(bound1, bound2, x): | 242 def inBetween(bound1, bound2, x): |
220 return bound1 <= x <= bound2 or bound2 <= x<= bound1 | 243 return bound1 <= x <= bound2 or bound2 <= x <= bound1 |
244 | |
245 def pointDistanceL2(x1,y1,x2,y2): | |
246 ''' Compute point-to-point distance (L2 norm, ie Euclidean distance)''' | |
247 return sqrt((x2-x1)**2+(y2-y1)**2) | |
221 | 248 |
222 def crossProduct(l1, l2): | 249 def crossProduct(l1, l2): |
223 return l1[0]*l2[1]-l1[1]*l2[0] | 250 return l1[0]*l2[1]-l1[1]*l2[0] |
224 | 251 |
225 def filterMovingWindow(input, halfWidth): | 252 def cat_mvgavg(cat_list, halfWidth): |
253 ''' Return a list of categories/values smoothed according to a window. | |
254 halfWidth is the search radius on either side''' | |
255 from copy import deepcopy | |
256 catgories = deepcopy(cat_list) | |
257 smoothed = catgories | |
258 for point in range(len(catgories)): | |
259 lower_bound_check = max(0,point-halfWidth) | |
260 upper_bound_check = min(len(catgories)-1,point+halfWidth+1) | |
261 window_values = catgories[lower_bound_check:upper_bound_check] | |
262 smoothed[point] = max(set(window_values), key=window_values.count) | |
263 return smoothed | |
264 | |
265 def filterMovingWindow(inputSignal, halfWidth): | |
226 '''Returns an array obtained after the smoothing of the input by a moving average | 266 '''Returns an array obtained after the smoothing of the input by a moving average |
227 The first and last points are copied from the original.''' | 267 The first and last points are copied from the original.''' |
268 from numpy import ones,convolve,array | |
228 width = float(halfWidth*2+1) | 269 width = float(halfWidth*2+1) |
229 win = ones(width,'d') | 270 win = ones(width,'d') |
230 result = convolve(win/width,array(inputSignal),'same') | 271 result = convolve(win/width,array(inputSignal),'same') |
231 result[:halfWidth] = inputSignal[:halfWidth] | 272 result[:halfWidth] = inputSignal[:halfWidth] |
232 result[-halfWidth:] = inputSignal[-halfWidth:] | 273 result[-halfWidth:] = inputSignal[-halfWidth:] |
249 xx = arange(min(x), max(x),(max(x)-min(x))/1000) | 290 xx = arange(min(x), max(x),(max(x)-min(x))/1000) |
250 plot(xx, [poly(z) for z in xx]) | 291 plot(xx, [poly(z) for z in xx]) |
251 return coef | 292 return coef |
252 | 293 |
253 ######################### | 294 ######################### |
295 # iterable section | |
296 ######################### | |
297 | |
298 def mostCommon(L): | |
299 '''Returns the most frequent element in a iterable | |
300 | |
301 taken from http://stackoverflow.com/questions/1518522/python-most-common-element-in-a-list''' | |
302 from itertools import groupby | |
303 from operator import itemgetter | |
304 # get an iterable of (item, iterable) pairs | |
305 SL = sorted((x, i) for i, x in enumerate(L)) | |
306 # print 'SL:', SL | |
307 groups = groupby(SL, key=itemgetter(0)) | |
308 # auxiliary function to get "quality" for an item | |
309 def _auxfun(g): | |
310 item, iterable = g | |
311 count = 0 | |
312 min_index = len(L) | |
313 for _, where in iterable: | |
314 count += 1 | |
315 min_index = min(min_index, where) | |
316 # print 'item %r, count %r, minind %r' % (item, count, min_index) | |
317 return count, -min_index | |
318 # pick the highest-count/earliest item | |
319 return max(groups, key=_auxfun)[0] | |
320 | |
321 ######################### | |
322 # sequence section | |
323 ######################### | |
324 | |
325 class LCSS: | |
326 '''Class that keeps the LCSS parameters | |
327 and puts together the various computations''' | |
328 def __init__(self, similarityFunc, delta = float('inf'), aligned = False, lengthFunc = min): | |
329 self.similarityFunc = similarityFunc | |
330 self.aligned = aligned | |
331 self.delta = delta | |
332 self.lengthFunc = lengthFunc | |
333 self.subSequenceIndices = [(0,0)] | |
334 | |
335 def similarities(self, l1, l2, jshift=0): | |
336 from numpy import zeros, int as npint | |
337 n1 = len(l1) | |
338 n2 = len(l2) | |
339 self.similarityTable = zeros((n1+1,n2+1), dtype = npint) | |
340 for i in xrange(1,n1+1): | |
341 for j in xrange(max(1,i-jshift-self.delta),min(n2,i-jshift+self.delta)+1): | |
342 if self.similarityFunc(l1[i-1], l2[j-1]): | |
343 self.similarityTable[i,j] = self.similarityTable[i-1,j-1]+1 | |
344 else: | |
345 self.similarityTable[i,j] = max(self.similarityTable[i-1,j], self.similarityTable[i,j-1]) | |
346 | |
347 def subSequence(self, i, j): | |
348 '''Returns the subsequence of two sequences | |
349 http://en.wikipedia.org/wiki/Longest_common_subsequence_problem''' | |
350 if i == 0 or j == 0: | |
351 return [] | |
352 elif self.similarityTable[i][j] == self.similarityTable[i][j-1]: | |
353 return self.subSequence(i, j-1) | |
354 elif self.similarityTable[i][j] == self.similarityTable[i-1][j]: | |
355 return self.subSequence(i-1, j) | |
356 else: | |
357 return self.subSequence(i-1, j-1) + [(i-1,j-1)] | |
358 | |
359 def _compute(self, _l1, _l2, computeSubSequence = False): | |
360 '''returns the longest common subsequence similarity | |
361 based on the threshold on distance between two elements of lists l1, l2 | |
362 similarityFunc returns True or False whether the two points are considered similar | |
363 | |
364 if aligned, returns the best matching if using a finite delta by shiftinig the series alignments | |
365 | |
366 eg distance(p1, p2) < epsilon | |
367 ''' | |
368 if len(_l2) < len(_l1): # l1 is the shortest | |
369 l1 = _l2 | |
370 l2 = _l1 | |
371 revertIndices = True | |
372 else: | |
373 l1 = _l1 | |
374 l2 = _l2 | |
375 revertIndices = False | |
376 n1 = len(l1) | |
377 n2 = len(l2) | |
378 | |
379 if self.aligned: | |
380 lcssValues = {} | |
381 similarityTables = {} | |
382 for i in xrange(-n2-self.delta+1, n1+self.delta): # interval such that [i-shift-delta, i-shift+delta] is never empty, which happens when i-shift+delta < 1 or when i-shift-delta > n2 | |
383 self.similarities(l1, l2, i) | |
384 lcssValues[i] = self.similarityTable.max() | |
385 similarityTables[i] = self.similarityTable | |
386 #print self.similarityTable | |
387 alignmentShift = argmaxDict(lcssValues) # ideally get the medium alignment shift, the one that minimizes distance | |
388 self.similarityTable = similarityTables[alignmentShift] | |
389 else: | |
390 alignmentShift = 0 | |
391 self.similarities(l1, l2) | |
392 | |
393 # threshold values for the useful part of the similarity table are n2-n1-delta and n1-n2-delta | |
394 self.similarityTable = self.similarityTable[:min(n1, n2+alignmentShift+self.delta)+1, :min(n2, n1-alignmentShift+self.delta)+1] | |
395 | |
396 if computeSubSequence: | |
397 self.subSequenceIndices = self.subSequence(self.similarityTable.shape[0]-1, self.similarityTable.shape[1]-1) | |
398 if revertIndices: | |
399 self.subSequenceIndices = [(j,i) for i,j in self.subSequenceIndices] | |
400 return self.similarityTable[-1,-1] | |
401 | |
402 def compute(self, l1, l2, computeSubSequence = False): | |
403 '''get methods are to be shadowed in child classes ''' | |
404 return self._compute(l1, l2, computeSubSequence) | |
405 | |
406 def computeAlignment(self): | |
407 from numpy import mean | |
408 return mean([j-i for i,j in self.subSequenceIndices]) | |
409 | |
410 def _computeNormalized(self, l1, l2, computeSubSequence = False): | |
411 ''' compute the normalized LCSS | |
412 ie, the LCSS divided by the min or mean of the indicator lengths (using lengthFunc) | |
413 lengthFunc = lambda x,y:float(x,y)/2''' | |
414 return float(self._compute(l1, l2, computeSubSequence))/self.lengthFunc(len(l1), len(l2)) | |
415 | |
416 def computeNormalized(self, l1, l2, computeSubSequence = False): | |
417 return self._computeNormalized(l1, l2, computeSubSequence) | |
418 | |
419 def _computeDistance(self, l1, l2, computeSubSequence = False): | |
420 ''' compute the LCSS distance''' | |
421 return 1-self._computeNormalized(l1, l2, computeSubSequence) | |
422 | |
423 def computeDistance(self, l1, l2, computeSubSequence = False): | |
424 return self._computeDistance(l1, l2, computeSubSequence) | |
425 | |
426 ######################### | |
254 # plotting section | 427 # plotting section |
255 ######################### | 428 ######################### |
256 | 429 |
257 def stepPlot(X, firstX, lastX, initialCount = 0): | 430 def plotPolygon(poly, options = ''): |
258 '''for each value in x, increment by one the initial count | 431 'Plots shapely polygon poly' |
432 from numpy.core.multiarray import array | |
433 from matplotlib.pyplot import plot | |
434 from shapely.geometry import Polygon | |
435 | |
436 tmp = array(poly.exterior) | |
437 plot(tmp[:,0], tmp[:,1], options) | |
438 | |
439 def stepPlot(X, firstX, lastX, initialCount = 0, increment = 1): | |
440 '''for each value in X, increment by increment the initial count | |
259 returns the lists that can be plotted | 441 returns the lists that can be plotted |
260 to obtain a step plot increasing by one for each value in x, from first to last value''' | 442 to obtain a step plot increasing by one for each value in x, from first to last value |
443 firstX and lastX should be respectively smaller and larger than all elements in X''' | |
261 | 444 |
262 sortedX = [] | 445 sortedX = [] |
263 counts = [initialCount] | 446 counts = [initialCount] |
264 for x in sorted(X): | 447 for x in sorted(X): |
265 sortedX += [x,x] | 448 sortedX += [x,x] |
266 counts.append(counts[-1]) | 449 counts.append(counts[-1]) |
267 counts.append(counts[-1]+1) | 450 counts.append(counts[-1]+increment) |
268 counts.append(counts[-1]) | 451 counts.append(counts[-1]) |
269 return [firstX]+sortedX+[lastX], counts | 452 return [firstX]+sortedX+[lastX], counts |
270 | 453 |
271 class PlottingPropertyValues: | 454 class PlottingPropertyValues: |
272 def __init__(self, values): | 455 def __init__(self, values): |
300 | 483 |
301 ######################### | 484 ######################### |
302 # file I/O section | 485 # file I/O section |
303 ######################### | 486 ######################### |
304 | 487 |
305 def openCheck(filename, option = 'r', quit = False): | |
306 '''Open file filename in read mode by default | |
307 and checks it is open''' | |
308 try: | |
309 return open(filename, option) | |
310 except IOError: | |
311 print 'File %s could not be opened.' % filename | |
312 if quit: | |
313 from sys import exit | |
314 exit() | |
315 return None | |
316 | |
317 def readline(f, commentCharacter = commentChar): | |
318 '''Modified readline function to skip comments.''' | |
319 s = f.readline() | |
320 while (len(s) > 0) and s.startswith(commentCharacter): | |
321 s = f.readline() | |
322 return s.strip() | |
323 | |
324 def getLines(f, delimiterCharacter = delimiterChar): | |
325 '''Gets a complete entry (all the lines) in between delimiterChar.''' | |
326 dataStrings = [] | |
327 s = readline(f) | |
328 while (len(s) > 0) and (not s.startswith(delimiterCharacter)): | |
329 dataStrings += [s.strip()] | |
330 s = readline(f) | |
331 return dataStrings | |
332 | |
333 class FakeSecHead(object): | |
334 '''Add fake section header [asection] | |
335 | |
336 from http://stackoverflow.com/questions/2819696/parsing-properties-file-in-python/2819788#2819788 | |
337 use read_file in Python 3.2+ | |
338 ''' | |
339 def __init__(self, fp): | |
340 self.fp = fp | |
341 self.sechead = '[main]\n' | |
342 | |
343 def readline(self): | |
344 if self.sechead: | |
345 try: return self.sechead | |
346 finally: self.sechead = None | |
347 else: return self.fp.readline() | |
348 | |
349 def removeExtension(filename, delimiter = '.'): | 488 def removeExtension(filename, delimiter = '.'): |
350 '''Returns the filename minus the extension (all characters after last .)''' | 489 '''Returns the filename minus the extension (all characters after last .)''' |
351 i = filename.rfind(delimiter) | 490 i = filename.rfind(delimiter) |
352 if i>0: | 491 if i>0: |
353 return filename[:i] | 492 return filename[:i] |
384 if (os.path.exists(filename)): | 523 if (os.path.exists(filename)): |
385 os.remove(filename) | 524 os.remove(filename) |
386 else: | 525 else: |
387 print(filename+' does not exist') | 526 print(filename+' does not exist') |
388 | 527 |
389 def plotPolygon(poly, options = ''): | |
390 from numpy.core.multiarray import array | |
391 from matplotlib.pyplot import plot | |
392 from shapely.geometry import Polygon | |
393 | |
394 tmp = array(poly.exterior) | |
395 plot(tmp[:,0], tmp[:,1], options) | |
396 | |
397 def line2Floats(l, separator=' '): | 528 def line2Floats(l, separator=' '): |
398 '''Returns the list of floats corresponding to the string''' | 529 '''Returns the list of floats corresponding to the string''' |
399 return [float(x) for x in l.split(separator)] | 530 return [float(x) for x in l.split(separator)] |
400 | 531 |
401 def line2Ints(l, separator=' '): | 532 def line2Ints(l, separator=' '): |
402 '''Returns the list of ints corresponding to the string''' | 533 '''Returns the list of ints corresponding to the string''' |
403 return [int(x) for x in l.split(separator)] | 534 return [int(x) for x in l.split(separator)] |
404 | 535 |
405 ######################### | 536 ######################### |
406 # sqlite | 537 # CLI utils |
407 ######################### | 538 ######################### |
408 | 539 |
409 def dropTables(connection, tableNames): | 540 def parseCLIOptions(helpMessage, options, cliArgs, optionalOptions=[]): |
410 'deletes the table with names in tableNames' | 541 ''' Simple function to handle similar argument parsing |
411 cursor = connection.cursor() | 542 Returns the dictionary of options and their values |
412 for tableName in tableNames: | 543 |
413 cursor.execute('DROP TABLE '+tableName) | 544 * cliArgs are most likely directly sys.argv |
545 (only the elements after the first one are considered) | |
546 | |
547 * options should be a list of strings for getopt options, | |
548 eg ['frame=','correspondences=','video='] | |
549 A value must be provided for each option, or the program quits''' | |
550 import sys, getopt | |
551 from numpy.core.fromnumeric import all | |
552 optionValues, args = getopt.getopt(cliArgs[1:], 'h', ['help']+options+optionalOptions) | |
553 optionValues = dict(optionValues) | |
554 | |
555 if '--help' in optionValues.keys() or '-h' in optionValues.keys(): | |
556 print(helpMessage+ | |
557 '\n - Compulsory options: '+' '.join([opt.replace('=','') for opt in options])+ | |
558 '\n - Non-compulsory options: '+' '.join([opt.replace('=','') for opt in optionalOptions])) | |
559 sys.exit() | |
560 | |
561 missingArgument = [('--'+opt.replace('=','') in optionValues.keys()) for opt in options] | |
562 if not all(missingArgument): | |
563 print('Missing argument') | |
564 print(optionValues) | |
565 sys.exit() | |
566 | |
567 return optionValues | |
568 | |
569 | |
570 ######################### | |
571 # Profiling | |
572 ######################### | |
573 | |
574 def analyzeProfile(profileFilename, stripDirs = True): | |
575 '''Analyze the file produced by cProfile | |
576 | |
577 obtained by for example: | |
578 - call in script (for main() function in script) | |
579 import cProfile, os | |
580 cProfile.run('main()', os.path.join(os.getcwd(),'main.profile')) | |
581 | |
582 - or on the command line: | |
583 python -m cProfile [-o profile.bin] [-s sort] scriptfile [arg]''' | |
584 import pstats, os | |
585 p = pstats.Stats(os.path.join(os.pardir, profileFilename)) | |
586 if stripDirs: | |
587 p.strip_dirs() | |
588 p.sort_stats('time') | |
589 p.print_stats(.2) | |
590 #p.sort_stats('time') | |
591 # p.print_callees(.1, 'int_prediction.py:') | |
592 return p | |
414 | 593 |
415 ######################### | 594 ######################### |
416 # running tests | 595 # running tests |
417 ######################### | 596 ######################### |
418 | 597 |