changeset 1072:c67f8c36ebc7

interaction extraction
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Thu, 19 Jul 2018 01:44:11 -0400
parents 58994b08be42
children b123fa0e5440
files scripts/process.py trafficintelligence/processing.py
diffstat 2 files changed, 51 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/process.py	Wed Jul 18 02:12:47 2018 -0400
+++ b/scripts/process.py	Thu Jul 19 01:44:11 2018 -0400
@@ -60,7 +60,7 @@
 
 # analysis options
 parser.add_argument('--output', dest = 'output', help = 'kind of output to produce (interval means)', choices = ['figure', 'interval', 'event'])
-parser.add_argument('--min-user-duration', dest = 'minUserDuration', help = 'mininum duration we have to see the user to take into account in the analysis (s)', type = float, default = 0.1)
+parser.add_argument('--min-duration', dest = 'minDuration', help = 'mininum duration we have to see the user or interaction to take into account in the analysis (s)', type = float)
 parser.add_argument('--interval-duration', dest = 'intervalDuration', help = 'length of time interval to aggregate data (min)', type = int, default = 15)
 parser.add_argument('--aggregation', dest = 'aggMethods', help = 'aggregation method per user/interaction and per interval', choices = ['mean', 'median', 'centile'], nargs = '*', default = ['median'])
 parser.add_argument('--aggregation-centiles', dest = 'aggCentiles', help = 'centile(s) to compute from the observations', nargs = '*', type = int)
@@ -259,9 +259,9 @@
     headers.extend(tmpheaders)
     if args.nProcesses == 1:
         for vs in videoSequences:
-            data.extend(processing.extractVideoSequenceSpeeds(str(parentPath/vs.getDatabaseFilename()), vs.cameraView.site.name, args.nObjects, vs.startTime, vs.cameraView.cameraType.frameRate, args.minUserDuration, args.aggMethods, args.aggCentiles))
+            data.extend(processing.extractVideoSequenceSpeeds(str(parentPath/vs.getDatabaseFilename()), vs.cameraView.site.name, args.nObjects, vs.startTime, vs.cameraView.cameraType.frameRate, vs.cameraView.cameraType.frameRate*args.minDuration, args.aggMethods, args.aggCentiles))
     else:
-        jobs = [pool.apply_async(processing.extractVideoSequenceSpeeds, args = (str(parentPath/vs.getDatabaseFilename()), vs.cameraView.site.name, args.nObjects, vs.startTime, vs.cameraView.cameraType.frameRate, args.minUserDuration, args.aggMethods, args.aggCentiles)) for vs in videoSequences]
+        jobs = [pool.apply_async(processing.extractVideoSequenceSpeeds, args = (str(parentPath/vs.getDatabaseFilename()), vs.cameraView.site.name, args.nObjects, vs.startTime, vs.cameraView.cameraType.frameRate, vs.cameraView.cameraType.frameRate*args.minDuration, args.aggMethods, args.aggCentiles)) for vs in videoSequences]
         for job in jobs:
             data.extend(job.get())
         pool.close()
@@ -280,33 +280,55 @@
 if args.analyze == 'interaction': # redo as for object, export in dataframe all interaction data
     indicatorIds = [2,5,7,10]
     conversionFactors = {2: 1., 5: 30.*3.6, 7:1./30, 10:1./30}
-    maxIndicatorValue = {2: float('inf'), 5: float('inf'), 7:10., 10:10.}
+    #maxIndicatorValue = {2: float('inf'), 5: float('inf'), 7:10., 10:10.}
+    data = [] # list of observation per site-user with time
+    headers = ['site', 'date', 'time', events.Interaction.indicatorNames[10].replace(' ','-')] # user types?
+    aggFunctions, tmpheaders = utils.aggregationMethods(args.aggMethods, args.aggCentiles)
+    for i in indicatorIds[:3]:
+        for h in tmpheaders:
+            headers.append(events.Interaction.indicatorNames[i].replace(' ','-')+'-'+h)
     indicators = {}
     interactions = {}
     for vs in videoSequences:
