Beispiel #1
0
    def test_MergeStreaksPass2(self):
        import attrdict as ad

        ffd = eaissf.FlipFlopDetection([], None)
        unmerged_change_list = [
            (ad.AttrDict({'type': ecwm.MotionTypes.WALKING}),
             ad.AttrDict({'type': ecwm.MotionTypes.IN_VEHICLE})),
            (ad.AttrDict({'type': ecwm.MotionTypes.IN_VEHICLE}),
             ad.AttrDict({'type': ecwm.MotionTypes.WALKING})),
            (ad.AttrDict({'type': ecwm.MotionTypes.WALKING}),
             ad.AttrDict({'type': ecwm.MotionTypes.WALKING})),
            (ad.AttrDict({'type': ecwm.MotionTypes.WALKING}),
             ad.AttrDict({'type': ecwm.MotionTypes.WALKING})),
            (ad.AttrDict({'type': ecwm.MotionTypes.WALKING}),
             ad.AttrDict({'type': ecwm.MotionTypes.WALKING}))
        ]

        ret_list = ffd.merge_streaks_pass_2(unmerged_change_list)
        self.assertEqual(ret_list,
                         [(ad.AttrDict({'type': ecwm.MotionTypes.WALKING}),
                           ad.AttrDict({'type': ecwm.MotionTypes.IN_VEHICLE})),
                          (ad.AttrDict({'type': ecwm.MotionTypes.IN_VEHICLE}),
                           ad.AttrDict({'type': ecwm.MotionTypes.WALKING})),
                          (ad.AttrDict({'type': ecwm.MotionTypes.WALKING}),
                           ad.AttrDict({'type': ecwm.MotionTypes.WALKING}))])
Beispiel #2
0
 def test_GetStreakLast(self):
     ffd = eaissf.FlipFlopDetection([], None)
     flip_flop_list = [
         False, False, True, False, False, False, False, True, False, True,
         False, True, True
     ]
     sss_list = ffd.get_streaks(flip_flop_list)
     self.assertEqual(sss_list, [(2, 2), (7, 7), (9, 9), (11, 11)])
Beispiel #3
0
 def test_MergeStreaksPass1(self):
     ffd = eaissf.FlipFlopDetection([], None)
     unmerged_change_list = [({
         'idx': 'a'
     }, {
         'idx': 'b'
     }), ({
         'idx': 'b'
     }, {
         'idx': 'c'
     }), ({
         'idx': 'c'
     }, {
         'idx': 'd'
     }), ({
         'idx': 'd'
     }, {
         'idx': 'e'
     }), ({
         'idx': 'e'
     }, {
         'idx': 'f'
     }), ({
         'idx': 'f'
     }, {
         'idx': 'g'
     }), ({
         'idx': 'g'
     }, {
         'idx': 'h'
     }), ({
         'idx': 'h'
     }, {
         'idx': 'i'
     })]
     forward_merged_list = [(1, 2), (6, 6)]
     backward_merged_list = [(4, 4)]
     ret_list = ffd.merge_streaks_pass_1(unmerged_change_list,
                                         forward_merged_list,
                                         backward_merged_list)
     self.assertEqual(ret_list, [({
         'idx': 'a'
     }, {
         'idx': 'd'
     }), ({
         'idx': 'd'
     }, {
         'idx': 'e'
     }), ({
         'idx': 'e'
     }, {
         'idx': 'h'
     }), ({
         'idx': 'h'
     }, {
         'idx': 'i'
     })])
Beispiel #4
0
 def test_ShouldMerge(self):
     ffd = eaissf.FlipFlopDetection([(ad.AttrDict({
         'idx': 'a',
         'ts': 100
     }), ad.AttrDict({
         'idx': 'b',
         'ts': 200
     }))], None)
     sm = ffd.should_merge(0, 0)
     self.assertEqual(sm.direction, eaissf.Direction.NONE)
Beispiel #5
0
    def test_GetSectionSpeed(self):
        ffd = eaissf.FlipFlopDetection([], None)
        loc_points = pd.DataFrame()
        with_speed_loc_points = pd.DataFrame()
        points_before = pd.DataFrame()
        points_after = pd.DataFrame()

        curr_speed = ffd.get_section_speed(loc_points, with_speed_loc_points,
                                           points_before, points_after)
        self.assertEqual(curr_speed, 0)

        loc_points = pd.DataFrame({"speed": [0]})
        self.assertEqual(loc_points.speed.median(), 0)

        curr_speed = ffd.get_section_speed(loc_points, with_speed_loc_points,
                                           points_before, points_after)
        self.assertEqual(curr_speed, 0)
