def extract_runs(protocols, get_runs_pkts):
    """
    Given garmin packets which are result of A1000 (get_runs)
    Return an object tree runs->laps->points for easier processing.
    """
    runs, laps, trks = get_runs_pkts
    runs = [r.data for r in runs.by_pid[protocols.link_proto.PID_RUN]]
    laps = [l.data for l in laps.by_pid[protocols.link_proto.PID_LAP]]
    _log.debug("extract_runs: found %d run(s)", len(runs))
    for run_num, run in enumerate(runs):
        run.laps = [l for l in laps if run.first_lap_index <= l.index <= run.last_lap_index]
        run.time.time = run.laps[0].start_time.time
        run.wpts = list(extract_wpts(protocols, trks, run.track_index))
        _log.debug("extract_runs: run %d has: %d lap(s), %d wpt(s)", run_num + 1, len(run.laps), len(run.wpts))
        for lap in run.laps: lap.wpts = []
        lap_num = 0
        for wpt in run.wpts:
            try:
                while wpt.time.time >= run.laps[lap_num + 1].start_time.time:
                    _log.debug("extract_runs: run %d lap %d has: %d wpt(s)",
                            run_num + 1, lap_num + 1, len(run.laps[lap_num].wpts))
                    lap_num += 1
            except __HOLE__:
                pass
            run.laps[lap_num].wpts.append(wpt)
        all_wpt_in_laps = sum(len(lap.wpts) for lap in run.laps)
        if len(run.wpts) != all_wpt_in_laps:
            _log.warning("extract_runs: run %d waypoint mismatch: total(%d) != wpt_in_laps(%d)",
                    run_num + 1, len(run.wpts), all_wpt_in_laps)
    return runs
dataset/ETHPy150Open braiden/python-ant-downloader/antd/garmin.py/extract_runs