def test_midnight_rollover(self):
     """
     When a flight starts just before midnight, the majority of the
     flight will be in the next day so the fallback_dt needs to adjust
     throughout the data otherwise it will try to force the next day's
     flight to appear to that of the previous.
     """
     # fallback is at start of the recording
     dt = datetime(2012, 12, 12, 23, 59, 58, tzinfo=pytz.utc)
     hdf = MockHDF({
         'Hour': P('Hour', np.ma.array([23, 23] + [0] * 18)),
         'Minute': P('Minute', np.ma.array([59, 59] + [0] * 18)),
         'Second': P('Minute', np.ma.array([58, 59] + list(range(18)))),  # last two seconds and start of next flight
     }, duration=20)
     res, precise_timestamp, _ = _calculate_start_datetime(hdf, dt, dt)
     # result is the exact start of the data for the timestamp (not a day before!)
     self.assertEqual(res, datetime(2012, 12, 12, 23, 59, 58, tzinfo=pytz.utc))
     self.assertFalse(precise_timestamp)
Exemple #2
0
    def derive(self, tcas_ctl  =  M('TCAS Combined Control'), 
                     tcas_up   =  M('TCAS Up Advisory'), 
                     tcas_down =  M('TCAS Down Advisory'), 
                     tcas_vert =  M('TCAS Vertical Control'), 
                     vertspd   =  P('Vertical Speed'), 
                     ra_sections = S('TCAS RA Sections'), 
                     raduration  = KPV('TCAS RA Warning Duration'),
              ):
                    
        standard_vert_accel            =  8.0 * 60   #  8 ft/sec^2, converted to ft/min^2
        standard_vert_accel_reversal   = 11.2 * 60   # ft/sec^2 ==> ft/min^2
        standard_response_lag          =  5.0        # seconds
        standard_response_lag_reversal =  2.5        # seconds       
        self.array = vertspd.array * 0 #make a copy, mask and zero out
        self.array.mask = True
        required_fpm_array = vertspd.array * 0
        
        for ra in ra_sections:                      
            self.debug('TCAS RA Standard Response: in sections')
            #initialize response state
            ra_ctl_prev     = tcas_ctl.array[ra.start_edge] # used to check if the command has changed
            up_prev         = tcas_ctl.array[ra.start_edge] # used to check if the command has changed
            down_prev       = tcas_ctl.array[ra.start_edge] # used to check if the command has changed
            initial_vert_spd = vertspd.array[ra.start_edge]
            std_vert_spd    = initial_vert_spd # current standard response vert speed in fpm
            required_fpm    = None # nominal vertical speed in fpm required by the RA
            lag_end         = ra.start_edge + standard_response_lag # time pilot response lag ends
            acceleration    = standard_vert_accel
                        
            for t in range(int(ra.start_edge), int(ra.stop_edge)+1):               
                # set required_fpm for initial ra or a change in command
                if ra_ctl_prev!=tcas_ctl.array[t] or up_prev!=tcas_up.array[t] or down_prev!=tcas_down.array[t]:                        
                    if tcas_ctl.array[t] == 'Up Advisory Corrective' or tcas_up.array[t].lower()!='no up advisory':
                        required_fpm = tcas_vert_spd_up(tcas_up.array[t], vertspd.array[t], tcas_vert.array[t])                            
                    elif tcas_ctl.array[t] == 'Down Advisory Corrective'  or tcas_down.array[t].lower()!='no down advisory':
                        required_fpm = tcas_vert_spd_down(tcas_down.array[t], vertspd.array[t], tcas_vert.array[t])
                    else:
                        required_fpm = vertspd.array[t]
                    if tcas_vert.array[t]=='Reversal':                                                
                        lag_end = t + standard_response_lag_reversal
                        acceleration = standard_vert_accel_reversal                    
                        initial_vert_spd = std_vert_spd
                if required_fpm is None:
                    self.warning('TCAS RA Standard Response: No required_fpm found. Take a look! '+str(t))                

                std_vert_spd= update_std_vert_spd(t, lag_end, tcas_ctl.array[t], tcas_up.array[t], tcas_down.array[t],
                                                  acceleration, required_fpm, 
                                                  std_vert_spd, initial_vert_spd, vertspd.array[t])
                self.array.data[t] = std_vert_spd
                self.array.mask[t] = False
                required_fpm_array[t] = required_fpm
                ra_ctl_prev = tcas_ctl.array[t]
                up_prev     = tcas_up.array[t] 
                down_prev   = tcas_down.array[t]                
                #end of time loop within ra section
        return
    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 test_year_00_uses_fallback_year(self):
     # Ensure that a timebase error is not raised due to old date!
     #Other than the year 2000 or possibly 2100, no date values
     # can be all 0's
     dt = datetime(2012, 12, 12, 12, 12, 10, tzinfo=pytz.utc)
     # Test only without second and empty year
     hdf = MockHDF({
         'Year': P('Year', np.ma.array([0, 0, 0, 0])),
         'Month': P('Month', np.ma.array([11, 11, 11, 11])),
         'Day': P('Day', np.ma.array([11, 11, 11, 11])),
         'Hour': P('Hour', np.ma.array([11, 11, 11, 11], mask=[True, False, False, False])),
         'Minute': P('Minute', np.ma.array([11, 11]), frequency=0.5),
     }, duration=4)
     # add a masked invalid value
     hdf['Year'].array[2] = 50
     hdf['Year'].array[2] = np.ma.masked
     res = _calculate_start_datetime(hdf, dt, dt)
     print hdf, dt
     self.assertEqual(res, datetime(2012, 11, 11, 11, 11, 10, tzinfo=pytz.utc))
