Ejemplo n.º 1
0
def find_lineup_no_optimization(set1, set2):
    """
    Find the approximate offset between two GPS data sets without range start optimization.

    This algorithm first identifies a primary data set and a secondary one based
    on which starts later. The offset is then applied to the secondary data set.
    After mapping the timestamps to the corresponding points from each set,
    it finds the optimal offset using the later start time of the two sets as
    the starting point. Requires checking of more values in the set to obtain
    an accurate offset, compared to the optimized version.

    Args:
        set1: GpsDataSet object
        set2: GpsDataSet object

    Returns:
        Tuple of two datetimes, the start time for set 1 and for set 2 given the
        calculated offset. If no lineup is found, it will return None.
    """
    set1_start_time = set1.gps_data_list[0].time
    set2_start_time = set2.gps_data_list[0].time
    if set1_start_time > set2_start_time:
        later_start_time = utils.round_time(set1_start_time)
        primary_set = set1
        secondary_set = set2
    else:
        later_start_time = utils.round_time(set2_start_time)
        primary_set = set2
        secondary_set = set1

    # create dicts that map rounded times to points
    primary_time_points_mapping = create_time_to_points_mapping(primary_set)
    secondary_time_points_mapping = create_time_to_points_mapping(
        secondary_set)

    offset_range_length = 200  # how many offsets to check so, for 200, check offsets (-100,100)
    point_checking_range_length = 200  # points to check around each offset, for 200, check points (-100,100)

    # find best offset
    optimal_offset = find_optimal_offset(primary_time_points_mapping,
                                         secondary_time_points_mapping,
                                         later_start_time, offset_range_length,
                                         point_checking_range_length)
    print(optimal_offset)
    if optimal_offset is None:
        print(
            "no optimal line-up for these two data sets; check if correct files are being used"
        )
        return (None, None)
    if primary_set == set1:
        print("Optimal offset: set 2 is %s seconds from set 1" %
              optimal_offset)
        return (later_start_time,
                later_start_time + timedelta(seconds=optimal_offset))
    else:
        print("Optimal offset: set 1 is %s seconds from set 2" %
              optimal_offset)
        return (later_start_time + timedelta(seconds=optimal_offset),
                later_start_time)
Ejemplo n.º 2
0
    def test_round_time_rounds_to_nearest_second(self):
        unrounded_time = datetime(2020,
                                  7,
                                  7,
                                  18,
                                  46,
                                  36,
                                  883732,
                                  tzinfo=timezone.utc)
        rounded_time = datetime(2020, 7, 7, 18, 46, 37, tzinfo=timezone.utc)

        result = utils.round_time(unrounded_time)

        self.assertEqual(rounded_time, result)
    def get_availability(self):
        """
        Calculate the availability of wear captured gps data

        Returns:
            Percentile of wear captured gps data by compared gpsdataset
        """
        if self.availability:
            return self.availability
        if not self.starting_time_1 and not self.starting_time_2:
            return 0
        total_timestamps = 0
        available_timestamps = 0

        start_time = utils.round_time(max(self.starting_time_1, self.starting_time_2))
        end_time = utils.round_time(min(self.ending_time_1, self.ending_time_2))
        total_seconds = int((end_time-start_time).total_seconds())

        for timestamp in [start_time + timedelta(seconds=x) for x in range(total_seconds)]:
            if timestamp in self.offset_mapping_1 and timestamp in self.offset_mapping_2:
                available_timestamps += 1

        return round(available_timestamps / total_seconds, 4)*100
Ejemplo n.º 4
0
def create_time_to_points_mapping(dataset, offset=0):
    """
    Map timestamp to points from the dataset.

    Args:
        dataset: GpsDataSet
        offset: int, seconds of offset to apply to timestamps

    Returns:
        Dictionary that goups dataset points by seconds timestamp in the
        following format: {DateTime: [GpsData,], ...}
    """
    time_points_mapping = {}
    for point in dataset.gps_data_list:
        rounded_time = utils.round_time(point.time) + timedelta(seconds=offset)
        if rounded_time in time_points_mapping:
            time_points_mapping[rounded_time].append(point)
        else:
            time_points_mapping[rounded_time] = [point]
    return time_points_mapping
Ejemplo n.º 5
0
def find_lineup(set1, set2):
    """
    Optimized algorithm to find the approximate time offset between two GPS data sets.

    This algorithm assigns the data set that starts later as primary and the 
    other one as secondary. The offset is then applied to the secondary data
    set. After mapping the timestamps to the corresponding points from each set,
    it finds the range that has the most overlapping timestamps between the two
    sets and then finds the optimal offset using the middle of that range 
    as the starting point.

    Args:
        set1: GpsDataSet object
        set2: GpsDataSet object

    Returns:
        Tuple of two datetimes, the start time for set 1 and for set 2 given the
        calculated offset. If no lineup is found, it will return None.
    """

    # find primary data set (the one with the later start time)
    set1_start_time = set1.gps_data_list[0].time
    set2_start_time = set2.gps_data_list[0].time
    set1_end_time = set1.gps_data_list[-1].time
    set2_end_time = set2.gps_data_list[-1].time
    if set1_start_time > set2_start_time:
        later_start_time = utils.round_time(set1_start_time)
        primary_set = set1
        secondary_set = set2
    else:
        later_start_time = utils.round_time(set2_start_time)
        primary_set = set2
        secondary_set = set1

    # create dict that maps rounded times to points
    primary_time_points_mapping = create_time_to_points_mapping(primary_set)
    secondary_time_points_mapping = create_time_to_points_mapping(
        secondary_set)

    # how many offsets to check so, for 50, check offsets (-25,25); should be even
    offset_range_length = 50
    # points to check around each offset, for 100, check points (-50,50); should be even
    point_checking_range_length = 100

    # span length is total length of the span of points to check around the offsets
    span_length = offset_range_length + point_checking_range_length

    range_start = utils.round_time(max(
        set1_start_time, set2_start_time)) - timedelta(seconds=span_length)
    range_end = utils.round_time(min(set1_end_time, set2_end_time))

    range_optimization_size = offset_range_length

    best_range_start = find_best_data_range(primary_time_points_mapping,
                                            secondary_time_points_mapping,
                                            range_optimization_size,
                                            range_start, range_end)

    # find best offset starting at the middle of range with most valid points
    range_middle = best_range_start + timedelta(
        seconds=range_optimization_size // 2)

    optimal_offset = find_optimal_offset(primary_time_points_mapping,
                                         secondary_time_points_mapping,
                                         range_middle, offset_range_length,
                                         point_checking_range_length)
    if optimal_offset is None:
        print(
            "no optimal line-up for these two data sets; check if correct files are being used"
        )
        return (None, None)

    if primary_set == set1:
        print("Optimal offset: set 2 is %s seconds from set 1" %
              optimal_offset)
        return (later_start_time,
                later_start_time + timedelta(seconds=optimal_offset))
    else:
        print("Optimal offset: set 1 is %s seconds from set 2" %
              optimal_offset)
        return (later_start_time + timedelta(seconds=optimal_offset),
                later_start_time)