def mapTrajectory(self, tspots, **param):
   groups = seqGroupBy(tspots, keyf=lambda tsp:tsp.spot.linkId)
   ttob_seqs = completeGroups(groups, self.network)
   seqs = [[(ttob.linkId, self.learned_mixtures[ttob.linkId].assignment(ttob.tt),
             float(ttob.tt))
            for ttob in ttob_seq] for ttob_seq in ttob_seqs]
   return [model.toTrajectoryObservation(seq) for seq in seqs]
def detect_mode(tspots_data, network, **param):
  """
  Main function to be run to learn the mixture distribution from the TSpot
  Input:
  tspots_data: list of list of TSpot (completed).
    Each list of TSpot represents a trajectory provided by the PIF
  network: network object
  """
  tspots_cut_link = pip_fun.seqGroupBy(tspots_data, keyf=lambda tsp:tsp.spot.linkId)
  # If there are 2 links or less traveled, then there is no full link.
  # We only compute stop go for fully traversed links 
  if len(tspots_cut_link) <= 2:
    return None
  tspots_cut_link = tspots_cut_link[1: -1]
  seqs = ([(link_tspots[0].spot.linkId,
            1 if detect_stops_on_link_traj(link_tspots, **param)
            else 0,
            (link_tspots[-1].time - link_tspots[0].time).total_seconds()) 
            for link_tspots in tspots_cut_link[1: -1]])
  return seqs if len(seqs) >= 1 else None
def detect_stops(dates, network, **param):
  """
  Main function to be run to learn the mixture distribution from the TSpot
  Input:
  tspots_data: list of list of TSpot. 
    Each list of TSpot represents a trajectory provided by the PIF
  network: network object
  """
  
  learned_mixtures = {}
  
  tspots_data = [ttob_seq for date in dates 
               for ttob_seq in pip_fun.getDayTSpotsInterpolated(date,
                                                    network)]
  tspots_cut_link = [pip_fun.seqGroupBy(tspots, keyf=lambda tsp:tsp.spot.linkId) for tspots in tspots_data]
  tspots_groups_per_link = pip_fun.groupby([link_tspots for traj_tspots in tspots_cut_link
                                    for link_tspots in traj_tspots], lambda tspots:tspots[0].spot.linkId)
  
  for lid, link_obs in tspots_groups_per_link:
    stopping_obs = ([detect_stops_on_link_traj(traj, **param)
                     if len(traj) >= 2
                     else None 
                     for traj in link_obs])
    non_stop_mix = compute_tt_from_tspots(
      [traj for i, traj in enumerate(link_obs) if stopping_obs[i] is False],
      lid,
      network,
      avg_ff_tt=None,
      **param)
    stop_mix = compute_tt_from_tspots(
      [traj for i, traj in enumerate(link_obs) if stopping_obs[i] is True],
      lid,
      network,
      avg_ff_tt=non_stop_mix[0],
      **param)
    mixt_dist = compute_mixture(non_stop_mix, stop_mix, param['non_stopping_default'])
    learned_mixtures[lid] = mixt_dist
  return learned_mixtures