Exemple #5
0
 def test_airborne_helicopter_radio_refinement(self):
     '''
     Confirms that the beginning and end are trimmed to match the radio signal,
     not the (smoothed) AGL data.
     '''
     gog = M(name='Gear On Ground',
             array=np.ma.array([0]*3+[1]*5+[0]*10+[1]*5, dtype=int),
             frequency=1,
             offset=0,
             values_mapping={1:'Ground', 0:'Air'})
     agl = P(name='Altitude AGL',
             array=np.ma.array([0.0]*6+[20.0]*12+[0.0]*5, dtype=float))
     rad = P(name='Altitude Radio',
             array=np.ma.array([0.0]*7+[10.0]*10+[0.0]*6, dtype=float))
     rtr = buildsection('Rotors Turning', 0, 40)
     node = Airborne()
     node.derive(rad, agl, gog, rtr)
     self.assertEqual(node[0].start_edge, 6.1)
     self.assertEqual(node[0].stop_edge, 16.9)
Exemple #6
0
 def derive(self, tcas_sens=P('TCAS Sensitivity Level'), ra_sections=S('TCAS RA Sections') ):
     _change_points = change_indexes(tcas_sens.array.data) #returns array index
     for cp in _change_points:
         _value = tcas_sens.array.data[cp]
         if tcas_sens.array.mask[cp]:
             _name = 'TCAS Sensitivity|masked'
         else:
             _name = 'TCAS Sensitivity|' + tcas_sens.array[cp]
         kpv = KeyPointValue(index=cp, value=_value, name=_name)
         self.append(kpv)
Exemple #7
0
 def test_derive_masked(self):
     '''
     
     '''
     flight_number = FlightNumber()
     number_param = P(
         'Flight Number',
         array=np.ma.array([0, 0, 0, 0, 36, 36, 0, 0, 0, 0],
                           mask=[True] * 4 + [False] * 2 + [True] * 4))
     flight_number.derive(number_param)
     self.assertEqual(flight_number.value, '36')
