changeset 1256:56d0195d043e

cleaning indicators (no more time interval) and runtimeerror with arccos
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Wed, 03 Apr 2024 14:41:20 -0400
parents c0fe55a6b82f
children e59a0a475a0a
files trafficintelligence/events.py trafficintelligence/indicators.py trafficintelligence/storage.py trafficintelligence/tests/indicators.txt
diffstat 4 files changed, 43 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/trafficintelligence/events.py	Wed Apr 03 12:30:36 2024 -0400
+++ b/trafficintelligence/events.py	Wed Apr 03 14:41:20 2024 -0400
@@ -6,6 +6,7 @@
 from trafficintelligence.base import VideoFilenameAddable
 
 import numpy as np
+from matplotlib.pyplot import subplot, figure, ylabel
 
 import multiprocessing
 import itertools, logging
@@ -168,6 +169,20 @@
         self.roadUser1.plotOnWorldImage(nPixelsPerUnitDistance, options, withOrigin, timeStep, **kwargs)
         self.roadUser2.plotOnWorldImage(nPixelsPerUnitDistance, options, withOrigin, timeStep, **kwargs)
 
+    def plotIndicators(self, _indicatorNames = indicatorNames):
+        nrows = int(np.ceil(len(_indicatorNames)/2))
+        ncols = 2
+        #subplot(nrows, 2)
+        for i, indicatorName in enumerate(_indicatorNames):
+            if i==0:
+                ax = subplot(nrows, ncols, i+1)
+            else:
+                subplot(nrows, ncols, i+1, sharex = ax)
+            ind = self.getIndicator(indicatorName)
+            if ind is not None:
+                ind.plot()
+                ylabel(indicatorName)
+        
     def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1., allUserInstants = False):
         if self.roadUser1 is not None and self.roadUser2 is not None:
             if allUserInstants:
@@ -196,14 +211,14 @@
             v1Norm = v1.norm2()
             v2Norm = v2.norm2()
             if v1Norm != 0. and v2Norm != 0.:
-                velocityAngles[instant] = np.arccos(moving.Point.dot(v1, v2)/(v1Norm*v2Norm))
+                velocityAngles[instant] = np.arccos(max(-1, min(1, moving.Point.dot(v1, v2)/(v1Norm*v2Norm))))
             collisionCourseDotProducts[instant] = moving.Point.dot(deltap, deltav)
             distances[instant] = deltap.norm2()
             speedDifferentials[instant] = deltav.norm2()
             if collisionCourseDotProducts[instant] > 0:
                 interactionInstants.append(instant)
             if distances[instant] != 0 and speedDifferentials[instant] != 0:
-                collisionCourseAngles[instant] = np.arccos(collisionCourseDotProducts[instant]/(distances[instant]*speedDifferentials[instant]))
+                collisionCourseAngles[instant] = np.arccos(max(-1, min(1, collisionCourseDotProducts[instant]/(distances[instant]*speedDifferentials[instant])))) # avoid values slightly higher than 1.0
 
         if len(interactionInstants) >= 2:
             self.interactionInterval = moving.TimeInterval(interactionInstants[0], interactionInstants[-1])
--- a/trafficintelligence/indicators.py	Wed Apr 03 12:30:36 2024 -0400
+++ b/trafficintelligence/indicators.py	Wed Apr 03 14:41:20 2024 -0400
@@ -15,27 +15,23 @@
     '''Class for temporal indicators
     i.e. indicators that take a value at specific instants
 
-    values should be
-    * a dict, for the values at specific time instants
-    * or a list with a time interval object if continuous measurements
-
+    values is a dict, for the values at specific time instants
     it should have more information like name, unit'''
     
-    def __init__(self, name, values, timeInterval = None, maxValue = None):
+    def __init__(self, name, values, maxValue = None):
         self.name = name
-        if timeInterval is None:
-            self.values = values
-            instants = sorted(self.values.keys())
-            if len(instants) > 0:
-                self.timeInterval = moving.TimeInterval(instants[0], instants[-1])
-            else:
-                self.timeInterval = moving.TimeInterval()
+        self.values = values
+        instants = sorted(self.values.keys())
+        if len(instants) > 0:
+            self.timeInterval = moving.TimeInterval(instants[0], instants[-1])
         else:
