def lengthPoint(gpsTraces, j): return tripActivitySeparatorMongo.calDistance( gpsTraces[j]["gpsReading"]["location"]["coordinates"], gpsTraces[j + 1]["gpsReading"]["location"]["coordinates"] )
def inferModeChain( gpsTraces, trip, maxWalkSpeed, maxWalkAcceleration, minSegmentDuration, minSegmentLength, gpsAccuracyThreshold ): # Step 1: Label GPS points as walk points or non-walk points walkDummy = {} i = trip[0] while i < trip[1]: start, end = i, i while end < trip[1] and ( gpsTraces[end]["gpsReading"]["gpsAccuracy"] > gpsAccuracyThreshold or gpsTraces[end + 1]["gpsReading"]["gpsAccuracy"] > gpsAccuracyThreshold or gpsTraces[end + 2]["gpsReading"]["gpsAccuracy"] > gpsAccuracyThreshold ): end += 1 if start == end: features = determineFeatures(gpsTraces, i) if features["Acceleration"] <= 945: if features["Heading Change"] <= 0.0000: walkDummy[i] = 0 elif features["Speed"] <= 8.0205: walkDummy[i] = 1 else: walkDummy[i] = 0 else: walkDummy[i] = 0 i += 1 else: distance = tripActivitySeparatorMongo.calDistance( gpsTraces[start]["gpsReading"]["location"]["coordinates"], gpsTraces[end]["gpsReading"]["location"]["coordinates"], ) time = (gpsTraces[end]["epochTime"] - gpsTraces[start]["epochTime"]) / 1000.0 speed = 2.23694 * (float(distance) / time) dummy = int(speed < maxWalkSpeed) while i < end: walkDummy[i] = dummy i += 1 # print walkDummy # print # Step 2: Identify walk and non-walk segments as consecutive walk or non-walk points modeChains = [] beginSegment = trip[0] currentPoint = trip[0] + 1 while currentPoint < trip[1]: if walkDummy[currentPoint] != walkDummy[beginSegment]: modeChains.append([beginSegment, currentPoint, int(walkDummy[beginSegment] != 0)]) beginSegment = currentPoint currentPoint += 1 modeChains.append([beginSegment, currentPoint, int(walkDummy[beginSegment] != 0)]) # print modeChains # print # Step 3: If the time span of a segment is greater than minSegmentDuration milliseconds, label it # as certain. If it is less than minSegmentDuration milliseconds, and its backward segment is certain, # merge it with the backward segment. If no certain backward segment exists, label the segment as # uncertain, and save it as an independent segment. newModeChains = [] for i in range(0, len(modeChains)): if gpsTraces[modeChains[i][1]]["epochTime"] - gpsTraces[modeChains[i][0]]["epochTime"] >= minSegmentDuration: modeChains[i].append(1) newModeChains.append(modeChains[i]) elif newModeChains and newModeChains[-1][-1] == 1: newModeChains[-1][1] = modeChains[i][1] else: modeChains[i].append(0) newModeChains.append(modeChains[i]) modeChains = newModeChains # print modeChains # print # Step 4: Merge consecutive uncertain segments into a single certain segment. Calculate average # speed over segment and compare it against maxWalkSpeed to determine whether walk or non-walk. # Check if this segment exceeds minSegmentDuration milliseconds. If it doesn't, and there exists # a certain forward segment, merge the new segment with this forward segment. newModeChains, i = [modeChains[0][0:-1]], 1 while i < len(modeChains) and modeChains[i][-1] == 0: i += 1 if i > 1: newModeChains[0][1] = modeChains[i - 1][1] distance = tripActivitySeparatorMongo.calDistance( gpsTraces[newModeChains[0][0]]["gpsReading"]["location"]["coordinates"], gpsTraces[newModeChains[0][1]]["gpsReading"]["location"]["coordinates"], ) time = (gpsTraces[newModeChains[0][1]]["epochTime"] - gpsTraces[newModeChains[0][0]]["epochTime"]) / 1000.0 speed = 2.23694 * (float(distance) / time) newModeChains[0][-1] = int(speed < maxWalkSpeed) if i < len(modeChains) and modeChains[0][-1] == 0: time = gpsTraces[newModeChains[0][1]]["epochTime"] - gpsTraces[newModeChains[0][0]]["epochTime"] if time < minSegmentDuration: modeChains[i][0] = trip[0] newModeChains = [] while i < len(modeChains): newModeChains.append(modeChains[i][:-1]) i += 1 modeChains = newModeChains # print modeChains # print # Step 5: Merge consecutive walk segments and consecutive non-walk segments newModeChains = [modeChains[0]] for i in range(1, len(modeChains)): if modeChains[i][2] == newModeChains[-1][2]: newModeChains[-1][1] = modeChains[i][1] else: newModeChains.append(modeChains[i]) modeChains = newModeChains return modeChains
def calInfAccuray(modeChains, gpsTraces): timeTotal, timeInferred, distTotal, distInferred = 0, 0, 0, 0 segTotal, segInferred, segWalkInfNonWalk, segNonWalkInfWalk = 0, 0, 0, 0 for modeChain in modeChains: segTotal += 1 walk, nonWalk, activity = 0, 0, 0 for i in range(modeChain[0], modeChain[1]): try: timeTotal += (gpsTraces[i + 1]["epochTime"] - gpsTraces[i]["epochTime"]) / 1000.0 distTotal += ( tripActivitySeparatorMongo.calDistance( gpsTraces[i]["gpsReading"]["location"]["coordinates"], gpsTraces[i + 1]["gpsReading"]["location"]["coordinates"], ) / 1609.34 ) if gpsTraces[i]["groundTruth"]["label"] == "Trip" and gpsTraces[i]["groundTruth"]["mode"] == "Walk": walk += 1 elif gpsTraces[i]["groundTruth"]["label"] == "Trip": nonWalk += 1 else: activity += 1 if ( modeChain[-1] == 1 and gpsTraces[i]["groundTruth"]["label"] == "Trip" and gpsTraces[i]["groundTruth"]["mode"] == "Walk" ) or ( modeChain[-1] == 0 and gpsTraces[i]["groundTruth"]["label"] == "Trip" and gpsTraces[i]["groundTruth"]["mode"] != "Walk" ): timeInferred += (gpsTraces[i + 1]["epochTime"] - gpsTraces[i]["epochTime"]) / 1000.0 distInferred += ( tripActivitySeparatorMongo.calDistance( gpsTraces[i]["gpsReading"]["location"]["coordinates"], gpsTraces[i + 1]["gpsReading"]["location"]["coordinates"], ) / 1609.34 ) except: print "Unexpected error while calculating inference accuracy:", sys.exc_info()[0] pass if (max(walk, nonWalk, activity) == walk and modeChain[-1] == 1) or ( max(walk, nonWalk, activity) == nonWalk and modeChain[-1] == 0 ): segInferred += 1 elif max(walk, nonWalk, activity) == walk and modeChain[-1] == 0: segWalkInfNonWalk += 1 elif max(walk, nonWalk, activity) == nonWalk and modeChain[-1] == 1: segNonWalkInfWalk += 1 return ( timeTotal, timeInferred, distTotal, distInferred, segTotal, segInferred, segWalkInfNonWalk, segNonWalkInfWalk, )