Exemple #8
0
 def derive(self, ra_sections=S('TCAS RA Sections'),  tcas_ctl=M('TCAS Combined Control'),
                  tcas_up   =  M('TCAS Up Advisory'), tcas_down =  M('TCAS Down Advisory'), 
                  std=P('TCAS RA Standard Response'), vertspd=P('Vertical Speed') ):
     for ra in ra_sections:
         exceedance=0
         deviation=0
         for t in range(int(ra.start_edge), int(ra.stop_edge)): 
             if tcas_ctl.array[t] == 'Down Advisory Corrective' or tcas_down.array[t].lower()!='no down advisory':
                 deviation =  max(vertspd.array[t] - std.array[t], 0)
             elif tcas_ctl.array[t] == 'Up Advisory Corrective' or tcas_up.array[t].lower()!='no up advisory':
                 deviation =  max(std.array[t] - vertspd.array[t], 0)
             else:
                 deviation = abs(vertspd.array[t] - std.array[t])
                 deviation = max( deviation-250, 0 ) # allow 250 fpm buffer
             #print 't vert std DEV', t, vertspd.array[t], std.array[t], deviation
             if deviation and deviation!=0:
                 exceedance += deviation
         #print 'Alt Exceed', exceedance
         exceedance = exceedance / 60.0 # min to sec
         self.create_kpv(ra.start_edge, exceedance)
Exemple #9
0
 def test_airborne_helicopter_cant_fly_without_rotor_turning(self):
     gog = M(name='Gear On Ground',
             array=np.ma.array([1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], dtype=int),
             values_mapping={1:'Ground', 0:'Air'})
     agl = P(name='Altitude AGL',
             array=np.ma.array([0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 2, 0], dtype=float),
             frequency=0.2)
     rtr = buildsection('Rotors Turning', 0, 0)
     node = Airborne()
     node.derive(agl, agl, gog, rtr)
     self.assertEqual(len(node), 0)
    def derive(self,
               alt_agl=P('Altitude AGL'),
               ias=P('Airspeed'),
               airs=S('Airborne'),
               pitch_rate=P('Pitch Rate')):
        for air in airs:
            trans_slices = slices_from_to(ias.array[air.slice],
                                          ROTOR_TRANSITION_SPEED_HIGH,
                                          ROTOR_TRANSITION_SPEED_LOW,
                                          threshold=1.0)[1]

            if trans_slices:
                for trans in shift_slices(trans_slices, air.slice.start):
                    trans_end = index_at_value(
                        ias.array,
                        0.0,
                        _slice=slice(trans.stop,
                                     trans.stop + 20 * ias.frequency),
                        endpoint='first_closing')
                    self.create_phase(slice(trans.start, trans_end + 1))
Exemple #11
0
    def derive(self,
               alt_aal=P('Altitude AAL'),
               lat=P('Latitude Smoothed'),
               lon=P('Longitude Smoothed'),
               tdwns=KTI('Touchdown')):
        app_range = np_ma_masked_zeros_like(alt_aal.array)

        #Helicopter compuation does not rely on runways!
        stop_delay = 10 # To make sure the helicopter has stopped moving

        for tdwn in tdwns:
            end = tdwn.index
            endpoint = {'latitude': lat.array[int(end)],
                        'longitude': lon.array[int(end)]}
            prev_tdwn = tdwns.get_previous(end)
            begin = prev_tdwn.index + stop_delay if prev_tdwn else 0
            this_leg = slices_int(begin, end+stop_delay)
            _, app_range[this_leg] = bearings_and_distances(lat.array[this_leg],
                                                            lon.array[this_leg],
                                                            endpoint)
        self.array = app_range
Exemple #12
0
 def test_airborne_helicopter_short(self):
     gog = M(name='Gear On Ground',
             array=np.ma.array([0]*3+[1]*5+[0]*10+[1]*5, dtype=int),
             frequency=1,
             offset=0,
             values_mapping={1:'Ground', 0:'Air'})
     agl = P(name='Altitude AGL',
             array=np.ma.array([2.0, 0.0, 0.0]+[0.0]*4+[20.0]*10+[0.0]*6, dtype=float))
     rtr = buildsection('Rotors Turning', 0, 40)
     node = Airborne()
     node.derive(agl, agl, gog, rtr)
     self.assertEqual(len(node), 1)
Exemple #13
0
    def test_nose_down_multiple_climbs(self):
        node = NoseDownAttitudeAdoption()
        pitch = np.concatenate([np.ones(15) * 2, np.linspace(2, -11, num=15),
                                np.linspace(-11, 2, num=10),
                                np.ones(20) * 2, np.linspace(2, -11, num=15),
                                np.ones(10) * -11])
        climbs = buildsections('Initial Climb', [10, 40], [60, 85])
        node.derive(P('Pitch', pitch), climbs)

        self.assertEqual(len(node), 2)
        self.assertEqual(node[0], Section('Nose Down Attitude Adoption', slice(15, 28, None), 15, 28))
        self.assertEqual(node[1], Section('Nose Down Attitude Adoption', slice(60, 73, None), 60, 73))