Beispiel #6
0
    def test_GetStreakOneFF(self):
        ffd = eaissf.FlipFlopDetection([], None)

        flip_flop_list = [False]
        sss_list = ffd.get_streaks(flip_flop_list)
        self.assertEqual(sss_list, [])

        flip_flop_list = [True]
        sss_list = ffd.get_streaks(flip_flop_list)
        self.assertEqual(sss_list, [(0, 0)])

        flip_flop_list = [True, False]
        sss_list = ffd.get_streaks(flip_flop_list)
        self.assertEqual(sss_list, [(0, 0)])

        flip_flop_list = [False, True]
        sss_list = ffd.get_streaks(flip_flop_list)
        self.assertEqual(sss_list, [(1, 1)])

        flip_flop_list = [True, False, True, True]
        sss_list = ffd.get_streaks(flip_flop_list)
        self.assertEqual(sss_list, [(0, 0), (2, 2)])
Beispiel #7
0
    def segment_into_motion_changes(self, timeseries, time_query):
        """
        Use the motion changes detected on the phone to detect sections (consecutive chains of points)
        that have a consistent motion.
        :param timeseries: the time series for this user
        :param time_query: the range to consider for segmentation
        :return: a list of tuples [(start_motion, end_motion)] that represent the ranges with a consistent motion.
        The gap between end_motion[n] and start_motion[n+1] represents the transition between the activities.
        We don't actually know the motion/activity in that range with any level of confidence. We need a policy on
        how to deal with them (combine with first, combine with second, split in the middle). This policy can be
        enforced when we map the activity changes to locations.
        """
        motion_df = timeseries.get_data_df("background/motion_activity",
                                           time_query)
        filter_mask = motion_df.apply(self.is_filtered, axis=1)
        # Calling np.nonzero on the filter_mask even if it was related trips with zero sections
        # has not been a problem before this - the subsequent check on the
        # length of the filtered dataframe was sufficient. But now both Tom and
        # I have hit it (on 18th and 21st of Sept) so let's handle it proactively here.
        if filter_mask.shape == (0, 0):
            logging.info("Found filter_mask with shape (0,0), returning blank")
            return []

        # Replace RUNNING with WALKING so that we don't get extra, incorrect sections
        # https://github.com/e-mission/e-mission-server/issues/577#issuecomment-379496118
        motion_df["type"].replace([8], 7, inplace=True)

        logging.debug("filtered points %s" % np.nonzero(filter_mask))
        logging.debug("motion_df = %s" % motion_df.head())
        filtered_df = motion_df[filter_mask]
        filtered_df.reset_index(inplace=True)

        if len(filtered_df) == 0:
            # If there were no entries in the filtered_df, then there are no sections,
            # and we need to return an empty list. This check enforces that...
            return []

        motion_change_list = []
        prev_motion = None
        curr_start_motion = ecwm.Motionactivity(filtered_df.iloc[0])
        #         curr_section = ad.AttrDict({"user_id": trip.user_id, "loc_filter": trip.loc_filter,
        #                                     "start_ts": trip.start_ts, "start_time": trip.start_time,
        #                                     "activity": no_tilting_points_df.iloc[0].activity})

        for idx, row in filtered_df.iterrows():
            curr_motion = ecwm.Motionactivity(row)
            curr_motion.update({"idx": idx})
            # Since the start motion is set upstream makes sure to set an idx
            # for it too
            if curr_motion.ts == curr_start_motion.ts:
                curr_start_motion.update({"idx": idx})
            if curr_motion.type != curr_start_motion.type:
                # Because the curr_start_motion is initialized with the first
                # motion.  So when idx == 0, the activities will be equal and
                # this is guaranteed to not be invoked
                assert (idx > 0)
                logging.debug(
                    "At idx %d, time %s, found new activity %s compared to current %s"
                    % (idx, curr_motion.fmt_time, curr_motion.type,
                       curr_start_motion.type))
                curr_end_motion = get_curr_end_motion(prev_motion, curr_motion)
                logging.debug(
                    "creating new section for %s at %s -> %s with start_time %s -> %s"
                    % (curr_start_motion.type, curr_start_motion["idx"],
                       curr_end_motion["idx"], curr_start_motion.fmt_time,
                       curr_end_motion.fmt_time))
                # complete this section
                motion_change_list.append((curr_start_motion, curr_end_motion))
                curr_start_motion = curr_end_motion
            else:
                logging.debug(
                    "At %s, retained existing activity %s because of no change"
                    % (curr_motion.fmt_time, curr_motion.type))
            prev_motion = curr_motion

        logging.info("Detected trip end! Ending section at %s" %
                     curr_motion.fmt_time)
        motion_change_list.append((curr_start_motion, curr_motion))

        smoothed_motion_list = ffd.FlipFlopDetection(
            motion_change_list, self).merge_flip_flop_sections()
        return smoothed_motion_list
