def derive(self, alt_agl=P('Altitude AGL'), airs=S('Airborne'), hovers=S('Hover'), trans_hfs=S('Transition Hover To Flight'), trans_fhs=S('Transition Flight To Hover')): air_taxis = [] taxis = [] if airs: for air in airs: lows = slices_below(alt_agl.array[air.slice], HOVER_TAXI_HEIGHT)[1] taxis = shift_slices(lows, air.slice.start) # Remove periods identified already as transitions. if taxis: for taxi in slices_and_not(taxis, [h.slice for h in hovers]): if trans_fhs: for trans_fh in trans_fhs: if slices_overlap(taxi, trans_fh.slice): taxi = slice(trans_fh.slice.stop, taxi.stop) if trans_hfs: for trans_hf in trans_hfs: if slices_overlap(taxi, trans_hf.slice): taxi = slice(taxi.start, trans_hf.slice.start) air_taxis.extend([taxi]) self.create_phases(air_taxis)
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 derive(self, alt_agl=P('Altitude AGL'), airs=S('Airborne'), gspd=P('Groundspeed'), trans_hfs=S('Transition Hover To Flight'), trans_fhs=S('Transition Flight To Hover')): low_flights = [] hovers = [] for air in airs: lows = slices_below(alt_agl.array[air.slice], HOVER_HEIGHT_LIMIT)[1] for low in lows: if np.ma.min(alt_agl.array[shift_slice( low, air.slice.start)]) <= HOVER_MIN_HEIGHT: low_flights.extend([shift_slice(low, air.slice.start)]) repaired_gspd = repair_mask(gspd.array, frequency=gspd.hz, repair_duration=8, method='fill_start') slows = slices_below(repaired_gspd, HOVER_GROUNDSPEED_LIMIT)[1] low_flights = slices_and(low_flights, slows) # Remove periods identified already as transitions. for low_flight in low_flights: if trans_fhs: for trans_fh in trans_fhs: if slices_overlap(low_flight, trans_fh.slice): low_flight = slice(trans_fh.slice.stop, low_flight.stop) if trans_hfs: for trans_hf in trans_hfs: if slices_overlap(low_flight, trans_hf.slice): low_flight = slice(low_flight.start, trans_hf.slice.start) hovers.extend([low_flight]) # Exclude transition periods and trivial periods of operation. self.create_phases( filter_slices_duration(hovers, HOVER_MIN_DURATION, frequency=alt_agl.frequency))
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 derive(self, alt_agl=P('Altitude AGL'), airs=S('Airborne'), gspd=P('Groundspeed'), trans_hfs=S('Transition Hover To Flight'), trans_fhs=S('Transition Flight To Hover')): low_flights = [] hovers = [] for air in airs: lows = slices_below(alt_agl.array[air.slice], HOVER_HEIGHT_LIMIT)[1] for low in lows: if np.ma.min(alt_agl.array[shift_slice(low, air.slice.start)]) <= HOVER_MIN_HEIGHT: low_flights.extend([shift_slice(low, air.slice.start)]) repaired_gspd = repair_mask(gspd.array, frequency=gspd.hz, repair_duration=8, method='fill_start') slows = slices_below(repaired_gspd, HOVER_GROUNDSPEED_LIMIT)[1] low_flights = slices_and(low_flights, slows) # Remove periods identified already as transitions. for low_flight in low_flights: if trans_fhs: for trans_fh in trans_fhs: if slices_overlap(low_flight, trans_fh.slice): low_flight = slice(trans_fh.slice.stop, low_flight.stop) if trans_hfs: for trans_hf in trans_hfs: if slices_overlap(low_flight, trans_hf.slice): low_flight = slice(low_flight.start, trans_hf.slice.start) hovers.extend([low_flight]) # Exclude transition periods and trivial periods of operation. self.create_phases(filter_slices_duration(hovers, HOVER_MIN_DURATION, frequency=alt_agl.frequency))