Mercurial Hosting > traffic-intelligence
comparison python/moving.py @ 1012:01db14e947e4
resolved
author | Wendlasida |
---|---|
date | Fri, 01 Jun 2018 10:47:49 -0400 |
parents | 4f0312bee393 cc7c6b821ae6 |
children | d6f121ded971 |
comparison
equal
deleted
inserted
replaced
1011:4f0312bee393 | 1012:01db14e947e4 |
---|---|
120 | 120 |
121 def __iter__(self): | 121 def __iter__(self): |
122 self.iterInstantNum = -1 | 122 self.iterInstantNum = -1 |
123 return self | 123 return self |
124 | 124 |
125 def next(self): | 125 def __next__(self): |
126 if self.iterInstantNum >= self.length()-1: | 126 if self.iterInstantNum >= self.length()-1: |
127 raise StopIteration | 127 raise StopIteration |
128 else: | 128 else: |
129 self.iterInstantNum += 1 | 129 self.iterInstantNum += 1 |
130 return self[self.iterInstantNum] | 130 return self[self.iterInstantNum] |
169 def getFirstInstant(self): | 169 def getFirstInstant(self): |
170 return self.timeInterval.first | 170 return self.timeInterval.first |
171 | 171 |
172 def getLastInstant(self): | 172 def getLastInstant(self): |
173 return self.timeInterval.last | 173 return self.timeInterval.last |
174 | |
175 def setFirstInstant(self, t): | |
176 if t <= self.timeInterval.last: | |
177 self.timeInterval.first = t | |
178 else: | |
179 print('new first instant is after last, not changing') | |
180 | |
181 def setLastInstant(self, t): | |
182 if t >= self.timeInterval.first: | |
183 self.timeInterval.last = t | |
184 else: | |
185 print('new last instant is before first, not changing') | |
174 | 186 |
175 def getTimeInterval(self): | 187 def getTimeInterval(self): |
176 return self.timeInterval | 188 return self.timeInterval |
177 | 189 |
178 def existsAtInstant(self, t): | 190 def existsAtInstant(self, t): |
377 '''Optimized tests of a series of points within (Shapely) polygon (not prepared)''' | 389 '''Optimized tests of a series of points within (Shapely) polygon (not prepared)''' |
378 if type(polygon) == PreparedGeometry: | 390 if type(polygon) == PreparedGeometry: |
379 prepared_polygon = polygon | 391 prepared_polygon = polygon |
380 else: | 392 else: |
381 prepared_polygon = prep(polygon) | 393 prepared_polygon = prep(polygon) |
382 return filter(prepared_polygon.contains, points) | 394 return list(filter(prepared_polygon.contains, points)) |
383 | 395 |
384 # Functions for coordinate transformation | 396 # Functions for coordinate transformation |
385 # From Paul St-Aubin's PVA tools | 397 # From Paul St-Aubin's PVA tools |
386 def subsec_spline_dist(splines): | 398 def subsec_spline_dist(splines): |
387 ''' Prepare list of spline subsegments from a spline list. | 399 ''' Prepare list of spline subsegments from a spline list. |
415 | 427 |
416 def prepareSplines(splines): | 428 def prepareSplines(splines): |
417 'Approximates slope singularity by giving some slope roundoff; account for roundoff error' | 429 'Approximates slope singularity by giving some slope roundoff; account for roundoff error' |
418 for spline in splines: | 430 for spline in splines: |
419 p1 = spline[0] | 431 p1 = spline[0] |
420 for i in xrange(len(spline)-1): | 432 for i in range(len(spline)-1): |
421 p2 = spline[i+1] | 433 p2 = spline[i+1] |
422 if(round(p1.x, 10) == round(p2.x, 10)): | 434 if(round(p1.x, 10) == round(p2.x, 10)): |
423 p2.x += 0.0000000001 | 435 p2.x += 0.0000000001 |
424 if(round(p1.y, 10) == round(p2.y, 10)): | 436 if(round(p1.y, 10) == round(p2.y, 10)): |
425 p2.y += 0.0000000001 | 437 p2.y += 0.0000000001 |
664 @staticmethod | 676 @staticmethod |
665 def generate(p, v, nPoints): | 677 def generate(p, v, nPoints): |
666 t = Trajectory() | 678 t = Trajectory() |
667 p0 = Point(p.x, p.y) | 679 p0 = Point(p.x, p.y) |
668 t.addPosition(p0) | 680 t.addPosition(p0) |
669 for i in xrange(nPoints-1): | 681 for i in range(nPoints-1): |
670 p0 += v | 682 p0 += v |
671 t.addPosition(p0) | 683 t.addPosition(p0) |
672 return t, Trajectory([[v.x]*nPoints, [v.y]*nPoints]) | 684 return t, Trajectory([[v.x]*nPoints, [v.y]*nPoints]) |
673 | 685 |
674 @staticmethod | 686 @staticmethod |
703 return Trajectory([self.positions[0][i],self.positions[1][i]]) | 715 return Trajectory([self.positions[0][i],self.positions[1][i]]) |
704 else: | 716 else: |
705 raise TypeError("Invalid argument type.") | 717 raise TypeError("Invalid argument type.") |
706 | 718 |
707 def __str__(self): | 719 def __str__(self): |
708 return ' '.join([self.__getitem__(i).__str__() for i in xrange(self.length())]) | 720 return ' '.join([self.__getitem__(i).__str__() for i in range(self.length())]) |
709 | 721 |
710 def __repr__(self): | 722 def __repr__(self): |
711 return self.__str__() | 723 return self.__str__() |
712 | 724 |
713 def __iter__(self): | 725 def __iter__(self): |
714 self.iterInstantNum = 0 | 726 self.iterInstantNum = 0 |
715 return self | 727 return self |
716 | 728 |
717 def next(self): | 729 def __next__(self): |
718 if self.iterInstantNum >= self.length(): | 730 if self.iterInstantNum >= self.length(): |
719 raise StopIteration | 731 raise StopIteration |
720 else: | 732 else: |
721 self.iterInstantNum += 1 | 733 self.iterInstantNum += 1 |
722 return self[self.iterInstantNum-1] | 734 return self[self.iterInstantNum-1] |
817 return Trajectory([[alpha*x for x in self.getXCoordinates()], | 829 return Trajectory([[alpha*x for x in self.getXCoordinates()], |
818 [alpha*y for y in self.getYCoordinates()]]) | 830 [alpha*y for y in self.getYCoordinates()]]) |
819 | 831 |
820 def differentiate(self, doubleLastPosition = False): | 832 def differentiate(self, doubleLastPosition = False): |
821 diff = Trajectory() | 833 diff = Trajectory() |
822 for i in xrange(1, self.length()): | 834 for i in range(1, self.length()): |
823 diff.addPosition(self[i]-self[i-1]) | 835 diff.addPosition(self[i]-self[i-1]) |
824 if doubleLastPosition: | 836 if doubleLastPosition: |
825 diff.addPosition(diff[-1]) | 837 diff.addPosition(diff[-1]) |
826 return diff | 838 return diff |
827 | 839 |
854 Can be accessed through getDistance(idx) and getCumulativeDistance(idx)''' | 866 Can be accessed through getDistance(idx) and getCumulativeDistance(idx)''' |
855 self.distances = [] | 867 self.distances = [] |
856 self.cumulativeDistances = [0.] | 868 self.cumulativeDistances = [0.] |
857 p1 = self[0] | 869 p1 = self[0] |
858 cumulativeDistance = 0. | 870 cumulativeDistance = 0. |
859 for i in xrange(self.length()-1): | 871 for i in range(self.length()-1): |
860 p2 = self[i+1] | 872 p2 = self[i+1] |
861 self.distances.append(Point.distanceNorm2(p1,p2)) | 873 self.distances.append(Point.distanceNorm2(p1,p2)) |
862 cumulativeDistance += self.distances[-1] | 874 cumulativeDistance += self.distances[-1] |
863 self.cumulativeDistances.append(cumulativeDistance) | 875 self.cumulativeDistances.append(cumulativeDistance) |
864 p1 = p2 | 876 p1 = p2 |
921 intersects with the segment of extremities p1 and p2 | 933 intersects with the segment of extremities p1 and p2 |
922 Returns an empty list if there is no crossing''' | 934 Returns an empty list if there is no crossing''' |
923 indices = [] | 935 indices = [] |
924 intersections = [] | 936 intersections = [] |
925 | 937 |
926 for i in xrange(self.length()-1): | 938 for i in range(self.length()-1): |
927 q1=self.__getitem__(i) | 939 q1=self.__getitem__(i) |
928 q2=self.__getitem__(i+1) | 940 q2=self.__getitem__(i+1) |
929 p = segmentIntersection(q1, q2, p1, p2) | 941 p = segmentIntersection(q1, q2, p1, p2) |
930 if p is not None: | 942 if p is not None: |
931 if q1.x != q2.x: | 943 if q1.x != q2.x: |
943 intersects with the line going through p1 and p2 | 955 intersects with the line going through p1 and p2 |
944 Returns an empty list if there is no crossing''' | 956 Returns an empty list if there is no crossing''' |
945 indices = [] | 957 indices = [] |
946 intersections = [] | 958 intersections = [] |
947 | 959 |
948 for i in xrange(self.length()-1): | 960 for i in range(self.length()-1): |
949 q1=self.__getitem__(i) | 961 q1=self.__getitem__(i) |
950 q2=self.__getitem__(i+1) | 962 q2=self.__getitem__(i+1) |
951 p = segmentLineIntersection(p1, p2, q1, q2) | 963 p = segmentLineIntersection(p1, p2, q1, q2) |
952 if p is not None: | 964 if p is not None: |
953 if q1.x != q2.x: | 965 if q1.x != q2.x: |
1076 self.lanes[i] = lane | 1088 self.lanes[i] = lane |
1077 | 1089 |
1078 def differentiate(self, doubleLastPosition = False): | 1090 def differentiate(self, doubleLastPosition = False): |
1079 diff = CurvilinearTrajectory() | 1091 diff = CurvilinearTrajectory() |
1080 p1 = self[0] | 1092 p1 = self[0] |
1081 for i in xrange(1, self.length()): | 1093 for i in range(1, self.length()): |
1082 p2 = self[i] | 1094 p2 = self[i] |
1083 diff.addPositionSYL(p2[0]-p1[0], p2[1]-p1[1], p1[2]) | 1095 diff.addPositionSYL(p2[0]-p1[0], p2[1]-p1[1], p1[2]) |
1084 p1=p2 | 1096 p1=p2 |
1085 if doubleLastPosition and self.length() > 1: | 1097 if doubleLastPosition and self.length() > 1: |
1086 diff.addPosition(diff[-1]) | 1098 diff.addPosition(diff[-1]) |
1090 '''Returns a list of the indices at which the trajectory | 1102 '''Returns a list of the indices at which the trajectory |
1091 goes past the curvilinear coordinate S1 | 1103 goes past the curvilinear coordinate S1 |
1092 (in provided lane if lane is not None) | 1104 (in provided lane if lane is not None) |
1093 Returns an empty list if there is no crossing''' | 1105 Returns an empty list if there is no crossing''' |
1094 indices = [] | 1106 indices = [] |
1095 for i in xrange(self.length()-1): | 1107 for i in range(self.length()-1): |
1096 q1=self.__getitem__(i) | 1108 q1=self.__getitem__(i) |
1097 q2=self.__getitem__(i+1) | 1109 q2=self.__getitem__(i+1) |
1098 if q1[0] <= S1 < q2[0] and (lane is None or (self.lanes[i] == lane and self.lanes[i+1] == lane)): | 1110 if q1[0] <= S1 < q2[0] and (lane is None or (self.lanes[i] == lane and self.lanes[i+1] == lane)): |
1099 indices.append(i+(S1-q1[0])/(q2[0]-q1[0])) | 1111 indices.append(i+(S1-q1[0])/(q2[0]-q1[0])) |
1100 return indices | 1112 return indices |
1259 self.positions = positions | 1271 self.positions = positions |
1260 | 1272 |
1261 @staticmethod | 1273 @staticmethod |
1262 def concatenate(obj1, obj2, num = None): | 1274 def concatenate(obj1, obj2, num = None): |
1263 '''Concatenates two objects supposed to overlap temporally ''' | 1275 '''Concatenates two objects supposed to overlap temporally ''' |
1264 if num is None: | 1276 if num is None: |
1265 newNum = obj1.getNum() | 1277 newNum = obj1.getNum() |
1266 else: | 1278 else: |
1267 newNum = num | 1279 newNum = num |
1268 commonTimeInterval = obj1.commonTimeInterval(obj2) | 1280 commonTimeInterval = obj1.commonTimeInterval(obj2) |
1269 if commonTimeInterval.empty(): | 1281 if commonTimeInterval.empty(): |
1270 print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) | 1282 print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) |
1271 emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()) , max(obj1.getFirstInstant(),obj2.getFirstInstant())) | 1283 emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()) , max(obj1.getFirstInstant(),obj2.getFirstInstant())) |
1272 positions = Trajectory() | 1284 positions = Trajectory() |
1287 py+=vitessey | 1299 py+=vitessey |
1288 | 1300 |
1289 newObject = MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType()) | 1301 newObject = MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType()) |
1290 newObject.features = [MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType())] #In case there is features to add when we recursively call concatenate | 1302 newObject.features = [MovingObject(newNum, emptyInterval, positions, velocities, userType = obj1.getUserType())] #In case there is features to add when we recursively call concatenate |
1291 return MovingObject.concatenate(MovingObject.concatenate(obj1, newObject),obj2) | 1303 return MovingObject.concatenate(MovingObject.concatenate(obj1, newObject),obj2) |
1292 | 1304 |
1293 | |
1294 else: | 1305 else: |
1295 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) | 1306 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) |
1296 # positions | 1307 # positions |
1297 positions = Trajectory() | 1308 positions = Trajectory() |
1298 for t in newTimeInterval: | 1309 for t in newTimeInterval: |
1422 coords.append(NaN) | 1433 coords.append(NaN) |
1423 plot(instants, coords, options, **kwargs) | 1434 plot(instants, coords, options, **kwargs) |
1424 if withOrigin and len(instants)>0: | 1435 if withOrigin and len(instants)>0: |
1425 plot([instants[0]], [coords[0]], 'ro', **kwargs) | 1436 plot([instants[0]], [coords[0]], 'ro', **kwargs) |
1426 else: | 1437 else: |
1427 print('Object {} has no curvilinear positions'.format(self.getNum())) | 1438 print('Object {} has no curvilinear positions'.format(self.getNum())) |
1428 | 1439 |
1429 def setUserType(self, userType): | 1440 def setUserType(self, userType): |
1430 self.userType = userType | 1441 self.userType = userType |
1431 | 1442 |
1432 def setFeatures(self, features, featuresOrdered = False): | 1443 def setFeatures(self, features, featuresOrdered = False): |
1531 def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1.): | 1542 def play(self, videoFilename, homography = None, undistort = False, intrinsicCameraMatrix = None, distortionCoefficients = None, undistortedImageMultiplication = 1.): |
1532 cvutils.displayTrajectories(videoFilename, [self], homography = homography, firstFrameNum = self.getFirstInstant(), lastFrameNumArg = self.getLastInstant(), undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication) | 1543 cvutils.displayTrajectories(videoFilename, [self], homography = homography, firstFrameNum = self.getFirstInstant(), lastFrameNumArg = self.getLastInstant(), undistort = undistort, intrinsicCameraMatrix = intrinsicCameraMatrix, distortionCoefficients = distortionCoefficients, undistortedImageMultiplication = undistortedImageMultiplication) |
1533 | 1544 |
1534 def speedDiagnostics(self, framerate = 1., display = False, nInstantsIgnoredAtEnds=0): | 1545 def speedDiagnostics(self, framerate = 1., display = False, nInstantsIgnoredAtEnds=0): |
1535 speeds = framerate*self.getSpeeds(nInstantsIgnoredAtEnds) | 1546 speeds = framerate*self.getSpeeds(nInstantsIgnoredAtEnds) |
1536 coef = utils.linearRegression(range(len(speeds)), speeds) | 1547 coef = utils.linearRegression(list(range(len(speeds))), speeds) |
1537 print('min/5th perc speed: {} / {}\nspeed diff: {}\nspeed stdev: {}\nregression: {}'.format(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0])) | 1548 print('min/5th perc speed: {} / {}\nspeed diff: {}\nspeed stdev: {}\nregression: {}'.format(min(speeds), scoreatpercentile(speeds, 5), speeds[-2]-speeds[1], std(speeds), coef[0])) |
1538 if display: | 1549 if display: |
1539 from matplotlib.pyplot import figure, axis | 1550 from matplotlib.pyplot import figure, axis |
1540 figure(1) | 1551 figure(1) |
1541 self.plot() | 1552 self.plot() |
1666 ''' | 1677 ''' |
1667 | 1678 |
1668 self.curvilinearPositions = CurvilinearTrajectory() | 1679 self.curvilinearPositions = CurvilinearTrajectory() |
1669 | 1680 |
1670 #For each point | 1681 #For each point |
1671 for i in xrange(int(self.length())): | 1682 for i in range(int(self.length())): |
1672 result = getSYfromXY(self.getPositionAt(i), alignments) | 1683 result = getSYfromXY(self.getPositionAt(i), alignments) |
1673 | 1684 |
1674 # Error handling | 1685 # Error handling |
1675 if(result is None): | 1686 if(result is None): |
1676 print('Warning: trajectory {} at point {} {} has alignment errors (spline snapping)\nCurvilinear trajectory could not be computed'.format(self.getNum(), i, self.getPositionAt(i))) | 1687 print('Warning: trajectory {} at point {} {} has alignment errors (spline snapping)\nCurvilinear trajectory could not be computed'.format(self.getNum(), i, self.getPositionAt(i))) |
1682 #Run through objects looking for outlier point | 1693 #Run through objects looking for outlier point |
1683 smoothed_lanes = utils.cat_mvgavg(self.curvilinearPositions.getLanes(),ln_mv_av_win) | 1694 smoothed_lanes = utils.cat_mvgavg(self.curvilinearPositions.getLanes(),ln_mv_av_win) |
1684 ## Recalculate projected point to new lane | 1695 ## Recalculate projected point to new lane |
1685 lanes = self.curvilinearPositions.getLanes() | 1696 lanes = self.curvilinearPositions.getLanes() |
1686 if(lanes != smoothed_lanes): | 1697 if(lanes != smoothed_lanes): |
1687 for i in xrange(len(lanes)): | 1698 for i in range(len(lanes)): |
1688 if(lanes[i] != smoothed_lanes[i]): | 1699 if(lanes[i] != smoothed_lanes[i]): |
1689 result = getSYfromXY(self.getPositionAt(i),[alignments[smoothed_lanes[i]]]) | 1700 result = getSYfromXY(self.getPositionAt(i),[alignments[smoothed_lanes[i]]]) |
1690 | 1701 |
1691 # Error handling | 1702 # Error handling |
1692 if(result is None): | 1703 if(result is None): |
1706 if nFeatures == 0: | 1717 if nFeatures == 0: |
1707 print('Empty object features\nCannot compute smooth trajectory') | 1718 print('Empty object features\nCannot compute smooth trajectory') |
1708 else: | 1719 else: |
1709 # compute the relative position vectors | 1720 # compute the relative position vectors |
1710 relativePositions = {} # relativePositions[(i,j)] is the position of j relative to i | 1721 relativePositions = {} # relativePositions[(i,j)] is the position of j relative to i |
1711 for i in xrange(nFeatures): | 1722 for i in range(nFeatures): |
1712 for j in xrange(i): | 1723 for j in range(i): |
1713 fi = self.features[i] | 1724 fi = self.features[i] |
1714 fj = self.features[j] | 1725 fj = self.features[j] |
1715 inter = fi.commonTimeInterval(fj) | 1726 inter = fi.commonTimeInterval(fj) |
1716 if inter.length() >= minCommonIntervalLength: | 1727 if inter.length() >= minCommonIntervalLength: |
1717 xi = array(fi.getXCoordinates()[inter.first-fi.getFirstInstant():int(fi.length())-(fi.getLastInstant()-inter.last)]) | 1728 xi = array(fi.getXCoordinates()[inter.first-fi.getFirstInstant():int(fi.length())-(fi.getLastInstant()-inter.last)]) |
1960 gtMatches = {a.getNum():{} for a in annotations} | 1971 gtMatches = {a.getNum():{} for a in annotations} |
1961 toMatches = {o.getNum():{} for o in objects} | 1972 toMatches = {o.getNum():{} for o in objects} |
1962 else: | 1973 else: |
1963 gtMatches = None | 1974 gtMatches = None |
1964 toMatches = None | 1975 toMatches = None |
1965 for t in xrange(firstInstant, lastInstant+1): | 1976 for t in range(firstInstant, lastInstant+1): |
1966 previousMatches = matches.copy() | 1977 previousMatches = matches.copy() |
1967 # go through currently matched GT-TO and check if they are still matched withing matchingDistance | 1978 # go through currently matched GT-TO and check if they are still matched withing matchingDistance |
1968 toDelete = [] | 1979 toDelete = [] |
1969 for a in matches: | 1980 for a in matches: |
1970 if a.existsAtInstant(t) and matches[a].existsAtInstant(t): | 1981 if a.existsAtInstant(t) and matches[a].existsAtInstant(t): |
1977 toDelete.append(a) | 1988 toDelete.append(a) |
1978 for a in toDelete: | 1989 for a in toDelete: |
1979 del matches[a] | 1990 del matches[a] |
1980 | 1991 |
1981 # match all unmatched GT-TO | 1992 # match all unmatched GT-TO |
1982 matchedGTs = matches.keys() | 1993 matchedGTs = list(matches.keys()) |
1983 matchedTOs = matches.values() | 1994 matchedTOs = list(matches.values()) |
1984 costs = [] | 1995 costs = [] |
1985 unmatchedGTs = [a for a in annotations if a.existsAtInstant(t) and a not in matchedGTs] | 1996 unmatchedGTs = [a for a in annotations if a.existsAtInstant(t) and a not in matchedGTs] |
1986 unmatchedTOs = [o for o in objects if o.existsAtInstant(t) and o not in matchedTOs] | 1997 unmatchedTOs = [o for o in objects if o.existsAtInstant(t) and o not in matchedTOs] |
1987 nGTs = len(matchedGTs)+len(unmatchedGTs) | 1998 nGTs = len(matchedGTs)+len(unmatchedGTs) |
1988 nTOs = len(matchedTOs)+len(unmatchedTOs) | 1999 nTOs = len(matchedTOs)+len(unmatchedTOs) |
1994 for k,v in newMatches: | 2005 for k,v in newMatches: |
1995 if costs[k][v] < matchingDistance: | 2006 if costs[k][v] < matchingDistance: |
1996 matches[unmatchedGTs[k]]=unmatchedTOs[v] | 2007 matches[unmatchedGTs[k]]=unmatchedTOs[v] |
1997 dist += costs[k][v] | 2008 dist += costs[k][v] |
1998 if debug: | 2009 if debug: |
1999 print('{} '.format(t)+', '.join(['{} {}'.format(k.getNum(), v.getNum()) for k,v in matches.iteritems()])) | 2010 print('{} '.format(t)+', '.join(['{} {}'.format(k.getNum(), v.getNum()) for k,v in matches.items()])) |
2000 if returnMatches: | 2011 if returnMatches: |
2001 for a,o in matches.iteritems(): | 2012 for a,o in matches.items(): |
2002 gtMatches[a.getNum()][t] = o.getNum() | 2013 gtMatches[a.getNum()][t] = o.getNum() |
2003 toMatches[o.getNum()][t] = a.getNum() | 2014 toMatches[o.getNum()][t] = a.getNum() |
2004 | 2015 |
2005 # compute metrics elements | 2016 # compute metrics elements |
2006 ct += len(matches) | 2017 ct += len(matches) |
2012 mismatches = [] | 2023 mismatches = [] |
2013 for a in matches: | 2024 for a in matches: |
2014 if a in previousMatches: | 2025 if a in previousMatches: |
2015 if matches[a] != previousMatches[a]: | 2026 if matches[a] != previousMatches[a]: |
2016 mismatches.append(a) | 2027 mismatches.append(a) |
2017 elif matches[a] in previousMatches.values(): | 2028 elif matches[a] in list(previousMatches.values()): |
2018 mismatches.append(matches[a]) | 2029 mismatches.append(matches[a]) |
2019 for a in previousMatches: | 2030 for a in previousMatches: |
2020 if a not in matches and previousMatches[a] in matches.values(): | 2031 if a not in matches and previousMatches[a] in list(matches.values()): |
2021 mismatches.append(previousMatches[a]) | 2032 mismatches.append(previousMatches[a]) |
2022 if debug: | 2033 if debug: |
2023 for mm in set(mismatches): | 2034 for mm in set(mismatches): |
2024 print('{} {}'.format(type(mm), mm.getNum())) | 2035 print('{} {}'.format(type(mm), mm.getNum())) |
2025 # some object mismatches may appear twice | 2036 # some object mismatches may appear twice |