Exemple #14
0
    def test_2_sources(self):
        lat1 = P('Latitude (1)',
                 array=np.ma.arange(-10, 10),
                 frequency=0.5,
                 offset=0.25)
        lat1.array[5:8] = np.ma.masked
        lat2 = P('Latitude (2)',
                 array=np.ma.arange(-9.5, 10),
                 frequency=0.5,
                 offset=0.75)
        lat2.array[5:8] = np.ma.masked
        latitude = Latitude()
        latitude.get_derived((lat1, lat2, None))

        expected = np.ma.arange(-9.75, 10, 0.5)
        expected[-1] = np.ma.masked

        np.testing.assert_array_equal(latitude.array, expected)
        np.testing.assert_array_equal(latitude.array.mask, expected.mask)
        assert latitude.offset == 0.5
        assert latitude.frequency == 1
Exemple #15
0
    def derive(self,
               pilot_flying=M('Pilot Flying'),
               pitch_capt=P('Pitch (Capt)'),
               pitch_fo=P('Pitch (FO)'),
               roll_capt=P('Roll (Capt)'),
               roll_fo=P('Roll (FO)'),
               cc_capt=P('Control Column Force (Capt)'),
               cc_fo=P('Control Column Force (FO)'),
               ap1_eng=M('AP (1) Engaged'),
               ap2_eng=M('AP (2) Engaged'),
               takeoffs=S('Takeoff'),
               liftoffs=KTI('Liftoff'),
               rejected_toffs=S('Rejected Takeoff')):

        #TODO: Tidy
        phase = takeoffs or rejected_toffs or None
        if phase is None:
            # Nothing to do as no attempt to takeoff
            return
        lift = liftoffs.get_first() if liftoffs else None
        if lift and ap1_eng and ap2_eng:
            # check AP state at the floored index (just before lift)
            ap1 = ap1_eng.array[lift.index] == 'Engaged'
            ap2 = ap2_eng.array[lift.index] == 'Engaged'
        else:
            ap1 = ap2 = None
        args = (pilot_flying, pitch_capt, pitch_fo, roll_capt, roll_fo,
                cc_capt, cc_fo, phase.get_first(), ap1, ap2)
        self.set_flight_attr(self._determine_pilot(*args))
    def derive(self,
               pilot_flying=M('Pilot Flying'),
               pitch_capt=P('Pitch (Capt)'),
               pitch_fo=P('Pitch (FO)'),
               roll_capt=P('Roll (Capt)'),
               roll_fo=P('Roll (FO)'),
               cc_capt=P('Control Column Force (Capt)'),
               cc_fo=P('Control Column Force (FO)'),
               ap1_eng=M('AP (1) Engaged'),
               ap2_eng=M('AP (2) Engaged'),
               landings=S('Landing'),
               touchdowns=KTI('Touchdown'),
               afr_landing_pilot=A('AFR Landing Pilot')):

        if afr_landing_pilot and afr_landing_pilot.value:
            self.set_flight_attr(afr_landing_pilot.value.replace('_', ' ').title())
            return

        phase = landings.get_last() if landings else None
        tdwn = touchdowns.get_last() if touchdowns else None
        if tdwn and ap1_eng and ap2_eng:
            # check AP state at the floored index (just before tdwn)
            ap1 = ap1_eng.array[int(tdwn.index)] == 'Engaged'
            ap2 = ap2_eng.array[int(tdwn.index)] == 'Engaged'
        else:
            ap1 = ap2 = None
        args = (pilot_flying, pitch_capt, pitch_fo, roll_capt, roll_fo,
                cc_capt, cc_fo, phase, ap1, ap2)
        self.set_flight_attr(self._determine_pilot(*args))
