예제 #1
0
    def derive(self, pitch=P('Pitch'), climbs=S('Initial Climb')):

        for climb in climbs:
            masked_pitch = mask_outside_slices(pitch.array, [climb.slice])

            pitch_index = np.ma.argmax(
                masked_pitch <= -10) or np.ma.argmin(masked_pitch)

            scaling_factor = abs(masked_pitch[pitch_index]) / 10

            window_threshold = -10.00 * scaling_factor
            min_window_threshold = -8.00 * scaling_factor
            window_size = 32
            window_threshold_step = 0.050 * scaling_factor

            diffs = np.ma.ediff1d(masked_pitch[climb.slice.start:pitch_index])
            diffs_exist = diffs.data.size >= 2

            big_diff_index = -1

            while diffs_exist:
                sig_pitch_threshold = window_threshold / window_size

                for i, d in enumerate(diffs):
                    # Look for the first big negative pitch spike
                    if diffs[slices_int(
                            i, i + window_size)].sum() < window_threshold:

                        # Find the first significant negative value within the
                        # spike and make that the starting point of the phase
                        big_diff_index = np.ma.argmax(
                            diffs[i:i + window_size] < sig_pitch_threshold) + i
                        break

                # Bail on match or total failure
                if big_diff_index != -1 or window_size < 2:
                    break

                # Shrink window size instead of looking for insignificant
                # spikes and scale window/pitch thresholds accordingly
                if window_threshold >= min_window_threshold:
                    window_size //= 2
                    min_window_threshold /= 2
                    window_threshold /= 2
                    window_threshold_step /= 2
                    sig_pitch_threshold *= 2
                else:
                    window_threshold += window_threshold_step

            if big_diff_index != -1:
                self.create_section(
                    slice(climb.slice.start + big_diff_index, pitch_index))

            # Worst case fallback, this should happen extremely rarely
            # and would trigger all events related to this phase
            else:
                self.create_section(slice(climb.slice.start, climb.slice.stop))
    def derive(self, pitch=P('Pitch'), climbs=S('Initial Climb')):

        for climb in climbs:
            masked_pitch = mask_outside_slices(pitch.array, [climb.slice])

            pitch_index = np.ma.argmax(masked_pitch <= -10) or np.ma.argmin(masked_pitch)

            scaling_factor = abs(masked_pitch[pitch_index]) / 10

            window_threshold = -10.00 * scaling_factor
            min_window_threshold = -8.00 * scaling_factor
            window_size = 32
            window_threshold_step = 0.050 * scaling_factor

            diffs = np.ma.ediff1d(masked_pitch[climb.slice.start:pitch_index])
            diffs_exist = diffs.data.size >= 2

            big_diff_index = -1

            while diffs_exist:
                sig_pitch_threshold = window_threshold / window_size

                for i, d in enumerate(diffs):
                    # Look for the first big negative pitch spike
                    if diffs[i:i+window_size].sum() < window_threshold:

                        # Find the first significant negative value within the
                        # spike and make that the starting point of the phase
                        big_diff_index = np.ma.argmax(diffs[i:i+window_size] < sig_pitch_threshold) + i
                        break

                # Bail on match or total failure
                if big_diff_index != -1 or window_size < 2:
                    break

                # Shrink window size instead of looking for insignificant
                # spikes and scale window/pitch thresholds accordingly
                if window_threshold >= min_window_threshold:
                    window_size /= 2; min_window_threshold /= 2; window_threshold /= 2; window_threshold_step /= 2
                    sig_pitch_threshold *= 2
                else:
                    window_threshold += window_threshold_step

            if big_diff_index != -1:
                self.create_section(slice(climb.slice.start + big_diff_index,
                                          pitch_index))

            # Worst case fallback, this should happen extremely rarely
            # and would trigger all events related to this phase
            else:
                self.create_section(slice(climb.slice.start, climb.slice.stop))
    def derive(self,
               num=P('Flight Number'),
               mobiles=S('Mobile')):

        # Limit to Mobile sections
        num_array = mask_outside_slices(num.array, mobiles.get_slices())
        # Q: Should we validate the flight number?
        if num.array.dtype.type is np.string_:
            value = most_common_value(num_array, threshold=0.45)
            if value is not None:
                # Only parse valid ASCII characters
                try:
                    self.set_flight_attr(re.sub(r'[^\x00-\x7f]', r'', value.decode()))
                except UnicodeDecodeError:
                    self.set_flight_attr(None)
            return

        # Values of 0 are invalid flight numbers
        array = np.ma.masked_less_equal(num_array, 0)
        # Ignore masked values
        compressed_array = array.compressed()
        _, minvalue = min_value(compressed_array)
        if minvalue is None or minvalue < 0:
            self.warning(
                "'%s' only supports unsigned (positive) values > 0, "
                "but none were found. Cannot determine flight number",
                self.name)
            self.set_flight_attr(None)
            return

        # note reverse of value, index from max_value due to bincount usage.
        value, count = max_value(
            np.bincount(compressed_array.astype(np.integer)))
        if count > len(compressed_array) * 0.45:
            # this value accounts for at least 45% of the values in the array
            self.set_flight_attr(str(int(value)))
        else:
            self.warning("Only %d out of %d flight numbers were the same."
                         " Flight Number attribute will be set as None.",
                         count or 0, len(num.array))
            self.set_flight_attr(None)
            return