01234567890123456789012345678901234567890123456789012345678901234567890123456789
44084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463 45374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562 45634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594 470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736 473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763 476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811 | <----SKIPPED LINES----> histograms_to_generate.append({'generate': 'bearing'}) if which_histograms in ['distance', 'all']: histograms_to_generate.append({'generate': 'distance', 'exhaustive': True}) if which_histograms in ['day_of_week', 'all']: histograms_to_generate.append({'generate': 'day_of_week'}) if which_histograms in ['day_of_month', 'all']: histograms_to_generate.append({'generate': 'day_of_month'}) if which_histograms in ['speed', 'all']: histograms_to_generate.append({'generate': 'speed', 'exhaustive': True}) if which_histograms in ['aircraft_length', 'all']: histograms_to_generate.append({'generate': 'aircraft_length', 'exhaustive': True}) if which_histograms in ['vert_rate', 'all']: histograms_to_generate.append({'generate': 'vert_rate', 'exhaustive': True}) histograms_generated = [] for histogram in histograms_to_generate: this_histogram = which_histograms if this_histogram == 'all': this_histogram = histogram['generate'] (key, sort, title, hours) = HistogramSettingsKeySortTitle( this_histogram, hours, flights) # if multiple histograms are getting generated, this might take a few seconds; # logging a heartbeat with each histogram ensures that monitoring.py does not # mistake this pause for a hang. if heartbeat: Heartbeat() CreateSingleHistogramChart( flights, key, sort, title, truncate=histogram.get('truncate', TRUNCATE), hours=hours, exhaustive=histogram.get('exhaustive', False)) filename = ( WEBSERVER_IMAGE_RELATIVE_FOLDER + # i.e.: images/ filename_prefix + # i.e.: histogram_ histogram['generate'] + # i.e.: destination '.' + filename_suffix) # i.e.: .png filepath = WEBSERVER_PATH + filename # i.e.: /var/www/html/ + filename matplotlib.pyplot.savefig(filepath) matplotlib.pyplot.close() histograms_generated.append((histogram['generate'], filename)) return histograms_generated def MessageboardHistograms( flights, which_histograms, how_much_history, <----SKIPPED LINES----> 'suppress_percent_sign': True, 'column_divider': '|', 'absolute': True}) if which_histograms in ['speed', 'all']: histograms_to_generate.append({ 'generate': 'speed', 'columns': 2}) if which_histograms in ['aircraft_length', 'all']: histograms_to_generate.append({ 'generate': 'aircraft_length', 'columns': 3}) if which_histograms in ['vert_rate', 'all']: histograms_to_generate.append({ 'generate': 'vert_rate', 'columns': 2}) for histogram in histograms_to_generate: this_histogram = which_histograms if this_histogram == 'all': this_histogram = histogram['generate'] (key, sort, title, hours) = HistogramSettingsKeySortTitle( this_histogram, hours, flights) # if multiple histograms are getting generated, this might take a few seconds; # logging a heartbeat with each histogram ensures that monitoring.py does not # mistake this pause for a hang. Heartbeat() histogram = MessageboardHistogram( flights, key, sort, title, screen_limit=screen_limit, columns=histogram.get('columns', 2), suppress_percent_sign=histogram.get('suppress_percent_sign', False), column_divider=histogram.get('column_divider', ' '), data_summary=data_summary, hours=hours, absolute=histogram.get('absolute', False)) messages.extend(histogram) messages = [(FLAG_MSG_HISTOGRAM, m) for m in messages] return messages def MessageboardHistogram( data, keyfunction, sort_type, title, screen_limit=1, columns=2, column_divider=' ', data_summary=False, hours=0, suppress_percent_sign=False, absolute=False): <----SKIPPED LINES----> # Otherwise, if it rounds to at least 0.1%, display i.e. '.5%' if values[index]/total*100 >= 0.95: value_string = '%2d' % round(values[index]/total*100) elif round(values[index]/total*1000)/10 >= 0.1: value_string = ('%.1f' % (round(values[index]/total*1000)/10))[1:] else: value_string = ' 0' key_value.append('%s %s%s' % ( str(keys[index])[:column_key_width].ljust(column_key_width), value_string, printed_percent_sign)) line = (column_divider.join(key_value)).upper() lines.append(line) split_flap_boards.append(lines) return split_flap_boards def TriggerHistograms(flights, histogram_settings): """Triggers the text-based or web-based histograms. Based on the histogram settings, determines whether to generate text or image histograms (or both). For image histograms, also generates empty images for the histograms not created so that broken image links are not displayed in the webpage. Args: flights: List of flight attribute dictionaries. histogram_settings: Dictionary of histogram parameters. Returns: List of histogram messages, if text-based histograms are selected; empty list otherwise. """ histogram_messages = [] if histogram_settings['type'] in ('messageboard', 'both'): histogram_messages = MessageboardHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], histogram_settings['histogram_max_screens'], histogram_settings.get('histogram_data_summary', False)) if histogram_settings['type'] in ('images', 'both'): # Since Google Chrome seems to ignore all instructions to not cache, we need # to make sure we do not reuse file names - hence the epoch_string - and then # we need to 1) update the histograms.html file with the correct file links, and # 2) delete the images that are now obsolete. epoch_string = '%d_' % round(time.time()) generated_histograms = ImageHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string) html_lines = ReadFile(HISTOGRAM_IMAGE_HTML).split('\n') replaced_images = [] for identifier, new_filename in generated_histograms: # for each histogram, find the html_line with the matching id # Example line: <img id="destination" src="images/histogram_destination.png"><p> identifier = '"%s"' % identifier # add quotations to make sure its complete n, line = None, None # addresses pylint complaint found = False for n, line in enumerate(html_lines): if identifier in line: found = True break found = False if found: start_char = line.find(WEBSERVER_IMAGE_RELATIVE_FOLDER) end_character = ( line.find(HISTOGRAM_IMAGE_SUFFIX, start_char) + len(HISTOGRAM_IMAGE_SUFFIX)) old_filename = line[start_char:end_character] print(old_filename, new_filename) line = line.replace(old_filename, new_filename) html_lines[n] = line replaced_images.append(line[start_char:end_character]) new_html = '\n'.join(html_lines) WriteFile(HISTOGRAM_IMAGE_HTML, new_html) # Remove those obsoleted files for f in replaced_images: RemoveFile(f) return histogram_messages def SaveFlightsByAltitudeDistanceCSV( flights, max_days=0, filename='flights_by_alt_dist.csv', precision=100): """Extracts hourly histogram into text file for a variety of altitudes and distances. Generates a csv with 26 columns: - col#1: altitude (in feet) - col#2: distance (in feet) - cols#3-26: hour of the day The first row is a header row; subsequent rows list the number of flights that have occurred in the last max_days with an altitude and min distance less than that identified in the first two columns. Each row increments elevation or altitude by precision feet, up to the max determined by the max altitude and max distance amongst all the flights. <----SKIPPED LINES----> |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
44084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463 45374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595 4708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786 47874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815 | <----SKIPPED LINES----> histograms_to_generate.append({'generate': 'bearing'}) if which_histograms in ['distance', 'all']: histograms_to_generate.append({'generate': 'distance', 'exhaustive': True}) if which_histograms in ['day_of_week', 'all']: histograms_to_generate.append({'generate': 'day_of_week'}) if which_histograms in ['day_of_month', 'all']: histograms_to_generate.append({'generate': 'day_of_month'}) if which_histograms in ['speed', 'all']: histograms_to_generate.append({'generate': 'speed', 'exhaustive': True}) if which_histograms in ['aircraft_length', 'all']: histograms_to_generate.append({'generate': 'aircraft_length', 'exhaustive': True}) if which_histograms in ['vert_rate', 'all']: histograms_to_generate.append({'generate': 'vert_rate', 'exhaustive': True}) histograms_generated = [] for histogram in histograms_to_generate: this_histogram = which_histograms if this_histogram == 'all': this_histogram = histogram['generate'] (key, sort, title, updated_hours) = HistogramSettingsKeySortTitle( this_histogram, hours, flights) # if multiple histograms are getting generated, this might take a few seconds; # logging a heartbeat with each histogram ensures that monitoring.py does not # mistake this pause for a hang. if heartbeat: Heartbeat() CreateSingleHistogramChart( flights, key, sort, title, truncate=histogram.get('truncate', TRUNCATE), hours=updated_hours, exhaustive=histogram.get('exhaustive', False)) filename = ( WEBSERVER_IMAGE_RELATIVE_FOLDER + # i.e.: images/ filename_prefix + # i.e.: histogram_ histogram['generate'] + # i.e.: destination '.' + filename_suffix) # i.e.: .png filepath = WEBSERVER_PATH + filename # i.e.: /var/www/html/ + filename matplotlib.pyplot.savefig(filepath) matplotlib.pyplot.close() histograms_generated.append((histogram['generate'], filename)) return histograms_generated def MessageboardHistograms( flights, which_histograms, how_much_history, <----SKIPPED LINES----> 'suppress_percent_sign': True, 'column_divider': '|', 'absolute': True}) if which_histograms in ['speed', 'all']: histograms_to_generate.append({ 'generate': 'speed', 'columns': 2}) if which_histograms in ['aircraft_length', 'all']: histograms_to_generate.append({ 'generate': 'aircraft_length', 'columns': 3}) if which_histograms in ['vert_rate', 'all']: histograms_to_generate.append({ 'generate': 'vert_rate', 'columns': 2}) for histogram in histograms_to_generate: this_histogram = which_histograms if this_histogram == 'all': this_histogram = histogram['generate'] (key, sort, title, updated_hours) = HistogramSettingsKeySortTitle( this_histogram, hours, flights) # if multiple histograms are getting generated, this might take a few seconds; # logging a heartbeat with each histogram ensures that monitoring.py does not # mistake this pause for a hang. if heartbeat: Heartbeat() histogram = MessageboardHistogram( flights, key, sort, title, screen_limit=screen_limit, columns=histogram.get('columns', 2), suppress_percent_sign=histogram.get('suppress_percent_sign', False), column_divider=histogram.get('column_divider', ' '), data_summary=data_summary, hours=updated_hours, absolute=histogram.get('absolute', False)) messages.extend(histogram) messages = [(FLAG_MSG_HISTOGRAM, m) for m in messages] return messages def MessageboardHistogram( data, keyfunction, sort_type, title, screen_limit=1, columns=2, column_divider=' ', data_summary=False, hours=0, suppress_percent_sign=False, absolute=False): <----SKIPPED LINES----> # Otherwise, if it rounds to at least 0.1%, display i.e. '.5%' if values[index]/total*100 >= 0.95: value_string = '%2d' % round(values[index]/total*100) elif round(values[index]/total*1000)/10 >= 0.1: value_string = ('%.1f' % (round(values[index]/total*1000)/10))[1:] else: value_string = ' 0' key_value.append('%s %s%s' % ( str(keys[index])[:column_key_width].ljust(column_key_width), value_string, printed_percent_sign)) line = (column_divider.join(key_value)).upper() lines.append(line) split_flap_boards.append(lines) return split_flap_boards def TriggerHistograms(flights, histogram_settings, heartbeat=True): """Triggers the text-based or web-based histograms. Based on the histogram settings, determines whether to generate text or image histograms (or both). For image histograms, also generates empty images for the histograms not created so that broken image links are not displayed in the webpage. Args: flights: List of flight attribute dictionaries. histogram_settings: Dictionary of histogram parameters. heartbeat: boolean indicating whether we should log heartbeats between each histogram to make sure monitoring does not mistake this slow procedure for being hung; this should be set to false if this is called from outside of messageboard.main. Returns: List of histogram messages, if text-based histograms are selected; empty list otherwise. """ histogram_messages = [] if histogram_settings['type'] in ('messageboard', 'both'): histogram_messages = MessageboardHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], histogram_settings['histogram_max_screens'], histogram_settings.get('histogram_data_summary', False)) if histogram_settings['type'] in ('images', 'both'): # Since Google Chrome seems to ignore all instructions to not cache, we need # to make sure we do not reuse file names - hence the epoch_string - and then # we need to 1) update the histograms.html file with the correct file links, and # 2) delete the images that are now obsolete. epoch_string = '%d_' % round(time.time()) generated_histograms = ImageHistograms( flights, histogram_settings['histogram'], histogram_settings['histogram_history'], filename_prefix=HISTOGRAM_IMAGE_PREFIX + epoch_string, heartbeat=heartbeat) html_lines = ReadFile(HISTOGRAM_IMAGE_HTML).split('\n') replaced_images = [] for identifier, new_filename in generated_histograms: # for each histogram, find the html_line with the matching id # Example line: <img id="destination" src="images/histogram_destination.png"><p> identifier = '"%s"' % identifier # add quotations to make sure its complete n, line = None, None # addresses pylint complaint found = False for n, line in enumerate(html_lines): if identifier in line: found = True break found = False if found: start_char = line.find(WEBSERVER_IMAGE_RELATIVE_FOLDER) end_character = ( line.find(HISTOGRAM_IMAGE_SUFFIX, start_char) + len(HISTOGRAM_IMAGE_SUFFIX)) old_filename = line[start_char:end_character] line = line.replace(old_filename, new_filename) html_lines[n] = line replaced_images.append(old_filename) new_html = '\n'.join(html_lines) WriteFile(HISTOGRAM_IMAGE_HTML, new_html) # Remove those obsoleted files for f in replaced_images: RemoveFile(WEBSERVER_PATH + f) return histogram_messages def SaveFlightsByAltitudeDistanceCSV( flights, max_days=0, filename='flights_by_alt_dist.csv', precision=100): """Extracts hourly histogram into text file for a variety of altitudes and distances. Generates a csv with 26 columns: - col#1: altitude (in feet) - col#2: distance (in feet) - cols#3-26: hour of the day The first row is a header row; subsequent rows list the number of flights that have occurred in the last max_days with an altitude and min distance less than that identified in the first two columns. Each row increments elevation or altitude by precision feet, up to the max determined by the max altitude and max distance amongst all the flights. <----SKIPPED LINES----> |