Exemple #17
0
 def test_derive_ascii(self):
     flight_number_param = P('Flight Number',
                             array=np.ma.masked_array(['ABC', 'DEF', 'DEF'],
                                                      dtype=np.string_))
     flight_number = FlightNumber()
     flight_number.set_flight_attr = Mock()
     flight_number.derive(flight_number_param)
     flight_number.set_flight_attr.assert_called_with('DEF')
     flight_number.set_flight_attr.reset_mock()
     # Entirely masked.
     flight_number_param.array[:] = np.ma.masked
     flight_number.derive(flight_number_param)
     flight_number.set_flight_attr.called = False
Exemple #18
0
    def test_derive_most_common_positive_float(self):
        flight_number = FlightNumber()

        neg_number_param = P(
            'Flight Number',
            array=np.ma.array([-1,2,-4,10,20,40,11]))
        flight_number.derive(neg_number_param)
        self.assertEqual(flight_number.value, None)

        # TODO: Implement variance checks as below
        ##high_variance_number_param = P(
            ##'Flight Number',
            ##array=np.ma.array([2,2,4,4,4,7,7,7,4,5,4,7,910]))
        ##self.assertRaises(ValueError, flight_number.derive, high_variance_number_param)

        flight_number_param= P(
            'Flight Number',
            array=np.ma.array([2,555.6,444,444,444,444,444,444,888,444,444,
                               444,444,444,444,444,444,7777,9100]))
        flight_number.set_flight_attr = Mock()
        flight_number.derive(flight_number_param)
        flight_number.set_flight_attr.assert_called_with('444')
 def test_basic(self):
     # Although "basic" the synthetic radio altitude tests for noise rejection, transfer from radio to pressure altimetry and use of
     # the gear on ground signals. The wide tolerance is because the noise signal varies from run to run.
     alt_rad = P(name='Altitude Radio',
                 array=(np.minimum(
                     6000,
                     (1.0 - np.cos(np.arange(100) * 3.14 / 50)) * 4000 +
                     np.random.rand(100) * 300)),
                 frequency=2)
     alt_baro = P(
         name='Altitude STD',
         array=np.ma.array((1.0 - np.cos(np.arange(100) * 3.14 / 50)) *
                           4000 + 1000))
     gog = M(name='Gear On Ground',
             array=np.ma.array([1] * 5 + [0] * 90 + [1] * 5),
             values_mapping={
                 0: 'Air',
                 1: 'Ground'
             })
     alt_aal = AltitudeAGL()
     alt_aal.derive(alt_rad, None, alt_baro, gog)
     self.assertLess(abs(np.max(alt_aal.array) - 8000), 300)
Exemple #20
0
 def test_derive(self):
     start = KTI(items=[
         KeyTimeInstance(index=2, name='TCAS RA Start'),
     ])
     param = P('AP Engaged',
               array=np.ma.arange(10) * 1.0,
               frequency=1.,
               offset=0.)
     expected = [
         KeyPointValue(index=2, value=2.0, name='TCAS RA Start Autopilot'),
     ]
     k = self.klass()
     k.derive(param, start)
     self.assertEqual(k, expected)