Beispiel #8
0
    def test_MergeStreaksPass1(self):
        ffd = eaissf.FlipFlopDetection([], None)
        unmerged_change_list = [({
            'idx': 'a'
        }, {
            'idx': 'b'
        }), ({
            'idx': 'b'
        }, {
            'idx': 'c'
        }), ({
            'idx': 'c'
        }, {
            'idx': 'd'
        }), ({
            'idx': 'd'
        }, {
            'idx': 'e'
        }), ({
            'idx': 'e'
        }, {
            'idx': 'f'
        }), ({
            'idx': 'f'
        }, {
            'idx': 'g'
        }), ({
            'idx': 'g'
        }, {
            'idx': 'h'
        }), ({
            'idx': 'h'
        }, {
            'idx': 'i'
        })]
        forward_merged_list = [
            ad.AttrDict({
                "start": 1,
                "end": 2,
                "final_mode": ecwm.MotionTypes.IN_VEHICLE
            }),
            ad.AttrDict({
                "start": 6,
                "end": 6,
                "final_mode": ecwm.MotionTypes.WALKING
            })
        ]
        backward_merged_list = [
            ad.AttrDict({
                "start": 4,
                "end": 4,
                "final_mode": ecwm.MotionTypes.BICYCLING
            })
        ]
        ret_list = ffd.merge_streaks_pass_1(unmerged_change_list,
                                            forward_merged_list,
                                            backward_merged_list, [])
        self.assertEqual(ret_list, [({
            'idx': 'a'
        }, {
            'idx': 'd'
        }), ({
            'idx': 'd'
        }, {
            'idx': 'e'
        }), ({
            'idx': 'e'
        }, {
            'idx': 'h'
        }), ({
            'idx': 'h'
        }, {
            'idx': 'i'
        })])

        unmerged_change_list = [({
            'idx': 'a'
        }, {
            'idx': 'b'
        }), ({
            'idx': 'b'
        }, {
            'idx': 'c'
        }), ({
            'idx': 'c'
        }, {
            'idx': 'd'
        }), ({
            'idx': 'd'
        }, {
            'idx': 'e'
        }), ({
            'idx': 'e'
        }, {
            'idx': 'f'
        }), ({
            'idx': 'f'
        }, {
            'idx': 'g'
        }), ({
            'idx': 'g'
        }, {
            'idx': 'h'
        }), ({
            'idx': 'h'
        }, {
            'idx': 'i'
        }), ({
            'idx': 'k'
        }, {
            'idx': 'l'
        }), ({
            'idx': 'm'
        }, {
            'idx': 'n'
        }), ({
            'idx': 'o'
        }, {
            'idx': 'p'
        })]

        forward_merged_list = [
            ad.AttrDict({
                "start": 1,
                "end": 2,
                "final_mode": ecwm.MotionTypes.IN_VEHICLE
            }),
            ad.AttrDict({
                "start": 6,
                "end": 6,
                "final_mode": ecwm.MotionTypes.WALKING
            })
        ]
        backward_merged_list = [
            ad.AttrDict({
                "start": 4,
                "end": 4,
                "final_mode": ecwm.MotionTypes.BICYCLING
            })
        ]
        new_merged_list = [
            ad.AttrDict({
                "start": 8,
                "end": 10,
                "final_mode": ecwm.MotionTypes.BICYCLING
            })
        ]
        ret_list = ffd.merge_streaks_pass_1(unmerged_change_list,
                                            forward_merged_list,
                                            backward_merged_list,
                                            new_merged_list)
        self.assertEqual(ret_list, [({
            'idx': 'a'
        }, {
            'idx': 'd'
        }), ({
            'idx': 'd'
        }, {
            'idx': 'e'
        }), ({
            'idx': 'e'
        }, {
            'idx': 'h'
        }), ({
            'idx': 'h'
        }, {
            'idx': 'i'
        }), ({
            'idx': 'k',
            'type': ecwm.MotionTypes.BICYCLING
        }, {
            'idx': 'p'
        })])
Beispiel #9
0
 def test_GetStreakOne(self):
     ffd = eaissf.FlipFlopDetection([], None)
     flip_flop_list = [False, False, False, True, True, False, False, False]
     sss_list = ffd.get_streaks(flip_flop_list)
     self.assertEqual(sss_list, [(3, 4)])