def listed(self): return [datetime_string(self.from_epoch), datetime_string(self.until_epoch), duration_string(self.duration), self.config, '{:d}'.format(sum(self.runway_list)), '{:d}'.format(self.runway_list[0]), '{:d}'.format(self.runway_list[1]), '{:d}'.format(self.runway_list[2]), '{:d}'.format(self.runway_list[3]), '{:d}'.format(self.runway_list[4]), '{:d}'.format(self.runway_list[5]), '{:d}'.format(self.runway_list[6]), '{:d}'.format(self.runway_list[7]), '{:d}'.format(self.missed), duration_string(self.slack)]
def write(self, path, name): log_file_name = '%s\\%s_flightsLog.txt' % (path, name) prev_hour = 24 with open(log_file_name, 'w') as guess_log_file: guess_log_file.write("call \ticao \ttype\topTimestamp\topTimestampDate \tguess_count\tV(fpm)\tGS(kts)\tinclin(deg)\t"\ "track(deg)\trunway\tchange_comment\tmiss_comment\top_comment\tSID/STAR\twaypoints\n") for operation in self.final_op_list: date = datetime_string(operation.get_op_timestamp()) hour = time.gmtime(operation.get_op_timestamp()).tm_hour if hour - prev_hour != 0: guess_log_file.write('\n') try: guess_log_file.write('%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' % ('{:<8}'.format(operation.flight.callsign.call), '{:6}'.format(operation.flight.aircraft.icao), '{:4}'.format(operation.flight.aircraft.model), ('{:.0f}'.format(operation.get_op_timestamp()) if operation.get_op_timestamp() else 'None'), date, '{:1}'.format(operation.guess_count),'{:+05.0f}'.format(operation.get_mean_vrate()), '{:05.1f}'.format(operation.get_mean_gs()), '{:+04.1f}'.format(operation.get_mean_inclin()), '{:03.0f}'.format(operation.get_mean_track()), operation.op_runway, operation.zone_change_comment, operation.get_miss_comment(), operation.op_comment, operation.flight.sid_star, ', '.join(operation.flight.waypoints))) except Exception: print 'Error in logging!!' guess_log_file.write('Error with logging ' + '{:6}'.format(operation.flight.aircraft.icao) + '\n') prev_hour = hour
def get_op_rows(self): return [ self.flight.callsign.call, self.flight.aircraft.icao, self.flight.aircraft.model, (self.flight.aircraft.operator if len(self.flight.aircraft.operator) <= 8 else self.flight.aircraft.operator[0:8]), ('{:.0f}'.format(self.get_op_timestamp()) if self.get_op_timestamp() else 'None'), datetime_string(self.runway_ths_timestamp), '{:1}'.format( self.guess_count), '{:4.0f}'.format(self.get_mean_vrate()), '{:3.0f}'.format(self.get_mean_gs()), '{:.1f}'.format(self.get_mean_inclin()), '{:3.0f}'.format(self.get_mean_track()), self.op_runway, self.LorT, self.zone_change_comment, self.get_miss_comment(), self.op_comment, self.flight.sid_star ]
def __init__(self, operation, epoch, missed_time): self.operation = operation self.operation.validate_operation(epoch) self.timestamp = missed_time if missed_time else epoch self.runway = self.operation.op_runway self.position = self.operation.flight.aircraft.get_position_delimited( self.timestamp, 0, 20) self.alt = self.position.alt - self.operation.flight.aircraft.get_current_diff( epoch) self.dist_to_ths = None for runway_ths_key in runway_ths_dict.keys(): if self.runway in runway_ths_key: self.dist_to_ths = great_circle( (self.position.lon, self.position.lat), (runway_ths_dict[runway_ths_key].x, runway_ths_dict[runway_ths_key].y)).nautical break self.miss_comment = '(missed @ ' + datetime_string(self.timestamp) + ', ' + '{:1.0f}'.format(self.alt / 0.3048) + ' ft, ' +\ '{:1.2f}'.format(self.dist_to_ths) + ' nm from ths) '
def run(self, key_timestamp, infile, icao_filter): # Open database filepath = infile.name try: database = open(filepath, 'r') except Exception: raise NameError('No valid input path') print_time = True prev_epoch = 0 for i, current_line in enumerate(database): self.line_count += 1 if i == 0: # skip header continue if self.dead: break # wait while paused (triggered in GUI) while self.dataExtractor.paused: time.sleep(0.1) data = current_line.split('\t') self.epoch_now = float(data[0]) icao0 = str(data[2]) # filter time start and end if self.is_delimited: if self.analyseStart and self.epoch_now <= self.analyseStart: continue if self.analyseEnd and self.epoch_now > self.analyseEnd: break if self.epoch_now < prev_epoch: # database going backwards, could be that raw data was already corrupt continue prev_epoch = self.epoch_now # print hour to console and update clock and progress bar in GUI if self.epoch_now % 3600 == 0: if print_time: print datetime_string(self.epoch_now) + ' ...' print_time = False with self.lock2: self.dataExtractor.dispTime(datetime_string(self.epoch_now)) # progress bar TODO should be queued for main thread to process or might hang self.dataExtractor.core.controller.update_progressbar(100 * self.line_count / self.dataExtractor.num_lines) else: print_time = True # icao filter. For now only editable in core if icao_filter is not None and icao0 != icao_filter: continue # get the icao_dict where aircraft model is and get the current aircraft with self.lock1: icao_dict = self.dataExtractor.core.files_data_dict[key_timestamp] if icao0 not in icao_dict.keys(): icao_dict[icao0] = Aircraft(icao0, self.epoch_now) current_aircraft = icao_dict[icao0] current_aircraft.last_seen = self.epoch_now # check if current line has call information call = str(data[3]).strip() if call: # call found in or outside airport. # record call+icao0 if seen more than once to avoid corrupt callsigns () if call+icao0 not in self.dataExtractor.call_icao_list: self.dataExtractor.call_icao_list.append(call+icao0) else: current_aircraft.set_call(call, self.epoch_now) # already fixes unknown call to op_timestamp # check if current line has velocity information and save it to the aircraft velocity buffer # TODO this is not efficient since we store for all ac in or out of TMA. Better only for those known to be within TMA if str(data[8]) and str(data[9]) and str(data[10]): # vrate, gs, ttrack current_aircraft.set_new_vel(self.epoch_now, float(data[8]), float(data[9]), float(data[10])) # check if current line has kollsman value if data[16]: # kollsman found current_aircraft.set_kolls(float(data[16]), self.epoch_now) # check if current line has position and altitude information pos = None FL = None alt_uncorrected = None if data[4] and data[5] and (data[6] or data[7]): # VERY IMPORTANT! (lon, lat) as in (x, y) coordinates, everywhere in the program pos = Point(float(data[5]), float(data[4])) if data[6]: FL = float(data[6]) alt_uncorrected = FL * 30.48 # m, no QNH correction elif data[7]: # ground boolean alt_uncorrected = Metrics.airport_altitude # ground position. Will be corrected but doesn't really matter FL = 20 # only store previous points if we are interested in waypoints if self.evaluate_waypoints: current_aircraft.set_new_pos(self.epoch_now, pos.x, pos.y, alt_uncorrected) # get a new line if no position information (we already checked for any other kind of valuable info) else: continue # detect waypoints. Efficient manner by making lines between periodical points # TODO make more efficient by categorizing waypoints sections if self.evaluate_waypoints: current_flight = current_aircraft.get_current_flight() # will be no_call flight if new line = None if self.epoch_now - current_aircraft.last_waypoint_check >= Metrics.time_between_waypoint: # make line between current position and time_between_waypoint position, or up to 10 minutes prev_tbw_pos = current_aircraft.get_position_delimited(self.epoch_now, Metrics.time_between_waypoint, 360) if prev_tbw_pos: line = LineString([pos, (prev_tbw_pos.lon, prev_tbw_pos.lat)]) if line: for waypoint in waypoints_dict.keys(): if line.crosses(waypoints_dict[waypoint]): current_flight.set_waypoint(waypoint) current_aircraft.last_waypoint_check = self.epoch_now # evaluate further only if below FL 130 and within TMA if pos and FL and alt_uncorrected and FL < 130 and airport_poly.contains(pos): # store prev positions only inside TMA if not interested in waypoints if not self.evaluate_waypoints: current_flight = current_aircraft.get_current_flight() # will be no_call flight if new current_aircraft.set_new_pos(self.epoch_now, pos.x, pos.y, alt_uncorrected) NorS = None EorW = None poly = None prev_vel = current_aircraft.get_velocity_delimited(self.epoch_now, 0, 20) if prev_vel: vrate = prev_vel.vrate # fpm gs = prev_vel.gs # knots if gs == 0: continue # TODO: what? ttrack = prev_vel.ttrack # [0 , 360] ttrack = ttrack % 360 inclin = np.rad2deg(np.arctan(vrate / gs * 0.0098748)) # | A1 - | B1 # | A0 - | B0 # ##### # \ C0 - \ D0 # \ C1 - \ D1 if poly_SE.contains(pos): # ZONE 4, will only be useful for approaches current_flight.set_guess(self.epoch_now, 'S', 'E', ttrack, vrate, inclin, gs, 4) elif poly_SW.contains(pos): current_flight.set_guess(self.epoch_now, 'S', 'W', ttrack, vrate, inclin, gs, 4) elif poly_NE.contains(pos): current_flight.set_guess(self.epoch_now, 'N', 'E', ttrack, vrate, inclin, gs, 4) elif poly_NW.contains(pos): current_flight.set_guess(self.epoch_now, 'N', 'W', ttrack, vrate, inclin, gs, 4) if alt_uncorrected <= Metrics.guess_alt_ths + Metrics.airport_altitude: if poly_north.contains(pos): NorS = 'N' if poly_AA.contains(pos): EorW = 'W' if poly_A0.contains(pos): poly = 'A0' elif poly_A1.contains(pos): poly = 'A1' elif poly_A2.contains(pos): poly = 'A2' elif poly_A3.contains(pos): poly = 'A3' elif poly_BB.contains(pos): EorW = 'E' if poly_B0.contains(pos): poly = 'B0' elif poly_B1.contains(pos): poly = 'B1' elif poly_B2.contains(pos): poly = 'B2' elif poly_B3.contains(pos): poly = 'B3' elif poly_south.contains(pos): NorS = 'S' if poly_CC.contains(pos): EorW = 'W' if poly_C0.contains(pos): poly = 'C0' elif poly_C1.contains(pos): poly = 'C1' elif poly_C2.contains(pos): poly = 'C2' elif poly_C3.contains(pos): poly = 'C3' elif poly_DD.contains(pos): EorW = 'E' if poly_D0.contains(pos): poly = 'D0' elif poly_D1.contains(pos): poly = 'D1' elif poly_D2.contains(pos): poly = 'D2' elif poly_D3.contains(pos): poly = 'D3' if poly: zone = int(poly[1]) current_flight.set_guess(self.epoch_now, NorS, EorW, ttrack, vrate, inclin, gs, zone) # here we set the alt_ths_operation timestamp current_diff = current_aircraft.get_current_diff(self.epoch_now) alt_corr = alt_uncorrected - current_diff prev10_30_pos = current_aircraft.get_position_delimited(self.epoch_now, 10, 30) if prev10_30_pos: # can happen there was no prev data prev_alt_corr = prev10_30_pos.alt - current_diff prev_epoch = prev10_30_pos.epoch if current_flight.operations: current_flight.operations[-1].set_alt_ths_timestamp( self.epoch_now, prev_epoch, alt_corr, prev_alt_corr, NorS) database.close()