Exemple #21
0
    def derive(self,
               gear=M('Gear Down'),
               alt_aal=P('Altitude AAL'),
               touchdowns=KTI('Touchdown')):

        for touchdown in touchdowns:
            rough_index = index_at_value(gear.array.data, 0.5,
                                         slice(touchdown.index, 0, -1))
            # index_at_value tries to be precise, but in this case we really
            # just want the index at the new flap setting.
            if rough_index:
                last_index = np.round(rough_index)
                alt_last = value_at_index(alt_aal.array, last_index)
                self.create_kpv(last_index, alt_last)
    def test_derive(self):
        p1 = [26.51]*7 + [26.63] + [26.51]*7 + [26.4]*27 + [26.29] + [26.4]*7
        p2 = [26.51]*14 + [26.63] + [26.4]*20 + [26.29] + [26.4]*14
        oil_press1 = P('MGB Oil Press (1)', np.ma.array(p1))
        oil_press2 = P('MGB Oil Press (2)', np.ma.array(p2))

        mgb_oil_press = self.node_class()
        mgb_oil_press.derive(oil_press1, oil_press2)

        # array size should be double, 100
        self.assertEqual(mgb_oil_press.array.size, (oil_press1.array.size*2))
        self.assertEqual(mgb_oil_press.array.size, (oil_press2.array.size*2))
        # Frequency should be doubled 2Hz
        self.assertEqual(mgb_oil_press.frequency, (oil_press1.frequency*2))
        self.assertEqual(mgb_oil_press.frequency, (oil_press2.frequency*2))
        # Offset should remain the same as the parameter. 0.0
        self.assertEqual(mgb_oil_press.offset, oil_press1.offset)
        self.assertEqual(mgb_oil_press.offset, oil_press2.offset)
        # Element 7 will become 14 and values 26.63, 26.51 average to 26.57
        self.assertEqual(oil_press1.array[7], 26.63)
        self.assertEqual(oil_press2.array[7], 26.51)
        self.assertEqual(mgb_oil_press.array[14],
                         (oil_press1.array[7]+oil_press2.array[7])/2)
    def test_nose_down_insufficient_pitch(self):
        node = NoseDownAttitudeAdoption()
        pitch = np.concatenate(
            [np.ones(15) * 2,
             np.linspace(2, -6, num=15),
             np.ones(10) * -6])

        node.derive(P('Pitch', pitch), self.climbs, self.offshore)

        self.assertEqual(len(node), 1)
        self.assertEqual(
            node[0],
            Section('Nose Down Attitude Adoption', slice(15, 29, None), 15,
                    29))
Exemple #24
0
    def test_nose_down_basic(self):
        node = NoseDownAttitudeAdoption()
        pitch = np.concatenate(
            [np.ones(15) * 2,
             np.linspace(2, -11, num=15),
             np.ones(10) * -11])

        node.derive(P('Pitch', pitch), self.climbs)

        self.assertEqual(len(node), 1)
        self.assertEqual(
            node[0],
            Section('Nose Down Attitude Adoption', slice(15, 28, None), 15,
                    28))
    def derive(self,
               gnds=S('Grounded'),
               pitch=P('Pitch'),
               roll=P('Roll'),
               offshores=S('Offshore')):

        if offshores is not None:
            self.create_sections(
                slices_and(gnds.get_slices(edges=False),
                           offshores.get_slices(edges=False)))
            return

        decks = []
        for gnd in gnds:
            # The fourier transform for pitching motion...
            p = pitch.array[gnd.slice]
            if np.all(p.mask):
                continue
            n = float(
                len(p))  # Scaling the result to be independet of data length.
            fft_p = np.abs(np.fft.rfft(p - moving_average(p))) / n

            # similarly for roll
            r = roll.array[gnd.slice]
            if np.all(r.mask):
                continue
            fft_r = np.abs(np.fft.rfft(r - moving_average(r))) / n

            # What was the maximum harmonic seen?
            fft_max = np.ma.max(fft_p + fft_r)

            # Values of less than 0.1 were on the ground, and 0.34 on deck for the one case seen to date.
            if fft_max > 0.2:
                decks.append(gnd.slice)
        if decks:
            self.create_sections(decks)
