Mercurial Hosting > traffic-intelligence
comparison python/storage.py @ 649:df9ddeaee4a6
added ability to select lanes to count collisions or stationary vehicles in VISSIM files
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Thu, 16 Apr 2015 11:34:51 +0200 |
parents | 458890c0437c |
children | 994dd644f6ab |
comparison
equal
deleted
inserted
replaced
648:da665302c88d | 649:df9ddeaee4a6 |
---|---|
637 if self.sechead: | 637 if self.sechead: |
638 try: return self.sechead | 638 try: return self.sechead |
639 finally: self.sechead = None | 639 finally: self.sechead = None |
640 else: return self.fp.readline() | 640 else: return self.fp.readline() |
641 | 641 |
642 def generatePDLaneColumn(data): | |
643 data['LANE'] = data['LANE\LINK\NO'].astype(str)+'_'+data['LANE\INDEX'].astype(str) | |
644 | |
642 def loadTrajectoriesFromVissimFile(filename, simulationStepsPerTimeUnit, nObjects = -1, warmUpLastInstant = None, usePandas = False, nDecimals = 2): | 645 def loadTrajectoriesFromVissimFile(filename, simulationStepsPerTimeUnit, nObjects = -1, warmUpLastInstant = None, usePandas = False, nDecimals = 2): |
643 '''Reads data from VISSIM .fzp trajectory file | 646 '''Reads data from VISSIM .fzp trajectory file |
644 simulationStepsPerTimeUnit is the number of simulation steps per unit of time used by VISSIM | 647 simulationStepsPerTimeUnit is the number of simulation steps per unit of time used by VISSIM |
645 for example, there seems to be 5 simulation steps per simulated second in VISSIM, | 648 for example, there seems to be 5 simulation steps per simulated second in VISSIM, |
646 so simulationStepsPerTimeUnit should be 5, | 649 so simulationStepsPerTimeUnit should be 5, |
651 | 654 |
652 if usePandas: | 655 if usePandas: |
653 from pandas import read_csv | 656 from pandas import read_csv |
654 from numpy import min, max, round | 657 from numpy import min, max, round |
655 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1) | 658 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1) |
656 data['LANE'] = data['LANE\LINK\NO'].astype(str)+'_'+data['LANE\INDEX'].astype(str) | 659 generatePDLaneColumn(data) |
657 data['TIME'] = data['$VEHICLE:SIMSEC']*simulationStepsPerTimeUnit | 660 data['TIME'] = data['$VEHICLE:SIMSEC']*simulationStepsPerTimeUnit |
658 grouped = data.loc[:,['NO','TIME']].groupby(['NO'], as_index = False) | 661 grouped = data.loc[:,['NO','TIME']].groupby(['NO'], as_index = False) |
659 instants = grouped['TIME'].agg({'first': min, 'last': max}) | 662 instants = grouped['TIME'].agg({'first': min, 'last': max}) |
660 if warmUpLastInstant is not None: | 663 if warmUpLastInstant is not None: |
661 instants = instants[instants['first'] >= warmUpLastInstant] | 664 instants = instants[instants['first'] >= warmUpLastInstant] |
690 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane) | 693 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane) |
691 line = readline(inputfile, '*$') | 694 line = readline(inputfile, '*$') |
692 | 695 |
693 return objects.values() | 696 return objects.values() |
694 | 697 |
695 def countStoppedVehiclesVissim(filename, proportionStationaryTime = 0.7): | 698 def selectPDLanes(data, lanes = None): |
699 '''Selects the subset of data for the right lanes | |
700 | |
701 Lane format is a string 'x_y' where x is link index and y is lane index''' | |
702 if lanes is not None: | |
703 if 'LANE' not in data.columns: | |
704 generatePDLaneColumn(data) | |
705 indices = (data['LANE'] == lanes[0]) | |
706 for l in lanes[1:]: | |
707 indices = indices | (data['LANE'] == l) | |
708 return data[indices] | |
709 else: | |
710 return data | |
711 | |
712 def countStoppedVehiclesVissim(filename, lanes = None, proportionStationaryTime = 0.7): | |
696 '''Counts the number of vehicles stopped for a long time in a VISSIM trajectory file | 713 '''Counts the number of vehicles stopped for a long time in a VISSIM trajectory file |
697 and the total number of vehicles | 714 and the total number of vehicles |
698 | 715 |
699 Vehicles are considered finally stationary | 716 Vehicles are considered finally stationary |
700 if more than proportionStationaryTime of their total time''' | 717 if more than proportionStationaryTime of their total time |
718 If lanes is not None, only the data for the selected lanes will be provided | |
719 (format as string x_y where x is link index and y is lane index)''' | |
701 from pandas import read_csv | 720 from pandas import read_csv |
702 from numpy import array, sum as npsum | 721 from numpy import array, sum as npsum |
703 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = ['NO', '$VEHICLE:SIMSEC', 'POS']) # 'LANE\LINK\NO', 'LANE\INDEX', | 722 columns = ['NO', '$VEHICLE:SIMSEC', 'POS'] |
723 if lanes is not None: | |
724 columns += ['LANE\LINK\NO', 'LANE\INDEX'] | |
725 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = columns) | |
726 data = selectPDLanes(data, lanes) | |
704 data.sort(['$VEHICLE:SIMSEC'], inplace = True) | 727 data.sort(['$VEHICLE:SIMSEC'], inplace = True) |
705 #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) | |
706 #merged = merged[merged['NO_x']>merged['NO_y']] | |
707 | 728 |
708 nStationary = 0 | 729 nStationary = 0 |
709 from matplotlib.pyplot import plot, figure | 730 from matplotlib.pyplot import plot, figure |
710 nVehicles = 0 | 731 nVehicles = 0 |
711 for name, group in data.groupby(['NO'], sort = False): | 732 for name, group in data.groupby(['NO'], sort = False): |
715 if npsum(diff == 0.) >= proportionStationaryTime*len(positions): | 736 if npsum(diff == 0.) >= proportionStationaryTime*len(positions): |
716 nStationary += 1 | 737 nStationary += 1 |
717 | 738 |
718 return nStationary, nVehicles | 739 return nStationary, nVehicles |
719 | 740 |
720 def countCollisionsVissim(filename, collisionTimeDifference = 0.2): | 741 def countCollisionsVissim(filename, lanes = None, collisionTimeDifference = 0.2): |
721 '''Counts the number of collisions per lane in a VISSIM trajectory file | 742 '''Counts the number of collisions per lane in a VISSIM trajectory file |
722 | 743 |
723 To distinguish between cars passing and collision, | 744 To distinguish between cars passing and collision, |
724 one checks when the sign of the position difference inverts | 745 one checks when the sign of the position difference inverts |
725 (if the time are closer than collisionTimeDifference)''' | 746 (if the time are closer than collisionTimeDifference) |
747 If lanes is not None, only the data for the selected lanes will be provided | |
748 (format as string x_y where x is link index and y is lane index)''' | |
726 from pandas import read_csv, merge | 749 from pandas import read_csv, merge |
727 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = ['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC', 'NO', 'POS']) | 750 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = ['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC', 'NO', 'POS']) |
751 data = selectPDLanes(data, lanes) | |
728 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) | 752 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) |
729 merged = merged[merged['NO_x']>merged['NO_y']] | 753 merged = merged[merged['NO_x']>merged['NO_y']] |
730 | 754 |
731 nCollisions = 0 | 755 nCollisions = 0 |
732 for name, group in merged.groupby(['LANE\LINK\NO', 'LANE\INDEX', 'NO_x', 'NO_y']): | 756 for name, group in merged.groupby(['LANE\LINK\NO', 'LANE\INDEX', 'NO_x', 'NO_y']): |