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')): print 'in Alt Exceed' 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)
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))
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 test_dual_ap(self): # Two result in just "Engaged" state still ase1 = M(array=np.ma.array(data=[0, 0, 1, 1, 0, 0]), values_mapping={ 1: 'Engaged', 0: '-' }, name='AP (1) Engaged') ase2 = M(array=np.ma.array(data=[0, 0, 0, 1, 1, 0]), values_mapping={ 1: 'Engaged', 0: '-' }, name='AP (2) Engaged') ase3 = None node = self.node_class() node.derive(ase1, ase2, ase3) expected = M(array=np.ma.array(data=[0, 0, 1, 1, 1, 0]), values_mapping={ 0: '-', 1: 'Engaged' }, name='AP Engaged', frequency=1, offset=0.1) np.testing.assert_array_equal(expected.array, node.array)
def derive(self, gl=M('Gear (L) Position'), gn=M('Gear (N) Position'), gr=M('Gear (R) Position'), gc=M('Gear (C) Position')): up_state = vstack_params_where_state( (gl, 'Up'), (gn, 'Up'), (gr, 'Up'), (gc, 'Up'), ).all(axis=0) down_state = vstack_params_where_state( (gl, 'Down'), (gn, 'Down'), (gr, 'Down'), (gc, 'Down'), ).all(axis=0) transit_state = vstack_params_where_state( (gl, 'In Transit'), (gn, 'In Transit'), (gr, 'In Transit'), (gc, 'In Transit'), ).any(axis=0) param = first_valid_parameter(gl, gn, gr, gc) self.array = np_ma_masked_zeros_like(param.array) self.array[repair_mask(up_state, repair_duration=None)] = 'Up' self.array[repair_mask(down_state, repair_duration=None)] = 'Down' self.array[repair_mask(transit_state, repair_duration=None)] = 'In Transit' self.array = nearest_neighbour_mask_repair(self.array)
def derive(self, any_running=M('Eng (*) Any Running'), eng_oei=M('One Engine Inoperative'), autorotation=S('Autorotation')): aeo = np.ma.logical_not(eng_oei.array == 'OEI') for section in autorotation: aeo[section.slice] = False self.array = np.ma.logical_and(any_running.array == 'Running', aeo)
def derive(self, gl=M('Gear (L) On Ground'), gr=M('Gear (R) On Ground'), vert_spd=P('Vertical Speed'), torque=P('Eng (*) Torque Avg'), ac_series=A('Series'), collective=P('Collective')): pass
def derive(self, ian_final=P('IAN Final Approach Course'), alt_aal=P('Altitude AAL For Flight Phases'), apps=S('Approach Information'), ils_freq=P('ILS Frequency'), app_src_capt=M('Displayed App Source (Capt)'), app_src_fo=M('Displayed App Source (FO)')): pass
def derive(self, baro_cpt=P('Baro Correction (Capt)'), baro_fo=P('Baro Correction (FO)'), baro_sel=M('Baro Setting Selection'), baro_sel_cpt=M('Baro Setting Selection (Capt)'), baro_sel_fo=M('Baro Setting Selection (FO)'), baro_cor_isis=P('Baro Correction (ISIS)'), fasts=S('Fast')): pass
def setUp(self): self.node_class = RotorBrakeEngaged self.values_mapping = {1: 'Engaged', 0: '-'} self.brk1 = M('Rotor Brake (1) Engaged', np.ma.array(data=[0, 0, 1, 1, 0, 0]), values_mapping=self.values_mapping) self.brk2 = M('Rotor Brake (2) Engaged', np.ma.array(data=[0, 0, 0, 1, 1, 0]), values_mapping=self.values_mapping)
def derive(self, gear_L=M('Gear (L) Up In Transit'), gear_N=M('Gear (N) Up In Transit'), gear_R=M('Gear (R) Up In Transit'), gear_C=M('Gear (C) Up In Transit')): combine_params = [(x, 'Retracting') for x in (gear_L, gear_R, gear_N, gear_C) if x] if len(combine_params): self.array = vstack_params_where_state(*combine_params).any(axis=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, eng_1_oei=M('Eng (1) One Engine Inoperative'), eng_2_oei=M('Eng (2) One Engine Inoperative'), autorotation=S('Autorotation')): oei = vstack_params_where_state((eng_1_oei, 'Active'), (eng_2_oei, 'Active')).any(axis=0) for section in autorotation: oei[section.slice] = False self.array = oei
def derive(self, brk1=M('Rotor Brake (1) Engaged'), brk2=M('Rotor Brake (2) Engaged')): stacked = vstack_params_where_state( (brk1, 'Engaged'), (brk2, 'Engaged'), ) self.array = stacked.any(axis=0) self.array.mask = stacked.mask.any(axis=0)
def derive( self, tcas_ops=S('TCAS Operational'), tcas_ta1=M('TCAS TA'), tcas_ta2=M('TCAS All Threat Traffic'), tcas_ta3=M('TCAS Traffic Alert'), tcas_ta4=M('TCAS TA (1)'), tcas_ras=S('TCAS Resolution Advisory'), ): pass
def derive(self, accel_lon=P('Acceleration Longitudinal Offset Removed'), eng_running=M('Eng (*) All Running'), groundeds=S('Grounded'), eng_n1=P('Eng (*) N1 Max'), toff_acc=KTI('Takeoff Acceleration Start'), toff_rwy_hdg=S('Takeoff Runway Heading'), seg_type=A('Segment Type'), toga=M('Takeoff And Go Around')): pass
def derive(self, ase1=M('ASE (1) Engaged'), ase2=M('ASE (2) Engaged'), ase3=M('ASE (3) Engaged')): stacked = vstack_params_where_state( (ase1, 'Engaged'), (ase2, 'Engaged'), (ase3, 'Engaged'), ) self.array = stacked.sum(axis=0) self.offset = offset_select('mean', [ase1, ase2, ase3])
def derive(self, gl=M('Gear (L) In Transit'), gn=M('Gear (N) In Transit'), gr=M('Gear (R) In Transit'), gc=M('Gear (C) In Transit')): # Join all available gear parameters and use whichever are available. self.array = vstack_params_where_state( (gl, 'In Transit'), (gn, 'In Transit'), (gr, 'In Transit'), (gc, 'In Transit'), ).any(axis=0)
def test_derive(self): # combine individal (L/R/C/N) params left = M('Gear (L) Up', array=np.ma.array([0] * 15 + [1] * 30 + [0] * 15), values_mapping=self.values_mapping) right = M('Gear (R) Up', array=np.ma.array([0] * 14 + [1] * 31 + [0] * 15), values_mapping=self.values_mapping) node = self.node_class() node.derive(left, None, right, None) np.testing.assert_array_equal(node.array, self.expected.array) self.assertEqual(node.values_mapping, self.values_mapping)
def test_derive__combine(self): # combine individal (L/R/C/N) params left = M('Gear (L) Down In Transit', array=np.ma.array([0] * 46 + [1] * 9 + [0] * 5), values_mapping=self.values_mapping) right = M('Gear (R) Down In Transit', array=np.ma.array([0] * 45 + [1] * 9 + [0] * 6), values_mapping=self.values_mapping) node = self.node_class() node.derive(left, None, right, None) np.testing.assert_array_equal(node.array, self.expected.array) self.assertEqual(node.values_mapping, self.values_mapping)
def test_derive__gear_position(self): gl = M('Gear (L) Position', array=np.ma.array([3] * 5 + [2] * 10 + [1] * 30 + [2] * 10 + [3] * 5), values_mapping=self.values_mapping) gr = M('Gear (R) Position', array=np.ma.array([3] * 6 + [2] * 9 + [1] * 30 + [2] * 9 + [3] * 6), values_mapping=self.values_mapping) node = self.node_class() node.derive(gl, None, gr, None) np.testing.assert_array_equal(node.array, self.expected.array) self.assertEqual(node.values_mapping, self.values_mapping)
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')): pass
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'), afr_takeoff_pilot=A('AFR Takeoff Pilot')): pass
def derive(self, eng2_np=P('Eng (2) Np'), eng1_n1=P('Eng (1) N1'), eng2_n1=P('Eng (2) N1'), groundeds=S('Grounded'), prop_brake=M('Propeller Brake')): pass
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)
def derive(self, alt_rad=P('Altitude Radio'), alt_agl=P('Altitude AGL'), gog=M('Gear On Ground'), rtr=S('Rotors Turning')): # When was the gear in the air? gear_off_grounds = runs_of_ones(gog.array == 'Air') if alt_rad and alt_agl and rtr: # We can do a full analysis. # First, confirm that the rotors were turning at this time: gear_off_grounds = slices_and(gear_off_grounds, rtr.get_slices()) # When did the radio altimeters indicate airborne? airs = slices_remove_small_gaps( np.ma.clump_unmasked( np.ma.masked_less_equal(alt_agl.array, 1.0)), time_limit=AIRBORNE_THRESHOLD_TIME_RW, hz=alt_agl.frequency) # Both is a reliable indication of being in the air. for air in airs: for goff in gear_off_grounds: # Providing they relate to each other :o) if slices_overlap(air, goff): start_index = max(air.start, goff.start) end_index = min(air.stop, goff.stop) better_begin = index_at_value( alt_rad.array, 1.0, _slice=slice( max(start_index - 5 * alt_rad.frequency, 0), start_index + 5 * alt_rad.frequency)) if better_begin: begin = better_begin else: begin = start_index better_end = index_at_value( alt_rad.array, 1.0, _slice=slice( max(end_index + 5 * alt_rad.frequency, 0), end_index - 5 * alt_rad.frequency, -1)) if better_end: end = better_end else: end = end_index duration = end - begin if (duration / alt_rad.hz) > AIRBORNE_THRESHOLD_TIME_RW: self.create_phase(slice(begin, end)) else: # During data validation we can select just sensible flights; # short hops make parameter validation tricky! self.create_phases( slices_remove_small_gaps( slices_remove_small_slices(gear_off_grounds, time_limit=30)))
def hdf_getitem(self, key, **kwargs): if key == 'Airspeed': return Parameter('Airspeed', array=airspeed_array, frequency=airspeed_frequency) elif key == 'Frame Counter': return Parameter('Frame Counter', array=dfc_array, frequency=0.25) elif key == 'Heading': # TODO: Give heading specific data. return Parameter('Heading', array=heading_array, frequency=heading_frequency) elif key == 'Eng (1) N1' and eng_array is not None: return Parameter('Eng (1) N1', array=eng_array, frequency=eng_frequency) elif key == 'Segment Split': seg_split = M('Segment Split', array=np.ma.zeros(len(heading_array), dtype=int), frequency=heading_frequency, values_mapping={ 0: "-", 1: "Split" }) seg_split.array[390 / heading_frequency] = "Split" return seg_split else: raise KeyError
def test_derive(self): '''[[[State]]] 0 = SL = 0 (Automatic) 1 = SL = 1 (Standby) 2 = SL = 2 (TA Only) 3 = SL = 3 ... ''' values_mapping = { 0: '0', 1: '1', } tcas_sens = M('TCAS Sensitivity Level', array=np.ma.array([0, 0, 1, 0, 0]), values_mapping=values_mapping, frequency=.25, offset=0.) start = KTI(items=[ KeyTimeInstance(index=2, name='TCAS RA Start'), ]) node = tcas.TCASSensitivityAtTCASRAStart() node.derive(tcas_sens, start) expected = [ KeyPointValue(index=2, value=1, name='TCAS RA Start Pilot Sensitivity Mode'), ] self.assertEqual(expected, node)
def derive(self, alt_aal=P('Altitude AAL'), alt_agl=P('Altitude AGL'), ac_type=A('Aircraft Type'), app=S('Approach And Landing'), hdg=P('Heading Continuous'), lat=P('Latitude Prepared'), lon=P('Longitude Prepared'), ils_loc=P('ILS Localizer'), ils_gs=S('ILS Glideslope'), ils_freq=P('ILS Frequency'), land_afr_apt=A('AFR Landing Airport'), land_afr_rwy=A('AFR Landing Runway'), lat_land=KPV('Latitude At Touchdown'), lon_land=KPV('Longitude At Touchdown'), precision=A('Precise Positioning'), fast=S('Fast'), u=P('Airspeed'), gspd=P('Groundspeed'), height_from_rig=P('Altitude ADH'), hdot=P('Vertical Speed'), roll=P('Roll'), heading=P('Heading'), distance_land=P('Distance To Landing'), tdwns=KTI('Touchdown'), offshore=M('Offshore'), takeoff=S('Takeoff')): pass
def test_derive(self): #based on FDS TestTCASRAWarningDuration() values_mapping = { 0: 'A', 1: 'B', 2: 'Drop Track', 3: 'Altitude Lost', 4: 'Up Advisory Corrective', 5: 'Down Advisory Corrective', 6: 'G', } tcas = M( 'TCAS Combined Control', array=np.ma.array([0, 1, 2, 3, 4, 5, 4, 5, 6]), values_mapping=values_mapping, frequency=1, offset=0, ) # _,_, a,a,a,a,a,a,_ # u,d,u,d # 3.5 4.5 5.5 airborne = buildsection('Airborne', 2, 7) node = TCASRAStart() node.derive( tcas, airborne) # create_ktis_on_state_change() offsets times by 0.5 expected = [ KeyTimeInstance(index=3.5, name='TCAS RA Start'), ] self.assertEqual(expected, node)