Exemple #26
0
 def test_airborne_helicopter_overlap(self):
     gog = M(name='Gear On Ground',
             array=np.ma.array([1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], dtype=int),
             values_mapping={1:'Ground', 0:'Air'})
     agl = P(name='Altitude AGL',
             array=np.ma.array([0, 0, 0, 0, 5, 5, 5, 5, 5, 5, 2, 0], dtype=float),
             frequency=0.2)
     rtr = buildsection('Rotors Turning', 0, 40)
     node = Airborne()
     node.derive(agl, agl, gog, rtr)
     self.assertEqual(len(node), 2)
     self.assertEqual(node[0].slice.start, 3.2)
     self.assertEqual(node[0].slice.stop, 6)
     self.assertEqual(node[1].slice.start, 8)
     self.assertEqual(node[1].slice.stop, 10.5)
 def test_empty_year_no_seconds(self):
     # NB: 12's are the fallback_dt, 11's are the recorded time parameters
     dt = datetime(2012, 12, 12, 12, 12, 10, tzinfo=pytz.utc)
     # Test only without second and empty year
     hdf = MockHDF(
         {
             'Month':
             P('Month', np.ma.array([11, 11, 11, 11])),
             'Day':
             P('Day', np.ma.array([])),
             'Hour':
             P(
                 'Hour',
                 np.ma.array([11, 11, 11, 11],
                             mask=[True, False, False, False])),
             'Minute':
             P('Minute', np.ma.array([11, 11]), frequency=0.5),
         },
         duration=4)
     res, precise_timestamp = _calculate_start_datetime(hdf, dt, dt)
     # 9th second as the first sample (10th second) was masked
     self.assertEqual(res,
                      datetime(2012, 11, 12, 11, 11, 10, tzinfo=pytz.utc))
     self.assertFalse(precise_timestamp)
    def test_derive(self):
        t1 = [78.0]*14 + [78.5,78] + [78.5]*23 + [79.0]*5 + [79.5] + [79.0]*5
        t2 = [78.0]*13 + [78.5,78.0, 77.5] + [78.5]*20 + [79.0]*14

        oil_temp1 = P('MGB Oil Temp (1)', np.ma.array(t1))
        oil_temp2 = P('MGB Oil Temp (2)', np.ma.array(t2))

        mgb_oil_temp = self.node_class()
        mgb_oil_temp.derive(oil_temp1, oil_temp2)

        # array size should be double, 100
        self.assertEqual(mgb_oil_temp.array.size, (oil_temp1.array.size*2))
        self.assertEqual(mgb_oil_temp.array.size, (oil_temp2.array.size*2))
        # Frequency should be doubled 2Hz
        self.assertEqual(mgb_oil_temp.frequency, (oil_temp1.frequency*2))
        self.assertEqual(mgb_oil_temp.frequency, (oil_temp2.frequency*2))
        # Offset should remain the same as the parameter. 0.0
        self.assertEqual(mgb_oil_temp.offset, oil_temp1.offset)
        self.assertEqual(mgb_oil_temp.offset, oil_temp2.offset)
        # Element 44 will become 88 and values 79.5, 79 average to 79.25
        self.assertEqual(oil_temp1.array[44], 79.5)
        self.assertEqual(oil_temp2.array[44], 79)
        self.assertEqual(mgb_oil_temp.array[88],
                         (oil_temp1.array[44]+oil_temp2.array[44])/2)
Exemple #29
0
    def test_2_sources(self):
        long1 = P('Longitude (1)',
                  array=np.ma.concatenate(
                      (np.arange(160, 180), np.arange(-180, -170))),
                  frequency=0.5,
                  offset=0.25)
        long1.array[5:8] = np.ma.masked
        long2 = P('Longitude (2)',
                  array=np.ma.concatenate(
                      (np.arange(160.5, 180), np.arange(-179.5, -170))),
                  frequency=0.5,
                  offset=0.75)
        long2.array[5:8] = np.ma.masked
        longitude = Longitude()
        longitude.get_derived((long1, long2, None))

        expected = np.ma.concatenate(
            (np.arange(160.25, 180, 0.5), np.arange(-179.75, -170, 0.5)))
        expected[-1] = np.ma.masked

        np.testing.assert_array_equal(longitude.array, expected)
        np.testing.assert_array_equal(longitude.array.mask, expected.mask)
        assert longitude.offset == 0.5
        assert longitude.frequency == 1
Exemple #30
0
 def test_derive_basic(self):
     alt_agl = P(name='Altitude AGL', array=np.ma.concatenate((np.zeros(5), np.ones(30) * 10.0, np.zeros(5))))
     alt_agl.array[14] = 20.0
     alt_agl.array[17] = 60.0
     hovers = buildsections('Hover', [6, 8], [24,26])
     airs = buildsections('Airborne', [6, 26])
     t_hf = buildsections('Transition Hover To Flight', [12, 15])
     t_fh = buildsections('Transition Flight To Hover', [18, 20])
     node = HoverTaxi()
     node.derive(alt_agl, airs, hovers, t_hf, t_fh)
     self.assertEqual(len(node), 2)
     self.assertEqual(node[0].slice.start, 9)
     self.assertEqual(node[0].slice.stop, 12)
     self.assertEqual(node[1].slice.start, 21)
     self.assertEqual(node[1].slice.stop, 24)