-            assert len(values) == timeInterval.length()
-            self.timeInterval = timeInterval
-            self.values = {}
-            for i in range(int(round(self.timeInterval.length()))):
-                self.values[self.timeInterval[i]] = values[i]
+            self.timeInterval = moving.TimeInterval()
+        # else:
+        #     assert len(values) == timeInterval.length()
+        #     self.timeInterval = timeInterval
+        #     self.values = {}
+        #     for i in range(int(round(self.timeInterval.length()))):
+        #         self.values[self.timeInterval[i]] = values[i]
         self.maxValue = maxValue
 
     def __len__(self):
@@ -67,6 +63,12 @@
             self.iterInstantNum += 1
             return self.getIthValue(self.iterInstantNum-1)
 
+    def min(self):
+        return min(self.values.values())
+
+    def max(self):
+        return max(self.values.values())
+        
     def getTimeInterval(self):
         return self.timeInterval
 
@@ -160,8 +162,8 @@
     field mostSevereIsMax is True 
     if the most severe value taken by the indicator is the maximum'''
 
-    def __init__(self, name, values, timeInterval=None, mostSevereIsMax=True, maxValue = None): 
-        TemporalIndicator.__init__(self, name, values, timeInterval, maxValue)
+    def __init__(self, name, values, mostSevereIsMax=True, maxValue = None): 
+        TemporalIndicator.__init__(self, name, values, maxValue)
         self.mostSevereIsMax = mostSevereIsMax
 
     def getMostSevereValue(self, minNInstants=None, centile=None):
--- a/trafficintelligence/storage.py	Wed Apr 03 12:30:36 2024 -0400
+++ b/trafficintelligence/storage.py	Wed Apr 03 14:41:20 2024 -0400
@@ -1450,8 +1450,8 @@
             xCoords = worldCorners[:4,0]
             yCoords = worldCorners[:4,1]
             t.addPositionXY(xCoords.mean(), yCoords.mean())
-            for i in range(4):
-                featureTrajectories[i].addPositionXY(xCoords[i], yCoords[i])
+            for j in range(4):
+                featureTrajectories[j].addPositionXY(xCoords[j], yCoords[j])
             # check https://docs.opencv.org/3.4/d9/d0c/group__calib3d.html#ga1019495a2c8d1743ed5cc23fa0daff8c
         if interval.length()>1:
             objects.append(moving.MovingObject(num = objNum, timeInterval = interval, positions = t, velocities = t.differentiate(True), userType = userType, features = [moving.MovingObject(num = featureNum+i, timeInterval = copy(interval), positions = featureTrajectories[i], velocities = featureTrajectories[i].differentiate(True)) for i in range(4)]))
--- a/trafficintelligence/tests/indicators.txt	Wed Apr 03 12:30:36 2024 -0400
+++ b/trafficintelligence/tests/indicators.txt	Wed Apr 03 14:41:20 2024 -0400
@@ -1,7 +1,7 @@
 >>> from trafficintelligence.indicators import *
->>> from trafficintelligence.moving import TimeInterval,Trajectory
+>>> from trafficintelligence.moving import TimeInterval, Trajectory
 
->>> indic1 = TemporalIndicator('bla', [0,3,-4], TimeInterval(4,6))
+>>> indic1 = TemporalIndicator('bla', {4:0,5:3,6:-4})
 >>> indic1.empty()
 False
 >>> indic1.getIthValue(1)
@@ -19,7 +19,7 @@
 >>> indic1[2]
 0
 
->>> ttc = SeverityIndicator('TTC', list(range(11)), TimeInterval(1,11), mostSevereIsMax = False)
+>>> ttc = SeverityIndicator('TTC', {t:t-1 for t in TimeInterval(1,11)}, mostSevereIsMax = False)
 >>> ttc.getMostSevereValue(1)
 0.0
 >>> ttc.getMostSevereValue(2)