comparison python/storage.py @ 758:0a05883216cf

merge with dev
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Tue, 03 Nov 2015 13:48:56 -0500
parents a73f43aac00e
children a05b70f307dd
comparison
equal deleted inserted replaced
748:d99866b0528a 758:0a05883216cf
1 #! /usr/bin/env python 1 #! /usr/bin/env python
2 # -*- coding: utf-8 -*- 2 # -*- coding: utf-8 -*-
3 '''Various utilities to save and load data''' 3 '''Various utilities to save and load data'''
4 4
5 import utils, moving, events, indicators 5 import utils, moving, events, indicators, shutil
6 from base import VideoFilenameAddable 6 from base import VideoFilenameAddable
7 7
8 import sqlite3, logging 8 import sqlite3, logging
9 from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt 9 from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt
10 from pandas import read_csv, merge
10 11
11 12
12 commentChar = '#' 13 commentChar = '#'
13 14
14 delimiterChar = '%'; 15 delimiterChar = '%';
161 returns a moving object''' 162 returns a moving object'''
162 cursor = connection.cursor() 163 cursor = connection.cursor()
163 164
164 try: 165 try:
165 objectCriteria = getObjectCriteria(objectNumbers) 166 objectCriteria = getObjectCriteria(objectNumbers)
167 queryStatement = None
166 if trajectoryType == 'feature': 168 if trajectoryType == 'feature':
167 queryStatement = 'SELECT * from '+tableName 169 queryStatement = 'SELECT * from '+tableName
168 if objectNumbers is not None: 170 if objectNumbers is not None:
169 queryStatement += ' where trajectory_id '+objectCriteria 171 queryStatement += ' WHERE trajectory_id '+objectCriteria
170 queryStatement += ' ORDER BY trajectory_id, frame_number' 172 queryStatement += ' ORDER BY trajectory_id, frame_number'
171 cursor.execute(queryStatement)
172 logging.debug(queryStatement)
173 elif trajectoryType == 'object': 173 elif trajectoryType == 'object':
174 queryStatement = 'SELECT OF.object_id, P.frame_number, avg(P.x_coordinate), avg(P.y_coordinate) from '+tableName+' P, objects_features OF where P.trajectory_id = OF.trajectory_id' 174 queryStatement = 'SELECT OF.object_id, P.frame_number, avg(P.x_coordinate), avg(P.y_coordinate) from '+tableName+' P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id'
175 if objectNumbers is not None: 175 if objectNumbers is not None:
176 queryStatement += ' and OF.object_id '+objectCriteria 176 queryStatement += ' and OF.object_id '+objectCriteria
177 queryStatement += ' GROUP BY OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number' 177 queryStatement += ' GROUP BY OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number'
178 cursor.execute(queryStatement)
179 logging.debug(queryStatement)
180 elif trajectoryType in ['bbtop', 'bbbottom']: 178 elif trajectoryType in ['bbtop', 'bbbottom']:
181 if trajectoryType == 'bbtop': 179 if trajectoryType == 'bbtop':
182 corner = 'top_left' 180 corner = 'top_left'
183 elif trajectoryType == 'bbbottom': 181 elif trajectoryType == 'bbbottom':
184 corner = 'bottom_right' 182 corner = 'bottom_right'
185 queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName 183 queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName
186 if objectNumbers is not None: 184 if objectNumbers is not None:
187 queryStatement += ' WHERE object_id '+objectCriteria 185 queryStatement += ' WHERE object_id '+objectCriteria
188 queryStatement += ' ORDER BY object_id, frame_number' 186 queryStatement += ' ORDER BY object_id, frame_number'
187 else:
188 print('no trajectory type was chosen')
189 if queryStatement is not None:
189 cursor.execute(queryStatement) 190 cursor.execute(queryStatement)
190 logging.debug(queryStatement) 191 logging.debug(queryStatement)
191 else:
192 print('no trajectory type was chosen')
193 except sqlite3.OperationalError as error: 192 except sqlite3.OperationalError as error:
194 printDBError(error) 193 printDBError(error)
195 return [] 194 return []
196 195
197 objId = -1 196 objId = -1
218 217
219 def loadUserTypesFromTable(cursor, trajectoryType, objectNumbers): 218 def loadUserTypesFromTable(cursor, trajectoryType, objectNumbers):
220 objectCriteria = getObjectCriteria(objectNumbers) 219 objectCriteria = getObjectCriteria(objectNumbers)
221 queryStatement = 'SELECT object_id, road_user_type from objects' 220 queryStatement = 'SELECT object_id, road_user_type from objects'
222 if objectNumbers is not None: 221 if objectNumbers is not None:
223 queryStatement += ' where object_id '+objectCriteria 222 queryStatement += ' WHERE object_id '+objectCriteria
224 cursor.execute(queryStatement) 223 cursor.execute(queryStatement)
225 userTypes = {} 224 userTypes = {}
226 for row in cursor: 225 for row in cursor:
227 userTypes[row[0]] = row[1] 226 userTypes[row[0]] = row[1]
228 return userTypes 227 return userTypes
245 if trajectoryType == 'object': 244 if trajectoryType == 'object':
246 cursor = connection.cursor() 245 cursor = connection.cursor()
247 try: 246 try:
248 # attribute feature numbers to objects 247 # attribute feature numbers to objects
249 objectCriteria = getObjectCriteria(objectNumbers) 248 objectCriteria = getObjectCriteria(objectNumbers)
250 queryStatement = 'SELECT P.trajectory_id, OF.object_id from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id' 249 queryStatement = 'SELECT P.trajectory_id, OF.object_id from positions P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id'
251 if objectNumbers is not None: 250 if objectNumbers is not None:
252 queryStatement += ' and OF.object_id '+objectCriteria 251 queryStatement += ' and OF.object_id '+objectCriteria
253 queryStatement += ' group by P.trajectory_id order by OF.object_id' # order is important to group all features per object 252 queryStatement += ' group by P.trajectory_id order by OF.object_id' # order is important to group all features per object
254 cursor.execute(queryStatement) 253 cursor.execute(queryStatement)
255 logging.debug(queryStatement) 254 logging.debug(queryStatement)
393 TODO choose the interactions to load''' 392 TODO choose the interactions to load'''
394 interactions = [] 393 interactions = []
395 connection = sqlite3.connect(filename) 394 connection = sqlite3.connect(filename)
396 cursor = connection.cursor() 395 cursor = connection.cursor()
397 try: 396 try:
398 cursor.execute('select INT.id, INT.object_id1, INT.object_id2, INT.first_frame_number, INT.last_frame_number, IND.indicator_type, IND.frame_number, IND.value from interactions INT, indicators IND where INT.id = IND.interaction_id ORDER BY INT.id, IND.indicator_type, IND.frame_number') 397 cursor.execute('select INT.id, INT.object_id1, INT.object_id2, INT.first_frame_number, INT.last_frame_number, IND.indicator_type, IND.frame_number, IND.value from interactions INT, indicators IND WHERE INT.id = IND.interaction_id ORDER BY INT.id, IND.indicator_type, IND.frame_number')
399 interactionNum = -1 398 interactionNum = -1
400 indicatorTypeNum = -1 399 indicatorTypeNum = -1
401 tmpIndicators = {} 400 tmpIndicators = {}
402 for row in cursor: 401 for row in cursor:
403 if row[0] != interactionNum: 402 if row[0] != interactionNum:
416 printDBError(error) 415 printDBError(error)
417 return [] 416 return []
418 connection.close() 417 connection.close()
419 return interactions 418 return interactions
420 # load first and last object instants 419 # load first and last object instants
421 # CREATE TEMP TABLE IF NOT EXISTS object_instants AS SELECT OF.object_id, min(frame_number) as first_instant, max(frame_number) as last_instant from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id group by OF.object_id order by OF.object_id 420 # CREATE TEMP TABLE IF NOT EXISTS object_instants AS SELECT OF.object_id, min(frame_number) as first_instant, max(frame_number) as last_instant from positions P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id group by OF.object_id order by OF.object_id
422 421
423 def createBoundingBoxTable(filename, invHomography = None): 422 def createBoundingBoxTable(filename, invHomography = None):
424 '''Create the table to store the object bounding boxes in image space 423 '''Create the table to store the object bounding boxes in image space
425 ''' 424 '''
426 connection = sqlite3.connect(filename) 425 connection = sqlite3.connect(filename)
427 cursor = connection.cursor() 426 cursor = connection.cursor()
428 try: 427 try:
429 cursor.execute('CREATE TABLE IF NOT EXISTS bounding_boxes (object_id INTEGER, frame_number INTEGER, x_top_left REAL, y_top_left REAL, x_bottom_right REAL, y_bottom_right REAL, PRIMARY KEY(object_id, frame_number))') 428 cursor.execute('CREATE TABLE IF NOT EXISTS bounding_boxes (object_id INTEGER, frame_number INTEGER, x_top_left REAL, y_top_left REAL, x_bottom_right REAL, y_bottom_right REAL, PRIMARY KEY(object_id, frame_number))')
430 cursor.execute('INSERT INTO bounding_boxes SELECT object_id, frame_number, min(x), min(y), max(x), max(y) from ' 429 cursor.execute('INSERT INTO bounding_boxes SELECT object_id, frame_number, min(x), min(y), max(x), max(y) from '
431 '(SELECT object_id, frame_number, (x*{}+y*{}+{})/w as x, (x*{}+y*{}+{})/w as y from ' 430 '(SELECT object_id, frame_number, (x*{}+y*{}+{})/w as x, (x*{}+y*{}+{})/w as y from '
432 '(SELECT OF.object_id, P.frame_number, P.x_coordinate as x, P.y_coordinate as y, P.x_coordinate*{}+P.y_coordinate*{}+{} as w from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id)) '.format(invHomography[0,0], invHomography[0,1], invHomography[0,2], invHomography[1,0], invHomography[1,1], invHomography[1,2], invHomography[2,0], invHomography[2,1], invHomography[2,2])+ 431 '(SELECT OF.object_id, P.frame_number, P.x_coordinate as x, P.y_coordinate as y, P.x_coordinate*{}+P.y_coordinate*{}+{} as w from positions P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id)) '.format(invHomography[0,0], invHomography[0,1], invHomography[0,2], invHomography[1,0], invHomography[1,1], invHomography[1,2], invHomography[2,0], invHomography[2,1], invHomography[2,2])+
433 'GROUP BY object_id, frame_number') 432 'GROUP BY object_id, frame_number')
434 except sqlite3.OperationalError as error: 433 except sqlite3.OperationalError as error:
435 printDBError(error) 434 printDBError(error)
436 connection.commit() 435 connection.commit()
437 connection.close() 436 connection.close()
645 644
646 def setRoutes(filename, objects): 645 def setRoutes(filename, objects):
647 connection = sqlite3.connect(filename) 646 connection = sqlite3.connect(filename)
648 cursor = connection.cursor() 647 cursor = connection.cursor()
649 for obj in objects: 648 for obj in objects:
650 cursor.execute('update objects set startRouteID = {} where object_id = {}'.format(obj.startRouteID, obj.getNum())) 649 cursor.execute('update objects set startRouteID = {} WHERE object_id = {}'.format(obj.startRouteID, obj.getNum()))
651 cursor.execute('update objects set endRouteID = {} where object_id = {}'.format(obj.endRouteID, obj.getNum())) 650 cursor.execute('update objects set endRouteID = {} WHERE object_id = {}'.format(obj.endRouteID, obj.getNum()))
652 connection.commit() 651 connection.commit()
653 connection.close() 652 connection.close()
654 653
655 def setRoadUserTypes(filename, objects): 654 def setRoadUserTypes(filename, objects):
656 '''Saves the user types of the objects in the sqlite database stored in filename 655 '''Saves the user types of the objects in the sqlite database stored in filename
657 The objects should exist in the objects table''' 656 The objects should exist in the objects table'''
658 connection = sqlite3.connect(filename) 657 connection = sqlite3.connect(filename)
659 cursor = connection.cursor() 658 cursor = connection.cursor()
660 for obj in objects: 659 for obj in objects:
661 cursor.execute('update objects set road_user_type = {} where object_id = {}'.format(obj.getUserType(), obj.getNum())) 660 cursor.execute('update objects set road_user_type = {} WHERE object_id = {}'.format(obj.getUserType(), obj.getNum()))
662 connection.commit() 661 connection.commit()
663 connection.close() 662 connection.close()
664 663
665 ######################### 664 #########################
666 # txt files 665 # txt files
731 else: return self.fp.readline() 730 else: return self.fp.readline()
732 731
733 def generatePDLaneColumn(data): 732 def generatePDLaneColumn(data):
734 data['LANE'] = data['LANE\LINK\NO'].astype(str)+'_'+data['LANE\INDEX'].astype(str) 733 data['LANE'] = data['LANE\LINK\NO'].astype(str)+'_'+data['LANE\INDEX'].astype(str)
735 734
736 def loadTrajectoriesFromVissimFile(filename, simulationStepsPerTimeUnit, nObjects = -1, warmUpLastInstant = None, usePandas = False, nDecimals = 2, lowMemory = True): 735 def convertTrajectoriesVissimToSqlite(filename):
736 '''Relies on a system call to sqlite3
737 sqlite3 [file.sqlite] < import_fzp.sql'''
738 sqlScriptFilename = "import_fzp.sql"
739 # create sql file
740 out = openCheck(sqlScriptFilename, "w")
741 out.write(".separator \";\"\n"+
742 "CREATE TABLE IF NOT EXISTS curvilinear_positions (t REAL, trajectory_id INTEGER, link_id INTEGER, lane_id INTEGER, s_coordinate REAL, y_coordinate REAL, speed REAL, PRIMARY KEY (t, trajectory_id));\n"+
743 ".import "+filename+" curvilinear_positions\n"+
744 "DELETE FROM curvilinear_positions WHERE trajectory_id IS NULL OR trajectory_id = \"NO\";\n")
745 out.close()
746 # system call
747 from subprocess import check_call
748 out = openCheck("err.log", "w")
749 check_call("sqlite3 "+utils.removeExtension(filename)+".sqlite < "+sqlScriptFilename, stderr = out, shell = True)
750 out.close()
751 shutil.os.remove(sqlScriptFilename)
752
753 def loadObjectNumbersInLinkFromVissimFile(filename, linkIds):
754 '''Finds the ids of the objects that go through any of the link in the list linkIds'''
755 connection = sqlite3.connect(filename)
756 cursor = connection.cursor()
757 queryStatement = 'SELECT DISTINCT trajectory_id FROM curvilinear_positions where link_id IN ('+','.join([str(id) for id in linkIds])+')'
758 try:
759 cursor.execute(queryStatement)
760 return [row[0] for row in cursor]
761 except sqlite3.OperationalError as error:
762 printDBError(error)
763
764
765 def loadTrajectoriesFromVissimFile(filename, simulationStepsPerTimeUnit, objectNumbers = None, warmUpLastInstant = None, usePandas = False, nDecimals = 2, lowMemory = True):
737 '''Reads data from VISSIM .fzp trajectory file 766 '''Reads data from VISSIM .fzp trajectory file
738 simulationStepsPerTimeUnit is the number of simulation steps per unit of time used by VISSIM 767 simulationStepsPerTimeUnit is the number of simulation steps per unit of time used by VISSIM (second)
739 for example, there seems to be 5 simulation steps per simulated second in VISSIM, 768 for example, there seems to be 10 simulation steps per simulated second in VISSIM,
740 so simulationStepsPerTimeUnit should be 5, 769 so simulationStepsPerTimeUnit should be 10,
741 so that all times correspond to the number of the simulation step (and can be stored as integers) 770 so that all times correspond to the number of the simulation step (and can be stored as integers)
742 771
743 Objects positions will be considered only after warmUpLastInstant 772 Objects positions will be considered only after warmUpLastInstant
744 (if the object has no such position, it won't be loaded) 773 (if the object has no such position, it won't be loaded)
745 774
746 Assumed to be sorted over time''' 775 Assumed to be sorted over time
776 Warning: if reading from SQLite a limited number of objects, objectNumbers will be the maximum object id'''
747 objects = {} # dictionary of objects index by their id 777 objects = {} # dictionary of objects index by their id
748 778
749 if usePandas: 779 if usePandas:
750 from pandas import read_csv
751 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, low_memory = lowMemory) 780 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, low_memory = lowMemory)
752 generatePDLaneColumn(data) 781 generatePDLaneColumn(data)
753 data['TIME'] = data['$VEHICLE:SIMSEC']*simulationStepsPerTimeUnit 782 data['TIME'] = data['$VEHICLE:SIMSEC']*simulationStepsPerTimeUnit
754 if warmUpLastInstant is not None: 783 if warmUpLastInstant is not None:
755 data = data[data['TIME']>=warmUpLastInstant] 784 data = data[data['TIME']>=warmUpLastInstant]
759 objNum = int(row['NO']) 788 objNum = int(row['NO'])
760 tmp = data[data['NO'] == objNum] 789 tmp = data[data['NO'] == objNum]
761 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(row['first'], row['last'])) 790 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(row['first'], row['last']))
762 # positions should be rounded to nDecimals decimals only 791 # positions should be rounded to nDecimals decimals only
763 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory(S = npround(tmp['POS'].tolist(), nDecimals), Y = npround(tmp['POSLAT'].tolist(), nDecimals), lanes = tmp['LANE'].tolist()) 792 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory(S = npround(tmp['POS'].tolist(), nDecimals), Y = npround(tmp['POSLAT'].tolist(), nDecimals), lanes = tmp['LANE'].tolist())
764 if nObjects > 0 and len(objects) >= nObjects: 793 if objectNumbers is not None and objectNumbers > 0 and len(objects) >= objectNumbers:
765 break 794 objects.values()
766 return objects.values()
767 else: 795 else:
768 inputfile = openCheck(filename, quitting = True) 796 if filename.endswith(".fzp"):
769 # data = pd.read_csv(filename, skiprows=15, delimiter=';') 797 inputfile = openCheck(filename, quitting = True)
770 # skip header: 15 lines + 1
771 line = readline(inputfile, '*$')
772 while len(line) > 0:#for line in inputfile:
773 data = line.strip().split(';')
774 objNum = int(data[1])
775 instant = int(float(data[0])*simulationStepsPerTimeUnit)
776 s = float(data[4])
777 y = float(data[5])
778 lane = data[2]+'_'+data[3]
779 if objNum not in objects:
780 if warmUpLastInstant is None or instant >= warmUpLastInstant:
781 if nObjects < 0 or len(objects) < nObjects:
782 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(instant, instant))
783 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory()
784 if (warmUpLastInstant is None or instant >= warmUpLastInstant) and objNum in objects:
785 objects[objNum].timeInterval.last = instant
786 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane)
787 line = readline(inputfile, '*$') 798 line = readline(inputfile, '*$')
788 799 while len(line) > 0:#for line in inputfile:
800 data = line.strip().split(';')
801 objNum = int(data[1])
802 instant = float(data[0])*simulationStepsPerTimeUnit
803 s = float(data[4])
804 y = float(data[5])
805 lane = data[2]+'_'+data[3]
806 if objNum not in objects:
807 if warmUpLastInstant is None or instant >= warmUpLastInstant:
808 if objectNumbers is None or len(objects) < objectNumbers:
809 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(instant, instant))
810 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory()
811 if (warmUpLastInstant is None or instant >= warmUpLastInstant) and objNum in objects:
812 objects[objNum].timeInterval.last = instant
813 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane)
814 line = readline(inputfile, '*$')
815 elif filename.endswith(".sqlite"):
816 connection = sqlite3.connect(filename)
817 cursor = connection.cursor()
818 queryStatement = 'SELECT t, trajectory_id, link_id, lane_id, s_coordinate, y_coordinate FROM curvilinear_positions'
819 if objectNumbers is not None:
820 queryStatement += ' WHERE trajectory_id '+getObjectCriteria(objectNumbers)
821 queryStatement += ' ORDER BY trajectory_id, t'
822 try:
823 cursor.execute(queryStatement)
824 for row in cursor:
825 objNum = row[1]
826 instant = row[0]*simulationStepsPerTimeUnit
827 s = row[4]
828 y = row[5]
829 lane = '{}_{}'.format(row[2], row[3])
830 if objNum not in objects:
831 if warmUpLastInstant is None or instant >= warmUpLastInstant:
832 if objectNumbers is None or len(objects) < objectNumbers:
833 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(instant, instant))
834 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory()
835 if (warmUpLastInstant is None or instant >= warmUpLastInstant) and objNum in objects:
836 objects[objNum].timeInterval.last = instant
837 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane)
838 except sqlite3.OperationalError as error:
839 printDBError(error)
840 else:
841 print("File type of "+filename+" not supported (only .sqlite and .fzp files)")
789 return objects.values() 842 return objects.values()
790 843
791 def selectPDLanes(data, lanes = None): 844 def selectPDLanes(data, lanes = None):
792 '''Selects the subset of data for the right lanes 845 '''Selects the subset of data for the right lanes
793 846
808 861
809 Vehicles are considered finally stationary 862 Vehicles are considered finally stationary
810 if more than proportionStationaryTime of their total time 863 if more than proportionStationaryTime of their total time
811 If lanes is not None, only the data for the selected lanes will be provided 864 If lanes is not None, only the data for the selected lanes will be provided
812 (format as string x_y where x is link index and y is lane index)''' 865 (format as string x_y where x is link index and y is lane index)'''
813 from pandas import read_csv 866 if filename.endswith(".fzp"):
814 columns = ['NO', '$VEHICLE:SIMSEC', 'POS'] 867 columns = ['NO', '$VEHICLE:SIMSEC', 'POS']
815 if lanes is not None: 868 if lanes is not None:
816 columns += ['LANE\LINK\NO', 'LANE\INDEX'] 869 columns += ['LANE\LINK\NO', 'LANE\INDEX']
817 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = columns, low_memory = lowMemory) 870 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = columns, low_memory = lowMemory)
818 data = selectPDLanes(data, lanes) 871 data = selectPDLanes(data, lanes)
819 data.sort(['$VEHICLE:SIMSEC'], inplace = True) 872 data.sort(['$VEHICLE:SIMSEC'], inplace = True)
820 873
821 nStationary = 0 874 nStationary = 0
822 nVehicles = 0 875 nVehicles = 0
823 for name, group in data.groupby(['NO'], sort = False): 876 for name, group in data.groupby(['NO'], sort = False):
824 nVehicles += 1 877 nVehicles += 1
825 positions = array(group['POS']) 878 positions = array(group['POS'])
826 diff = positions[1:]-positions[:-1] 879 diff = positions[1:]-positions[:-1]
827 if npsum(diff == 0.) >= proportionStationaryTime*len(positions): 880 if npsum(diff == 0.) >= proportionStationaryTime*(len(positions)-1):
828 nStationary += 1 881 nStationary += 1
882 elif filename.endswith(".sqlite"):
883 # select trajectory_id, t, s_coordinate, speed from curvilinear_positions where trajectory_id between 1860 and 1870 and speed < 0.1
884 # pb of the meaning of proportionStationaryTime in arterial network? Why proportion of existence time?
885 pass
886 else:
887 print("File type of "+filename+" not supported (only .sqlite and .fzp files)")
829 888
830 return nStationary, nVehicles 889 return nStationary, nVehicles
831 890
832 def countCollisionsVissim(filename, lanes = None, collisionTimeDifference = 0.2, lowMemory = True): 891 def countCollisionsVissim(filename, lanes = None, collisionTimeDifference = 0.2, lowMemory = True):
833 '''Counts the number of collisions per lane in a VISSIM trajectory file 892 '''Counts the number of collisions per lane in a VISSIM trajectory file
835 To distinguish between cars passing and collision, 894 To distinguish between cars passing and collision,
836 one checks when the sign of the position difference inverts 895 one checks when the sign of the position difference inverts
837 (if the time are closer than collisionTimeDifference) 896 (if the time are closer than collisionTimeDifference)
838 If lanes is not None, only the data for the selected lanes will be provided 897 If lanes is not None, only the data for the selected lanes will be provided
839 (format as string x_y where x is link index and y is lane index)''' 898 (format as string x_y where x is link index and y is lane index)'''
840 from pandas import read_csv, merge
841 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = ['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC', 'NO', 'POS'], low_memory = lowMemory) 899 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = ['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC', 'NO', 'POS'], low_memory = lowMemory)
842 data = selectPDLanes(data, lanes) 900 data = selectPDLanes(data, lanes)
843 data = data.convert_objects(convert_numeric=True) 901 data = data.convert_objects(convert_numeric=True)
844 902
845 merged = merge(data, data, how='inner', left_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], right_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], sort = False) 903 merged = merge(data, data, how='inner', left_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], right_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], sort = False)
852 if len(diff) >= 2 and npmin(diff) < 0 and npmax(diff) > 0: 910 if len(diff) >= 2 and npmin(diff) < 0 and npmax(diff) > 0:
853 xidx = diff[diff < 0].argmax() 911 xidx = diff[diff < 0].argmax()
854 yidx = diff[diff > 0].argmin() 912 yidx = diff[diff > 0].argmin()
855 if abs(group.loc[xidx, '$VEHICLE:SIMSEC'] - group.loc[yidx, '$VEHICLE:SIMSEC']) <= collisionTimeDifference: 913 if abs(group.loc[xidx, '$VEHICLE:SIMSEC'] - group.loc[yidx, '$VEHICLE:SIMSEC']) <= collisionTimeDifference:
856 nCollisions += 1 914 nCollisions += 1
915
916 # select TD1.link_id, TD1.lane_id from temp.diff_positions as TD1, temp.diff_positions as TD2 where TD1.link_id = TD2.link_id and TD1.lane_id = TD2.lane_id and TD1.id1 = TD2.id1 and TD1.id2 = TD2.id2 and TD1.t = TD2.t+0.1 and TD1.diff*TD2.diff < 0; # besoin de faire un group by??
917 # create temp table diff_positions as select CP1.t as t, CP1.link_id as link_id, CP1.lane_id as lane_id, CP1.trajectory_id as id1, CP2.trajectory_id as id2, CP1.s_coordinate - CP2.s_coordinate as diff from curvilinear_positions CP1, curvilinear_positions CP2 where CP1.link_id = CP2.link_id and CP1.lane_id = CP2.lane_id and CP1.t = CP2.t and CP1.trajectory_id > CP2.trajectory_id;
918 # SQL select link_id, lane_id, id1, id2, min(diff), max(diff) from (select CP1.t as t, CP1.link_id as link_id, CP1.lane_id as lane_id, CP1.trajectory_id as id1, CP2.trajectory_id as id2, CP1.s_coordinate - CP2.s_coordinate as diff from curvilinear_positions CP1, curvilinear_positions CP2 where CP1.link_id = CP2.link_id and CP1.lane_id = CP2.lane_id and CP1.t = CP2.t and CP1.trajectory_id > CP2.trajectory_id) group by link_id, lane_id, id1, id2 having min(diff)*max(diff) < 0
857 return nCollisions 919 return nCollisions
858 920
859 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1): 921 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1):
860 '''Reads data from the trajectory data provided by NGSIM project 922 '''Reads data from the trajectory data provided by NGSIM project
861 and returns the list of Feature objects''' 923 and returns the list of Feature objects'''