-        if not vs.cameraView.siteIdx in interactions:
-            interactions[vs.cameraView.siteIdx] = []
-            indicators[vs.cameraView.siteIdx] = {}
-            for i in indicatorIds:
-                indicators[vs.cameraView.siteIdx][i] = []
-        interactions[vs.cameraView.siteIdx] += storage.loadInteractionsFromSqlite(str(parentPath/vs.getDatabaseFilename()))
-        print(vs.getDatabaseFilename(), len(interactions[vs.cameraView.siteIdx]))
-        for inter in interactions[vs.cameraView.siteIdx]:
-            for i in indicatorIds:
-                indic = inter.getIndicator(events.Interaction.indicatorNames[i])
-                if indic is not None:
-                    v = indic.getMostSevereValue()*conversionFactors[i]
-                    if v < maxIndicatorValue[i]:
-                        indicators[vs.cameraView.siteIdx][i].append(v)
-
-    for i in indicatorIds:
-        tmp = [indicators[siteId][i] for siteId in indicators]
-        plt.ioff()
-        plt.figure()
-        plt.boxplot(tmp, labels = [session.query(Site).get(siteId).name for siteId in indicators])
-        plt.ylabel(events.Interaction.indicatorNames[i]+' ('+events.Interaction.indicatorUnits[i]+')')
-        plt.savefig(events.Interaction.indicatorNames[i]+'.png', dpi=150)
-        plt.close()
+        print('Extracting SMoS from '+vs.getDatabaseFilename())
+        interactions = storage.loadInteractionsFromSqlite(str(parentPath/vs.getDatabaseFilename()))
+        minDuration = vs.cameraView.cameraType.frameRate*args.minDuration
+        for inter in interactions:
+            if inter.length() > minDuration:
+                d = vs.startTime.date()
+                t = vs.startTime.time()
+                row = [vs.cameraView.site.name, d, utils.framesToTime(inter.getFirstInstant(), vs.cameraView.cameraType.frameRate, t)]
+                pet = inter.getIndicator('Post Encroachment Time')
+                if pet is None:
+                    row.append(None)
+                else:
+                    row.append(conversionFactors[10]*pet.getValues()[0])
+                for i in indicatorIds[:3]:
+                    indic = inter.getIndicator(events.Interaction.indicatorNames[i])
+                    if indic is not None:
+                        #v = indic.getMostSevereValue()*
+                        tmp = list(indic.values.values())
+                        for method,func in aggFunctions.items():
+                            agg = conversionFactors[i]*func(tmp)
+                            if method == 'centile':
+                                row.extend(agg.tolist())
+                            else:
+                                row.append(agg)
+                    else:
+                        row.extend([None]*len(aggFunctions))
+                data.append(row)
+    data = pd.DataFrame(data, columns = headers)
+    if args.output == 'figure':
+        for i in indicatorIds:
+            pass # tmp = [indicators[siteId][i] for siteId in indicators]
+            # plt.ioff()
+            # plt.figure()
+            # plt.boxplot(tmp, labels = [session.query(Site).get(siteId).name for siteId in indicators])
+            # plt.ylabel(events.Interaction.indicatorNames[i]+' ('+events.Interaction.indicatorUnits[i]+')')
+            # plt.savefig(events.Interaction.indicatorNames[i]+'.png', dpi=150)
+            # plt.close()
+    elif args.output == 'event':
+        data.to_csv(args.eventFilename, index = False)
 
 if args.analyze == 'event': # aggregate event data by 15 min interval (args.intervalDuration), count events with thresholds
     data = pd.read_csv(args.eventFilename, parse_dates = [2])
--- a/trafficintelligence/processing.py	Wed Jul 18 02:12:47 2018 -0400
+++ b/trafficintelligence/processing.py	Thu Jul 19 01:44:11 2018 -0400
@@ -18,16 +18,15 @@
             objectsNotInZone.append(o)
     return speeds, objectsNotInZone
 
-def extractVideoSequenceSpeeds(dbFilename, siteName, nObjects, startTime, frameRate, minUserDurationSeconds, aggMethods, aggCentiles):
+def extractVideoSequenceSpeeds(dbFilename, siteName, nObjects, startTime, frameRate, minDuration, aggMethods, aggCentiles):
     data = []
     d = startTime.date()
     t1 = startTime.time()
-    minUserDuration = minUserDurationSeconds*frameRate
     print('Extracting speed from '+dbFilename)
     aggFunctions, tmpheaders = utils.aggregationMethods(aggMethods, aggCentiles)
     objects = storage.loadTrajectoriesFromSqlite(dbFilename, 'object', nObjects)
     for o in objects:
-        if o.length() > minUserDuration:
+        if o.length() > minDuration:
             row = [siteName, d, utils.framesToTime(o.getFirstInstant(), frameRate, t1), o.getUserType()]
             tmp = o.getSpeeds()
             for method,func in aggFunctions.items():