def notWalkSegProcess(hw_mode_refined, ave_vel, delta_t, timestamp, lat, lon, dist, num_pt_total, NOT_STOP_V, IS_STOP_V, TIME_SET_STOPPED, VC_MIN_DIST): # function used to pick up all the none walking segments in the given mode vector # and call notWalkSegRefine() function to refine those modes # input: whole modes of the device # output: refined modes of the device # get the start and end idx of non walking segment idx_nonwalking = np.where((hw_mode_refined!=MODE_WALK_IN) & (hw_mode_refined!=MODE_WALK_OUT))[0] if len(idx_nonwalking)==0: num_nonwalking_seg = 0 else: start_idx_nonwalking,end_idx_nonwalking,num_nonwalking_seg = getStartEndIdx(idx_nonwalking) # go through each not walking segment #print "nonwalking_seg:",num_nonwalking_seg for i_seg in range(0,num_nonwalking_seg): #print i_seg,start_idx_nonwalking[i_seg],end_idx_nonwalking[i_seg] timestamp_seg = timestamp[start_idx_nonwalking[i_seg]:end_idx_nonwalking[i_seg]+1] # check whether it's indoor or outdoor if start_idx_nonwalking[i_seg]>0: # set indoor/outdoor as previous state if hw_mode_refined[start_idx_nonwalking[i_seg]-1]==MODE_WALK_IN: indoor_seg = 1 elif hw_mode_refined[start_idx_nonwalking[i_seg]-1]==MODE_WALK_OUT: indoor_seg = 0 else: indoor_seg = 1 # assign default value raise Exception("The segment before this none walking segment is not walking segment!") elif end_idx_nonwalking[i_seg]<num_pt_total-1: # set indoor/outdoor as next state if hw_mode_refined[end_idx_nonwalking[i_seg]+1]==MODE_WALK_IN: indoor_seg = 1 elif hw_mode_refined[end_idx_nonwalking[i_seg]+1]==MODE_WALK_OUT: indoor_seg = 0 else: indoor_seg = 1 # assign default value raise Exception("The segment before this none walking segment is not walking segment!") else: indoor_seg = 1 # assign default value # refine the modes of none-walking period hw_mode_refined_seg = hw_mode_refined[start_idx_nonwalking[i_seg]:end_idx_nonwalking[i_seg]+1] v_pt_filtered_seg = ave_vel[start_idx_nonwalking[i_seg]: end_idx_nonwalking[i_seg]+1] delta_t_seg = delta_t[start_idx_nonwalking[i_seg]: end_idx_nonwalking[i_seg]+1] travel_dist = np.nansum(dist[start_idx_nonwalking[i_seg]: end_idx_nonwalking[i_seg]+1]) jump_dist = great_circle_dist([lat[start_idx_nonwalking[i_seg]],lon[start_idx_nonwalking[i_seg]]],[lat[end_idx_nonwalking[i_seg]],lon[end_idx_nonwalking[i_seg]]],'meters') # call the function to refind the non-walking modes hw_mode_refined_seg = notWalkSegRefine(timestamp_seg,hw_mode_refined_seg,v_pt_filtered_seg,delta_t_seg,travel_dist,jump_dist,NOT_STOP_V,IS_STOP_V,indoor_seg,TIME_SET_STOPPED,VC_MIN_DIST) # update the modes into the entire trip hw_mode_refined[start_idx_nonwalking[i_seg]:end_idx_nonwalking[i_seg]+1] = hw_mode_refined_seg return hw_mode_refined
def predict(self, data, modes): """predict whether a list of position follows a bus route by detecting the nearest bus stops. Input is the pandas data frame of measurements and an array of current mode predictions. Returns an array of predicted modes of the same size as the input data frame has rows. """ # extract lat/lon from data frame lat = data['WLATITUDE'].values lon = data['WLONGITUDE'].values # array of indices of motorized mode, if no motorized mode, return idx_motor = np.where(modes == MODE_CAR)[0] if len(idx_motor) == 0: return modes start_idx_motor, end_idx_motor, num_motor_seg = getStartEndIdx(idx_motor) for i_seg in xrange(0,num_motor_seg): start_idx = start_idx_motor[i_seg] end_idx = end_idx_motor[i_seg] # test for distance first lat_seg = lat[start_idx:end_idx+1] lon_seg = lon[start_idx:end_idx+1] valid_lat_seg = lat_seg[np.where(np.invert(np.isnan(lat_seg)))[0]] valid_lon_seg = lon_seg[np.where(np.invert(np.isnan(lon_seg)))[0]] is_bus = predict_mode_by_location(valid_lat_seg, valid_lon_seg, self.bus_location_tree, self.busstop_location_dict, self.busstop_route_dict) #check entry point distance entry_pt_near = -1 exit_pt_near = -1 if start_idx-1>=0: if not np.isnan(lat[start_idx-1]): nearest_busstops = find_nearest_station(lat[start_idx-1],lon[start_idx-1],self.bus_location_tree,self.dist_thres_entry_exit) if len(nearest_busstops)!=0: #print nearest_busstops[0][2] entry_pt_near = 1 else: entry_pt_near = 0 if end_idx+1 < len(modes): if not np.isnan(lat[end_idx+1]): nearest_busstops = find_nearest_station(lat[end_idx+1],lon[end_idx+1],self.bus_location_tree,self.dist_thres_entry_exit) if len(nearest_busstops)!=0: #print nearest_busstops[0][2] exit_pt_near = 1 else: exit_pt_near = 0 # print "# of trip points:",end_idx - start_idx+1 # print "# of points with valid positions:", len(valid_lat_seg) if is_bus or entry_pt_near + exit_pt_near == 2: # print "Bus" # print "---" modes[start_idx:end_idx+1] = 5 #else: # print "Car" # print "---" return modes
def modeSmooth(hw_mode,timestamp,delta_t,lat,lon,vel,ave_vel,delta_steps,dist): # this function smooths the hw_mode code # Output: s_hw_mode : smoothed hw_code # Input: # - hw_mode: a vector of hw_code # - timestamp: a vector of timestamp # - lat,lon: vectors of lat and lon representing location # - vel: vector of geographical velocity, m/s # - ave_vel: 5-window moving average of geographical velocity, m/s NUM_AFT_WALKING = 3 # num of points after walking segment to be set as invalid hw mode TIME_NOT_HIDE = 60*5 # sec, time longer than which the several points after each walking segment won't be set as TBD TIME_SET_STOPPED = 60*1 # sec, time shorter than which the not walking seg is set as stopped NOT_STOP_V = 5.0 # m/s, mean velocity above which the not walking seg is considered as not stopped IS_STOP_V = 1.0 # m/s, mean velocity below which the not walking seg is considered as stopped WALK_MAX_V_AVE = 7.0 # m/s, moving average velocity above which it's considered as TBD WALK_MAX_V_PT = 7.0 # m/s, single point velocity above which it's considered as TBD SINGLE_WALK_MAX_V = 1.5 # m/s, single point velocity above which it's considered as TBD for single walking point SLEEPING_TIME = 60 # s, time larger than which the mode is check and reset SLEEP_MAX_V = 2.0 # m/s, vel_ave or vel above which the sleeping point will be assigned as TBD_VC SLEEP_TO_WALK_STEPS = 1 # steps to time ratio below which the sleeping point will be assigned as stopped TBD_VC_TIME = 200 # s, time above which the point will be considered as vehicle mode TBD_VC_DIST = 300 # m, distance above which the point will be considered as vehicle mode SHORT_WALK = 200 # s, time below which the walking segment between two vehicle seg will be considered as invalid FEW_STEPS = 50 # steps below which the walking segment between two vehicle seg will be considered as invalid SHORT_WALK_MAX_V = 1.5 # m/s, single point velocity above which it's considered as TBD for single walking point VC_MIN_DIST = 100 #m, distance smaller than which the vehicle mode segment is needed to reprocess WALK_IN_MAX_DIST = 150 #m, jump distance larger than which the walking mode segment is considered as outdoor #mode representation # MODE_WALK_IN = 3 # MODE_WALK_OUT = 2 # MODE_STOP_OUT = 0 # MODE_STOP_IN = 1 # MODE_TBD = 10 # MODE_TBD_VC = 11 # initialization num_pt_total = len(hw_mode) # total number of points in this trip hw_mode_refined = hw_mode.copy() # initialize the refined mode vector # check the long delta timestamp points # assign points with long delta timestamp but low velocity as "stopped indoor" idx_sleep = np.where(delta_t>SLEEPING_TIME)[0].tolist() prev_i_sp = 0 for i_sp in idx_sleep: if ave_vel[i_sp] > SLEEP_MAX_V or vel[i_sp] > SLEEP_MAX_V: hw_mode_refined[i_sp] = MODE_TBD_VC if i_sp<num_pt_total-1: hw_mode_refined[i_sp+1] = hw_mode_refined[i_sp] elif delta_t[i_sp]>TBD_VC_TIME and delta_t[i_sp]*vel[i_sp]>TBD_VC_DIST: hw_mode_refined[i_sp] = MODE_TBD_VC if i_sp<num_pt_total-1: hw_mode_refined[i_sp+1] = hw_mode_refined[i_sp] elif (delta_steps[i_sp]/delta_t[i_sp]) < SLEEP_TO_WALK_STEPS: if hw_mode_refined[i_sp]==MODE_WALK_OUT: hw_mode_refined[i_sp] = MODE_STOP_OUT if delta_t[i_sp]>500: if i_sp>0 and i_sp-1!=prev_i_sp: hw_mode_refined[i_sp-1] = MODE_WALK_OUT vel[i_sp-1] = 0 ave_vel[i_sp-1] = 0 if i_sp<num_pt_total-1: if delta_t[i_sp+1]<SLEEPING_TIME: hw_mode_refined[i_sp+1] = MODE_WALK_OUT vel[i_sp+1] = 0 ave_vel[i_sp+1] = 0 else: hw_mode_refined[i_sp] = MODE_STOP_IN if delta_t[i_sp]>500: if i_sp>0 and i_sp-1!=prev_i_sp: hw_mode_refined[i_sp-1] = MODE_WALK_IN vel[i_sp-1] = 0 ave_vel[i_sp-1] = 0 if i_sp<num_pt_total-1: if delta_t[i_sp+1]<SLEEPING_TIME: hw_mode_refined[i_sp+1] = MODE_WALK_IN vel[i_sp+1] = 0 ave_vel[i_sp+1] = 0 prev_i_sp = i_sp # refine the walking mode points by checking the moving average of velocity idx_walking = np.where((hw_mode_refined == MODE_WALK_IN) | (hw_mode_refined == MODE_WALK_OUT))[0].tolist() for i_walk in idx_walking: if ave_vel[i_walk] > WALK_MAX_V_AVE or vel[i_walk] > WALK_MAX_V_PT: hw_mode_refined[i_walk] = MODE_TBD_VC idx_walking = np.where((hw_mode_refined == MODE_WALK_IN) | (hw_mode_refined == MODE_WALK_OUT))[0].tolist() # get the start and end idx of each walking segment if(len(idx_walking)==0): num_walking_seg = 0 else: start_idx_walking,end_idx_walking,num_walking_seg = getStartEndIdx(idx_walking) # check the single walking point, if vel>3m/s, set as TBD_VC idx_single_walking = list(set(start_idx_walking).intersection(end_idx_walking)) for i_sw in idx_single_walking: if ave_vel[i_sw] > SINGLE_WALK_MAX_V or vel[i_sw] > SINGLE_WALK_MAX_V: hw_mode_refined[i_sw] = MODE_TBD_VC start_idx_walking.remove(i_sw) end_idx_walking.remove(i_sw) num_walking_seg = num_walking_seg-1 # go through each walking segment and change indoor to outdoor if dist larger than a threshold for i_walk_seg in xrange(0,num_walking_seg): jump_dist = great_circle_dist([lat[start_idx_walking[i_walk_seg]],lon[start_idx_walking[i_walk_seg]]],[lat[end_idx_walking[i_walk_seg]],lon[end_idx_walking[i_walk_seg]]],'meters') if jump_dist>WALK_IN_MAX_DIST: walk_seg_length = end_idx_walking[i_walk_seg]+1-start_idx_walking[i_walk_seg] hw_mode_refined[start_idx_walking[i_walk_seg]:end_idx_walking[i_walk_seg]+1] = np.ones(walk_seg_length)*MODE_WALK_OUT # # go through each walking segment # # modify modes of the several pts before and after the walking segment # # updated in hw_mode_trip_refined and idx_walking_trip # #print "walking_seg:",num_walking_seg # for i_seg in xrange(0,num_walking_seg): # if(i_seg<num_walking_seg-1): # start_next_seg = start_idx_walking[i_seg+1] # else: # start_next_seg = num_pt_total # # #print start_idx_walking[i_seg],end_idx_walking[i_seg] # # if (end_idx_walking[i_seg]+NUM_AFT_WALKING < start_next_seg) and (timestamp[end_idx_walking[i_seg]+NUM_AFT_WALKING]-timestamp[end_idx_walking[i_seg]] < TIME_NOT_HIDE): # # make several pts after walking seg as MODE_TBD # hw_mode_refined[end_idx_walking[i_seg]+1:end_idx_walking[i_seg]+NUM_AFT_WALKING+1] = MODE_TBD # elif(timestamp[start_next_seg-1]-timestamp[end_idx_walking[i_seg]] < TIME_NOT_HIDE): # hw_mode_refined[end_idx_walking[i_seg]+1:start_next_seg] = MODE_TBD hw_mode_refined = notWalkSegProcess(hw_mode_refined, ave_vel, delta_t, timestamp, lat, lon, dist, num_pt_total, NOT_STOP_V, IS_STOP_V, TIME_SET_STOPPED, VC_MIN_DIST) # try to combine mode segments like: vehicle + stop/walk + vehicle temp_modes = np.array(hw_mode_refined.copy()) temp_modes[(temp_modes==MODE_STOP_IN) | (temp_modes==MODE_STOP_OUT) | (temp_modes==MODE_WALK_OUT)]=MODE_WALK_IN mode_segs = list(chunks(temp_modes,True)) # take the mode chunk num_mode_segs = len(mode_segs) # go through each mode chunk for i_seg in xrange(1,num_mode_segs-1): mode_seg = mode_segs[i_seg] mode_seg_prev = mode_segs[i_seg-1] mode_seg_aft = mode_segs[i_seg+1] # check the steps and average velocity of walking seg between two vehicle seg if mode_seg[2]==MODE_WALK_IN: if mode_seg_prev[2]!=MODE_WALK_IN and mode_seg_aft[2]!=MODE_WALK_IN: time_span = np.sum(delta_t[mode_seg[0]:mode_seg[1]]) tot_steps = np.nansum(delta_steps[mode_seg[0]:mode_seg[1]]) v_mean_mode_seg = aveVelCalc(ave_vel[mode_seg[0]:mode_seg[1]], delta_t[mode_seg[0]:mode_seg[1]]) if time_span<SHORT_WALK and (tot_steps<FEW_STEPS or v_mean_mode_seg>SHORT_WALK_MAX_V): hw_mode_refined[mode_seg[0]:mode_seg[1]] = MODE_TBD_VC hw_mode_refined = notWalkSegProcess(hw_mode_refined, ave_vel, delta_t, timestamp, lat, lon, dist, num_pt_total, NOT_STOP_V, IS_STOP_V, TIME_SET_STOPPED, VC_MIN_DIST) return hw_mode_refined