From 9bcf8ffb8c1d788d47472372acbc15eff44d63c1 Mon Sep 17 00:00:00 2001 From: tkoleary Date: Fri, 26 Sep 2025 11:04:24 -0500 Subject: [PATCH 01/17] translates delete.initial.batchin.scenarios to python --- .../delete.initial.batchin.scenarios | 47 ---------------- .../delete_initial_batchin_scenarios.py | 53 +++++++++++++++++++ 2 files changed, 53 insertions(+), 47 deletions(-) delete mode 100644 Database/useful_macros/delete.initial.batchin.scenarios create mode 100644 Database/useful_macros/delete_initial_batchin_scenarios.py diff --git a/Database/useful_macros/delete.initial.batchin.scenarios b/Database/useful_macros/delete.initial.batchin.scenarios deleted file mode 100644 index 07f53cd..0000000 --- a/Database/useful_macros/delete.initial.batchin.scenarios +++ /dev/null @@ -1,47 +0,0 @@ -~/ delete.initial.batchin.scenarios -~/ Craig Heither, 3/31/09 -~/ Deletes scenarios -~/ submit with 3-digit scenario number -~/ -~# Heither, modified 07-26-2016: delete build_turn.rpt -~# ------------------------------------------------------------- -~x=%0% -~+;~?!x=1;~$>error -~/ -~! if exist report\build_turn.rpt (del report\build_turn.rpt) -~/ -~/ DELETE SCENARIOS xxx0,xxx00-xxx08 IF THEY EXIST -~/ -~r1=%1% -~r1*10 -1.22 -2 -%r1% -~?e -~+;~/Scenario %r1% does not exist; ;q;~$>next1 -y -q -~:next1 -~/ -~r1*10 -~/ -~:loop -1.22 -2 -%r1% -~?e -~+;~/Scenario %r1% does not exist; ;q;~$>next2 -y -q -~:next2 -~r1+1 -~+;~?r1<%1%09;~$loop -~/ END LOOP -~/ -~/ -~$>end -~:error -~/ SUBMIT WITH PROJECT DIRECTORY NAME!!!!!!! -~/ -~:end -~/end of macro diff --git a/Database/useful_macros/delete_initial_batchin_scenarios.py b/Database/useful_macros/delete_initial_batchin_scenarios.py new file mode 100644 index 0000000..713719f --- /dev/null +++ b/Database/useful_macros/delete_initial_batchin_scenarios.py @@ -0,0 +1,53 @@ +''' +delete_initial_batchin_scenarios.py + +author: Craig Heither, 3/31/09 + - deletes scenarios + - submit with 3-digit scenario number + - modified 7/26/2016: also delete build.turn.rpt +translated: Tim O'Leary, 9/26/2025 to Python 3 +''' + +import os +import sys +from pathlib import Path +import yaml + +proj_dir = Path(__file__).resolve().parents[2] +sys.path.append(str(proj_dir.joinpath('Scripts'))) +from tbmtools import project as tbm + +print('delete initial batchin scenarios (*0001-*0008)') +print('(and build_turn.rpt if it exists)') +print(' executing...') + +#connect to modeller +modeller = tbm.connect(proj_dir) +emmebank = modeller.emmebank + +#define tools +delete_scenario = modeller.tool('inro.emme.data.scenario.delete_scenario') + +#get scenario info from batch_file.yaml for scenario numbers to delete +db = proj_dir.joinpath('Database') +with open(os.path.join(db, 'batch_file.yaml')) as f: + lines_without_backslashes = ''.join([line.replace('\\','/') for line in f]) + config = yaml.safe_load(lines_without_backslashes) +scen_yr = config['scenario_code'] # e.g., '200' +scenarios_to_delete = [f'{scen_yr}0{i}' for i in range(1,9)] + [f'{scen_yr}0'] + +#delete scenarios +for scen in scenarios_to_delete: + if emmebank.scenario(scen): #returns None if DNE + delete_scenario(emmebank.scenario(scen)) + else: + print(f'scenario {scen} does not exist') + +#delete build_turn.rpt if it exists +rptfile = db.joinpath('report/build_turn.rpt') +if os.path.exists(rptfile): + os.remove(rptfile) +else: + print('build_turn.rpt does not exist') + +print('done') \ No newline at end of file From 0ae4ace1295ca6d5a7a43614e78635bfdecfcddb Mon Sep 17 00:00:00 2001 From: tkoleary Date: Fri, 26 Sep 2025 14:17:21 -0500 Subject: [PATCH 02/17] translated delete.scenarios and delete.matrices to python 3, adding interactive prompt and/or importable function --- Database/useful_macros/delete_matrices.py | 108 +++++++++++++++++++++ Database/useful_macros/delete_scenarios.py | 107 ++++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 Database/useful_macros/delete_matrices.py create mode 100644 Database/useful_macros/delete_scenarios.py diff --git a/Database/useful_macros/delete_matrices.py b/Database/useful_macros/delete_matrices.py new file mode 100644 index 0000000..8afd251 --- /dev/null +++ b/Database/useful_macros/delete_matrices.py @@ -0,0 +1,108 @@ +''' +`delete_matrices.py` +Author: Tim O'Leary +Date: 9/26/2025 + +Description: This script deletes specified matrices from the emme databank. It can +be called as a subscript or by itself. Contains delete_matrices() function that can take +a string or a list of strings as input. + +Translated from 'delete.matrices' Emme macro written by DBE 5/11/2004 +- Added functionality to call a single matrix, range, or list +- Runs interactively if called by itself, or function could be imported and called by another script +''' + +print('delete_matrices.py\nstarting up...') +import os +import sys +from pathlib import Path +import textwrap + +proj_dir = Path(__file__).resolve().parents[2] +sys.path.append(str(proj_dir.joinpath('Scripts'))) +from tbmtools import project as tbm + +#connect to modeller +modeller = tbm.connect(proj_dir) +emmebank = modeller.emmebank + +#define tools +delete_matrix = modeller.tool('inro.emme.data.matrix.delete_matrix') + +def delete_matrices(mats_to_delete): + ''' + Deletes specified matrices from the databank. + Input may be one of the following: + - a single matrix (e.g., 'mf2') + - a range of matrices separated by a hyphen (e.g., 'mf25-mf90') + - a list of numbers (e.g., 'mf25, mf30, mf45')) + ''' + + bad_input_msg = textwrap.dedent(f'''\ + Input not recognized. Please input IDs with prefix (e.g., "mf"), in one of the following formats: + \t- a single matrix ID (e.g., "mf54"); + \t- a range of IDs with hyphen between (e.g., "mf25-mf90"); or + \t- a list of IDs (e.g., [id1,id2,...]).''') + + #if passed function with no input + if mats_to_delete is None or mats_to_delete == '': + raise ValueError(bad_input_msg) + + #check for incorrectly formatted matrix IDs + if '-' in str(mats_to_delete): + input_type = 'range' + mats_check = str(mats_to_delete).split('-') + mats_check = [m.strip() for m in mats_check] + else: + input_type = 'list' + mats_check = str(mats_to_delete).replace('[','').replace(']','').split(',') + mats_check = [m.strip() for m in mats_check] + + #make sure prefixes and suffixes aren't invalid, and check if mixed matrix types + bad_prefix = [m for m in mats_check if m[:2] not in ['mf', 'mo', 'md', 'ms']] + mixed_types = [m[:2] for m in mats_check] + bad_suffix = [m for m in mats_check if not m[2:].isdigit()] + if len(bad_prefix + bad_suffix) > 0: + raise ValueError(bad_input_msg) + if len(set(mixed_types)) > 1: + raise ValueError('Sorry, cannot mix matrix types in one call for now. Please only do one matrix type at a time.') + + #handle range input + if input_type == 'range': + mtx_type = set(mixed_types)[0] + min = int(mats_check[0][2:]) + max = int(mats_check[1][2:]) + mats = [f'{mtx_type}{m}' for m in range(min, max+1)] + else: + mats = mats_check + + #delete matrices + for mat in mats: + if emmebank.matrix(mat): + delete_matrix(emmebank.matrix(mat)) + else: + print(f' - matrix {mat} not in dabatank, skipping...') + +print(''' + DELETE_MATRICES.PY + This script will delete specified matrices from the emme databank! + Input may be one of the following: + - a single matrix (e.g., 'mf2') + - a range of matrices, min and max separated by a hyphen (e.g., 'mf25-mf90') + - a list of matrix IDs, separated by commas (e.g., 'mf25, mf30, mf45')) + ''') + +while True: + try: + user_input = input('Enter matrices to delete (or "exit" to quit): ') + if user_input.lower() == 'exit': + break + delete_matrices(user_input) + print('\n - done! want to go again?\n') + except ValueError as e: + print(f'\n!! Error: {e}\n') + except Exception as e: + print(f'\n!! Unexpected error occurred: {e}\n') +print('bye-bye, then!') +input('press any key to exit') +sys.exit() diff --git a/Database/useful_macros/delete_scenarios.py b/Database/useful_macros/delete_scenarios.py new file mode 100644 index 0000000..d30b5cf --- /dev/null +++ b/Database/useful_macros/delete_scenarios.py @@ -0,0 +1,107 @@ +''' +`delete_scenarios.py` +Author: Tim O'Leary +Date: 9/26/2025 + +Description: This script deletes specified scenarios from the emme databank. It can +be called as a subscript or by itself. Contains delete_scenarios() function that can take +a string or a list of strings as input. + +Translated to Python 3 from 'delete.scenarios' Emme macro +Written by DBE 5/2004 and modified to handle non-existent scenarios by CH 3/2009 +Added functionality with Python translation: +- Can call a single scenario, a range of scenarios, or list +- Runs interactively with user input if called by itself, or the function 'delete_scenarios()' can be imported and called by another script +''' + +print('delete_scenarios.py\nstarting up...') +import os +import sys +from pathlib import Path +import textwrap + +proj_dir = Path(__file__).resolve().parents[2] +sys.path.append(str(proj_dir.joinpath('Scripts'))) +from tbmtools import project as tbm + +#connect to modeller +modeller = tbm.connect(proj_dir) +emmebank = modeller.emmebank + +#define tools +delete_scenario = modeller.tool('inro.emme.data.scenario.delete_scenario') + +def delete_scenarios(scens_to_delete): + ''' + Deletes specified scenarios from the databank. + Input may be one of the following: + - a single scenario (e.g., '20003') + - a range of scenarios separated by a hyphen (e.g., '20021-20028') + - a list of scenarios (e.g., '221, 22003, 22004')) + ''' + + bad_input_msg = textwrap.dedent(f'''\ + Input not recognized. Please input scenario IDs as integers in one of the following formats: + \t- a single scenario ID (e.g., '20003'); + \t- a range of IDs with hyphen between (e.g., '20021-20028'); or + \t- a list of IDs (e.g., '221, 22003, 22004').''') + + #if passed function with no input + if scens_to_delete is None or scens_to_delete == '': + raise ValueError(bad_input_msg) + + #check for incorrectly formatted input + if '-' in str(scens_to_delete): + input_type = 'range' + scens_check = str(scens_to_delete).split('-') + scens_check = [m.strip() for m in scens_check] + else: + input_type = 'list' + scens_check = str(scens_to_delete).replace('[','').replace(']','').split(',') + scens_check = [m.strip() for m in scens_check] + + #make sure prefixes and suffixes aren't invalid, and check if mixed matrix types + not_a_number = [m for m in scens_check if not m.isnumeric()] + if not_a_number: + raise ValueError(bad_input_msg) + + #handle range input + if input_type == 'range': + min = int(scens_check[0]) + max = int(scens_check[1]) + if min >= max: + raise ValueError('Your min should be less than your max.') + scens = [m for m in range(min, max+1)] + else: + scens = scens_check + + #delete matrices + for scen in scens: + if emmebank.scenario(scen): + delete_scenario(emmebank.scenario(scen)) + else: + print(f' - scenario {scen} not in dabatank, skipping...') + +print(''' + DELETE_SCENARIOS.PY + This script will delete specified scenarios from the emme databank! + Input may be one of the following: + - a single scenario ID (e.g., '20027') + - a range of scenarios, min and max separated by a hyphen (e.g., '221-227') + - a list of scenario IDs, separated by commas (e.g., '5, 8, 20005, 20008')) + ''') + +while True: + try: + user_input = input('Enter scenarios to delete (or "exit" to quit): ') + if user_input.lower() == 'exit': + break + delete_scenarios(user_input) + print('\n - done! want to go again?\n') + except ValueError as e: + print(f'\n!! Error: {e}\n') + except Exception as e: + print(f'\n!! Unexpected error occurred: {e}\n') +print('bye-bye, then!') +input('press any key to exit') +sys.exit() From 3ab7094ca142206b5f548b3f15a57513801075b6 Mon Sep 17 00:00:00 2001 From: tkoleary Date: Fri, 26 Sep 2025 14:19:14 -0500 Subject: [PATCH 03/17] remove emme macro versions of delete_matrices and delete_scenarios --- Database/useful_macros/delete.matrices | 58 ---------------------- Database/useful_macros/delete.scenarios | 21 -------- Database/useful_macros/delete_matrix_named | 12 ----- 3 files changed, 91 deletions(-) delete mode 100644 Database/useful_macros/delete.matrices delete mode 100644 Database/useful_macros/delete.scenarios delete mode 100644 Database/useful_macros/delete_matrix_named diff --git a/Database/useful_macros/delete.matrices b/Database/useful_macros/delete.matrices deleted file mode 100644 index ac46569..0000000 --- a/Database/useful_macros/delete.matrices +++ /dev/null @@ -1,58 +0,0 @@ -~/ -~/********************************************************************** -~/********************************************************************** -~/ -~/ Macro Delete.matx.mac %1% %2% -~/ where %1% = low end range of matrix number to delete -~/ %2% = high end range of matrix number to delete -~/ -~/********************************************************************** -~/ Macro deletes a range of full matrices. -~/ -~/********************************************************************** -~/ -~/ Written by DBE 11May2004 -~/ -~/********************************************************************** -~/ -~/ register x = matrix number to be deleted, incremented & checked. -~/ REMOVED LINE BETWEEM ~:ERR AND ~:END IT WAS CAUSING THE PROGRAM TO FAIL -~/ WHEN THE MATRICES DID NOT EXIST BOZIC 11-2-2017 -~/********************************************************************** -~/ -~x=%1% -~:startloop -3.12 -2 -mf%x% -~?e -~$>err -yes -~$>end -~:err - -~:end -q -~/ -~/********************************************************************** -~/ -~/ All requested matrices deleted? -~/ -~/********************************************************************** -~/ -~x+1 -~?x>%2% -~$>done -~$startloop -~:done -~/ -~/********************************************************************** -~/ -~/ End of macro -~/ -~/********************************************************************** -~/ -3.14 -2 -m -1 \ No newline at end of file diff --git a/Database/useful_macros/delete.scenarios b/Database/useful_macros/delete.scenarios deleted file mode 100644 index 7a4396a..0000000 --- a/Database/useful_macros/delete.scenarios +++ /dev/null @@ -1,21 +0,0 @@ -~/ macro for deleting a range of network scenarios -~/ -~/ r11 = counter -~/ Created by DBE 21May2004, modified kww 6/6 -~/ modified by cmh 3/09: continues running if scenario does not exist -~x=%1% -~:loop -~x+1 -~r11+1 -1.22 -2 -%x% -~?e -~+; ;q;~$>next -yes -q -~:next -~?!x=%2% -~$loop -~:done -s= \ No newline at end of file diff --git a/Database/useful_macros/delete_matrix_named b/Database/useful_macros/delete_matrix_named deleted file mode 100644 index 4bbbfbf..0000000 --- a/Database/useful_macros/delete_matrix_named +++ /dev/null @@ -1,12 +0,0 @@ -3.12 -2 -%1% -~?e -~$>err1 -yes -~$>end1 -~:err1 - -r -~:end1 -q \ No newline at end of file From e7bf2b4cf3fd6b5186253dab51ae92fbf6cdced2 Mon Sep 17 00:00:00 2001 From: tkoleary Date: Fri, 26 Sep 2025 16:35:01 -0500 Subject: [PATCH 04/17] translates summarize_transit_boardings.mac to python, and edits submit_full.bat to call it at the end of transit assignment. additional functionality includes outputting a transit equivalent to "punch_link.csv" in transit_asmt/report, --- Database/Submit_Full_Regional_Model_SOLA.bat | 1 + .../summarize_transit_boardings.mac | 97 ---------- .../summarize_transit_boardings.py | 168 ++++++++++++++++++ 3 files changed, 169 insertions(+), 97 deletions(-) delete mode 100644 Database/transit_asmt_macros/summarize_transit_boardings.mac create mode 100644 Database/transit_asmt_macros/summarize_transit_boardings.py diff --git a/Database/Submit_Full_Regional_Model_SOLA.bat b/Database/Submit_Full_Regional_Model_SOLA.bat index a769936..1e9ba53 100644 --- a/Database/Submit_Full_Regional_Model_SOLA.bat +++ b/Database/Submit_Full_Regional_Model_SOLA.bat @@ -454,6 +454,7 @@ if "%transitAsmt%" EQU "T" ( if %ERRORLEVEL% GTR 0 (goto issue) @ECHO -- Completed Select Line Boarding Analysis >> model_run_timestamp.txt ) + call python transit_asmt_macros\summarize_transit_boardings.py @ECHO End Transit Assignment: %date% %time% >> model_run_timestamp.txt ) goto last diff --git a/Database/transit_asmt_macros/summarize_transit_boardings.mac b/Database/transit_asmt_macros/summarize_transit_boardings.mac deleted file mode 100644 index 900821c..0000000 --- a/Database/transit_asmt_macros/summarize_transit_boardings.mac +++ /dev/null @@ -1,97 +0,0 @@ - -~# SUMMARIZE_TRANSIT_BOARDINGS.MAC -~# Craig Heither, 10-25-2022 -~# -~# Summarize transit boardings for congested transit assignment. -~# submit with: ~ -~# e.g.: " ~>%t3% -~"Line,Scenario,TotalBoard,PassengerMiles -~> -~# #### -~# -~:full_loop -~# -~:scenario_loop -s=%x% -~?y=1 -~+;~t1=CTA_Rail_Blue_Line;~t2=cbl___ -~?y=2 -~+;~t1=CTA_Rail_Brown_Line;~t2=cbr___ -~?y=3 -~+;~t1=CTA_Rail_Green_Line;~t2=cg____ -~?y=4 -~+;~t1=CTA_Rail_Orange_Line;~t2=cor___ -~?y=5 -~+;~t1=CTA_Rail_Pink_Line;~t2=cpk___ -~?y=6 -~+;~t1=CTA_Rail_Purple_Line;~t2=cpr___ -~?y=7 -~+;~t1=CTA_Rail_Red_Line;~t2=crd___ -~?y=8 -~+;~t1=CTA_Rail_Yellow_Line;~t2=cye___ -~?y=9 -~+;~t1=Metra_BNSF;~t2=mbn___ -~?y=10 -~+;~t1=Metra_Heritage_Corridor;~t2=mhc___ -~?y=11 -~+;~t1=Metra_Electric;~t2=mme___ -~?y=12 -~+;~t1=Metra_Milwaukee_North;~t2=mmn___ -~?y=13 -~+;~t1=Metra_Milwaukee_West;~t2=mmw___ -~?y=14 -~+;~t1=Metra_North_Central;~t2=mnc___ -~?y=15 -~+;~t1=Metra_Rock_Island;~t2=mri___ -~?y=16 -~+;~t1=Metra_SouthWest_Service;~t2=msw___ -~?y=17 -~+;~t1=Metra_UP_North;~t2=mun___ -~?y=18 -~+;~t1=Metra_UP_Northwest;~t2=mnw___ -~?y=19 -~+;~t1=Metra_UP_West;~t2=muw___ -~?y=20 -~+;~t1=NICTD_South_Shore;~t2=mss___ -~?y=21 -~+;~t1=CTA_Bus_Regular;~t2=mod=B -~?y=22 -~+;~t1=CTA_Bus_Express;~t2=mod=E -~?y=23 -~+;~t1=Pace_Bus_Regular;~t2=mod=P -~?y=24 -~+;~t1=Pace_Bus_Express;~t2=mod=Q -~?y=25 -~+;~t1=Pace_Bus_Local;~t2=mod=L -~# -~# ##-- Boardings -- ## -2.41 -~+;1;n;board; ;%t2%; ;*;5;4;ms900;allbrd;All line boards;1 -~+;1;n;voltr*len; ;%t2%; ;*;5;4;ms901;pssmle;Passenger miles;1;q -~# -~>>%t3% -~"%t1%,%s%,%ms900.0%,%ms901.0% -~> -~x+2 -~+;~?x<%z%;~$scenario_loop -~# ##-- next line --## -~+;~x-8;~y+1 -~+;~?y<26;~$full_loop -~# -~# ##-- Delete matrices --## -3.12 -~+;2;ms900;y -~+;2;ms901;y;q -~/ summary done! -q diff --git a/Database/transit_asmt_macros/summarize_transit_boardings.py b/Database/transit_asmt_macros/summarize_transit_boardings.py new file mode 100644 index 0000000..eb14e30 --- /dev/null +++ b/Database/transit_asmt_macros/summarize_transit_boardings.py @@ -0,0 +1,168 @@ +''' +SUMMARIZE_TRANSIT_BOARDINGS.PY + Craig Heither, 10-25-2022 + Translated from Emme macro to Python by Tim O'Leary, 9-26-2025 + + Summarize transit boardings for congested transit assignment. + No inputs necessary-- reads batch_file.yaml to determine scen numbers. + Will not run unless transit assignment has been completed. +''' + +#libraries +import os +import sys +from pathlib import Path +import yaml +import pandas as pd + +#startup emme +proj_dir = Path(__file__).resolve().parents[2] +db = proj_dir.joinpath('Database') +sys.path.append(str(proj_dir.joinpath('Scripts'))) +from tbmtools import project as tbm + +#connect to modeller +modeller = tbm.connect(proj_dir) +emmebank = modeller.emmebank + +#output location +out_boarding_csv = os.path.join( + db, 'transit_asmt_macros/report/Boarding_summary.csv' +) +out_transit_punch = os.path.join( + db, 'transit_asmt_macros/report/transit_punch_segment.csv' +) + +if os.path.exists(out_boarding_csv): + os.remove(out_boarding_csv) + +#get scenario info from batch_file.yaml for transit asmt scenarios +db = proj_dir.joinpath('Database') +with open(os.path.join(db, 'batch_file.yaml')) as f: + lines_without_backslashes = ''.join([line.replace('\\','/') for line in f]) + config = yaml.safe_load(lines_without_backslashes) +yr = config['scenario_code'][0] # e.g., '2' from '200' + +trnt_scens = { + f'Night (6pm-6am)': f'{yr}21', + f'AM (6am-9am)': f'{yr}23', + f'Midday (9am-4pm)': f'{yr}25', + f'PM (4pm-6pm)': f'{yr}27', +} + +tr_dfs = [] + +trnt_scens = { + f'Night (6pm-6am)': f'{yr}21', + f'AM (6am-9am)': f'{yr}23', + f'Midday (9am-4pm)': f'{yr}25', + f'PM (4pm-6pm)': f'{yr}27', +} + +for period_name, scen_num in trnt_scens.items(): + + scen = emmebank.scenario(scen_num) + if scen is None: + raise ValueError(f'Scenario {scen_num} not found in Emmebank') + + network = scen.get_network() + links = network.links() + + trpunch_list = [] + for link in network.links(): + segments = link.segments() #empty if link does not have transit segments + inode = network.node(link.i_node) + jnode = network.node(link.j_node) + #for each segment (if it has any), add this info to table: + for segment in segments: + line = network.transit_line(str(segment.id).split('-')[0]) + seg = [ + link.id, + segment.id, + link.length, + line.headway, + segment['transit_boardings'], + segment['transit_volume'], + segment['data1'], + inode['@zone'], + jnode['@zone'] + ] + + trpunch_list.append(seg) + + columns = ['id', 'segment_id', 'length', 'headway', 'transit_boardings','transit_volume','ltime','inode_zone','jnode_zone'] + trpunch = pd.DataFrame(data=trpunch_list, columns=columns) + + trpunch.eval('pmt = transit_volume * length', inplace=True) + trpunch.eval('pht = transit_volume * ltime / 60', inplace=True) + + #use transit line info to determine mode + def line_mode(x): + # b - cta local; e - cta express + # p - pace regular; q - pace express; l - pace feeder; + # m__ and c__ - 3 letter code for CTA rail and metra lines + + line = x.split('-')[0] + name = ''.join([char for char in line if char.isalpha()]) + name_key = { + 'cbl': 'CTA Blue Line', + 'cbr': 'CTA Brown Line', + 'cg': 'CTA Green Line', + 'cor': 'CTA Orange Line', + 'cpk': 'CTA Pink Line', + 'cpr': 'CTA Purple Line', + 'crd': 'CTA Red Line', + 'cye': 'CTA Yellow Line', + 'mbn': 'Metra BNSF', + 'mhc': 'Metra Heritage Corridor', + 'mme': 'Metra Electric', + 'mmn': 'Metra Milwaukee North', + 'mmw': 'Metra Milwaukee West', + 'mnc': 'Metra North Central', + 'mri': 'Metra Rock Island', + 'msw': 'Metra SouthWest Service', + 'mun': 'Metra UP North', + 'mnw': 'Metra UP Northwest', + 'muw': 'Metra UP West', + 'mss': 'NICTD South Shore', + 'b': 'CTA Regular Bus', + 'e': 'CTA Express Bus', + 'p': 'Pace Regular Bus', + 'q': 'Pace Express Bus', + 'l': 'Pace Feeder Bus', + } + nam = [code for code in name_key.keys() if code in name] + nam = max(nam, key=len) if len(nam) > 0 else None + return name_key[nam] + + trpunch['mode'] = trpunch['segment_id'].map(line_mode) + + if len(trpunch.loc[trpunch['mode'].isnull()]) > 0: + print(f'SOME TRANSIT SEGMENTS WERE NOT MAPPED TO A MODE!') + print(trpunch.loc[trpunch['mode'].isnull()]) + raise ValueError('Some transit segments were not mapped to a mode (must be c, m, p, q, l, b, or e). Look at printed output of errors above.') + + trpunch['tod'] = scen_num + + tr_dfs.append(trpunch) + +tr_all = pd.concat(tr_dfs, ignore_index=True) + +#output all segment info to csv (similar to punch link) +tr_all.to_csv(out_transit_punch, index=False) + +#summary by time-of-day +summary_tod = tr_all.groupby(['tod', 'mode']).agg({ + 'transit_boardings':'sum', + 'pmt':'sum' +}).reset_index() +#total daily +summary_daily = summary_tod.groupby('mode').agg({ + 'transit_boardings':'sum', + 'pmt':'sum' +}).reset_index() +summary_daily['tod'] = 'Daily' + +summary = pd.concat([summary_tod, summary_daily], ignore_index=True) +summary.to_csv(out_boarding_csv, index=False) +print(f'Summary transit boarding information written to: {out_boarding_csv}') \ No newline at end of file From c089942723ad0c9b4702395a177bfa79884acf74 Mon Sep 17 00:00:00 2001 From: tkoleary Date: Mon, 29 Sep 2025 10:50:56 -0500 Subject: [PATCH 05/17] cleanup edits --- .../summarize_transit_boardings.py | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Database/transit_asmt_macros/summarize_transit_boardings.py b/Database/transit_asmt_macros/summarize_transit_boardings.py index eb14e30..c1338f6 100644 --- a/Database/transit_asmt_macros/summarize_transit_boardings.py +++ b/Database/transit_asmt_macros/summarize_transit_boardings.py @@ -52,13 +52,6 @@ tr_dfs = [] -trnt_scens = { - f'Night (6pm-6am)': f'{yr}21', - f'AM (6am-9am)': f'{yr}23', - f'Midday (9am-4pm)': f'{yr}25', - f'PM (4pm-6pm)': f'{yr}27', -} - for period_name, scen_num in trnt_scens.items(): scen = emmebank.scenario(scen_num) @@ -98,9 +91,23 @@ #use transit line info to determine mode def line_mode(x): - # b - cta local; e - cta express - # p - pace regular; q - pace express; l - pace feeder; - # m__ and c__ - 3 letter code for CTA rail and metra lines + ''' + function for .map() method used directly below this function + to determine mode name from segment_id + + segment_id format: [alpha-code][5-digit number], e.g., 'b12535', 'cbl10011' + + b -> CTA local bus + e -> CTA express + p -> Pace regular bus + l -> Pace feeder bus + q -> Pace express bus + c** -> CTA rail lines (3-letter code) + m** -> Metra lines (3-letter code) + + returns: the english name representation of the mode code + + ''' line = x.split('-')[0] name = ''.join([char for char in line if char.isalpha()]) From 214a6d3f6a5ca1a371b08b91fb0b56beb08527a3 Mon Sep 17 00:00:00 2001 From: tkoleary Date: Mon, 29 Sep 2025 10:58:43 -0500 Subject: [PATCH 06/17] final error fixes --- .../transit_asmt_macros/summarize_transit_boardings.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Database/transit_asmt_macros/summarize_transit_boardings.py b/Database/transit_asmt_macros/summarize_transit_boardings.py index c1338f6..ececcc1 100644 --- a/Database/transit_asmt_macros/summarize_transit_boardings.py +++ b/Database/transit_asmt_macros/summarize_transit_boardings.py @@ -41,7 +41,7 @@ with open(os.path.join(db, 'batch_file.yaml')) as f: lines_without_backslashes = ''.join([line.replace('\\','/') for line in f]) config = yaml.safe_load(lines_without_backslashes) -yr = config['scenario_code'][0] # e.g., '2' from '200' +yr = str(config['scenario_code'])[0] # e.g., '2' from '200' trnt_scens = { f'Night (6pm-6am)': f'{yr}21', @@ -150,6 +150,7 @@ def line_mode(x): raise ValueError('Some transit segments were not mapped to a mode (must be c, m, p, q, l, b, or e). Look at printed output of errors above.') trpunch['tod'] = scen_num + trpunch['tod_name'] = period_name tr_dfs.append(trpunch) @@ -159,7 +160,7 @@ def line_mode(x): tr_all.to_csv(out_transit_punch, index=False) #summary by time-of-day -summary_tod = tr_all.groupby(['tod', 'mode']).agg({ +summary_tod = tr_all.groupby(['tod_name', 'tod', 'mode']).agg({ 'transit_boardings':'sum', 'pmt':'sum' }).reset_index() @@ -168,7 +169,8 @@ def line_mode(x): 'transit_boardings':'sum', 'pmt':'sum' }).reset_index() -summary_daily['tod'] = 'Daily' +summary_daily['tod'] = 'All' +summary_daily['tod_name'] = 'Daily' summary = pd.concat([summary_tod, summary_daily], ignore_index=True) summary.to_csv(out_boarding_csv, index=False) From dc237312ef0703aeaa46d87409d5d2081a7f7160 Mon Sep 17 00:00:00 2001 From: Tim O'Leary Date: Thu, 21 May 2026 15:39:09 -0500 Subject: [PATCH 07/17] Revert "Merge branch 'develop' of https://github.com/CMAP-REPOS/cmap_trip-based_model into develop" This reverts commit 28680133fc397397b0c430c44c106ad53d6f373e, reversing changes made to 214a6d3f6a5ca1a371b08b91fb0b56beb08527a3. --- .gitignore | 9 +- Database/Submit_Full_Regional_Model_SOLA.bat | 162 +- Database/Telework.yaml | 37 - Database/batch_file.yaml | 14 +- Database/build_scenario_networks.bat | 11 +- Database/choice_model_params.yaml | 1 + Database/data/land_use_proportions.csv | 3633 ---- Database/data/tg_rates.csv | 21 - Database/macros/TOD_skim.py | 247 +- Database/macros/skim_transit.py | 53 +- Database/macros/tod_skim_setup.mac | 147 + ...ces.py => transit_skim_final_matrices1.py} | 78 +- .../macros/transit_skim_final_matrices2.py | 182 + Database/macros/transit_skim_wrapup.py | 154 +- Database/macros/transit_triple_indexing.py | 36 +- Database/prep_macros/create_distr_m01_files.R | 2 +- Database/prep_macros/distr_m01_data.py | 228 +- Database/prep_macros/free.skim.mac.py | 607 +- Database/prep_macros/initialize_scenarios.py | 78 +- .../preload_congested_times_mac.py | 218 +- Database/tg/data/m01auto.csv | 7264 +++---- Database/tg/fortran/EXT_IN.TXT | 148 +- Database/tg/fortran/TG_INPUT.TXT | 25 + Database/tg/fortran/TG_PopSyn.exe | Bin 0 -> 1565184 bytes Database/tg/fortran/airport_sz.csv | 68 - .../tg/fortran/coefficients_attractions.csv | 197 - .../coefficients_nonhome_productions.csv | 197 - Database/tg/fortran/create_HHvtype_file.py | 45 + Database/tg/fortran/highinc_workers.csv | 4 + Database/tg/fortran/subzone_tg_data.txt | 17419 ---------------- Database/tg/fortran/tg_hhtype_lookup.csv | 625 - Database/tg/fortran/tg_hhvtype_lookup.csv | 625 - Database/tg/fortran/wfhmodule/edudist.csv | 7 - Database/tg/fortran/wfhmodule/indp_naics.csv | 590 +- Database/tg/fortran/wfhmodule/wfhflag.py | 442 +- Database/tg/fortran/wfhmodule/wfhflag_base.py | 393 - Database/tg/scripts/summarize_tg_results.py | 7 +- .../tg/scripts/urbansim_hcv_allocation.py | 150 +- Database/tg/scripts/urbansim_skims.py | 30 +- .../scripts/urbansim_update_tg_input_files.py | 480 +- .../create_transit_demand.bat | 6 +- .../run_transit_assignment.bat | 6 +- Database/trip_gen.bat | 107 +- .../household_trip_enumeration.py | 115 - Database/trip_generation/trip_generation.yaml | 39 - .../trip_generation/trip_generation_model.py | 987 - .../trip_generation/vehicle_availability.py | 326 - Database/useful_macros/cleanup_for_rerun.py | 31 +- Scripts/manage/env/CMAP-TRIP2.yml | 57 + Scripts/manage/env/activate_env.cmd | 64 + Scripts/manage/env/emme-plus.yml | 16 + Scripts/{manage_envs => manage/env}/emme.pth | 0 Scripts/manage/env/set_condapath.cmd | 46 + .../cmap-modedest/cmap-modedest.yml | 7 - .../cmap-modedest/requirements.txt | 1 - Scripts/manage_envs/install_envs.ps1 | 49 - Scripts/manage_envs/tbm-r/tbm-r.yml | 8 - Scripts/manage_envs/uninstall_envs.ps1 | 4 - .../conformity_scenario/hand/config.yaml | 42 +- Scripts/prepare/conformity_scenario/run.cmd | 3 +- .../src/prepare_conformity_scenario.py | 11 +- .../standard_data/hand/data_user_guide_md.txt | 4 +- .../share/standard_data/src/standard_data.py | 6 +- c25q4_100.emp => c25q2_100.emp | 6 +- c25q4_100.emp.prj => c25q2_100.emp.prj | 0 copy_scenario_data.ps1 | 5 + pyproject.toml | 21 - src/Mode-Dest-TOD/.gitignore | 1 + src/Mode-Dest-TOD/README.md | 81 + src/Mode-Dest-TOD/TECHNICALGUIDE.md | 66 + src/Mode-Dest-TOD/USERGUIDE.md | 495 + src/Mode-Dest-TOD/cmap_modedest/__init__.py | 6 + src/Mode-Dest-TOD/cmap_modedest/__main__.py | 274 + src/Mode-Dest-TOD/cmap_modedest/addict.py | 203 + .../cmap_modedest/ae_distance_sim.py | 80 + .../cmap_modedest/application.py | 1495 ++ .../cmap_modedest/choice_model.py | 544 + .../cmap_modedest/cmap_logging.py | 121 + .../cmap_modedest/configuration.py | 0 .../cmap_modedest/data_handlers/__init__.py | 267 + .../data_handlers/distr_handler.py | 28 + .../cmap_modedest/data_handlers/filepaths.py | 284 + .../data_handlers/household_types.csv | 625 + .../data_handlers/household_types.py | 23 + .../data_handlers/m01_handler.py | 171 + .../data_handlers/m023_handler.py | 39 + .../data_handlers/pa_trip_types.csv | 50 + .../data_handlers/parking_handler.py | 74 + .../data_handlers/shp_handler.py | 11 + .../data_handlers/skims_handler.py | 226 + .../cmap_modedest/data_handlers/tabler.py | 1 + .../cmap_modedest/data_handlers/tg_handler.py | 129 + .../cmap_modedest/data_handlers/visitors.py | 39 + .../cmap_modedest/deadheading.py | 144 + .../cmap_modedest/estimation/__init__.py | 12 + .../cmap_modedest/estimation/est_choice.py | 863 + .../cmap_modedest/estimation/est_config.py | 137 + .../cmap_modedest/estimation/est_data.py | 25 + .../cmap_modedest/estimation/est_logging.py | 13 + .../estimation/est_sample_dest.py | 270 + .../estimation/est_skims_convol.py | 29 + .../cmap_modedest/estimation/est_survey.py | 565 + .../cmap_modedest/estimation/est_timeofday.py | 60 + .../cmap_modedest/fast/__init__.py | 0 .../cmap_modedest/fast/__sc/S1/__init__.py | 467 + .../fast/__sc/S1/__init__.py.lock | 0 .../cmap_modedest/fast/__sc/S1/extra_funcs.py | 6 + .../fast/__sc/S1/extra_funcs.py.lock | 0 .../cmap_modedest/fast/__sc/S1/extra_vars.py | 7 + .../fast/__sc/S1/extra_vars.py.lock | 0 .../fast/__sc/S1/f_auto_dist_OFFPEAK.py | 16 + .../fast/__sc/S1/f_auto_dist_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_auto_dist_PEAK.py | 16 + .../fast/__sc/S1/f_auto_dist_PEAK.py.lock | 0 .../fast/__sc/S1/f_auto_opcost_OFFPEAK.py | 16 + .../__sc/S1/f_auto_opcost_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_auto_opcost_PEAK.py | 16 + .../fast/__sc/S1/f_auto_opcost_PEAK.py.lock | 0 .../fast/__sc/S1/f_auto_opcost_hov_PEAK.py | 16 + .../__sc/S1/f_auto_opcost_hov_PEAK.py.lock | 0 .../fast/__sc/S1/f_auto_time_OFFPEAK.py | 16 + .../fast/__sc/S1/f_auto_time_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_auto_time_PEAK.py | 16 + .../fast/__sc/S1/f_auto_time_PEAK.py.lock | 0 .../fast/__sc/S1/f_auto_toll_OFFPEAK.py | 16 + .../fast/__sc/S1/f_auto_toll_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_auto_toll_hiinc_PEAK.py | 16 + .../__sc/S1/f_auto_toll_hiinc_PEAK.py.lock | 0 .../__sc/S1/f_auto_toll_hov_hiinc_PEAK.py | 16 + .../S1/f_auto_toll_hov_hiinc_PEAK.py.lock | 0 .../__sc/S1/f_auto_toll_hov_loinc_PEAK.py | 16 + .../S1/f_auto_toll_hov_loinc_PEAK.py.lock | 0 .../fast/__sc/S1/f_auto_toll_loinc_PEAK.py | 16 + .../__sc/S1/f_auto_toll_loinc_PEAK.py.lock | 0 .../fast/__sc/S1/f_autopropensity.py | 16 + .../fast/__sc/S1/f_autopropensity.py.lock | 0 ...__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py | 16 + ...atype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py.lock | 0 ...__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py | 16 + ...atype___2_FIT25FYRGELBEONPX2MTPZFN.py.lock | 0 ...__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py | 16 + ...atype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py.lock | 0 ...__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py | 16 + ...atype___4_J3D56DXM2MR6NEMIQ6ALSFID.py.lock | 0 ...__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py | 16 + ...atype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py.lock | 0 ...__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py | 16 + ...atype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py.lock | 0 ...__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py | 16 + ...atype___3_34BD5WGYZOPLALWPB2MCWKA7.py.lock | 0 ...__areatype___4_64S6AODYPVZP57LTAC522OHX.py | 16 + ...atype___4_64S6AODYPVZP57LTAC522OHX.py.lock | 0 .../fast/__sc/S1/f_log_attractions_HBO.py | 16 + .../__sc/S1/f_log_attractions_HBO.py.lock | 0 ...ons_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py | 16 + ...BO____666_5VORECHSLO2A6MKP5I3SGJVQ.py.lock | 0 .../fast/__sc/S1/f_log_attractions_HBS.py | 16 + .../__sc/S1/f_log_attractions_HBS.py.lock | 0 ...ons_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py | 16 + ...BS____666_L3ZMVRT365KFSBLEDVABFEGL.py.lock | 0 .../fast/__sc/S1/f_log_attractions_HBWH.py | 16 + .../__sc/S1/f_log_attractions_HBWH.py.lock | 0 ...ns_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py | 16 + ...WH____666_GW3RKVJQOVET3XE7MYE2MA7V.py.lock | 0 .../fast/__sc/S1/f_log_attractions_HBWL.py | 16 + .../__sc/S1/f_log_attractions_HBWL.py.lock | 0 ...ns_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py | 16 + ...WL____666_IQGLCTAX7EZOXKEFCIBK33BD.py.lock | 0 .../fast/__sc/S1/f_log_attractions_NHB.py | 16 + .../__sc/S1/f_log_attractions_NHB.py.lock | 0 ...ons_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py | 16 + ...HB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py.lock | 0 ...o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py | 16 + ...e____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py.lock | 0 ...FPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py | 16 + ..._0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py.lock | 0 ...FPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py | 16 + ..._10_None__6EE7X5PWAQKBS6WQUONWVI63.py.lock | 0 ...PEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py | 16 + ...1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py.lock | 0 ..._OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py | 16 + ...EAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py.lock | 0 ...PEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py | 16 + ...None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py.lock | 0 ...FFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py | 16 + ...K_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py.lock | 0 ..._PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py | 16 + ..._0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py.lock | 0 ..._PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py | 16 + ..._10_None__L3GKJNRUTTFCDUYV65K7KFQD.py.lock | 0 ...PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py | 16 + ...1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py.lock | 0 ...ist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py | 16 + ...EAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py.lock | 0 ...PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py | 16 + ...None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py.lock | 0 ...t_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py | 16 + ...K_None_5__7D72ALZRBNSP634JYUY7IV5P.py.lock | 0 ...EAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py | 16 + ...20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py.lock | 0 ...EAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py | 16 + ...None__20__54N5BOFSYCN6SMRBKXM4V4TW.py.lock | 0 .../fast/__sc/S1/f_taxi_fare_OFFPEAK.py | 16 + .../fast/__sc/S1/f_taxi_fare_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_taxi_fare_PEAK.py | 16 + .../fast/__sc/S1/f_taxi_fare_PEAK.py.lock | 0 .../fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py | 16 + .../__sc/S1/f_taxi_wait_time_OFFPEAK.py.lock | 0 ...o_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py | 16 + ...t_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py.lock | 0 .../fast/__sc/S1/f_taxi_wait_time_PEAK.py | 16 + .../__sc/S1/f_taxi_wait_time_PEAK.py.lock | 0 ...auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py | 16 + ...dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py.lock | 0 .../fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py | 16 + .../__sc/S1/f_tnc_pool_fare_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_tnc_pool_fare_PEAK.py | 16 + .../fast/__sc/S1/f_tnc_pool_fare_PEAK.py.lock | 0 .../__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py | 16 + .../S1/f_tnc_pool_wait_time_OFFPEAK.py.lock | 0 ...o_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py | 16 + ...t_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py.lock | 0 .../fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py | 16 + .../__sc/S1/f_tnc_pool_wait_time_PEAK.py.lock | 0 ...auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py | 16 + ...dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py.lock | 0 .../fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py | 16 + .../__sc/S1/f_tnc_solo_fare_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_tnc_solo_fare_PEAK.py | 16 + .../fast/__sc/S1/f_tnc_solo_fare_PEAK.py.lock | 0 .../__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py | 16 + .../S1/f_tnc_solo_wait_time_OFFPEAK.py.lock | 0 ...o_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py | 16 + ...t_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py.lock | 0 .../fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py | 16 + .../__sc/S1/f_tnc_solo_wait_time_PEAK.py.lock | 0 ...auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py | 16 + ...dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py.lock | 0 .../fast/__sc/S1/f_transit_fare_OFFPEAK.py | 16 + .../__sc/S1/f_transit_fare_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_transit_fare_PEAK.py | 16 + .../fast/__sc/S1/f_transit_fare_PEAK.py.lock | 0 .../fast/__sc/S1/f_transit_ivtt_OFFPEAK.py | 16 + .../__sc/S1/f_transit_ivtt_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_transit_ivtt_PEAK.py | 16 + .../fast/__sc/S1/f_transit_ivtt_PEAK.py.lock | 0 .../fast/__sc/S1/f_transit_ovtt_OFFPEAK.py | 16 + .../__sc/S1/f_transit_ovtt_OFFPEAK.py.lock | 0 .../fast/__sc/S1/f_transit_ovtt_PEAK.py | 16 + .../fast/__sc/S1/f_transit_ovtt_PEAK.py.lock | 0 .../cmap_modedest/fast/__sc/S2/__init__.py | 312 + .../fast/__sc/S2/__init__.py.lock | 0 ...auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py | 16 + ...avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py.lock | 0 ...auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py | 16 + ...avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py.lock | 0 ...uto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py | 16 + ...vail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py.lock | 0 ...uto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py | 16 + ...vail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py.lock | 0 ...auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py | 16 + ...avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py.lock | 0 ...nsit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py | 16 + ...avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py.lock | 0 ...nsit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py | 16 + ...avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py.lock | 0 ...sit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py | 16 + ...vail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py.lock | 0 ...sit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py | 16 + ...vail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py.lock | 0 ...nsit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py | 16 + ...avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py.lock | 0 .../fast/__sc/S2/f_auto_avail_HBO.py | 16 + .../fast/__sc/S2/f_auto_avail_HBO.py.lock | 0 .../fast/__sc/S2/f_auto_avail_HBS.py | 16 + .../fast/__sc/S2/f_auto_avail_HBS.py.lock | 0 .../fast/__sc/S2/f_auto_avail_HBWH.py | 16 + .../fast/__sc/S2/f_auto_avail_HBWH.py.lock | 0 .../fast/__sc/S2/f_auto_avail_HBWL.py | 16 + .../fast/__sc/S2/f_auto_avail_HBWL.py.lock | 0 .../fast/__sc/S2/f_auto_avail_NHB.py | 16 + .../fast/__sc/S2/f_auto_avail_NHB.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_HBO.py | 16 + .../__sc/S2/f_auto_parking_cost_HBO.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_HBOR.py | 16 + .../__sc/S2/f_auto_parking_cost_HBOR.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_HBS.py | 16 + .../__sc/S2/f_auto_parking_cost_HBS.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_HBWH.py | 16 + .../__sc/S2/f_auto_parking_cost_HBWH.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_HBWL.py | 16 + .../__sc/S2/f_auto_parking_cost_HBWL.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_NHB.py | 16 + .../__sc/S2/f_auto_parking_cost_NHB.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_NHBR.py | 16 + .../__sc/S2/f_auto_parking_cost_NHBR.py.lock | 0 .../fast/__sc/S2/f_auto_parking_cost_NHBS.py | 16 + .../__sc/S2/f_auto_parking_cost_NHBS.py.lock | 0 ...EAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py | 16 + ...4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py.lock | 0 ...EAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py | 16 + ...4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py.lock | 0 ...og_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py | 16 + ...samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py.lock | 0 .../cmap_modedest/fast/__sc/S2/f_samp_wgt.py | 16 + .../fast/__sc/S2/f_samp_wgt.py.lock | 0 ...o_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py | 16 + ...t_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py.lock | 0 ...auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py | 16 + ...dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py.lock | 0 ...o_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py | 16 + ...t_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py.lock | 0 ...auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py | 16 + ...dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py.lock | 0 ...o_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py | 16 + ...t_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py.lock | 0 ...auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py | 16 + ...dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py.lock | 0 .../fast/__sc/S2/f_transit_avail_HBO.py | 16 + .../fast/__sc/S2/f_transit_avail_HBO.py.lock | 0 .../fast/__sc/S2/f_transit_avail_HBS.py | 16 + .../fast/__sc/S2/f_transit_avail_HBS.py.lock | 0 .../fast/__sc/S2/f_transit_avail_HBWH.py | 16 + .../fast/__sc/S2/f_transit_avail_HBWH.py.lock | 0 .../fast/__sc/S2/f_transit_avail_HBWL.py | 16 + .../fast/__sc/S2/f_transit_avail_HBWL.py.lock | 0 .../fast/__sc/S2/f_transit_avail_NHB.py | 16 + .../fast/__sc/S2/f_transit_avail_NHB.py.lock | 0 ...o_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py | 16 + ...t_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py.lock | 0 ...auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py | 16 + ...dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py.lock | 0 .../cmap_modedest/fast/application_data.py | 335 + .../cmap_modedest/fast/parking_cost.py | 102 + .../cmap_modedest/fast/random_generator.py | 42 + .../cmap_modedest/fast/tnc_los.py | 388 + .../cmap_modedest/fast/transit/__init__.py | 0 .../fast/transit/access_egress_distance.py | 165 + .../cmap_modedest/fast/transit/approach.py | 836 + .../cmap_modedest/hh_sampling.py | 25 + src/Mode-Dest-TOD/cmap_modedest/incomes.py | 99 + src/Mode-Dest-TOD/cmap_modedest/modecodes.py | 60 + .../cmap_modedest/numexpr_patch.py | 31 + .../cmap_modedest/parking_costs.py | 371 + src/Mode-Dest-TOD/cmap_modedest/purposes.py | 60 + .../cmap_modedest/random_states.py | 46 + src/Mode-Dest-TOD/cmap_modedest/runtime.py | 40 + .../cmap_modedest/skims/__init__.py | 57 + .../cmap_modedest/skims/compression.py | 191 + .../cmap_modedest/skims/names.py | 15 + .../cmap_modedest/time_of_day_model.py | 130 + .../cmap_modedest/timeperiods.py | 51 + src/Mode-Dest-TOD/cmap_modedest/tnc_costs.py | 124 + .../cmap_modedest/transit_approach.py | 731 + .../cmap_modedest/transit_skim_convolution.py | 265 + src/Mode-Dest-TOD/cmap_modedest/util.py | 138 + src/Mode-Dest-TOD/cmap_modedest/validation.py | 96 + src/Mode-Dest-TOD/nesting-tree.png | Bin 0 -> 43030 bytes src/Mode-Dest-TOD/requirements.txt | 5 + src/Mode-Dest-TOD/setup.py | 62 + .../sharrow/.idea/sharrow_lite.iml | 12 + src/Mode-Dest-TOD/sharrow/LICENSE | 29 + src/Mode-Dest-TOD/sharrow/README.md | 4 + src/Mode-Dest-TOD/sharrow/requirements.txt | 5 + src/Mode-Dest-TOD/sharrow/setup.py | 64 + src/Mode-Dest-TOD/sharrow/sharrow/__init__.py | 19 + src/Mode-Dest-TOD/sharrow/sharrow/dataset.py | 457 + .../sharrow/sharrow/interface.py | 90 + .../sharrow/sharrow/local_dir.py | 6 + src/Mode-Dest-TOD/sharrow/sharrow/logging.py | 142 + src/Mode-Dest-TOD/sharrow/sharrow/maths.py | 80 + src/Mode-Dest-TOD/sharrow/sharrow/tables.py | 102 + src/Mode-Dest-TOD/tests/__init__.py | 0 .../tests/data/HH_VTYPE_TRIPS_IN.TXT | 624 + src/Mode-Dest-TOD/tests/data/MCHO_DISTR.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/MCHO_M01.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/MCHO_M023.TXT | 6 + src/Mode-Dest-TOD/tests/data/MCHW_CBDPARK.TXT | 315 + src/Mode-Dest-TOD/tests/data/MCHW_DISTR.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/MCHW_HH.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/MCHW_M01.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/MCHW_M023.TXT | 6 + src/Mode-Dest-TOD/tests/data/MCNH_DISTR.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/MCNH_M01.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/MCNH_M023.TXT | 6 + .../tests/data/MC_HO_NAMELIST.TXT | 46 + .../tests/data/MC_HWhigh_NAMELIST.TXT | 62 + .../tests/data/MC_HWlow_NAMELIST.TXT | 62 + .../tests/data/MC_NH_NAMELIST.TXT | 46 + src/Mode-Dest-TOD/tests/data/PDHO_DISTR.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/PDHO_M01.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/PDHO_M023.TXT | 6 + .../tests/data/PDHO_NAMELIST.TXT | 38 + src/Mode-Dest-TOD/tests/data/PDHW_CBDPARK.TXT | 315 + src/Mode-Dest-TOD/tests/data/PDHW_DISTR.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/PDHW_M01.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/PDHW_M023.TXT | 6 + .../tests/data/PDHW_NAMELIST.TXT | 39 + src/Mode-Dest-TOD/tests/data/PDNH_DISTR.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/PDNH_M01.TXT | 3632 ++++ src/Mode-Dest-TOD/tests/data/PDNH_M023.TXT | 6 + .../tests/data/PDNH_NAMELIST.TXT | 38 + .../tests/data/TG_HHENUM_OUTPUT.TXT.gz | Bin 0 -> 3006579 bytes .../tests/data/TRIP49_PA_OUT.TXT.gz | Bin 0 -> 4741040 bytes .../tests/data/TRIP49_PA_WFH_OUT.TXT.gz | Bin 0 -> 4099457 bytes src/Mode-Dest-TOD/tests/data/__HW_CBDPARK.TXT | 310 + .../tests/data/__HW_CBDPARK2.TXT | 5 + .../tests/data/cmap_trip_config.yaml | 243 + .../tests/data/default_auto_propensity.csv | 3633 ++++ uv.lock | 542 - 410 files changed, 74669 insertions(+), 30980 deletions(-) delete mode 100644 Database/Telework.yaml delete mode 100644 Database/data/land_use_proportions.csv delete mode 100644 Database/data/tg_rates.csv create mode 100644 Database/macros/tod_skim_setup.mac rename Database/macros/{transit_skim_final_matrices.py => transit_skim_final_matrices1.py} (78%) create mode 100644 Database/macros/transit_skim_final_matrices2.py create mode 100644 Database/tg/fortran/TG_INPUT.TXT create mode 100644 Database/tg/fortran/TG_PopSyn.exe delete mode 100644 Database/tg/fortran/airport_sz.csv delete mode 100644 Database/tg/fortran/coefficients_attractions.csv delete mode 100644 Database/tg/fortran/coefficients_nonhome_productions.csv create mode 100644 Database/tg/fortran/create_HHvtype_file.py create mode 100644 Database/tg/fortran/highinc_workers.csv delete mode 100644 Database/tg/fortran/subzone_tg_data.txt delete mode 100644 Database/tg/fortran/tg_hhtype_lookup.csv delete mode 100644 Database/tg/fortran/tg_hhvtype_lookup.csv delete mode 100644 Database/tg/fortran/wfhmodule/edudist.csv delete mode 100644 Database/tg/fortran/wfhmodule/wfhflag_base.py delete mode 100644 Database/trip_generation/household_trip_enumeration.py delete mode 100644 Database/trip_generation/trip_generation.yaml delete mode 100644 Database/trip_generation/trip_generation_model.py delete mode 100644 Database/trip_generation/vehicle_availability.py create mode 100644 Scripts/manage/env/CMAP-TRIP2.yml create mode 100644 Scripts/manage/env/activate_env.cmd create mode 100644 Scripts/manage/env/emme-plus.yml rename Scripts/{manage_envs => manage/env}/emme.pth (100%) create mode 100644 Scripts/manage/env/set_condapath.cmd delete mode 100644 Scripts/manage_envs/cmap-modedest/cmap-modedest.yml delete mode 100644 Scripts/manage_envs/cmap-modedest/requirements.txt delete mode 100644 Scripts/manage_envs/install_envs.ps1 delete mode 100644 Scripts/manage_envs/tbm-r/tbm-r.yml delete mode 100644 Scripts/manage_envs/uninstall_envs.ps1 rename c25q4_100.emp => c25q2_100.emp (99%) rename c25q4_100.emp.prj => c25q2_100.emp.prj (100%) delete mode 100644 pyproject.toml create mode 100644 src/Mode-Dest-TOD/.gitignore create mode 100644 src/Mode-Dest-TOD/README.md create mode 100644 src/Mode-Dest-TOD/TECHNICALGUIDE.md create mode 100644 src/Mode-Dest-TOD/USERGUIDE.md create mode 100644 src/Mode-Dest-TOD/cmap_modedest/__init__.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/__main__.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/addict.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/ae_distance_sim.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/application.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/choice_model.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/cmap_logging.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/configuration.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/__init__.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/distr_handler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/filepaths.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.csv create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/data_handlers/m01_handler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/m023_handler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/pa_trip_types.csv create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/parking_handler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/shp_handler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/skims_handler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/tabler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/tg_handler.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/data_handlers/visitors.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/deadheading.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/__init__.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_choice.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_config.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_data.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_logging.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_sample_dest.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_skims_convol.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_survey.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/estimation/est_timeofday.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__init__.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/__init__.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/__init__.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_funcs.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_funcs.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_vars.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_vars.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_hov_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_hov_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hiinc_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hiinc_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_hiinc_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_hiinc_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_loinc_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_loinc_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_loinc_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_loinc_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_autopropensity.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_autopropensity.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_OFFPEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_OFFPEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_PEAK.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_PEAK.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/__init__.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/__init__.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBO.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBO.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBS.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBS.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWH.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWH.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWL.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWL.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_NHB.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_NHB.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBO.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBO.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBOR.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBOR.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBS.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBS.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWH.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWH.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWL.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWL.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHB.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHB.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBR.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBR.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBS.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBS.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_samp_wgt.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_samp_wgt.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBO.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBO.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBS.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBS.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWH.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWH.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWL.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWL.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_NHB.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_NHB.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py create mode 100755 src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py.lock create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/application_data.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/parking_cost.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/random_generator.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/tnc_los.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/transit/__init__.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/transit/access_egress_distance.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/fast/transit/approach.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/hh_sampling.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/incomes.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/modecodes.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/numexpr_patch.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/parking_costs.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/purposes.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/random_states.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/runtime.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/skims/__init__.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/skims/compression.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/skims/names.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/time_of_day_model.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/timeperiods.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/tnc_costs.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/transit_approach.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/transit_skim_convolution.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/util.py create mode 100644 src/Mode-Dest-TOD/cmap_modedest/validation.py create mode 100644 src/Mode-Dest-TOD/nesting-tree.png create mode 100644 src/Mode-Dest-TOD/requirements.txt create mode 100644 src/Mode-Dest-TOD/setup.py create mode 100644 src/Mode-Dest-TOD/sharrow/.idea/sharrow_lite.iml create mode 100644 src/Mode-Dest-TOD/sharrow/LICENSE create mode 100644 src/Mode-Dest-TOD/sharrow/README.md create mode 100644 src/Mode-Dest-TOD/sharrow/requirements.txt create mode 100644 src/Mode-Dest-TOD/sharrow/setup.py create mode 100644 src/Mode-Dest-TOD/sharrow/sharrow/__init__.py create mode 100644 src/Mode-Dest-TOD/sharrow/sharrow/dataset.py create mode 100644 src/Mode-Dest-TOD/sharrow/sharrow/interface.py create mode 100644 src/Mode-Dest-TOD/sharrow/sharrow/local_dir.py create mode 100644 src/Mode-Dest-TOD/sharrow/sharrow/logging.py create mode 100644 src/Mode-Dest-TOD/sharrow/sharrow/maths.py create mode 100644 src/Mode-Dest-TOD/sharrow/sharrow/tables.py create mode 100644 src/Mode-Dest-TOD/tests/__init__.py create mode 100644 src/Mode-Dest-TOD/tests/data/HH_VTYPE_TRIPS_IN.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHO_DISTR.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHO_M01.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHO_M023.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHW_CBDPARK.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHW_DISTR.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHW_HH.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHW_M01.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCHW_M023.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCNH_DISTR.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCNH_M01.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MCNH_M023.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MC_HO_NAMELIST.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MC_HWhigh_NAMELIST.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MC_HWlow_NAMELIST.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/MC_NH_NAMELIST.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHO_DISTR.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHO_M01.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHO_M023.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHO_NAMELIST.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHW_CBDPARK.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHW_DISTR.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHW_M01.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHW_M023.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDHW_NAMELIST.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDNH_DISTR.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDNH_M01.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDNH_M023.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/PDNH_NAMELIST.TXT create mode 100755 src/Mode-Dest-TOD/tests/data/TG_HHENUM_OUTPUT.TXT.gz create mode 100644 src/Mode-Dest-TOD/tests/data/TRIP49_PA_OUT.TXT.gz create mode 100644 src/Mode-Dest-TOD/tests/data/TRIP49_PA_WFH_OUT.TXT.gz create mode 100644 src/Mode-Dest-TOD/tests/data/__HW_CBDPARK.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/__HW_CBDPARK2.TXT create mode 100644 src/Mode-Dest-TOD/tests/data/cmap_trip_config.yaml create mode 100644 src/Mode-Dest-TOD/tests/data/default_auto_propensity.csv delete mode 100644 uv.lock diff --git a/.gitignore b/.gitignore index 06b0a8e..ed0389f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ # Ignore compiled Python. **/__pycache__ +# Ignore files generated by installing Python eggs. +src/Mode-Dest-TOD/cmap_modedest.egg-info +src/Mode-Dest-TOD/sharrow/sharrow.egg-info + # Ignore large Emme project files. Database/emmemat Database/emmebank @@ -11,6 +15,7 @@ Database/tg/fortran/HH_IN.TXT Database/tg/fortran/POPSYN_HH.CSV Database/tg/fortran/GQ_IN.TXT Database/tg/fortran/ATTR_IN.TXT +Database/tg/fortran/airport_sz.csv Database/tg/fortran/SCHOOL_IN.CSV Database/tg/fortran/wfhmodule/indusmix.csv @@ -34,10 +39,6 @@ Database/tg/fortran/wfhmodule/synthetic_*.zip Database/TG_HHENUM_OUTPUT.TXT Database/tg/fortran/HH_WFH_STATUS.CSV Database/tg/fortran/SIMULATED_HHVEH.TXT -Database/tg/fortran/households_selected_noWFH_enumeration_count.csv -Database/tg/fortran/households_selected_WFH_enumeration_count.csv -Database/tg/fortran/missing_hhtype.csv -Database/tg/fortran/trip_generation_model_log.txt # Ignore files generated by prep macros. Database/*_DISTR.TXT diff --git a/Database/Submit_Full_Regional_Model_SOLA.bat b/Database/Submit_Full_Regional_Model_SOLA.bat index 07b0c25..1e9ba53 100644 --- a/Database/Submit_Full_Regional_Model_SOLA.bat +++ b/Database/Submit_Full_Regional_Model_SOLA.bat @@ -33,23 +33,34 @@ for /f "eol=# skip=1 tokens=2 delims=:" %%z in (batch_file.yaml) do (set ver=%%z :break0 for /f "eol=# skip=2 tokens=2 delims=:" %%a in (batch_file.yaml) do (set val=%%a & goto break1) :break1 -for /f "eol=# skip=5 tokens=2 delims=:" %%e in (batch_file.yaml) do (set selLinkFile=%%e & goto break2) +for /f "eol=# skip=4 tokens=2 delims=:" %%b in (batch_file.yaml) do (set wfhFile=%%b & goto break2) :break2 -for /f "eol=# skip=8 tokens=2* delims=:" %%g in (batch_file.yaml) do (set transactFilePath1=%%g & set transactFilePath2=%%h & goto break3) +for /f "eol=# skip=5 tokens=2 delims=:" %%c in (batch_file.yaml) do (set wfh=%%c & goto break3) :break3 -for /f "eol=# skip=10 tokens=2 delims=:" %%f in (batch_file.yaml) do (set transitAsmt=%%f & goto break4) +for /f "eol=# skip=6 tokens=2 delims=:" %%d in (batch_file.yaml) do (set tc14=%%d & goto break4) :break4 -for /f "eol=# skip=12 tokens=2 delims=:" %%i in (batch_file.yaml) do (set selLineFile=%%i & goto break5) +for /f "eol=# skip=9 tokens=2 delims=:" %%e in (batch_file.yaml) do (set selLinkFile=%%e & goto break5) :break5 -for /f "eol=# skip=14 tokens=2 delims=:" %%j in (batch_file.yaml) do (set utilFile=%%j & goto break6) +for /f "eol=# skip=12 tokens=2* delims=:" %%g in (batch_file.yaml) do (set transactFilePath1=%%g & set transactFilePath2=%%h & goto break6) :break6 -for /f "eol=# skip=16 tokens=2 delims=:" %%k in (batch_file.yaml) do (set UrbansimFile=%%k & goto break7) +for /f "eol=# skip=14 tokens=2 delims=:" %%f in (batch_file.yaml) do (set transitAsmt=%%f & goto break7) :break7 -for /f "eol=# skip=18 tokens=2 delims=:" %%l in (batch_file.yaml) do (set RSPrun=%%l & goto break8) +for /f "eol=# skip=16 tokens=2 delims=:" %%i in (batch_file.yaml) do (set selLineFile=%%i & goto break8) :break8 +for /f "eol=# skip=18 tokens=2 delims=:" %%j in (batch_file.yaml) do (set utilFile=%%j & goto break9) +:break9 +for /f "eol=# skip=20 tokens=2 delims=:" %%k in (batch_file.yaml) do (set UrbansimFile=%%k & goto break10) +:break10 +for /f "eol=# skip=22 tokens=2 delims=:" %%l in (batch_file.yaml) do (set RSPrun=%%l & goto break11) +:break11 +for /f "eol=# skip=25 tokens=2 delims=:" %%m in (batch_file.yaml) do (set srcCode=%%m & goto break12) +:break12 set ver=%ver:~1,5% set val=%val:~1,3% +set wfhFile=%wfhFile:~1% +set wfh=%wfh:~1% +set tc14=%tc14:~1% set selLinkFile=%selLinkFile:~1% set transitAsmt=%transitAsmt:~1,1% rem Construct complete transit file path @@ -61,6 +72,7 @@ set selLineFile=%selLineFile:~1% set utilFile=%utilFile:~1,1% set UrbansimFile=%UrbansimFile:~1,1% set RSPrun=%RSPrun:~1,1% +set srcCode=%srcCode:~1,1% REM -- Count number of select link files -- set tempCnt=0 for %%a in (%selLinkFile:None=%) do set /a tempCnt+=1 @@ -84,6 +96,9 @@ cd Database @echo --- Model Run Settings --- @echo Conformity version = %ver% @echo Scenario = %val% +@echo Create WFH validation file = %wfhFile% +@echo Usual WFH share = %wfh% +@echo WFH 1-4 days share = %tc14% @echo Highway assignment select link files = %selLinkFile% @echo Location of network transaction files = %transactFilePath% @echo Run transit assignment = %transitAsmt% @@ -91,6 +106,7 @@ if "%transitAsmt%" EQU "T" (@echo Transit assignment select line file = %selLin @echo Save utility files = %utilFile% @echo Create UrbanSim travel time file = %UrbansimFile% @echo RSP evaluation run = %RSPrun% +@echo Have CMAP-TRIP2 use destination-mode choice code in this model setup = %srcCode% @echo ================================================================================== @echo. @@ -103,11 +119,14 @@ set transactFilePath=%transactFilePath:~0,-1% if "%check2%" NEQ "None" ( if not exist Select_Line\%selLineFile% (goto no_select_line_file) ) + +rem Activate Emme Python env +call %~dp0..\Scripts\manage\env\activate_env.cmd emme + @echo -- Verifying select link files -- -uv run macros\verify_select_link.py %file1% %selLinkFile% %RSPrun% %trnAsmt% +call python macros\verify_select_link.py %file1% %selLinkFile% %RSPrun% %trnAsmt% if %ERRORLEVEL% GTR 0 (goto end) - REM Clean up prior to run if exist cache\choice_simulator_trips_out (rmdir /S /Q cache\choice_simulator_trips_out) if exist cache\choice_simulator_trips_out.001 (rmdir /S /Q cache\choice_simulator_trips_out.001) @@ -120,6 +139,7 @@ echo. echo Select Destination Choice-Mode Choice model run mode: echo 1) Minimize run time (default) - resources allocated to support a single model run. echo 2) Balanced - resources allocated to support two simultaneous model runs. +echo [If this is the second of two simultaneous runs: only proceed if srcCode is False (currently set to %srcCode%)] echo. set /a jobs=38 set /a zones=10 @@ -188,6 +208,19 @@ REM PREP WORK CD %~dp0 CD prep_macros +REM Now find R executable +set infile=path.txt +if exist %infile% (del %infile% /Q) +dir "C:\Program Files\R\*R.exe" /s /b >> %infile% 2>nul +set /p path2=<%infile% +set paren=" +set rpath=%paren%%path2%%paren% +echo rpath = %rpath% +call :CheckEmpty2 %infile% +:Rpass +if exist %infile% (del %infile% /Q) +set rfile=create_distr_m01_files + REM -- Start DISTR & M01 Data Processing -- @ECHO. @ECHO Start Time: %date% %time% @@ -196,23 +229,21 @@ if exist report.txt (del report.txt /Q) if exist temp\nul (rmdir temp /S /Q) if not exist temp (mkdir temp) cd .. +if not exist tg\fortran\MCHW_HH.TXT (goto filemiss1) +copy tg\fortran\MCHW_HH.TXT MCHW_HH.TXT /y if not exist tg\data\m01auto.csv (goto filemiss2) if not exist tg\data\m01tg.txt (goto filemiss2) if not exist tg\data\m01type.csv (goto filemiss2) @ECHO. @ECHO -- OBTAINING TRANSIT NETWORK DATA FROM EMME -- -uv run prep_macros/distr_m01_data.py %file1% %val% >> prep_macros\report.txt +call python prep_macros/distr_m01_data.py %file1% %val% >> prep_macros\report.txt if %ERRORLEVEL% GTR 0 (goto issue) cd prep_macros @ECHO. @ECHO -- CREATING FILES FOR SPATIAL ANALYSIS -- @ECHO. -rem Activate R env -call %LOCALAPPDATA%\miniconda3\condabin\conda_hook.bat -call conda activate tbm-r -Rscript create_distr_m01_files.R +%rpath% CMD BATCH %rfile%.R if %ERRORLEVEL% GTR 0 (goto issue) -call conda deactivate @ECHO. @ECHO -- DISTR AND M01 FILES CREATED -- @@ -223,21 +254,32 @@ if exist temp\nul (rmdir temp /S /Q) if exist report.txt (del report.txt /Q) CD .. +rem Activate Python env to build it if necessary +call %~dp0..\Scripts\manage\env\activate_env.cmd +if "%srcCode%" EQU "T" ( + @ECHO -- Ensure CMAP-TRIP2 uses the destination choice-mode choice source code in this model setup -- +python -m pip install -e %~dp0..\src\Mode-Dest-TOD +python -m pip install -e %~dp0..\src\Mode-Dest-TOD\sharrow +) + +rem Activate Emme Python env +call %~dp0..\Scripts\manage\env\activate_env.cmd emme + @ECHO *** Cleaning up databank. *** if exist cleanup.rpt (del cleanup.rpt) -uv run useful_macros\cleanup_for_rerun.py %val%>> cleanup.rpt +call python useful_macros\cleanup_for_rerun.py %val%>> cleanup.rpt if exist reports (del reports) REM RUN FREESKIM TO CREATE TIME, DISTANCE AND TOLL MATRICES @ECHO. @ECHO *** Skimming highway network. *** -uv run prep_macros\free.skim.mac.py %file1% %val% +call python prep_macros\free.skim.mac.py %file1% %val% if %ERRORLEVEL% neq 0 (goto issue) @ECHO. REM IF PRELOAD=1, REPLACE UNCONGESTED TIME AND DISTANCE MATRICES if %preload% EQU 1 (@echo *** Preloading congested times and distances. ***) -if %preload% EQU 1 (uv run prep_macros\preload_congested_times_mac.py %file1% %val%) +if %preload% EQU 1 (call python prep_macros\preload_congested_times_mac.py %file1% %val%) @ECHO ================================================================== REM - LOOP TO RUN MODEL @@ -249,22 +291,22 @@ if %counter% GTR 2 (goto loopend) @ECHO BEGINNING TRANSIT SKIM - FULL MODEL ITERATION %counter% @ECHO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - REM AM Peak Skim -uv run macros/skim_transit.py %val% %counter% AM +call python macros/skim_transit.py %val% %counter% AM if %ERRORLEVEL% neq 0 (goto issue) -uv run macros/transit_triple_indexing.py %val% AM +call python macros/transit_triple_indexing.py AM if %ERRORLEVEL% neq 0 (goto issue) -uv run macros/transit_skim_final_matrices.py AM +call python macros/transit_skim_final_matrices1.py if %ERRORLEVEL% neq 0 (goto issue) -uv run macros/transit_skim_wrapup.py AM +call python macros/transit_skim_wrapup.py %file1% AM if %ERRORLEVEL% neq 0 (goto issue) REM Midday Skim -uv run macros/skim_transit.py %val% %counter% MD +call python macros/skim_transit.py %val% %counter% MD if %ERRORLEVEL% neq 0 (goto issue) -uv run macros/transit_triple_indexing.py %val% MD +call python macros/transit_triple_indexing.py MD if %ERRORLEVEL% neq 0 (goto issue) -uv run macros/transit_skim_final_matrices.py MD +call python macros/transit_skim_final_matrices2.py if %ERRORLEVEL% neq 0 (goto issue) -uv run macros/transit_skim_wrapup.py MD +call python macros/transit_skim_wrapup.py %file1% MD if %ERRORLEVEL% neq 0 (goto issue) @ECHO -- End of Transit Skim Procedures: %date% %time% >> model_run_timestamp.txt @@ -272,20 +314,24 @@ if %ERRORLEVEL% neq 0 (goto issue) @ECHO PREPARING EMMEBANK - FULL MODEL ITERATION %counter% @ECHO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rem @ECHO on -uv run macros\init_HOVsim_databk_mac.py %val% %counter% %file1% +call python macros\init_HOVsim_databk_mac.py %val% %counter% %file1% if %ERRORLEVEL% neq 0 (goto issue) +rem Activate Python env +call %~dp0..\Scripts\manage\env\activate_env.cmd + @ECHO -- Begin Mode-Destination Choice Procedures: %date% %time% >> model_run_timestamp.txt @ECHO. @ECHO RUN CMAP MODE-DESTINATION CHOICE MODEL - FULL MODEL ITERATION %counter% @ECHO - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -call conda activate cmap-modedest -cmap_modedest . --njobs %jobs% --max_zone_chunk %zones% +call cmap_modedest . --njobs %jobs% --max_zone_chunk %zones% if %ERRORLEVEL% NEQ 0 (goto issue) -call conda deactivate @ECHO -- End Mode-Destination Choice Procedures: %date% %time% >> model_run_timestamp.txt @ECHO. +rem Activate Emme Python env +call %~dp0..\Scripts\manage\env\activate_env.cmd emme + @ECHO -- Begin Time-of-Day Procedures: %date% %time% >> model_run_timestamp.txt @ECHO. @ECHO BEGINNING TOD HIGHWAY ASSIGNMENT - FULL MODEL ITERATION %counter% @@ -298,12 +344,12 @@ REM call emme -ng 000 -m macros\ttables.mac %val% %tod_cntr% 92 93 >> blog.txt @ECHO --- End ttables.mac Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt @ECHO --- Begin TOD_network_prep.py Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt -uv run macros\TOD_network_prep.py %val% %tod_cntr% %counter% >> blog.txt +call python macros\TOD_network_prep.py %val% %tod_cntr% %counter% >> blog.txt @ECHO --- End TOD_network_prep.py Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt @ECHO --- Begin assignment Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt @ECHO --- Begin assignment Period %tod_cntr%: %date% %time% --- @ECHO -- Run TOD assignment -- -uv run macros/SOLA_assignment.py %tod_cntr% %sola_threads% %counter% %RSPrun% %tempCnt% %selLinkFile% %trnAsmt% +call python macros/SOLA_assignment.py %tod_cntr% %sola_threads% %counter% %RSPrun% %tempCnt% %selLinkFile% %trnAsmt% if %ERRORLEVEL% NEQ 0 (goto issue) @ECHO --- End assignment Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt @ECHO --- End assignment Period %tod_cntr%: %date% %time% --- @@ -313,7 +359,8 @@ call emme -ng 000 -m macros\balance5I_7c.mac %val% >> blog.txt @ECHO --- End balance5I_7c.mac Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt @ECHO --- Begin time-of-day skim Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt @ECHO --- Complete time of day skims --- -uv run macros/TOD_skim.py %tod_cntr% %val%%counter%%tod_cntr% %sola_threads% +call emme -ng 000 -m macros\TOD_skim_setup.mac %val% %tod_cntr% >> blog.txt +call python macros/TOD_skim.py %file1% %tod_cntr% %val%%counter%%tod_cntr% %sola_threads% if %ERRORLEVEL% NEQ 0 (goto issue) @ECHO -- End Time-of-Day Procedures Period %tod_cntr%: %date% %time% >> model_run_timestamp.txt @ECHO -- End Time-of-Day Procedures for Period %tod_cntr%: %date% %time% -- @@ -323,9 +370,9 @@ if %tod_cntr% LSS 9 (goto tod_loop) REM -- End time-of-day loop -- @ECHO --- Begin Global Iteration MSA skims: %date% %time% >> model_run_timestamp.txt @ECHO --- Begin Global Iteration MSA skims: %date% %time% --- -uv run macros/MSA_iteration_skims.py %file1% 3 %val%%counter%3 %counter% %sola_threads% +call python macros/MSA_iteration_skims.py %file1% 3 %val%%counter%3 %counter% %sola_threads% if %ERRORLEVEL% NEQ 0 (goto issue) -uv run macros/MSA_iteration_skims.py %file1% 5 %val%%counter%5 %counter% %sola_threads% +call python macros/MSA_iteration_skims.py %file1% 5 %val%%counter%5 %counter% %sola_threads% if %ERRORLEVEL% NEQ 0 (goto issue) @ECHO --- End Global Iteration MSA skims: %date% %time% >> model_run_timestamp.txt @ECHO --- End Global Iteration MSA skims: %date% %time% @@ -348,17 +395,17 @@ REM Run script to complete select link analysis, if necessary set /A counter=counter-1 if %tempCnt% EQU 0 (goto skip_sel_link) if %trnAsmt% EQU 1 (goto skip_sel_link) -uv run macros/complete_select_link.py %file1% %val%%counter%9 %val%%counter%0 %tempCnt% %RSPrun% +call python macros/complete_select_link.py %file1% %val%%counter%9 %val%%counter%0 %tempCnt% %RSPrun% if %ERRORLEVEL% NEQ 0 (goto issue) :skip_sel_link @ECHO End Daily Accumulation Procedures: %date% %time% >> model_run_timestamp.txt REM Run script to write link data for MOVES emissions analysis. -uv run post_macros\punchmovesdata.py +call python post_macros\punchmovesdata.py @ECHO Link Data Written for MOVES Emissions Analysis: %date% %time% >> model_run_timestamp.txt -uv run post_macros\final_run_statistics.py +call python post_macros\final_run_statistics.py rem Run script to create input files for MOVES. -uv run post_macros\createMOVESinputfile.py +call python post_macros\createMOVESinputfile.py if %ERRORLEVEL% NEQ 0 (goto issue) @echo %DATE% %TIME% - INFO - MOVES files created >> model_run_timestamp.txt @@ -371,7 +418,7 @@ if "%utilFile%"=="F" (del cache\choice_simulator_trips_out\choice_simulator_util :USskim if "%UrbansimFile%"=="F" (goto skip_UrbanSim) @ECHO Creating skim file for UrbanSim ... -uv run tg\scripts\urbansim_skims.py +call python tg\scripts\urbansim_skims.py :skip_UrbanSim REM The following lines run transit assignment. @@ -379,27 +426,31 @@ if "%transitAsmt%" EQU "T" ( @ECHO Begin Transit Assignment setup: %date% %time% >> model_run_timestamp.txt REM -- Create matrices to hold TOD transit demand if "%RSPrun%" EQU "T" (@ECHO -- Creating HBW transit demand matrices >> model_run_timestamp.txt) - uv run transit_asmt_macros/setup_transit_asmt_2_initialize_matrices.py %file1% %RSPrun% + call python transit_asmt_macros/setup_transit_asmt_2_initialize_matrices.py %file1% %RSPrun% if %ERRORLEVEL% NEQ 0 (goto issue) REM -- Fill matrices with demand (point to conda environment) - uv run transit_asmt_macros\setup_transit_asmt_3_TOD_transit_demand.py %RSPrun% + rem Activate Python env + call %~dp0..\Scripts\manage\env\activate_env.cmd + call python transit_asmt_macros\setup_transit_asmt_3_TOD_transit_demand.py %RSPrun% if %ERRORLEVEL% NEQ 0 (goto issue) @ECHO End Transit Assignment setup >> model_run_timestamp.txt + rem Activate Emme Python env + call %~dp0..\Scripts\manage\env\activate_env.cmd emme @ECHO Submit Transit Assignment >> model_run_timestamp.txt cd transit_asmt_macros - uv run cmap_transit_assignment_runner.py %file1% 1 %val% + call python cmap_transit_assignment_runner.py %file1% 1 %val% if %ERRORLEVEL% GTR 0 (goto issue) cd .. REM -- Delete transit assignment matrices - uv run transit_asmt_macros\delete_transit_skims.py %file1% + call python transit_asmt_macros\delete_transit_skims.py %file1% if %ERRORLEVEL% GTR 0 (goto issue) if "%check2%" NEQ "None" ( REM -- Run select line analysis - uv run transit_asmt_macros\transit_select_line.py %file1% %val% %selLineFile% + call python transit_asmt_macros\transit_select_line.py %file1% %val% %selLineFile% if %ERRORLEVEL% GTR 0 (goto issue) @ECHO -- Completed Select Line Analysis >> model_run_timestamp.txt REM -- Summarize select line boardings - uv run transit_asmt_macros\select_line_boardings.py %file1% %val% %RSPrun% %selLineFile% + call python transit_asmt_macros\select_line_boardings.py %file1% %val% %RSPrun% %selLineFile% if %ERRORLEVEL% GTR 0 (goto issue) @ECHO -- Completed Select Line Boarding Analysis >> model_run_timestamp.txt ) @@ -417,6 +468,13 @@ REM Open tod_factors.xls and create files @ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ goto end +:filemiss1 +@ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@ECHO tg\fortran\MCHW_HH.TXT DOES NOT EXIST!!! +@ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +pause +goto end + :filemiss2 @ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @ECHO VERIFY m01auto.csv, m01tg.txt, m01type.csv EXIST in tg\data!!! @@ -424,6 +482,18 @@ goto end pause goto end +:CheckEmpty2 +if %~z1 == 0 (goto badR) +goto Rpass + +:badR +@ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@ECHO COULD NOT FIND R INSTALLATION. +@ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +@ECHO. +pause +goto end + :mcmiss @ECHO @ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Database/Telework.yaml b/Database/Telework.yaml deleted file mode 100644 index 1adf002..0000000 --- a/Database/Telework.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# ---------------- Work from home module inputs (trip generation) -validationfiles: N -usualwfhpct: 0.0510 -tc14pct: 0.1031 -# ---------------- New Work from home module inputs (trip generation) -wfhpctlow: 0.143 -wfhpctmedium: 0.232 -wfhpcthigh: 0.552 -declinerate: 0.1 -# ---------------- Education portion of WFH workers -# ---------------- Group by high/medium/low WFH rates -# ---------------- 1 for Lower edu level -# ---------------- 2 for Higher edu level -edu: - high: - 1: 0.202 - 2: 0.798 - medium: - 1: 0.268 - 2: 0.732 - low: - 1: 0.305 - 2: 0.695 -# ---------------- Income portion of WFH workers -# ---------------- Group by high/medium/low WFH rates -# ---------------- 1 for Lower income level -# ---------------- 2 for Higher income level -inc: - high: - 1: 0.231 - 2: 0.769 - medium: - 1: 0.418 - 2: 0.582 - low: - 1: 0.353 - 2: 0.647 diff --git a/Database/batch_file.yaml b/Database/batch_file.yaml index 76ebf8c..c0b1d76 100644 --- a/Database/batch_file.yaml +++ b/Database/batch_file.yaml @@ -1,12 +1,16 @@ # Project details -model_version: c26q2 +model_version: c25q2 scenario_code: 100 +# ---------------- Work from home module inputs (trip generation) +validationfiles: N +usualwfhpct: 0.0510 +tc14pct: 0.1031 # ---------------- Select link analysis files: provide file name (ex: RSP32_links.txt [stored in Database\Select_Link\]) or use None # ---------------- Can submit up to 5, comma-separated, any order, no spaces, (ex: None,test4.txt,test1.txt,None,None) selectLinkFile: None,None,None,None,None # ---------------- Transaction file path: include the path to the transaction files that will build the scenario networks in double quotes (spaces OK), # ---------------- point to directory above highway\ and transit\, no ending backslash (ex: "M:\catslib\modelprod\c24q2" or "M:/catslib/modelprod/24q2") -transactionFilePath: "M:/proj1/nrf/Conformity/c25q4" +transactionFilePath: "M:/proj1/nrf/Conformity/c25q2" # ---------------- Run Transit Assignment at the end of the model run? Default is False. runTransitAsmt: False # ---------------- Transit select line analysis file: provide file name (ex: rsp57_line.txt [stored in Database\Select_Line\]) or use None @@ -17,6 +21,6 @@ util_files: False UrbanSim_file: False # ---------------- Is this an RSP evaluation run? Default is False. RSP: False -# ---------------- PUMA version used in Trip Generation. 2010 is the current option. -pumaVersion: 2010 - +# ---------------- sourceCode will force CMAP-TRIP2 to use the source code in this model setup if set to True. Default is True. +# ---------------- Set to False if this is the second of two simultaneous runs being submitted. +sourceCode: True \ No newline at end of file diff --git a/Database/build_scenario_networks.bat b/Database/build_scenario_networks.bat index beae1c9..d0d05f6 100644 --- a/Database/build_scenario_networks.bat +++ b/Database/build_scenario_networks.bat @@ -11,7 +11,7 @@ for /f "eol=# skip=1 tokens=2 delims=:" %%z in (batch_file.yaml) do (set ver=%%z :break0 for /f "eol=# skip=2 tokens=2 delims=:" %%a in (batch_file.yaml) do (set val=%%a & goto break1) :break1 -for /f "eol=# skip=8 tokens=2* delims=:" %%g in (batch_file.yaml) do (set transactFilePath1=%%g & set transactFilePath2=%%h & goto break6) +for /f "eol=# skip=12 tokens=2* delims=:" %%g in (batch_file.yaml) do (set transactFilePath1=%%g & set transactFilePath2=%%h & goto break6) :break6 set ver=%ver:~1,5% @@ -39,14 +39,17 @@ set ok=%ok:y=Y% if not "%ok%"=="Y" (goto end) @echo ================================================================== +rem Activate Emme Python env +call %~dp0..\Scripts\manage\env\activate_env.cmd emme + @ECHO --- Cleaning up databank --- if exist cleanup.rpt (del cleanup.rpt) -uv run useful_macros\cleanup_for_rerun.py %val%>> cleanup.rpt +call python useful_macros\cleanup_for_rerun.py %val%>> cleanup.rpt if exist reports (del reports) @ECHO Cleanup complete. @ECHO --- Creating time-of-day highway and transit networks --- -uv run prep_macros\initialize_scenarios.py +call python prep_macros\initialize_scenarios.py if %ERRORLEVEL% GTR 0 (goto end) @ECHO -- Checking for transit network input errors -- @@ -56,7 +59,7 @@ if exist report\build_transit.error (del report\build_transit.error /Q) :while if %trnscen% GTR %maxscen% (goto loopend) -uv run prep_macros\build_transit_error_check.py %trnscen% +python prep_macros\build_transit_error_check.py %trnscen% if exist report\build_transit.error (goto badnet) set /A trnscen=%trnscen%+2 goto while diff --git a/Database/choice_model_params.yaml b/Database/choice_model_params.yaml index 3ad2d23..f0f2098 100644 --- a/Database/choice_model_params.yaml +++ b/Database/choice_model_params.yaml @@ -77,6 +77,7 @@ HBWL: intrazonal : 0.02173059479852062 log_attraction : 1.0 metra_longtrip : 5.625 + ovtt_dist : -0.076 ovtt_dist : -0.07639147912439262 samp_af : 1.0 totaltime : -0.014712168298471244 diff --git a/Database/data/land_use_proportions.csv b/Database/data/land_use_proportions.csv deleted file mode 100644 index 59f49ab..0000000 --- a/Database/data/land_use_proportions.csv +++ /dev/null @@ -1,3633 +0,0 @@ -"","zone17","propArea" -"1",1,7.09460854997193e-05 -"2",2,0.000109912703908677 -"3",3,0.000108351798769616 -"4",4,8.79199695344484e-05 -"5",5,0.000108081476392989 -"6",6,0.000119513462885129 -"7",7,0.000148779350792582 -"8",8,6.10492716110398e-05 -"9",9,7.60977062383847e-05 -"10",10,0.000111507003558509 -"11",11,0.00011021968753277 -"12",12,0.000105459815297883 -"13",13,9.10959598012768e-05 -"14",14,6.76578429801979e-05 -"15",15,6.2824797579728e-05 -"16",16,7.50765151190544e-05 -"17",17,7.8468591256738e-05 -"18",18,6.09604972124467e-05 -"19",19,8.93872898324428e-05 -"20",20,6.36749937446737e-05 -"21",21,0.000105865608647998 -"22",22,0.000100416552709868 -"23",23,0.000129955873877235 -"24",24,0.000102792161068702 -"25",25,4.66215086045978e-05 -"26",26,6.60163362277968e-05 -"27",27,0.00010963918793867 -"28",28,0.000135171770327988 -"29",29,0.000121570688172301 -"30",30,0.00010978323394288 -"31",31,4.11839440982933e-05 -"32",32,4.37871230176265e-05 -"33",33,5.81481735376668e-05 -"34",34,5.6873675407932e-05 -"35",35,0.000120185103517916 -"36",36,7.15181845377783e-05 -"37",37,6.53552125870132e-05 -"38",38,0.000114741893094857 -"39",39,7.26188298044693e-05 -"40",40,9.75615376003173e-05 -"41",41,7.13990565100378e-05 -"42",42,2.06975204145148e-06 -"43",43,5.17520895959138e-05 -"44",44,7.8562765069568e-05 -"45",45,2.65919972807977e-05 -"46",46,6.9453904782059e-05 -"47",47,6.31367079234347e-05 -"48",48,0.000239310254341515 -"49",49,0.000332429850343703 -"50",50,0.000252486790350859 -"51",51,0.000374971104782443 -"52",52,0.000115751970549862 -"53",53,0.000235565541873836 -"54",54,0.000215273281239209 -"55",55,0.000244343823177208 -"56",56,0.000319410129719748 -"57",57,0.000301075612656147 -"58",58,0.00032643002143816 -"59",59,0.000245977811704878 -"60",60,0.00029499458577802 -"61",61,0.000336550257381565 -"62",62,0.000213432496040462 -"63",63,0.000363687530478774 -"64",64,0.000236050313226866 -"65",65,0.00026078374967046 -"66",66,0.000127055484577668 -"67",67,0.000193851356354039 -"68",68,0.000242759454592311 -"69",69,0.000115056959489806 -"70",70,0.000252951121314838 -"71",71,0.000102140129052406 -"72",72,0.000330950747418252 -"73",73,0.000289097262117488 -"74",74,0.000216428377283891 -"75",75,0.000166137978348446 -"76",76,0.000318302064112812 -"77",77,0.000154580105886894 -"78",78,0.000290442555934173 -"79",79,0.000220470810266646 -"80",80,0.000306562572352121 -"81",81,0.000361346834521608 -"82",82,0.000327160954515996 -"83",83,0.000157106043383149 -"84",84,0.000341637922999603 -"85",85,0.000309258064193544 -"86",86,0.000177395804602629 -"87",87,0.000329936232513857 -"88",88,0.000336010202037464 -"89",89,0.000195989019045693 -"90",90,0.000284354833105859 -"91",91,0.000358140916769153 -"92",92,0.000341031945957806 -"93",93,0.000360055862371785 -"94",94,0.000321976818189821 -"95",95,0.000366495693659948 -"96",96,0.000302771361649045 -"97",97,0.000257621407732688 -"98",98,0.00018226741843086 -"99",99,0.000190721481161173 -"100",100,0.000260839253557052 -"101",101,0.000322944082722953 -"102",102,0.000106930220184946 -"103",103,0.000111011041749015 -"104",104,0.000272520603911642 -"105",105,0.000309330881329141 -"106",106,0.000300744030654323 -"107",107,0.000321656178057151 -"108",108,0.000154940807943219 -"109",109,0.000134602742886408 -"110",110,0.000158386819455311 -"111",111,0.000202834929803622 -"112",112,0.000318906383868916 -"113",113,0.000236807930597965 -"114",114,0.000168425162962178 -"115",115,0.000187348730833215 -"116",116,0.000178094069704533 -"117",117,0.000226022467597891 -"118",118,0.000311314519569877 -"119",119,0.000189046674619712 -"120",120,0.000138553130387356 -"121",121,1.18440332382022e-05 -"122",122,0.000262127182250228 -"123",123,0.000243522795201308 -"124",124,0.000324303176126267 -"125",125,0.000430094738503811 -"126",126,0.00015683406135976 -"127",127,0.000340852484268395 -"128",128,0.000372126868665952 -"129",129,0.000295099846200363 -"130",130,0.000369077205098422 -"131",131,0.000135583553955917 -"132",132,0.000208299623830546 -"133",133,0.00047714191327394 -"134",134,0.00022267685876798 -"135",135,0.000270898512811496 -"136",136,0.000261903320503681 -"137",137,0.000251899142851438 -"138",138,0.000518078316853656 -"139",139,0.000700448198609233 -"140",140,0.000398450290762472 -"141",141,0.000217238266471859 -"142",142,0.000195933507961972 -"143",143,0.000234505667148619 -"144",144,0.000199053300445836 -"145",145,0.000214051562543102 -"146",146,0.000196123268816593 -"147",147,0.000171722233646669 -"148",148,0.000197480025740452 -"149",149,0.000207815984645934 -"150",150,0.00021384445335141 -"151",151,0.000867244582293737 -"152",152,0.000797778796990459 -"153",153,0.000237041753336635 -"154",154,0.000104132344040459 -"155",155,0.000112370040900293 -"156",156,9.89272323980986e-05 -"157",157,0.00018856419168456 -"158",158,1.81893867184448e-05 -"159",159,0.000226701186451272 -"160",1160,0.000280235516310481 -"161",160,0.000172820358224641 -"162",161,0.000205936744488103 -"163",162,0.000215200678309358 -"164",163,0.000253863742995065 -"165",164,0.000288195207869484 -"166",165,0.000133340559662106 -"167",166,0.000318240151763928 -"168",167,0.000247492591160284 -"169",168,0.000300115017880085 -"170",169,0.000194964486186533 -"171",170,0.000249077017808332 -"172",171,0.000333204978335785 -"173",172,0.000240143786347086 -"174",173,0.000141776419970849 -"175",174,0.000296257778750015 -"176",175,0.00032359401389393 -"177",176,2.97728142866671e-05 -"178",177,0.00031449518905973 -"179",178,0.000143406245696006 -"180",179,0.000150382902925022 -"181",180,0.000188431231557805 -"182",181,0.000206757339394851 -"183",182,0.000167592720558609 -"184",183,0.000218403913701407 -"185",184,0.000188048142227697 -"186",185,5.58143518846876e-05 -"187",186,0.000244452607526415 -"188",187,0.000151951058072223 -"189",188,0.000125615618881159 -"190",189,5.65483090398712e-05 -"191",190,4.37317880464471e-05 -"192",191,0.000218064309034966 -"193",192,0.000192628637870337 -"194",193,0.000189609676296651 -"195",194,0.000267399520182976 -"196",195,0.000182693694141169 -"197",196,0.000209100907442613 -"198",197,5.89786079257647e-05 -"199",198,0.000244567521045785 -"200",199,0.000263232769354111 -"201",200,0.000309836382902875 -"202",201,0.000178650742152715 -"203",202,0.000295031623110097 -"204",203,0.000832525887952841 -"205",204,0.00022057431756398 -"206",205,0.000268615702811721 -"207",206,0.000224959592256525 -"208",207,0.000230387590727254 -"209",208,0.000248868949768281 -"210",209,0.000192976719350548 -"211",210,0.000222168634534578 -"212",211,0.000311470266476779 -"213",212,0.00024382430434247 -"214",213,6.0661850170291e-05 -"215",214,0.00024688644450509 -"216",215,0.000282378692990099 -"217",216,4.99308878448203e-05 -"218",217,0.000296638418789072 -"219",218,0.000268661677551408 -"220",219,0.000308049128894755 -"221",220,0.000168787899135561 -"222",221,0.000198651017150954 -"223",222,0.00028193028780702 -"224",223,0.000234314796594947 -"225",224,0.000240586289407502 -"226",225,0.00106731165618088 -"227",226,0.000234235064438056 -"228",227,0.000250114875825464 -"229",228,0.000276885700301369 -"230",229,0.000195485958263558 -"231",230,0.000180456292585033 -"232",231,0.000254823356840376 -"233",232,0.000284134645864979 -"234",233,0.000230846557649238 -"235",234,0.000309947562707417 -"236",235,0.00027082795167321 -"237",236,0.000302157455675431 -"238",237,0.00029446592190759 -"239",238,0.000286659215614921 -"240",239,0.000298759209259928 -"241",240,0.000186190620536598 -"242",241,0.000308617763088947 -"243",242,0.000285874673914047 -"244",243,0.000249147656136261 -"245",244,9.39637626354183e-05 -"246",245,0.000251519911950858 -"247",246,0.000263077968644414 -"248",247,0.000283770993881532 -"249",248,0.000268355658732963 -"250",249,0.000262290781295276 -"251",250,0.000269809794528787 -"252",251,0.000279139290533536 -"253",252,0.000283716322482492 -"254",253,0.000279584157293717 -"255",254,0.000221370800506523 -"256",255,0.000291426870282872 -"257",256,0.000250733612110657 -"258",257,0.000281537094441408 -"259",258,0.000173582470666191 -"260",259,0.000267455003815564 -"261",260,0.000267101989511553 -"262",261,0.000277815546391841 -"263",262,0.000258816683249703 -"264",263,0.000176549100693783 -"265",264,0.000279715545829303 -"266",265,0.000257665484969473 -"267",266,0.000281558494101966 -"268",267,0.000252899397546978 -"269",268,0.000263435468680282 -"270",269,0.000259989347432248 -"271",270,0.000989307529479749 -"272",271,0.00118454885804685 -"273",272,0.000381528028400972 -"274",273,0.000305183584276883 -"275",274,0.000324315647295881 -"276",275,0.000219960381414928 -"277",276,0.000305520525285662 -"278",277,0.00028191001520626 -"279",278,0.000291524320625374 -"280",279,0.000297270851193523 -"281",280,0.000291424439341463 -"282",281,0.000228850736508901 -"283",282,0.000239422342624708 -"284",283,0.00030217118055285 -"285",284,0.000246876080279576 -"286",285,0.000249977037817235 -"287",286,0.000229947085491157 -"288",287,0.000206144159187022 -"289",288,0.000305068116831022 -"290",289,0.000248364347070901 -"291",290,0.000233609826773676 -"292",291,0.000310443132774927 -"293",292,0.000266683165268484 -"294",293,0.000284929911192317 -"295",294,0.000230628540407056 -"296",295,0.000232671455982599 -"297",296,0.000321185089808516 -"298",297,0.000273137723267636 -"299",298,0.000292332038016617 -"300",299,0.000280470725058376 -"301",300,0.00023441479789457 -"302",301,0.000285434507815647 -"303",302,0.000295425783151372 -"304",303,0.000264445239137051 -"305",304,0.000304627496618672 -"306",305,0.000283087185955246 -"307",306,0.000320564731535979 -"308",307,0.000279199495263307 -"309",308,0.000150170726207532 -"310",309,0.000239042690553009 -"311",310,0.000237001926484363 -"312",311,0.000215284527179497 -"313",312,0.000216422153082541 -"314",313,0.000309525034942948 -"315",314,0.000309210156947167 -"316",315,0.000240964242105937 -"317",316,0.000304227788092248 -"318",317,0.000298411222477821 -"319",318,0.00017339728894354 -"320",319,0.000317348150342661 -"321",320,0.000311275544468621 -"322",321,0.0002739756812591 -"323",322,3.21120848507779e-06 -"324",323,0.000231656046852023 -"325",324,0.00030645651350063 -"326",325,0.000320975228300703 -"327",326,0.000329122776448566 -"328",327,0.000275883111254159 -"329",328,0.000327275604640248 -"330",329,0.000265260875581748 -"331",330,0.000363443497357009 -"332",331,0.000149659139505876 -"333",332,0.000153965707238083 -"334",333,0.000327524410694082 -"335",334,0.000306890198035492 -"336",335,0.000295956201905664 -"337",336,0.000325383013693555 -"338",337,0.000317274570630027 -"339",338,0.000381960924081085 -"340",339,0.000342206872705687 -"341",340,0.000320687631436386 -"342",341,0.000361624860403368 -"343",342,0.000219244560534973 -"344",343,0.000263878249151105 -"345",344,0.00026771994991678 -"346",345,0.000308409386740688 -"347",346,0.000286400539609817 -"348",347,0.000360290751715765 -"349",348,0.000373774432946572 -"350",349,0.00034261307869498 -"351",350,0.000350419734629532 -"352",351,9.11997596234333e-05 -"353",352,0.000457227953169251 -"354",353,1.18582212116723e-05 -"355",354,0.000416882251161393 -"356",355,0.000981255194650284 -"357",356,0.000230911190218665 -"358",357,0.00028464966931101 -"359",358,0.000261505221803954 -"360",359,0.000268093317165982 -"361",360,0.000281074491654331 -"362",361,0.000390354134381563 -"363",362,0.000206385443112598 -"364",363,0.000252593394693916 -"365",364,0.000270753615210373 -"366",365,0.000285913220854752 -"367",366,0.000257895063246243 -"368",367,0.000229918187829184 -"369",368,0.00031314573690432 -"370",369,0.000191043241855336 -"371",370,1.51487077360276e-05 -"372",371,0.000335168956630323 -"373",372,0.000214756032882636 -"374",373,0.000220014199731301 -"375",374,0.000196061187411619 -"376",375,0.000217424226717181 -"377",376,0.000205256678589394 -"378",377,0.000208116401510377 -"379",378,0.000208058824464792 -"380",379,0.000263236467311332 -"381",380,0.000181943224763701 -"382",381,0.000236583910581252 -"383",382,0.000162274146775841 -"384",383,0.000159304875028298 -"385",384,0.000142753972206352 -"386",385,0.000201076497030231 -"387",386,0.000227220433824669 -"388",387,0.000206486619210439 -"389",388,0.000234227165548812 -"390",389,0.000201348288663047 -"391",390,0.000204035521245286 -"392",391,9.23405334943998e-05 -"393",392,0.000203100181475407 -"394",393,0.000269957525890716 -"395",394,0.000252597491102619 -"396",395,0.000277235819625842 -"397",396,0.000206312987292342 -"398",397,0.000169603998429038 -"399",398,0.000187917695795518 -"400",399,0.000180917629381886 -"401",400,0.000190386397504419 -"402",401,0.000223395914696354 -"403",402,0.000118992099614732 -"404",403,0.00019509672245115 -"405",404,0.000135349217578874 -"406",405,0.000183718839833656 -"407",406,0.000144795800162069 -"408",407,0.000213461140726853 -"409",408,0.0002212281464628 -"410",409,0.000155299337762317 -"411",410,0.000228921393387001 -"412",411,0.000194332405210111 -"413",412,0.000178815456077136 -"414",413,0.000214431858218459 -"415",414,0.000177705375369601 -"416",415,0.000190536520010475 -"417",416,0.000138151117812361 -"418",417,0.000282418120067259 -"419",418,6.69610104140195e-05 -"420",419,0.000287308067507074 -"421",420,0.000250418039832636 -"422",421,0.00015333919532428 -"423",422,0.000276587991597241 -"424",423,0.000183379280890668 -"425",424,0.000256286314381443 -"426",425,0.000293064552973407 -"427",426,0.000297311605206822 -"428",427,0.000291679211409414 -"429",428,8.68264764524857e-05 -"430",429,0.000293863452963162 -"431",430,0.000260352762222738 -"432",431,0.000222097856290256 -"433",432,0.000449403430205254 -"434",433,0.000266988562142014 -"435",434,8.71305892824034e-05 -"436",435,8.70513791886624e-05 -"437",436,0.000196361142414723 -"438",437,0.000129584505148321 -"439",438,0.000141296796055167 -"440",439,0.000266360183433666 -"441",440,0.000260667788099189 -"442",441,0.000286309428236572 -"443",442,0.000116264044639308 -"444",443,0.000219153376586651 -"445",444,0.000185616747556642 -"446",445,0.000226589651058898 -"447",446,0.000196930102807101 -"448",447,0.000271606437190355 -"449",448,0.00031449190398201 -"450",449,0.00029655643701827 -"451",450,0.000177996748229513 -"452",451,0.000292739196622135 -"453",452,0.000105202090149617 -"454",453,0.000189273619989473 -"455",454,2.85068682540502e-05 -"456",455,0.000207897932516253 -"457",456,0.000119369745988946 -"458",457,8.04590075441591e-05 -"459",458,0.000368010003282667 -"460",459,0.00108284674299263 -"461",460,0.00022054589476491 -"462",461,0.000175845399498965 -"463",462,0.000117362832343631 -"464",463,1.91461855617979e-05 -"465",464,0.000265465820361679 -"466",465,0.00027909986762101 -"467",466,0.000277270135011688 -"468",467,0.000293698312516436 -"469",468,0.000647272960975784 -"470",469,0.000199958042935905 -"471",470,0.000228541282489309 -"472",471,0.00024374671388135 -"473",472,0.000327912121988709 -"474",473,0.000201951608650938 -"475",474,0.00019879033344929 -"476",475,0.000273296918287411 -"477",476,0.000227104344077787 -"478",477,0.000270772505909593 -"479",478,0.000276671237384064 -"480",479,0.000247681728768441 -"481",480,0.000330052681318378 -"482",481,0.000221425493295395 -"483",482,0.000247212026450594 -"484",483,0.000350849316623487 -"485",484,0.000259684765469186 -"486",485,0.000225317525853538 -"487",486,0.000276079790133478 -"488",487,0.000383670544428727 -"489",488,0.000265015245090025 -"490",489,0.000363766646729806 -"491",490,0.000345485532518887 -"492",491,0.000264852889428867 -"493",492,0.000855519565476129 -"494",493,0.000503739559262856 -"495",494,0.000142859548347372 -"496",495,0.000172219098713857 -"497",496,0.000230748405303826 -"498",497,0.000255136283196215 -"499",498,0.000200622255293125 -"500",499,0.000217096865849706 -"501",500,0.000213375869088423 -"502",501,0.00100783605841284 -"503",502,0.00117532858479072 -"504",503,0.000665006302240963 -"505",504,1.78330441824121e-05 -"506",505,0.000216460940374827 -"507",506,0.000237223843483346 -"508",507,0.000241573463403736 -"509",508,0.000299517692764008 -"510",509,0.000272089213753916 -"511",510,0.000312310517512375 -"512",511,0.000258233961904936 -"513",512,0.000206846080168492 -"514",513,0.000192617186065648 -"515",514,0.000226255250861271 -"516",515,0.000842622704096806 -"517",516,0.000577813944965751 -"518",517,0.000878006159337728 -"519",518,0.000181521240747966 -"520",519,0.000179787240880667 -"521",520,0.000186176893696601 -"522",521,0.000170079243628593 -"523",522,0.000688927386111086 -"524",523,0.000315504009084677 -"525",524,0.000144251164751064 -"526",525,0.000266177482486211 -"527",526,0.000179322222177655 -"528",527,0.00110068648174823 -"529",528,0.00021708447708245 -"530",529,8.9530848770386e-05 -"531",530,0.000237453096060458 -"532",531,0.000106778297861457 -"533",532,0.000178867116173865 -"534",533,0.000205450570423434 -"535",534,0.000189696252581319 -"536",535,0.00016576383584045 -"537",536,0.000133272172702038 -"538",537,7.85907823509271e-05 -"539",538,0.000236668042832225 -"540",539,0.000281626990939005 -"541",540,0.000189759857512032 -"542",541,0.000190222232869861 -"543",542,0.000187357388572973 -"544",543,0.000207955969180566 -"545",544,0.000147776489938831 -"546",545,0.000103296808473825 -"547",546,0.000140864612956856 -"548",547,0.000362851280729681 -"549",548,0.000192011195406168 -"550",549,0.000164498913526776 -"551",550,3.69021594095373e-05 -"552",551,0.000254989556816895 -"553",552,0.000288153815687617 -"554",553,0.000225915769297676 -"555",554,0.00029152962580267 -"556",555,0.000182700476389449 -"557",556,4.11746440476184e-05 -"558",557,0.000146910298630629 -"559",558,0.000152215968013465 -"560",559,0.000168241785762396 -"561",560,0.00017698361934237 -"562",561,7.75700243191358e-05 -"563",562,0.000623248502056633 -"564",563,0.000358499701161807 -"565",564,0.000163601029518671 -"566",565,3.20025909966149e-05 -"567",566,0.000197172905732568 -"568",567,0.000159229446173362 -"569",568,0.000269668275960452 -"570",569,0.00015253624374073 -"571",570,0.000338912910858362 -"572",571,0.00017687886972718 -"573",572,3.64339716736457e-05 -"574",573,0.000101674396869734 -"575",574,0.000663461952301357 -"576",575,0.000642217691060155 -"577",576,0.000124410288293401 -"578",577,0.000126689687428949 -"579",578,0.000139123642499851 -"580",579,0.000112191000599635 -"581",580,0.000176942246240131 -"582",581,0.000210770932801222 -"583",582,9.81976744069435e-05 -"584",583,0.000200939607387748 -"585",584,0.000145084396657289 -"586",585,0.000157621152847621 -"587",586,0.000218601260207216 -"588",587,0.000250386226324416 -"589",588,1.36390713687176e-05 -"590",589,1.06624092891657e-05 -"591",590,7.67181700689439e-06 -"592",591,0.00034589098650887 -"593",592,0.000824010736077832 -"594",593,0.000209186357688838 -"595",594,0.000183853007471752 -"596",595,0.000224532877473549 -"597",596,0.000256921244515088 -"598",597,0.000615296496649495 -"599",598,0.000963455340564442 -"600",599,0.000125135538034745 -"601",600,0.000144415156009887 -"602",601,0.000199325649482034 -"603",602,0.00013344942189462 -"604",603,0.000253610748089541 -"605",604,0.000273266219507854 -"606",605,0.000260037408349451 -"607",606,0.000263024845144498 -"608",607,0.000715641252080341 -"609",608,0.00101110597868534 -"610",609,0.000200764223481997 -"611",610,0.000117710015238888 -"612",611,0.000124343948254817 -"613",612,0.000187302287556874 -"614",613,0.000180210863901575 -"615",614,0.000311744938885192 -"616",615,0.000194897827511128 -"617",616,0.000216493744865119 -"618",617,0.000192153256326705 -"619",618,0.000239472656247676 -"620",619,0.000202632845704826 -"621",620,0.000265912445581026 -"622",621,0.000886313402643095 -"623",622,0.000218678387043693 -"624",623,0.000225978962437303 -"625",624,0.000292300563065827 -"626",625,0.000172763539880544 -"627",626,0.00021573362660689 -"628",627,0.000226364419914625 -"629",628,0.00021757938955047 -"630",629,7.46895014206011e-05 -"631",630,0.000151223961252795 -"632",631,0.00080462883925814 -"633",632,0.000570167940519752 -"634",633,0.000337227071807085 -"635",634,0.000620477974295088 -"636",635,0.000478455421389121 -"637",636,0.000155780890203418 -"638",637,0.000185834289797099 -"639",638,0.00015398189938512 -"640",639,8.6618940484214e-05 -"641",640,0.000833611865563294 -"642",641,0.000125063520172852 -"643",642,0.000170086426665959 -"644",643,7.19028218117175e-05 -"645",644,0.00020604028474776 -"646",645,0.000762257002931285 -"647",646,0.00019074760067585 -"648",647,0.000176615964112089 -"649",648,0.000154685646660407 -"650",649,0.000208409147370203 -"651",650,0.000821892107461749 -"652",651,0.000686897696767942 -"653",652,0.000656218709657863 -"654",653,0.000676780451753706 -"655",654,0.00014212357267737 -"656",655,0.000164406845075211 -"657",656,0.000178293144532324 -"658",657,7.99887004437402e-05 -"659",658,0.000173184690817074 -"660",659,2.82719084733076e-05 -"661",660,0.000334208984769455 -"662",661,0.000161689242399108 -"663",662,0.000142497976477657 -"664",663,8.74779697073316e-05 -"665",664,0.000234933790230576 -"666",665,7.30366381855837e-05 -"667",666,7.34378047592492e-05 -"668",667,0.000157586941446458 -"669",668,0.000124536844714666 -"670",669,0.000181006381547087 -"671",670,0.000159053403305076 -"672",671,0.000605096373687869 -"673",672,0.000712552280917929 -"674",673,0.000202053020448827 -"675",674,0.000176006827132615 -"676",675,0.000182016603883886 -"677",676,0.000222622907181113 -"678",677,0.000262733875457073 -"679",678,0.000273549172845694 -"680",679,1.91168514679766e-06 -"681",680,0.00062210608355358 -"682",681,0.000716345117656029 -"683",682,0.000690267710078633 -"684",683,0.00070082043007438 -"685",684,0.000232674943761328 -"686",685,5.33924637259137e-05 -"687",686,0.000142090300453845 -"688",687,7.29181192519466e-05 -"689",688,0.000774090431014063 -"690",689,0.000155020196382407 -"691",690,0.000462054952654316 -"692",691,0.000112321362837193 -"693",692,1.15124273923114e-05 -"694",693,0.000142593085899876 -"695",694,0.000110789282258393 -"696",695,6.39541123308233e-05 -"697",696,3.63229226542332e-05 -"698",697,0.000203419603163199 -"699",698,0.000508101250758362 -"700",699,0.000144690551437285 -"701",700,0.000376603514771805 -"702",701,8.7646736098476e-05 -"703",702,0.000164475632242171 -"704",703,4.58385753236982e-05 -"705",704,0.000119946780222558 -"706",705,0.000244771040065366 -"707",706,2.80914857458893e-06 -"708",707,0.000209519295638328 -"709",708,0.00056050998281817 -"710",709,0.00038801352975909 -"711",710,0.00022669773781382 -"712",711,0.000479917111624661 -"713",712,2.32261182690369e-06 -"714",713,8.81272323046363e-05 -"715",714,0.000190727239866845 -"716",715,5.94614083278234e-05 -"717",716,0.000145419863611266 -"718",717,0.000210565679107471 -"719",718,0.000127922866472129 -"720",719,0.000301817551804629 -"721",720,0.00110035907678969 -"722",721,0.000101727633893313 -"723",722,0.00034500873699785 -"724",723,0.000541187121403804 -"725",724,0.000367841331461025 -"726",725,0.000689162950986896 -"727",726,0.000945261484665261 -"728",727,0.00131241139378976 -"729",728,0.000333763075598466 -"730",729,5.14796739752116e-05 -"731",730,0.000348127504433569 -"732",731,0.000476050256743919 -"733",732,0.000283704867329105 -"734",733,0.000289544898136284 -"735",734,0.000873840551340939 -"736",735,0.00165280525971147 -"737",736,0.000915690048841452 -"738",737,0.00131182040872502 -"739",738,0.00052688206933901 -"740",739,0.000176958012502758 -"741",740,0.000157772695722913 -"742",741,0.000153652518000554 -"743",742,0.000116356355344572 -"744",743,0.000507844002494571 -"745",744,0.00013868652193127 -"746",745,0.000162980496463583 -"747",746,0.000126467881462606 -"748",747,0.000111784480936723 -"749",748,0.000635802030062321 -"750",749,0.000918356315323613 -"751",750,3.22434446327745e-05 -"752",751,0.000115101090282211 -"753",752,0.000148067935097857 -"754",753,0.000121594887438821 -"755",754,0.000194944441125662 -"756",755,0.0001657493208724 -"757",756,0.000152909370227699 -"758",757,0.000145883147638243 -"759",758,0.000579643714628094 -"760",759,0.000156352379607484 -"761",760,0.000201956730153031 -"762",761,9.22646777619987e-05 -"763",762,0.000124718755469779 -"764",763,0.00129458644914344 -"765",764,0.000345426347383075 -"766",765,9.97839161620733e-05 -"767",766,0.000182418386249991 -"768",767,0.000128903015270419 -"769",768,0.000131977620997771 -"770",769,0.000563174469469418 -"771",770,0.000559156529250562 -"772",771,0.000398493692057689 -"773",772,0.000542286391694148 -"774",773,0.000812945648512116 -"775",774,0.000113932671039103 -"776",775,0.000160801901995381 -"777",776,9.14751584963445e-05 -"778",777,8.66204459241059e-05 -"779",778,0.000497202963135738 -"780",779,0.000462766794338077 -"781",780,0.00010215456275724 -"782",781,0.000154443736507214 -"783",782,0.000112192016276673 -"784",783,0.000135660974308576 -"785",784,0.000527016556311966 -"786",785,0.00040912133442171 -"787",786,0.000200759593574926 -"788",787,8.11181511039586e-05 -"789",788,0.000101780551741954 -"790",789,0.000167695125009465 -"791",790,0.000145024100733979 -"792",791,0.000463670299537488 -"793",792,0.000559218337133853 -"794",793,0.000315843144965382 -"795",794,0.000387952941392942 -"796",795,0.000268179653324196 -"797",796,0.000143029323336694 -"798",797,0.000366252835363571 -"799",798,0.00033824712011292 -"800",799,0.000148312841042083 -"801",800,0.000103121772657589 -"802",801,0.000190255686129576 -"803",802,0.000274480288590951 -"804",803,0.000251670229158613 -"805",804,0.000463017798913338 -"806",805,0.000336412037605558 -"807",806,0.000426662735105774 -"808",807,0.000451886205934513 -"809",808,0.000135955438195713 -"810",809,0.000154700354449244 -"811",810,0.000163278732294184 -"812",811,0.000149884488253139 -"813",812,0.000480618960963258 -"814",813,0.000139679212731516 -"815",814,0.000157294435098504 -"816",815,0.000135879369767085 -"817",816,0.000129109233108462 -"818",817,0.000599483038619776 -"819",818,0.000498833246069048 -"820",819,0.000556505731262142 -"821",820,0.000525540438868126 -"822",821,0.000572558834581751 -"823",822,0.000364266365006915 -"824",823,7.71308672992826e-05 -"825",824,0.000136098997810112 -"826",825,0.00021269496552385 -"827",826,0.00014878533164978 -"828",827,0.00051701299047937 -"829",828,0.000536784230669683 -"830",829,0.000556827943436874 -"831",830,0.000151785226538508 -"832",831,0.000137504785290176 -"833",832,0.000131692540218801 -"834",833,0.000161587527427181 -"835",834,0.00190614483137266 -"836",835,0.000239268784237221 -"837",836,0.000341208693649193 -"838",837,0.000774538439742599 -"839",838,0.000380615120117632 -"840",839,0.000123813628691803 -"841",840,0.000196326773253259 -"842",841,0.000140500587938593 -"843",842,0.000143316603527219 -"844",843,0.000585489924117377 -"845",844,0.000151294326266156 -"846",845,0.000123826124986602 -"847",846,8.34005017617575e-05 -"848",847,0.000162626282607686 -"849",848,0.000223026436287129 -"850",849,0.000137041701503113 -"851",850,0.000218584945536175 -"852",851,0.000141646630741805 -"853",852,0.000153820882312834 -"854",853,5.01468877673492e-05 -"855",854,0.000142221851642817 -"856",855,8.87825689486819e-05 -"857",856,0.000140522352982308 -"858",857,0.000604054721078385 -"859",858,0.000607703069074234 -"860",859,0.000123249946352107 -"861",860,0.000116661856929839 -"862",861,0.000154108168130084 -"863",862,0.000150253985410293 -"864",863,0.000627376836303386 -"865",864,0.000673565564088246 -"866",865,0.000215411312981659 -"867",866,0.0004899247621576 -"868",867,0.000642759700342097 -"869",868,0.000467689471399124 -"870",869,0.000466560602140407 -"871",870,0.000936145059412526 -"872",871,0.000172549692886065 -"873",872,0.000585977277895133 -"874",873,0.000637885156764181 -"875",874,0.000574497504702016 -"876",875,0.000326379870970095 -"877",876,0.000603942047007195 -"878",877,0.000178675696637178 -"879",878,0.000201023624795749 -"880",879,0.000158335162431888 -"881",880,0.000125390266625419 -"882",881,0.000172542364609214 -"883",882,0.000180987543458173 -"884",883,0.000126107470997903 -"885",884,0.000147852143534677 -"886",885,0.000158777053480954 -"887",886,0.000211709634639106 -"888",887,0.00014171233878757 -"889",888,0.000169921412514312 -"890",889,0.000433663596227889 -"891",890,9.85745209567973e-05 -"892",891,7.37172563589274e-05 -"893",892,0.000195875445012119 -"894",893,0.000121343078090406 -"895",894,0.000509425516085547 -"896",895,0.000434357884414113 -"897",896,0.000135913451327863 -"898",897,0.000205828651355035 -"899",898,0.000121089115664116 -"900",899,0.000162325795386714 -"901",900,0.000639198336629352 -"902",901,0.000576562393738539 -"903",902,0.000579183724752996 -"904",903,0.000780551530957953 -"905",904,0.000294431408552234 -"906",905,0.000254180852351316 -"907",906,0.000179501156639597 -"908",907,0.000185509235898658 -"909",908,0.000134607239833591 -"910",909,0.000189105368968777 -"911",910,0.00060759923977671 -"912",911,0.000634552202553209 -"913",912,0.000481290820865144 -"914",913,0.00015351538345295 -"915",914,0.000144966460129117 -"916",915,0.000172257174547841 -"917",916,0.000177803573113016 -"918",917,1.53920176619894e-05 -"919",918,0.000424577717527471 -"920",919,0.00015346159697017 -"921",920,0.000184677841885789 -"922",921,0.00024157890563056 -"923",922,0.000181778999409713 -"924",923,0.000147463666512791 -"925",924,0.000169034572746149 -"926",925,0.000147703145901928 -"927",926,0.000156615589383672 -"928",927,0.000642663299790577 -"929",928,0.000259657435211058 -"930",929,0.000131875282403532 -"931",930,0.000216768794861057 -"932",931,0.00022389440259761 -"933",932,0.000184759644848035 -"934",933,0.000106741828282351 -"935",934,0.000211446150059686 -"936",935,0.00016183208192007 -"937",936,0.000255512655372446 -"938",937,0.000150921066894658 -"939",938,0.000192545610896051 -"940",939,0.000168216218967066 -"941",940,0.000133952000088462 -"942",941,0.000497707110259576 -"943",942,0.000224807783612358 -"944",943,0.000742293566641765 -"945",944,0.000248337363963865 -"946",945,0.000505900542063335 -"947",946,0.00123173798123178 -"948",947,0.000712747748467894 -"949",948,4.39503727141972e-05 -"950",949,0.000265559315296022 -"951",950,0.000218167997385984 -"952",951,4.690321476564e-05 -"953",952,0.000620957474554785 -"954",953,0.00147885516384315 -"955",954,0.00152716460506465 -"956",955,0.000607801018164485 -"957",956,0.000846252426895049 -"958",957,0.00036669639739685 -"959",958,0.00028624424943975 -"960",959,0.000310671611594875 -"961",960,0.000193005237373783 -"962",961,0.000487086897920424 -"963",962,0.000466171858805983 -"964",963,0.000591614710447375 -"965",964,0.00052220125488037 -"966",965,0.000248338275606637 -"967",966,0.000220041451922092 -"968",967,0.00024500735833876 -"969",968,0.000535094637764697 -"970",969,0.000597958940873767 -"971",970,0.00040489222763356 -"972",971,0.000300556842482095 -"973",972,0.000235795720637058 -"974",973,0.000177256089215758 -"975",974,0.000495550606351208 -"976",975,0.000597350758446377 -"977",976,0.000555637315353929 -"978",977,0.000495514320933166 -"979",978,0.000465943797871498 -"980",979,0.000296165805345265 -"981",980,0.000370023667258563 -"982",981,0.000537394701337617 -"983",982,0.0001294483882464 -"984",983,0.000187605142348778 -"985",984,0.000225217152250911 -"986",985,0.000131053390062019 -"987",986,0.000141976475490186 -"988",987,0.000103364866856634 -"989",988,0.000188145002605545 -"990",989,6.87949103538064e-05 -"991",990,7.74919880968197e-05 -"992",991,0.000125821020289249 -"993",992,0.000190197827175482 -"994",993,0.000150796747199557 -"995",994,0.000380014508341264 -"996",995,0.000540503245505669 -"997",996,0.000475136540640966 -"998",997,0.000166303555617774 -"999",998,0.00014311840397109 -"1000",999,0.000142822859547802 -"1001",1000,0.00014438283536161 -"1002",1001,0.000272911873979597 -"1003",1002,0.000514856456055164 -"1004",1003,0.000228672343390988 -"1005",1004,0.000157996459333026 -"1006",1005,0.000342361196019837 -"1007",1006,0.000459453642899308 -"1008",1007,0.000457270757375246 -"1009",1008,0.000470881700878334 -"1010",1009,0.000108680845546313 -"1011",1010,0.000197044309855125 -"1012",1011,0.000252012555228567 -"1013",1012,0.000158587527102169 -"1014",1013,0.000246350296501647 -"1015",1014,0.000199624977596241 -"1016",1015,0.00016223497170741 -"1017",1016,0.000179450498822607 -"1018",1017,0.000140856461269306 -"1019",1018,0.000199158946973816 -"1020",1019,0.000188854773010967 -"1021",1020,0.000194185543107441 -"1022",1021,0.000220950391385021 -"1023",1022,0.000736935363764238 -"1024",1023,0.00060286452244339 -"1025",1024,0.000154800317977731 -"1026",1025,0.00016212805132038 -"1027",1026,0.000161376891765926 -"1028",1027,0.000211064984275609 -"1029",1028,0.000323124247541834 -"1030",1029,0.000193130657084293 -"1031",1030,0.000131371485058836 -"1032",1031,0.000156362821241575 -"1033",1032,0.000170481808545945 -"1034",1033,0.000510702145233563 -"1035",1034,0.000178334051095266 -"1036",1035,0.000694371362275782 -"1037",1036,0.00018484760579461 -"1038",1037,0.000907653146465442 -"1039",1038,0.000172208694990502 -"1040",1039,0.000221733772184931 -"1041",1040,9.0965085960054e-05 -"1042",1041,0.000142711259512597 -"1043",1042,0.000206779447744417 -"1044",1043,3.67241116003264e-07 -"1045",1044,0.000157007038783318 -"1046",1045,3.86144787321775e-05 -"1047",1046,0.000197040151017681 -"1048",1047,0.000185212052720534 -"1049",1048,9.73879384122867e-05 -"1050",1049,0.000195331132451425 -"1051",1050,0.000175128316459525 -"1052",1051,0.000127604450014213 -"1053",1052,0.000180535258798077 -"1054",1053,0.000115445579217597 -"1055",1054,0.000125577570624214 -"1056",1055,9.73792200672521e-05 -"1057",1056,0.000126749466432625 -"1058",1057,8.91753098535001e-05 -"1059",1058,5.71832257556841e-05 -"1060",1059,0.000133085289771807 -"1061",1060,0.000188563097625305 -"1062",1061,0.000256715487354682 -"1063",1062,6.9449353824136e-05 -"1064",1063,0.000182372565305437 -"1065",1064,0.000215086590570427 -"1066",1065,0.000173125430407666 -"1067",1066,0.000156622448032178 -"1068",1067,0.00017968851795234 -"1069",1068,0.000201655402879163 -"1070",1069,0.000300768856130708 -"1071",1070,0.000415113161691492 -"1072",1071,0.00018759893426368 -"1073",1072,0.000322055130194418 -"1074",1073,0.000529269931405445 -"1075",1074,0.000200130890355195 -"1076",1075,0.000575281754074776 -"1077",1076,0.000417099244241675 -"1078",1077,0.000333905219800422 -"1079",1078,0.000427083047494074 -"1080",1079,0.000554897149534317 -"1081",1080,0.000474642537806849 -"1082",1081,0.000625184270049787 -"1083",1082,0.000612286798670131 -"1084",1083,0.000186672344493596 -"1085",1084,0.000162285804219864 -"1086",1085,0.000184263499215993 -"1087",1086,0.000152213180805329 -"1088",1087,0.000160564834869986 -"1089",1088,0.000201701205202898 -"1090",1089,0.00015541525705169 -"1091",1090,0.000160431054391894 -"1092",1091,0.000426859437767568 -"1093",1092,0.000354033424140713 -"1094",1093,5.73485044060697e-05 -"1095",1094,0.000464053427792989 -"1096",1095,0.000288985519687773 -"1097",1096,0.000207848969588094 -"1098",1097,0.000184164865410463 -"1099",1098,0.000173233344820739 -"1100",1099,0.000198694395057438 -"1101",1100,0.000210026499491172 -"1102",1101,7.51030362898225e-05 -"1103",1102,0.000165107077444309 -"1104",1103,0.000164489476725512 -"1105",1104,0.000400108116418484 -"1106",1105,0.000135563972532627 -"1107",1106,0.000108526913851514 -"1108",1107,0.000211857175479168 -"1109",1108,0.000190109722825307 -"1110",1109,0.000184567843002363 -"1111",1110,0.000198951031497682 -"1112",1111,0.000215039761615136 -"1113",1112,0.00017921740456813 -"1114",1113,0.000665323537229825 -"1115",1114,0.000195827888953269 -"1116",1115,0.000133812705857412 -"1117",1116,0.000156203100919615 -"1118",1117,0.00017105054448216 -"1119",1118,2.53698055439272e-05 -"1120",1119,0.000186003403723203 -"1121",1120,7.44568752708114e-05 -"1122",1121,0.000180875833923273 -"1123",1122,0.000179768773346741 -"1124",1123,0.000175923954637304 -"1125",1124,0.000208223756427315 -"1126",1125,0.000359728549078599 -"1127",1126,0.000197021158904873 -"1128",1127,0.000146545224256834 -"1129",1128,0.000252360426743306 -"1130",1129,0.000180038248389182 -"1131",1130,0.00013288611591854 -"1132",1131,5.47771160935669e-05 -"1133",1132,0.000216239875597997 -"1134",1133,0.000190406561373831 -"1135",1134,0.000234996011675845 -"1136",1135,0.000254442933035638 -"1137",1136,0.000158002179702013 -"1138",1137,0.000185918357517116 -"1139",1138,0.000184808988358788 -"1140",1139,0.000240032739551177 -"1141",1140,0.000161888201821943 -"1142",1141,0.000157302132639865 -"1143",1142,0.000175781597859051 -"1144",1143,0.000199067770316538 -"1145",1144,0.000268513092070768 -"1146",1145,0.000199766696827729 -"1147",1146,7.0522138433057e-05 -"1148",1147,0.000164763591362037 -"1149",1148,0.000335896692209394 -"1150",1149,6.73726433308691e-05 -"1151",1150,0.00111504093263311 -"1152",1151,0.000195945840688903 -"1153",1152,0.000277462425001908 -"1154",1153,0.000166468388306509 -"1155",1154,0.000165058663386055 -"1156",1155,0.000212207510976318 -"1157",1156,0.000178521718614121 -"1158",1157,0.000176939603716385 -"1159",1158,0.000114691566558946 -"1160",1159,0.000739957544019803 -"1161",1161,0.00015826651130787 -"1162",1162,0.000186423099943489 -"1163",1163,0.000194144330950618 -"1164",1164,0.000182706246215152 -"1165",1165,0.000200307426838603 -"1166",1166,3.59363753668619e-05 -"1167",1167,0.000221576019363086 -"1168",1168,0.000323223999225356 -"1169",1169,0.000192559355638636 -"1170",1170,0.000161943099290158 -"1171",1171,0.000220388186613681 -"1172",1172,0.000184181887729791 -"1173",1173,0.000150492108165712 -"1174",1174,0.00029028766190922 -"1175",1175,0.000159551513659869 -"1176",1176,0.000291787337793132 -"1177",1177,0.000203153434692462 -"1178",1178,0.00024961455619979 -"1179",1179,3.21456949612008e-05 -"1180",1180,0.000225664060805505 -"1181",1181,0.000216663946474512 -"1182",1182,0.000229726066460507 -"1183",1183,0.000444466068490434 -"1184",1184,0.000131983475620418 -"1185",1185,0.000302631135963619 -"1186",1186,0.000237772557930212 -"1187",1187,0.000194650931123674 -"1188",1188,0.000282154072733701 -"1189",1189,0.000203780270653033 -"1190",1190,4.69361683515937e-05 -"1191",1191,0.000843067255579518 -"1192",1192,0.000744830426222338 -"1193",1193,0.00024874981764191 -"1194",1194,0.000202100655357532 -"1195",1195,0.000220798193360159 -"1196",1196,0.000120654651175796 -"1197",1197,0.000513838781868961 -"1198",1198,0.000113386022110835 -"1199",1199,0.000143044058296884 -"1200",1200,0.000235183976711206 -"1201",1201,0.000113752176090314 -"1202",1202,0.000148326168691144 -"1203",1203,0.00018635573414734 -"1204",1204,0.000152650592855862 -"1205",1205,0.000175147661559168 -"1206",1206,0.000187185359750202 -"1207",1207,0.000161047599488494 -"1208",1208,0.000229094522656639 -"1209",1209,0.000248816488235966 -"1210",1210,3.7355317689824e-05 -"1211",1211,0.000148920979881583 -"1212",1212,0.000194976640459064 -"1213",1213,0.000108445481562437 -"1214",1214,0.000240171457424224 -"1215",1215,0.000269579834556578 -"1216",1216,0.00024759019311125 -"1217",1217,0.000746153756134096 -"1218",1218,0.000626489000058788 -"1219",1219,0.000391798339180535 -"1220",1220,0.000152257325315127 -"1221",1221,0.000103728680782423 -"1222",1222,0.000296840716867854 -"1223",1223,0.00118856866903728 -"1224",1224,0.000272969346848962 -"1225",1225,0.000255405257339644 -"1226",1226,0.000196046426870031 -"1227",1227,0.000102820113752346 -"1228",1228,0.000207815317780978 -"1229",1229,0.000401598168892779 -"1230",1230,0.000173256736469862 -"1231",1231,0.000176118989843202 -"1232",1232,0.000179768029701984 -"1233",1233,0.000151171166749788 -"1234",1234,0.000125403898820587 -"1235",1235,0.000187259573114263 -"1236",1236,0.000279141464770723 -"1237",1237,0.000318191910104508 -"1238",1238,0.000248841235877774 -"1239",1239,0.00018169313277167 -"1240",1240,0.000218514434051712 -"1241",1241,0.000217154353553166 -"1242",1242,0.000162417363396104 -"1243",1243,1.23266662140581e-05 -"1244",1244,0.000168373592597656 -"1245",1245,6.43093161472371e-05 -"1246",1246,0.00015677542396364 -"1247",1247,0.000180789036394978 -"1248",1248,0.000164582777597983 -"1249",1249,0.000160478735478262 -"1250",1250,0.000458153830298886 -"1251",1251,0.000776021601519527 -"1252",1252,0.000191190982655163 -"1253",1253,0.000135496039730598 -"1254",1254,0.00021374035909082 -"1255",1255,0.000195965321276824 -"1256",1256,0.000234562131647092 -"1257",1257,0.000209255401564608 -"1258",1258,0.000188285924923192 -"1259",1259,0.000169923208954252 -"1260",1260,6.59286814198292e-05 -"1261",1261,0.000172055996855351 -"1262",1262,5.90069018243626e-05 -"1263",1263,0.00016129053902294 -"1264",1264,0.00018007667082163 -"1265",1265,0.000275494421129433 -"1266",1266,0.000171018849870792 -"1267",1267,0.000166254567667653 -"1268",1268,0.000230015390254312 -"1269",1269,0.000594083862046629 -"1270",1270,0.000241618992927817 -"1271",1271,0.000128726052004938 -"1272",1272,0.000209841205780879 -"1273",1273,0.000163451643076321 -"1274",1274,0.000733992967154119 -"1275",1275,2.06066248826638e-05 -"1276",1276,0.000173270226366867 -"1277",1277,0.000151754233550433 -"1278",1278,0.000103489683278776 -"1279",1279,0.000264949298087614 -"1280",1280,0.000115246959851856 -"1281",1281,9.58478372027138e-05 -"1282",1282,0.000203604981897648 -"1283",1283,8.59621169342578e-05 -"1284",1284,0.000497557745839722 -"1285",1285,0.000149698822229796 -"1286",1286,0.000173172440922313 -"1287",1287,0.000243472442603156 -"1288",1288,0.000263517117081116 -"1289",1289,0.000180594013678541 -"1290",1290,0.000351119344147189 -"1291",1291,0.000186981192999847 -"1292",1292,0.000127660840991298 -"1293",1293,0.000455766523448413 -"1294",1294,0.000586965670550797 -"1295",1295,0.000207608039736806 -"1296",1296,0.000684187311384601 -"1297",1297,0.000416331244868246 -"1298",1298,0.000481517396024137 -"1299",1299,0.000240342575492935 -"1300",1300,0.000153644298709011 -"1301",1301,0.00014403330022058 -"1302",1302,0.000207108274088489 -"1303",1303,0.000196165127127736 -"1304",1304,3.11828820962404e-05 -"1305",1305,0.000147339535448018 -"1306",1306,0.000180083477587741 -"1307",1307,0.000165544013701885 -"1308",1308,0.000118168889366646 -"1309",1309,0.000163631917318659 -"1310",1310,0.000667962027548527 -"1311",1311,0.000386645689844399 -"1312",1312,0.000534651084376163 -"1313",1313,0.000172594054623668 -"1314",1314,0.000223391000633722 -"1315",1315,0.000200161726393839 -"1316",1316,0.000189818646657364 -"1317",1317,0.00031859633708409 -"1318",1318,0.000225993902769207 -"1319",1319,0.000328063657202783 -"1320",1320,0.000232502466951506 -"1321",1321,0.000230692505692736 -"1322",1322,0.000242015391064961 -"1323",1323,0.000223760986355321 -"1324",1324,0.000219258177527464 -"1325",1325,0.000223260245769816 -"1326",1326,0.000223886156847389 -"1327",1327,0.000261724822082681 -"1328",1328,0.000233562318564435 -"1329",1329,0.000296245034299983 -"1330",1330,0.000289467203225906 -"1331",1331,0.000276933812464914 -"1332",1332,0.000264096700151551 -"1333",1333,0.00106099666213717 -"1334",1334,0.000225087716409961 -"1335",1335,0.000252237088804875 -"1336",1336,0.00033343948087957 -"1337",1337,0.000273716813163038 -"1338",1338,0.000228247149806408 -"1339",1339,0.000245553445623284 -"1340",1340,0.000291908730363957 -"1341",1341,0.000228234197588915 -"1342",1342,0.00027342819359785 -"1343",1343,0.000286215511441072 -"1344",1344,0.000212367447531408 -"1345",1345,7.52325468542962e-05 -"1346",1346,0.00021714270226092 -"1347",1347,0.000267413516844114 -"1348",1348,0.000169136285052934 -"1349",1349,0.000100071990857503 -"1350",1350,0.000221942738309474 -"1351",1351,0.000237140390963165 -"1352",1352,0.000257294029122499 -"1353",1353,0.000251458637618704 -"1354",1354,0.000294376162070591 -"1355",1355,0.000200491875733327 -"1356",1356,0.00018184444802431 -"1357",1357,0.000220434806668937 -"1358",1358,0.000205760984806518 -"1359",1359,0.000171799458745735 -"1360",1360,0.000144434588895949 -"1361",1361,0.000169322201807277 -"1362",1362,0.00051536372744919 -"1363",1363,0.000642011188008706 -"1364",1364,0.000197881680679996 -"1365",1365,0.00016349992746871 -"1366",1366,0.000175710234391076 -"1367",1367,0.000221148365566631 -"1368",1368,0.000731284823530134 -"1369",1369,0.000118021009165231 -"1370",1370,0.000200026159561369 -"1371",1371,0.000189825653931419 -"1372",1372,0.000110297512006458 -"1373",1373,0.000391895834342892 -"1374",1374,0.000527956469829946 -"1375",1375,0.000545677182179395 -"1376",1376,0.000180846547694554 -"1377",1377,0.000176948042577632 -"1378",1378,0.000295770245985789 -"1379",1379,0.000139714557205183 -"1380",1380,0.000504780917347567 -"1381",1381,0.000563398594085014 -"1382",1382,0.00023557399355914 -"1383",1383,0.000393956762048788 -"1384",1384,0.000455011191986884 -"1385",1385,0.000683103622726881 -"1386",1386,8.52762282817453e-05 -"1387",1387,5.53738080986553e-05 -"1388",1388,9.45620785507325e-05 -"1389",1389,0.00023557098990672 -"1390",1390,0.00014653205242947 -"1391",1391,0.000263402108761569 -"1392",1392,0.00040345513805534 -"1393",1393,0.000159575154210355 -"1394",1394,0.000148166326977361 -"1395",1395,6.04728898295543e-05 -"1396",1396,3.4909863918044e-05 -"1397",1397,0.000218924862386734 -"1398",1398,0.000300645118441876 -"1399",1399,0.000270459856239955 -"1400",1400,0.000526437585828366 -"1401",1401,0.0004032184528771 -"1402",1402,0.000286960297532526 -"1403",1403,0.000264750516991348 -"1404",1404,0.000333905774233046 -"1405",1405,0.000193004723213501 -"1406",1406,0.000754907138116655 -"1407",1407,0.000333775190413312 -"1408",1408,0.000290972126378906 -"1409",1409,0.000258713002899338 -"1410",1410,0.000241896249814006 -"1411",1411,0.000540225671176403 -"1412",1412,0.000157698306695736 -"1413",1413,0.00019412858602687 -"1414",1414,0.000236701242630307 -"1415",1415,0.000147065555883815 -"1416",1416,0.000576944764809568 -"1417",1417,0.000348545966205479 -"1418",1418,0.000317785987867642 -"1419",1419,0.000169392219159546 -"1420",1420,0.000355525728218811 -"1421",1421,0.000203506268734982 -"1422",1422,0.00020710586575091 -"1423",1423,0.000107523521233702 -"1424",1424,0.000187755522805058 -"1425",1425,0.000122825549165019 -"1426",1426,0.000165364420651487 -"1427",1427,0.000301195218279159 -"1428",1428,0.000172254024929636 -"1429",1429,8.72986105700344e-05 -"1430",1430,0.000193245586906563 -"1431",1431,0.000351625894435494 -"1432",1432,0.000148939908160339 -"1433",1433,0.0002756105495737 -"1434",1434,0.00020912948740072 -"1435",1435,0.000349311635868395 -"1436",1436,0.000326463726446431 -"1437",1437,0.000168292425497221 -"1438",1438,0.000626783774380918 -"1439",1439,0.000669661802123435 -"1440",1440,0.00062911707591456 -"1441",1441,0.000260202812364948 -"1442",1442,0.000311151110383807 -"1443",1443,0.000310293769794891 -"1444",1444,0.00129917345882888 -"1445",1445,0.00118107341910087 -"1446",1446,0.000319983092786607 -"1447",1447,0.000175210406310946 -"1448",1448,0.000521119749256986 -"1449",1449,0.000588839656065486 -"1450",1450,0.000137821825869056 -"1451",1451,0.000264641372848887 -"1452",1452,0.000141890747099627 -"1453",1453,0.000124182510240189 -"1454",1454,7.87348929413182e-05 -"1455",1455,9.31366025750693e-05 -"1456",1456,0.000133953316695327 -"1457",1457,0.000139699620768492 -"1458",1458,0.000708513389608698 -"1459",1459,1.58587570100662e-05 -"1460",1460,0.000177815426033403 -"1461",1461,0.000558083891108499 -"1462",1462,0.00035176956876828 -"1463",1463,0.00044410203585704 -"1464",1464,0.000357474041217382 -"1465",1465,0.000496535489367006 -"1466",1466,0.000893972721554769 -"1467",1467,0.000284166562727627 -"1468",1468,0.000495992991416644 -"1469",1469,0.000340681865535765 -"1470",1470,0.000434170226675345 -"1471",1471,0.000593824910134499 -"1472",1472,0.00070889724635315 -"1473",1473,0.000707084971255789 -"1474",1474,0.000210618685393361 -"1475",1475,0.000180267821341828 -"1476",1476,0.000211032799154723 -"1477",1477,0.000224746755643898 -"1478",1478,2.18239265806209e-05 -"1479",1479,0.000180828223845012 -"1480",1480,0.000191701475169657 -"1481",1481,9.21563188214742e-06 -"1482",1482,0.000185430903080867 -"1483",1483,0.000181987516875579 -"1484",1484,9.29235610902705e-05 -"1485",1485,0.000159224910625552 -"1486",1486,0.000736448307859344 -"1487",1487,0.000120560580125077 -"1488",1488,0.000168179387502132 -"1489",1489,0.000185972936186738 -"1490",1490,0.000134095766679387 -"1491",1491,0.000548147452245097 -"1492",1492,0.000692357056514844 -"1493",1493,0.000188104563671842 -"1494",1494,0.000187543501600447 -"1495",1495,0.000157391040957184 -"1496",1496,0.000225026014439323 -"1497",1497,0.000184583135943715 -"1498",1498,0.000211182281820721 -"1499",1499,0.000200240079329743 -"1500",1500,0.000150222981126052 -"1501",1501,0.000104542479993059 -"1502",1502,0.000152195636307063 -"1503",1503,0.000140248810472915 -"1504",1504,0.000173972337800812 -"1505",1505,0.000159469157864903 -"1506",1506,0.000151477935074793 -"1507",1507,0.00018769656433744 -"1508",1508,0.000774506915175068 -"1509",1509,0.000755636328294812 -"1510",1510,0.000435757412849487 -"1511",1511,0.000550492975377734 -"1512",1512,0.000611280970196769 -"1513",1513,0.00050567962274463 -"1514",1514,0.000449674988711411 -"1515",1515,0.000756715904525718 -"1516",1516,0.000215673806024239 -"1517",1517,4.19209084911916e-05 -"1518",1518,0.000144037412188504 -"1519",1519,0.000115678314113339 -"1520",1520,8.18537387019429e-05 -"1521",1521,3.68857880409487e-06 -"1522",1522,0.000184977208835541 -"1523",1523,0.000184180741516834 -"1524",1524,0.000398145408803469 -"1525",1525,0.000425621280687214 -"1526",1526,0.0004144561852448 -"1527",1527,0.000139961148375469 -"1528",1528,0.000198819405450975 -"1529",1529,0.000163387435541347 -"1530",1530,8.93586059427406e-05 -"1531",1531,0.000510275963858661 -"1532",1532,0.000359621070554236 -"1533",1533,4.5980467516768e-05 -"1534",1534,0.000199432198348367 -"1535",1535,0.000111708045843829 -"1536",1536,9.48488451263824e-05 -"1537",1537,0.000124190494949015 -"1538",1538,0.000125797540168635 -"1539",1539,0.000152312469236939 -"1540",1540,0.000187585960141718 -"1541",1541,3.30247470257962e-05 -"1542",1542,8.16307238217193e-05 -"1543",1543,0.000118114226627848 -"1544",1544,0.000149184753421839 -"1545",1545,3.5620329906154e-05 -"1546",1546,0.000149739852872016 -"1547",1547,5.78881355206679e-06 -"1548",1548,0.000137611907854713 -"1549",1549,0.000419484778553066 -"1550",1550,8.94498288798892e-05 -"1551",1551,1.50399530341058e-05 -"1552",1552,0.00114967471789487 -"1553",1553,3.63856432433517e-05 -"1554",1554,0.000504387350493353 -"1555",1555,0.000482057726575112 -"1556",1556,0.000190506272853399 -"1557",1557,0.000131751354341942 -"1558",1558,0.000150813566506412 -"1559",1559,0.000108896764216185 -"1560",1560,0.00108087154265881 -"1561",1561,0.00089879512204269 -"1562",1562,0.000399002444924893 -"1563",1563,0.000557313939715855 -"1564",1564,0.000141789104271194 -"1565",1565,0.000612638509851497 -"1566",1566,0.000642157805089671 -"1567",1567,0.000674468905294412 -"1568",1568,0.000591356673343606 -"1569",1569,0.000743456436124589 -"1570",1570,0.00183099260081171 -"1571",1571,0.00118671566245094 -"1572",1572,0.00193047219980479 -"1573",1573,0.000251870413145523 -"1574",1574,0.000522776957960861 -"1575",1575,0.000482916474171601 -"1576",1576,0.000302403837198161 -"1577",1577,0.000364570272131513 -"1578",1578,0.000462158851303509 -"1579",1579,0.000558615758183361 -"1580",1580,0.000425153373898738 -"1581",1581,0.000482202677452946 -"1582",1582,0.000179009402958864 -"1583",1583,0.000149687574615928 -"1584",1584,7.79732797802039e-05 -"1585",1585,0.000148146815050707 -"1586",1586,0.000142372120863083 -"1587",1587,0.000168150267601286 -"1588",1588,0.000159263549057148 -"1589",1589,0.000181872934362785 -"1590",1590,0.000193733317528361 -"1591",1591,0.000523251031147993 -"1592",1592,0.000128916253135894 -"1593",1593,0.000428027648132174 -"1594",1594,0.000360465512800145 -"1595",1595,0.000470556331119034 -"1596",1596,0.00010488163356388 -"1597",1597,0.000212956656822548 -"1598",1598,0.000451781361356488 -"1599",1599,0.00026931460640015 -"1600",1600,0.000342043678216851 -"1601",1601,0.000508268815553456 -"1602",1602,0.000206440905044891 -"1603",1603,0.000310998772446122 -"1604",1604,0.00036660762774498 -"1605",1605,0.000401942938559127 -"1606",1606,0.000323017811822846 -"1607",1607,0.000137304988768072 -"1608",1608,8.0223705646252e-05 -"1609",1609,0.000180728000833541 -"1610",1610,0.000126668008103539 -"1611",1611,8.67481122470917e-05 -"1612",1612,0.000481784374969812 -"1613",1613,0.000376285720789621 -"1614",1614,0.000457390268105612 -"1615",1615,0.000485223642529076 -"1616",1616,0.000441232344320191 -"1617",1617,0.000154003794522053 -"1618",1618,1.53843105762623e-05 -"1619",1619,0.000586669370703688 -"1620",1620,0.000551423737650996 -"1621",1621,0.000365298034333118 -"1622",1622,0.00032484709041055 -"1623",1623,0.000477684381909645 -"1624",1624,0.000486541097112895 -"1625",1625,0.0003917347546013 -"1626",1626,0.000703624708684675 -"1627",1627,0.000737924670192941 -"1628",1628,0.000142799768488897 -"1629",1629,9.10629436543595e-05 -"1630",1630,0.000139197117578549 -"1631",1631,9.01295685617915e-05 -"1632",1632,0.000489139730731918 -"1633",1633,0.000473237746155361 -"1634",1634,0.000425928713857976 -"1635",1635,0.000523556115167711 -"1636",1636,0.000155350222477386 -"1637",1637,0.000417360048354928 -"1638",1638,0.000402653400104437 -"1639",1639,0.000667126707347684 -"1640",1640,0.000584961082026643 -"1641",1641,0.000569020651815451 -"1642",1642,0.000406761784169665 -"1643",1643,0.000283686239601264 -"1644",1644,0.000396041096238447 -"1645",1645,0.000211914101220102 -"1646",1646,0.000427183243248376 -"1647",1647,0.000235271003208175 -"1648",1648,0.000444242336576851 -"1649",1649,0.000458997875869401 -"1650",1650,0.000464953789202195 -"1651",1651,0.000199413407928968 -"1652",1652,0.00013316302164942 -"1653",1653,6.91049270655419e-05 -"1654",1654,0.000486494046060687 -"1655",1655,0.000244622898857137 -"1656",1656,5.6975513764748e-06 -"1657",1657,0.000639681399757848 -"1658",1658,0.000382964190155812 -"1659",1659,0.00016132080568577 -"1660",1660,0.000425492876575972 -"1661",1661,0.000578780959375933 -"1662",1662,0.000321538939452641 -"1663",1663,0.000424490815167459 -"1664",1664,0.000393470009599469 -"1665",1665,0.000631613259433437 -"1666",1666,0.000466902674674434 -"1667",1667,0.000651677529701024 -"1668",1668,0.000794532837248361 -"1669",1669,0.000424889424882406 -"1670",1670,0.000536767618726007 -"1671",1671,0.000304970858566484 -"1672",1672,0.000470665911650907 -"1673",1673,0.000973619563648501 -"1674",1674,0.000274817883401335 -"1675",1675,0.00027851920882497 -"1676",1676,0.000325394544417389 -"1677",1677,0.000459719086541861 -"1678",1678,0.000368945860764996 -"1679",1679,0.000223655902951561 -"1680",1680,0.00036167668353057 -"1681",1681,0.00046254368333616 -"1682",1682,0.000213578777576398 -"1683",1683,0.000181309915772883 -"1684",1684,1.65686551156244e-05 -"1685",1685,3.63123899325503e-05 -"1686",1686,0.000461634522693723 -"1687",1687,0.000208681169574167 -"1688",1688,0.000402452839057107 -"1689",1689,0.000255015172393046 -"1690",1690,0.000383576177239937 -"1691",1691,8.40774567514165e-05 -"1692",1692,5.92710717560466e-05 -"1693",1693,0.000103300734940457 -"1694",1694,0.000111440948653274 -"1695",1695,0.000465085502467569 -"1696",1696,0.000521184845173011 -"1697",1697,0.000491975666130518 -"1698",1698,0.00062768787874677 -"1699",1699,0.000224544664429832 -"1700",1700,0.000485832674451996 -"1701",1701,0.000228248545067661 -"1702",1702,0.00019361738761256 -"1703",1703,6.83309592728981e-05 -"1704",1704,0.000241342899881958 -"1705",1705,0.000444440047399411 -"1706",1706,0.000435250375896272 -"1707",1707,0.000109364037108103 -"1708",1708,0.000130365961791836 -"1709",1709,0.000141326491425561 -"1710",1710,9.47551284794042e-05 -"1711",1711,0.000132732813539619 -"1712",1712,0.000132712453627118 -"1713",1713,0.000134176789054569 -"1714",1714,0.000111390410466535 -"1715",1715,0.000135000263976171 -"1716",1716,0.000138782979429263 -"1717",1717,0.000130860054788077 -"1718",1718,6.83132867322413e-05 -"1719",1719,0.000380160987876201 -"1720",1720,0.000144923845023846 -"1721",1721,0.000536918016965412 -"1722",1722,0.000482469625317361 -"1723",1723,0.000184887930846567 -"1724",1724,0.000213620243930239 -"1725",1725,4.37729591692294e-05 -"1726",1726,0.00020040739013581 -"1727",1727,0.00103391951751546 -"1728",1728,0.000992473386093814 -"1729",1729,0.00112979935550767 -"1730",1730,0.00127877633959092 -"1731",1731,0.000453945958890315 -"1732",1732,0.000286399251320397 -"1733",1733,4.1214819106079e-05 -"1734",1734,3.0289478844047e-06 -"1735",1735,0.000595390419953816 -"1736",1736,0.00114551296121379 -"1737",1737,0.00114317451671873 -"1738",1738,0.000485951028180459 -"1739",1739,0.000730688535382549 -"1740",1740,0.00161831302414476 -"1741",1741,0.00105527983730825 -"1742",1742,0.00108071452446955 -"1743",1743,0.000989041345869176 -"1744",1744,0.000934620240611416 -"1745",1745,0.000143612541739256 -"1746",1746,0.000433325533306224 -"1747",1747,0.000373748590609902 -"1748",1748,0.00048969900151222 -"1749",1749,0.000847063154047376 -"1750",1750,0.000261061739613187 -"1751",1751,0.000624092053009362 -"1752",1752,0.000673177277715573 -"1753",1753,0.000282798296256894 -"1754",1754,0.00114269717320759 -"1755",1755,0.000640064090331342 -"1756",1756,0.000304217882392209 -"1757",1757,0.000617026261646742 -"1758",1758,0.000460143372452032 -"1759",1759,0.00059152323552488 -"1760",1760,0.000444255141029276 -"1761",1761,0.000501000336954004 -"1762",1762,0.000521606171496006 -"1763",1763,0.000156201888323278 -"1764",1764,0.000149903166511078 -"1765",1765,0.00012441706679511 -"1766",1766,0.000125075115945165 -"1767",1767,0.000254122445324727 -"1768",1768,0.000376191534809595 -"1769",1769,0.000278428276818945 -"1770",1770,0.000179192582320745 -"1771",1771,0.000105766108102906 -"1772",1772,0.000110809228548831 -"1773",1773,0.000132781405553513 -"1774",1774,0.00029934976791523 -"1775",1775,0.000557490725771206 -"1776",1776,0.000435417769693908 -"1777",1777,0.00015475277272006 -"1778",1778,8.54525281775693e-05 -"1779",1779,0.000195123472822348 -"1780",1780,6.86018964339674e-05 -"1781",1781,0.000604889592542899 -"1782",1782,0.000791546046556529 -"1783",1783,0.000187425257431444 -"1784",1784,0.000172171605159874 -"1785",1785,0.000123393342059025 -"1786",1786,0.000169153668016237 -"1787",1787,0.000231269119367234 -"1788",1788,0.000121584350512354 -"1789",1789,0.00013008972449517 -"1790",1790,0.000281876791416579 -"1791",1791,0.00013581023832613 -"1792",1792,0.000126831245317481 -"1793",1793,0.000117190411821075 -"1794",1794,8.11002709642039e-05 -"1795",1795,0.000194756301821172 -"1796",1796,0.000126558724700071 -"1797",1797,0.000119055847053795 -"1798",1798,0.000142200363174613 -"1799",1799,0.000488642829841335 -"1800",1800,0.000467457136193283 -"1801",1801,0.000430527705403637 -"1802",1802,0.000114858839709363 -"1803",1803,8.57716899875279e-05 -"1804",1804,0.000104999981156315 -"1805",1805,0.00010145062820005 -"1806",1806,0.000423628460817765 -"1807",1807,0.000517570234011221 -"1808",1808,0.000432687802154916 -"1809",1809,0.000389662669563233 -"1810",1810,0.000263524941667563 -"1811",1811,0.000370270899176881 -"1812",1812,0.000926493589996529 -"1813",1813,0.000284054291626912 -"1814",1814,0.000928904051684852 -"1815",1815,0.000179906280730582 -"1816",1816,0.00030245141204448 -"1817",1817,0.00181111786024816 -"1818",1818,0.000307168607162135 -"1819",1819,0.000487791873935846 -"1820",1820,0.000441107355732945 -"1821",1821,0.000869956034583616 -"1822",1822,0.000502521705032869 -"1823",1823,0.000480619749358621 -"1824",1824,0.000167062851397752 -"1825",1825,0.000473857160686981 -"1826",1826,0.000501949296822492 -"1827",1827,0.000535671706103379 -"1828",1828,0.000611675592091015 -"1829",1829,0.000157435899377818 -"1830",1830,0.000125475436290183 -"1831",1831,0.000125890141764824 -"1832",1832,0.000145657959148868 -"1833",1833,0.000343672103721266 -"1834",1834,0.00034891799211888 -"1835",1835,0.000161485003071344 -"1836",1836,0.000139204670673361 -"1837",1837,0.000181161544376493 -"1838",1838,7.098365169897e-05 -"1839",1839,0.000474367061803455 -"1840",1840,0.000424429735638422 -"1841",1841,0.000272186158502011 -"1842",1842,0.000872535003004911 -"1843",1843,0.000782648292101121 -"1844",1844,0.000173795361874246 -"1845",1845,0.000182939923919409 -"1846",1846,0.000344163068533889 -"1847",1847,0.000381219067315619 -"1848",1848,0.000823821206252821 -"1849",1849,0.000774165022839634 -"1850",1850,0.000396876963753486 -"1851",1851,0.000608028468387561 -"1852",1852,0.000500839365124064 -"1853",1853,0.000236002088750429 -"1854",1854,0.000717962312282729 -"1855",1855,0.000282441445974806 -"1856",1856,0.000694646599689039 -"1857",1857,0.000368895404872092 -"1858",1858,0.000455493909352521 -"1859",1859,0.000173570763020757 -"1860",1860,0.000201529218294247 -"1861",1861,0.000125044450996404 -"1862",1862,0.000200603160659634 -"1863",1863,0.000425411050254838 -"1864",1864,0.000150708609609981 -"1865",1865,0.000132063605553103 -"1866",1866,0.000112288765872124 -"1867",1867,0.000146436829880422 -"1868",1868,0.000525705709676172 -"1869",1869,0.000391396706267434 -"1870",1870,0.00021280864301254 -"1871",1871,0.000132429768005611 -"1872",1872,0.000146549812797308 -"1873",1873,0.000186689381250778 -"1874",1874,9.93397926953243e-05 -"1875",1875,0.000331289615616176 -"1876",1876,0.000426233393288078 -"1877",1877,0.000126161247485743 -"1878",1878,0.000175835839938815 -"1879",1879,7.13144984009715e-05 -"1880",1880,0.000136735635176871 -"1881",1881,0.000355352381772631 -"1882",1882,0.000430689185376246 -"1883",1883,0.000195996388217481 -"1884",1884,0.000164332710277733 -"1885",1885,0.000157233708236211 -"1886",1886,0.00014031348965051 -"1887",1887,0.000539831769501696 -"1888",1888,0.000536490682048503 -"1889",1889,5.61715207321416e-05 -"1890",1890,0.000158403530477224 -"1891",1891,0.000180008751748608 -"1892",1892,9.82507455000583e-05 -"1893",1893,0.000151150243521715 -"1894",1894,0.000150340667689051 -"1895",1895,0.000153345670190462 -"1896",1896,0.000133758255859185 -"1897",1897,0.000411127283476183 -"1898",1898,9.82199635485955e-05 -"1899",1899,0.000125423584008599 -"1900",1900,0.000101809410449921 -"1901",1901,0.000101379499352287 -"1902",1902,0.000351751653448775 -"1903",1903,0.000753882057149506 -"1904",1904,0.000601205262610632 -"1905",1905,0.000251273997137291 -"1906",1906,0.000101211902487968 -"1907",1907,0.000481539895572667 -"1908",1908,0.000368878053202238 -"1909",1909,0.000363067835357902 -"1910",1910,4.20634179018116e-05 -"1911",1911,0.000271017367122151 -"1912",1912,0.000285101308111552 -"1913",1913,0.000391986877697901 -"1914",1914,0.000475108052290181 -"1915",1915,0.000120331235625825 -"1916",1916,0.00016219002262334 -"1917",1917,0.00010413042039452 -"1918",1918,7.66915663826865e-05 -"1919",1919,0.000503535938682973 -"1920",1920,0.000223340470937476 -"1921",1921,0.000119686559709701 -"1922",1922,0.000129954074608115 -"1923",1923,0.00010427595753009 -"1924",1924,0.000133264849303968 -"1925",1925,0.000135589989563968 -"1926",1926,7.89547124732711e-05 -"1927",1927,0.000108377451274759 -"1928",1928,0.000105034872487606 -"1929",1929,0.000251297122590393 -"1930",1930,0.000254930817662153 -"1931",1931,0.000560261136627589 -"1932",1932,0.000402128031232366 -"1933",1933,0.000557150336767553 -"1934",1934,0.000538104057459571 -"1935",1935,0.000407794042237768 -"1936",1936,0.000519490735965852 -"1937",1937,0.0004205165636581 -"1938",1938,0.000491467664355921 -"1939",1939,0.000359358105733989 -"1940",1940,0.000269983270810553 -"1941",1941,0.000494033300547077 -"1942",1942,0.000554422127756601 -"1943",1943,0.000410024346075831 -"1944",1944,0.00043693259862366 -"1945",1945,0.000509481117345897 -"1946",1946,0.000445083463141034 -"1947",1947,0.00054368643530886 -"1948",1948,0.000568934763404442 -"1949",1949,0.000971153460378523 -"1950",1950,0.000485111817382617 -"1951",1951,0.000148315627982411 -"1952",1952,0.000345628537279739 -"1953",1953,0.000457566397570972 -"1954",1954,0.000375743507636539 -"1955",1955,0.000399927919231504 -"1956",1956,0.000599928165543495 -"1957",1957,0.00135389067350327 -"1958",1958,0.00110340766090116 -"1959",1959,0.000390248946594715 -"1960",1960,0.000430453501798072 -"1961",1961,0.000525519231193065 -"1962",1962,0.000597776184618432 -"1963",1963,0.00128318904459213 -"1964",1964,0.000187289618783858 -"1965",1965,0.000252702592141521 -"1966",1966,0.000345003044991617 -"1967",1967,0.000514545334330573 -"1968",1968,0.000577342031725909 -"1969",1969,0.000134409922843778 -"1970",1970,0.000364222053225125 -"1971",1971,0.000129496257514237 -"1972",1972,0.000132305244538496 -"1973",1973,0.00013981828942408 -"1974",1974,0.000143798740561899 -"1975",1975,0.000253570899229624 -"1976",1976,0.000265838167441987 -"1977",1977,0.000287433165641764 -"1978",1978,0.0004959684676934 -"1979",1979,0.000548181337419564 -"1980",1980,0.000162961698800952 -"1981",1981,0.000256249685036766 -"1982",1982,0.00011315934536944 -"1983",1983,0.000157818518972397 -"1984",1984,0.000200308009282178 -"1985",1985,8.6787105225567e-05 -"1986",1986,0.000171652214727991 -"1987",1987,0.000143058530407376 -"1988",1988,0.00038099643952766 -"1989",1989,0.000934116452548077 -"1990",1990,0.000346734840645447 -"1991",1991,0.000716569392419096 -"1992",1992,0.00068294379740426 -"1993",1993,0.000833866691748396 -"1994",1994,0.000465249829189034 -"1995",1995,0.000167948901200491 -"1996",1996,0.000159235748890586 -"1997",1997,0.000154047802655894 -"1998",1998,0.000114155531145984 -"1999",1999,3.55216613747532e-05 -"2000",2000,0.000133863648844766 -"2001",2001,0.000157511566791172 -"2002",2002,0.00022017133396519 -"2003",2003,0.000305045081793856 -"2004",2004,0.000545823094078795 -"2005",2005,0.000657838375663964 -"2006",2006,0.000480114180872595 -"2007",2007,0.000145688929065088 -"2008",2008,0.00012672495514911 -"2009",2009,0.000189875970686405 -"2010",2010,0.000246363280138971 -"2011",2011,0.000207509061597454 -"2012",2012,0.000157036980221426 -"2013",2013,0.00014907879778366 -"2014",2014,0.000136251973881424 -"2015",2015,0.000379333904036009 -"2016",2016,0.000506451745698695 -"2017",2017,0.000538397104075347 -"2018",2018,0.000518347966638727 -"2019",2019,0.000682834122965031 -"2020",2020,0.000573674277875197 -"2021",2021,0.000419944980706249 -"2022",2022,0.000470283051243785 -"2023",2023,0.000546493226312468 -"2024",2024,0.00044383591020733 -"2025",2025,0.000577341892693916 -"2026",2026,0.000518585839978937 -"2027",2027,0.000545552682151104 -"2028",2028,0.000496787483863532 -"2029",2029,0.000126182768641015 -"2030",2030,0.000105091886898179 -"2031",2031,0.000171028520015448 -"2032",2032,8.12402319109889e-05 -"2033",2033,0.000459555518892064 -"2034",2034,0.000538267675825816 -"2035",2035,0.000380683507575708 -"2036",2036,0.000695096404826798 -"2037",2037,0.000122893864662014 -"2038",2038,0.000176775546789352 -"2039",2039,0.000143862281958461 -"2040",2040,0.000197312908253194 -"2041",2041,0.000320953705106895 -"2042",2042,0.000398499453133463 -"2043",2043,0.000280553948110776 -"2044",2044,0.000215065359694685 -"2045",2045,0.000484788627053413 -"2046",2046,0.000365352773087221 -"2047",2047,0.000468626564319311 -"2048",2048,0.000377173328027167 -"2049",2049,0.000229254668661094 -"2050",2050,0.000235346428926215 -"2051",2051,0.000364080182039227 -"2052",2052,0.000154210065093896 -"2053",2053,0.000104892514186445 -"2054",2054,0.000156744473378608 -"2055",2055,0.000157133154850494 -"2056",2056,0.000526598078065729 -"2057",2057,0.000597179082010023 -"2058",2058,0.000409817273303773 -"2059",2059,0.000592926349555262 -"2060",2060,0.000386965077436518 -"2061",2061,0.000692582557763516 -"2062",2062,0.000529269041794988 -"2063",2063,0.000570444842559775 -"2064",2064,0.000592285576180379 -"2065",2065,0.000603804962304574 -"2066",2066,0.000388550395668707 -"2067",2067,0.000454804000762646 -"2068",2068,0.000167798398044863 -"2069",2069,0.000115190124705796 -"2070",2070,0.000121606655077947 -"2071",2071,0.000118568915188615 -"2072",2072,0.000497137704327306 -"2073",2073,0.000155474317592645 -"2074",2074,0.000137638526474074 -"2075",2075,0.000137235420231794 -"2076",2076,3.45406516949929e-05 -"2077",2077,0.000531643097949263 -"2078",2078,0.000538711634262154 -"2079",2079,0.000496168527256517 -"2080",2080,0.00015984593498662 -"2081",2081,0.000139583730891297 -"2082",2082,0.000112637082973212 -"2083",2083,9.05355932969471e-05 -"2084",2084,0.000487589425967097 -"2085",2085,0.000143528909292322 -"2086",2086,0.00010845575614906 -"2087",2087,0.000150914912523343 -"2088",2088,9.18991165576099e-05 -"2089",2089,0.000501072745484648 -"2090",2090,9.12687600712404e-05 -"2091",2091,0.000165402949656879 -"2092",2092,0.00011458380914826 -"2093",2093,2.67225767537381e-05 -"2094",2094,0.000146708517188531 -"2095",2095,0.000116769215661631 -"2096",2096,0.000163781278100585 -"2097",2097,0.000144245914066426 -"2098",2098,0.000573371458434949 -"2099",2099,0.000552425459157193 -"2100",2100,0.000574565717542932 -"2101",2101,0.000346236307740672 -"2102",2102,0.000475866206010171 -"2103",2103,0.000426111433929204 -"2104",2104,0.000457338617211595 -"2105",2105,0.000420101007546584 -"2106",2106,0.000512064827328763 -"2107",2107,0.000403448137613355 -"2108",2108,0.00131246797763204 -"2109",2109,0.000634900936067739 -"2110",2110,0.000853201577916302 -"2111",2111,0.000663734356231661 -"2112",2112,0.000144709334142364 -"2113",2113,0.000595019382945609 -"2114",2114,0.000544068254848127 -"2115",2115,0.000895853095692794 -"2116",2116,0.0001745252819824 -"2117",2117,0.000194672592095431 -"2118",2118,0.000118766124012757 -"2119",2119,0.000163506604839599 -"2120",2120,0.000298402958457848 -"2121",2121,0.0001567578131185 -"2122",2122,0.000194017483792695 -"2123",2123,0.000257800941299558 -"2124",2124,0.000129981989904736 -"2125",2125,0.000139043867752961 -"2126",2126,8.98744562899578e-05 -"2127",2127,0.000171294574340422 -"2128",2128,0.000143380280614881 -"2129",2129,0.000138111206423345 -"2130",2130,0.000148788447442796 -"2131",2131,0.000258255107910581 -"2132",2132,0.00224187629438096 -"2133",2133,0.000672318276497619 -"2134",2134,0.0013397779096465 -"2135",2135,0.00107291045662214 -"2136",2136,0.00015364289222317 -"2137",2137,0.000528850986976208 -"2138",2138,0.000337556430773727 -"2139",2139,0.000968391088077227 -"2140",2140,0.000528791848798725 -"2141",2141,0.000935711796146889 -"2142",2142,0.000565906266864033 -"2143",2143,0.00105617360624987 -"2144",2144,0.000869777328323115 -"2145",2145,0.000891485960986883 -"2146",2146,0.000264118912832988 -"2147",2147,0.000544270095228646 -"2148",2148,0.000728882169059165 -"2149",2149,0.0014419002918438 -"2150",2150,0.000119414978947836 -"2151",2151,0.000372694141980846 -"2152",2152,1.42297401856144e-05 -"2153",2153,3.00549324991199e-05 -"2154",2154,8.20964736674275e-05 -"2155",2155,0.000351917536110973 -"2156",2156,0.000210535927094815 -"2157",2157,0.000116941752568076 -"2158",2158,0.00121334573814644 -"2159",2159,0.000459733151008199 -"2160",2160,0.000387688125842948 -"2161",2161,0.000355785170429025 -"2162",2162,0.000263210203399035 -"2163",2163,2.51931264621201e-05 -"2164",2164,0.00114190324667198 -"2165",2165,0.00018193595450541 -"2166",2166,0.000293025247167988 -"2167",2167,0.000289689650893721 -"2168",2168,0.000543819997673481 -"2169",2169,0.000400257074906646 -"2170",2170,0.000363862784846242 -"2171",2171,0.000178720887142699 -"2172",2172,0.000423205542979329 -"2173",2173,0.00169226760819899 -"2174",2174,0.000435568125072375 -"2175",2175,0.000198741362608541 -"2176",2176,0.000564189104175367 -"2177",2177,0.000294744355928593 -"2178",2178,0.000485667203760773 -"2179",2179,0.000498367452550291 -"2180",2180,0.000207976539293299 -"2181",2181,0.000333448863668149 -"2182",2182,0.00049667082110528 -"2183",2183,0.000502841175685865 -"2184",2184,0.000178252311194776 -"2185",2185,0.000186163898990545 -"2186",2186,0.000427696325383753 -"2187",2187,0.000539412473279601 -"2188",2188,0.00107459788176539 -"2189",2189,0.000373039676157318 -"2190",2190,0.000148255554532938 -"2191",2191,0.000142887407290649 -"2192",2192,0.000140980585186356 -"2193",2193,0.000125632297183232 -"2194",2194,0.000376236520730436 -"2195",2195,0.000125669088291915 -"2196",2196,0.00015558339457289 -"2197",2197,9.11504618869254e-05 -"2198",2198,2.30221020577727e-05 -"2199",2199,0.000128949190253985 -"2200",2200,0.00013070318671786 -"2201",2201,0.00013134202980385 -"2202",2202,0.000147190325677962 -"2203",2203,0.000172023189312128 -"2204",2204,0.000108021439474785 -"2205",2205,0.000191006465769828 -"2206",2206,0.000130508294802509 -"2207",2207,0.000323431919945371 -"2208",2208,0.000451665193678926 -"2209",2209,0.000867255940924721 -"2210",2210,0.00012206023905393 -"2211",2211,0.000118710585222828 -"2212",2212,9.61372790251071e-05 -"2213",2213,0.000157404868025362 -"2214",2214,0.000527118057628486 -"2215",2215,0.000389463867380693 -"2216",2216,0.000500715325043267 -"2217",2217,0.000412920511021839 -"2218",2218,0.00023815116770477 -"2219",2219,0.000393135567658323 -"2220",2220,5.89883376455567e-05 -"2221",2221,0.000939057481013538 -"2222",2222,0.000715458480177077 -"2223",2223,0.000560724867008893 -"2224",2224,0.000280635157435583 -"2225",2225,0.000644579025834955 -"2226",2226,0.000844595042979805 -"2227",2227,0.000903505272310748 -"2228",2228,0.000429631170203359 -"2229",2229,0.00035125137037581 -"2230",2230,0.000132385460442997 -"2231",2231,0.000120578477001995 -"2232",2232,0.000159269153023478 -"2233",2233,0.000127424585267416 -"2234",2234,0.00047846382299434 -"2235",2235,0.000558860511533947 -"2236",2236,0.000566454449622516 -"2237",2237,0.000683299287978888 -"2238",2238,0.000718557035337892 -"2239",2239,0.000996008740757915 -"2240",2240,0.000497105307028886 -"2241",2241,0.00053838541850639 -"2242",2242,0.000359624143623081 -"2243",2243,0.000319228799602531 -"2244",2244,0.00122422905579409 -"2245",2245,0.00068256603849176 -"2246",2246,0.000494414091377872 -"2247",2247,0.000343533611870495 -"2248",2248,0.000299416410841423 -"2249",2249,0.000403538166872483 -"2250",2250,0.000853041953327228 -"2251",2251,0.000467686772753817 -"2252",2252,8.36834927291582e-05 -"2253",2253,0.000715295179669921 -"2254",2254,0.000589109174839803 -"2255",2255,0.00110912345679196 -"2256",2256,0.000960774883091835 -"2257",2257,0.000243577177540066 -"2258",2258,0.000545862320841433 -"2259",2259,0.000535420383796041 -"2260",2260,0.000485122623075684 -"2261",2261,0.000460605628169372 -"2262",2262,0.000497789183090377 -"2263",2263,0.000453256965801477 -"2264",2264,0.000533857709459682 -"2265",2265,0.000542370400558788 -"2266",2266,0.000262421225169771 -"2267",2267,0.000756321787102046 -"2268",2268,0.000364793992237118 -"2269",2269,0.000234520305581568 -"2270",2270,0.000371625652976673 -"2271",2271,0.000450913823298531 -"2272",2272,0.000465529483645494 -"2273",2273,0.000444813559813628 -"2274",2274,0.000448846171672069 -"2275",2275,0.000397238448054844 -"2276",2276,0.000538654981282278 -"2277",2277,0.000147603278512967 -"2278",2278,0.000159071057231715 -"2279",2279,0.000178634283443065 -"2280",2280,0.00016845071281591 -"2281",2281,0.000331521150129148 -"2282",2282,0.000193334284437076 -"2283",2283,0.000463246745683746 -"2284",2284,0.000436190273300371 -"2285",2285,0.000595062810908032 -"2286",2286,0.000309578607889115 -"2287",2287,0.000189964792355752 -"2288",2288,0.000116843549739844 -"2289",2289,9.27726940204703e-05 -"2290",2290,0.000154925772078605 -"2291",2291,0.00051918729579506 -"2292",2292,0.000301154320997274 -"2293",2293,0.00063937222315953 -"2294",2294,0.000148754294661125 -"2295",2295,0.000105138909040639 -"2296",2296,0.000112050714752012 -"2297",2297,0.000110102234378543 -"2298",2298,0.00031904047391417 -"2299",2299,0.000324110433152496 -"2300",2300,0.000154517092538009 -"2301",2301,0.000134138889774316 -"2302",2302,0.000127603920874341 -"2303",2303,8.77872081084042e-05 -"2304",2304,5.45725256126423e-05 -"2305",2305,0.000189745416636135 -"2306",2306,0.000465129515649247 -"2307",2307,0.000514699706519584 -"2308",2308,0.00169205004401566 -"2309",2309,0.00100514454797215 -"2310",2310,0.00113220467652084 -"2311",2311,0.000641648774500829 -"2312",2312,0.000810567312416917 -"2313",2313,0.0024629327865533 -"2314",2314,0.00047333554215922 -"2315",2315,0.00138998235873974 -"2316",2316,0.00175225636790341 -"2317",2317,0.000875275107617975 -"2318",2318,0.00109196713549929 -"2319",2319,0.000545363092791108 -"2320",2320,0.000540092995002717 -"2321",2321,0.00132057221484068 -"2322",2322,0.00134205022724737 -"2323",2323,0.000598423046848164 -"2324",2324,0.000365707150375693 -"2325",2325,0.00116433982369353 -"2326",2326,8.57590682918928e-05 -"2327",2327,0.000424465586634612 -"2328",2328,6.93198908715198e-06 -"2329",2329,0.000341124754565039 -"2330",2330,0.000473592848206551 -"2331",2331,0.000485522278193995 -"2332",2332,0.000756520998319805 -"2333",2333,0.000676230029621204 -"2334",2334,0.000574493323294807 -"2335",2335,0.000800947686860555 -"2336",2336,0.000470521558057019 -"2337",2337,0.000702189339348375 -"2338",2338,0.000261054014279217 -"2339",2339,0.00051520273098086 -"2340",2340,0.000456535340118165 -"2341",2341,0.000930067421115118 -"2342",2342,0.00040005571149153 -"2343",2343,0.00113215506364318 -"2344",2344,0.000351537350840229 -"2345",2345,0.000820594002148294 -"2346",2346,0.000715308222063831 -"2347",2347,0.000414025370911447 -"2348",2348,0.000326330074926242 -"2349",2349,0.00101160098414343 -"2350",2350,0.001140430206327 -"2351",2351,0.00044373474105733 -"2352",2352,0.000128210047349478 -"2353",2353,0.000685057738688517 -"2354",2354,0.000518251540755044 -"2355",2355,0.000184169717655104 -"2356",2356,0.00037350843358194 -"2357",2357,0.000610248817931433 -"2358",2358,0.000810440800294654 -"2359",2359,0.000694224623084 -"2360",2360,0.0011594818098269 -"2361",2361,0.000817782022946248 -"2362",2362,0.000326364276921402 -"2363",2363,0.000385279975104184 -"2364",2364,0.000379013534614181 -"2365",2365,0.000517060651323477 -"2366",2366,0.000424338750189747 -"2367",2367,0.000198090222270346 -"2368",2368,0.000282810459422784 -"2369",2369,0.000234287486851976 -"2370",2370,0.000594472674314057 -"2371",2371,0.000790407763321071 -"2372",2372,0.000988767981162864 -"2373",2373,0.000477939671499125 -"2374",2374,0.000223599392581714 -"2375",2375,0.000261271811878879 -"2376",2376,0.000265787498856631 -"2377",2377,0.000513168665823164 -"2378",2378,0.000646850084165939 -"2379",2379,0.000718532275554441 -"2380",2380,0.000261543226408626 -"2381",2381,0.000461119270854651 -"2382",2382,0.00114344915599408 -"2383",2383,0.000143123339947956 -"2384",2384,0.000619903556516532 -"2385",2385,0.000977198542970266 -"2386",2386,0.000706430130747283 -"2387",2387,0.000772512904603499 -"2388",2388,0.000546866903796248 -"2389",2389,0.00137232025566521 -"2390",2390,0.00187503542289278 -"2391",2391,0.000412789545683652 -"2392",2392,0.000770523523820055 -"2393",2393,0.00104439937936764 -"2394",2394,0.000497254943190426 -"2395",2395,0.000353577546507819 -"2396",2396,0.000330701717089396 -"2397",2397,0.000196074800108228 -"2398",2398,0.000844163402282416 -"2399",2399,0.000682345787399251 -"2400",2400,0.000852620211385503 -"2401",2401,0.00123785974410781 -"2402",2402,0.000421478428337833 -"2403",2403,0.000410719607009216 -"2404",2404,0.00031888867986215 -"2405",2405,0.000382060276423757 -"2406",2406,0.000457085751326853 -"2407",2407,0.000329731965542001 -"2408",2408,0.000529060507288162 -"2409",2409,0.000218432709774798 -"2410",2410,0.000310593581669412 -"2411",2411,0.000410478091887513 -"2412",2412,0.00028775300199878 -"2413",2413,0.000246694983257082 -"2414",2414,0.0010084523824905 -"2415",2415,0.000501388182533839 -"2416",2416,0.000449759674732018 -"2417",2417,0.000784574890989652 -"2418",2418,0.000193966353258273 -"2419",2419,0.000302887686528541 -"2420",2420,0.000596408396236127 -"2421",2421,0.00041108024611997 -"2422",2422,0.00115077505696114 -"2423",2423,0.000365747269681737 -"2424",2424,0.000237840290257153 -"2425",2425,0.000341841518789456 -"2426",2426,0.000308290648398608 -"2427",2427,7.48393481092806e-05 -"2428",2428,9.36935019021391e-05 -"2429",2429,0.000177909458647835 -"2430",2430,0.000135111110752352 -"2431",2431,0.000188347912919578 -"2432",2432,0.000954655108134849 -"2433",2433,0.000561858364109226 -"2434",2434,0.000391484885414608 -"2435",2435,0.000581411092904915 -"2436",2436,0.000589523367267951 -"2437",2437,0.000542328729426485 -"2438",2438,0.000412585555928208 -"2439",2439,0.000446230123363986 -"2440",2440,0.000107731665820348 -"2441",2441,0.000237021483758953 -"2442",2442,0.000533168576623295 -"2443",2443,0.000675011116897783 -"2444",2444,0.000385367142090211 -"2445",2445,0.000315929197919758 -"2446",2446,0.000631749705559086 -"2447",2447,0.000192469736714549 -"2448",2448,0.000444478156013351 -"2449",2449,0.000695066081488682 -"2450",2450,0.000299357481683621 -"2451",2451,0.000273533700943715 -"2452",2452,0.00050247014384206 -"2453",2453,0.000777816472663828 -"2454",2454,0.000637782075927348 -"2455",2455,0.000473883527431556 -"2456",2456,0.000300204535593083 -"2457",2457,0.000473504448647731 -"2458",2458,0.00110261623750958 -"2459",2459,0.00131767959504281 -"2460",2460,0.000832893774914215 -"2461",2461,0.00060705461877335 -"2462",2462,0.000485817962095275 -"2463",2463,0.000658155963047079 -"2464",2464,0.000257067904197179 -"2465",2465,0.000221869795096517 -"2466",2466,0.000218880140487701 -"2467",2467,0.000147659405745527 -"2468",2468,0.000327761522577716 -"2469",2469,0.000766240778180117 -"2470",2470,0.000294881045036709 -"2471",2471,0.000208913153939581 -"2472",2472,0.000369065950920138 -"2473",2473,0.000313890126293591 -"2474",2474,0.00100400876817509 -"2475",2475,0.000660220357567784 -"2476",2476,0.00102937210156007 -"2477",2477,0.000178588856988609 -"2478",2478,0.000346753893374863 -"2479",2479,0.000118558318741938 -"2480",2480,2.60326557864656e-05 -"2481",2481,0.000328876655673995 -"2482",2482,9.50107655012956e-05 -"2483",2483,6.70840849542839e-05 -"2484",2484,3.49017042249131e-05 -"2485",2485,0.000136024441742406 -"2486",2486,0.000388531131499462 -"2487",2487,0.000621795621688015 -"2488",2488,0.000108679069968302 -"2489",2489,0.000118897612847618 -"2490",2490,4.95447491717163e-05 -"2491",2491,9.21797338723753e-05 -"2492",2492,0.000142361074316465 -"2493",2493,0.000163090420537314 -"2494",2494,0.000138894182123025 -"2495",2495,7.69557499900884e-05 -"2496",2496,0.000105070208210118 -"2497",2497,9.40002020840597e-05 -"2498",2498,0.00014012855906336 -"2499",2499,0.000158789169949349 -"2500",2500,7.83809013592707e-05 -"2501",2501,0.000144585741585255 -"2502",2502,0.000128664504570965 -"2503",2503,0.000173386998889147 -"2504",2504,0.00014254293735855 -"2505",2505,0.00064987484205636 -"2506",2506,0.000110147439009653 -"2507",2507,0.000556953329430577 -"2508",2508,5.73202311615445e-05 -"2509",2509,9.80765027828298e-05 -"2510",2510,9.79958437615547e-05 -"2511",2511,0.000126338563847512 -"2512",2512,0.000109957853592433 -"2513",2513,0.000169459517958859 -"2514",2514,0.000103628864360704 -"2515",2515,0.000114037801970769 -"2516",2516,7.36353169658329e-05 -"2517",2517,0.000144361445162564 -"2518",2518,9.65594985094023e-05 -"2519",2519,0.000118442943393747 -"2520",2520,8.38647808563975e-05 -"2521",2521,0.000130683379034227 -"2522",2522,0.000126972201400183 -"2523",2523,3.75357092654131e-05 -"2524",2524,7.30047444997003e-05 -"2525",2525,0.000155517163958051 -"2526",2526,0.000160446026200738 -"2527",2527,6.55306944535663e-05 -"2528",2528,1.76682958632107e-05 -"2529",2529,0.000261352900353618 -"2530",2530,0.00057869358657893 -"2531",2531,0.000365972754479095 -"2532",2532,0.000300522681603946 -"2533",2533,0.000103496639331595 -"2534",2534,9.09215949761922e-05 -"2535",2535,0.000206002554665299 -"2536",2536,0.000170351313117752 -"2537",2537,9.43819552052448e-05 -"2538",2538,0.000306174438601252 -"2539",2539,0.000271466545948776 -"2540",2540,2.94876002037509e-05 -"2541",2541,0.000432418382240078 -"2542",2542,0.000256872887432219 -"2543",2543,0.000370584698782316 -"2544",2544,0.000175723249724248 -"2545",2545,0.000127642861014925 -"2546",2546,0.000433338901843463 -"2547",2547,0.000191684221495186 -"2548",2548,0.000145963523610232 -"2549",2549,0.000367679781868363 -"2550",2550,0.000126088796364812 -"2551",2551,0.000151746041077854 -"2552",2552,0.000193355624772236 -"2553",2553,0.000283284253088472 -"2554",2554,0.000184462325197561 -"2555",2555,0.000332639409971762 -"2556",2556,0.000193771743468879 -"2557",2557,0.000262388161115633 -"2558",2558,0.000320351784166376 -"2559",2559,0.000278799333379892 -"2560",2560,0.000164852451982798 -"2561",2561,0.000258705606574694 -"2562",2562,0.000160531023160947 -"2563",2563,0.000164449407502745 -"2564",2564,0.000169397883970897 -"2565",2565,0.000108169839197908 -"2566",2566,0.00019814300912858 -"2567",2567,0.000146330261360712 -"2568",2568,0.000313621569064472 -"2569",2569,0.00031560841150776 -"2570",2570,0.000311054682862559 -"2571",2571,0.000674479012515182 -"2572",2572,0.000220064825846859 -"2573",2573,0.000514800102880376 -"2574",2574,0.00055562976986589 -"2575",2575,0.000371220726464706 -"2576",2576,0.000448748427618649 -"2577",2577,0.000308515158147641 -"2578",2578,0.000420281495239845 -"2579",2579,0.000579574635288872 -"2580",2580,0.000470740871756297 -"2581",2581,0.000484645728275658 -"2582",2582,0.00028255853278449 -"2583",2583,0.000646520029786799 -"2584",2584,9.18408723825155e-05 -"2585",2585,0.000118017930450304 -"2586",2586,0.000220080599368847 -"2587",2587,0.00122385598711099 -"2588",2588,0.000118946904813544 -"2589",2589,0.000540454702800485 -"2590",2590,6.71909547519053e-05 -"2591",2591,0.000178344967203785 -"2592",2592,6.39571124165703e-05 -"2593",2593,0.000239065234287849 -"2594",2594,0.000103430379380476 -"2595",2595,0.00114292799203582 -"2596",2596,9.58965818036721e-05 -"2597",2597,0.000435373177268393 -"2598",2598,7.77735564644196e-05 -"2599",2599,0.000114040392931201 -"2600",2600,0.000122412738067192 -"2601",2601,0.000150832521042609 -"2602",2602,0.000209102986012631 -"2603",2603,0.000134059998184557 -"2604",2604,0.000211826866246222 -"2605",2605,0.000181501877367563 -"2606",2606,0.000154318828309618 -"2607",2607,0.000300909722807914 -"2608",2608,0.00021500960447412 -"2609",2609,0.000276318479564589 -"2610",2610,0.000296581905183368 -"2611",2611,0.000242714828743004 -"2612",2612,0.000513646818423603 -"2613",2613,0.000155119613638946 -"2614",2614,0.00028179097038868 -"2615",2615,0.000350926126927468 -"2616",2616,0.000370793894652872 -"2617",2617,0.000126129273765802 -"2618",2618,9.88382512789192e-05 -"2619",2619,0.000152032372708479 -"2620",2620,0.000123661114827181 -"2621",2621,0.000686358975333943 -"2622",2622,0.000951612150118201 -"2623",2623,0.000324295024874478 -"2624",2624,0.000491945743055591 -"2625",2625,0.000263201923514725 -"2626",2626,0.000332796686125953 -"2627",2627,0.000403336542080511 -"2628",2628,0.000681965016843842 -"2629",2629,0.000163164911535967 -"2630",2630,0.000252683436279039 -"2631",2631,0.000665864648194005 -"2632",2632,0.000215611073370642 -"2633",2633,0.000116101928948964 -"2634",2634,0.000128911858779816 -"2635",2635,0.00027310510737478 -"2636",2636,0.00105361470395151 -"2637",2637,0.000160307496811763 -"2638",2638,9.25427542388079e-05 -"2639",2639,0.00145232205975873 -"2640",2640,0.000225804491802998 -"2641",2641,0.000783852209934499 -"2642",2642,0.00100719678734952 -"2643",2643,0.0013489697979438 -"2644",2644,0.00107975775045714 -"2645",2645,0.000567148760034149 -"2646",2646,0.000410359325257592 -"2647",2647,0.000158634007476433 -"2648",2648,0.000240033846961687 -"2649",2649,0.000884308594756214 -"2650",2650,0.000349476683715271 -"2651",2651,0.000389619973958833 -"2652",2652,0.000492725607935188 -"2653",2653,0.00029747613946904 -"2654",2654,0.000224180026207244 -"2655",2655,0.000800603543036893 -"2656",2656,0.000394458698698803 -"2657",2657,0.000328980773733229 -"2658",2658,0.000840190927285188 -"2659",2659,0.000494041229050872 -"2660",2660,0.000372847934694264 -"2661",2661,0.00132326358771061 -"2662",2662,0.00142717409282528 -"2663",2663,0.000370875810927008 -"2664",2664,0.000191619987057817 -"2665",2665,2.40498984730148e-05 -"2666",2666,0.000485549185799644 -"2667",2667,0.000334592952817497 -"2668",2668,0.000182834875033497 -"2669",2669,0.000600169885381189 -"2670",2670,0.000229334052234296 -"2671",2671,0.000386303224806454 -"2672",2672,0.000320214492929091 -"2673",2673,0.000203915618195048 -"2674",2674,0.000754132607822585 -"2675",2675,0.00099408908068195 -"2676",2676,0.000967388305220698 -"2677",2677,0.000602893136698118 -"2678",2678,0.000435953780983594 -"2679",2679,0.000309787294817844 -"2680",2680,0.000521813920814369 -"2681",2681,0.000418781689092775 -"2682",2682,0.000190720084073095 -"2683",2683,0.000144357091129697 -"2684",2684,0.000148985314366176 -"2685",2685,0.000139676698147896 -"2686",2686,0.000364384019295496 -"2687",2687,0.00012242888606599 -"2688",2688,0.000481337379321387 -"2689",2689,0.000425852831820948 -"2690",2690,0.00127076021861605 -"2691",2691,0.000773543418203352 -"2692",2692,0.00126834503388411 -"2693",2693,0.000536979341499433 -"2694",2694,0.00100814542168755 -"2695",2695,0.00112094975872945 -"2696",2696,0.00047935482719826 -"2697",2697,0.000324957757803279 -"2698",2698,0.000433801029037595 -"2699",2699,0.000305354476640135 -"2700",2700,0.00126526559946978 -"2701",2701,0.000587900599469546 -"2702",2702,0.000259557288505139 -"2703",2703,0.00154683119935604 -"2704",2704,0.00201606920369701 -"2705",2705,0.00191913130701227 -"2706",2706,0.000532669071539098 -"2707",2707,0.00140511800581269 -"2708",2708,0.00071165733875242 -"2709",2709,0.000998887541066405 -"2710",2710,0.0011111436003925 -"2711",2711,0.000757886728446611 -"2712",2712,0.000690103553681261 -"2713",2713,0.00128911719898739 -"2714",2714,0.000963250103725099 -"2715",2715,0.000404600318464692 -"2716",2716,0.00115450000003569 -"2717",2717,0.000837015500179463 -"2718",2718,0.00147947331107549 -"2719",2719,0.00106494267063616 -"2720",2720,0.00174035883892567 -"2721",2721,0.000587197067092699 -"2722",2722,0.0015509963830453 -"2723",2723,0.00162927791100224 -"2724",2724,0.000903975732690188 -"2725",2725,0.00139286094224817 -"2726",2726,0.000136274810081445 -"2727",2727,7.76954452478023e-05 -"2728",2728,0.000463174349152968 -"2729",2729,0.000557912993296545 -"2730",2730,5.02813124260081e-05 -"2731",2731,0.00106771018408921 -"2732",2732,0.000712676401843266 -"2733",2733,0.00122160182541794 -"2734",2734,0.00151891064889692 -"2735",2735,0.000547427929315775 -"2736",2736,0.00060595424682423 -"2737",2737,0.00100248293266659 -"2738",2738,4.53702237491218e-05 -"2739",2739,0.000497350254605497 -"2740",2740,0.00105990688640855 -"2741",2741,0.00103664620775967 -"2742",2742,0.000316914497087783 -"2743",2743,0.000191351750026662 -"2744",2744,7.38542473030362e-05 -"2745",2745,0.00154181387664825 -"2746",2746,0.000215649718163236 -"2747",2747,4.69700198073819e-05 -"2748",2748,0.000469424615178222 -"2749",2749,0.000465297539828778 -"2750",2750,0.000458237639766551 -"2751",2751,0.000450719811631318 -"2752",2752,0.000522373214897968 -"2753",2753,0.000380973643857186 -"2754",2754,0.00230353894453882 -"2755",2755,0.000501041218137435 -"2756",2756,0.000975174532448806 -"2757",2757,0.000991984266326501 -"2758",2758,0.000587955626639968 -"2759",2759,0.00286261755420429 -"2760",2760,0.00089502706695725 -"2761",2761,0.00104940374496005 -"2762",2762,0.000755078021245757 -"2763",2763,0.000291203267989932 -"2764",2764,0.00256682406518508 -"2765",2765,0.000483150831743385 -"2766",2766,0.00246827521303356 -"2767",2767,0.00104947879940985 -"2768",2768,0.000279824691121964 -"2769",2769,0.00181290148998958 -"2770",2770,0.000216749318490924 -"2771",2771,0.00148245927054897 -"2772",2772,0.000466951929215677 -"2773",2773,5.99178593837919e-05 -"2774",2774,0.000354415014968729 -"2775",2775,0.000353014176187383 -"2776",2776,5.74607534451183e-05 -"2777",2777,0.000164960815607886 -"2778",2778,0.000413261164058633 -"2779",2779,0.000138672990042025 -"2780",2780,0.000804424985558818 -"2781",2781,0.000143887642315 -"2782",2782,0.000138326995500383 -"2783",2783,0.000173409094168524 -"2784",2784,0.000143233057670189 -"2785",2785,0.000637562882027756 -"2786",2786,0.00021836511208984 -"2787",2787,0.000164705552962371 -"2788",2788,0.000150191159462884 -"2789",2789,0.000179184125884589 -"2790",2790,0.000577975035642419 -"2791",2791,0.000547753781000247 -"2792",2792,0.000254495028365406 -"2793",2793,0.000193942510763191 -"2794",2794,0.00012141173911355 -"2795",2795,0.000168923609565924 -"2796",2796,0.00014276623182884 -"2797",2797,0.000163068949422394 -"2798",2798,0.000205550231147162 -"2799",2799,0.00012256965162901 -"2800",2800,0.00013642641076108 -"2801",2801,0.000237636993320864 -"2802",2802,0.000126806392587129 -"2803",2803,8.0519858969491e-05 -"2804",2804,0.00011005589255684 -"2805",2805,5.40680297502813e-05 -"2806",2806,3.08560414382781e-05 -"2807",2807,0.000202309267476058 -"2808",2808,0.000556228416382818 -"2809",2809,0.000509843742916849 -"2810",2810,0.000348395054132728 -"2811",2811,0.000222879544173843 -"2812",2812,0.00038658042732135 -"2813",2813,0.000392253831261296 -"2814",2814,0.000106950265833791 -"2815",2815,0.000318457905323785 -"2816",2816,0.000258467774474846 -"2817",2817,0.000284932001660567 -"2818",2818,0.000137601605792817 -"2819",2819,0.000233033833833322 -"2820",2820,0.000263243981180676 -"2821",2821,4.36947435794228e-05 -"2822",2822,2.98699316389482e-05 -"2823",2823,0.000155124779482726 -"2824",2824,0.00113724138225317 -"2825",2825,0.000563352362776032 -"2826",2826,0.00127446362228078 -"2827",2827,0.000334345504952677 -"2828",2828,0.00116886189204731 -"2829",2829,6.84975184525962e-05 -"2830",2830,0.000110717487347685 -"2831",2831,0.000161036216026912 -"2832",2832,0.00020350235183221 -"2833",2833,6.12272494989932e-05 -"2834",2834,0.000168207068716811 -"2835",2835,8.83142869055873e-05 -"2836",2836,0.000190840913436752 -"2837",2837,8.02865217635984e-05 -"2838",2838,0.000940055279050676 -"2839",2839,0.000779222197166866 -"2840",2840,0.00152321074168411 -"2841",2841,0.000867659472820729 -"2842",2842,0.000564042649912696 -"2843",2843,0.000825219805697239 -"2844",2844,0.000740836967638359 -"2845",2845,0.000222372649816406 -"2846",2846,0.000409627552518066 -"2847",2847,0.000564430327849837 -"2848",2848,0.000464831658439471 -"2849",2849,0.000695269361353857 -"2850",2850,0.0012727894873313 -"2851",2851,0.00130264180347784 -"2852",2852,0.00115719196354925 -"2853",2853,0.000926598082468908 -"2854",2854,0.000842853084986944 -"2855",2855,0.000562705111441388 -"2856",2856,0.000231542955471337 -"2857",2857,0.000213111950850611 -"2858",2858,0.00018448584448275 -"2859",2859,0.000652831834345913 -"2860",2860,0.00027086101107664 -"2861",2861,0.000108796256852418 -"2862",2862,4.30913123250591e-05 -"2863",2863,8.37836282292402e-05 -"2864",2864,7.96489892299218e-05 -"2865",2865,0.000104374362204561 -"2866",2866,0.000118444120253431 -"2867",2867,6.73886054511591e-05 -"2868",2868,6.42887917907287e-05 -"2869",2869,0.0015161143695467 -"2870",2870,0.000143803872235832 -"2871",2871,0.000259704748793434 -"2872",2872,0.000535414895096076 -"2873",2873,0.000573681716007983 -"2874",2874,0.000414120848767843 -"2875",2875,0.000526096655880486 -"2876",2876,0.000460332515810601 -"2877",2877,0.000443445914049204 -"2878",2878,0.000881601250816684 -"2879",2879,0.00124059251067971 -"2880",2880,0.00120365045913355 -"2881",2881,0.00112855586837161 -"2882",2882,0.00082790149434152 -"2883",2883,0.000596138482815283 -"2884",2884,9.66528145502645e-05 -"2885",2885,0.000193477884015223 -"2886",2886,0.000135708685380585 -"2887",2887,9.29598290741618e-05 -"2888",2888,0.000187781743407381 -"2889",2889,0.000235694718510181 -"2890",2890,8.43915172386177e-05 -"2891",2891,0.000110045696949853 -"2892",2892,0.000134322288598873 -"2893",2893,0.000105097198541755 -"2894",2894,0.000112447656631118 -"2895",2895,0.000141072656942281 -"2896",2896,0.000669267387221811 -"2897",2897,0.000785639248439269 -"2898",2898,0.000954841493639983 -"2899",2899,0.000493351722116804 -"2900",2900,0.00126317498448021 -"2901",2901,0.000830861207472753 -"2902",2902,0.000395110448220432 -"2903",2903,0.000154586112065321 -"2904",2904,0.000148189075909579 -"2905",2905,6.54890597320194e-05 -"2906",2906,0.000107720471556417 -"2907",2907,0.000144642513573888 -"2908",2908,0.00021045215251696 -"2909",2909,9.4446383966248e-05 -"2910",2910,0.000820770320443553 -"2911",2911,0.000663824626380831 -"2912",2912,0.000437392502110975 -"2913",2913,0.000398034901035792 -"2914",2914,0.000257733995659223 -"2915",2915,0.000325686569880628 -"2916",2916,0.000122800381273265 -"2917",2917,0.000215867524465255 -"2918",2918,0.000227488510679963 -"2919",2919,0.000198913198548793 -"2920",2920,0.000138310528743548 -"2921",2921,0.000682367510907885 -"2922",2922,0.000205178236476559 -"2923",2923,0.00014278527336589 -"2924",2924,0.000228775230253359 -"2925",2925,0.000202744466681051 -"2926",2926,8.39417199649511e-05 -"2927",3161,0.00151891064889692 -"2928",2927,0.000298411222477821 -"2929",2930,0.000304970858566484 -"2930",2931,0.000280470725058376 -"2931",2932,0.000220798193360159 -"2932",2933,0.000391798339180535 -"2933",2934,0.000265015245090025 -"2934",2935,0.000220434806668937 -"2935",2937,0.000308290648398608 -"2936",2938,0.000305183584276883 -"2937",2939,0.00032484709041055 -"2938",2940,0.000302403837198161 -"2939",2941,0.000306174438601252 -"2940",2942,0.000302403837198161 -"2941",2943,0.000252899397546978 -"2942",2944,0.000261271811878879 -"2943",2945,0.000398499453133463 -"2944",2951,8.36834927291582e-05 -"2945",2955,0.000508101250758362 -"2946",2957,0.000425852831820948 -"2947",2958,0.00023557399355914 -"2948",2960,1.91168514679766e-06 -"2949",2962,0.000263402108761569 -"2950",2963,0.000307168607162135 -"2951",2964,0.000290972126378906 -"2952",2965,0.000320953705106895 -"2953",2966,0.000295956201905664 -"2954",2967,0.00030217118055285 -"2955",2968,0.000306890198035492 -"2956",2969,0.000305045081793856 -"2957",2970,0.00030217118055285 -"2958",2971,0.000298402958457848 -"2959",2972,0.00030645651350063 -"2960",2973,0.000220434806668937 -"2961",2974,0.000291787337793132 -"2962",2975,0.000305045081793856 -"2963",2976,0.000300556842482095 -"2964",2977,0.000665006302240963 -"2965",2978,0.000309210156947167 -"2966",2979,0.000309578607889115 -"2967",2980,0.000242759454592311 -"2968",2981,0.000306890198035492 -"2969",2982,0.000328063657202783 -"2970",2983,0.000309787294817844 -"2971",2984,0.00031314573690432 -"2972",2985,0.000298402958457848 -"2973",2987,0.000300909722807914 -"2974",2988,0.000300744030654323 -"2975",2990,0.000291787337793132 -"2976",2991,0.000503739559262856 -"2977",2993,0.00026931460640015 -"2978",2994,0.000310443132774927 -"2979",2995,0.000269957525890716 -"2980",2996,0.000336412037605558 -"2981",2997,0.00028775300199878 -"2982",2998,0.000992473386093814 -"2983",2999,0.000252597491102619 -"2984",3000,0.00034891799211888 -"2985",3001,9.81976744069435e-05 -"2986",3002,0.000308617763088947 -"2987",3003,0.000312310517512375 -"2988",3004,0.000302403837198161 -"2989",3005,0.000313890126293591 -"2990",3006,0.00029934976791523 -"2991",3007,0.000302403837198161 -"2992",3008,0.000264118912832988 -"2993",3009,0.000308290648398608 -"2994",3010,0.000323017811822846 -"2995",3011,0.000308290648398608 -"2996",3012,0.000302403837198161 -"2997",3013,0.000276079790133478 -"2998",3014,0.00031314573690432 -"2999",3015,0.000309525034942948 -"3000",3016,0.000306890198035492 -"3001",3017,0.000302157455675431 -"3002",3018,0.000309578607889115 -"3003",3019,0.00030217118055285 -"3004",3020,0.000298411222477821 -"3005",3021,0.000298411222477821 -"3006",3024,0.000312310517512375 -"3007",3027,0.000298411222477821 -"3008",3028,0.00114292799203582 -"3009",3029,0.000306562572352121 -"3010",3032,0.000398499453133463 -"3011",3033,0.000295956201905664 -"3012",3036,0.000309525034942948 -"3013",3039,0.000328063657202783 -"3014",3041,0.000830861207472753 -"3015",3042,0.000302631135963619 -"3016",3044,0.00030645651350063 -"3017",3045,0.000305520525285662 -"3018",3046,0.000309210156947167 -"3019",3047,0.000294744355928593 -"3020",3048,0.000310443132774927 -"3021",3049,0.000267455003815564 -"3022",3052,0.00082790149434152 -"3023",3056,0.000324303176126267 -"3024",3057,0.000266988562142014 -"3025",3060,0.000412585555928208 -"3026",3061,0.000474367061803455 -"3027",3062,0.000258233961904936 -"3028",3063,0.000551423737650996 -"3029",3065,0.000444478156013351 -"3030",3066,0.00034891799211888 -"3031",3067,0.000304970858566484 -"3032",3072,0.000312310517512375 -"3033",3073,0.000196930102807101 -"3034",3077,0.000294376162070591 -"3035",3078,0.000324315647295881 -"3036",3079,0.00029934976791523 -"3037",3080,0.000327912121988709 -"3038",3081,0.000106741828282351 -"3039",3083,0.000460605628169372 -"3040",3085,0.00123785974410781 -"3041",3087,0.000754907138116655 -"3042",3089,0.000136274810081445 -"3043",3091,0.000551423737650996 -"3044",3099,0.00169226760819899 -"3045",3102,0.000320953705106895 -"3046",3103,0.000312310517512375 -"3047",3104,0.000261271811878879 -"3048",3105,0.000220798193360159 -"3049",3106,0.000321976818189821 -"3050",3107,0.000298411222477821 -"3051",3108,0.000336412037605558 -"3052",3109,0.000173184690817074 -"3053",3110,0.000334208984769455 -"3054",3115,0.000305183584276883 -"3055",3116,0.000324315647295881 -"3056",3117,0.000309578607889115 -"3057",3118,0.000276671237384064 -"3058",3121,0.0013489697979438 -"3059",3126,0.000306562572352121 -"3060",3128,0.000991984266326501 -"3061",3130,0.000263524941667563 -"3062",3131,0.000309210156947167 -"3063",3132,0.000328063657202783 -"3064",3133,0.000302157455675431 -"3065",3134,0.00030645651350063 -"3066",3136,0.00147885516384315 -"3067",3139,0.000504780917347567 -"3068",3142,0.000302157455675431 -"3069",3143,0.000309525034942948 -"3070",3144,0.000309787294817844 -"3071",3145,0.000298402958457848 -"3072",3146,0.000376236520730436 -"3073",3147,0.000308290648398608 -"3074",3148,0.000350849316623487 -"3075",3151,0.000305183584276883 -"3076",3152,0.000106741828282351 -"3077",3154,0.000444466068490434 -"3078",3155,0.00016183208192007 -"3079",3156,0.000460332515810601 -"3080",3157,9.81976744069435e-05 -"3081",3158,0.000482469625317361 -"3082",3159,0.000444466068490434 -"3083",3160,0.000500839365124064 -"3084",3162,0.000321976818189821 -"3085",3163,0.001140430206327 -"3086",3164,0.000309210156947167 -"3087",3165,0.000284354833105859 -"3088",3166,0.000329122776448566 -"3089",3167,0.000295956201905664 -"3090",3168,0.000903505272310748 -"3091",3169,0.000345485532518887 -"3092",3170,0.000324315647295881 -"3093",3171,0.00024374671388135 -"3094",3172,0.000294376162070591 -"3095",3173,0.000308409386740688 -"3096",3174,0.000199413407928968 -"3097",3175,0.00029934976791523 -"3098",3176,0.000264118912832988 -"3099",3177,0.000252899397546978 -"3100",3179,0.000261271811878879 -"3101",3180,0.000302403837198161 -"3102",3181,0.00029934976791523 -"3103",3182,0.000261271811878879 -"3104",3183,0.000269957525890716 -"3105",3184,0.000327912121988709 -"3106",3185,0.000282810459422784 -"3107",3186,0.000136274810081445 -"3108",3187,0.000926598082468908 -"3109",3189,0.00123785974410781 -"3110",3197,0.000467686772753817 -"3111",3200,0.00224187629438096 -"3112",3204,0.000143612541739256 -"3113",3207,0.000308409386740688 -"3114",3208,0.000300204535593083 -"3115",3209,0.000243577177540066 -"3116",3210,0.000306562572352121 -"3117",3211,0.000279824691121964 -"3118",3212,0.000187755522805058 -"3119",3216,0.000324315647295881 -"3120",3217,0.000512064827328763 -"3121",3218,0.000134409922843778 -"3122",3219,0.000272186158502011 -"3123",3220,0.000269957525890716 -"3124",3221,0.000500839365124064 -"3125",3222,0.000323017811822846 -"3126",3224,0.000310998772446122 -"3127",3225,0.000261271811878879 -"3128",3228,0.00047333554215922 -"3129",3229,0.00032484709041055 -"3130",3230,0.000260667788099189 -"3131",3231,0.000260667788099189 -"3132",3235,0.000261271811878879 -"3133",3236,0.000310998772446122 -"3134",3237,0.000267455003815564 -"3135",3238,0.000361346834521608 -"3136",3239,0.00031449190398201 -"3137",3250,0.00187503542289278 -"3138",3252,0.000305068116831022 -"3139",3254,0.000310443132774927 -"3140",3256,0.000302403837198161 -"3141",3257,0.000326364276921402 -"3142",3258,0.000294744355928593 -"3143",3259,0.000326364276921402 -"3144",3260,0.000309525034942948 -"3145",3261,0.000301075612656147 -"3146",3262,0.000300909722807914 -"3147",3263,0.000305520525285662 -"3148",3268,0.000402653400104437 -"3149",3270,0.000391798339180535 -"3150",3271,0.000326463726446431 -"3151",3273,0.000301154320997274 -"3152",3274,0.000332429850343703 -"3153",3276,0.000332429850343703 -"3154",3277,0.000350849316623487 -"3155",3279,0.000304227788092248 -"3156",3280,0.000309210156947167 -"3157",3281,0.000309787294817844 -"3158",3282,0.000261271811878879 -"3159",3283,0.00029028766190922 -"3160",3284,0.000329122776448566 -"3161",3285,0.000304227788092248 -"3162",3286,0.00030217118055285 -"3163",3287,0.000220434806668937 -"3164",3288,0.000203100181475407 -"3165",3289,0.000398499453133463 -"3166",3290,0.000143612541739256 -"3167",3291,0.000251297122590393 -"3168",3292,0.000293025247167988 -"3169",3293,0.000251297122590393 -"3170",3294,0.000251297122590393 -"3171",3295,0.000305354476640135 -"3172",3296,8.70513791886624e-05 -"3173",3297,0.000376236520730436 -"3174",3298,0.000169153668016237 -"3175",3299,0.000266988562142014 -"3176",3300,0.000299416410841423 -"3177",3301,0.000273533700943715 -"3178",3302,0.000482916474171601 -"3179",3303,0.000313890126293591 -"3180",3304,0.000265015245090025 -"3181",3305,0.000306562572352121 -"3182",3306,0.000324303176126267 -"3183",3307,0.000299357481683621 -"3184",3308,0.000300556842482095 -"3185",3310,0.000731284823530134 -"3186",3311,0.000324315647295881 -"3187",3315,0.000991984266326501 -"3188",3316,0.00224187629438096 -"3189",3318,0.000444242336576851 -"3190",3320,0.000323017811822846 -"3191",3328,0.000349311635868395 -"3192",3329,0.000716569392419096 -"3193",3336,0.000611280970196769 -"3194",3337,0.000308409386740688 -"3195",3345,0.000608028468387561 -"3196",3349,0.000327912121988709 -"3197",3350,0.000903505272310748 -"3198",3353,0.00020040739013581 -"3199",3354,0.00029934976791523 -"3200",3355,0.000252899397546978 -"3201",3356,0.000332429850343703 -"3202",3357,0.000326364276921402 -"3203",3358,0.000305068116831022 -"3204",3359,0.000320953705106895 -"3205",3360,0.000321976818189821 -"3206",3361,0.000500839365124064 -"3207",3362,0.00017698361934237 -"3208",3363,0.00020710586575091 -"3209",3364,0.000304217882392209 -"3210",3369,0.000595390419953816 -"3211",3370,0.000263243981180676 -"3212",3371,0.000449759674732018 -"3213",3376,0.000754907138116655 -"3214",3380,0.000269957525890716 -"3215",3381,0.000172254024929636 -"3216",3382,0.000168425162962178 -"3217",3385,0.000286960297532526 -"3218",3396,0.000350849316623487 -"3219",3398,0.000143612541739256 -"3220",3399,0.000267455003815564 -"3221",3401,0.000304227788092248 -"3222",3402,0.00029934976791523 -"3223",3403,0.000302403837198161 -"3224",3404,0.000277815546391841 -"3225",3405,0.000261271811878879 -"3226",3406,0.000301154320997274 -"3227",3407,0.000302403837198161 -"3228",3408,0.000302631135963619 -"3229",3409,0.000584961082026643 -"3230",3410,0.000236002088750429 -"3231",3411,0.000996008740757915 -"3232",3412,0.000236002088750429 -"3233",3413,0.00031314573690432 -"3234",3414,0.00031449190398201 -"3235",3415,0.000300556842482095 -"3236",3417,0.000302157455675431 -"3237",3418,0.000300556842482095 -"3238",3419,0.00020040739013581 -"3239",3420,0.000460605628169372 -"3240",3421,0.000273533700943715 -"3241",3422,0.000266360183433666 -"3242",3423,0.00031449190398201 -"3243",3424,0.000302887686528541 -"3244",3425,0.000169153668016237 -"3245",3426,0.000460605628169372 -"3246",3427,0.000380683507575708 -"3247",3428,0.000313890126293591 -"3248",3429,0.000324303176126267 -"3249",3430,0.000243577177540066 -"3250",3431,0.000252899397546978 -"3251",3432,0.000460605628169372 -"3252",3433,0.00028775300199878 -"3253",3434,0.000261271811878879 -"3254",3435,0.000164763591362037 -"3255",3436,0.001140430206327 -"3256",3437,0.000164763591362037 -"3257",3438,0.000265015245090025 -"3258",3439,0.000263402108761569 -"3259",3443,0.000282810459422784 -"3260",3444,0.00024374671388135 -"3261",3445,0.000220434806668937 -"3262",3446,0.000266360183433666 -"3263",3447,0.000332429850343703 -"3264",3448,0.000258713002899338 -"3265",3450,0.00147885516384315 -"3266",3451,0.000299357481683621 -"3267",3452,0.000310998772446122 -"3268",3453,0.000273716813163038 -"3269",3458,0.000300645118441876 -"3270",3459,1.91168514679766e-06 -"3271",3460,0.000504780917347567 -"3272",3465,0.000283686239601264 -"3273",3468,0.000305068116831022 -"3274",3469,0.000277815546391841 -"3275",3470,0.000313890126293591 -"3276",3471,0.000252899397546978 -"3277",3472,0.000329122776448566 -"3278",3473,0.000305520525285662 -"3279",3474,0.000305520525285662 -"3280",3475,0.000284354833105859 -"3281",3476,0.000305520525285662 -"3282",3477,0.000309525034942948 -"3283",3478,0.000329122776448566 -"3284",3479,0.000309787294817844 -"3285",3480,0.000308617763088947 -"3286",3485,0.000320953705106895 -"3287",3488,0.000328063657202783 -"3288",3491,0.000608028468387561 -"3289",3494,0.000304970858566484 -"3290",3495,0.000298402958457848 -"3291",3496,0.000391798339180535 -"3292",3497,0.000302631135963619 -"3293",3498,0.000310443132774927 -"3294",3499,0.000376236520730436 -"3295",3501,0.000536979341499433 -"3296",3502,0.000833866691748396 -"3297",3503,0.000261061739613187 -"3298",3504,0.000273716813163038 -"3299",3505,0.000433325533306224 -"3300",3506,0.000369077205098422 -"3301",3507,0.000329122776448566 -"3302",3508,0.000482916474171601 -"3303",3509,0.000168425162962178 -"3304",3510,0.000299357481683621 -"3305",3511,0.000268513092070768 -"3306",3512,0.000312310517512375 -"3307",3513,0.00029747613946904 -"3308",3514,0.000294744355928593 -"3309",3515,0.000869956034583616 -"3310",3517,0.000165364420651487 -"3311",3518,0.000449759674732018 -"3312",3519,0.000309525034942948 -"3313",3520,0.000350849316623487 -"3314",3521,0.000350849316623487 -"3315",3522,0.000361346834521608 -"3316",3523,0.000299357481683621 -"3317",3524,0.000482916474171601 -"3318",3525,0.000279824691121964 -"3319",3526,0.000284354833105859 -"3320",3527,0.000309578607889115 -"3321",3528,0.000261271811878879 -"3322",3529,0.000302403837198161 -"3323",3538,0.00082790149434152 -"3324",3540,0.000310593581669412 -"3325",3543,0.00023557098990672 -"3326",3544,0.000134409922843778 -"3327",3545,0.000336550257381565 -"3328",3546,0.000398499453133463 -"3329",3547,0.000220434806668937 -"3330",3548,0.000383670544428727 -"3331",3549,0.000359621070554236 -"3332",3551,0.000485667203760773 -"3333",3552,0.000313890126293591 -"3334",3553,0.000302631135963619 -"3335",3554,0.000261271811878879 -"3336",3555,0.000305068116831022 -"3337",3560,0.00020040739013581 -"3338",3564,0.001140430206327 -"3339",3565,0.001140430206327 -"3340",3566,0.000295956201905664 -"3341",3567,0.000313890126293591 -"3342",3568,0.000308617763088947 -"3343",3570,0.000308409386740688 -"3344",3571,0.001140430206327 -"3345",3573,0.000264118912832988 -"3346",3574,0.000282810459422784 -"3347",3575,0.000305183584276883 -"3348",3576,0.000294376162070591 -"3349",3577,0.000305183584276883 -"3350",3578,0.000242759454592311 -"3351",3579,0.000199413407928968 -"3352",3580,0.000460605628169372 -"3353",3581,0.000332429850343703 -"3354",3586,0.000412585555928208 -"3355",3587,0.000220798193360159 -"3356",3588,0.000326364276921402 -"3357",3589,0.000992473386093814 -"3358",3590,0.000361346834521608 -"3359",3591,0.000302403837198161 -"3360",3592,0.00038658042732135 -"3361",3593,0.000300909722807914 -"3362",3594,0.000305183584276883 -"3363",3595,0.000313890126293591 -"3364",3596,0.000310998772446122 -"3365",3597,0.000329122776448566 -"3366",3598,0.000306562572352121 -"3367",3599,0.000326364276921402 -"3368",3600,0.000308290648398608 -"3369",3601,0.000273716813163038 -"3370",3602,0.000306562572352121 -"3371",3603,0.000381528028400972 -"3372",3604,0.000346734840645447 -"3373",3605,0.00031449190398201 -"3374",3606,0.00031449190398201 -"3375",3607,0.000279824691121964 -"3376",3609,0.000336550257381565 -"3377",3610,0.000369077205098422 -"3378",3611,0.000473504448647731 -"3379",3612,0.000336412037605558 -"3380",3613,0.00019412858602687 -"3381",3614,0.000305354476640135 -"3382",3615,0.000281876791416579 -"3383",3616,0.000220798193360159 -"3384",3618,0.000323017811822846 -"3385",3619,0.000305183584276883 -"3386",3620,0.000267455003815564 -"3387",3621,0.000311054682862559 -"3388",3622,0.000301075612656147 -"3389",3623,0.000306562572352121 -"3390",3624,0.000361346834521608 -"3391",3625,0.000273716813163038 -"3392",3626,0.00029934976791523 -"3393",3629,0.00047714191327394 -"3394",3630,0.000263524941667563 -"3395",3631,0.000243577177540066 -"3396",3632,0.000164763591362037 -"3397",2936,0.000412585555928208 -"3398",2952,0.000604889592542899 -"3399",2953,0.000782648292101121 -"3400",2956,0.000345485532518887 -"3401",2959,0.000406761784169665 -"3402",2961,0.000595390419953816 -"3403",2992,0.00100514454797215 -"3404",3022,0.00181111786024816 -"3405",3023,0.000542328729426485 -"3406",3025,0.000396041096238447 -"3407",3026,0.000833866691748396 -"3408",3030,0.000406761784169665 -"3409",3034,0.000594083862046629 -"3410",3035,0.00114190324667198 -"3411",3037,0.000611675592091015 -"3412",3038,0.000535420383796041 -"3413",3050,0.000915690048841452 -"3414",3053,0.00147885516384315 -"3415",3055,0.000444255141029276 -"3416",3058,0.000284054291626912 -"3417",3059,0.000542328729426485 -"3418",3064,0.000412585555928208 -"3419",3071,0.000402653400104437 -"3420",3076,0.000284054291626912 -"3421",3082,0.000473857160686981 -"3422",3084,0.000444466068490434 -"3423",3086,0.000542328729426485 -"3424",3088,0.000540454702800485 -"3425",3090,0.000540454702800485 -"3426",3092,0.00114190324667198 -"3427",3094,0.00128318904459213 -"3428",3095,0.00068294379740426 -"3429",3096,0.000708513389608698 -"3430",3098,0.000755078021245757 -"3431",3100,0.000510275963858661 -"3432",3114,0.0013489697979438 -"3433",3119,0.000694646599689039 -"3434",3124,0.000833866691748396 -"3435",3135,0.000557912993296545 -"3436",3137,0.00147885516384315 -"3437",3138,0.000718532275554441 -"3438",3141,0.000402653400104437 -"3439",3149,0.00174035883892567 -"3440",3153,0.000473857160686981 -"3441",3178,0.000345485532518887 -"3442",3188,0.00147885516384315 -"3443",3190,0.000833866691748396 -"3444",3191,0.00147885516384315 -"3445",3192,0.000376603514771805 -"3446",3195,0.000718532275554441 -"3447",3196,0.000774538439742599 -"3448",3199,0.00068294379740426 -"3449",3201,0.00128911719898739 -"3450",3202,0.00118856866903728 -"3451",3203,0.000376603514771805 -"3452",3205,0.000262733875457073 -"3453",3206,0.00108284674299263 -"3454",3213,0.00021714270226092 -"3455",3214,0.00070082043007438 -"3456",3215,0.000424429735638422 -"3457",3223,0.000376603514771805 -"3458",3227,0.000345485532518887 -"3459",3232,0.000444255141029276 -"3460",3233,0.000444255141029276 -"3461",3234,0.000542328729426485 -"3462",3247,0.000264750516991348 -"3463",3249,0.000355525728218811 -"3464",3267,0.000376603514771805 -"3465",3269,0.00114190324667198 -"3466",3275,0.000510275963858661 -"3467",3278,0.000599928165543495 -"3468",3309,0.000574565717542932 -"3469",3314,0.000694646599689039 -"3470",3317,0.000594083862046629 -"3471",3319,0.000396041096238447 -"3472",3323,0.000574565717542932 -"3473",3324,0.000220080599368847 -"3474",3325,0.00105527983730825 -"3475",3327,0.000483150831743385 -"3476",3330,0.00100514454797215 -"3477",3331,0.000220080599368847 -"3478",3334,0.000427183243248376 -"3479",3341,0.00105990688640855 -"3480",3344,0.000117362832343631 -"3481",3346,0.000833866691748396 -"3482",3348,0.0013489697979438 -"3483",3351,0.000594083862046629 -"3484",3352,0.000718532275554441 -"3485",3365,0.000424429735638422 -"3486",3366,0.000284054291626912 -"3487",3367,0.000376603514771805 -"3488",3368,0.000444255141029276 -"3489",3372,0.000574565717542932 -"3490",3373,0.000604889592542899 -"3491",3375,0.00174035883892567 -"3492",3377,0.000501041218137435 -"3493",3378,0.000504780917347567 -"3494",3379,0.00116433982369353 -"3495",3383,0.000604889592542899 -"3496",3384,0.000218167997385984 -"3497",3387,0.000155124779482726 -"3498",3388,0.000504780917347567 -"3499",3389,0.000594083862046629 -"3500",3394,0.000503739559262856 -"3501",3395,0.00135389067350327 -"3502",3397,0.000529060507288162 -"3503",3400,0.000542328729426485 -"3504",3416,0.000542328729426485 -"3505",3440,0.000345485532518887 -"3506",3441,0.000284054291626912 -"3507",3442,0.000406761784169665 -"3508",3449,0.00068294379740426 -"3509",3454,0.00021714270226092 -"3510",3455,0.00114190324667198 -"3511",3456,0.000557912993296545 -"3512",3457,0.000427183243248376 -"3513",3461,0.000345485532518887 -"3514",3464,0.00100514454797215 -"3515",3466,0.00089502706695725 -"3516",3481,0.00021714270226092 -"3517",3482,0.000218167997385984 -"3518",3483,0.000424429735638422 -"3519",3484,0.00060286452244339 -"3520",3486,0.000718532275554441 -"3521",3487,0.000155124779482726 -"3522",3490,0.00118856866903728 -"3523",3492,0.00139286094224817 -"3524",3493,0.00135389067350327 -"3525",3516,0.000595390419953816 -"3526",3530,0.000755078021245757 -"3527",3531,0.000755078021245757 -"3528",3536,0.000915690048841452 -"3529",3537,0.000218167997385984 -"3530",3541,0.000412585555928208 -"3531",3542,0.000915690048841452 -"3532",3550,0.000595390419953816 -"3533",3557,0.000755078021245757 -"3534",3558,0.000264750516991348 -"3535",3561,0.000503739559262856 -"3536",3562,0.00070082043007438 -"3537",3572,0.00060286452244339 -"3538",3582,0.000604889592542899 -"3539",3583,0.000510275963858661 -"3540",3584,0.00181111786024816 -"3541",3585,0.000599928165543495 -"3542",3617,0.000218167997385984 -"3543",3628,0.000424429735638422 -"3544",2929,0.000791546046556529 -"3545",2948,0.000954841493639983 -"3546",2954,0.000782648292101121 -"3547",2986,0.000716569392419096 -"3548",2989,0.000449403430205254 -"3549",3031,0.000782648292101121 -"3550",3040,0.000928904051684852 -"3551",3043,0.000716569392419096 -"3552",3051,0.000611675592091015 -"3553",3054,0.000716569392419096 -"3554",3068,0.000915690048841452 -"3555",3069,0.000915690048841452 -"3556",3070,0.000915690048841452 -"3557",3074,0.000716569392419096 -"3558",3075,0.000716569392419096 -"3559",3093,0.000708513389608698 -"3560",3097,0.000264750516991348 -"3561",3101,0.00113724138225317 -"3562",3111,0.000716569392419096 -"3563",3112,0.000716569392419096 -"3564",3113,0.000716569392419096 -"3565",3122,0.000716569392419096 -"3566",3123,0.000716569392419096 -"3567",3125,0.000485122623075684 -"3568",3127,0.000791546046556529 -"3569",3129,0.000830861207472753 -"3570",3140,0.000791546046556529 -"3571",3150,0.000756715904525718 -"3572",3193,0.000915690048841452 -"3573",3194,0.000716569392419096 -"3574",3198,0.000716569392419096 -"3575",3226,0.000716569392419096 -"3576",3240,0.00113724138225317 -"3577",3241,0.00122422905579409 -"3578",3242,0.000954841493639983 -"3579",3243,0.000577813944965751 -"3580",3245,0.000954841493639983 -"3581",3248,0.000436190273300371 -"3582",3253,0.000756715904525718 -"3583",3255,0.000755078021245757 -"3584",3264,0.000915690048841452 -"3585",3265,0.000782648292101121 -"3586",3266,0.000915690048841452 -"3587",3272,0.000611675592091015 -"3588",3312,0.000716569392419096 -"3589",3313,0.000915690048841452 -"3590",3321,0.000954841493639983 -"3591",3322,0.00122422905579409 -"3592",3326,0.000355525728218811 -"3593",3333,0.000436190273300371 -"3594",3338,0.000355525728218811 -"3595",3339,0.000485122623075684 -"3596",3340,0.000483150831743385 -"3597",3342,0.00022054589476491 -"3598",3343,0.000353577546507819 -"3599",3347,0.000716569392419096 -"3600",3374,0.000915690048841452 -"3601",3386,0.000436190273300371 -"3602",3390,0.000830861207472753 -"3603",3392,0.000485122623075684 -"3604",3393,0.000485122623075684 -"3605",3462,0.000436190273300371 -"3606",3463,0.000915690048841452 -"3607",3467,0.00122422905579409 -"3608",3489,0.000915690048841452 -"3609",3500,0.000436190273300371 -"3610",3532,0.000755078021245757 -"3611",3533,0.000264750516991348 -"3612",3534,0.000716569392419096 -"3613",3535,0.000716569392419096 -"3614",3539,0.000915690048841452 -"3615",3556,0.000755078021245757 -"3616",3559,0.000264750516991348 -"3617",3563,0.000264750516991348 -"3618",3569,0.000755078021245757 -"3619",3608,0.000782648292101121 -"3620",3627,0.000716569392419096 -"3621",2928,0.00286261755420429 -"3622",2946,0.000755078021245757 -"3623",2947,0.000755078021245757 -"3624",2949,0.00286261755420429 -"3625",2950,0.000755078021245757 -"3626",3120,0.000755078021245757 -"3627",3244,0.000449403430205254 -"3628",3246,0.000755078021245757 -"3629",3251,0.000449403430205254 -"3630",3332,0.00126317498448021 -"3631",3335,0.00126317498448021 -"3632",3391,0.00060595424682423 diff --git a/Database/data/tg_rates.csv b/Database/data/tg_rates.csv deleted file mode 100644 index 3433187..0000000 --- a/Database/data/tg_rates.csv +++ /dev/null @@ -1,21 +0,0 @@ -"","NAICS","CategoryLab","total_Emp","total_trips","mean_rate","sd_rate","trips_emp" -"1",42,"Wholesale Trade",211117,138302.87764262,0.054306056320185,1.0907249095855,1.31020124047443 -"2",48,"Transportation & Warehousing",286088,172550.324671092,0.0462102302464996,1.72155588191626,1.20627446569651 -"3",23,"Construction",208859,105418.279643416,0.0501681138815619,1.06372844061995,1.00946839392524 -"4",31,"Manufacturing",369302,183702.412101598,0.0586375362089278,0.926820916371811,0.994862806600547 -"5",56,"Administrative support & waste services",235794,81310.6501648148,0.0502588693693567,2.06755495467036,0.689675311202277 -"6",81,"Other services",181951,43529.3457471916,0.0408978995111304,1.15170084892178,0.239236639244586 -"7",54,"Professional, scientific, & technical services",379351,56060.3750137273,0.0289806765158682,0.730417145331389,0.147779694830717 -"8",11,"Ag, Forestry, fishing, & hunting",11387,1632.5959057717,0.00329060407340987,0.48574431788492,0.143373663455845 -"9",51,"Information",81171,10253.5873624701,0.00698272554238067,0.437769165268995,0.126320821013294 -"10",44,"Retail Trade",401584,44766.1934825593,0.0276378378942476,0.816508235653153,0.111474046482328 -"11",21,"Mining",1446,139.167593579884,0.000203597539907065,0.0349084055347222,0.0962431490870567 -"12",22,"Utilities",12795,1093.36349985689,0.000615674559377637,0.0652212808159401,0.0854524032713473 -"13",53,"Real estate, rental & leasing",85943,7272.85009263104,0.00759360229904134,0.265957436138571,0.0846241124074217 -"14",71,"Arts, entertainment, & recreation",89455,4054.77595459591,0.00440691233087754,0.25943481154402,0.0453275496573239 -"15",72,"Accommodation & food services",285208,11765.8539069518,0.00576882253558519,0.29514091073291,0.0412535900358749 -"16",55,"Management of companies & enterprises",60127,2382.87183092978,0.0015739648829436,0.085367798371118,0.0396306456488729 -"17",52,"Finance & Insurance",230474,7471.49336876564,0.00417240934028016,0.236756942238187,0.0324179446218039 -"18",61,"Educational services",383252,10293.2579117949,0.00398090263573298,0.219553021732184,0.0268576756593439 -"19",62,"Healthcare & social assistance",561260,15058.3472232268,0.00633589284580108,0.269344682288787,0.0268295392923544 -"20",92,"Public Administration",136229,2475.94727030646,0.00125682308879804,0.164365821451684,0.0181748913249489 diff --git a/Database/macros/TOD_skim.py b/Database/macros/TOD_skim.py index 3a262b3..fa41ef3 100644 --- a/Database/macros/TOD_skim.py +++ b/Database/macros/TOD_skim.py @@ -1,164 +1,83 @@ -## TOD_skim.py -## -## Create travel time (and distance) skims for each time period, which are used in the utility calculations in -## the time-of-day model. Travel time skims are stored in the following matrices: -## - mf461 = overnight 8p-6a SOV hwy time skim -## - mf462 = am pre-pk shoulder 6a-7a SOV hwy time skim -## - mf463 = am peak 7a-9a SOV time skim -## - mf464 = am post-pk shoulder 9a-10a SOV hwy time skim -## - mf465 = midday 10a-2p SOV hwy time skim -## - mf466 = pm pre-pk shoulder 2p-4p SOV hwy time skim -## - mf467 = pm peak 4p-6p SOV hwy time -## - mf468 = pm post-pk shoulder 6p-8p SOV hwy time skim -## -## Travel distance skims are stored in the following matrices: -## - mf471 = overnight 8p-6a SOV hwy time skim -## - mf472 = am pre-pk shoulder 6a-7a SOV hwy time skim -## - mf473 = am peak 7a-9a SOV time skim -## - mf474 = am post-pk shoulder 9a-10a SOV hwy time skim -## - mf475 = midday 10a-2p SOV hwy time skim -## - mf476 = pm pre-pk shoulder 2p-4p SOV hwy time skim -## - mf477 = pm peak 4p-6p SOV hwy time -## - mf478 = pm post-pk shoulder 6p-8p SOV hwy time skim -## -## ms97 = dummy operand for demand matrix in assignment setup -## extra function parameter (el1) used in averaging vdfs -## -## Heither, rev. 01-12-2025 -## ========================================================================================== -import os -import sys -from pathlib import Path -import inro.modeller as _m -sys.path.append(str(Path(__file__).resolve().parents[2].joinpath('Scripts'))) -from tbmtools import project as tbm - -tod = int(sys.argv[1]) -currentScen = int(sys.argv[2]) -sThreads = int(sys.argv[3]) - -proj_dir = Path(__file__).resolve().parents[2] -my_modeller = tbm.connect(proj_dir) - -assign_SOLA = my_modeller.tool("inro.emme.traffic_assignment.sola_traffic_assignment") -matrix_init = my_modeller.tool("inro.emme.data.matrix.create_matrix") -my_emmebank = my_modeller.emmebank -delete_function = my_modeller.tool("inro.emme.data.function.delete_function") -readin_functions = my_modeller.tool("inro.emme.data.function.function_transaction") -change_scenario = my_modeller.tool("inro.emme.data.scenario.change_primary_scenario") -delete_scenario = my_modeller.tool("inro.emme.data.scenario.delete_scenario") -copy_scenario = my_modeller.tool("inro.emme.data.scenario.copy_scenario") -create_extra = my_modeller.tool("inro.emme.data.extra_attribute.create_extra_attribute") -netcalc = my_modeller.tool("inro.emme.network_calculation.network_calculator") -set_extra_function_parameters = my_modeller.tool("inro.emme.traffic_assignment.set_extra_function_parameters") -skimScen = my_emmebank.scenario(currentScen) -## ======================================================================================================================= - -default_path = os.getcwd().replace("\\","/") -vdf_file = os.path.join(default_path,"data/vdf_iter.in") - -mtxIndex = tod-1 - -## -- Initialize storage matrices -- ## -mtx = ["mf461","mf462","mf463","mf464","mf465","mf466","mf467","mf468"] ##-- TOD time storage matrices -mtx2 = ["mf471","mf472","mf473","mf474","mf475","mf476","mf477","mf478"] ##-- TOD distance storage matrices -# -new_mf1 = matrix_init(matrix_id="%s" %(mtx[mtxIndex]), matrix_name="todtime_%s" %(tod), - matrix_description="SOV hwy time skim period %s" %(tod), overwrite=True, default_value=0) -new_mf2 = matrix_init(matrix_id="%s" %(mtx2[mtxIndex]), matrix_name="toddist_%s" %(tod), - matrix_description="SOV hwy distance skim period %s" %(tod), overwrite=True, default_value=0) - -## -- Delete current volume-delay functions (fd1 - fd10) -- ## -for i in range(1,11): - f_id = "fd%s" % i - f = my_modeller.emmebank.function(f_id) - if f is not None: - delete_function(f) -## -- Import global iteration vdf functions -- ## -readin_functions(transaction_file=vdf_file, throw_on_error=True) - -## -- Copy scenario for skimming and set as primary scenario -- ## -s90 = copy_scenario(from_scenario=skimScen, - scenario_id=90, - scenario_title="temp scenario for skimming", - copy_linkshapes=True, - overwrite=True, - set_as_primary=True) - -## -- Create @avtot to hold the sum of class average volumes -- ## -new_att = create_extra(extra_attribute_type="LINK", - extra_attribute_name="@avtot", - extra_attribute_description="total average volume (veq)", - overwrite=True) - -calcSpec = {"type": "NETWORK_CALCULATION", "result": "@avtot", - "expression": "@avs1v+@avs2v+@avs3v+@avh2v+@avh3v+@avbqv+@avlqv+@avmqv+@avhqv", - "aggregation": None, "selections": {"link": "all"}} -report = netcalc(calcSpec, full_report=False) - -## -- Set extra function parameters -- ## -set_extra_function_parameters(el1="@avtot", el2="@busveq") - - -skimSpec = { - "type": "SOLA_TRAFFIC_ASSIGNMENT", - "classes": [ - { - "mode": "S", - "demand": "ms97", - "generalized_cost": None, - "results": { - "link_volumes": None, - "turn_volumes": None, - "od_travel_times": { - "shortest_paths": mtx[mtxIndex] - } - }, - "path_analyses": [ - { - "link_component": "length", - "turn_component": None, - "operator": "+", - "selection_threshold": { - "lower": None, - "upper": None - }, - "path_to_od_composition": { - "considered_paths": "ALL", - "multiply_path_proportions_by": { - "analyzed_demand": False, - "path_value": True - } - }, - "analyzed_demand": None, - "results": { - "selected_link_volumes": None, - "selected_turn_volumes": None, - "od_values": mtx2[mtxIndex] - } - } - ] - } - ], - "performance_settings": { - "number_of_processors": sThreads - }, - "background_traffic": None, - "stopping_criteria": { - "max_iterations": 0, - "relative_gap": 0.0001, - "best_relative_gap": 0.01, - "normalized_gap": 0.005 - } -} - -with _m.logbook_trace("Travel Time (and Distance) Skims for Time-of-Day Model: Scenario %s" % currentScen): - report = assign_SOLA(skimSpec) - - ## -- Reset primary scenario -- ## - change_scenario(scenario=currentScen) - - ## -- Delete temporary skim scenario (cannot be current scenario) -- ## - s90 = my_emmebank.scenario(90) - delete_scenario(scenario=s90) -print(" Travel Time and Distance Skims Completed for Time Period {0}".format(tod)) +## TOD_skim.py +## +## Create travel time skims for each time period, which are used in the utility calculations in +## the time-of-day model. Travel time skims are stored in the following matrices: +## - mf461 = overnight 8p-6a SOV hwy time skim +## - mf462 = am pre-pk shoulder 6a-7a SOV hwy time skim +## - mf463 = am peak 7a-9a SOV time skim +## - mf464 = am post-pk shoulder 9a-10a SOV hwy time skim +## - mf465 = midday 10a-2p SOV hwy time skim +## - mf466 = pm pre-pk shoulder 2p-4p SOV hwy time skim +## - mf467 = pm peak 4p-6p SOV hwy time +## - mf468 = pm post-pk shoulder 6p-8p SOV hwy time skim +## +## ms97 = dummy operand for demand matrix in assignment setup +## extra function parameter (el1) used in averaging vdfs +## +## This is the SOLA Python implementation of the Emme macro skimTOD5I_7c.mac. +## +## Heither 11-11-2022 +## ========================================================================================== +import os +import sys +import inro.modeller as _m +import inro.emme.desktop.app as _app + +empFl = sys.argv[1] +tod = int(sys.argv[2]) +currentScen = int(sys.argv[3]) +sThreads = int(sys.argv[4]) + +directory = os.getcwd().replace('\\Database','') +empFile = os.path.join(directory,empFl) +my_app = _app.start_dedicated(project=empFile, visible=False, user_initials="CMAP") +my_modeller = _m.Modeller(my_app) + +assign_SOLA = my_modeller.tool("inro.emme.traffic_assignment.sola_traffic_assignment") +my_emmebank = my_modeller.emmebank + +change_scenario = my_modeller.tool("inro.emme.data.scenario.change_primary_scenario") +delete_scenario = my_modeller.tool("inro.emme.data.scenario.delete_scenario") +s90 = my_emmebank.scenario(90) + +mtx = ["mf461","mf462","mf463","mf464","mf465","mf466","mf467","mf468"] ##-- storage matrices +mtxIndex = tod-1 + +skimSpec = { + "type": "SOLA_TRAFFIC_ASSIGNMENT", + "classes": [ + { + "mode": "S", + "demand": "ms97", + "generalized_cost": None, + "results": { + "link_volumes": None, + "turn_volumes": None, + "od_travel_times": { + "shortest_paths": mtx[mtxIndex] + } + }, + "path_analyses": [] + } + ], + "performance_settings": { + "number_of_processors": sThreads + }, + "background_traffic": None, + "stopping_criteria": { + "max_iterations": 0, + "relative_gap": 0.0001, + "best_relative_gap": 0.01, + "normalized_gap": 0.005 + } +} + +with _m.logbook_trace("Travel Time Skims for Time-of-Day Model: Scenario %s" % currentScen): + report = assign_SOLA(skimSpec) + + ## -- Reset primary scenario -- ## + change_scenario(scenario=currentScen) + + ## -- Delete temporary skim scenario (cannot be current scenario) -- ## + delete_scenario(scenario=s90) +print(" Travel time skim Completed for Time Period {0}".format(tod)) diff --git a/Database/macros/skim_transit.py b/Database/macros/skim_transit.py index 560b280..3e380a3 100644 --- a/Database/macros/skim_transit.py +++ b/Database/macros/skim_transit.py @@ -15,12 +15,12 @@ also performs calculations to identify first, priority and last modes. - Arguments: 1= 3-digit scenario number - 2= model Global Iteration number 0-2 - 3= time period indicator: AM, MD, PM, NT + Arguments: 1= name of Emme project file + 2= 3-digit scenario number + 3= model Global Iteration number 0-2 + 4= time period indicator: AM or MD - - Craig Heither, rev. 06-09-2025 + Craig Heither, 03-25-2024 ========================================================================================== ''' @@ -33,6 +33,7 @@ currentScen = int(sys.argv[1]) globalIter = int(sys.argv[2]) timePeriod = sys.argv[3] +donorScen = currentScen*100 + (globalIter-1)*10 + 3 ## -- used for Global Iterations 1 & 2 ## -- Trasit base fares in cents (updated Oct. 2020) -- ## ctaBusFare= 225 @@ -64,47 +65,19 @@ init_partition = my_modeller.tool("inro.emme.data.zone_partition.init_partition") change_partition = my_modeller.tool("inro.emme.data.zone_partition.change_partition_description") compute_matrix = my_modeller.tool("inro.emme.matrix_calculation.matrix_calculator") -copy_scenario = my_modeller.tool("inro.emme.data.scenario.copy_scenario") ########################################################################################################################### -## -- Set time period parameters -- ## -if timePeriod == 'AM': - donorScen = currentScen*100 + (globalIter-1)*10 + 3 ## -- used for Global Iterations 1 & 2 - currentScen = currentScen + 3 - mtx = ("mf803","mf804","mf805","mf806","mf807","mf808","mf809","mf810","mf811","mf812","mf813","mf815","mf816","mf817","mf818") -elif timePeriod == 'MD': - donorScen = currentScen*100 + (globalIter-1)*10 + 5 ## -- used for Global Iterations 1 & 2 +## -- Set primary scenario -- ## +if timePeriod == 'MD': currentScen = currentScen + 5 - mtx = ("mf903","mf904","mf905","mf906","mf907","mf908","mf909","mf910","mf911","mf912","mf913","mf915","mf916","mf917","mf918") -elif timePeriod == 'PM': - donorScen = currentScen*100 + (globalIter-1)*10 + 7 ## -- used for Global Iterations 1 & 2 - currentScen = currentScen + 7 - mtx = ("mf853","mf854","mf855","mf856","mf857","mf858","mf859","mf860","mf861","mf862","mf863","mf865","mf866","mf867","mf868") - ## -- Copy PM peak transit scenario for skimming -- ## - skimScen = currentScen + 20 - pmTran = copy_scenario(from_scenario=skimScen, - scenario_id=currentScen, - scenario_title="pm (4pm-6pm) transit skim network", - copy_linkshapes=True, - overwrite=True, - set_as_primary=True) -elif timePeriod == 'NT': - donorScen = currentScen*100 + (globalIter-1)*10 + 1 ## -- used for Global Iterations 1 & 2 - currentScen = currentScen + 1 - mtx = ("mf953","mf954","mf955","mf956","mf957","mf958","mf959","mf960","mf961","mf962","mf963","mf965","mf966","mf967","mf968") - ## -- Copy EA transit scenario for skimming -- ## - skimScen = currentScen + 20 - eaTran = copy_scenario(from_scenario=skimScen, - scenario_id=currentScen, - scenario_title="night/early am (6pm-6am) transit skim network", - copy_linkshapes=True, - overwrite=True, - set_as_primary=True) - change_scenario(scenario=currentScen) ## -- Initialize matrices -- ## +mtx = ("mf803","mf804","mf805","mf806","mf807","mf808","mf809","mf810","mf811","mf812","mf813","mf815","mf816","mf817","mf818") +if timePeriod == 'MD': + mtx = ("mf903","mf904","mf905","mf906","mf907","mf908","mf909","mf910","mf911","mf912","mf913","mf915","mf916","mf917","mf918") + new_mf1 = matrix_init(matrix_id="%s" %(mtx[0]), matrix_name="fmode_%s" %(timePeriod), matrix_description="skimmed first mode - %s" %(timePeriod), overwrite=True, default_value=3) ##-- 3=value for bus new_mf2 = matrix_init(matrix_id="%s" %(mtx[1]), matrix_name="pmode_%s" %(timePeriod), @@ -141,6 +114,8 @@ ## -- Use ul2 temporarily to store congested highway time from auto scenario -- ## ## -- Global Iteration 0: @hwytm has already been filled with pre-loaded congested times. -- ## if globalIter > 0: + if timePeriod == 'MD': + donorScen = donorScen + 2 print("currentScen={0}, timePeriod={1}, donorScen={2}".format(currentScen,timePeriod,donorScen)) ## -- Initialize ul2 [link variable] and @hwytm [segment variable] -- ## diff --git a/Database/macros/tod_skim_setup.mac b/Database/macros/tod_skim_setup.mac new file mode 100644 index 0000000..f85cf17 --- /dev/null +++ b/Database/macros/tod_skim_setup.mac @@ -0,0 +1,147 @@ +~# +~/********************************************************************** +~/********************************************************************** +~# +~/ Macro TOD_skim_setup.mac %1% %2% +~/ Where %1% = three digit alternative ID number. +~/ %2% = time period number +~# +~/********************************************************************** +~/ Macro written to create time skims for each time period. +~/********************************************************************** +~/ Time and distance skims are prepared for the following time periods +~/ and stored in these full matricies. +~# +~/ mf461 = overnight 8p-6a SOV hwy time skim +~/ mf462 = am pre-pk shoulder 6a-7a SOV hwy time skim +~/ mf463 = am peak 7a-9a SOV time skim +~/ mf464 = am post-pk shoulder 9a-10a SOV hwy time skim +~/ mf465 = midday 10a-2p SOV hwy time skim +~/ mf466 = pm pre-pk shoulder 2p-4p SOV hwy time skim +~/ mf467 = pm peak 4p-6p SOV hwy time +~/ mf468 = pm post-pk shoulder 6p-8p SOV hwy time skim +~/ +~/ ms97 = dummy operand for demand matrix in assignment setup (5.11) +~/ +~/ extra function parameter (el1) used in averaging vdfs +~# +~/********************************************************************** +~/ Set reports and batchin +~/********************************************************************** +reports=report\iter_%ms98%\skimtod_iter_%s%.rxt +~o|39 +~x=%ms98% +batchin=data\vdf_iter.in +~# +~/********************************************************************** +~# +~/ Use averaging volume delay functions for skimming. +~/ Delete existing functions and batch in new functions. +~# +~/********************************************************************** +~+;4.12;4;fd1,fd10; ;~?e;~$>err;y +~:err +q +~# +4.11 +2 +~# +~/********************************************************************** +~/ Make temp copy of scenarios for skimming. +~/********************************************************************** +~# +~z=%s% +~# ## -- Delete temp scenario if it exists -- ## +1.22 +2 +90 +~?e +~+; ;q;~$>next +yes +q +~:next +~# ## -- Copy scenario -- ## +1.22 +3 +%z% +90 +temp scenario %2% for skimming +no +q +~# +~/********************************************************************** +~/ Set scenario. +~/********************************************************************** +~x=90 +~# +s=%x% +~/********************************************************************** +~/ Set period text registers. +~/********************************************************************** +~# -- SOV -- +~r1=46%2% +~t1=todtime%2% +~t2=SOV hwy time skim period %2% +~# +~# +~/********************************************************************** +~/ Initialize time matrix +~/********************************************************************** +~# +3.12 +2 +mf%r1% +~?e +~$>err +yes +~$>end +~:err + +r +~:end +~+; 1; mf%r1%; %t1%; %t2%; 0.0 +~# +q +~# +~/********************************************************************** +~/ Sum class average volumes into new extra attrib @avtot +~/********************************************************************** +2.42 +3 +@avtot +~?e +~$>err +yes +q +~$>end +~:err + +q +~:end +~/ +2.42 +2 +2 +@avtot +total average volume (veq) +0 +q +2.41 +1 +yes +@avtot +no +@avs1v+@avs2v+@avs3v+@avh2v+@avh3v+@avbqv+@avlqv+@avmqv+@avhqv + +all +2 +2 +q +~# +~# +el1=@avtot +~/********************************************************************** +reports= +batchin= +~/********************************************************************** +q diff --git a/Database/macros/transit_skim_final_matrices.py b/Database/macros/transit_skim_final_matrices1.py similarity index 78% rename from Database/macros/transit_skim_final_matrices.py rename to Database/macros/transit_skim_final_matrices1.py index b3412ca..6ccf024 100644 --- a/Database/macros/transit_skim_final_matrices.py +++ b/Database/macros/transit_skim_final_matrices1.py @@ -1,22 +1,19 @@ ############################################################################# # TRANSIT_SKIM_FINAL_MATRICES1.PY # -# Craig Heither, last revised 06-09-2025 # +# Craig Heither, last revised 04-04-2019 # # # # This program performs the matrix convolution portion of the transit # -# skim procedures (much more efficiently than Emme). # +# skim procedures (much more efficiently than Emme) for the AM peak. # # # # Written to work with Emme 4 structure. # # Rev Bozic to work with series 800 ampk matrices 11/2/2017 # # for integration with global iterations # # 04-04-2019: Heither - implement vectorized calculations using NumPy. # -# 07/23/2020 Ferguson: Explicity cast kzone values as integers for # +# 07/23/2020 Ferguson: Explicity cast kzone values as integers for # # compatibility with np.add() in NumPy 1.16. # -# 01/14/2025 Heither: Flexibility to work for any transit time period. # -# # -# Arguments: 1= time period indicator: AM, MD, PM, NT # ############################################################################# -import os, sys, string, array, numpy as np +import os, string, array, numpy as np from array import * # ---------------------------------------------------------------------------------------- @@ -26,51 +23,40 @@ embank = os.getcwd() + "\\emmebank" mtxpath = os.getcwd() + "\\emmemat" ### path to Emme matrix storage -timePeriod = sys.argv[1] - -if timePeriod == 'AM': - inputmtx = (44, 803, 804, 805, 808, 809, 810, 811, 818, 819, 820, 821) ## -- Input Matrix Numbers - outputmtx = (822, 823, 824, 825, 828, 829, 830, 831, 832, 833, 834) ## -- Output Matrix Numbers -elif timePeriod == 'MD': - inputmtx = (46, 903, 904, 905, 908, 909, 910, 911, 918, 919, 920, 921) ## -- Input Matrix Numbers - outputmtx = (922, 923, 924, 925, 928, 929, 930, 931, 932, 933, 934) ## -- Output Matrix Numbers -elif timePeriod == 'PM': - inputmtx = (467, 853, 854, 855, 858, 859, 860, 861, 868, 869, 870, 871) ## -- Input Matrix Numbers - outputmtx = (872, 873, 874, 875, 878, 879, 880, 881, 882, 883, 884) ## -- Output Matrix Numbers -elif timePeriod == 'NT': - inputmtx = (461, 953, 954, 955, 958, 959, 960, 961, 968, 969, 970, 971) ## -- Input Matrix Numbers - outputmtx = (972, 973, 974, 975, 978, 979, 980, 981, 982, 983, 984) ## -- Output Matrix Numbers - + # -- Input Matrix Numbers -- +inputmtx = (44, 803, 804, 805, 808, 809, 810, 811, 818, 819, 820, 821) + # -- Output Matrix Numbers -- +outputmtx = (822, 823, 824, 825, 828, 829, 830, 831, 832, 833, 834) # -- Input Matrices -- -mfauto = mtxpath + "\\mf" + str(inputmtx[0]) + ".emx" ### time period hwy time matrix -mffmode = mtxpath + "\\mf" + str(inputmtx[1]) + ".emx" ### time period skimmed first mode -mfpmode = mtxpath + "\\mf" + str(inputmtx[2]) + ".emx" ### time period skimmed priority mode -mflmode = mtxpath + "\\mf" + str(inputmtx[3]) + ".emx" ### time period skimmed last mode -mfinveh = mtxpath + "\\mf" + str(inputmtx[4]) + ".emx" ### time period skimmed in-vehicle minutes -mftrnfr = mtxpath + "\\mf" + str(inputmtx[5]) + ".emx" ### time period skimmed transfer link minutes -mftwait = mtxpath + "\\mf" + str(inputmtx[6]) + ".emx" ### time period skimmed total wait minutes -mffwait = mtxpath + "\\mf" + str(inputmtx[7]) + ".emx" ### time period skimmed first wait minutes -mfafare = mtxpath + "\\mf" + str(inputmtx[8]) + ".emx" ### time period skimmed final average fare -mfcghwy = mtxpath + "\\mf" + str(inputmtx[9]) + ".emx" ### time period congested hwy generalized cost matrix -mftcost = mtxpath + "\\mf" + str(inputmtx[10]) + ".emx" ### time period indexed transit generalized cost -mfkzone = mtxpath + "\\mf" + str(inputmtx[11]) + ".emx" ### time period intermediate zone matrix +mfauto = mtxpath + "\\mf" + str(inputmtx[0]) + ".emx" ### AM peak hwy time matrix (mf44) +mffmode = mtxpath + "\\mf" + str(inputmtx[1]) + ".emx" ### skimmed first mode (mf803) +mfpmode = mtxpath + "\\mf" + str(inputmtx[2]) + ".emx" ### skimmed priority mode (mf804) +mflmode = mtxpath + "\\mf" + str(inputmtx[3]) + ".emx" ### skimmed last mode (mf805) +mfinveh = mtxpath + "\\mf" + str(inputmtx[4]) + ".emx" ### skimmed in-vehicle minutes (mf808) +mftrnfr = mtxpath + "\\mf" + str(inputmtx[5]) + ".emx" ### skimmed transfer link minutes (mf809) +mftwait = mtxpath + "\\mf" + str(inputmtx[6]) + ".emx" ### skimmed total wait minutes (mf810) +mffwait = mtxpath + "\\mf" + str(inputmtx[7]) + ".emx" ### skimmed first wait minutes (mf811) +mfafare = mtxpath + "\\mf" + str(inputmtx[8]) + ".emx" ### skimmed final average fare (mf818) +mfcghwy = mtxpath + "\\mf" + str(inputmtx[9]) + ".emx" ### congested hwy generalized cost matrix (mf819) +mftcost = mtxpath + "\\mf" + str(inputmtx[10]) + ".emx" ### indexed transit generalized cost (mf820) +mfkzone = mtxpath + "\\mf" + str(inputmtx[11]) + ".emx" ### intermediate zone matrix (mf821) # -- Output Matrices -- -mfinvehi = mtxpath + "\\mf" + str(outputmtx[0]) + ".emx" ### indexed in-vehicle minutes -mftrnfri = mtxpath + "\\mf" + str(outputmtx[1]) + ".emx" ### indexed walk transfer minutes -mftwaiti = mtxpath + "\\mf" + str(outputmtx[2]) + ".emx" ### indexed total wait minutes -mffwaiti = mtxpath + "\\mf" + str(outputmtx[3]) + ".emx" ### indexed first wait minutes -mfafarei = mtxpath + "\\mf" + str(outputmtx[4]) + ".emx" ### indexed final average fare -mffmodei = mtxpath + "\\mf" + str(outputmtx[5]) + ".emx" ### indexed first mode -mfpmodei = mtxpath + "\\mf" + str(outputmtx[6]) + ".emx" ### indexed priority mode -mflmodei = mtxpath + "\\mf" + str(outputmtx[7]) + ".emx" ### indexed last mode -mfacosti = mtxpath + "\\mf" + str(outputmtx[8]) + ".emx" ### indexed auto generalized cost -mfautrni = mtxpath + "\\mf" + str(outputmtx[9]) + ".emx" ### indexed auto min. to transit -mfratioi = mtxpath + "\\mf" + str(outputmtx[10]) + ".emx" ### indexed transit/auto only +mfinvehi = mtxpath + "\\mf" + str(outputmtx[0]) + ".emx" ### indexed in-vehicle minutes (mf822) +mftrnfri = mtxpath + "\\mf" + str(outputmtx[1]) + ".emx" ### indexed walk transfer minutes (mf823) +mftwaiti = mtxpath + "\\mf" + str(outputmtx[2]) + ".emx" ### indexed total wait minutes (mf824) +mffwaiti = mtxpath + "\\mf" + str(outputmtx[3]) + ".emx" ### indexed first wait minutes (mf825) +mfafarei = mtxpath + "\\mf" + str(outputmtx[4]) + ".emx" ### indexed final average fare (mf828) +mffmodei = mtxpath + "\\mf" + str(outputmtx[5]) + ".emx" ### indexed first mode (mf829) +mfpmodei = mtxpath + "\\mf" + str(outputmtx[6]) + ".emx" ### indexed priority mode (mf830) +mflmodei = mtxpath + "\\mf" + str(outputmtx[7]) + ".emx" ### indexed last mode (mf831) +mfacosti = mtxpath + "\\mf" + str(outputmtx[8]) + ".emx" ### indexed auto generalized cost (mf832) +mfautrni = mtxpath + "\\mf" + str(outputmtx[9]) + ".emx" ### indexed auto min. to transit (mf833) +mfratioi = mtxpath + "\\mf" + str(outputmtx[10]) + ".emx" ### indexed transit/auto only (mf834) # -- Others -- cutoff = 0.4 ### cutoff value for indexed transit cost/auto only trip cost -stats = os.getcwd() + "\\report\\transit_skim_stats_%s.txt" %(timePeriod) +stats = os.getcwd() + "\\report\\transit_skim_stats8.txt" if os.path.exists(stats): os.remove(stats) diff --git a/Database/macros/transit_skim_final_matrices2.py b/Database/macros/transit_skim_final_matrices2.py new file mode 100644 index 0000000..7d316b4 --- /dev/null +++ b/Database/macros/transit_skim_final_matrices2.py @@ -0,0 +1,182 @@ +############################################################################# +# TRANSIT_SKIM_FINAL_MATRICES2.PY # +# Craig Heither, last revised 04-04-2019 # +# # +# This program performs the matrix convolution portion of the transit # +# skim procedures (much more efficiently than Emme) for the midday. # +# # +# Written to work with Emme 4 structure. # +# Rev Bozic to work with series 900 midday matrices 11/2/2017 # +# for integration with global iterations # +# 04-04-2019: Heither - implement vectorized calculations using NumPy. # +# 07/23/2020 Ferguson: Explicity cast kzone values as integers for # +# compatibility with np.add() in NumPy 1.16. # +############################################################################# + +import os, string, array, numpy as np +from array import * + +# ---------------------------------------------------------------------------------------- +# Set Variables. +# Note: these should only be changed if the transit skim procedures are altered. +# ---------------------------------------------------------------------------------------- +embank = os.getcwd() + "\\emmebank" +mtxpath = os.getcwd() + "\\emmemat" ### path to Emme matrix storage + + # -- Input Matrix Numbers -- +inputmtx = (46, 903, 904, 905, 908, 909, 910, 911, 918, 919, 920, 921) + # -- Output Matrix Numbers -- +outputmtx = (922, 923, 924, 925, 928, 929, 930, 931, 932, 933, 934) + +# -- Input Matrices -- +mfauto = mtxpath + "\\mf" + str(inputmtx[0]) + ".emx" ### midday hwy time matrix (mf46) +mffmode = mtxpath + "\\mf" + str(inputmtx[1]) + ".emx" ### skimmed first mode (mf903) +mfpmode = mtxpath + "\\mf" + str(inputmtx[2]) + ".emx" ### skimmed priority mode (mf904) +mflmode = mtxpath + "\\mf" + str(inputmtx[3]) + ".emx" ### skimmed last mode (mf905) +mfinveh = mtxpath + "\\mf" + str(inputmtx[4]) + ".emx" ### skimmed in-vehicle minutes (mf908) +mftrnfr = mtxpath + "\\mf" + str(inputmtx[5]) + ".emx" ### skimmed transfer link minutes (mf909) +mftwait = mtxpath + "\\mf" + str(inputmtx[6]) + ".emx" ### skimmed total wait minutes (mf910) +mffwait = mtxpath + "\\mf" + str(inputmtx[7]) + ".emx" ### skimmed first wait minutes (mf911) +mfafare = mtxpath + "\\mf" + str(inputmtx[8]) + ".emx" ### skimmed final average fare (mf918) +mfcghwy = mtxpath + "\\mf" + str(inputmtx[9]) + ".emx" ### congested hwy generalized cost matrix (mf919) +mftcost = mtxpath + "\\mf" + str(inputmtx[10]) + ".emx" ### indexed transit generalized cost (mf920) +mfkzone = mtxpath + "\\mf" + str(inputmtx[11]) + ".emx" ### intermediate zone matrix (mf921) +# -- Output Matrices -- +mfinvehi = mtxpath + "\\mf" + str(outputmtx[0]) + ".emx" ### indexed in-vehicle minutes (mf922) +mftrnfri = mtxpath + "\\mf" + str(outputmtx[1]) + ".emx" ### indexed walk transfer minutes (mf923) +mftwaiti = mtxpath + "\\mf" + str(outputmtx[2]) + ".emx" ### indexed total wait minutes (mf924) +mffwaiti = mtxpath + "\\mf" + str(outputmtx[3]) + ".emx" ### indexed first wait minutes (mf925) +mfafarei = mtxpath + "\\mf" + str(outputmtx[4]) + ".emx" ### indexed final average fare (mf928) +mffmodei = mtxpath + "\\mf" + str(outputmtx[5]) + ".emx" ### indexed first mode (mf929) +mfpmodei = mtxpath + "\\mf" + str(outputmtx[6]) + ".emx" ### indexed priority mode (mf930) +mflmodei = mtxpath + "\\mf" + str(outputmtx[7]) + ".emx" ### indexed last mode (mf931) +mfacosti = mtxpath + "\\mf" + str(outputmtx[8]) + ".emx" ### indexed auto generalized cost (mf932) +mfautrni = mtxpath + "\\mf" + str(outputmtx[9]) + ".emx" ### indexed auto min. to transit (mf933) +mfratioi = mtxpath + "\\mf" + str(outputmtx[10]) + ".emx" ### indexed transit/auto only (mf934) + +# -- Others -- +cutoff = 0.4 ### cutoff value for indexed transit cost/auto only trip cost +stats = os.getcwd() + "\\report\\transit_skim_stats9.txt" + +if os.path.exists(stats): + os.remove(stats) + +# --------------------------------------------------------------- +# Open emmebank and read metadata. +# --------------------------------------------------------------- +a0 = array('i') +a1 = array('i') +with open(embank,'r+b') as f: + # ## Read first 512 items: this is File 0 - metadata about files ## + a0.fromfile(f,512) ## grabs file offset, # of records, words/record & file type: 1-integer, 2-real, 3-text + + # ## Read Global parameters from File 1: array index starts with zero not 1, so is -1 from EMME documentation ## + offst = a0[102] * 4 ## File 1 offset: elements * 4 bytes + f.seek(offst, 0) + a1.fromfile(f,80) + mcent = a1[51] ## maximum number of centroids defined in emmebank + print("\tREADING EMMEBANK: {0} Centroids".format(str(mcent),)) + + # ## Read Project title from File 2 ## + offst = a0[104] * 4 + f.seek(offst, 0) + + # ## Write Emmebank parameters to File to review ## + outFile = open(stats, 'w') + outFile.write("Max. scenarios: {0} \n".format((a1[50]),)) + outFile.write("Max. centroids: {0} \n".format((a1[51]),)) + outFile.write("Max. nodes: {0} \n".format((a1[52]),)) + outFile.write("Max. links: {0} \n".format((a1[53]),)) + outFile.write("Max. length turn penalty table: {0} \n".format((a1[54]),)) + outFile.write("Max. transit lines: {0} \n".format((a1[55]),)) + outFile.write("Max. line segments: {0} \n".format((a1[56]),)) + outFile.write("Max. number of matrices: {0} \n".format((a1[57]),)) + outFile.write("Max. number of functions/class: {0} \n".format((a1[58]),)) + outFile.write("Max. number of operators/function class: {0} \n".format((a1[59]),)) + outFile.write("\n") + for z in range(1, 100): + outFile.write("File {0:>3} - Type {1} Offset {2:>10} Word/Rec {3:>8} Records {4:>4} \n".format(z, (a0[z+400]), (a0[2*z+100]), (a0[z+300]), (a0[z]))) + + outFile.close() + + +# --------------------------------------------------------------- +# Store matrix values in arrays. +# --------------------------------------------------------------- + # -- Input Matrices -- +dt = np.dtype('float32') +auto = np.fromfile(mfauto, dtype=dt) +kzone = np.fromfile(mfkzone, dtype=dt) +tcost = np.fromfile(mftcost, dtype=dt) +inveh = np.fromfile(mfinveh, dtype=dt) +trnfr = np.fromfile(mftrnfr, dtype=dt) +twait = np.fromfile(mftwait, dtype=dt) +fwait = np.fromfile(mffwait, dtype=dt) +afare = np.fromfile(mfafare, dtype=dt) +fmode = np.fromfile(mffmode, dtype=dt) +pmode = np.fromfile(mfpmode, dtype=dt) +lmode = np.fromfile(mflmode, dtype=dt) +cghwy = np.fromfile(mfcghwy, dtype=dt) + +## -- create leg1 (p-k) indices +indxloc = np.arange(mcent*mcent) ## -- array of consecutive numbers representing element index values +leg1pt1 = np.divide(indxloc,mcent) +leg1pt1 = np.multiply(leg1pt1.astype('i4'),mcent,dtype='i4') ## -- portion of element index defining origin zone +leg1indx = np.add(leg1pt1,kzone.astype('i4')-1,dtype='i4') ## -- add portion of element index defining destination zone +#print("Kzone 1-1: {0}, Index 1-1: {1}, Kzone 121-2: {2}, Index 121-2: {3} \n".format(kzone[0], leg1indx[0], kzone[437882], leg1indx[437882])) + +## -- create leg2 (k-q) indices +leg2pt1 = np.multiply(kzone.astype('i4')-1,mcent) +leg2pt2 = np.mod(indxloc,mcent) +leg2indx = np.add(leg2pt1,leg2pt2,dtype='i4') +#print("Kzone 1-1: {0}, Index 1-1: {1}, Kzone 121-2: {2}, Index 121-2: {3} \n".format(kzone[0], leg2indx[0], kzone[437882], leg2indx[437882])) + +# --------------------------------------------------------------- +# Create indexed matrices. +# --------------------------------------------------------------- +autoval = np.where(kzone>0, auto[leg1indx], kzone) ## -- hwy time matrix +tcostval = np.where(kzone>0, tcost[leg1indx], kzone) ## -- indexed transit generalized cost +invehval = np.where(kzone>0, inveh[leg2indx], kzone) ## -- skimmed in-vehicle minutes +trnfrval = np.where(kzone>0, trnfr[leg2indx], kzone) ## -- skimmed transfer link minutes +twaitval = np.where(kzone>0, twait[leg2indx], kzone) ## -- skimmed total wait minutes +fwaitval = np.where(kzone>0, fwait[leg2indx], kzone) ## -- skimmed first wait minutes +afareval = np.where(kzone>0, afare[leg2indx], kzone) ## -- skimmed final average fare +fmodeval = np.where(kzone>0, fmode[leg2indx], kzone) ## -- skimmed first mode +pmodeval = np.where(kzone>0, pmode[leg2indx], kzone) ## -- skimmed priority mode +lmodeval = np.where(kzone>0, lmode[leg2indx], kzone) ## -- skimmed last mode +threshold = np.where(cghwy>0, np.divide(tcostval,cghwy), cghwy) ## -- ratio of indexed transit cost to auto only cost + +## -- Swap original matrix value back in if the threshold exceeds the cutoff value +autoval = np.where(threshold>cutoff, 0, autoval).astype(dt) +tcostval = np.where(threshold>cutoff, 0, tcostval).astype(dt) +invehval = np.where(threshold>cutoff, inveh, invehval).astype(dt) +trnfrval = np.where(threshold>cutoff, trnfr, trnfrval).astype(dt) +twaitval = np.where(threshold>cutoff, twait, twaitval).astype(dt) +fwaitval = np.where(threshold>cutoff, fwait, fwaitval).astype(dt) +afareval = np.where(threshold>cutoff, afare, afareval).astype(dt) +fmodeval = np.where(threshold>cutoff, fmode, fmodeval).astype(dt) +pmodeval = np.where(threshold>cutoff, pmode, pmodeval).astype(dt) +lmodeval = np.where(threshold>cutoff, lmode, lmodeval).astype(dt) + + +# --------------------------------------------------------------- +# Write final matrix values into files. +# --------------------------------------------------------------- + # -- Arrays to write out +mtxlist = (invehval, trnfrval, twaitval, fwaitval, afareval, fmodeval, pmodeval, lmodeval, tcostval, autoval, threshold) + # -- Files to write to +outmtx = (mfinvehi, mftrnfri, mftwaiti, mffwaiti, mfafarei, mffmodei, mfpmodei, mflmodei, mfacosti, mfautrni, mfratioi) +x = 0 +outFl = open(stats, 'a') +outFl.write("\n\n {0:=^100}\n\n".format('=',)) + +for m in outmtx: + mtxlist[x].tofile(outmtx[x]) + (fpath, fname) = os.path.split(outmtx[x]) + outFl.write("{0} Written Successfully.\n".format(fname, )) + outFl.write("\t-- Minimum = {0:.4f}\n\t-- Maximum = {1:0.4f}\n\t-- Mean = {2:0.4f}\n\t-- Sum = {3:0.4f}\n\n".format(min(mtxlist[x]), max(mtxlist[x]), sum(mtxlist[x])/len(mtxlist[x]), sum(mtxlist[x]))) + x += 1 + +outFl.close() + +print("-- TRANSIT SKIM MATRICES CREATED --") diff --git a/Database/macros/transit_skim_wrapup.py b/Database/macros/transit_skim_wrapup.py index c9a82ef..7a6b533 100644 --- a/Database/macros/transit_skim_wrapup.py +++ b/Database/macros/transit_skim_wrapup.py @@ -1,80 +1,76 @@ -''' - transit_skim_wrapup.py - - Finalizes the transit skimming process: transit skim matrices moved to final locations in preparation for the destination choice- - mode choice model and temporary matrices deleted. - - - Arguments: 1= time period indicator: AM, MD, PM, NT - - - Craig Heither, 06-09-2025 - ========================================================================================== -''' - -import os -import sys -from pathlib import Path -sys.path.append(str(Path(__file__).resolve().parents[2].joinpath('Scripts'))) -from tbmtools import project as tbm - -timePeriod = sys.argv[1] - -maxInternal=3632 ## -- highest non-POE zone number - -proj_dir = Path(__file__).resolve().parents[2] -my_modeller = tbm.connect(proj_dir) -my_emmebank = my_modeller.emmebank - -matrix_init = my_modeller.tool("inro.emme.data.matrix.create_matrix") -compute_matrix = my_modeller.tool("inro.emme.matrix_calculation.matrix_calculator") -netcalc = my_modeller.tool("inro.emme.network_calculation.network_calculator") -delete_matrix = my_modeller.tool("inro.emme.data.matrix.delete_matrix") -########################################################################################################################### - -if timePeriod == 'AM': - mtx = ("mf837","mf838","mf821","mf824") - a = list(range(803,820)) ## -- matrices to delete -elif timePeriod == 'MD': - mtx = ("mf937","mf938","mf921","mf924") - a = list(range(903,920)) ## -- matrices to delete -elif timePeriod == 'PM': - mtx = ("mf887","mf888","mf871","mf874") - a = list(range(853,870)) ## -- matrices to delete -elif timePeriod == 'NT': - mtx = ("mf987","mf988","mf971","mf974") - a = list(range(953,970)) ## -- matrices to delete - - -## -- Initialize matrices -- ## -new_mf1 = matrix_init(matrix_id="%s" %(mtx[0]), matrix_name="kasmtp_%s" %(timePeriod), - matrix_description="indexed station zone for transit assignment - %s" %(timePeriod), overwrite=True, default_value=0) -new_mf2 = matrix_init(matrix_id="%s" %(mtx[1]), matrix_name="phdway_%s" %(timePeriod), - matrix_description="indexed headway (indexed wait time x 2) - %s" %(timePeriod), overwrite=True, default_value=0) -## -- Create indexed station zone matrix for transit assignment: equal to mfx21 [05-06-2022] -- ## -m1Spec = { - "type": "MATRIX_CALCULATION", "result": "%s" %(mtx[0]), "expression": "%s" %(mtx[2]), - "constraint": { - "by_value": None, - "by_zone": {"origins": "1,%s" %(maxInternal), "destinations": "1,%s" %(maxInternal)} - }, - "aggregation": {"origins": None, "destinations": None}, - } -## -- Recalculate headway matrix -- ## -m2Spec = { - "type": "MATRIX_CALCULATION", "result": "%s" %(mtx[1]), "expression": "%s*2" %(mtx[3]), - "constraint": {"by_value": None, "by_zone": None}, - "aggregation": {"origins": None, "destinations": None}, - } -report = compute_matrix([m1Spec,m2Spec]) -## -- Initialize ui3 -- ## -calcUi3 = {"type": "NETWORK_CALCULATION", "result": "ui3", "expression": "0", "aggregation": None, "selections": {"node": "all"}} -report=netcalc(calcUi3, full_report=False) - -## -- Delete unneeded matrices -- ## -for item in a: - matrix = my_emmebank.matrix("mf" + str(item)) - if matrix: - delete_matrix(matrix) - +''' + transit_skim_wrapup.py + + Finalizes the transit skimming process: transit skim matrices moved to final locations in preparation for the destination choice- + mode choice model and temporary matrices deleted. + + + Arguments: 1= name of Emme project file + 2= time period indicator: AM or MD + + Craig Heither, 03-25-2024 + ========================================================================================== +''' + +import os +import sys +import inro.modeller as _m +import inro.emme.desktop.app as _app + +empFl = sys.argv[1] +timePeriod = sys.argv[2] + +maxInternal=3632 ## -- highest non-POE zone number + +directory = os.getcwd().replace('\\Database','') +empFile = os.path.join(directory,empFl) +my_app = _app.start_dedicated(project=empFile, visible=False, user_initials="CMAP") +my_modeller = _m.Modeller(my_app) +my_emmebank = my_modeller.emmebank + +matrix_init = my_modeller.tool("inro.emme.data.matrix.create_matrix") +compute_matrix = my_modeller.tool("inro.emme.matrix_calculation.matrix_calculator") +netcalc = my_modeller.tool("inro.emme.network_calculation.network_calculator") +delete_matrix = my_modeller.tool("inro.emme.data.matrix.delete_matrix") +########################################################################################################################### + +## -- Initialize matrices -- ## +mtx = ("mf837","mf838","mf821","mf824") +if timePeriod == 'MD': + mtx = ("mf937","mf938","mf921","mf924") + +new_mf1 = matrix_init(matrix_id="%s" %(mtx[0]), matrix_name="kasmtp_%s" %(timePeriod), + matrix_description="indexed station zone for transit assignment - %s" %(timePeriod), overwrite=True, default_value=0) +new_mf2 = matrix_init(matrix_id="%s" %(mtx[1]), matrix_name="phdway_%s" %(timePeriod), + matrix_description="indexed headway (indexed wait time x 2) - %s" %(timePeriod), overwrite=True, default_value=0) +## -- Create indexed station zone matrix for transit assignment: equal to mfx21 [05-06-2022] -- ## +m1Spec = { + "type": "MATRIX_CALCULATION", "result": "%s" %(mtx[0]), "expression": "%s" %(mtx[2]), + "constraint": { + "by_value": None, + "by_zone": {"origins": "1,%s" %(maxInternal), "destinations": "1,%s" %(maxInternal)} + }, + "aggregation": {"origins": None, "destinations": None}, + } +## -- Recalculate headway matrix -- ## +m2Spec = { + "type": "MATRIX_CALCULATION", "result": "%s" %(mtx[1]), "expression": "%s*2" %(mtx[3]), + "constraint": {"by_value": None, "by_zone": None}, + "aggregation": {"origins": None, "destinations": None}, + } +report = compute_matrix([m1Spec,m2Spec]) +## -- Initialize ui3 -- ## +calcUi3 = {"type": "NETWORK_CALCULATION", "result": "ui3", "expression": "0", "aggregation": None, "selections": {"node": "all"}} +report=netcalc(calcUi3, full_report=False) + +## -- Delete unneeded matrices -- ## +a = list(range(803,820)) +if timePeriod == 'MD': + a = list(range(903,920)) + +for item in a: + matrix = my_emmebank.matrix("mf" + str(item)) + if matrix: + delete_matrix(matrix) + print(' -- {0} transit skim matrix clean up done'.format(timePeriod)) \ No newline at end of file diff --git a/Database/macros/transit_triple_indexing.py b/Database/macros/transit_triple_indexing.py index 00b9b77..09b7247 100644 --- a/Database/macros/transit_triple_indexing.py +++ b/Database/macros/transit_triple_indexing.py @@ -4,10 +4,10 @@ Performs the matrix triple-indexing necessary to identify the least cost transit station used to support drive to transit trips. - Arguments: 1= 3-digit scenario number - 2= time period indicator: AM, MD, PM, NT + Arguments: 1= name of Emme project file + 2= time period indicator: AM or MD - Craig Heither, 06-09-2025 + Craig Heither, 03-25-2024 ========================================================================================== ''' @@ -17,8 +17,7 @@ sys.path.append(str(Path(__file__).resolve().parents[2].joinpath('Scripts'))) from tbmtools import project as tbm -currentScen = int(sys.argv[1]) -timePeriod = sys.argv[2] +timePeriod = sys.argv[1] maxInternal=3632 ## -- highest non-POE zone number @@ -35,7 +34,6 @@ my_modeller = tbm.connect(proj_dir) my_emmebank = my_modeller.emmebank -change_scenario = my_modeller.tool("inro.emme.data.scenario.change_primary_scenario") matrix_init = my_modeller.tool("inro.emme.data.matrix.create_matrix") compute_matrix = my_modeller.tool("inro.emme.matrix_calculation.matrix_calculator") init_partition = my_modeller.tool("inro.emme.data.zone_partition.init_partition") @@ -44,24 +42,13 @@ triple_index = my_modeller.tool("inro.emme.matrix_calculation.matrix_triple_index_operation") ########################################################################################################################### -if timePeriod == 'AM': - mtx = ("mf819","mf820","mf821","mf834","mo801","mo802","mo803","mo804","mo805","mo602","mf822","mf823","mf824","mf825","mf828","mf829", - "mf830","mf831","mf832","mf833","mf44","mf45","mf807","mf808") - currentScen = currentScen + 3 -elif timePeriod == 'MD': +## -- Initialize matrices -- ## +mtx = ("mf819","mf820","mf821","mf834","mo801","mo802","mo803","mo804","mo805","mo602","mf822","mf823","mf824","mf825","mf828","mf829", + "mf830","mf831","mf832","mf833","mf44","mf45","mf807","mf808") +if timePeriod == 'MD': mtx = ("mf919","mf920","mf921","mf934","mo901","mo902","mo903","mo904","mo905","mo602","mf922","mf923","mf924","mf925","mf928","mf929", "mf930","mf931","mf932","mf933","mf46","mf47","mf907","mf908") - currentScen = currentScen + 5 -elif timePeriod == 'PM': - mtx = ("mf869","mf870","mf871","mf884","mo851","mo852","mo853","mo854","mo855","mo652","mf872","mf873","mf874","mf875","mf878","mf879", - "mf880","mf881","mf882","mf883","mf467","mf477","mf857","mf858") ## need TOD time/dist skim not mf44-45 - currentScen = currentScen + 7 -elif timePeriod == 'NT': - mtx = ("mf969","mf970","mf971","mf984","mo951","mo952","mo953","mo954","mo955","mo652","mf972","mf973","mf974","mf975","mf978","mf979", - "mf980","mf981","mf982","mf983","mf461","mf471","mf957","mf958") ## need TOD time/dist skim not mf46-47 - currentScen = currentScen + 1 - -## -- Initialize matrices -- ## + new_mf1 = matrix_init(matrix_id="%s" %(mtx[0]), matrix_name="hwygc_%s" %(timePeriod), matrix_description="congested hwy generalized cost - %s" %(timePeriod), overwrite=True, default_value=0) new_mf2 = matrix_init(matrix_id="%s" %(mtx[1]), matrix_name="trngc_%s" %(timePeriod), @@ -103,7 +90,6 @@ new_mf14 = matrix_init(matrix_id="%s" %(mtx[19]), matrix_name="minut_%s" %(timePeriod), matrix_description="indexed auto minutes to transit - %s" %(timePeriod), overwrite=True, default_value=0) -change_scenario(scenario=currentScen) #============================================================================== ## -- INDEX AUTO ACCESS AND PARKING @@ -195,8 +181,8 @@ } report = triple_index(tripleSpec) -## -- Adjust kzone matrix - Keep the original zone if: the trip is intrazonal or if there is skimmed transit service available (mtx[23]) and service -- ## -## -- originates within the City of Chicago. Otherwise, apply the indexed station zone. (mtx[23] is unindexed transit in-vehicle time) [07-16-2022] -- ## +## -- Adjust kzone matrix - Keep the original zone if: the trip is intrazonal or if there is skimmed transit service available (mf8) and service -- ## +## -- originates within the City of Chicago. Otherwise, apply the indexed station zone. (mf8 is unindexed transit in-vehicle time) [07-16-2022] -- ## finIndexSpec = { "type": "MATRIX_CALCULATION", "result": "%s" %(mtx[2]), "expression": "((%s.lt.1000 .and. ga(p).eq.1).or.(p.eq.q))*p + ((%s.ge.1000 .or. ga(p).ne.1).and.(p.ne.q))*%s" %(mtx[23], mtx[23], mtx[2]), diff --git a/Database/prep_macros/create_distr_m01_files.R b/Database/prep_macros/create_distr_m01_files.R index 2b8827c..2adfdcc 100644 --- a/Database/prep_macros/create_distr_m01_files.R +++ b/Database/prep_macros/create_distr_m01_files.R @@ -370,7 +370,7 @@ cta_s <- bus %>% #pace flag cutoffs reflect the distribution of sidewalk density in the whole region sidewalk_zn <- in8 %>% - rename(subzone17 = V1, sidewalkD = V14) %>% + rename(subzone17 = V1, sidewalkD = V36) %>% select(subzone17, sidewalkD) %>% left_join(szC, by = "subzone17") %>% group_by(zone17) %>% diff --git a/Database/prep_macros/distr_m01_data.py b/Database/prep_macros/distr_m01_data.py index a1f799d..5d7c4af 100644 --- a/Database/prep_macros/distr_m01_data.py +++ b/Database/prep_macros/distr_m01_data.py @@ -1,115 +1,115 @@ -#filename: distr_m01_data.py -#description: Python script uses the EMME Modeler API to punch transit network and itinerary data for DISTR and M01 files creation -#author: Karly Cazzato, 9/20/2023 - -import os -import sys -import inro.emme.desktop.app as _app -import inro.modeller as _m -import pandas as pd - -def main(): - # Define the path to the Emme project (.emp file) - empFl = sys.argv[1] - directory = os.getcwd().replace('\\Database','') - empFile = os.path.join(directory,empFl) - - # start a dedicated instance of Emme Desktop connected to the specified project - desktop = _app.start_dedicated( - visible=True, - user_initials='KCC', - project= empFile - ) - - # Connect to the Modeller - modeller = _m.Modeller(desktop=desktop) - emmebank = modeller.emmebank - netcalc = modeller.tool('inro.emme.network_calculation.network_calculator') - - # define variables - currentScen = int(sys.argv[2]) - scenAM = currentScen + 3 - scenMD = currentScen + 5 - t1= r'prep_macros\temp' - t2= 'transit.itin' - t3= 'node.txt' - itinOut = (t1 + '\\' + t2) - nodeOut = (t1 + '\\' + t3) - - #load specs - itinAM = '''{ - "result": null, - "expression": "dwt + veh + hdw", - "aggregation": null, - "selections": { - "link": "all", - "transit_line": "all" - }, - "type": "NETWORK_CALCULATION" - }''' - - nodeAM = '''{ - "result": null, - "expression": "@pspac+@pcost+xi+yi+@zone", - "aggregation": null, - "selections": { - "node": "5000,99999" - }, - "type": "NETWORK_CALCULATION" - }''' - #run and save AM - itineraryAM = netcalc(itinAM, scenario = emmebank.scenario(scenAM), full_report = True) - nodeAM = netcalc(nodeAM, scenario = emmebank.scenario(scenAM), full_report = True) - - itineraryAMDF = pd.DataFrame(columns = itineraryAM['table'][0], data = itineraryAM['table'][1:]) - with open(itinOut, 'a') as f: - dfAsString = itineraryAMDF.to_string(header=True, index=False) - f.write(dfAsString) - - nodeAMDF = pd.DataFrame(columns = nodeAM['table'][0], data = nodeAM['table'][1:]) - with open(nodeOut, 'a') as f: - dfAsString = nodeAMDF.to_string(header=True, index=False) - f.write(dfAsString) - #load spec Midday - itinMD = '''{ - "result": null, - "expression": "dwt + veh + hdw", - "aggregation": null, - "selections": { - "link": "mod=BEPLQ", - "transit_line": "mod=BEPLQ" - }, - "type": "NETWORK_CALCULATION" - }''' - - nodeMD = '''{ - "result": null, - "expression": "@pspac+@pcost+xi+yi+@zone", - "aggregation": null, - "selections": { - "node": "5000,29999" - }, - "type": "NETWORK_CALCULATION" - }''' - #run and save midday - itineraryMD = netcalc(itinMD, scenario = emmebank.scenario(scenMD), full_report = True) - nodeMD = netcalc(nodeMD, scenario = emmebank.scenario(scenMD), full_report = True) - - t1= r'prep_macros\temp' - t2= 'transit_midday.itin' - t3= 'node_midday.txt' - itinOut = (t1 + '\\' + t2) - nodeOut = (t1 + '\\' + t3) - - itineraryMDDF = pd.DataFrame(columns = itineraryMD['table'][0], data = itineraryMD['table'][1:]) - with open(itinOut, 'a') as f: - dfAsString = itineraryMDDF.to_string(header=True, index=False) - f.write(dfAsString) - - nodeMDDF = pd.DataFrame(columns = nodeMD['table'][0], data = nodeMD['table'][1:]) - with open(nodeOut, 'a') as f: - dfAsString = nodeMDDF.to_string(header=True, index=False) - f.write(dfAsString) - desktop.close() -if __name__ == '__main__': +#filename: distr_m01_data.py +#description: Python script uses the EMME Modeler API to punch transit network and itinerary data for DISTR and M01 files creation +#author: Karly Cazzato, 9/20/2023 + +import os +import sys +import inro.emme.desktop.app as _app +import inro.modeller as _m +import pandas as pd + +def main(): + # Define the path to the Emme project (.emp file) + empFl = sys.argv[1] + directory = os.getcwd().replace('\\Database','') + empFile = os.path.join(directory,empFl) + + # start a dedicated instance of Emme Desktop connected to the specified project + desktop = _app.start_dedicated( + visible=True, + user_initials='KCC', + project= empFile + ) + + # Connect to the Modeller + modeller = _m.Modeller(desktop=desktop) + emmebank = modeller.emmebank + netcalc = modeller.tool('inro.emme.network_calculation.network_calculator') + + # define variables + currentScen = int(sys.argv[2]) + scenAM = currentScen + scenMD = scenAM + 5 + t1= r'prep_macros\temp' + t2= 'transit.itin' + t3= 'node.txt' + itinOut = (t1 + '\\' + t2) + nodeOut = (t1 + '\\' + t3) + + #load specs + itinAM = '''{ + "result": null, + "expression": "dwt + veh + hdw", + "aggregation": null, + "selections": { + "link": "all", + "transit_line": "all" + }, + "type": "NETWORK_CALCULATION" + }''' + + nodeAM = '''{ + "result": null, + "expression": "@pspac+@pcost+xi+yi+@zone", + "aggregation": null, + "selections": { + "node": "5000,99999" + }, + "type": "NETWORK_CALCULATION" + }''' + #run and save AM + itineraryAM = netcalc(itinAM, scenario = emmebank.scenario(scenAM), full_report = True) + nodeAM = netcalc(nodeAM, scenario = emmebank.scenario(scenAM), full_report = True) + + itineraryAMDF = pd.DataFrame(columns = itineraryAM['table'][0], data = itineraryAM['table'][1:]) + with open(itinOut, 'a') as f: + dfAsString = itineraryAMDF.to_string(header=True, index=False) + f.write(dfAsString) + + nodeAMDF = pd.DataFrame(columns = nodeAM['table'][0], data = nodeAM['table'][1:]) + with open(nodeOut, 'a') as f: + dfAsString = nodeAMDF.to_string(header=True, index=False) + f.write(dfAsString) + #load spec Midday + itinMD = '''{ + "result": null, + "expression": "dwt + veh + hdw", + "aggregation": null, + "selections": { + "link": "mod=BEPLQ", + "transit_line": "mod=BEPLQ" + }, + "type": "NETWORK_CALCULATION" + }''' + + nodeMD = '''{ + "result": null, + "expression": "@pspac+@pcost+xi+yi+@zone", + "aggregation": null, + "selections": { + "node": "5000,29999" + }, + "type": "NETWORK_CALCULATION" + }''' + #run and save midday + itineraryMD = netcalc(itinMD, scenario = emmebank.scenario(scenMD), full_report = True) + nodeMD = netcalc(nodeMD, scenario = emmebank.scenario(scenMD), full_report = True) + + t1= r'prep_macros\temp' + t2= 'transit_midday.itin' + t3= 'node_midday.txt' + itinOut = (t1 + '\\' + t2) + nodeOut = (t1 + '\\' + t3) + + itineraryMDDF = pd.DataFrame(columns = itineraryMD['table'][0], data = itineraryMD['table'][1:]) + with open(itinOut, 'a') as f: + dfAsString = itineraryMDDF.to_string(header=True, index=False) + f.write(dfAsString) + + nodeMDDF = pd.DataFrame(columns = nodeMD['table'][0], data = nodeMD['table'][1:]) + with open(nodeOut, 'a') as f: + dfAsString = nodeMDDF.to_string(header=True, index=False) + f.write(dfAsString) + desktop.close() +if __name__ == '__main__': main() \ No newline at end of file diff --git a/Database/prep_macros/free.skim.mac.py b/Database/prep_macros/free.skim.mac.py index 196ed35..7a527a7 100644 --- a/Database/prep_macros/free.skim.mac.py +++ b/Database/prep_macros/free.skim.mac.py @@ -1,305 +1,304 @@ -#filename: free.skim.mac.py -#description: creates time and distance skims from am-peak and midday scenarios to start distribution and mode choice -#author: Karly Cazzato, 12/05/2023 - -import os -import os.path -import sys -import inro.emme.desktop.app as _app -import inro.modeller as _m - - -def main(): - - #set variables - currentScen = int(sys.argv[2]) - scenario = str(currentScen) - directory = os.getcwd().replace('\\Database','') - batchin = directory + "\\Database\\data\\vdf_free.in" - - # Define the path to the Emme project (.emp file) - empFl = sys.argv[1] - empFile = os.path.join(directory,empFl) - desktop = _app.start_dedicated( - visible=True, - user_initials='KCC', - project= empFile - ) - - # Connect to the Modeller - modeller = _m.Modeller(desktop=desktop) - emmebank = modeller.emmebank - - #define tools - delete_function = modeller.tool("inro.emme.data.function.delete_function") - batchin_function = modeller.tool("inro.emme.data.function.function_transaction") - - create_matrix = modeller.tool("inro.emme.data.matrix.create_matrix") - matrix_calculation = modeller.tool("inro.emme.matrix_calculation.matrix_calculator") - delete_matrix = modeller.tool("inro.emme.data.matrix.delete_matrix") - - copy_scenario = modeller.tool("inro.emme.data.scenario.copy_scenario") - change_scenario = modeller.tool("inro.emme.data.scenario.change_primary_scenario") - delete_scenario = modeller.tool("inro.emme.data.scenario.delete_scenario") - - net_calc = modeller.tool("inro.emme.network_calculation.network_calculator") - - sola_assign_traffic = modeller.tool("inro.emme.traffic_assignment.sola_traffic_assignment") - - #delete existing functions for skimming and batch in new functions - for i in range(1,10): - f_id = "fd%s" % i - f = _m.Modeller().emmebank.function(f_id) - if f: delete_function(f) - - #input functions using process function transaction tool - batchin_function(transaction_file = batchin, throw_on_error = True) - - #initialize base toll matrices - mf111 = create_matrix(matrix_id="mf111", matrix_name="tshwl", matrix_description="low inc h-w sov toll", default_value=0, overwrite = "True") - mf112 = create_matrix(matrix_id="mf112", matrix_name="th2hwl", matrix_description="low inc h-w hov 2 per toll", default_value=0, overwrite = "True") - mf117 = create_matrix(matrix_id="mf117", matrix_name="tsho", matrix_description="h-o sov toll", default_value=0, overwrite = "True") - mf118 = create_matrix(matrix_id="mf118", matrix_name="th2ho", matrix_description="h-o hov 2 per toll", default_value=0, overwrite = "True") - - spec_mf112 = {"expression": "mf111", "result": "mf112", "type": "MATRIX_CALCULATION"} - spec_mf118 = {"expression": "mf117", "result": "mf118", "type": "MATRIX_CALCULATION"} - - matrix_calculation([spec_mf112, spec_mf118]) - - #set scenario and define temporary copy of AM and MD scenarios for skimming - scen = currentScen*100 - scen = scen + 3 - currentScen = currentScen+3 ## -- set to AM transit skim scenario - scenarioWorking = emmebank.scenario(scen) - s93 = copy_scenario(from_scenario=scenarioWorking, scenario_id=93, scenario_title="temp am peak scenario for skimming", overwrite=True) - - #then repeate with midday period scenario - scen = scen + 2 - scenarioWorking = emmebank.scenario(scen) - s95 = copy_scenario(from_scenario=scenarioWorking, scenario_id=95, scenario_title="temp midday scenario for skimming", overwrite=True) - - #spec to @ftime to ul1 - ftime_to_ul1 = { - "result": "ul1", - "expression": "@ftime", - "selections": { - "link": "!vdf = 6,7", - }, - "type": "NETWORK_CALCULATION" - } - - periodMat = { - 93 : ["S", #mode class [0] - "mf44", "amtime", "am peak 7-9am SOV hwy time skim initsim", #[1, 2, 3] - "mf45", "amdist", "am peak 7-9am SOV hwy distance skim init", #[4, 5, 6] - "mf111", #matrix to hold additional attribute, toll SOVAM, [7] - "H", #mode class [8] - "mf76", "amhovt", "am peak 7-9am HOV hwy time skim initsim", #[9, 10, 11] - "mf77", "amhovd", "am peak 7-9am HOV hwy distance skim init", #[12, 13, 14] - "mf112"], #matrix to hold additional attribute, toll HOVAM [15] - 95 : ["S", #mode class, [0] - "mf46", "mdtime", "midday 10a-2p SOV hwy time skim initsim", #[1, 2, 3] - "mf47", "mddist", "midday 10a-2p SOvhwy distance skim init", #[4, 5, 6] - "mf117", #matrix to hold additional attribute, toll SOVMD, [7] - "H", #mode class, [8] - "mf78", "mdhovt", "midday 10a-2p HOV hwy time skim initsim", #[9, 10, 11] - "mf79", "mdhovd", "midday 10a-2p HOV hwy distance skim init", #[12, 13, 14] - "mf118"] #matrix to hold additional attribute, toll HOVMD - } - #the loop will say for scenario in periodMat - #then call periodMat[scenario][#] - for scenario in periodMat: - change_scenario(scenario = str(scenario)) #set scenario - net_calc(ftime_to_ul1) #put @ftime in ul1 - - delete_matrix(periodMat[scenario][1]) #delete first matrix in the list - new_mat = create_matrix(matrix_id=periodMat[scenario][1], matrix_name=periodMat[scenario][2], matrix_description=periodMat[scenario][3], default_value=0.0, overwrite ="True") - delete_matrix(periodMat[scenario][4]) #delete second matrix in the list - new_mat = create_matrix(matrix_id=periodMat[scenario][4], matrix_name=periodMat[scenario][5], matrix_description=periodMat[scenario][6], default_value=0.0, overwrite ="True") - - traffic_assignment = { - "type": "SOLA_TRAFFIC_ASSIGNMENT", - "background_traffic": None, - "classes": [ - {#start mode SOV - "mode": periodMat[scenario][0], #mode class - "demand": "ms97", #dummy matrix to hold assignment demand - "results": { - "od_travel_times": { - "shortest_paths": periodMat[scenario][1] #store skimmed time - } - }, - "path_analyses": [ - { - "link_component": "length", - "operator": "+", - "selection_threshold": { - "lower": .0000000001, - "upper": 999999 - }, - "path_to_od_composition": { - "considered_paths": "ALL", - "multiply_path_proportions_by": { - "analyzed_demand": False, - "path_value": True - } - }, - "analyzed_demand": None, - "results": { - "od_values": periodMat[scenario][4] - } - }, - - { - "link_component": "@toll", - "operator": "+", - "selection_threshold": { - "lower": .0000000001, - "upper": 999999 - }, - "path_to_od_composition": { - "considered_paths": "ALL", - "multiply_path_proportions_by": { - "analyzed_demand": False, - "path_value": True - } - }, - "analyzed_demand": None, - "results": { - "od_values": periodMat[scenario][7] - } - } - ] - }, - - { #start mode HOV - "mode": periodMat[scenario][8], #mode class - "demand": "ms97", #dummy matrix to hold assignment demand - "results": { - "od_travel_times": { - "shortest_paths": periodMat[scenario][9] #store skimmed time - } - }, - "path_analyses": [ - { - "link_component": "length", - "operator": "+", - "selection_threshold": { - "lower": .0000000001, - "upper": 999999 - }, - "path_to_od_composition": { - "considered_paths": "ALL", - "multiply_path_proportions_by": { - "analyzed_demand": False, - "path_value": True - } - }, - "analyzed_demand": None, - "results": { - "od_values": periodMat[scenario][12]} - }, - { - "link_component": "@toll", - "operator": "+", - "selection_threshold": { - "lower": .0000000001, - "upper": 999999 - }, - "path_to_od_composition": { - "considered_paths": "ALL", - "multiply_path_proportions_by": { - "analyzed_demand": False, - "path_value": True - } - }, - "analyzed_demand": None, - "results": { - "od_values": periodMat[scenario][15] - } - } - ] - } - - ], - - "performance_settings": { - "number_of_processors": "max" - }, - "stopping_criteria": { - "max_iterations": 0, - "relative_gap": 0.0001, - "best_relative_gap": 0.01, - "normalized_gap": 0.001 - } - } - #setup highway asmt - see spec above - #run assignment - sola_assign_traffic(traffic_assignment) - print("ran spec for " + str(scenario)) - - #change scenario (can't delete current primary scenario) - change_scenario(scenario = str(currentScen)) #set scenario - - #delete temporary scenarios - sdel = emmebank.scenario(scenario) - delete_scenario(scenario = sdel) - - print("completed loop") - - #initialize time of day skim travel time matrices and toll skims - mf461 = create_matrix(matrix_id="mf461", matrix_name="todtime1", matrix_description="SOV hwy time skim period 1", default_value=0, overwrite = "True") - mf462 = create_matrix(matrix_id="mf462", matrix_name="todtime2", matrix_description="SOV hwy time skim period 2", default_value=0, overwrite = "True") - mf463 = create_matrix(matrix_id="mf463", matrix_name="todtime3", matrix_description="SOV hwy time skim period 3", default_value=0, overwrite = "True") - mf464 = create_matrix(matrix_id="mf464", matrix_name="todtime4", matrix_description="SOV hwy time skim period 4", default_value=0, overwrite = "True") - mf465 = create_matrix(matrix_id="mf465", matrix_name="todtime5", matrix_description="SOV hwy time skim period 5", default_value=0, overwrite = "True") - mf466 = create_matrix(matrix_id="mf466", matrix_name="todtime6", matrix_description="SOV hwy time skim period 6", default_value=0, overwrite = "True") - mf467 = create_matrix(matrix_id="mf467", matrix_name="todtime7", matrix_description="SOV hwy time skim period 7", default_value=0, overwrite = "True") - mf468 = create_matrix(matrix_id="mf468", matrix_name="todtime8", matrix_description="SOV hwy time skim period 8", default_value=0, overwrite = "True") - - mf113 = create_matrix(matrix_id="mf113", matrix_name="th3hwl", matrix_description="low inc h-w hov 3+ per toll", default_value=0, overwrite = "True") - mf114 = create_matrix(matrix_id="mf114", matrix_name="tshwh", matrix_description="high inc h-w sov toll", default_value=0, overwrite = "True") - mf115 = create_matrix(matrix_id="mf115", matrix_name="th2hwh", matrix_description="high inc h-w hov 2 per toll", default_value=0, overwrite = "True") - mf116 = create_matrix(matrix_id="mf116", matrix_name="th3hwh", matrix_description="high inc h-w hov 3+ per toll", default_value=0, overwrite = "True") - mf119 = create_matrix(matrix_id="mf119", matrix_name="th3ho", matrix_description="h-o hov 3+ per toll", default_value=0, overwrite = "True") - mf120 = create_matrix(matrix_id="mf120", matrix_name="tsnh", matrix_description="nh sov toll", default_value=0, overwrite = "True") - mf121 = create_matrix(matrix_id="mf121", matrix_name="th2nh", matrix_description="nh hov 2 per toll", default_value=0, overwrite = "True") - mf122 = create_matrix(matrix_id="mf122", matrix_name="th3nh", matrix_description="nh hov 3+ per toll", default_value=0, overwrite = "True") - - spec_mf461 = {"expression": "mf46", "result": "mf461", "type": "MATRIX_CALCULATION"} - spec_mf462 = {"expression": "mf44", "result": "mf462", "type": "MATRIX_CALCULATION"} - spec_mf463 = {"expression": "mf44", "result": "mf463", "type": "MATRIX_CALCULATION"} - spec_mf464 = {"expression": "mf44", "result": "mf464", "type": "MATRIX_CALCULATION"} - spec_mf465 = {"expression": "mf46", "result": "mf465", "type": "MATRIX_CALCULATION"} - spec_mf466 = {"expression": "mf44", "result": "mf466", "type": "MATRIX_CALCULATION"} - spec_mf467 = {"expression": "mf44", "result": "mf467", "type": "MATRIX_CALCULATION"} - spec_mf468 = {"expression": "mf44", "result": "mf468", "type": "MATRIX_CALCULATION"} - matrix_calculation([spec_mf461, spec_mf462, spec_mf463, spec_mf464, spec_mf465, spec_mf466, spec_mf467, spec_mf468]) - - spec_mf113 = {"expression": "mf112", "result": "mf113", "type": "MATRIX_CALCULATION"} - spec_mf114 = {"expression": "mf111", "result": "mf114", "type": "MATRIX_CALCULATION"} - spec_mf115 = {"expression": "mf112", "result": "mf115", "type": "MATRIX_CALCULATION"} - spec_mf116 = {"expression": "mf112", "result": "mf116", "type": "MATRIX_CALCULATION"} - spec_mf119 = {"expression": "mf118", "result": "mf119", "type": "MATRIX_CALCULATION"} - spec_mf120 = {"expression": "mf117", "result": "mf120", "type": "MATRIX_CALCULATION"} - spec_mf121 = {"expression": "mf118", "result": "mf121", "type": "MATRIX_CALCULATION"} - spec_mf122 = {"expression": "mf118", "result": "mf122", "type": "MATRIX_CALCULATION"} - matrix_calculation([spec_mf113, spec_mf114, spec_mf115, spec_mf116, spec_mf119, spec_mf120, spec_mf121, spec_mf122]) - - #convert tolls to cents - toll111 = {"expression": "mf111*100", "result": "mf111", "type": "MATRIX_CALCULATION"} - toll112 = {"expression": "mf112*100", "result": "mf112", "type": "MATRIX_CALCULATION"} - toll113 = {"expression": "mf113*100", "result": "mf113", "type": "MATRIX_CALCULATION"} - toll114 = {"expression": "mf114*100", "result": "mf114", "type": "MATRIX_CALCULATION"} - toll115 = {"expression": "mf115*100", "result": "mf115", "type": "MATRIX_CALCULATION"} - toll116 = {"expression": "mf116*100", "result": "mf116", "type": "MATRIX_CALCULATION"} - toll117 = {"expression": "mf117*100", "result": "mf117", "type": "MATRIX_CALCULATION"} - toll118 = {"expression": "mf118*100", "result": "mf118", "type": "MATRIX_CALCULATION"} - toll119 = {"expression": "mf119*100", "result": "mf119", "type": "MATRIX_CALCULATION"} - toll120 = {"expression": "mf120*100", "result": "mf120", "type": "MATRIX_CALCULATION"} - toll121 = {"expression": "mf121*100", "result": "mf121", "type": "MATRIX_CALCULATION"} - toll122 = {"expression": "mf122*100", "result": "mf122", "type": "MATRIX_CALCULATION"} - matrix_calculation([toll111, toll112, toll113, toll114, toll115, toll116, toll117, toll118, toll119, toll120, toll121, toll122]) - -if __name__ == '__main__': +#filename: free.skim.mac.py +#description: creates time and distance skims from am-peak and midday scenarios to start distribution and mode choice +#author: Karly Cazzato, 12/05/2023 + +import os +import os.path +import sys +import inro.emme.desktop.app as _app +import inro.modeller as _m + + +def main(): + + #set variables + currentScen = int(sys.argv[2]) + scenario = str(currentScen) + directory = os.getcwd().replace('\\Database','') + batchin = directory + "\\Database\\data\\vdf_free.in" + + # Define the path to the Emme project (.emp file) + empFl = sys.argv[1] + empFile = os.path.join(directory,empFl) + desktop = _app.start_dedicated( + visible=True, + user_initials='KCC', + project= empFile + ) + + # Connect to the Modeller + modeller = _m.Modeller(desktop=desktop) + emmebank = modeller.emmebank + + #define tools + delete_function = modeller.tool("inro.emme.data.function.delete_function") + batchin_function = modeller.tool("inro.emme.data.function.function_transaction") + + create_matrix = modeller.tool("inro.emme.data.matrix.create_matrix") + matrix_calculation = modeller.tool("inro.emme.matrix_calculation.matrix_calculator") + delete_matrix = modeller.tool("inro.emme.data.matrix.delete_matrix") + + copy_scenario = modeller.tool("inro.emme.data.scenario.copy_scenario") + change_scenario = modeller.tool("inro.emme.data.scenario.change_primary_scenario") + delete_scenario = modeller.tool("inro.emme.data.scenario.delete_scenario") + + net_calc = modeller.tool("inro.emme.network_calculation.network_calculator") + + sola_assign_traffic = modeller.tool("inro.emme.traffic_assignment.sola_traffic_assignment") + + #delete existing functions for skimming and batch in new functions + for i in range(1,10): + f_id = "fd%s" % i + f = _m.Modeller().emmebank.function(f_id) + if f: delete_function(f) + + #input functions using process function transaction tool + batchin_function(transaction_file = batchin, throw_on_error = True) + + #initialize base toll matrices + mf111 = create_matrix(matrix_id="mf111", matrix_name="tshwl", matrix_description="low inc h-w sov toll", default_value=0, overwrite = "True") + mf112 = create_matrix(matrix_id="mf112", matrix_name="th2hwl", matrix_description="low inc h-w hov 2 per toll", default_value=0, overwrite = "True") + mf117 = create_matrix(matrix_id="mf117", matrix_name="tsho", matrix_description="h-o sov toll", default_value=0, overwrite = "True") + mf118 = create_matrix(matrix_id="mf118", matrix_name="th2ho", matrix_description="h-o hov 2 per toll", default_value=0, overwrite = "True") + + spec_mf112 = {"expression": "mf111", "result": "mf112", "type": "MATRIX_CALCULATION"} + spec_mf118 = {"expression": "mf117", "result": "mf118", "type": "MATRIX_CALCULATION"} + + matrix_calculation([spec_mf112, spec_mf118]) + + #set scenario and define temporary copy of AM and MD scenarios for skimming + scen = currentScen*100 + scen = scen + 3 + scenarioWorking = emmebank.scenario(scen) + s93 = copy_scenario(from_scenario=scenarioWorking, scenario_id=93, scenario_title="temp am peak scenario for skimming", overwrite=True) + + #then repeate with midday period scenario + scen = scen + 2 + scenarioWorking = emmebank.scenario(scen) + s95 = copy_scenario(from_scenario=scenarioWorking, scenario_id=95, scenario_title="temp midday scenario for skimming", overwrite=True) + + #spec to @ftime to ul1 + ftime_to_ul1 = { + "result": "ul1", + "expression": "@ftime", + "selections": { + "link": "!vdf = 6,7", + }, + "type": "NETWORK_CALCULATION" + } + + periodMat = { + 93 : ["S", #mode class [0] + "mf44", "amtime", "am peak 7-9am SOV hwy time skim initsim", #[1, 2, 3] + "mf45", "amdist", "am peak 7-9am SOV hwy distance skim init", #[4, 5, 6] + "mf111", #matrix to hold additional attribute, toll SOVAM, [7] + "H", #mode class [8] + "mf76", "amhovt", "am peak 7-9am HOV hwy time skim initsim", #[9, 10, 11] + "mf77", "amhovd", "am peak 7-9am HOV hwy distance skim init", #[12, 13, 14] + "mf112"], #matrix to hold additional attribute, toll HOVAM [15] + 95 : ["S", #mode class, [0] + "mf46", "mdtime", "midday 10a-2p SOV hwy time skim initsim", #[1, 2, 3] + "mf47", "mddist", "midday 10a-2p SOvhwy distance skim init", #[4, 5, 6] + "mf117", #matrix to hold additional attribute, toll SOVMD, [7] + "H", #mode class, [8] + "mf78", "mdhovt", "midday 10a-2p HOV hwy time skim initsim", #[9, 10, 11] + "mf79", "mdhovd", "midday 10a-2p HOV hwy distance skim init", #[12, 13, 14] + "mf118"] #matrix to hold additional attribute, toll HOVMD + } + #the loop will say for scenario in periodMat + #then call periodMat[scenario][#] + for scenario in periodMat: + change_scenario(scenario = str(scenario)) #set scenario + net_calc(ftime_to_ul1) #put @ftime in ul1 + + delete_matrix(periodMat[scenario][1]) #delete first matrix in the list + new_mat = create_matrix(matrix_id=periodMat[scenario][1], matrix_name=periodMat[scenario][2], matrix_description=periodMat[scenario][3], default_value=0.0, overwrite ="True") + delete_matrix(periodMat[scenario][4]) #delete second matrix in the list + new_mat = create_matrix(matrix_id=periodMat[scenario][4], matrix_name=periodMat[scenario][5], matrix_description=periodMat[scenario][6], default_value=0.0, overwrite ="True") + + traffic_assignment = { + "type": "SOLA_TRAFFIC_ASSIGNMENT", + "background_traffic": None, + "classes": [ + {#start mode SOV + "mode": periodMat[scenario][0], #mode class + "demand": "ms97", #dummy matrix to hold assignment demand + "results": { + "od_travel_times": { + "shortest_paths": periodMat[scenario][1] #store skimmed time + } + }, + "path_analyses": [ + { + "link_component": "length", + "operator": "+", + "selection_threshold": { + "lower": .0000000001, + "upper": 999999 + }, + "path_to_od_composition": { + "considered_paths": "ALL", + "multiply_path_proportions_by": { + "analyzed_demand": False, + "path_value": True + } + }, + "analyzed_demand": None, + "results": { + "od_values": periodMat[scenario][4] + } + }, + + { + "link_component": "@toll", + "operator": "+", + "selection_threshold": { + "lower": .0000000001, + "upper": 999999 + }, + "path_to_od_composition": { + "considered_paths": "ALL", + "multiply_path_proportions_by": { + "analyzed_demand": False, + "path_value": True + } + }, + "analyzed_demand": None, + "results": { + "od_values": periodMat[scenario][7] + } + } + ] + }, + + { #start mode HOV + "mode": periodMat[scenario][8], #mode class + "demand": "ms97", #dummy matrix to hold assignment demand + "results": { + "od_travel_times": { + "shortest_paths": periodMat[scenario][9] #store skimmed time + } + }, + "path_analyses": [ + { + "link_component": "length", + "operator": "+", + "selection_threshold": { + "lower": .0000000001, + "upper": 999999 + }, + "path_to_od_composition": { + "considered_paths": "ALL", + "multiply_path_proportions_by": { + "analyzed_demand": False, + "path_value": True + } + }, + "analyzed_demand": None, + "results": { + "od_values": periodMat[scenario][12]} + }, + { + "link_component": "@toll", + "operator": "+", + "selection_threshold": { + "lower": .0000000001, + "upper": 999999 + }, + "path_to_od_composition": { + "considered_paths": "ALL", + "multiply_path_proportions_by": { + "analyzed_demand": False, + "path_value": True + } + }, + "analyzed_demand": None, + "results": { + "od_values": periodMat[scenario][15] + } + } + ] + } + + ], + + "performance_settings": { + "number_of_processors": "max" + }, + "stopping_criteria": { + "max_iterations": 0, + "relative_gap": 0.0001, + "best_relative_gap": 0.01, + "normalized_gap": 0.001 + } + } + #setup highway asmt - see spec above + #run assignment + sola_assign_traffic(traffic_assignment) + print("ran spec for " + str(scenario)) + + #change scenario (can't delete current primary scenario) + change_scenario(scenario = str(currentScen)) #set scenario + + #delete temporary scenarios + sdel = emmebank.scenario(scenario) + delete_scenario(scenario = sdel) + + print("completed loop") + + #initialize time of day skim travel time matrices and toll skims + mf461 = create_matrix(matrix_id="mf461", matrix_name="todtime1", matrix_description="SOV hwy time skim period 1", default_value=0, overwrite = "True") + mf462 = create_matrix(matrix_id="mf462", matrix_name="todtime2", matrix_description="SOV hwy time skim period 2", default_value=0, overwrite = "True") + mf463 = create_matrix(matrix_id="mf463", matrix_name="todtime3", matrix_description="SOV hwy time skim period 3", default_value=0, overwrite = "True") + mf464 = create_matrix(matrix_id="mf464", matrix_name="todtime4", matrix_description="SOV hwy time skim period 4", default_value=0, overwrite = "True") + mf465 = create_matrix(matrix_id="mf465", matrix_name="todtime5", matrix_description="SOV hwy time skim period 5", default_value=0, overwrite = "True") + mf466 = create_matrix(matrix_id="mf466", matrix_name="todtime6", matrix_description="SOV hwy time skim period 6", default_value=0, overwrite = "True") + mf467 = create_matrix(matrix_id="mf467", matrix_name="todtime7", matrix_description="SOV hwy time skim period 7", default_value=0, overwrite = "True") + mf468 = create_matrix(matrix_id="mf468", matrix_name="todtime8", matrix_description="SOV hwy time skim period 8", default_value=0, overwrite = "True") + + mf113 = create_matrix(matrix_id="mf113", matrix_name="th3hwl", matrix_description="low inc h-w hov 3+ per toll", default_value=0, overwrite = "True") + mf114 = create_matrix(matrix_id="mf114", matrix_name="tshwh", matrix_description="high inc h-w sov toll", default_value=0, overwrite = "True") + mf115 = create_matrix(matrix_id="mf115", matrix_name="th2hwh", matrix_description="high inc h-w hov 2 per toll", default_value=0, overwrite = "True") + mf116 = create_matrix(matrix_id="mf116", matrix_name="th3hwh", matrix_description="high inc h-w hov 3+ per toll", default_value=0, overwrite = "True") + mf119 = create_matrix(matrix_id="mf119", matrix_name="th3ho", matrix_description="h-o hov 3+ per toll", default_value=0, overwrite = "True") + mf120 = create_matrix(matrix_id="mf120", matrix_name="tsnh", matrix_description="nh sov toll", default_value=0, overwrite = "True") + mf121 = create_matrix(matrix_id="mf121", matrix_name="th2nh", matrix_description="nh hov 2 per toll", default_value=0, overwrite = "True") + mf122 = create_matrix(matrix_id="mf122", matrix_name="th3nh", matrix_description="nh hov 3+ per toll", default_value=0, overwrite = "True") + + spec_mf461 = {"expression": "mf46", "result": "mf461", "type": "MATRIX_CALCULATION"} + spec_mf462 = {"expression": "mf44", "result": "mf462", "type": "MATRIX_CALCULATION"} + spec_mf463 = {"expression": "mf44", "result": "mf463", "type": "MATRIX_CALCULATION"} + spec_mf464 = {"expression": "mf44", "result": "mf464", "type": "MATRIX_CALCULATION"} + spec_mf465 = {"expression": "mf46", "result": "mf465", "type": "MATRIX_CALCULATION"} + spec_mf466 = {"expression": "mf44", "result": "mf466", "type": "MATRIX_CALCULATION"} + spec_mf467 = {"expression": "mf44", "result": "mf467", "type": "MATRIX_CALCULATION"} + spec_mf468 = {"expression": "mf44", "result": "mf468", "type": "MATRIX_CALCULATION"} + matrix_calculation([spec_mf461, spec_mf462, spec_mf463, spec_mf464, spec_mf465, spec_mf466, spec_mf467, spec_mf468]) + + spec_mf113 = {"expression": "mf112", "result": "mf113", "type": "MATRIX_CALCULATION"} + spec_mf114 = {"expression": "mf111", "result": "mf114", "type": "MATRIX_CALCULATION"} + spec_mf115 = {"expression": "mf112", "result": "mf115", "type": "MATRIX_CALCULATION"} + spec_mf116 = {"expression": "mf112", "result": "mf116", "type": "MATRIX_CALCULATION"} + spec_mf119 = {"expression": "mf118", "result": "mf119", "type": "MATRIX_CALCULATION"} + spec_mf120 = {"expression": "mf117", "result": "mf120", "type": "MATRIX_CALCULATION"} + spec_mf121 = {"expression": "mf118", "result": "mf121", "type": "MATRIX_CALCULATION"} + spec_mf122 = {"expression": "mf118", "result": "mf122", "type": "MATRIX_CALCULATION"} + matrix_calculation([spec_mf113, spec_mf114, spec_mf115, spec_mf116, spec_mf119, spec_mf120, spec_mf121, spec_mf122]) + + #convert tolls to cents + toll111 = {"expression": "mf111*100", "result": "mf111", "type": "MATRIX_CALCULATION"} + toll112 = {"expression": "mf112*100", "result": "mf112", "type": "MATRIX_CALCULATION"} + toll113 = {"expression": "mf113*100", "result": "mf113", "type": "MATRIX_CALCULATION"} + toll114 = {"expression": "mf114*100", "result": "mf114", "type": "MATRIX_CALCULATION"} + toll115 = {"expression": "mf115*100", "result": "mf115", "type": "MATRIX_CALCULATION"} + toll116 = {"expression": "mf116*100", "result": "mf116", "type": "MATRIX_CALCULATION"} + toll117 = {"expression": "mf117*100", "result": "mf117", "type": "MATRIX_CALCULATION"} + toll118 = {"expression": "mf118*100", "result": "mf118", "type": "MATRIX_CALCULATION"} + toll119 = {"expression": "mf119*100", "result": "mf119", "type": "MATRIX_CALCULATION"} + toll120 = {"expression": "mf120*100", "result": "mf120", "type": "MATRIX_CALCULATION"} + toll121 = {"expression": "mf121*100", "result": "mf121", "type": "MATRIX_CALCULATION"} + toll122 = {"expression": "mf122*100", "result": "mf122", "type": "MATRIX_CALCULATION"} + matrix_calculation([toll111, toll112, toll113, toll114, toll115, toll116, toll117, toll118, toll119, toll120, toll121, toll122]) + +if __name__ == '__main__': main() \ No newline at end of file diff --git a/Database/prep_macros/initialize_scenarios.py b/Database/prep_macros/initialize_scenarios.py index 86424e0..d01be1b 100644 --- a/Database/prep_macros/initialize_scenarios.py +++ b/Database/prep_macros/initialize_scenarios.py @@ -51,26 +51,14 @@ #set path to batchin files with open(os.path.join(db, 'batch_file.yaml')) as f: lines_without_backslashes = ''.join([line.replace('\\','/') for line in f]) - batch_config = yaml.safe_load(lines_without_backslashes) - -# find and read config file -config_file = Path(__file__).resolve().parents[2].joinpath('Scripts','prepare', - 'conformity_scenario', - 'hand','config.yaml') -with open(config_file) as f: - config = yaml.safe_load(f) - -scen_code = batch_config['scenario_code'] -batchin_path = batch_config['transactionFilePath'] # e.g., M:/catslib/modelprod/c24q2 -real_year = config['scenario_years'][scen_code] + config = yaml.safe_load(lines_without_backslashes) +scen_yr = config['scenario_code'] # e.g., '200' +batchin_path = config['transactionFilePath'] # e.g., M:/catslib/modelprod/c24q2 hwy_batchin_dir = os.path.join(batchin_path, 'highway') trn_batchin_dir = os.path.join(batchin_path, 'transit') -link_shape_dir = os.path.join(batchin_path, 'linkshape') -link_shape_file = os.path.join(link_shape_dir, "linkshape_%s.in" %(str(scen_code))) print('highway transaction file location: ', hwy_batchin_dir) print('transit transaction file location: ', trn_batchin_dir) -print('link shape transaction file: ', link_shape_file) ## ## EMME SETUP ##### @@ -97,7 +85,6 @@ process_vehicle_transaction = modeller.tool("inro.emme.data.network.transit.vehicle_transaction") process_network_transaction = modeller.tool("inro.emme.data.network.base.base_network_transaction") process_transit_line_transaction = modeller.tool("inro.emme.data.network.transit.transit_line_transaction") -process_link_shape_transaction = modeller.tool("inro.emme.data.network.base.link_shape_transaction") create_extra = modeller.tool("inro.emme.data.extra_attribute.create_extra_attribute") import_attribute_values = modeller.tool("inro.emme.data.network.import_attribute_values") net_calc = modeller.tool("inro.emme.network_calculation.network_calculator") @@ -115,7 +102,7 @@ ## print('create base daily network - all links... ') -base_scen = int(f'{scen_code}00') +base_scen = int(f'{scen_yr}00') create_scenario( scenario_id = base_scen, @@ -188,7 +175,7 @@ print('creating tod highway scenarios...') for bscen in batchin_scens: - scen = int(f'{scen_code}{bscen[0]}') + scen = int(f'{scen_yr}{bscen[0]}') tod = int(bscen[0][-1]) print(' building scenario ', scen) # print(' building scenario ', scen, '\n - tod: ', tod, '\n - title: ', bscen[1]) @@ -198,17 +185,15 @@ from_scenario = emmebank.scenario(base_scen), scenario_id = scen, scenario_title = bscen[1], - overwrite=True, - set_as_primary=True + overwrite=True ) - print(" from: {0}, to: {1}".format(base_scen, scen)) - else: - change_primary_scenario(emmebank.scenario(base_scen)) + + change_primary_scenario(emmebank.scenario(scen)) print(' -- l1, n1...') #n1, l1 batchin - l1_batchin = os.path.join(hwy_batchin_dir, str(scen_code), f'{scen}.l1') - n1_batchin = os.path.join(hwy_batchin_dir, str(scen_code), f'{scen}.n1') + l1_batchin = os.path.join(hwy_batchin_dir, str(scen_yr), f'{scen}.l1') + n1_batchin = os.path.join(hwy_batchin_dir, str(scen_yr), f'{scen}.n1') process_network_transaction( transaction_file = n1_batchin @@ -223,7 +208,7 @@ print(' -- l2, n2...') #n2 batchin (extra attributes) - n2_batchin = os.path.join(hwy_batchin_dir, str(scen_code), f'{scen}.n2') + n2_batchin = os.path.join(hwy_batchin_dir, str(scen_yr), f'{scen}.n2') n2_columns = {0: 'i_node', 1:'@zone', 2:'@atype', 3:'@imarea'} import_attribute_values( @@ -233,7 +218,7 @@ ) #l2 batchin (extra attributes) - l2_batchin = os.path.join(hwy_batchin_dir, str(scen_code), f'{scen}.l2') + l2_batchin = os.path.join(hwy_batchin_dir, str(scen_yr), f'{scen}.l2') l2_columns = {0: 'i_node', 1:'j_node', 2: '@speed', 3:'@width', 4:'@parkl', 6:'@toll', 7:'@sigic', 9: '@tipid'} import_attribute_values( @@ -241,8 +226,6 @@ column_labels=l2_columns, # scenario = emmebank.scenario(scen) ) - - process_link_shape_transaction(transaction_file = link_shape_file, revert_on_error = False) print(' -- other link calculations...') @@ -401,12 +384,23 @@ ## BUILD TRANSIT ASSIGNMENT SCENARIO NETWORKS ####################### +scen_yr = str(scen_yr) #just to ensure it works here - convert to string +scen3_yr4 = { + '100': 2019, + '200': 2025, + '300': 2030, + '400': 2035, + '500': 2040, + '600': 2045, + '700': 2050 +} + network_batchin_list = [ #[{transit asmt scenario number}, {transaction file time-of-day suffix}, {name of scenario}] - [int(scen_code)+21, 1, f'{real_year} Night (6pm-6am)'], - [int(scen_code)+23, 2, f'{real_year} AM (6am-9am)'], - [int(scen_code)+25, 3, f'{real_year} Midday (9am-4pm)'], - [int(scen_code)+27, 4, f'{real_year} PM (4pm-6pm)'] + [int(scen_yr)+21, 1, f'{scen3_yr4[scen_yr]} Night (6pm-6am)'], + [int(scen_yr)+23, 2, f'{scen3_yr4[scen_yr]} AM (6am-9am)'], + [int(scen_yr)+25, 3, f'{scen3_yr4[scen_yr]} Midday (9am-4pm)'], + [int(scen_yr)+27, 4, f'{scen3_yr4[scen_yr]} PM (4pm-6pm)'] ] for asmt_scen in network_batchin_list: @@ -430,7 +424,7 @@ #build transit network transit_modes = os.path.join(trn_batchin_dir, 'tranmodes.txt') transit_vehicles = os.path.join(trn_batchin_dir, 'transveh.txt') - transit_transaction = os.path.join(trn_batchin_dir, str(scen_code)) + transit_transaction = os.path.join(trn_batchin_dir, str(scen_yr)) print(' - import modes and vehicles') #import modes and vehicles @@ -445,8 +439,6 @@ #import lines process_transit_line_transaction(os.path.join(transit_transaction, f'rail.itinerary_{asmt_scen[1]}')) process_transit_line_transaction(os.path.join(transit_transaction, f'bus.itinerary_{asmt_scen[1]}')) - - process_link_shape_transaction(transaction_file = link_shape_file, revert_on_error = False) print(' - create and calculate extra attributes') #create extra attributes @@ -456,7 +448,7 @@ ['@pspac', 'NODE', 'off-street parking spaces at station'], ['@zone', 'NODE', 'CMAP zone'], ['@ltime', 'TRANSIT_SEGMENT', 'line service time in minutes'], - ['@hwytm', 'TRANSIT_SEGMENT', f'AM peak congested hwy time from scen {scen_code}'], + ['@hwytm', 'TRANSIT_SEGMENT', f'AM peak congested hwy time from scen {scen_yr}'], ['@zfare_link', 'TRANSIT_SEGMENT', 'incremental zone fare'], ['@timbo', 'NODE', 'Base boarding time by station type, min'], ['@easeb', 'TRANSIT_LINE', 'Ease of boarding 1=worst, 4=best'] @@ -795,16 +787,16 @@ ## Create transit skim scenarios ## today = str(date.today().strftime('%Y%m%d')) copy_scenario( - from_scenario = emmebank.scenario(int(scen_code)+23), - scenario_id = int(scen_code)+3, - scenario_title = f'{real_year} am (6am-9am) transit skim network - {today}', + from_scenario = emmebank.scenario(int(scen_yr)+23), + scenario_id = int(scen_yr)+0, + scenario_title = f'{scen3_yr4[scen_yr]} am (6am-9am) transit skim network - {today}', copy_linkshapes=True, overwrite=True ) copy_scenario( - from_scenario = emmebank.scenario(int(scen_code)+25), - scenario_id = int(scen_code)+5, - scenario_title = f'{real_year} midday (9am-4pm) transit skim network - {today}', + from_scenario = emmebank.scenario(int(scen_yr)+25), + scenario_id = int(scen_yr)+5, + scenario_title = f'{scen3_yr4[scen_yr]} midday (9am-4pm) transit skim network - {today}', copy_linkshapes=True, overwrite=True ) diff --git a/Database/prep_macros/preload_congested_times_mac.py b/Database/prep_macros/preload_congested_times_mac.py index 784bc67..078f703 100644 --- a/Database/prep_macros/preload_congested_times_mac.py +++ b/Database/prep_macros/preload_congested_times_mac.py @@ -1,110 +1,110 @@ -#filename: free.skim.mac.py -#description: creates time and distance skims from am-peak and midday scenarios to start distribution and mode choice -#author: Karly Cazzato, 12/29/2023 - -from asyncio.windows_events import NULL -import os -import os.path -import sys -import inro.emme.desktop.app as _app -import inro.modeller as _m - - -def main(): - - #set variables - currentScen = int(sys.argv[2]) - cScenAM = currentScen + 3 - cScenMD = currentScen + 5 - directory1 = os.getcwd() - directory = os.getcwd().replace('\\Database','') - - # Define the path to the Emme project (.emp file) - empFl = sys.argv[1] - empFile = os.path.join(directory,empFl) - desktop = _app.start_dedicated( - visible=True, - user_initials='KCC', - project= empFile - ) - - # Connect to the Modeller - modeller = _m.Modeller(desktop=desktop) - eb = _m.Modeller().emmebank - - #define tools - batchin_data = modeller.tool("inro.emme.data.network_field.import_network_fields") - change_scenario = modeller.tool("inro.emme.data.scenario.change_primary_scenario") - process_mat = modeller.tool("inro.emme.data.matrix.matrix_transaction") - net_calc = modeller.tool("inro.emme.network_calculation.network_calculator") - delete_mat = modeller.tool("inro.emme.data.matrix.delete_matrix") - - #delete report\iter_0\preload_times.rpt if it exists - if os.path.isfile("report\\iter_0\\preload_times.rpt"): os.remove("report\\iter_0\\preload_times.rpt") - - hwytm_spec = { - "result": "@hwytm", - "expression": "ul2", - "selections": { - "link": "all", - "transit_line": "all" - }, - "type": "NETWORK_CALCULATION" - } - ul2_spec = { - "result": "ul2", - "expression": "0", - "selections": { - "link": "all", - }, - "type": "NETWORK_CALCULATION" - } - #set scenario to transit AM _00, batchin and store per3_timau.txt - change_scenario(scenario = str(cScenAM)) - batchin = directory1 + "\\defaults_base_year\\per3_timau.txt" - batchin_data(batchin, - column_labels = { - 0 : 'i_node', - 1: 'j_node', - 2: 'ul2' - }, - revert_on_error=False) - - #add net calc to store ul2 in @hwytm - net_calc(hwytm_spec) - #add net calc to make all ul2 back to 0 - net_calc(ul2_spec) - - #set scenario to transit MD _00, batchin and store per5_timau.txt - change_scenario(scenario = str(cScenMD)) - batchin = directory1 + "\\defaults_base_year\\per5_timau.txt" - batchin_data(batchin, - column_labels = { - 0: 'i_node', - 1: 'j_node', - 2: 'ul2' - }, - revert_on_error = False) - #add net calc to store ul2 in @hwytm - net_calc(hwytm_spec) - #add net calc to make all ul2 back to 0 - net_calc(ul2_spec) - - #change to scenario 10000 - scen_00 = str(currentScen) + str(0) + str(0) - - change_scenario(scenario = str(scen_00)) - - matpairs = (44, 45, 46, 47, 76, 77) - for mat in matpairs: - name = "mf" + str(mat) - mfName = eb.matrix(name) - if mfName: delete_mat(matrix = mfName) - batchin = directory1 + "\\defaults_base_year\\preload_mf" + str(mat) + ".txt" - process_mat(batchin) - print("processed mf_" + str(mat)) - - - -if __name__ == '__main__': +#filename: free.skim.mac.py +#description: creates time and distance skims from am-peak and midday scenarios to start distribution and mode choice +#author: Karly Cazzato, 12/29/2023 + +from asyncio.windows_events import NULL +import os +import os.path +import sys +import inro.emme.desktop.app as _app +import inro.modeller as _m + + +def main(): + + #set variables + currentScen = int(sys.argv[2]) + scenario = str(currentScen) + cScenMD = currentScen + 5 + directory1 = os.getcwd() + directory = os.getcwd().replace('\\Database','') + + # Define the path to the Emme project (.emp file) + empFl = sys.argv[1] + empFile = os.path.join(directory,empFl) + desktop = _app.start_dedicated( + visible=True, + user_initials='KCC', + project= empFile + ) + + # Connect to the Modeller + modeller = _m.Modeller(desktop=desktop) + eb = _m.Modeller().emmebank + + #define tools + batchin_data = modeller.tool("inro.emme.data.network_field.import_network_fields") + change_scenario = modeller.tool("inro.emme.data.scenario.change_primary_scenario") + process_mat = modeller.tool("inro.emme.data.matrix.matrix_transaction") + net_calc = modeller.tool("inro.emme.network_calculation.network_calculator") + delete_mat = modeller.tool("inro.emme.data.matrix.delete_matrix") + + #delete report\iter_0\preload_times.rpt if it exists + if os.path.isfile("report\\iter_0\\preload_times.rpt"): os.remove("report\\iter_0\\preload_times.rpt") + + hwytm_spec = { + "result": "@hwytm", + "expression": "ul2", + "selections": { + "link": "all", + "transit_line": "all" + }, + "type": "NETWORK_CALCULATION" + } + ul2_spec = { + "result": "ul2", + "expression": "0", + "selections": { + "link": "all", + }, + "type": "NETWORK_CALCULATION" + } + #set scenario to transit AM _00, batchin and store per3_timau.txt + change_scenario(scenario = str(scenario)) + batchin = directory1 + "\\defaults_base_year\\per3_timau.txt" + batchin_data(batchin, + column_labels = { + 0 : 'i_node', + 1: 'j_node', + 2: 'ul2' + }, + revert_on_error=False) + + #add net calc to store ul2 in @hwytm + net_calc(hwytm_spec) + #add net calc to make all ul2 back to 0 + net_calc(ul2_spec) + + #set scenario to transit MD _00, batchin and store per5_timau.txt + change_scenario(scenario = str(cScenMD)) + batchin = directory1 + "\\defaults_base_year\\per5_timau.txt" + batchin_data(batchin, + column_labels = { + 0: 'i_node', + 1: 'j_node', + 2: 'ul2' + }, + revert_on_error = False) + #add net calc to store ul2 in @hwytm + net_calc(hwytm_spec) + #add net calc to make all ul2 back to 0 + net_calc(ul2_spec) + + #change to scenario 100000 + scen_00 = scenario + str(0) + str(0) + + change_scenario(scenario = str(scen_00)) + + matpairs = (44, 45, 46, 47, 76, 77) + for mat in matpairs: + name = "mf" + str(mat) + mfName = eb.matrix(name) + if mfName: delete_mat(matrix = mfName) + batchin = directory1 + "\\defaults_base_year\\preload_mf" + str(mat) + ".txt" + process_mat(batchin) + print("processed mf_" + str(mat)) + + + +if __name__ == '__main__': main() \ No newline at end of file diff --git a/Database/tg/data/m01auto.csv b/Database/tg/data/m01auto.csv index ad60e2f..b0ecdaf 100644 --- a/Database/tg/data/m01auto.csv +++ b/Database/tg/data/m01auto.csv @@ -1,3633 +1,3633 @@ zone17,zwkrauto,zveh,z_veh_occ -1,660.9874477002464,624.8866602687357,1.0577717364233465 -2,1600.9965988820513,1499.8219729541754,1.0674577568220274 -3,2177.5238452020517,2011.1872413128538,1.0827056777570931 -4,2593.6289164646673,2335.4890466821785,1.1105292573087444 -5,4576.805634798305,4235.894968359385,1.0804813785481935 -6,10247.779746744407,9336.35625940083,1.0976208985626335 -7,9245.63173524657,8489.381552436722,1.0890818934381363 -8,398.1361967008224,379.5768040229973,1.0488949600742743 -9,1299.0328658752067,1220.9175347222201,1.0639808414011838 -10,2179.504054017697,2013.3087588226108,1.082548339625899 -11,2619.509241828243,2359.0403985471335,1.1104130490692423 -12,3066.6570366075894,2870.4932217301675,1.0683380171018784 -13,2505.6133083909717,2342.576748672161,1.0695971049022084 -14,2471.5147480430096,2257.1650846985,1.09496410554886 -15,2378.451338771252,2179.8802345655195,1.0910926669534715 -16,4610.33782663054,4228.246108404901,1.0903664801975737 -17,5147.85466010726,4690.281625718401,1.0975576886214744 -18,4485.87087577747,4121.052758021174,1.0885254664712114 -19,5160.377806572046,4713.452981692858,1.0948189844292608 -20,2442.058878840008,2230.7802474714026,1.0947106428829512 -21,2935.7722017162528,2682.51733491149,1.0944094054896831 -22,7411.855430751148,6777.554503488468,1.0935884657122563 -23,7403.3367080188245,6769.815241611219,1.0935803184869233 -24,4812.761156399375,4405.634737443494,1.0924103887904537 -25,4670.681439637949,4231.885263632466,1.1036881079400622 -26,3416.4773320733184,3192.6992247424473,1.070090569633575 -27,3940.5735779855395,3662.8654860504967,1.0758171690968874 -28,7541.836094999198,6896.411521757579,1.0935884657122563 -29,7553.7498308703125,6907.328665883998,1.0935848279782971 -30,1849.2822426985708,1703.236267062959,1.0857461636179528 -31,4825.2276270709435,4431.723237461409,1.0887926363007594 -32,1750.9777369098015,1644.079717686261,1.065019973224887 -33,1764.3058668724373,1654.7665568276745,1.0661962314821969 -34,6792.603154038064,6213.82629954773,1.0931433913002138 -35,7319.295998538335,6692.9162367959525,1.0935884657122565 -36,1663.1305706000774,1533.0374834240106,1.084859691026932 -37,833.1024159169755,791.8872525063748,1.052046757010107 -38,803.2605171714522,763.5216893347025,1.052046757010107 -39,940.9393360062497,859.092617221908,1.0952711234430272 -40,962.9070641440055,863.7085647537162,1.1148518185860243 -41,813.1182854829831,754.6931262732942,1.0774157828867406 -42,2131.3162020594173,1978.9375375988113,1.0770002395555638 -43,759.1127507747493,721.5579970344003,1.052046757010107 -44,722.7821028394055,687.0246954551105,1.052046757010107 -45,726.7434866567228,668.0219875169994,1.0879035424537267 -46,676.9226785205699,604.208469951204,1.1203462251617198 -47,554.4798436477629,516.1121895460261,1.074339755733119 -48,1339.3046455952883,1260.3662700552795,1.0626312980722235 -49,3270.5704849018966,3071.3960919482593,1.0648481625264088 -50,2563.1149850685133,2447.466555243368,1.047252302417528 -51,2216.6997964209127,1974.1460002615026,1.1228651761963302 -52,761.4355475823072,728.228993589083,1.0455990550850844 -53,1333.4536345894157,1292.108951198331,1.0319978306417124 -54,2336.5014000262695,2205.876480972124,1.0592167876038912 -55,2319.9504464758966,2171.1565826318433,1.068532074118619 -56,3970.761575007212,3610.656007555382,1.0997341111139638 -57,8214.072976520627,7588.69703766549,1.0824088688415372 -58,1338.799302676619,1226.9540679469428,1.091156822941894 -59,2225.206901220152,2059.228676575924,1.0806021334746638 -60,5298.408550378703,4922.427466289286,1.0763812339875565 -61,5330.1709338606715,4950.779183980878,1.0766327351273075 -62,3922.1170208250282,3666.632050235669,1.0696783770743885 -63,3802.7152692506293,3551.3536044513494,1.070779114894168 -64,1214.003134308817,1117.9313208143253,1.0859371337986226 -65,2030.3417143913819,1905.744401270567,1.0653798657562605 -66,1514.5439900490567,1454.8407309099061,1.041037659910587 -67,1935.441475448105,1858.5378520391935,1.041378561821882 -68,3057.8446076761584,2906.496632627767,1.0520723035937452 -69,1730.8963924497941,1644.7385912208879,1.0523838874388856 -70,1356.9532443794494,1229.8199864368771,1.1033755015731301 -71,965.0371477458056,905.8178938911315,1.0653765555461543 -72,1185.4021972900846,1079.3714533200584,1.0982337856387476 -73,1002.9983861990063,947.4650373875503,1.0586125573188203 -74,1116.6620158708936,1046.5273550487218,1.0670165576502362 -75,1386.9155240923674,1274.929090597955,1.0878373819534461 -76,1695.5462852845412,1606.8997509310673,1.0551661883711854 -77,935.9742925481413,878.5384732521393,1.0653765555461543 -78,650.3056730286855,624.4686633585904,1.0413743894387517 -79,1592.5346151222193,1476.1730839330146,1.078826482108168 -80,2022.054846474856,1792.5821604222494,1.128012367365384 -81,1533.1584394153697,1455.9931597028979,1.0529983806573773 -82,1211.6283759252801,1154.7323926717643,1.0492720076223658 -83,1147.742205473262,1002.020429841788,1.145427948664163 -84,1110.780605534009,1022.7747487507539,1.0860461767273273 -85,1422.0362109661753,1245.0899874708805,1.1421152087607107 -86,1631.297036813201,1545.3380024728344,1.0556247463032784 -87,1991.2368458070723,1919.6938687471393,1.0372679093394326 -88,807.8863567910877,744.6875007365123,1.0848662774547313 -89,1297.6363423190294,1241.2047925663326,1.0454651400725081 -90,1792.7605912957633,1676.2103507697755,1.0695319895098272 -91,1994.9820070803669,1892.5037773911095,1.0541495509353898 -92,2020.6713678798521,1808.3882548640324,1.1173880180015772 -93,886.5350245917059,834.9445584211072,1.0617890920424191 -94,1439.0297008463708,1362.219736369453,1.05638588432262 -95,1812.3625332584338,1759.7094209236222,1.0299214811881698 -96,2226.972512116245,2079.0442683086576,1.0711520413790563 -97,3799.6721269440377,3567.1136198815016,1.0651951498730958 -98,855.569237567565,796.8315661052761,1.0737140368941265 -99,8515.01507350408,8067.704370039371,1.0554446076539277 -100,9155.43093170757,8758.534587133148,1.0453153824565 -101,11149.103485782258,10660.150844550235,1.0458673285549227 -102,1564.4769281195752,1503.4700728457854,1.0405773659054718 -103,1508.7617839384477,1449.9252395226235,1.0405790193949556 -104,629.2100417372325,589.3772133469112,1.0675846087841123 -105,723.1675074746031,692.6748641824577,1.0440215819410958 -106,898.3629419497506,819.8559954884977,1.0957569950006596 -107,1069.995485512972,1007.8859298281153,1.0616235963284544 -108,986.6545776813324,928.3210343114641,1.0628376835316828 -109,731.2989402215853,685.9504588919435,1.066110432235727 -110,944.66811817823,845.8637343748833,1.1168088662370257 -111,1300.1953807598745,1169.7611583121227,1.111505003838526 -112,1539.9699737946414,1479.3861782237,1.0409519816142154 -113,882.1358483842946,840.3248638163585,1.0497557389627272 -114,885.1124030527577,807.5195338195784,1.0960879161228012 -115,1065.8943678526934,1004.1492041500733,1.0614900290190263 -116,371.4263450492747,355.18721427329683,1.045719919308477 -117,381.75579018746896,353.0320714604787,1.081362915862464 -118,711.7511568900239,668.1970094166039,1.0651815959359752 -119,447.9949139056055,412.99199266397227,1.0847544791748858 -120,1768.2632715798984,1609.6270940773447,1.098554614349037 -121,517.7020322842686,482.749440701732,1.0724031736457924 -122,4520.2062976761745,4315.170536323313,1.0475151004176904 -123,3605.2388941223976,3415.43553784555,1.0555722261988805 -124,4010.5738537490297,3778.446556953763,1.0614345851651825 -125,11780.673018403126,11220.112001901043,1.0499603761893914 -126,7439.762376491827,7097.894401261345,1.0481647029251 -127,5662.021608012371,5428.86982175703,1.04294665260179 -128,4955.66664209299,4759.8548575557425,1.0411381839146665 -129,3177.3554824801977,3024.487735307124,1.0505433516520941 -130,4137.581707488197,3939.308431919155,1.0503320009071864 -131,391.13048746891786,377.9495820927709,1.0348747716644162 -132,3747.1383540280012,3605.70259749564,1.039225574685665 -133,2141.901667658892,2055.6161597122673,1.0419754960277714 -134,343.1374044200349,315.117768399022,1.0889179818814045 -135,2260.34661197004,2177.6216754869506,1.0379886632348987 -136,195.39776050593687,189.59701060631738,1.030595154855391 -137,1233.9722236941177,1170.8065745904048,1.0539505418525779 -138,587.4983527631875,570.1489377259772,1.030429619156019 -139,1788.18871860277,1697.481550929971,1.053436320190405 -140,365.5161674751306,355.43069725391763,1.0283753493976013 -141,211.6032532994384,198.96721748107575,1.0635081295217113 -142,440.1868045765366,413.6309641562433,1.0642017709541256 -143,481.3660955140739,442.18313521900836,1.0886125163404494 -144,654.2628612989893,605.8971999519092,1.0798248636087424 -145,484.06897958875624,452.89553350671486,1.0688314275052995 -146,371.0540875736111,343.8745256016064,1.0790391842037563 -147,927.116887974283,866.5046727183415,1.0699502462759871 -148,871.8209749438853,806.2523745307868,1.0813251563460602 -149,465.1864499911505,420.74556965572293,1.105624119516675 -150,1292.193288590304,1213.1741408926043,1.0651342169554987 -151,1435.680347064488,1357.1694170377832,1.0578490268356224 -152,1010.3363727802443,963.4901286465522,1.0486214053894862 -153,214.04511280990823,206.4011120085236,1.0370346880741077 -154,792.050922435694,740.6815681440853,1.0693541685130954 -155,776.5792745303107,725.5669138924621,1.0703069002473964 -156,122.84809019607775,120.66956147307866,1.018053672329663 -157,287.88854603011805,272.2380452553359,1.0574882939675214 -158,324.6169187335406,308.9472185165232,1.0507196675608825 -159,505.34658167796925,472.33474623484744,1.069890762232233 -160,383.91467872690754,364.4215427350932,1.0534906247460358 -161,498.80649709037385,437.15060120959913,1.1410404005168295 -162,504.88634875069505,442.5285001601288,1.140912615951294 -163,935.2292686703029,900.9604070042526,1.0380359241090253 -164,512.5055767798042,493.9477407133874,1.0375704442733447 -165,612.080549570175,588.7943381277097,1.0395489731041103 -166,929.402859874816,859.4005941578985,1.0814547560157446 -167,452.75837915970635,406.1273942134474,1.1148186150716817 -168,430.1961006047303,385.3108725110058,1.1164909461319248 -169,653.8952885319858,591.0171835788218,1.1063896392528123 -170,381.04647875238487,333.46962929143587,1.1426722114455863 -171,2007.093452354803,1916.8391096286034,1.0470849860443878 -172,375.35903667831326,343.66477420756064,1.092224355969665 -173,349.9959239266513,332.2250993150805,1.053490313188881 -174,541.7682244343282,401.5110261959478,1.349323403561852 -175,1133.6882628027113,1051.827956304563,1.0778267073122414 -176,303.02575885871255,289.8779429531899,1.04535638611057 -177,985.5221028191506,899.8307196827791,1.0952305597730434 -178,747.7187961878197,714.733193814328,1.0461509310872452 -179,299.29383796505977,267.80061356679914,1.1175995229391253 -180,385.517605983923,359.9197743757929,1.0711209370269368 -181,460.843040371853,439.87586386322556,1.0476661218110093 -182,351.766527975549,323.2455754568987,1.088233079380396 -183,451.3881236532409,409.25324931759747,1.1029555034832357 -184,356.65864488119655,325.77526746552365,1.0947996379711091 -185,305.0519558857232,280.0029970898018,1.0894596095622782 -186,342.4969408190382,313.6938508389157,1.0918191093102207 -187,445.7201918152273,418.4739086939967,1.0651086783552712 -188,452.0525349354793,410.1607743327575,1.1021349754151175 -189,289.71935711765,274.399344031944,1.0558310849457517 -190,420.90827436348553,390.6817023021066,1.0773687937860097 -191,314.1858856814529,287.330692891244,1.0934644068824688 -192,311.08235908162686,284.89120914138107,1.0919338649275347 -193,298.4750087040794,275.1433964282403,1.084798009251602 -194,486.7790447449508,428.7992554199312,1.135214295715693 -195,651.4353358754664,585.4104640845777,1.1127838941077584 -196,651.6228412624503,584.6935081455408,1.1144690888208897 -197,669.5338381484053,601.5913702338138,1.11293790316205 -198,454.7060969220172,365.5143764929601,1.2440169967726973 -199,612.1734600274835,557.9405071490711,1.09720203531292 -200,1048.3778807634567,894.3159298976883,1.172267926484764 -201,1101.1995968730714,1005.1386823189418,1.0955698116527648 -202,572.1374243348503,564.9529869200697,1.01271687659171 -203,938.488239272157,886.0022327824759,1.0592391356902675 -204,239.08408684279604,224.58416978271399,1.0645633976522513 -205,528.4097363407409,476.1041261432023,1.109861703197687 -206,1029.9232058648063,970.5013414690943,1.0612280085113146 -207,108.50388643969518,100.600544215358,1.0785616249492478 -208,500.85385645068817,460.9100110592474,1.0866630023931205 -209,334.8559887012539,288.8872415976576,1.1591234934757642 -210,745.6040048074641,714.2482334575412,1.043900383481714 -211,407.0352536320223,391.53494546708134,1.0395885688988753 -212,421.1410549893627,374.5659745551853,1.124344130535315 -213,1060.8815172956515,929.2503860089303,1.141653028364151 -214,448.1647713421873,397.14710329170987,1.1284603806187257 -215,1018.8143060303275,969.0962403590216,1.0513035378745117 -216,1018.4817179166938,968.8437311756817,1.0512342549616096 -217,628.0324267919692,579.4166690034637,1.083904658580361 -218,691.5037129330145,649.7668361334439,1.0642336211677614 -219,2057.949011771204,1948.7178156748778,1.0560528544552241 -220,1139.1309285818188,1096.8955584879157,1.038504459031747 -221,872.8461628271302,829.2077710056626,1.0526266074044905 -222,945.3937775749339,825.1625585309648,1.1457061009384824 -223,1153.3820246443277,1037.6035492496896,1.1115825745568813 -224,1284.1857405928295,1173.641271318745,1.094189316595754 -225,1265.6431728028542,1191.2390011449095,1.0624594825945375 -226,351.35786362028904,330.2453823917906,1.063929678821221 -227,364.0470846931991,342.21000328773613,1.063811931842045 -228,746.065707360836,690.5415627810871,1.0804066656844389 -229,735.8428914011022,681.0146480682711,1.080509638799039 -230,573.6636711908103,445.65235128631895,1.2872447986305984 -231,855.0480651482706,806.4688397499353,1.060236952754924 -232,825.9074766119481,777.7569811833349,1.0619094352008949 -233,884.1129358956242,840.0602990242071,1.052439850951875 -234,637.4957884813215,565.8542197075482,1.126607819255638 -235,509.14770285702315,473.83513168656,1.0745250168445135 -236,635.1978193297534,588.331581859306,1.0796595642925304 -237,803.4935859041539,620.9029445265621,1.2940727580488718 -238,619.7210073049968,564.0851349546269,1.098630275649517 -239,455.1421265203198,420.80656661375576,1.081594639035373 -240,468.82726197809234,447.39778667442783,1.0478980360250614 -241,472.3567697567566,420.29801664923724,1.1238615245500085 -242,576.698532428225,565.5971671428929,1.0196276889812064 -243,450.6210251092992,427.4311666069826,1.0542540186912468 -244,505.3813245151343,495.5935433574656,1.0197496139504967 -245,395.10712268302603,374.69356585524724,1.0544806708414765 -246,325.9169158230024,319.10734217010753,1.0213394452367845 -247,1210.3152953067784,1104.148250921188,1.0961528891586936 -248,433.64463760941135,421.9816590795173,1.027638591106862 -249,262.67999206763795,256.51825429908973,1.0240206599931243 -250,542.7376736256194,494.6379596777542,1.0972422617528204 -251,245.85009647507448,231.20814846334687,1.0633279930185886 -252,395.204308192566,360.62058478116626,1.0959005804740347 -253,469.81104309459874,410.5479941202725,1.1443510864090711 -254,727.8855300832219,603.2791271420585,1.2065485068768529 -255,746.3928909902921,706.1399693550582,1.057004168269923 -256,658.527721110181,620.6048879942123,1.0611062430373934 -257,1015.9256968873975,957.9893662206573,1.0604770081063672 -258,292.2255047547188,278.8117889348048,1.0481102892785161 -259,896.3582506204853,862.0962634497312,1.039742646643256 -260,893.9640006962309,860.6219344577755,1.0387418271641684 -261,696.9526984324328,580.6849861610725,1.200225104905863 -262,1844.1799395114865,1725.5571558613133,1.06874462734963 -263,1881.5272370555617,1783.1018785983933,1.0551989539344413 -264,426.7581851542223,351.30317413064813,1.2147860212487371 -265,1108.1807927809937,1083.8528562675808,1.0224457926855404 -266,657.8392317495063,621.9389094724856,1.0577232292918777 -267,479.581656888716,454.05746543281896,1.0562135707460878 -268,444.7243831908688,430.8160139989018,1.032283779479011 -269,862.2380699461003,824.8168274411947,1.0453691550171162 -270,1671.5820696539436,1561.6785925934062,1.0703752216248452 -271,1593.3094851620397,1488.8671423250328,1.0701488667913703 -272,828.1668710844359,745.820213075127,1.1104108692224652 -273,965.1724880499529,848.1693685161727,1.1379478249001977 -274,544.7394096684159,484.4260036816415,1.1245048893502663 -275,453.83845267667346,425.93058545156634,1.0655221019066277 -276,814.4074464140309,734.8702798530089,1.108232934085906 -277,1008.1043539684329,866.8726455993188,1.1629209424084115 -278,601.6630487097033,586.3777903236828,1.0260672532934492 -279,405.36056563272086,354.96057602360645,1.14198756992597 -280,808.047211421263,770.9094835395248,1.048173914933859 -281,459.6150020577587,425.3695024637366,1.0805076513376546 -282,1007.1622702419287,942.7238192503822,1.068353477100839 -283,1042.7950435138318,1012.7364113271212,1.0296806077578675 -284,580.8455367046848,547.9288430622923,1.0600747598144789 -285,303.6860379464303,286.84600426758624,1.0587075762893832 -286,349.1168231303067,329.7640411682159,1.058686756425995 -287,494.55120523279317,470.08091573707475,1.052055483803995 -288,303.20276654176496,284.94512410895294,1.064074240574936 -289,161.0646221201953,151.65521762262262,1.0620447132982063 -290,159.43003752048105,150.00875255488273,1.0628049017483256 -291,664.8602934635467,559.3973012754981,1.1885296763991877 -292,437.73757371767783,428.6988790997756,1.0210840173804108 -293,420.1394425034233,400.277410160027,1.0496206676650968 -294,173.78879065665885,163.66473388788964,1.061858511166518 -295,1488.187610151785,1325.6028591923107,1.1226496682864258 -296,600.9306697576484,578.6294490645433,1.0385414546894545 -297,679.8469282889496,646.8948515378275,1.0509388452741382 -298,555.7100272613819,526.2555595578483,1.0559698936544837 -299,950.7203177772922,911.7213280041775,1.0427751206155134 -300,613.5255813615199,554.575136529999,1.106298391234011 -301,584.5961837097396,564.3879820276402,1.0358055138054123 -302,483.607331703794,423.6474591941855,1.1415324728340337 -303,497.2909761245954,440.5934936180714,1.1286843390285564 -304,1241.1993817650389,1081.1521182492502,1.1480339915302198 -305,471.427651248313,423.8805966990294,1.112170868210426 -306,906.8142391769213,804.438157349709,1.1272640797702824 -307,694.6700045460116,663.394743182968,1.047144270714273 -308,581.2023553167763,536.3385508191012,1.0836482934690388 -309,999.8731404386514,929.8741195687003,1.075277953646477 -310,576.5842199940929,531.5783450763531,1.084664613099082 -311,738.5179043536491,655.8461702395703,1.126053544055735 -312,765.6852975625422,722.1297606971634,1.0603153882251428 -313,867.8977701164027,820.8651223773626,1.0572964381807644 -314,571.0893533979245,526.9886423896791,1.0836843671018537 -315,397.2140761344623,350.6543789818407,1.1327794544811112 -316,1067.0727513934148,959.3932074239148,1.112237133988714 -317,795.0374549744429,725.010888083695,1.0965869175783522 -318,269.1097565827872,245.04382476709145,1.0982107255245868 -319,1428.3910331153156,1309.4039850709387,1.0908711516086693 -320,806.4867814201144,712.803474030664,1.131429364197263 -321,1109.7455831838924,989.7418997310183,1.1212474519725673 -322,285.0771135862483,279.3518071175256,1.020494968433528 -323,788.1700587012592,773.7313568603697,1.0186611305240085 -324,1346.219739350336,1219.566415075051,1.1038511086478968 -325,1998.0132478292014,1850.5400365547923,1.0796919863182017 -326,1556.8414347336136,1438.3387118759626,1.0823886069944493 -327,1077.1240989609648,986.9806695678996,1.0913325176191446 -328,926.4687274563241,866.9406884550734,1.068664488579181 -329,1305.6160498672843,1120.915971292816,1.1647760254155743 -330,1216.4172511254728,1108.1731062632018,1.097678010998908 -331,982.2015238365921,742.4290491085067,1.3229567525893542 -332,1044.668386602361,999.485743292742,1.0452058907421407 -333,1013.3146432251377,987.6230314687921,1.0260135810301396 -334,1171.3602589751686,1082.54869949579,1.0820393202825365 -335,785.7918120159267,742.5514880366129,1.0582320885163747 -336,1033.7605117973283,988.6131556508989,1.0456673633042082 -337,2122.378946050979,1957.5762449012996,1.084187117400369 -338,1517.9951019524376,1301.016998372939,1.1667757637685388 -339,1120.2102393889259,1106.9321793232427,1.0119953691054506 -340,792.2252713317145,761.1574082528862,1.0408166073692162 -341,1184.491117755064,1044.7577247439344,1.1337471738200142 -342,615.902772378719,598.8608133550644,1.0284572953240647 -343,1737.452110123338,1619.7402171586668,1.0726733162007671 -344,1058.1412071604805,996.163774775746,1.0622161073852405 -345,807.3401971846574,759.2188626229765,1.0633826909877206 -346,1193.9324826471354,1110.0405176625716,1.075575588142689 -347,1444.4765098039368,1405.3344246345523,1.027852505768912 -348,3201.506009131552,2994.7206782501653,1.0690499559385327 -349,569.4961091862584,526.8660484755011,1.0809125219476723 -350,1655.2262717266651,1518.1281991043975,1.090307309160812 -351,1317.5834731290724,1222.0248660138875,1.0781969416276174 -352,1914.5680058897053,1792.8726513621943,1.0678772998378043 -353,471.3446860980949,447.119211927869,1.0541812418790317 -354,1775.7756490720838,1607.8298674605549,1.1044549457690984 -355,1099.7611228323692,1064.7373067476701,1.0328943260114387 -356,257.25555674464397,202.03493751188626,1.273322128899161 -357,317.27996230951317,246.70876515513862,1.28605062779183 -358,612.9113091441358,588.7365523558037,1.041062095926604 -359,206.30023998266344,190.11008236287694,1.085162014652559 -360,310.9362990507455,257.86993390407594,1.2057873298498207 -361,872.637742090539,829.0338423491535,1.0525960431456325 -362,394.79519228351364,353.41119209798075,1.1170987255379832 -363,724.4803560387836,658.2033421486292,1.1006938276457252 -364,486.669672210764,438.17435730977115,1.1106758396331913 -365,726.0806449279311,674.7673623284946,1.076045887018548 -366,711.4200914440393,672.9798219608294,1.0571194978345833 -367,252.5128337639312,208.73708310900068,1.2097171714911394 -368,1308.9715322877603,1254.1580606041268,1.0437053936066318 -369,692.4847151184633,665.7406114599006,1.0401719576636848 -370,669.4710549736442,649.8584584285512,1.030179797293889 -371,701.8969627483336,693.5383458585949,1.0120521337279351 -372,208.85997289573461,208.85997289573461,1.0 -373,355.4770872448971,342.3463335182284,1.0383551755665863 -374,934.5311719132742,934.4517394231801,1.0000850043792986 -375,303.5721124315758,280.7200049554519,1.0814053400994716 -376,170.97489426143713,158.34032524816286,1.0797937543293057 -377,315.67181725373024,285.23285675185866,1.1067161786636392 -378,827.5422880788946,806.892608483694,1.0255916083232008 -379,733.4602440780619,666.543327411908,1.1003939487714665 -380,578.8775575749454,538.0675255676318,1.075845558537028 -381,361.96226385523846,346.43457708581604,1.044821411592458 -382,373.97622125745306,325.5020911425457,1.148921101995868 -383,331.04552327756494,259.0498024947924,1.2779223148962635 -384,443.5575334261658,371.34821161574735,1.1944517828596333 -385,576.7486769720102,525.4754230820554,1.0975749799852168 -386,985.9331056244325,938.9973876035085,1.0499849292879424 -387,632.9841274861946,599.1827747429442,1.0564124240015937 -388,1637.874975831905,1539.8606461079073,1.0636514284404468 -389,775.5096495110796,721.2497293158826,1.0752304201856178 -390,1016.4787783830459,943.8251917560532,1.076977799768001 -391,534.1949765230688,534.1570255951885,1.0000710482612074 -392,1181.306588642486,1082.7897628274566,1.0909842604697106 -393,1183.3737881808604,1084.699132771002,1.0909696084644056 -394,253.3618411692522,227.21393671793228,1.1150805484426793 -395,275.847045899951,267.196116579019,1.032376703043787 -396,834.1205133597847,758.7865718326598,1.099282122699107 -397,455.5179354563597,406.31421655243696,1.1210977044352883 -398,243.779809471478,193.06206834661532,1.2627017391826871 -399,145.9578848792575,144.20173199955337,1.0121784451223483 -400,756.1852173457752,744.3830810809112,1.0158549227740725 -401,800.4731470453307,756.0718109934762,1.058726347691116 -402,150.77599942680467,118.98084279389253,1.2672292100669522 -403,564.7846040749281,537.0076435700606,1.0517254471839628 -404,353.9778231532897,325.61876703305234,1.0870928183244388 -405,849.7447827559178,788.9219943714679,1.0770960739064033 -406,654.4588213285937,613.595297981251,1.0665968652005402 -407,1331.4927852924873,1264.3352268683898,1.0531168925747951 -408,562.0889664721561,517.5362550167664,1.086086165024219 -409,194.85801575102982,164.50015577258952,1.1845460865119666 -410,727.6351071541995,650.0497452336084,1.1193529610456339 -411,296.5580165180137,281.8655607953417,1.052125756978661 -412,269.59522588044024,268.9661900359872,1.0023387171613238 -413,813.8559319663902,759.6933090766554,1.0712953796520401 -414,357.6223334857362,319.25405704060216,1.1201810144585083 -415,797.7804420095451,729.2337163262343,1.0939982945778186 -416,665.8527040517467,594.3013039706436,1.1203958322202126 -417,2938.592490719571,2804.95259269009,1.047644262643781 -418,462.58285851607485,402.7319199783011,1.1486123536992014 -419,1125.5725077113234,987.1793254826583,1.1401905192463395 -420,636.4667886644748,544.1695695141939,1.1696111365298856 -421,597.6139774111778,554.6810696557219,1.0774010690180997 -422,761.6817115249329,623.1119779461554,1.2223833572185827 -423,853.4277447040772,768.9003953165214,1.1099327687986942 -424,423.9218636566557,400.82098603645727,1.0576339024775945 -425,392.50216409227386,386.15457579200057,1.0164379466105107 -426,406.19308313212093,378.0835600406031,1.074347382595792 -427,545.9329325183191,426.305763856444,1.2806135379913814 -428,1978.283931451097,1868.088000141303,1.0589886190058813 -429,971.0237680093393,867.6708683885894,1.1191153274659245 -430,679.9946420302075,633.4476336046042,1.07348201486006 -431,2341.674365318192,2223.0306123917844,1.0533702740146962 -432,2039.614342223146,1931.5111596794059,1.05596818946761 -433,437.86709779701795,416.5007088112754,1.0512997662038173 -434,450.25283167626327,428.25515562101646,1.0513658172389024 -435,621.3579608282894,582.7608805787384,1.066231419327976 -436,629.7623404390164,592.2830179922886,1.063279414246545 -437,2107.709340294671,2000.0731125927146,1.0538161465319769 -438,1318.2046879909908,1234.9710810458282,1.067397211337675 -439,602.8399346043452,550.4239026530955,1.0952284806284747 -440,369.4995599647615,343.3512226827644,1.0761562375624816 -441,477.08423719082344,474.3262980043614,1.0058144344896447 -442,462.97004760978484,422.3434905625491,1.0961931649357786 -443,568.1623479156337,550.8766702743807,1.0313784891864153 -444,436.12759871853405,372.705815578139,1.1701657996455344 -445,496.31792871916304,481.6059413049863,1.0305477697686045 -446,764.3425495833176,744.3135085762001,1.026909414885444 -447,902.9327187485856,798.2287710004958,1.131170350596176 -448,465.61084090312096,451.2087541546034,1.031918899214404 -449,704.8901180003335,623.5521811916482,1.1304428711214565 -450,846.4764823832335,767.7546520497723,1.1025351394788523 -451,517.7526504833812,482.37328264855574,1.0733443768704785 -452,1102.8351404514149,1039.3934576042316,1.0610372158714703 -453,5009.136028231875,4851.299674801677,1.0325348595243502 -454,214.78036616273113,214.63852444338207,1.0006608399853516 -455,1055.497848006371,946.1905105637738,1.1155236035684484 -456,237.47930944098744,231.4103637142357,1.0262259028910483 -457,555.9351791868214,531.4992883914405,1.0459753970119792 -458,162.75930426630234,155.65889248954906,1.0456152016964273 -459,3418.837676657973,3093.235588314585,1.1052626219526975 -460,262.3103670808626,252.0853288781299,1.0405618139232369 -461,1004.8233010078904,930.0132396526526,1.0804397810327715 -462,999.7541592013986,925.3080728464689,1.0804554596891343 -463,264.5567188985617,253.55180455941223,1.0434030211627652 -464,307.65740560296274,266.92493537693395,1.1525989700756472 -465,892.4176382697038,747.1015843442614,1.1945064191678672 -466,658.8791616767875,588.3517538763566,1.119872860641208 -467,458.00811523517535,417.6195376820188,1.096711417711278 -468,1583.596549171574,1530.0269831328242,1.035012170784768 -469,573.5608671202012,543.2212327388701,1.0558513411347372 -470,566.4884549159962,536.5308655127691,1.0558357241471956 -471,1135.8938167186247,1072.0593950171724,1.0595437361009554 -472,553.1327515102718,543.6014754514694,1.0175335728272012 -473,193.09143743382728,190.57722841221596,1.013192599360156 -474,726.5036013983344,700.8192324950429,1.0366490639987866 -475,509.5668059807296,469.005411213006,1.086483852420419 -476,887.6761591645925,845.6622256740443,1.0496816958532829 -477,417.9390747755091,390.16959256004293,1.0711728508448355 -478,600.645485766306,530.6251903102226,1.131958106653676 -479,876.41369499685,821.8925931118418,1.0663360423757817 -480,621.6089666901921,546.5587896868366,1.13731400614078 -481,490.5927973521472,468.3294279192416,1.0475378400452442 -482,306.4454921481086,251.41976911217358,1.2188599696445697 -483,759.0277543268764,669.4528756129246,1.1338031129255224 -484,251.65317227093396,215.9140332769121,1.1655248547378392 -485,757.9167117518456,668.4513662062523,1.1338397227809518 -486,334.40474348586565,317.26247882011864,1.0540318058709561 -487,440.4053873737114,415.9018419199226,1.0589166552873952 -488,350.33715949283726,332.2996450693776,1.0542808717706988 -489,445.6375565737255,400.12301185017867,1.1137513798896155 -490,421.1418984754702,397.7786241020321,1.0587343636832665 -491,426.3745466198633,382.505550456771,1.1146885218023788 -492,1248.2400899267109,1084.3521803154156,1.151139005008155 -493,2637.639660991428,2475.341651452485,1.0655659025669082 -494,4761.601232517938,4471.422315005137,1.0648963343361737 -495,535.827861332873,503.66360579994847,1.063860591002678 -496,534.4665739537145,502.37828277558475,1.063872767351418 -497,346.78746341064743,311.5450630225306,1.1131213572964505 -498,311.9571635780916,291.5570894499475,1.0699693983316643 -499,730.9974014506064,685.3115066872526,1.0666644209495273 -500,289.2289800335143,269.22321974684513,1.074309193335853 -501,2008.0915629456563,1867.1243758775445,1.075499623318804 -502,1294.5814856983882,1106.2318631985625,1.1702623371878216 -503,2650.159989055442,2386.035111713998,1.1106961402389888 -504,565.5107725062097,534.4595523429742,1.0580983537989217 -505,158.61748269589174,134.47806647223533,1.1795044861731434 -506,420.7915428597136,388.5784051484072,1.0828999689239123 -507,394.43161815169856,388.18679595214047,1.0160871576897428 -508,271.7502382735223,230.82293544410513,1.1773103818763622 -509,1125.1221043048233,1063.2684944046248,1.0581730863142271 -510,264.0632437319486,223.14003490146837,1.1833969814002703 -511,709.9058933259751,630.415144913985,1.126092701061038 -512,504.1920517848882,467.02408796513777,1.0795846826267448 -513,714.8713474048309,634.684868157618,1.1263406192115162 -514,502.4109992488525,465.8749891533648,1.0784244935790277 -515,1004.5904164398681,925.9829634155233,1.0848908199502918 -516,1018.9139748995592,889.3655085199329,1.1456639201077392 -517,871.5360487076322,782.9291187417809,1.1131736294445767 -518,329.6813291444663,318.15643616006037,1.0362239818986654 -519,208.0012684461536,182.29455061694884,1.1410174782636353 -520,330.2279545808784,318.6797009940959,1.0362378072740706 -521,208.36475871936577,182.64233412418844,1.1408349532901132 -522,494.0585494531947,480.52555176411397,1.0281629096296714 -523,636.2735771064024,557.7617363312818,1.1407623285375184 -524,646.5043944989013,564.3394176876864,1.1455949633075007 -525,744.7179294816476,618.0376255754433,1.2049718312671573 -526,629.0693623605687,549.8934317625185,1.1439841358793383 -527,3427.1534473808933,3225.407154321153,1.0625490933104231 -528,497.2629667673311,463.8763824888391,1.0719730202675175 -529,266.2760660017803,262.19974365959513,1.0155466297765618 -530,849.5304281285022,799.6006992171303,1.0624433282265222 -531,242.9286042737912,240.8325988681974,1.0087031631741055 -532,385.48672707997684,380.8134688334385,1.0122717777311137 -533,400.38076159529385,394.6965793983891,1.014401397158214 -534,344.97531566841747,344.1048514239323,1.0025296482769224 -535,507.38220556694586,485.42715191817723,1.045228318115319 -536,161.35417790074968,158.0685510253811,1.0207860884031321 -537,226.4081805188226,194.5336969969074,1.163850705630819 -538,562.8615482908018,512.5573694999593,1.0981435089693827 -539,503.24212709279067,393.3535549793587,1.2793633633721662 -540,322.87878513214434,255.64527232843696,1.2629953301750483 -541,467.222835024663,418.37441437585153,1.116757667224191 -542,780.5964652621042,689.4332428440227,1.1322292235895364 -543,496.55820764506404,444.5600245540562,1.116965494464258 -544,489.16518287513406,426.43038918610404,1.147116142000966 -545,177.28474135074444,149.94886023357236,1.1823013597742025 -546,41.11486559881637,40.73841167326815,1.009240760994009 -547,1982.2422061670547,1675.7980002447973,1.1828646447110527 -548,650.8669339201496,640.9791843712788,1.0154260072557104 -549,196.93334929097594,185.57893079668793,1.0611837693295443 -550,195.65310868390213,184.29754014812823,1.0616154102037765 -551,629.8260685909356,603.3346210126751,1.04390838293648 -552,1479.3120313647003,1422.220399314842,1.0401426052371083 -553,122.54736485175181,116.31474082397446,1.0535841285775593 -554,542.0901408048409,520.375042002747,1.0417297084781771 -555,541.7948203883107,521.3717030193156,1.0391718945441855 -556,265.4406392466856,253.3190490847606,1.047851080310463 -557,576.3829078824733,537.9924235122147,1.0713587825635744 -558,176.5829588871897,163.91882819101824,1.0772585482456822 -559,458.68534988673366,348.98608367994876,1.314337079146654 -560,458.82103379787986,334.96859922227503,1.3697434173327396 -561,253.43754969922136,229.15335833014007,1.1059735346932824 -562,1570.0598462896683,1436.2811764943533,1.0931423957820288 -563,1021.7882261285928,954.7363926587168,1.0702307296395734 -564,191.04131485068984,171.32416992209164,1.1150867676029856 -565,141.52836519152183,132.32084844532113,1.0695847771109592 -566,232.86629440134132,214.48672885995782,1.085690921946895 -567,306.9907187824588,306.980091372692,1.000034619214944 -568,1024.622764389989,925.3964596131319,1.1072257233600604 -569,891.9105937337315,834.2136391916113,1.0691632836380272 -570,10889.59625452566,10140.422034862853,1.0738799841946558 -571,3811.6122369821724,3527.7277278843826,1.0804723411202821 -572,375.71658064555544,347.9875448201671,1.0796839893787524 -573,571.0178061468097,492.9906059353302,1.1582731988643917 -574,1318.8446976365153,1232.2034868576918,1.0703140444763486 -575,598.4878096934729,584.1490511820004,1.0245464038372716 -576,130.68224581641033,104.21076699742989,1.2540186545180432 -577,692.4454132481414,638.164202190007,1.0850583766244737 -578,1186.3952832650245,1122.7756143239405,1.0566628524252297 -579,750.3600809696972,712.8909916909645,1.052559352994287 -580,651.9561852175249,604.9817643333909,1.0776460112577007 -581,138.54705577893563,126.43708007432998,1.0957786726606342 -582,301.85443676524636,291.39917111792323,1.0358795311847064 -583,194.7667958464967,188.63891759943635,1.0324846978822924 -584,468.84695863659186,414.82357267231987,1.1302321987544004 -585,273.3312130868827,258.302287953626,1.0581834766247016 -586,376.59810954228857,343.3631288078778,1.0967925148218427 -587,261.20279608125674,240.66906577990437,1.08531935849259 -588,74.56129291096681,65.2810114016841,1.142158972571361 -589,141.3132261397901,139.94191989751613,1.0097991098255492 -590,210.17026167342402,207.97250364125438,1.010567541351335 -591,242.1442363895885,221.337580707027,1.0940041705348817 -592,1104.6881525566907,1062.0127175120263,1.0401835442654963 -593,122.02277543770548,121.95366105574824,1.0005667265858107 -594,79.71970040860565,79.71970040860565,1.0 -595,332.31602147497637,326.47132044743057,1.01790264767985 -596,408.8257880174553,397.27934842011337,1.0290637800410705 -597,1157.3760645664017,1077.44590130029,1.0741848506450764 -598,1192.660924388985,1147.9824028104213,1.0389191693785413 -599,376.5127540418257,367.69268340317734,1.023987615301491 -600,319.1969691740032,304.1842201864616,1.0493541347356512 -601,368.82851552985164,325.00645248186436,1.1348344400960242 -602,146.1074004773684,120.91223231340433,1.208375676157051 -603,157.4903262054921,137.95949032203782,1.1415693537129166 -604,286.3130055192401,277.76506713649303,1.0307739863434542 -605,668.2564722683135,656.2260687105264,1.01833271205063 -606,680.1318545393187,658.4052309312701,1.032998862383456 -607,863.7622989051698,811.6656878347034,1.0641848138356638 -608,1271.9010388918869,1139.0758578429684,1.1166078449774586 -609,423.23313577717823,392.5008363937386,1.0782986850825724 -610,331.34414880780594,310.3710025240345,1.0675744386982393 -611,244.37428243349882,232.65144919428735,1.050387965687769 -612,421.80076304236195,391.1963221034547,1.0782329465020217 -613,138.40636864196375,107.73757569552565,1.2846619923313514 -614,422.5460840488552,394.64438265422814,1.0707008705076981 -615,428.1601814245591,406.3254530014457,1.0537370432047133 -616,140.22458339174307,109.15103731082016,1.2846839283115323 -617,409.04246454096983,359.80275729297534,1.1368519452670571 -618,93.32879171726736,88.12631906112581,1.059034267078976 -619,97.42400311008338,91.77123515133515,1.0615962937561705 -620,289.43570656915045,268.107216166698,1.079552093775765 -621,1154.4710177505606,1094.3969612405815,1.054892382414769 -622,413.47112731544684,411.1696948678976,1.0055972813081193 -623,467.9895231735361,445.8942030699031,1.0495528310337086 -624,453.10311489507717,430.22022701516624,1.053188777381925 -625,75.21726322767675,57.40467481474374,1.3102985683730073 -626,19.832192795841408,14.326581170407922,1.3842934723886204 -627,94.12715551782763,75.31097110123552,1.2498465249013821 -628,40.98032561865422,36.46079292763605,1.1239559627786515 -629,65.72513841981277,54.26080456362277,1.2112820469285088 -630,478.1146021780306,459.2802804417651,1.0410083396529664 -631,1634.09465629211,1511.6523378041868,1.0809989938994715 -632,1244.24107174307,1126.1716143810127,1.104841443217296 -633,938.6777759721608,909.2398345675426,1.0323764317020048 -634,659.9519940732137,623.6163130865453,1.0582660848091472 -635,736.3077757752237,701.0289553756134,1.0503243412830328 -636,305.80025391895725,293.0001753943718,1.0436862486766665 -637,278.1851960074465,264.30624366467526,1.0525108758322768 -638,334.1083940509987,324.046690708478,1.0310501653959876 -639,281.32844066048756,267.2200720290411,1.0527968147164977 -640,701.3719256850159,672.1135711167527,1.04353186102112 -641,142.18678151694405,142.17315291232856,1.000095859199408 -642,66.67152602637472,48.9341507005673,1.3624743675300324 -643,289.47229931801667,273.547646261283,1.0582152808638061 -644,121.98534514546954,121.95196629886489,1.000273704866085 -645,331.33286459036316,321.9699504995522,1.0290800867481078 -646,406.38062751173317,374.758531417623,1.0843799231854476 -647,313.27358023101766,265.8826345388082,1.1782400936955222 -648,503.2134264697961,473.13482869949434,1.063572994304771 -649,476.9587758743969,437.7580164147487,1.089548924268032 -650,1577.0313568635188,1514.6917602262927,1.0411566222740347 -651,1436.99243542599,1341.2010872868425,1.0714220626922744 -652,582.2953102711087,512.7440526936207,1.1356451765985611 -653,456.74994164182556,448.4971540544648,1.0184009809488301 -654,216.18958976759228,205.15968273160533,1.0537625467593286 -655,146.41247214932497,141.41661172532667,1.0353272530224509 -656,370.6876816033252,339.836025941822,1.090783946687232 -657,396.9845410020808,363.2552483629853,1.0928528707874063 -658,352.24139252672717,335.71413639724017,1.049230146537323 -659,347.6302289000389,330.89653271471934,1.0505707812893477 -660,348.15367701491925,331.5165493710697,1.0501849083414159 -661,352.80263440180147,335.53252461019935,1.0514707473192515 -662,251.18954980762226,229.69106220832367,1.093597405979167 -663,290.9675165773856,267.6977249990335,1.0869256232134066 -664,1116.3799240819385,1054.839151676231,1.0583413805867121 -665,258.51069757765674,236.44792581595408,1.0933092209862558 -666,260.03624676731505,237.7805994652009,1.093597405979167 -667,131.59562823184527,131.59562823184527,1.0 -668,201.58543273235648,172.82717057735195,1.1663989641150392 -669,294.310954174587,294.27536555118996,1.0001209364682306 -670,188.74090112242288,160.47091334194587,1.1761689217798417 -671,478.02641718278574,457.56115287379714,1.044726839637615 -672,476.25160926755245,461.81256081711064,1.0312660366467599 -673,111.51717086810592,97.17917389511595,1.1475418692945956 -674,194.30996345214612,171.75089189264818,1.1313476239389681 -675,283.22122605287876,265.84799860799967,1.0653502284607996 -676,411.42916408534626,388.8624413219446,1.0580326623643201 -677,1904.5445068808742,1801.4924291382274,1.0572037251313586 -678,2029.5098841350346,1939.313857167451,1.046509246883495 -679,255.85337402496847,241.69788438946412,1.0585668743905705 -680,1834.685477423359,1664.7000833502204,1.1021117231706037 -681,1289.7434381198304,1248.4672713889195,1.0330614727969532 -682,904.7466033439702,781.6333033599229,1.1575077462217045 -683,1232.0236054780387,1137.0266009271943,1.0835486210026912 -684,402.03793451629303,394.1413769785714,1.020034835211303 -685,875.9986757636102,827.5326736139681,1.0585668743905703 -686,109.35702244730476,109.17948143165724,1.001626139026486 -687,107.76013108212308,107.68022698547227,1.00074204985342 -688,401.3689889578308,368.17947761451086,1.090144924856648 -689,111.5013887844769,99.50206490272248,1.1205937172608977 -690,889.3971375483512,840.1956706202016,1.0585595339854952 -691,33.107621938236704,31.14716842437672,1.0629416288231734 -692,33.702262831430154,31.73250830943923,1.062073710114022 -693,36.695568567187706,35.28743441446081,1.0399046906099199 -694,44.93805398878813,44.273009798415835,1.015021436161679 -695,179.4495147183747,171.28770949831394,1.0476496839380125 -696,309.43367922366645,294.4351407729649,1.0509400420456834 -697,305.4055499260967,292.79411371017653,1.043072710909768 -698,826.4064737192446,780.9652757906165,1.0581859390388713 -699,209.55616328296207,202.1242206825116,1.0367691836997817 -700,857.2660958870093,768.1205621871279,1.1160566948579669 -701,535.0787441854276,503.74148685298184,1.0622090063064265 -702,322.0489223151719,292.2687392072884,1.1018931521333941 -703,80.16543816026484,73.86936689786958,1.0852325060684505 -704,131.963536355012,120.0910349341933,1.0988625123209614 -705,226.76155833615417,206.71724579976248,1.0969648780818593 -706,31.641554858902836,28.656093563734977,1.1041824241858993 -707,916.0472239778628,860.0729003426956,1.0650809060637352 -708,425.0230316709216,397.00467974363187,1.0705743618573533 -709,777.332988105624,735.3512046647984,1.057090793044886 -710,286.16284433194187,268.93322954348434,1.0640665150145443 -711,560.6536691998617,528.6651196681923,1.0605081522150477 -712,272.39652529390463,253.91390429700462,1.0727908975606186 -713,78.73785351927714,74.89778150548732,1.0512708378886828 -714,86.2608190213831,80.38870138123013,1.0730465542950547 -715,80.01719480869554,76.13437092837333,1.0509996186081991 -716,82.77287867056536,77.72028383919161,1.0650099894363214 -717,265.4303774877686,247.43244228522903,1.0727387849237344 -718,1461.9847728850093,1385.7572106689427,1.055007877014235 -719,1469.5631601658613,1392.9402345365004,1.0550080496848144 -720,1800.4870418043547,1698.0544170713265,1.0603235230291947 -721,1434.2941955470974,1359.510191391995,1.0550080496848144 -722,1209.4422980831084,1141.1533377237415,1.0598420546143106 -723,1651.782321826873,1549.7802425010316,1.0658171246016344 -724,1436.8689427828501,1361.9110550049224,1.0550387541847634 -725,1024.2135564244027,961.0853981111167,1.0656842341350268 -726,1471.887723952808,1374.318451049651,1.0709946612654713 -727,673.6495597713234,654.536038929014,1.0292016324625668 -728,94.15095359617804,83.34808155614064,1.129611526004482 -729,4797.566271980058,4554.015969180602,1.0534803356966 -730,501.16821402947585,486.3516997631499,1.0304646087873066 -731,395.9555719516341,359.33077136440335,1.1019250326048167 -732,293.32062291593866,262.0219759525725,1.1194504653649027 -733,305.98158569311926,301.08319269749865,1.0162692342662318 -734,1154.211103786878,1097.6115767060471,1.051566080644564 -735,4437.0842271057845,4121.103229483426,1.0766738856143545 -736,2086.258715366478,1969.504158813093,1.0592811932033424 -737,2078.0375005619157,1927.826903490524,1.0779170561420324 -738,1135.5465233127513,1039.1273219268837,1.0927886307590053 -739,533.6653817237453,497.97803295870057,1.0716645040605726 -740,326.44635021007235,309.21074401118483,1.055740644633823 -741,217.2883594378391,212.14665758920265,1.0242365442240091 -742,530.9053084007803,497.63655721200024,1.0668535112757143 -743,1527.7568960648941,1440.646951019666,1.0604658518060746 -744,196.83601005197528,189.67950081350395,1.037729481613871 -745,384.5849121329855,347.26564994064034,1.107466034140504 -746,189.62875574227522,185.03585008456884,1.0248217070130314 -747,364.5232708099188,311.6399603120222,1.1696936119647443 -748,1734.1544797948982,1641.1099206411318,1.0566961164413757 -749,2481.642066784463,2365.6434262179064,1.0490347105066509 -750,136.45355790952217,129.30096018676295,1.0553174370277527 -751,135.56326526064146,128.4692193497651,1.0552198102143238 -752,135.97808841854888,128.86070681431647,1.0552331411194904 -753,139.73983186888816,132.30927694996802,1.0561604982674795 -754,78.21382143989882,72.87408297787889,1.0732734909836303 -755,141.7430065125841,131.74766923432355,1.0758672797503768 -756,333.94790489738807,313.32079573873625,1.065833833691179 -757,269.73989938613477,253.18248742793932,1.0653971454597861 -758,1627.5431462021907,1496.8044348613773,1.087345219118703 -759,461.125768471042,430.93253605697765,1.0700648706879543 -760,453.00054798150524,412.2899567058883,1.0987426218210266 -761,329.97675764905034,313.7886348771662,1.0515892577760857 -762,443.1104027116273,399.81663984312587,1.1082840446197746 -763,1578.4972443320987,1501.890528336415,1.0510068573909566 -764,140.751123678607,134.46914289442034,1.0467168946642205 -765,308.96276616385603,300.31089736591065,1.0288097064536543 -766,664.6838138968245,641.0769357055157,1.036823783350323 -767,699.9450198116341,672.5971763913404,1.0406600627838225 -768,842.198733810284,811.2120682947292,1.0381979838893334 -769,1952.4980672873858,1824.5739361123806,1.070111782615712 -770,238.67217990438516,215.56046334009008,1.1072168625274834 -771,1090.0552031144657,1058.094598947701,1.0302058097627096 -772,973.8788202503,949.9258768020428,1.025215592114298 -773,2624.709092422478,2508.0712518335417,1.0465049948256724 -774,924.2762881901068,896.6226852797218,1.0308419621367908 -775,926.1554795816432,898.5134773602518,1.0307641486943535 -776,926.1868069861544,898.545446817674,1.0307623395860233 -777,926.2101262634872,898.5643051111148,1.030766658540875 -778,2986.7569523376424,2849.895502810733,1.0480233220452921 -779,1096.8896632821397,1064.6795529660399,1.0302533379422638 -780,262.5028547022448,250.9277734475129,1.0461291354707418 -781,262.9430808501646,251.3423489758086,1.0461551024792586 -782,263.2591410302535,251.87975759758962,1.045177840177391 -783,266.54445903294845,254.43894883103954,1.0475772685649145 -784,1998.0952425684422,1927.6985007003486,1.036518543663606 -785,2525.1627520739635,2418.950235296329,1.043908516689523 -786,862.3846472706673,826.6271025317973,1.0432571647231885 -787,382.33326445235036,357.4688739218777,1.069556798771539 -788,337.9330664480846,316.37420938566754,1.0681435351645125 -789,252.80273785937766,239.31040260400167,1.0563800616628538 -790,329.7142687302062,310.9881659614576,1.0602148403649205 -791,580.4744635658817,556.147551249469,1.0437418312132432 -792,1029.319404835687,958.7830128171994,1.0735686709876409 -793,1081.6187037437367,1028.4159939200792,1.0517326744607123 -794,1314.0663933227743,1247.60497737194,1.0532712013467869 -795,695.3708658941681,665.3338313076629,1.0451458097771307 -796,755.2151871391948,717.0528123714449,1.0532211492784456 -797,1569.032116479277,1477.4177321158895,1.0620098042495953 -798,3457.234732483933,3299.6680280398728,1.0477522899591996 -799,5137.911005075546,4932.046971473148,1.0417400796855973 -800,2386.7861595484583,2291.153203612947,1.0417400965525598 -801,2330.9225995345128,2237.5308253707694,1.0417387653858434 -802,904.4544774395426,857.1101605722744,1.0552371434211647 -803,2292.3301821940636,2192.488500200548,1.0455380641606025 -804,4009.269594999486,3848.6275734053593,1.0417400796855973 -805,3937.3603706432036,3779.587389192948,1.041743440540991 -806,441.68844635851497,438.0765948385723,1.0082447945461994 -807,270.1295985178061,264.87854394598514,1.0198243862775527 -808,565.5019085602497,536.1512047089542,1.0547433328387807 -809,531.3009780377267,499.14472542733705,1.0644227034210558 -810,233.5528726890993,226.15305907275186,1.0327203781663947 -811,287.56393389944884,270.95078587795217,1.0613142640190751 -812,3215.80103096718,3010.419979771108,1.0682233882900576 -813,606.5468069718296,540.0845934615121,1.1230588954303393 -814,1953.1016999566161,1874.8454994129368,1.0417400796855973 -815,1969.6040136713855,1890.4962318850185,1.0418449825247673 -816,1238.5225158163896,1199.5355145128908,1.0325017482448868 -817,6974.192097741601,6705.543665533137,1.040063631766255 -818,646.8288375060883,601.5579091326227,1.0752561435668613 -819,765.765593357104,709.3727824927232,1.0794967219720744 -820,720.935418573055,701.4365185123604,1.0277985242371594 -821,1580.0602718127009,1462.6085651099809,1.0803028981946978 -822,1534.3780646810922,1438.5173734991818,1.066638535583849 -823,830.3705353669291,813.1469880304442,1.0211813455500864 -824,838.3939341743095,821.2281628188507,1.0209025604973623 -825,462.62910919951963,453.8923323494196,1.0192485667358095 -826,828.9051269649611,811.774445654405,1.0211027600120455 -827,681.5711420719587,607.8287127575209,1.1213210691872262 -828,523.6088550800145,492.4036136677511,1.06337329894845 -829,274.17455280056964,270.9755768302881,1.0118054033049815 -830,562.7553988563513,536.0863986436107,1.0497475785250618 -831,397.37743063114937,388.8407644199639,1.0219541441955544 -832,398.04717557846226,389.5187589436113,1.0218947520216493 -833,397.85765187077027,389.3388908946145,1.0218800668912924 -834,2590.1550943326097,2340.200466946996,1.1068090665376638 -835,358.2061668455981,355.80140902772575,1.0067587079670193 -836,457.4091491728153,453.72254252410136,1.0081252446224185 -837,2315.372429203523,2200.9455400875004,1.0519898775466627 -838,1797.969544415505,1702.3825160183549,1.0561489721010031 -839,546.4285925776696,503.45590186099037,1.085355421513252 -840,537.2438619355332,495.177220838923,1.0849526984002646 -841,278.3369243292272,269.4900435143453,1.0328282288262385 -842,315.8949463611428,302.3970462675411,1.044636348999453 -843,1049.6799013351774,1011.3552164206525,1.037894385960812 -844,229.0893658080519,222.68749515708038,1.0287482269556973 -845,421.8237254576232,401.0543138733811,1.0517870295014438 -846,320.8222047582353,308.74799684349654,1.0391070000070612 -847,267.36371492092957,255.83541209719363,1.045061403850364 -848,350.9241553515416,319.1255838030215,1.0996428151249307 -849,388.4655172227859,362.54201013791896,1.0715048362947097 -850,427.431750951356,405.9819482554631,1.0528343754890195 -851,427.7001641616263,404.5681208592709,1.0571771281761517 -852,271.199472784603,238.96664168822494,1.1348842284791851 -853,305.04285983729176,267.9697118712373,1.1383482771510707 -854,345.43438670144985,307.3879155786433,1.1237734770776069 -855,300.8269722080143,263.7870131688841,1.140416158453624 -856,1180.5018435260417,1039.7565939303313,1.135363651855947 -857,4525.156511487591,4327.211587067328,1.0457442212929589 -858,1604.9997099207735,1522.179420458729,1.0544090192975315 -859,72.67280776980667,70.65511131902389,1.0285569778762702 -860,106.6449513727977,100.60297180220152,1.060057664921425 -861,72.32196588802988,70.33728536293788,1.028216621026119 -862,107.09214446272593,100.94072327016805,1.0609409264494132 -863,1729.8997976933706,1630.7630391387465,1.0607916393585797 -864,2330.5382858760827,2175.070691562473,1.0714770305704082 -865,1017.4609245829391,952.9140622547408,1.0677362890158957 -866,1009.5846296148684,981.4916346430676,1.028622755386007 -867,867.0264287765291,760.0976743153255,1.1406776498264146 -868,344.4615419472781,303.94676691933404,1.1332956275159078 -869,528.0035101461852,512.1123441104863,1.0310306248588892 -870,3002.230293912561,2798.024958766373,1.0729819562568237 -871,2240.2652392079967,2089.7046660955066,1.0720487327971584 -872,746.2777056797352,708.4618698926857,1.0533773762486012 -873,1187.5922184963722,1090.8124251893453,1.0887226722689995 -874,780.0348236982693,718.3465109549134,1.0858754261384973 -875,710.6201377397621,672.3281254236949,1.0569543514068163 -876,1064.0308300758063,1019.058407282158,1.044131349559826 -877,129.6234663225341,124.13833885392368,1.0441856038936117 -878,92.50459834369619,91.86792584792403,1.0069303022779255 -879,380.3019734749943,357.3738832820318,1.0641571509993868 -880,53.77361476604286,51.46652471166714,1.0448270029363906 -881,205.97273495124531,197.76275107784846,1.0415143085775795 -882,815.6026680676213,754.8801431934143,1.0804399551660333 -883,154.9360681711892,143.64765662100064,1.0785840285579587 -884,821.589555834443,762.0373193667963,1.0781487139201145 -885,393.4171347238553,364.3758838677905,1.0797013527563808 -886,790.793033536332,730.2522951072807,1.0829038660127146 -887,310.0221392983548,281.2735554924065,1.1022086266006061 -888,306.8876334013616,287.65386813945895,1.0668642677614815 -889,1189.3074277288574,1098.7151140725746,1.0824529602769248 -890,179.2770284564643,173.2853299939261,1.0345770669839636 -891,177.89028708510375,164.54907725515943,1.0810773907243287 -892,384.8168679983151,355.89928133904925,1.0812521636752543 -893,337.720735937091,314.718341523113,1.0730888269894137 -894,1309.3010851540114,1228.614578852758,1.065672756688754 -895,1356.6115450573002,1283.5683041904458,1.0569063918362516 -896,1110.4888857637593,1057.486887002712,1.0501207148877973 -897,1103.087187192728,1050.511604092518,1.050047598613275 -898,1109.267047230303,1056.375243188045,1.0500691438798162 -899,1117.6014950426859,1064.1383792842896,1.0502407551491133 -900,2162.7116584476585,1934.41191031247,1.1180202349448474 -901,1603.064751253635,1493.2309483882566,1.073554464554816 -902,1762.3490907344424,1713.6408526286175,1.0284238310676999 -903,2634.470620495443,2564.703321823413,1.027202872971065 -904,2705.086284290663,2633.2933933770546,1.0272635366397733 -905,1977.8695642130895,1886.5970329592,1.0483794523469194 -906,1188.0021357287005,1136.0739360358568,1.0457084684770066 -907,765.0731733268558,729.330758982769,1.0490071396329677 -908,569.9019105990537,546.4221175538337,1.0429700634197092 -909,915.4266253169321,875.5742348135693,1.0455157186207613 -910,1339.2025397129185,1274.105076080972,1.0510926962414908 -911,1073.4575319340822,1019.560684077011,1.0528628150327932 -912,290.3003033209318,285.7480930083513,1.0159308510676481 -913,400.8401756509472,390.235195528434,1.0271758678971856 -914,384.8751888992039,374.6750290296822,1.0272240183604915 -915,386.5825110503057,376.39025453409454,1.0270789596527343 -916,400.3653599149384,389.6832601608896,1.0274122623323323 -917,5372.466911599063,5066.5032083825445,1.0603895212600083 -918,4652.7166233474645,4483.951768885668,1.0376375267086644 -919,333.99221851129255,315.4109525504805,1.0589112895749497 -920,967.0388841576321,934.6067245066978,1.034701397711484 -921,1241.6383569407972,1200.6256148575753,1.0341594761728343 -922,508.88751006220747,487.4752343319572,1.0439248483250516 -923,289.361043234239,279.3006611198102,1.0360199008269202 -924,147.2068390211058,142.84857590192294,1.0305096714592041 -925,134.95033888798235,130.75557976470222,1.0320809186944733 -926,290.9513040142932,281.0832404596849,1.0351072640918402 -927,675.3207866476325,565.2901404229998,1.1946445521627145 -928,3462.3129514978677,3250.2944158608625,1.0652305632998635 -929,1526.198244634608,1475.0155114474574,1.0346997931817843 -930,1585.7346442785022,1487.042842787409,1.0663678265692056 -931,1574.4223195952736,1486.2345855057797,1.059336349018875 -932,1581.6577287370349,1493.1690048270236,1.059262363218062 -933,866.5156135743359,819.9239398343873,1.0568243851366987 -934,845.8732832874671,798.9038424617281,1.0587923581403842 -935,851.0415069686827,804.0198534536868,1.058483199529232 -936,853.6391644351154,806.451009271418,1.0585133562004332 -937,347.57065893756777,309.37627185459445,1.123456097179051 -938,853.7150065072105,806.2512764819637,1.058869649462575 -939,352.6594887444566,314.2979154457979,1.1220548130083743 -940,840.5852265371245,793.3483344616103,1.0595411750723225 -941,946.5201321255753,891.2018093886519,1.0620716005669588 -942,1534.5517298964348,1445.4890716862767,1.0616142037699805 -943,1851.5260409445566,1775.7390993892232,1.0426790971609516 -944,1290.9885101237278,1243.7287963703761,1.0379984076040303 -945,2692.1947664383783,2528.9065930487814,1.0645686850745804 -946,4752.475607358436,4459.375180822753,1.0657267923533642 -947,3915.160436618252,3756.2165363950307,1.042314892840487 -948,998.7757310889679,958.4984515036257,1.0420212255138837 -949,349.6427571198203,311.72108375562794,1.1216525777060395 -950,1115.3858700424387,1074.5315041100582,1.03802063110864 -951,508.66216194961754,470.0756370667252,1.0820857790539251 -952,1693.6898344731237,1593.7744361750513,1.062691053407697 -953,1807.1422299152032,1701.0749533469077,1.062353088180862 -954,4364.67521461628,4204.666175992597,1.038055111137547 -955,5455.430030959194,5201.985580491248,1.0487207137633034 -956,5435.027248818627,5182.523946139762,1.0487220715819257 -957,3751.2401127122257,3571.5277965762584,1.0503180505295922 -958,2240.171127195193,2125.571452237297,1.0539147601165197 -959,2228.276690742236,2114.378149944001,1.053868576347732 -960,789.7143951278535,769.6385335007258,1.0260847927348598 -961,685.061809638414,672.4226020369232,1.0187965240359318 -962,570.0539068320276,561.8865534257118,1.0145355914935517 -963,1153.3156531740347,1101.6409401418734,1.0469070376283458 -964,2173.272157874146,2072.596130560671,1.0485748409103903 -965,1948.7676601897876,1843.143566286418,1.0573064930130114 -966,1170.5217830439692,1114.3943534451662,1.0503658596485923 -967,1440.4950039010757,1398.088666865799,1.0303316506601417 -968,1440.0118666503718,1397.444787293297,1.030460652001517 -969,1710.056895309291,1612.120165580435,1.0607502665247006 -970,2252.283271937038,2148.7471460012557,1.048184415801766 -971,1730.1569907811454,1627.6595763350247,1.0629722676266942 -972,1546.304094054608,1453.6618334867505,1.0637302696086104 -973,1936.2059932316524,1801.9055046647268,1.0745324814310473 -974,1598.896415008401,1515.6097129185275,1.0549526051330806 -975,2648.7806996504964,2493.1013358192413,1.0624440577663476 -976,2728.476429329482,2570.292570226524,1.061543133624285 -977,1974.2328035909898,1861.06374388509,1.0608088036090866 -978,1547.3113848461521,1454.6166352435328,1.0637245218820837 -979,3880.5818772221637,3607.9825825238,1.0755544929786438 -980,1628.0473899483518,1531.5595766837664,1.0629997126677286 -981,1626.807386800545,1548.5947227164577,1.0505055731733937 -982,178.09745049703622,168.5618793551627,1.0565701520317172 -983,689.7900275165799,650.2829431986609,1.0607536838096792 -984,567.3564274015697,534.1718625594198,1.06212338606371 -985,577.3120241169956,546.1681886677574,1.057022426599407 -986,778.9386613236262,733.1538728834331,1.0624490848832666 -987,708.2361019641745,667.241080186441,1.0614395950655178 -988,770.5728447597465,725.3490333400844,1.0623476551852777 -989,778.0235448184392,732.2925454860007,1.0624490848832664 -990,548.4243771610059,518.2895016942255,1.0581429401295475 -991,557.2328204721616,526.525537606912,1.0583205954355337 -992,240.8672280266206,227.89408220684862,1.056926207535292 -993,498.78347953073234,471.4090761326099,1.058069317677757 -994,628.2197750863105,594.8678186242731,1.0560661636381157 -995,1052.1371535054259,1014.2502547768225,1.0373545863559483 -996,1078.7954034957697,1032.8337475993142,1.044500536512568 -997,177.6381081556009,172.19738636950655,1.0315958441693156 -998,395.4295543328034,385.2459892284555,1.0264339289417206 -999,393.88985877159985,383.74756072402454,1.0264296091640026 -1000,290.639329569865,282.7373007750419,1.0279483066902104 -1001,1583.886469862182,1543.0457331675282,1.0264676126033003 -1002,1057.617583505029,994.7316889710191,1.0632189516341446 -1003,1382.267396770656,1299.6270263488536,1.0635877592157887 -1004,1320.511623526912,1238.2130311536373,1.0664656164186848 -1005,803.0510384389929,750.7870198842986,1.0696123097103472 -1006,671.7958431793846,624.3336901302893,1.0760204900030155 -1007,477.45235028784634,434.51189086062885,1.0988245899143663 -1008,1370.6815115708596,1315.729982060755,1.0417650507773921 -1009,488.6344166239234,470.3657868197493,1.038839197739471 -1010,591.0493054528018,574.7191780309284,1.0284140986521848 -1011,793.224958746583,728.4703691301804,1.08889117850287 -1012,288.49225318509764,265.3158071243766,1.087354184855847 -1013,1555.1664210318197,1488.9708362583451,1.0444572742202383 -1014,312.8677728397632,303.19731695531965,1.0318949256594794 -1015,292.71852831004134,280.3310952442729,1.0441885801322697 -1016,671.3178438456439,599.295897202235,1.120177606720883 -1017,156.44897654694375,150.1417713537833,1.0420083307682484 -1018,822.6511911251345,749.1965005001083,1.0980446259105499 -1019,814.4536186125176,741.4920739834511,1.0983982798859897 -1020,815.870479498712,742.8156670173238,1.0983485078804678 -1021,823.280068412352,749.5667537555238,1.0983412274990925 -1022,490.51054198624536,450.00218831361474,1.0900181259660888 -1023,3407.288024093223,3201.790570877312,1.064182040850849 -1024,401.1694396336901,376.85390628631103,1.0645224394434314 -1025,190.03833502801,183.59856844032706,1.0350752549019793 -1026,1142.192075899366,1072.3210645968313,1.0651586671281186 -1027,682.7093769166705,586.9428838822454,1.1631615199097263 -1028,2137.819100853374,2021.4595086050374,1.057562168202238 -1029,1547.235738886203,1483.8433931008415,1.042721722575378 -1030,863.0872758216248,826.919946947185,1.0437374004677984 -1031,1609.3032178921287,1543.3821612811025,1.0427120762859587 -1032,1139.947532587803,1092.7411431171302,1.0431999744569083 -1033,3428.0385335235383,3268.1554560950435,1.0489215031464663 -1034,527.2426382864779,494.4612019975799,1.0662972871409604 -1035,1265.9809140173088,1171.804701000793,1.0803685229595712 -1036,611.1146210705332,574.1118887372761,1.064452126944527 -1037,3060.228447810476,2850.5719343369137,1.0735489292335054 -1038,914.0868504104604,851.5144256926523,1.0734836930882405 -1039,1096.0039538380734,1028.9832611635181,1.065132928011649 -1040,907.7747186394627,845.5840545047508,1.0735475838308424 -1041,955.0777143224441,896.354066366655,1.0655138969735738 -1042,649.1404436923259,608.274815248773,1.0671828381170763 -1043,109.53862878286766,102.0078520877748,1.0738254608930777 -1044,651.1725771274071,610.2834062336851,1.0670002993298904 -1045,590.6299889709612,553.3550993944451,1.067361608517401 -1046,177.8679967614671,172.95042676510033,1.0284334077015362 -1047,42.093833290545945,38.766922834657954,1.0858182752878622 -1048,88.95264422514772,82.66034986815963,1.0761222807189188 -1049,376.6616647133569,370.2983870469842,1.0171841895319014 -1050,401.63686472149925,395.0746202291043,1.0166101393417515 -1051,720.7901878338309,711.8737766537606,1.012525269889815 -1052,667.638544471394,648.7807097572934,1.0290665773974002 -1053,680.5753402084617,661.5980227204499,1.0286840601638716 -1054,1297.3173141147759,1212.4055386102657,1.070035786542052 -1055,1012.0100825253018,927.4078326495085,1.0912244288837776 -1056,1014.503780646932,929.6930620263664,1.0912244288837776 -1057,1013.7539471368718,929.2648642868895,1.0909203458529755 -1058,453.36356105578227,418.5915563199621,1.0830690543342953 -1059,178.21835748085215,168.0035651985771,1.0608010447290293 -1060,178.3424321705692,168.09969333547124,1.0609325254071513 -1061,7796.741629311352,7506.17654816758,1.0387101314869425 -1062,534.8961630285337,492.8741515919921,1.0852591098575768 -1063,247.1104362129474,236.05420428283952,1.0468376827419703 -1064,462.5942563305032,452.17322538944114,1.0230465457836138 -1065,317.11959770740594,299.96775904198415,1.0571789405641463 -1066,574.3832393992597,544.4066003754665,1.0550629603004793 -1067,586.3214316358137,556.0926895223633,1.0543591791134934 -1068,443.91775234586737,428.94982888493894,1.0348943453359982 -1069,390.8811094960442,377.64331002330084,1.0350537110585292 -1070,702.7800958390644,684.162005921899,1.027212984287366 -1071,187.7885717197514,177.6678768385621,1.0569641235167426 -1072,534.8683283668978,525.5782944208228,1.0176758325918167 -1073,886.8802696588319,812.4245489823857,1.0916463205964257 -1074,960.0207082350403,909.6902764192643,1.0553269976830877 -1075,988.7313693570029,911.0814565117629,1.0852282880858277 -1076,953.5231662180772,854.4446080238087,1.1159566778979637 -1077,957.1350099610722,911.8605327473292,1.0496506599285926 -1078,914.124104079998,873.6681058836888,1.046305911734513 -1079,1256.4729141505675,1228.1338730944317,1.023074879438617 -1080,1235.5897316930534,1193.7394043740242,1.0350581769904588 -1081,861.7832662191353,794.3869724516417,1.0848406332237484 -1082,961.882279115143,887.4439711748402,1.083879445191067 -1083,338.18009483580397,327.23902027037593,1.0334345047127576 -1084,330.79923342557356,321.00871295272304,1.0304992359328653 -1085,243.93289373604094,226.12725657610872,1.0787416671016803 -1086,307.026956365228,293.2884786077017,1.0468428825528557 -1087,332.83734181151027,321.8124776767301,1.0342586596218153 -1088,418.4581459703609,394.69195556026716,1.0602145295217824 -1089,947.3413502780219,899.2139285552253,1.053521659523361 -1090,451.5744735515773,420.26424218874484,1.074501297564047 -1091,2612.9345981744696,2477.577990017094,1.054632632636699 -1092,778.2492551446779,760.709725096269,1.0230567974481846 -1093,802.0974655138878,779.049227495413,1.0295850855183737 -1094,3626.5084332044107,3390.4014750562305,1.0696398228602895 -1095,2220.6498857541887,2134.9523201477605,1.04014027142325 -1096,505.2204408842573,457.53499000126646,1.1042225227033649 -1097,462.3936214615769,423.9881716345536,1.0905814180592894 -1098,1116.828350111589,1070.1256535559,1.0436422549076378 -1099,357.44876773582183,342.01894923867843,1.0451139287208782 -1100,397.09813665995847,387.368638549773,1.025116896779798 -1101,348.85895323329635,339.89411939823503,1.0263753719862323 -1102,362.6969906009746,353.81037200763683,1.025116896779798 -1103,396.9922970289312,386.98508468449063,1.025859426475311 -1104,672.5010799647566,637.4560771117636,1.0549763412904896 -1105,417.5393412968697,389.96034631150724,1.0707225625534034 -1106,1142.6846683762587,1067.0754989134607,1.0708564384992312 -1107,513.0261041450707,479.3514555235031,1.070250435736742 -1108,1471.874953032884,1375.0348151783319,1.0704274079358438 -1109,588.6802963312361,560.5578813610532,1.0501686193438238 -1110,313.50055834851935,294.5449313063186,1.064355638231939 -1111,257.4913534354425,232.68560628558507,1.1066062810924895 -1112,1076.208453987698,1038.0613539009103,1.0367484060007008 -1113,746.7884000943706,646.4679066139631,1.1551824807605084 -1114,676.2576102828375,630.1531572018889,1.0731638849286564 -1115,424.0980307374465,415.45417932212666,1.0208057876067669 -1116,757.7090648007149,704.9218659926394,1.0748837585478257 -1117,824.2471057812992,781.492490326129,1.0547089268091725 -1118,998.8238909538538,934.3368946293783,1.0690189980671323 -1119,784.7938637080404,731.220664679691,1.0732654335635015 -1120,997.5305925979886,933.1141800053026,1.0690337945484014 -1121,919.8441146566068,858.9013839188154,1.0709542816891675 -1122,658.6999830898412,619.6255174990652,1.063061420950655 -1123,655.2184111741246,616.4299229933386,1.062924408329226 -1124,995.8772753164255,931.5805463470427,1.0690189691288705 -1125,991.099088143752,927.1446113819012,1.0689800447273563 -1126,927.0849753658134,875.5789016417762,1.0588251654162286 -1127,696.6203333617494,659.453186334454,1.0563605541644094 -1128,927.0302710201177,875.4876369395581,1.0588730576033456 -1129,632.9982243804005,599.7672008322023,1.0554065369064676 -1130,205.26429158281232,188.1126978827148,1.0911772245741287 -1131,205.04249958365185,187.86667486077357,1.091425606673494 -1132,307.8347303184395,271.5203837409775,1.133744458066562 -1133,304.2748102533792,280.6609486395213,1.0841366129784853 -1134,655.9758668213062,617.407221228421,1.0624687309554743 -1135,999.1000658468971,933.7335459703468,1.0700055386878284 -1136,263.30612935377883,241.59027220786302,1.0898871338959857 -1137,207.54332688785968,190.26345756791451,1.0908207468781919 -1138,221.46528924580636,221.16030872355145,1.0013790020642273 -1139,599.3289688721226,550.9042382634034,1.087900450287634 -1140,508.5142045169269,494.3564297394256,1.0286387997117057 -1141,596.8297479045497,578.6393109610243,1.031436573006618 -1142,594.0364896050878,547.0211020543858,1.0859480326702784 -1143,593.7599202731416,576.0393321690019,1.0307628092641088 -1144,770.5041572822036,718.4982434661665,1.0723814070374773 -1145,780.2669561410123,726.9575359152608,1.0733322341292375 -1146,1112.1479073294954,1029.704317483756,1.0800653046179345 -1147,1209.7052952446052,1119.8084804079697,1.0802787408824446 -1148,1130.9188318625543,1046.9091214908156,1.0802454660554561 -1149,1189.603126313294,1101.186374116013,1.0802922686618406 -1150,3863.9531371357753,3626.321790275186,1.065529580827011 -1151,391.408843069889,368.05258395560656,1.0634590276836626 -1152,871.5437976603051,840.0870528901637,1.0374446251277416 -1153,434.0418977871499,411.89217165493744,1.053775545291908 -1154,506.8130923271383,483.91222214678083,1.0473244302009201 -1155,767.7185948119463,717.9034167416127,1.069389804963504 -1156,629.2518990363384,586.0168159021257,1.0737778882123985 -1157,652.9625761562293,613.6487015562238,1.0640657667820443 -1158,638.9051312749463,590.5959131738277,1.0817974134658461 -1159,3800.9185604086792,3557.59300487167,1.0683961192873401 -1160,774.5072235572038,743.9283300699669,1.0411046229202763 -1161,764.9039317953949,740.159939308449,1.0334306021885822 -1162,394.03473607685174,377.82256919490516,1.0429094718097247 -1163,537.917499768294,503.69963509036893,1.0679330741857416 -1164,305.41137484605883,300.3927092672121,1.0167070152637505 -1165,330.2505966360929,322.0579390699152,1.025438458650756 -1166,540.0661019989199,505.75842421234785,1.0678341202917216 -1167,787.5723231952763,749.2939019276406,1.051085990649544 -1168,789.7367840990474,751.353163418162,1.0510859906495438 -1169,788.2746714558754,749.3900900918326,1.0518883047402958 -1170,786.6904597674995,748.0841529539458,1.0516069036633242 -1171,2072.163826992017,1987.2338681515107,1.0427377774713082 -1172,1438.916366619473,1377.8643408789626,1.0443091703074079 -1173,2269.1020049277945,2153.2874126170736,1.0537850133856315 -1174,2645.245021453263,2456.5159170172415,1.076827959114216 -1175,2937.8174451216455,2808.631361296627,1.0459960981726626 -1176,3194.1518295682386,2981.200775026513,1.0714313025562097 -1177,540.2452628005789,532.7187329731707,1.0141285247946916 -1178,375.67984117533155,357.6220600369494,1.0504940359006836 -1179,59.65115821351867,57.06029330050038,1.0454057412459106 -1180,369.08128778780093,341.2191141562812,1.0816547856658423 -1181,454.7878533693068,418.01429558501826,1.0879720099831114 -1182,1044.0143143240105,996.0355859618221,1.0481696929692101 -1183,2440.315214762457,2318.7803100372794,1.0524132899520884 -1184,448.6845265575367,430.0082606969068,1.0434323420446892 -1185,1317.3953948661838,1224.821664179164,1.0755813955569278 -1186,1375.9904430351878,1278.4187448788225,1.0763221742071796 -1187,204.1552212657298,193.4730502020101,1.0552127081914828 -1188,693.3628999576034,647.7454915678089,1.0704248952460969 -1189,312.1436297185025,305.067483932651,1.023195345812121 -1190,489.15859104220834,459.5392990188587,1.0644543178060908 -1191,2087.851604653095,1982.4951410375188,1.0531433653655458 -1192,2566.359406211248,2436.881323470448,1.0531326993619885 -1193,638.6625832581725,606.3406282646635,1.0533065961388963 -1194,694.2410559723787,659.3092786793551,1.0529823838714882 -1195,697.7524098403604,662.6132134299713,1.0530312340565826 -1196,642.2033333160222,609.7099833857428,1.053293124297953 -1197,1258.8816844399764,1198.604545566443,1.050289429567487 -1198,247.57086516598676,236.43630876951377,1.0470932592985425 -1199,336.99255411947763,321.93180975628997,1.0467824051763912 -1200,567.0408040851783,538.7254314426834,1.0525599331122488 -1201,541.1475681862896,514.2095967577536,1.0523871425161802 -1202,477.36207078731013,444.6675977221694,1.0735256475457617 -1203,254.1898965777284,244.10123051954508,1.0413298451495332 -1204,474.6838641632096,442.13112792074,1.0736268816800096 -1205,257.61743567650666,247.25041357958403,1.0419292406707572 -1206,459.34388849492274,430.04845845298416,1.0681212302151324 -1207,398.7121682457978,373.4901142704791,1.0675307136966228 -1208,270.073492899828,259.1387880418455,1.0421963263030187 -1209,1058.1673913659245,1011.2596901398535,1.0463854158169636 -1210,177.30250396283145,167.17477420871052,1.0605816864539437 -1211,240.35675728837575,225.91670606717963,1.0639175892415063 -1212,179.2134367760287,168.91348985955202,1.0609776455689883 -1213,177.23576188460333,167.11184451731518,1.0605816864539437 -1214,412.87623590168425,379.0332301781381,1.0892877009956108 -1215,204.90558894555232,199.41313501577415,1.0275430900243543 -1216,397.3959002746149,370.2212469839362,1.0734011176075418 -1217,2087.4572440331344,1902.42644228748,1.097260423653055 -1218,2097.326124373133,1945.361242929898,1.0781165359367197 -1219,424.56702102951647,405.6652038385892,1.0465946228862364 -1220,423.6912380920814,404.871283414397,1.0464837973169405 -1221,1011.1783047163008,966.7952840427711,1.0459073615749725 -1222,1000.1164392174103,956.2303015311314,1.0458949456171882 -1223,4089.30418502754,3903.545058467319,1.0475872889329878 -1224,1578.7944381367597,1486.2462104272424,1.062269782126417 -1225,304.82725223134304,285.25960588427375,1.0685959243560326 -1226,314.19801354265917,310.3956002124769,1.0122502165867666 -1227,314.49429675482736,310.7150987972996,1.0121629041271443 -1228,305.7448432248403,288.41360658805206,1.0600916053920537 -1229,1692.2092736634636,1634.1527586229456,1.0355269816326356 -1230,633.8505146608135,614.6597453870619,1.0312217766297138 -1231,720.8305569255673,691.1420766800527,1.0429556834220326 -1232,609.9428650948565,594.194318591659,1.0265040341357088 -1233,730.3874478942678,700.8645534200793,1.0421235377508002 -1234,701.4509986850434,672.4309025464611,1.0431569935716587 -1235,583.3421749464387,556.2938555750746,1.0486223586694168 -1236,738.5090954437225,708.5928171519447,1.0422192796308896 -1237,754.9902974263465,724.0921569129405,1.0426715580584875 -1238,604.6955961760233,575.2118627161672,1.0512571721324262 -1239,830.2386505849078,791.7588024200394,1.0486004677778804 -1240,642.3477476942755,618.86694582385,1.0379415996101835 -1241,425.44961432185374,396.29123144751384,1.0735781681765566 -1242,193.13900842156207,183.93541754661635,1.050037078218572 -1243,505.6241266493386,472.88272077680176,1.0692378986035962 -1244,327.21952128251667,298.02548781637927,1.097958176933258 -1245,429.57311826365867,397.5434890902145,1.0805688686959622 -1246,516.4968399794366,483.03015070694374,1.0692848867167242 -1247,516.5037848087416,482.89589288396655,1.069596557808891 -1248,531.8630240071277,497.2929496144745,1.0695165182202033 -1249,529.2375098505808,494.9004365026788,1.069381780284035 -1250,1903.9665615254755,1813.8956351611296,1.0496560687497023 -1251,1548.8318651908673,1389.8252908967524,1.114407598807991 -1252,258.2237944268267,251.86658572666448,1.0252403814575917 -1253,273.11511174540004,268.31496203896364,1.0178899814977123 -1254,556.7138385658676,540.4883491255745,1.0300200540243716 -1255,273.61695085200967,268.7914858193645,1.0179524474814952 -1256,329.9476460313539,319.93803146860085,1.0312861041146195 -1257,600.4191272152922,574.8439754834365,1.044490597140463 -1258,377.7743567948937,366.21803136592007,1.03155586136999 -1259,81.79886171047572,75.69353224768439,1.0806585355643528 -1260,259.9151479116874,250.85065351997147,1.0361350240253382 -1261,318.45009784556186,305.01471395232966,1.0440483139948848 -1262,471.65441453123174,447.1284422062531,1.0548521856582436 -1263,755.2843106071577,710.0080377469334,1.0637686764841416 -1264,337.64913697053737,321.3653951943714,1.0506704891679985 -1265,1181.3817568762115,1018.9742185278211,1.1593833635781592 -1266,294.66436288677386,282.80067565995415,1.0419507032617026 -1267,291.66435977375374,280.27185800136215,1.0406480402764384 -1268,1450.7991745687104,1375.172790471282,1.054994095739424 -1269,1691.0315283102323,1587.7541153964949,1.0650462259314926 -1270,821.8548365824863,794.2615876428916,1.0347407571622371 -1271,291.64570369216926,241.9985332629442,1.20515484023732 -1272,741.7633273334635,682.8106410501724,1.086338265309722 -1273,244.74123118060237,236.07260976416583,1.0367201490469242 -1274,2208.670680813155,2114.8903609295676,1.044342875458739 -1275,525.8168519313731,482.74398728365964,1.0892250670797148 -1276,5153.015701882737,4864.226254528666,1.0593700687925862 -1277,3307.6616220221463,3121.074956667983,1.059782820965428 -1278,647.8482272296172,609.2022994945853,1.0634369367402157 -1279,512.1351527848213,469.93427779987417,1.089801653079069 -1280,511.8775274096739,469.5611924579012,1.090118893195303 -1281,369.3429120325745,347.47240261430113,1.0629417163887687 -1282,396.7337879580644,371.3004907003919,1.0684978821592643 -1283,1269.2252826395384,1212.1001291225862,1.0471290713897572 -1284,1319.5449371801724,1200.3412817066483,1.0993081361861021 -1285,146.97242487434144,145.2858540780305,1.011608637379143 -1286,290.9258522947192,241.41326917931949,1.2050947045442737 -1287,745.1281410924577,685.9435175538687,1.0862820655403906 -1288,668.6764897912146,633.4993001632214,1.0555283796192512 -1289,1199.5999338143602,1128.1154950895418,1.0633662413431741 -1290,1181.9964190435392,1113.6847711543728,1.0613384053176547 -1291,1248.9893737435411,1168.2516262857234,1.0691098951982725 -1292,1250.5741885579816,1169.6745758418929,1.0691642054866928 -1293,3524.132878452886,3277.161557139707,1.0753613506710162 -1294,2055.081185719063,1885.05756336552,1.0901954537929273 -1295,2084.967721729846,1968.9087707876276,1.0589458245420842 -1296,2244.3120781330476,2119.267616942447,1.0590036200199233 -1297,1166.6961843073468,1117.5168947927853,1.044007647440248 -1298,2337.9552004733905,2204.879171007041,1.0603552481316105 -1299,1791.936462421403,1620.9592170946034,1.105479054330101 -1300,125.71939377925835,117.88592972780557,1.0664495251429917 -1301,131.29810685353343,123.17103956218605,1.0659819655678413 -1302,481.63614752679723,429.31812041976445,1.1218630768621622 -1303,476.4924632480145,424.41036393465765,1.1227163701435325 -1304,206.42345895961842,191.63824393129207,1.0771516933416865 -1305,226.50858834712673,210.42249289410057,1.0764466537383046 -1306,84.55810832086055,78.41469274043963,1.0783452101349964 -1307,479.97302383420276,441.0992402667657,1.0881293369354414 -1308,151.3579195258174,139.46303225428682,1.0852906112771328 -1309,477.2940807946,438.8608425889092,1.0875749998085205 -1310,1108.8120529150092,1087.224980732505,1.0198552025248355 -1311,1093.3186376991937,1049.4039247148103,1.041847292496374 -1312,757.6616208679997,721.2842482374976,1.0504341703279843 -1313,358.72618346124915,341.59728884050617,1.0501435321073072 -1314,564.8590500032432,515.1309314795068,1.096534910805904 -1315,332.3872864807063,312.7122409844764,1.0629174138955646 -1316,382.7024438857436,359.71338015146745,1.0639093928743935 -1317,1187.4228861061927,1143.318126377943,1.0385761046822328 -1318,1364.4490326485397,1281.0340965248488,1.0651153129725246 -1319,3584.659159387492,3365.687626662009,1.0650599690211455 -1320,1261.1076346390173,1188.3334535449371,1.061240538905125 -1321,514.902144385691,478.91735252185157,1.0751377908408477 -1322,682.9075621572274,661.6217785714288,1.0321721325917639 -1323,459.314216093525,418.20128783578684,1.0983089470395935 -1324,582.2871096291918,512.7864021447231,1.1355353948423415 -1325,652.5761874804479,611.5972302730319,1.0670031765662542 -1326,916.1851024273113,854.0819357173342,1.0727133593544715 -1327,837.5358966005227,780.5041355735472,1.0730704149121084 -1328,365.4903516707114,352.74036777835664,1.0361455196428386 -1329,727.1122812487044,685.4775841930561,1.0607382327529509 -1330,574.6812232153601,529.0260861621591,1.0863003512443177 -1331,772.107005066734,626.9436123266702,1.2315413856779613 -1332,912.139579092282,819.4562685806251,1.1131034248748783 -1333,2086.3195515376115,1930.7515138022757,1.08057382662825 -1334,513.3169479636442,457.0960917967654,1.1229957052266284 -1335,664.84412543911,615.0912301003241,1.0808870178992327 -1336,477.3735790965437,441.4804640099597,1.0813017064460055 -1337,762.1243160629477,637.908038960963,1.1947244265871153 -1338,718.5663457558016,695.503799125301,1.0331594833263387 -1339,754.2887508696031,715.9721463842895,1.053516892631669 -1340,546.2529858425678,510.951768725719,1.0690891377181995 -1341,338.33354093896486,290.8791406992758,1.163141296847922 -1342,598.4518370383796,566.5550516018949,1.0562995340811079 -1343,694.8722777624291,661.9847473745409,1.0496801935668783 -1344,496.45750090430374,458.0286276700809,1.0839005924797855 -1345,495.420445968472,445.04500792182586,1.1131917831903753 -1346,1026.720571943594,954.5788239228157,1.0755744273943915 -1347,632.0911148836009,597.7171833956218,1.057508688796098 -1348,749.4137050824082,704.8960269757956,1.0631549567637741 -1349,437.8545274115063,395.08796819767525,1.108245663387131 -1350,846.5191806032105,778.829898082663,1.0869115100578268 -1351,1191.9655506976035,1126.192734709744,1.0584028061633797 -1352,320.8642510427492,290.49424990095565,1.104545963137474 -1353,742.457642117216,691.0265414060516,1.0744270988586286 -1354,591.8261703637875,528.9665043639797,1.118834870414695 -1355,345.9156374917375,315.1838177642803,1.097504433906061 -1356,592.1468094567987,529.2010138898562,1.118944964039777 -1357,340.18015368925774,320.12901590731985,1.0626345529008308 -1358,744.4024279567838,700.1824364556717,1.0631549567637744 -1359,656.2268678523561,577.044425618217,1.1372207038466873 -1360,359.02974923805925,349.6648437379072,1.026782519512232 -1361,424.11674919728324,403.81416773540303,1.0502770409858015 -1362,819.2772403321566,779.0062027206421,1.051695400461344 -1363,1656.3027573156978,1600.077466884976,1.0351391051960634 -1364,2143.906613266991,2047.4715532029386,1.0470995848089784 -1365,1075.4311744947395,1025.6933566587168,1.0484918982004992 -1366,331.4157296535978,319.2924919125707,1.0379690661324623 -1367,1641.3079324043827,1569.9522780744737,1.0454508428864002 -1368,1313.489680212454,1260.5051754536921,1.0420343413026378 -1369,208.92404475804872,191.21489074576877,1.0926138855776943 -1370,275.9983752722659,249.5878250278941,1.1058166608944973 -1371,275.9260918394003,249.50869179089364,1.1058776744765524 -1372,288.0283300085285,260.506531915875,1.1056472476534334 -1373,710.8806027318276,656.0195772757384,1.083627116257584 -1374,450.19234861701665,400.85010345539513,1.1230940063038106 -1375,2097.326659952877,1923.7723125856319,1.0902156384265562 -1376,743.1738280314609,700.7519364333469,1.060537673023111 -1377,336.4983061795237,324.0864852570349,1.0382978664248985 -1378,868.6535628759773,813.7767307904012,1.0674347520753948 -1379,444.27156496717294,417.4066285552028,1.0643615471679486 -1380,1777.6957015467178,1699.2674740031973,1.0461541392060876 -1381,1715.3822206813584,1639.703133979032,1.0461541392060876 -1382,1637.8032197112016,1545.0509740299046,1.0600318353506322 -1383,802.6557040166232,778.6046762096606,1.030889909272117 -1384,1349.9599226709595,1264.7850782281837,1.0673433343806489 -1385,2176.0554090336254,2028.7347532617164,1.072617011925809 -1386,1740.9932289896356,1664.1842380042124,1.0461541392060876 -1387,1739.4564570244365,1667.7979612317113,1.0429659331996086 -1388,541.9683448420683,528.7360302820993,1.0250263152161374 -1389,388.23118502835865,355.8771265299373,1.0909135656283873 -1390,549.963908244571,537.5001838490265,1.0231883165253863 -1391,551.2355867526816,538.7879776511612,1.023102982282169 -1392,874.2970968746489,846.1542168417698,1.0332597527409615 -1393,215.23962908542242,208.41405615427246,1.032750060418658 -1394,428.10112675495463,402.24061945588227,1.0642911383093392 -1395,386.5867075128841,370.08560810447847,1.0445872496715605 -1396,372.69311804215795,356.9409621917828,1.044130983884981 -1397,1678.4661676193778,1605.017223323838,1.0457620910406396 -1398,1674.5564253696436,1601.0729948175958,1.0458963649939144 -1399,1616.402091999227,1549.5204488622708,1.0431628012305767 -1400,1881.9221282394392,1803.6875201497137,1.0433748125524713 -1401,1477.7891156694225,1415.2236479406874,1.044208890813671 -1402,1620.2473677450996,1549.8663404313677,1.045411030279 -1403,1707.336670750729,1631.980827691749,1.0461744658885253 -1404,639.588949028411,610.0421061704158,1.0484341040710743 -1405,376.9379298716734,362.58256799519734,1.0395919802649372 -1406,1848.166477341775,1763.846187511017,1.0478047861700137 -1407,387.61707006711816,376.6108531403109,1.0292243753334076 -1408,865.8740373784634,831.1219981690209,1.0418134031899071 -1409,1135.480896008992,1083.9961277988507,1.047495343285668 -1410,356.23448226446993,337.80127438029876,1.054568201135378 -1411,481.98036357865317,476.43805323075367,1.0116328036988582 -1412,514.1121480564009,488.85932508849805,1.0516566252742163 -1413,401.332205249738,384.8371228874848,1.0428625030726983 -1414,403.67535994594857,387.0508326948595,1.042951793012148 -1415,512.894099085148,487.6902356923779,1.0516800656404122 -1416,1430.8203994529126,1388.1714804467672,1.0307230912080252 -1417,1382.8859309000632,1335.7017889415658,1.0353253565647216 -1418,342.7160081587714,328.07360912447234,1.044631444368156 -1419,342.2152455367241,327.57948987915984,1.0446784860156026 -1420,1179.3369217305299,1115.234083213286,1.057479267789724 -1421,342.8116641119158,328.18052447332917,1.0445825956981054 -1422,744.8965787187218,696.6622395453519,1.0692363335277768 -1423,722.5299843485676,675.7415681447853,1.0692401036275414 -1424,719.4264540395781,672.7958094678687,1.0693087619088928 -1425,719.7734891805623,673.163573587105,1.0692401036275414 -1426,745.6408864865784,697.3615801751567,1.0692313825193744 -1427,728.7258696955629,681.5362304717734,1.0692401036275414 -1428,727.1548238156117,680.0835054745352,1.069214027339528 -1429,739.7329351541914,691.8641189615485,1.0691881756557797 -1430,703.6997749355619,663.8994235009602,1.0599493688738595 -1431,736.8520702385698,689.1362077972008,1.0692401036275414 -1432,733.1958105699883,685.7167272570168,1.069240083296343 -1433,736.5759618981822,688.9116582218794,1.0691878314257697 -1434,662.1571341420429,632.2874680284189,1.0472406423090477 -1435,693.4999137765298,654.9874155065727,1.0587988369824957 -1436,693.3655796379613,654.9852520945623,1.0585972392823555 -1437,662.7919984477471,632.8973126011653,1.0472346544239803 -1438,796.4682047192483,760.613266527518,1.0471395119827733 -1439,479.34191111875083,450.21481666884137,1.0646959926050903 -1440,1111.8608831736037,1101.5184274025357,1.0093892716760593 -1441,984.4599670946486,912.2783104462957,1.0791224079557926 -1442,507.03265820092037,481.1348217484353,1.053826568524749 -1443,1036.4423028771425,983.573838543858,1.0537513933997618 -1444,2239.613410052841,2086.4963469996383,1.0733847740847395 -1445,1175.4106954222816,1128.7079237526193,1.0413771983759885 -1446,460.07984625635106,430.6096527622412,1.0684383020795443 -1447,565.413603179445,544.9312274833067,1.037587083769696 -1448,838.7960891693677,790.3093914211574,1.0613515393775343 -1449,350.88558617263703,314.93276491806716,1.114160307403783 -1450,745.998277913402,710.7578482190049,1.0495814851467367 -1451,732.5284572073256,698.0073275417146,1.0494566866327744 -1452,751.7967503244171,716.2835843146574,1.0495797569390604 -1453,739.8527622943014,704.9392354362815,1.049527001907352 -1454,181.67601779623106,174.62287624786737,1.0403907076776824 -1455,175.55055714785212,168.80504488349783,1.0399603712614736 -1456,175.9971120397586,169.2254812114212,1.0400154325451574 -1457,181.2259192624169,174.1930294165049,1.040374117549193 -1458,3007.951695450548,2865.8431572619133,1.0495869907704258 -1459,334.92067145686997,319.8906114347421,1.0469849988867024 -1460,1235.305801798828,1184.5308024121452,1.042865073059549 -1461,1063.0464402733148,1015.3568685732318,1.0469682859063099 -1462,400.99970540098536,394.69893816594396,1.0159634765280072 -1463,1161.2466598429542,1108.3223360618715,1.0477517433864367 -1464,1245.6836382518757,1196.0201602487025,1.0415239472157778 -1465,340.9711904134811,325.6240277053992,1.047131542522307 -1466,1085.4044788805606,1054.2927530965487,1.0295095699867367 -1467,850.7189484599429,823.6847927734586,1.032820996482716 -1468,1426.8547385260847,1381.7372957522236,1.0326526923117458 -1469,1673.0505500891927,1615.5348918641519,1.035601619324157 -1470,1176.0953417159308,1142.8472613851382,1.0290923218300367 -1471,966.3862574843461,924.0042245133076,1.0458677913440948 -1472,1063.4388661655819,975.7114281016329,1.089911254021728 -1473,1547.9509661249906,1428.8377387003081,1.083363718775394 -1474,3112.389303220831,2967.8412380061995,1.0487047835859775 -1475,191.06928302924803,187.9819856501421,1.016423368273446 -1476,340.2048075702032,329.9490006449496,1.0310830064804155 -1477,3146.95216381003,3000.882792837822,1.0486754668728917 -1478,178.93395087513247,173.18211490552352,1.0332126442314598 -1479,887.8267962297599,859.0243532437337,1.0335292508032703 -1480,536.3655760224459,505.236977208639,1.0616118776297567 -1481,182.83823626785716,176.7694362007531,1.0343317272348589 -1482,781.4132886540291,760.4027459846661,1.0276308085160264 -1483,180.50984281993246,174.80158006855467,1.0326556702127012 -1484,182.8802213849376,177.08509570879377,1.0327250898950502 -1485,481.04879686119443,467.68218346143624,1.0285805486555601 -1486,2499.297270152121,2421.1937646454376,1.032258263112668 -1487,573.3694842301145,547.119055260199,1.0479793725287656 -1488,613.3643654684274,585.2817072258243,1.0479814385037114 -1489,482.75809334546085,459.3609518153545,1.0509341106109322 -1490,353.5108201370418,335.2663759974212,1.054417756881653 -1491,1776.1045236685738,1667.4433138647705,1.0651663591201492 -1492,1378.224518131272,1303.2729936709386,1.0575102260419107 -1493,376.1531780259984,363.5298204558475,1.0347244073521171 -1494,540.8408333412424,509.48658474374145,1.0615408718038597 -1495,1358.7879606264278,1323.0549161039096,1.0270079828793077 -1496,1982.532171615005,1887.285033651617,1.0504678075993106 -1497,287.93279316518726,268.7138483748426,1.07152197367787 -1498,2326.433006056708,2216.1821755214924,1.0497480900951983 -1499,280.51532194559945,261.54011233354146,1.0725518141089538 -1500,141.88295471352228,129.4953806547127,1.0956603548032333 -1501,427.4673557170246,404.61521826872973,1.05647868991699 -1502,605.5135877474409,577.7926813778624,1.0479772542349832 -1503,263.6459221908298,244.4437609055852,1.078554515828536 -1504,346.19599908447356,335.45431663559555,1.0320212974351042 -1505,347.0424091124282,336.3032462215555,1.031932974217554 -1506,479.8828545618755,460.5925763992808,1.041881435244567 -1507,315.32979648235226,305.89264330997156,1.0308511936418743 -1508,1589.1976706339165,1540.6906613694673,1.0314839380030596 -1509,1621.254242604141,1549.1395702680409,1.0465514365007296 -1510,718.5366625440289,662.8785137985353,1.0839643276813304 -1511,1442.1432966919845,1354.9701114570853,1.0643358731663508 -1512,2330.454392163275,2205.7100294114907,1.0565551958727175 -1513,739.9122832247234,723.5609614558173,1.0225984024013774 -1514,1294.939292952034,1243.2774269121796,1.0415529671186603 -1515,2246.0827738181783,2127.7482607637917,1.0556149029640887 -1516,488.2022841552479,452.65671689588964,1.0785265432558107 -1517,489.7375596544143,454.12278431080233,1.0784254315661845 -1518,324.904792972198,314.16659972289665,1.0341799327451509 -1519,446.0679472009931,417.05963623539157,1.0695543477365645 -1520,238.31983280864566,222.1457517812643,1.0728084192368763 -1521,236.4366089338024,220.41213329076874,1.0727023299660827 -1522,177.0601251374307,163.42351675329758,1.083443366383547 -1523,487.34395620613077,451.8610460361654,1.0785261541821984 -1524,1107.211320864657,1020.5944852081414,1.0848690022451482 -1525,813.3869717345156,790.9380379956146,1.028382670525988 -1526,1752.1103833609313,1636.5221276904197,1.070630426386986 -1527,443.3732438345996,414.1845840739153,1.0704725885101394 -1528,437.4715904985955,408.7634850257226,1.0702315801791011 -1529,438.24810818280815,409.33917004912627,1.0706234346696224 -1530,514.3074627720664,483.9755988360979,1.062672300026929 -1531,1787.0766739575047,1691.6517336286247,1.0564093296698793 -1532,1644.8060577964127,1549.5695771193837,1.0614599577090766 -1533,323.47612217028006,313.9545284081613,1.0303279389228623 -1534,347.60377086223275,315.9744530599069,1.1001008704850233 -1535,236.93492978816144,220.87743258279696,1.0726986773505947 -1536,321.08274769057545,311.3867522563738,1.0311381115732843 -1537,268.7757149397843,253.91453358765253,1.0585282817101984 -1538,289.8745552192905,280.7436808643798,1.032523882022198 -1539,290.5954756209545,281.4451346612645,1.03251198842255 -1540,222.64431805892238,195.5215382907312,1.138720163544647 -1541,297.1339862382941,286.9201045986657,1.0355983476791046 -1542,110.07473497128484,96.18410492181417,1.1444171057240908 -1543,136.47880230992456,112.5164274956325,1.2129677892165764 -1544,245.85235721253187,232.88617934820002,1.0556760298125956 -1545,146.42886379993286,127.30063530440914,1.1502602752121631 -1546,125.59410153425814,104.51325410124582,1.2017050144911816 -1547,166.4671801929255,165.55820593614183,1.0054903606356684 -1548,109.2624431637597,95.49859164209124,1.1441262251620683 -1549,995.9675449518721,983.9834252837404,1.012179188551551 -1550,306.28434072038294,304.54602023155593,1.0057079074207087 -1551,178.61051529014483,169.939850928366,1.0510219605019762 -1552,1923.8556155647439,1824.966659738321,1.0541867191374348 -1553,1252.9039958466126,1189.7156219192675,1.0531121662716412 -1554,351.9885158481799,334.30107362135544,1.0529087209778394 -1555,778.4603105029074,745.009907819925,1.0448992722537962 -1556,915.5315684470106,872.4650039481602,1.049361939222733 -1557,945.1723786527031,900.3528138668472,1.0497800019009929 -1558,1015.8173912334921,966.9256943586153,1.0505640683251343 -1559,1021.2517228585472,972.0113474856602,1.0506582309972605 -1560,2978.599522851719,2886.6279520502203,1.0318612486019114 -1561,1511.6068582221255,1441.7292085174006,1.0484679434195436 -1562,1243.705837806913,1181.185620564127,1.0529300527828358 -1563,1229.6665548342296,1170.2013085411709,1.0508162534591514 -1564,780.0403057630077,748.1126822206643,1.04267755954567 -1565,1143.432042227453,1117.1808973694963,1.0234976671367793 -1566,1294.3678615511385,1205.4342502653094,1.0737772394191183 -1567,655.8787706894561,642.4921969344904,1.0208353872916074 -1568,614.8702156292086,579.4652810990015,1.0610993198126708 -1569,1338.99933432982,1221.6228739275052,1.09608240227604 -1570,1137.1522705773666,1061.4306769136297,1.0713391795721563 -1571,1733.9853513923276,1619.4102768476448,1.0707511099458473 -1572,2749.622785757705,2542.4077886166624,1.081503446484401 -1573,1343.2113224422021,1260.0362867873748,1.0660100320339922 -1574,367.28971235752505,340.5370401328726,1.078560241829241 -1575,2580.2211443945607,2463.104179946406,1.047548522470821 -1576,799.3211916037303,766.3916921004849,1.0429669317173755 -1577,422.0190277929895,408.21003110652816,1.0338281659787476 -1578,844.4760322224514,767.5566530876346,1.1002132921724994 -1579,1068.0573670335275,960.8783830381948,1.111542715381362 -1580,897.4302103874955,841.3622671936749,1.0666394790686688 -1581,529.9068508841468,508.50275694938205,1.042092385227511 -1582,478.45362983993016,452.9548458077685,1.0562943177850077 -1583,286.5071488692783,259.10169192289146,1.1057710458893595 -1584,241.0594491312998,231.0111869610406,1.0434968639503757 -1585,206.73769849389663,191.60387913208368,1.0789849319876261 -1586,289.8807337216556,261.9160994548581,1.10676943618587 -1587,242.60760284466338,232.49979820230425,1.0434744663028226 -1588,217.12581745257032,208.72486125727914,1.0402489485185762 -1589,144.13435321439582,140.6118494168968,1.025051258568225 -1590,242.73867629488913,232.6139401543874,1.0435259216785626 -1591,584.3552599102999,531.0322270192827,1.100413930036455 -1592,487.5268658249923,452.6995563781723,1.0769325018240712 -1593,1029.44141920649,998.9343442863737,1.030539619640278 -1594,394.3592153643787,374.2251524788902,1.0538020032916529 -1595,856.7714712256004,797.7478741491827,1.0739877835956226 -1596,895.3428863342821,833.7354087072847,1.0738933203311112 -1597,377.6129030253942,363.6833061539574,1.038301446988991 -1598,718.3293848366836,659.8292386478157,1.0886595239531245 -1599,70.94987449008805,67.79087028107547,1.0465992573323615 -1600,976.5498505598675,951.6583860648075,1.0261558820471162 -1601,1343.1547335429564,1237.74322986047,1.0851642740912988 -1602,435.2751588831172,407.17985953230374,1.0689997274990084 -1603,516.0043362897105,471.8867110780592,1.0934919847835118 -1604,424.6524851079203,397.13209637167535,1.0692978205178578 -1605,411.7360683712254,361.01621252493163,1.140491906143387 -1606,656.1651092280483,609.2953593889309,1.0769245147150366 -1607,95.67172272798472,89.3593329783824,1.0706405200129392 -1608,89.52021871552503,83.61370323854652,1.0706405200129392 -1609,95.67747526889487,89.36470596847816,1.0706405200129392 -1610,104.0427379168798,96.92628628486023,1.073421276155209 -1611,332.45952941924133,310.5232131789038,1.0706430801606424 -1612,283.84345242921063,262.95893444250936,1.0794212146888176 -1613,2240.6565989736737,2193.668550164137,1.0214198488673327 -1614,644.9174540415853,596.87629299465,1.0804876347256196 -1615,645.7880253876333,628.2763495844214,1.0278725688382113 -1616,494.68582583288537,472.09707592318784,1.0478476801948522 -1617,419.61931280342964,402.24948026058456,1.0431817401767494 -1618,99.33631272779125,94.91791095488672,1.0465497157328352 -1619,491.10037550049975,475.1227191151831,1.033628483216024 -1620,678.7437740010138,637.1045526785915,1.06535696715297 -1621,810.607253980028,774.7328770155924,1.0463054789963606 -1622,420.35140014169104,402.13356289271337,1.0453029513824443 -1623,506.6160554850257,493.1280789473569,1.0273518728977278 -1624,906.0443086537246,844.9799040353691,1.072267286271224 -1625,509.6624156419754,474.54787409187236,1.0739957830752074 -1626,504.3428979865124,482.5999350825351,1.0450538040380357 -1627,705.8821699828287,621.1496883396311,1.1364123386581622 -1628,658.6583549896076,635.4266803840834,1.0365607477978134 -1629,661.1878310672081,637.9560097464736,1.0364160239355171 -1630,328.7060377983884,317.12999927628834,1.0365025022814536 -1631,609.9665426828791,588.5344577814338,1.0364160239355171 -1632,1232.9271389603875,1143.2398063620728,1.078450148515831 -1633,1274.7963506505746,1195.5360549324096,1.0662968677449431 -1634,995.3969046140014,966.7670295665871,1.0296140374793805 -1635,419.7834259082184,383.4733816412844,1.0946872612422935 -1636,246.12640612300902,220.09379081578507,1.1182796443767595 -1637,1305.3413168515738,1244.3401019284854,1.0490229438306684 -1638,1667.386215692161,1542.1263600254952,1.0812254163560209 -1639,1762.5450642172088,1628.415604705537,1.0823680755232792 -1640,1270.7241216249233,1224.5401143877552,1.0377153893894764 -1641,990.9847334405314,925.8238609498742,1.0703815004549608 -1642,774.0906001693556,741.6473703278429,1.043744818817562 -1643,1014.5084488910118,981.9802081543248,1.0331251490270106 -1644,2087.2183603997037,1983.5391188361978,1.0522698244662487 -1645,622.0525074409911,578.5778527323454,1.0751405441866395 -1646,727.3044775249917,677.2928026585266,1.073840552668149 -1647,827.0660259194618,771.1719721443859,1.0724793636102363 -1648,1027.5170472785148,958.2426415452808,1.072293177875617 -1649,1781.7903702781543,1734.1305341085722,1.0274834190576556 -1650,2421.9766710745625,2346.1600701126176,1.032315186814302 -1651,615.8889424128188,572.7622730207885,1.075295932402421 -1652,607.1405205448489,564.5414153438307,1.0754578920929536 -1653,580.445073727848,534.1844282101997,1.0866005129963183 -1654,547.1662557394866,489.1561001259135,1.1185923176643218 -1655,349.0887655308634,346.0429827898428,1.0088017468710535 -1656,251.9767846563558,250.48264421006436,1.0059650458058818 -1657,701.9377369338525,626.7518043849618,1.1199612542363104 -1658,552.4803088236407,514.6602008003165,1.073485589063449 -1659,529.7386987660947,481.3262121300377,1.1005814464618802 -1660,595.0078243541342,544.6321934918275,1.0924947725534382 -1661,1085.9337137386935,982.2164281410352,1.1055951444367063 -1662,762.682860041763,699.7561811844415,1.0899265780701053 -1663,1172.682836245262,1069.0799411919318,1.096908464055384 -1664,832.0753212416228,760.1414421487115,1.0946322290882786 -1665,867.7532639686129,812.9512788903354,1.0674111555037853 -1666,1057.9113506136932,1009.6788396508935,1.0477701513279971 -1667,1035.2279409117727,966.3915740159788,1.0712303053406547 -1668,1051.3518214896167,1015.0010052975445,1.0358135765406618 -1669,279.0184778121485,273.66909357518324,1.0195469066933407 -1670,489.4307507725727,475.35405428416954,1.0296130775819323 -1671,283.34172504991733,277.8398418081828,1.019802355219929 -1672,487.660212451722,473.6322943494665,1.0296177398999424 -1673,1013.5987693921146,882.7284094036219,1.148256653569029 -1674,511.6598434188773,491.4175867605652,1.0411915592841303 -1675,547.281442564535,527.9386693113753,1.0366382960323588 -1676,755.0258132046789,724.2829685035748,1.042445903104171 -1677,768.0110634434703,736.8571013764829,1.0422795166237666 -1678,1170.2937259218086,1131.9368487813001,1.0338860574967634 -1679,1165.3681329591825,1127.1686109159202,1.0338898028860313 -1680,740.7403054418465,709.4224625919085,1.0441455472603967 -1681,762.6258356307053,730.2217938756062,1.0443756157743755 -1682,332.51160983282705,315.0032521342398,1.055581514095372 -1683,332.90458120632087,315.30746894497213,1.0558093733720586 -1684,189.28663443971993,165.00151419875766,1.1471811962386531 -1685,189.96507400584332,165.61991674938693,1.146994140163076 -1686,563.1528360263338,530.6846059371661,1.0611817824107226 -1687,577.0117070490381,548.3776778577164,1.052215891250685 -1688,191.01220540754184,166.6652875092146,1.1460827162163636 -1689,275.6937439255967,256.97251583875357,1.0728530365425946 -1690,701.8841054173976,648.8684510894678,1.0817047804357185 -1691,281.97900593647506,261.19471848421915,1.0795739193076819 -1692,277.45791014829086,257.53730122222436,1.0773503831543119 -1693,244.3056368125451,229.9764323416159,1.0623072735107224 -1694,194.0414871770692,188.62319348003928,1.0287254902065015 -1695,246.82430091147108,231.3425509512319,1.0669213246615525 -1696,469.8497564271628,458.8336028191126,1.024009038440877 -1697,407.46775611279105,377.49992500394893,1.0793849988408042 -1698,400.13029411945934,376.448667199012,1.0629079844979976 -1699,399.9226760166895,363.69965210268117,1.0995959817519476 -1700,466.97836444269603,447.55499052585975,1.0433988545050399 -1701,391.87618401587895,367.0556516360058,1.0676206244727344 -1702,572.6107147909465,553.4231954275475,1.034670609258753 -1703,347.7974730827219,322.85796828802415,1.0772460562981956 -1704,590.1175269324528,570.6750075644211,1.034069337381727 -1705,1020.8787247675907,954.7240353281828,1.069291949287385 -1706,551.7923632441327,530.4717489856006,1.0401917996562544 -1707,265.35634336568,255.66696476590266,1.0378984379489515 -1708,237.0378963194763,230.57166819108681,1.0280443307676057 -1709,98.61597304789616,89.42459246347322,1.1027835892925908 -1710,362.59952976127863,348.30459748120785,1.0410414688277034 -1711,161.37660607212734,161.243330093866,1.0008265518839368 -1712,135.47775547864657,130.26523006138245,1.0400147101019046 -1713,164.71088597765248,164.65272210040078,1.0003532518412677 -1714,163.78210324228075,163.78166356765448,1.0000026845167933 -1715,235.45954670494197,229.0426394215529,1.0280162126126164 -1716,323.6947346939156,311.73431064286206,1.0383673649088823 -1717,233.9814672198241,227.61302324250275,1.027979260090651 -1718,342.7602172064903,329.78604236806143,1.0393411884422596 -1719,1187.332949528651,1130.5101879079798,1.0502629363524996 -1720,526.3223291059322,491.17654060258855,1.0715542897472787 -1721,1147.5801661748599,1082.6077716244833,1.0600147128566089 -1722,741.4982607609243,696.2834584227995,1.0649373495681542 -1723,706.1225193052477,685.2776715282145,1.030418104431373 -1724,455.5524512629893,439.7141500596804,1.03601953951484 -1725,519.1277953771614,486.04456891956016,1.0680662403679209 -1726,747.5451933473212,702.5625540531697,1.0640265255166832 -1727,1620.7436822689897,1569.820618395798,1.0324387788492866 -1728,3193.4371776412195,3038.774252157666,1.050896484124721 -1729,2084.3063669489147,1976.4716970284264,1.054559177387976 -1730,558.7766681051422,519.4164404639279,1.0757777855588455 -1731,1025.0894779741811,961.1364096191465,1.0665390133127681 -1732,658.4772511157015,638.2019019329152,1.031769490378168 -1733,968.0024443166972,897.5770110989442,1.0784617167629191 -1734,2888.4115644668136,2676.060982367686,1.0793519219099585 -1735,1683.7927431849764,1497.07104982177,1.124724670472678 -1736,1674.3461210512648,1523.744138537581,1.0988367920208866 -1737,560.1610103638474,531.031459136746,1.0548546620466797 -1738,732.5034506269905,662.2687437188807,1.1060516709783346 -1739,776.8417983791434,719.6670610869481,1.0794460944285007 -1740,1937.1364346199894,1837.6652002421445,1.0541291386291354 -1741,3414.1436615470802,3297.1460399671146,1.0354845130187598 -1742,1756.5545672300855,1696.8890045228845,1.0351617357105671 -1743,799.5457444304172,744.7369197485792,1.0735948805926545 -1744,2659.1685470962134,2557.6732571223865,1.0396826645824253 -1745,925.6914902101976,879.126813219295,1.0529669625481974 -1746,908.3097737122513,866.5727962556401,1.0481632675719244 -1747,646.0500768628915,596.6806086031997,1.0827401922366193 -1748,1068.258003570958,938.7478042576088,1.1379605882708508 -1749,1477.7142997535968,1414.1937451295169,1.044916444329389 -1750,636.2938307756968,610.1071677925538,1.042921415065307 -1751,1487.315526017514,1384.6716965788155,1.0741286398012657 -1752,4384.091820653534,4175.521055281819,1.049950835503005 -1753,1149.0424985403913,1110.7973650340584,1.0344303423020456 -1754,1131.8294472435982,1087.3890047743673,1.040868945955962 -1755,1014.8853877075012,967.3092648563726,1.0491839834266374 -1756,971.5170623355064,912.5253306310303,1.0646466785351394 -1757,1102.0501532996764,1028.032004946388,1.0719998482509778 -1758,941.494331190685,884.2587345076532,1.0647272053409798 -1759,1032.9771326825726,943.9417994047357,1.0943229056431063 -1760,1689.536424196861,1579.7508205036568,1.0694955193365256 -1761,3893.116511778345,3742.8786396131,1.0401396589713565 -1762,1649.510718792898,1567.343048200276,1.0524248157970089 -1763,562.2869157601052,533.2196627883025,1.0545127177415117 -1764,975.8979138452258,937.7748407808659,1.0406526933827907 -1765,603.8749627949753,573.8655018946481,1.0522935440469052 -1766,985.6642544109773,948.1065154866152,1.0396134171750582 -1767,3799.202877399403,3660.0905956918637,1.038007879332627 -1768,3666.1092461358458,3535.4219707352568,1.036965113777751 -1769,3404.7412880657034,3284.0287499611068,1.0367574547287464 -1770,534.7640433531137,518.689158020231,1.0309913656075604 -1771,834.7506632459668,805.9348860360215,1.035754473108461 -1772,738.536016684704,713.846843936544,1.0345860921819172 -1773,562.6624288606104,545.3858216573508,1.0316777710699527 -1774,1015.7850112266352,935.2656042415368,1.0860925566170012 -1775,1437.1843876546486,1348.5388068938098,1.0657345419410085 -1776,1203.8431544533157,1141.4034897755373,1.0547042875171666 -1777,332.11777921928734,317.5639809781378,1.045829499291204 -1778,806.0693811769552,759.8189180244558,1.0608703758952875 -1779,757.5835533767676,714.2776645502361,1.0606289276227057 -1780,316.0591288365113,298.15078952935227,1.0600647052970358 -1781,1835.661524862744,1747.0961324415646,1.0506929131011293 -1782,3077.661363728373,2869.779503471317,1.0724382692139238 -1783,935.91394922401,881.9139467498646,1.061230466615425 -1784,923.4244087360397,870.3823664337317,1.060941081009764 -1785,909.0440243964391,856.8541064670961,1.0609087562695214 -1786,868.9255041235701,818.987203020123,1.060975679374834 -1787,898.2806069512019,835.6235260821792,1.074982427987386 -1788,929.6306737112722,863.6998003120942,1.0763354042404016 -1789,694.4640866315028,651.6636785630875,1.0656786767106459 -1790,934.9985471870167,868.6372460774519,1.0763970246604504 -1791,1375.4784304264053,1322.8676921225078,1.0397702193629696 -1792,1364.4780877193527,1311.5730066343224,1.0403371225371527 -1793,856.2713861706002,821.7711937388539,1.041982723043356 -1794,900.8905032610102,871.1958581637358,1.0340849245540071 -1795,1457.6681529224163,1407.9561223248872,1.0353079402186498 -1796,877.2689460602481,848.7049440882814,1.0336559863011656 -1797,1467.0840182222203,1417.0508707895958,1.0353079402186496 -1798,889.8807176306699,860.8348690949693,1.0337414869895287 -1799,1725.5772430306545,1646.4696691245983,1.0480467848205892 -1800,3236.5352845319885,3129.842347627704,1.0340889172852918 -1801,1848.8215831708192,1814.4627130849292,1.018936112513149 -1802,126.2136477138279,123.03870014957977,1.0258044628266416 -1803,285.20344898468676,272.3512030502888,1.0471899730585175 -1804,346.27015806582494,330.09350298579636,1.0490062813527252 -1805,352.03888017188933,346.1468276596709,1.0170218301639657 -1806,805.5852709212169,779.8668664311691,1.0329779422579402 -1807,742.0866901280383,715.013287556254,1.0378641950337941 -1808,943.7156802962506,909.5493611213822,1.0375640076672088 -1809,1164.7103564500217,1114.796435454227,1.0447740227797346 -1810,397.84585101888086,384.25226657499405,1.0353767189587515 -1811,1339.7298228869363,1274.4019315442865,1.0512616072885947 -1812,2017.7822930228892,1951.7468299057182,1.0338340311895682 -1813,862.1560083475279,830.3448989341008,1.0383107181777866 -1814,1657.6564030083173,1593.1721055229568,1.0404754120799733 -1815,379.5577505433757,368.64469651295354,1.0296031765373266 -1816,709.2635653835517,678.8050890746946,1.0448707247471822 -1817,5058.634941134445,4821.801442827577,1.0491172233272188 -1818,2074.617711500103,1978.8207485451362,1.0484111373025566 -1819,1494.968561438746,1430.6708394038983,1.044942358692121 -1820,897.7931121266372,871.9274852259343,1.0296648830768313 -1821,2010.6362974394472,1917.5453476691418,1.048546935217705 -1822,1494.3646454905436,1414.9045880325925,1.0561593044011817 -1823,1384.4982279895917,1322.233961676871,1.0470902034869505 -1824,1054.5740159049426,1010.4409407772166,1.0436770456804525 -1825,1965.0723628255073,1862.7562770911059,1.054927253228307 -1826,1753.283778372399,1696.104312236331,1.0337122343971146 -1827,1330.0488393778826,1278.8064746060622,1.0400704608471782 -1828,2080.3235327103116,1974.9108604811192,1.0533759139911318 -1829,500.7837472683377,473.74448641370554,1.0570756212052665 -1830,258.3928139097221,221.8952521521078,1.1644810396060006 -1831,328.13898889354886,314.7913828043356,1.042401434150787 -1832,437.1649272878046,406.1760910582032,1.0762940924190458 -1833,1190.4766890155383,1120.982387808052,1.0619941062083715 -1834,1865.4693290083796,1771.9660072639638,1.0527681238585336 -1835,407.91010813477067,373.42009832753575,1.0923624892224812 -1836,393.14536659471224,362.21880946186803,1.0853808701397656 -1837,391.6662271568988,359.2761489984379,1.0901537111460236 -1838,442.60305864787915,413.2607806156302,1.071001845344574 -1839,1492.9890777123856,1411.727690842093,1.0575616582414844 -1840,530.5021525590524,502.9165721102159,1.0548512059029764 -1841,1009.7590454466825,945.8033141380192,1.0676205404999568 -1842,2906.544549349679,2707.071469220619,1.0736859304961348 -1843,2981.3578862679146,2806.6308400917032,1.062255086661309 -1844,549.3359930565265,518.4810412150256,1.0595102798150429 -1845,269.3630604045545,257.5569858933944,1.0458386887476885 -1846,863.952413832826,804.0564788696392,1.074492198666678 -1847,734.9133374683195,685.2168818351204,1.072526607196402 -1848,1849.2771329957209,1752.2394464544527,1.055379238686595 -1849,4290.316225058476,4049.7199070868637,1.059410607027557 -1850,2645.1178653173315,2480.090316778394,1.0665409430545683 -1851,2107.8942378644156,2014.352509178302,1.0464376161867872 -1852,1189.01105078709,1130.5202089112315,1.0517379887726104 -1853,1290.6287363447327,1259.6703676070395,1.0245765634675554 -1854,2256.155068395385,2161.6905800544555,1.0436993569813076 -1855,1359.6457217846432,1301.9733346786948,1.0442961353891176 -1856,1863.0294914845763,1784.7768628255424,1.0438444885122218 -1857,481.74999999468565,446.4803605654487,1.078994828315784 -1858,866.510980171034,813.5822273029037,1.0650564271095175 -1859,482.1134383399081,456.86605122656454,1.0552621212400461 -1860,464.0036273390115,443.7353239973461,1.0456765604303944 -1861,391.5777639120517,335.735811312413,1.1663270664554637 -1862,454.90416268504345,420.94471425911405,1.080674367145101 -1863,1186.7232933697453,1059.282254567815,1.1203088584297356 -1864,259.3681267219557,248.0295733158401,1.0457145220811115 -1865,259.0615477237488,247.6184349859256,1.046212685006565 -1866,260.73766334130625,249.22088771606323,1.0462111170969106 -1867,258.76716313652423,247.40620339648177,1.0459202703249761 -1868,1038.3400661599242,1014.0404199066245,1.0239631929618123 -1869,757.0161275185098,692.4557926242679,1.0932338722296933 -1870,1052.2773597158268,1001.282569969532,1.0509294691386135 -1871,400.28922288098624,384.8980547486513,1.039987648527831 -1872,201.05792072355675,194.2701123471308,1.0349400548258147 -1873,607.4629701652773,585.4080209801579,1.037674490944269 -1874,200.321193998453,193.55825785694222,1.034940054825815 -1875,1246.6679702634508,1189.4069839060144,1.0481424669034574 -1876,2505.5512949337817,2371.698129869909,1.0564376905214388 -1877,1218.8199981104303,1161.4372558809837,1.0494066656970809 -1878,615.074447435115,581.2708953430688,1.058154558163617 -1879,1050.4917927510494,988.5852726464051,1.062621325461306 -1880,464.9087179900554,438.2127240428638,1.0609201706899325 -1881,1544.3500917126553,1491.700953980946,1.0352947000477561 -1882,657.2836821661434,625.0974907782147,1.0514898745599803 -1883,1215.696272004938,1167.9125065065966,1.0409138229380468 -1884,1189.7081781274585,1140.9498230061038,1.0427348811824952 -1885,466.30571873076326,441.43982947772736,1.0563290568557329 -1886,259.11731381007183,255.91102204414858,1.0125289318932504 -1887,1231.5259501762564,1204.8341741398735,1.0221539001874993 -1888,1281.7674050905919,1240.7184608293721,1.0330848178351277 -1889,223.03485959023374,213.83452408487636,1.0430254915324408 -1890,181.35467473906104,179.70009132982975,1.0092074711647998 -1891,25.800521049478,25.724236262496312,1.0029654830644246 -1892,267.3173473398645,256.06988631867324,1.0439234038132623 -1893,429.9487325640014,419.35793554136,1.025254791015149 -1894,337.9701087236291,328.5529390811902,1.028662563995849 -1895,574.8489202066128,552.245090832535,1.0409307927753626 -1896,391.2858356536227,371.64330568291285,1.0528531784922528 -1897,1322.2829797739246,1259.616206695153,1.0497506881426921 -1898,524.4741518458527,501.3558244593388,1.0461116162586614 -1899,382.5700468143861,366.1017576552462,1.0449828191610264 -1900,374.1424546297658,358.0458650729683,1.0449567810356282 -1901,526.4816709947726,503.2748540520887,1.0461116162586617 -1902,725.3903824393493,684.1715095752292,1.0602464035512251 -1903,1804.9960543869663,1674.1858735796864,1.078133606830397 -1904,1303.005435506759,1231.814457911913,1.0577935882612746 -1905,117.65105987474071,100.49764366917015,1.170684760152568 -1906,221.7227949688625,199.16161015245694,1.1132807914092235 -1907,1621.3170446547708,1538.331141735024,1.0539454091959357 -1908,1673.4248754359508,1599.962696706177,1.0459149321924877 -1909,848.5343648823168,804.463724702206,1.0547826319905533 -1910,1509.67459988983,1445.6034313308753,1.0443214004410382 -1911,1304.2878316929969,1247.1447778600257,1.0458191020380352 -1912,3759.023373164279,3642.4999653446885,1.0319899544071962 -1913,4834.714319094085,4658.934122834605,1.0377297020359093 -1914,2553.4103504860595,2456.564512967069,1.0394232828031937 -1915,478.0605980045608,457.76363971597146,1.044339385061651 -1916,870.9200740881635,840.9880912074824,1.0355914467679381 -1917,854.6701202130218,819.3671312732038,1.0430856786810099 -1918,431.0968190863744,415.3511528037107,1.037909287542305 -1919,5222.051588733133,4984.7237273178025,1.0476110361171476 -1920,2070.5715319023734,1951.0926577563637,1.0612369041885499 -1921,804.9396881597501,772.2131063654709,1.0423802464947938 -1922,412.3016044610551,395.08891150189186,1.0435666313532588 -1923,458.47142737768974,442.19384640549094,1.036810962216042 -1924,594.4810088826235,569.812607170995,1.0432921304323226 -1925,455.6183628384898,422.0501259781497,1.0795361375204944 -1926,527.0852100140049,503.63399400987976,1.0465640053750327 -1927,456.1063363016764,422.4957722482817,1.0795524269379986 -1928,610.8143138306706,591.8167502052087,1.0321004155743727 -1929,2746.612368718363,2681.467273768751,1.024294570210455 -1930,2627.800356608649,2546.669129338595,1.0318577809482163 -1931,2659.7295459812008,2577.712775811124,1.0318176528198602 -1932,2764.0105751875494,2713.252216954697,1.0187075709053774 -1933,353.96662059694916,349.31056078062153,1.013329284422213 -1934,1332.789983814086,1273.1375542878363,1.0468546617962409 -1935,1010.4089265028969,966.1789785873074,1.0457782138670209 -1936,419.8545819563705,402.07678265256095,1.044214936228167 -1937,836.7697871627187,797.688110366512,1.0489936809741967 -1938,1080.491792068006,1029.1079963501961,1.0499304211997633 -1939,716.1694992358407,690.35091694302,1.0373992148908113 -1940,532.6925582894403,522.0718628088888,1.0203433592904418 -1941,397.18000630767636,377.83153725034776,1.0512092484341995 -1942,871.094958823329,828.9510936969517,1.0508399897736116 -1943,1049.2041935496977,1014.0187078205792,1.0346990498870996 -1944,370.36274632885454,351.66237121223503,1.0531770716672255 -1945,520.9063227646444,501.7271992262987,1.0382261985555525 -1946,951.2498230811898,890.6834636585255,1.0679998696437958 -1947,798.7137090131154,786.9984413872294,1.0148860112165352 -1948,559.6318299512881,555.7370142091686,1.007008379219912 -1949,678.949960993233,633.1293381370751,1.0723716626226496 -1950,1160.7079902024664,1119.4343064118257,1.0368701258789692 -1951,270.72432777192154,256.7562518919392,1.0544020867147612 -1952,251.08145196278113,246.87204630714976,1.01705096108935 -1953,816.3169404829862,790.2107838574844,1.0330369531254209 -1954,2188.8172142724957,2135.838827833459,1.0248044869999748 -1955,3204.971670327929,3127.202961095324,1.0248684559972936 -1956,3170.6268200494123,3023.4079613720996,1.0486930181299454 -1957,3187.5136530166446,3024.712064496662,1.053823830185659 -1958,1862.902087839933,1725.9439714633427,1.0793525853915584 -1959,2168.503969841598,2115.543571075296,1.0250339437534643 -1960,2864.069396805012,2791.782709067249,1.0258926625997746 -1961,3143.8040479075084,2974.4829189928323,1.0569245591674161 -1962,3347.17204917528,3176.2470752707827,1.0538135006043021 -1963,1946.3577593509724,1803.264091543255,1.0793525853915584 -1964,459.6588993623951,437.87207576363693,1.049756138389877 -1965,503.3334882846133,452.0418001313375,1.1134666929880674 -1966,753.2180452898548,664.0663001444417,1.1342512714860273 -1967,772.8166005745827,718.6309631789854,1.0754012005771334 -1968,1531.9667372678696,1427.358167711998,1.073288241117193 -1969,1899.7075848763182,1774.8069044018305,1.0703742362984459 -1970,505.15642776497293,449.4626642104771,1.1239118796492855 -1971,119.87608334322813,111.0577049411386,1.0794035713844738 -1972,125.42286849644162,120.21151373251239,1.0433515443081869 -1973,427.8791884679381,404.2965315313145,1.0583300995615814 -1974,383.56392333854836,367.0157664810972,1.0450884086428027 -1975,607.7365519344514,585.692425371302,1.037637718379531 -1976,419.1839330628931,384.7709832274283,1.0894374870651933 -1977,1177.9385025940157,1120.8216990133944,1.0509597589258832 -1978,1072.1683753527368,1025.5319449529663,1.045475356110832 -1979,2205.3438457043508,2104.3755625225663,1.0479801633225352 -1980,946.4442534527485,906.6587055743363,1.0438815042902052 -1981,959.6680226782568,919.9684081589781,1.0431532367494278 -1982,663.1530871395584,627.9562601270478,1.0560498067260122 -1983,563.8881564555405,534.8085134437416,1.0543739343724152 -1984,665.7259921706664,621.0231087968274,1.0719826408077575 -1985,145.1920809535233,136.67752295571816,1.062296695269812 -1986,521.0194360598915,484.6396576137622,1.075065624272792 -1987,151.78303809427962,139.40491543865502,1.0887925839392054 -1988,1806.383448329206,1690.5357997423996,1.0685271785456771 -1989,4258.643856506577,4005.1827399557314,1.0632832839366644 -1990,2205.7942173660517,2100.1559844105764,1.0503001842432782 -1991,2211.7696758829934,2077.024410824363,1.0648741846058278 -1992,2945.0624116080376,2765.6835983764945,1.0648587616229281 -1993,2725.385194493634,2558.1257489309114,1.065383590166599 -1994,2965.926470555442,2789.553956173923,1.0632260630740504 -1995,367.7288131878078,351.0124308648107,1.0476233342557468 -1996,375.1954018779702,358.1998588382251,1.0474470958611428 -1997,1389.8124874630532,1305.1078803122743,1.0649023796642094 -1998,1421.1540467225452,1334.3357743033223,1.0650647866085672 -1999,395.79365061119273,382.5188978922502,1.03470352129552 -2000,373.4803423354667,358.21534691506895,1.0426140184999304 -2001,404.4847193683968,391.81242547007037,1.0323427565706296 -2002,402.97282380144884,390.04655947314865,1.0331403111099358 -2003,71.91706371902858,56.01692345230402,1.2838452968639529 -2004,729.92641241155,643.621595602396,1.134092481356809 -2005,1227.99361998139,1185.421373335324,1.0359131761951315 -2006,1244.645740257406,1196.471574370765,1.0402635272902128 -2007,749.5914173633158,735.0572965319027,1.019772772680425 -2008,513.1137053057785,498.49253170546837,1.0293307776352985 -2009,374.619376457337,362.2624886392183,1.0341103156016385 -2010,1017.3629227641159,999.9892988389839,1.0173738098450686 -2011,593.704662933787,584.1855001132762,1.016294760514708 -2012,762.9198229886244,745.1147033336612,1.0238958103702729 -2013,240.53417985879372,237.26657680357923,1.013771864116873 -2014,336.0549401243085,331.1467031931149,1.0148219411030381 -2015,929.9049559800326,855.6216679004033,1.0868179136485778 -2016,437.7213410261114,406.8714256510157,1.0758222706982536 -2017,452.4524001757941,441.19903355125695,1.0255063265527977 -2018,747.8134049160615,703.5587560862207,1.062901141442716 -2019,820.0576680927272,777.181870717265,1.0551682932797852 -2020,915.6101774339188,848.7404711557107,1.0787869891336195 -2021,1320.8488162048816,1257.6429521729317,1.0502573993061735 -2022,1116.940185171962,1038.813834867066,1.0752072678305191 -2023,1629.0775087551988,1578.0879184570358,1.032310994654859 -2024,2291.2326221190315,2202.4811283406975,1.0402961426712416 -2025,2632.7878525318993,2527.3035292597365,1.0417378926001262 -2026,3409.0847226632964,3288.3556945726227,1.036714102519364 -2027,2594.7605257306204,2411.2992741052444,1.0760839824386597 -2028,2835.7678468997424,2716.8404920539847,1.0437741395542313 -2029,1214.4282971053124,1171.45019170457,1.0366879494365913 -2030,1767.3911055425017,1705.4679133971565,1.0363086233748011 -2031,1371.0574123830033,1326.4467476141683,1.0336317042874692 -2032,710.3890127960086,688.2497650000485,1.0321674614679435 -2033,3324.3803406366005,3197.612783259282,1.0396444366375426 -2034,4315.30102462731,4134.367658888341,1.0437632500704155 -2035,4603.068441016602,4426.552445867346,1.0398766302461981 -2036,5479.507890028579,5245.149594922998,1.0446809553978071 -2037,1695.770163290725,1633.0540277757825,1.0384042012378254 -2038,1910.4755596188313,1840.212293435184,1.03818215237139 -2039,1773.7397643028667,1708.5305058185245,1.0381668681140122 -2040,1875.8735441546135,1804.7015371850423,1.0394369958151555 -2041,4191.084417510977,4042.150532244368,1.0368452100134713 -2042,1884.3033614630524,1829.6285555395518,1.0298830086347102 -2043,4239.691859543293,4062.2012616573816,1.043693206331558 -2044,4725.514540076735,4542.6582883523815,1.0402531381665239 -2045,6333.258615442008,6099.439665113252,1.038334496800767 -2046,3790.5869091786476,3656.940453880975,1.0365459752443709 -2047,2759.769026406769,2666.0958163033547,1.0351349750937668 -2048,1611.1040792373158,1570.327640441595,1.0259668350384854 -2049,3829.52988203126,3674.00346861899,1.0423315913391693 -2050,4381.772039472903,4197.633681242832,1.043867181420069 -2051,973.6418045717995,940.1254997065005,1.0356508837126135 -2052,324.3124083017474,309.79900454284785,1.0468478063069186 -2053,371.6503916419757,353.40124383558737,1.051638606611352 -2054,371.7403625349667,353.510615648211,1.0515677495379565 -2055,327.9253695224198,313.22011130509276,1.046948639907108 -2056,1705.8729971314663,1636.927740535037,1.0421186927737534 -2057,2146.0878718324084,2066.223960345987,1.0386521079123718 -2058,2005.7284013452443,1930.1007782478496,1.0391832509212549 -2059,2957.0485646013476,2859.5639907213854,1.0340907124989254 -2060,931.241939710887,894.142433311587,1.0414917187879078 -2061,1651.7922796422756,1588.1944467535475,1.0400441098498545 -2062,1068.3263153966193,1043.2901874442457,1.0239972811531035 -2063,823.0200178663495,809.8639618718564,1.016244772719711 -2064,695.6738806390098,670.3082876999666,1.037841681811932 -2065,3082.3712504079754,3018.9124026302184,1.0210204336245294 -2066,749.2857382209114,707.0767135869262,1.0596951134479642 -2067,465.6494870494198,434.45242584642864,1.0718077730656264 -2068,420.7988699836177,413.2494231381196,1.0182684994165736 -2069,101.4983068196211,95.90523753169064,1.0583187053374672 -2070,147.98547580463983,144.92207012753465,1.0211382964265505 -2071,420.367337012713,412.9293804744504,1.0180126600091195 -2072,768.7419652425102,739.4374027481651,1.0396308901678937 -2073,216.20065188419238,212.0271302752269,1.0196839036756662 -2074,218.173560165359,214.39968362631353,1.0176020620703112 -2075,146.70907315683186,135.35240764907127,1.0839044218349263 -2076,146.60449210056308,135.22833368061208,1.0841255535013814 -2077,864.3505780478672,809.9996371737202,1.0670999570614503 -2078,614.8513265248888,578.1136366485364,1.0635475234407714 -2079,622.5014057302518,575.0875355687598,1.082446353344452 -2080,348.7932516353076,325.45372852193356,1.0717137985156042 -2081,348.05412867525797,324.7671552470305,1.071703597645256 -2082,116.97581882974357,114.80055346403854,1.0189482132277912 -2083,115.98167109215716,113.84885244345199,1.0187337737968376 -2084,844.6167319344738,773.2688457775679,1.0922678917513629 -2085,429.0955308431512,409.440262612151,1.0480052159638706 -2086,231.9597165192344,213.05392866413885,1.0887371003840953 -2087,226.94534113388679,208.09729235412317,1.0905732533400267 -2088,147.0329147876788,135.60703967982224,1.0842572416213336 -2089,2238.745700271761,2144.9653340496648,1.043721157043149 -2090,204.67117448317174,200.30508420213678,1.0217972014960386 -2091,117.33167178027,105.38138068318428,1.113400403559076 -2092,104.91027029555676,94.09806555001667,1.114903581517231 -2093,182.60910566302496,178.88145114262835,1.0208386867200916 -2094,440.4506964691184,408.37408241158306,1.0785471346959934 -2095,437.6968463615393,405.82078639049143,1.0785471346959934 -2096,167.2180880384433,160.23319216733674,1.0435920658923903 -2097,171.58495212241692,167.0576813443199,1.0271000455750727 -2098,883.2906682785319,830.1955690571857,1.0639549296578923 -2099,1006.6449782186427,923.6028981316774,1.0899110215601835 -2100,2200.8705568564637,2126.758557018983,1.0348473970366252 -2101,3441.4409931385953,3312.984277676706,1.0387737171973457 -2102,776.6981253098454,760.8636173603833,1.0208112302759276 -2103,782.1283028214277,726.5852641559277,1.0764439376981094 -2104,405.53433902612386,378.16465050399574,1.0723750580220848 -2105,605.038718429464,591.9212020299068,1.0221609166128407 -2106,2086.869389775564,2013.9564802941545,1.0362038158196745 -2107,1860.348413294323,1784.0706820036505,1.0427548818889882 -2108,3965.3428744881917,3723.8648878617514,1.0648460655523668 -2109,5426.766091083658,5135.003345125944,1.056818414000577 -2110,2328.69669880598,2201.825792771889,1.0576207738371401 -2111,1945.0792142311589,1838.574480249041,1.0579278865916226 -2112,421.2096508225763,366.214815860197,1.1501709722835836 -2113,489.09254976104154,436.06942074537034,1.121593320909866 -2114,665.5858900543686,626.3578020461795,1.0626288806174988 -2115,652.4874667669694,612.6361781776711,1.0650488658829107 -2116,172.8710157462687,141.328694326114,1.223184128110398 -2117,187.83115330335235,153.55918130945508,1.2231841281103981 -2118,183.34261137955048,149.9101501216603,1.2230166618521687 -2119,201.08325004429017,164.40552233307355,1.2230930396420032 -2120,182.73727634336274,170.53454045981786,1.071555802423616 -2121,195.36975570768695,182.32345589258395,1.0715557948988705 -2122,184.99352667560518,172.64012277064742,1.0715558104726863 -2123,196.3825073410496,183.26875750992264,1.0715547483886716 -2124,184.3046498222277,171.99724988620096,1.0715557948988703 -2125,199.1112162275163,185.85638106809088,1.0713176221513177 -2126,184.24822391230705,171.94459195631129,1.0715557948988703 -2127,196.17270135140797,183.0727481292992,1.0715559981262563 -2128,184.14611791690515,171.8493043419024,1.0715557948988705 -2129,194.7276175623024,181.74490479469918,1.0714337096947428 -2130,186.36907885426962,173.92392064462413,1.0715551843790048 -2131,198.6622004799351,185.44671141758525,1.0712630003591246 -2132,1573.5479871590742,1529.4657894643149,1.028821957312428 -2133,1079.831141660636,1031.898749733099,1.0464506735180508 -2134,1294.6315344126815,1227.883291192556,1.0543604133217723 -2135,1108.548060054803,1066.7689784094266,1.0391641325263037 -2136,225.06654523864694,200.75172005801403,1.1211188884140386 -2137,396.58978881398565,370.26352964514047,1.0711014103767558 -2138,184.0929386266095,165.93653738735014,1.1094177420183018 -2139,242.96030189389975,230.84187093417216,1.0524966762341972 -2140,197.15390501498445,176.43374795078293,1.1174387400645227 -2141,302.1175899675996,278.4621376204398,1.0849503366931827 -2142,271.4373478119364,263.36160518527026,1.0306640849222686 -2143,1409.0270314467605,1373.6608314187554,1.025745947776263 -2144,1139.7252364540454,1079.727064475474,1.0555679059575285 -2145,1319.7561246582563,1273.86170963427,1.036027784395186 -2146,264.4010369682493,244.91398123679195,1.0795669386984343 -2147,338.917435558194,321.0232117529906,1.055741214809638 -2148,1341.0991197183469,1310.118042359755,1.0236475465239678 -2149,1204.1965828162797,1172.1837317527616,1.0273104379427358 -2150,170.82750716841903,164.68101587840437,1.037323617766319 -2151,185.81149966760296,178.95466037191454,1.0383160700114662 -2152,166.84339819737173,160.68550986532946,1.0383226112746768 -2153,187.14284653002855,180.23687770522702,1.0383160700114662 -2154,187.42108665023662,180.50485017357667,1.038316070011466 -2155,356.85677041632636,336.6309561050188,1.0600830492398259 -2156,282.14375420536544,267.26189347980534,1.0556826883615738 -2157,418.8959442424393,392.65918290991203,1.0668181529286858 -2158,1410.3946375860658,1338.33410137444,1.0538434581750709 -2159,545.1458288755011,506.1287489301206,1.0770892387121986 -2160,290.36030921545233,284.1157403065938,1.0219789614687307 -2161,119.50034573030378,98.61711595137463,1.211760702769143 -2162,169.8053397651085,159.61982440253715,1.0638110923921644 -2163,170.2138649084052,160.05913185485167,1.0634436344610583 -2164,3502.1064217703647,3329.373882462279,1.0518813883348959 -2165,163.85842935282608,152.59703472503818,1.0737982533414203 -2166,926.4617160549205,892.0234813588344,1.0386068701281561 -2167,889.6243140291068,845.9972791501382,1.0515687649998058 -2168,1067.7947905254252,1020.014771820584,1.0468424772119336 -2169,616.2651965252718,567.7642626304672,1.0854244218720257 -2170,1351.5276206028118,1276.401286225134,1.058857927509505 -2171,1121.4629349113836,1046.0575668717152,1.0720852947559778 -2172,1523.4529824430986,1466.5666235216427,1.0387887996420209 -2173,5822.723675746971,5555.253320471066,1.0481472832733438 -2174,1455.1328054605558,1388.2890443461517,1.0481483026799263 -2175,1421.9861369837472,1356.6951004009713,1.0481250625608356 -2176,859.7998309885086,823.8608721849251,1.0436226067009 -2177,934.4009013962113,894.6779625736085,1.0443991474969796 -2178,2597.5947740910183,2482.6695756051035,1.0462909763003414 -2179,4997.348275632482,4680.706049536446,1.067648389526062 -2180,1402.0094133401853,1297.3623485187966,1.0806614011427607 -2181,854.4146750779803,796.3227437085917,1.0729502351004643 -2182,1408.3772268816872,1328.8442194527393,1.0598512649298366 -2183,1120.7807325048698,1052.0598152577907,1.0653203517998073 -2184,600.4209993367289,563.3226830899808,1.0658562443167627 -2185,417.03238182180905,395.17399166695634,1.0553133318886898 -2186,2314.971817815019,2183.9192987017864,1.060007949557081 -2187,619.188941514328,588.7239713953807,1.0517474599288694 -2188,1223.4100576091314,1124.861307534534,1.087609689669739 -2189,1005.6917453104046,969.4830254393763,1.0373484825632902 -2190,239.7309350974117,232.02196518854115,1.033225172895188 -2191,380.9840246996484,355.0253145750641,1.0731179131709374 -2192,265.40026543021014,242.27250073691468,1.0954617821789443 -2193,211.82746618297352,206.47537574881315,1.025921204476564 -2194,2072.552767832066,1953.3439846453284,1.0610280545176902 -2195,473.2710219125561,428.13210575389536,1.1054322148514788 -2196,398.4894363081732,378.7318613024371,1.0521677128979614 -2197,588.6654848310886,551.0745074526604,1.0682139653895302 -2198,475.59784386376856,430.2202112698451,1.1054753621639162 -2199,1110.8312547010958,1048.9618549192626,1.0589815535156855 -2200,317.40500313773134,301.2064930599057,1.0537787546120527 -2201,292.6658531405483,267.51139265359546,1.0940313615709283 -2202,344.2014268135048,321.3421783564809,1.071136781900025 -2203,701.7844297782242,666.2536460476683,1.053329214693729 -2204,253.43639991733224,251.04786806839914,1.0095142486861604 -2205,752.6413146232635,715.1762318959751,1.0523858051433927 -2206,236.66916433461517,232.14615578775886,1.0194834522738834 -2207,1218.8110734642348,1115.7200708934406,1.0923986269138652 -2208,1299.7090729640834,1248.659414635597,1.0408835729984742 -2209,1669.4464991459392,1527.307004384992,1.0930654376316327 -2210,614.9447434317078,579.4862908195089,1.061189458963824 -2211,144.03098427711686,132.80582992818012,1.0845230541084467 -2212,152.0149268641806,141.75134580105424,1.0724055281812361 -2213,331.75177227932875,312.8323572548589,1.0604778073166408 -2214,1810.1326301445583,1656.286102029312,1.0928864451176346 -2215,571.1582665314965,531.5916464126468,1.0744304775777762 -2216,767.913829605514,709.4944779781799,1.082339402829194 -2217,1630.0597181463777,1478.2732031394385,1.1026782564174114 -2218,757.497435528419,704.4855665631,1.075249049067027 -2219,765.624397661923,708.0941729228226,1.081246572756885 -2220,661.7892733981292,615.2079152773451,1.0757164479910577 -2221,1111.499610044447,1069.903442185195,1.0388784316594917 -2222,843.931143336503,829.7262309269291,1.0171199991998625 -2223,669.4678164948963,629.4064619319048,1.0636494173256927 -2224,1143.6863665227343,1100.2951122152335,1.0394360147798356 -2225,1024.9157986641185,1001.5499821315266,1.023329655982684 -2226,2190.653471540826,2007.0138001340083,1.0914989580014627 -2227,2986.9508276959828,2841.6964916356224,1.0511153589019477 -2228,770.9398133698959,747.2829581651321,1.0316571587057872 -2229,1697.6866689254316,1628.3451422483547,1.0425840473729868 -2230,327.60680131163656,311.9313825372078,1.0502527788224674 -2231,156.50236350333057,142.7950332465729,1.095993046432423 -2232,430.23393252483976,413.29629191830213,1.0409818353993017 -2233,192.72039048983515,178.5457811864238,1.079389214403287 -2234,2618.6975617587423,2483.958608416793,1.0542436387166 -2235,1573.7011930470696,1472.6780830326566,1.0685982301076813 -2236,3043.387128640438,2841.5551207716526,1.071028714661701 -2237,2192.405835595776,2028.586850460841,1.0807552238139173 -2238,3047.7682646036214,2845.844447593503,1.0709539192069577 -2239,3787.2833614026454,3649.632160986114,1.037716458630543 -2240,1642.482325528904,1575.1168464435698,1.042768559829347 -2241,2791.5019560143537,2631.8709380429113,1.0606530569808814 -2242,1432.7168225783569,1370.993357892432,1.045020980102201 -2243,1636.7741844038062,1558.332366491818,1.0503370266822987 -2244,5449.148735774608,5192.68880648477,1.049388657562064 -2245,2804.2622935799664,2686.041837370123,1.0440128871282182 -2246,922.1978442179126,880.9344671765704,1.0468404615539597 -2247,891.2727045668427,852.5479201731955,1.0454224137756154 -2248,1351.453504639286,1292.3955217361342,1.0456965239432403 -2249,1277.1021294326595,1225.0102921188027,1.0425235915559188 -2250,1272.506246874689,1202.9812378527658,1.0577939263176042 -2251,1155.910453500445,1083.4729726342039,1.0668567492644758 -2252,1202.0514431415324,1126.0198722768475,1.067522405897639 -2253,1271.3801895669733,1201.789531025302,1.0579058618378048 -2254,613.8404076909477,547.8580302661387,1.1204369996963557 -2255,813.0501989848052,792.0187080953255,1.0265542854916356 -2256,3297.7223209756303,3114.6397742640206,1.0587812909295014 -2257,1177.397422184554,1121.9970644952257,1.0493765620628004 -2258,1319.6688487497458,1251.7571844639622,1.0542530653138336 -2259,1219.0029277171043,1151.4421796655195,1.058674894184622 -2260,1158.1477500675453,1103.6302655003938,1.049398323216909 -2261,1341.45441471742,1282.3144485089156,1.0461197066579673 -2262,2343.9694860358363,2189.6143405556286,1.0704942156348132 -2263,1035.4732584273556,968.0548877739781,1.0696431281994812 -2264,816.2609022180754,775.2232994902075,1.05293649294965 -2265,2143.9805897014503,2003.7876261640665,1.0699639830622973 -2266,1017.4546522515276,968.2141130447997,1.050857076490941 -2267,1027.2196134347241,977.2930272700789,1.0510866083881798 -2268,1446.4868934018348,1283.7196143005763,1.1267934814487826 -2269,1373.2595497035566,1294.2850661793834,1.06101784343174 -2270,1090.7713330260688,1048.0480864105039,1.0407645862528019 -2271,1432.3565788622968,1269.0887655656124,1.1286496403771398 -2272,2145.4887543794966,2018.955245160995,1.0626727657890265 -2273,1226.7201227588657,1175.0770835923925,1.043948639529751 -2274,1348.7144000780158,1195.832296320273,1.1278457725453481 -2275,1055.9008953294217,1006.4123181089434,1.0491732626181163 -2276,1245.5139592025434,1142.0101185305757,1.090633032923689 -2277,1018.7681643874619,959.5395165535376,1.0617261163424108 -2278,466.8354265737036,453.34646545074054,1.0297541993838017 -2279,370.0805086653339,337.4965014845459,1.096546207256848 -2280,668.67391828112,625.0826589087158,1.069736792008447 -2281,947.2437526487699,904.4773315684669,1.0472830214618438 -2282,1101.343223927256,1051.6269829755317,1.0472755470870996 -2283,1948.6710261296193,1847.2401743572198,1.054909401159865 -2284,832.9147133953832,794.3570246897053,1.0485394948458338 -2285,1004.8486994766341,958.33184327815,1.0485394036781295 -2286,979.7461367495915,934.602700131732,1.0483022749789794 -2287,944.4454514650736,891.1953095775447,1.059751371349532 -2288,510.5478761462964,495.89280613164766,1.0295528990004308 -2289,258.04934098710294,237.98781648455866,1.0842964349977382 -2290,303.73898603054636,287.1879863595244,1.0576312396657919 -2291,507.71080805044426,473.2792019570206,1.0727511497463826 -2292,726.8475160825728,648.5221594260626,1.1207751431744872 -2293,1127.5459392949388,1058.3416575390452,1.0653893582123695 -2294,210.52875319679586,191.82639226331156,1.0974962866830775 -2295,170.93140774589563,162.04522996473128,1.054837638745049 -2296,218.2831770195717,213.54137548674086,1.0222055398960623 -2297,176.7873522103319,162.80055898365876,1.0859136683190203 -2298,359.6911868677615,323.1757021579109,1.1129895733683848 -2299,406.6514050515002,393.9078547642312,1.0323516023687735 -2300,446.7273673716195,432.07478579762426,1.0339121421930375 -2301,148.5498435062265,137.66457352700056,1.079070959945196 -2302,151.77144336863515,140.87602978436863,1.0773404361334113 -2303,128.99909752611066,118.78139949866889,1.0860210274551974 -2304,141.11238522398568,131.12247571968737,1.0761876211493646 -2305,811.101316429877,746.4058479651401,1.0866759935511094 -2306,1626.829260822661,1545.1473084252311,1.0528635373158548 -2307,2471.370607803723,2266.897409973479,1.0901995815649355 -2308,3082.051988075531,2839.4383441930345,1.0854442373713338 -2309,1008.8096398193485,960.4084071687043,1.0503965107857933 -2310,501.59066847182027,445.8858883836269,1.124930574255507 -2311,1015.9512284522157,978.0640265312707,1.038736934283651 -2312,997.673612389302,928.4869591853638,1.074515481902558 -2313,5643.374226622121,5351.050887879198,1.054629145726323 -2314,1212.7850008247235,1141.7472369213756,1.0622184679814906 -2315,1462.4926038782653,1389.6293943346468,1.0524335551915303 -2316,2410.628106964676,2237.078124164843,1.0775788654518375 -2317,1115.400357817583,1025.0340701529435,1.0881593015256128 -2318,1622.0631684059697,1533.7192496601986,1.0576011018739864 -2319,1389.7220982624856,1226.7023286669955,1.132892687806859 -2320,487.6673111571152,446.7026328995276,1.0917045820654507 -2321,986.195245294007,919.1912969374323,1.072894454701452 -2322,908.0811558008506,814.7011552761504,1.1146187162249062 -2323,243.97052046040216,237.00982224203977,1.0293688175136217 -2324,249.61139610723438,242.49087570730782,1.0293640755725637 -2325,252.3289987326382,244.7409904985001,1.03100423929266 -2326,74.650020966633,74.650020966633,1.0 -2327,330.4984316854444,321.55500108688454,1.0278130664064633 -2328,110.11723501748521,110.11723501748521,1.0 -2329,113.66185824304031,108.13273771911946,1.0511327155914894 -2330,106.10647286946453,105.99654211682841,1.0010371164043725 -2331,218.1992260011354,190.51549657418173,1.145309593837551 -2332,1129.5796944851074,1055.6569069860702,1.0700253908346877 -2333,794.6800983758836,759.4311953566399,1.0464148737038519 -2334,788.4980723880873,734.4551968221767,1.0735822631519825 -2335,1071.0522610039013,1023.8725912126922,1.046079629629824 -2336,984.7017782764209,954.8906181552273,1.0312194502222531 -2337,2077.894612864239,2029.1818425119004,1.0240061138591885 -2338,625.7355859745471,594.3298238554063,1.0528423122289443 -2339,1442.10783684483,1408.7915567661805,1.0236488357121656 -2340,597.3126532751041,560.9173981598348,1.0648852312919317 -2341,1255.882004126128,1221.7836954898912,1.0279086296225002 -2342,1349.606604614708,1262.2928777971506,1.0691707355347913 -2343,2165.0762137835973,1964.964587904197,1.1018398128450937 -2344,139.8129978439558,128.95300843833334,1.0842166424586814 -2345,298.94857106730024,251.33651600010344,1.1894354860364866 -2346,1236.0100044438989,1180.888193879009,1.046678263743009 -2347,2073.3108788719146,1982.3975787831127,1.0458602759919675 -2348,1540.3271049448556,1458.2218261474795,1.0563050678059678 -2349,3523.4272979526627,3334.612879124158,1.0566225902894302 -2350,1250.0399367947384,1202.119623040566,1.039863182361973 -2351,861.9132427423845,812.1719622844964,1.0612447643698197 -2352,507.5682552006303,469.8313331121388,1.0803201477400923 -2353,595.6062873847743,554.3069958825072,1.0745061704236925 -2354,956.7583043507019,889.2452161517584,1.075921789594898 -2355,950.3526587635205,883.3593988457485,1.0758391884495817 -2356,759.538333929338,637.3249515001369,1.19175992112271 -2357,615.9026495911926,538.5587196875277,1.1436128078077352 -2358,581.2837640753581,552.2044316040452,1.0526604474847172 -2359,642.0128166104366,585.7030665809075,1.0961404391447738 -2360,1204.948066116563,1132.84813237836,1.0636448361236492 -2361,698.3761649054194,659.6791050716648,1.0586604298002598 -2362,509.4070485220213,474.5360844997336,1.0734843253470374 -2363,761.4423259804896,720.9971111718427,1.0560962231081772 -2364,399.9980536526625,379.7107041875485,1.0534284370742775 -2365,592.596508473301,538.9988052334983,1.099439372999322 -2366,900.3973805195562,798.6885824805709,1.127344750219288 -2367,371.52724098365485,345.7506818998697,1.0745524461214226 -2368,144.67307696333958,138.50173481029282,1.04455786897904 -2369,1019.5480948570023,902.9304209916291,1.1291546625899476 -2370,3340.253114980357,3164.1968069262307,1.0556401256927983 -2371,1344.6401671036954,1277.9206532992866,1.0522094338425119 -2372,2328.2837326577464,2240.4680548485844,1.0391952376286377 -2373,1001.3566266816647,960.1378624785084,1.042930047667065 -2374,840.215163300122,803.3972824834525,1.0458277388029724 -2375,825.5545185907213,794.8358792874125,1.0386477763571125 -2376,849.7556309778574,812.5443104913212,1.0457960507581865 -2377,618.1654138261656,597.0541703366849,1.035359008509355 -2378,1068.4973959151007,1030.4491739984314,1.0369239190799013 -2379,1566.0802669784214,1491.4122077768352,1.0500653399591584 -2380,144.15821804417698,140.86606657250326,1.0233707915027161 -2381,920.5245287795748,884.3318979472517,1.040926524211481 -2382,3022.3042527295715,2833.1410977159376,1.0667679965414134 -2383,145.43800712372436,141.93480637381103,1.0246817594599524 -2384,317.325676040142,303.9768214379969,1.0439140541670147 -2385,645.2587970931144,597.6747830526404,1.0796152278626134 -2386,1135.6819198609678,1095.986760850014,1.036218648280174 -2387,1605.9649303092094,1535.0368103609537,1.0462061362108817 -2388,1697.621683699541,1623.0401985448832,1.0459517177834061 -2389,6688.274461881955,6277.629517270931,1.0654140139173973 -2390,4031.1152360022734,3820.598644599578,1.0551004203752887 -2391,1628.338468401982,1580.55299361974,1.0302333898168166 -2392,1103.354212011251,980.5320762027144,1.1252607016021214 -2393,1272.4107442479758,1217.628420967676,1.0449910024576816 -2394,1545.4829701359888,1524.7040778221449,1.0136281476622822 -2395,466.70135132454925,429.609933292556,1.086337431138341 -2396,460.77187792124005,424.906617317527,1.0844073948062602 -2397,571.473364977791,526.1705847796951,1.0860990361463554 -2398,543.7538426293374,500.5615484782235,1.0862876788727072 -2399,2876.935564893306,2680.8498237979306,1.073143127733124 -2400,1223.9459899719247,1145.4078567148924,1.0685678317959901 -2401,3291.1302001208405,3080.9633758806754,1.0682146454207981 -2402,1055.2809381826983,964.028819838487,1.094657043924786 -2403,563.9957070327563,516.9194277157161,1.0910708261151487 -2404,546.3753078716339,504.690417682329,1.082594970557858 -2405,1338.8117409141466,1228.9521647836063,1.0893928822281576 -2406,647.9868098694238,612.3696652752101,1.05816281670028 -2407,1318.6669895129648,1232.997483043119,1.0694806823598761 -2408,1576.774384513409,1482.1368019683748,1.063852123784626 -2409,1275.0134941475167,1193.5998408786656,1.0682084987619624 -2410,1279.8088808141094,1194.4162333910203,1.0714932073391654 -2411,1190.8319032940697,1107.1159295900632,1.0756162669748637 -2412,543.2423929083509,516.8364678544206,1.0510914509642695 -2413,1188.7431400277735,1112.0658585834326,1.0689503061824177 -2414,1348.6890095516897,1278.1772689599593,1.0551658539891773 -2415,2307.5736617433517,2191.2177117557762,1.05310104484978 -2416,1747.6303098990604,1612.1960281481574,1.0840060882090554 -2417,1785.7946441971076,1646.6103362824917,1.0845277749372377 -2418,1117.4858930889623,1038.966774978198,1.0755742339425745 -2419,1351.6776848149568,1256.447431508324,1.0757932651366975 -2420,3322.8418279041157,3172.0704175762703,1.0475309152950796 -2421,2196.314966255032,2063.258988412023,1.0644882579406159 -2422,3811.4508658372674,3660.9040655649715,1.0411228476835441 -2423,2387.122226687485,2325.642230461548,1.0264357068428946 -2424,873.093545461814,826.8897718466086,1.0558765813634665 -2425,1507.6819999861987,1447.9941697844836,1.041221043183205 -2426,1528.9105821038086,1491.3613115084454,1.0251778494625046 -2427,218.18552119450393,204.48940926957033,1.066977121083462 -2428,384.0206095391821,371.54690561776994,1.0335723531344505 -2429,221.6215169131476,207.96762068785893,1.06565395218798 -2430,327.7633769854844,321.20289995852113,1.020424712939424 -2431,897.1375440456117,841.1935989489818,1.066505433667741 -2432,6548.304665781314,6286.795480339556,1.0415965790933657 -2433,2033.983721606127,1964.908639599525,1.0351543479500809 -2434,983.8161891049815,917.8955815974538,1.0718171095156632 -2435,2820.3387371752556,2594.984017596281,1.0868424306473068 -2436,1774.4226639104113,1644.5745325164607,1.078955455545856 -2437,1911.4465022012198,1768.0896414339848,1.081080086330333 -2438,651.5929179266589,617.1997978848832,1.0557244512387065 -2439,2069.1262153800244,1914.2007540120214,1.080934803229646 -2440,978.2588718948923,911.7965185583237,1.0728916506959851 -2441,998.3301587376848,930.4700650145068,1.072930980022576 -2442,620.9329434479146,585.2816476964168,1.0609130593652065 -2443,4895.384224544075,4577.261786516065,1.0695005994555853 -2444,553.0299509198171,543.7271407873171,1.017109335610927 -2445,520.1458493262512,500.6322132975957,1.0389779872536005 -2446,2306.5710988136916,2212.3092857738957,1.0426078820199056 -2447,168.98347146753505,167.4334475764683,1.0092575522603322 -2448,3270.685581082847,3108.3404117698037,1.0522288899562993 -2449,3477.4623204856466,3306.5086095285224,1.0517021823153518 -2450,2144.496909164364,2027.2069664979992,1.0578579023280406 -2451,1415.7886453062702,1328.8420949693857,1.0654303100918003 -2452,4887.325530268643,4569.825629843506,1.0694774650375467 -2453,829.0823992527862,790.4317670415069,1.048898126091192 -2454,5755.884466398039,5372.525997332642,1.0713553492818326 -2455,1717.8979142455169,1613.3957402177575,1.0647715693197843 -2456,1005.4359128721643,946.9630636338844,1.0617477613265038 -2457,2364.0587308034796,2178.786538369511,1.0850345773536019 -2458,5079.4024225480825,4745.444030751538,1.0703745296820317 -2459,2639.753323557394,2533.4855159538483,1.0419452990492177 -2460,2710.902912767601,2598.3512699722173,1.0433165615812163 -2461,1637.1225277569652,1550.3990517331752,1.0559362287579077 -2462,1260.8500642848142,1156.1111798832037,1.0905958581009412 -2463,1922.3057181010643,1789.9124627633726,1.073966329690389 -2464,2622.977687028921,2531.0937024234668,1.0363020873219657 -2465,2381.1569787920757,2282.504551506321,1.0432211305868588 -2466,1538.2721978511142,1479.5944181283683,1.0396580164157223 -2467,2674.187924377598,2578.014743385084,1.0373051322686515 -2468,628.2776553585273,601.7803364876796,1.0440315465033314 -2469,499.79083683205306,465.76036965957525,1.0730643253253829 -2470,284.39532082867834,269.5625836031863,1.0550252079766635 -2471,383.21702425218575,354.7689317943532,1.0801876655713554 -2472,279.9533834973556,264.4987701098317,1.0584298119084126 -2473,275.96212775165833,257.09235928342093,1.0733968466462094 -2474,3135.558001731709,2923.019599296651,1.0727119320329566 -2475,916.8565703173186,895.3853672566065,1.0239798458249305 -2476,606.8137566500685,554.5505590038988,1.0942442430137416 -2477,161.1096907291657,145.75571942999426,1.1053404378175764 -2478,496.2739272541063,426.5783711992465,1.163382770342818 -2479,15.252822956117864,15.097877967141713,1.0102626997855835 -2480,12.461605875185747,12.461605875185747,1.0 -2481,562.313135093433,546.8528829484338,1.0282713187167323 -2482,340.75002883264534,322.6682969995095,1.0560381419596463 -2483,305.37598286666383,286.505505992688,1.0658642730393373 -2484,127.11004753274476,109.52576609268567,1.1605492667832926 -2485,125.09084201074165,107.52787432522777,1.1633340917015909 -2486,747.0616048637801,718.3525638420973,1.0399651124903528 -2487,30.91684644534162,29.81397365226026,1.0369918081348324 -2488,234.60477565253794,230.70856562341436,1.0168880163534255 -2489,235.25155815551298,231.44647221499537,1.0164404577183748 -2490,240.11183509745882,236.26390473948425,1.0162865773433207 -2491,238.4338829742511,234.62090232670414,1.0162516664531343 -2492,276.77919127113597,249.06609049707276,1.111268060291768 -2493,338.2374167083275,320.2667545146029,1.0561115443311029 -2494,287.3406469563991,256.8291609322988,1.1188007074949844 -2495,316.01601785005,297.1901200692495,1.0633463110294978 -2496,270.79536159054805,260.4492275478852,1.039724187858306 -2497,603.3092525128169,567.3658077647922,1.063351446731745 -2498,207.03220478372978,198.88183517485922,1.0409809654144868 -2499,209.398053935429,200.45233682356275,1.0446276519077962 -2500,1873.7929850810492,1762.7453751579994,1.0629969656922778 -2501,430.598125681436,396.9482090721907,1.084771554173017 -2502,463.9474519906994,426.8167533423862,1.0869944732898698 -2503,429.1242687281631,395.62188760677026,1.0846828301741804 -2504,463.3163776165783,426.2095255761907,1.0870624653220105 -2505,1423.4583647894924,1299.1996759825925,1.095642487528272 -2506,783.911875541348,737.1580796645522,1.0634243823225424 -2507,1480.6393622007736,1374.7558887480336,1.0770198362628336 -2508,271.6142610362014,238.3150171491398,1.1397278454602071 -2509,275.79638406833743,242.06239246975153,1.1393607294978767 -2510,390.5283554740046,360.71037218005023,1.0826646129240516 -2511,376.2937090226481,346.09008371602323,1.0872709930961437 -2512,359.08594281074943,345.80905069144205,1.0383937091662592 -2513,280.00043635810044,275.5563252750364,1.0161277774285469 -2514,361.18920802937913,330.79119121925663,1.0918948799636383 -2515,273.7700629669533,240.48933381001328,1.1383875477123313 -2516,277.4753891723738,259.8018972962555,1.0680268006509783 -2517,143.57387928481484,142.053795071247,1.0107007645434987 -2518,291.2399520828572,272.413458012194,1.0691099999538953 -2519,214.1318713423285,202.62080289731838,1.056810891480099 -2520,207.51167705712095,206.85305866811487,1.003183991540888 -2521,126.05148549850504,125.87865350909945,1.0013730047517 -2522,375.0333426200579,360.0177388817084,1.0417079552385144 -2523,270.46474038801017,237.68405822308551,1.1379170416812614 -2524,52.97852670144763,52.72096311230939,1.0048854113038406 -2525,475.69608670999753,461.94219708782805,1.0297740490236151 -2526,341.9752822527585,333.48148712986915,1.0254700649082256 -2527,415.81063730206586,403.78603357123103,1.0297796425113688 -2528,255.41411972986023,247.95292567749638,1.0300911716688852 -2529,1342.2350335344363,1216.5361621447453,1.1033252239440912 -2530,1886.3761751434895,1748.8810986422063,1.0786188818714042 -2531,3413.3456478897174,3235.1039093905533,1.0550961401832506 -2532,2693.198870478994,2532.2402709229677,1.0635637152620432 -2533,536.2010146234646,504.4418088887871,1.0629591068286717 -2534,796.7471330701757,737.0561629863969,1.0809856467951147 -2535,278.7968664886253,266.49222979699414,1.0461725908519153 -2536,797.7814840945927,738.013022152366,1.0809856467951147 -2537,1953.6665664711336,1854.2622809329227,1.0536085356210763 -2538,2802.0272587766212,2682.2558690257465,1.0446532305638605 -2539,2698.0203132882334,2582.939635763193,1.0445541490523593 -2540,249.23613808347844,233.02632483400347,1.0695621546665255 -2541,2066.434411998078,1978.0997345137057,1.0446563314999324 -2542,2706.339357798838,2610.8094921643137,1.036590132647071 -2543,368.5668505906128,346.7096329061813,1.0630418529223444 -2544,1149.8026729222408,1071.1320645933579,1.0734462265946163 -2545,1158.773910333984,1079.4894812850198,1.0734462265946163 -2546,739.6073834150147,706.9070265653577,1.0462583559376089 -2547,1150.3937269613198,1071.684115473577,1.0734447869024921 -2548,1144.5713173288218,1066.260848378042,1.0734440067549162 -2549,798.7075495456343,753.9817176684886,1.0593195177403636 -2550,253.292467933093,245.5972622731441,1.0313326198701294 -2551,232.4292998243266,220.7422602489098,1.0529442779204963 -2552,202.39870232436445,198.32900783985497,1.0205199155122868 -2553,158.83891795562295,158.6949591534528,1.0009071416189783 -2554,73.29959662643431,72.99889102900455,1.0041193173374412 -2555,238.4967389517162,226.48692589080218,1.0530265180370915 -2556,223.16146784634054,214.0375084976427,1.042627852532671 -2557,231.9259079925142,231.62854575282284,1.0012837892614872 -2558,901.9254842728429,880.8644870012558,1.0239094634672872 -2559,1067.2847099328828,1021.7326259282366,1.0445831745494694 -2560,841.4858551079088,804.8965909623666,1.0454583415514216 -2561,254.45174832355954,245.2077003032268,1.0376988488081795 -2562,78.23910810857431,78.23910810857431,1.0 -2563,373.49760828952503,360.6237183082206,1.035698955248144 -2564,367.79353245467183,355.1754756871596,1.0355262613306846 -2565,416.0090681922164,398.57047538608106,1.043752846442635 -2566,553.0438265060264,539.0083869807454,1.0260393713053344 -2567,2919.6388138816037,2796.142014712362,1.0441668550879901 -2568,1426.6527326372175,1371.298383574774,1.0403663781168784 -2569,255.43899722714434,240.81009072219263,1.0607487271861384 -2570,2982.9421210160694,2845.022942494934,1.048477351961242 -2571,1977.1193707159046,1865.9135428482589,1.0595985962446541 -2572,3906.5220782121814,3740.019915483051,1.0445190577835801 -2573,1614.587016317255,1551.9907773119305,1.0403328679012784 -2574,702.7624534079401,685.3149126757877,1.0254591581321777 -2575,988.1626025271082,916.6119367907023,1.0780599323056206 -2576,552.3174027357028,511.23385974722595,1.0803615453185949 -2577,598.3532983709572,575.7006699941642,1.039347927764306 -2578,3872.9568251318224,3707.90208066255,1.0445143212734949 -2579,746.6574245625485,725.7038734830969,1.0288734177191072 -2580,4310.897269150378,4163.909758191931,1.0353003593964225 -2581,847.5779641983407,799.0820286046746,1.060689558590559 -2582,789.9263270440528,725.9787356973145,1.0880846617157671 -2583,798.7820856915273,770.6363855935026,1.0365226722020766 -2584,265.87075624573174,262.97234900324315,1.0110217186463692 -2585,563.8547726341224,552.6703211673938,1.0202371125033525 -2586,320.3226275917697,316.83729558779424,1.0110003842745516 -2587,1141.6418660181873,1115.193863001178,1.0237160586105032 -2588,210.48040903236665,202.9056454423334,1.037331458045538 -2589,210.29193748091143,202.7414330194073,1.0372420395232254 -2590,209.0674417923382,201.52890241301716,1.0374067406166456 -2591,209.77805891466497,202.194588049721,1.0375058053634905 -2592,472.3202679321322,442.6941541955081,1.066922306192325 -2593,475.79952977635065,445.95837084626595,1.0669146738370603 -2594,439.0040552743126,412.28368516690597,1.0648106414800027 -2595,448.883549653499,421.38105742602875,1.0652675096395339 -2596,357.20746050788586,338.24604818647424,1.0560580453875938 -2597,356.46817092959895,337.54600183815484,1.0560580453875938 -2598,356.26412238403464,337.36146046366935,1.0560308871510857 -2599,350.6133132149995,331.8336013670383,1.0565937619656218 -2600,178.59105942643356,172.16068610829242,1.0373509972776032 -2601,178.46458934947546,172.02353906578801,1.037442842524151 -2602,208.12410875437425,200.63430290786977,1.037330634582182 -2603,208.96911052872846,201.43978290967604,1.037377560233117 -2604,208.9707557974766,201.45032156954315,1.0373314580455377 -2605,209.95513352685356,202.40340453397204,1.0373102864068378 -2606,207.79694883496512,200.31256534762142,1.0373635247212543 -2607,209.1291105225051,201.61315412956975,1.0372790973157688 -2608,373.0497382508325,352.30315273233407,1.0588884469457498 -2609,379.10753641764427,358.12116065217634,1.0586013284645048 -2610,386.80258059311893,364.82498836495387,1.0602414662621182 -2611,375.19243827386055,354.3637674420056,1.058777653771456 -2612,361.98891450415766,342.08787872097645,1.058175214677552 -2613,376.5007336232215,355.55641574376284,1.0589057515265101 -2614,318.4914085924621,299.873870937912,1.0620845610733616 -2615,329.4028708345084,310.29258081506794,1.0615879695519697 -2616,113.41880359977361,100.46374993528221,1.128952519419561 -2617,112.17899549717788,99.35604418940875,1.1290606063514759 -2618,132.3191899932812,117.17516645284459,1.1292426031801808 -2619,132.3219084763673,117.19639768163238,1.1290612262317468 -2620,126.91704907426278,126.9057752508987,1.0000888361726785 -2621,174.16432897487778,172.85621102745205,1.0075676652846335 -2622,1785.1430508101944,1724.494447293802,1.0351689178307106 -2623,501.9839950233502,491.08481345120504,1.0221940920867596 -2624,887.3361797210297,845.5424990043089,1.0494282437203761 -2625,541.5318675000929,521.4344734763893,1.0385425111801965 -2626,546.9315952384791,526.60707949757,1.0385952193432348 -2627,1218.144871155509,1162.0132550456817,1.0483054869349322 -2628,1650.9947020056259,1576.5338778219716,1.0472307162130408 -2629,849.8011218577227,814.9989228988412,1.0427021410471253 -2630,906.7393369940085,867.0954930779224,1.0457202744479304 -2631,779.6719745315395,746.8765587340777,1.0439100885065244 -2632,766.6549804697792,734.2502055378196,1.0441331506447777 -2633,726.7887725752515,695.5458450065472,1.0449185740853792 -2634,731.0277090834345,699.6054014690177,1.0449143296327286 -2635,750.7873289635957,718.8451525077071,1.04443540635206 -2636,254.90497346309706,254.6682316516811,1.000929608730074 -2637,184.49978692802102,180.7497924654461,1.0207468811522526 -2638,169.72493705772607,160.2875154735333,1.058878082652364 -2639,1010.282270551641,976.5036898751072,1.0345913497580885 -2640,170.0252342538545,160.56954323779033,1.05888844687103 -2641,552.8868155938329,524.6243369766316,1.0538718405251188 -2642,160.52468653698742,151.50870406638234,1.0595080165602553 -2643,3736.563352323259,3655.692290821059,1.0221219553147993 -2644,1019.7205576133074,978.149074452817,1.0425001507911724 -2645,533.5179393056501,512.428562369372,1.0411557404972995 -2646,723.1553150093844,698.3744175896416,1.035483684389917 -2647,372.6277288064253,358.40871136305924,1.0396726334839628 -2648,674.8087648252747,649.0029535083346,1.0397622401831006 -2649,1176.8838618656916,1134.322941636856,1.0375209904221976 -2650,451.71047531534975,434.33283048512055,1.0400099730218864 -2651,691.4739619575053,665.5687106736473,1.0389219788557043 -2652,317.67305959861346,310.0421001591423,1.0246126556217825 -2653,551.5270894926731,527.4643343275881,1.0456196819369035 -2654,465.46837596900343,447.58964164950305,1.0399444773869473 -2655,348.1160074639107,333.9897303848145,1.0422955432276924 -2656,249.8150055349058,242.52239644188452,1.0300698376727808 -2657,1560.9859858610525,1443.6107581968533,1.0813067005754426 -2658,1945.921271062619,1882.6807312622275,1.0335906873376202 -2659,526.2010061446722,473.03408456388917,1.112395540439332 -2660,238.5314734332977,228.80789197843401,1.042496704859202 -2661,1447.5772876553037,1382.6233721362544,1.0469787483909596 -2662,2068.5428626500693,2014.8115689454276,1.0266681482937707 -2663,537.52422455815,480.94682707520485,1.1176375314231946 -2664,176.9821702845557,175.90661376435716,1.0061143608940102 -2665,828.0873044239014,802.328119781182,1.0321055488491975 -2666,733.7472889660163,709.4864479648041,1.0341949322228854 -2667,884.828425465755,857.2489150477567,1.0321721146960703 -2668,299.0137147304503,290.4653025856108,1.029430062967056 -2669,836.284486943913,778.8540056562637,1.0737371585310886 -2670,262.8094804820694,210.382928940238,1.249195844006544 -2671,535.2414787220464,522.53989386315,1.0243073974027002 -2672,2965.0935077891318,2866.723025581494,1.034314609862836 -2673,851.6978731480101,787.3332581889242,1.0817501538130647 -2674,458.9785323939216,399.47273862882787,1.1489608376515121 -2675,3425.3335230915814,3319.333229354012,1.0319342128112272 -2676,3690.796663970903,3549.064666469676,1.0399350281893316 -2677,918.945322260851,856.9626402490995,1.0723283362664846 -2678,718.2549549508068,649.3927547002021,1.106040912455815 -2679,592.361870067468,579.6824980394262,1.021872959889121 -2680,2230.214077396445,2143.172643158351,1.0406133563322377 -2681,546.0672247653716,526.7431424172629,1.0366859685337888 -2682,364.31337978579074,349.6390081537721,1.0419700642371255 -2683,264.375099425789,244.9952576796848,1.0791029260306828 -2684,291.47255196424817,268.7377417443119,1.0845985013953383 -2685,274.53876257510865,252.9373241406155,1.0854023363609409 -2686,1431.9183710981365,1384.3428378248343,1.034366872116777 -2687,1502.0692540441742,1457.5543124671235,1.030540845851365 -2688,2366.6643864585367,2279.030653439298,1.0384521958434345 -2689,1515.7624270927902,1470.8227710144454,1.0305540932354136 -2690,2221.3167743142026,2148.9973891608965,1.0336526165727655 -2691,882.9969024961538,865.2368198975558,1.0205262677109612 -2692,1832.5963311315888,1733.2877454553611,1.0572949217096888 -2693,2921.1089899295393,2806.1286412172194,1.0409747247590349 -2694,1944.5501346224312,1824.4265695532079,1.0658418196017836 -2695,739.593493499077,711.9943820350796,1.0387631028563897 -2696,1155.6182974601315,1072.4485477842852,1.0775512725973455 -2697,1861.0717090023484,1718.8509696048798,1.0827417512701298 -2698,1427.5322219002394,1327.7193995202585,1.0751761421999604 -2699,1807.418593205153,1669.119487456764,1.0828575226565207 -2700,2420.924294299497,2314.8252409088454,1.0458345846224637 -2701,1339.2596512803598,1265.004678056266,1.0586993665020985 -2702,431.3232705129539,410.9064612280465,1.049687243232655 -2703,1016.2980349557579,951.8633863582229,1.0676931684955953 -2704,3525.793670389413,3339.7482931006484,1.0557064068789563 -2705,1144.9092501593373,1107.4117957292262,1.0338604434002974 -2706,1065.8206348338206,1047.1572011620033,1.017822953087757 -2707,2349.941688931126,2252.448593818609,1.0432831609920277 -2708,909.1342444178483,863.3389794502749,1.0530443615516274 -2709,1333.2787202218653,1301.123914650009,1.024713100120449 -2710,2670.1415198480872,2544.625116582905,1.049326088329166 -2711,931.9781307077069,868.7282779231239,1.0728074064030642 -2712,1302.0451071968605,1238.4289252375092,1.0513684561648549 -2713,3188.1236196023006,3012.692551749939,1.0582306574065985 -2714,1113.3772353593063,1058.9626727058326,1.051384778761309 -2715,1467.1069109951418,1428.8887618081744,1.0267467630850455 -2716,1771.7475908934782,1718.3657267463536,1.0310654846731613 -2717,2072.5340877280396,1963.5658707910254,1.0554950656649558 -2718,628.2928662001901,606.4016621884923,1.0361001715145253 -2719,1187.3213596528187,1080.1549627944335,1.0992139096237994 -2720,4131.850341379386,3907.913836439778,1.05730333735905 -2721,2030.3161705125133,1941.877833661917,1.0455426882770595 -2722,2935.383964528094,2802.286833065546,1.0474958986682128 -2723,5341.316009073344,5103.187316655035,1.0466627379404905 -2724,1271.2256619945542,1177.013071544531,1.0800437928241469 -2725,2332.07363791071,2205.114358917732,1.057574918271037 -2726,908.0042659632031,865.0163147775332,1.0496961160746727 -2727,840.0537580379289,804.367453393123,1.044365674536268 -2728,836.9080252580452,801.3319606775864,1.0443961632958911 -2729,969.8822727968411,920.1803970600566,1.0540131868659453 -2730,360.89049717852845,350.90765996288786,1.0284486158458221 -2731,1906.07647258786,1827.7894600686643,1.0428315264036234 -2732,3329.5400815177027,3187.944506251098,1.0444159473256063 -2733,1835.5411086997551,1717.7514992231968,1.0685719730297574 -2734,1937.2328191548847,1855.3659087063877,1.044124401588028 -2735,1883.610723207381,1804.0356829931645,1.0441094602309582 -2736,1593.017501447234,1525.8398478743843,1.0440266740093553 -2737,466.18013875598473,445.2761513538199,1.0469461194780099 -2738,111.60609726265925,107.22076011398367,1.0409000751721367 -2739,472.06615438854004,450.91008047779275,1.0469186093341047 -2740,2028.0452437150457,1950.8926371792295,1.0395473359555911 -2741,1376.1989121591866,1336.4098241687332,1.0297731184483045 -2742,19.01342755254413,18.8405781021726,1.0091743177642516 -2743,1380.0255408398525,1347.0807418897384,1.024456439711177 -2744,18.914518402484358,18.914234567037045,1.0000150064464046 -2745,1773.0802574574213,1683.4082810729185,1.053268109342643 -2746,56.961840667233425,47.1944658175767,1.206960173835023 -2747,151.81479931488633,139.51651093550737,1.0881493401527504 -2748,1265.7777456189892,1224.302908938772,1.0338762869690212 -2749,678.1699475296793,612.7347764809244,1.1067919980396153 -2750,934.5085294628645,822.8810284733004,1.1356544836094566 -2751,1533.7493145190078,1434.1228614386923,1.0694685621149442 -2752,889.8255503230426,726.1719255031131,1.2253648469080451 -2753,1310.57841432554,1255.9045259373781,1.043533475084306 -2754,6955.693982276586,6569.799509217439,1.058737633091807 -2755,1883.2021412072222,1752.2606079537654,1.0747272024829493 -2756,1929.203010206194,1843.268083250799,1.0466209596619498 -2757,2931.574934142544,2763.926038236801,1.060656071684426 -2758,2795.1331752118094,2667.457198401914,1.047864301960079 -2759,5253.060461866992,4999.218538753743,1.050776320568 -2760,787.1247323158121,744.0574219791441,1.0578817024929499 -2761,2365.4389105911378,2235.245384411842,1.0582457420949125 -2762,964.7068498873414,909.4055779414629,1.0608103505050617 -2763,947.7834361102716,893.3194776487225,1.060968063301275 -2764,5325.396055976353,4997.873861093924,1.0655323051331955 -2765,5359.69697581554,5106.929319253029,1.0494950371859626 -2766,2188.859029519461,2063.2485628443214,1.0608799487067022 -2767,2304.2282301628534,2166.289839271616,1.063674947087236 -2768,1210.794218727556,1116.3934886877228,1.084558653374804 -2769,2342.8602093790623,2239.6166822969262,1.0460987489056612 -2770,1919.8292985157404,1826.681974860166,1.0509926330568324 -2771,2779.5560217173297,2632.2491909466885,1.055962342500583 -2772,881.1563650896767,852.0342168685753,1.0341795524693036 -2773,468.60289308728494,455.6700263650292,1.0283820878573555 -2774,862.0615889008977,836.3751048138092,1.0307116794118432 -2775,917.5854630068765,862.0380826019473,1.0644372696821778 -2776,237.12743513620129,229.28951368804059,1.034183514640903 -2777,332.91439208485116,331.8516207113613,1.003202549896281 -2778,293.812049537955,286.9375514416708,1.0239581681161787 -2779,190.91575327341624,183.73955693212486,1.0390563494389091 -2780,474.68775461986814,458.63831259189135,1.0349936793053267 -2781,327.5329664717575,303.64559913534873,1.078668577461454 -2782,295.7142165248577,268.87310881005794,1.0998281599583888 -2783,254.50549186607574,243.25356226092947,1.0462559705213144 -2784,336.36736495241405,330.0743896278393,1.0190653244308658 -2785,1082.6524975018287,960.5630040300695,1.1271020151302198 -2786,1956.5017729122562,1865.2646604942497,1.0489137624007903 -2787,1087.5980285184278,1034.3621740928354,1.051467325235749 -2788,221.0341127790648,214.2155980079647,1.031830150719681 -2789,389.985765907709,378.3792991173737,1.0306741590182367 -2790,837.3110829366342,799.096185482028,1.0478226503253227 -2791,743.7433221634444,709.868944503789,1.047719199328172 -2792,461.55896281416597,443.7681677192781,1.0400902912579844 -2793,1219.105107027842,1177.7975628782106,1.0350718539854058 -2794,337.9296396950561,324.6049367669131,1.0410489842232775 -2795,415.7282256113903,392.54027612213144,1.0590715167328317 -2796,420.40075773011034,410.54556678714204,1.0240051086657525 -2797,162.6174962929763,147.14239592057623,1.105170914715519 -2798,2158.5363885871398,2086.7615435232156,1.0343953267141113 -2799,590.7613870732557,572.2455086197128,1.0323565291026997 -2800,248.8402628908143,222.35906610567807,1.1190920489500114 -2801,232.49424849045593,222.8829477810568,1.0431226381609082 -2802,151.83405109304388,148.93750714111653,1.0194480491014457 -2803,167.14170624590278,160.65923838906988,1.0403491758197823 -2804,177.22198518527225,171.45716636788654,1.0336225014066571 -2805,148.0455062500798,142.55516114906283,1.0385138290102032 -2806,244.3835134897812,220.6487375942773,1.1075681472474441 -2807,255.7209190490819,250.51797428776862,1.020768748334747 -2808,4936.834406215937,4704.136577209011,1.0494666396665264 -2809,784.5695016958142,691.2571925551401,1.1349892777184099 -2810,854.2976296223037,821.0852153556309,1.0404494121262282 -2811,744.2124325329546,711.6350110648232,1.0457782725155493 -2812,1532.5066466921428,1489.9423784907729,1.0285677277295013 -2813,1888.268043245527,1814.3814644033307,1.0407227368068899 -2814,554.5475468051685,516.9003574183074,1.0728325853262948 -2815,499.8565736339191,475.7044718513607,1.0507712313246973 -2816,316.278215587313,290.3484118556324,1.0893058224977428 -2817,115.24397982430615,112.10527560251157,1.0279978279784387 -2818,476.18465658212375,459.98007992454967,1.0352288661287943 -2819,474.42399364429815,458.3651620478621,1.0350350177676881 -2820,714.6989273006097,678.115071091727,1.0539493336285606 -2821,551.2953221647357,512.2475878952171,1.076228244294839 -2822,574.5865309277104,533.8806630776488,1.076245256037942 -2823,540.283622712814,502.00753090129297,1.0762460510160097 -2824,2191.2122387469176,2035.9765986020452,1.0762462791819225 -2825,2174.2459545516335,2020.3241340014445,1.076186695966123 -2826,1097.4094982219742,1031.041743240122,1.0643696100734843 -2827,1085.3927765100475,1019.759652411709,1.0643613658798106 -2828,814.6973578136327,765.8006463729058,1.0638504442015275 -2829,722.4222221513662,679.1243541804693,1.0637554340443975 -2830,34.801946841046195,33.564064292450574,1.0368811875048771 -2831,29.68132750345774,28.84030954178963,1.0291611974708341 -2832,85.17911629452557,80.3649253179701,1.0599041305334105 -2833,85.58113317231098,80.74431672778559,1.059902871688565 -2834,18.607096229191058,17.83667886492608,1.0431928707187705 -2835,18.012021901316334,17.267595990083066,1.0431111494420415 -2836,19.32363179921504,19.157767367212916,1.0086578163740514 -2837,18.79950626952022,18.280010309119906,1.0284188001874996 -2838,632.8474994381477,594.290144471005,1.0648796809535916 -2839,433.87161325812696,399.3307371158813,1.0864969132897533 -2840,2038.2672377441356,1843.626929979306,1.1055746716430392 -2841,999.8869825602359,938.1690387743313,1.0657855260993647 -2842,359.5602934482665,333.33886842942184,1.0786629688352607 -2843,1663.2062594445972,1604.075498338442,1.0368628291918958 -2844,1366.700397706279,1281.8839641109873,1.0661654533248754 -2845,432.87981896356695,403.4386700224618,1.0729755254732176 -2846,239.94634631493278,226.8903976554269,1.0575429757910408 -2847,2510.054421221148,2449.6864162804522,1.0246431561768454 -2848,1207.1631367522293,1149.9843798775112,1.0497213335026416 -2849,380.18645591990804,320.8640148146373,1.184883434621178 -2850,2425.2105306105723,2303.6413228372376,1.052772628519967 -2851,2755.3174200802055,2589.552593119695,1.0640129215374652 -2852,2569.3121585757663,2434.1825718567843,1.0555133325993316 -2853,1085.018103500167,1004.0310765850445,1.08066187272866 -2854,1463.390865177504,1362.9228615807924,1.0737151062828187 -2855,1339.7488593960693,1268.0300212559553,1.0565592588013635 -2856,120.12521326449135,112.81673025952239,1.064781907684761 -2857,119.39694298828056,112.14248046543021,1.064689692012713 -2858,121.05557571289042,113.70404882876429,1.0646549261864664 -2859,191.14644377319593,183.60199569899976,1.041091318454755 -2860,179.3442499422903,171.62698830644615,1.044965315257206 -2861,179.584479397503,171.6603582656017,1.046161625269596 -2862,194.15368544181223,187.5515201419659,1.0352018757024675 -2863,230.43301845418347,222.54790084438517,1.0354311030563794 -2864,222.96193170026731,215.33059020719008,1.0354401178473267 -2865,84.61999365182531,79.8540930570766,1.0596826087717537 -2866,85.06943932435722,80.2641886652139,1.0598679278898124 -2867,84.80825388349216,80.01511844069813,1.059902872559595 -2868,84.97540420481467,80.17376948441924,1.0598903450751254 -2869,2353.7640858618647,2240.39626081532,1.050601684634703 -2870,1036.5138541817455,987.5977767509555,1.049530364063512 -2871,1908.3987240137199,1851.4691911884336,1.0307483014549887 -2872,1216.45363249325,1172.5368081589743,1.0374545379118891 -2873,948.9090812004177,903.1967094643813,1.0506117562841266 -2874,1897.2233944164607,1840.5605798434467,1.0307856286794068 -2875,1914.9884043056359,1857.8152279737803,1.0307744147377946 -2876,1349.98802752943,1304.889701225592,1.0345610255498838 -2877,1917.3139258803367,1860.1318002843295,1.0307408999659415 -2878,2986.2196451852597,2851.3275767146515,1.0473085132596491 -2879,3325.748192523468,3181.9262254260166,1.0451996548342963 -2880,1770.4933482731544,1699.9705638585865,1.04148470915549 -2881,1880.0738702572517,1756.8780960163201,1.0701219820090393 -2882,2936.9146993410895,2815.4431478175575,1.0431447360667514 -2883,830.610444318352,805.3310322477478,1.0313900881231999 -2884,80.40174368648408,76.85889502714487,1.046095493021178 -2885,76.44154865238009,73.07969685940772,1.0460025415737557 -2886,76.57215243591739,73.16156608950739,1.0466171861635305 -2887,75.54994188917013,72.22730240741288,1.046002541573756 -2888,75.40310643794484,72.08692468805823,1.046002541573756 -2889,77.72135943963957,74.24419086234501,1.046834217423711 -2890,75.66103653107656,72.33364468431482,1.04600061093677 -2891,75.19413263285554,71.88723312766194,1.046001207186831 -2892,76.19878669026095,72.81988801264913,1.0464007672879816 -2893,258.66249615315024,248.33302408276535,1.041595241343907 -2894,257.655834477767,247.36810541596842,1.0415887450182753 -2895,258.70449050498206,248.37381119849854,1.041593271273787 -2896,259.1825926379491,248.81567156013497,1.0416650647960033 -2897,1391.3753012690609,1293.9211777737635,1.0753168934625297 -2898,1245.8080210149928,1169.4654565638066,1.0652798798140652 -2899,607.6769027077635,514.0689324695036,1.182092253248183 -2900,1410.2704955541908,1311.4845514272913,1.0753237573552739 -2901,1317.6006788726165,1230.6435994506276,1.07065983966504 -2902,1262.3868092282164,1186.4517838660247,1.064001779418932 -2903,1409.7368719005867,1310.9892805176228,1.0753229586621602 -2904,1409.3021618702753,1310.5844218179584,1.0753234499120492 -2905,1411.8862173002387,1312.990860009225,1.0753206745782824 -2906,29.09430641528018,28.886243045413234,1.0072028532592432 -2907,26.308706828995643,26.29793228608134,1.0004097106493808 -2908,26.20363132207452,26.193996850286375,1.000367812206866 -2909,26.35464405421052,26.341709231723584,1.0004910396046494 -2910,1083.0270312430252,1019.9555991067214,1.0618374291896058 -2911,777.9421055526296,725.689505378124,1.0720040730743092 -2912,363.260266559763,338.09431138955773,1.0744347193147792 -2913,215.10684267964513,212.22331704378087,1.0135872234777548 -2914,383.08720266384336,356.02765635364005,1.0760040570649523 -2915,319.4954268093887,261.6133748208715,1.2212503547578537 -2916,163.80561944873403,140.5670192051805,1.1653204313142118 -2917,171.44076622551367,167.9561817307106,1.0207469856655234 -2918,386.6555011254162,359.35556587482773,1.0759691454454825 -2919,130.86999721041067,115.67054729163368,1.1314029394229066 -2920,51.160635026955326,46.85880493790787,1.091804093056743 -2921,258.005747612486,246.53809954500812,1.0465147094450784 -2922,256.5240226523913,245.12162670503986,1.0465172987819316 -2923,124.67001532117627,119.11814795514375,1.046608073256169 -2924,257.56171547282963,246.1134321834587,1.0465162879888534 -2925,257.20571875259714,245.77004009825913,1.0465299946639794 -2926,120.72304365937157,115.35541870950466,1.0465311903845973 -2927,100.45793348965923,94.84877667817021,1.0591378930539226 -2928,99.58125095639889,94.0210444829482,1.0591378930539226 -2929,276.7805910825886,272.7747894031489,1.0146853808895049 -2930,172.75129122285122,166.67689041652972,1.036444169261506 -2931,113.46263143763339,107.8345461029095,1.0521918581578935 -2932,218.60730559890536,213.26444562436723,1.0250527459412937 -2933,305.14250297687954,298.1106010128282,1.023588231817857 -2934,526.5575823487751,512.9148165406615,1.0265985020673156 -2935,777.3207463947948,757.5484533241055,1.026100367552635 -2936,989.2122949517433,965.9433035271177,1.0240893966961202 -2937,176.06869448959716,173.64228747805842,1.0139735950659217 -2938,196.1519910441689,193.53210160979668,1.0135372344566096 -2939,4243.663258404672,4094.5166554314915,1.0364259363251906 -2940,819.4040338025582,795.9645315597189,1.0294479230084645 -2941,305.49088224979965,297.80866520260287,1.025795814376222 -2942,352.2039263733932,342.4089623102479,1.0286060388053462 -2943,358.3625215990702,348.3938264792736,1.028613294387378 -2944,351.0036199882291,341.2297352358631,1.028643121460708 -2945,1202.7417715820764,1167.0703586655036,1.0305649206594207 -2946,339.95463363694705,329.6523085751043,1.031252094385062 -2947,1239.6149077796908,1202.1651020216716,1.0311519654788184 -2948,302.72881023068203,293.7503776004704,1.0305648377494963 -2949,6240.502877832574,5860.451386865792,1.064850207924007 -2950,307.13940465067145,297.92459638982024,1.0309300016598633 -2951,681.5232024455839,627.660283969809,1.0858154002274991 -2952,677.8406718505632,624.2656689776882,1.085820838042577 -2953,689.2857607304704,634.8058861716265,1.0858213128542331 -2954,1739.5545007775438,1617.425365379053,1.075508359156881 -2955,2784.5630534973516,2564.6256500208033,1.0857580924041543 -2956,200.6416657164745,186.3392708483868,1.076754592861559 -2957,489.2099191330638,453.33362646926923,1.0791388297029993 -2958,4302.237985648219,4034.9821815498867,1.0662346925149684 -2959,115.22824626094989,91.13405574229935,1.2643818528913264 -2960,264.67495580512576,234.3717670038708,1.129295389067722 -2961,847.9138041842768,825.6995869485276,1.026903510171108 -2962,152.67330785329156,107.46299549150177,1.4207058639582129 -2963,106.60025630966919,85.40355948389161,1.2481945360810822 -2964,72.54483903455409,69.9988853769469,1.036371345684965 -2965,376.03786023022747,350.50153112799,1.072856540797571 -2966,359.248270220318,335.474728846076,1.070865371755468 -2967,163.85251827123074,158.0886701190428,1.0364595903542466 -2968,161.9784303256946,156.290847919024,1.036391013820703 -2969,107.81117535721036,96.49629902900598,1.1172571014853452 -2970,170.718088230111,163.52600151732156,1.0439813035606305 -2971,102.30348715389582,90.7773812847531,1.1269711210658004 -2972,92.8102025779818,82.29489452712015,1.1277759466280906 -2973,313.67822052639286,277.8436609501918,1.1289738245373357 -2974,284.450312281633,251.792212643724,1.1297025801354663 -2975,265.9393777177608,235.46242764208586,1.129434451096382 -2976,284.2747911171415,267.4104385585561,1.0630654235096082 -2977,2640.33802923255,2455.8322426679815,1.0751296376678092 -2978,444.07521180724854,408.38003413973786,1.0874067649822876 -2979,265.2217537906566,249.48582093266458,1.0630734556343346 -2980,262.30183347310117,248.3907398346698,1.0560048802450956 -2981,62.050288224189444,59.607783855894795,1.0409762653515109 -2982,65.14843132848706,62.578647453501844,1.0410648676434668 -2983,61.9487874865658,59.51027852267822,1.0409762653515109 -2984,65.2643448347664,62.69072282259277,1.0410526772750202 -2985,264.72166701192026,249.2750159111146,1.0619663027373492 -2986,2810.8905637526977,2614.443158163139,1.0751392911244548 -2987,558.0996246953275,525.6086175402943,1.0618159711822883 -2988,262.23150691859433,247.19076804322722,1.0608466853128466 -2989,925.5451450891758,861.4625683519225,1.074388115156124 -2990,231.92416064197872,214.5872885129813,1.0807917013590889 -2991,427.3114462902086,395.0579314064727,1.0816424942258671 -2992,3375.4395757740426,3180.182110845015,1.0613982024058193 -2993,5491.115301822613,5236.739587701777,1.0485752078866448 -2994,210.91104126445484,179.40808569508027,1.1755938448778533 -2995,2120.1784764095064,1991.0167269684766,1.0648722573203548 -2996,410.8952173429026,350.09875371788087,1.173655184371245 -2997,140.93738957333974,112.78509934047163,1.2496100140665123 -2998,1124.8289272192026,1052.8828891252356,1.0683324221877533 -2999,194.53324693508108,181.10514345290682,1.0741453457707346 -3000,6387.052154205229,6055.268461298758,1.0547925653547836 -3001,128.81384041706355,119.42476469840568,1.0786191686654687 -3002,258.1641552534863,243.35668432907943,1.0608467811978546 -3003,1350.299504163861,1283.3183330910138,1.0521937303829485 -3004,1616.566757886967,1540.0203998206457,1.0497047688947732 -3005,491.95801668268126,467.9206217256771,1.0513706681025405 -3006,38.187064187601365,35.16380647934671,1.0859764061672432 -3007,79.99825990285626,77.32829913681219,1.0345276023893952 -3008,66.78781663115814,63.8124746303214,1.0466263378449667 -3009,44.950072633504085,41.93152518977773,1.0719875423101048 -3010,76.30771198506214,73.76092571832145,1.0345275800423976 -3011,83.39555221800401,80.61220780378181,1.034527579507525 -3012,82.1246136032394,79.35181012202153,1.0349431660973334 -3013,378.56437207602835,356.3134085942625,1.0624477298498278 -3014,185.92838485904906,178.47239213678847,1.0417767287869713 -3015,94.04772771109076,88.52216475316418,1.062420106572564 -3016,95.08037932828815,89.49936760280092,1.0623581135260733 -3017,93.98347588255606,88.45982380568256,1.0624424946742734 -3018,292.1440015836722,282.4065230952971,1.0344803596660876 -3019,289.326336701113,279.6975622696591,1.0344256644688619 -3020,291.448800349443,281.6690200075316,1.0347208235454857 -3021,259.55694687226094,250.54047888508578,1.0359880687835306 -3022,77.91255294259899,76.12815403739886,1.0234394085573588 -3023,38.370777211881304,37.035436321324795,1.0360557623507092 -3024,15.85628584689902,14.78654345303011,1.0723456700524352 -3025,150.4513697040262,147.00564434596342,1.0234394085573586 -3026,121.02661368439401,118.25479131685309,1.0234394085573588 -3027,145.96344743486563,143.83450795929875,1.014801312326033 -3028,972.4562204692116,950.1912451310951,1.0234320990139671 -3029,68.8124331260031,62.257352940223534,1.1052900561331838 -3030,832.0979447803068,797.631583242855,1.0432108786331218 -3031,80.6764329806615,78.72448529020201,1.0247946707211109 -3032,27.572614734773573,26.359621408970447,1.0460170996761862 -3033,15.924920829000364,14.850547984421548,1.072345670052435 -3034,917.2143921482259,869.4182631779604,1.0549748389176432 -3035,280.4277596966462,266.2826892376287,1.0531205032498172 -3036,59.86147973329261,55.28036875781278,1.082870485100235 -3037,3282.9733637561103,3155.0903961278,1.0405322674067468 -3038,778.2026857735373,706.2949725688322,1.1018097480478628 -3039,155.2023025919926,143.50408645774232,1.081518348522396 -3040,225.49944178149929,220.3351151556561,1.0234385092099134 -3041,906.8429580538827,862.9641599402054,1.0508466053986734 -3042,110.65671534254477,109.98604438619599,1.006097782314944 -3043,1380.346905786203,1292.2692790236747,1.0681573323704423 -3044,106.22064404556941,104.67421729874981,1.0147737120632674 -3045,108.31865898361913,106.74776332360784,1.0147159585465888 -3046,88.29699717204257,87.76714573087352,1.0060370134719177 -3047,1359.63091342205,1289.936423305712,1.0540293993232104 -3048,254.76239928327286,243.21048145331036,1.047497615073716 -3049,745.3060378405559,711.6693181085557,1.0472645354747039 -3050,6077.8362866257385,5797.596334943349,1.048337265220299 -3051,1953.2549295435244,1802.445310793495,1.0836694560700086 -3052,1365.2244459493104,1270.8574055305007,1.0742546252696363 -3053,4849.324717576143,4607.028378343877,1.052592760307538 -3054,1750.6984958867067,1633.3857058864005,1.071821854187614 -3055,1599.4774774664518,1492.5095150061215,1.0716698696958669 -3056,1611.7552868321854,1511.0573585079844,1.0666407054353184 -3057,1040.928717536522,980.789246308789,1.0613174251798423 -3058,727.6509453070107,686.098579243685,1.0605632591589544 -3059,819.5412219928018,767.5308941064237,1.067763171861544 -3060,293.9023827737034,279.8272234347686,1.0502994639555356 -3061,377.2132550764392,358.234317481204,1.0529791163746645 -3062,292.1846233114091,278.1914383732699,1.0503005592837964 -3063,142.4740830841439,133.26323184434298,1.0691177237136165 -3064,175.09013265685994,163.10080765177227,1.073508679556544 -3065,125.86992233283222,117.44898493200601,1.0716986818208882 -3066,177.11856044528946,164.99157503193416,1.0735006342657685 -3067,289.4756365337324,284.4496823819606,1.0176690446960068 -3068,299.6084831337562,298.78901811171437,1.0027426209544803 -3069,1393.4417571256186,1330.210821449575,1.047534522089618 -3070,178.98084709706757,171.8202161329728,1.041675136519169 -3071,1755.360386758179,1661.888015128665,1.0562446872344027 -3072,254.41962042505526,246.59160376305283,1.0317448629334691 -3073,543.3638930401266,509.0863916748702,1.0673314037181099 -3074,236.0939600189601,226.65037594400854,1.0416658654794577 -3075,233.8332726645497,224.59604109300278,1.0411282030021263 -3076,2001.8601896006332,1887.7949957446021,1.0604224474125383 -3077,735.6406889575953,721.5103640227111,1.0195843686237602 -3078,26.003741671559368,24.963611205201943,1.0416658654794577 -3079,25.984413863550756,24.945056495242515,1.0416658654794575 -3080,555.8123392727164,544.9930186580135,1.019852218733635 -3081,443.75747529602256,429.6628704373301,1.0328038697976074 -3082,25.905696939823105,24.869488190341382,1.0416658654794575 -3083,25.509187231969033,24.489342653664984,1.0416444243819432 -3084,26.260995102205325,25.210574688571487,1.0416658654794575 -3085,975.2426765906994,938.3420156104714,1.0393253849516915 -3086,538.3145537104272,521.8283209099438,1.0315932120582019 -3087,1274.8241637639596,1212.6032813468705,1.0513118209180323 -3088,195.92384196529457,189.75366621090842,1.03251676701481 -3089,179.60471092167612,174.63259580463566,1.0284718617056052 -3090,430.72042963170054,417.86316517954987,1.0307690783097048 -3091,541.1878396889161,524.6169796774614,1.03158658726914 -3092,362.0578121791318,335.620927485373,1.0787700722116353 -3093,460.16603576677113,439.20763521015834,1.0477186616908067 -3094,454.95628277470274,434.5829748312141,1.046880133653191 -3095,232.85963600121173,219.4158947405436,1.0612705897016494 -3096,2306.859002690667,2163.5382935452208,1.0662436664851436 -3097,699.0870946849951,636.3909864422042,1.0985182216255116 -3098,1453.6736742622843,1301.7224870937453,1.1167308613587745 -3099,2984.16205219764,2790.9214364307513,1.0692390023038485 -3100,226.8358688533369,217.81008168307352,1.041438794295098 -3101,946.1887713090315,904.9597695352988,1.045558933293691 -3102,207.2197595215028,196.68961500960629,1.053536860659279 -3103,190.16328051103474,180.54054575352282,1.0532995772077096 -3104,192.03890276284042,182.31397077346026,1.0533416717771134 -3105,167.01227041070374,159.51692675299202,1.0469877636830232 -3106,339.13775125666706,320.9320614733247,1.0567275506839804 -3107,516.679704697669,486.27640521088773,1.0625226705655109 -3108,163.48887395619343,156.47163591848826,1.0448467097344127 -3109,3612.6640470496745,3476.7962975458004,1.0390784325212785 -3110,842.1260877149375,806.6000958944143,1.0440441205020308 -3111,69.90613629284813,67.99638441347979,1.0280860798091163 -3112,136.05476733274756,129.9615902234799,1.046884445618047 -3113,479.62519620082725,465.68117104721966,1.0299432874261383 -3114,617.9958167643551,606.9144606989923,1.018258513815275 -3115,131.70870801738354,127.55431793234753,1.0325695762587936 -3116,134.91882457613195,129.9934732050774,1.0378892205094352 -3117,130.27308041663713,123.89041166647104,1.0515186660881317 -3118,137.16117650995946,130.35983638020892,1.0521735859648802 -3119,2100.965788248361,2017.6439602149487,1.0412965962659417 -3120,1595.528645377444,1528.7351876663004,1.0436919737636887 -3121,367.746913810125,351.9645321711328,1.044840829675754 -3122,719.6658916152109,695.6033709819742,1.0345923002058888 -3123,373.8547623616845,357.8082401177167,1.0448467096193441 -3124,363.8035358475231,348.18857235103616,1.0448462836992372 -3125,1384.9644965196483,1336.974814018144,1.0358942307651078 -3126,893.6138713760423,861.3019326223517,1.037515228434833 -3127,2694.5527285901494,2536.2236211646095,1.0624271085973234 -3128,930.3820076518355,893.5504921551445,1.0412192884678038 -3129,113.86394687478193,112.0616934430496,1.0160826896003339 -3130,751.0326083244187,725.6625554024355,1.034961226444864 -3131,257.03028619838983,248.59126233823295,1.0339473872926184 -3132,279.5768281909166,270.3978976092308,1.0339460131267397 -3133,197.95893726917555,191.47397631457446,1.0338686284132257 -3134,275.9166226531777,266.85755205128436,1.0339472146553768 -3135,807.2579292435591,755.0609257141381,1.069129525514849 -3136,808.2833718003643,737.8729768670497,1.0954234633070201 -3137,28.064472302013602,27.58981295616564,1.0172041523660234 -3138,531.2156777616816,484.19333212226434,1.0971148145169904 -3139,106.88260643028626,105.22261807234584,1.0157759651712819 -3140,113.67965107454265,111.90790552910329,1.015832175010894 -3141,178.35151439636306,173.359570080353,1.0287953201181583 -3142,44.3534048007097,42.966540152253394,1.0322777827477359 -3143,99.85297250404851,96.63484203916299,1.0333019684927027 -3144,59.41310875374106,59.34898384538735,1.0010804718834068 -3145,68.00180223620572,67.82770205705269,1.00256680049409 -3146,156.07313075489594,151.18369385329976,1.0323410334605305 -3147,154.54418369283465,149.71748285004642,1.0322387255710312 -3148,338.8879111867537,313.52158763516735,1.0809077414506594 -3149,336.41295081275103,311.2805204796438,1.0807388470514676 -3150,527.9136296571484,481.7256992866836,1.095880145981121 -3151,520.6643582569665,475.17876129857683,1.0957231270902887 -3152,439.3604663956873,390.3746095606006,1.1254842288288789 -3153,541.2853941114358,479.06528123845413,1.1298781508694047 -3154,544.1636661051396,481.58522598645203,1.12994260775028 -3155,182.4816823513786,171.92130071797007,1.0614256731964378 -3156,174.07421941477403,160.73929512751252,1.0829599524912876 -3157,253.2961826790544,236.79773590024953,1.0696731610041863 -3158,177.35472986969523,165.51653722755407,1.0715227181551406 -3159,175.01535042156434,161.62389122100362,1.082855691070136 -3160,231.30653265459605,215.66573775804855,1.0725233180714808 -3161,3473.4441243405454,3272.2097788497113,1.0614979964889582 -3162,1338.0881406453555,1259.197139848463,1.0626518265490872 -3163,497.37689413052584,460.7603679900977,1.0794697823082195 -3164,108.07014088032669,101.97656716580357,1.0597546464239729 -3165,134.3516850896269,131.47391957800383,1.021888489525983 -3166,108.08189828351999,101.95175869231734,1.0601278454617242 -3167,131.56629644834948,128.789912694551,1.0215574628145232 -3168,385.53994455990306,354.47178937863237,1.087646340589561 -3169,433.59377163016995,391.63226440491076,1.1071451742849128 -3170,204.086720839401,199.24359924308627,1.0243075391867718 -3171,676.4558355550257,650.4687446924298,1.0399513290602207 -3172,237.77880426046335,232.38148311795698,1.0232261240013116 -3173,207.55055212060407,202.89284119001587,1.0229565070076874 -3174,108.52007234681666,97.99511483744297,1.1074028794887663 -3175,107.90004931794792,97.39775569055934,1.1078289078934758 -3176,106.29396706631027,95.99550730099081,1.1072806431766538 -3177,105.95351754629894,95.64145734420325,1.1078199819246135 -3178,881.8353178100881,861.7129236118753,1.023351621690748 -3179,87.44117322061403,80.69627589947083,1.0835837496335743 -3180,87.20155979791936,80.47849355788419,1.0835386690631776 -3181,86.59657977713046,79.92035088441811,1.083536030796056 -3182,85.9157837739573,79.29204136463869,1.083536030796056 -3183,328.62608325199,303.4145360606738,1.083092746704379 -3184,150.94755011595717,139.31013443554667,1.0835360307960558 -3185,130.26098848351054,120.21841893694108,1.083536030796056 -3186,742.1636551134694,696.8837885524911,1.0649747738500703 -3187,774.5183376687077,727.2330062801861,1.0650208818634168 -3188,486.84988662501445,458.6575177081577,1.0614671466800103 -3189,751.1358082326342,705.2784294785583,1.065020248510904 -3190,1591.1859518500225,1507.3838707187629,1.0555943862470152 -3191,1800.8653287427587,1710.8824008636532,1.0525944552551842 -3192,740.3314554958735,695.1651970105726,1.0649719788613266 -3193,3074.5280617741564,2902.218321113145,1.059371736236205 -3194,1362.7967267807285,1306.7605519983192,1.042881746542408 -3195,128.92072227450987,124.48384009804558,1.0356422341483822 -3196,130.09459090968926,125.61763922514695,1.0356395145789852 -3197,129.85024541833235,125.34507467025739,1.035942144196145 -3198,608.3890443986397,565.9565612111918,1.0749748056575916 -3199,150.04646609138524,143.86625505106323,1.042958030972089 -3200,129.80605826556814,125.29860969031681,1.0359736519534555 -3201,5408.771665099265,5151.845088041369,1.0498707885557899 -3202,2977.8296748249863,2822.4504115933337,1.0550511933153637 -3203,276.76489945337505,263.0761061635989,1.0520335863617485 -3204,864.2563084694324,822.6832482148889,1.0505334955400532 -3205,1877.496464844914,1804.3777847490642,1.040522933009851 -3206,9151.895971719054,8668.707193859735,1.055739427697082 -3207,858.2984710817353,847.2453816554577,1.0130459128672744 -3208,4807.126874402824,4599.846361142621,1.0450624862193687 -3209,6529.789937719424,6087.938611646079,1.0725781507106682 -3210,502.6375785315653,486.6541736945721,1.0328434557863764 -3211,2800.624636773593,2657.292906437745,1.0539390031067342 -3212,4743.543676565577,4460.398584605249,1.0634797735201476 -3213,3745.9434248081466,3539.908394690856,1.0582034920525913 -3214,5378.273642350935,5086.529393475768,1.0573562494791384 -3215,3284.489015802604,3166.8406780076234,1.03715006524073 -3216,4417.777405782918,4242.735928725965,1.0412567456465565 -3217,7189.447892771567,6805.9381313518525,1.0563492870517086 -3218,3084.216356854389,2950.4145195428346,1.045350182635451 -3219,4609.323090723947,4312.2749206761355,1.0688843303156645 -3220,3754.5511808460747,3542.4292078676235,1.0598803703705173 -3221,3372.4991345699177,3171.7795223683443,1.0632829649053595 -3222,319.65268177981744,306.82625238332304,1.0418035591702568 -3223,643.6263712071666,602.9115274745424,1.0675303786331127 -3224,319.8921963288238,307.0700505172639,1.0417564193901712 -3225,319.45122371003976,306.64238093419243,1.0417712735494191 -3226,4312.924393655993,4072.481013801604,1.0590410069536307 -3227,2124.6824950285622,1959.319524148087,1.0843981641801763 -3228,1018.0795580392416,937.646117799904,1.0857822996463389 -3229,2953.605680508211,2778.024091941461,1.06320376741011 -3230,1305.6566292001953,1247.0887362057338,1.0469636933556583 -3231,209.60053817735687,203.8760396193185,1.028078329207921 -3232,719.1344522565132,689.7085143900415,1.0426643099983985 -3233,1178.8194268547518,1129.894054519235,1.043300849437901 -3234,211.578183775542,202.71066470864864,1.0437447091382115 -3235,385.43966732134663,353.4358566093973,1.0905505486029918 -3236,108.35260551630599,105.3404504789977,1.0285944765150672 -3237,692.4849727879279,625.7886374390866,1.1065796522317544 -3238,99.70820621066468,96.13443360691238,1.0371747403054896 -3239,835.3526977339302,782.8099470494832,1.0671206988139175 -3240,1152.465997324426,1101.5749719138496,1.0461984219940652 -3241,169.1667137950342,161.5659709849475,1.0470442059287028 -3242,1442.5321078466668,1306.5784351706745,1.104053204167749 -3243,756.0424611224856,700.0685446236278,1.0799549085996296 -3244,168.89002213898405,161.29937629238873,1.0470593626650837 -3245,138.86728561673038,132.62800360676496,1.0470434737784682 -3246,824.9039560271841,799.318751179216,1.0320087634754256 -3247,1085.0520758888877,1052.2914406964544,1.031132663371994 -3248,51.27644996206919,48.56550303851233,1.055820423015223 -3249,152.54105290438872,142.15096594519383,1.0730919194963529 -3250,640.894851875979,626.5940545262939,1.022823065821294 -3251,185.68418807836198,177.84087462188114,1.0441029851723178 -3252,93.3240760284707,86.38223920071425,1.0803618532234003 -3253,71.26765605599715,67.49737903762244,1.0558581247469356 -3254,28.634129021729358,25.915619742132098,1.1048984861889166 -3255,71.43870709397919,67.6587197917508,1.0558684425874885 -3256,75.70024478972621,74.41127067762153,1.017322296748419 -3257,1049.4492414223973,980.591317963852,1.070220816967384 -3258,227.67771825874067,223.7951020111371,1.017348977760069 -3259,75.62674909802121,74.33768382886024,1.017340670340613 -3260,985.4398226672614,920.7571536101133,1.0702494341787514 -3261,112.26241610391192,110.30472426608935,1.0177480325602375 -3262,75.19451990812261,73.9070725869661,1.0174198121518288 -3263,13.084328219040039,11.8464518818679,1.1044934255012528 -3264,124.45175108809111,121.95349076183722,1.0204853531510036 -3265,61.9997817731062,60.7572596743997,1.0204505947991271 -3266,124.62810792676915,122.11544802468315,1.0205761018997213 -3267,262.3812421171766,249.36912007335914,1.0521801658520893 -3268,125.80081475082497,123.21407921626994,1.020993830826871 -3269,595.062578423785,562.5033667676091,1.057882696495268 -3270,174.91917601985486,168.96571668878056,1.0352347177151922 -3271,132.67352487457063,129.50750621076932,1.0244466035709832 -3272,87.98925021848764,85.61817341593787,1.0276936158288608 -3273,2657.0412814507786,2474.5786979237078,1.07373480733515 -3274,564.6183159181123,549.5197414625817,1.0274759454780364 -3275,145.43000644743256,142.3589059887351,1.0215729422572304 -3276,3992.03244151316,3758.82231200122,1.0620434035328947 -3277,3433.8389334492385,3329.7585709725604,1.0312576303231134 -3278,895.0592332967276,870.4711465782603,1.0282468716109898 -3279,335.5538615667111,313.15762257679063,1.0715174639711302 -3280,518.0496093929337,493.5946757022043,1.0495445653986015 -3281,205.80365414807986,185.50394341605664,1.109430076569823 -3282,333.76802307691116,311.4836689862581,1.0715426081989428 -3283,522.4626444202393,497.79578580236284,1.0495521644043604 -3284,90.86632045281289,82.76565931983926,1.0978746644386588 -3285,578.7695438389585,543.5584460681517,1.0647788623753478 -3286,313.40854997529647,293.48232292162606,1.067895833913621 -3287,1866.6425474979012,1813.183195105027,1.02948370166743 -3288,527.1500641155372,495.69767847279144,1.0634507422742998 -3289,262.44757231558856,246.7837701477113,1.0634717678496515 -3290,526.3382254267249,494.9244929096567,1.0634717678496515 -3291,260.98577408054615,245.40921721717308,1.0634717678496513 -3292,1631.7324536178655,1574.5412363473129,1.0363224639344646 -3293,811.166841261741,782.7366921620331,1.0363214723219114 -3294,2683.06284394937,2570.2096501085744,1.0439081667271883 -3295,7176.3854101072375,6941.642932103219,1.0338165590336543 -3296,1269.0599430737743,1189.3070051161446,1.0670583269202565 -3297,2187.672075074287,2072.968940192293,1.0553327802737624 -3298,6331.110750618061,6078.902172179278,1.041489165526144 -3299,4143.434770511739,3876.3634354984492,1.0688973929966263 -3300,287.3543137444997,278.1499462722221,1.0330913868423666 -3301,2005.7529610462157,1935.7731492167688,1.0361508329928852 -3302,2679.707427003957,2526.504978576889,1.060638094809282 -3303,1003.9140385185877,977.5505793511011,1.0269688952411922 -3304,1336.0008043644505,1250.721192876886,1.0681843499360604 -3305,1200.4486415229,1123.7707448031551,1.0682326863146594 -3306,4438.663497419972,4306.559734102006,1.0306750100949227 -3307,2945.646731777671,2857.3043968183924,1.0309180691625464 -3308,917.3230037692194,892.7737028597958,1.0274977867636397 -3309,6102.231590392752,5799.591523391837,1.052182996988712 -3310,4600.011154315595,4434.311441634605,1.037367630772436 -3311,1401.430294217235,1367.1329674224653,1.025087045380401 -3312,2272.1848249499376,2181.7348552291633,1.0414578194522512 -3313,1862.4435021702022,1794.1977101468988,1.0380369407659737 -3314,903.498396927955,846.0923553688416,1.0678484342694339 -3315,580.9486042321047,540.45228949192,1.0749304157417028 -3316,752.8560777992094,719.6493916688764,1.0461428669498716 -3317,555.4571741317097,521.0613708047192,1.0660110406455006 -3318,792.1117628160017,758.1385444659344,1.0448113588183272 -3319,1068.1879529474825,1028.3655491129687,1.0387239769640895 -3320,1019.3318803144731,977.0070645948646,1.0433208901484856 -3321,710.2125353297888,690.6674970729435,1.0282987665405963 -3322,1576.9052110411053,1556.6438527161733,1.0130160526375882 -3323,1169.7945892300695,1112.3043442790847,1.0516857146577503 -3324,2270.292773673654,2184.40723919528,1.0393175470843128 -3325,3233.992647552472,3158.3057799241797,1.0239643887901537 -3326,1985.1449731025943,1930.9250201995726,1.0280797816258125 -3327,7236.857548743346,6865.75862996078,1.054050679434486 -3328,1476.9450554419163,1416.8125877886341,1.042442076087944 -3329,6654.769381990642,6257.738715700913,1.063446347686835 -3330,11471.078984644631,10859.833642963351,1.0562849636354548 -3331,4268.969183379104,3999.350777786108,1.0674155433153194 -3332,1414.318483732333,1332.8312634341244,1.0611384370503523 -3333,7421.386635110782,7077.87923285882,1.0485325322671855 -3334,3110.8435298616178,2925.966877959033,1.0631848068053125 -3335,1698.0838111562618,1638.1870578132946,1.036562829047691 -3336,195.10303800394524,183.93331278275642,1.060727037708397 -3337,162.68191026541692,149.66567002258623,1.0869687767466407 -3338,5715.108917908968,5533.1510960615,1.0328850267575354 -3339,6265.865535021409,6027.485661078272,1.0395488081344508 -3340,1711.8859826566402,1617.1722673497575,1.058567486729228 -3341,2804.993275292815,2666.19166800426,1.0520598758724848 -3342,5209.284260480768,5037.449369019494,1.034111487555203 -3343,9477.418189126414,9214.677685891256,1.0285132602779417 -3344,4898.346547077135,4737.305317537316,1.0339942686285495 -3345,72.01884895293391,69.49967793299805,1.036247233006813 -3346,180.9093739587483,174.5822559985784,1.0362414721013882 -3347,223.42614391597624,211.82829050143204,1.0547512014900853 -3348,183.29792403457918,176.88451408773432,1.0362576112438189 -3349,71.0700356214137,66.21583675131411,1.073308729576739 -3350,421.3328180051258,401.5117270640441,1.0493661569638788 -3351,411.55580105332933,379.28252441406477,1.0850903338853326 -3352,455.4302893696791,414.50698500646763,1.0987276592276796 -3353,110.84092205389243,103.27061768221864,1.073305501037758 -3354,80.66387462330697,76.5964631533773,1.053101818314836 -3355,76.02683719486137,72.19086248499724,1.0531365685049314 -3356,1298.4007953497887,1186.454519598711,1.0943536173547899 -3357,37.093346204155615,34.56157519901984,1.0732539240632635 -3358,165.3023199366145,161.4008133842373,1.0241727812305947 -3359,99.50424697765291,94.82296702317426,1.0493686297891793 -3360,892.8498503420569,852.9522556958772,1.0467758826824716 -3361,2008.7948746436202,1867.6219755919522,1.0755896540609737 -3362,780.2422257320479,736.340456465568,1.0596215634778623 -3363,319.68978189756916,317.07890794869235,1.0082341457707407 -3364,270.50079223708286,269.0787505698674,1.0052848530930212 -3365,309.59574110996687,307.2092043908516,1.0077684414561974 -3366,210.61589409813826,203.10284574714368,1.036991349497624 -3367,2244.513938423191,2121.2228771280465,1.0581226341769754 -3368,190.94177931525394,187.02157169590853,1.0209612590879065 -3369,425.932589569074,399.3884558547863,1.0664619453195685 -3370,235.70471419268412,231.40017977067706,1.0186021222035047 -3371,351.0550426691959,335.0961071997879,1.0476249503545951 -3372,575.6864339070929,543.638903426739,1.0589500314976494 -3373,4202.096718621688,3921.7338317648096,1.0714895245021543 -3374,102.04972258089241,96.21107705554789,1.0606857931958662 -3375,475.67127989011254,443.5742486849311,1.0723599967769541 -3376,669.5325463689662,618.1481176165845,1.0831264017279654 -3377,61.12314374542408,54.65999326296841,1.1182427969092779 -3378,61.42176059048772,54.92641547680594,1.1182553978317518 -3379,156.83268180880546,143.21854911880936,1.0950584458071997 -3380,111.26311474859473,111.25652992825295,1.0000591859223547 -3381,116.3540278678947,116.3540278678947,1.0 -3382,117.76491229780011,117.55387636761688,1.0017952273179258 -3383,670.5403833451543,650.3654341946672,1.0310209431340234 -3384,486.40422175791895,472.90886156889263,1.0285369154307131 -3385,108.0589714530207,107.5009215894459,1.0051911170185688 -3386,2077.2840847372377,1946.4288596894403,1.0672283625452799 -3387,2182.01723039181,2120.6241078004236,1.028950497339703 -3388,1311.6146591061986,1260.7941928776183,1.0403082965607482 -3389,241.10907010716898,235.7654142451462,1.0226651389014443 -3390,37.62278832467875,32.793595495050305,1.1472602426396745 -3391,301.25563906221504,273.7786966739531,1.1003618715483352 -3392,136.6761119119244,122.22400384754084,1.1182427969092779 -3393,100.2359033667688,88.37863065498156,1.1341644764567178 -3394,134.1532111943856,110.31022189050996,1.2161448766510627 -3395,55.22188653842099,48.84193878380866,1.1306243755566745 -3396,3962.227951935659,3730.278621259759,1.062180162455953 -3397,2518.137306503915,2415.827489642419,1.042349802417655 -3398,1353.2657481874537,1301.8988036524731,1.0394554049753104 -3399,1235.3223911327364,1151.1053257993442,1.0731619109440838 -3400,1110.2281030227723,996.939000073819,1.1136369456311417 -3401,164.46931766469612,160.30988366101477,1.0259462106059334 -3402,146.22766182518416,142.529766494012,1.0259447231419376 -3403,144.36198622292397,140.7108129308584,1.025948064800533 -3404,146.83894867796522,143.12567540986262,1.0259441449444278 -3405,144.3529720396064,140.70358488230744,1.0259367034631814 -3406,580.8505465435173,565.8126432798474,1.0265775313476555 -3407,190.62244503365756,185.64031175547592,1.0268375614707224 -3408,204.70643869876406,199.35646541436577,1.0268362165896063 -3409,137.38627885671087,135.27476452334412,1.0156090778705615 -3410,137.69568301524657,135.58046111793035,1.0156012295567896 -3411,138.536039687868,136.3969364290708,1.0156829274527701 -3412,138.31920074436002,136.1948704706421,1.015597726011097 -3413,132.28460008529214,131.55294228160372,1.0055616985146727 -3414,134.69807023242507,133.49947685948663,1.0089782626953663 -3415,97.70010283945187,97.30352746303373,1.0040756526177204 -3416,135.9782841910299,134.28824864023412,1.0125851336055733 -3417,103.97842279417439,103.5165367005874,1.0044619546625961 -3418,104.90225707838933,104.84707163001607,1.0005263422956436 -3419,2016.7793477475122,1915.9086618315973,1.0526490056261257 -3420,858.4672097271393,815.3578551159997,1.0528716984090458 -3421,866.1442912265293,822.6489094120985,1.0528723509103226 -3422,4977.937107763867,4767.816577435648,1.0440705985466479 -3423,860.5323494709698,817.3169217854152,1.0528747497251756 -3424,866.7734642265032,823.2446114343144,1.0528747497251756 -3425,1317.336235904857,1249.5599773761512,1.054240100319973 -3426,791.250792498794,751.5146437934129,1.0528747497251754 -3427,808.3936363746238,767.796584147956,1.0528747497251756 -3428,64.23234852954182,62.461041819552825,1.0283585841412353 -3429,648.4562317765823,624.0584096593733,1.0390954143707893 -3430,2419.463463152526,2319.384910760058,1.0431487468630949 -3431,72.76120165642905,63.57692522782165,1.144459273481636 -3432,787.8116521007464,765.9048031781733,1.0286025741471645 -3433,5453.073295275411,5132.987562631431,1.0623585638457864 -3434,75.11754183487656,63.98492487536201,1.1739881226898379 -3435,195.43299782748605,184.63787080994186,1.0584664834477875 -3436,1594.5438649170892,1515.3934125367048,1.0522309597795398 -3437,151.9895465718319,144.18591444401204,1.054122014330672 -3438,175.6251080348946,150.16828670172333,1.1695219536181811 -3439,65.04555019293392,64.76426464689074,1.004343221490691 -3440,707.2653741388663,686.2935463548347,1.0305581014063456 -3441,1533.06504453689,1472.210425122984,1.0413355444136476 -3442,114.03375142858866,111.02957042222991,1.0270574856313888 -3443,452.47347723146436,425.0532818288829,1.064510019272408 -3444,272.48571824376006,267.6926805463998,1.0179050009420392 -3445,568.5220228267939,552.5624021516279,1.028882929082798 -3446,648.3605698513815,637.1162998292994,1.0176486930645077 -3447,422.67181989063795,412.3096379437898,1.0251320391114913 -3448,719.988044658233,698.3469179631514,1.0309890774032504 -3449,952.8769366613919,907.198951055845,1.0503505714511514 -3450,785.7971119691405,732.5325759761135,1.0727128563832822 -3451,1098.3036245850863,1014.8442760508426,1.0822385764040732 -3452,466.76857300770007,441.62254331623257,1.0569400952737622 -3453,936.802470290771,886.2903183812767,1.0569927831342554 -3454,809.0813332773638,779.0812536608406,1.038506997152807 -3455,3402.500582462423,3227.959585283548,1.0540716178649254 -3456,969.4937199279975,936.7589788615765,1.0349446781990848 -3457,1744.6270590534407,1685.621352317399,1.0350053151942578 -3458,3500.6596777835043,3347.611274607842,1.0457186903200375 -3459,139.9090297287215,135.4752388752493,1.0327276843376154 -3460,1801.569005474002,1722.942916707632,1.0456347613167687 -3461,157.55487611134618,152.4403565586056,1.0335509550633615 -3462,635.8407909965159,624.3682896570873,1.0183745739965901 -3463,1520.4466535450674,1448.5483171736857,1.0496347519229907 -3464,1781.39868300459,1742.0327267229984,1.0225977133940787 -3465,265.80661555341646,262.6363968699065,1.0120707515077596 -3466,1352.452359769041,1302.0705289811,1.038693626548299 -3467,2811.862958455327,2735.189755341923,1.0280321330407363 -3468,516.2041212818518,490.3449831250555,1.0527366222694714 -3469,947.8415576820411,901.9177768418709,1.0509179240273714 -3470,339.8791080857997,315.9987337050046,1.0755711078357935 -3471,512.1843013299725,480.17515633050095,1.0666613934050346 -3472,286.3792848654168,273.6587734974136,1.0464831118163418 -3473,286.67909203243755,276.1241371364864,1.0382253974803148 -3474,253.01167834879624,252.0696909557246,1.0037370117347313 -3475,342.3372712297296,322.6366653534774,1.06106127415701 -3476,290.03512621408646,276.76720163486755,1.047938933879611 -3477,246.0822709506301,244.70743842687608,1.0056182702601615 -3478,417.27717699723297,387.95561270207776,1.0755796883332427 -3479,429.487568340138,399.1243445632179,1.0760745972790713 -3480,556.343257926514,514.0022646023574,1.0823751104616484 -3481,1313.7281107541983,1257.8376513570215,1.0444337624469098 -3482,1325.2073674698604,1268.8462933450573,1.0444191502315212 -3483,1331.0216467386674,1274.366070924781,1.0444578501472286 -3484,1320.1439927811587,1263.9902639867205,1.0444257605413234 -3485,392.86340387852806,381.79449244714885,1.0289918048854816 -3486,1732.273521770177,1656.104991093762,1.0459925735904643 -3487,2538.7386109879867,2424.927056664578,1.0469340114831964 -3488,2090.195931267377,1999.7285171962349,1.0452398479559537 -3489,2164.8808243660105,2061.6207504841964,1.0500868425279297 -3490,2521.1960002006304,2408.170635361228,1.0469341180312368 -3491,4753.469072526308,4489.213391189186,1.0588645845741633 -3492,3696.87444975071,3408.3267996994696,1.0846596195167328 -3493,4220.390643412513,3998.5922898314293,1.055469109502643 -3494,157.11288944583276,156.28185826249756,1.0053175153698222 -3495,618.9649317779802,597.175017748085,1.03648832148415 -3496,2911.144751174508,2725.6791970598297,1.0680437941173484 -3497,196.00033751978614,179.45990048834966,1.09216787140986 -3498,193.88560922548294,177.48999413707048,1.092374869739139 -3499,754.5192677233644,697.7691255343982,1.0813308300872486 -3500,753.4858692823382,696.9562636974356,1.0811092582553263 -3501,4218.980501858702,4016.6432717296493,1.0503747075457668 -3502,2249.34439298126,2105.122594881759,1.0685099283291868 -3503,1727.73248013887,1603.6118855425348,1.0774006452030895 -3504,1415.6510066900662,1334.2299658712075,1.0610247430364776 -3505,1823.765723855935,1694.3354749461178,1.076389977559747 -3506,1718.3646247543102,1594.8396473400005,1.0774529136019 -3507,1342.998641922402,1248.0286186086644,1.0760960300891278 -3508,1805.6236579514573,1675.827159915961,1.0774521986157601 -3509,1708.4595165726294,1585.6470938938896,1.077452557477432 -3510,4692.752500593484,4513.3254135624875,1.039754963489187 -3511,1204.67951986083,1181.08299041458,1.019978722611158 -3512,319.8811613271241,315.50366158145613,1.0138746400714522 -3513,294.02441266980713,279.13812826985946,1.053329455535921 -3514,292.711154157702,277.8849088959089,1.0533539058335364 -3515,1065.6929985413917,1014.2965530366765,1.050672010420267 -3516,877.2852762031711,832.8821204469883,1.0533126533348471 -3517,1967.903062194417,1891.5234248176516,1.0403799584898763 -3518,2445.4637599711773,2363.1625785369147,1.0348267115355292 -3519,388.70236764442546,369.0382541822986,1.0532847563613639 -3520,958.2586522088417,912.6277106353473,1.0499995135384694 -3521,985.3396362180505,940.7606161125024,1.0473861462119467 -3522,341.15577691721984,316.75152153013323,1.0770454243414422 -3523,343.78727768258017,319.1808133774416,1.0770925546706989 -3524,343.8164393105304,319.20462918358174,1.0771035501267554 -3525,347.2306313211173,322.38044349394914,1.0770834221761179 -3526,164.53610702067346,162.06211200775297,1.0152657211625264 -3527,1433.3888962067804,1399.5052369490104,1.0242111700358034 -3528,167.91712628526452,165.39438299559924,1.0152528957995652 -3529,168.0561345890881,165.5309299560112,1.0152551830268093 -3530,2714.827088075962,2624.629387519512,1.0343658807545755 -3531,830.7762030588444,803.3704405785616,1.0341134812734036 -3532,830.5338613026532,803.1348238996032,1.0341151156539503 -3533,836.3442216356981,808.7626703874105,1.0341033930696575 -3534,2899.7511975450157,2766.5908450596976,1.0481315669511098 -3535,4204.093412625356,4038.8303742988187,1.0409185390350117 -3536,607.5925831838642,589.4430499394502,1.030790986926181 -3537,6391.10352197768,6016.711702252217,1.062225321446816 -3538,3247.8458160109585,3122.5764760566544,1.0401173008619153 -3539,586.7427503781836,569.4303844950945,1.0304029541704904 -3540,3150.9875480809546,2962.475851394903,1.0636331589326844 -3541,687.446275933486,659.9603110367008,1.0416479058469574 -3542,582.7082412533249,565.5434615854325,1.030350947069166 -3543,1555.384865713468,1478.1365556269266,1.0522606046054912 -3544,6067.006618988446,5766.430760104257,1.0521251136775556 -3545,4619.225447669572,4446.8417950939665,1.03876541161545 -3546,3431.0150573173673,3307.514330557967,1.0373394381449488 -3547,3793.6971822605205,3656.74101330052,1.037453067762211 -3548,106.680376751088,103.54211038765443,1.0303090824755659 -3549,1395.2814903700291,1355.7290544276298,1.0291742924688576 -3550,104.46079806087113,101.41284966124232,1.0300548540920615 -3551,103.76597377272407,100.73651810381253,1.030073063134757 -3552,251.44249274725237,241.99579135904446,1.0390366350387972 -3553,232.7058160251902,223.74221878251095,1.0400621630171296 -3554,417.77876077898384,403.7053466632727,1.0348606086890637 -3555,228.02250141584645,219.24486761694962,1.0400357549725294 -3556,282.8526168378107,264.5070753457851,1.0693574698069712 -3557,284.07301622079444,265.63138143955814,1.0694256630421226 -3558,274.23031624189446,256.42765618865934,1.0694256630421226 -3559,280.6310721952331,262.4128887018743,1.0694256428618352 -3560,532.6393905164314,506.27813602559706,1.052068719968388 -3561,549.0018483074015,533.473957279384,1.0291071210058815 -3562,525.1177782706861,510.5546822617491,1.0285240670880202 -3563,535.9638455515372,520.7984595630807,1.0291194908701908 -3564,2208.106189818837,2172.6843613423994,1.0163032555978595 -3565,790.5783287733462,732.7936320145361,1.0788553478555118 -3566,414.35967290841654,373.2900876196613,1.1100205621602264 -3567,1312.031892631412,1272.4500504012503,1.0311067945006407 -3568,30.519177058956206,30.519177058956206,1.0 -3569,1207.954038751797,1071.1960304049792,1.127668516746757 -3570,991.243698405684,924.0377473132806,1.072730742102052 -3571,1039.487747860942,963.3571635418001,1.0790263333271393 -3572,428.67690154398645,398.94807018745814,1.074518047781405 -3573,1649.5672357020069,1552.6119099162013,1.062446594133777 -3574,225.6805108956392,211.3922547188518,1.0675912000455765 -3575,253.94213794435944,238.66972370432168,1.0639897428253537 -3576,1448.0405996879392,1366.3588714841692,1.0597805817406123 -3577,628.2733698869439,588.6150806305808,1.0673755915561616 -3578,215.97719447965645,200.29732976798434,1.0782829443100164 -3579,224.2213756555042,209.92066191590317,1.0681243742711237 -3580,206.315493146554,188.6808824691668,1.0934626256068574 -3581,1067.3951114512074,1009.8243385534302,1.0570106806697164 -3582,297.2122261693954,263.5576858452583,1.12769326083663 -3583,356.83757388751576,318.4088443692224,1.1206898935060108 -3584,298.34052799427076,264.5582606103382,1.1276931111733066 -3585,565.1343294816977,510.3892845858777,1.1072613523621275 -3586,455.88265504537304,408.8902724462644,1.1149266337836008 -3587,459.3960703866519,412.13880370349045,1.1146634732243272 -3588,834.9724626517907,788.4038776678697,1.0590669151979222 -3589,1554.0677549603613,1473.3633151312822,1.0547756544500961 -3590,621.932684601885,574.4617629004803,1.0826354768361293 -3591,811.4863610109776,763.219057554618,1.0632417429551744 -3592,1469.8107825441164,1392.0809994882081,1.0558371122689594 -3593,844.5576642763109,799.100346680967,1.056885618663725 -3594,927.7043812092459,889.1770578155922,1.0433291919252867 -3595,2464.7053389194934,2277.742813113008,1.0820823688829742 -3596,369.49325337085935,341.7861365763409,1.081065654306695 -3597,246.63821830595734,230.48833261949125,1.0700681266722842 -3598,698.1743295351664,649.2294695779648,1.0753891532203836 -3599,294.57510805024833,277.5967592121983,1.0611619130073184 -3600,316.93006341535914,298.9484746456677,1.0601494581666768 -3601,378.84584031093385,358.07155520896663,1.058017133167262 -3602,379.17473642195125,358.3822237998569,1.05801770077108 -3603,838.3432040192776,794.2242098957179,1.0555497976186756 -3604,843.3652098325357,797.1026938491252,1.0580383385232506 -3605,2187.4243655001014,2053.1699237088956,1.065388860532637 -3606,848.8041570459382,802.2963578629445,1.0579683538722215 -3607,841.7198226413695,795.5620217057283,1.058019110611485 -3608,305.7877947493682,301.4304951018522,1.0144554042086673 -3609,92.545762607005,91.11003216180843,1.0157582036920672 -3610,1421.2606002190582,1370.256997534501,1.0372219246289769 -3611,88.98881315630499,87.68626006758912,1.01485470001471 -3612,189.56041154224255,188.76248042240508,1.004227170134933 -3613,99.53104391146304,96.10074642820607,1.035694805823591 -3614,707.2571988717929,674.1944081094582,1.0490404405089144 -3615,100.76381623972712,98.87595501294365,1.0190932287484489 -3616,103.57606623366362,103.57606623366362,1.0 -3617,409.7812878530549,395.43143945329166,1.0362890932992146 -3618,21.318865472134977,21.18391831614373,1.0063702641776338 -3619,21.624455482758766,21.487573960096505,1.0063702641776338 -3620,21.315696350815674,21.18076925517471,1.0063702641776338 -3621,115.04710520815425,112.82819729418749,1.0196662533584684 -3622,21.574242019480188,21.43767834506697,1.006370264177634 -3623,21.269097262563182,21.134465136391377,1.0063702641776338 -3624,21.096954772370093,20.963412297967384,1.0063702641776338 -3625,3230.039098775614,3126.604902239179,1.0330819530354982 -3626,2587.5200961041587,2458.976142534519,1.052275396798745 -3627,444.53264067403444,443.3609377085841,1.002642774466118 -3628,413.8963659919811,413.6303112890658,1.0006432185834886 -3629,157.86895974090035,157.85950480754497,1.0000598946092407 -3630,2130.5980732282446,2046.0879858018614,1.041303251870307 -3631,155.46668812330356,155.06907888622356,1.0025640781510783 -3632,143.57165721334405,141.29532245527966,1.0161104749860694 +1,581.4814321959664,525.3426109414437,1.1068613512121523 +2,1205.0578737456863,1081.4902511220064,1.1142568067492824 +3,1733.3993448053388,1569.1786794526006,1.1046538979296008 +4,2305.5733209051646,2102.740900466383,1.0964609669188408 +5,3446.3637995904246,3152.44442021895,1.0932353882232952 +6,5647.083385598999,5194.660896190982,1.087093748456181 +7,8298.067776017118,7597.446316431478,1.0922180204248844 +8,393.44787948374426,357.6135461413648,1.1002040714873091 +9,1018.3669940341003,914.9844909775601,1.1129882572611558 +10,1734.0023732874333,1569.5779702103255,1.1047570787802754 +11,2326.4707879993175,2121.6886990683092,1.0965184426070298 +12,2439.1543992590764,2226.2684941243197,1.0956245420067776 +13,534.7773999402599,490.2049633776051,1.0909261225254479 +14,1825.4416977149417,1650.3587197798588,1.1060878315948408 +15,1903.754333527428,1719.0885026653855,1.1074207817548223 +16,3777.7805784322204,3393.0178850783454,1.1133983687636797 +17,4293.3128839103,3865.888600803522,1.1105630107960014 +18,2807.495083215058,2544.8523514257045,1.1032054891680505 +19,5578.733645379582,5060.894025910268,1.1023217670273533 +20,1995.7439418939941,1804.0611536930057,1.1062507153976482 +21,2377.786658076691,2145.205937390829,1.108418831326164 +22,6190.219597988151,5547.266461349129,1.1159044983901227 +23,6192.393473569563,5549.312307931532,1.1158848394095402 +24,2848.7927228969274,2576.5832552078723,1.105647456622586 +25,6273.414949967922,5679.30646556161,1.1046093370746746 +26,2685.356943537536,2427.5338578359792,1.106207822753662 +27,3133.1297669953374,2826.089337963004,1.108644983337166 +28,6298.776606784356,5644.548091589736,1.1159044983901205 +29,6317.602529935916,5661.418642052377,1.1159044983901172 +30,1036.9756188415374,934.8052715617229,1.1092958612750703 +31,5929.550501342218,5346.416198273302,1.109070128744793 +32,1413.6076755553152,1289.281167279612,1.0964308728235228 +33,1411.5099250588398,1286.8710025032856,1.0968542474833145 +34,5736.2439905701085,5142.278642802451,1.1155062549165864 +35,6112.915983984235,5477.992061868315,1.1159044983901225 +36,835.1077845068967,751.8221613552448,1.1107783561494384 +37,640.3527879640073,599.0851516192528,1.0688844252494212 +38,617.4152202718674,577.625799092165,1.0688844252494227 +39,648.1508400819165,590.8754002013873,1.0969331941404366 +40,612.5360792183907,551.1529005422625,1.1113723226635206 +41,434.2287631266125,395.3871566851076,1.0982368946102086 +42,2233.815955241247,2038.2747272987922,1.0959346771676821 +43,583.4816428927521,545.879076455435,1.0688844252494205 +44,555.5565868016347,519.7536550053077,1.068884425249422 +45,422.68617189460394,390.36803332761446,1.0827888961386 +46,281.7336844671054,254.680285579461,1.1062249432699165 +47,300.3383125843052,275.3094564245239,1.0909117197964573 +48,1141.543112432139,1030.3814436856715,1.107883997162102 +49,2946.744493225811,2758.075205275649,1.0684061433819045 +50,2274.751354403984,2087.8562873500314,1.0895152928802228 +51,1588.2470874943224,1426.8868278470206,1.113085534534489 +52,883.9242697961704,835.039720202103,1.058541586000527 +53,1381.402730193132,1254.416087589909,1.1012316757250782 +54,2205.728818233965,2042.6973327259516,1.0798118658579976 +55,2105.090673655456,1967.3677025932586,1.0700036759171454 +56,3024.2454597111914,2697.2709541492904,1.12122419701992 +57,7216.704330821451,6607.269280111671,1.092237053595533 +58,1203.4825892383933,1120.678826879723,1.0738871480147607 +59,1523.487485106905,1431.340451819072,1.064378138108739 +60,4322.474950924633,3981.5387522168285,1.0856292554023188 +61,4313.5930469257355,3973.160833789625,1.0856829681398537 +62,3122.522076987296,2957.73634858432,1.0557134608978411 +63,3293.3265009775155,3107.069985577077,1.0599460315554639 +64,712.8333554353464,674.6282049983685,1.0566314158730887 +65,1777.8086073927307,1658.6515131612643,1.0718397404674607 +66,877.0929265936486,811.0101546234158,1.0814820524669233 +67,1342.7293255136549,1253.3279749184233,1.0713311698009857 +68,2364.5907250125524,2212.2205588718725,1.0688765708869379 +69,1269.5968850176878,1184.7617233213732,1.0716052519476125 +70,822.5634389753253,756.093544581959,1.0879122628009175 +71,1454.9831253351915,1335.3155563374871,1.0896174454268543 +72,1169.3030243988878,1104.9320710228542,1.0582578378021414 +73,1063.1215106105353,895.8479518822407,1.1867209255508604 +74,863.2851874632447,812.0618704070366,1.0630780965378082 +75,933.908653439933,862.0475993461682,1.0833608888282604 +76,823.9763193338605,757.4455642042233,1.087835691795931 +77,1198.1340850628962,1101.0557948098067,1.0881683659544779 +78,839.9801726008759,811.1966586914551,1.0354827816424337 +79,1262.985791806962,1178.2495113669254,1.0719170936398108 +80,1151.125717654061,1111.7469786644522,1.0354205945645247 +81,1630.84753282974,1531.6951549071457,1.0647337543668114 +82,1232.8437346748342,1117.302541625501,1.1034108388236894 +83,714.8972973937698,639.0825455566912,1.1186306094012284 +84,769.2842148266324,726.5724330370136,1.0587853045994147 +85,904.9392544581638,816.3181333372706,1.1085619901135755 +86,1493.6019548107615,1374.5205564958449,1.0866348616993395 +87,1773.426301874137,1669.6690029377464,1.0621424358683258 +88,463.81366083667757,438.2114033186351,1.0584244438281456 +89,1131.7019295966268,1045.8753564676683,1.0820619518360473 +90,1360.409730474772,1284.1434889427685,1.0593907473648394 +91,1526.1809467393518,1435.2228609018177,1.0633755832041172 +92,1771.1158737218418,1683.9901737511377,1.0517376534190988 +93,1050.5037384639213,984.7616383008851,1.0667594041096768 +94,1080.059977027821,1015.8176171839906,1.0632420217537875 +95,1716.566935299429,1601.0626191732001,1.0721422852192228 +96,1310.0428371943922,1226.1966279979172,1.0683790896843157 +97,2424.3406585620846,2267.8107333782086,1.0690224818500191 +98,1081.036654399707,986.971312802162,1.09530706756864 +99,5337.070041060727,5008.44062864558,1.06561511591763 +100,7320.444047102662,6763.254385656826,1.0823848445842132 +101,8795.31780067365,8161.620029595609,1.0776436257483357 +102,902.9273097602611,834.7797402670343,1.081635389799263 +103,874.8725062256113,808.929243183643,1.0815191978750085 +104,792.2713869011283,732.751513111601,1.0812279097681812 +105,1015.1272488878267,959.4738388740232,1.0580040932425159 +106,816.0173584132425,769.5906049459587,1.0603265595615528 +107,912.9635671110552,862.2261510180688,1.0588446732137253 +108,857.1732028042591,809.8416063273042,1.0584454986100398 +109,629.7668725591133,594.4310777190525,1.0594447298678444 +110,641.6185058608341,589.5909786493108,1.0882434248412565 +111,860.1328878543211,788.6502844475115,1.0906391651869962 +112,1288.2178663853572,1208.5978994338104,1.065877962380082 +113,1452.945349171461,1355.3887794895425,1.0719768166582135 +114,805.6459388309152,759.8856997618128,1.0602198976549315 +115,913.378717712633,862.613716462491,1.0588502133473199 +116,327.053519271234,311.64597031888667,1.0494392689774932 +117,347.9220926573663,329.06484960435677,1.0573055526157902 +118,472.4298940512998,421.5274302419951,1.1207571800963987 +119,537.4599893761834,497.3978300532998,1.0805434943666536 +120,895.1009081085588,835.5445391039715,1.0712785090648247 +121,685.6473508228004,646.1267647596095,1.0611653753081942 +122,2719.8696268794242,2583.4421143143663,1.0528084263274717 +123,2248.2853341605287,2137.963522788129,1.0516013534358755 +124,2922.4914297394607,2778.2685739329095,1.0519110561015308 +125,6024.418686285043,5731.049592412553,1.0511894181234946 +126,4341.258109674228,4134.47916861138,1.050013298563141 +127,4455.9799304943435,4253.207949541225,1.0476750686443606 +128,4559.432743497806,4352.467630349971,1.0475512124902795 +129,1847.8736114559015,1742.3812086386938,1.060544961282972 +130,2315.153283716055,2192.417946104273,1.0559817245748564 +131,324.4040531165652,299.31328754238507,1.0838277704949102 +132,3404.1114813200033,3267.0150965235243,1.0419638051083282 +133,2079.7564650512854,1978.3419308504303,1.051262389286396 +134,288.77252075264454,266.8230872608489,1.0822621225064293 +135,2184.622968602783,2092.4927965062416,1.0440289076504197 +136,199.22237352826198,183.46818156465764,1.0858687965904992 +137,1251.2837852256416,1184.5290983810323,1.0563554639019395 +138,479.0306860768821,464.3279326631711,1.031664589570097 +139,1415.959165209374,1334.0295318572175,1.0614151571577994 +140,279.60094974874266,267.4436243362621,1.0454575256473302 +141,246.1038769585684,231.12753590267377,1.0647968706861526 +142,370.7219082737158,350.40775448395226,1.0579729002278513 +143,478.4336778189567,449.0470008513882,1.065442318759176 +144,518.9227714781915,497.9699198324152,1.0420765407935237 +145,394.9143318938435,367.8894573739814,1.0734592252595858 +146,361.71090152184985,330.37292845094925,1.0948563588967108 +147,693.3990773141198,640.5086861965826,1.0825756032000233 +148,718.1725477928251,667.1469673167696,1.0764832682688759 +149,513.7026173297638,485.6287400161407,1.0578093407583127 +150,943.0085227031931,871.1949632518508,1.0824311003627576 +151,800.0864232635814,743.2867946918632,1.0764168406829628 +152,868.6630361202511,804.6796512387629,1.0795141082329958 +153,237.37028331560046,233.3729209802939,1.0171286467963612 +154,643.3514390028237,592.5072815694153,1.085811869347384 +155,625.7285189011814,577.9169578737551,1.0827308497804464 +156,94.07438064156322,90.51958643635962,1.0392709947664511 +157,226.25700293978528,214.6018160523261,1.0543107560870655 +158,259.12397518646975,236.36670081408568,1.0962795279284445 +159,425.4855959295943,401.5852656646262,1.0595149581133483 +160,360.7248717195995,338.40966667172296,1.0659413936586024 +161,326.32064595023763,291.3541137738463,1.1200138612202089 +162,331.62089217480275,296.63308891619687,1.1179497654372956 +163,523.7748280164371,452.05192441720357,1.1586607637865949 +164,343.3316058378806,267.3310506726903,1.2842937809653934 +165,501.44445146513397,471.0355177104376,1.064557623812542 +166,694.598288967065,622.0909959051105,1.1165541593420107 +167,481.3701760124787,463.97172956661683,1.037498936545365 +168,358.556109827813,339.0594290422965,1.0575022521585276 +169,509.4740511048828,463.27240611762267,1.0997288946571313 +170,379.0688976982093,347.6033438790513,1.0905214359218203 +171,1536.9316048396595,1441.6353496068261,1.0661028846572216 +172,90.29319560308289,75.58888256906911,1.1945301019707197 +173,266.38334750018896,234.10834415281653,1.1378635326483904 +174,423.5565352832689,411.3912127706359,1.0295711773489327 +175,918.7935496249058,849.7368961426954,1.0812682770345585 +176,437.0411805421561,394.91769732982766,1.1066639542799412 +177,440.29888387750896,417.71226835635747,1.054072186124738 +178,575.0951908598507,520.2862748604226,1.1053437667832613 +179,366.7990242476041,346.7790775043188,1.0577311263625353 +180,357.7668112468468,323.6456609284468,1.1054274919691993 +181,355.42794747509527,310.83393586638545,1.1434657109894169 +182,367.0884348047264,338.30529884062184,1.0850803580752204 +183,559.0798353709861,534.03491690352,1.0468975298706746 +184,549.5948960701321,512.5313058929344,1.0723147830211568 +185,354.4190019951909,338.88114969427886,1.045850447317384 +186,558.5399902199447,518.3178916027398,1.077601215911784 +187,388.44302963578787,365.72067953344396,1.0621303398301982 +188,537.1753830778475,512.2908095879718,1.0485750925531732 +189,245.4582489876234,232.06232497241052,1.057725544276976 +190,379.81736336173003,357.5263624894915,1.0623478523849936 +191,298.95484751355804,279.0545954643027,1.0713131135365983 +192,279.9717872769178,260.1283227254651,1.076283367929893 +193,282.8323841043703,262.6251402083064,1.0769432959846728 +194,463.83893137145526,441.231897912915,1.0512361721024126 +195,556.3366332970653,528.8732496551423,1.051928101222421 +196,575.3719885119156,545.2833615563867,1.055179800222856 +197,566.3746488981868,539.0564721248652,1.0506777641786549 +198,463.9184564240239,448.03059251239955,1.03546156038705 +199,708.487919083055,646.7253676449919,1.0955004311381311 +200,548.6901556974088,520.775780356107,1.053601523715665 +201,658.3380053964077,556.3551116004262,1.1833053955460473 +202,781.1743138259397,749.8124975117929,1.0418262117772366 +203,1036.708741639872,955.8331368791801,1.0846126814819925 +204,179.47484326919917,173.2010578537424,1.036222558298429 +205,439.7992999036912,423.1950365540088,1.0392354869870108 +206,679.6014426472703,666.3750526918201,1.0198482669812177 +207,94.86094617398018,89.78930969577799,1.0564837450625892 +208,424.34298434869896,402.5006953952177,1.0542664626505407 +209,378.08380448944143,355.21827817448275,1.064370354004495 +210,523.5518333886769,500.6776336375784,1.0456864821080787 +211,381.3798988840642,355.1409805665788,1.0738831048887256 +212,843.6780063199068,780.9536202318434,1.0803176839995214 +213,1013.0193024900319,966.3534055510014,1.0482907150437601 +214,771.11103718515,716.9378702997626,1.0755618710206183 +215,931.2781703838491,895.81236581466,1.0395906619763349 +216,926.9468811067434,890.8649672866452,1.0405021132776102 +217,820.6366121192424,788.8443104590201,1.0403023780975522 +218,686.5084448673352,615.1104591410887,1.116073437973959 +219,1916.9807128748523,1777.2364634304497,1.0786300823328068 +220,612.8327013714588,577.2618557655483,1.0616199481234345 +221,455.3973082849794,420.3730756913347,1.0833170215196222 +222,624.0505510924145,583.4829572530595,1.0695266131342387 +223,814.0351947743345,763.4028497889783,1.0663245428011594 +224,1088.7962580600474,1017.7205905614442,1.0698380952078341 +225,1153.6134916077904,1084.8034479020898,1.0634308858796244 +226,363.58509439767283,329.3517226801809,1.1039416810663973 +227,367.2207767507774,333.1331599623087,1.10232429816451 +228,460.2096788050414,426.6297984895319,1.0787096457734502 +229,459.34104133968674,425.80851425666515,1.0787502503127713 +230,303.5241557880576,275.3498702461484,1.102321767999102 +231,865.4133568823771,781.6981913470312,1.107093973687066 +232,744.1038383595837,716.5667605960384,1.0384291866128985 +233,548.9742432172819,501.01810409037216,1.0957173777462133 +234,775.1567113315065,723.7475827627154,1.0710318483863535 +235,421.96901861581574,359.6668881431616,1.1732217574831505 +236,390.5889518267507,347.920955871517,1.1226370393480711 +237,290.99200656160866,267.96225081211725,1.085944030100116 +238,623.6848074118708,605.3528364331523,1.0302831173415057 +239,505.1138355083008,485.68768625933956,1.0399972035498308 +240,363.4730323480116,340.8476703434472,1.0663796879754714 +241,221.33802872258883,206.14857308249938,1.0736820799337317 +242,366.45835240724784,335.5344112050359,1.092163248148385 +243,377.520597423101,352.8169129940285,1.0700184246254958 +244,321.907776291689,294.7392691542255,1.0921781044494865 +245,332.3113888091836,310.66527405018235,1.0696766473986556 +246,201.10337530224513,186.5245433627443,1.0781603947484197 +247,865.1503375615185,794.2612954872664,1.089251537846576 +248,535.0923348933715,515.911520723786,1.0371784955348085 +249,331.4078308511703,312.66750708280057,1.05993690851735 +250,561.6066326232836,521.8211165715958,1.0762435915071467 +251,411.74682108231616,404.15731334597365,1.0187785980501252 +252,368.027162865535,294.0820328128476,1.2514438891264932 +253,451.4226512556684,433.862921178778,1.0404729909372799 +254,539.1063843646749,466.8775662227372,1.1547061229056332 +255,599.9677852758888,538.4138588435833,1.1143245579980283 +256,1029.4837683871276,943.3802535971259,1.0912712710083632 +257,864.4002619770652,803.8273868778897,1.075355575199352 +258,344.6168616317853,310.32212957457324,1.110513330468012 +259,913.3141700903676,850.0695879748764,1.0743992997869256 +260,916.5842613851416,853.1846128608527,1.0743094138930855 +261,751.5217510082699,717.0861997909874,1.0480214948039994 +262,1302.8644915332172,1241.4090134161863,1.0495046172960465 +263,1496.5107441419707,1442.082137944599,1.037743069389202 +264,521.4167965150589,453.59313811186126,1.1495253184065397 +265,1478.6247428821625,1437.2327873286547,1.028799757365988 +266,672.3088598979775,630.4402654025104,1.0664116757655633 +267,641.5210889189003,608.7188351622386,1.0538873645135673 +268,468.0418774307284,466.38398093727267,1.0035547886746108 +269,529.9576525740812,508.773243657198,1.0416382134496776 +270,1554.8819874593835,1456.5879338076393,1.0674824027923913 +271,1846.7160220014814,1645.564166804525,1.1222388401830403 +272,793.2804767181954,746.4874558024055,1.0626842695775667 +273,488.75231233330754,443.0288225332287,1.1032065804175741 +274,299.21545579683004,278.2234759736928,1.0754500667122788 +275,541.0070317026896,507.16496997674057,1.0667279164164296 +276,734.3193994892224,706.9718112764912,1.0386827137610382 +277,740.0591712056196,710.7111883738972,1.0412938241465852 +278,729.62802379189,673.6742340314574,1.0830576366645184 +279,446.78403134862634,424.89617172507616,1.051513430998179 +280,620.4056235562841,539.1183618140999,1.150778136119604 +281,430.3791543544267,393.0618851417007,1.0949399334389112 +282,806.5859507180755,754.4785801588828,1.0690640820422226 +283,929.3456271254737,831.8206379270522,1.1172428102306522 +284,641.953653269009,599.091197797337,1.0715457940782025 +285,381.6770563836496,349.8377332248938,1.091011689520318 +286,437.7133698187122,401.14512413061203,1.0911596414573235 +287,465.6591111369383,433.381574365024,1.0744783319854017 +288,577.4965366342756,540.4986671225113,1.068451361237822 +289,288.9572565862203,274.423623110974,1.0529605771926167 +290,289.53144179209414,274.85807781277254,1.0533852382876547 +291,816.5646230110399,684.9715854437113,1.1921145933113197 +292,439.79531990030506,402.0128873431568,1.0939831377218943 +293,458.24578892273985,402.72378018674215,1.1378662285853898 +294,401.63898454136483,360.92568232264443,1.1128024527285518 +295,1000.2359341324386,943.8864347319155,1.0596994482885302 +296,586.5364198730537,543.0181226405573,1.0801415190728407 +297,698.5730658959748,647.9752060962677,1.0780861047207875 +298,669.7090565067144,622.6739098682432,1.075537365373834 +299,593.5659404893115,551.1158343930937,1.0770257420438032 +300,485.9325140837668,430.2130561928477,1.1295159621235258 +301,233.41904921907067,204.36503132589135,1.142167266604668 +302,315.31499234122487,276.1426188279883,1.141855587809998 +303,285.8636852028997,248.27824556373847,1.1513843452285564 +304,785.180118126691,754.1120158409163,1.0411982591884978 +305,564.3236593706544,536.9353229121008,1.05100863230605 +306,685.798895750358,649.1808034099957,1.0564066160736978 +307,711.1635780466881,633.4850198857183,1.1226209866414572 +308,663.4975084072835,604.4117045339995,1.0977575441210874 +309,746.2274141227695,722.1351275561882,1.0333625739106655 +310,375.60599437373304,349.0816909973853,1.075983083789251 +311,739.9820323781148,679.4118310086461,1.089150937038507 +312,794.4406869550767,746.912808558319,1.0636324318610832 +313,519.645909807253,416.1358536480741,1.2487410187124066 +314,366.7176415195325,352.09946876488965,1.0415171678785007 +315,502.03026376071875,479.8984132065517,1.0461177823162364 +316,866.210249696327,778.7441057969942,1.1123169257375205 +317,723.706386060446,661.1780283792697,1.0945711366641306 +318,254.32413108730407,226.7958931108518,1.1213789085810173 +319,656.9303977431572,616.503013814365,1.0655753224605733 +320,853.1804443951899,739.6739276541458,1.1534548028494482 +321,958.5722090461142,885.5282864347992,1.0824862669326973 +322,493.5888250699082,457.07295363154424,1.0798906851701406 +323,887.6060054477853,852.760441588112,1.0408620782112965 +324,892.6916733467955,840.8916804231945,1.0616012669997301 +325,1162.7123112033241,1104.7586917339693,1.0524581701895406 +326,1293.0361034624411,1213.5452105905472,1.0655030337379943 +327,739.8456219809391,677.7526467377236,1.0916159834153245 +328,607.0526032042573,542.0002719691932,1.120022691130239 +329,1307.5190391222702,1236.908380097085,1.0570864100861237 +330,932.9236153276106,899.2851115241488,1.0374058275538998 +331,724.1802076684087,666.6354274845274,1.0863212151820671 +332,1296.3622369083914,1239.3687732879916,1.045985879948547 +333,588.7458275853583,571.3521141884178,1.0304430717328272 +334,753.7823005405658,680.1905657106903,1.1081928191006059 +335,534.4031090962077,484.41607689142546,1.1031902832902594 +336,1297.6258278253963,1203.0313489515636,1.0786301029946321 +337,1550.647829918182,1448.2526746958945,1.0707025486721704 +338,1053.7921053701477,996.458323146391,1.0575375616741511 +339,689.7587499020274,651.2384813834923,1.059149251187833 +340,586.2995541941191,561.7353905678972,1.0437290653903581 +341,749.2711029953405,727.2943962769257,1.03021707142378 +342,846.0717309513932,793.5343889194974,1.066206761503345 +343,1361.9042496054417,1261.9090702135086,1.0792411923745142 +344,896.6932185883402,853.6999819097534,1.0503610607820437 +345,572.6877293458657,504.571132095046,1.1349989979965571 +346,980.0266124693915,897.7978148414634,1.0915894383664193 +347,1433.1984189797322,1277.082783676934,1.122243943226073 +348,3169.518197961122,3005.3699132260754,1.0546183296813683 +349,675.4781985004199,629.385752826949,1.0732340150161361 +350,1373.593017546874,1292.291232066174,1.0629128972350228 +351,1300.3630272005437,1216.790523778658,1.068682736912149 +352,1023.6979455123318,930.1637077808252,1.1005567481821663 +353,295.48693304030047,277.9156974261274,1.0632250562919128 +354,1729.127932321823,1631.5521642310762,1.059805484758578 +355,1053.5196870850555,974.3683489032636,1.0812334865668447 +356,206.02890230899618,196.08421813600984,1.0507163925150182 +357,91.51382155745591,91.41346121630214,1.001097872674532 +358,551.1757034751289,507.1089900712569,1.0868979139921773 +359,539.5120033650522,507.9411545471064,1.0621545400196903 +360,504.3350514472461,443.4189882745844,1.1373781114103751 +361,736.645364510372,651.7257259911261,1.1302996569455694 +362,589.2683890269819,534.3747457149638,1.1027249954310125 +363,584.7658737213608,532.6928514480069,1.0977543102592893 +364,198.94516597553763,168.74750259807308,1.1789517646930163 +365,599.532288422089,533.1962364680137,1.12441207836255 +366,483.0163998113642,401.289077701671,1.203661965029737 +367,195.2752753580507,168.65087702252322,1.157866942678109 +368,1058.8757054935618,949.0731918663132,1.1156944633651769 +369,688.847594404672,651.2404447787793,1.0577469503428454 +370,800.5319168129535,781.8740655935185,1.0238629877118022 +371,589.1651307906311,539.838742974739,1.0913724486391674 +372,179.68488937793438,162.87723477832736,1.1031921656975692 +373,217.9817551615065,199.97663899741138,1.090036097488008 +374,454.5915613000705,430.4518430074748,1.0560799510670849 +375,299.5174316158907,291.51737693040275,1.0274428055360758 +376,248.9600332929434,235.49206414676033,1.0571907558540474 +377,331.3998739754187,282.1276834977883,1.1746450042291459 +378,689.7736045713663,577.9164386320413,1.1935524903982604 +379,591.6348111708057,539.0145857512995,1.0976230083758534 +380,408.58603627866296,376.5016611466864,1.0852170878456666 +381,246.09127468868675,211.3741468452072,1.1642449105609092 +382,337.479609008466,311.0029632060885,1.0851330981847673 +383,272.2066334090452,264.7766731316434,1.0280612343584652 +384,499.8509263511553,473.3943793407177,1.055886905643626 +385,375.39475673270425,355.3101833997056,1.0565268722129604 +386,651.954379612702,591.7740286502863,1.101694816008865 +387,629.0305676019027,611.8252929008437,1.0281212216962847 +388,961.1947994155202,889.4766419753339,1.0806296130283037 +389,414.3575581012328,400.6853298059604,1.0341221084931995 +390,546.1535982226443,520.0713573564276,1.0501512734690779 +391,284.87865836889966,259.89905038341806,1.0961127328038722 +392,639.6865810856071,613.591480419493,1.0425284598936637 +393,643.9517892620469,617.3305762954072,1.0431231077624459 +394,421.954295171257,382.8077130589247,1.1022617381439923 +395,272.7774846668158,261.9542888118897,1.041317116448123 +396,651.3459211766318,610.2487217513981,1.0673449987855539 +397,601.1319332184277,546.795687406641,1.0993721184406084 +398,225.7200170489887,211.12399841682497,1.0691348152820912 +399,110.26698236205884,99.16219566011321,1.1119860913528803 +400,679.8264273014985,609.0648573966125,1.1161806809989814 +401,860.959794253114,802.2549366219912,1.0731748163224872 +402,177.98100803473963,145.9172068611543,1.2197396856978988 +403,541.8587629094667,505.9244062459067,1.0710271262266282 +404,543.3171154178755,521.8574746974468,1.0411216505672745 +405,548.518134860175,533.1997801658296,1.0287291091710151 +406,496.3606610846389,450.68971888584446,1.1013356646157764 +407,988.7035362854049,921.9725819432912,1.0723784585887155 +408,588.5468009794973,539.3306480926178,1.0912541370695992 +409,321.35189728352185,304.8976495208313,1.0539664631345949 +410,674.5394906434294,641.1012184237513,1.0521575552482825 +411,514.1441636885036,480.95911119647104,1.0689976584693006 +412,324.7512679720171,310.13153883354204,1.0471404140109786 +413,532.4232316196279,513.0482662266378,1.0377644106186907 +414,248.05782176266086,244.6698170747993,1.013847252302583 +415,438.25329983890566,406.73448280433786,1.0774923650860704 +416,572.2055926819311,518.3079688230299,1.10398764267756 +417,2729.2721963132735,2584.1637314786,1.0561529685859516 +418,280.3943348438249,263.7329544124354,1.0631751935153837 +419,1078.1886664962374,959.1611969212769,1.1240953762068522 +420,490.51972014641683,478.36852463976345,1.0254013273883433 +421,629.345614224198,585.945453760258,1.0740686017536665 +422,552.2916228879483,496.3684419654398,1.1126646583353947 +423,626.5658819442376,598.9398387690696,1.0461249050187487 +424,540.7804948679129,533.3489134285943,1.013933808154863 +425,465.158629436036,424.9153254774995,1.0947089962295735 +426,576.1954251755241,541.6622753421774,1.0637540242423777 +427,470.3469714428288,447.00998051229345,1.0522068677388146 +428,1779.642221322064,1671.0982423563585,1.0649536790922904 +429,1120.9796761431646,991.848384561656,1.130192571356133 +430,714.7914640064361,660.9282373646007,1.0814963313666408 +431,2087.4897427806377,1959.2671949992252,1.0654441354954973 +432,1445.3279838297015,1349.3823535162085,1.071103368191735 +433,306.1524793908451,286.03066644217597,1.0703484461961947 +434,306.29157409992956,286.0973354825301,1.0705852034005838 +435,506.4761154400971,475.6082805040017,1.0649018030203024 +436,717.8726706619995,686.2450535260277,1.0460879345846856 +437,1905.734410299244,1787.8606390170473,1.0659300667567708 +438,1173.502978996329,1105.6812635894537,1.0613393006106486 +439,442.67324211199264,420.9482939881541,1.051609540730078 +440,389.32614875840585,358.05130463205285,1.0873473821258444 +441,450.4862423622394,435.72433010579124,1.0338790176184656 +442,298.0267132639301,291.66733991429453,1.0218035154416132 +443,1059.8676977629293,994.8680527055375,1.0653349405286718 +444,589.2349667197734,571.343463469912,1.0313147946791967 +445,851.6996060899377,793.0139445903728,1.0740033159566678 +446,701.4040798914979,678.1800249534683,1.0342446755780266 +447,934.6091637854745,877.674144327278,1.064870339209817 +448,625.3187167729142,571.4662429272938,1.0942356167352336 +449,672.6032847029999,633.8895584207169,1.0610732986022597 +450,809.324580090076,730.545280460371,1.1078362994557438 +451,271.17455742906515,242.41657583907048,1.1186304257060615 +452,767.7293471262476,698.0331345683572,1.099846567600245 +453,2643.815426220109,2542.967975686453,1.0396573812560237 +454,203.25253320436838,179.79695752958276,1.130455909805517 +455,1317.6196320659562,1234.315321398643,1.0674902994584223 +456,270.5968628435161,261.24345581479855,1.0358034118004793 +457,143.80203658548078,126.2666750202037,1.1388756103894497 +458,184.40958214082283,162.0304544905149,1.1381167986023146 +459,3079.8530502577537,2895.575363436691,1.063641129548204 +460,284.6853777875873,273.4991365655649,1.040900462657734 +461,953.242332611096,898.5783222016686,1.0608338851036283 +462,949.1763209518565,894.7602863725598,1.0608163274656548 +463,290.2520268712928,278.6562048918624,1.0416133636210627 +464,327.7559085529118,293.1990595402777,1.1178613910522688 +465,956.4342640115079,868.7068792995661,1.1009861747413303 +466,869.1192576171763,761.6828094569632,1.141051428266852 +467,434.98783405519424,400.0660972850041,1.0872899178590285 +468,1058.2954198250277,993.8257388689153,1.0648702065509856 +469,357.5505460161984,336.4767354864333,1.0626308101191584 +470,355.7146919858309,334.766545885136,1.0625753868126433 +471,570.5565250393025,531.4630731486151,1.0735581715190128 +472,492.98898210061225,465.21414758606056,1.0597033315918527 +473,216.02043197074414,208.97734281964932,1.0337026447750994 +474,390.5250224845427,363.4059631881139,1.074624695364151 +475,802.8965934147674,739.2759302551399,1.0860580746050674 +476,367.53109352998,331.4194466581833,1.1089605550788373 +477,550.0431262593434,514.6760879007282,1.0687170808787152 +478,607.9682930433573,522.3356477065535,1.1639417981767004 +479,1045.3837753269324,1003.7209480292992,1.0415083767848363 +480,623.8484363952361,550.5581101325063,1.1331200556560517 +481,416.6795474438982,351.74318114770404,1.1846130068088685 +482,265.81202093751335,242.9078047186569,1.094291808554216 +483,847.4894664622412,782.7995150172226,1.0826392329121401 +484,272.27183212612704,251.61531099508576,1.0820956445351002 +485,846.5873630475255,782.253559279836,1.0822416248599966 +486,246.78797674691347,234.10100962540977,1.0541944143761037 +487,409.7130476424878,388.9758834225148,1.0533122106119053 +488,259.086872880366,245.5105328755787,1.0552984014403473 +489,665.3196813490714,614.6855852247646,1.082373976780002 +490,391.83022923809494,372.05443709697784,1.0531529533565607 +491,637.7533188602271,589.1075625470867,1.0825753383691321 +492,761.7895935375916,755.3692251075578,1.0084996425809107 +493,1977.415504111046,1871.949985099451,1.0563399235295232 +494,3955.070632067969,3849.3016009249027,1.0274774600976064 +495,384.19022382701013,368.0627390622978,1.0438172166131237 +496,381.84899706415763,365.72102335542917,1.0440991156613229 +497,242.01961765291725,224.21065100738758,1.0794296192688138 +498,410.99261242809683,381.2194738887641,1.0780997314634042 +499,620.9314956224008,600.1525042112789,1.0346228521339416 +500,260.2444669274577,245.0265863713698,1.0621070585908716 +501,1343.6879751526571,1279.7116155235433,1.0499927943554224 +502,1329.5094748353847,1250.92004523509,1.0628253019844487 +503,1637.8779457362398,1534.0160715104469,1.067705857946799 +504,437.28123596079064,400.79365110436447,1.0910383304622882 +505,174.93850996388352,163.43741458933292,1.0703700275940442 +506,310.9385757992902,303.96618597905496,1.0229380442359983 +507,324.7294583411948,324.5087404414903,1.0006801601072568 +508,253.53575261629717,242.0722161187541,1.0473558538908048 +509,869.5017405716437,796.6206891940435,1.0914877712394533 +510,254.1335231620356,242.81441043088554,1.0466163137149223 +511,671.7088908730659,624.8477863784332,1.0749960318595924 +512,466.77423744619443,439.50781620418286,1.0620385354633701 +513,674.2115247795866,627.1625953865359,1.0750187108401343 +514,466.3736112083081,439.18949527441146,1.061896097758239 +515,1174.2434225758357,1097.939565509258,1.069497319764759 +516,1321.350502823959,1195.1358741310637,1.105606928404405 +517,625.2225601046255,581.9709123152364,1.0743192604202887 +518,280.05298283796753,252.54552195728567,1.1089208023468116 +519,207.12891532017454,197.09732510069892,1.050896632992611 +520,279.92381672954593,252.64949521588198,1.1079532001057781 +521,207.25285737962702,197.18985751231568,1.0510320357966831 +522,545.5921220748646,494.16382995656426,1.1040713403140427 +523,475.03738164594364,433.43137754427266,1.095992136834674 +524,481.0782781994994,438.3547872111266,1.0974632700151068 +525,733.2823991212052,675.6840304773162,1.0852445315352508 +526,471.80039189372656,429.21707071686524,1.099211620604325 +527,4165.193104707423,3735.538618930361,1.1150180816227486 +528,521.7233097256867,464.47653594010063,1.1232500876921987 +529,453.69323559455216,432.70396780763264,1.0485072228324255 +530,1042.5368912966994,934.9258315540095,1.115101172853275 +531,413.4793234645548,363.39685200599337,1.1378175710166456 +532,363.59694447171523,340.87568734015133,1.0666555520836865 +533,292.29823733407574,285.4821248040427,1.0238757944467158 +534,259.5874036847489,252.33027252524892,1.0287604459301403 +535,178.65859191043265,151.12966962515583,1.1821543205484157 +536,148.14398037777195,133.85361821201852,1.106761119771287 +537,198.4873445646488,173.04071218410624,1.147055753870619 +538,449.13775897806033,433.6511245497718,1.0357121970901544 +539,923.1678968056643,798.1642214332,1.1566139799501476 +540,134.43109396670525,128.49617828888614,1.0461874878836954 +541,344.0095333954205,292.8780595725783,1.1745828072524882 +542,410.7967937423567,403.601421995782,1.0178279147555875 +543,248.21436042480855,238.60536648725508,1.040271491287128 +544,386.9273621098437,373.0229295088266,1.0372750077839066 +545,104.97938172704143,100.9478893361243,1.0399363713043424 +546,195.50632460624954,195.5011662251199,1.0000263854238276 +547,1578.2065684167546,1514.748713163182,1.0418933217781428 +548,435.8204313157761,402.99631272027256,1.0814501710299453 +549,114.62232441698775,105.5369800312582,1.086086833099058 +550,118.31650515473675,109.11043291527056,1.0843738952682476 +551,824.2424095589498,783.3513184555127,1.0522001943956125 +552,1085.4062185303433,989.4087586920891,1.0970250758292803 +553,241.10072391135492,226.60277931253694,1.0639795533082232 +554,629.1375099126936,596.0417984364996,1.055525823126849 +555,230.3944766860219,189.78195135899594,1.2139957200155582 +556,187.4928863867619,176.5617851918493,1.0619109122794326 +557,405.3443108132535,391.0057819180697,1.0366708871281813 +558,243.41181656459736,234.40511764722896,1.0384236445337476 +559,263.2949150708932,253.32201291748297,1.039368478240613 +560,246.39341873753798,206.01562108415825,1.195993864158899 +561,299.37890412026195,275.93866678144514,1.0849472732916494 +562,675.2494408045701,644.549280089276,1.0476304320920844 +563,594.4042521416065,583.7260295749859,1.018293209529127 +564,241.25705697576262,216.9256511058707,1.1121647243922157 +565,68.0599609103607,64.94119762169224,1.0480244190573211 +566,160.58693369954722,157.76338977828536,1.0178973329948726 +567,143.64433624471084,143.6228835823433,1.0001493679964673 +568,853.3990164632435,785.6128811329447,1.0862843990446585 +569,810.0640417737034,743.8048745959852,1.089081383358382 +570,7806.312352607709,7222.701290325217,1.0808023257260047 +571,3023.71815132052,2791.9178629646794,1.0830254684175045 +572,260.5165820457793,240.26406179177283,1.0842927573228096 +573,607.536287905399,564.2425886541766,1.0767288753486084 +574,890.2034762380505,824.2308066378216,1.0800414993821241 +575,929.1504801004271,854.522683866428,1.087332726963237 +576,209.89335597788718,185.53717846037353,1.1312738380502836 +577,169.23655244123728,157.01099844411968,1.0778643159922883 +578,636.4159391698406,603.5240106915098,1.0544997844255504 +579,507.1713707560005,486.04304854222624,1.043470063561538 +580,463.9650003386223,414.45852726292856,1.1194485571394392 +581,149.30239687552157,142.59426365044402,1.0470434998810463 +582,374.1373752410401,364.96433382698086,1.0251340763023926 +583,322.9783435945955,293.9150393663225,1.0988833517704066 +584,317.92822010106636,272.99729143752614,1.1645837891905326 +585,143.57104332399973,130.90809468905312,1.0967315937568642 +586,207.56452557691395,199.83520519056805,1.038678471988832 +587,177.47578277045352,161.3602025782002,1.0998733264755491 +588,182.61581936125856,160.69343928550393,1.1364236161303707 +589,170.98860735451086,160.6321753578385,1.0644729611212789 +590,165.56687982264052,155.46197335225614,1.064999216544666 +591,179.41443636043743,156.23984839396252,1.1483269998319483 +592,1070.7538695912938,949.3480496530206,1.1278833616213213 +593,84.50532375610976,84.23868232608962,1.003165308652241 +594,152.7749593593033,140.68205800120654,1.085959087675509 +595,152.20475274924877,148.10823831151208,1.0276589235307803 +596,329.8614842489202,318.5151488255327,1.0356225927251028 +597,1176.109217395178,1159.1093115553492,1.0146663525780992 +598,895.0099218249118,837.1073638209158,1.0691698108349017 +599,496.3700922554636,474.7587734541184,1.0455206307070675 +600,191.6809897392677,191.55852798108342,1.0006392916017623 +601,148.18184957973202,123.02895295533696,1.2044469697594378 +602,114.97088972743632,105.34207109971953,1.0914052526896105 +603,122.81297364680934,117.661439215679,1.0437826909603523 +604,285.3665129306292,253.59847465250778,1.1252690432056085 +605,852.07687980034,813.3503519401551,1.0476135871433598 +606,343.4837779321524,336.21551129820614,1.0216178801682343 +607,481.3948028653687,429.08649516118874,1.1219062084080043 +608,1192.9179709784516,1118.3058591268648,1.0667188777047465 +609,419.49408793418655,391.3944267809568,1.0717937181281216 +610,397.32762608667986,369.61770071253943,1.074969151425167 +611,376.0155648871773,348.54949200604995,1.078801069894116 +612,414.28575030925685,386.3554465381901,1.0722917303776276 +613,109.03971178210158,107.87495052409122,1.0107973283172003 +614,153.68145406682942,144.88708698424352,1.0606980736905993 +615,430.66992290177717,385.373996305818,1.1175375791572975 +616,109.32359689201823,108.09060138011631,1.011407055712142 +617,269.2083013407881,230.54511353157793,1.1677033497563785 +618,170.7100863525387,164.22077881548398,1.0395157518059637 +619,171.28154100082716,164.7953418598935,1.0393591169976644 +620,385.9635633821089,324.7760761634988,1.1883989976768088 +621,1315.486625013579,1287.3367581197028,1.0218667467671723 +622,559.5214848703991,516.9482523433965,1.082354921085452 +623,205.42984316784197,180.90993880907072,1.135536524528092 +624,166.6404478048215,146.07138632856706,1.14081513151376 +625,210.33235050419592,198.0724420883716,1.0618960835064297 +626,39.95449326161085,34.609618741285274,1.154433210035618 +627,92.51558986906207,84.04689253916808,1.1007615757590008 +628,59.39630915136592,54.21396459522961,1.09559058436011 +629,187.22349964570756,167.56003424236172,1.1173517628607323 +630,327.3129208671196,306.0064673133007,1.0696274616052628 +631,993.3262787343637,911.8579957576856,1.0893431689536088 +632,1068.5593524665273,1026.6724645695972,1.040798686379974 +633,1098.7520412860822,1056.110377175898,1.0403761434711118 +634,883.8220566214032,865.0959098527826,1.0216463244772565 +635,798.8730896826652,771.7382247581911,1.0351607113059305 +636,322.9895836895231,265.6655430088973,1.2157752188386206 +637,268.7061444388782,240.3854977831331,1.117813457620871 +638,299.03718883620155,267.4521089529813,1.1180962079785768 +639,272.33828604058704,243.5958854176247,1.1179921433142679 +640,873.2056794099237,840.3972119253727,1.0390392388491936 +641,239.94520190632014,228.27859528126407,1.0511068793404899 +642,91.55400529842316,86.02943365758283,1.0642172266625562 +643,334.29723970631767,313.97453737524415,1.0647272307524256 +644,192.54955484515204,165.301483344382,1.1648386387677028 +645,455.3021517876138,414.5887423277566,1.0982019174743314 +646,339.0876385720931,301.2477955864414,1.125610356457509 +647,288.0021933053879,263.04869761896566,1.0948626467733673 +648,369.1084340848648,342.9805946294793,1.0761787688997722 +649,345.5688791816119,324.90923916993097,1.063585880366042 +650,1638.273126009631,1552.6972983442708,1.0551143019032843 +651,1223.7987359398912,1095.5910414240068,1.1170214885558438 +652,752.7047055369725,710.4371840177889,1.059495086223028 +653,286.09557408157974,262.22243414405983,1.0910415617772982 +654,166.86117906781055,154.77026258830358,1.0781217029505816 +655,113.26964640189166,103.75564156065325,1.0916962653609226 +656,296.54477151456837,280.8194706138401,1.0559979009516487 +657,316.7237850349228,300.18973356382094,1.0550786706620887 +658,264.52953327305556,245.19036386000843,1.0788741005502518 +659,263.8005621186031,243.8633919560568,1.081755486145862 +660,264.3760860406761,244.5027670498336,1.0812805483988326 +661,267.58008949525475,248.33639993318832,1.0774904104563152 +662,234.088347913325,194.10541788862574,1.2059856466636123 +663,255.93252369562316,217.33677104028953,1.1775850099851664 +664,729.5276142564128,713.5553009803263,1.0223841281175303 +665,241.20715208029915,200.02842052845165,1.2058644038834987 +666,242.33275408978633,200.94165694277166,1.205985646663613 +667,162.47326515139832,162.3546631020732,1.0007305121211736 +668,155.72075463042955,143.82613842157383,1.0827013527540523 +669,181.91763280661584,167.4266487497801,1.0865512399910278 +670,150.50715957410893,138.71905007772207,1.0849783031947102 +671,535.4059952195818,507.46331795169624,1.0550634425768393 +672,514.9087163926531,510.8689113212821,1.0079077136655716 +673,212.97771409325867,203.36654611340285,1.0472603196717338 +674,288.96337053969705,241.86452992121545,1.1947323182685097 +675,278.6033481525209,259.0207559661464,1.0756024053490674 +676,346.8479289002994,306.02896220628844,1.1333826916241203 +677,1237.8294077795485,1215.6247641466261,1.0182660342959615 +678,1469.118843009576,1374.8509670169826,1.0685658869609167 +679,162.83477224532274,160.0612946933273,1.0173275966392084 +680,1429.016884662874,1335.7991217918077,1.069784267222774 +681,732.2760837536252,713.7277129191195,1.0259880210600814 +682,775.8128380797843,740.9671852363301,1.0470272551035311 +683,1293.075129473537,1236.978369409254,1.0453498310492473 +684,400.20241463798936,386.3479285952358,1.0358601276655697 +685,557.2993114892525,547.8906187288745,1.0171725750336928 +686,115.88275181025381,112.2276010008295,1.03256908975001 +687,114.35567246779169,110.7676920979691,1.0323919393991632 +688,254.77759691108307,222.00508868839333,1.147620527152372 +689,89.40678073287819,82.70569983297862,1.0810232053344833 +690,566.8278709386377,557.2583107835583,1.0171725750336926 +691,82.95157834324417,82.94519276771376,1.0000769854806206 +692,82.92770088827453,82.927576731162,1.000001497175215 +693,77.98050617866768,77.27101282470682,1.009181882416507 +694,70.54975185059858,68.69488008180161,1.0270016013797272 +695,294.6679162056675,291.8632257814644,1.009609605378319 +696,198.28881058708393,192.25381754931433,1.031390757877781 +697,284.79428084712043,266.8347815216185,1.067305690896398 +698,778.2231295355616,712.2965792491527,1.09255491631857 +699,204.17316792432112,183.44010891352931,1.1130235864642068 +700,922.6138486308605,902.2665958527173,1.022551264639154 +701,474.6044286302828,445.4675732062152,1.0654073543767901 +702,269.7131509081001,249.73076049378304,1.0800157352454565 +703,75.88245580285422,67.94745404345304,1.116781443412533 +704,89.85037569863428,84.5595942264278,1.0625686714867528 +705,199.9694096637273,179.390382198956,1.1147164480755039 +706,46.85485520248383,43.51355301431189,1.0767876203322897 +707,646.0657184927227,625.5010766878759,1.0328770685955326 +708,456.14478758465447,424.1871891354317,1.0753384337569412 +709,546.6716969052172,535.7935042650128,1.0203029573027895 +710,264.6691159632415,258.56347551577727,1.0236137004087094 +711,383.1931363650983,375.62869987330214,1.0201380685084702 +712,225.72802259546907,220.9028667433674,1.0218428847177763 +713,50.29343363009293,48.76249507043372,1.0313958208546934 +714,71.88182599473696,70.34529179148615,1.0218427440432734 +715,51.00802421827482,49.45041226618136,1.0314984624134003 +716,63.29127545816372,61.76743207874472,1.024670661028555 +717,219.75855542083335,215.06100608895824,1.0218428687622338 +718,1364.9996544566875,1273.7950277181278,1.0716007087120942 +719,1374.175596959433,1282.3541542461699,1.0716038096100218 +720,1577.9306641223918,1494.5691226667047,1.0557763038132009 +721,1340.9513566938774,1251.3144031496581,1.071634237821123 +722,1347.3196034182793,1257.2569593872709,1.0716342378211219 +723,1610.0409287441153,1530.7443479593892,1.0518026284992887 +724,1346.57762303959,1256.4348190654741,1.0717449107635868 +725,1354.611608636214,1264.4390860381145,1.071314248028063 +726,1624.0011368135488,1544.8646506865482,1.0512255142169458 +727,839.7043923058782,785.112487578949,1.069533863733685 +728,222.55318872475655,206.2350591134019,1.0791239359665898 +729,4120.059502069351,3942.4928993196263,1.0450391686895284 +730,458.5107102559005,437.1898435004105,1.0487679827710132 +731,475.75612031489146,437.0176243166336,1.0886428689434058 +732,417.4951352544647,381.688926155604,1.0938099238547556 +733,335.17803857655997,318.0913451509384,1.0537163103809495 +734,1047.6650740556922,987.1716302631922,1.061279560653877 +735,3944.5342991930684,3605.6207211909277,1.0939959036762463 +736,1360.7775583962136,1293.476942788737,1.052030781053102 +737,1857.6609399576319,1765.1432957907975,1.052413673375671 +738,1587.3136384861355,1479.649272182857,1.0727634368004293 +739,471.0546202996289,423.9838779970549,1.11102012304086 +740,270.2692821043431,247.79247523713846,1.0907081897692585 +741,257.47740719358126,239.41094001257014,1.0754621621721319 +742,479.0837403057549,433.0605429795854,1.1062742798259018 +743,1353.6073548102613,1232.146896066006,1.0985762810684778 +744,129.55270319557835,122.58045746059764,1.0568789338808093 +745,312.2446400890602,285.9532817575687,1.0919428452434456 +746,181.19720406764685,170.31376689475786,1.0639022750263882 +747,282.43675698442456,261.6500120728062,1.0794448459869908 +748,1398.2859481518785,1288.7067619662728,1.0850303493545832 +749,2192.0181079221566,2060.407595199233,1.063875959800176 +750,101.9057291018664,92.93681359924075,1.0965055197749853 +751,101.86587841610975,92.92223230447416,1.0962487220747166 +752,102.2614787338451,93.2850695219902,1.0962255724077998 +753,104.00735641893114,94.98409418130697,1.094997613183534 +754,54.02016290478402,53.43760661819126,1.0109016163608355 +755,459.3784054464599,451.3797163329236,1.0177205328997034 +756,371.7022395511468,350.12874514020245,1.061615890469963 +757,254.2882915534273,237.47205982598484,1.0708135169239072 +758,1194.6925489370385,1142.0158446407565,1.0461260713180844 +759,407.0756074033151,380.287544339457,1.0704415999487646 +760,340.37849388594157,318.81233665989856,1.0676453033530169 +761,193.26621664922618,185.99673564757623,1.0390839171254276 +762,296.84214107395746,279.15017480688556,1.0633779515965236 +763,1589.472072368564,1455.006649796816,1.0924156756194383 +764,192.67205644536045,188.34689200713,1.0229638216598058 +765,342.174375345135,315.92154075475577,1.083099223078172 +766,567.1530256712443,527.6475751636702,1.0748709031692603 +767,556.2083772468326,521.6299959380575,1.066289096827325 +768,667.7337813202631,622.7570145887377,1.072222015453696 +769,1703.6778208098913,1563.5423031451146,1.0896269435005945 +770,331.50375571834246,309.7507130374184,1.0702275790348101 +771,937.2392190804568,885.3640090146359,1.0585919571358624 +772,1197.9845870900585,1102.9370587240662,1.086176747452795 +773,2426.64070397115,2225.69425181949,1.0902848412298263 +774,814.9845377523288,763.732073968432,1.067107910654562 +775,824.2071902346338,772.5722538100144,1.0668350904009 +776,819.3712637008836,768.0377640158836,1.0668372078692974 +777,823.9972832955465,772.364262976706,1.0668506076651525 +778,4770.809910874593,4503.655402895774,1.059319482526803 +779,946.6459594555585,894.2303795311731,1.0586152977176484 +780,143.15265332064848,135.99812901246895,1.0526075201190714 +781,143.10730942714562,135.9720567817855,1.0524758749278251 +782,146.75043072202877,139.49421675036288,1.0520180272752921 +783,146.30938541869787,139.2026174377732,1.0510534076997622 +784,1642.8532541999846,1543.2899648827286,1.0645136633962509 +785,2195.517925946823,2076.910182312266,1.0571077866749676 +786,1170.5744382093765,1105.5161239334295,1.0588488153790732 +787,330.36657855307806,314.7529546677428,1.0496059644676479 +788,372.8548718781408,354.2197159295465,1.0526090308092866 +789,341.53482856788094,323.3466115074988,1.0562499077246719 +790,251.03163453911984,238.93849306211192,1.0506119433584287 +791,525.5283996748681,482.58045368080354,1.0889964474658806 +792,794.5062413753841,755.865632741468,1.051121002146598 +793,735.4133741674848,707.0231844495383,1.0401545385531452 +794,1124.5521602260314,1076.3068338121411,1.0448248816213603 +795,382.4538583642559,364.6062694050825,1.048950307377585 +796,645.4851058374137,617.7499477811602,1.044897062566938 +797,1040.903422845019,1003.1697521105334,1.0376144422766924 +798,2988.6972995629994,2876.7053124187355,1.038930642864528 +799,4620.83896933922,4439.086380408021,1.0409436927682614 +800,2140.189993277252,2055.98633096933,1.040955360957202 +801,2078.2863093287638,1996.4588985064574,1.04098627368864 +802,557.7419906582969,527.807068959911,1.056715651340887 +803,2040.5859659246557,1956.620948710164,1.0429132772343273 +804,3605.7824210739377,3463.9552995271106,1.040943692768261 +805,3543.7065431389706,3404.3210672759096,1.0409436927682603 +806,606.3176178837075,569.8222468431509,1.06404693962502 +807,527.968383053604,506.8943492984545,1.0415748050541818 +808,417.66064963938044,398.2475398296636,1.0487463395706602 +809,294.52773661778895,262.1592965413245,1.123468595252971 +810,232.65243114873343,223.07783969244292,1.0429204060317734 +811,210.80880351747717,191.01539536810077,1.1036220568045474 +812,2619.0944563357134,2518.6736252926116,1.0398705215454167 +813,497.7243165934755,484.1721440183903,1.0279904012292174 +814,1756.544330433587,1687.4537428266415,1.0409436927682607 +815,1773.2146686806257,1703.4852467445144,1.0409333876353608 +816,1244.1830577300507,1196.922105709132,1.0394854032651677 +817,6401.939117372134,6151.832118054676,1.0406556932175428 +818,451.4178861771213,423.80856509739937,1.0651457364326198 +819,389.16644523860845,365.99350588348216,1.0633151653857587 +820,607.8382245387302,582.4259209809633,1.0436318210476718 +821,1289.8609831905214,1236.1136074212884,1.0434809352850325 +822,1665.1848386154734,1606.8017465942028,1.0363349692300374 +823,936.1785429971329,901.9592192922263,1.0379388812409487 +824,942.9879591107092,908.5265550863662,1.0379310916465914 +825,553.992888504749,535.1114811502036,1.0352849976493876 +826,934.0594901708074,899.9197314964913,1.0379364486403078 +827,285.83455102122707,276.67087327970125,1.0331212231808071 +828,505.12808196719004,473.705909021857,1.0663326598779734 +829,342.43516234327905,333.34707558497786,1.0272631363042644 +830,436.20493339955306,418.5460926338186,1.0421909105747738 +831,332.7369223974978,318.18362068988944,1.0457386891130778 +832,333.09009726960016,318.49711518007626,1.0458182551552253 +833,333.4075460132846,318.8249124607387,1.0457386891130778 +834,2639.394115497748,2531.5749554055647,1.042589756176076 +835,364.33832976220543,348.3483785832996,1.0459021834519093 +836,457.18202147756824,437.10303299108426,1.045936511465235 +837,1773.1049716110408,1701.9182063130233,1.0418273716292359 +838,1418.7655661216766,1363.0833057088137,1.0408502254995395 +839,427.73543844644536,413.49539834709157,1.0344382069456564 +840,421.5544304570062,407.53981960588186,1.0343883227525532 +841,254.42791781894553,248.1465845669233,1.0253129949903792 +842,279.8752953190084,272.46355149478944,1.0272026984290437 +843,913.0400372489668,886.9756767837575,1.0293856541362223 +844,299.41470297540116,257.5880658582004,1.1623780083826782 +845,333.6773175003982,300.19199450060984,1.1115463557097633 +846,275.49724818405446,259.1512731563728,1.0630750326965148 +847,235.4522762541101,219.76280038159356,1.0713927736872368 +848,309.60579410257446,282.12011255947675,1.0974254592972459 +849,325.54133414145025,294.54606327867634,1.10523064038866 +850,338.2401728847697,304.56629543915375,1.1105633747065204 +851,388.2458819544914,355.9120465618418,1.0908478252000706 +852,257.66953049922466,234.20491768257176,1.1001883865156732 +853,286.4275317102524,262.45407547524644,1.0913434329095304 +854,323.652832909735,296.3830175231717,1.0920086974431027 +855,280.60237864538436,256.62555124798615,1.0934311773741834 +856,1093.8729148897448,998.4970039542955,1.0955194763306622 +857,4188.497846555089,3954.9626995691697,1.0590486345197034 +858,1420.1935793752439,1320.3401438652943,1.0756270541147288 +859,166.01339154070672,154.94645265510667,1.0714242804269538 +860,137.17949858277382,125.25020980944336,1.0952436629964912 +861,166.06106835119078,154.87088800116624,1.0722548988673732 +862,136.55930281480826,124.66228047291132,1.095434018187098 +863,1684.0217006375183,1558.0477161227907,1.0808537397225642 +864,2405.629148309622,2213.4451794449124,1.0868257188609955 +865,1105.452671610548,988.5698895647492,1.1182342121478737 +866,549.1352992667004,534.9838094197952,1.0264521834076676 +867,543.3513501336909,521.3843378552573,1.0421320908272698 +868,238.42744289582288,232.96932978716887,1.0234284620797094 +869,680.8340293921214,627.5779062288792,1.0848597801717696 +870,3092.5797755438753,2856.0813002848795,1.0828052322023909 +871,2332.3885504177842,2140.8397728140812,1.089473663576381 +872,991.4575589422785,917.5576354216058,1.08053981642986 +873,1185.5786584868263,1142.0266724345176,1.0381356995449735 +874,573.8780273845686,540.8186235452187,1.061128449354492 +875,391.20232953941263,372.0562123053951,1.0514602810026508 +876,1008.8192717294979,959.7630320671849,1.0511128664298033 +877,121.34627092243589,114.42940039005651,1.0604466204384693 +878,192.3334436900439,181.66493847912844,1.0587262754179787 +879,459.1986860822245,426.7600920897095,1.076011310789801 +880,52.841791699681586,48.68943077784838,1.0852825932753019 +881,246.11613231163247,229.3568389487481,1.07307082465777 +882,823.3553872164524,801.1204082980952,1.0277548526888654 +883,252.51622022123445,231.29576135429937,1.0917459911183998 +884,818.6782934638248,796.4008245737529,1.0279726843602845 +885,389.45644241365693,376.2372449168887,1.035135270830745 +886,798.721121987891,777.3389275921946,1.0275069131838381 +887,315.1830939124204,304.4119223605975,1.0353835403958447 +888,390.9835745657283,384.1017790922214,1.0179165935908217 +889,1341.399041462366,1307.2070627725902,1.026156513121383 +890,79.9127407628711,78.26687662083683,1.0210288721499345 +891,117.14768062195414,109.24076549956895,1.072380627197421 +892,301.3424696831536,278.2033025545442,1.083173588940673 +893,351.27690621321494,337.51411453530403,1.0407769366826622 +894,1114.214060646121,1043.081429682291,1.0681947055518917 +895,1162.5783736199098,1089.2275054496836,1.0673421005283406 +896,967.3334640875935,941.4104784020051,1.0275363258433148 +897,966.69403050753,940.7886545193045,1.027535808243204 +898,966.0495438420343,940.137020555545,1.0275624964445897 +899,970.7244866564621,944.7017288636293,1.0275460042019138 +900,1602.1572946796784,1563.7594054571432,1.0245548574087138 +901,1361.3584731657386,1322.2009389456828,1.02961541855452 +902,1422.4649435418296,1359.4559470410022,1.0463486857650468 +903,2297.2959200018017,2160.743089299336,1.0631971618369243 +904,2366.453158389186,2224.4619182190654,1.0638317244305986 +905,1907.5222348976545,1783.8366867681243,1.0693368115181094 +906,1175.3633096569727,1093.4166514947901,1.0749455004642143 +907,726.2877938985406,679.7312963234652,1.0684925025916718 +908,663.2156280620937,622.2810883690433,1.0657814297399542 +909,927.5098836999772,864.0633017865991,1.0734281640965324 +910,1394.3597435371992,1327.783105388931,1.0501411999279555 +911,848.5574108908821,821.4995551832873,1.032937151988546 +912,355.21973668428956,318.4295745240505,1.1155362601455234 +913,304.40654881465343,297.7691127878678,1.0222905457340505 +914,292.4883020562785,286.0793279308516,1.0224027865689618 +915,293.4842569763246,287.04061223428937,1.0224485472347578 +916,304.737951595381,298.10368611746327,1.0222548924648438 +917,4283.086982007105,4076.5579950065885,1.0506625901688373 +918,3443.6727435674534,3253.37966823338,1.0584908909317075 +919,246.3211594008834,235.79055692179674,1.044660832123906 +920,697.7901636385722,660.1125527182476,1.0570775555852918 +921,899.5115072596775,850.8216410302739,1.057226877974618 +922,355.21752598386036,337.20859037531903,1.0534059218019833 +923,137.89333569706972,134.35391070766107,1.026344041425858 +924,95.36421711035314,88.34097696501401,1.0795014996055632 +925,92.5102147761995,85.22985265843778,1.08542032973984 +926,137.84035535581947,134.31043861496934,1.026281775096941 +927,672.2395789718767,649.6160659414435,1.0348259752437718 +928,2797.5973804077203,2661.677056965938,1.0510656704524173 +929,1116.8047657150319,1056.6441884956946,1.056935511380596 +930,1299.4897831869905,1242.8909226705102,1.045538075372592 +931,1261.2681413905088,1203.7956587751642,1.0477427229417173 +932,1269.0900723677148,1211.129043313101,1.0478570218216043 +933,653.705174936396,619.0323573084237,1.056011317047676 +934,624.972540376637,591.8352206685287,1.0559907868792886 +935,619.369413167786,586.5929365495581,1.0558760165286423 +936,621.6168940871338,588.7070247289423,1.0559019477869218 +937,544.226929887476,511.94462059624607,1.0630582058927227 +938,624.6221562999884,591.5688157703044,1.055874041444602 +939,544.2098856532816,511.9567024131449,1.0629998261339464 +940,619.0301250441684,586.2829150044859,1.0558556444364953 +941,763.5946075806792,733.8879015148178,1.0404785335805968 +942,1233.9564700116698,1183.3040414174563,1.0428059288410254 +943,1274.0181338822294,1212.3389510370903,1.0508761867235032 +944,849.2348771581403,805.6446385740361,1.0541060369510526 +945,2153.432613713273,2042.2994452119588,1.0544157071392537 +946,3897.7503896555127,3720.056916842705,1.0477663317483916 +947,3832.1150753526063,3626.3267891424116,1.0567484118713033 +948,971.0346839947579,918.904332134553,1.0567309893284642 +949,538.9359984575661,506.9753077404318,1.0630419080163527 +950,1055.786060750818,999.6551878258668,1.056150234209287 +951,646.5065280755691,609.4758122818366,1.060758302540493 +952,1340.757249773852,1264.7805951434227,1.060071015417353 +953,1419.8211167390214,1335.6513765347554,1.0630177467586175 +954,4134.582782460631,3914.767429868574,1.05615029667278 +955,4595.730681758689,4353.3219743801255,1.0556836155940614 +956,4565.415960055091,4324.263962722528,1.055767177816022 +957,3300.4809295148566,3139.187089968616,1.0513807667155808 +958,2120.5853298489405,2032.6462361845947,1.04326335399583 +959,2111.7808125088754,2023.6482852127078,1.0435513067859536 +960,760.5488388613198,714.6623480396846,1.0642072314954072 +961,710.0971347890602,664.4511433060873,1.0686972878936647 +962,674.7508167396029,623.9394220516239,1.0814364229798177 +963,1117.112155187363,1048.319089583016,1.0656222578487151 +964,2036.4253474814873,1948.2248854661507,1.045272218147564 +965,1695.0753906885375,1628.4450289254607,1.040916555720056 +966,940.1482621329985,897.8114753016598,1.0471555421110137 +967,956.5804220105008,940.4518885861506,1.0171497698288399 +968,957.2200230453549,941.1449458822905,1.0170803415917986 +969,1366.4862032305336,1295.7933974891353,1.0545556150219473 +970,1786.6374529902478,1703.7833005918542,1.0486295131368009 +971,1255.979644247234,1210.3727206799515,1.037680065642641 +972,1108.4420892691442,1070.834926676597,1.0351194770133838 +973,2204.6849487931563,2074.266980457473,1.0628742440411023 +974,1279.9840792725804,1227.2562446976447,1.0429639977818375 +975,1948.4193626817264,1863.5887017137306,1.0455200554124344 +976,2170.3476851277846,2071.3971840183185,1.047769931268088 +977,1672.1018132192753,1608.1519562715964,1.039766053635841 +978,1112.6934870972489,1075.050589437796,1.0350150011816082 +979,4479.633566571583,4211.320363440493,1.0637123704623337 +980,1407.2606571600616,1339.6289352679225,1.0504854143648463 +981,1656.2263897791918,1578.537356648996,1.0492158343943905 +982,180.31249314189162,171.83117259584233,1.0493584511932412 +983,523.8022576585697,495.4198389972051,1.0572896287698417 +984,427.06851715512096,408.69336106113144,1.0449607403611358 +985,456.64691919192194,427.06777907643254,1.0692609968831097 +986,587.7302397846115,558.3167714973389,1.052682401441012 +987,571.557571334655,544.667176220391,1.0493703242792498 +988,585.4336262290419,556.3269619180921,1.052319348698464 +989,587.0397596871256,557.6608470736554,1.0526824014410139 +990,536.337603369259,515.2410090566198,1.0409450993647924 +991,537.2290911610752,515.8065949033183,1.0415320324893718 +992,203.2646500345067,196.88844463750286,1.0323848634628774 +993,486.3922595180221,467.5056270811768,1.0403987275078634 +994,448.8461546272614,439.41211708146614,1.021469680008952 +995,1033.8393310263007,939.9155028873528,1.0999279486830684 +996,1095.9737589040783,981.3270302424297,1.116828259212758 +997,222.7919852664284,199.15075209033196,1.118710237987819 +998,300.38775450061877,288.3429444532026,1.0417725152604558 +999,300.0187169390011,287.9786835603871,1.0418087659466966 +1000,264.46983035437574,246.73425739173229,1.0718812748182156 +1001,1205.360127387088,1157.0095203412245,1.0417892905769728 +1002,1124.1531069167127,1102.9133488706216,1.0192578665113088 +1003,1246.6362724969872,1207.7530875928574,1.0321946474851305 +1004,1120.0310294836895,1084.974214288367,1.0323111966474856 +1005,739.9297531310528,717.1809943096831,1.0317196900111196 +1006,817.5850455008083,755.8689843977265,1.0816491513436775 +1007,612.5852840534818,558.5858825963196,1.096671618706459 +1008,1515.829823095026,1443.5903744088437,1.050041514522958 +1009,535.3799143381681,508.67661501574804,1.0524956299034767 +1010,597.5486691174684,567.6367405740284,1.052695547002809 +1011,673.9165972384338,628.5380095339718,1.0721970461867658 +1012,240.46216990500108,222.6055690779653,1.0802163256786343 +1013,1363.465140395154,1314.922101079142,1.0369170457140946 +1014,499.12493782411445,482.40149170842176,1.034667069656992 +1015,238.98131000164884,230.60789041195906,1.0363102041943641 +1016,519.0474913651859,500.4870739669631,1.0370847088039838 +1017,141.0942815891771,133.85619522199895,1.0540736000688937 +1018,748.656439213971,711.2055171260898,1.0526583683422712 +1019,744.9770093599518,707.7052001044152,1.0526657275515814 +1020,745.4811433349546,708.108478135517,1.0527781637325422 +1021,748.0755998060164,710.6250793440898,1.0527008144667418 +1022,573.5513040225466,511.7123997536691,1.1208469919795687 +1023,3096.9902632549088,2964.1706407403003,1.0448083591035895 +1024,473.5734505304724,431.57228636506625,1.0973212726868136 +1025,154.43881075360036,143.81462112471576,1.0738741968361571 +1026,1042.5900269410681,998.5627808684444,1.0440906139465096 +1027,569.6165889979917,519.8169425256672,1.095802276529041 +1028,1846.9313646889302,1758.7452013903664,1.0501415231887192 +1029,963.9750587868976,905.089487556215,1.0650604962716743 +1030,621.7938764863073,598.8002064165321,1.0383995693778711 +1031,988.6507952921685,927.0977925061006,1.066393214700339 +1032,750.7328090934762,714.0524319187704,1.0513693050188766 +1033,2159.3055767817405,2029.4351978502712,1.0639933608469183 +1034,311.22106915595634,300.4710510964175,1.0357772172071555 +1035,782.6306133742457,755.8152461555097,1.035478732871735 +1036,463.19235745004414,438.9725501164982,1.0551738538710866 +1037,2965.4771614288884,2818.242222282833,1.052243536053048 +1038,883.201726710766,839.3463452735036,1.0522494458744227 +1039,484.0947999964967,446.73750130985115,1.0836224820551499 +1040,879.0492267653397,835.4034861918238,1.0522451022708492 +1041,473.25797168176706,435.6837679997765,1.0862419177434444 +1042,442.530780941454,405.39714901863465,1.0915981575418343 +1043,95.28788155834745,89.25264327957181,1.067619714744706 +1044,444.4102787025855,407.10150525536784,1.0916448919141541 +1045,396.4003947190924,363.38635861280153,1.0908510606515867 +1046,206.47119835764562,200.2463951457771,1.0310857192077638 +1047,47.60243088250422,45.8980317037534,1.0371344721218503 +1048,74.23792123048572,70.06521827758286,1.0595545558192874 +1049,327.78949692540004,317.3624507945743,1.0328553239512732 +1050,336.74357788566624,326.1056267375211,1.032621182451131 +1051,518.6669227838016,501.7619643744056,1.0336911914606224 +1052,491.11188632915844,471.95808568525933,1.0405836900030832 +1053,496.3579833335192,477.0163329249523,1.0405471449792263 +1054,909.7813833687886,865.5384700830767,1.0511160564376363 +1055,579.6644500623559,549.0703547315887,1.055719809068408 +1056,581.2742760074848,550.5964157815534,1.0557175080451353 +1057,581.6505009778512,551.0453725401792,1.0555401242126217 +1058,287.96434740448825,273.35716075468457,1.0534362685414063 +1059,137.13214756303583,130.84789625404838,1.0480271482300811 +1060,136.46347891361,130.1742924941132,1.048313582497721 +1061,6978.799929533525,6672.605088720765,1.0458883504630516 +1062,328.57899266097377,311.79065117705255,1.0538449161979133 +1063,198.74255410130678,190.66365448596687,1.0423725205368626 +1064,301.1929299867166,282.53249876494647,1.0660470257522294 +1065,192.05721042026437,181.97131920105411,1.0554257190830534 +1066,297.7289897071626,280.4643670321313,1.0615572768039137 +1067,337.39034935780455,318.9534577668999,1.0578043320802588 +1068,358.5075004523971,330.5924847964448,1.0844393534025445 +1069,280.9121558773332,264.2360208689575,1.0631107558823174 +1070,644.6992178704478,605.7767741666655,1.0642521228340684 +1071,227.83846927603398,214.01529794722532,1.0645896413078721 +1072,440.87228148670056,420.9543996099587,1.0473160083258353 +1073,763.8991445306533,717.2635140403748,1.0650188244311747 +1074,989.6070084953803,976.6863924239248,1.0132290325448166 +1075,863.8873321011063,839.1048336415297,1.0295344484574425 +1076,730.5985525500852,689.2778422629509,1.0599478290952677 +1077,1058.3029103015992,1032.969188684871,1.0245251474044275 +1078,1030.33107957822,994.5002290913206,1.0360290017425517 +1079,1008.5011152716621,972.1387431283831,1.0374045087702846 +1080,750.8575409019237,721.5751974099394,1.0405811391482023 +1081,759.4098738614854,710.391759524252,1.0690015244124744 +1082,724.2749251062154,671.8546380332459,1.0780232569747856 +1083,286.17950488802336,280.0476576813311,1.021895727525312 +1084,355.3937859976267,348.2510677496351,1.020510255127564 +1085,152.62451497764718,143.46459867817603,1.063847920559266 +1086,213.5712691508638,206.69536209074826,1.0332658991017742 +1087,282.0393002954088,275.7553055289318,1.0227883004986016 +1088,402.31383331841727,388.4650568588356,1.0356499927472604 +1089,597.0703412788545,571.7547594785043,1.04427699355479 +1090,332.7577594597165,317.44968848677854,1.0482220380996705 +1091,2473.4429905323145,2366.517145420846,1.045182789111994 +1092,513.5588455449874,493.04398607276795,1.0416085786495968 +1093,571.5023081648238,546.7567608846233,1.0452587860827978 +1094,3652.693047464574,3444.9473737144417,1.0603044549635994 +1095,1883.8715170701373,1763.6883355024263,1.068143094870259 +1096,334.25176901123353,327.8726280900444,1.0194561557588675 +1097,346.0925633080839,326.49710829834237,1.060017239086344 +1098,748.8633998932124,707.5998484884253,1.0583148109668683 +1099,372.9311838661672,321.78112772742867,1.15895915493859 +1100,258.5826127164605,250.11542821854226,1.0338531075760744 +1101,230.200827945516,222.5336921684416,1.034453820014234 +1102,236.21849449096777,228.48430851351262,1.0338499655743218 +1103,256.4825206327394,248.08584688481128,1.0338458394679273 +1104,587.36611325561,560.4158172914367,1.0480898203309599 +1105,412.8010873628097,388.1740255398696,1.0634433532452074 +1106,1153.8310125433018,1088.1527040554909,1.060357620987414 +1107,513.9298611082479,482.9698832325191,1.0641033301466203 +1108,1504.1261466580224,1418.2745855020373,1.0605323976284857 +1109,512.090979682217,479.59705326999784,1.0677525564234986 +1110,172.78158587523643,170.43086813536254,1.0137927933219637 +1111,182.38611301853385,174.86373541836886,1.0430185114264394 +1112,912.2222767180606,852.8668334432389,1.069595206364385 +1113,683.7364174124939,641.4690746889677,1.0658914737924359 +1114,461.82594942639827,440.256886097166,1.0489919953789704 +1115,297.5364031371154,279.3949343994002,1.0649312729191491 +1116,506.9077545900649,480.5077027364771,1.054941995109007 +1117,536.502372725499,500.00838682425416,1.0729867475484405 +1118,697.2895039268659,661.337356047812,1.0543627961588407 +1119,666.3581230764954,626.1566802511965,1.0642034878701148 +1120,701.1769029783725,664.9936052055123,1.0544114973281253 +1121,706.3873000468428,666.8062533485127,1.0593591414291113 +1122,449.55037085594796,428.70806707213467,1.048616542082252 +1123,447.5254455835957,426.78675210464274,1.0485926364318545 +1124,694.8662021129512,659.0108972195347,1.0544077572081059 +1125,695.8541269079512,659.9483383795088,1.05440696860698 +1126,643.352226175337,600.7709759593656,1.0708776753869873 +1127,476.72532377367213,448.10759392626414,1.0638635234825256 +1128,643.6476360726114,601.0343419642384,1.0708999322220234 +1129,423.5848656141095,399.41467446037916,1.0605140289008785 +1130,201.65422786918984,172.035542111298,1.1721660849519693 +1131,201.37126363865306,171.83544100409333,1.1718843473847527 +1132,145.48389569418046,133.83382018821115,1.0870488153860194 +1133,263.9529504050013,243.82273361138002,1.082560869101345 +1134,506.9854598303209,469.2131915225315,1.080501292355451 +1135,626.0548909165259,579.4977832536912,1.0803404413411761 +1136,248.2472647644607,215.4016724210675,1.15248531719469 +1137,202.1217191836353,172.42894572039353,1.172202951999665 +1138,155.3185632324905,149.13410279370945,1.041469122909706 +1139,553.6063309730686,500.49400460100316,1.1061198053998806 +1140,353.3512895407008,330.20463241071025,1.0700979176488372 +1141,417.937460463649,389.1261279986856,1.0740411151858216 +1142,553.8482523484433,500.92021980367593,1.1056616012935379 +1143,417.5685435864643,388.7456380327498,1.0741433542497685 +1144,631.9311119780145,594.8457226613368,1.0623445507025886 +1145,663.4769147976048,623.4285183674266,1.064238954828459 +1146,916.7459244852333,862.6971791489466,1.0626508891446775 +1147,993.7705541585242,935.0988642720724,1.062743836109912 +1148,935.9745925253737,880.7213958627161,1.0627362942721903 +1149,979.5557979492755,921.694892685057,1.0627766365241103 +1150,3843.1319808828052,3612.4061823421403,1.0638703918923844 +1151,400.1570373130172,363.2559743644263,1.1015841873300367 +1152,1223.7545496498433,1146.4140867297606,1.0674629384053564 +1153,442.4314845578824,408.8774547447541,1.082063780782618 +1154,616.9937737029418,570.3874305885256,1.0817099757375925 +1155,575.3368206398645,544.8453056548973,1.055963618789588 +1156,429.97852668123534,397.814551870267,1.0808516799090282 +1157,509.6678567229329,478.323961695976,1.0655285905306144 +1158,392.707902004019,362.26362380456493,1.0840390152334982 +1159,2502.615880076405,2316.637208683878,1.0802795840002004 +1160,1036.2007635510174,972.1389680738531,1.065897775504353 +1161,1080.664723398333,1012.1366388343735,1.067706356962712 +1162,406.5018251272123,386.3675318711238,1.0521117630111956 +1163,521.6788128777663,507.77323284875746,1.0273854136638798 +1164,334.0752083959615,308.96928613852293,1.0812570160976538 +1165,356.00666553023615,333.10230712610974,1.068760731805604 +1166,523.1234655936013,509.13225807687553,1.0274804970511477 +1167,765.5415950925577,708.1356509061031,1.0810663099831228 +1168,766.5699371518195,709.137959013477,1.0809884415413884 +1169,763.2573731364066,705.8829500999315,1.0812803638738586 +1170,764.0066938996182,706.6331670681373,1.0811928020156867 +1171,2157.7233219969626,2001.3428234254884,1.0781377866605653 +1172,1080.650789599873,1027.1549282561002,1.0520815895169755 +1173,2295.4289774585404,2199.1990889326325,1.0437567881008047 +1174,1275.797201803619,1181.9060332484135,1.079440468120084 +1175,2451.830186974562,2277.4360679555652,1.0765747594291633 +1176,1140.946633926358,1071.0470420747392,1.0652628587780937 +1177,580.1778971310509,541.0143182003286,1.072389172732062 +1178,146.155538309115,126.88596985138042,1.1518652415259523 +1179,136.20005764600083,119.17262595388387,1.1428803935117287 +1180,1698.5933694811279,1635.7843455101377,1.0383968853494576 +1181,383.67631928143214,326.9308836554279,1.1735701289261238 +1182,1025.2469457132481,972.192197393181,1.0545722836105116 +1183,2046.1687386111141,1938.1978472796325,1.055706847205008 +1184,368.9180016438625,353.0882551930281,1.044832265639027 +1185,1347.6991479337123,1255.6372378709534,1.0733188752978196 +1186,1423.6081296309521,1325.6573093531676,1.0738884925890673 +1187,151.74231221256883,138.68348390918655,1.0941628226756515 +1188,573.9220685859535,540.0603089821873,1.062699959690767 +1189,220.16197488149353,215.83578805442775,1.0200438808877 +1190,288.52189157830793,276.74953605768565,1.0425379413036069 +1191,1960.0380109460937,1800.5768162248544,1.0885611728887916 +1192,2406.2619150584196,2210.784487589654,1.088419938065464 +1193,546.3406805770529,515.28423730645,1.0602705090164306 +1194,514.2813002559836,484.5765251297207,1.061300483176132 +1195,515.7778676896314,485.8793826661968,1.0615347884476405 +1196,545.2362668174839,514.213107391343,1.0603313275764685 +1197,1127.0653664053355,1051.4704852660223,1.0718944394527514 +1198,202.50520398485347,193.29320254867974,1.047658175842235 +1199,441.43185880423175,412.7481388905873,1.0694944863730762 +1200,532.7597995673909,490.7476639237734,1.0856084271654183 +1201,505.2604336603138,465.8971815986017,1.0844891396995526 +1202,386.0810368291177,348.2222227953223,1.1087202698606862 +1203,368.9821473312951,354.19118208744555,1.0417598347781505 +1204,388.5538821993826,350.51058494507276,1.1085367999949887 +1205,371.25129091272885,356.11370954915975,1.042507718623732 +1206,544.9877952775557,508.45021082251253,1.0718606929003665 +1207,460.7985394374458,429.6519691564917,1.0724925579698894 +1208,421.546174158814,405.0838988062494,1.0406391747513974 +1209,801.4895503752064,745.8742401589344,1.0745639240797766 +1210,120.6994890677325,111.04482470651479,1.0869438480067346 +1211,214.87374300029964,199.24861615108597,1.078420252802988 +1212,121.91046652009074,112.1732815292325,1.0868048510136588 +1213,120.73227269580012,111.0984507254987,1.0867142782585206 +1214,512.6405160482648,487.0484658882809,1.0525451817475886 +1215,285.1676234608099,275.46373444281767,1.035227464833512 +1216,495.13461395773663,470.5578048706042,1.0522290966864118 +1217,1747.6658282799947,1645.5613075366125,1.06204844527867 +1218,2364.5241327166846,2210.73364777817,1.0695653612967246 +1219,695.9976562952054,646.5308315562297,1.0765111613005474 +1220,698.6502425255226,648.8962849535678,1.076674745603629 +1221,805.482753280193,748.515906713678,1.0761063940733406 +1222,805.433114831492,748.6200748696084,1.0758903506184752 +1223,3162.5685745460837,2941.1055448160664,1.0752992459316408 +1224,1591.7251309807589,1481.7636823961645,1.0742098418870514 +1225,411.9082568056363,354.34007188844805,1.162465917586966 +1226,93.01744448299029,85.89448619269342,1.0829268397312186 +1227,99.19295793691826,91.70700525671059,1.0816290168810185 +1228,361.6339378304062,311.14518419022414,1.1622675079210445 +1229,1451.1018982958503,1392.610076676691,1.0420015786175723 +1230,625.9504463220627,599.3673386558739,1.0443519457129635 +1231,544.3652071277056,513.9637142803158,1.0591510489995581 +1232,650.1944080008225,622.988484457912,1.0436700263674752 +1233,557.151539462987,525.396436794771,1.0604402703260434 +1234,530.9095399744365,501.6507391697294,1.0583250427441464 +1235,437.5591650279039,419.11831864327036,1.0439991419232841 +1236,559.677849209958,527.4530470560563,1.0610951104250175 +1237,569.7462149091409,537.5555957227369,1.0598833301011854 +1238,350.5868031402706,350.3671384371022,1.0006269557817216 +1239,681.1005693467356,643.3342341760555,1.0587040657319426 +1240,442.0826881517437,392.3228437621869,1.126833920534384 +1241,365.53525218019496,357.2822325468181,1.0230994403907152 +1242,210.59158303644705,200.24732768347496,1.0516573952453585 +1243,319.072613408933,291.82428437813377,1.093372383620727 +1244,378.7164625014584,365.6665029868361,1.0356881459144538 +1245,358.5838061409677,337.9378320853291,1.0610940004208391 +1246,318.0475152464701,290.2207175746238,1.0958814997922788 +1247,318.40525657389713,290.53290056834487,1.0959352828923263 +1248,326.108264760411,297.75741102432994,1.0952146031850218 +1249,325.4193618507805,296.9443242722256,1.0958935236372804 +1250,1393.4951814245696,1329.0398573589,1.0484976607050422 +1251,1483.135255391621,1388.1686903219013,1.068411401101186 +1252,254.27427056778214,239.72167861466272,1.0607061991106435 +1253,249.70414539805145,231.94075628025305,1.0765858894429703 +1254,473.3791860103253,453.5225428290742,1.0437831448407953 +1255,252.54455433948738,234.6576758102146,1.076225414180524 +1256,294.51211187233696,267.3029198076286,1.1017916006465256 +1257,556.118483064601,520.4888808557323,1.0684541082804504 +1258,388.7888844128516,372.30118754111305,1.0442859099661557 +1259,245.82447247999224,225.77271354831962,1.0888139165115769 +1260,338.22018846953836,316.7440786074982,1.0678027193324515 +1261,305.2852404172953,292.3032549960197,1.0444127295861019 +1262,535.4917771695413,510.8630693128742,1.0482099986005906 +1263,735.9890670403146,713.6758270186202,1.031265231603693 +1264,411.80984487130297,385.6334703904795,1.067878896648463 +1265,410.1930777921354,398.54905772501087,1.029216027089841 +1266,404.8042529462774,378.8124150430067,1.0686140075433375 +1267,404.2708783661374,378.27472791674893,1.0687229374073062 +1268,1058.7814457528204,1021.3345625546159,1.0366646587427144 +1269,1099.2001278832313,1051.8347516842623,1.0450311953689728 +1270,699.1013260881502,677.0215278731841,1.0326131405072572 +1271,440.9004395070926,426.98704672327585,1.032585046526795 +1272,704.2142640244869,664.44987247054,1.059845585350323 +1273,262.48928796124835,251.05957540198492,1.045525897751411 +1274,1408.059075851627,1339.5675356960357,1.0511295909541458 +1275,392.67701118044164,377.3014385346322,1.0407514286336286 +1276,4371.679484695965,4247.953146684903,1.0291261070305395 +1277,2735.0096894614985,2656.95188074624,1.029378706208761 +1278,696.4663128099439,674.9543492606394,1.0318717311368824 +1279,361.66964554012895,347.11770049779705,1.0419222212565453 +1280,360.3473700913345,345.84975672842745,1.04191881902722 +1281,519.008403871337,501.3499208611094,1.0352218725394386 +1282,492.5775007942048,475.40187211778715,1.0361286517444805 +1283,1031.3809325275827,1007.4353009681746,1.0237689026147838 +1284,980.4022828572744,948.8509059283491,1.033252196664191 +1285,152.8540279058892,126.56395530296778,1.2077216419160453 +1286,439.6644116607989,425.79672566629415,1.0325687943532313 +1287,706.1199603547659,666.2229159267243,1.0598854279465069 +1288,558.8152987799874,512.8786377259123,1.089566337287427 +1289,871.549404932817,816.8331914308244,1.0669857861752015 +1290,964.7077542917882,899.3796574705583,1.0726368406029558 +1291,594.4245442201664,571.1709386113262,1.0407121651976483 +1292,594.1156537338128,570.8798184915628,1.040701798328843 +1293,1942.4947582161128,1865.8771840550091,1.041062495868348 +1294,1445.5859233483577,1387.4172054007463,1.0419259021159464 +1295,1226.314363093765,1163.2211760139878,1.0542400606013542 +1296,1310.3891991197127,1242.6238616303142,1.0545340706724324 +1297,756.8513771682954,693.4429148106691,1.0914400608951909 +1298,1761.7996965220264,1640.1082200179783,1.0741972237068076 +1299,1636.0767113979996,1551.3634351151275,1.0546056935244097 +1300,108.48171822675637,105.82315774654231,1.0251226719824558 +1301,111.16360323878304,108.35327373999519,1.0259367290141277 +1302,436.02259559182073,411.58405968526824,1.0593767793758588 +1303,434.2364858594725,409.91822926932224,1.0593246527081692 +1304,244.1891228863866,233.52062846420407,1.045685447544168 +1305,261.7578909031361,250.30246431624752,1.04576633561392 +1306,86.17567300832644,82.73835692993161,1.0415444082519765 +1307,461.9456050462635,447.8439397276555,1.0314879002877286 +1308,153.60966612674352,148.20189201809777,1.0364892379915458 +1309,454.40642363317966,440.57178774287394,1.0314015474326736 +1310,456.608409038502,422.01650961939293,1.081968118854655 +1311,990.6660375511266,939.5647437724684,1.0543882623495218 +1312,643.7621806495955,595.5503394280811,1.080953427493322 +1313,277.5784711681402,257.53753556846885,1.077817532715899 +1314,386.3799148463812,348.13059048418813,1.1098706215647267 +1315,322.0477572408135,312.2223211460541,1.0314693583043448 +1316,368.2824293149463,356.9459617645381,1.0317596184429911 +1317,1103.3459138251217,1024.8191221978914,1.0766250257497312 +1318,1226.8660484059646,1192.3064192216323,1.028985526394208 +1319,2220.03648020727,2103.244373170338,1.05552949934243 +1320,877.6713070442569,833.8961351980209,1.0524947532414703 +1321,658.0805126347022,573.3732399810079,1.1477349599651705 +1322,413.4612395502542,388.2233643080685,1.065008645956091 +1323,280.11925216190156,271.5478835271758,1.0315648515591098 +1324,175.6544978790388,174.25719080362958,1.0080186480050848 +1325,410.23702285081424,390.90352479938326,1.0494584899467283 +1326,777.2097702299782,746.1362105690475,1.0416459611807771 +1327,662.3426330194966,635.279335727014,1.042600625851479 +1328,418.3027201933916,401.1643689866821,1.0427215189873418 +1329,509.62481466942177,482.03145598843565,1.0572438963021702 +1330,359.5974103669035,355.41070710348157,1.0117799018986868 +1331,507.8425438187582,501.0581758744242,1.0135400803160117 +1332,709.0664073534956,678.779474228361,1.0446196950188644 +1333,1431.903566943852,1327.8654207789186,1.0783499174968387 +1334,589.361779433958,552.5697770143736,1.0665834505433462 +1335,642.2440128850316,575.3861327976354,1.1161965439839863 +1336,400.9022851678308,360.71313459870225,1.1114158224757729 +1337,620.2947410520377,602.6856376847848,1.0292177252388133 +1338,555.1409974024647,531.92995798966,1.043635518293662 +1339,544.8523962825275,509.7885009295617,1.068781259853899 +1340,434.4099307096457,398.68339707685215,1.0896112902988704 +1341,331.69298454800486,316.0649421665497,1.0494456685842113 +1342,384.2927396578069,345.74738246814644,1.111484161975432 +1343,573.8394336063335,539.0333133059773,1.0645713714554759 +1344,487.1595379869091,462.1537032457057,1.054107182449448 +1345,389.23822371570725,371.68644326414716,1.0472220086840416 +1346,758.2004839760136,719.3527670107806,1.0540037082593872 +1347,508.4950069281342,484.540940052853,1.0494366211298232 +1348,543.8826228784742,507.69794296069296,1.071272063279923 +1349,358.95663774022063,351.013742139278,1.0226284462612036 +1350,797.9193175624945,760.9856575870247,1.0485339764386377 +1351,1061.9974651683476,1016.5835942311545,1.044673031509563 +1352,280.52927937643386,244.89853416622583,1.1454918680159332 +1353,678.5368617489196,634.4146865610126,1.069547846420582 +1354,543.8120930835653,497.2153208824863,1.093715479479547 +1355,394.7172497048737,371.4860037981896,1.0625359923904552 +1356,544.3968876574155,497.6739878311593,1.093882543529897 +1357,360.5112333822936,331.488077274032,1.087554147789964 +1358,540.5358861717077,504.5472377661593,1.071328600598202 +1359,563.8702735462972,509.58009736899817,1.1065390435333002 +1360,198.32770568809727,186.96492645651054,1.060774924190018 +1361,339.2476072316823,335.3840331494364,1.011519850977892 +1362,548.7237255410203,520.7698976904566,1.0536778872483512 +1363,1223.1283058881972,1181.7376195400582,1.0350252760542977 +1364,1418.6214453183243,1335.0876624705809,1.0625680134689912 +1365,763.0592589344883,715.8401113718043,1.0659632602484308 +1366,283.4647400945277,270.50728567371647,1.0479005746131378 +1367,1098.769439406274,1037.3741831276202,1.0591833277492513 +1368,856.2629613041277,806.0942119703602,1.0622368311157309 +1369,215.88526983112595,210.63345242712305,1.0249334440635445 +1370,278.55672299386015,266.80231037066284,1.0440566373164728 +1371,278.58481471183313,266.8292010404859,1.0440566985378918 +1372,290.31311196201665,278.27101599957746,1.0432747044070787 +1373,724.5560118035385,711.6417340179048,1.0181471619331823 +1374,393.2616473068411,363.0004809240849,1.0833639842727503 +1375,1968.9002449601778,1837.5467758401965,1.071483061463794 +1376,622.222733446266,587.3458526862322,1.0593804835779874 +1377,285.45280544317995,272.3836287301821,1.0479807717296545 +1378,732.4561718252268,687.2862051989104,1.0657222075528834 +1379,394.69911807279163,368.0083524261093,1.0725276083293285 +1380,1198.6202643179333,1144.4364747642278,1.0473453885370687 +1381,1157.5163671219905,1105.3203115807223,1.0472225607313979 +1382,1253.1459423567255,1154.6310961754575,1.0853214905674926 +1383,826.9523906172774,777.5440196517217,1.0635441463335886 +1384,1841.5626901068485,1770.5597781295849,1.0401019569371845 +1385,2564.4519835298292,2462.2232042846417,1.041518891978312 +1386,1175.0867969710991,1122.0861121242745,1.0472340618729221 +1387,1214.941153249753,1161.897328190302,1.045652764467639 +1388,421.7931891156584,405.18094222445995,1.0409995761399746 +1389,380.9790391930553,331.61800961768097,1.1488490617028977 +1390,430.24285311340486,415.1110164131776,1.036452505719978 +1391,430.6848065492442,415.1178166248147,1.0375001729653512 +1392,812.3956547065092,763.8754561857747,1.063518467739503 +1393,206.33423867052343,193.99734480798725,1.0635931067754916 +1394,428.56033223426255,412.26679798410936,1.0395218201655454 +1395,164.70893849991097,154.71297040555098,1.0646097613416474 +1396,166.4581849380975,156.36873825729754,1.064523425802658 +1397,958.0631189148195,910.1459922704867,1.0526477367930795 +1398,1142.065050872648,1090.6656129404523,1.0471266695514696 +1399,1202.5915626004187,1149.615225010098,1.0460817988817568 +1400,1578.616941689499,1493.8619995390272,1.0567354562714797 +1401,655.2715586425008,615.5522530874771,1.064526293837445 +1402,903.1960732149005,857.3655693402001,1.0534550319182634 +1403,1152.7036047901845,1100.5782598680005,1.0473617795507206 +1404,488.1940736027453,460.8882911603119,1.0592459885966934 +1405,280.63809359414233,263.8117273211821,1.0637817220781647 +1406,1583.494532005555,1491.4745972671003,1.0616972859658937 +1407,651.9776998751958,612.4156380954644,1.0646000188740516 +1408,818.2819317173888,775.6494226123842,1.05496363158683 +1409,811.0089996304891,777.2090550589381,1.0434888713037291 +1410,325.38194306082136,316.0848908683414,1.0294131496350214 +1411,561.7997676045356,535.6987531788154,1.048723306281446 +1412,483.9652295043181,451.505515107674,1.0718921769735263 +1413,301.7551777146909,288.48230651611067,1.0460093076725279 +1414,302.7583417604144,289.40740316659844,1.0461319871148231 +1415,483.7828645264,451.3386476294693,1.0718844199745245 +1416,887.2794744562884,837.235845157777,1.0597724399736859 +1417,967.6759914332519,913.920141688245,1.0588189791349887 +1418,290.03527770723133,274.3072495562531,1.057337267521808 +1419,289.13897516785914,273.4590744364042,1.0573391128591034 +1420,854.4151879252274,808.5505635338188,1.0567244974648888 +1421,290.0241241827925,274.29677236232135,1.0573369919194555 +1422,605.0001008021796,571.39602759829,1.0588104774636524 +1423,587.2088517892172,554.6161299136709,1.0587662711515793 +1424,584.7065664912278,552.2527326595559,1.0587662711515788 +1425,584.9686148456514,552.5002361563745,1.0587662711515788 +1426,605.5302201298663,571.8889482761971,1.0588248329593912 +1427,592.2443227015408,559.3721096322596,1.0587662711515808 +1428,592.2625374717616,559.3893134011344,1.05876627115158 +1429,603.5340767243711,570.0214906168737,1.0587917940975 +1430,602.1586265358554,561.5375560198337,1.0723390093512943 +1431,598.8485841079406,565.6098049445753,1.0587662711515802 +1432,596.355713550327,563.2552998705679,1.0587662711515813 +1433,598.7697764449484,565.5307978649524,1.0587748336703908 +1434,607.3072180038437,556.820415848525,1.0906698115197213 +1435,597.5729704994758,556.2529199877021,1.0742828469335266 +1436,597.76880699199,556.368413156994,1.0744118336986068 +1437,607.4071197181069,556.91066465801,1.090672451193058 +1438,850.7389167726623,798.2823232659483,1.0657118314885172 +1439,716.8709177515568,693.6306366666357,1.0335052690241688 +1440,999.0249258940933,955.5185680170193,1.0455316718411474 +1441,832.7208107974144,789.2249194482781,1.055112161663044 +1442,493.6096951886948,458.0246526113865,1.0776924175902396 +1443,1023.7089197235703,949.6852795170647,1.0779454434043119 +1444,1847.791773541921,1758.0904107888243,1.0510220419852294 +1445,1073.679975166658,1024.7192572455795,1.0477796406917186 +1446,593.9578219630623,571.1167632007769,1.0399936759591413 +1447,721.5119471906293,678.5984636222819,1.063238403664046 +1448,675.8021167193034,644.8073282693651,1.0480682943432527 +1449,574.9221233647486,556.0195158112344,1.0339963023167185 +1450,583.8945089889439,542.953950727589,1.0754033711449973 +1451,576.1198370235322,535.7020179890802,1.0754483232789984 +1452,586.7204292703838,545.6326517485106,1.0753030035688023 +1453,581.8686165299742,541.0602807023544,1.0754229007064542 +1454,156.11490899239823,151.8784504812769,1.0278937433039166 +1455,153.39470116894955,149.39933592833748,1.0267428580976325 +1456,153.37314512606616,149.3781797794309,1.0267439685805126 +1457,155.33988736804227,151.1681979099742,1.0275963431180972 +1458,2356.3166622826266,2191.1854576735814,1.0753615829416683 +1459,268.92971115103563,253.65828123863628,1.0602047362216112 +1460,894.4344017566921,833.3940660614564,1.0732430649329034 +1461,804.2832069817786,743.4080007769473,1.0818866707665369 +1462,544.4529940000382,518.1964245383151,1.0506691443985092 +1463,864.0012465887942,795.6903237672111,1.0858511418087424 +1464,1108.6230614612457,1045.0195414044952,1.0608634743530903 +1465,271.89862577126365,256.51970933386514,1.0599521825333997 +1466,922.1884601772365,881.9305534993791,1.045647479292014 +1467,800.0243011261549,773.1401051221075,1.0347727350139229 +1468,1207.9185785441227,1167.501529795071,1.0346184118115425 +1469,1599.7189150192596,1550.883312061847,1.0314888957651414 +1470,841.655625420224,809.4214934296888,1.0398236669673206 +1471,906.3532790793533,846.6536917744377,1.070512404168221 +1472,1214.150507174305,1127.0534333119008,1.0772785666483133 +1473,1469.8309856138,1414.2632467621484,1.0392909445811238 +1474,2215.961608248435,2112.505319132907,1.0489732679858965 +1475,177.8027505562946,174.4145188873808,1.0194263166307935 +1476,282.92029747561475,274.5051141314779,1.030655834485132 +1477,2231.120933303633,2127.053558688325,1.0489256014218478 +1478,243.04209367579156,229.01637866007474,1.0612432835493175 +1479,585.5702637648394,546.2528984919975,1.0719764881456604 +1480,401.90594755816386,373.9224703356964,1.074837645347563 +1481,243.68278790240075,229.60922493167365,1.0612935433012984 +1482,539.7045361231475,504.5182364011847,1.0697423743747156 +1483,246.9039339649755,232.61586027646786,1.0614234716047566 +1484,249.83883781163792,235.3805985344126,1.0614249405739 +1485,394.6152685900777,369.7874486958574,1.0671407858265105 +1486,1753.4292647258408,1657.5236433514742,1.0578607863357217 +1487,524.2229937446563,492.68581329220257,1.0640107338218598 +1488,560.7973293252314,527.0619424213345,1.0640064937128941 +1489,423.9137746535398,400.0640511136919,1.059614762869734 +1490,296.7411744531541,281.59749476810197,1.0537777500383059 +1491,1824.8932165240344,1736.0033968839539,1.0512037129648673 +1492,1217.8764691059255,1145.9804771284148,1.0627375364697895 +1493,278.1420685000802,270.24875868271727,1.0292075710387627 +1494,407.60666262140745,379.2986967072717,1.074632383817503 +1495,834.9789963883585,778.7122326501124,1.0722561703528903 +1496,1441.6069075515152,1374.6914360607875,1.0486767209974592 +1497,231.66811544617056,226.9838520536091,1.020636989592789 +1498,1676.6650233934008,1598.7133444554654,1.0487590093673025 +1499,227.17085991597327,222.5375654299163,1.0208202802843915 +1500,74.39789607425679,70.78359499049836,1.0510612817029652 +1501,371.43844757897267,351.9377830260977,1.0554094089733723 +1502,556.6541755276368,523.1782442175428,1.0639857098036636 +1503,191.62080710088867,186.37531273118623,1.0281447917797362 +1504,186.4695831054165,179.86888989814508,1.0366972477064222 +1505,186.93593573447615,180.31379134726367,1.0367256677247665 +1506,368.46151925649076,348.71222873492945,1.0566349238545734 +1507,223.43584247970247,213.96109377080901,1.0442825774626232 +1508,1250.2134591524896,1195.6131505557976,1.045667203117756 +1509,1224.7558204974446,1172.9065183725163,1.0442058265622673 +1510,456.8259672311092,437.60044586648377,1.0439339620108417 +1511,1163.8181949264633,1094.2418270672013,1.0635840872997346 +1512,2065.5962278875704,1938.8186899668724,1.0653890632356469 +1513,703.7605977149535,644.233270714508,1.0924002682047527 +1514,1187.791775564841,1091.5880290782889,1.0881319178333095 +1515,1998.9270398809444,1873.5205092817107,1.0669362998579148 +1516,428.1676501909557,396.8645312304936,1.0788760811237166 +1517,430.0064707258853,398.60197357116726,1.0787866072848509 +1518,310.08642667962516,294.70202988257483,1.0522032264358012 +1519,397.88136071969615,370.7887806771641,1.073067421277023 +1520,143.8175819806557,136.38006960929596,1.0545351853292555 +1521,143.0266105752594,135.68498180150632,1.0541078951869056 +1522,182.66230391641113,181.15207826813452,1.0083367834513124 +1523,426.22762893119904,395.1231671817396,1.0787209263666202 +1524,839.131711915463,781.818184662823,1.0733079997075763 +1525,772.5419685644542,731.9001674987493,1.0555291593996996 +1526,1423.389376142532,1335.836094506218,1.0655419343708312 +1527,358.94100624958526,336.8553396529452,1.0655642467160962 +1528,357.312018847549,335.3536238190643,1.0654783293480439 +1529,357.9239880279381,335.92528014713236,1.0654869078956204 +1530,440.2114982723038,413.1541530380347,1.0654897089507853 +1531,1303.6681270511206,1211.936782394944,1.0756898758983975 +1532,1218.5114442164984,1134.0950881439196,1.074434989583401 +1533,154.81052092569695,146.09231311564758,1.0596760200733353 +1534,328.3242621056622,301.5847244375998,1.0886634351853424 +1535,143.2245781809377,135.85522340205492,1.0542441769579491 +1536,156.19955894022775,147.36197045301117,1.0599719755378447 +1537,356.2775601084585,342.08258741526464,1.0414957475633277 +1538,394.2944410878263,379.02044962556465,1.0402985946466765 +1539,395.0683710581856,379.65619670861514,1.040595081769202 +1540,267.66715537743636,256.0339116296585,1.0454363395603814 +1541,395.747713699072,380.0202270202986,1.041385919907714 +1542,130.0112008093732,123.67471552926732,1.0512350908024233 +1543,117.61258784021263,111.07604021835846,1.0588475031069196 +1544,318.5880724425834,305.68612933813597,1.0422065048629534 +1545,109.8472150229051,104.02916607704245,1.0559270939608791 +1546,116.62985848712219,110.31762499733914,1.057218721758516 +1547,117.66174922534317,113.29407203911317,1.0385516833106865 +1548,129.2152958399479,122.90663349595366,1.0513289003575381 +1549,695.6647559117977,669.0138572792083,1.0398360935915065 +1550,216.61083981115837,208.51409174244196,1.038830699647473 +1551,130.06223296523353,124.47043745617106,1.0449246875269598 +1552,1577.2442887746122,1519.6144785734748,1.0379239675679037 +1553,1103.1271759699591,1060.6533912019981,1.040044924308239 +1554,445.1525114554199,428.65271348510504,1.0384922279767355 +1555,642.2883662493829,614.8668248401684,1.044597529581048 +1556,855.2301160463898,833.7531909614235,1.0257593317996188 +1557,879.8781946001448,858.2751947061827,1.0251702484555172 +1558,949.8546048428775,927.532451060124,1.024066170145573 +1559,944.9398323836732,922.7579572268634,1.0240386712280134 +1560,2837.461951874497,2688.0333576854423,1.0555903049944744 +1561,1022.9408695541076,979.5310874343714,1.0443169008892172 +1562,1093.6571977486558,1051.4702675248677,1.0401218479749266 +1563,865.0828912909371,825.8025955896484,1.0475662051815682 +1564,465.6034443795842,441.3386354279225,1.0549800244162502 +1565,1059.1271152330878,994.5066184408782,1.0649774426775733 +1566,997.0998707745598,961.2122427833241,1.037335799934589 +1567,547.3127402289418,542.5248656056315,1.0088251708388805 +1568,936.5327457025043,906.7567619027227,1.0328378955093758 +1569,885.2577170966719,855.5375774920332,1.034738555484333 +1570,1215.718108794289,1162.4634512100656,1.0458118984547755 +1571,2039.4440444986537,1945.3548128924108,1.0483661031821483 +1572,2323.5787147802503,2244.4512779457505,1.035254691252163 +1573,1167.8648878984602,1100.214735865869,1.0614881348406504 +1574,241.76215477338607,236.44806234236063,1.0224746710900552 +1575,2019.225787233882,1961.618438771546,1.0293672547747932 +1576,747.1310312801322,701.4086343793201,1.0651865327282035 +1577,418.75596766670026,383.39038672804827,1.092244308054959 +1578,512.1770053162893,501.1420291884957,1.0220196580711114 +1579,688.114345918301,662.4654536966888,1.0387173279428932 +1580,751.4720864055827,725.0269480570729,1.0364746971397096 +1581,347.99996056158693,331.98657351919417,1.0482350441846013 +1582,360.7672974877322,345.4811430268578,1.0442459878618788 +1583,147.9680266264216,138.279830575897,1.0700622499331678 +1584,220.10559234588553,212.3223440603195,1.0366576976154467 +1585,159.49028226709328,148.96684846734738,1.0706427900436692 +1586,148.23888470842647,138.45369831910526,1.0706747924260465 +1587,221.83672309618814,214.01868880204933,1.036529680365297 +1588,208.9491697307606,200.59759180175462,1.0416334904820772 +1589,176.41490091462447,166.57847646355913,1.0590497923854956 +1590,221.95006435608735,214.12533387006943,1.0365427590682286 +1591,651.2415204879494,626.04188816882,1.0402523102612808 +1592,680.0611150556517,658.11642770117,1.0333446886155624 +1593,1238.7492411862806,1186.6462931880876,1.0439077324871688 +1594,415.6951801954124,400.964890584969,1.0367371058073271 +1595,930.1909860410265,891.6512593351142,1.0432228702672954 +1596,977.8132149828646,937.3381607244048,1.043180845456222 +1597,710.0310014202673,691.9034182354102,1.0261995861085478 +1598,695.856914379242,661.390496495075,1.052112054930961 +1599,99.40772609761765,91.95864988636404,1.0810046278458705 +1600,1186.8791065018681,1136.5873620062293,1.0442480236687368 +1601,1025.2628795248402,994.9161622583221,1.0305017833840746 +1602,261.1010570556513,261.0749956075751,1.0000998236082148 +1603,506.4490810632138,484.6494394111292,1.0449802266945198 +1604,288.5237807952873,285.87751887380466,1.0092566282648157 +1605,320.06332213626246,301.5396389389849,1.0614303421681344 +1606,500.53052521663795,482.9527458651736,1.0363964787486095 +1607,134.53353162851403,128.60234894640234,1.046120329299612 +1608,126.24613224468753,120.66574587384612,1.0462466487935658 +1609,134.92942006759776,128.96521123693515,1.0462466487935662 +1610,136.16588834870268,130.35846946673152,1.0445496092868232 +1611,468.74449457937305,448.03072226786793,1.0462329284176204 +1612,246.23637300755962,237.35708630268036,1.0374089808869507 +1613,1759.1105256418243,1730.8968203232032,1.0163000503480923 +1614,468.4256868369749,452.4063148333043,1.0354092581788412 +1615,517.2844227178207,489.57924451666497,1.0565897727721434 +1616,417.0011329960813,388.70953185566515,1.0727833994843259 +1617,384.84575825745446,360.1729278165235,1.068502734479532 +1618,84.16315671936333,78.5620141435204,1.071295811810661 +1619,404.7500695924648,392.7991086213576,1.0304251224323104 +1620,646.5969451142615,617.0633232894362,1.0478615738614763 +1621,735.7380990326961,689.8694460618412,1.0664888889234023 +1622,331.98400134042754,311.651526362043,1.0652410569450075 +1623,522.4926643772279,500.4893367685438,1.0439636291768986 +1624,989.3279081441983,914.5056934596017,1.081817111932395 +1625,630.759734639024,614.9048878152894,1.0257842263704648 +1626,570.249023144399,525.458642966822,1.0852405432417733 +1627,618.6542968985328,571.8727224280013,1.08180417186522 +1628,686.7025320646852,669.5909322061832,1.0255553040452958 +1629,687.7883887263773,670.6710313181134,1.0255227326199285 +1630,343.40106671518447,335.0661555161539,1.0248754195606269 +1631,629.4351375752876,613.8072629987201,1.0254605566252482 +1632,1067.0524320090058,996.8128339270569,1.0704641791230076 +1633,1438.292999812982,1306.359363867364,1.1009933710392215 +1634,868.2278719466811,830.0959053118321,1.045936820541868 +1635,412.122937420097,383.2427595207399,1.0753573999296762 +1636,523.4113964207227,482.66770353430434,1.0844135470181144 +1637,1352.7641321346914,1318.8546940783324,1.0257112767681025 +1638,1683.3820743284814,1589.2333735643394,1.0592415829734212 +1639,1780.2431677248214,1676.7511217917697,1.061721769312109 +1640,905.5627674130899,846.6143700155217,1.0696283921999663 +1641,715.5725987835849,698.7283164491544,1.0241070555434635 +1642,967.1257220785759,931.1882760399862,1.0385931040620688 +1643,862.2638706590529,835.6131606588268,1.0318935977255477 +1644,1885.6306571966788,1799.5631573771393,1.047826884800744 +1645,529.968181710619,511.72514924468885,1.0356500603749044 +1646,701.0760741597243,653.7057061289217,1.0724643636833426 +1647,864.2854452561675,812.2498965107856,1.0640634722994895 +1648,1179.239330323498,1141.8528074898588,1.032741980917686 +1649,973.0625187941398,952.9207103394444,1.0211369196158204 +1650,2016.8854718954178,1946.1480482724783,1.0363474010549867 +1651,515.767789453259,498.35438535747346,1.034941809698925 +1652,507.04523558559083,489.931636115372,1.0349305866547243 +1653,554.2418872868795,525.1097373691433,1.055478213113494 +1654,684.3053263158839,625.6873736814191,1.0936856888921516 +1655,500.56095858308464,445.3692046339924,1.1239235972645418 +1656,363.9487287370061,323.7313200073186,1.124230824279771 +1657,752.9136254978055,699.0507905401541,1.0770513898082166 +1658,641.1316938866742,580.6172991175657,1.1042242366203685 +1659,551.7347698434913,511.2784753903125,1.0791277090675375 +1660,446.09696257954414,413.5820844304879,1.078617714289607 +1661,1056.3302264258416,1004.5730052227669,1.0515216125995714 +1662,673.9958497762563,638.9106003206108,1.0549141764716994 +1663,983.2763597389918,939.7007878261663,1.0463717520271851 +1664,703.2473259894526,671.7544025903333,1.0468816032729824 +1665,804.9322050735145,747.2154024743156,1.0772425225819442 +1666,865.1990251640955,812.1687513010911,1.065294649391583 +1667,1097.8829398209855,998.2226176151091,1.0998377721033596 +1668,1025.128196377406,954.9537280358161,1.0734846791853752 +1669,266.21692975695487,259.22552759623983,1.0269703459591548 +1670,815.3666666776833,788.7505200064921,1.0337446961949033 +1671,262.2073058134987,255.3080893698947,1.0270231016206004 +1672,813.6291798413865,787.0896586835304,1.0337185489163274 +1673,278.1377942661367,228.8506637374871,1.2153680908052182 +1674,443.5055806589142,418.5742779329851,1.0595624338147234 +1675,489.3222407984855,462.76033244684004,1.0573988444757132 +1676,738.2792104685002,704.2612267191851,1.0483030762715542 +1677,752.6995068362311,718.1156456480336,1.0481591807639683 +1678,925.1907663032567,890.8716485550128,1.0385230777114856 +1679,922.1441680191075,887.9548609484575,1.038503429142931 +1680,713.4059612486622,681.5350269248881,1.0467634575842373 +1681,681.4719566770577,653.4200807289003,1.0429308446059158 +1682,240.52361256638437,216.21037029127532,1.1124517859266168 +1683,241.2126071520422,216.89134407363957,1.1121357017832165 +1684,115.2477435357605,102.58263825528948,1.123462463979064 +1685,115.46513324058297,102.77059182311925,1.1235230934479057 +1686,540.5247094749748,513.3781711685872,1.0528782481043064 +1687,633.219086801164,608.0092015908899,1.0414629994814406 +1688,116.07220635304637,103.35282394250734,1.1230675846613973 +1689,347.91060960884795,337.05551931561735,1.032205644682133 +1690,657.4650134703401,643.0032765549263,1.0224909225858019 +1691,225.18423197688534,218.01124391119654,1.0329019179791048 +1692,226.62371648542222,219.23809837368978,1.033687658151202 +1693,233.76309175886004,224.6136254066342,1.040734244575154 +1694,248.33446676219972,236.17454757864806,1.0514870010685733 +1695,277.43560316439635,275.99268719567743,1.0052280949302685 +1696,562.9864340110597,536.5086258775729,1.0493520641726437 +1697,575.8903743668407,541.606280227606,1.0633007691949714 +1698,322.36315111733154,300.65151669931714,1.0722152831835812 +1699,503.5243340221586,478.5089222825848,1.0522778376215958 +1700,446.8946561910919,436.3721202042927,1.024113676148405 +1701,290.1058670380254,265.18179190983443,1.0939886368090668 +1702,559.8982031801498,519.2169528309662,1.0783511596209912 +1703,234.19222419908556,212.68336687143307,1.10113088599286 +1704,579.6741521119579,537.7242680094402,1.0780137453304997 +1705,630.0398017992,577.3287562820059,1.0913016109861786 +1706,458.7546295361633,446.92143063976545,1.0264771346486086 +1707,301.8604510011718,289.0161769600068,1.0444413671797421 +1708,280.863936756843,274.60685687082434,1.0227855923093792 +1709,121.32826322041517,115.5859425961551,1.0496800951333944 +1710,440.53276491579436,419.16041914104665,1.0509884636019413 +1711,166.2101904076256,161.25753439538695,1.0307127107629912 +1712,112.41440784087182,109.53427817392628,1.0262943227906451 +1713,168.31385417217913,163.2698624501779,1.030893587134248 +1714,169.49067164529043,164.448808868602,1.0306591626377604 +1715,281.0330177309089,274.8096703064971,1.0226460277670393 +1716,393.6461452304461,376.90308893033983,1.0444227091574747 +1717,281.1446659217521,274.9190855398456,1.0226451370943623 +1718,415.5316887463385,396.8095093556325,1.0471817810543613 +1719,1264.2468692764696,1201.011684595028,1.052651598225511 +1720,349.71962768257043,333.3234710513177,1.0491899252685042 +1721,1065.2514088001074,1026.573219559826,1.0376769903045648 +1722,517.3323766424114,503.37584409252776,1.0277258686797817 +1723,545.7448934156088,520.9411334813059,1.047613364236658 +1724,334.0043936846144,317.23144931917955,1.0528728926511914 +1725,347.8770424074694,332.0081809400643,1.0477965977298307 +1726,522.8945127866995,508.5374964242138,1.0282319720048907 +1727,1199.8265031627755,1121.92312108177,1.0694373621660371 +1728,2335.186247850204,2221.1513858909357,1.0513404276194922 +1729,1458.9491775812835,1410.0904012954604,1.0346493928622846 +1730,494.4941124846914,468.41477279606045,1.0556757412516224 +1731,775.5716024192492,743.8136051736859,1.0426961768710155 +1732,412.26181565938856,390.53744499156306,1.0556268571590999 +1733,855.0256846138493,803.5231581387374,1.064095883178291 +1734,2568.0053909724,2412.0801894801857,1.0646434567856622 +1735,807.4718212604766,735.9394005200248,1.0971987920335642 +1736,1095.1391392301452,1001.0626801853084,1.093976591982654 +1737,658.4675603124896,627.9850972058476,1.0485401058755541 +1738,566.1965049649586,526.2333307151374,1.075941929021319 +1739,581.1062972160222,524.2754837152621,1.108398762227122 +1740,1975.5792717995216,1832.6072293242821,1.0780156490640693 +1741,3239.217303921733,3033.994788334724,1.0676410244262977 +1742,1619.267074313892,1496.6019907139219,1.0819623950529795 +1743,602.3479203308261,547.5639326035446,1.1000503949681197 +1744,2423.274804418977,2296.860552002698,1.055037843854323 +1745,913.3500425372237,854.9970521913217,1.0682493468209577 +1746,871.808946129992,819.8397195732089,1.0633894959173693 +1747,704.8090657407753,647.1193287556292,1.0891485301421608 +1748,1245.4308297726661,1121.9674725848,1.1100418329449695 +1749,1110.1107069841498,1016.159639499752,1.0924569957636276 +1750,465.8093944040363,442.936472273025,1.0516392836508448 +1751,1197.7021408582173,1137.5244273908586,1.0529023483085882 +1752,3521.965845647765,3390.722325463933,1.0387066552746618 +1753,442.0864100937076,421.01051562215235,1.0500602566670103 +1754,730.2074440561796,714.3087427298792,1.0222574642801379 +1755,1870.5519853068606,1806.186391391185,1.035636185845747 +1756,759.559226646561,708.4800695699377,1.0720968158040487 +1757,808.1762021712823,750.3491394238305,1.0770668742178546 +1758,731.3784474661687,682.1680675114951,1.072138205082202 +1759,734.6572592725236,684.9885507574905,1.0725102754784839 +1760,1067.0700110971402,973.7225899744608,1.0958665456504688 +1761,3182.2077951562837,3032.7787935987044,1.0492713157560254 +1762,1293.6125421133222,1219.6194549192853,1.0606689954768995 +1763,468.10427993245213,446.489465087633,1.0484105819620555 +1764,801.8003395611719,763.8727192628384,1.0496517539400214 +1765,514.9421745085543,491.0322272796893,1.0486932341718704 +1766,833.8790916083493,797.2649078150557,1.045924740239272 +1767,3387.4706982253024,3259.024525110927,1.0394124598095817 +1768,3456.3330750185573,3342.593833326904,1.0340272397315016 +1769,3338.8081090067767,3241.103462729514,1.0301454882267105 +1770,478.0002170093043,467.19730522096114,1.023122804150666 +1771,821.236198899038,797.8487844317455,1.0293130915577566 +1772,710.9412215146239,691.6121911159884,1.0279477872815488 +1773,509.93597264268186,497.94336446911433,1.024084281525377 +1774,918.5495617795763,884.6969981519302,1.038264585161204 +1775,1344.5102503225535,1297.614446903309,1.0361400133384449 +1776,969.1510651963104,939.9553504882483,1.031060746335341 +1777,260.0361387814345,251.87289990194054,1.032410151638672 +1778,801.0220558304098,770.1270071505121,1.0401168228007094 +1779,748.0270694327841,719.7497989940937,1.0392876392299242 +1780,247.65855210755328,240.44766209654327,1.0299894369865603 +1781,1742.4924390042427,1681.2564514774062,1.0364227524438792 +1782,2609.37144654024,2478.6191558659575,1.0527520697824193 +1783,951.1370110986264,914.0249917571283,1.0406028496771775 +1784,934.1213134458653,897.8397924222314,1.0404097939630768 +1785,922.3840757771723,886.3052825351169,1.0407069595014242 +1786,875.644744366778,841.0502306183778,1.0411325179983184 +1787,766.6456572658711,727.5998058865426,1.0536639112097523 +1788,794.6738446315929,753.838283234163,1.0541701878315795 +1789,579.0994545959085,551.738632568702,1.049590187114185 +1790,797.9317916465861,756.9193341493758,1.054183392664028 +1791,1227.6884498190282,1179.3870627588954,1.0409546522811122 +1792,1213.0087366083255,1164.973609404981,1.041232802885448 +1793,758.3946762789025,729.7795526941334,1.0392106403627375 +1794,809.9640043754074,784.1061435757757,1.0329775005737254 +1795,1287.6724343341207,1238.5950610052184,1.0396234208209034 +1796,774.0497276446804,749.3122115901481,1.0330136299287527 +1797,1308.502081960732,1258.7556918384435,1.0395202901125578 +1798,784.9038904349659,759.5726539178802,1.0333493266067795 +1799,1465.1745845944447,1412.4189026131178,1.0373512998755 +1800,2859.989689088638,2753.070514833239,1.0388363369842255 +1801,1982.375171285536,1909.100476380864,1.0383817906973556 +1802,133.5449481324279,123.76733277032535,1.078999968273105 +1803,266.19966775488854,259.08109745468215,1.0274762241249635 +1804,268.8664323903578,255.1202806688865,1.0538810622402537 +1805,391.8905225893318,374.9105653418761,1.0452906874789507 +1806,748.2647041101816,695.297680485945,1.0761789160395556 +1807,626.1401824175939,594.2232360567933,1.0537120469616743 +1808,801.667534107944,785.9348510948698,1.0200177953569018 +1809,815.2073599717921,787.0808906223343,1.0357351698974913 +1810,200.87510722245204,198.6352586360386,1.0112761883353123 +1811,1116.301955133574,1078.4838658955164,1.035065975888898 +1812,1263.9251273944008,1236.2594604863084,1.0223785279646795 +1813,784.7196600835209,740.1792532633649,1.0601751624674463 +1814,1602.2300849823098,1516.5083236560286,1.0565257440325955 +1815,239.82396261046637,221.0634642519035,1.0848647623525212 +1816,816.551761284929,777.9233970238638,1.049655742980411 +1817,4207.48469171843,4004.751247690017,1.0506232301307983 +1818,1726.023008004711,1637.481772163829,1.0540715856176404 +1819,1144.358045483595,1054.3403247783883,1.0853782394447709 +1820,815.4526470521214,769.0449947673553,1.060344521582648 +1821,1657.8714851109867,1571.3517110342273,1.055060731133079 +1822,1225.3812530147559,1142.2763480574245,1.0727537649699752 +1823,1212.7549466852731,1147.626181474011,1.0567508534247718 +1824,801.8842160343528,753.4951125088295,1.0642195320476697 +1825,1611.5548788093804,1504.5364646167604,1.0711304888312427 +1826,1493.12754613103,1406.2936945727283,1.061746598092146 +1827,1052.7152469907878,992.565999442963,1.0605997460940444 +1828,1634.6237982585246,1535.5837628531751,1.0644966675222778 +1829,359.95429152023183,340.2328640744945,1.0579644988128463 +1830,404.8951580349478,378.8063426481016,1.0688711155269168 +1831,221.4512142053868,208.35101732786583,1.0628756079309476 +1832,471.9216399216774,444.58024474006487,1.0614993479919432 +1833,1063.7661883232902,1009.6559782922293,1.0535927198911703 +1834,1593.0095540271604,1506.845983471041,1.0571814050681148 +1835,391.802721763472,367.35798769085795,1.0665419968850247 +1836,370.1806450624109,348.1796509921481,1.063188626927422 +1837,457.22448892400166,430.11169627829645,1.0630366318337978 +1838,406.7544538209558,383.3179104313369,1.061141268779344 +1839,1328.6570054426695,1243.5732017843488,1.068418814056332 +1840,396.7188433536442,366.64768007847056,1.0820165104242245 +1841,735.5057860977242,675.4054969444439,1.0889840094952972 +1842,2085.5242455289576,1921.4591453639487,1.085385682313809 +1843,2230.519252483809,2042.561876402397,1.0920204074367945 +1844,403.5525766666266,381.7254728899081,1.0571801080275656 +1845,228.76197030517798,214.0653368820719,1.0686548959171396 +1846,623.1064557144939,573.8827116594788,1.0857731781336928 +1847,539.9684964108901,497.85342392118736,1.0845933169606357 +1848,1785.573450379329,1699.0230067544853,1.0509413017250275 +1849,3244.103252706746,2964.7295035799543,1.0942324582358842 +1850,2155.3179370536104,1996.6422192629423,1.0794712824660408 +1851,1985.4869984168824,1882.6860410421823,1.0546033460352175 +1852,962.6745781384329,905.9498444401231,1.0626135475892329 +1853,873.0527128311838,801.9031930960167,1.088725821704825 +1854,1969.6318564653661,1860.3643264646953,1.0587344792878903 +1855,1242.3881194927947,1186.9543925727112,1.0467024910703868 +1856,1711.0584808632566,1634.5934544523539,1.0467792319873943 +1857,345.64633432771706,338.38050786553066,1.0214723552134208 +1858,606.8072697976279,586.4502553958653,1.0347122611243835 +1859,428.369656282869,409.3691533261245,1.0464141052210834 +1860,423.83004263149843,404.61950063656116,1.0474780428642578 +1861,353.81638797450506,337.67966986370726,1.0477870584193323 +1862,368.8919605278371,352.8374347587918,1.0455011973999317 +1863,1111.352534189252,1062.0896976119836,1.0463829342173563 +1864,175.90289248924142,168.61056373122432,1.0432495366639158 +1865,173.0566903485451,165.94299978862728,1.042868277474669 +1866,175.17117583640868,167.9655970060828,1.0428991350536203 +1867,173.20454349988273,166.05736867240552,1.0430403955248564 +1868,916.3129709309213,862.4237804851824,1.0624857426999774 +1869,799.1407061069732,762.9708437871486,1.0474066114247416 +1870,867.6001218210945,828.2753202414241,1.047477934714037 +1871,340.1525189508618,321.66335664501855,1.0574798525349207 +1872,117.00520788893965,107.18658904511256,1.0916030534351144 +1873,563.8346078238981,537.9357776650402,1.0481448366778543 +1874,116.57647141687112,106.79383045881201,1.0916030534351144 +1875,994.085406372844,932.9604737706727,1.0655171728284774 +1876,1936.9744152704548,1834.099691013984,1.0560900395766362 +1877,1082.6891661763775,1034.8804512757597,1.0461973311426274 +1878,486.95128097662047,459.55555553315065,1.0596135224862788 +1879,710.3789388182402,668.6624813147448,1.0623879141857506 +1880,341.3847594307659,319.2497101366902,1.0693345948054214 +1881,1721.9474762804036,1651.1873460981635,1.042854089422045 +1882,690.6567767187903,650.5303676692371,1.061682607060022 +1883,1280.7691092138612,1232.641495386069,1.0390442914731817 +1884,1248.7010526584966,1201.015515142336,1.0397043476249423 +1885,564.0298132846651,540.8409786041611,1.042875513501864 +1886,349.90075214136726,340.70101774516843,1.0270023684023153 +1887,1442.0284316647083,1371.714911944403,1.051259572312031 +1888,1566.563330187955,1511.6663177634916,1.0363155623561708 +1889,220.57147550924708,206.4224688838627,1.0685439269372603 +1890,270.04057024253905,261.1062318920086,1.0342172543557888 +1891,49.72332199272184,44.53962360419581,1.1163839738429606 +1892,265.06329717579285,248.54587110757058,1.0664562480745197 +1893,409.8419103526135,384.4148365676317,1.0661448814307362 +1894,311.28126121535,288.2304899637312,1.0799733964804326 +1895,539.5591805423064,513.4955808238385,1.050757203551104 +1896,341.68868016618666,320.3598469671386,1.066577735633754 +1897,1109.1737575858217,1046.7670678143002,1.0596185070111441 +1898,499.99169274011007,471.1413680683391,1.0612349639133922 +1899,260.76237340583316,244.5992895346338,1.0660798479911804 +1900,250.77130963992346,235.18374646521676,1.0662782331219138 +1901,501.4243446233241,472.48493684628585,1.061249376477907 +1902,739.0310224940034,722.3717923685746,1.0230618502846092 +1903,1855.9862002763225,1793.489769195591,1.0348462713053346 +1904,1311.5377207110248,1262.4725853817606,1.0388643174492596 +1905,45.91890806076547,45.5721798234393,1.0076083311939323 +1906,169.32146934039835,164.5248629674299,1.029154294897775 +1907,1573.714161400757,1498.623690547009,1.0501062884080923 +1908,1336.3082806198604,1256.805678257907,1.0632576727948542 +1909,814.6076438602876,793.7691200176504,1.0262526260056246 +1910,1004.3908536441735,943.1947372669853,1.0648817407044817 +1911,838.8797591519361,786.4639116758788,1.0666474922725497 +1912,3317.135249226867,3181.177537953211,1.042738171526614 +1913,4870.760268993229,4672.179179725656,1.0425028839067843 +1914,2524.1505017486224,2434.1430117671,1.0369770755236687 +1915,470.03812653062715,456.1020013663853,1.0305548432642089 +1916,818.9465798728331,787.3114787411935,1.0401811760476551 +1917,918.3928311905576,883.3244504888008,1.0397004528543856 +1918,342.64010751399087,330.09899002311374,1.0379919898876364 +1919,6126.415287768368,5875.8554747340295,1.042642269557469 +1920,1831.3843602740556,1743.4334495590635,1.0504469561125123 +1921,842.3244726185113,810.6826804819973,1.039031044943135 +1922,408.653685159134,387.9837376816968,1.0532752934464353 +1923,325.9369701405026,316.55305336103123,1.0296440570698553 +1924,545.0942412200346,525.3423051964869,1.0375982208707906 +1925,421.91562770463486,399.54784939039223,1.0559827273463496 +1926,482.9397248078401,461.22773148165743,1.0470743449367943 +1927,422.8794443332698,400.4215626857611,1.0560855951334793 +1928,554.5517476223364,532.350503492524,1.0417041854645754 +1929,2345.561607170538,2261.3520764522427,1.0372385758039098 +1930,2176.460586832919,2094.9266176197707,1.0389197256492861 +1931,2208.9495446270616,2126.6340945550896,1.0387069173219445 +1932,2427.079423093013,2341.6645004583247,1.0364761572881043 +1933,480.0522423790589,459.7554143549366,1.0441470124992436 +1934,1533.6184009094834,1457.3564938651389,1.0523289307491854 +1935,1164.8233211895756,1106.9481683572649,1.0522835255404945 +1936,454.65790322760483,437.6727969294147,1.0388077724212077 +1937,756.2610922158327,704.1313443029791,1.0740341249322696 +1938,949.968877618251,879.0878158498998,1.0806302402221597 +1939,692.7358320650354,666.7702089931738,1.038942386329872 +1940,402.6658090341081,382.1295384586891,1.0537416465061864 +1941,438.03647763431115,411.07148508163624,1.0655968451504727 +1942,1209.6628580180538,1174.6713887678877,1.0297883046992986 +1943,840.7046440797124,815.366282212107,1.0310760481766081 +1944,369.15194073324767,328.9415208570353,1.1222418494674884 +1945,423.3437638293442,403.78805672349876,1.0484306228978848 +1946,686.0314698287879,654.365739726088,1.0483914853426692 +1947,860.119657073753,814.8474965227113,1.0555590595101987 +1948,524.3622807301792,484.78073096893723,1.0816483561178882 +1949,547.2087702209009,504.6389282120082,1.0843570315903341 +1950,1241.8443394229603,1165.899650337791,1.065138272460384 +1951,310.4915278601796,301.5157988103613,1.0297686857048032 +1952,180.42984027787827,172.04267751954796,1.048750477958455 +1953,688.4319839164167,643.6768691779611,1.0695304070746123 +1954,2277.2913601078017,2189.0990287244927,1.0402870451387005 +1955,3333.415432064004,3204.2784680151685,1.040301417413583 +1956,3121.8293227077534,2963.049453638037,1.0535866415846573 +1957,3105.0007913436034,2938.38108965216,1.0567045922934277 +1958,1664.6262402670986,1563.6338646847325,1.0645882503975626 +1959,2272.286358962395,2184.0148146820497,1.0404170995942605 +1960,3035.263344205639,2915.7971002152703,1.0409720703753866 +1961,3042.333462491256,2878.409691875835,1.0569494228281984 +1962,3268.0508610905813,3092.720232936015,1.0566913962302111 +1963,1730.914433143678,1625.7970884948463,1.0646558819625818 +1964,510.4492017169913,482.75588054052906,1.057365062328096 +1965,457.54840645522927,425.25702954599285,1.075933787487795 +1966,518.6808085079155,482.4254503347757,1.0751522502554138 +1967,722.8922500813503,676.5178803983621,1.0685486238082593 +1968,1380.9054606261889,1244.3155895528002,1.1097710839759536 +1969,1372.0702031232302,1315.4545289335579,1.0430388682728324 +1970,379.735743340297,364.67948433122217,1.0412862792012723 +1971,108.77131327941599,101.6444793965006,1.0701153070509086 +1972,112.39771322468395,104.89911706413052,1.0714838825189457 +1973,194.10447984198336,183.6674462855987,1.0568257128166052 +1974,178.92791193012016,168.0297482284848,1.0648585373514705 +1975,453.2907629576567,423.58277424718096,1.0701350255880322 +1976,346.17290491486625,318.93589388699365,1.0853996415891756 +1977,1015.2790502723382,936.4997564918655,1.0841209976130486 +1978,811.944014108172,759.5836094507538,1.0689330364767606 +1979,1995.4587685441327,1865.140456861477,1.069870508252202 +1980,878.1589883538561,819.8393115323892,1.0711354969212927 +1981,887.1126852363923,827.7950146669631,1.0716574387601183 +1982,522.42363666261,491.9883063919739,1.0618618976817467 +1983,435.01724160168015,407.9823769480537,1.0662647853955434 +1984,734.4373710345579,694.435676087063,1.0576031680470284 +1985,172.06924166718537,161.5006614911127,1.0654398568928105 +1986,499.2285723401918,474.0408211093098,1.053134139739147 +1987,255.4415958479544,240.55708630306347,1.0618751655735421 +1988,1744.9488498593453,1673.0046871625295,1.0430029654123896 +1989,3834.2651355999787,3702.7770012783044,1.0355106813821844 +1990,1914.0624961034762,1838.1348585206995,1.0413068917282173 +1991,2228.389429924768,2115.3150298145842,1.0534551111850678 +1992,2950.7649377764424,2801.0988283355505,1.0534312134676895 +1993,2765.240423139063,2624.385555754908,1.0536715602154112 +1994,2774.0400491954056,2653.763268299905,1.0453231010965625 +1995,245.13479795512706,236.79223930886138,1.0352315543390085 +1996,255.4630758188688,246.79211986759316,1.035134654850113 +1997,1294.1107030151693,1252.4665953127642,1.0332496753671947 +1998,1292.9797282901666,1251.3720875997672,1.033249615444281 +1999,308.0973330146478,297.14051980216635,1.0368741806730917 +2000,258.4059016152079,249.42296430024558,1.03601487673825 +2001,325.3960898533892,313.8174265541244,1.0368961769472282 +2002,319.9509974417451,308.4976393952838,1.0371262420967373 +2003,188.39384952383955,160.61266575110804,1.1729700683492943 +2004,441.09757315122516,431.9689725618993,1.0211325376801634 +2005,1172.1493918048677,1108.875432685296,1.0570613770081867 +2006,1301.6593535799004,1232.5981026357128,1.0560290096151463 +2007,857.8176778867917,808.4211475150959,1.061102471803873 +2008,528.7252613919202,503.4535001967904,1.050196812983228 +2009,384.99141097790425,368.2432556308439,1.0454812276693806 +2010,1178.1544354948132,1107.9101106785115,1.0634025487620853 +2011,620.4710672263524,581.2295377316832,1.0675146855884405 +2012,886.477927716298,833.2095137451093,1.063931595946088 +2013,177.89006773969822,163.88087874384686,1.0854839753315477 +2014,278.61839368526097,258.538322065879,1.077667679819881 +2015,945.9572116383475,919.2822626689999,1.029017147455778 +2016,491.9838735567481,476.2524338913475,1.0330317255008288 +2017,587.8027741925456,559.955016985027,1.0497321326942648 +2018,906.1287564108123,856.1028952293285,1.0584344025236396 +2019,662.088208253209,635.0631471261468,1.0425549195373072 +2020,759.8767991819583,710.9691214629933,1.0687901573254341 +2021,1043.586540175075,985.0970809422789,1.059374309765337 +2022,906.2081220818358,826.5522079220467,1.0963713040704883 +2023,1373.648969306262,1275.561985044208,1.0768970739267165 +2024,2664.773866935898,2586.423964551888,1.0302927530280537 +2025,2512.8976528012713,2421.2231012945,1.0378629096417253 +2026,2943.659944201912,2845.987748854036,1.0343192606458704 +2027,1697.3284515111795,1605.1616938810237,1.0574189864993049 +2028,3529.7561792756087,3403.9866223626427,1.0369477236152214 +2029,1381.0431156786087,1315.2882223251424,1.0499927637436197 +2030,1625.121385240347,1535.347543551442,1.0584713487613675 +2031,1214.6967248471328,1145.6468266610452,1.060271539691976 +2032,897.9844266196139,858.6990036686406,1.0457499342413736 +2033,3660.5260426508426,3530.974954827717,1.036689891455049 +2034,4402.936396565676,4233.415658509561,1.0400434901107247 +2035,4302.120368764673,4148.919274552885,1.036925542309641 +2036,3698.7817557269686,3564.9682132319585,1.0375356902197161 +2037,1750.6036197841283,1687.6594354041338,1.037296733606044 +2038,994.18735532437,961.6461760055166,1.033839035739759 +2039,1475.2720708499432,1423.3925366406572,1.0364478054182626 +2040,1049.6133067576945,1014.8572190551954,1.0342472685318789 +2041,3836.03223741874,3689.559644101397,1.0396992073434868 +2042,1942.4054071258527,1874.994494067275,1.0359525925392712 +2043,4347.358653906917,4178.882974940037,1.040315960025011 +2044,4466.353609190482,4306.328010660348,1.0371605688498389 +2045,6764.664218956403,6520.551843564242,1.037437379726242 +2046,3772.0604601505465,3632.9501131211823,1.0382912901905637 +2047,2564.5096859163477,2468.0482323518754,1.039084103908517 +2048,1632.1754326953628,1572.6751342011069,1.0378338139901226 +2049,3904.319195183272,3753.6758276632886,1.0401322262326953 +2050,4503.482371956956,4328.854121519246,1.0403405255838056 +2051,1073.8734345174662,1025.3825500567332,1.0472905302104567 +2052,323.67103911593904,314.917473404426,1.027796379847972 +2053,347.9396929280354,341.7215687411787,1.0181964638924104 +2054,345.53227096918397,339.4184008778342,1.0180127832655435 +2055,311.332009230639,303.0865870399302,1.0272048402776153 +2056,1330.915647516842,1310.0816513054374,1.0159028226909708 +2057,2087.8111781897205,1991.5506148634097,1.0483344799815257 +2058,2027.4015036175513,1925.9790894849912,1.0526601844673613 +2059,2988.3767790968645,2849.343385705826,1.0487948887061211 +2060,1122.9595521975718,1078.4442897115312,1.0412772944423008 +2061,1516.068861835419,1451.7175979181416,1.0443276736533065 +2062,948.4559312878648,902.6853992137479,1.0507048547744138 +2063,859.2501396089435,818.2470518731683,1.0501108896657911 +2064,633.9234797999893,608.7728104768619,1.041313719815158 +2065,3152.617430506149,3048.714557327859,1.034080879408192 +2066,580.4744500052456,540.9741219658781,1.0730170380346935 +2067,581.1920437729817,552.5986054081732,1.051743594871522 +2068,462.7281562577168,430.9582453435419,1.0737192321006628 +2069,165.5316986900603,160.25269069768459,1.0329417744525395 +2070,117.44301422078132,112.9219830904809,1.0400367670365642 +2071,460.62468078281614,429.0010116294849,1.0737146726839042 +2072,732.7692400653641,712.5776353437135,1.028336006801436 +2073,161.7915957359013,156.4096698000605,1.0344091637219142 +2074,161.7390602326158,156.3697442267519,1.034337307593711 +2075,58.45213105750841,55.35968412002281,1.055860993187407 +2076,57.3452947824548,54.31096574595294,1.0558695466896197 +2077,599.7520772132152,591.4594436092741,1.0140206292984972 +2078,633.1014061006241,602.5994374052437,1.0506173202330225 +2079,592.1094295695297,555.5014094210463,1.0659008591654824 +2080,354.32199133606184,334.75401401315116,1.0584547951742915 +2081,356.68657411659416,336.9521210715384,1.058567528770255 +2082,90.76110725165708,82.75952242393663,1.0966847631953727 +2083,88.49031175628932,80.6107583873167,1.097748160749377 +2084,671.639077922477,638.1879946757658,1.0524157200163349 +2085,276.9217352059233,265.0388791685705,1.0448343883532465 +2086,188.5236506964379,178.84052627092728,1.0541439047816352 +2087,183.6321359136567,174.16444375253238,1.054360648804855 +2088,58.52457946036846,55.4245254216094,1.0559328927974976 +2089,1567.8068817414344,1505.1277123917575,1.0416437547682085 +2090,95.5109109736468,88.05046290794529,1.0847292316168882 +2091,143.53721578114713,133.80784099750852,1.072711544488785 +2092,130.13522348673746,121.35815252643317,1.072323702838114 +2093,86.51929380349296,79.81047762442473,1.0840593413140418 +2094,410.69149599479215,395.98102778228525,1.0371494268169708 +2095,406.75305412898194,392.1630362859399,1.0372039598153355 +2096,208.15287732379466,204.25612388666792,1.0190777802054487 +2097,236.5505309961547,235.21672475772968,1.0056705416666218 +2098,745.849131158833,712.2169728173224,1.0472217872153082 +2099,711.5972885549944,694.4480838068816,1.0246947254200816 +2100,1677.912656838802,1607.8959451443905,1.043545549017554 +2101,2519.41447680543,2415.35158525792,1.0430839519110415 +2102,366.35589766159825,337.81070985590986,1.084500541199135 +2103,787.1785775485291,759.7231679831851,1.0361387025200628 +2104,448.92270073289006,433.8354551452682,1.0347764236617543 +2105,515.8536188149169,496.6184793083737,1.0387322266648866 +2106,1559.1489180873416,1495.6546569397035,1.0424524878473986 +2107,1371.3150679494365,1310.9362854284157,1.046057755203022 +2108,2864.699000576037,2738.5163069929868,1.0460770283751222 +2109,5254.73883849958,4997.134726352279,1.0515503636091361 +2110,1910.4341927192463,1810.9117592718746,1.0549570860854023 +2111,1898.7149367641991,1804.207737731975,1.0523815506694516 +2112,494.02245533670623,461.5005499631301,1.0704699168314629 +2113,492.1548921056606,459.7607886668513,1.070458604207508 +2114,493.07192322886686,460.6185782854743,1.0704560051923897 +2115,491.61150470874725,459.2535371704164,1.070457742661487 +2116,123.58697651016138,115.15228844365454,1.0732481150006328 +2117,134.1814251798062,125.0221491467217,1.0732612268753714 +2118,130.84624049218604,121.91388374516782,1.0732677564902222 +2119,143.50752252611846,133.71115635676722,1.0732651368537465 +2120,157.09156978996194,150.49866125515996,1.0438070909057733 +2121,167.96556405373278,160.91815407542447,1.043794996399257 +2122,159.06620846257255,152.39585580792868,1.0437699084353764 +2123,168.85577926979613,161.77509527768896,1.0437686899825531 +2124,158.47259523282645,151.82731029462744,1.043768706205119 +2125,169.94134890708332,162.8407165527197,1.0436047722257769 +2126,158.33488375931043,151.69562591032437,1.0437669696086747 +2127,168.67098651070464,161.59804427313944,1.043768736616702 +2128,158.22979321446837,151.59498852882206,1.0437666492146926 +2129,167.09068852649466,160.08401350293988,1.043768736616702 +2130,160.18169065633688,153.46490558473786,1.0437675639652366 +2131,169.98531111036743,162.86311798144615,1.0437311603584347 +2132,486.37673566539627,452.4394531398521,1.0750095560633035 +2133,474.3847899349564,437.8018358341433,1.0835605315156152 +2134,470.7993195986682,435.7161263435343,1.0805184640503138 +2135,481.0409481911438,443.943726444246,1.0835628921801124 +2136,269.201297691135,248.80241620113628,1.0819882772903133 +2137,424.3664469279532,391.4025482004218,1.0842199389837694 +2138,303.44584019570885,280.39058120701634,1.0822255116040096 +2139,469.2407999959037,432.7387557529842,1.0843512252083924 +2140,221.70089995041405,213.66674453851428,1.0376013376777573 +2141,253.50548615355206,244.50452624602457,1.0368130604603638 +2142,491.9732118204364,472.197230206293,1.0418807658094558 +2143,1178.5006776202817,1133.1732258205243,1.0400004613301166 +2144,424.2723386682712,414.6977490786561,1.0230881156478113 +2145,459.75199490749236,449.2922821148541,1.0232804194708254 +2146,433.7162242274991,423.8773171449295,1.0232116857510578 +2147,465.16947021183887,454.4637353812379,1.023556851729039 +2148,976.7739661629628,943.0569205635506,1.0357529273834962 +2149,933.8230593359801,902.2320036201069,1.0350143373202432 +2150,153.7287115682934,148.94636089663308,1.0321078718732792 +2151,169.90353224845765,164.65233175917103,1.0318926579003285 +2152,152.19416297095486,147.49379175335008,1.0318682648383268 +2153,170.75212673104983,165.47868898129482,1.03186777573728 +2154,171.16943849052942,165.88134035929926,1.0318788003507575 +2155,182.28525391193867,176.64955046355695,1.0319032991229964 +2156,170.52392289731912,165.25753289996683,1.0318677757372798 +2157,170.2160002987999,164.94514069908078,1.0319552281284543 +2158,799.8534352680547,771.6585996630196,1.0365379659053209 +2159,335.17736669614834,320.59314705236415,1.0454913642973225 +2160,311.46741617522804,309.94523010726067,1.0049111453253874 +2161,152.99642104736682,139.9427596493613,1.0932785764030422 +2162,60.53015352002237,52.47467553624364,1.1535117254458278 +2163,58.89715313039946,50.91942447308113,1.1566735826233818 +2164,2474.3117860743837,2354.7895836553707,1.0507570626473883 +2165,98.28563963342904,93.88444923480708,1.0468788008503356 +2166,594.3685622081514,552.2721596728198,1.0762240170865585 +2167,647.62932967384,615.0321172274912,1.0530008296043043 +2168,740.9602963300638,691.1982386144458,1.0719939012219843 +2169,294.1014806426806,263.21428261828675,1.1173462082571957 +2170,1022.6955867957469,956.2668820031597,1.0694667001887947 +2171,755.5265111867932,705.8780896256818,1.0703356886844857 +2172,1007.542659275699,935.0218951724493,1.0775604982917266 +2173,4786.268832165345,4511.955030299119,1.0607971045863993 +2174,1197.1830182482197,1128.569525512503,1.0607968682341995 +2175,1169.4026994586845,1102.3813648745686,1.0607968682341993 +2176,700.8518119455503,649.4442931789509,1.079156163671815 +2177,762.2487584195887,708.5736250632123,1.0757509614496137 +2178,2101.7564708487193,1923.2623592986752,1.092807988825369 +2179,3435.3532662570174,3228.3061657963835,1.064134902276085 +2180,948.9407228886071,886.8552677442315,1.0700062991138268 +2181,788.3919764942957,748.9044767254262,1.0527270179256079 +2182,1116.5895134254613,1048.152177387705,1.065293320487414 +2183,1052.077517157576,994.4707784296351,1.0579270301123453 +2184,682.7833461285267,654.1412477373048,1.0437858008347523 +2185,523.3331931147222,497.9298776373397,1.051017857369637 +2186,2401.0713963364947,2284.9152582361476,1.0508360814177478 +2187,980.4230639137512,931.382501984222,1.0526535143456668 +2188,1490.4660959308667,1418.5614061485924,1.0506884576660633 +2189,752.9521077614485,718.777466779465,1.0475455096486335 +2190,172.32123712775112,164.28987908537138,1.0488852879257786 +2191,243.95371224663123,229.5962248453258,1.0625336388304196 +2192,127.85964478560201,113.54613075314815,1.1260590205717513 +2193,182.0000571877806,172.68572014955998,1.0539380849218665 +2194,1696.950443770196,1638.387677905467,1.0357441444747657 +2195,361.84296360626297,340.1797079301192,1.0636817986821068 +2196,305.0858960561415,293.3814638550257,1.0398949274003881 +2197,470.90322400672864,453.08177516471886,1.0393338461595167 +2198,364.796437513294,342.943314666921,1.0637222593698832 +2199,1085.2624646077059,1030.5801845085616,1.0530597045442125 +2200,323.3839830470826,298.9304408487857,1.0818034527660125 +2201,167.80135024986197,150.3637562480876,1.1159693960624646 +2202,246.9794444451864,230.64949585026972,1.0707998451707763 +2203,749.4383902414255,715.0106506944207,1.048149967435546 +2204,242.72038891305937,227.5496768939334,1.0666698904002285 +2205,702.7821667737461,670.7393089031576,1.04777244667975 +2206,256.30814666603203,241.95354416847317,1.0593279282057704 +2207,1235.382267072337,1138.90201471144,1.0847133915952742 +2208,857.0695490839408,797.4211259764813,1.074801658953313 +2209,1270.4357127925157,1208.3033699768007,1.0514211450199862 +2210,495.1885823989764,478.4240119236706,1.0350412396900774 +2211,118.87362421918266,110.01616202665602,1.0805105543527374 +2212,153.5712538709248,140.3061571846809,1.094543938430182 +2213,295.9455271399512,285.2697834044007,1.0374233247144038 +2214,1426.4150313752011,1347.8960604032366,1.0582529864717276 +2215,559.0541147182458,509.2741355951257,1.0977469218320863 +2216,583.2790188026016,551.967330338404,1.0567274306705812 +2217,1241.095218392615,1169.4709271170134,1.061245037918275 +2218,476.8548333502213,460.57304977259076,1.035351142637785 +2219,524.4698602174676,504.6695926290341,1.0392341204574773 +2220,437.10615818416073,423.29553453649527,1.0326264335927569 +2221,582.6542085022811,566.9423572649423,1.0277133134189096 +2222,580.4354286372153,561.170647041999,1.0343296316312398 +2223,447.5656702664612,433.73850157992774,1.0318790437929002 +2224,634.9192644269817,617.1890678648506,1.0287273341108718 +2225,750.8996702168342,718.9680500801442,1.0444131281398814 +2226,1922.8582934441304,1805.1061443445706,1.0652328116374095 +2227,2927.3920070624504,2819.7293831243037,1.0381818995051415 +2228,395.2912158386148,380.996622298275,1.0375189508350782 +2229,1472.7883205599805,1419.153970185513,1.037793186293561 +2230,216.7624877115552,210.41074243628975,1.0301873621171633 +2231,200.38488531486237,196.97539770703025,1.0173092053501178 +2232,227.45312217992543,219.4138820419128,1.036639614883059 +2233,205.09708340151658,200.99815980073973,1.020392841431187 +2234,2182.6006710655765,2109.6894900587677,1.034560147998262 +2235,1512.8368011203274,1413.298045118727,1.070430123600177 +2236,2491.317115946004,2326.5400159459787,1.0708249584665004 +2237,1736.7173417099666,1622.258444812721,1.070555278823319 +2238,2502.877425511017,2337.3353922207184,1.0708251087290541 +2239,2949.1636990472084,2868.737172554548,1.0280355158576768 +2240,1708.4178629178941,1609.843094076572,1.061232532042426 +2241,1673.9637617548035,1576.2289521035202,1.0620054653360183 +2242,988.2824335381775,919.3990815332106,1.0749221457673153 +2243,1094.1309662215947,1018.5892313166297,1.0741630998860254 +2244,4229.980907983025,3907.088923020135,1.0826425994710398 +2245,2169.771193100682,2108.3533871332393,1.0291306980804358 +2246,821.5724540613371,765.8903435549306,1.0727024579627866 +2247,748.2956990511393,693.8160887663643,1.078521687759709 +2248,1098.2961783180547,1019.7878749835969,1.076984935063795 +2249,1028.9840939882909,955.8568270467422,1.076504414544473 +2250,1029.5671831228194,935.2866109491486,1.1008039365366227 +2251,974.4150458053456,874.6619142671589,1.1140476450512489 +2252,1020.5091718371538,911.0365697116373,1.1201626869491823 +2253,1030.411485256028,936.1145553871288,1.1007322547504914 +2254,426.68180231694384,403.645360310801,1.0570709941727192 +2255,906.8359140841764,857.0015790815775,1.0581496419831629 +2256,2307.209106660056,2237.7707065735663,1.031030167604979 +2257,798.2286305881457,753.3145145352447,1.0596219974343792 +2258,1145.4690042997374,1096.1071689103044,1.0450337674905512 +2259,1294.134308895479,1246.7793625600862,1.0379818175993516 +2260,786.6578803882518,742.4045083075687,1.059608167226201 +2261,863.8855159203285,816.3356802595309,1.0582478958235422 +2262,1724.5363525115947,1654.51319475538,1.0423225139443917 +2263,784.2463223070797,746.1194205523839,1.0511002672018226 +2264,723.8967362447067,636.8157808021787,1.1367443428189463 +2265,1674.288949180085,1578.3098235080695,1.0608113338981096 +2266,934.8689057960206,875.2117646735219,1.0681630932426422 +2267,942.8203006893297,882.7164328459261,1.0680896668589543 +2268,1264.723128631035,1224.0433686482193,1.0332339204841579 +2269,1206.8544218002316,1140.6398164927948,1.0580504067541947 +2270,1142.9105645029094,1075.2774738722676,1.0628982679113355 +2271,1254.459483938456,1215.104439791712,1.0323881987901304 +2272,1921.1955502579633,1836.28488162654,1.0462404659979618 +2273,1397.7996940456476,1328.0536595371202,1.0525174822626042 +2274,1244.386910406875,1199.544481436263,1.0373828813058439 +2275,1022.1590574996834,988.6454983032721,1.033898459310165 +2276,1157.4214137119689,1120.1042932574987,1.0333157552194931 +2277,1016.02986884377,966.8779460080196,1.0508357058289368 +2278,391.8442318180849,370.5124354050773,1.0575737664234826 +2279,264.091710989738,255.21878683149743,1.0347659522576553 +2280,655.6057370056685,628.2737255161703,1.0435033495424992 +2281,1039.058158441731,992.8029367835342,1.0465905366960875 +2282,1207.8625229990557,1154.2176653253696,1.0464772453976987 +2283,1922.8491456090044,1816.7844898605415,1.058380427805504 +2284,1011.9362411804514,952.7661488619381,1.0621034787908774 +2285,1223.5515914862629,1152.0028559311827,1.0621081234188834 +2286,1162.3488538084737,1093.3723530059538,1.063086011469822 +2287,902.978382389129,856.1742837813271,1.0546665550395766 +2288,426.50740756991894,402.31791046155274,1.0601253299427191 +2289,195.1712109793487,184.0892264010445,1.0601989849974258 +2290,282.8808887491905,259.10916021931735,1.0917440684449444 +2291,591.5156969811553,544.4583365343491,1.0864296811879883 +2292,886.2479015456402,833.3284913873882,1.063503661167456 +2293,693.5470112078941,620.2189785850384,1.1182292628164099 +2294,220.80792223486876,203.83216690593275,1.0832830047711273 +2295,91.904629711905,88.19149893268971,1.0421030464857985 +2296,120.17618404118306,117.33989867600941,1.024171534125873 +2297,157.82063466400052,146.4626379705884,1.0775487650010303 +2298,323.4239379891427,306.589477784474,1.0549087996310915 +2299,391.6383796947883,369.8802546562954,1.0588247811679248 +2300,374.92778788974744,359.99340822149657,1.0414851475809859 +2301,81.0642045442013,76.83219177760242,1.0550812448361335 +2302,80.09681744350391,75.9121349327058,1.0551253434580352 +2303,82.47514943757255,78.19977965037633,1.0546724019723712 +2304,80.35759606910769,76.16247228580785,1.0550812448361337 +2305,1014.0619891776727,933.4609120917703,1.0863464940436396 +2306,1062.440846476047,978.0272412912618,1.086310075651202 +2307,1575.6210423400332,1477.0202426416868,1.0667565662620822 +2308,1496.6285051193197,1403.0101444246113,1.0667267881609668 +2309,1519.7806254857805,1444.5336280344459,1.0520908589395195 +2310,620.5509263348323,590.5962773366687,1.0507193325586914 +2311,1166.0977538996851,1110.7267595007872,1.0498511392881038 +2312,466.86508827638494,450.45932201143495,1.0364200838195408 +2313,2224.903899816578,2157.413976371393,1.0312827877191646 +2314,999.816646924631,920.345437354392,1.0863493274858682 +2315,953.221647852883,877.9152588086222,1.08577865379223 +2316,1222.9790095893163,1146.841147176847,1.0663891966205574 +2317,1521.3040086049057,1472.248474945886,1.0333201456777346 +2318,1415.1317780536763,1387.5756991516828,1.0198591535718307 +2319,2094.191716831727,2033.0106024948475,1.0300938491229705 +2320,895.7969748741908,847.2623001159245,1.057284119394461 +2321,918.7196027168217,868.9664472211351,1.0572555541756439 +2322,393.44575882878456,358.9628370923313,1.0960626509857445 +2323,406.07132155629296,370.11333656372824,1.0971539834970883 +2324,415.13590352684616,378.3499851990071,1.0972272228542315 +2325,400.2157292805893,364.82282495714725,1.0970139528073644 +2326,71.5407071992151,70.19593023662873,1.0191574776208987 +2327,410.0695316910435,403.9640517814379,1.0151139188813487 +2328,133.34851002081555,126.11080265427744,1.0573916525325726 +2329,162.70805587356213,148.42868242267116,1.096203599047174 +2330,146.00762283588844,138.31460763280546,1.0556196871375019 +2331,213.1764280493494,201.7891710040235,1.056431457588469 +2332,728.4451309796839,699.1404796045513,1.0419152548450747 +2333,617.803582996178,594.1804685183994,1.0397574739147575 +2334,500.42051326466105,490.7393231231506,1.01972776520108 +2335,940.929365372884,921.3419681279822,1.0212596385733956 +2336,621.0084614854869,606.7018058746838,1.0235810335032334 +2337,1591.0387523533568,1540.8190745673458,1.0325928453346234 +2338,647.607776448821,613.2127616752422,1.0560898548158306 +2339,1448.5217143079576,1375.4915158379345,1.053093892349844 +2340,613.8616379512689,576.0650078498212,1.0656117444844024 +2341,1391.577165752522,1319.568780400163,1.0545696339758222 +2342,1262.1805159881628,1145.6781062553257,1.1016886061597422 +2343,1942.8282980928689,1833.9571627588618,1.0593640557941004 +2344,261.0227724349342,251.18710722357034,1.039156727907255 +2345,226.09080588408406,207.76527715515155,1.0882030384473131 +2346,1167.582337313273,1103.8361906266769,1.0577496436771163 +2347,1825.7643153182325,1736.623177666798,1.0513301554406282 +2348,1503.4684160077438,1423.157757344601,1.0564313114612047 +2349,3179.6499326086814,3065.0250843069803,1.0373976868537174 +2350,1278.5237873221233,1250.2740986782953,1.0225947963520092 +2351,510.9432572155424,473.0259238123768,1.080159102269848 +2352,501.2248122498809,464.0596751180854,1.0800869783015266 +2353,509.2108942262469,480.2479826989603,1.0603082419305898 +2354,780.0892482106451,752.0146230238238,1.0373325522234318 +2355,774.9580200639647,747.0425590484259,1.037367966091647 +2356,541.3179189807483,523.4006119943417,1.0342324914717531 +2357,477.15223680197647,466.7295595941625,1.0223312987008513 +2358,489.7918916966633,486.9582465135894,1.0058190721758211 +2359,675.8588177369686,623.8194437055571,1.0834205707380518 +2360,1334.3312127871502,1241.3580064621744,1.0748963682040011 +2361,531.2440876444892,515.212024883762,1.0311174079532486 +2362,390.72900702466734,383.3350956195264,1.019288375861311 +2363,602.2572418785583,588.5008962197012,1.0233752331512533 +2364,367.7325048156225,355.4264930701601,1.0346232258579364 +2365,462.4612808317623,449.5468124239772,1.0287277499269758 +2366,460.48603131311694,444.07353515105865,1.0369589603138032 +2367,276.40446327227534,262.2631117066314,1.053920475028385 +2368,131.59874321585005,120.8686026714828,1.0887752510346416 +2369,474.20031763855275,459.27145263729204,1.0325055365743594 +2370,2515.945553557102,2361.6569326083277,1.0653306662870676 +2371,1248.653235521218,1166.676765939653,1.0702649371058146 +2372,1956.6111389257069,1868.500884224074,1.0471555863021291 +2373,795.5769772473569,762.3290230264564,1.0436136539691296 +2374,670.3555035300252,627.148022412325,1.0688951883344902 +2375,661.5377393605694,626.5939862913114,1.0557677759981121 +2376,676.5356112183142,632.9316567432368,1.0688920423090267 +2377,341.9894550019057,320.48431159128165,1.0671020160202096 +2378,354.05008761761314,331.8304057807231,1.0669609579164758 +2379,805.7641826780047,770.2819485691352,1.0460639564185306 +2380,339.4782698012211,318.1404729944283,1.067070362365264 +2381,459.04485474407545,438.1517137098198,1.0476847182848013 +2382,2283.7066817952978,2214.3161324345056,1.0313372369664766 +2383,338.39191627253393,317.1452245605461,1.066993572870058 +2384,335.68812322754457,323.1198745506929,1.0388965509915729 +2385,565.1968337109212,542.5577762864392,1.041726537548565 +2386,642.1864961779231,590.5870226962702,1.0873698058011507 +2387,764.4243891300725,710.3400887811484,1.0761386006549705 +2388,537.9301925796201,498.27514370745587,1.079584641885019 +2389,4937.802563067375,4717.966103244788,1.0465955996740615 +2390,2935.5541355692344,2806.2417362614915,1.0460802779877454 +2391,925.8392865492012,867.5744745314721,1.067158282923428 +2392,1295.706651049219,1221.4370221407562,1.060805123442463 +2393,1367.068931915014,1310.2739354699427,1.0433458950129395 +2394,1306.3056495315304,1229.9385551080725,1.0620901703636307 +2395,280.16423037527386,255.94518349530986,1.0946259138352092 +2396,291.531284907421,266.8993334166064,1.0922892956512795 +2397,339.78123307130755,310.6609541303412,1.0937365270845998 +2398,323.67071976847524,295.6052335967319,1.094942453590083 +2399,2482.940243109331,2379.809287438404,1.0433358068712872 +2400,1018.4147355090834,971.1711971933257,1.0486459426023866 +2401,2766.201047667978,2655.6695480509056,1.041620953818669 +2402,788.5574639692296,755.4689567950819,1.0437986324607151 +2403,647.6167703426456,622.5614172013934,1.0402455925615883 +2404,720.4720472646042,691.3107969586789,1.0421825471759099 +2405,1034.3771029003008,988.2048084244218,1.046723406000721 +2406,473.46764646491994,452.379159734891,1.0466168396050506 +2407,1169.448116319056,1123.875696272083,1.0405493420652636 +2408,1317.1282013658642,1262.1824065161497,1.0435323726317616 +2409,1203.9259679696802,1149.278309164107,1.0475495433698037 +2410,997.288532288403,966.3009118637981,1.0320682926448201 +2411,1032.1201702090366,965.4946095688699,1.0690066624710806 +2412,346.1986054050067,329.67895965426095,1.0501082803951762 +2413,935.3553313577014,907.8070967783989,1.030345912338717 +2414,1249.3409560950356,1190.4252280551764,1.049491330199807 +2415,1510.6662394409177,1442.325504587688,1.0473823243337612 +2416,2125.4084408655744,1936.814299625399,1.0973733730056887 +2417,2218.699897520594,2019.0130471387702,1.0989031995928944 +2418,1185.2106920557555,1086.6636606894524,1.090687703041232 +2419,1247.3714226657194,1172.6680118606369,1.0637038019708176 +2420,3412.7586307125403,3221.335570039819,1.0594235082035726 +2421,1766.7661341604519,1669.4925787043694,1.0582653416354644 +2422,3337.08349464688,3193.8773709202133,1.044837702608916 +2423,1186.5937286679618,1175.8674169996411,1.0091220417482867 +2424,652.0178794175218,626.9413546105241,1.039998198591599 +2425,1713.4293448004967,1630.1225674881603,1.051104609539087 +2426,1335.1979327968693,1292.433323034307,1.0330884456477505 +2427,169.58747837357265,164.18553108374488,1.0329014819647686 +2428,394.0198059416661,377.7074576050923,1.043187784641597 +2429,171.61212924080286,166.23192997766688,1.0323656187103092 +2430,215.2062740076424,212.6146766712062,1.0121891742235833 +2431,697.7064967622256,675.4603404713181,1.03293480750533 +2432,5953.765718811917,5741.349328115977,1.0369976426370218 +2433,1071.5923461535117,1054.8015310116364,1.0159184592060382 +2434,753.2197522769802,726.258940004321,1.037122864570175 +2435,2601.855126584694,2404.0771957215456,1.0822677122078805 +2436,1556.064042721991,1450.5088841154575,1.0727711217507658 +2437,1932.022102089892,1835.6199164138877,1.0525175091063177 +2438,410.98866645478626,396.112058893142,1.037556563168549 +2439,2327.774669232547,2240.028186167157,1.0391720441766092 +2440,747.4657592475783,720.0982894351978,1.0380051865334188 +2441,762.5471797577286,734.6440107449524,1.037981891371416 +2442,365.20316880297224,352.27110304615576,1.036710549474511 +2443,4236.2970751015555,4070.8744738697246,1.0406356428560133 +2444,699.2029664501557,665.265186470162,1.0510139124520623 +2445,586.4147987876539,565.0722296852741,1.0377696301130688 +2446,2490.4075938761553,2387.0914626571866,1.0432811783022182 +2447,225.82600577981196,218.65978581119964,1.0327733787080535 +2448,3168.8299439279654,3047.2834032356955,1.0398868515357673 +2449,3587.4006953588027,3452.055235314159,1.0392072115938569 +2450,2090.4812589504245,2010.6462019859252,1.0397061685370832 +2451,1280.8958824836893,1231.325844755546,1.040257449268422 +2452,4233.737242513008,4068.469882828854,1.0406215025412062 +2453,1040.2586927851728,997.1451399663322,1.0432369883689112 +2454,5330.940793726476,5057.669366059029,1.0540310977030873 +2455,1531.4214487312997,1463.7679414761649,1.0462187381880412 +2456,919.8373087299151,878.3389356631211,1.0472464231993357 +2457,2117.2169050406446,2017.2028353915418,1.0495805716184659 +2458,5141.130398985293,4917.564885383697,1.0454626464138972 +2459,2031.6274197066577,1910.4414777466686,1.0634334751268726 +2460,2183.943872628788,2102.836187309599,1.0385706151571223 +2461,1324.0691133611992,1275.4587362172533,1.0381120735337266 +2462,1038.7605891231158,1001.2478945804057,1.037465940997989 +2463,1762.306303819247,1699.8872548909478,1.0367195228675936 +2464,2056.5598790906492,1984.7832192826706,1.036163475744177 +2465,2049.7378507014755,1978.1835584054938,1.036171715204052 +2466,1336.647273563479,1290.4132240514439,1.0358288714423405 +2467,2113.5264913523747,2038.3178121556077,1.0368974252926881 +2468,761.0899455240992,715.1877551214769,1.0641820138472948 +2469,564.2192121286138,543.5234504587881,1.0380770354109954 +2470,211.02217623629892,193.02479340768906,1.0932387104831525 +2471,289.33842385271464,270.8439645806165,1.0682845538047545 +2472,293.66526068315625,274.9009496440267,1.0682584438628813 +2473,216.66744207446837,200.6783069199179,1.0796754537147408 +2474,3281.3651239065675,3159.2213810528947,1.038662609586722 +2475,719.9364486494812,687.812517066745,1.0467044881935739 +2476,815.7169135114433,744.0990375312904,1.0962477739761103 +2477,157.68805405447432,129.5895036890077,1.2168273630625075 +2478,527.1952327825037,447.8534176412343,1.1771602314863396 +2479,41.43609909826653,41.39554476631483,1.0009796786630214 +2480,58.087330226661365,58.087330226661365,1.0 +2481,525.9550205292248,492.20701394611086,1.068564660045273 +2482,177.7567136225389,162.7258443951097,1.092369280880382 +2483,252.85907894376587,242.00189031000704,1.0448640653998638 +2484,133.03367673658107,112.96913669032187,1.1776108115375032 +2485,132.88310653863024,112.84148664409668,1.1776086126704894 +2486,899.4145879106654,870.8635665259842,1.0327847236721315 +2487,62.510949746475674,62.230414675987234,1.0045080058030964 +2488,219.53474842864114,209.89817405547998,1.0459107108316914 +2489,219.33016933079864,209.69420304755053,1.0459524686100314 +2490,225.58428438432497,215.72502787729738,1.0457028866981324 +2491,223.7419233300037,213.96105482353227,1.0457133122405773 +2492,185.50521991430745,168.14748315798795,1.103229239179337 +2493,176.89770682019736,161.98786473847534,1.0920429570807266 +2494,199.15659047458414,180.25530729760214,1.1048584003453275 +2495,259.3310064312481,249.11034893934735,1.0410286346409048 +2496,319.85210734169095,309.9198809835194,1.0320477225489761 +2497,317.76185668040785,303.238265560975,1.0478949815009824 +2498,108.61768092252781,105.03821548192639,1.0340777442207911 +2499,111.90524683078121,107.92670088805436,1.0368634073865888 +2500,1510.1445422121606,1441.5560838264014,1.0475794588606646 +2501,399.4016184856045,375.06760157579805,1.0648790159629098 +2502,440.07786209015643,413.51517885534065,1.064236295529331 +2503,397.3161794093664,373.1008009731294,1.0649030459679472 +2504,438.5855009908618,412.10744652473466,1.0642503664746032 +2505,1320.9636620183305,1229.4903312465383,1.0743993900944715 +2506,1028.2254424869536,980.0128455307248,1.0491958826622516 +2507,965.2690487236382,914.0841777139278,1.0559957958551704 +2508,193.46440531904986,181.25920456949112,1.0673356190575112 +2509,193.40010528280564,181.20910453933587,1.0672758732209475 +2510,348.0107218738492,326.57881464889095,1.0656255282449965 +2511,330.1263202423597,309.7632771196642,1.0657374344436221 +2512,423.3334074878323,396.5333451991741,1.067585898167522 +2513,441.12460781618506,428.1359634579038,1.0303376624878147 +2514,312.2264951686599,293.0454813202147,1.0654540508935055 +2515,194.55532667203096,182.31504466713054,1.0671380797303296 +2516,265.8974382547266,243.54438281092396,1.091782266483873 +2517,157.79189164877465,131.41305021433644,1.2007322818503487 +2518,286.4326740281197,262.43115865363006,1.0914583294820113 +2519,181.4359197504533,162.697832087952,1.115171096148176 +2520,241.3628102721945,226.9304925373291,1.0635979659388055 +2521,95.14421261361093,92.1385319302408,1.0326213216165172 +2522,420.5171850719012,390.7565762106686,1.0761615048167168 +2523,193.74942064742783,181.50627003238006,1.0674530450813828 +2524,58.051571655240444,54.63222314971649,1.062588492804941 +2525,524.8528016228915,499.8270868656935,1.0500687446015158 +2526,359.8344131707332,343.36373893378106,1.0479685894850084 +2527,581.3754166069841,549.7633775520615,1.0575011729513195 +2528,509.5813204779952,477.7648705480624,1.0665943686764474 +2529,1355.3981379507022,1251.667131390117,1.0828742754037013 +2530,1725.9518328261613,1613.0825093313545,1.069971202862768 +2531,1864.297491562841,1723.9454130341376,1.081413296191139 +2532,2001.7761626219037,1898.7985318168796,1.0542330474136659 +2533,484.1157441928308,466.35211501501846,1.038090594222437 +2534,584.2541087378329,550.3866233756913,1.0615339906962524 +2535,296.2182886541353,289.3811987657814,1.0236265863764276 +2536,585.0125976119285,551.1011448895975,1.061533990696253 +2537,876.5281437200307,809.7479896760543,1.0824702930978467 +2538,2009.8613457940037,1927.2464622476487,1.0428667973529475 +2539,1982.1585654918397,1903.2223941454313,1.04147501184792 +2540,118.79839761337549,112.10900178664342,1.059668677092164 +2541,1529.295376627289,1469.5479132004252,1.0406570366914707 +2542,1929.3950978211924,1857.8589669426617,1.0385046078046776 +2543,181.76459704254032,172.3856126446134,1.0544070021508258 +2544,946.7502324864729,904.0024486864802,1.0472872433720788 +2545,953.6124449821929,910.5464453242425,1.047296873080005 +2546,790.1186144905026,768.1705501207725,1.0285718638475263 +2547,945.2562608427485,902.559969274567,1.0473057669536336 +2548,938.407961782168,895.9999734394681,1.0473303455355123 +2549,642.9470077785418,618.8194168674238,1.0389897121089966 +2550,372.8806268887395,365.0163526499206,1.0215449915646968 +2551,135.9225850182541,134.36438295633272,1.0115968385939582 +2552,147.19471911030988,143.86874165895577,1.023118138193204 +2553,145.79623430724084,140.8706003341171,1.034965663250111 +2554,156.0352473371785,147.59586403407323,1.057178995890813 +2555,133.14702224305645,131.8340061824454,1.009959615873267 +2556,134.87223140533945,132.97675077740575,1.0142542257714404 +2557,219.06476384196066,209.96422699206101,1.0433432731864545 +2558,535.7022281181135,502.8376674546303,1.065358191700005 +2559,811.175809567744,787.125446552482,1.0305546760311202 +2560,649.4101578632542,630.2305068577965,1.0304327556294974 +2561,323.9122994586152,310.40343340598423,1.043520349966498 +2562,82.11394067020508,77.7564791959607,1.0560398505603987 +2563,179.1713303675093,163.29853446712804,1.0972010921725477 +2564,178.57401388190704,163.03566508316098,1.095306439795368 +2565,400.56225221011806,379.47170172577194,1.0555787174338163 +2566,400.932506496668,378.431235767001,1.0594593379271708 +2567,2587.2790283433437,2502.185883632411,1.0340075232889587 +2568,1171.9100436101637,1137.3650291775443,1.030372847367744 +2569,348.09295364304427,335.5461204023703,1.0373922762856813 +2570,2901.626699070897,2748.9853076194277,1.0555264486239302 +2571,2170.8249195555304,2069.0182163222753,1.0492053199097584 +2572,3671.7308235541623,3548.7399530193948,1.0346576171156532 +2573,1307.622843621802,1268.8110103409551,1.0305891365731588 +2574,690.8291730876125,675.0754720355028,1.0233362071423049 +2575,885.8767689842292,821.3879723402489,1.078511980715085 +2576,393.7130120658356,380.078739721168,1.0358722309873736 +2577,428.5846117662641,402.92245069236816,1.06369007492583 +2578,3647.054232797955,3524.876228398734,1.0346616438372713 +2579,1449.231010327405,1381.5621539231497,1.0489799580946102 +2580,3609.454722722636,3508.5417194592574,1.0287620930096653 +2581,730.8645291793383,687.117779596423,1.0636670318858723 +2582,660.7554465145327,613.0813478350749,1.0777614566938065 +2583,571.9401622440861,535.8560429277497,1.0673392038637541 +2584,193.56028949167938,178.7582122281629,1.0828050195793155 +2585,411.79747264313824,384.4865289299053,1.0710322512189026 +2586,233.4697526215918,215.61942617812792,1.0827862626288474 +2587,826.1837493899001,774.4934803499607,1.0667407413379164 +2588,140.47576283908754,133.8208359696125,1.049730124769107 +2589,142.24857655572345,135.47334017524398,1.0500115843583337 +2590,139.29694823787256,132.70086762389647,1.0497063864922935 +2591,139.5262113803358,132.91969505147068,1.0497030656465687 +2592,302.27656153170955,293.5006421752349,1.0299008523164832 +2593,304.2639709935201,295.4246269487893,1.0299208097037322 +2594,283.70241490816187,272.71342544864353,1.0402950072642747 +2595,288.91523834793514,278.2079250921445,1.0384867298523013 +2596,239.15154589522248,220.508371436306,1.0845463341708166 +2597,238.5514637589618,219.95414337315935,1.0845508982035927 +2598,238.59611636113905,219.99611150350106,1.0845469709919942 +2599,233.65444639816428,215.3308596046145,1.0850950338803975 +2600,119.16622434725087,113.52593950494546,1.0496827849820147 +2601,119.13218185760792,113.49710148785101,1.0496495531241394 +2602,138.90003837668232,132.32297497522606,1.0497046216100239 +2603,139.5023795779549,132.89699167643,1.0497030656465673 +2604,139.45988501946402,132.85650922012243,1.0497030656465678 +2605,140.16634999034406,133.52952332668303,1.0497030656465678 +2606,138.75637038964226,132.1668693808172,1.049857434315392 +2607,139.98354395224467,133.26774747300766,1.050393261734969 +2608,204.13373341186013,187.17389320450144,1.0906100734295718 +2609,208.76313620542692,191.37141590994227,1.0908794043916623 +2610,219.04029665801642,203.23762472624784,1.0777546576479333 +2611,204.0879079580885,187.12405490584393,1.090655651197706 +2612,218.64690239505876,201.02353708795158,1.0876681684264495 +2613,206.21494904348512,189.07362671480675,1.0906595098772494 +2614,202.93208435273712,186.0642071292434,1.0906562174624859 +2615,206.852109430309,189.71672799071084,1.0903208779799174 +2616,299.455648074907,288.7519970597863,1.037068664889284 +2617,298.14019847427124,287.5031646378912,1.0369979713085153 +2618,351.70388080201246,339.1399102412189,1.0370465704017473 +2619,353.0965888137239,340.49089501105834,1.0370221171472327 +2620,164.95407851121993,156.61180905050782,1.0532671802419555 +2621,165.4600814447687,157.08325036185545,1.0533273347961445 +2622,1350.4346708374694,1288.3302818780767,1.048205331996745 +2623,178.3768618432078,169.42838205032902,1.0528157070532647 +2624,670.4112780835925,648.4374803921175,1.033887303488668 +2625,589.4805868617948,534.2453182711631,1.1033893357631566 +2626,585.7930266756363,530.9571624859972,1.1032773791634938 +2627,1217.9280222025723,1181.9276201523771,1.0304590580982902 +2628,1287.1000000565737,1241.902019987128,1.036394159395855 +2629,718.2941552153908,686.7089045989361,1.0459951085604484 +2630,895.5598716068139,859.3757903322603,1.042105074033519 +2631,715.0973555885449,683.6573326735033,1.0459879846415054 +2632,714.4178563735625,683.0001273646121,1.0459995946562661 +2633,702.935939283337,671.9789836936883,1.0460683389523384 +2634,714.8051781063338,683.3701694890399,1.0459999719343882 +2635,725.2892468967077,693.7224169442125,1.0455035460603168 +2636,178.68755222816142,158.5791687452452,1.1268034360504184 +2637,172.57996072424206,158.49128685438095,1.0888924189429134 +2638,92.82545261305543,85.10946979548427,1.0906595098772494 +2639,640.1892772647508,592.9360353155353,1.079693658564822 +2640,93.04234297755626,85.30833145903428,1.0906595098772494 +2641,577.1215863051513,535.7117674203133,1.0772986919519134 +2642,94.16312773120478,86.37882032254186,1.0901182417124478 +2643,1194.7289749242616,1149.6563006807817,1.039205347038754 +2644,1228.7451543830616,1161.6726641152097,1.0577378570915568 +2645,300.19068088634987,289.48078554768915,1.0369969126565617 +2646,361.36362461186417,348.0950058508092,1.0381178084661802 +2647,369.8259237651282,355.18845605053673,1.0412104263673165 +2648,359.62367097257504,346.92079446820304,1.036616071180871 +2649,746.2668824854825,717.4607458974705,1.040150122153343 +2650,504.0243115665785,484.0669751184011,1.0412284610890794 +2651,507.5655019357732,487.47029538747915,1.0412234483586755 +2652,272.21593217292633,255.55990267366218,1.0651746589547466 +2653,454.64756010603463,441.04165933853284,1.0308494684785734 +2654,377.76159072780337,373.11016816789873,1.0124666196655663 +2655,251.46798428542724,240.72790207218324,1.044615028506432 +2656,237.237366764949,216.1716289566912,1.097449132940929 +2657,1435.0492249089186,1354.975783933851,1.0590958465269344 +2658,1409.2552623282468,1316.0798864261747,1.0707976596732973 +2659,410.8333619226353,382.1356323071156,1.0750982823618391 +2660,237.49453010109335,216.47043237817093,1.0971222604951127 +2661,1628.3570874210948,1548.3794722168598,1.0516524641661187 +2662,2011.924878019477,1939.737461149753,1.037215044981879 +2663,417.7119935012011,387.05989893162047,1.0791921215661655 +2664,1713.6669256140585,1604.2576948997494,1.0681992868490784 +2665,426.2744357613504,399.06192301228486,1.068191203369277 +2666,385.0324058348587,361.5117680061674,1.0650618870816124 +2667,428.9393322774424,401.92118031411337,1.067222513484394 +2668,429.7459220544671,402.3516154758179,1.0680854892212945 +2669,692.1708328447871,662.7938367009733,1.0443229772473994 +2670,210.71826098970325,206.48541152733966,1.0204995085660236 +2671,1726.1775367097937,1615.9959834428128,1.068181823714836 +2672,1589.7435653143216,1494.5463187713206,1.0636964176669101 +2673,607.1030522319738,585.8528776891152,1.0362722030600575 +2674,295.91223027033465,292.78034793527337,1.010697037410973 +2675,2498.4944212782516,2425.194836026344,1.0302242047373018 +2676,3068.2753897007465,2938.5673257389535,1.0441398986593495 +2677,721.6013949885607,692.8881532813688,1.0414399374144474 +2678,400.85880077150665,398.74061528225246,1.0053121889470797 +2679,549.484051306304,498.79326632096337,1.10162684303906 +2680,1888.8599813750075,1812.9248192106247,1.0418854446470902 +2681,476.74645809932224,434.9831964555715,1.0960112068329435 +2682,212.90622831210652,204.29248532207134,1.042163777960092 +2683,184.12394760655175,181.44273398341042,1.0147771892777282 +2684,202.44300554756296,200.4493508826212,1.0099459272687255 +2685,194.21114166334198,192.31570094081675,1.009855881310016 +2686,1234.0595788393919,1181.0195608724484,1.0449103636588046 +2687,833.1876532072602,790.1776685374874,1.054430777257194 +2688,2022.535678393758,1939.0787631487851,1.0430394663852904 +2689,836.9107523292288,793.9989960927963,1.0540451013761953 +2690,1963.618285022351,1862.9217367057192,1.054053021301205 +2691,727.6372400213368,691.2129293796336,1.0526962229632975 +2692,1676.0115723809363,1582.7913525086906,1.058896088688186 +2693,2381.5210421470906,2251.3549539307273,1.0578167773984735 +2694,1878.4459631257057,1799.792883602223,1.0437011837529113 +2695,743.152092255103,730.7748808267336,1.01693710573955 +2696,794.8514569037604,765.959981562754,1.0377193013165784 +2697,1139.9608373010944,1100.8374523467658,1.0355396565323294 +2698,1241.3449676434648,1184.7420884715425,1.0477765411752584 +2699,1093.5490573342515,1055.8585246471362,1.035696574689977 +2700,1770.8016639074078,1684.6750642090867,1.051123567700431 +2701,1172.2135742074438,1127.7919942529481,1.039388096546935 +2702,622.3663185267226,609.9204940489552,1.0204056505711847 +2703,888.0445296861676,828.7076709018614,1.0716016767646561 +2704,2675.412588504647,2526.6739771046146,1.0588673539791138 +2705,985.9924856113327,918.7790488946004,1.0731551691319017 +2706,1078.358721101172,1038.7691203743545,1.0381120308163858 +2707,2018.3014283018583,1941.6584244554804,1.0394729592399197 +2708,536.7466809235596,513.8839990432589,1.0444899664571499 +2709,945.4695623772325,917.1855784708987,1.0308377983368293 +2710,1630.6317071353526,1584.4746613291836,1.0291308197806388 +2711,735.1633417475315,705.0481979941233,1.042713595806764 +2712,1695.7536504775546,1642.5838884684774,1.0323695869552525 +2713,1322.145327446136,1268.5096485767665,1.0422824366606491 +2714,640.4098636638894,609.783366803005,1.05022520870232 +2715,1019.6773687072649,984.3230691689947,1.0359173737217373 +2716,871.0170024061432,833.822629109026,1.0446070567032475 +2717,2011.7349155944503,1921.2188119818736,1.0471138961621986 +2718,446.79394261135445,437.5760506738165,1.0210658054144952 +2719,677.7761516299997,648.3777552699137,1.0453414635544487 +2720,3224.9142797263085,3097.7790909036225,1.0410407537438702 +2721,1331.1763262326665,1257.6608773751893,1.0584541112632113 +2722,2282.279444107512,2215.1793308127076,1.030291052449549 +2723,4501.34866406489,4344.44585325357,1.036115724792338 +2724,706.6149287222929,650.2478191880327,1.0866855802832927 +2725,1308.01904868787,1248.0985380634143,1.048009438996243 +2726,732.060998391494,706.3504154640387,1.0363991899269496 +2727,473.85030384038924,461.10198401605805,1.0276475059016168 +2728,468.5381944095977,456.0982021885486,1.0272748109099243 +2729,971.5280686342599,933.6530344737075,1.04056649821944 +2730,65.76335035064113,63.98618897635856,1.0277741400560547 +2731,994.4650078930396,968.0513997267583,1.0272853364746302 +2732,1869.0206266471737,1819.2033415779508,1.0273841213517187 +2733,1451.9241548027128,1403.3992507766443,1.0345766922700113 +2734,999.8702776114972,970.159703245414,1.0306244160283036 +2735,963.1638162730686,934.4819135069795,1.030692838835639 +2736,816.5388082033808,792.2368676083826,1.0306750942661396 +2737,228.38773129458826,224.23940450895577,1.0184995442469917 +2738,49.05102739724872,48.18781595338143,1.0179134793056899 +2739,230.14599488603005,225.98036845586347,1.0184335765917656 +2740,1664.2855777712257,1604.9706881340765,1.0369569924707522 +2741,771.4459915598871,733.2230522955554,1.0521300293882803 +2742,35.26221502281803,34.79867892545876,1.013320508469652 +2743,795.3417298585042,750.4831379342737,1.0597729511254643 +2744,18.894468315092478,18.891259201429808,1.0001698729358617 +2745,1878.4803836684544,1775.858143536926,1.0577874085861039 +2746,33.16124129625454,33.0299865133547,1.0039738067360933 +2747,169.65390438671272,161.67416374705638,1.0493569315882831 +2748,1847.0916627684283,1742.3768890214308,1.0600988077876816 +2749,804.0302507930134,761.2938856334301,1.0561364881106652 +2750,790.940371372459,765.0328317789485,1.0338646114484618 +2751,1288.1313393409218,1274.0236776632987,1.011073311999584 +2752,508.2682824790116,485.53727041570363,1.0468162043334928 +2753,1115.1514859796425,1082.2107744939135,1.0304383510699506 +2754,5593.762794948765,5250.314276076662,1.0654148496285345 +2755,1151.5699812648008,1080.838248070282,1.0654415527215129 +2756,1446.0206773595432,1356.8981956462744,1.0656810378252592 +2757,1486.5486778875702,1391.8309353673108,1.0680526205542795 +2758,2234.838615913996,2128.1089273030666,1.0501523616773634 +2759,3726.066603078549,3516.5063669237234,1.0595933049136355 +2760,1681.794053252545,1573.4269294292183,1.0688733120022538 +2761,1276.508806815966,1198.2280535686962,1.0653304293904031 +2762,914.5107565641165,848.2114658773856,1.0781636341335603 +2763,686.617542697342,633.9858212167471,1.0830171901629975 +2764,3698.4969988529524,3533.170784918629,1.0467925905648319 +2765,3491.7776543924037,3302.0127518907307,1.057469463857465 +2766,1053.3055563328846,997.1428408162425,1.0563236411251455 +2767,1377.367816780722,1306.1263986761217,1.0545440457958817 +2768,497.5848054615402,465.9738119043519,1.067838562489166 +2769,1389.1109359243758,1338.8753148297885,1.0375207612973085 +2770,1127.4026837955867,1080.3628168417713,1.0435408052003559 +2771,2290.0910711858996,2184.0469703947365,1.0485539469748661 +2772,633.1184001142102,610.1640118960765,1.037620029648755 +2773,210.88607826964997,195.28344411341936,1.0798973729036072 +2774,619.2371880507737,601.3229750168263,1.0297913330742872 +2775,637.9322919960811,576.3534212371818,1.1068422056499916 +2776,163.05716752644258,157.70600742999494,1.033931238154152 +2777,181.72595859410046,163.29198905204527,1.1128896135632216 +2778,201.79489707349924,194.14462032985642,1.039405041101035 +2779,122.59936369117392,119.06543899256648,1.029680524663652 +2780,579.1656624243741,558.4421042953264,1.0371095910742578 +2781,271.17581730028076,259.8225503033628,1.0436962341554348 +2782,291.04456392018625,282.7291799061351,1.0294111276975793 +2783,319.9367165555409,313.4767975511789,1.0206073274156993 +2784,281.54999618818636,268.29334186900627,1.0494110447424096 +2785,742.9954642660638,713.021557323278,1.0420378691708978 +2786,1798.2608809235378,1721.6002586052148,1.044528700512877 +2787,1086.582531399281,1035.1428554894424,1.0496933110604494 +2788,150.5176781600955,139.3679720238224,1.0800019256530995 +2789,263.43293590007175,246.04044899130025,1.0706895430408945 +2790,766.89270790939,729.7478508484039,1.0509009475229032 +2791,1064.3674714442818,1004.65860165211,1.0594319997798094 +2792,536.8850947180632,489.3174404595821,1.0972122600285903 +2793,1070.7804491710096,1019.8250707661206,1.049964822267617 +2794,448.3926236171512,417.2339491047111,1.074679144828218 +2795,557.2712812334146,532.2765587063572,1.0469581500786067 +2796,432.303153942216,403.99024455546044,1.0700831511857676 +2797,200.65367195662404,185.88016052074988,1.079478688820182 +2798,1662.344439588141,1595.2345995187284,1.0420689471565243 +2799,456.26988524163926,432.16249361871616,1.0557831648486191 +2800,227.8268778215136,218.72835524262277,1.0415973620283403 +2801,245.67484490998746,232.72299177994094,1.055653517647683 +2802,108.41176485816906,105.24306932010279,1.0301083535337467 +2803,146.89528608929675,143.8949906148819,1.0208505901532374 +2804,147.70901914703444,144.7378217154402,1.0205281342249004 +2805,139.9264253792785,136.9252608217043,1.021918267962857 +2806,235.2504193168673,225.5082069201955,1.043201143451597 +2807,253.2587781887849,245.02173693967666,1.03361759389999 +2808,4767.318042758431,4553.690054669384,1.0469131595528756 +2809,892.9469707370314,835.7915915772146,1.0683847262114223 +2810,1040.919910010833,986.7147641703436,1.0549349698705142 +2811,814.8478477851044,772.8609668373733,1.0543265642196238 +2812,1116.5908913736394,1048.8673686879495,1.064568242570466 +2813,1407.1922412077806,1353.3658421672098,1.039772245880224 +2814,256.247805462737,244.96743259479825,1.0460484593745882 +2815,384.3482899821688,365.42348738523583,1.0517886869624833 +2816,226.68387346051574,211.38755497432854,1.072361490192953 +2817,222.3137223500933,206.70395378959887,1.075517513208206 +2818,485.7535578980502,460.9147088947928,1.0538903370274673 +2819,485.5738320711522,460.7352544977013,1.053910737958462 +2820,645.7137167775145,613.200452172778,1.0530222449926951 +2821,201.5212140711063,193.31724946088522,1.042437830214841 +2822,214.20902540609023,205.6071166577093,1.0418366294329258 +2823,197.0900910728475,189.07293097465066,1.0424024743090894 +2824,799.2783009189569,766.7655446124334,1.0424024743090894 +2825,798.6937391120359,766.1147057135315,1.0425250072287302 +2826,309.90487000783844,295.10916146975524,1.0501363917826034 +2827,299.33730523776745,284.85438645400404,1.0508432359566349 +2828,226.32075190305076,215.49889007329043,1.0502177149315242 +2829,196.80067685849156,187.29201311046785,1.0507691897273557 +2830,14.033633367572932,11.692157740902706,1.2002603521571589 +2831,9.152064904010976,7.814239896423178,1.1712034728035623 +2832,40.762044469177994,33.01916250495539,1.2344966188364281 +2833,40.67674584376099,32.914648898205144,1.2358249960241598 +2834,41.28568243656466,41.267829103010946,1.0004326210983658 +2835,39.921071950232644,39.906428791421504,1.0003669373395367 +2836,24.27177779853686,24.27126846110429,1.0000209852003978 +2837,33.43537378100923,33.43165425719189,1.0001112575461786 +2838,351.1805077795214,343.43914365759673,1.0225407157713002 +2839,372.3429227363838,363.2907662388844,1.0249171114124798 +2840,1894.8689548108255,1841.1563246253947,1.029173313241807 +2841,453.7342782289698,444.74441216993483,1.020213555950423 +2842,308.79972276241,296.18574574482886,1.042588062385853 +2843,1315.0876779580226,1280.6834456548877,1.026863962691063 +2844,557.0659076625891,546.7649348328641,1.0188398563504695 +2845,199.79210023198496,183.70788887893218,1.0875531881140534 +2846,268.39293334177944,252.12557528129395,1.0645208564911994 +2847,1158.4103515186262,1132.763390341381,1.0226410576082583 +2848,716.7722540076516,701.3894099937519,1.0219319593291787 +2849,230.63897141922322,229.53475252433734,1.0048106828388386 +2850,1497.00193849071,1450.426920714686,1.0321112474615919 +2851,1906.257949187485,1840.9214455541148,1.0354911958851694 +2852,1475.6382352255573,1422.0073502391344,1.0377149140455595 +2853,927.5247447036395,912.9458945784615,1.0159690187685322 +2854,1047.0278262815427,993.4820652992466,1.0538970584900973 +2855,852.7029930606185,799.9502926844685,1.0659449729046573 +2856,83.66282067054166,81.37330386138134,1.0281359696671588 +2857,83.14149380273345,80.74822834314092,1.0296386126197383 +2858,82.89035609439931,80.51745349017125,1.0294706613457134 +2859,104.4936994400388,101.74168626631648,1.0270490226249909 +2860,101.97323721031748,99.25326240880823,1.0274043868735128 +2861,103.34592614528341,100.57730778644164,1.0275272665353148 +2862,99.61652799291089,97.05514212983987,1.0263910371657012 +2863,118.67715778962146,115.62269233489799,1.026417525773196 +2864,114.9517400502958,111.99243504744106,1.0264241508955596 +2865,40.35217354572218,32.699939246285034,1.2340137161051912 +2866,40.81026923701335,33.09777016741679,1.233021712054462 +2867,40.34741373393045,32.64752561676814,1.2358490566037739 +2868,40.40511147850427,32.69465455797852,1.2358323409367284 +2869,1797.5053401383218,1741.3183475956662,1.0322669273084017 +2870,830.492597730984,801.5901463051781,1.0360563956019517 +2871,1719.693876439968,1628.4244254474693,1.0560477044965837 +2872,813.114284172682,757.971665828927,1.0727502370203381 +2873,731.4368429273213,708.0494062331112,1.033030797693389 +2874,1712.428402613802,1621.4695706497537,1.0560965395900703 +2875,1647.354498401027,1558.7299784844647,1.056856877804282 +2876,1199.3440455456598,1141.8474997961869,1.0503539621181774 +2877,1725.0401483546314,1633.5309981860241,1.056019230899337 +2878,2039.027671237546,1983.5098451907704,1.0279896901854984 +2879,2144.2626964598467,2061.096399969288,1.0403505127134267 +2880,1220.658154350825,1159.4314412494418,1.0528075321429986 +2881,948.6274526751964,909.8227138269444,1.0426508794059772 +2882,1849.1245502272184,1783.5208321464718,1.0367832642592643 +2883,611.0472984193922,567.6202931875889,1.076507139989534 +2884,45.9296776804884,43.95975358946712,1.044811991200362 +2885,43.885862760427905,42.00233792802699,1.0448433331408462 +2886,41.83711249340922,40.00136027614291,1.0458922447785148 +2887,41.28516170564084,39.50055355704585,1.0451793199813693 +2888,41.204921731977734,39.423782067092766,1.0451793199813697 +2889,41.48818431186682,39.694569396908044,1.0451853979576986 +2890,41.33966824685871,39.552703977720874,1.0451793199813695 +2891,41.08646502927484,39.31044581900761,1.0451793199813695 +2892,41.132567780779176,39.35445567846001,1.045181976771499 +2893,244.57503515937884,234.48794874056026,1.043017504622291 +2894,243.7724309921334,233.718971238804,1.0430151634676554 +2895,244.7132192275619,234.61902935316735,1.0430237474863984 +2896,244.2613000425117,234.18782549393757,1.043014509944433 +2897,595.6137151300213,569.1232064553167,1.046546175545531 +2898,531.6243584488548,501.5537901489125,1.0599548221757316 +2899,367.0088170037165,363.4079804119794,1.0099085237139125 +2900,604.0125707413861,577.2115073239028,1.0464319631147683 +2901,563.3444286631484,535.2032129888872,1.0525804311171905 +2902,544.6128238912405,515.4519479645338,1.0565734129861377 +2903,604.189112791656,577.3802416228372,1.0464319165017968 +2904,603.9159061346946,577.1191283393018,1.0464319695528068 +2905,606.4242352276103,579.5166330899277,1.0464311127606707 +2906,64.67512294264046,62.367655880228654,1.0369978160930575 +2907,62.404641931434234,60.19032381937561,1.036788606067373 +2908,61.40114798985884,59.237589557816065,1.0365234042808433 +2909,61.576144053614584,59.400671418187414,1.0366237044714797 +2910,747.1077731167031,733.2260257457208,1.0189324258599033 +2911,767.0364450377313,724.6643800417231,1.0584712953513302 +2912,370.6879893560238,352.16554949282585,1.0525958313920065 +2913,61.65801904777842,60.06928231811511,1.0264484053804683 +2914,292.3334006979143,271.1065701509054,1.0782969978750183 +2915,398.26143025137407,360.860454549752,1.1036438746060095 +2916,172.3281555553511,153.21848551590827,1.1247217003555274 +2917,57.997008304934035,53.27329497933786,1.0886694417424017 +2918,268.6474622773832,248.41939075000064,1.0814271038436742 +2919,101.98638966314775,86.53942299312264,1.1784962984009344 +2920,41.509067459177835,30.63241284790061,1.3550701234435294 +2921,213.38244196048748,189.2173824728182,1.1277105685104838 +2922,211.34235988337247,187.3531761521986,1.1280425783210952 +2923,102.8788300972546,91.2466762527933,1.1274803019918789 +2924,213.07963239751757,188.97652033145704,1.127545538587464 +2925,212.71948103079234,188.657106275408,1.1275455519828512 +2926,99.84728343279305,88.55277133345619,1.127545551982851 +2927,102.34617286219225,100.91470410451191,1.0141849373724352 +2928,101.2827732479599,99.86623096477166,1.0141843971631204 +2929,202.92070186787163,199.17324834174573,1.0188150444767359 +2930,164.60884785591034,159.20197217516144,1.0339623662123985 +2931,113.2872111714894,111.07897189215778,1.0198799038352238 +2932,191.4814660894022,183.61121748583255,1.0428636589383593 +2933,264.19460529514174,253.04962044023495,1.0440426855235652 +2934,473.53207696153254,451.9955741183465,1.0476475967385184 +2935,697.7262317800852,665.5894441744122,1.0482831990305 +2936,725.4445886540901,694.3865717278334,1.0447272717975744 +2937,155.4969897544091,146.93252582396102,1.058288414239262 +2938,172.90888698008598,163.30746682512142,1.0587935159464954 +2939,3192.488912336507,3131.7160600361576,1.0194056073843578 +2940,638.9128476124188,616.1646500375402,1.0369190241171617 +2941,254.5489882326123,245.28059320722542,1.0377869072485342 +2942,289.61342656184195,280.4193027954938,1.0327870573626428 +2943,291.7239588454594,282.54307353900424,1.0324937546387516 +2944,288.93369244791853,279.7601032212319,1.0327909130753796 +2945,777.5927513015589,752.49583235474,1.0333515720190565 +2946,209.5987321434356,203.04073867725666,1.0322989046873159 +2947,875.4989754720738,847.6600951030755,1.0328420324724772 +2948,195.77686228895197,189.46202313052558,1.0333303690844466 +2949,3344.6635184055,3235.9725756146568,1.033588338668228 +2950,197.71403736324447,191.3336382817663,1.033346980378234 +2951,480.656015300986,445.29899733982404,1.0794006233393327 +2952,477.7179565553523,442.5765214272948,1.0794019416455432 +2953,485.70380703985563,449.9743918191164,1.07940321909497 +2954,1574.150146444033,1495.6448330670783,1.0524892752886834 +2955,1991.0753244167565,1847.205208017495,1.077885291669175 +2956,150.3295927133522,140.06000299481263,1.0733227866553732 +2957,454.04905524581255,434.61906975030416,1.044705782253575 +2958,4052.719956962972,3892.169945521943,1.041249486453115 +2959,63.28611503734042,60.3076884255443,1.049387179140074 +2960,261.66715677293456,253.968025417362,1.0303153569939367 +2961,446.5553931290881,434.3768091741121,1.0280369110361378 +2962,57.702246301668545,54.99238274128572,1.0492770712105985 +2963,51.56211920909296,49.05175019811451,1.0511779702220483 +2964,51.55146004391705,49.042841304091546,1.0511515783571905 +2965,264.7602933009549,246.97500526756002,1.0720125018891171 +2966,256.03464675875125,239.24005967740237,1.0701997278549218 +2967,116.22449724653536,110.56998776262239,1.0511396410394147 +2968,115.03046814243683,109.4311687310389,1.0511673180166792 +2969,59.71544103253567,50.57657784109307,1.1806935854805374 +2970,58.50324533172592,50.947089347543084,1.1483137914442454 +2971,59.538045097423485,50.380917199533556,1.181757864026634 +2972,58.74973648223329,51.40534186831309,1.1428722064087153 +2973,229.4567579330624,211.00778032877315,1.0874326888588834 +2974,214.84825946491569,199.28292987591732,1.0781066878065775 +2975,201.07578056896804,186.57913117779682,1.077697057005571 +2976,214.3671574688139,205.88413137103893,1.0412029137033736 +2977,2668.043289089789,2520.500048670279,1.058537289256292 +2978,220.65268120004623,198.71604362401484,1.1103918796689465 +2979,200.05356299264616,192.1376035744125,1.041199428279368 +2980,184.17080970540613,177.20836575353476,1.03928958953075 +2981,36.5046890241946,35.30453486449505,1.0339943342776206 +2982,38.294914451227804,37.03539056874873,1.0340086566696527 +2983,36.44497531506053,35.24678434579827,1.0339943342776203 +2984,38.32976120088161,37.06960466824989,1.0339943342776203 +2985,237.3312232053753,226.17327923016282,1.0493336083430869 +2986,2643.5156574436664,2382.741526152542,1.1094428952653548 +2987,411.11162669968655,383.23445163869883,1.0727418292947979 +2988,272.6784489849003,258.3741788194129,1.0553626149131765 +2989,758.4960560099449,680.718142672562,1.1142586166897503 +2990,310.85808857412763,280.8312845682706,1.1069211503697605 +2991,580.3524681989188,523.5984454597005,1.1083922674548627 +2992,2677.3738892258434,2554.1271428691207,1.0482539589702164 +2993,4759.742830505775,4507.845293302118,1.055879809712621 +2994,240.7433881331884,220.55837372167363,1.0915177876537419 +2995,1618.3896738251876,1536.1749428642406,1.0535191199041793 +2996,374.0816244421845,346.8506132789537,1.0785093354911566 +2997,148.02071149124328,136.7157347631662,1.0826896534452364 +2998,820.3400048038474,778.6367140820595,1.0535593685316422 +2999,158.69374275606614,151.71415684781323,1.0460048426150121 +3000,5339.707517183519,5066.292798399529,1.053967413583037 +3001,145.87936750823235,136.66891966231765,1.0673924098373788 +3002,268.42812630213655,254.3471001329633,1.0553614574800034 +3003,1146.1893322500912,1071.6531487038894,1.069552526054115 +3004,1581.0656667873386,1493.46631841684,1.0586550545467666 +3005,540.6015389197884,510.6288559896127,1.0586975894107822 +3006,61.293865457832574,56.54112316035751,1.0840581515155918 +3007,55.141473036139,50.865614394999184,1.0840618695359785 +3008,61.18604527527177,56.44146980417439,1.0840618695359787 +3009,61.16990842220746,56.426881223481836,1.0840561642941173 +3010,52.69268363445875,48.61424815012662,1.0838938302971886 +3011,57.5690509448574,53.111786939652866,1.083922312956049 +3012,57.05289141977005,52.64967054415992,1.0836324487902906 +3013,262.52345080834084,249.0880657506598,1.0539382929374466 +3014,150.51060880638408,143.85193804415366,1.0462883632487914 +3015,64.9092191058168,61.597085327720116,1.0537709497206704 +3016,65.97616270741916,62.60372392563006,1.0538696194142603 +3017,65.55771364711784,62.19294673250993,1.054102066092473 +3018,250.07961968454336,239.5137592131471,1.044113793320715 +3019,248.02155290445458,237.55055120508862,1.0440790461072256 +3020,250.16940981889596,239.57433375334384,1.044224587415363 +3021,219.89798998740378,210.51492880937872,1.0445719514102556 +3022,34.85205986677205,33.77481437998092,1.0318949343339587 +3023,22.312834968966506,21.922471990270008,1.0178065219501593 +3024,14.945375156842948,14.945375156842948,1.0 +3025,67.73440550341704,65.64079660603869,1.0318949343339587 +3026,54.29964562826592,52.62129294521043,1.0318949343339587 +3027,104.05332025411332,94.10847401428566,1.1056742906947787 +3028,435.9405582988626,422.4561433764823,1.0319190882504536 +3029,78.7012735831062,64.74938737004945,1.2154751848588201 +3030,655.4932136020641,624.8053517629015,1.0491158754523726 +3031,36.91946068136794,35.76603057809662,1.0322493182673083 +3032,18.87296029018184,18.66850159022995,1.010952068057722 +3033,15.020359875856467,15.020359875856467,1.0 +3034,568.2007123724782,547.4363413063392,1.0379302021064025 +3035,165.6219670889078,159.5677395042488,1.0379414260267679 +3036,35.63094055298104,34.48023761646747,1.033372825016844 +3037,2685.840870198098,2590.5399836273227,1.0367880392401174 +3038,684.3561550360344,665.2308428026053,1.028749888013091 +3039,94.39729657655707,91.41841512533816,1.0325851355783706 +3040,100.88472304396667,97.76641458351116,1.031895497791748 +3041,540.4281005790143,520.9706384496232,1.0373484812643097 +3042,82.1622089558824,79.45123804973977,1.0341211914714967 +3043,975.2225268853578,945.5451518842754,1.0313865233637352 +3044,78.16251691223597,70.78250159099255,1.1042632734837188 +3045,76.98712473822846,69.67155938014703,1.1050007409503455 +3046,65.68092426355224,63.51378876676682,1.0341207088864357 +3047,1040.5630255862613,1010.1896574492305,1.0300669957498128 +3048,183.59758162142361,179.50365528214726,1.0228069246436315 +3049,532.5914235920595,524.4996950305239,1.0154275181438661 +3050,4851.331572789168,4655.675736254846,1.0420252284777274 +3051,1537.246298763454,1469.04685091156,1.0464242837521318 +3052,994.8860247641477,941.1554542071897,1.057090006031171 +3053,3394.751885370797,3186.1083275503133,1.0654853935807331 +3054,1266.3582320365483,1190.1389442126176,1.0640423441267661 +3055,1129.842113699136,1059.9316254076916,1.0659575453884151 +3056,1359.8559002495183,1296.0970384655188,1.0491929692698667 +3057,864.8517584063865,820.9120425745755,1.0535254857438874 +3058,533.1609904718107,501.57278125479894,1.0629783162036557 +3059,600.428336126524,563.7700986739379,1.0650233801665094 +3060,238.04192800733327,223.98742936775906,1.062746818780167 +3061,297.11432183333136,279.55597916900075,1.0628079668212569 +3062,236.57811034524946,222.60893145615162,1.062752104319091 +3063,92.96004418805678,88.08583583199669,1.0553347573990957 +3064,107.70947881799633,102.35276749200628,1.0523357741783426 +3065,80.16375119665481,75.94296949212399,1.0555783074161798 +3066,108.59030719962699,103.19156189062954,1.0523177012740583 +3067,326.65036227119504,322.14893052345894,1.01397313888462 +3068,456.03355693065225,440.7535101613517,1.0346680092546667 +3069,1012.2766574484017,976.4240275897004,1.0367182994740547 +3070,141.00864534323208,137.4302183097066,1.0260381383187598 +3071,1008.8434431214381,973.1761870946315,1.0366503583829865 +3072,298.7305317141787,272.36612634890975,1.0967976661367036 +3073,377.19519353752383,354.8720820607878,1.0629046707396728 +3074,107.65631227980384,106.95036924846086,1.0066006600660067 +3075,107.79171766711265,107.04401348080728,1.0069850163684253 +3076,1610.9835562398775,1508.2777069750052,1.0680947870474455 +3077,491.3769817510922,446.1733098825937,1.1013141549869792 +3078,11.89317676067819,11.815188716345872,1.0066006600660067 +3079,11.824750706252651,11.747211357359191,1.0066006600660067 +3080,366.81182795557856,333.33923118037,1.1004160136107608 +3081,270.7397163711414,253.00189801167735,1.070109428027474 +3082,11.78892892461553,11.711624472650836,1.0066006600660067 +3083,11.613545910494322,11.537100008108903,1.006626093414436 +3084,11.950614780549119,11.87225009346355,1.0066006600660067 +3085,743.8851805737625,701.2790939484522,1.0607548221428116 +3086,494.7062087033889,462.6760085959628,1.0692281413177764 +3087,808.1949522827263,765.4778259582055,1.0558045248025945 +3088,125.18446448842593,120.58407488376648,1.0381508885737514 +3089,105.47525509692831,104.00124302517516,1.0141730235993078 +3090,381.93651974219836,358.5920705822155,1.0651002938299234 +3091,496.9404340561131,464.7582934280824,1.0692448980106486 +3092,316.9813709535229,270.05393133350015,1.1737706219950201 +3093,281.3710318634543,272.61730577573235,1.0321099427742242 +3094,275.83903256690104,268.4864047666151,1.0273854752782632 +3095,182.47835359262768,166.80221612287565,1.093980390873249 +3096,1667.5201635950825,1634.7954735633223,1.0200176049915475 +3097,467.6662246917788,448.9530514905198,1.0416818042312697 +3098,931.0653151405638,889.9617384866845,1.046185779541234 +3099,1496.604038570276,1451.5453203821407,1.0310418955270877 +3100,105.75093509400763,103.13479961630604,1.0253661759894277 +3101,659.1004006200483,622.2154923289511,1.0592799580624987 +3102,160.69233079999893,156.81928961997158,1.02469747943262 +3103,147.7640425481683,144.20995985187835,1.0246451957960494 +3104,149.38875087545009,145.7941207547671,1.0246555217869815 +3105,118.40559642142699,113.41101687235064,1.0440396328929664 +3106,257.0441257053044,247.05430086840258,1.0404357455093367 +3107,401.25825950569447,379.57717981887123,1.0571190283282286 +3108,112.29334883967135,106.7308916203172,1.052116656526603 +3109,3047.29295835836,2888.8408119404376,1.0548497327242792 +3110,723.6732623398342,698.9544073371743,1.0353654755491593 +3111,54.98691175137459,52.44704764080337,1.048427208485902 +3112,101.95575738955631,99.65307318032842,1.0231070064950334 +3113,445.3732870141932,426.8339126196642,1.0434346331123148 +3114,339.32795229225127,331.3150019827372,1.0241852927321762 +3115,119.94009822963982,112.43744519988792,1.0667273524083893 +3116,117.76359230861203,111.85713067445357,1.052803621892899 +3117,101.73454210829446,100.30091866038933,1.0142932235023616 +3118,106.49448436051357,105.18665735959497,1.0124333925399644 +3119,960.0332439328159,937.6637141752007,1.0238566656888202 +3120,976.8714902243138,934.7132170893368,1.0451028961227875 +3121,252.56918476754916,240.0583447408761,1.05211583059184 +3122,607.0865563117623,578.3262660912793,1.049730216154394 +3123,256.5329024819756,243.82528507517344,1.0521177178276826 +3124,249.83236210651856,237.45681255891182,1.0521170541044655 +3125,1126.8278191215209,1080.3689054200959,1.0430028238209612 +3126,729.8695609560716,707.4792691655575,1.031647982868703 +3127,1641.2682102336357,1602.469540253392,1.0242117987304198 +3128,514.9349320546822,495.2414210921002,1.039765476238143 +3129,68.64274874117625,64.31037917321393,1.0673665685642046 +3130,605.2618109248074,581.1295689061128,1.0415264397303339 +3131,212.24441468150573,204.82961183258666,1.0361998579335268 +3132,231.08434651095396,223.01005828412013,1.0362059374763581 +3133,162.61084105218353,156.51244258272664,1.0389643044912134 +3134,227.75465929256723,219.79249732115255,1.0362258132941666 +3135,579.0741557894811,567.6135647991237,1.0201908335196557 +3136,598.3342793044616,580.209608579551,1.0312381430036686 +3137,16.790970255408705,15.739623500813526,1.066796181912537 +3138,393.84757279663387,381.24396599602744,1.0330591640124156 +3139,64.98002092451594,60.878095622207915,1.0673793301249666 +3140,69.21266506780776,64.8462931191876,1.0673341796206417 +3141,135.39338219052777,125.06592801119336,1.08257608082043 +3142,34.556268750935494,31.822506215541924,1.0859065755813544 +3143,80.4001792692849,76.29672229184456,1.0537828736828838 +3144,35.046314050828535,34.12867221315502,1.0268877098980664 +3145,47.98167516565434,46.63366868196438,1.0289062928521278 +3146,49.63771978211743,46.79629623563001,1.060718983660164 +3147,49.22409527413379,46.40624008700756,1.0607214715487185 +3148,64.69908403822204,60.50984662359247,1.069232325784746 +3149,64.42019284111181,60.255828266139716,1.0691113987609433 +3150,83.54178749351867,77.62210337282846,1.0762628666767409 +3151,83.67670872889794,77.94965900894975,1.073471132430363 +3152,326.2815362886475,284.9176082989663,1.14517855964268 +3153,408.0347386965657,356.73031119582686,1.143818525901981 +3154,410.56985741196166,358.980921820911,1.1437094075344412 +3155,84.13275377063916,72.44142397391211,1.1613901157014441 +3156,104.5671671403641,89.93940897058776,1.1626401411483587 +3157,165.4670133316142,152.57524201105625,1.0844945166111797 +3158,93.2937639809725,80.28387832046211,1.1620485448968967 +3159,105.2977044376764,90.56775240331211,1.1626401411483587 +3160,173.07586162162136,160.3096708590223,1.0796345641170066 +3161,2430.682901843321,2337.36560696232,1.0399241327942177 +3162,292.8533103316772,269.61754491250053,1.0861804650981353 +3163,312.48288109471673,297.67564173241146,1.0497428653420553 +3164,57.69269643866974,54.64351398206396,1.0558013611204917 +3165,57.5402199057238,54.49907950310641,1.055801683814569 +3166,57.88403240054969,54.825830789316335,1.0557803058741664 +3167,57.22434020407832,54.20949668934041,1.0556146745286188 +3168,232.88501253426992,220.56615980467166,1.055851055032683 +3169,232.40926368834096,215.58801041321988,1.078024994260486 +3170,98.13556242061904,96.05599148670518,1.0216495702321877 +3171,117.23157979640828,114.75775982415112,1.021556886227545 +3172,115.53580028707135,113.0946574879795,1.0215849524045937 +3173,101.25849176748642,98.91572479345396,1.0236844746265004 +3174,57.7711020150771,53.57469162327944,1.0783282229845672 +3175,57.60453294665568,53.419855824987394,1.0783356124243018 +3176,56.535907710893206,52.430166005465125,1.0783087679905516 +3177,56.49923882631724,52.39910185810139,1.078248229889878 +3178,428.69999189148473,419.3929444595698,1.022191711984826 +3179,42.6753240964978,41.59443807076464,1.0259863115326682 +3180,42.56202329952249,41.48989503835439,1.0258407079646017 +3181,42.24782908833772,41.18361531213045,1.025840707964602 +3182,41.96993346578535,40.91271982085701,1.0258407079646017 +3183,161.72064438762126,157.57844542820422,1.0262865834737804 +3184,73.65490905742337,71.79955765604589,1.025840707964602 +3185,63.432664293285,61.8348090505625,1.025840707964602 +3186,394.10931047027674,383.1232297925835,1.0286750575882357 +3187,557.6671023342413,539.0001631851306,1.0346325296801426 +3188,268.7963856143114,258.4115018696055,1.0401873897623417 +3189,398.0676165759412,386.97239872137357,1.0286718584871382 +3190,1074.2382331404747,1025.6299776216322,1.0473935596457133 +3191,1645.6833817881286,1573.4361692193402,1.0459168372903451 +3192,392.74795747138006,381.7894571046063,1.0287029936601189 +3193,2348.320843916628,2241.0894169029734,1.0478479020983646 +3194,1043.3188760856256,1007.957734211095,1.035081968890498 +3195,77.80308510114918,69.34398967333328,1.121987434926446 +3196,79.203523569445,70.6816018189103,1.1205677507474756 +3197,78.04846265495263,69.56323601234861,1.1219786072214604 +3198,440.1735267355409,418.7205308222134,1.0512346406114879 +3199,208.8250928661199,200.27584182572983,1.0426873803772558 +3200,77.90282548271138,69.43318764407714,1.1219825579959057 +3201,4923.761014178907,4683.929660700902,1.0512030220031352 +3202,2456.924803810356,2351.7168482789393,1.0447366593509806 +3203,168.95075035616014,158.59886932100613,1.0652708375505608 +3204,523.8485270535492,506.957869158128,1.033317675734022 +3205,2223.1514658123447,2119.8166105129926,1.0487470731132469 +3206,8324.307254892286,8025.883234289881,1.0371827015034825 +3207,702.739287347706,654.6600752646794,1.073441491087704 +3208,4225.279375721608,4016.314740150862,1.0520289491960724 +3209,6550.802086791783,6332.478531437385,1.0344767936078327 +3210,258.5814815928225,232.50104881876763,1.1121733983849007 +3211,2206.569463218067,2066.007124442757,1.0680357473661775 +3212,4273.368663928568,4050.5436488886053,1.0550111378508664 +3213,3715.9466380296763,3550.099703050427,1.0467161344332796 +3214,5390.029042952019,5142.382303742693,1.0481579790419482 +3215,3331.472655834009,3144.8896351778126,1.0593289565933042 +3216,3701.987544304869,3540.4869375858884,1.0456153657861258 +3217,6178.944262944281,5932.623606605597,1.041519683814834 +3218,2306.753039438238,2233.429174255298,1.032830172556239 +3219,4252.031720233519,4036.433587222942,1.0534130262152803 +3220,3170.185761906024,2977.52163265303,1.064706206376518 +3221,1802.636228540164,1751.690861640732,1.029083537520835 +3222,358.5414978435381,335.5314204399304,1.0685780108862477 +3223,555.8386845821201,518.4234601322344,1.0721711637824844 +3224,358.34398259171763,335.4123556325477,1.068368462205048 +3225,357.91828259242897,334.9962274871046,1.0684248156382798 +3226,3860.5412491897077,3576.8634874129048,1.0793090826012997 +3227,1313.1273347961394,1235.3674717805868,1.0629447227580584 +3228,663.7611835924356,637.9849065863203,1.0404026439183913 +3229,2310.4585987479218,2169.5025931972177,1.0649715773526576 +3230,1301.575878727823,1233.107788616812,1.0555248217090676 +3231,363.02933080718714,346.9195933885596,1.0464365164886613 +3232,616.8231955372621,589.1436972489776,1.0469825925619416 +3233,945.5476749689668,901.1712370102169,1.0492430696145785 +3234,63.74210014484601,57.259528067278595,1.1132138579617796 +3235,389.2029185887922,378.2021209320045,1.0290870861053831 +3236,105.31636360581332,105.18702558374578,1.0012296005267738 +3237,710.7576811722392,686.4880825185951,1.0353532701756505 +3238,88.91348214876535,88.61357196535423,1.0033844723416452 +3239,813.238265931829,765.361798317774,1.0625540335554833 +3240,1143.8899551394288,1064.7704612452624,1.074306619852729 +3241,99.54487428671459,99.5365065653853,1.000084066857659 +3242,1275.3460264237688,1227.1042341289563,1.0393135244367047 +3243,555.0030460770997,537.0294532251372,1.0334685420772025 +3244,99.46277527161917,99.45956218668638,1.000032305440142 +3245,81.54219273582063,81.54096841175249,1.0000150148335492 +3246,463.15670235279924,448.17223917499604,1.0334346080993033 +3247,601.6981887265451,581.152876760834,1.0353526804861128 +3248,33.2479162644851,32.08528805255996,1.036235554750844 +3249,142.373476410333,136.26799724826557,1.0448049379557838 +3250,408.4207466855593,393.7746456393897,1.0371941190433633 +3251,175.86397571430757,172.71313830918535,1.0182431830952066 +3252,99.59969532728222,94.26079371457196,1.056639684457536 +3253,46.13134900279076,44.518364771923956,1.036231884057971 +3254,41.035421467783785,39.01611966171758,1.051755577529857 +3255,46.25617866492351,44.638740002534554,1.0362339676768906 +3256,43.83834562351459,42.37272485601225,1.0345887778631822 +3257,941.5194744989901,888.2302075626258,1.0599948825007814 +3258,131.8812730613697,127.46363416323567,1.0346580334629139 +3259,43.78053757071229,42.31684946470779,1.0345887778631822 +3260,876.3023621930289,826.7151620475604,1.0599809975937224 +3261,65.56058834250605,63.29760130597421,1.035751544921786 +3262,43.44009557262829,41.987997861527376,1.0345836378264521 +3263,18.87638913305142,17.93960718816794,1.0522186430871983 +3264,196.29819098062055,195.65283266117146,1.0032984869713935 +3265,97.73891452431789,97.41845906686112,1.0032894736842104 +3266,195.8563002874684,195.21414848324721,1.0032894736842104 +3267,97.63088458669924,97.3108894156039,1.003288379882427 +3268,201.55877804777055,200.6109772727522,1.0047245708480335 +3269,100.6706199215365,100.18950216109353,1.0048020775636692 +3270,301.79593519931734,284.8327322655149,1.0595549633600037 +3271,229.13339922870375,216.7914924009829,1.0569298485426402 +3272,133.10245100804875,128.55867586590165,1.0353439790161394 +3273,1607.5278256453191,1524.9093771607804,1.0541792513850006 +3274,302.0379506415851,285.6382106248434,1.0574143773722244 +3275,247.1379428497277,238.7371776790073,1.0351883408038591 +3276,3657.96430585738,3519.349237544918,1.0393865623887781 +3277,2278.5408694791613,2197.557954928064,1.0368513214268098 +3278,249.19530796687917,240.66958913916693,1.0354249943177585 +3279,238.59854056643468,217.4505594919366,1.0972542040080715 +3280,361.99466801455213,354.9311596882746,1.0199010656953342 +3281,314.90550182710246,292.42863117068254,1.0768627564491138 +3282,237.28133405489334,216.24373555751316,1.0972865107196823 +3283,364.77484185385833,357.6523755638964,1.0199144945667766 +3284,209.1888455990299,196.44168074258891,1.0648903267791954 +3285,237.721139994392,216.67647079288616,1.0971248475872664 +3286,169.60117033114025,155.00372807795674,1.094174781691973 +3287,2094.3939488926317,2006.7664847051944,1.0436659994350614 +3288,1256.3868642119737,1199.9901314538556,1.0469976637972767 +3289,624.5506301375798,596.5157819669284,1.0469976637972767 +3290,1252.535382421035,1196.3115350977093,1.0469976637972762 +3291,621.0719658058406,593.1932680282415,1.0469976637972767 +3292,1556.467892417626,1502.9725845814808,1.0355930030826488 +3293,774.6773632831919,748.104307787909,1.0355205219628498 +3294,3807.4522440625196,3666.259763476231,1.0385113138989406 +3295,3490.775759334937,3359.6609258089543,1.0390262102103094 +3296,1266.321266496344,1209.4785979785468,1.0469976637972767 +3297,2672.6963652607365,2587.1497833485046,1.0330659563906308 +3298,3580.7843913265197,3456.8057876272906,1.0358650764075255 +3299,1254.6451623908408,1198.3266111984083,1.0469976637972767 +3300,817.3762639751205,770.4072935503087,1.0609664145420563 +3301,1941.729625567139,1873.9062941567322,1.036193555473876 +3302,936.9918113118282,891.2886306900609,1.0512776434569602 +3303,1027.8790139596379,942.1181392306553,1.0910298519451243 +3304,857.6638292350124,836.2661107218017,1.0255872122986567 +3305,727.6412069744121,699.2567529581415,1.0405923201973992 +3306,2854.8092976693597,2761.1946229028636,1.033903685741673 +3307,1911.2725726355752,1858.519782842314,1.0283843036163889 +3308,460.32712848943265,443.0937159508219,1.0388933806060194 +3309,3964.778451049716,3747.0542372199247,1.0581054343081322 +3310,3224.021690444689,3100.7247249807615,1.0397639185673577 +3311,789.9485100373569,777.001699140757,1.016662525848936 +3312,1514.8729655053676,1415.5463298100997,1.0701684103187163 +3313,1153.335932765149,1110.5902249244007,1.0384891806909773 +3314,718.6280622445646,650.4658226602663,1.104789886278005 +3315,536.5185616423325,479.67806234542013,1.118497183337897 +3316,627.9306768366839,584.7223906748129,1.0738953849740651 +3317,499.0535018637477,453.1390140928719,1.10132539097917 +3318,672.6098700351358,644.6025770721443,1.0434489311076038 +3319,1161.99890594181,1099.7094120804143,1.0566417757065092 +3320,561.7562038807255,497.9700111217504,1.1280924379668713 +3321,1056.3023813086609,976.3344060000935,1.0819063374363556 +3322,1527.0860139427791,1440.2647303080912,1.060281475903472 +3323,1051.719021559097,999.4652504943065,1.0522817286933661 +3324,1770.2550806107204,1720.7768072351303,1.0287534520267563 +3325,3328.6161265275587,3126.0904817688734,1.0647855991180677 +3326,1599.3984010047286,1499.566377638714,1.066573927539783 +3327,5961.254496028445,5690.06000049891,1.0476610959297012 +3328,1288.470150008244,1224.0220527834194,1.052652725560189 +3329,4792.301786991529,4582.806452777151,1.0457133279297504 +3330,9507.848343238129,9080.381939371002,1.0470758175945998 +3331,2924.0063677827297,2784.569598375749,1.0500748013223713 +3332,1723.3450992931382,1594.6917025608732,1.0806760306871002 +3333,6892.059318257811,6573.8186292328655,1.0484103238884281 +3334,2946.4902423585445,2814.3240212077744,1.0469619774250623 +3335,1733.0210877273576,1663.5836668049249,1.0417396625778337 +3336,406.6838042280194,376.6201109053325,1.0798249813330965 +3337,79.42485031220663,75.34898989636791,1.0540930996081632 +3338,6554.550323631639,6366.034983375607,1.029612677396264 +3339,5422.701545548887,5171.4055924338245,1.0485933560273688 +3340,1331.638093201846,1276.5957217477376,1.0431165250802752 +3341,2811.739441138827,2697.442121037185,1.042372482883041 +3342,3137.011884687005,2967.5182509068445,1.0571162902632072 +3343,8984.165550151969,8643.400361312326,1.0394248992983017 +3344,6839.553366591685,6537.689857644052,1.0461728095888008 +3345,54.20330821178826,52.05238328274904,1.0413223140495869 +3346,135.93208318276953,130.5415505343879,1.0412936159124417 +3347,154.80741920662064,147.70053909228017,1.0481168190584615 +3348,138.6487011601174,133.13435852923038,1.0414193803298066 +3349,22.61729215610673,20.88263258071211,1.0830670926517574 +3350,226.61867017509738,199.20019804083205,1.1376427955590942 +3351,265.4623755659037,254.44288388099704,1.043308311542564 +3352,302.8896706136195,298.10480839619976,1.016050939410076 +3353,35.28045409111691,32.574505750181835,1.0830695133699755 +3354,40.71210824242207,35.978960099705716,1.1315532224833553 +3355,37.999492887869835,33.57601877739376,1.1317450451705826 +3356,1105.8862596724503,1054.909586988295,1.0483232623088494 +3357,11.986600255312762,11.068731711730686,1.0829244548957053 +3358,143.6518593513018,134.94730372187223,1.0645033682730687 +3359,54.41969864834576,47.882068545025604,1.1365360833810372 +3360,1099.9574108771753,1021.7965072883976,1.0764936100595979 +3361,1463.7705949213405,1376.3217934550635,1.0635380489374866 +3362,304.4301165314383,291.9973734183338,1.0425782703712632 +3363,349.5781191739872,335.30148597021264,1.0425784966698384 +3364,227.2505039577289,217.48159646102448,1.0449183179435375 +3365,326.10197406179674,312.6956445298503,1.0428734130662527 +3366,109.74531062910854,101.9016638778755,1.0769727053783271 +3367,1939.5612320236298,1828.3767775645797,1.0608104717929907 +3368,116.54895650303074,108.3647853941622,1.075524268138397 +3369,322.9240635726388,307.3898334975651,1.050535926638565 +3370,147.58410712120312,137.24433886648035,1.0753383953037359 +3371,277.2190401955121,255.37858125673952,1.0855218900163586 +3372,456.42432588270094,416.9098114702493,1.0947795262315898 +3373,3827.263907871095,3658.06503027988,1.0462536549215664 +3374,75.24150094167189,70.47860581600636,1.0675793039677839 +3375,382.7441012642638,358.79149035593736,1.066759138809464 +3376,540.0915500173563,519.1677274387655,1.0403026256693868 +3377,60.7227022621936,57.40945957923662,1.0577124868835255 +3378,61.006915862051905,57.6779547663905,1.0577163512323642 +3379,127.28066567888351,121.79674266634913,1.0450252025832667 +3380,43.39766292489227,41.067298263319344,1.0567450200066941 +3381,45.30554939125315,42.87056058032261,1.0567986230636832 +3382,63.77021284530677,60.702349787622694,1.0505394448224412 +3383,404.3702043068976,382.97343244737544,1.0558701206054608 +3384,287.4189653100889,272.1975675100132,1.055920403475008 +3385,45.28456539779825,42.8463550578068,1.0569058986861752 +3386,1570.4184742529542,1502.3309552547717,1.0453212514592938 +3387,2115.4385102217802,2054.3050255125886,1.029758718374326 +3388,839.3580335275467,795.4283727309195,1.0552276764352835 +3389,154.53823391165952,143.78296387108952,1.0748021166833976 +3390,31.528858613066944,29.532192996389856,1.0676097984637025 +3391,231.20118817056664,216.1373510715718,1.0696956681680003 +3392,135.78069355440962,128.37202475927816,1.0577124868835255 +3393,93.90217154216799,88.48829841797541,1.0611817971526596 +3394,79.86316381228531,75.22491960485438,1.0616583471513823 +3395,52.251780746161515,49.27631472316632,1.0603832904248485 +3396,3525.204160250043,3371.874345460311,1.0454731698398447 +3397,2160.333782154971,2077.24854252684,1.0399977363936734 +3398,1090.169139951758,1027.6627976263612,1.0608237862358845 +3399,1373.131762103105,1330.481259983202,1.0320564470937692 +3400,907.1571063150963,860.3802881824,1.0543676078766457 +3401,82.40230815124407,82.04115681317374,1.0044020751547025 +3402,72.98071222456414,72.66132179907372,1.0043956043956044 +3403,72.06962890590569,71.753261605678,1.0044090999230988 +3404,73.46322591764228,73.1320013373323,1.0045291332693351 +3405,72.78293892356419,72.42375956955826,1.0049594132663184 +3406,456.3245906685372,436.8209839418076,1.0446489693574974 +3407,172.4124844224429,163.54451442603005,1.0542235857163145 +3408,184.58956696240122,175.103142261883,1.0541762105349908 +3409,586.8997324401296,556.2753431228069,1.055052573686628 +3410,588.6004270755941,557.886558126258,1.0550539684133868 +3411,591.1936432141252,560.3708250116504,1.0550043236134465 +3412,591.2063348721067,560.3562252731388,1.055054460372829 +3413,49.05258844659352,49.050129871487286,1.0000501237226624 +3414,230.37799352451364,220.06727779750207,1.0468525617720374 +3415,86.20492189296343,86.18985348121073,1.0001748281397878 +3416,408.1820878371599,387.83550113462155,1.0524618985188667 +3417,83.39205834481294,83.37518499574587,1.0002023785502596 +3418,131.25223933632407,131.251108910435,1.0000086126959113 +3419,1137.5921461612236,1102.7250623681132,1.0316190181786864 +3420,261.68906156519984,248.03369900572343,1.0550544648336728 +3421,264.1075167640078,250.32597888345632,1.0550543652801123 +3422,3619.958164255343,3498.409737072298,1.0347439083235472 +3423,262.0489418949568,248.37480019220462,1.0550544648336726 +3424,263.94948348291433,250.1761684165997,1.0550544648336726 +3425,969.4171604384196,934.6945817015352,1.0371485824531848 +3426,240.9409207993596,228.36825476539397,1.0550543509074048 +3427,246.14511484999787,233.30092356307784,1.0550541810583416 +3428,72.08816379843948,72.08816379843948,1.0 +3429,859.9968083021893,839.1474973171021,1.024845823948407 +3430,2169.1659255659915,2100.4576972336276,1.0327110745543007 +3431,48.40892306830406,47.51378863028655,1.018839466685823 +3432,1098.9777010971668,1068.3148586133802,1.0287020649732284 +3433,4298.464620299019,4156.792205652644,1.034082149801407 +3434,42.52088972127572,41.34609883141394,1.028413584910439 +3435,256.4564276105243,250.36775182167045,1.0243189298324276 +3436,1094.6949497698365,1057.2537190365692,1.0354136666148461 +3437,158.90244771650725,158.16234822330046,1.004679365863751 +3438,106.95673830372394,103.8979014467435,1.0294407953807263 +3439,103.3159270590029,99.07091462013494,1.042848220945012 +3440,363.6511528040501,353.7770179121642,1.0279106171174113 +3441,941.7402383120133,919.4433187784101,1.0242504557684178 +3442,103.92217953282176,99.65650644320978,1.0428037590505224 +3443,472.74168170572864,445.73791455688803,1.0605821633452144 +3444,385.522555468921,376.2615724093529,1.0246131514315064 +3445,382.5247586208696,373.3798682024309,1.0244921893150403 +3446,522.6263920382972,497.77122512696616,1.0499329122630408 +3447,386.09520652474305,376.81387313562004,1.0246310819500601 +3448,383.95974825151416,374.7797264695763,1.024494446026773 +3449,586.688567283378,563.19046908766,1.0417231815619745 +3450,531.3297099824001,517.8726783706235,1.0259852125316136 +3451,691.8386465402677,670.8932802139941,1.0312201164387766 +3452,411.31409319312263,391.69650536893784,1.0500836427062505 +3453,828.6011031081118,788.8628881498743,1.0503740454205368 +3454,885.867531301081,859.4371036141118,1.0307531843526696 +3455,3632.9502421083375,3470.7128066919818,1.0467447018674496 +3456,614.8282188418216,584.1978245055438,1.0524315446778714 +3457,1065.6749369726654,1020.2176723959739,1.0445564371277116 +3458,2365.090043381584,2311.9764368350457,1.022973247348164 +3459,104.32494409215487,100.04273880556705,1.0428037590505221 +3460,1684.7360714484207,1646.7453406100735,1.023070191790719 +3461,137.41721630777,131.79076048331387,1.0426923390063334 +3462,583.0210643086026,568.6256197105313,1.0253162082380312 +3463,1132.8750342613507,1105.062765000573,1.025168044876404 +3464,1493.6719024866259,1453.607326635281,1.0275621724775452 +3465,433.45265243103523,422.750219833068,1.0253162082380307 +3466,1322.8900930434847,1292.6085822284554,1.0234266669983145 +3467,2215.0900563332184,2142.7577960625717,1.0337566198118895 +3468,333.48896164278204,321.35568991507716,1.037756517492848 +3469,601.4806735652443,572.7832624616398,1.0501016928816533 +3470,165.23817057879808,156.53770463393715,1.055580640876311 +3471,271.51602266663923,256.2996757353127,1.0593693569360614 +3472,214.49229945590955,204.6337616372745,1.0481764970733907 +3473,190.81478164273238,181.65397708032907,1.0504299697129797 +3474,114.18879297188288,107.06371736049631,1.0665498619611309 +3475,236.54761376317637,226.19395765544618,1.0457733540499856 +3476,212.67847999456032,202.93658482402054,1.0480046275489834 +3477,117.55902937215257,110.36081626295106,1.0652243554637244 +3478,267.8617554024145,256.79142286614615,1.0431102114420652 +3479,305.48855504688356,294.6660694220753,1.0367279668338953 +3480,492.63366776590095,481.9165136955923,1.0222386113896031 +3481,635.6365962928143,609.6630387124555,1.0426031363738437 +3482,638.9729496653632,612.8694808459612,1.0425922152027713 +3483,639.550897640225,613.4179048257661,1.042602266104185 +3484,635.4819847999057,609.5142781194181,1.0426039349900182 +3485,738.7299497350228,706.0502955601274,1.0462851646410967 +3486,1404.1885819076406,1344.9974587767622,1.044008353134519 +3487,1408.1787930789244,1348.8198393704904,1.044008066886188 +3488,1926.7671871865848,1831.9188922914882,1.0517753789724031 +3489,1423.2196121102852,1359.1243545064276,1.0471592296844199 +3490,1399.3219893946298,1340.3360231017316,1.0440083421442306 +3491,3390.2399314299614,3189.64446192629,1.0628896016148859 +3492,2482.327409614778,2377.7836611618454,1.043966888224747 +3493,2510.4427919660734,2404.650644542125,1.0439948096677023 +3494,50.7871589826298,46.21996842663791,1.0988142292490117 +3495,696.4942621773755,663.6786538092674,1.0494450261128014 +3496,3169.3598290516493,2987.224438620419,1.0609714449562235 +3497,72.51271993186182,66.79622187098634,1.0855811586457182 +3498,71.49448757696118,65.84872420713577,1.0857383865489316 +3499,425.52776034417116,391.8110267657918,1.0860535596884409 +3500,429.8511858105297,395.84744395623244,1.0859011277537944 +3501,3962.9197436956274,3768.6590003616,1.051546383823898 +3502,1226.1952540566926,1152.0880471766843,1.0643242563462194 +3503,737.8569275222765,687.3749333036467,1.073441715391052 +3504,1486.1795886528218,1443.6177836521144,1.0294827380783804 +3505,800.1704488155585,747.454061085551,1.0705279300422101 +3506,735.4303043900771,685.1138736371502,1.0734424344464166 +3507,619.0355314456565,576.4885106197816,1.073803761986744 +3508,776.0873298531706,723.0054808166343,1.0734183217761784 +3509,728.9438586563399,679.072262090014,1.0734407799441457 +3510,4056.4361435505593,3785.8674291744824,1.071468090058049 +3511,1013.4358934623785,953.3071708162518,1.063073817639117 +3512,174.65018713576953,162.26536235855596,1.0763245131135686 +3513,216.01566887625285,206.6310042854498,1.045417504615322 +3514,215.38321350763337,206.02591858173884,1.0454180473520478 +3515,770.1738099084506,735.4910864960015,1.0471558718375273 +3516,644.0607971433278,616.0802148337661,1.0454171090644608 +3517,1312.9370335260598,1248.0907575806898,1.0519563786138988 +3518,1754.6136207528739,1687.0387140540058,1.040055338467298 +3519,285.36701977830006,272.9664163655205,1.0454290442681209 +3520,609.9311400997574,573.2667336234115,1.0639569755680807 +3521,660.2777574495819,625.0543828629682,1.0563524959624766 +3522,223.07474527181424,206.22190534426235,1.08172187091094 +3523,223.16609436537718,206.3140261210296,1.0816816411428163 +3524,224.65004652393046,207.67622284299702,1.0817321475158261 +3525,227.19549585694847,210.02878763207804,1.0817350250811453 +3526,137.08358925866122,135.89754111108428,1.0087275173478485 +3527,875.5906025666798,859.5584928947699,1.0186515633367985 +3528,141.18467451346066,139.83088752259363,1.0096816019325365 +3529,139.87043470139278,138.65688597433646,1.008752170644312 +3530,1837.2280562967678,1755.4362914360595,1.0465934111421369 +3531,439.1130327637216,405.84515324243756,1.081971853687288 +3532,438.3169942413113,405.1065060006872,1.081979646706952 +3533,441.7828302667813,408.3219508983139,1.0819472950079048 +3534,2103.9955076839983,1966.6524389052258,1.069835963926207 +3535,2506.14786333735,2342.7424836778064,1.0697496121737708 +3536,335.44428116473523,313.4098703339697,1.070305414463449 +3537,5175.483132536222,4797.7509495237055,1.0787310944204005 +3538,1866.9287281861052,1741.3712757771605,1.072102632078222 +3539,326.8117852676253,305.38747731698606,1.0701545071162208 +3540,2015.9400531029341,1894.5706847146346,1.064061673374082 +3541,394.22597437629236,367.7717439267481,1.0719311118551111 +3542,325.0916462004725,303.79964033172024,1.0700856849122777 +3543,1543.6031948119703,1512.6570936648582,1.0204581073111132 +3544,5284.00914569579,4993.716150408401,1.0581316571755182 +3545,2763.381017345602,2660.866964813488,1.0385265606615173 +3546,3278.586115799993,3118.47987972334,1.0513411156242114 +3547,2759.6829405573885,2646.820774681249,1.0426406528752334 +3548,52.973907246964195,52.96101122466343,1.0002435003033847 +3549,734.4454654474036,709.9434754940813,1.0345125926205185 +3550,51.91351882694043,51.91304282761613,1.0000091691663284 +3551,51.671696828963555,51.601460549273156,1.001361129683981 +3552,123.07835568002805,112.56839124521453,1.0933651473433519 +3553,110.81846251688307,103.12046804102604,1.0746504997707576 +3554,227.22162318093598,194.09388327028103,1.1706789485195865 +3555,108.43457290762278,100.89271853013771,1.0747512257312428 +3556,216.8796957418918,197.88272771555086,1.096001142927686 +3557,218.86221884693205,199.7491361564365,1.0956854335306205 +3558,210.13599417436265,191.7257026005352,1.096024118436461 +3559,215.9570326549648,197.0885625427356,1.0957359974054195 +3560,434.7193185844026,394.4804001329244,1.10200486117414 +3561,438.1137060238966,414.1552527331809,1.0578489663781976 +3562,417.31017668924585,394.54114333332484,1.0577101621482472 +3563,427.0935073390819,403.73760412780587,1.0578492143721212 +3564,1542.0048069361799,1464.1052383447297,1.0532062631505374 +3565,1063.0693249190485,1008.6563472364415,1.053946002354211 +3566,322.63409252234146,301.97894747637065,1.0683992881576192 +3567,555.9453581083925,525.8128945470526,1.057306437087848 +3568,37.028889857161246,35.29645790822013,1.0490823173658357 +3569,734.4488599761485,678.5028782128924,1.0824550397053763 +3570,562.0501265122637,528.8427961927898,1.0627924414562093 +3571,402.2347800170092,379.72716726535805,1.0592731168373912 +3572,196.34549052900957,187.59458981648302,1.0466479375609246 +3573,1182.081552382842,1121.2683924861753,1.0542360422394732 +3574,128.90296239076267,124.67629554409764,1.0339011263385673 +3575,177.7094180643739,170.1658106263213,1.044330922940908 +3576,992.7490010990123,927.1080256705252,1.070801863009451 +3577,1104.7791932785412,1035.6045203617814,1.0667964184750702 +3578,177.216969585259,167.88495635387545,1.0555857620245206 +3579,130.89787573769016,126.42172045915962,1.0354065366479217 +3580,240.47468088357064,224.60976586283692,1.0706332378727557 +3581,337.7979945802796,316.4618950063413,1.0674207540010805 +3582,181.22947697470195,167.42439588182782,1.082455612398435 +3583,220.28275429255353,204.2855574624616,1.0783080166253627 +3584,181.17623309427623,167.38135818773836,1.082415838035352 +3585,358.46374951162596,334.80264858935703,1.070671785369565 +3586,388.4423591230155,359.0480911406576,1.0818672169763537 +3587,390.4183282952064,360.875401701622,1.0818646171345614 +3588,504.4986097247462,478.322261529209,1.0547253395897793 +3589,1162.9443141168456,1097.4902621152144,1.0596397565072517 +3590,387.69893004560765,358.3601981927329,1.0818693928645944 +3591,390.2467628882134,360.7174219226032,1.0818628077574421 +3592,1034.6398736939227,976.2106689330918,1.0598530692403605 +3593,447.9257841739161,421.37671812135665,1.0630055361647042 +3594,596.2641810379303,577.0089173728458,1.0333708251039773 +3595,1357.5774765011831,1315.0441835414179,1.032343622740662 +3596,1091.7870367703167,1058.1016380994379,1.0318356927708614 +3597,271.290382676033,258.2718675385398,1.0504062454094059 +3598,297.51380914825455,283.33310011310897,1.0500496024978534 +3599,163.51372121195539,152.6570571614999,1.071117996457707 +3600,176.2367715336812,164.93671034705181,1.0685114985187492 +3601,208.96522503232364,196.50866404655613,1.0633893729124144 +3602,209.00094154602687,196.54239103800052,1.0633886178051917 +3603,533.8693463121834,504.97725395399334,1.0572146411189094 +3604,465.90942751191966,438.1334331645503,1.0633961990682814 +3605,716.962245608935,680.6609161700302,1.0533324722729291 +3606,467.1467047999673,439.32068516745625,1.0633387422263183 +3607,463.7208654827342,436.07847726773076,1.06338856342601 +3608,325.99904286523514,314.05707750629404,1.0380248248304538 +3609,105.36490178141565,102.53792169723943,1.027570093457944 +3610,990.0941768664734,966.4447218208845,1.0244705718926488 +3611,103.92992189692671,101.11350995098063,1.0278539628118089 +3612,103.9256291736448,101.13667773514096,1.0275760634120057 +3613,36.780368255266474,35.15200831353818,1.046323382926066 +3614,450.3824082428985,427.22469895318494,1.0542049870863182 +3615,36.51286243355573,34.89661130189201,1.0463154177831615 +3616,36.60170079853948,34.98170383134391,1.0463098359932956 +3617,152.9310169450208,146.06637060822558,1.0469967611861004 +3618,15.987540807195826,14.537690292817773,1.0997304582210243 +3619,16.18341619532117,14.715802471725869,1.099730458221024 +3620,15.95234551979272,14.50568673490956,1.099730458221024 +3621,74.65450573138172,64.77694822899655,1.152485687770694 +3622,16.145837197062864,14.681631372819417,1.0997304582210243 +3623,15.91747146526872,14.473975278467389,1.0997304582210243 +3624,16.22349112397784,14.771931665950147,1.0982647016553422 +3625,1557.4956550401532,1437.387239793629,1.0835602347936306 +3626,1279.2179884682923,1215.7758867031712,1.0521823984658534 +3627,212.4022626329599,199.8235596701017,1.0629490485687723 +3628,145.5181551264822,139.05464712833395,1.0464817834687903 +3629,95.11261112023261,87.25889212076963,1.090004798463326 +3630,464.813218076366,431.9304816967341,1.0761296962660751 +3631,253.3551437341684,234.7923356106202,1.0790605369433046 +3632,1013.9474842627728,943.9019914654623,1.0742084384084845 diff --git a/Database/tg/fortran/EXT_IN.TXT b/Database/tg/fortran/EXT_IN.TXT index aa42986..6947bdc 100644 --- a/Database/tg/fortran/EXT_IN.TXT +++ b/Database/tg/fortran/EXT_IN.TXT @@ -1,74 +1,74 @@ -1700104,0.245,0.449 -1702300,0.023,0.081 -1702400,0.098,0.154 -1702601,0.014,0.021 -1702700,0.153,0.192 -1702801,0.065,0.064 -1702901,0.093,0.098 -1703005,0.004,0.008 -1703007,0.012,0.009 -1703008,0.005,0.009 -1703009,0.009,0.007 -1703102,0.007,0.016 -1703105,0.01,0.011 -1703106,0.011,0.012 -1703107,0.005,0.01 -1703108,0.016,0.016 -1703202,0.009,0.01 -1703203,0.014,0.012 -1703204,0.013,0.014 -1703205,0.012,0.009 -1703207,0.007,0.012 -1703208,0.009,0.007 -1703209,0.011,0.006 -1703306,0.014,0.004 -1703307,0.009,0.01 -1703308,0.009,0.008 -1703309,0.009,0.016 -1703310,0.018,0.018 -1703401,0.013,0.01 -1703407,0.006,0.01 -1703408,0.006,0.005 -1703409,0.006,0.011 -1703410,0.006,0.011 -1703411,0.006,0.008 -1703412,0.008,0.006 -1703413,0.008,0.021 -1703414,0.01,0.017 -1703415,0.006,0.014 -1703416,0.016,0.013 -1703417,0.008,0.008 -1703418,0.007,0.011 -1703419,0.007,0.022 -1703420,0.007,0.013 -1703421,0.009,0.007 -1703422,0.008,0.053 -1703501,0.007,0.012 -1703502,0.009,0.01 -1703503,0.004,0.007 -1703504,0.008,0.012 -1703520,0.002,0.006 -1703521,0.003,0.009 -1703522,0.007,0.005 -1703523,0.002,0.008 -1703524,0.01,0.011 -1703525,0.015,0.015 -1703526,0.007,0.011 -1703527,0.002,0.044 -1703528,0.002,0.003 -1703529,0.012,0.008 -1703530,0.001,0.006 -1703531,0.003,0.002 -1703532,0.003,0.018 -1703601,0.015,0.011 -1703602,0.013,0.006 -1703700,0.018,0.019 -1800101,0.006,0.029 -1800102,0.011,0.038 -1800103,0.008,0.024 -1800104,0.016,0.048 -1800200,0.029,0.056 -1800300,0.139,0.074 -5510000,0.066,0.067 -5530000,0.255,0.115 -5550000,0.222,0.197 +1700104,0.162,0.190 +1702300,0.024,0.067 +1702400,0.102,0.148 +1702601,0.031,0.060 +1702700,0.082,0.049 +1702801,0.057,0.119 +1702901,0.079,0.060 +1703005,0.009,0.009 +1703007,0.008,0.012 +1703008,0.009,0.010 +1703009,0.015,0.007 +1703102,0.006,0.012 +1703105,0.007,0.006 +1703106,0.012,0.010 +1703107,0.008,0.009 +1703108,0.010,0.008 +1703202,0.013,0.010 +1703203,0.012,0.011 +1703204,0.011,0.010 +1703205,0.011,0.021 +1703207,0.008,0.018 +1703208,0.009,0.008 +1703209,0.016,0.014 +1703306,0.013,0.007 +1703307,0.010,0.009 +1703308,0.017,0.015 +1703309,0.016,0.024 +1703310,0.017,0.030 +1703401,0.012,0.014 +1703407,0.008,0.013 +1703408,0.007,0.007 +1703409,0.008,0.016 +1703410,0.012,0.010 +1703411,0.007,0.012 +1703412,0.012,0.009 +1703413,0.006,0.011 +1703414,0.011,0.009 +1703415,0.009,0.011 +1703416,0.010,0.024 +1703417,0.007,0.008 +1703418,0.012,0.016 +1703419,0.008,0.020 +1703420,0.009,0.012 +1703421,0.007,0.019 +1703422,0.006,0.025 +1703501,0.008,0.007 +1703502,0.014,0.009 +1703503,0.006,0.007 +1703504,0.005,0.007 +1703520,0.006,0.005 +1703521,0.005,0.006 +1703522,0.007,0.007 +1703523,0.004,0.011 +1703524,0.009,0.029 +1703525,0.023,0.080 +1703526,0.004,0.010 +1703527,0.007,0.007 +1703528,0.007,0.007 +1703529,0.013,0.014 +1703530,0.005,0.006 +1703531,0.005,0.007 +1703532,0.005,0.008 +1703601,0.016,0.007 +1703602,0.014,0.008 +1703700,0.018,0.014 +1800101,0.012,0.045 +1800102,0.011,0.035 +1800103,0.013,0.040 +1800104,0.023,0.028 +1800200,0.028,0.049 +1800300,0.128,0.095 +5510000,0.068,0.040 +5530000,0.246,0.111 +5550000,0.218,0.184 diff --git a/Database/tg/fortran/TG_INPUT.TXT b/Database/tg/fortran/TG_INPUT.TXT new file mode 100644 index 0000000..aeed33c --- /dev/null +++ b/Database/tg/fortran/TG_INPUT.TXT @@ -0,0 +1,25 @@ + &PARAM + TITLE = 'CMAP Trip Generation' + SUBZONES = 17418 + PUMA5 = 74 + ZONES = 3632 + COUNTIES = 21 + TRIPGEN = .TRUE. + HHENUM = .FALSE. + SAVE_FILE = .TRUE. + EXP_TTYPE = .TRUE. + SYNTH_VEH = .FALSE. + MODE_CHOICE = .TRUE. + IN_EMPFACT = 1.000 + WI_EMPFACT = 1.000 + SWIDX_MAX = 40.0 + REPLICATE_MAX = 1900 + RESAMPLE_MAX = 100 + REGMED_INC = 68300 + GQATT1 = 1.00,2.00,1.00 + GQATT2 = 0.385,0.77,1.00 + GQATT3 = 0.306,0.612,1.00 + GQATT4 = 0.12,0.24,1.00 + RNSEED = 211 + &END + \ No newline at end of file diff --git a/Database/tg/fortran/TG_PopSyn.exe b/Database/tg/fortran/TG_PopSyn.exe new file mode 100644 index 0000000000000000000000000000000000000000..09fbe9497d1d0967aaa302e5f7927f347858a2fd GIT binary patch literal 1565184 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

XW0EY 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 of workers in income group 4 +# low is based on other industries +lowlist = ['11', '21', '44-45', '48-49', '56', '61', '62', '71', '72', '81'] +highlist = ['22', '23', '31-33', '42', '51', '52', '53', '54', '55', '92'] + +# setup education weights for usualwfh (low to high) +eduw = [0.177, 0.246, 0.576] +# setup education weights for usualwfh (low to high, fine they don't sum to 1) +eduwtc = [0.049, 0.114, 0.720] + +# set distribution of tc14 into the 4 days +tcportions = [0.575, 0.254, 0.112, 0.059] + +print('setting up for wfhflag script...') # read in files dfpop = pd.read_csv(synpoppath) dfhh = pd.read_csv(synhhpath, dtype={'MV': object}) indpxwalk = pd.read_csv(indpxwalkpath) +indmix = pd.read_csv(indmixpath) +incdist = pd.read_csv(incdistpath) + +# industry mix - source: mdt + nirpc survey (rescaled after removing industries -7, -8, and 97 to sum to 1) +indmix1 = indmix[indmix['cat'] == 'usualwfh'][['indus', 'pct']] +indmix2 = indmix[indmix['cat'] == 'tc14'][['indus', 'pct']] -# merge income2, edu2, trc get workers +# merge naics2, income4, edu, get workers dfpop = dfpop.merge(indpxwalk, on='INDP', how='left') dfpop = dfpop.merge(dfhh[['household_id', 'HINCP19']], on='household_id', how='left') - -dfpop['inccat2'] = pd.cut(dfpop.HINCP19, bins=[-99999, 100000, 2000000], right=False, labels=[1, 2]) +dfpop['inccat4'] = pd.cut(dfpop.HINCP19, bins=[-99999, 30000, 60000, 100000, 2000000], right=False, labels=[1, 2, 3, 4]) workers = dfpop[dfpop['JWTR'] != 'bb'].copy() workers.JWTR = workers.JWTR.astype(float).astype(int) workers.SCHL = workers.SCHL.astype(float).astype(int) +workers.loc[workers.SCHL.isin([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]), 'edu'] = 1 +workers.loc[workers.SCHL.isin([18, 19, 20]), 'edu'] = 2 +workers.loc[workers.SCHL.isin([21, 22, 23, 24]), 'edu'] = 3 +workers.loc[:, 'selected'] = 0 -workers.loc[workers.SCHL.isin([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]), 'edu'] = 1 -workers.loc[workers.SCHL.isin([21, 22, 23, 24]), 'edu'] = 2 +# overall targets +targetwfh = round(len(workers) * usualwfhpct, 0) +targettc14 = round(len(workers) * tc14pct, 0) -workers.loc[:, 'selected'] = 0 workers = workers[workers['ESR'] != '4'] -def samplingworkers(df, wfhpctlist): +# functions +def portionout(df, pctcol, total, colname): + """ + divides up a total based on a percent column into a new column (no decimals) + :param df: input dataframe + :param pctcol: name of column that has percentages + :param total: can be name of column that has totals, or a numeric total that the percentages will be applied to + :param colname: the name of the result column + :return: dataframe with targetdec, targetint, decimal, and colname columns + """ df = df.copy() + indcounts = workers[workers.selected == 0].groupby('naics2').agg({'household_id':'count'}).reset_index() + indcounts.rename({'household_id':'sectortotal'}, axis=1, inplace=True) + + + if isinstance(total, int) or isinstance(total, float): + df['targetdec'] = df[pctcol] * total + + df2 = df.merge(indcounts, left_on='indus', right_on='naics2') + df2['testtot'] = df2['sectortotal'] - df2['targetdec'] + + if len(df2[df2.testtot < 0]) == 0: + pass + else: + # don't go all the way up to max to prevent same issue further down the line + df2.loc[df2.testtot < 0, 'newpct'] = (df2.sectortotal - 10) / total + df2.loc[df2.testtot < 0, 'pctdiff'] = df2[pctcol] - df2.newpct + todistribute = df2.pctdiff.sum() + # normalize unchanged pcts to one to distribute out the missing pct + newdenom = 1 - df2.loc[df2.testtot < 0][pctcol].sum() + df2.loc[df2.testtot >=0, 'pctfordist'] = df2[pctcol] / newdenom + df2.loc[df2.testtot >= 0, 'newpct'] = (df2.pctfordist * todistribute) + df2[pctcol] + df2[pctcol] = df2['newpct'] + df2['targetdec'] = df2[pctcol] * total + + df2['targetint'] = df2['targetdec'].astype('int') + df2['decimal'] = df2['targetdec'] - df2['targetint'] + leftover = total - df2['targetint'].sum() + df2.sort_values('decimal', ascending=False, inplace=True) + df2.reset_index(drop=True, inplace=True) + df2.loc[df2.index < leftover, 'targetint'] = df2.targetint + 1 + assert (total - df2.targetint.sum()) == 0, "Targets do not sum to total" + df2.rename({'targetint': colname}, axis=1, inplace=True) + return df2 + + elif isinstance(total, str): + df['targetdec'] = df[pctcol] * df[total] + + df2 = df.merge(indcounts, left_on='indus', right_on='naics2') + df2['testtot'] = df2['sectortotal'] - df2['targetdec'] + + if len(df2[df2.testtot < 0]) == 0: + pass + else: + df2.loc[df2.testtot < 0, 'newpct'] = (df2.sectortotal - 10) / df[total] + df2.loc[df2.testtot < 0, 'pctdiff'] = df2[pctcol] - df2.newpct + todistribute = df2.pctdiff.sum() + df2.loc[df2.testtot >= 0, 'newpct'] = df2[pctcol] * (1 + todistribute) + df2[pctcol] = df2['newpct'] + df2['targetdec'] = df2[pctcol] * df2[total] + + df2['targetint'] = df2['targetdec'].astype('int') + df2['decimal'] = df2['targetdec'] - df2['targetint'] + + totallist = [x for x in df2[total].unique()] + piecelist = [] + for i in totallist: + selection = df2[df2[total] == i].copy() + leftover = i - selection['targetint'].sum() + if leftover != 0: + selection.sort_values('decimal', ascending=False, inplace=True) + selection.reset_index(drop=True, inplace=True) + selection.loc[selection.index < leftover, 'targetint'] = selection.targetint + 1 + assert (i - selection.targetint.sum()) == 0, "Targets do not sum to total" + piecelist.append(selection) + df2 = pd.concat(piecelist) + df2.rename({'targetint': colname}, axis=1, inplace=True) + return df2 + + +def settargets(indmix, overalltarget): + """ + use portionout function to set industry/income targets for group of interest (usualwfh or tc14) + :param indmix: input df with distribution of people in group of interest into industries + :param overalltarget: total target value for people in group of interest + :return: + """ + indmixfinal = portionout(indmix, 'pct', overalltarget, 'indint') + + # income targets + indmixfinal.loc[indmixfinal['indus'].isin(lowlist), 'incdist'] = 'low' + indmixfinal.loc[indmixfinal['indus'].isin(highlist), 'incdist'] = 'high' + targets = indmixfinal[['indus', 'pct', 'indint', 'incdist']].merge(incdist, on='incdist', how='left') + finaltargets = portionout(targets, 'pct_y', 'indint', 'indincint') + finaltargets.reset_index(drop=True, inplace=True) + + return finaltargets - for idx, trc in enumerate(["low", "medium", "high"]): - filtered_df = df[df["trc"] == trc] - targetgrouptotal = int(len(filtered_df) * wfhpctlist[idx]) + +def jwtr11flag(targetdf, workerdf, flagvalue): + """ + flag workers in workerdf with jwtr11 with the flagvalue according to counts in targetdf + :param targetdf: guiding dataframe with targets values for each category + :param workerdf: worker df with selected flag column + :param flagvalue: the value to set the selected column to + :return:workerdf + """ + for i, row in targetdf.iterrows(): + ind = row['indus'] + inc4 = row['hhinc4'] + target = row['indincint'] + options = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & ( + workerdf['inccat4'] == inc4) & (workerdf['JWTR'] == 11)] + if len(options) > target: + ilist = [x for x in options.sample(target, random_state=seedvalue).index.values] + workerdf.loc[workerdf.index.isin(ilist), 'selected'] = flagvalue + else: + ilist2 = [x for x in options.index.values] + workerdf.loc[workerdf.index.isin(ilist2), 'selected'] = flagvalue + + return workerdf + + + +def preproundtwo(workerdf, flagvalue, eduweights, targets): + """ + prepare for roundtwo assignment by calculating numbers still needed and adding eduwgt column + :param workerdf: worker df with selected flag column + :param flagvalue: value in the 'selected' column to evaluate + :param eduweights: weights to apply based on edu field for use in sampling + :return: b, workerdf. b is the new guiding df that lists how many are still needed in each category + """ + result = workerdf[workerdf['selected'] == flagvalue].groupby(['naics2', 'inccat4']). \ + household_id.count().reset_index() + + # calculate number still needed in each category + comparison = targets.merge(result, left_on=['indus', 'hhinc4'], + right_on=['naics2', 'inccat4'], how='left').reset_index() + comparison.household_id.fillna(0, inplace=True) + comparison['needed'] = comparison['indincint'] - comparison['household_id'] + b = comparison[comparison['needed'] > 0] + workerdf = workerdf.merge(comparison[['indus', 'hhinc4', 'needed']], + left_on=['naics2', 'inccat4'], right_on=['indus', 'hhinc4'], how='left') + workerdf.loc[workerdf['edu'] == 1, 'eduwgt'] = eduweights[0] + workerdf.loc[workerdf['edu'] == 2, 'eduwgt'] = eduweights[1] + workerdf.loc[workerdf['edu'] == 3, 'eduwgt'] = eduweights[2] + + return b, workerdf + + +def roundtwo(dfb, workerdf, flagvalue): + """ + finish flagging workers to meet target values (outside of jwtr == 11) using eduwgt column + :param dfb: guiding dataframe with targets values for each category + :param workerdf: worker df with selected flag column + :param flagvalue: value to set 'selected' column to + :return: workerdf + """ + dolater = {} + + for i, row in dfb.iterrows(): + ind = row['indus'] + inc4 = row['hhinc4'] + target = int(row['needed']) + options = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & ( + workerdf['inccat4'] == inc4)] + + if len(options) >= target: + ilist = [x for x in options.sample(target, weights='eduwgt', random_state=seedvalue).index.values] + workerdf.loc[workerdf.index.isin(ilist), 'selected'] = flagvalue + elif len(options) < target: + dolater[i] = (ind,inc4,target) - for i in [1, 2]: - for e in [1, 2]: - inc_factor = incdist_dict[trc][i] - edu_factor = edudist_dict[trc][e] - targetwfhworkers = int(targetgrouptotal * inc_factor * edu_factor) - - sub_filtered_df = filtered_df[(filtered_df["inccat2"] == i) & (filtered_df["edu"] == e)] - if targetwfhworkers > 0 and len(sub_filtered_df) >= targetwfhworkers: - sample_idx = sub_filtered_df.sample(n=targetwfhworkers, random_state=2).index - df.loc[sample_idx, "selected"] = 1 # mark selected rows - - return df + + if len(dolater) > 0: + donow = pd.DataFrame.from_dict(dolater, orient='index', columns=['ind','inc','target']) + for i,row in donow.iterrows(): + ind = row['ind'] + inc4 = row['inc'] + target = int(row['target']) + options = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & ( + workerdf['inccat4'] == inc4)] + ilist = [x for x in options.index.values] + stillneed = target - len(ilist) + options2 = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & (workerdf.inccat4 != inc4)] + ilist.extend([x for x in options2.sample(stillneed).index.values]) + workerdf.loc[workerdf.index.isin(ilist), 'selected'] = flagvalue -workers = samplingworkers(workers, wfhpctlist) + return workerdf + + +########################################## +# part one: usualwfh +########################################## + +# industry targets +finaltargets1 = settargets(indmix1, targetwfh) + +print('selecting usualwfh from JWTR 11...') +# round one +workers = jwtr11flag(finaltargets1, workers, 1) + +# round two +b1, workers = preproundtwo(workers, 1, eduw, finaltargets1) + +print('selecting usualwfh from any...') +workers = roundtwo(b1, workers, 1) + +current = workers.selected.sum() +remaining = int(targetwfh - current) +print('checking overall usualwfh target met...') +assert remaining == 0, "overall usualwfh target not met" +workers = workers.drop(['indus', 'hhinc4', 'needed', 'eduwgt'], axis=1) + +########################################## +# part two: tc14 +########################################## + +# industry targets +finaltargets2 = settargets(indmix2, targettc14) + +print('selecting tc14 from JWTR 11...') +# round one +workers = jwtr11flag(finaltargets2, workers, 2) + +# round two +b2, workers = preproundtwo(workers, 2, eduwtc, finaltargets2) + +print('selecting tc14 from any...') +workers = roundtwo(b2, workers, 2) + +current = len(workers[workers['selected'] == 2]) +remaining = int(targettc14 - current) +print('checking overall tc14 target met...') +assert remaining == 0, "overall tc14 target not met" + +########################################## +# assign tc14 wfh status for given day +########################################## +print('assigning wfh status for tc14...') +workers['tc'] = 0 + +tc1 = targettc14 * tcportions[0] +tc2 = targettc14 * tcportions[1] +tc3 = targettc14 * tcportions[2] +tc4 = targettc14 * tcportions[3] + +count = 4 +for t in [tc4, tc3, tc2]: + options = workers[(workers['selected'] == 2) & (workers['tc'] == 0)] + it = int(t) + ilist = [x for x in options.sample(it, random_state=seedvalue).index.values] + workers.loc[workers.index.isin(ilist), 'tc'] = count + count -= 1 + +workers.loc[(workers['selected'] == 2) & (workers['tc'] == 0), 'tc'] = 1 + +workers['random'] = np.random.random(size=len(workers)) +workers.loc[(workers['selected'] == 2) & (workers['random'] < (workers['tc'] / 5)), 'working'] = 1 +workers.working.fillna(0, inplace=True) ########################################## # format and save @@ -113,10 +343,18 @@ def samplingworkers(df, wfhpctlist): popsynhh = pd.read_csv(popsynhhpath, names=['sz', 'hhtype', 'vehicles', 'serialno', 'stpuma5', 'rowcol', 'adults', 'workers', 'children', 'iq', 'age', 'hhvtype', 'income']) - -hhsummary = workers.groupby("household_id").agg(finalflag=("selected", lambda x: int(x.sum() > 0)),wfhworkers=("selected", "sum")).reset_index() - -final1 = dfhh[['household_id','SERIALNO']].merge(hhsummary[['household_id','finalflag','wfhworkers']],on='household_id', how='left') +workers.loc[workers['selected'] == 1, 'usualwfh'] = 1 +workers.loc[(workers['selected'] == 2) & (workers['working'] == 1), 'tc14'] = 1 +workers.loc[(workers['selected'] == 2) & (workers['working'] == 0), 'tc14nw'] = 1 +workers.usualwfh.fillna(0, inplace=True) +workers.tc14.fillna(0, inplace=True) +workers.tc14nw.fillna(0, inplace=True) +hhsummary = workers.groupby('household_id').agg({'usualwfh':'sum','tc14':'sum','tc14nw':'max'}).reset_index() +hhsummary['wfhworkers'] = hhsummary['tc14'] + hhsummary['usualwfh'] +hhsummary.loc[(hhsummary['tc14'] > 0) & (hhsummary['usualwfh'] > 0), 'finalflag'] = 1 +hhsummary.loc[(hhsummary['tc14'] > 0) & (hhsummary['usualwfh'] == 0), 'finalflag'] = 2 +hhsummary.loc[(hhsummary['tc14'] == 0) & (hhsummary['usualwfh'] > 0), 'finalflag'] = 1 +final1 = dfhh[['household_id','SERIALNO']].merge(hhsummary[['household_id','finalflag','wfhworkers','tc14nw']],on='household_id', how='left') final1.finalflag.fillna(0, inplace=True) try: final1['SERIALNO'] = final1['SERIALNO'].str.replace('HU','99') @@ -133,73 +371,11 @@ def samplingworkers(df, wfhpctlist): final1sort['diffcheck'] = final1sort['SERIALNO'] - final1sort['sn2'] assert (final1sort.diffcheck == 0).all(), "file not aligned with popsyn_hh" final1sort.wfhworkers.fillna(0, inplace=True) +final1sort.tc14nw.fillna(0, inplace=True) final1sort['finalflag'] = final1sort.finalflag.astype('int') final1sort['wfhworkers'] = final1sort.wfhworkers.astype('int') -final1sort[['SERIALNO', 'finalflag','wfhworkers']].to_csv(savedir + "/HH_WFH_STATUS.CSV", index=False, header=False) - -# Red GEO data get puma to county -pumacross = pd.read_csv(geoinpath, sep=",", usecols=[1, 2, 3, 4], names=["fips", "cnty_name", "state", "puma5"], header=None ) -pumacross = pumacross.drop_duplicates() -pumacross["puma5"] = pumacross["puma5"].astype(str) - -# Merge to new data prepare the county status -final2 = pd.merge(popsynhh, final1sort, left_index=True, right_index=True, how='inner') -final2['State'] = final2['stpuma5'].astype(str).str[0:2] -final2['PUMA'] = final2['stpuma5'].astype(str).str[2:] -final2['PUMA'] = final2['PUMA'].str.lstrip('0') -final2["PUMA"] = final2["PUMA"].astype(str) -final2_all = pd.merge(final2, pumacross, left_on="PUMA", right_on="puma5") - -# Convert children to numeric first -final2_all["children"] = pd.to_numeric(final2_all["children"], errors="coerce") -final2_all["wfhworkers"] = pd.to_numeric(final2_all["wfhworkers"], errors="coerce") - -# --- COUNTY MERGES & FILTERS --- -# Combine Boone + Winnebago → Winnebago-Boone -final2_all.loc[ - final2_all["cnty_name"].isin(["BOONE", "WINNEBAGO"]), "cnty_name" - ] = "WINNEBAGO-BOONE" - -# Combine Kane + Kendall → Kane-Kendall -final2_all.loc[ - final2_all["cnty_name"].isin(["KANE", "KENDALL"]), "cnty_name" - ] = "KANE-KENDALL" - -# Remove Lee + Ogle -final2_all = final2_all[~final2_all["cnty_name"].isin(["LEE", "OGLE"])] - -county_worker = final2_all.groupby(['State','cnty_name'])[['workers','wfhworkers']].sum().reset_index() - -county_worker.to_csv(savedir + "/PERSON_COUNTY_STATUS.CSV", index=False) - -# Now collapse 3+ into "3+" -final2_all["children"] = final2_all["children"].apply( - lambda x: "3+" if x >= 3 else x -) -final2_all["wfhworkers"] = final2_all["wfhworkers"].apply( - lambda x: "3+" if x >= 3 else x -) - -# Group and compute counts -hh_child_work = ( - final2_all - .groupby(['cnty_name','State','children','wfhworkers']) - .size() - .reset_index(name='HH') -) - -# Totals per county/state -hh_child_work['HH_county'] = ( - hh_child_work.groupby(['cnty_name','State'])['HH'] - .transform('sum') -) - -# Shares -hh_child_work['HH_county_share'] = ( - hh_child_work['HH'] / hh_child_work['HH_county'] -) - -hh_child_work.to_csv(savedir + "/HH_CHILD_WORK.CSV", index=False) +final1sort['tc14nw'] = final1sort.tc14nw.astype('int') +final1sort[['SERIALNO', 'finalflag','wfhworkers','tc14nw']].to_csv(savedir + "/HH_WFH_STATUS.CSV", index=False, header=False) ########################################## # save additional files @@ -207,4 +383,6 @@ def samplingworkers(df, wfhpctlist): if savefiles == "Y": print('saving additional files...') - workers.to_csv("workers.csv", index=False) \ No newline at end of file + workers.to_csv("workers.csv", index=False) + finaltargets1.to_csv("finaltargets_usualwfh.csv", index=False) + finaltargets2.to_csv("finaltargets_tc14.csv", index=False) \ No newline at end of file diff --git a/Database/tg/fortran/wfhmodule/wfhflag_base.py b/Database/tg/fortran/wfhmodule/wfhflag_base.py deleted file mode 100644 index edb7d40..0000000 --- a/Database/tg/fortran/wfhmodule/wfhflag_base.py +++ /dev/null @@ -1,393 +0,0 @@ -# coding=utf-8 - -# this flags tbm people as usualwfh or tc14 -import pandas as pd -import numpy as np -from pathlib import Path -import yaml -import sys -import os - -# pathways -savedir = sys.argv[2] -assert os.path.exists(savedir) == True, "savedir not valid" -os.chdir(sys.argv[1]) -synpoppath = "synthetic_persons.zip" -synhhpath = "synthetic_households.zip" -popsynhhpath = savedir + "/POPSYN_HH.csv" -incdistpath = "incdist.csv" -indmixpath = "indusmix.csv" -indpxwalkpath = "indp_naics.csv" -db = Path(__file__).resolve().parents[3] # database folder -with open(os.path.join(db, 'Telework.yaml')) as f: - lines_without_backslashes = ''.join([line.replace('\\','/') for line in f]) - wfh_data = yaml.safe_load(lines_without_backslashes) -# save additional output files? -savefiles = sys.argv[3] - -# major parameters - source: mdt + nirpc survey (which is higher than PUMS data...) -# Read WFH data from YAML file -usualwfhpct = wfh_data['usualwfhpct'] -tc14pct = wfh_data['tc14pct'] - -# set seedvalue -seedvalue = 2 -np.random.seed(seed=seedvalue) - -# place industries in one of two income distributions types -# high is based on industries that had >60% of workers in income group 4 -# low is based on other industries -lowlist = ['11', '21', '44-45', '48-49', '56', '61', '62', '71', '72', '81'] -highlist = ['22', '23', '31-33', '42', '51', '52', '53', '54', '55', '92'] - -# setup education weights for usualwfh (low to high) -eduw = [0.177, 0.246, 0.576] -# setup education weights for usualwfh (low to high, fine they don't sum to 1) -eduwtc = [0.049, 0.114, 0.720] - -# set distribution of tc14 into the 4 days -tcportions = [0.575, 0.254, 0.112, 0.059] - -print('setting up for wfhflag script...') -# read in files -dfpop = pd.read_csv(synpoppath) -dfhh = pd.read_csv(synhhpath, dtype={'MV': object}) -indpxwalk = pd.read_csv(indpxwalkpath) -indmix = pd.read_csv(indmixpath) -incdist = pd.read_csv(incdistpath) - -# industry mix - source: mdt + nirpc survey (rescaled after removing industries -7, -8, and 97 to sum to 1) -indmix1 = indmix[indmix['cat'] == 'usualwfh'][['indus', 'pct']] -indmix2 = indmix[indmix['cat'] == 'tc14'][['indus', 'pct']] - -# merge naics2, income4, edu, get workers -dfpop = dfpop.merge(indpxwalk, on='INDP', how='left') -dfpop = dfpop.merge(dfhh[['household_id', 'HINCP19']], on='household_id', how='left') -dfpop['inccat4'] = pd.cut(dfpop.HINCP19, bins=[-99999, 30000, 60000, 100000, 2000000], right=False, labels=[1, 2, 3, 4]) - -workers = dfpop[dfpop['JWTR'] != 'bb'].copy() -workers.JWTR = workers.JWTR.astype(float).astype(int) -workers.SCHL = workers.SCHL.astype(float).astype(int) -workers.loc[workers.SCHL.isin([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]), 'edu'] = 1 -workers.loc[workers.SCHL.isin([18, 19, 20]), 'edu'] = 2 -workers.loc[workers.SCHL.isin([21, 22, 23, 24]), 'edu'] = 3 -workers.loc[:, 'selected'] = 0 - -# overall targets -targetwfh = round(len(workers) * usualwfhpct, 0) -targettc14 = round(len(workers) * tc14pct, 0) - -workers = workers[workers['ESR'] != '4'] - -# functions -def portionout(df, pctcol, total, colname): - """ - divides up a total based on a percent column into a new column (no decimals) - :param df: input dataframe - :param pctcol: name of column that has percentages - :param total: can be name of column that has totals, or a numeric total that the percentages will be applied to - :param colname: the name of the result column - :return: dataframe with targetdec, targetint, decimal, and colname columns - """ - df = df.copy() - indcounts = workers[workers.selected == 0].groupby('naics2').agg({'household_id':'count'}).reset_index() - indcounts.rename({'household_id':'sectortotal'}, axis=1, inplace=True) - - - if isinstance(total, int) or isinstance(total, float): - df['targetdec'] = df[pctcol] * total - - df2 = df.merge(indcounts, left_on='indus', right_on='naics2') - df2['testtot'] = df2['sectortotal'] - df2['targetdec'] - - if len(df2[df2.testtot < 0]) == 0: - pass - else: - # don't go all the way up to max to prevent same issue further down the line - df2.loc[df2.testtot < 0, 'newpct'] = (df2.sectortotal - 10) / total - df2.loc[df2.testtot < 0, 'pctdiff'] = df2[pctcol] - df2.newpct - todistribute = df2.pctdiff.sum() - # normalize unchanged pcts to one to distribute out the missing pct - newdenom = 1 - df2.loc[df2.testtot < 0][pctcol].sum() - df2.loc[df2.testtot >=0, 'pctfordist'] = df2[pctcol] / newdenom - df2.loc[df2.testtot >= 0, 'newpct'] = (df2.pctfordist * todistribute) + df2[pctcol] - df2[pctcol] = df2['newpct'] - df2['targetdec'] = df2[pctcol] * total - - df2['targetint'] = df2['targetdec'].astype('int') - df2['decimal'] = df2['targetdec'] - df2['targetint'] - leftover = total - df2['targetint'].sum() - df2.sort_values('decimal', ascending=False, inplace=True) - df2.reset_index(drop=True, inplace=True) - df2.loc[df2.index < leftover, 'targetint'] = df2.targetint + 1 - assert (total - df2.targetint.sum()) == 0, "Targets do not sum to total" - df2.rename({'targetint': colname}, axis=1, inplace=True) - return df2 - - elif isinstance(total, str): - df['targetdec'] = df[pctcol] * df[total] - - df2 = df.merge(indcounts, left_on='indus', right_on='naics2') - df2['testtot'] = df2['sectortotal'] - df2['targetdec'] - - if len(df2[df2.testtot < 0]) == 0: - pass - else: - df2.loc[df2.testtot < 0, 'newpct'] = (df2.sectortotal - 10) / df[total] - df2.loc[df2.testtot < 0, 'pctdiff'] = df2[pctcol] - df2.newpct - todistribute = df2.pctdiff.sum() - df2.loc[df2.testtot >= 0, 'newpct'] = df2[pctcol] * (1 + todistribute) - df2[pctcol] = df2['newpct'] - df2['targetdec'] = df2[pctcol] * df2[total] - - df2['targetint'] = df2['targetdec'].astype('int') - df2['decimal'] = df2['targetdec'] - df2['targetint'] - - totallist = [x for x in df2[total].unique()] - piecelist = [] - for i in totallist: - selection = df2[df2[total] == i].copy() - leftover = i - selection['targetint'].sum() - if leftover != 0: - selection.sort_values('decimal', ascending=False, inplace=True) - selection.reset_index(drop=True, inplace=True) - selection.loc[selection.index < leftover, 'targetint'] = selection.targetint + 1 - assert (i - selection.targetint.sum()) == 0, "Targets do not sum to total" - piecelist.append(selection) - df2 = pd.concat(piecelist) - df2.rename({'targetint': colname}, axis=1, inplace=True) - return df2 - - -def settargets(indmix, overalltarget): - """ - use portionout function to set industry/income targets for group of interest (usualwfh or tc14) - :param indmix: input df with distribution of people in group of interest into industries - :param overalltarget: total target value for people in group of interest - :return: - """ - indmixfinal = portionout(indmix, 'pct', overalltarget, 'indint') - - # income targets - indmixfinal.loc[indmixfinal['indus'].isin(lowlist), 'incdist'] = 'low' - indmixfinal.loc[indmixfinal['indus'].isin(highlist), 'incdist'] = 'high' - targets = indmixfinal[['indus', 'pct', 'indint', 'incdist']].merge(incdist, on='incdist', how='left') - finaltargets = portionout(targets, 'pct_y', 'indint', 'indincint') - finaltargets.reset_index(drop=True, inplace=True) - - return finaltargets - - -def jwtr11flag(targetdf, workerdf, flagvalue): - """ - flag workers in workerdf with jwtr11 with the flagvalue according to counts in targetdf - :param targetdf: guiding dataframe with targets values for each category - :param workerdf: worker df with selected flag column - :param flagvalue: the value to set the selected column to - :return:workerdf - """ - for i, row in targetdf.iterrows(): - ind = row['indus'] - inc4 = row['hhinc4'] - target = row['indincint'] - options = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & ( - workerdf['inccat4'] == inc4) & (workerdf['JWTR'] == 11)] - if len(options) > target: - ilist = [x for x in options.sample(target, random_state=seedvalue).index.values] - workerdf.loc[workerdf.index.isin(ilist), 'selected'] = flagvalue - else: - ilist2 = [x for x in options.index.values] - workerdf.loc[workerdf.index.isin(ilist2), 'selected'] = flagvalue - - return workerdf - - - -def preproundtwo(workerdf, flagvalue, eduweights, targets): - """ - prepare for roundtwo assignment by calculating numbers still needed and adding eduwgt column - :param workerdf: worker df with selected flag column - :param flagvalue: value in the 'selected' column to evaluate - :param eduweights: weights to apply based on edu field for use in sampling - :return: b, workerdf. b is the new guiding df that lists how many are still needed in each category - """ - result = workerdf[workerdf['selected'] == flagvalue].groupby(['naics2', 'inccat4']). \ - household_id.count().reset_index() - - # calculate number still needed in each category - comparison = targets.merge(result, left_on=['indus', 'hhinc4'], - right_on=['naics2', 'inccat4'], how='left').reset_index() - comparison.household_id.fillna(0, inplace=True) - comparison['needed'] = comparison['indincint'] - comparison['household_id'] - b = comparison[comparison['needed'] > 0] - workerdf = workerdf.merge(comparison[['indus', 'hhinc4', 'needed']], - left_on=['naics2', 'inccat4'], right_on=['indus', 'hhinc4'], how='left') - workerdf.loc[workerdf['edu'] == 1, 'eduwgt'] = eduweights[0] - workerdf.loc[workerdf['edu'] == 2, 'eduwgt'] = eduweights[1] - workerdf.loc[workerdf['edu'] == 3, 'eduwgt'] = eduweights[2] - - return b, workerdf - - -def roundtwo(dfb, workerdf, flagvalue): - """ - finish flagging workers to meet target values (outside of jwtr == 11) using eduwgt column - :param dfb: guiding dataframe with targets values for each category - :param workerdf: worker df with selected flag column - :param flagvalue: value to set 'selected' column to - :return: workerdf - """ - dolater = {} - - for i, row in dfb.iterrows(): - ind = row['indus'] - inc4 = row['hhinc4'] - target = int(row['needed']) - options = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & ( - workerdf['inccat4'] == inc4)] - - if len(options) >= target: - ilist = [x for x in options.sample(target, weights='eduwgt', random_state=seedvalue).index.values] - workerdf.loc[workerdf.index.isin(ilist), 'selected'] = flagvalue - elif len(options) < target: - dolater[i] = (ind,inc4,target) - - - if len(dolater) > 0: - donow = pd.DataFrame.from_dict(dolater, orient='index', columns=['ind','inc','target']) - for i,row in donow.iterrows(): - ind = row['ind'] - inc4 = row['inc'] - target = int(row['target']) - options = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & ( - workerdf['inccat4'] == inc4)] - ilist = [x for x in options.index.values] - stillneed = target - len(ilist) - options2 = workerdf[(workerdf['naics2'] == ind) & (workerdf['selected'] == 0) & (workerdf.inccat4 != inc4)] - ilist.extend([x for x in options2.sample(stillneed).index.values]) - - workerdf.loc[workerdf.index.isin(ilist), 'selected'] = flagvalue - - return workerdf - - -########################################## -# part one: usualwfh -########################################## - -# industry targets -finaltargets1 = settargets(indmix1, targetwfh) - -print('selecting usualwfh from JWTR 11...') -# round one -workers = jwtr11flag(finaltargets1, workers, 1) - -# round two -b1, workers = preproundtwo(workers, 1, eduw, finaltargets1) - -print('selecting usualwfh from any...') -workers = roundtwo(b1, workers, 1) - -current = workers.selected.sum() -remaining = int(targetwfh - current) -print('checking overall usualwfh target met...') -assert remaining == 0, "overall usualwfh target not met" -workers = workers.drop(['indus', 'hhinc4', 'needed', 'eduwgt'], axis=1) - -########################################## -# part two: tc14 -########################################## - -# industry targets -finaltargets2 = settargets(indmix2, targettc14) - -print('selecting tc14 from JWTR 11...') -# round one -workers = jwtr11flag(finaltargets2, workers, 2) - -# round two -b2, workers = preproundtwo(workers, 2, eduwtc, finaltargets2) - -print('selecting tc14 from any...') -workers = roundtwo(b2, workers, 2) - -current = len(workers[workers['selected'] == 2]) -remaining = int(targettc14 - current) -print('checking overall tc14 target met...') -assert remaining == 0, "overall tc14 target not met" - -########################################## -# assign tc14 wfh status for given day -########################################## -print('assigning wfh status for tc14...') -workers['tc'] = 0 - -tc1 = targettc14 * tcportions[0] -tc2 = targettc14 * tcportions[1] -tc3 = targettc14 * tcportions[2] -tc4 = targettc14 * tcportions[3] - -count = 4 -for t in [tc4, tc3, tc2]: - options = workers[(workers['selected'] == 2) & (workers['tc'] == 0)] - it = int(t) - ilist = [x for x in options.sample(it, random_state=seedvalue).index.values] - workers.loc[workers.index.isin(ilist), 'tc'] = count - count -= 1 - -workers.loc[(workers['selected'] == 2) & (workers['tc'] == 0), 'tc'] = 1 - -workers['random'] = np.random.random(size=len(workers)) -workers.loc[(workers['selected'] == 2) & (workers['random'] < (workers['tc'] / 5)), 'working'] = 1 -workers.working.fillna(0, inplace=True) - -########################################## -# format and save -########################################## -print('preparing and saving HH_WFH_STATUS.csv...') -popsynhh = pd.read_csv(popsynhhpath, names=['sz', 'hhtype', 'vehicles', - 'serialno', 'stpuma5', 'rowcol', 'adults', 'workers', - 'children', 'iq', 'age', 'hhvtype', 'income']) -workers.loc[workers['selected'] == 1, 'usualwfh'] = 1 -workers.loc[(workers['selected'] == 2) & (workers['working'] == 1), 'tc14'] = 1 -workers.loc[(workers['selected'] == 2) & (workers['working'] == 0), 'tc14nw'] = 1 -workers.usualwfh.fillna(0, inplace=True) -workers.tc14.fillna(0, inplace=True) -workers.tc14nw.fillna(0, inplace=True) -hhsummary = workers.groupby('household_id').agg({'usualwfh':'sum','tc14':'sum','tc14nw':'max'}).reset_index() -hhsummary['wfhworkers'] = hhsummary['tc14'] + hhsummary['usualwfh'] -hhsummary.loc[(hhsummary['tc14'] > 0) & (hhsummary['usualwfh'] > 0), 'finalflag'] = 1 -hhsummary.loc[(hhsummary['tc14'] > 0) & (hhsummary['usualwfh'] == 0), 'finalflag'] = 2 -hhsummary.loc[(hhsummary['tc14'] == 0) & (hhsummary['usualwfh'] > 0), 'finalflag'] = 1 -final1 = dfhh[['household_id','SERIALNO']].merge(hhsummary[['household_id','finalflag','wfhworkers','tc14nw']],on='household_id', how='left') -final1.finalflag.fillna(0, inplace=True) -try: - final1['SERIALNO'] = final1['SERIALNO'].str.replace('HU','99') -except AttributeError: - pass -final1sort = final1.sort_values('SERIALNO').reset_index() - -pssort = popsynhh.sort_values('serialno').reset_index() -final1sort['newindex'] = pssort['index'] -final1sort['sn2'] = pssort['serialno'] -final1sort.sort_values('newindex', inplace=True) -final1sort.set_index('newindex', inplace=True) -final1sort['SERIALNO'] = final1sort.SERIALNO.astype('int64') -final1sort['diffcheck'] = final1sort['SERIALNO'] - final1sort['sn2'] -assert (final1sort.diffcheck == 0).all(), "file not aligned with popsyn_hh" -final1sort.wfhworkers.fillna(0, inplace=True) -final1sort.tc14nw.fillna(0, inplace=True) -final1sort['finalflag'] = final1sort.finalflag.astype('int') -final1sort['wfhworkers'] = final1sort.wfhworkers.astype('int') -final1sort['tc14nw'] = final1sort.tc14nw.astype('int') -final1sort[['SERIALNO', 'finalflag','wfhworkers','tc14nw']].to_csv(savedir + "/HH_WFH_STATUS.CSV", index=False, header=False) - -########################################## -# save additional files -########################################## - -if savefiles == "Y": - print('saving additional files...') - workers.to_csv("workers.csv", index=False) - finaltargets1.to_csv("finaltargets_usualwfh.csv", index=False) - finaltargets2.to_csv("finaltargets_tc14.csv", index=False) \ No newline at end of file diff --git a/Database/tg/scripts/summarize_tg_results.py b/Database/tg/scripts/summarize_tg_results.py index 5bbdce7..da062db 100644 --- a/Database/tg/scripts/summarize_tg_results.py +++ b/Database/tg/scripts/summarize_tg_results.py @@ -1,6 +1,6 @@ """ summarize_tg_results.py -06/12/2025 +05/22/2020 N. Ferguson Reads data files from the trip generation model and creates a dataset @@ -8,7 +8,6 @@ Revision history ---------------- -06/12/2025 Heither: revised line 103 to identify correct columns in new file layout 05/22/2020 Ferguson: Adapted from summary_tg_results_popsyn.sas. 08/13/2020 Ferguson: Corrected error in P-A to O-D format conversion affecting non-home attractions. @@ -101,7 +100,7 @@ labels_bin = {'1': 'yes', '0': 'no'} # Households -hh = pd.read_csv(pth_hh, header=None, usecols=[0, 12, 13]) +hh = pd.read_csv(pth_hh, header=None, usecols=[0, 34, 35]) hh.columns = ['subzone17', 'wrkautoms', 'sdwlkidx'] labels_hh = dict( subzone17 = 'subzone', @@ -180,7 +179,7 @@ widths=[6, 6, 2, 9, 9], names=['subzone17', 'zone17', 'trip_type', 'hh_prods', 'hh_attrs'] ) -trip = pd.concat([not_wfh_trip, wfh_trip], ignore_index=True) +trip = not_wfh_trip.append(wfh_trip) trip = trip.groupby(['subzone17', 'zone17', 'trip_type']).sum().reset_index() # Calculate TAZ median household income diff --git a/Database/tg/scripts/urbansim_hcv_allocation.py b/Database/tg/scripts/urbansim_hcv_allocation.py index c79e1c2..c38d084 100644 --- a/Database/tg/scripts/urbansim_hcv_allocation.py +++ b/Database/tg/scripts/urbansim_hcv_allocation.py @@ -1,20 +1,15 @@ ''' ##################################################################################### URBANSIM_HCV_ALLOCATION.PY - Craig Heither, rev. 07-21-2025 - Karly Cazzato, rev. 01-21-2026 - - Script reads subzone employment by NAICS from UrbanSim files and uses it to develop - allocation weights for heavy commercial vehicle trips. NAICS-level employment - is paired with trips/employee by NAICS estimates and weighted by the zonal share - of 2020 building squarefeet. If no buildings exist in the zone in 2020 then a county average - zonal share of building sqft is applied to ensure future employment in the zones is - considered. External zones were assigned a zonal share of building sqft based on - an internal zone with a similar trip truck generation rate based on the ATRI - calibration dataset. These weighted values are then scaled up to realistic trip volumes. - A file of estimated 2018 truck trips from rail intermodal facilities is also included to - address a gap in the methodology. This ensures the allocation is consistent with the - forecast growth in HCV-dependent land uses. + Craig Heither, rev. 03-28-2022 + + Script reads the scenario buildings file from UrbanSim and uses it to develop + allocation weights for heavy commercial vehicle trips. For the external area, + subzone employment by NAICS is used (along with sqft per worker and truck trip + rates) to develop heavy truck trips. A file of estimated 2018 truck trips from + rail intermodal facilities is also included to address a gap in the methodology. + This ensures the allocation is consistent with the forecast growth in HCV-dependent + land uses. ##################################################################################### ''' @@ -24,104 +19,106 @@ # ---------------------------------------------------------------------------- import os, pandas as pd, csv import fnmatch ##-- filter files in directory -import numpy as np + cmapSubzone = 16426 ##-- maximum internal CMAP subzone -maxZone = 2926 -total_wgt = 564043.02617679 # From ATRI calibration dataset, total weight value for all internal and external truck trips; used to scale final weights to realistic value so intermodal can be added in - + + # ---------------------------------------------------------------------------- # Input files. # ---------------------------------------------------------------------------- USpth ="..\\UrbanSim_inputs" ## -- create a list of the UrbanSim files to be processed -- ## -d1 = fnmatch.filter(os.listdir(USpth), '*subzonetm*') ##-- subzone files +d1 = fnmatch.filter(os.listdir(USpth), '*buildings*') ##-- 7 county +d2 = fnmatch.filter(os.listdir(USpth), '*xsubzonetm*') ##-- external area +dirListing = d1 + d2 newFiles = [] -for item in d1: +for item in dirListing: newFiles.append(USpth+"\\"+item) # geog = "..\\fortran\\GEOG_IN.TXT" +# +rates = "..\\..\\data\\hcv_tg_rates.txt" ##-- heavy truck trip rates +corresp = "..\\..\\data\\hcv_building_naics_corresp.csv" ##-- NAICS-building type correspondence +jobsqft = "..\\..\\data\\hcv_sqft_per_job.csv" ##-- average square feet per job imx = "..\\..\\data\\hcv_intermodal.csv" ##-- estimate of 2018 truck trips for intermodal facilities -in_naicsRates = "..\\..\\data\\tg_rates.csv" ##-- estimated trips/employee by NAICS code -in_build_props = "..\\..\\data\\land_use_proportions.csv" ##-- proportion of building sqft in zone of all building sqft in CMAP region + # ---------------------------------------------------------------------------- # Output files. # ---------------------------------------------------------------------------- +chk2 = "..\\..\\data\\chk2.csv" mo20 = "..\\..\\data\\mo20.txt" -print("Subzone files: {0}".format(newFiles)) +print("Building files: {0}".format(newFiles)) + # ---------------------------------------------------------------------------- -# Read subzone employment, geographic correspondence and truck trip rates. +# Calculate allocation weights for CMAP 7 counties. # ---------------------------------------------------------------------------- +## -- Start with CMAP 7-county buildings -- ## +bldg1 = pd.read_csv(newFiles[0], sep=',') ##-- CMAP buildings +print(" --> CMAP Buildings: {0}".format(bldg1.shape[0])) +test = bldg1[bldg1['subzone_id'] < 5] +##test.to_csv(chk1,index=False) + ## -- Read in GEOG_IN to attach Zones -- ## geo = pd.read_csv(geog, sep=',', header=None, usecols=[0, 5]) geo.columns=['subzone_id','zone'] print(" --> GEOG_IN subzone summary Rows: {0}".format(geo.shape[0])) + +## -- Read in truck trip rates file -- ## +rate = pd.read_csv(rates, sep=',') +rate.to_csv(chk2,index=False) +bldg1 = bldg1.merge(geo, how='left', on='subzone_id', copy=False) +bldg1 = bldg1.merge(rate, how='left', on='building_type_id', copy=False) # -## -- Read in trips/employee by NAICS -- ## -naicsRates = pd.read_csv(in_naicsRates, sep=',') +## -- Calculate HCV allocation weights -- ## +bldg1['hcvWgt'] = bldg1['non_residential_sqft'] * bldg1['hcv_rate'] / 1000 ##-- rates per 1000 sqft +hcv1 = bldg1.groupby(['zone']).agg({'hcvWgt': 'sum'}).round(4).reset_index() + + +# ---------------------------------------------------------------------------- +# Calculate allocation weights for external area. +# ---------------------------------------------------------------------------- +extern = pd.read_csv(newFiles[1], usecols=['subzone_id','num_jobs_sector_11','num_jobs_sector_21','num_jobs_sector_22','num_jobs_sector_23', + 'num_jobs_sector_31','num_jobs_sector_42','num_jobs_sector_44','num_jobs_sector_48','num_jobs_sector_51','num_jobs_sector_52','num_jobs_sector_53', + 'num_jobs_sector_54','num_jobs_sector_55','num_jobs_sector_56','num_jobs_sector_61','num_jobs_sector_62','num_jobs_sector_71','num_jobs_sector_72', + 'num_jobs_sector_81','num_jobs_sector_92'], sep=',') ##-- external subzones +ext1 = extern[extern['subzone_id'] > cmapSubzone] ##-- Ensure only external subzones +print(" --> External subzone summary Rows: {0}".format(ext1.shape[0])) +## -- Convert from wide to long -- ## +external = pd.melt(ext1, id_vars='subzone_id') +external['NAICS1'] = external['variable'].str[-2:].astype(int) ##-- extract NAICS code # -## -- Read in zonal share of building sqft -- ## -landUse = pd.read_csv(in_build_props, sep=',') +## -- Attach likely building types to NAICS employment (Cartesian join)-- ## +bldgType = pd.read_csv(corresp, usecols=['building_type_id', 'NAICS'], sep=',') +externalCart = external.merge(bldgType, how='cross') +external = externalCart[externalCart['NAICS1'] == externalCart['NAICS']] ##-- keep only true NAICS matches +print(" --> External subzone summary Rows after building types attached: {0}".format(external.shape[0])) # -intmod = pd.read_csv(imx, usecols=['zone','hcvWgt'], sep=',') -# +## -- Calculate square feet by industry for each subzone -- ## +jbsqft = pd.read_csv(jobsqft, usecols=['building_type_id', 'building_sqft_per_job'], sep=',') +external = external.merge(jbsqft, how='left', on='building_type_id', copy=False) +external['non_residential_sqft'] = external['building_sqft_per_job'] * external['value'] # -## -- Read in subzone employment -- ## -goodCols = ['subzone_id','num_jobs_sector_11','num_jobs_sector_21','num_jobs_sector_22','num_jobs_sector_23', - 'num_jobs_sector_31','num_jobs_sector_42','num_jobs_sector_44','num_jobs_sector_48','num_jobs_sector_51','num_jobs_sector_52','num_jobs_sector_53', - 'num_jobs_sector_54','num_jobs_sector_55','num_jobs_sector_56','num_jobs_sector_61','num_jobs_sector_62','num_jobs_sector_71','num_jobs_sector_72', - 'num_jobs_sector_81','num_jobs_sector_92'] -cmap = pd.read_csv(newFiles[0], usecols=goodCols, sep=',') ##-- CMAP 7-county subzones -cmap = cmap[cmap.subzone_id.le(cmapSubzone)] ##-- ensure only CMAP 7-county subzones -print(" --> CMAP subzones: {0:,}".format(cmap.shape[0])) -print(' --> QC: CMAP subzone id is unique: {0}'.format(cmap.subzone_id.is_unique)) +## -- Use NAICS-building type correspondence file to determine average truck trip rate per industry -- ## +external = external.merge(rate, how='left', on='building_type_id', copy=False) +external['hcvWgt'] = external['non_residential_sqft'] * external['hcv_rate'] / 1000 ##-- rates per 1000 sqft # -extern = pd.read_csv(newFiles[1], usecols=goodCols, sep=',') ##-- external subzones -extern = extern[extern.subzone_id.gt(cmapSubzone)] ##-- Ensure only external subzones -print(" --> External subzones: {0:,}".format(extern.shape[0])) -print(' --> QC: External subzone id is unique: {0}'.format(extern.subzone_id.is_unique)) -sz = pd.concat([cmap,extern], ignore_index=True, sort=False) -print(" --> Total subzones: {0:,}".format(sz.shape[0])) -print(' --> QC: subzone id is unique: {0}'.format(sz.subzone_id.is_unique)) - +## -- We do not know what the actual building types are so use the average trip rate per subzone-NAICS combination to estimate -- ## +hcv2a = external.groupby(['subzone_id','NAICS']).agg({'hcvWgt': 'mean'}).round(4).reset_index() # -# ---------------------------------------------------------------------------- -# Calculate allocation weights for internal and external area. -# ---------------------------------------------------------------------------- -emp = pd.melt(sz, id_vars='subzone_id') -emp['NAICS'] = emp['variable'].str[-2:].astype(int) ##-- extract NAICS code +## -- Now calculate zonal values -- ## +hcv2a = hcv2a.merge(geo, how='left', on='subzone_id', copy=False) +hcv2 = hcv2a.groupby(['zone']).agg({'hcvWgt': 'sum'}).round(4).reset_index() -# Merge subzones with zone crosswalk -internal = emp.merge(geo, how='left', on='subzone_id', copy=False) - -# Aggregate employment by NAICS to zone level -zn_internal=internal.groupby(['zone', 'NAICS']).agg({'value': 'sum'}).reset_index() - -# Apply trips/employee rates by NAICS -naics_emp = zn_internal.merge(naicsRates, how='left', on=['NAICS']) -naics_emp['hcvWgt_1']=naics_emp['trips_emp']*naics_emp['value'].round(4) - -# Apply land use adjustment -naics_emp=naics_emp.merge(landUse, how='left', left_on='zone', right_on='zone17') -naics_emp['propArea'] = np.where(naics_emp['propArea'].isnull(), naics_emp['propArea'].min(), naics_emp['propArea']) -naics_emp['hcvWgt_o']=naics_emp['hcvWgt_1']*naics_emp['propArea'] -naics_emp=naics_emp[['zone', 'NAICS', 'value', 'hcvWgt_o']].copy() - -# Find shares of developed weights, and apply to total weight to find adjusted weight -naics_emp['total'] = naics_emp['hcvWgt_o'].sum() -naics_emp['prop'] = naics_emp['hcvWgt_o']/naics_emp['total'] -naics_emp['hcvWgt'] = naics_emp['prop'] *total_wgt - -zn_wt = naics_emp[['zone', 'hcvWgt']].copy() -zn_wt = zn_wt.groupby(['zone']).agg({'hcvWgt': 'sum'}).round(4).reset_index() # ---------------------------------------------------------------------------- # Create allocation weight file. # ---------------------------------------------------------------------------- ## -- Add estimate of truck trips for intermodal facilities since building sqft won't quite cover these -- ## -a = pd.concat([intmod, zn_wt]) +intmod = pd.read_csv(imx, usecols=['zone','hcvWgt'], sep=',') +a = pd.concat([hcv1,hcv2,intmod]) hcv = a.groupby(['zone']).agg({'hcvWgt': 'sum'}).round(4).reset_index() # ## -- Create a template with all zones -- ## @@ -139,6 +136,7 @@ geo1['a1'] = 'all:' geo1.sort_values(by=['zone'], inplace=True) +##geo1.to_csv(chk2,index=False) f = open(mo20,'w') print("t matrices \nd matrix=mo20 \na matrix=mo20 htrkseed 0 heavy truck allocation seed matrix", file=f) diff --git a/Database/tg/scripts/urbansim_skims.py b/Database/tg/scripts/urbansim_skims.py index c8c22f2..18afed8 100644 --- a/Database/tg/scripts/urbansim_skims.py +++ b/Database/tg/scripts/urbansim_skims.py @@ -14,15 +14,13 @@ # ---------------------------------------------------------------------------- import os, numpy as np, pandas as pd -cwd = os.getcwd() +hwyTime = os.getcwd() + "\\emmemat\\mf44.emx" ## -- Congested highway skim time +tranTime = os.getcwd() + "\\emmemat\\mf822.emx" ## -- Indexed peak in-vehicle minutes +tranXfer = os.getcwd() + "\\emmemat\\mf823.emx" ## -- Indexed peak walk transfer minutes +tranWait = os.getcwd() + "\\emmemat\\mf824.emx" ## -- Indexed wait time minutes -hwyTime = cwd + "\\emmemat\\mf44.emx" ## -- Congested highway skim time -tranTime = cwd + "\\emmemat\\mf822.emx" ## -- Indexed peak in-vehicle minutes -tranXfer = cwd + "\\emmemat\\mf823.emx" ## -- Indexed peak walk transfer minutes -tranWait = cwd + "\\emmemat\\mf824.emx" ## -- Indexed wait time minutes - -outFolder = cwd + "\\data\\UrbanSim_skims" ## -- output folder for skims -outFile = outFolder + "\\skims.parquet" +outFolder = os.getcwd() + "\\data\\UrbanSim_skims" ## -- output folder for skims +outFile = outFolder + "\\skims.csv" maxZone = 3649 ## -- maximum zone number maxInternal = 3632 ## -- maximum non-POE zone @@ -69,18 +67,4 @@ skims['am_peak_transit_time'] = skims['InVehicle'] + skims['Walk_time'] + skims['Wait_time'] skims['am_peak_transit_time'] = np.where(skims['am_peak_transit_time'] > 1000.0, 1000000.0, skims['am_peak_transit_time']) ##-- replace 1.00E20 with 1000000 to show no transit path exists skims = skims.round({'am_peak_travel_time': 2, 'am_peak_transit_time': 2}) - -# skims.to_csv(outFile, columns=['from_zone_id','to_zone_id','am_peak_travel_time','am_peak_transit_time'], index=False) - -#NEW in 2026: set from/to as index, rename columns, then write as parquet instead of csv -skims.rename( - columns={ - 'am_peak_travel_time': 'travel_time_sov', - 'am_peak_transit_time': 'travel_time_transit' - }, - inplace=True -) - -skims.set_index(['from_zone_id', 'to_zone_id'], inplace=True) - -skims[['travel_time_sov', 'travel_time_transit']].to_parquet(outFile) \ No newline at end of file +skims.to_csv(outFile, columns=['from_zone_id','to_zone_id','am_peak_travel_time','am_peak_transit_time'], index=False) diff --git a/Database/tg/scripts/urbansim_update_tg_input_files.py b/Database/tg/scripts/urbansim_update_tg_input_files.py index da124fa..5f44631 100644 --- a/Database/tg/scripts/urbansim_update_tg_input_files.py +++ b/Database/tg/scripts/urbansim_update_tg_input_files.py @@ -1,419 +1,237 @@ ''' -######################################################################################################## +##################################################################################### URBANSIM_UPDATE_TG_INPUT_FILES.PY - Craig Heither, rev. 01-31-2026 + Craig Heither, rev. 01-11-2022 Script reads output files from UrbanSim and uses the data to create new versions - of ATTR_IN.TXT, HH_IN.TXT, GQ_IN.TXT and POPSYN_HH.CSV that the Trip Generation - model will use. + of ATTR_IN.TXT, HH_IN.TXT and POPSYN_HH.CSV that the Trip Generation model will + use. - Additonal data cleanup steps for 2026 LRTP: - - if necessary, set household_id to unique values across the CMAP & external files - - if necessary, remove persons from the files that are not in households in the household files - - if necessary, updates hhtype and hhvtype for households with no report_fileadults - -######################################################################################################## +##################################################################################### ''' # ---------------------------------------------------------------------------- # Import System Modules and Set Variables. # ---------------------------------------------------------------------------- -import os -import pandas as pd -import numpy as np -import zipfile ##-- to write zip objects -import fnmatch ##-- filter files in directory -import yaml -import math -from pathlib import Path +import os, pandas as pd +import zipfile ##-- to write zip objects +import fnmatch ##-- filter files in directory -with open(Path.cwd().parent.parent.joinpath('batch_file.yaml')) as f: - lines_without_backslashes = ''.join([line.replace('\\','/') for line in f]) - config = yaml.safe_load(lines_without_backslashes) - -puma = config['pumaVersion'] -print("PUMA version: {0}".format(puma)) - -cmapSubzone = 16426 ##-- maximum internal CMAP subzone +cmapSubzone = 16426 ##-- maximum internal CMAP subzone +dollar2010 = 0.855 ##-- CPI value to convert 2019 dollars from UrbanSim to 2010 [https://www.bls.gov/data/inflation_calculator.htm] + ##-- (not used for new trip-based model) # ---------------------------------------------------------------------------- # Input files. # ---------------------------------------------------------------------------- -UrbanSim_path = Path(__file__).resolve().parents[1].joinpath('UrbanSim_inputs') +USpth ="..\\UrbanSim_inputs" +rptFile =USpth + "\\UrbansSim_file_report.TXT" # -fortran_path = Path(__file__).resolve().parents[1].joinpath('fortran') -hhtypeCat_file = fortran_path / 'tg_hhtype_lookup.csv' -hhvtypeCat_file = fortran_path / 'tg_hhvtype_lookup.csv' -geog_file = fortran_path / 'GEOG_IN.TXT' -sz_data = fortran_path / 'subzone_tg_data.txt' - -# ---------------------------------------------------------------------------- -# Output files. -# ---------------------------------------------------------------------------- -noHHID_file = fortran_path / 'persons_missing_HHID_CMAP.csv' -noHHIDext_file = fortran_path / 'persons_missing_HHID_External.csv' -noHHIDany_file = fortran_path / 'persons_missing_HHID.csv' -noHHTYPE_file = fortran_path / 'missing_hhtype.csv' -attr_file = fortran_path / 'ATTR_IN.TXT' -hh_file = fortran_path / 'HH_IN.TXT' -gq_file = fortran_path / 'GQ_IN.TXT' -popsyn_file = fortran_path / 'POPSYN_HH.CSV' +pth2 = "..\\fortran" +attr = pth2 + "\\ATTR_IN.TXT" +hh = pth2 + "\\HH_IN.TXT" +popsyn = pth2 + "\\POPSYN_HH.CSV" +noHH = pth2 + "\\persons_missing_HHID_CMAP.CSV" +noHH2 = pth2 + "\\persons_missing_HHID_External.CSV" +noHH3 = pth2 + "\\persons_missing_HHID.CSV" +# -- files renamed +attr_r = pth2 + "\\ATTR_INr.TXT" +hh_r = pth2 + "\\HH_INr.TXT" +popsyn_r = pth2 + "\\POPSYN_HHr.CSV" # -wfh_path = Path(__file__).resolve().parents[1].joinpath('fortran','wfhmodule') -hhZip_file = wfh_path / 'synthetic_households.zip' -temp1_file = wfh_path / 'synthetic_households.csv' -perZip_file = wfh_path / 'synthetic_persons.zip' -temp2_file = wfh_path / 'synthetic_persons.csv' +geog = pth2 + "\\GEOG_IN.TXT" # -report_file = UrbanSim_path / 'UrbansSim_file_report.txt' +pth3 = "..\\fortran\\wfhmodule\\" +hhZip = pth3 + "\\synthetic_households.zip" +temp1 = pth3 + "synthetic_households.csv" +perZip = pth3 + "\\synthetic_persons.zip" +temp2 = pth3 + "synthetic_persons.csv" + # ---------------------------------------------------------------------------- # Get the UrbanSim input file names. # ---------------------------------------------------------------------------- ## -- create a list of the UrbanSim files to be processed -- ## -d1 = fnmatch.filter(os.listdir(UrbanSim_path), '*hhtm*') -d2 = fnmatch.filter(os.listdir(UrbanSim_path), '*persons*') -d3 = fnmatch.filter(os.listdir(UrbanSim_path), '*subzone*') +d1 = fnmatch.filter(os.listdir(USpth), '*hhtm*') +d2 = fnmatch.filter(os.listdir(USpth), '*persons*') +d3 = fnmatch.filter(os.listdir(USpth), '*subzone*') dirListing = d1 + d2 + d3 -if os.path.exists(report_file): - os.remove(report_file) +if os.path.exists(rptFile): + os.remove(rptFile) newFiles = [] for item in dirListing: - newFiles.append(UrbanSim_path / item) + newFiles.append(USpth+"\\"+item) + +print("{0} {1} {2} {3} {4} {5} \n".format(newFiles[0], newFiles[1], newFiles[2], newFiles[3], newFiles[4], newFiles[5])) -print("{0} \n{1} \n{2} \n{3} \n{4} \n{5} \n".format(newFiles[0], newFiles[1], newFiles[2], - newFiles[3], newFiles[4], newFiles[5])) # ---------------------------------------------------------------------------- # Rename existing TG files prior to update. # ---------------------------------------------------------------------------- -if os.path.exists(hhZip_file): - os.remove(hhZip_file) -if os.path.exists(perZip_file): - os.remove(perZip_file) +origFiles = (attr, hh, popsyn) +renamedFiles = (attr_r, hh_r, popsyn_r) +x = 0 +for f in origFiles: + if os.path.exists(renamedFiles[x]): + os.remove(renamedFiles[x]) + os.rename(origFiles[x],renamedFiles[x]) + x += 1 + +if os.path.exists(hhZip): + os.remove(hhZip) +if os.path.exists(perZip): + os.remove(perZip) + # ---------------------------------------------------------------------------- # Read in the UrbanSim household files. # ---------------------------------------------------------------------------- ## -- HH files are 0 & 1, Person files are 2 & 3, Subzone files are 4 & 5 -hh1 = pd.read_csv(newFiles[0], sep=',') ##-- CMAP households -##hh1 = hh1[hh1.subzone_id.le(cmapSubzone)] ##-- limit to CMAP 7-county subzones -print(" --> CMAP Households: {0:,}".format(hh1.shape[0])) -print(' --> QC: Household id is unique: {0}'.format(hh1.household_id.is_unique)) -print(' --> QC: CMAP household_id Minimum = {0:,}, Maximum = {1:,}'.format( - hh1['household_id'].min(), hh1['household_id'].max())) -print(' --> QC: CMAP subzone_ID Minimum = {0:,}, Maximum = {1:,}'.format( - hh1['subzone_id'].min(), hh1['subzone_id'].max())) -# -hh2=pd.read_csv(newFiles[1], sep=',') ##-- external households -##hh2 = hh2[hh2.subzone_id.gt(cmapSubzone)] ##-- limit to external subzones -print(" --> External Households: {0:,}".format(hh2.shape[0])) -print(' --> QC: Household id is unique: {0}'.format(hh2.household_id.is_unique)) -print(' --> QC: External household_id Minimum = {0:,}, Maximum = {1:,}'.format( - hh2['household_id'].min(), hh2['household_id'].max())) -print(' --> QC: External subzone_ID Minimum = {0:,}, Maximum = {1:,}'.format( - hh2['subzone_id'].min(), hh2['subzone_id'].max())) - -## -- Read in Person files and remove persons not in households in the modeling area -- ## -per1 = pd.read_csv(newFiles[2], sep=',') ##-- CMAP persons -print(" --> CMAP Persons in households: {0:,}".format(per1.shape[0])) -inRegion = hh1[['household_id','subzone_id']].copy() -per1 = per1.merge(inRegion, how='left', on='household_id', copy=False) -##per1 = per1[per1.subzone_id.gt(0)] -print(' --> QC: CMAP household_id Minimum = {0:,}, Maximum = {1:,}'.format( - per1['household_id'].min(), per1['household_id'].max())) -print(' --> QC: CMAP subzone_ID Minimum = {0:,}, Maximum = {1:,}'.format( - per1['subzone_id'].min(), per1['subzone_id'].max())) -print(" --> Confirmed CMAP Persons in households: {0:,}".format(per1.shape[0])) -# -per2 = pd.read_csv(newFiles[3], sep=',') ##-- external persons -print(" --> External Persons in households: {0:,}".format(per2.shape[0])) -inExternal = hh2[['household_id','subzone_id']].copy() -per2 = per2.merge(inExternal, how='left', on='household_id', copy=False) -##per2 = per2[per2.subzone_id.gt(0)] -print(' --> QC: External household_id Minimum = {0:,}, Maximum = {1:,}'.format( - per2['household_id'].min(), per2['household_id'].max())) -print(' --> QC: External subzone_ID Minimum = {0:,}, Maximum = {1:,}'.format( - per2['subzone_id'].min(), per2['subzone_id'].max())) -print(" --> Confirmed External Persons in households: {0:,}".format(per2.shape[0])) - -## -## -- If needed, implement adjustment so all Household_ids are unique -- ## -maxCmapHH = hh1['household_id'].max() -minExternalHH = hh2['household_id'].min() -print(' --> QC: Maximum CMAP Household id: {0:,}, Minimum external Household id: {1:,}'.format( - maxCmapHH, minExternalHH)) - -if minExternalHH < maxCmapHH: - print(' --> FIXING_ISSUE: Implementing adjustment to external files so all Household_ids are unique') - hh2['household_id'] = hh2['household_id'] + maxCmapHH - per2['household_id'] = per2['household_id'] + maxCmapHH - print(' --> FIXING_ISSUE: Done') - -# -## -- Finish processing household files -- ## -hhs = pd.concat([hh1,hh2], ignore_index=True, sort=False) ##-- concatenate the household files -print(' --> QC: Household id is unique: {0}'.format(hhs.household_id.is_unique)) -# Trip Generation model Fortran code expects this sort order -hhs.sort_values(by=['subzone_id', 'hhtype'], ignore_index=True, inplace=True) -# index location in POPSYN_HH (new HH_ID based on row number) -hhs['HH_id'] = hhs.index + 1 -#---------------------------------------------------------------------------------------------------# -### --- Missing hhtype and hhvtype --- ### -# The TBM trip generation model requires households to have at least one adult (age 16+). -# In some PUMS records, the head of household is 15. This code block corrects the issue for the TBM. -nullHHTYPE = hhs[hhs['hhtype'].isnull()] -if nullHHTYPE.shape[0] > 0: - nullHHTYPE.to_csv(noHHTYPE_file, index=False) ##-- file of households where hhtype & hhvtype is corrected -### --- Adjust household types -- ### -hhs.loc[hhs['adults'] == 0, 'children_15_under'] = hhs['children_15_under'] - 1 ##-- reclassify one child as an adult -hhs.loc[hhs['adults'] == 0, 'adults'] = 1 -### --- Update hhtype --- ### -hhtype = pd.read_csv(hhtypeCat_file, sep=',') ##-- hhtype definitions -### --- set category values --- ### -hhs['ADULT'] = hhs['adults'] -hhs.loc[hhs['adults'] > 4, 'ADULT'] = 4 -hhs['WORKER'] = hhs['adult_workers'] -hhs.loc[hhs['adult_workers'] > 3, 'WORKER'] = 3 -hhs['CHILD'] = hhs['children_15_under'] -hhs.loc[hhs['children_15_under'] > 3, 'CHILD'] = 3 -hhs['INCOME'] = hhs['income_category'] -hhs['AGE_INDEX'] = hhs['age_of_head_category'] -hhs['VEH'] = hhs['cars'] -hhs.loc[hhs['cars'] > 3, 'VEH'] = 3 -# -hhs = hhs.merge(hhtype, how='left', on=['ADULT','WORKER','CHILD','AGE_INDEX','INCOME'], copy=False) -hhs.loc[hhs['hhtype'].isnull(), 'hhtype'] = hhs['HHTYPE'] -### --- Update hhtype --- ### -hhvtype = pd.read_csv(hhvtypeCat_file, sep=',') ##-- hhvtype definitions -hhs = hhs.merge(hhvtype, how='left', on=['ADULT','WORKER','CHILD','AGE_INDEX','VEH'], copy=False) -hhs.loc[hhs['hhvtype'].isnull(), 'hhvtype'] = hhs['HHVTYPE'] -hhs.drop(['ADULT','WORKER','CHILD','AGE_INDEX','INCOME','VEH','HHTYPE','HHVTYPE'], axis=1, inplace=True) -#---------------------------------------------------------------------------------------------------------------------# - -### --- Convert SERIALNO to integers --- ### -hhs['serialno'] = hhs['serialno'].astype(str).str.replace('HU', '99', regex=False) -hhs['serialno'] = hhs['serialno'].astype(np.int64) -print(" --> Total Households: {0:,}".format(hhs.shape[0])) +hh1 = pd.read_csv(newFiles[0], sep=',') ##-- CMAP households +print(" --> CMAP Households: {0}".format(hh1.shape[0])) +hh2=pd.read_csv(newFiles[1], sep=',') ##-- external households +print(" --> External Households: {0}".format(hh2.shape[0])) +hhs = pd.concat([hh1,hh2],ignore_index=True,sort=False) ##-- concatenate the household files +print(" --> Total Households: {0}".format(hhs.shape[0])) +##hhs['income_2019_usd'] = hhs['income_2019_usd'] * dollar2010 ##-- For Current set up, convert 2019 dollars to 2010 - commented out for new TBM hhs['income_2019_usd'] = round(hhs['income_2019_usd'],2) -## -- Read in GEOG_IN to fill in RowCol -- ## -geo = pd.read_csv(geog_file, sep=',', header=None) -geo.columns=['subzone_id','county','cntyname','state','stpuma5','zone','chicago','cbd', - 'rowcol','area','cmap'] -# get stpuma5 and rowcol to attach to UrbanSim data -geoSumry = geo.groupby('subzone_id')[['rowcol']].mean() -print(" --> GEOG_IN subzone summary Rows: {0:,}".format(geoSumry.shape[0])) -szTemplate = geo[['subzone_id']].copy() +## -- Read in GEOG_IN to fill in PUMA nd RowCol -- ## +geo = pd.read_csv(geog, sep=',', header=None) +geo.columns=['subzone_id','county','cntyname','state','stpuma5','zone','chicago','cbd','rowcol','area','cmap'] ##-- updated for new TBM FY22 +geoSumry = geo.groupby('subzone_id')[['rowcol']].mean() ##-- get stpuma5 and rowcol to attach to UrbanSim data +print(" --> GEOG_IN subzone summary Rows: {0}".format(geoSumry.shape[0])) ## -- Merge files -- ## hhsData = hhs.merge(geoSumry, how='left', on='subzone_id', copy=False) hhsData['rowcol'] = hhsData['rowcol'].astype(int) hhsData['adults'] = hhsData['adults'].astype(int) hhsData['adult_workers'] = hhsData['adult_workers'].astype(int) hhsData['children_15_under'] = hhsData['children_15_under'].astype(int) - -#urbansim data on or after 2026 has puma_id column -if 'puma_id' in hhsData.columns: - hhsData['puma_id'] = hhsData['puma_id'].astype(int) - -## -- Set 2010 PUMA values, if needed -- ## -if puma == 2010: - geo.eval('puma_id_2010 = floor(county/1000) * 100000 + stpuma5', inplace=True) - geo['puma_id_2010'] = geo['puma_id_2010'].astype(int) - geo2 = geo[['subzone_id', 'puma_id_2010']].copy() - hhsData = hhsData.merge(geo2, how='left', on='subzone_id', copy=False) - - if 'puma_id' in hhsData.columns: - puma_mismatch = hhsData.loc[hhsData['puma_id'].astype(int) != hhsData['puma_id_2010']] - if len(puma_mismatch>0): - print('puma in urbansim input files is 2020. converting to 2010.') - hhsData['puma_id'] = hhsData['puma_id_2010'] - else: - hhsData['puma_id'] = hhsData['puma_id_2010'] - -# Trip Generation model Fortran code expects this sort order -hhsData.sort_values(by=['HH_id'], inplace=True) -print(' --> QC: Household file contains null values: {0}'.format(hhsData.isnull().values.any())) -print(' --> QC: Household Adults Minimum = {0:,}, Maximum = {1:,}'.format(hhsData['adults'].min(), - hhsData['adults'].max())) -print(' --> QC: Household Workers Minimum = {0:,}, Maximum = {1:,}'.format(hhsData['adult_workers'].min(), - hhsData['adult_workers'].max())) -print(' --> QC: Household Children Minimum = {0:,}, Maximum = {1:,}'.format(hhsData['children_15_under'].min(), - hhsData['children_15_under'].max())) -print(' --> QC: Household type categories Minimum = {0:,}, Maximum = {1:,}'.format( - hhsData['hhtype'].min(), hhsData['hhtype'].max())) -hhsData.to_csv(popsyn_file, columns=['subzone_id','hhtype','cars','serialno','puma_id','rowcol','adults', - 'adult_workers','children_15_under','income_category', - 'age_of_head_category','hhvtype','income_2019_usd'], header=False, index=False) +hhsData.sort_values(by=['subzone_id', 'hhtype'], inplace=True) ##-- Trip Generation model Fortran code expects this sort order +hhsData.to_csv(popsyn, columns=['subzone_id','hhtype','cars','serialno','puma_id','rowcol','adults','adult_workers','children_15_under','income_category','age_of_head_category','hhvtype','income_2019_usd'], header=False, index=False) ## -- Create synthetic HH file ... -- ## -hhsData['HINCP19'] = hhsData['income_2019_usd'] -# save household_id & HH_id to link to person file -ids = hhsData[['household_id','HH_id']].copy() -# reset household_id to reflect index position in POPSYN_HH -hhsData['household_id'] = hhsData['HH_id'] +hhsData['HH_id'] = hhsData.reset_index().index + 1 ##-- index location in POPSYN_HH +hhsData['HINCP19'] = hhsData['income_2019_usd'] +ids = hhsData.filter(['household_id','HH_id'], axis=1) ##-- save household_id & HH_id to link to person file +hhsData['household_id'] = hhsData['HH_id'] ##-- reset household_id to reflect index position in POPSYN_HH hhsData['SERIALNO'] = hhsData['serialno'] -hhsData.to_csv(temp1_file , columns=['household_id','HINCP19','SERIALNO'], header=True, index=False) +hhsData.to_csv(temp1, columns=['household_id','HINCP19','SERIALNO'], header=True, index=False) ## -- ... and write zipped file into WFH module. -- ## -with zipfile.ZipFile(hhZip_file , "w", compression=zipfile.ZIP_DEFLATED) as zf: - zf.write(temp1_file , os.path.basename(temp1_file )) -if os.path.exists(temp1_file ): - os.remove(temp1_file ) +with zipfile.ZipFile(hhZip, "w", compression=zipfile.ZIP_DEFLATED) as zf: + zf.write(temp1, os.path.basename(temp1)) +if os.path.exists(temp1): + os.remove(temp1) ## -- Create synthetic Person file ... -- ## -### --- person files already opened +per1 = pd.read_csv(newFiles[2], sep=',') ##-- CMAP persons +per1.drop(['Unnamed: 0'], axis=1, inplace=True) +print(" --> CMAP Persons: {0}".format(per1.shape[0])) nullDf = per1[per1['household_id'].isnull()] -if nullDf.shape[0] > 0: - nullDf.to_csv(noHHID_file, index=False) -# +nullDf.to_csv(noHH, index=False) + +per2 = pd.read_csv(newFiles[3], sep=',') ##-- external persons +per2.drop(['Unnamed: 0'], axis=1, inplace=True) +print(" --> External Persons: {0}".format(per2.shape[0])) nullDf = per2[per2['household_id'].isnull()] -if nullDf.shape[0] > 0: - nullDf.to_csv(noHHIDext_file, index=False) -# -# concatenate the person files -pers = pd.concat([per1,per2],ignore_index=True,sort=False) -print(" --> Total Persons in households: {0:,}".format(pers.shape[0])) -print(' --> QC: Household id is unique: {0}'.format(ids.household_id.is_unique)) -# attach HH_id -persData = pers.merge(ids, how='left', on='household_id', copy=False) +nullDf.to_csv(noHH2, index=False) + +pers = pd.concat([per1,per2],ignore_index=True,sort=False) ##-- concatenate the person files +print(" --> Total Persons: {0}".format(pers.shape[0])) +persData = pers.merge(ids, how='left', on='household_id', copy=False) ##-- attach HH_id nullDf = persData[persData['HH_id'].isnull()] -if nullDf.shape[0] > 0: - nullDf.to_csv(noHHIDany_file, index=False) -# +nullDf.to_csv(noHH3, index=False) + + persData['household_id'] = persData['HH_id'] persData['per_num'] = persData['member_id'] persData['SEX'] = persData['sex'] persData['AGEP'] = persData['age'] persData['SCHL'] = persData['education'] persData['RAC1P'] = persData['race_id'] -persData['INDP'] = persData['INDP'].fillna(169) + +persData['INDP'] = persData['INDP'].fillna(169) ##-- replace Nulls with 169 persData.loc[persData.JWTR.isnull(),'JWTR'] = 'bb' persData.loc[persData.ESR.isnull(),'ESR'] = 'b' persData.loc[persData.SCHL.isnull(),'SCHL'] = 'bb' persData['INDP'] = persData['INDP'].astype(int) -# change in schema post-2026, some of these no longer exist -- change to keeping some cols instead of dropping -# persData.drop(['person_id','member_id','age','hh_relationship','education','race_id','sex', -# 'hours','income','student_status','worker_status'], axis=1, inplace=True) -keepcols = [ - 'household_id', 'per_num', 'JWTR', - 'INDP', 'ESR', 'SEX', 'AGEP', - 'SCHL', 'RAC1P' -] -persData = persData[keepcols].copy() persData = persData[~persData.household_id.isnull()] -print(' --> QC: Person file contains null values: {0}'.format(persData.isnull().values.any())) + persData.sort_values(by=['household_id','per_num'], inplace=True) -print(" --> Total Persons with indexed HH id: {0:,}".format(persData.shape[0])) -persData.to_csv(temp2_file, columns=['household_id','per_num','JWTR','INDP','ESR','SEX','AGEP', - 'SCHL','RAC1P'], header=True, index=False) +print(" --> Total Persons with indexed HH id: {0}".format(persData.shape[0])) +persData.to_csv(temp2, columns=['household_id','per_num','JWTR','INDP','ESR','SEX','AGEP','SCHL','RAC1P'], header=True, index=False) ## -- ... and write zipped file into WFH module. -- ## -with zipfile.ZipFile(perZip_file, "w", compression=zipfile.ZIP_DEFLATED) as zf: - zf.write(temp2_file, os.path.basename(temp2_file)) -if os.path.exists(temp2_file): - os.remove(temp2_file) +with zipfile.ZipFile(perZip, "w", compression=zipfile.ZIP_DEFLATED) as zf: + zf.write(temp2, os.path.basename(temp2)) +if os.path.exists(temp2): + os.remove(temp2) + # ---------------------------------------------------------------------------- # Read in the subzone files. # ---------------------------------------------------------------------------- -# CMAP subzones -sz1 = pd.read_csv(newFiles[4], sep=',') -#sz1 = sz1[sz1.subzone_id.le(cmapSubzone)] ##-- limit to CMAP 7-county subzones -print(" --> CMAP Subzones with UrbanSim data: {0:,}".format(sz1.shape[0])) -# external subzones -sz2=pd.read_csv(newFiles[5], sep=',') -#sz2 = sz2[sz2.subzone_id.gt(cmapSubzone)] ##-- limit to external subzones -print(" --> External Subzones with UrbanSim data: {0:,}".format(sz2.shape[0])) -subzs = pd.concat([sz1,sz2], ignore_index=True, sort=False) -## -- Clean things up if external file has data in CMAP subzones -- ## -szsCols = subzs.columns.tolist() -szsCols.remove('subzone_id') -szs = subzs.groupby('subzone_id')[szsCols].sum() -# -print(" --> Subzones with UrbanSim data: {0:,}".format(szs.shape[0])) -# merge UrbanSim data to full template of subzones -szs = szTemplate.merge(szs, how='left', on='subzone_id', copy=False) -print(" --> Total Subzones: {0:,}".format(szs.shape[0])) -print(' --> QC: Households in subzone file: {0:,}'.format(szs['total_households'].sum())) -## -- Read in original ATTR_IN to get highEarn -- ## -jobs = pd.read_csv(sz_data, sep=',', header=None, usecols=[0, 1], skiprows=1) +sz1 = pd.read_csv(newFiles[4], sep=',') ##-- CMAP subzones +sz1 = sz1[sz1.subzone_id.le(cmapSubzone)] ##-- limit to internal CMAP households +print(" --> CMAP Subzones: {0}".format(sz1.shape[0])) +sz2=pd.read_csv(newFiles[5], sep=',') ##-- external subzones +print(" --> External Subzones: {0}".format(sz2.shape[0])) + +## -- External subzones do not contain household type distribution so add Zeroes -- ## +l = ['building_type_1_hhs','building_type_2_hhs','building_type_3_hhs','building_type_4_hhs','building_type_5_hhs','building_type_6_hhs','building_type_7_hhs', +'building_type_8_hhs','building_type_9_hhs','building_type_10_hhs',] +for col in l: + sz2[col] = 0 + +szs = pd.concat([sz1,sz2],ignore_index=True,sort=False) ##-- concatenate the subzone files +print(" --> Total Subzones: {0}".format(szs.shape[0])) +## -- Read in original ATTR_IN -- ## +jobs = pd.read_csv(attr_r, sep=',', header=None, usecols=[0, 3]) jobs.columns=['subzone_id','highEarn'] -jobs['subzone_id']=jobs['subzone_id'].astype(int) -## -- Read in original HH_IN to get private auto commute share and sidewalk density-- ## -# read the HH_IN file in to determine its vintage -szhh = pd.read_csv(sz_data, sep=',', header=None, usecols=[0,2,3], skiprows=1) +## -- Read in original HH_IN -- ## +test = pd.read_csv(hh_r, sep=',', header=None) ##-- read file in to check if it is in the old or new format +if len(test.columns)==9: + szhh = pd.read_csv(hh_r, sep=',', header=None, usecols=[0, 7, 8]) ##-- old format +else: + szhh = pd.read_csv(hh_r, sep=',', header=None, usecols=[0, 34, 35]) ##-- new format szhh.columns=['subzone_id','commuteShare','pef'] -szhh['subzone_id']=szhh['subzone_id'].astype(int) ## -- Merge files -- ## szData = szs.merge(jobs, how='left', on='subzone_id', copy=False) szData = szData.merge(szhh, how='left', on='subzone_id', copy=False) szData.sort_values(by=['subzone_id'], inplace=True) -szData.fillna(0, inplace=True) szData['jobs_retail_44_45'] = szData['jobs_retail_44_45'].round().astype(int) szData['total_households'] = szData['total_households'].round().astype(int) szData['total_jobs'] = szData['total_jobs'].round().astype(int) szData['highEarn'] = szData['highEarn'].round(3) szData['pef'] = szData['pef'].round(2) -szData.to_csv(attr_file, columns=['subzone_id','jobs_retail_44_45','total_jobs', - 'highEarn'], header=False, index=False) -print(" --> {0:,} records written to {1}".format(szData.shape[0], attr_file)) -#accommodate change in schema post-2026 -- fix "househols" typo to "households", if exists -szData.rename(columns={c: c.replace('househols','households') for c in szData.columns}, inplace=True) +szData.to_csv(attr, columns=['subzone_id','jobs_retail_44_45','total_jobs','highEarn'], header=False, index=False) +szData.to_csv(hh, columns=['subzone_id','total_households','total_adults','total_adult_workers','total_children_15_under','households_income_30k_less','income_category2_hhs','income_category3_hhs', +'income_category4_hhs','households_head_35_less','age_householder_category2_hhs','age_householder_category3_hhs', +'households_size1','households_size2','households_size3','households_size4','households_size5','households_size6','households_size7','building_type_1_hhs','building_type_2_hhs', +'building_type_3_hhs','building_type_4_hhs','building_type_5_hhs','building_type_6_hhs','building_type_7_hhs','building_type_8_hhs','building_type_9_hhs','building_type_10_hhs', +'race_ethnicity_category1_hhs','race_ethnicity_category2_hhs','race_ethnicity_category3_hhs','race_ethnicity_category4_hhs','race_ethnicity_category5_hhs','commuteShare','pef'], header=False, index=False) + +print("Households: Subzone Minimum = {0:.1f}, Subzone Maximum = {1:.1f}, Subzone Mean = {2:.1f}".format(szData['total_households'].min(), szData['total_households'].max(), + szData['total_households'].mean())) +print("Total Employment: Subzone Minimum = {0:.1f}, Subzone Maximum = {1:.1f}, Subzone Mean = {2:.1f}".format(szData['total_jobs'].min(), szData['total_jobs'].max(), + szData['total_jobs'].mean())) +print("Retail Employment: Subzone Minimum = {0:.1f}, Subzone Maximum = {1:.1f}, Subzone Mean = {2:.1f}".format(szData['jobs_retail_44_45'].min(), szData['jobs_retail_44_45'].max(), + szData['jobs_retail_44_45'].mean())) + +x = 0 +for f in renamedFiles: + if os.path.exists(renamedFiles[x]): + os.remove(renamedFiles[x]) + x += 1 -szData.to_csv(hh_file, columns=['subzone_id','total_households','total_adults', - 'total_adult_workers','total_children_15_under', - 'households_income_30k_less','income_category2_hhs', - 'income_category3_hhs','income_category4_hhs', - 'households_head_35_less','age_householder_category2_hhs', - 'age_householder_category3_hhs','commuteShare','pef'], - header=False, index=False) -## -- Group Quarters population -- ## -szData['total_mil'] = szData['total_mil'].astype(int) -szData['total_uni'] = szData['total_uni'].astype(int) -szData['total_non_inst_16_64'] = szData['total_non_inst_16_64'].astype(int) -szData['total_non_inst_65_plus'] = szData['total_non_inst_65_plus'].astype(int) -szData.to_csv(gq_file, columns=['subzone_id','total_mil','total_uni', - 'total_non_inst_16_64','total_non_inst_65_plus'], - header=False, index=False) -print(" --> Group Quarters population") -print(" - In military barracks: {0:,}".format(szData['total_mil'].sum())) -print(" - In dormitories: {0:,}".format(szData['total_uni'].sum())) -print(" - In other non-institutionalized group quarters ages 16-64: {0:,}".format( - szData['total_non_inst_16_64'].sum())) -print(" - In other non-institutionalized group quarters ages 65+: {0:,}".format( - szData['total_non_inst_65_plus'].sum())) -print(" --> {0:,} records written to {1}".format(szData.shape[0], gq_file)) -print("-----") -print("Households: Subzone Minimum = {0:.1f}, Subzone Maximum = {1:.1f}, " \ - "Subzone Mean = {2:.1f}".format(szData['total_households'].min(), - szData['total_households'].max(), - szData['total_households'].mean())) -print("Total Employment: Subzone Minimum = {0:.1f}, Subzone Maximum = {1:.1f}," \ - "Subzone Mean = {2:.1f}".format(szData['total_jobs'].min(), - szData['total_jobs'].max(),szData['total_jobs'].mean())) -print("Retail Employment: Subzone Minimum = {0:.1f}, Subzone Maximum = {1:.1f}," \ - "Subzone Mean = {2:.1f}".format(szData['jobs_retail_44_45'].min(), - szData['jobs_retail_44_45'].max(), - szData['jobs_retail_44_45'].mean())) - # ---------------------------------------------------------------------------- # Write report file. # ---------------------------------------------------------------------------- -f = open(report_file,'w') -print("Subzone File: Subzone Minimum = {0}, Subzone Maximum = {1}".format( - szData['subzone_id'].min(), szData['subzone_id'].max()), file=f) -print("Household File: Subzone Minimum = {0}, Subzone Maximum = {1}".format( - hhsData['subzone_id'].min(), hhsData['subzone_id'].max()), file=f) -print("Household File: Puma Minimum = {0}, Puma Maximum = {1}".format( - hhsData['puma_id'].min(), hhsData['puma_id'].max()), file=f) -print("Household File: Rowcol Minimum = {0}, Rowcol Maximum = {1}".format( - hhsData['rowcol'].min(), hhsData['rowcol'].max()), file=f) -print("QC: Total households: {0:,}".format(hhs.shape[0]), file=f) -print("QC: Total people: {0:,}".format(persData.shape[0]), file=f) -print("QC: Total jobs: {0:,}".format(szData['total_jobs'].sum()), file=f) -print("QC: Household file contains null values: {0}".format(hhs.isnull().values.any()), file=f) -print("QC: Household id is unique: {0}".format(hhs.household_id.is_unique), file=f) -print("QC: Person file contains null values: {0}".format(persData.isnull().values.any()), file=f) -f.close() \ No newline at end of file +f = open(rptFile,'w') +print("Subzone File: Subzone Minimum = {0}, Subzone Maximum = {1}".format(szData['subzone_id'].min(), szData['subzone_id'].max()), file=f) +print("Household File: Subzone Minimum = {0}, Subzone Maximum = {1}".format(hhsData['subzone_id'].min(), hhsData['subzone_id'].max()), file=f) +print("Household File: Puma Minimum = {0}, Puma Maximum = {1}".format(hhsData['puma_id'].min(), hhsData['puma_id'].max()), file=f) +print("Household File: Rowcol Minimum = {0}, Rowcol Maximum = {1}".format(hhsData['rowcol'].min(), hhsData['rowcol'].max()), file=f) +f.close() diff --git a/Database/transit_asmt_macros/create_transit_demand.bat b/Database/transit_asmt_macros/create_transit_demand.bat index 85cb418..a57193e 100644 --- a/Database/transit_asmt_macros/create_transit_demand.bat +++ b/Database/transit_asmt_macros/create_transit_demand.bat @@ -29,11 +29,11 @@ cd .. rem -- Read model run settings from batch_file.yaml -- for /f "eol=# skip=2 tokens=2 delims=:" %%a in (batch_file.yaml) do (set val=%%a & goto break1) :break1 -for /f "eol=# skip=10 tokens=2 delims=:" %%f in (batch_file.yaml) do (set transitAsmt=%%f & goto break2) +for /f "eol=# skip=14 tokens=2 delims=:" %%f in (batch_file.yaml) do (set transitAsmt=%%f & goto break2) :break2 -for /f "eol=# skip=12 tokens=2 delims=:" %%h in (batch_file.yaml) do (set selLineFile=%%h & goto break4) +for /f "eol=# skip=16 tokens=2 delims=:" %%h in (batch_file.yaml) do (set selLineFile=%%h & goto break4) :break4 -for /f "eol=# skip=18 tokens=2 delims=:" %%k in (batch_file.yaml) do (set RSPrun=%%k & goto break5) +for /f "eol=# skip=22 tokens=2 delims=:" %%k in (batch_file.yaml) do (set RSPrun=%%k & goto break5) :break5 set val=%val:~1,3% diff --git a/Database/transit_asmt_macros/run_transit_assignment.bat b/Database/transit_asmt_macros/run_transit_assignment.bat index f143a5a..434dae4 100644 --- a/Database/transit_asmt_macros/run_transit_assignment.bat +++ b/Database/transit_asmt_macros/run_transit_assignment.bat @@ -21,11 +21,11 @@ echo. rem -- Read model run settings from batch_file.yaml -- for /f "eol=# skip=2 tokens=2 delims=:" %%a in (batch_file.yaml) do (set val=%%a & goto break1) :break1 -for /f "eol=# skip=10 tokens=2 delims=:" %%f in (batch_file.yaml) do (set transitAsmt=%%f & goto break2) +for /f "eol=# skip=14 tokens=2 delims=:" %%f in (batch_file.yaml) do (set transitAsmt=%%f & goto break2) :break2 -for /f "eol=# skip=12 tokens=2 delims=:" %%h in (batch_file.yaml) do (set selLineFile=%%h & goto break4) +for /f "eol=# skip=16 tokens=2 delims=:" %%h in (batch_file.yaml) do (set selLineFile=%%h & goto break4) :break4 -for /f "eol=# skip=18 tokens=2 delims=:" %%k in (batch_file.yaml) do (set RSPrun=%%k & goto break5) +for /f "eol=# skip=22 tokens=2 delims=:" %%k in (batch_file.yaml) do (set RSPrun=%%k & goto break5) :break5 set val=%val:~1,3% diff --git a/Database/trip_gen.bat b/Database/trip_gen.bat index e456432..c571a05 100644 --- a/Database/trip_gen.bat +++ b/Database/trip_gen.bat @@ -39,47 +39,26 @@ rem -------- rem In case CMD.exe is doing stuff in the wrong directory, this command rem changes the directory to where the batch file was called from. cd %~dp0 -rem -- Read model run settings from Telework.yaml -- +rem -- Read model run settings from batch_file.yaml -- for /f "eol=# skip=2 tokens=2 delims=:" %%a in (batch_file.yaml) do (set sc=%%a & goto break1) :break1 -for /f "eol=# skip=1 tokens=2 delims=:" %%b in (Telework.yaml) do (set wfhFile=%%b & goto break2) +for /f "eol=# skip=4 tokens=2 delims=:" %%b in (batch_file.yaml) do (set wfhFile=%%b & goto break2) :break2 -for /f "eol=# skip=2 tokens=2 delims=:" %%c in (Telework.yaml) do (set wfh=%%c & goto break3) +for /f "eol=# skip=5 tokens=2 delims=:" %%c in (batch_file.yaml) do (set wfh=%%c & goto break3) :break3 -for /f "eol=# skip=3 tokens=2 delims=:" %%d in (Telework.yaml) do (set tc14=%%d & goto break4) +for /f "eol=# skip=6 tokens=2 delims=:" %%d in (batch_file.yaml) do (set tc14=%%d & goto break4) :break4 -for /f "eol=# skip=5 tokens=2 delims=:" %%e in (Telework.yaml) do (set wfhLow=%%e & goto break5) -:break5 -for /f "eol=# skip=6 tokens=2 delims=:" %%f in (Telework.yaml) do (set wfhMedium=%%f & goto break6) -:break6 -for /f "eol=# skip=7 tokens=2 delims=:" %%g in (Telework.yaml) do (set wfhHigh=%%g & goto break7) -:break7 -for /f "eol=# skip=8 tokens=2 delims=:" %%g in (Telework.yaml) do (set declineScaled=%%g & goto break8) -:break8 - set sc=%sc:~1,3% set wfhFile=%wfhFile:~1% set wfh=%wfh:~1% set tc14=%tc14:~1% -set wfhLow=%wfhLow:~1% -set wfhMedium=%wfhMedium:~1% -set wfhHigh=%wfhHigh:~1% -set declineScaled=%declineScaled:~1% - @echo. @echo ======================================== @echo --- Model Run Settings --- @echo Scenario = %sc% @echo Create WFH validation file = %wfhFile% -if %sc%==100 ( - @echo 2019 Usual WFH share = %wfh% - @echo 2019 WFH 1-4 days share = %tc14% -) else ( - @echo 2025/26 WFH low rate group share= %wfhLow% - @echo 2025/26 WFH medium rate group share= %wfhMedium% - @echo 2025/26 WFH high rate group share= %wfhHigh% - @echo Decline factor= %declineScaled% -) +@echo Usual WFH share = %wfh% +@echo WFH 1-4 days share = %tc14% @echo ======================================== @echo. rem @@ -120,6 +99,14 @@ echo * prep_macros\distribute.poes echo. echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ pause +echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +echo. +echo WORK FROM HOME RATES +echo. +echo Do the WFH rates and industry files need to be updated? +echo. +echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +pause echo. rem -- Run trip generation model. -- @@ -130,9 +117,9 @@ goto badscen :runit rem Supply project and run titles. -set /p project="[ENTER PROJECT TITLE (E.G., c26q2)] " +set /p project="[ENTER PROJECT TITLE (E.G., c20q2)] " echo. -set /p run="[ENTER RUN TITLE (E.G., 100_20260202)] " +set /p run="[ENTER RUN TITLE (E.G., 100_20200330)] " echo. set project=%project: =% @@ -152,19 +139,17 @@ if "%run%" == "" ( echo =================================================================== echo. +rem Activate Python env +call %~dp0..\Scripts\manage\env\activate_env.cmd +if %ERRORLEVEL% NEQ 0 (goto end) + cd tg\scripts -echo. -echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ echo Updating Trip Generation inputs with UrbanSim data ... -echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -uv run urbansim_update_tg_input_files.py +python urbansim_update_tg_input_files.py if %ERRORLEVEL% NEQ 0 (goto urbansim_issue) @echo. -echo. -echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ echo Updating Heavy Truck Trip allocation weights with UrbanSim data ... -echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -uv run urbansim_hcv_allocation.py +python urbansim_hcv_allocation.py if %ERRORLEVEL% NEQ 0 (goto hcv_issue) cd ..\fortran @@ -173,18 +158,9 @@ set savedir="%cd%" cd wfhmodule set filedir="%cd%" echo. -echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ echo Starting the work-from-home allocation model ... -echo ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -if %val%==100 ( - echo Running wfhflag_base.py ... - uv run wfhflag_base.py %filedir% %savedir% %wfhFile% -) else ( - echo Running wfhflag.py ... - uv run wfhflag.py %filedir% %savedir% %wfhFile% -) - +echo wfh arguments: %filedir% %savedir% %wfhFile% %wfh% %tc14% +python wfhflag.py %filedir% %savedir% %wfhFile% %wfh% %tc14% if %ERRORLEVEL% NEQ 0 (goto wfh_issue) cd .. @@ -194,24 +170,17 @@ if not exist GQ_IN.TXT (goto socec_data_error) if not exist ATTR_IN.TXT (goto socec_data_error) if not exist POPSYN_HH.CSV (goto socec_data_error) -rem Delete old output files and deprecated files. +rem Delete old output files. if exist *OUT.TXT (del *OUT.TXT) if exist *OUTPUT.TXT (del *OUTPUT.TXT) if exist MCHW_HH.TXT (del MCHW_HH.TXT) -if exist TG_PopSyn.exe (del TG_PopSyn.exe) -if exist TG_INPUT.TXT (del TG_INPUT.TXT) -if exist highinc_workers.csv (del highinc_workers.csv) - -cd ..\.. -@echo ============================================================= -@echo BEGIN CMAP TRIP GENERATION MODEL -@echo ============================================================= -uv run trip_generation\trip_generation_model.py -cd tg\scripts + +TG_PopSyn.exe +cd ..\scripts echo Creating summary files ... -uv run summarize_tg_results.py %project% %run% -uv run prepare_iom_inputs.py %project% %run% +python summarize_tg_results.py %project% %run% +python prepare_iom_inputs.py %project% %run% echo. cd ..\data @@ -229,6 +198,8 @@ if not exist m01type.csv (goto m01_data_error) cd %~dp0 +python tg\fortran\create_HHvtype_file.py + echo Module 1 finished. echo. echo =================================================================== @@ -264,6 +235,8 @@ if exist tg.rpt (del tg.rpt) if exist report\stop_truck_distribution.txt ( del report\stop_truck_distribution.txt ) +if not exist tg\fortran\MCHW_HH.TXT (goto filemiss1) +copy tg\fortran\MCHW_HH.TXT MCHW_HH.TXT /y copy tg\fortran\TG_HHENUM_OUTPUT.TXT TG_HHENUM_OUTPUT.TXT /y echo. @@ -279,8 +252,12 @@ call :CheckEmpty %infile% if exist %infile% (del %infile% /Q) cd Database +rem Activate Emme Python env +call %~dp0..\Scripts\manage\env\activate_env.cmd emme +if %ERRORLEVEL% NEQ 0 (goto end) + echo Preparing emmebank for model run... -uv run useful_macros\cleanup_for_rerun.py %val%>> tg.rpt +call python useful_macros\cleanup_for_rerun.py %val%>> tg.rpt echo. echo Importing production and attraction matrices (used only for b/l/m truck distribution)... @@ -288,7 +265,7 @@ call emme -ng 000 -m prep_macros\import.tg.results 1 >> tg.rpt echo. echo Skimming highway network... -uv run prep_macros\free.skim.mac.py %file1% %val% +call python prep_macros\free.skim.mac.py %file1% %val% echo. echo Distributing trucks... @@ -339,6 +316,10 @@ goto end echo !!! THE WORK FROM HOME ALLOCATION MODEL DID NOT RUN PROPERLY !!! goto end +:filemiss1 +echo !!! tg\fortran\MCHW_HH.TXT DOES NOT EXIST !!! +goto end + :truck_balance_err echo !!! TRUCK BALANCING PROCEDURES PRODUCED NaN ERRORS !!! echo Please review report\truck.access.rpt, modify distribute.trucks and diff --git a/Database/trip_generation/household_trip_enumeration.py b/Database/trip_generation/household_trip_enumeration.py deleted file mode 100644 index ed7574b..0000000 --- a/Database/trip_generation/household_trip_enumeration.py +++ /dev/null @@ -1,115 +0,0 @@ -""" -Filename: household_trip_enumeration.py -Author: Craig Heither -Description: This function completes the household trip enumeration process - for trip generation. -""" - -import numpy as np - -def tripEnumeration(starts, ends, selection_array, probability_array, - rng=None, households_chosen=None, replicateMax=3000, - resampleMax=200): - """ - Select travel survey households to attach daily trips to synthetic households. - - Parameters - ---------- - starts : array_like - 0-based inclusive start indices (length N) - ends : array_like - 0-based inclusive end indices (length N) - selection_array : ndarray - 1D array of survey identifiers (length M) - probability_array : ndarray - 1D array of probabilities for each survey (length M) - rng : numpy.random.Generator, optional - NumPy Generator instance for reproducible draws. If None, uses - np.random.default_rng(). - households_chosen : dict, optional - Dictionary to track selected households and their replication counts. - If None, no resampling occurs when thresholds are reached. - replicateMax : int, optional - Maximum times a specific survey household can be matched to synthetic - households before resampling occurs. Default is 3000. - resampleMax : int, optional - Maximum times resampling will occur once replicateMax has been reached. - Default is 200. - - Returns - ------- - ndarray - Integer array (dtype int64) of length N with selected survey identifiers. - """ - # Use provided generator or default - if rng is None: - rng = np.random.default_rng() - - # Read inputs into numpy arrays, + 1 to ends to be inclusive of selection - # Example: array = [1,2,3,4,5,6,7] - # the slice for (1,2,3) is [0:3], slice for (4,5,6,7) is [3:7] - starts = np.asarray(starts, dtype=np.int64) - ends = np.asarray(ends + 1, dtype=np.int64) - selection_array = np.asarray(selection_array).astype(np.int64) - probability_array = np.asarray(probability_array).astype(float) - - # Cumulative probabilities with a leading zero for easy slice arithmetic - cumul_prob = np.concatenate(([0.0], np.cumsum(probability_array))) - - # Compute total mass for each slice - masses = cumul_prob[ends] - cumul_prob[starts] - - # Draw uniform random values within each slice's mass using RNG - u = rng.random(size=masses.shape) * masses + cumul_prob[starts] - # Map cumulative draws to travel survey household index - idx = np.searchsorted(cumul_prob, u, side='right') - 1 - selected_households = selection_array[idx].astype(np.int64) - - # Place current selections into output - keep_output = selected_households - - # Update counts and resample if threshold reached - if households_chosen is not None: - for survey_id in selected_households: - households_chosen[survey_id] = households_chosen.get(survey_id, 0) + 1 - ### households_chosen[survey_id] += 1 - - # Identify households needing resample - needs_resample = np.array( - [households_chosen.get(int(survey_id), 0) > replicateMax for - survey_id in selected_households], dtype=bool, - ) - if np.any(needs_resample): - # Iterate only on houseohlds above threshold - for i, need in enumerate(needs_resample): - if not need: - continue - - start_i = int(starts[i]) - end_i = int(ends[i]) - choices = selection_array[start_i : end_i] - probs = probability_array[start_i : end_i] - total_p = np.nansum(probs) - - if not np.isfinite(total_p) or total_p <= 0: - # Uniform if invalid probabilities - new_sel = int(rng.choice(choices)) - else: - probs = probs / total_p - new_sel = int(selected_households[i]) # default to current - for _ in range(resampleMax): - candidate = int(rng.choice(choices, p=probs)) - if households_chosen.get(candidate, 0) < replicateMax: - # Roll back previous count of selected[i] - households_chosen[int(selected_households[i])] -= 1 - # Use the candidate and increment its count - new_sel = candidate - households_chosen[new_sel] = households_chosen.get(new_sel, 0) + 1 - break - # If we never found below-threshold, keep the last selection (new_sel) - selected_households[i] = new_sel - - # Write back selections to out for the resampled subset - keep_output = selected_households - - return keep_output.astype(np.int64) \ No newline at end of file diff --git a/Database/trip_generation/trip_generation.yaml b/Database/trip_generation/trip_generation.yaml deleted file mode 100644 index 738087e..0000000 --- a/Database/trip_generation/trip_generation.yaml +++ /dev/null @@ -1,39 +0,0 @@ -## -- Name identifying the model run -rtpVersion: '2026 LRTP' -## -- Number of trip generation subzones in the modeling area -subzones: 17418 -## -- Number of Census 2010 five percent sample PUMAs in the modeling area -puma5: 74 -## -- Zones used for trip distribution, mode choice, and assignment -## -- (excluding Points of entry) -zones: 3632 -## -- Number of counties in the modeling area -counties: 21 -## -- Maximum value used by the vehicle availability submodel for subzone -## -- sidewalk density (miles of sidewalk per square mile) -sidewalkMaxDensity: 40.0 -## -- Regional median household income, in 2019 dollars -incomeRegMed: 72800 -## -- Seed for random number generator -randomSeed: 211 -## -- Maximum times a specific survey household can be matched to synthetic -## -- households before resampling occurs -replicateMax: 1900 -## -- Maximum times resampling will occur once replicateMax has been reached -resampleMax: 100 -## -- Group quarters trip information -### --- Workers per person by GQ type -militaryWorkersPerPerson: 1.00 -univWorkersPerPerson: 0.385 -other1664WorkersPerPerson: 0.306 -other65WorkersPerPerson: 0.12 -### --- Person work trip rates by GQ type -militaryWorkTrips: 2.00 -univWorkTrips: 0.77 -other1664WorkTrips: 0.612 -other65WorkTrips: 0.24 -## -- Flag to write optional files (HI_HHENUM_TRIP_OUT.CSV, PRODS_HH_OUT.CSV, -## -- PRODS_GQ_OUT.CSV, FIRST_PA_OUT.CSV, EXTERNAL_PA_OUT.CSV). These are -## -- useful for debugging and model validation, but are not required for -## -- production model runs. -writeOptionalFiles: False diff --git a/Database/trip_generation/trip_generation_model.py b/Database/trip_generation/trip_generation_model.py deleted file mode 100644 index 9bda35c..0000000 --- a/Database/trip_generation/trip_generation_model.py +++ /dev/null @@ -1,987 +0,0 @@ -""" -Filename: trip_generation_model.py -Author: Craig Heither -Description: This is the Python translation of CMAP's Trip Generation model, - originally written by Ronald W. Eash. It creates the subzone- - level trip productions and attractions by trip type used in the - trip-based model. Trip generation has seven major steps: - 1. Load the input files - 2. Run the vehicle availability model to estimate the number - of vehicles for each synthetic household - 3. Run the household trip enumeration process to create - productions for each synthetic household - 4. Calculate non-institutional group quarters trip productions - 5. Allocate trip productions and attractions for non-home trip - ends - 6. Factor external home-based productions and attractions - 7. Finalize productions and attractions -Input files: - - POPSYN_HH.CSV: contains information about each synthetic household - - GEOG_IN.TXT: defines various geographies for each zone and subzone - - HH_IN.TXT: contains subzone totals of household and person level attributes - - HH_WFH_STATUS.CSV: contains the telework status for each synthetic household - - tg_hhvtype_lookup.csv: defines the attributes in household vehicle type categories - - HHID_choices1.csv: defines the range of survey households available for trip - enumeration for non-telework households based on synthetic household attributes - - HHID_choices2.csv: lists the survey households in each group defined in HHID_choices1.csv - - HHID_wfh1.csv: defines the range of survey households available for trip - enumeration for telework households based on synthetic household attributes - - HHID_wfh2.csv: lists the survey households in each group defined in HHID_wfh1.csv - - HI_HHENUM_IN.TXT: contains travel survey households including the number of weekday - household trips by purpose - - GQ_IN.TXT: contains the number of workers and nonworking adults in non-institutionalized - group quarters for each subzone - - GQ_TRIPRATES.csv: contains group quarters trip rates for non-work trips developed from - the household travel survey - - airport_sz.csv: contains subzones representing airports - - SCHOOL_IN.CSV: lists high school and college enrollment values for subzones containing - these institutions - - ATTR_IN.TXT: contains subzone-level employment information - - coefficients_attractions.csv: contains the trip type coefficients used to allocate - attractions - - coefficients_nonhome_productions.csv: contains the trip type coefficients used to - allocate non-home productions - - EXT_IN.TXT: PUMA-level adjustment factors to modify workplace trips from internal - households to external workplaces and vice-versa -Output files: - - SIMULATED_HHVEH.TXT: stores the category of simulated vehicles available for each - household following the vehicle availability model - - TRIP49_PA_OUT.TXT: contains subzone-level productions and attractions by trip type - for non-telework households - - TRIP49_PA_WFH_OUT.TXT: contains subzone-level productions and attractions by trip type - for telework households - - TG_HHENUM_OUTPUT.TXT: lists the subzone, zone and household vehicle type of each - enumerated household - - households_selected_noWFH_enumeration_count.csv: lists the number of times each survey - household was selected during trip enumeration for non-telework households - - households_selected_WFH_enumeration_count.csv: lists the number of times each survey - household was selected during trip enumeration for telework households - - trip_generation_model_log.txt: trip generation model log file - - HI_HHENUM_TRIP_OUT.CSV (optional): contains the number of trips by type for each - synthetic household - - PRODS_HH_OUT.CSV (optional): contains a subzone-level summary of trip productions - by trip type within four categories of households - - PRODS_GQ_OUT.CSV (optional): contains a subzone-level summary of trip productions for - workers and nonworking adults within each group quarters resident category - - FIRST_PA_OUT.CSV (optional): contains preliminary subzone-level productions and - attractions by trip type prior to external adjustments - - EXTERNAL_PA_OUT.CSV (optional): contains subzone-level external productions and - attractions by trip type -""" - -# ---------------------------------------------------------------------------- -# Import packages, set paths and variables. -# ---------------------------------------------------------------------------- -import os -import pandas as pd -import numpy as np -from pathlib import Path -import numexpr as ne -import yaml -import timeit -import logging -import vehicle_availability as veh -import household_trip_enumeration as enumer - -t_alpha = timeit.default_timer() - -# Input Files -baseDir = Path(__file__).resolve().parents[1] -fileDir = Path(__file__).resolve().parents[1].joinpath('tg', 'fortran') -yamlDir = Path(__file__).resolve().parent -configDir = Path(__file__).resolve().parents[2].joinpath('Scripts', - 'prepare', - 'conformity_scenario', - 'hand') -popSynFile = fileDir / 'POPSYN_HH.CSV' -geoFile = fileDir / 'GEOG_IN.TXT' -szAttributesFile = fileDir / 'HH_IN.TXT' -wfhFile = fileDir / 'HH_WFH_STATUS.CSV' -hhvtypeFile = fileDir / 'tg_hhvtype_lookup.csv' -enumerateNoWfhDataFile1 = fileDir / 'HHID_choices1.csv' -enumerateNoWfhDataFile2 = fileDir / 'HHID_choices2.csv' -enumerateWfhDataFile1 = fileDir / 'HHID_wfh1.csv' -enumerateWfhDataFile2 = fileDir / 'HHID_wfh2.csv' -travelSurveyFile = fileDir / 'HI_HHENUM_IN.TXT' -groupQuartersFile = fileDir / 'GQ_IN.TXT' -groupQuartersTripsFile = fileDir / 'GQ_TRIPRATES.csv' -airportFile = fileDir / 'airport_sz.csv' -enrollmentFile = fileDir / 'SCHOOL_IN.CSV' -attractionsFile = fileDir / 'ATTR_IN.TXT' -coeffsAttractFile = fileDir / 'coefficients_attractions.csv' -coeffsProdsFile = fileDir / 'coefficients_nonhome_productions.csv' -externalShares = fileDir / 'EXT_IN.TXT' -yamlBatchin = baseDir / 'batch_file.yaml' -yamlTg = yamlDir / 'trip_generation.yaml' -yamlConfig = configDir / 'config.yaml' - -# Output Files -simVehicles = fileDir / 'SIMULATED_HHVEH.TXT' -nowfhEnumCount = fileDir / 'households_selected_noWFH_enumeration_count.csv' -wfhEnumCount = fileDir / 'households_selected_WFH_enumeration_count.csv' -finalProdsAttrs = fileDir / 'TRIP49_PA_OUT.TXT' -finalWfhProdsAttrs = fileDir / 'TRIP49_PA_WFH_OUT.TXT' -logFile = fileDir / 'trip_generation_model_log.txt' -hhVehtypeFile = fileDir / 'TG_HHENUM_OUTPUT.TXT' -syntheticHHTrips = fileDir / 'HI_HHENUM_TRIP_OUT.CSV' -householdProductions = fileDir / 'PRODS_HH_OUT.CSV' -groupQuartersProductions = fileDir / 'PRODS_GQ_OUT.CSV' -firstProdsAttrs = fileDir / 'FIRST_PA_OUT.CSV' -extrnlProdsAttrs = fileDir / 'EXTERNAL_PA_OUT.CSV' - -for fl1 in [syntheticHHTrips, householdProductions, groupQuartersProductions, - firstProdsAttrs, extrnlProdsAttrs]: - if os.path.exists(fl1): - os.remove(fl1) - -# Configure the logging -handlers = [logging.FileHandler(logFile, mode='w'), - logging.StreamHandler()] -logging.basicConfig(level=logging.DEBUG, handlers = handlers, - format='%(asctime)s - %(levelname)s - %(message)s') -logger = logging.getLogger() - -# Read configuration file attributes -with open(yamlTg, 'r') as file: - tgConfig = yaml.safe_load(file) - -with open(yamlBatchin, 'r') as file: - batchConfig = yaml.safe_load(file) - -with open(yamlConfig, 'r') as file: - config = yaml.safe_load(file) - -# Create a NumPy Generator seeded from config to pass to functions -rng = np.random.default_rng(tgConfig['randomSeed']) -# Model version -modelVersion = tgConfig['rtpVersion'] -# Set maximum sidewalk density value -sidewalkMax = float(tgConfig['sidewalkMaxDensity']) -# Set threshold for enumeration replicates to trigger resampling -replicateMax = int(tgConfig['replicateMax']) -# Set replicate resampling maximum -resampleMax = int(tgConfig['resampleMax']) -# Get regional median household income -regionalMedianIncome = int(tgConfig['incomeRegMed']) -# Get military group quarters workers per person -militaryWorkers = float(tgConfig['militaryWorkersPerPerson']) -# Get dormitory group quarters workers per person -univWorkers = float(tgConfig['univWorkersPerPerson']) -# Get other 16-64 group quarters workers per person -other1664Workers = float(tgConfig['other1664WorkersPerPerson']) -# Get other 65+ group quarters workers per person -other65Workers = float(tgConfig['other65WorkersPerPerson']) -# Get military group quarters worker trip rates -militaryWorkTrips = float(tgConfig['militaryWorkTrips']) -# Get dormitory group quarters worker trip ratesn -univWorkTrips = float(tgConfig['univWorkTrips']) -# Get other 16-64 group quarters worker trip rates -other1664WorkTrips = float(tgConfig['other1664WorkTrips']) -# Get other 65+ group quarters worker trip rates -other65WorkTrips = float(tgConfig['other65WorkTrips']) -# Write optional files -writeOptional = bool(tgConfig['writeOptionalFiles']) - -scen_code = batchConfig['scenario_code'] -real_year = int(config['scenario_years'][scen_code]) - -pdVersion = pd.__version__ -if float(pdVersion[:3]) >= 1.5: - pdEngine = 'pyarrow' -else: - pdEngine = 'c' - -# ---------------------------------------------------------------------------- -# Functions. -# ---------------------------------------------------------------------------- -def run_formula(df): - """ - Evaluate weight formulas from a DataFrame column using numexpr to calculate - non-home trip production weights or trip allocation weights. - - For each unique formula in the 'weight_formula' column, evaluates the - formula expression using numexpr on the subset of rows with that formula. - Results are aggregated into a single output array. - - Parameters - ---------- - df : DataFrame - Input DataFrame containing a 'weight_formula' column with formula - expressions and numeric columns referenced in those formulas. - - Returns - ------- - ndarray - Numeric array (float64) of evaluated results with length equal to - the number of rows in df. NaN values are returned for rows where - formula evaluation fails. - """ - result = np.zeros(len(df)) - for formula in df['weight_formula'].unique(): - mask = df['weight_formula'] == formula - subset = df[mask] - # Filter the data to only needed columns for this formula - local_dict = {col: subset[col].values for col in df.columns} - try: - result[mask.values] = ne.evaluate(formula, local_dict) - except Exception as e: - logging.error(f"Error evaluating formula '{formula}': {e}") - result[mask.values] = np.nan - return result - -def fixed_width(outfile, df): - """ - Write DataFrame to fixed-width format file. - - Extracts specified columns from the input DataFrame and writes them - to a file with right-justified fields of fixed widths. Suitable for - output compatibility with legacy fixed-format data files. - - Parameters - ---------- - outfile : str or Path - Path where the fixed-width file will be written. - df : DataFrame - Input DataFrame containing at least the columns: 'subzone', 'zone', - 'trip_type', 'sz_prods', 'sz_attrs'. - - Returns - ------- - None - Writes data directly to outfile. - - Notes - ----- - Field widths are: subzone (6), zone (6), trip_type (2), sz_prods (9), - sz_attrs (9). All numeric values are right-justified. sz_prods and - sz_attrs are formatted with 1 decimal place. - """ - data = df[['subzone', 'zone', 'trip_type', 'sz_prods', 'sz_attrs']].values - with open(outfile, 'w') as f: - for row in data: - # write right-justified fields of specified width - f.write('{:>6.0f}{:>6.0f}{:>2.0f}{:>9.1f}{:>9.1f}\n'.format(*row)) - -# ---------------------------------------------------------------------------- -# Step 1. Load data files and prepare data. -# ---------------------------------------------------------------------------- -logging.info("Beginning CMAP Trip Generation model: {0} Scenario {1}" - .format(modelVersion, batchConfig['scenario_code'])) -logging.info("Loading data files") - -# Load synthetic households -popSynCols = ['subzone','hh_type','vehicles','serial_number','state_puma', - 'row_column','adults','workers','children','income_category', - 'age_category','hh_veh_type','income'] -popSynDrop = ['vehicles','hh_veh_type'] -hh = pd.read_csv(popSynFile, names=popSynCols, dtype='Int64', engine=pdEngine) -hh['household_record'] = hh.index + 1 -hh.drop(popSynDrop, axis=1, inplace=True) -numberHouseholds = len(hh) - -# Load geography file -geogCols = ['subzone','county','county_name','state','puma','zone','chicago', - 'cbd','row_column','area','cmap'] -geogDrop = ['state','puma','row_column','state_puma'] -geog = pd.read_csv(geoFile, names=geogCols, engine=pdEngine) -geog.loc[geog.state.eq('IL'), 'state_puma'] = 1700000 + geog['puma'] -geog.loc[geog.state.eq('IN'), 'state_puma'] = 1800000 + geog['puma'] -geog.loc[geog.state.eq('WI'), 'state_puma'] = 5500000 + geog['puma'] -pumas = geog[['subzone','state_puma']].copy().reset_index(drop=True) -geog.drop(geogDrop, axis=1, inplace=True) - -# Load subzone summary data file -szCols = ['subzone','households','adults','workers','children', - 'income_category1','income_category2','income_category3', - 'income_category4','age_category1','age_category2','age_category3', - 'auto_commute_share','sidewalk_density'] -szDrop = ['adults','workers','children','income_category1', - 'income_category2','income_category3','income_category4', - 'age_category1','age_category2','age_category3'] -sz = pd.read_csv(szAttributesFile, names=szCols, engine=pdEngine) -totalHHs = sz['households'].sum() -sz.drop(szDrop, axis=1, inplace=True) - -# Load household work from home flag file -wfhCols = ['serial_number','wfh_flag','number_WFH_workers','tc14_not_working'] -wfhDrop = ['number_WFH_workers','tc14_not_working'] -wfh = pd.read_csv(wfhFile, names=wfhCols, engine=pdEngine) -wfh['household_record'] = wfh.index + 1 -wfh['wfh_flag'] = wfh['wfh_flag'].clip(upper=1) -wfh.drop(wfhDrop, axis=1, inplace=True) - -# Load household vehicle type category file -hhvtype = pd.read_csv(hhvtypeFile, dtype='Int64', engine=pdEngine) -hhvtype.rename(columns={'ADULT': 'adults', 'WORKER': 'workers', 'CHILD': - 'children', 'VEH': 'vehicles', 'AGE_INDEX': - 'age_category', 'HHVTYPE': 'hh_veh_type'}, - inplace=True) - -# Load trip enumeration data for non-Work From Home households -# This identifies the set of survey households that will be sampled -enumNoWfhData1Cols = ['state_puma','hh_veh_type','match_category', - 'choice_start','choice_end'] -enumData1 = pd.read_csv(enumerateNoWfhDataFile1, names=enumNoWfhData1Cols, - dtype='Int64', engine=pdEngine) - -# Load trip enumeration choices data for non-Work From Home households -# This identifies the survey household numbers and probability of selection -enumNoWfhData2Cols = ['survey_number','cumul_probability'] -enumData2 = pd.read_csv(enumerateNoWfhDataFile2, names=enumNoWfhData2Cols, - engine=pdEngine) - -# Load trip enumeration data for Work From Home households -# This identifies the set of survey households that will be sampled -enumWfhData1Cols = ['state_puma','hh_type','match_category','choice_start', - 'choice_end'] -enumWfhData1 = pd.read_csv(enumerateWfhDataFile1, names=enumWfhData1Cols, - dtype='Int64', engine=pdEngine) - -# Load trip enumeration choices data for Work From Home households -# This identifies the survey household numbers and probability of selection -enumWfhData2 = pd.read_csv(enumerateWfhDataFile2, names=enumNoWfhData2Cols, - engine=pdEngine) - -# convert enumeration selection boundaries from FORTRAN index to Python index -# (1-based to 0-based) -enumData1['choice_start'] = enumData1['choice_start'] - 1 -enumWfhData1['choice_start'] = enumWfhData1['choice_start'] - 1 -enumData1['choice_end'] = enumData1['choice_end'] - 1 -enumWfhData1['choice_end'] = enumWfhData1['choice_end'] - 1 - -# Convert Lee County state_puma to match GEOG_IN.TXT values, if needed -enumData1.loc[enumData1['state_puma'] == 1700104, 'state_puma'] = 1717104 -enumWfhData1.loc[enumWfhData1['state_puma'] == 1700104, 'state_puma'] = 1717104 - -# Convert from cumulative probability to individual probabilities -enumData2['p'] = enumData2['cumul_probability'].shift(1).fillna(0) -enumData2['probability'] = np.where(enumData2['p'] < 1, - enumData2['cumul_probability'] - - enumData2['p'], - enumData2['cumul_probability']) -enumWfhData2['p'] = enumWfhData2['cumul_probability'].shift(1).fillna(0) -enumWfhData2['probability'] = np.where(enumWfhData2['p'] < 1, - enumWfhData2['cumul_probability'] - - enumWfhData2['p'], - enumWfhData2['cumul_probability']) - -# Load file of household travel survey data -surveyCols = ['state_puma','hh_veh_type','survey_number','adults_survey', - 'workers_survey','nonworkers_survey','children_survey', - 'children12-15_survey','vehicles_survey'] -for i in range(1,50): - fieldName = f"trips{i}" - surveyCols.append(fieldName) -surveyDrop = ['state_puma','hh_veh_type','adults_survey','workers_survey', - 'nonworkers_survey','children_survey','children12-15_survey', - 'vehicles_survey'] -surveyHouseholds = pd.read_csv(travelSurveyFile, names=surveyCols, - engine=pdEngine) -surveyHouseholds.drop(surveyDrop, axis=1, inplace=True) - -# Load file of group quarters residents -gqCols = ['subzone','military','college','other16-64','other65'] -gq = pd.read_csv(groupQuartersFile, names=gqCols, dtype='Int64', - engine=pdEngine) -groupQuarters = pd.melt(gq, id_vars='subzone', var_name='gq_type', - value_name='gq_persons') -groupQuarters['gq_persons'] = groupQuarters['gq_persons'].astype(int) -numberGqHousholds = groupQuarters['gq_persons'].sum() - -# Load file of group quarters trip rates 3-33, add trip type 1 placeholder -gqTripRates = pd.read_csv(groupQuartersTripsFile, names=['trip_type', - 'trip_production_rate'], - engine=pdEngine) -new_row = {'trip_type': 1, 'trip_production_rate': 0.0} -gqTripRates.loc[len(gqTripRates)] = new_row -gqTripRates.sort_values('trip_type', inplace=True) - -# Load airport subzone file -airports = pd.read_csv(airportFile, usecols=['subzone','year_open'], - engine=pdEngine) -airports['notairport_flag'] = np.where(real_year >= airports['year_open'], 0, 1) -airports.drop('year_open', axis=1, inplace=True) - -# Load subzone high school and college enrollment file -schools = pd.read_csv(enrollmentFile, names=['subzone','enrollment'], - engine=pdEngine) - -# Load subzone attractions file -attrCols = ['subzone','retail_employment','total_employment', - 'high_earner_share'] -attractions = pd.read_csv(attractionsFile, names=attrCols, engine=pdEngine) -attractions['high_earner_share'] = attractions['high_earner_share'].round(3) -attractions['nonretail_employment'] = (attractions['total_employment'] - - attractions['retail_employment']) -attractions['low_earner_share'] = (1.0 - attractions['high_earner_share'] - ).round(3) - -# Load file of coefficients for attractions allocation -coeffsAttr = pd.read_csv(coeffsAttractFile) - -# Load file of coefficients for nonhome productions allocation -coeffsProd = pd.read_csv(coeffsProdsFile) - -# Load file of external home-workplace production and attraction shares -extCols = ['state_puma','ext_prod_factor','ext_attr_factor'] -extrnShare = pd.read_csv(externalShares, names=extCols, engine=pdEngine) -# Convert Lee County state_puma to match GEOG_IN.TXT values, if needed -extrnShare.loc[extrnShare['state_puma'] == 1700104, 'state_puma'] = 1717104 - -# Attach data to synthetic households -hh = hh.merge(geog, how='left', on='subzone', copy=False) -hh = hh.merge(sz, how='left', on='subzone', copy=False) -hh = hh.merge(wfh, how='left', on=['household_record','serial_number'], - copy=False) - -# Prepare variables -# Set household category attributes to maximum values for HHTYPE and HHVTYPE -hh['adults'] = hh['adults'].clip(upper=4) -hh['workers'] = hh['workers'].clip(upper=3) -hh['children'] = hh['children'].clip(upper=3) -hh['nonworkers'] = hh['adults'] - hh['workers'] -# Set sidewalk density to maximum subzone value -hh['sidewalk_density'] = hh['sidewalk_density'].clip(upper=sidewalkMax) - -# ---------------------------------------------------------------------------- -# Verify values are within acceptable ranges. -# ---------------------------------------------------------------------------- -assert totalHHs == len(hh), "Number of households is not consistent" -assert hh['adults'].min() == 1, "Minimum number of adults for HHTYPE is " \ - "below 1" -assert hh['adults'].max() == 4, "Maximum number of adults for HHTYPE is not 4" -assert hh['workers'].min() == 0, "Minimum number of workers for HHTYPE is" \ - "not 0" -assert hh['workers'].max() == 3, "Maximum number of workers for HHTYPE is " \ - "not 3" -assert hh['children'].min() == 0, "Minimum number of children for HHTYPE is" \ - "not 0" -assert hh['children'].max() == 3, "Maximum number of children for HHTYPE is" \ - "not 3" -assert hh['age_category'].min() == 1, "Minimum age of head of householder " \ - "category for HHTYPE is not 1" -assert hh['age_category'].max() == 3, "Maximum age of head of householder" \ - "category for HHTYPE is not 3" -assert hh['income_category'].min() == 1, "Minimum income category for HHTYPE" \ - "is not 1" -assert hh['income_category'].max() == 4, "Maximum income category for HHTYPE" \ - "is not 4" -assert hh['sidewalk_density'].max() == tgConfig['sidewalkMaxDensity'], "Maximum" \ - "sidewalk density does not match yaml file " \ - "parameter" -assert hh['nonworkers'].min() == 0, "Minimum number of nonworkers is not 0" -assert hh['wfh_flag'].min() == 0, "Minimum WFH flag is not 0" -assert hh['wfh_flag'].max() == 1, "Maximum WFH flag is not 1" -logging.info(' -- Number of households to process: {0:,}'.format(len(hh))) - -# ---------------------------------------------------------------------------- -# Step 2. Run the vehicle availability model for each household. -# ---------------------------------------------------------------------------- -logging.info("Running the Vehicle Availability model") - -# Separate households by number of adults to apply the appropriate model -adult1 = hh[hh.adults.eq(1)].copy().reset_index() -adult2 = hh[hh.adults.eq(2)].copy().reset_index() -adult3 = hh[hh.adults.gt(2)].copy().reset_index() - -# Apply vehicle availability model -adult1['vehicles'] = veh.vehOwnOneAdult(adult1[['sidewalk_density', - 'row_column', 'age_category', - 'workers', 'income_category', - 'auto_commute_share'] - ].to_numpy(), rng=rng - ).astype(int) -adult2['vehicles'] = veh.vehOwnTwoAdult(adult2[['sidewalk_density', - 'row_column', 'age_category', - 'workers', 'income_category', - 'auto_commute_share', - 'children']].to_numpy(), - rng=rng).astype(int) -adult3['vehicles'] = veh.vehOwnThreeAdult(adult3[['sidewalk_density', - 'row_column', 'age_category', - 'workers', 'income_category', - 'auto_commute_share', - 'nonworkers']].to_numpy(), - rng=rng).astype(int) - -# Re-combine the households and write simulated vehicles file -hh = pd.concat([adult1, adult2, adult3], ignore_index=True, sort=False) -hh.sort_values('household_record', inplace=True) -logging.info(' - 0-vehicle households: {0:>10,}'.format((hh['vehicles'] - == 0).sum())) -logging.info(' - 1-vehicle households: {0:>10,}'.format((hh['vehicles'] - == 1).sum())) -logging.info(' - 2-vehicle households: {0:>10,}'.format((hh['vehicles'] - == 2).sum())) -logging.info(' - 3+-vehicle households: {0:>9,}'.format((hh['vehicles'] - == 3).sum())) -logging.info(' --> Writing {0:,} records to {1}'.format(len(hh), - Path(simVehicles).name)) -hh.to_csv(simVehicles, columns=['serial_number','vehicles', - 'household_record'], index=False) - -# Apply household vehicle type category (HHVTYPE) -hh = hh.merge(hhvtype, how='left', on=['adults','workers','children', - 'vehicles','age_category'], - copy=False) -assert hh['vehicles'].min() == 0, "Minimum household vehicles is not 0" -assert hh['vehicles'].max() < 4, "Maximum household vehicles is not within " \ - "range" -assert hh['hh_veh_type'].min() > 0, "Minimum household vehicle type code " \ - "is not greater than 0" -assert hh['hh_veh_type'].max() < 625, "Maximum household vehicle type code " \ - "is not within range" - -# Write household vehicle type file -veh = hh[['subzone','zone','hh_veh_type']].reset_index(drop=True) -veh.sort_values(by=['zone', 'subzone'], inplace=True) -logging.info(' --> Writing {0:,} records to {1}'.format( - len(veh), Path(hhVehtypeFile).name)) -veh.to_csv(hhVehtypeFile, header=False, index=False) - -# ---------------------------------------------------------------------------- -# Step 3. Run the household trip enumeration process. -# ---------------------------------------------------------------------------- -logging.info('Running the Household Trip Enumeration Process') -logging.info(' -- Non-Work From Home households') -logging.info(' -- Preparing the data') - -# Attach trip enumeration data to households -nowfh = hh[hh.wfh_flag.eq(0)].reset_index(drop=True) -nowfh = nowfh.merge(enumData1, how='left', on=['state_puma','hh_veh_type'], - copy=False) -assert nowfh.isnull().any().sum() == 0, "Non-work from home data have" \ - "missing values" -# Create data arrays -selection_array = enumData2['survey_number'].to_numpy().astype(np.int64) -probability_array = enumData2['probability'].to_numpy() - -# Create a dictionary of survey household ids to track how many times each is -# selected during the trip enumeration process -households_chosen = {key: 0 for key in enumData2['survey_number'].unique()} - -# Implement household trip enumeration -logging.info(' -- Running trip enumeration') -nowfh['survey_number'] = enumer.tripEnumeration( - nowfh['choice_start'].to_numpy(), - nowfh['choice_end'].to_numpy(), - selection_array, - probability_array, - rng=rng, - households_chosen=households_chosen, - replicateMax=replicateMax, - resampleMax=resampleMax -) - -assert nowfh['survey_number'].min() >= enumData2['survey_number'].min(), \ - "Invalid non-work from home survey household selected during enumeration" -assert nowfh['survey_number'].max() <= enumData2['survey_number'].max(), \ - "Invalid non-work from home survey household selected during enumeration" - -# Output dictionary of households selected during trip enumeration -dictList = [[key, value] for key, value in households_chosen.items()] -nowfhCount = pd.DataFrame(dictList, columns=['survey_household', - 'selection_count']) -nowfhCount.sort_values(['selection_count'], ascending=False, inplace=True) -nowfhCount.to_csv(nowfhEnumCount, index=False) -# ---------------------------------------------------------------------------- -logging.info(' -- Work From Home households') -logging.info(' -- Preparing the data') - -# Attach trip enumeration data to households -wfh = hh[hh.wfh_flag.eq(1)].reset_index(drop=True) -wfh = wfh.merge(enumWfhData1, how='left', on=['state_puma','hh_type'], - copy=False) -assert wfh.isnull().any().sum() == 0, "Work from home data have" \ - "missing values" -# Create data arrays -selection_array = enumWfhData2['survey_number'].to_numpy() -probability_array = enumWfhData2['probability'].to_numpy() - -# Create a dictionary of survey household ids to track selections -wfh_households_chosen = {key: 0 for key in enumWfhData2['survey_number']. - unique()} - -# Implement household trip enumeration -logging.info(' -- Running trip enumeration') -wfh['survey_number'] = enumer.tripEnumeration( - wfh['choice_start'].to_numpy(), - wfh['choice_end'].to_numpy(), - selection_array, - probability_array, - rng=rng, - households_chosen=wfh_households_chosen, - replicateMax=replicateMax, - resampleMax=resampleMax -) -assert wfh['survey_number'].min() >= enumWfhData2['survey_number'].min(), \ - "Invalid work from home survey household selected during enumeration" -assert wfh['survey_number'].max() <= enumWfhData2['survey_number'].max(), \ - "Invalid work from home survey household selected during enumeration" - -# Output dictionary of households selected during trip enumeration -dictList = [[key, value] for key, value in wfh_households_chosen.items()] -wfhCount = pd.DataFrame(dictList, columns=['survey_household', - 'selection_count']) -wfhCount.sort_values(['selection_count'], ascending=False, inplace=True) -wfhCount.to_csv(wfhEnumCount, index=False) - -# recombine the household data -households = pd.concat([nowfh, wfh], ignore_index=True, sort=False) -households.sort_values('household_record', inplace=True) - -# split out fields for HI_HHENUM_TRIP_OUT.CSV -housholds_out = households[['household_record', 'subzone', 'survey_number', - 'state_puma', 'hh_type', 'hh_veh_type', - 'vehicles', 'row_column', 'serial_number', - 'match_category', 'wfh_flag', 'income', - 'children']].copy().reset_index(drop=True) -householdEnum = housholds_out.merge(surveyHouseholds, how='left', - on='survey_number', copy=True - ).reset_index(drop=True) - -# Redefine work trips for high income households -householdEnum['trips2'] = np.where(householdEnum['income'] >= regionalMedianIncome, - householdEnum['trips1'], - 0) -householdEnum['trips1'] = np.where(householdEnum['income'] >= regionalMedianIncome, - 0, - householdEnum['trips1']) -householdEnum.sort_values('household_record', inplace=True) - -if writeOptional: - logging.info(' --> Writing {0:,} records to {1}'.format( - len(householdEnum), Path(syntheticHHTrips).name)) - householdEnum.to_csv(syntheticHHTrips, index=False) - -# prepare data for PRODS_HH_OUT.CSV -# Summarize household productions by subzone, trip type and four household -# categories: -# 1 = 0 children and 0 vehicles -# 2 = 1 or more children and 0 vehicles -# 3 = 0 children and 1 or more vehicles -# 4 = 1 or more children and 1 or more vehicles -householdEnum.loc[householdEnum.children.eq(0) & householdEnum.vehicles.eq(0), - 'household_category'] = 1 -householdEnum.loc[householdEnum.children.ge(1) & householdEnum.vehicles.eq(0), - 'household_category'] = 2 -householdEnum.loc[householdEnum.children.eq(0) & householdEnum.vehicles.ge(1), - 'household_category'] = 3 -householdEnum.loc[householdEnum.children.ge(1) & householdEnum.vehicles.ge(1), - 'household_category'] = 4 -dropCols = ['children','vehicles','survey_number','household_record', - 'state_puma','hh_type','hh_veh_type','vehicles', 'row_column', - 'serial_number', 'match_category', 'income'] -householdEnum.drop(dropCols, axis=1, inplace=True) -hhProds = pd.melt(householdEnum, id_vars=['subzone','wfh_flag', - 'household_category'], - var_name='trip_type', - value_name='productions') -prods = hhProds.groupby(['subzone','wfh_flag','household_category', - 'trip_type']).agg({'productions': 'sum'} - ).reset_index() -prods['trip_type'] = prods['trip_type'].str.replace('trips', '', - regex=False).astype(int) -prods.sort_values(['subzone','wfh_flag','household_category','trip_type'], - inplace=True) - -if writeOptional: - logging.info(' --> Writing {0:,} records to {1}'.format( - len(prods), Path(householdProductions).name)) - prods.to_csv(householdProductions, index=False) - -# Prepare household data for production and attraction allocations -# Summarize household productions by trip type, subzone and WFH flag -# Summarize household productions by trip type and WFH flag -householdTrips = prods.groupby(['subzone','trip_type','wfh_flag']).agg({ - 'productions': 'sum'}).reset_index() -householdTrips.rename(columns={'productions':'hh_productions'}, - inplace=True) -tripWfh = prods.groupby(['trip_type','wfh_flag']).agg({'productions': 'sum'} - ).reset_index() -tripWfh.rename(columns={'productions':'trip_hh_productions'}, inplace=True) - -# ---------------------------------------------------------------------------- -# Step 4. Calculate group quarters trip productions -# ---------------------------------------------------------------------------- -logging.info('Calculating Group Quarters Trip Productions') - -# Determine workers and nonworkers -groupQuarters['workers'] = 0.0 -groupQuarters.loc[groupQuarters.gq_type.eq('military'), 'workers'] = ( - groupQuarters['gq_persons'] * militaryWorkers) -groupQuarters.loc[groupQuarters.gq_type.eq('college'), 'workers'] = ( - groupQuarters['gq_persons'] * univWorkers) -groupQuarters.loc[groupQuarters.gq_type.eq('other16-64'), 'workers'] = ( - groupQuarters['gq_persons'] * other1664Workers) -groupQuarters.loc[groupQuarters.gq_type.eq('other65'), 'workers'] = ( - groupQuarters['gq_persons'] * other65Workers) -groupQuarters['workers'] = groupQuarters['workers'].round(3) -groupQuarters['nonworkers'] = 0.0 -groupQuarters['nonworkers'] = (groupQuarters['gq_persons'] - - groupQuarters['workers']).round(3) -groupQuarters = groupQuarters.merge(gqTripRates, how='cross', copy=False) - -# Calculate Worker trip productions -# 1 - Home-work low income household -groupQuarters.loc[groupQuarters.gq_type.eq('military') & - groupQuarters.trip_type.eq(1), 'productions'] = ( - groupQuarters['workers'] * militaryWorkTrips) -groupQuarters.loc[groupQuarters.gq_type.eq('college') & - groupQuarters.trip_type.eq(1), 'productions'] = ( - groupQuarters['workers'] * univWorkTrips) -groupQuarters.loc[groupQuarters.gq_type.eq('other16-64') & - groupQuarters.trip_type.eq(1), 'productions'] = ( - groupQuarters['workers'] * other1664WorkTrips) -groupQuarters.loc[groupQuarters.gq_type.eq('other65') & - groupQuarters.trip_type.eq(1), 'productions'] = ( - groupQuarters['workers'] * other65WorkTrips) -# 4 - Home-school (only for 16-64) -groupQuarters.loc[groupQuarters.gq_type.eq('other16-64') & - groupQuarters.trip_type.eq(4), 'productions'] = ( - groupQuarters['workers'] - * groupQuarters['trip_production_rate']) -# Remaining Worker trip types applied to all GQ persons -workTypes = [3,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] -groupQuarters.loc[groupQuarters['trip_type'].isin(workTypes), 'productions'] = ( - groupQuarters['workers'] - * groupQuarters['trip_production_rate']) - -# Calculate Nonworker trip productions -# 21 - Home-school (only for 16-64) -groupQuarters.loc[groupQuarters.gq_type.eq('other16-64') & - groupQuarters.trip_type.eq(21), 'productions'] = ( - groupQuarters['nonworkers'] - * groupQuarters['trip_production_rate']) -# Remaining Nonworker trip types applied to all GQ persons except military -skipType = ['military'] -nonworkTypes = [22,23,24,25,26,27,28,29,30,31,32,33] -groupQuarters.loc[groupQuarters['trip_type'].isin(nonworkTypes) & - ~groupQuarters['gq_type'].isin(skipType), 'productions'] = ( - groupQuarters['nonworkers'] - * groupQuarters['trip_production_rate']) - -groupQuarters.fillna(0, inplace=True) -groupQuarters['productions'] = groupQuarters['productions'].round(3) -groupQuarters.drop('trip_production_rate', axis=1, inplace=True) - -if writeOptional: - logging.info(' --> Writing {0:,} records to {1}'.format(len(groupQuarters), - Path(groupQuartersProductions).name)) - groupQuarters.to_csv(groupQuartersProductions, index=False) - -# Prepare GQ data for production and attraction allocations -# Summarize GQ productions by trip type and subzone -# Summarize GQ productions by trip type -groupQuartersTrips = groupQuarters.groupby(['subzone','trip_type']).agg( - {'productions': 'sum'}).reset_index() -groupQuartersTrips['wfh_flag'] = 0 -groupQuartersTrips.rename(columns={'productions':'gq_productions'}, - inplace=True) -gqTripTypeTrips = groupQuarters.groupby(['trip_type']).agg( - {'productions': 'sum'}).reset_index() -gqTripTypeTrips.rename(columns={'productions':'trip_gq_productions'}, - inplace=True) -groupQuartersTrips = groupQuartersTrips.merge(gqTripTypeTrips, how='left', - on='trip_type', copy=False) -gq1Sum = int(groupQuarters['productions'].sum()) -gq2Sum = int(groupQuartersTrips['gq_productions'].sum()) -assert gq1Sum == gq2Sum, "Mismatch in GQ productions" - -# ---------------------------------------------------------------------------- -# Step 5. Allocate trip productions and attractions for non-home trip ends -# ---------------------------------------------------------------------------- -logging.info('Allocating Productions and Attractions for Non-Home Trip Ends') -logging.info(' -- Preparing the data') - -totalHouseholds = numberGqHousholds + numberHouseholds - -# Create complete template of subzone-trip type-wfh flag options -prodTemplate = geog[['subzone', 'zone', 'cbd']].copy().reset_index(drop=True) -hhPart = sz[['subzone', 'households']].copy().reset_index(drop=True) -tripTypes = coeffsAttr[['trip_type']].copy().reset_index(drop=True) -tripTypes.drop_duplicates(subset=['trip_type'], keep='first', inplace=True) -prodTemplate = prodTemplate.merge(hhPart, how='left', on='subzone', - copy=False) -prodTemplate = prodTemplate.merge(attractions, how='left', on='subzone', - copy=False) -prodTemplate = prodTemplate.merge(airports, how='left', on='subzone', - copy=False) -prodTemplate = prodTemplate.merge(schools, how='left', on='subzone', - copy=False) -prodTemplate = prodTemplate.merge(tripTypes, how='cross', copy=False) -prodTemplate['notairport_flag'] = prodTemplate['notairport_flag'].fillna(1) -prodTemplate['wfh_flag'] = 0 -prodWFH = prodTemplate.copy() -prodWFH['wfh_flag'] = 1 -prodTemplate = pd.concat([prodTemplate, prodWFH], ignore_index=True, - sort=False) -assert len(prodTemplate) == (17418 * 49 * 2), "prodTemplate is not complete" - -logging.info(' -- Allocating non-home productions') -# Attach household and group quarters productions -prodTemplate = prodTemplate.merge(householdTrips, how='left', - on=['subzone','trip_type','wfh_flag'], - copy=False) -prodTemplate = prodTemplate.merge(tripWfh, how='left', on=['trip_type', - 'wfh_flag'], - copy=False) -prodTemplate = prodTemplate.merge(groupQuartersTrips, how='left', - on=['subzone','trip_type','wfh_flag'], - copy=False) -prodTemplate.fillna(0, inplace=True) - -# Attach nonhome production coefficients and calculate shares -prodTemplate = prodTemplate.merge(coeffsProd, how='left', - on=['cbd','trip_type','wfh_flag'], - copy=False) -prodTemplate['sz_share'] = run_formula(prodTemplate) -prodTemplate.drop('weight_formula', axis=1, inplace=True) - -logging.info(' -- Allocating attractions') -# Attach attraction coefficients and calculate shares -prodTemplate = prodTemplate.merge(coeffsAttr, how='left', - on=['cbd','trip_type','wfh_flag'], - copy=False) -prodTemplate['sz_share_attr'] = run_formula(prodTemplate) - -# Sum subzone shares to determine trip type totals -tripTotals = prodTemplate.groupby(['trip_type','wfh_flag']).agg( - {'sz_share': 'sum', - 'sz_share_attr': 'sum'} - ).round(3).reset_index() -tripTotals.rename(columns={'sz_share':'tripShare', - 'sz_share_attr':'tripShareAttr'}, inplace=True) -prodTemplate = prodTemplate.merge(tripTotals, how='left', - on=['trip_type','wfh_flag'], copy=False) - -logging.info(' -- Updating productions') -homeTypes = [1,2,3,4,5,6,7,21,22,23,24,34,35,36,37] -prodTemplate['sz_prods'] = np.where(prodTemplate['trip_type'].isin(homeTypes), - prodTemplate['hh_productions'], - prodTemplate['sz_share'] - / prodTemplate['tripShare'] - * prodTemplate['trip_hh_productions'] - ).round(1) - -prodTemplate['sz_gq_prods'] = np.where(prodTemplate['trip_type'].isin(homeTypes), - prodTemplate['gq_productions'], - prodTemplate['sz_share'] - / prodTemplate['tripShare'] - * prodTemplate['trip_gq_productions'] - ).round(1) - -logging.info(' -- Updating attractions') -notUsed = [2,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49] -prodTemplate['sz_attrs'] = (prodTemplate['sz_share_attr'] - / prodTemplate['tripShareAttr'] - * prodTemplate['trip_hh_productions']).round(1) -prodTemplate['sz_gq_attrs'] = np.where(prodTemplate['trip_type'].isin(notUsed), - prodTemplate['gq_productions'], - prodTemplate['sz_share_attr'] - / prodTemplate['tripShareAttr'] - * prodTemplate['trip_gq_productions'] - ).round(1) - -firstPass = prodTemplate[['subzone', 'zone', 'wfh_flag', 'trip_type', - 'sz_prods', 'sz_attrs', 'sz_gq_prods', - 'sz_gq_attrs']].copy().reset_index(drop=True) - -if writeOptional: - logging.info(' --> Writing {0:,} records to {1}'.format(len(firstPass), - Path(firstProdsAttrs).name)) - firstPass.to_csv(firstProdsAttrs, index=False) - -# ---------------------------------------------------------------------------- -# Step 6. Factor external home-based productions and attractions -# ---------------------------------------------------------------------------- -logging.info('Factoring External Home-Workplace Productions and Attractions') - -# Apply external factors to trip type 1 and 2 -adjusted = firstPass[firstPass.trip_type.le(2)].copy().reset_index(drop=True) -unadjusted = firstPass[firstPass.trip_type.gt(2)].copy().reset_index(drop=True) -adjusted = adjusted.merge(pumas, how='left', on='subzone', copy=False) -adjusted = adjusted.merge(extrnShare, how='left', on='state_puma', - copy=False) -adjusted['sz_ext_prods'] = (adjusted['sz_prods'] * adjusted['ext_prod_factor'] - ).round(1) -adjusted['sz_ext_attrs'] = adjusted['sz_attrs'] * adjusted['ext_attr_factor'] - -# Balance external attractions to productions -extTotals = adjusted.groupby(['wfh_flag','trip_type']).agg( - {'sz_ext_prods': 'sum', - 'sz_ext_attrs': 'sum'} - ).reset_index() - -extTotals.rename(columns={'sz_ext_prods':'total_ext_prods', - 'sz_ext_attrs':'total_ext_attrs'}, inplace=True) -adjusted = adjusted.merge(extTotals, how='left', on=['wfh_flag', 'trip_type'], - copy=True) -adjusted['sz_ext_attrs'] = (adjusted['sz_ext_attrs'] - * adjusted['total_ext_prods'] - / adjusted['total_ext_attrs']) - -# Update productions and attractions, adjust external attractions if needed -adjusted['sz_ext_attrs'] = np.where(adjusted['sz_ext_attrs'] - > adjusted['sz_attrs'], - adjusted['sz_attrs'], - adjusted['sz_ext_attrs']).round(1) -adjusted['sz_prods'] = (adjusted['sz_prods'] - adjusted['sz_ext_prods'] - ).round(1) -adjusted['sz_attrs'] = (adjusted['sz_attrs'] - adjusted['sz_ext_attrs'] - ).round(1) - -if writeOptional: - logging.info(' --> Writing {0:,} records to {1}'.format(len(adjusted), - Path(extrnlProdsAttrs).name)) - writeCols = ['subzone', 'zone', 'wfh_flag', 'trip_type', 'sz_ext_prods', - 'sz_ext_attrs'] - adjusted.to_csv(extrnlProdsAttrs, columns=writeCols, index=False) - -# ---------------------------------------------------------------------------- -# Step 7. Finalize productions and attractions -# ---------------------------------------------------------------------------- -logging.info('Finalizing Productions and Attractions') - -dropCols = ['state_puma', 'ext_prod_factor', 'ext_attr_factor', 'sz_ext_prods', - 'sz_ext_attrs', 'total_ext_prods', 'total_ext_attrs'] -adjusted.drop(dropCols, axis=1, inplace=True) -prodsAttrs = pd.concat([adjusted, unadjusted], ignore_index=True, sort=False) -prodsAttrs.sort_values(['trip_type','subzone'], inplace=True) -prodsAttrs['sz_prods'] = prodsAttrs['sz_prods'] + prodsAttrs['sz_gq_prods'] -prodsAttrs['sz_attrs'] = prodsAttrs['sz_attrs'] + prodsAttrs['sz_gq_attrs'] - -# Write final productions and attractions -noWfhPA = prodsAttrs[prodsAttrs.wfh_flag.eq(0)].copy().reset_index(drop=True) -fixed_width(finalProdsAttrs, noWfhPA) -logging.info(' --> Writing {0:,} records to {1}'.format(len(noWfhPA), - Path(finalProdsAttrs).name)) -# -wfhPA = prodsAttrs[prodsAttrs.wfh_flag.eq(1)].copy().reset_index(drop=True) -fixed_width(finalWfhProdsAttrs, wfhPA) -logging.info(' --> Writing {0:,} records to {1}'.format(len(wfhPA), - Path(finalWfhProdsAttrs).name)) - -# Final summary -workers = prodsAttrs[prodsAttrs.trip_type.le(20)].copy() -nonworkers = prodsAttrs[prodsAttrs.trip_type.ge(21) & - prodsAttrs.trip_type.le(33)].copy() -children = prodsAttrs[prodsAttrs.trip_type.ge(34)].copy() -logging.info('Final Results') -logging.info(' - Workers') -logging.info(' - Productions: {0:>12,.1f}'.format(workers['sz_prods'].sum())) -logging.info(' - Attractions: {0:>12,.1f}'.format(workers['sz_attrs'].sum())) -logging.info(' - Nonworking Adults') -logging.info(' - Productions: {0:>12,.1f}'.format(nonworkers['sz_prods'].sum())) -logging.info(' - Attractions: {0:>12,.1f}'.format(nonworkers['sz_attrs'].sum())) -logging.info(' - Children 12-15') -logging.info(' - Productions: {0:>12,.1f}'.format(children['sz_prods'].sum())) -logging.info(' - Attractions: {0:>12,.1f}'.format(children['sz_attrs'].sum())) -logging.info(' - Total') -logging.info(' - Productions: {0:>12,.1f}'.format(prodsAttrs['sz_prods'].sum())) -logging.info(' - Attractions: {0:>12,.1f}'.format(prodsAttrs['sz_attrs'].sum())) - -t_omega = timeit.default_timer() -logging.info('Trip Generation model took {0:.2f} minutes for {1:,} households' - .format((t_omega-t_alpha)/60, len(hh))) -logging.info('Trip Generation model finished') \ No newline at end of file diff --git a/Database/trip_generation/vehicle_availability.py b/Database/trip_generation/vehicle_availability.py deleted file mode 100644 index 3349c74..0000000 --- a/Database/trip_generation/vehicle_availability.py +++ /dev/null @@ -1,326 +0,0 @@ -""" -Filename: vehicle_availability.py -Author: Craig Heither -Description: These functions are the household vehicle availability model - for trip generation. -""" - -import numpy as np - -def vehOwnOneAdult(rows, rng=None): - """ - Vehicle ownership model for 1-adult households. - - Parameters - ---------- - rows : array_like - Six inputs: [sidewalk_density, row_column, age_category, workers, - income_category, auto_commute_share] - rng : numpy.random.Generator, optional - A Numpy Generator instance for reproducible results. If None, uses - np.random.default_rng(). - - Returns - ------- - ndarray - Integer array of vehicle counts (0..2). - """ - - # Read household parameters - rows = np.asarray(rows) - if rows.ndim == 1: - rows = rows.reshape(1, -1) - sidewalk = rows[:, 0].astype(float) - rowcol = rows[:, 1] - age = rows[:, 2] - workers = rows[:, 3] - income = rows[:, 4] - auto_comm = rows[:, 5].astype(float) - if rng is None: - rng = np.random.default_rng() - - # Lookup tables - bias1_lookup = np.array([-2.600, -2.676, -2.869, -3.082]) - bias2_lookup = np.array([-5.077, -4.823, -4.914, -4.984]) - hh_lookup = np.array([0.392, 0.401, 0.249]) - hh2_lookup = np.array([0.394, 0.465, 0.218]) - - # Safe indexing (rowcol and age are 1-based) - rowcol_idx = np.clip(rowcol.astype(int) - 1, 0, 3) - age_idx = np.clip(age.astype(int) - 1, 0, 2) - - # Utility for zero vehicles - COEF_PEF0 = 0.06165 - UTIL0 = COEF_PEF0 * sidewalk - - # Utility for one vehicle - COEF_WORKER = 0.4731 - COEF_HINC2 = 1.182 - COEF_HINC3 = 0.9910 - COEF_AUTOMS = 4.677 - COEF_PEF1 = 0.03188 - - bias1 = bias1_lookup[rowcol_idx] - hh_bias = hh_lookup[age_idx] - temp1 = (workers.astype(int) == 1).astype(int) - temp2 = (income.astype(int) != 1).astype(int) - temp3 = (income.astype(int) >= 3).astype(int) - - UTIL1 = (COEF_WORKER * temp1 + COEF_HINC2 * temp2 + COEF_HINC3 * temp3 - + COEF_AUTOMS * auto_comm + COEF_PEF1 * sidewalk + bias1 + hh_bias) - - # Utility for two or more vehicles - COEF_WORKER = 0.4731 - COEF_HINC2 = 1.766 - COEF_HINC3 = 1.690 - COEF_HINC4 = 0.4668 - COEF_AUTOMS = 4.677 - - bias2 = bias2_lookup[rowcol_idx] - hh_bias2 = hh2_lookup[age_idx] - temp1 = (workers.astype(int) == 1).astype(int) - temp2 = (income.astype(int) != 1).astype(int) - temp3 = (income.astype(int) >= 3).astype(int) - temp4 = (income.astype(int) == 4).astype(int) - - UTIL2 = (COEF_WORKER * temp1 + COEF_HINC2 * temp2 + COEF_HINC3 * temp3 - + COEF_HINC4 * temp4 + COEF_AUTOMS * auto_comm + bias2 + hh_bias2) - - # Vehicle ownership probabilities - expU = np.exp(np.vstack([UTIL0, UTIL1, UTIL2]).T) - denom = expU.sum(axis=1, keepdims=True) - probs = expU / denom - cumul_probs = probs.cumsum(axis=1) - - # Determine vehicle ownership level - u = rng.random(size=cumul_probs.shape[0]) - # Vectorized row-wise mapping: count how many cumulative probs are < u - idx = np.sum(u[:, None] > cumul_probs, axis=1) - # idx maps to 0->0 vehicles, 1->1, 2->2+ - return idx.astype(int) - -def vehOwnTwoAdult(rows, rng=None): - """ - Vehicle ownership model for 2-adult households. - - Parameters - ---------- - rows : array_like - Seven inputs: [sidewalk_density, row_column, age_category, workers, - income_category, auto_commute_share, children] - rng : numpy.random.Generator, optional - A Numpy Generator instance for reproducible results. If None, uses - np.random.default_rng(). - - Returns - ------- - ndarray - Integer array of vehicle counts (0..3). - """ - rows = np.asarray(rows) - if rows.ndim == 1: - rows = rows.reshape(1, -1) - sidewalk = rows[:, 0].astype(float) - rowcol = rows[:, 1] - age = rows[:, 2] - workers = rows[:, 3].astype(int) - income = rows[:, 4].astype(int) - auto_comm = rows[:, 5].astype(float) - children = rows[:, 6].astype(float) - if rng is None: - rng = np.random.default_rng() - - # Lookup tables - bias1_lookup = np.array([2.018, 2.259, 2.151, 1.925]) - bias2_lookup = np.array([-2.827, -2.637, -2.728, -3.144]) - bias3_lookup = np.array([-4.393, -3.944, -4.126, -4.302]) - hh_lookup = np.array([0.392, 0.401, 0.249]) - hh2_lookup = np.array([0.394, 0.465, 0.218]) - hh3_lookup = np.array([0.403, 0.574, 0.007]) - - # Safe indexing (rowcol and age are 1-based) - rowcol_idx = np.clip(rowcol.astype(int) - 1, 0, 3) - age_idx = np.clip(age.astype(int) - 1, 0, 2) - - # Utility for zero vehicles - COEF_PEF = 0.1280 - UTIL0 = COEF_PEF * sidewalk - - # Utility for one vehicle - COEF_HINC2 = 1.702 - COEF_PEF = 0.06309 - bias1 = bias1_lookup[rowcol_idx] - hh_bias = hh_lookup[age_idx] - temp1 = (income != 1).astype(int) - - UTIL1 = COEF_HINC2 * temp1 + COEF_PEF * sidewalk + bias1 + hh_bias - - # Utility for two vehicles - COEF_WORK1 = 0.6940 - COEF_WORK2 = 0.5198 - COEF_HINC2 = 2.466 - COEF_HINC3 = 0.8650 - COEF_HINC4 = 0.4517 - COEF_AUTOMS = 5.284 - COEF_CHILD = 0.2218 - COEF_PEF = 0.03359 - - bias2 = bias2_lookup[rowcol_idx] - hh_bias2 = hh2_lookup[age_idx] - temp1 = (workers > 0).astype(int) - temp2 = (workers > 1).astype(int) - temp3 = (income > 1).astype(int) - temp4 = (income > 2).astype(int) - temp5 = (income == 4).astype(int) - - UTIL2 = (COEF_WORK1 * temp1 + COEF_WORK2 * temp2 + COEF_HINC2 * temp3 - + COEF_HINC3 * temp4 + COEF_HINC4 * temp5 + COEF_AUTOMS * auto_comm - + COEF_CHILD * children + COEF_PEF * sidewalk + bias2 + hh_bias2) - - # Utility for three plus vehicles - COEF_WORK1 = 0.6940 - COEF_WORK2 = 0.5198 - COEF_HINC2 = 2.466 - COEF_HINC3 = 0.8650 - COEF_HINC4 = 0.8827 - COEF_AUTOMS = 5.284 - - bias3 = bias3_lookup[rowcol_idx] - hh_bias3 = hh3_lookup[age_idx] - temp1 = (workers > 0).astype(int) - temp2 = (workers > 1).astype(int) - temp3 = (income > 1).astype(int) - temp4 = (income > 2).astype(int) - temp5 = (income == 4).astype(int) - - UTIL3 = (COEF_WORK1 * temp1 + COEF_WORK2 * temp2 + COEF_HINC2 * temp3 - + COEF_HINC3 * temp4 + COEF_HINC4 * temp5 + COEF_AUTOMS * auto_comm - + bias3 + hh_bias3) - - # Vehicle ownership probabilities - expU = np.exp(np.vstack([UTIL0, UTIL1, UTIL2, UTIL3]).T) - denom = expU.sum(axis=1, keepdims=True) - probs = expU / denom - cumul_probs = probs.cumsum(axis=1) - - # Determine vehicle ownership level - u = rng.random(size=cumul_probs.shape[0]) - # Vectorized row-wise mapping: count how many cumulative probs are < u - idx = np.sum(u[:, None] > cumul_probs, axis=1) - return idx.astype(int) - -def vehOwnThreeAdult(rows, rng=None): - """ - Vehicle ownership model for 3-or-more-adult households. - - Parameters - ---------- - rows : array_like - Seven inputs: [sidewalk_density, row_column, age_category, workers, - income_category, auto_commute_share, nonworkers] - rng : numpy.random.Generator, optional - A Numpy Generator instance for reproducible results. If None, uses - np.random.default_rng(). - - Returns - ------- - ndarray - Integer array of vehicle counts (0..3). - """ - rows = np.asarray(rows) - if rows.ndim == 1: - rows = rows.reshape(1, -1) - sidewalk = rows[:, 0].astype(float) - rowcol = rows[:, 1] - age = rows[:, 2] - workers = rows[:, 3].astype(int) - income = rows[:, 4].astype(int) - auto_comm = rows[:, 5].astype(float) - nonworkers = rows[:, 6].astype(float) - if rng is None: - rng = np.random.default_rng() - - # Lookup tables - bias1_lookup = np.array([2.806, 2.552, 1.547, 2.272]) - bias2_lookup = np.array([-1.836, -2.139, -2.783, -2.430]) - bias3_lookup = np.array([-1.631, -1.789, -2.668, -2.278]) - hh_lookup = np.array([0.392, 0.401, 0.249]) - hh2_lookup = np.array([0.394, 0.465, 0.218]) - hh3_lookup = np.array([0.403, 0.574, 0.007]) - - # Safe indexing (rowcol and age are 1-based) - rowcol_idx = np.clip(rowcol.astype(int) - 1, 0, 3) - age_idx = np.clip(age.astype(int) - 1, 0, 2) - - # Utility for zero vehicles - COEF_PEF = 0.1703 - UTIL0 = COEF_PEF * sidewalk - - # Utility for one vehicle - COEF_WORK1 = 1.114 - COEF_HINC2 = 0.9492 - COEF_PEF = 0.06586 - - bias1 = bias1_lookup[rowcol_idx] - hh_bias = hh_lookup[age_idx] - temp1 = (workers > 0).astype(int) - temp2 = (income > 1).astype(int) - - UTIL1 = (COEF_WORK1 * temp1 + COEF_HINC2 * temp2 + COEF_PEF * sidewalk - + bias1 + hh_bias) - - # Utility for two vehicles - COEF_WORK1 = 1.114 - COEF_WORK2 = 0.7934 - COEF_HINC2 = 1.487 - COEF_HINC3 = 0.8723 - COEF_HINC4 = 1.390 - COEF_AUTOMS = 4.959 - COEF_PEF2 = 0.06586 - - bias2 = bias2_lookup[rowcol_idx] - hh_bias2 = hh2_lookup[age_idx] - temp1 = (workers > 0).astype(int) - temp2 = (workers > 1).astype(int) - temp3 = (income > 1).astype(int) - temp4 = (income > 2).astype(int) - temp5 = (income == 4).astype(int) - - UTIL2 = (COEF_WORK1 * temp1 + COEF_WORK2 * temp2 + COEF_HINC2 * temp3 - + COEF_HINC3 * temp4 + COEF_HINC4 * temp5 + COEF_AUTOMS * auto_comm - + COEF_PEF2 * sidewalk + bias2 + hh_bias2) - - # Utility for three plus vehicles - COEF_WORK1 = 1.114 - COEF_WORK2 = 0.7934 - COEF_WORK3 = 1.389 - COEF_HINC2 = 1.487 - COEF_HINC3 = 1.571 - COEF_HINC4 = 1.834 - COEF_ADULT = 0.1491 - COEF_AUTOMS = 4.959 - - bias3 = bias3_lookup[rowcol_idx] - hh_bias3 = hh3_lookup[age_idx] - temp1 = (workers > 0).astype(int) - temp2 = (workers > 1).astype(int) - temp3 = (workers > 2).astype(int) - temp4 = (income > 1).astype(int) - temp5 = (income > 2).astype(int) - temp6 = (income == 4).astype(int) - - UTIL3 = (COEF_WORK1 * temp1 + COEF_WORK2 * temp2 + COEF_WORK3 * temp3 - + COEF_HINC2 * temp4 + COEF_HINC3 * temp5 + COEF_HINC4 * temp6 - + COEF_ADULT * nonworkers + COEF_AUTOMS * auto_comm + bias3 + hh_bias3) - - # Vehicle ownership probabilities - expU = np.exp(np.vstack([UTIL0, UTIL1, UTIL2, UTIL3]).T) - denom = expU.sum(axis=1, keepdims=True) - probs = expU / denom - cumul_probs = probs.cumsum(axis=1) - - # Determine vehicle ownership level - u = rng.random(size=cumul_probs.shape[0]) - # Vectorized row-wise mapping: count how many cumulative probs are < u - idx = np.sum(u[:, None] > cumul_probs, axis=1) - return idx.astype(int) \ No newline at end of file diff --git a/Database/useful_macros/cleanup_for_rerun.py b/Database/useful_macros/cleanup_for_rerun.py index f5caa0c..cd281db 100644 --- a/Database/useful_macros/cleanup_for_rerun.py +++ b/Database/useful_macros/cleanup_for_rerun.py @@ -16,10 +16,9 @@ def main(): #set variables currentScen = int(sys.argv[1]) - cScenAM = currentScen + 3 - scenario = str(cScenAM) + scenario = str(currentScen) cScenMD = currentScen + 5 - moveF11 = "build_" + str(cScenAM) + "transit.rpt" + moveF11 = "build_" + str(currentScen) + "transit.rpt" moveF12 = "report/" + moveF11 moveF21 = "build_" + str(cScenMD) + "transit.rpt" moveF22 = "report/" + moveF21 @@ -66,7 +65,7 @@ def main(): if os.path.isfile("truck.access.rpt"): shutil.move("truck.access.rpt", "report/truck.access.rpt") #Set primary scenario - change_scenario(scenario=cScenMD) + change_scenario(scenario=currentScen) #delete scenarios and matrices for c in counters1: if c == 0: @@ -76,17 +75,19 @@ def main(): counter1 = counter1+1 else: while counter1 <= c +9: - scen = str(currentScen) + str(counter1) + scen = str(scenario) + str(counter1) scenDel = emmebank.scenario(scen) if scenDel: delete_scenario(scenDel) counter1 = int(counter1) counter1 = counter1+1 - #delete transit overnight and PM peak skim scenarios if exist - trSkims= (currentScen+1, currentScen+7) - for t in trSkims: - scenDel = emmebank.scenario(t) - if scenDel: delete_scenario(scenDel) + # #delete transit assignment scenarios if exist + # for c in counters2: + # scen = currentScen + c + # scenDel = _m.Modeller().emmebank.scenario(scen) + # if scenDel: delete_scenario(scenDel) + # counter2 = int(counter2) + # counter2 = counter2+1 #delete matrices matpairs = {} @@ -103,7 +104,7 @@ def main(): begVal = begVal + 1 if matrix: delete_matrix(matrix) - #set ms97, ms98, & ms99 to proper values for rerun (create if necessary) + #set ms97, ms98, &ms99 to proper values for rerun (create if necessary) new_mat97 = create_matrix(matrix_id="ms97", matrix_name="one", matrix_description="dummy for assignment", @@ -120,11 +121,9 @@ def main(): default_value=0, overwrite ="True") - #delete set of matrices no longer used in model - unneeded = ("ms1","mf835","mf836","mf839","mf935","mf936","mf939") - for u in unneeded: - matrix = emmebank.matrix(u) - if matrix: delete_matrix(matrix) + #delete ms1: no using lower bound for impedance matrix balancing in revised distribution + matrix = emmebank.matrix("ms1") + if matrix: delete_matrix(matrix) if __name__ == '__main__': main() \ No newline at end of file diff --git a/Scripts/manage/env/CMAP-TRIP2.yml b/Scripts/manage/env/CMAP-TRIP2.yml new file mode 100644 index 0000000..674f2a1 --- /dev/null +++ b/Scripts/manage/env/CMAP-TRIP2.yml @@ -0,0 +1,57 @@ +# To use this file: +# conda env create -f CMAP-TRIP2.yml +name: CMAP-TRIP2 +channels: + - conda-forge +dependencies: + - altair=4.1 + - appdirs=1.4 + - cloudpickle=2.0 + - dask=2021.12 + - datashader=0.13 + - distributed=2021.12 + - fiona=1.8 + - geopandas=0.10 + - gh=2.4 + - git=2.34 + - graphviz=2.50 + - ipykernel=6.6 + - ipyparallel=8.1 + - ipywidgets=7.6 + - joblib=1.1 + - jupyter=1.0 + - jupyter_contrib_nbextensions=0.5 # On conda-forge only + - larch=5.5.9 + - matplotlib=3.5 + - nb_conda=2.2 + - notebook=6.4 + - numba=0.53 + - numpy=1.21 + - numexpr=2.7 + - pandas=1.3 + - pip=21.3 + - platypus-opt=1.0 + - plotly=5.5 + - pyarrow=6.0 + - pydot=1.4 + - pyscaffold=4.1 + - pytest=6.2 + - python=3.9 + - python-kaleido=0.2 # Plotly Static Image Export + - pyzmq=22.3 + - salib=1.4 + - scikit-learn=1.0 + - scipy=1.7 + - seaborn=0.11 + - shortuuid=1.0 + - sqlalchemy=1.4 + - statsmodels=0.13 + - tbb=2021.4 + - tbb4py=2021.4 + - xarray=0.20 + - zarr=2.10 + - pip: + - emat + # Uses relative paths to local packages + - -e ../../../src/Mode-Dest-TOD + - -e ../../../src/Mode-Dest-TOD/sharrow \ No newline at end of file diff --git a/Scripts/manage/env/activate_env.cmd b/Scripts/manage/env/activate_env.cmd new file mode 100644 index 0000000..7b67d2f --- /dev/null +++ b/Scripts/manage/env/activate_env.cmd @@ -0,0 +1,64 @@ +@echo off + +rem activate_env.cmd [1] + +rem Activates an existing conda environment or, if it does not exist, +rem creates the environment before activating it. + +rem Parameters: +rem 1 : emme +rem Activate the custom Emme environment instead of the TBM +rem environment (default). + +if [%~1] == [emme] (set EMME_ENV=y) else (set EMME_ENV=n) +set PDIR=%~dp0 + +rem Define here the name of the TBM environment to be used. +set TBM_ENVNAME=CMAP-TRIP2 +rem Define here the name of the custom Emme environment to be used. +set EMME_ENVNAME=emme-plus + +call "%PDIR%set_condapath.cmd" +if %ERRORLEVEL% neq 0 (goto end) + +if %EMME_ENV%==y (set ENVNAME=%EMME_ENVNAME%) else (set ENVNAME=%TBM_ENVNAME%) +set ENVPATH=%CONDAPATH%\envs\%ENVNAME% + +rem Create it if it doesn't exist. +if not exist "%ENVPATH%\python.exe" ( + echo Python not found at "%ENVPATH%" + echo. + rem Activate the conda base environment. + rem Using call is required here, see: + rem https://stackoverflow.com/questions/24678144/conda-environments-and-bat-files + call "%CONDAPATH%\Scripts\activate.bat" + if %ERRORLEVEL% neq 0 ( + echo Error in activating conda + goto end + ) + rem Create it from a file. + echo Creating %ENVNAME% environment + echo. + call conda env create -f "%PDIR%%ENVNAME%.yml" + + if %EMME_ENV%==y ( + rem Add the path configuration file to include Emme Python libraries. + copy "%PDIR%emme.pth" "%ENVPATH%\Lib\site-packages" + ) +) + +rem Activate it. +call "%CONDAPATH%\Scripts\activate.bat" "%ENVPATH%" +if %ERRORLEVEL% neq 0 ( + echo Error in activating %ENVNAME% + goto end +) else (goto activated) + +:end +echo. +pause +exit + +:activated +echo Active conda environment is %ENVNAME% +echo. \ No newline at end of file diff --git a/Scripts/manage/env/emme-plus.yml b/Scripts/manage/env/emme-plus.yml new file mode 100644 index 0000000..e9cb7f3 --- /dev/null +++ b/Scripts/manage/env/emme-plus.yml @@ -0,0 +1,16 @@ +# To use this file: +# conda env create -f emme-plus_environment.yml +name: emme-plus +channels: + - conda-forge +dependencies: + - jinja2 + - markdown + - myst-parser + - openpyxl + - pyarrow + - python=3.11.6 + - pyyaml + - sphinx + - sphinx_rtd_theme + - tqdm \ No newline at end of file diff --git a/Scripts/manage_envs/emme.pth b/Scripts/manage/env/emme.pth similarity index 100% rename from Scripts/manage_envs/emme.pth rename to Scripts/manage/env/emme.pth diff --git a/Scripts/manage/env/set_condapath.cmd b/Scripts/manage/env/set_condapath.cmd new file mode 100644 index 0000000..cc8d49e --- /dev/null +++ b/Scripts/manage/env/set_condapath.cmd @@ -0,0 +1,46 @@ +@echo off + +rem The `CONDAPATH` environment variable should be set before running this .cmd +rem It points to the place where conda is installed +rem Alternatively, if running in a conda prompt itself then CONDA_PREFIX will be set +if defined CONDAPATH ( + goto condafound +) +if defined CONDA_PREFIX ( + set CONDAPATH=%CONDA_PREFIX% + echo CONDA_PREFIX is "%CONDAPATH%" + goto condafound +) +rem Define here all the places where we might find the conda installation +rem If you try to run the model, you know that conda is installed, and the +rem model fails with "cannot find conda", then visit a conda prompt, +rem run `where conda`, and add the resulting path to this list. +for %%x in ( + %CONDAPATH% + %CONDA_PREFIX% + %LOCALAPPDATA%\mambaforge + %LOCALAPPDATA%\miniforge + %LOCALAPPDATA%\miniconda + %LOCALAPPDATA%\miniconda3 + %LOCALAPPDATA%\Anaconda3 + %USERPROFILE%\Anaconda3 + %USERPROFILE%\Anaconda + %USERPROFILE%\Anaconda2 + %USERPROFILE%\miniconda3 + %USERPROFILE%\miniconda + %USERPROFILE%\miniconda2 +) do ( + if exist "%%x\Scripts\activate.bat" ( + set CONDAPATH=%%x + goto condafound + ) +) +echo Cannot find conda in any of the usual places. +echo CONDAPATH is not defined, first run set CONDAPATH=C:\... to point to the conda installation. +echo. +pause +exit + +:condafound +echo CONDAPATH is "%CONDAPATH%" +echo. \ No newline at end of file diff --git a/Scripts/manage_envs/cmap-modedest/cmap-modedest.yml b/Scripts/manage_envs/cmap-modedest/cmap-modedest.yml deleted file mode 100644 index d44d1a7..0000000 --- a/Scripts/manage_envs/cmap-modedest/cmap-modedest.yml +++ /dev/null @@ -1,7 +0,0 @@ -name: cmap-modedest -channels: - - conda-forge -dependencies: - - larch=5.5.9 - - python=3.9 - - uv \ No newline at end of file diff --git a/Scripts/manage_envs/cmap-modedest/requirements.txt b/Scripts/manage_envs/cmap-modedest/requirements.txt deleted file mode 100644 index 4b2351e..0000000 --- a/Scripts/manage_envs/cmap-modedest/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -git+https://github.com/CMAP-REPOS/cmap_modedest@v24.4.1 \ No newline at end of file diff --git a/Scripts/manage_envs/install_envs.ps1 b/Scripts/manage_envs/install_envs.ps1 deleted file mode 100644 index 4fa4c9c..0000000 --- a/Scripts/manage_envs/install_envs.ps1 +++ /dev/null @@ -1,49 +0,0 @@ -# Install miniconda. -$condaPath = "$env:LOCALAPPDATA\miniconda3" -if (-not (Test-Path -Path "$condaPath\python.exe")) { - Invoke-WebRequest -Uri "https://repo.anaconda.com/miniconda/Miniconda3-latest-Windows-x86_64.exe" -OutFile "$env:USERPROFILE\Downloads\Miniconda3-latest-Windows-x86_64.exe" - Start-Process -FilePath "$env:USERPROFILE\Downloads\Miniconda3-latest-Windows-x86_64.exe" -ArgumentList "/S", "/D=$condaPath" -Wait -} -# Install uv. -$uvPath = "$env:USERPROFILE\.local\bin" -if (-not (Test-Path -Path "$uvPath\uv.exe")) { - # Run the installer. Please review the printed message after installation. - powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" - # Add uv to Path - $env:Path = "$uvPath;$env:Path" -} -.$condaPath\shell\condabin\conda-hook.ps1 -# Create the R conda environment for running R scripts. -if (-not (conda env list | Select-String -Pattern "tbm-r" -Quiet)) { - conda env create --file "$PSScriptRoot\tbm-r\tbm-r.yml" --yes - if ($LastExitCode -ne 0) { - Write-Error "conda env create tbm-r failed" - exit $LastExitCode - } -} -# Create the Python conda environment for running cmap_modedest. -if (-not (conda env list | Select-String -Pattern "cmap-modedest" -Quiet)) { - conda env create --file "$PSScriptRoot\cmap-modedest\cmap-modedest.yml" --yes - if ($LastExitCode -ne 0) { - Write-Error "conda env create cmap-modedest failed" - exit $LastExitCode - } - conda activate cmap-modedest - uv pip install --requirements "$PSScriptRoot\cmap-modedest\requirements.txt" - if ($LastExitCode -ne 0) { - Write-Error "(cmap-modedest) uv pip install failed" - exit $LastExitCode - } - conda deactivate -} -# Sync the base uv environment for running the model. -if (-not (Test-Path -Path "$PSScriptRoot\..\..\uv.lock")) { - uv lock -} -uv sync --locked -if ($LastExitCode -ne 0) { - Write-Error "uv sync failed" - exit $LastExitCode -} -# Extend the base environment to include Emme packages. -Copy-Item -Path "$PSScriptRoot\emme.pth" -Destination "$PSScriptRoot\..\..\.venv\Lib\site-packages" \ No newline at end of file diff --git a/Scripts/manage_envs/tbm-r/tbm-r.yml b/Scripts/manage_envs/tbm-r/tbm-r.yml deleted file mode 100644 index 6cc3d50..0000000 --- a/Scripts/manage_envs/tbm-r/tbm-r.yml +++ /dev/null @@ -1,8 +0,0 @@ -name: tbm-r -channels: - - conda-forge -dependencies: - - r-base=4.3 - - r-foreign - - r-tidyverse - - r-sf \ No newline at end of file diff --git a/Scripts/manage_envs/uninstall_envs.ps1 b/Scripts/manage_envs/uninstall_envs.ps1 deleted file mode 100644 index 8bac98a..0000000 --- a/Scripts/manage_envs/uninstall_envs.ps1 +++ /dev/null @@ -1,4 +0,0 @@ -$condaPath = "$env:LOCALAPPDATA\miniconda3" -.$condaPath\shell\condabin\conda-hook.ps1 -conda remove --name tbm-r --yes --all -conda remove --name cmap-modedest --yes --all \ No newline at end of file diff --git a/Scripts/prepare/conformity_scenario/hand/config.yaml b/Scripts/prepare/conformity_scenario/hand/config.yaml index 3249257..5300f9a 100644 --- a/Scripts/prepare/conformity_scenario/hand/config.yaml +++ b/Scripts/prepare/conformity_scenario/hand/config.yaml @@ -1,28 +1,46 @@ # model_version: c24q4 # scenario_code: 100 -similar_model_version: c25q4 # For copying model data +similar_model_version: c24q4 # For copying model data scenario_years: 100: 2019 - 200: 2026 + 200: 2025 300: 2030 - 400: 2032 - 500: 2035 - 600: 2040 - 700: 2045 - 800: 2050 + 400: 2035 + 500: 2040 + 600: 2045 + 700: 2050 +wfh_rates: + 2019: + fully_remote: 0.0510 + hybrid: 0.1031 + 2025: + fully_remote: 0.0869 + hybrid: .1257 + 2030: + fully_remote: 0.0875 + hybrid: 0.1263 + 2035: + fully_remote: 0.0880 + hybrid: 0.1270 + 2040: + fully_remote: 0.0884 + hybrid: .1273 + 2045: + fully_remote: 0.0884 + hybrid: 0.1272 + 2050: + fully_remote: 0.0882 + hybrid: 0.1269 trip_growth_factors: 2019: truck/poe: 1.19 visit: 1.00 - 2026: - truck/poe: 1.26 + 2025: + truck/poe: 1.25 visit: 1.05 2030: truck/poe: 1.30 visit: 1.18 - 2032: - truck/poe: 1.32 - visit: 1.24 2035: truck/poe: 1.35 visit: 1.34 diff --git a/Scripts/prepare/conformity_scenario/run.cmd b/Scripts/prepare/conformity_scenario/run.cmd index 0d93afa..8bc1d72 100644 --- a/Scripts/prepare/conformity_scenario/run.cmd +++ b/Scripts/prepare/conformity_scenario/run.cmd @@ -2,6 +2,7 @@ cd %~dp0 -uv run ".\src\prepare_conformity_scenario.py" +call "..\..\manage\env\activate_env.cmd" "emme" +python ".\src\prepare_conformity_scenario.py" pause \ No newline at end of file diff --git a/Scripts/prepare/conformity_scenario/src/prepare_conformity_scenario.py b/Scripts/prepare/conformity_scenario/src/prepare_conformity_scenario.py index 560489d..e9266c8 100644 --- a/Scripts/prepare/conformity_scenario/src/prepare_conformity_scenario.py +++ b/Scripts/prepare/conformity_scenario/src/prepare_conformity_scenario.py @@ -69,7 +69,15 @@ def rename_project(config): emp_file.rename(Path(emp_file.parent, new_name + '.emp')) prj_file.rename(Path(prj_file.parent, new_name + '.emp.prj')) print('project renamed') - + +def get_wfh_rates(config): + scenario_year = config['scenario_years'][config['scenario_code']] + wfh_rates = config['wfh_rates'][scenario_year] + print('\n' + f'Set these {scenario_year} WFH rates in \\Database\\batch_file.yaml:\n' + f" * usualwfhpct: {wfh_rates['fully_remote']}\n" + f" * tc14pct: {wfh_rates['hybrid']}\n") + def get_trip_growth_factors(config): scenario_year = config['scenario_years'][config['scenario_code']] trip_growth_factors = config['trip_growth_factors'][scenario_year] @@ -104,6 +112,7 @@ def main(): input_data_mac.main() print('warm start matrices generated') rename_project(config) + get_wfh_rates(config) get_trip_growth_factors(config) get_tnc_surcharge_rates(config) diff --git a/Scripts/share/standard_data/hand/data_user_guide_md.txt b/Scripts/share/standard_data/hand/data_user_guide_md.txt index dac5706..355d1b9 100644 --- a/Scripts/share/standard_data/hand/data_user_guide_md.txt +++ b/Scripts/share/standard_data/hand/data_user_guide_md.txt @@ -521,12 +521,12 @@ SOV vehicle trip value-of-time conversion:
-[**Subzone 2017 Geography**](https://datahub.cmap.illinois.gov/datasets/CMAPGIS::trip-generation-zones-subzones-2017/about) +[**Subzone 2017 Geography**](https://datahub.cmap.illinois.gov/datasets/CMAPGIS::trip-generation-zone-subzone-geography-2017/about) Trip generation information can be joined to subzones for visualization and spatial analysis.
-[**Traffic Analysis Zone 2017 Geography**](https://datahub.cmap.illinois.gov/datasets/CMAPGIS::trip-generation-zones-zones-2017/about) +[**Traffic Analysis Zone 2017 Geography**](https://datahub.cmap.illinois.gov/datasets/CMAPGIS::traffic-analysis-zone-geography-2017/about) Trip productions and attractions and distributed trip table information can be joined to TAZs for visualization and spatial analysis. \ No newline at end of file diff --git a/Scripts/share/standard_data/src/standard_data.py b/Scripts/share/standard_data/src/standard_data.py index edaf8c9..50ea576 100644 --- a/Scripts/share/standard_data/src/standard_data.py +++ b/Scripts/share/standard_data/src/standard_data.py @@ -182,11 +182,7 @@ def export(project_file_name, trip_roster_file_name, tg_data_file_name, scenario # Copy TG results to output directory. logging.info('Copying TG results') tg_dir = _proj_dir.joinpath('Database/tg') - tg_results_file = sorted(tg_dir.joinpath('data').glob('tg_results*.csv')) - if len(tg_results_file) > 1: - raise FileNotFoundError(f'Multiple TG results files exist in {tg_dir}.') - else: - file = tg_results_file[0] + file = sorted(tg_dir.joinpath('data').glob('tg_results*.csv'))[0] shutil.copy(file, _out_dir) file_copy = _out_dir.joinpath(file.name) renamed_copy = file_copy.with_name(tg_data_file_name) diff --git a/c25q4_100.emp b/c25q2_100.emp similarity index 99% rename from c25q4_100.emp rename to c25q2_100.emp index 0fd214e..487c4aa 100644 --- a/c25q4_100.emp +++ b/c25q2_100.emp @@ -1,9 +1,9 @@ 0CAFACB7-AD3C-40E4-80DD-675DE315EA7F 07B0F5AD-A2A7-4B4E-B4A9-06EB441586D6 2 2 0 -# Emme project file generated on Tue Nov 4 17:13:01 2025 -# File: E:/nrf/tbm/c25q4/cmap_trip-based_model/c25q2_100.emp +# Emme project file generated on Sat Apr 5 07:23:11 2025 +# File: D:/nrf/TBM/cmap_trip-based_model/c25q2_100.emp # # String Name: name of preference configuration (tr) -Name = c25q4_100 +Name = c25q2_100 # Text Description: description of preference configuration (tr,subst) Description = Created by Claire Bozic 4-24-2017 # String TranslationContext: context for translations of configuration texts (subst) diff --git a/c25q4_100.emp.prj b/c25q2_100.emp.prj similarity index 100% rename from c25q4_100.emp.prj rename to c25q2_100.emp.prj diff --git a/copy_scenario_data.ps1 b/copy_scenario_data.ps1 index b6a6b43..fdd0ca8 100644 --- a/copy_scenario_data.ps1 +++ b/copy_scenario_data.ps1 @@ -8,6 +8,11 @@ $destination_db = "$destination_dir\Database\" $items = @("emmebank" "emmemat" "tg\UrbanSim_inputs" + "tg\fortran\ATTR_IN.TXT" + "tg\fortran\HH_IN.TXT" + "tg\fortran\GQ_IN.TXT" + "tg\fortran\POPSYN_HH.CSV" + "tg\fortran\airport_sz.csv" "tg\fortran\SCHOOL_IN.CSV" "tg\fortran\wfhmodule\indusmix.csv") diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 8f914ca..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,21 +0,0 @@ -[project] -name = "cmap_trip-based_model" -version = "26.4.22" -requires-python = "==3.11.6" -dependencies = [ - "jinja2", - "markdown", - "myst-parser", - "numpy~=1.0", - "numexpr>=2.8.0,<2.8.5", - "openpyxl", - "pandas~=2.0", - "pyarrow", - "pyyaml", - "sphinx", - "sphinx_rtd_theme", - "tqdm" -] - -[tool.uv] -package = false \ No newline at end of file diff --git a/src/Mode-Dest-TOD/.gitignore b/src/Mode-Dest-TOD/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/src/Mode-Dest-TOD/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/src/Mode-Dest-TOD/README.md b/src/Mode-Dest-TOD/README.md new file mode 100644 index 0000000..82de4bf --- /dev/null +++ b/src/Mode-Dest-TOD/README.md @@ -0,0 +1,81 @@ +# CMAP Trip-based Model + +This directory contains the code needed to run the CMAP trip-based model's +mode, destination and time-of-day model components. + +## Installation Instructions + +- First, if "conda" is not already installed and accessible by the current user + on the target development machine, install it. An easy installation solution + is using the "Mambaforge" installer, which can be downloaded for windows here: + + > https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Windows-x86_64.exe + + Once downloaded, double-click and run the installer. Mamba is a somewhat faster + implementation of the conda package installer, and can be used interchangably + with conda - nearly any command you might run as `conda foo` can also be run as + `mamba foo`. + +- Then if needed also install git and (optionally) the GitHub command line interface. + From either the Anaconda Prompt or the Miniforge Prompt, run: + + > mamba install git gh -c conda-forge + +- Now clone the CMAP trip-based model code from GitHub, and checkout the CS2021 branch. + + > gh repo clone camsys/cmap_trip-based_model + > cd cmap_trip-based_model + > git checkout CS2021 + + To clone into a different directory than the current directory (probably the + user's home directory) change to that directory using `cd` first. + +- Next, create a conda environment to use for the mode, destination and + time-of-day model components, which are written in Python. + Creating a unique environment will ensure that all the necessary computational + libraries are installed, and no conflicts are introduced with other tools + (including Emme). A conda environment file is included in the GitHub repository, + which installs everything you need into an environment called "CMAP-TRIP". + + > conda env create --file src/Mode-Dest-TOD/conda-environment.yml + + All the necessary files for a basic run of the model using the default base year + inputs are already in the `Database` folder of this repository, except for the + skim data, which is quite large. + +- Skim data can be accessed by the mode, destination and time-of-day model + components in one of two formats: either as uncompressed raw "emx" files stored + in the `Database/emmemat` directory, or as compressed and chunked files stored + in the `Database/emmemat.zarr` directory. A base year set of skims in zarr + format is available here: + + > https://camsys-my.sharepoint.com/:u:/p/jeffnewman/Eckzo0ouKfpKkpfiGtsLJBYB4zUQt6dZ5eloVisGIJV9gg?e=CNsW0M + +## Execution Instructions + +- To run the mode, destination, and time-of-day components for the CMAP Trip-based + model, first activate the correct conda environment. From either the Anaconda Prompt + or the Miniforge Prompt, run: + + > conda activate CMAP-TRIP + + (If you created an environment with some other name, activate that other environment instead.) + +- Then, you can run the model by calling its executable version right from that + same command prompt, pointing at the correct `Database` directory: + + > cmap_modedest .\path\to\Database + +- The `cmap_modedest` command line tool has a number of available options. The most important + of these include the number of jobs and maximum number of origin zones processed per chunk, + each of which needs to be set appropriately for the computer running the model to maximize + resource usage (CPU's, RAM) without exceeding available resources, which can cause + out-of-memory errors or processor thrashing that can slow the overall runtime. + These options can be reviewed in the online help: + + > cmap_modedest --help + + + + +cmap_modedest Database --njobs 12 --max_zone_chunk 5 \ No newline at end of file diff --git a/src/Mode-Dest-TOD/TECHNICALGUIDE.md b/src/Mode-Dest-TOD/TECHNICALGUIDE.md new file mode 100644 index 0000000..6ec0825 --- /dev/null +++ b/src/Mode-Dest-TOD/TECHNICALGUIDE.md @@ -0,0 +1,66 @@ +# Mode, Destination, and Time of Day Technical Guide + +## Functional Flow + +When you invoke the `cmap_modedest` tool on the command line, a Python session +is started and the `run` function (see `cmap_modedest/__main__.py`) is called. + +- `run()` in `cmap_modedest/__main__.py` + + This is the main control loop function. It processes command line arguments + and then launches `choice_simulator_trips_many` as configured. + +- `choice_simulator_trips_many()` in `cmap_modedest/application.py` + + This is the workhorse function, it breaks TAZ's into batches, starts multiple + parallel processes to handle trip simulation on the batches, and aggregates + the results. The other principal functions that this function calls include + `choice_simulator_trips`, `compute_deadhead_trip_table`, and `assemble_trips`. + +- `choice_simulator_trips()` in `cmap_modedest/application.py` + + This is the single-process function to model trips by mode/dest/time, called + once for each job started by `choice_simulator_trips_many`. + +- `compute_deadhead_trip_table()` in `cmap_modedest/application.py` + + This is where deadhead trips are created. + +- `assemble_trips()` in `cmap_modedest/application.py` + + This is where all the various parquet trip-list files are assembled into + a common dask DataFrame for processing. + +- `choice_simulator_initialize` in `cmap_modedest/application.py` + + This function checks if the mode+destination choice models have already been + loaded into memory for this process. If they have not, it then checks if + a pickled version of the choice models has been saved to disk, and loads that + if it is available. Otherwise, it initializes the choice models from scratch + using the `model_builder` function. + +- `model_builder` in `cmap_modedest/choice_model.py` + + This function creates the structure of the model and sets parameter + values within that structure if given. + +- `choice_simulator_prob` in `cmap_modedest/application.py` + + Here, the choice model is used to compute the probabilities for the mode and + destintion choices. + + + + +## Statefulness + +The program avoids creating a global "state" to facilitate passing the state to +subprocesses that actually execute jobs. Instead, a common DataHandler object +is used to pass state (i.e. the names of the input files, configuration options, +etc) from the main process to subprocessed. + +The main state object is a `DataHandler` object. This class is defined in +`cmap_modedest/data_handlers/__init__.py`. An instance of the DataHandler is passed +around between functions, generally as the first argument to each function that +needs it, as an argument named `dh`. + diff --git a/src/Mode-Dest-TOD/USERGUIDE.md b/src/Mode-Dest-TOD/USERGUIDE.md new file mode 100644 index 0000000..07a1111 --- /dev/null +++ b/src/Mode-Dest-TOD/USERGUIDE.md @@ -0,0 +1,495 @@ +# Mode, Destination, and Time of Day User Guide + +This document describes the Mode, Destination, and Time of Day (MDT) models, +including the basic conceptual structure, input files used, output files +generated, and method of operation. + +## Model Structure + +The CMAP trip-based model's MDT models are implemented in Python, using modern +multiprocessing techniques to greatly enhance the sensitivity and detail of the +model, without significantly increasing the overall model runtime. + +### Joint Mode and Destination + +The model includes an integrated mode and destination choice model. The mode and +destination choice model was estimated as a single model using full-information +maximum likelihood methods, which represents a significant theoretical enhancement +over two-step models (i.e. models where mode choice logsums are computed based on +the estimated mode choice model, and those logsums are used as static input values +when estimating parameters for a destination choice model). + +The integrated mode and destination choice model is represented as a hierarchical +nested logit model. The top of the nesting hierarchy represents the attraction +zone for each trip. For all home-based trips the attraction end is the non-home, +while for non-home-based trips it is modeled as the actual destination of the +trip in the normal sense. Below the attraction nest, the mode choice is further +sub-nested, with all private auto modes (SOV, HOV2, HOV3) grouped in one nest, +and all public auto modes (Taxi, TNC1, TNC2) grouped in a different nest. + +![](nesting-tree.png) + +For application, as this is a semi-aggregate model, there is no sampling of +alternatives. Thus, for each trip, the number of mode and destination alternatives +is 3632 zones times 9 modes = 32,688 alternatives. + +### Mode Choices + +The set of alternatives included explicitly in the mode choice level of the model +includes 9 discrete alternatives: + +1. SOV: Single occupant private vehicle (driving alone) +2. HOV2: 2-person trip in a private vehicle +3. HOV3: 3 or more persons sharing a private vehicle +4. Taxi +5. TNC1: Regular ride hail (e.g. Uber or Lyft) +6. TNC2: Shared ride hail (e.g. Uber Pool or Lyft Line) +7. Transit +8. Bike +9. Walk + + +### Transit Access and Egress + +To facilitate the implementation for these models, the calculation of transit +access and egress levels of service has been ported from Fortran to Python. +The actual mathematical logic underpinning these level of service calculations +is unchanged from the previous model, and is still based on a random distribution +of transit access characteristics computed based on the geography of each zone. + +### Work from Home Segmentation + +The unfolding pandemic has introduced a new wrinkle in travel demand forecasting: +unexpectedly large and deep uncertainty about the future of “work from home” +(WFH) behaviors. + +A fundamental challenge in modeling changing WFH behavior is that it impacts not +just the presence or absence of work trips, but also the number and temporal and +geographic distribution of non-work trips. A remote worker has much more limited +opportunity to undertake non-home-based trips in the middle of the day around the +workplace (e.g. going out for lunch in the loop) and much greater opportunity to +make home-based trips. + +The trip-based model has been built to include sensitivity to changes +in WFH, by bifurcating the regional population into two groups: households +that have at least one worker who works from home at least sometimes, and +households that have no WFH activity. Athough the parameters of the mode and +destination choice models are the same for both groups, the trip productions and +attractions by zone for these two groups differ, resulting in unique utility +functions and different behavior patterns for each. + +### Time of Day Models + +Although the mode and destination models are fully integrated, the time of day +models are estimated and applied separately as an independent step. These models, +which are applied only to automobile based modes (of both private and hired car +varieties), are sensitive to changes in congested travel times over the course +of the day. They are structured as a simple multinomial logit model, despite the +fact that the 8 modeled time periods are heterogeneously sized. This is not +problematic, as these models all include a complete set of alternative specific +constants, which represent not only behavioral preferences but also the aggregate +size (i.e. duration) of each time period. + +The utility functions for the time of day models are relatively simple compared +to the mode and destination models, as the differentiation available across the +alternatives is limited. Nevertheless, the models are structured to be sensitive +to congested travel times, as well as mode choice, as TNC usage exhibits a vastly +different temporal pattern than private auto usage, with many TNC rides clustered +in the evening and overnight hours. + + +## Input Files + +The descriptions here are focused on technical implementation, +i.e. what appears in these files, not where these values should come from. + +In most cases, there are several possible locations for each input file, which +are identified as "alternative file search locations"`under each heading. In +each case, the model checks each location in the order shown to find the file, +and the first location where a file exists is the location actually used. +Typically, files stored directly in the "Database" directory are preferred, but +fallback files from other locations can also used. This allows the MDT models to +run even if, for example, EMME has not been used to prepare a scenario specific +input file. + +In addition to the files below, the MDT models also read a wide variety of skim +data from various EMME matrix files found in the `emmemat` directory. + + +### HW_CBDPARK.TXT + +Alternative file search locations: +- HW_CBDPARK.TXT +- defaults_base_year/HW_CBDPARK.TXT + +This file contains CBD parking cost inputs. Two different sets of records are +included in the file. The first set identifies the parking supply characteristics +of each CBD zone that contains parking. Each zone in this set has five records +with the following information: + +- CBD parking zone number. +- The probability of finding parking within the zone at the threshold parking + cost (this value must be 100 percent in each zone’s fifth record). +- The threshold parking cost in cents per hour. +- The savings in parking costs in cents per hour determined by subtracting the + threshold parking cost from the maximum parking cost in the zone. +- The amount of time needed to walk one block in the CBD (180 seconds). + +Parking user characteristics are included in the second set of records in the +CBD parking file – these correspond to the final five records in the file. These +records are ordered by household income ranges and include the following variables +for CBD commuters: + +- The upper value of the household income quintile range (last record is the + lower bound of the highest quintile). +- The percentage of CBD auto commuters with free parking. +- The percentage of all CBD workers taking transit to CBD. +- The percentage of CBD auto commuters in single occupant vehicles. +- The percentage of CBD auto commuters ridesharing in two person vehicles +- The percentage of CBD auto commuters carpooling in three person vehicles. +- The percentage of CBD auto commuters carpooling in four or more person vehicles. + + +### ALLPURPOSE_M01.TXT + +Alternative file search locations: +- ALLPURPOSE_M01.TXT +- defaults_base_year/ALLPURPOSE_M01.TXT + +The M01 file stores several variables to provide the mode choice and distribution +models with zonal transit availability and park and ride characteristic parameters. +Some of the parameters are calculated using transit network characteristics and +are specific to each scenario network. The contents of the M01 file are summarized: + +1. Zone Number +2. Zone Type + - 1=Chicago downtown + - 2=Rest of Chicago + - 3=dense suburban CBD + - 4=all other zones +3. Park and Ride Cost + The cost of parking at the park and ride lot closest to the zone’s geographic + centroid. This represents the lowest rate of either the daily parking rate or the cost of a monthly parking pass divided by twenty work days. +4. Median zone household income + The median household income in the zone (in $100s) +5. Park and ride availability + A binary value indicating that the zone has park and ride access if + there is a park and ride location within ten miles of the zone’s + geographic centroid. +6. Average waiting time for bus service in zone for home-work trips +7. Average waiting time for bus service in zone for non-work trips +8. Average waiting time for feeder bus service in zone for home-work trips +9. Average waiting time for feeder bus service in zone for non-work trips +10. Home-work trip auto work end auto occupancy + +> Note: In prior version of the CMAP trip-based model, separate nearly identical copies +> of the M01 files were needed to support pre-distribution and mode choice +> components, e.g. PDHW_M01 and MCHW_M01. The current model does not require +> separate files, so the model reads only a common file with an ALLPURPOSE prefix. + + +### ALLPURPOSE_M023.TXT + +Alternative file search locations: +- ALLPURPOSE_M023.TXT +- defaults_base_year/ALLPURPOSE_M023.TXT + +The M023 file contains transit fare and auto operating cost data used by the +distribution and mode choice models. The file is composed of six records: + +1. CTA fares; +2. Pace feeder bus fares; +3. Pace regional bus fares; +4. Auto operating costs in 5 mile per hour increments for speeds + between 0-40 miles per hour; +5. Auto operating costs in 5 mile per hour increments for speeds + between 40-80 miles per hour; +6. Average auto operating costs per mile by zone type used to estimate + transit access/egress costs. + +The last record in the file contains the average per mile auto operating cost +for each of the four zone types (defined in the M01 file). The M023 data is +collapsed into six records. All values are reported in cents. + +> Note: In prior version of the CMAP trip-based model, separate identical copies +> of the M023 files were needed to support pre-distribution and mode choice +> components, e.g. PDHW_M023 and MCHW_M023. The current model does not require +> separate files, so the model reads only a common file with an ALLPURPOSE prefix. + + +### ??_DISTR.TXT + +Variants: +- HW_DISTR.TXT +- HO_DISTR.TXT +- NH_DISTR.TXT + +Alternative file search locations: +- ??_DISTR.TXT +- defaults_base_year/??_DISTR.TXT + +The DISTR files contain zonal transit approach distribution parameters. The +parameters are calculated using transit network characteristics and are thus +specific to each scenario network. The following describes the DISTR file fields. + +1. CMAP modeling zone number +2. Commuter Rail: Mean distance in miles to station +3. Commuter Rail: Standard deviation of distance to station +4. Commuter Rail: Type of Mode Choice distribution, with + - 101 = normal distribution. + - 102 = exponential distribution. +5. CTA Rail: Mean distance in miles to station +6. CTA Rail: Standard deviation of distance to station +7. CTA Rail: Type of Mode Choice distribution, with + - 101 = normal distribution. + - 102 = exponential distribution. +8. Regular Bus: Minimum bus stop distance +9. Regular Bus: Maximum bus stop distance +10. Regular Bus: Proportion of the zone within minimum walking distance +11. Feeder Bus: Minimum bus stop distance +12. Feeder Bus: Maximum bus stop distance +13. Feeder Bus: Proportion of the zone within minimum walking distance +14. Park and Ride: Mean distance in miles to lot +15. Park and Ride: Standard deviation of distance to lot +16. Park and Ride: Type of Mode Choice distribution, with + - 101 = normal distribution. + - 102 = exponential distribution. + +> Note: In prior version of the CMAP trip-based model, separate identical copies +> of the DISTR files were needed to support pre-distribution and mode choice +> components, e.g. PDHW_DISTR and MCHW_DISTR. The current model does not require +> separate files by component, so the model reads only a common file without the component- +> specific prefix. The purpose-specific prefix is still required, as the data in +> these files can vary by purpose. + + +### cmap_trip_config.yaml + +This yaml file contains a variety of model configurations, including: +- Taxi and TNC fare parameters +- Parking costs for zones other than those enumerated explicitly in `CBD_PARK` +- Intrazonal auto speeds by area type +- The regional income distribution across 5 income buckets +- Average occupancy of HOV3+ vehicles by trip purpose +- Activity durations by purpose (used to compute total parking costs) +- The number of replications used to simulate transit access and egress factors +- Factors by purpose to split trips into production-attraction and attraction-production +- Superdistrict codes for geographic validation summaries + + +### choice_model_params.yaml + +Alternative file search locations: +- choice_model_params.yaml +- cache/choice_model_params.yaml + +This file contains the choice model parameters used in the mode and destination +model. Mode and destination are modeled simultaneously in a single multi-level +nested logit structure. + + +### tod_model_params.yaml + +Alternative file search locations: +- tod_model_params.yaml +- cache/tod_model_params.yaml + +This file contains the choice model parameters used in the time-of-day model. +This model is only applied to auto trips, both private auto (sov, hov) and +hired-car (taxi, tnc) modes. + + +### CMAP_Zone_Districts.csv.gz + +Alternative file search locations: +- CMAP_Zone_Districts.csv.gz +- cache/CMAP_Zone_Districts.csv.gz + +This file is used to attach district and super-district codes to the resulting +trip tables, primarily for validation purposes. + + +### TG_HHENUM_OUTPUT.TXT.gz + +Alternative file search locations: +- TG_HHENUM_OUTPUT.TXT.gz +- cache/TG_HHENUM_OUTPUT.TXT.gz +- TG_HHENUM_OUTPUT.TXT +- cache/TG_HHENUM_OUTPUT.TXT +- defaults_base_year/TG_HHENUM_OUTPUT.TXT.gz + +This file, which is created as an output of the trip generation model, lists the +subzone and zone of each enumerated household, as well as the HHVTYPE. + + +### value_of_time_buckets.csv + +Alternative file search locations: +- value_of_time_buckets.csv +- cache/value_of_time_buckets.csv + +This file describes the share of single occupant vehicles to put into each of the +value of time buckets, based on trip purpose and household income group. If a +row does not sum to 1.0, the values will be scaled linearly so that the totals +are 1 and all trips are assigned to a bucket. + + +### CMAP_TripTable_VisitorsWeekday.csv.gz + +Alternative file search locations: +- cache/CMAP_TripTable_VisitorsWeekday.csv.gz +- CMAP_TripTable_VisitorsWeekday.csv.gz +- defaults_base_year/CMAP_TripTable_VisitorsWeekday.csv.gz + +This file contains a pre-computed trip table for weekday visitors (i.e. non-CMAP +region residents). It is used to replace the destination choice component for +visitor trips, although a mode choice model is still applied to distribute +visitor trips across modes. + + +### default_auto_propensity.csv.gz + +Alternative file search locations: +- cache/computed_auto_propensity.csv +- computed_auto_propensity.csv +- defaults_base_year/default_auto_propensity.csv +- defaults_base_year/default_auto_propensity.csv.gz + +This file contains the propensity of home-based trips to be attracted to a given +zone using a private auto mode (SOV or HOV). It is used to adjust the probability +that non-home-based trips produced in this zone will also use a private auto mode. + +To aid in computational efficiency, the model implementation uses computed auto +propensity lagged by one feedback iteration. That is, the computed auto propensity +from the prior global iteration is used at each iteration. When there is no prior +iteration (i.e. on the first iteration) then the default auto propensity is used. + + +## Output Files + +### cache/choice_simulator_trips_out/choice_simulator_trips_*.pq + +The primary output of the MDT models is a roster of trips. When the model is +run in multiprocessing/parallel mode, which is the default, individual trip +roster files are written out for each "job", so there will be numerous individual +trip roster files, which should be considered as different parts that can be +concatenated into one master trip roster table. The overall computational work is +split into numerous independent jobs, where just a few trip production/origin +zones are processed together in a batch. Moreover, the trips made by +work-from-home (WFH) households are modeled independently from trips made by +"typical" households that do not include a WFH person, so these trips are +seperated into two computational jobs even for the same zones. + +Each *.pq file is a [parquet format](https://parquet.apache.org/) file containing +a roster of trips, segmented on the following dimensions: + +- Trip Purpose + - HBWH: Home-based work trips by high-income households + - HBWL: Home-based work trips by low-income households + - HBS: Home-based shopping trips + - HBO: Home-based other purpose trips + - NHB: Non-home based trips + - VISIT: Trips made by visitors to the region + - DEAD: Deadhead trips made taxis and rideshare vehicles between revenue trips +- Mode + - 1: SOV + - 2: HOV2 + - 3: HOV3+ + - 4: TAXI + - 5: TNC Private / Regular + - 6: TNC Shared / Pooled + - 7: TRANSIT + - 8: WALK + - 9: BIKE +- Origin Zone + - TAZ number for the trip origin. Note this is always the beginning of the + actual trip, and not necessarily the home/production zone, e.g. for trips + returning home from a workplace, the origin zone is the workplace. +- Destination Zone + - TAZ number for the trip destination. Note this is always the end of the + actual trip, and not necessarily the attraction zone, e.g. for trips + returning home from a workplace, the destination zone is home. +- Attraction Zone + - TAZ number for the trip attraction zone. This can be either the production + or attraction zone, depending on directionality of the trip. For trips modeled + as O-D instead of P-A, the attraction zone is always the destination. +- Number of Autos Owned by Household + - The number of automobiles (0, 1, or 2) owned by the household of the person + making the trip. This is only applicable for home-based trips, as consistent + tours are not maintained and the model cannot use auto ownership for + anything other than home-based trips. +- Household Income Category + - The household income category (1 through 5 inclusive) of the person + making the trip. This is computed based on the income profile of zone households + for home-based trips, and based on the regional average income profile for + non-home-based trips, as consistent tours are not maintained. +- Time Period + - One of 9 time periods {EA, AM1, AM2, AM3, MD, PM1, PM2, PM3} is assigned for + all public and hired auto trips. No time period is actually assigned for + transit or non-motorized trips, trips by these modes are marked with 'NA'. + +Each new run of the MDT model generates a new `choice_simulator_trips_out` +directory in the `Database\cache` folder. Previous output directories are +rotated with a dot-number extensions, so that the un-numbered output directory is +the most recent output. + +### emmemat/mf*.emx + +Unless the "--no-aggregate" option is set, the trip roster is also aggregated +into Emme matrix files of vehicle trips for automobile modes, and person trips +for transit. In contrast to the trip roster files, which are written to a +rotated directory that prevents data loss, new EMX files will overwrite any +existing data stored with the same filename. + +For all automobile modes, trips are aggregated from person trips to vehicle +trips. SOV trips are split into three value of time categories according to the +ratios given in the `value_of_time_buckets.csv` input file. HOV2 and HOV3+ modes +are each in a single bucket, but are converted from person trips to vehicle trips +based on auto occupancy, which is 2 for HOV2 and slightly over 3 for HOV3+, the +exact value varies by purpose and is given by the `hov3_occupancy` key in the +`cmap_trip_config.yaml` input file. + +The time of day dimension for auto trips is preserved, along with origin and +destination, yielding 8 full matrix tables per bucket, organized as follows: + +- SOV low value of time – mf411-mf418 +- SOV med value of time – mf421-mf428 +- SOV high value of time – mf431-mf438 +- HOV2 not diff'd by vot – mf441-mf448 +- HOV3 not diff'd by vot – mf451-mf458 + +In each group, the time of day ordering is the same, with the last digit of the +file name representing the time period: + +- 1: EA +- 2: AM1 +- 3: AM2 +- 4: AM3 +- 5: MD +- 6: PM1 +- 7: PM2 +- 8: PM3 + +Unlike auto trips, transit person trips are not aggregated to vehicles nor +segmented by time period. Instead, transit person trips are segmented only by +trip purpose, yielding just 5 full matrix tables: + +- home-based work low income - mf40 +- home-based work high income - mf41 +- home-based shopping - mf39 +- home-based other - mf42 +- non-home-based - mf43 + + +### cache/choice_simulator_trips_out/validation_data.xlsx + +This excel file contains some extra validation output of the MDT models. +The file contains the following worksheets of partially aggregated data, +consistent with the format of the validation template: + +- Autos: Regional trips aggregated by purpose, mode, and auto ownership. +- Incomes: Regional trips aggregated by purpose, mode, and household income category. +- TimePeriod: Regional trips aggregated by purpose, mode, and time period. +- FlowsByPurp&Mode: Selected superdistrict-to-superdistrict trip flows by mode and purpose. +- FlowsByPurp&Mode%: Selected superdistrict-to-superdistrict mode shares by purpose. + diff --git a/src/Mode-Dest-TOD/cmap_modedest/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/__init__.py new file mode 100644 index 0000000..ba3e4a8 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/__init__.py @@ -0,0 +1,6 @@ +# CMAP Trip-based model tools + +__version__ = '21.01.1' + +from .cmap_logging import * +from .numexpr_patch import CacheDictSafe diff --git a/src/Mode-Dest-TOD/cmap_modedest/__main__.py b/src/Mode-Dest-TOD/cmap_modedest/__main__.py new file mode 100644 index 0000000..e1c0832 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/__main__.py @@ -0,0 +1,274 @@ +import sys +import os +import shutil +import time +import datetime + +import numpy as np +import pandas as pd +import argparse +import cmap_modedest + +def main(*args): + + parser = argparse.ArgumentParser( + prog='cmap_modedest', + description='Mode, destination, and time-of-day for CMAP trip-based model.', + ) + parser.add_argument( + 'database_dir', + type=str, + help='The path of the current database directory, which is used as the ' + 'base location for loading all input files.', + ) + parser.add_argument( + '-l', '--loglevel', + type=int, + help='The logging level, or how verbose the log output should be. Set to ' + '10 or less for debug-level output.', + default=20, + ) + parser.add_argument( + '--max_zone_chunk', + type=int, + help='Maximum number of zones to process in one chunk. Each job can ' + 'process a few zones at once, but trying to run too many can ' + 'trigger out-of-memory problems.', + default=4, + ) + parser.add_argument( + '--njobs', + type=int, + help=""" + Number of jobs to process in parallel. Larger computers with more CPUs + can handle more jobs at the same time.""", + default=10, + ) + parser.add_argument( + '--stagger', + type=int, + help=""" + Number of seconds to pause between initial parallel starts. + This can stagger storage-heavy and cpu-heavy sections of code to + better distribute workload.""", + default=5, + ) + parser.add_argument( + '--short', + type=float, + help=""" + Whether to shorten runtime by processing only a subset of origin zones. + Give a fraction less than one to run that fraction of zones spread over + the entire region, or an integer 1 or more to run in a single process + that number of zones starting from the first zone. This feature is + primarily for testing and quick validation. + """, + ) + parser.add_argument( + '--no-aggregate', + action="store_true", + help=""" + Disable vehicle trip table aggregation. If not set, the vehicle trip + tables in Database/emmemat will be overwritten. + """, + ) + parser.add_argument( + '--subdir', + type=str, + help="""cache subdirectory into which results are saved""", + default="choice_simulator_trips_out", + ) + parser.add_argument( + '--check', + help='Check input arguments to this command (including default arguments) ' + 'and the exit without processing anything.', + action="store_true", + ) + parser.add_argument( + '--rebuild', + help='Rebuild all numba caches. Try setting this argument in the model is ' + 'crashing unexpectedly. Rebuilding caches takes a little time but is ' + 'potentially necessary when switching the code to a new computer.', + action="store_true", + ) + parser.add_argument( + '--profile', + help='Run in profiler mode. This will slow down the model run somewhat, ' + 'but provide a profiling report for code optization. This features ' + 'requires that the pyinstrument library is installed.', + action="store_true", + ) + parser.add_argument( + '--tbb', + help='Use the TBB backend for numba. Experimental', + action="store_true", + ) + parser.add_argument( + '--zarr-to-emmemat', + help='Convert all matrix files that are only found in the emmemat.zarr ' + 'format into standard emmemat .EMX files, and then quit. Note that ' + 'EMME may not recognize these files as included in the model data ' + 'unless they were previously initialized.', + action="store_true", + ) + + args = parser.parse_args() + return run(args) + + +def run(args): + if args.tbb or os.environ.get("NUMBA_THREADING_LAYER", None) in ("safe", "tbb"): + from numba import config, njit, threading_layer + # set the threading layer before any parallel target compilation + config.THREADING_LAYER = 'tbb' + + @njit(parallel=True) + def foo(a, b): + return a + b + + x = np.arange(10.) + y = x.copy() + + # this will force the compilation of the function, select a threading layer + # and then execute in parallel + foo(x, y) + + # demonstrate the threading layer chosen + print("Threading layer chosen: %s" % threading_layer()) + os.environ["NUMBA_THREADING_LAYER"] = "tbb" + + + log_dir = os.path.join(args.database_dir, "cache", "logs") + os.makedirs(log_dir, exist_ok=True) + log = cmap_modedest.log_to_stderr( + level=args.loglevel, + log_dir=log_dir, + ) + + if args.profile: + from pyinstrument import Profiler + profiler = Profiler() + profiler.start() + + from cmap_modedest.runtime import working_dir, log_info + log.info(time.strftime("RUN STARTED %A, %d %B %Y, %I:%M:%S %p")) + start_time = time.time() + try: + log_info("###################################################################") + log_info("## CMAP TRIP-BASED MODEL: MODE, DESTINATION, AND TIME OF DAY ##") + log_info("###################################################################") + if not os.path.isdir(args.database_dir): + raise NotADirectoryError(args.database_dir) + log_info(f"# database_dir = {args.database_dir}") + log_info(f"# (full path) = {os.path.abspath(args.database_dir)}") + log_info(f"# --max_zone_chunk = {args.max_zone_chunk}") + log_info(f"# --njobs = {args.njobs}") + if args.short is not None and args.short >= 1.0 and args.njobs > 1: + log_info(f"# -> n_jobs is set to 1 when running in sequential short mode") + log_info(f"# --stagger = {args.stagger}") + log_info(f"# --short = {args.short}") + log_info(f"# --subdir = {args.subdir}") + log_info(f"# --check = {args.check}") + log_info(f"# --rebuild = {args.rebuild}") + log_info(f"# --tbb = {args.tbb}") + log_info(f"# --zarr-to-emmemat = {args.zarr_to_emmemat}") + log_info("###################################################################") + + if args.check: return # early exit if only checking arguments + + if args.rebuild: + import pathlib + here = os.path.dirname(__file__) + for p in pathlib.Path(here).rglob('*.py[co]'): + p.unlink() + for p in pathlib.Path(here).rglob('*.nb[ci]'): + p.unlink() + + + from cmap_modedest.application import choice_simulator_trips_many, choice_simulator_trips, assemble_trips + + if args.zarr_to_emmemat: + working_dir(args.database_dir, backfill_uncompressed_skims=True) + return + + dh = working_dir(args.database_dir) + + ## Rename subdir folder if it already exists. + cache_subdir = dh.filenames.cache_dir / args.subdir + if os.path.exists(cache_subdir): + n = 1 + while os.path.exists(cache_subdir.with_suffix(f".{n:03d}")): + n += 1 + shutil.move(cache_subdir, cache_subdir.with_suffix(f".{n:03d}")) + + + if args.short is None: + otaz = None + n_jobs = args.njobs + elif args.short < 1.0: + otaz = np.linspace(1, 3632, int(np.round(3632 * args.short)), dtype=int) + n_jobs = args.njobs + else: # args.short >= 1.0: + otaz = np.arange(0, int(args.short)) + 1 + n_jobs = 1 + + choice_simulator_trips_many( + dh, + otaz=otaz, + max_chunk_size=args.max_zone_chunk, + n_jobs=n_jobs, + cache_subdir=args.subdir, + with_wfh=True, + staggertime=args.stagger, + ) + + sim_trips_many = assemble_trips( + dh, + from_dir=dh.filenames.cache_dir / args.subdir, + pattern="choice_simulator_trips_*.pq", + compute_auto_propensity=False, + ) + + if True: + from cmap_modedest.validation import validation_aggregation + validation_aggregation(dh, sim_trips_many, to_dir=dh.filenames.cache_dir / args.subdir) + + if sim_trips_many is not None and not args.no_aggregate: + log.info("Aggregating trips to vehicle trip tables by value of time and time of day") + from cmap_modedest.application import aggregate_to_vehicle_matrixes + aggregate_to_vehicle_matrixes(dh, sim_trips_many) + + if sim_trips_many is not None: + s = str( + sim_trips_many + .groupby(["mode", "purpose"])['trips'] + .sum() + .compute() + .unstack(0) + .fillna(0) + ) + log_info(f"Trip Summary by Mode and Purpose ------\n{s}") + + s = str( + sim_trips_many + .groupby(["hh_inc5", "purpose"])['trips'] + .sum() + .compute() + .unstack(0) + .fillna(0) + ) + log_info(f"Trip Summary by Income and Purpose ------\n{s}") + + log_info("#### COMPLETED: MODE, DESTINATION, AND TIME OF DAY ####") + finally: + log.info(time.strftime("RUN ENDED %A, %d %B %Y, %I:%M:%S %p")) + end_time = time.time() + log.info(f"ELAPSED TIME {datetime.timedelta(seconds=end_time-start_time)}") + + if args.profile: + profiler.stop() + print(profiler.output_text(unicode=True, color=True)) + + +if __name__ == "__main__": + sys.exit(main()) \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/addict.py b/src/Mode-Dest-TOD/cmap_modedest/addict.py new file mode 100644 index 0000000..734665a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/addict.py @@ -0,0 +1,203 @@ +# - from https://github.com/mewwts/addict +# - edited to allow pickling +# +# The MIT License (MIT) +# +# Copyright (c) 2014 Mats Julian Olsen +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +import copy + + +class Dict(dict): + + def __init__(__self, *args, **kwargs): + object.__setattr__(__self, '__parent', kwargs.pop('__parent', None)) + object.__setattr__(__self, '__key', kwargs.pop('__key', None)) + object.__setattr__(__self, '__frozen', False) + for arg in args: + if not arg: + continue + elif isinstance(arg, dict): + for key, val in arg.items(): + __self[key] = __self._hook(val) + elif isinstance(arg, tuple) and (not isinstance(arg[0], tuple)): + __self[arg[0]] = __self._hook(arg[1]) + else: + for key, val in iter(arg): + __self[key] = __self._hook(val) + + for key, val in kwargs.items(): + __self[key] = __self._hook(val) + + def __setattr__(self, name, value): + if hasattr(self.__class__, name): + raise AttributeError("'Dict' object attribute " + "'{0}' is read-only".format(name)) + else: + self[name] = value + + def __setitem__(self, name, value): + isFrozen = (hasattr(self, '__frozen') and + object.__getattribute__(self, '__frozen')) + if isFrozen and name not in super(Dict, self).keys(): + raise KeyError(name) + super(Dict, self).__setitem__(name, value) + try: + p = object.__getattribute__(self, '__parent') + key = object.__getattribute__(self, '__key') + except AttributeError: + p = None + key = None + if p is not None: + p[key] = self + object.__delattr__(self, '__parent') + object.__delattr__(self, '__key') + + def __add__(self, other): + if not self.keys(): + return other + else: + self_type = type(self).__name__ + other_type = type(other).__name__ + msg = "unsupported operand type(s) for +: '{}' and '{}'" + raise TypeError(msg.format(self_type, other_type)) + + @classmethod + def _hook(cls, item): + if isinstance(item, dict): + return cls(item) + elif isinstance(item, (list, tuple)): + try: + return type(item)(cls._hook(elem) for elem in item) + except TypeError: + # some subclasses don't implement a constructor that + # accepts a generator, e.g. namedtuple + return type(item)(*(cls._hook(elem) for elem in item)) + return item + + def __getattr__(self, item): + return self.__getitem__(item) + + def __missing__(self, name): + if object.__getattribute__(self, '__frozen'): + raise KeyError(name) + return self.__class__(__parent=self, __key=name) + + def __delattr__(self, name): + del self[name] + + def to_dict(self): + base = {} + for key, value in self.items(): + if isinstance(value, type(self)): + base[key] = value.to_dict() + elif isinstance(value, (list, tuple)): + try: + base[key] = type(value)( + item.to_dict() if isinstance(item, type(self)) else + item for item in value) + except TypeError: + # some subclasses don't implement a constructor that + # accepts a generator, e.g. namedtuple + base[key] = type(value)(*( + item.to_dict() if isinstance(item, type(self)) else + item for item in value)) + else: + base[key] = value + return base + + def copy(self): + return copy.copy(self) + + def deepcopy(self): + return copy.deepcopy(self) + + def __deepcopy__(self, memo): + other = self.__class__() + memo[id(self)] = other + for key, value in self.items(): + other[copy.deepcopy(key, memo)] = copy.deepcopy(value, memo) + return other + + def update(self, *args, **kwargs): + other = {} + if args: + if len(args) > 1: + raise TypeError() + other.update(args[0]) + other.update(kwargs) + for k, v in other.items(): + if ((k not in self) or + (not isinstance(self[k], dict)) or + (not isinstance(v, dict))): + self[k] = v + else: + self[k].update(v) + + def __getnewargs__(self): + return tuple(self.items()) + + def __getstate__(self): + state = self.to_dict() + isFrozen = (hasattr(self, '__frozen') and + object.__getattribute__(self, '__frozen')) + state['__addict__frozen__'] = isFrozen + return state + + def __setstate__(self, state): + shouldFreeze = state.pop('__addict__frozen__', False) + self.update(state) + self.freeze(shouldFreeze) + + def __or__(self, other): + if not isinstance(other, (Dict, dict)): + return NotImplemented + new = Dict(self) + new.update(other) + return new + + def __ror__(self, other): + if not isinstance(other, (Dict, dict)): + return NotImplemented + new = Dict(other) + new.update(self) + return new + + def __ior__(self, other): + self.update(other) + return self + + def setdefault(self, key, default=None): + if key in self: + return self[key] + else: + self[key] = default + return default + + def freeze(self, shouldFreeze=True): + object.__setattr__(self, '__frozen', shouldFreeze) + for key, val in self.items(): + if isinstance(val, Dict): + val.freeze(shouldFreeze) + + def unfreeze(self): + self.freeze(False) diff --git a/src/Mode-Dest-TOD/cmap_modedest/ae_distance_sim.py b/src/Mode-Dest-TOD/cmap_modedest/ae_distance_sim.py new file mode 100644 index 0000000..b24f9fd --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/ae_distance_sim.py @@ -0,0 +1,80 @@ +import numpy as np +import pandas as pd +from scipy import stats +import logging +log = logging.getLogger('CMAP') + +def sloped_linear(x_min, x_max, ratio=1.0, random_state=None, replication=1): + if isinstance(replication, int): + replication = [replication] + x_max = np.asarray(x_max) + x_min = np.asarray(x_min) + reps = list(x_min.shape)+replication + if isinstance(ratio, float) and ratio == 1.0: + return stats.uniform(x_min, x_max).rvs(reps, random_state=random_state) + else: + span = x_max - x_min + slope = (1.0-ratio)/np.where(span!=0, span, 1.0) + area =.5*(1+ratio)*span + if len(replication) == 1: + y = stats.uniform().rvs(reps, random_state=random_state)*area[:,None] + zp = np.sqrt(ratio[:,None] ** 2 + 2 * slope[:,None] * y) + return (zp - ratio[:,None]) / np.where(slope != 0, slope, 1.0)[:,None] + x_min[:,None] + elif len(replication) == 2: + y = stats.uniform().rvs(reps, random_state=random_state)*area[:,None,None] + zp = np.sqrt(ratio[:,None,None] ** 2 + 2 * slope[:,None,None] * y) + return (zp - ratio[:,None,None]) / np.where(slope != 0, slope, 1.0)[:,None,None] + x_min[:,None,None] + else: + raise ValueError('too many dims') + + +def trunc_normal(*arg, random_state=None, replication=1): + if isinstance(replication, int): + replication = [replication] + rv = stats.norm(*(np.asarray(j) for j in arg)) + reps = replication+list(rv.args[0].shape) + return np.fmax(rv.rvs(reps, random_state=random_state), 0.06) + + +def simulate_ae_dist(p1,p2,p3, random_state=None, replication=1): + p1 = np.asarray(p1).reshape(-1) + p2 = np.asarray(p2).reshape(-1) + p3 = np.asarray(p3).reshape(-1) + if isinstance(replication, int): + replication = [replication] + reps = list(p1.shape)+replication + result = np.full(reps, np.nan, dtype=np.float32) + + use_normal = (p3 == 101) + if use_normal.any(): + result[use_normal,...] = trunc_normal( + p1[use_normal], + p2[use_normal], + random_state=random_state, + replication=replication, + ).T + + use_slopey = (p3 < 101) + n = use_slopey.sum() + if n: + result[use_slopey,...] = sloped_linear( + p1[use_slopey], + p2[use_slopey], + p3[use_slopey], + random_state=random_state, + replication=replication, + ) + + use_nan = (p3 == 999) + result[use_nan,...] = 255.0 + return result + + +ae_mode_speeds = { # minutes per mile + 1: 20, # walk + 2: 20, # bus + 3: 2, # pnr + 4: 2, # knr + 5: 20, # feeder + 999: 1, # not available +} \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/application.py b/src/Mode-Dest-TOD/cmap_modedest/application.py new file mode 100644 index 0000000..1de062a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/application.py @@ -0,0 +1,1495 @@ +import pickle + +import numpy as np +import pandas as pd +import xarray as xr +import os +import time +import larch +from larch.util import piece +from larch.util.dataframe import columnize +import re +from .addict import Dict +import pyarrow as pa +import pyarrow.feather as pf +import pyarrow.compute as pc +import sharrow as sh +from scipy.stats import binom +from pathlib import Path + +from .tnc_costs import taxi_cost, tnc_solo_cost, tnc_pool_cost +from .transit_approach import transit_approach +from .modecodes import mode9codes +from .choice_model import model_builder, alt_codes_and_names +from .random_states import check_random_generator +from .data_handlers import DataHandler +from .data_handlers.tabler import Table +from .data_handlers.m01_handler import attach_areatypes, sample_hh_income_cats +from .hh_sampling import sample_hh_from_zone +from .fast.random_generator import multichoices +from .deadheading import compute_deadhead_trip_table +from .purposes import purposesA, purposes_to_5, purposes_to_3 +from .time_of_day_model import time_of_day_simulator_initialize + +from .cmap_logging import getSubLogger, get_worker_log, LOGGER_NAME + +app_floatdtype = np.float32 + + +n_modes = len(mode9codes) + +av = {} + + +def _data_for_application_1(dh, otaz=1, replication=None): + """ + + Parameters + ---------- + dh : DataHandler + otaz : int + peak : bool + replication : int, optional + + Returns + ------- + pd.DataFrame + """ + global av + log = getSubLogger("application.DATA1") + log.info(f"prepare tier 1 data for otaz {otaz}") + + try: + fast_application_data = dh.fast_application_data + except AttributeError: + from .fast.application_data import application_data + fast_application_data = dh.fast_application_data = application_data(dh) + + from .purposes import purposes5 + purposes = purposes5 + + log.debug("prepare availability") + n_zones = dh.n_internal_zones + for purpose in purposes: + av_purpose = av.get(purpose, {}) + if len(av_purpose) != n_zones * n_modes: + av_purpose = {} + num = n_modes + for i in range(n_zones): + av_purpose[num + mode9codes.AUTO] = f"altdest{i + 1:04d}_auto_avail_{purpose}" + av_purpose[num + mode9codes.HOV2] = f"altdest{i + 1:04d}_auto_avail_{purpose}" + av_purpose[num + mode9codes.HOV3] = f"altdest{i + 1:04d}_auto_avail_{purpose}" + av_purpose[num + mode9codes.TNC1] = f"altdest{i + 1:04d}_auto_avail_{purpose}" + av_purpose[num + mode9codes.TNC2] = f"altdest{i + 1:04d}_auto_avail_{purpose}" + av_purpose[num + mode9codes.TAXI] = f"altdest{i + 1:04d}_auto_avail_{purpose}" + av_purpose[num + mode9codes.TRANSIT] = f"altdest{i + 1:04d}_transit_avail_{purpose}" + av_purpose[num + mode9codes.WALK] = f"altdest{i + 1:04d}_walk_avail_{purpose}" + av_purpose[num + mode9codes.BIKE] = f"altdest{i + 1:04d}_bike_avail_{purpose}" + num += n_modes + av[purpose] = av_purpose + + if replication is None: + replication = dh.cfg.get('n_replications', 50) + + log.debug("initialize dtaz and tbl") + dtaz = pd.Index(np.arange(n_zones) + 1) + otaz_series = pd.Series(otaz, index=dtaz) + + tbl = pa.table({ + 'otaz_idx': np.full_like(dtaz, otaz) - 1, + 'dtaz_idx': dtaz - 1, + 'otaz': np.full_like(dtaz, otaz), + 'dtaz': dtaz, + }) + + log.debug("load t1") + t1 = fast_application_data.load(tbl, as_table=True) + + log.debug("concat_tables t2") + t2 = sh.concat_tables([t1] * replication) + + log.debug("prepare transit approach function") + from .fast.transit.approach import compile_transit_approach, transit_approach_wrap, transit_approach_distances + if not dh.cfg.transit_approach_func: + trapp_struct = compile_transit_approach(dh) + dh.cfg.transit_approach_struct = trapp_struct + + oz = np.full(3632, otaz) + dz = np.arange(3632) + 1 + + random_generator = np.random.default_rng([otaz, 1234]) + + log.debug("run trapp_dist_HW") + trapp_dist_HW = transit_approach_distances(dh.cfg.transit_approach_struct, oz, dz, 'HW', random_seed=random_generator)[0] + log.debug("run trapp_HW") + trapp_HW = transit_approach_wrap(dh.cfg.transit_approach_struct, oz, dz, 'HW', trapp_dist_HW, ) + + log.debug("run trapp_dist_HO") + trapp_dist_HO = transit_approach_distances(dh.cfg.transit_approach_struct, oz, dz, 'HO', random_seed=random_generator)[0] + log.debug("run trapp_HO") + trapp_HO = transit_approach_wrap(dh.cfg.transit_approach_struct, oz, dz, 'HO', trapp_dist_HO, ) + + log.debug("run add peak transit approach columns on t2") + t2['transit_approach_drivetime_PEAK'] = trapp_HW['drivetime'].T.reshape(-1) + t2['transit_approach_waittime_PEAK'] = trapp_HW['waittime'].T.reshape(-1) + t2['transit_approach_walktime_PEAK'] = trapp_HW['walktime'].T.reshape(-1) + t2['transit_approach_cost_PEAK'] = trapp_HW['cost'].T.reshape(-1) + ##-- Heither, flag KnR-PnR approaches for HBW trips -- ## + t2['M_drive_PEAK'] = np.where((trapp_HW['drivetime']>0) & (trapp_HW['drivetime']=hhadults'] = (hh_data['N_VEHICLES'] >= hh_data['N_ADULTS']).astype(app_floatdtype) + + df2 = t2.to_pandas() + + # This can be fairly fast because we're not adding new columns, just overwriting dummy columns. + # parking cost + from .parking_costs import parking_cost_v3, parking_is_free + dtazs = sh.concat_tables([tbl.select(['dtaz'])] * replication).to_pandas().values + hhincs = hh_data['hhinc5'].repeat(len(tbl)).values + + # Whether a trip gets free parking is a function of income but not destination or purpose + paid_parking = parking_is_free( + dh, + hhincs, + random_state=random_generator, + ) + + for purp in purposesA: + temp_parking_cost = parking_cost_v3( + dh, + dtazs, + dh.cfg.default_activity_durations[purposes_to_3[purp]], + purposes_to_3[purp], + random_state=random_generator, + ).values + temp_parking_cost *= paid_parking.astype(temp_parking_cost.dtype).values + df2[f'auto_parking_cost_{purp}'] = temp_parking_cost + + df2_array = df2.to_numpy(dtype=app_floatdtype).reshape(replication, -1) + + col_names = getattr(dh, 'column_2_replacement', []) + try: + df3 = pd.DataFrame( + df2_array, + columns=col_names, + ) + except ValueError: + df3 = pd.DataFrame( + df2.to_numpy(dtype=app_floatdtype).reshape(replication, -1), + columns=pd.MultiIndex.from_product([ + [f"altdest{x:04d}" for x in range(1, n_zones + 1)], + df2.columns, + ]) + ) + need_to_fix_column_names = True + else: + need_to_fix_column_names = False + hh_data.index = df3.index + + addon = hh_data[[ + 'o_zone', 'ozone_autopropensity', 'hhveh==0', 'hhveh>=hhadults', + 'hhinc5', 'hhinc5g', + 'hhinc5==1', 'hhinc5==2', 'hhinc5==3', 'hhinc5==4', 'hhinc5==5', + 'hhinc5l', 'hhinc5l==1', 'hhinc5l==2', + 'hhinc5h', 'hhinc5h==3', 'hhinc5h==4', 'hhinc5h==5', + ]] + df3 = pd.concat([df3, addon], axis=1) + if need_to_fix_column_names: + _fix_column_names(dh, df3) + return df3 + + +def _fix_column_names(dh, dfx): + column_2_replacement = getattr(dh, 'column_2_replacement', []) + if len(dfx.columns) != len(column_2_replacement): + columns = [(f"{j[0]}_{j[1]}" if isinstance(j, tuple) else j) for j in dfx.columns] + if columns[-1] == '_o_zone': + columns[-1] = 'o_zone' + s0f = lambda c: c.replace("_dtaz", "") + + s1 = re.compile("(altdest[0-9]+)_o_zone == dtaz") + s1f = lambda c: s1.sub("o_zone == \g<1>", c) + + s2 = re.compile("(altdest[0-9]+_)piece\((.*)\)") + s2f = lambda c: s2.sub(r"piece(\g<1>\g<2>)", c) + + s3 = re.compile(r"(altdest[0-9]+_)log\(attractions\)") + s3f = lambda c: s3.sub(r"log(\g<1>attractions)", c) + + s4 = re.compile(r"(altdest[0-9]+_)log\(1/samp_wgt\)") + s4f = lambda c: s4.sub(r"log(1/\g<1>samp_wgt)", c) + + s5 = re.compile("(altdest[0-9]+_)1-(.*)") + s5f = lambda c: s5.sub(r"1-\g<1>\g<2>", c) + + s6 = re.compile(r"(altdest[0-9]+_)(.*)(time|ovtt)(.*)/auto_dist_(.*)") + s6f = lambda c: s6.sub(r"\g<1>\g<2>\g<3>\g<4>/\g<1>auto_dist_\g<5>", c) + + s7 = re.compile("(altdest[0-9]+_)(fm..)\(ozone_areatype, areatype\)==(.*)") + s7f = lambda c: s7.sub(r"\g<2>(ozone_areatype, \g<1>areatype)==\g<3>", c) + + s8 = re.compile("(altdest[0-9]+_)hard_sigmoid\((.*)\)") + s8f = lambda c: s8.sub(r"hard_sigmoid(\g<1>\g<2>)", c) + + column_2_replacement = [s8f(s7f(s6f(s5f(s4f(s3f(s2f(s1f(s0f(j))))))))) for j in columns] + dh.column_2_replacement = column_2_replacement + + dfx.columns = column_2_replacement + + +to_disk = False + + +def _data_for_application_2(dh, df2, filename): + # _fix_column_names(dh, df2) + log = getSubLogger("DATA2") + + n_zones = dh.n_internal_zones + alt_codes, alt_names = alt_codes_and_names( + n_sampled_dests=n_zones, + include_actual_dest=False, + ) + + log.debug("initialize dataframes") + dfas = larch.DataFrames( + co=df2.astype(app_floatdtype), + alt_codes=alt_codes, + av=True, + ) + + if to_disk: + log.debug("writing dataframes to disk") + dfas.to_feathers(filename) + return _reload_data_for_application_2(dh, filename) + + log.debug("completed _data_for_application_2") + return dfas + + +def _reload_data_for_application_2(dh, filename): + return larch.DataFrames.from_feathers(filename) + + +def data_for_application(dh, otaz=1, replication=None): + """ + + Parameters + ---------- + otaz : int or array-like + peak : bool + purpose : str + replication : int, optional + + Returns + ------- + + """ + log = getSubLogger("DATA") + if replication is None: + replication = dh.cfg.get('n_replications', 50) + + if isinstance(otaz, int): + df2 = _data_for_application_1(dh, otaz=otaz, replication=replication) + filename = dh.filenames.cache_dir / f"data_for_application_{otaz}" + else: + log.debug("data_for_application::_data_for_application_1") + df2_list = [ + _data_for_application_1(dh, otaz=z, replication=replication) + for z in otaz + ] + log.debug("data_for_application::concat") + df2 = pd.concat(df2_list) + log.debug("data_for_application::filename") + filename = dh.filenames.cache_dir / f"data_for_application_{otaz[0]}_{otaz[-1]}" + return _data_for_application_2(dh, df2.reset_index(drop=True), filename) + + +def blockwise_mean(a, blocksize): + """ + + Parameters + ---------- + a : array-like + blocksize : int + + Returns + ------- + array + """ + n_blocks = a.shape[0] // blocksize + (1 if a.shape[0] % blocksize else 0) + mean = np.zeros([n_blocks, *a.shape[1:]]) + for j in range(n_blocks): + mean[j] = a[j * blocksize:(j + 1) * blocksize].mean(0) + return mean + + +choice_simulator_global = Dict() + + +def choice_simulator_initialize(dh, n_threads=1, cache=True): + """ + Load or create the choice models. + + This function checks if the mode+destination choice models have already been + loaded into memory for this process. If they have not, it then checks if + a pickled version of the choice models has been saved to disk, and loads that + if it is available. Otherwise, it initializes the choice models from scratch + using the `model_builder` function. + + Not coincidentally, these three ways of making the choice model available in + the current process are ordered from fastest to slowest. + + Parameters + ---------- + dh : DataHandler + n_threads : int + How many threads each model should use in computation. + cache : bool + Whether to write pickles to disk. + + Returns + ------- + Dict + """ + global choice_simulator_global + log = getSubLogger("SIM_INIT") + + get_worker_log( + os.path.join(dh.filenames.cache_dir, 'logs'), + level=10, + ) + + log.debug(f"choice_simulator_initialize(n_threads={n_threads}), cache={cache}") + n_zones = dh.n_internal_zones + choice_model_params = dh.choice_model_params + + if len(choice_model_params) == 0: + raise ValueError("no choice_model_params") + + pickle_name = dh.filenames.cache_dir / f"choice_models_{n_zones}.pkl" + + if n_zones not in choice_simulator_global: + log.debug("choice_simulator_initialize: preloaded choice_simulator not available") + if os.path.exists(pickle_name): + import cloudpickle + with open(pickle_name, 'rb') as pkl_f: + log.debug("loading pickled choice_simulator") + choice_simulator_global[n_zones] = cloudpickle.load(pkl_f) + if n_zones in choice_simulator_global: + cache = False + else: + log.debug("pickled choice_simulator not available") + + if n_zones in choice_simulator_global: + log.info("using existing choice_simulator") + choice_simulator = choice_simulator_global[n_zones] + for purpose in purposesA: + choice_simulator[purpose].set_values(choice_model_params[purpose]) + else: + log.info("creating fresh choice_simulator") + choice_simulator = Dict() + for purpose in purposesA: + choice_simulator[purpose] = model_builder( + purpose=purpose, + include_actual_dest=False, + n_sampled_dests=n_zones, # 3632, + parameter_values=choice_model_params[purpose], + constraints=False, + n_threads=n_threads, + explicit_av=False, + ) + choice_simulator_global[n_zones] = choice_simulator + + if cache and not os.path.exists(pickle_name): + import cloudpickle + with open(pickle_name, 'wb') as pkl_f: + log.debug("pickling choice_simulator for future reload") + cloudpickle.dump( + choice_simulator_global[n_zones], + pkl_f, + ) + + return choice_simulator + + +def attach_dataframes(sim, purpose, dfa): + log = getSubLogger("ATTACH_DFS") + if sim.dataframes is None: + log.debug(f"attach_dataframes {purpose} attach dataframes new") + sim.dataframes = dfa + else: + log.debug(f"attach_dataframes {purpose} attach dataframes direct injection") + sim.set_dataframes(dfa, False) + # TODO: explore using inject_feathers instead + + +def _sim_prob(purpose, sim): + sim_pr = sim.probability() + return sim_pr + + +def choice_simulator_prob( + dh, + otaz, + n_threads=1, + temp_dir=None, + purposes=None, +): + """ + Compute probabilities for mode and destination choice. + + Parameters + ---------- + dh : DataHandler + otaz : int or array-like + n_threads : int + temp_dir : Path-like, optional + purposes : Collection, optional + Only compute probabilities for these purposes. + + Returns + ------- + simulated_probability : dict + By purpose, the average choice probabilities. Averages are computed by + simulation of a number of random households and transit accessibility + in the zone, and averaging over the simulation. + simulated_probability_disagg : dict + By purpose, the simulated disaggregated choice probabilities. + validation_useful_data : DataFrame + Validation data extracted from the simulation. + simulated_utility : DataFrame + By purpose, the simulated utilities for auto and transit + """ + if purposes is None: + purposes = purposesA + get_worker_log( + os.path.join(dh.filenames.cache_dir, 'logs'), + level=10, + ) + + data_cache_file = None + if temp_dir: + os.makedirs(temp_dir, exist_ok=True) + if isinstance(otaz, int): + data_cache_file = os.path.join(temp_dir, f"cached_data_for_application_{otaz}.feathers") + else: + data_cache_file = os.path.join(temp_dir, f"cached_data_for_application_{otaz[0]}_{otaz[-1]}.feathers") + + log = getSubLogger("CHOICE_SIM") + + log.debug("data_for_application") + if data_cache_file and os.path.exists(data_cache_file+".data_co"): + log.debug("data_for_application load") + dfa = larch.DataFrames.from_feathers(data_cache_file) + else: + log.debug("data_for_application make") + dfa = data_for_application(dh, otaz=otaz) + if data_cache_file: + dfa.to_feathers(data_cache_file) + + log.debug("settings") + replication = dh.cfg.get('n_replications', 50) + + choice_simulator = choice_simulator_initialize(dh, n_threads=n_threads) + simulated_utility = {} + simulated_probability = {} + simulated_probability_disagg = {} + + for purpose in purposes: + sim = choice_simulator[purpose] + attach_dataframes(sim, purpose, dfa) + log.critical("--- GENERATING SIMULATED UTILITY ---") + sim_u = sim.utility() + sim_u_auto = sim_u[:,mode9codes.AUTO-1:dh.n_internal_zones*9:9] + sim_u_transit = sim_u[:,mode9codes.TRANSIT-1:dh.n_internal_zones*9:9] + simulated_utility[purpose] = pd.concat([ + pd.DataFrame(blockwise_mean(sim_u_auto, replication), index=otaz).rename_axis('otaz', axis=0), + pd.DataFrame(blockwise_mean(sim_u_transit, replication), index=otaz).rename_axis('otaz', axis=0), + ], keys=['AUTO', 'TRANSIT'], names=['MODE']) + sim_pr = _sim_prob(purpose, sim) + simulated_probability_disagg[purpose] = sim_pr + simulated_probability[purpose] = blockwise_mean(sim_pr, replication) + if np.any(np.isnan(simulated_probability[purpose])): + raise ValueError(f"nan in simulated_probability[{purpose}]") + + simulated_utility = pd.concat( + objs=simulated_utility.values(), + keys=simulated_utility.keys(), + names=['PURPOSE'] + ) + + #transit_approach_walktime_cols = [i for i in dfa.data_co.columns if 'transit_approach_walktime' in i and 'auto' not in i and 'sigmoid' not in i] + validation_useful_data = pd.DataFrame(data=np.int8(0), index=dfa.data_co.index, columns=["hh_auto_own", 'hhinc5', 'hhinc5l', 'hhinc5h', 'hhinc5g']) + validation_useful_data.loc[dfa.data_co['hhveh==0'] == 0, "hh_auto_own"] = 1 + validation_useful_data.loc[dfa.data_co['hhveh==0'] > 0, "hh_auto_own"] = 0 + validation_useful_data.loc[dfa.data_co['hhveh>=hhadults'] > 0, "hh_auto_own"] = 2 + validation_useful_data['hhinc5'] = dfa.data_co['hhinc5'] + validation_useful_data['hhinc5g'] = dfa.data_co['hhinc5g'] + validation_useful_data['hhinc5l'] = dfa.data_co['hhinc5l'] + validation_useful_data['hhinc5h'] = dfa.data_co['hhinc5h'] + log.debug("complete") + return simulated_probability, simulated_probability_disagg, validation_useful_data, simulated_utility + + +def choice_simulator_trips( + dh, + otaz, + purposes=None, + random_state=None, + n_threads=1, + save_dir=None, + delay=0, + temp_dir=None, + disagg_choices=True, + use_wfh_pa=False, +): + """ + The single-process function to model trips by mode/dest/time. + + Parameters + ---------- + otaz : int or array-like + purposes : Collection, optional + + Returns + ------- + + """ + get_worker_log( + os.path.join(dh.filenames.cache_dir, 'logs'), + level=10, + ) + log = getSubLogger("TRIP_SIM") + try: + if delay: + log.debug(f"DELAY choice_simulator_trips {delay})") + time.sleep(delay) + + if use_wfh_pa: + dh['tripclass'] = 'wfh' + else: + dh['tripclass'] = 'typical' + + if purposes is None: + purposes = purposesA + + if isinstance(otaz, int): + otaz = [otaz] + + log.debug(f"CALL choice_simulator_trips({len(otaz)} OTAZ's starting from {otaz[0]})") + + simulated_probability, simulated_probability_disagg, validation_data, simulated_utility = choice_simulator_prob( + dh, + otaz=otaz, + n_threads=n_threads, + temp_dir=temp_dir, + ) + simulated_choices = {} + + tod_models = time_of_day_simulator_initialize(dh, cache=True) + + for purpose in purposes: + log.debug(f" choice_simulator_trips processing time-of-day for purpose {purpose})") + choices_data = {} + n = 0 + + for _o in otaz: + random_state = check_random_generator([_o, 534]) + + num_productions = dh.zone_productions5.loc[_o, purpose] + log.debug(f" {purpose} productions for {_o} = {num_productions}") + + if disagg_choices: + c = np.empty(num_productions, dtype=np.int32) + hh_autos = np.zeros(num_productions, dtype=np.int8) + hh_inc5 = np.zeros(num_productions, dtype=np.int8) + c_position = 0 + num_reps = 50 + for _rep in range(num_reps): + num_productions_rep = (num_productions // num_reps) + (1 if (num_productions % num_reps)>_rep else 0) + p = simulated_probability_disagg[purpose][n] + try: + c_ = random_state.choice(p.size, size=num_productions_rep, p=p) + except ValueError as err: + if 'probabilities do not sum to 1' in str(err): + log.error(f"probabilities sum to {np.sum(p)}, correcting") + p /= np.sum(p) + c_ = random_state.choice(p.size, size=num_productions, p=p) + else: + raise + c[c_position:c_position+c_.size] = c_ + hh_autos[c_position:c_position+c_.size] = validation_data["hh_auto_own"][n] + if purpose == 'HBWH': + hh_inc5[c_position:c_position+c_.size] = validation_data["hhinc5h"][n] + elif purpose == 'HBWL': + hh_inc5[c_position:c_position + c_.size] = validation_data["hhinc5l"][n] + elif purpose == 'NHB': + hh_inc5[c_position:c_position + c_.size] = validation_data["hhinc5g"][n] + hh_autos[c_position:c_position + c_.size] = 0 + else: + hh_inc5[c_position:c_position+c_.size] = validation_data["hhinc5"][n] + c_position += c_.size + n += 1 + + else: + p = simulated_probability[purpose][n] + try: + c = random_state.choice(p.size, size=num_productions, p=p) + except ValueError as err: + if 'probabilities do not sum to 1' in str(err): + log.error(f"probabilities sum to {np.sum(p)}, correcting") + p /= np.sum(p) + c = random_state.choice(p.size, size=num_productions, p=p) + else: + raise + n += 1 + hh_autos = np.zeros_like(c) + hh_inc5 = np.zeros_like(c) + + choices_data[_o] = pd.DataFrame(dict( + mode=(c % n_modes) + 1, + zone=(c // n_modes) + 1, + + # other things to track for calibration / validation + hh_autos=hh_autos, + hh_inc5=hh_inc5, + + )).value_counts().sort_index().rename(_o).astype(np.int16) + + full_index = pd.MultiIndex.from_product( + [ + np.arange(n_modes) + 1, + np.arange(dh.n_internal_zones) + 1, + np.arange(3), + np.arange(5) + 1, + ], + names=[ + 'mode', + 'a_zone', + 'hh_autos', + 'hh_inc5', + ], + ) + + simulated_choices_purpose = pd.concat( + choices_data, + axis=1, + ).reindex(full_index).fillna(0).astype(np.int16) + simulated_choices_purpose.columns.name = 'p_zone' + + # simulated_choices_purpose is now a dataframe, with columns giving + # the production zones (by batch) and a dense 2-level index (mode, a_zone) + + simtrips = simulated_choices_purpose.stack().rename("trips").reset_index() + + reg_auto_trips = simtrips.query("(mode in (1,2,3)) and (trips > 0)") + + def apply_tod(base_trips, is_hired_car=0.0, random_gen=123): + + time_data = dh.skims.raw[[f'mf46{j}' for j in range(1, 9)]].iat_df( + base_trips.rename(columns={'a_zone': 'dtaz', 'p_zone': 'otaz'})[['otaz', 'dtaz']] - 1 + ) + time_data["mode9 in ('TAXI','TNC1','TNC2')"] = is_hired_car + time_data["paFlip"] = 0.0 + time_data["(mode9 in ('TAXI','TNC1','TNC2'))*paFlip"] = 0.0 + time_dfs = larch.DataFrames( + co=time_data.astype(np.float64), + av=1, + alt_codes=[1, 2, 3, 4, 5, 6, 7, 8], + alt_names=['EA', 'AM1', 'AM2', 'AM3', 'MD', 'PM1', 'PM2', 'PM3'], + ) + tod_model = tod_models[purposes_to_5[purpose]] + tod_model.dataframes = time_dfs + tod_model_pr = tod_model.probability().copy() + tod_model.dataframes.data_co["paFlip"] = 1.0 + tod_model.dataframes.data_co["(mode9 in ('TAXI','TNC1','TNC2'))*paFlip"] = is_hired_car + tod_model_pr_flip = tod_model.probability().copy() + n_flipped_trips = binom.rvs( + n=base_trips["trips"].values, + p=dh.cfg.time_of_day.pa_split.get(purpose, 0.0 if purpose=='NHB' else 0.5), + random_state=random_gen, + ) + n_unflipped_trips = base_trips["trips"].values - n_flipped_trips + + # forward trips, which go from production to attraction (PA = OD) + reg_auto_trips_tod = pd.DataFrame( + multichoices( + tod_model_pr, + n_unflipped_trips, + seeds=base_trips.index.values+base_trips["p_zone"].values<<16, + ), + index=base_trips.index, + columns=['EA', 'AM1', 'AM2', 'AM3', 'MD', 'PM1', 'PM2', 'PM3'], + ) + reg_auto_trips_fwd = pd.concat([base_trips.drop(columns=['trips']), reg_auto_trips_tod], axis=1) + reg_auto_trips_fwd_= reg_auto_trips_fwd.rename(columns={'p_zone': 'o_zone', 'a_zone': 'd_zone'}) + reg_auto_trips_fwd_['a_zone'] = reg_auto_trips_fwd['a_zone'] + reg_auto_trips_fwd = reg_auto_trips_fwd_.set_index(['mode', 'o_zone', 'd_zone', 'a_zone', 'hh_autos', 'hh_inc5']) + reg_auto_trips_fwd.columns.name = "timeperiod" + reg_auto_trips_fwd = reg_auto_trips_fwd.stack().rename("trips") + + # flipped trips, which go from attraction to production + if isinstance(n_flipped_trips, int): + n_flipped_trips = np.asarray([n_flipped_trips]) + try: + reg_auto_trips_tod_r = pd.DataFrame( + multichoices( + tod_model_pr_flip, + n_flipped_trips, + seeds=base_trips.index.values+base_trips["p_zone"].values<<18, + ), + index=base_trips.index, + columns=['EA', 'AM1', 'AM2', 'AM3', 'MD', 'PM1', 'PM2', 'PM3'], + ) + except: + log.error(f"{tod_model_pr_flip=}") + log.error(f"{n_flipped_trips=}") + log.exception("error in reg_auto_trips_tod_r") + raise + reg_auto_trips_bwd = pd.concat([base_trips.drop(columns=['trips']), reg_auto_trips_tod_r], axis=1) + reg_auto_trips_bwd_ = reg_auto_trips_bwd.rename(columns={'p_zone': 'd_zone', 'a_zone': 'o_zone'}) + reg_auto_trips_bwd_['a_zone'] = reg_auto_trips_bwd['a_zone'] + reg_auto_trips_bwd = reg_auto_trips_bwd_.set_index(['mode', 'o_zone', 'd_zone', 'a_zone', 'hh_autos', 'hh_inc5']) + reg_auto_trips_bwd.columns.name = "timeperiod" + reg_auto_trips_bwd = reg_auto_trips_bwd.stack().rename("trips") + + return pd.concat([ + reg_auto_trips_fwd[reg_auto_trips_fwd > 0], + reg_auto_trips_bwd[reg_auto_trips_bwd > 0], + ]) + + + hired_auto_trips = simtrips.query("(mode in (4,5,6)) and (trips > 0)") + + log.debug(f" applying TOD to reg_auto_trips") + reg_auto_trips = apply_tod(reg_auto_trips, 0.0, random_state) + log.debug(f" applying TOD to hired_auto_trips") + hired_auto_trips = apply_tod(hired_auto_trips, 1.0, random_state) + + log.debug(f" applying directionality to non-auto trips") + # non-auto trips + non_auto_trips = simtrips.query("(mode in (7,8,9)) and (trips > 0)") + non_auto_trips = non_auto_trips.reset_index(drop=True) + non_auto_trips["timeperiod"] = "NA" + n_flipped_trips = binom.rvs( + n=non_auto_trips["trips"].values, + p=dh.cfg.time_of_day.pa_split.get(purpose, 0.5), + random_state=random_state, + ) + n_unflipped_trips = non_auto_trips["trips"].values - n_flipped_trips + + non_auto_trips_attractions = non_auto_trips['a_zone'] + + non_auto_trips_r = non_auto_trips.copy(deep=True) + non_auto_trips_r["trips"] = n_flipped_trips + non_auto_trips_r = non_auto_trips_r.rename(columns={'p_zone': 'o_zone', 'a_zone': 'd_zone'}) + non_auto_trips_r['a_zone'] = non_auto_trips_attractions + non_auto_trips_r = non_auto_trips_r.set_index(['mode', 'o_zone', 'd_zone', 'a_zone', 'hh_autos', 'hh_inc5', 'timeperiod'])["trips"] + + non_auto_trips["trips"] = n_unflipped_trips + non_auto_trips = non_auto_trips.rename(columns={'p_zone': 'd_zone', 'a_zone': 'o_zone'}) + non_auto_trips['a_zone'] = non_auto_trips_attractions + non_auto_trips = non_auto_trips.set_index(['mode', 'o_zone', 'd_zone', 'a_zone', 'hh_autos', 'hh_inc5', 'timeperiod'])["trips"] + + non_auto_trips = pd.concat([non_auto_trips[non_auto_trips>0], non_auto_trips_r[non_auto_trips_r>0]]) + #non_auto_trips = non_auto_trips.reset_index() + + sim_mode_dest_tod = pd.concat([reg_auto_trips, hired_auto_trips, non_auto_trips]) + if isinstance(sim_mode_dest_tod, pd.Series): + sim_mode_dest_tod = pd.DataFrame(sim_mode_dest_tod) + # if save_dir is not None: + # sim_mode_dest_tod.to_parquet(os.path.join(save_dir, f"choice_simulator_trips_{purpose}_{otaz[0]}_{otaz[-1]}.pq")) + simulated_choices[purpose] = sim_mode_dest_tod + + if purpose == 'NHB': + + # Visitor trips + visitor_choices_data = [] + for otaz_n, otaz_ in enumerate(otaz): + + visitor_pr = simulated_probability['NHB'][otaz_n] + k = 0 + for dtaz_ in range(1, dh.n_internal_zones+1): + n_visitor_trips_here = dh.visitor_trips.iloc[otaz_-1, dtaz_-1] + if n_visitor_trips_here == 0: + k += 9 + continue + else: + visitor_mode_pr = np.nan_to_num(visitor_pr[k:k+9]) + visitor_mode_pr[mode9codes.TAXI-1] *= dh.cfg.get('visitor_taxi_multiple', 5.0) + visitor_mode_pr[mode9codes.TNC1-1] *= dh.cfg.get('visitor_tnc1_multiple', 5.0) + visitor_mode_pr[mode9codes.TNC2-1] *= dh.cfg.get('visitor_tnc2_multiple', 5.0) + k += 9 + visitor_mode_pr_sum = visitor_mode_pr.sum() + if visitor_mode_pr_sum == 0: continue # this OD pair is not valid + visitor_mode_pr /= visitor_mode_pr_sum + c = random_state.choice( + 9, + size=n_visitor_trips_here, + p=visitor_mode_pr, + ) + visitor_choices_data.append(pd.DataFrame(dict( + mode=c+1, + p_zone=otaz_, + a_zone=dtaz_, + hh_autos=-1, + hh_inc5=-1, + )).value_counts().sort_index().rename('trips').astype(np.int16)) + + visitor_choices = pd.concat(visitor_choices_data).reset_index() + visitor_reg_auto_trips = apply_tod(visitor_choices.query("(mode in (1,2,3)) and (trips > 0)"), 0.0) + visitor_hired_auto_trips = apply_tod(visitor_choices.query("(mode in (4,5,6)) and (trips > 0)"), 1.0) + visitor_nonauto_trips = visitor_choices.query("(mode in (7,8,9)) and (trips > 0)").copy() + visitor_nonauto_trips['timeperiod'] = 'NA' + visitor_nonauto_trips = visitor_nonauto_trips.rename(columns={'p_zone': 'o_zone', 'a_zone': 'd_zone'}) + visitor_nonauto_trips['a_zone'] = visitor_nonauto_trips['d_zone'] + visitor_choices_with_time = pd.concat([ + visitor_reg_auto_trips.reset_index(), + visitor_hired_auto_trips.reset_index(), + visitor_nonauto_trips, + ], ignore_index=True).set_index(['mode','o_zone','d_zone','a_zone','hh_autos','hh_inc5','timeperiod']) + simulated_choices['VISIT'] = visitor_choices_with_time + + concatd = pd.concat(simulated_choices) + concatd.index.set_names('purpose', level=0, inplace=True) + if save_dir is not None: + os.makedirs(save_dir, exist_ok=True) + concise = pd.DataFrame(concatd) + concise.to_parquet(os.path.join( + save_dir, + f"choice_simulator_trips_{otaz[0]}_{otaz[-1]}_{'_'.join(purposes)}_{dh['tripclass']}.pq" + )) + log.critical(f"--- SAVING SIMULATED UTILITY to {save_dir} ---") + simulated_utility.columns = [f'dest{i+1}' for i in range(dh.n_internal_zones)] + simulated_utility.to_parquet(os.path.join( + save_dir, + f"choice_simulator_util_{otaz[0]}_{otaz[-1]}_{'_'.join(purposes)}_{dh['tripclass']}.pq" + )) + else: + log.critical(f"--- NOT SAVING SIMULATED UTILITY (save_dir is None) ---") + log.debug(f"COMPLETED choice_simulator_trips({len(otaz)} OTAZ's starting from {otaz[0]})") + + return concatd + except: + log.exception(f"error in choice_simulator_trips for otaz={otaz}") + raise + +def stagger_starts(iterable, delay=3, n_jobs=4): + pause = 0 + for n, i in enumerate(iterable, start=1): + yield (pause, i) + if n >= n_jobs: + pause = 0 + else: + pause += delay + + +def choice_simulator_trips_many( + dh, + otaz=None, + max_chunk_size=20, + n_jobs=5, + thread_saturation=1, + cache_subdir="choice_simulator_trips", + temp_dir=None, + with_nonhome_auto=False, + disagg_choices=True, + with_wfh=True, + staggertime=15, +): + """ + Run the choice simulators, batching a few TAZ's at at time in parallel jobs. + + Parameters + ---------- + dh : DataHandler + otaz : array-like, optional + The OTAZ's to process. Defaults to generating trips originating from + all internal zones. + max_chunk_size : int, default 20 + The number of OTAZ's to group together in each chunk. Larger chunks + run faster but require more RAM. + n_jobs : int, default 5 + Number of parallel jobs to start. + thread_saturation : int, default 1 + Number of threads per job to allow. Some parts of some computations are + multi-threaded, and can run faster if multiple threads are allowed. + However, if enough RAM is available, it is more efficent to have more + jobs than use more threads per job. + cache_subdir : Path-like, default "choice_simulator_trips" + Relative path, within the cache directory, in which partial results are + stored from each job. + temp_dir : Path-like, optional + A temporary directory used to store processed data during a job. This + feature is made available to handle the case where non-home-based trips + need to be processed separately from home-based trips, so that auto + propensity can be used from the current iteration. The model as + implemented (October 2021) uses lagged auto propensity from the prior + global iteration, so storing this data is not necessary. + with_nonhome_auto : bool, default False + Set to True to use auto propensity from the current home-based trips in + the current global iteration. Warning: This massively increases model + runtime. + disagg_choices : bool, default True + Keep a record of trip choices by disaggregate validation categories + (income, auto ownership, etc). The computed behavioral choices are the + same, but the output files are generated with more detail suitable for + validation (but they are also much larger). + with_wfh : bool, default True + Run the entire model a second time, using the WFH production and + attractions. + staggertime : int, default 15 + Number of seconds to stagger the initial launch of jobs. Staggering + helps prevent resource contention across jobs (i.e. trying to read + inputs from disk at the same time, which can saturate the bandwidth for + disk reading and cause slowdowns in processes). + + Returns + ------- + dask dataframe + The modeled trips + """ + log = getSubLogger("TRIP_SIM_MULTI") + + if otaz is None: + otaz = np.arange(dh.n_internal_zones) + 1 + + # auto chunk size calculation + n_chunks_per_job = 0 + chunk_size = np.inf + while chunk_size > max_chunk_size: + n_chunks_per_job += 1 + chunk_size = int(np.ceil(len(otaz) / n_jobs / n_chunks_per_job)) + if chunk_size == 1: + break + + log.info(f"using chunk_size={chunk_size} to process {len(otaz)} otazs across {n_jobs} jobs") + + otaz_chunks = [otaz[i:i + chunk_size] for i in range(0, len(otaz), chunk_size)] + # inits = [None for _ in range(0, min(len(otaz), n_jobs))] + + import joblib + save_dir = dh.filenames.cache_dir / cache_subdir + os.makedirs(save_dir, exist_ok=True) + n_threads = max(int(thread_saturation * joblib.cpu_count() // n_jobs), 1) + log.info(f"using n_threads={n_threads} (per job)") + + # if temp_dir is None: + # temp_dir = save_dir/"temp" + if temp_dir is not None: + os.makedirs(temp_dir, exist_ok=True) + + # The model allows for using auto propensity for non-home trips + # that is lagged by one global iteration. This allows all trip purposes + # to be processed together, greating improving runtime. + if with_nonhome_auto: + first_purposes = tuple(j for j in purposesA if 'NHB' not in j) + second_purposes = tuple(j for j in purposesA if j not in first_purposes) + else: + first_purposes = purposesA + second_purposes = () + + with joblib.Parallel(n_jobs=n_jobs, verbose=100) as parallel: + # IMPORTANT: Do not run the initialize step as show below + # the memory usage of the worker will be much smaller + # than for a real step, and loky will think there is + # a memory leak and kill the worker. + # if init_step: + # log.info("joblib model init starting") + # _ = parallel( + # joblib.delayed(choice_simulator_initialize)(dh, False) + # for _ in inits + # ) + # log.info("joblib model init complete") + # else: + log.info("joblib model body starting") + parallel( + joblib.delayed(choice_simulator_trips)( + dh, + otaz_chunk, + purposes=first_purposes, + save_dir=save_dir, + n_threads=n_threads, + delay=delay, + temp_dir=temp_dir, + disagg_choices=disagg_choices, + ) + for delay, otaz_chunk in stagger_starts(otaz_chunks, delay=staggertime, n_jobs=n_jobs) + ) + if with_wfh: + log.info("joblib model WFH starting") + parallel( + joblib.delayed(choice_simulator_trips)( + dh, + otaz_chunk, + purposes=first_purposes, + save_dir=save_dir, + n_threads=n_threads, + delay=delay, + temp_dir=temp_dir, + disagg_choices=disagg_choices, + use_wfh_pa=True, + ) + for delay, otaz_chunk in stagger_starts(otaz_chunks, delay=staggertime, n_jobs=n_jobs) + ) + log.info("joblib first purposes complete") + + log.info("computing auto propensity by zone") + trips = assemble_trips( + dh, + from_dir=save_dir, + pattern="choice_simulator_trips_*.pq", + compute_auto_propensity=True, + ) + if second_purposes: + with joblib.Parallel(n_jobs=n_jobs, verbose=100) as parallel: + log.info("joblib model second purposes starting") + parallel( + joblib.delayed(choice_simulator_trips)( + dh, + otaz_chunk, + purposes=second_purposes, + save_dir=save_dir, + n_threads=n_threads, + delay=delay, + temp_dir=temp_dir, + disagg_choices=disagg_choices, + ) + for delay, otaz_chunk in stagger_starts(otaz_chunks, delay=staggertime, n_jobs=n_jobs) + ) + if with_wfh: + log.info("joblib model second purposes WFH starting") + parallel( + joblib.delayed(choice_simulator_trips)( + dh, + otaz_chunk, + purposes=second_purposes, + save_dir=save_dir, + n_threads=n_threads, + delay=delay, + temp_dir=temp_dir, + disagg_choices=disagg_choices, + use_wfh_pa=True, + ) + for delay, otaz_chunk in stagger_starts(otaz_chunks, delay=staggertime, n_jobs=n_jobs) + ) + + log.info("joblib second purposes complete") + trips = assemble_trips( + dh, + from_dir=save_dir, + pattern="choice_simulator_trips_*.pq", + compute_auto_propensity=False, + ) + + log.info("computing deadhead trips by hired cars") + try: + deadheads = compute_deadhead_trip_table( + dh, + trips, + ) + except KeyError: + import numexpr as ne + ne.necompiler._numexpr_cache.clear() + deadheads = compute_deadhead_trip_table( + dh, + trips, + ) + if disagg_choices: + deadheads['hh_autos'] = -1 + deadheads['hh_inc5'] = -1 + deadheads.to_parquet(os.path.join(save_dir, "choice_simulator_trips_deadhead.pq")) + + return assemble_trips( + dh, + from_dir=save_dir, + pattern="choice_simulator_trips_*.pq", + compute_auto_propensity=False, + ) + + + +def assemble_trips( + dh, + from_dir, + pattern="choice_simulator_trips_*.pq", + compute_auto_propensity=False, + validation_dump=None, +): + """ + Assemble trip list files into a single dask DataFrame for processing. + + Parameters + ---------- + dh + from_dir + pattern + compute_auto_propensity + validation_dump + + Returns + ------- + + """ + from_dir = Path(from_dir) + + import dask.dataframe as ddf + import glob + + trips = ddf.read_parquet(glob.glob(os.fspath(from_dir/pattern))) + + if compute_auto_propensity: + homebased_trips_by_mode = ( + trips + .query("purpose not in ('NHB', 'NHBR', 'NHBS')") + .groupby(["mode", "a_zone"])['trips'] + .sum() + .compute() + .unstack(0) + .fillna(0) + ) + auto_propensity = ( + homebased_trips_by_mode.loc[:, [1, 2, 3]].sum(1) / homebased_trips_by_mode.sum(1) + ) + auto_propensity = auto_propensity.reindex(pd.RangeIndex(1, 3632 + 1)).fillna(0.95).rename("auto_propensity") + auto_propensity.index.name = "TAZ" + auto_propensity.to_csv(dh.filenames.emme_database_dir / "computed_auto_propensity.csv") + + if validation_dump is not None: + trips.to_csv( + os.fspath(from_dir/validation_dump), + single_file=True, + compression='gzip' if validation_dump.endswith(".gz") else None, + ) + + return trips + + +def aggregate_to_vehicle_matrixes( + dh, + trips, +): + """ + Aggregate person trips into emme matrix vehicle trips. + + This function writes vehicle trip tables to mfNNN.emx files in the + `Database/emmemat` directory, according to the following guide: + - Automobile Vehicle Trips (by 8 time of day periods EA AM1 AM2 AM3 MD PM1 PM2 PM3) + - SOV low value of time – mf411-mf418 + - SOV med value of time – mf421-mf428 + - SOV high value of time – mf431-mf438 + - HOV2 not diff'd by vot – mf441-mf448 + - HOV3 not diff'd by vot – mf451-mf458 + - Transit Person Trips (not by time of day) + - home-based work low income - mf40 + - home-based work high income - mf41 + - home-based shopping - mf39 + - home-based other - mf42 + - non-home-based - mf43 + + Parameters + ---------- + dh : DataHandler + trips : DataFrame + The output trip table from the mode/dest/time-of-day models + + Returns + ------- + vehicle_trips : xarray.DataArray + """ + + log = getSubLogger("application.ToMatrix") + log.info(f"running aggregate_to_vehicle_matrixes") + + # If we receive a dask dataframe, load it into a pandas dataframe now + import dask.dataframe as ddf + if isinstance(trips, ddf.DataFrame): + log.debug(f"converting trips from dask.dataframe to pandas.dataframe") + trips = trips.compute() + + # hov3_occupancy = { + # 'HBW': 3.36, + # 'HBO': 3.31, + # 'NHB': 3.39, + # } + + from .modecodes import mode9codes + from .time_of_day_model import time_period_names + n_timeperiods = len(time_period_names) + n_zones = dh.skims.raw.dims['otaz'] + z_range = pd.RangeIndex(1, n_zones + 1) + vot_names = ['sovL', 'sovM', 'sovH', 'hov2', 'hov3'] + + votb = pd.read_csv( + dh.filenames.value_of_time_buckets, + comment="#", + skipinitialspace=True, + ) + votb = votb.set_index(["Purpose", "Income Group"]) + votb = votb.div(votb.sum(1), axis=0) + + vehicle_trips = xr.DataArray( + data=np.float32(0.0), + dims=['vot', 'timeperiod', 'o_zone', 'd_zone'], + coords={ + 'vot': vot_names, + 'timeperiod': time_period_names, + 'o_zone': z_range, + 'd_zone': z_range, + } + ) + + for purpose, income in votb.index: + log.info(f" sov for purpose {purpose} income {income}") + + sov_array = xr.DataArray.from_series( + trips + .query(f"purpose == '{purpose}' and mode == {1} and hh_inc5 == {income}") + .groupby(["timeperiod", "o_zone", "d_zone"])['trips'] + .sum() + ).reindex( + timeperiod=time_period_names, o_zone=z_range, d_zone=z_range, + ).fillna(0).values + + log.info(f" sov for purpose {purpose} income {income} total={np.sum(sov_array)}") + + for vot_bucket in range(3): + vehicle_trips[vot_bucket] += sov_array * votb.loc[(purpose, income)].iloc[vot_bucket] + + # count up all HOV2 person trips, divide by 2 + #for modecode, vot_bucket in zip([mode9codes.HOV2, mode9codes.HOV3], [3,4]): + log.info(f" hov2") + vehicle_trips[3, ...] = xr.DataArray.from_series( + trips + .query(f"mode in ({mode9codes.HOV2},{mode9codes.TAXI},{mode9codes.TNC1})") ##-- Heither .query(f"mode == {mode9codes.HOV2}") + .groupby(["timeperiod", "o_zone", "d_zone"])['trips'] + .sum() + ).reindex( + timeperiod=time_period_names, o_zone=z_range, d_zone=z_range, + ).fillna(0).values / 2 + + log.info(f" hov3") + # count up all HOV3 person trips, divide by occupancy + vehicle_trips[4, ...] += xr.DataArray.from_series( + trips + .query(f"purpose in ('HBWH', 'HBWL') and mode in ({mode9codes.HOV3},{mode9codes.TNC2})") ##-- Heither .query(f"purpose in ('HBWH', 'HBWL') and mode == {mode9codes.HOV3}") + .groupby(["timeperiod", "o_zone", "d_zone"])['trips'] + .sum() + ).reindex( + timeperiod=time_period_names, o_zone=z_range, d_zone=z_range, + ).fillna(0).values / dh.cfg.hov3_occupancy['HBW'] + vehicle_trips[4, ...] += xr.DataArray.from_series( + trips + .query(f"purpose in ('HBO', 'HBS') and mode in ({mode9codes.HOV3},{mode9codes.TNC2})") ##-- Heither .query(f"purpose in ('HBO', 'HBS') and mode == {mode9codes.HOV3}") + .groupby(["timeperiod", "o_zone", "d_zone"])['trips'] + .sum() + ).reindex( + timeperiod=time_period_names, o_zone=z_range, d_zone=z_range, + ).fillna(0).values / dh.cfg.hov3_occupancy['HBO'] + vehicle_trips[4, ...] += xr.DataArray.from_series( + trips + .query(f"purpose in ('NHB', 'VISIT') and mode in ({mode9codes.HOV3},{mode9codes.TNC2})") ##-- Heither .query(f"purpose in ('NHB', 'VISIT') and mode == {mode9codes.HOV3}") + .groupby(["timeperiod", "o_zone", "d_zone"])['trips'] + .sum() + ).reindex( + timeperiod=time_period_names, o_zone=z_range, d_zone=z_range, + ).fillna(0).values / dh.cfg.hov3_occupancy['NHB'] + + output_mf_numbers = { + 'sovL': 411, # SOV low value of time – mf411-mf418 + 'sovM': 421, # SOV med value of time – mf421-mf428 + 'sovH': 431, # SOV high value of time – mf431-mf438 + 'hov2': 441, # HOV2 not diff'd by vot – mf441-mf448 + 'hov3': 451, # HOV3 not diff'd by vot – mf451-mf458 + } + + for vot in vot_names: + for t, time_period_name in enumerate(time_period_names): + n = output_mf_numbers[vot] + t + mtx_filename = os.fspath(dh.filenames.emme_database_dir / f"emmemat/mf{n}.emx") + write_out = vehicle_trips \ + .sel(vot=vot, timeperiod=time_period_name) \ + .transpose("o_zone", "d_zone") \ + .values + if os.path.exists(mtx_filename): + mmap_mode = 'r+' + else: + mmap_mode = 'w+' + # We write into the existing file instead of deleting and rewriting the file + # emme may be happier this way if the file handle was previously held open + mmap = np.memmap( + mtx_filename, + dtype=np.float32, + mode=mmap_mode, + shape=write_out.shape, + ) + mmap[:,:] = write_out + mmap.flush() + + # transit person trips + + purposes6 = np.asarray(( + 'HBWH', # Home-based Work, High Income + 'HBWL', # Home-based Work, Low Income + 'HBS', # Home-based Shopping + 'HBO', # Home-based Other Purpose Not Enumerated + 'NHB', # Non-home-based + 'VISIT', + ),) + + transit_trips = xr.DataArray.from_series( + trips + .query(f"mode == {mode9codes.TRANSIT}") + .groupby(["purpose", "o_zone", "d_zone"])['trips'] + .sum() + ).reindex( + purpose=purposes6, o_zone=z_range, d_zone=z_range, + ).astype(np.float32).fillna(0) + + transit_trip_mtx_numbers = { + 'HBWL': 'mf40', + 'HBWH': 'mf41', + 'HBS': 'mf39', + 'HBO': 'mf42', + 'NHB': 'mf43', + 'VISIT': 'mf38', + } + + for purpose, purp_mtx in transit_trip_mtx_numbers.items(): + mtx_filename = os.fspath(dh.filenames.emme_database_dir / f"emmemat/{purp_mtx}.emx") + write_out = transit_trips.sel(purpose=purpose).transpose("o_zone", "d_zone").values #.tofile(mtx_filename) + if os.path.exists(mtx_filename): + mmap_mode = 'r+' + else: + mmap_mode = 'w+' + # We write into the existing file instead of deleting and rewriting the file + # emme may be happier this way if the file handle was previously held open + mmap = np.memmap( + mtx_filename, + dtype=np.float32, + mode=mmap_mode, + shape=write_out.shape, + ) + mmap[:, :] = write_out + mmap.flush() + + # Example: home-based work high and low income auto person-trips + if False: + custom_person_trips = xr.DataArray.from_series( + trips + .query(f"purpose in ('HBWH', 'HBWL') and mode in ({mode9codes.AUTO},{mode9codes.HOV2},{mode9codes.HOV3})") + .groupby(["o_zone", "d_zone"])['trips'] + .sum() + ).reindex( + o_zone=z_range, d_zone=z_range, + ).astype(np.float32).fillna(0) + + custom_matrix_number = 1234 + mtx_filename = os.fspath(dh.filenames.emme_database_dir / f"emmemat/{custom_matrix_number}.emx") + write_out = custom_person_trips.transpose("o_zone", "d_zone").values # use "transpose" to ensure ozone is rows and dzone is cols + if os.path.exists(mtx_filename): + mmap_mode = 'r+' + else: + mmap_mode = 'w+' + # We write into the existing file instead of deleting and rewriting the file + # emme may be happier this way if the file handle was previously held open + mmap = np.memmap( + mtx_filename, + dtype=np.float32, + mode=mmap_mode, + shape=write_out.shape, + ) + mmap[:, :] = write_out + mmap.flush() + + return vehicle_trips \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/choice_model.py b/src/Mode-Dest-TOD/cmap_modedest/choice_model.py new file mode 100755 index 0000000..165c1f5 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/choice_model.py @@ -0,0 +1,544 @@ +import numpy as np +import pandas as pd +import larch +from larch import P,X +from larch.util.data_expansion import piecewise_linear +from .addict import Dict +from .cmap_logging import getLogger +from .modecodes import mode5codes, mode9codes, mode9names + +log = getLogger() + + + +def alt_codes_and_names( + n_sampled_dests=5, + include_actual_dest=True, +): + """ + Generate alternative names and codes for mode-destination model. + + Parameters + ---------- + n_sampled_dests : int + The number of destinations that will be used. In estimation, this + is the number of destinations to be sampled. In application, this + is the total number of destinations, as sampling is not used. + include_actual_dest : bool + Whether to include the "actual" destination. This destination is + included in estimation, where it is used to populate the actually + chosen alternative. In appplication, the "actual" destination is + not applicable and should be turned off. + + Returns + ------- + alt_codes : ndarray + alt_names : list + """ + n_modes = len(mode9names) + alt_codes = np.arange(n_modes * (n_sampled_dests + 1)) + 1 + alt_names = [i for i in mode9names] + for i in range(n_sampled_dests): + alt_names.extend([(j + f"d{i + 1:04d}") for j in mode9names]) + if not include_actual_dest: + alt_codes = alt_codes[n_modes:] + alt_names = alt_names[n_modes:] + return alt_codes, alt_names + + +def model_utility_for_dest( + m, + dest_number, + purpose, + n_modes, +): + """ + Construct some utility functions for the mode and destination model. + + This method constructs the utility functions for all of the modes, for + a single destination. It is called multiple times to build the complete + set of utility functions across all destinations. + + Parameters + ---------- + m : larch.Model + dest_number : int + The number of the destination. In application, this is + the TAZ index (TAZ ID minus 1). In estimation, this is + the sampling slot, or for actual destination, give -1. + purpose : str + n_modes : int + + Returns + ------- + + """ + if dest_number == -1: + dest_label = "actualdest" + else: + dest_label = f'altdest{dest_number + 1:04d}' + + alts_per_dest = n_modes + utility_destination = ( + + P("samp_af") * X(f"log(1/{dest_label}_samp_wgt)") + + P("log_attraction") * X(f"{dest_label}_log_attractions_{purpose}") + + P("intrazonal") * X(f"o_zone == {dest_label}") + + piecewise_linear(f"{dest_label}_auto_dist_OFFPEAK", "distance", breaks=[5, 10]) + ) + shift = (dest_number+1) * alts_per_dest + jAUTO = mode9codes.AUTO + shift + jHOV2 = mode9codes.HOV2 + shift + jHOV3 = mode9codes.HOV3 + shift + jTNC1 = mode9codes.TNC1 + shift + jTNC2 = mode9codes.TNC2 + shift + jTAXI = mode9codes.TAXI + shift + jTRANSIT = mode9codes.TRANSIT + shift + jWALK = mode9codes.WALK + shift + jBIKE = mode9codes.BIKE + shift + peaky = 'PEAK' if 'W' in purpose else 'OFFPEAK' + peaky_hov = 'hov_PEAK' if 'W' in purpose else 'OFFPEAK' + + + m.utility_co[jAUTO] = ( + + P("cost") * X(f"{dest_label}_auto_opcost_{peaky}") / 100 # cost in dollars + + P("totaltime") * X(f"{dest_label}_auto_time_{peaky}") + + P("cost") * X(f"{dest_label}_auto_parking_cost_{purpose}") / 100 # cost in dollars + # TODO add walk terminal time cost + + P("unavail") * X(f"1-{dest_label}_auto_avail_{purpose}") + ) + utility_destination + if purpose.upper()[-1] == 'H': + m.utility_co[jAUTO] += P("cost") * X(f"{dest_label}_auto_toll_hiinc_PEAK") / 100 # cost in dollars + elif purpose.upper()[-1] == 'L': + m.utility_co[jAUTO] += P("cost") * X(f"{dest_label}_auto_toll_loinc_PEAK") / 100 # cost in dollars + else: + m.utility_co[jAUTO] += P("cost") * X(f"{dest_label}_auto_toll_OFFPEAK") / 100 # cost in dollars + if purpose.upper() in {'NH', 'NHB'}: + m.utility_co[jAUTO] += ( + + P("AUTO_ozone_autopropensity") * X(f"ozone_autopropensity") + + P("AUTO_dzone_autopropensity") * X(f"{dest_label}_autopropensity") + ) + else: + m.utility_co[jAUTO] += ( + + P("AUTO_no_veh") * X("hhveh==0") + + P("AUTO_sufficient_veh") * X("hhveh>=hhadults") + ) + + + m.utility_co[jHOV2] = ( + P.Const_HOV2 + + P("cost") * X(f"{dest_label}_auto_opcost_{peaky_hov}") * 0.5 / 100 # cost in dollars + + P("totaltime") * X(f"{dest_label}_auto_time_{peaky}") + + P("cost") * 0.5 * X(f"{dest_label}_auto_parking_cost_{purpose}") / 100 # cost in dollars + # TODO add walk terminal time cost + + P("unavail") * X(f"1-{dest_label}_auto_avail_{purpose}") + + piecewise_linear(f"{dest_label}_auto_dist_OFFPEAK", "HOV2_distance", breaks=[5, 10]) + ) + utility_destination + if purpose.upper()[-1] == 'H': + m.utility_co[jHOV2] += P("cost") * X(f"{dest_label}_auto_toll_hov_hiinc_PEAK") / 2 / 100 # cost in dollars + elif purpose.upper()[-1] == 'L': + m.utility_co[jHOV2] += P("cost") * X(f"{dest_label}_auto_toll_hov_loinc_PEAK") / 2 / 100 # cost in dollars + else: + m.utility_co[jHOV2] += P("cost") * X(f"{dest_label}_auto_toll_OFFPEAK") / 2 / 100 # cost in dollars + if purpose.upper() in {'NH', 'NHB'}: + m.utility_co[jHOV2] += ( + + P("HOV_ozone_autopropensity") * X(f"ozone_autopropensity") + + P("HOV_dzone_autopropensity") * X(f"{dest_label}_autopropensity") + ) + else: + m.utility_co[jHOV2] += ( + + P("HOV_no_veh") * X("hhveh==0") + + P("HOV_sufficient_veh") * X("hhveh>=hhadults") + ) + + + + + m.utility_co[jHOV3] = ( + P.Const_HOV3 + + P("cost") * X(f"{dest_label}_auto_opcost_{peaky_hov}") * 0.33 / 100 # cost in dollars + + P("totaltime") * X(f"{dest_label}_auto_time_{peaky}") + + P("cost") * 0.33 * X(f"{dest_label}_auto_parking_cost_{purpose}") / 100 # cost in dollars + # TODO add walk terminal time cost + + P("unavail") * X(f"1-{dest_label}_auto_avail_{purpose}") + + piecewise_linear(f"{dest_label}_auto_dist_OFFPEAK", "HOV3_distance", breaks=[5, 10]) + ) + utility_destination + if purpose.upper()[-1] == 'H': + m.utility_co[jHOV3] += P("cost") * X(f"{dest_label}_auto_toll_hov_hiinc_PEAK") / 3 / 100 # cost in dollars + elif purpose.upper()[-1] == 'L': + m.utility_co[jHOV3] += P("cost") * X(f"{dest_label}_auto_toll_hov_loinc_PEAK") / 3 / 100 # cost in dollars + else: + m.utility_co[jHOV3] += P("cost") * X(f"{dest_label}_auto_toll_OFFPEAK") / 3 / 100 # cost in dollars + if purpose.upper() in {'NH', 'NHB'}: + m.utility_co[jHOV3] += ( + + P("HOV_ozone_autopropensity") * X(f"ozone_autopropensity") + + P("HOV_dzone_autopropensity") * X(f"{dest_label}_autopropensity") + ) + else: + m.utility_co[jHOV3] += ( + + P("HOV_no_veh") * X("hhveh==0") + + P("HOV_sufficient_veh") * X("hhveh>=hhadults") + ) + m.utility_co[jTNC1] = ( + P.Const_TNC1 + + P("cost") * X(f"{dest_label}_tnc_solo_fare_{peaky}") / 100 # cost in dollars + + P("ovtt_dist") * X(f"{dest_label}_tnc_solo_wait_time_{peaky}")/X(f"{dest_label}_auto_dist_{peaky}") + + P("totaltime") * X(f"{dest_label}_tnc_solo_wait_time_{peaky}") + + P("totaltime") * X(f"{dest_label}_auto_time_{peaky}") + + P("unavail") * X(f"1-{dest_label}_auto_avail_{purpose}") + ) + utility_destination + m.utility_co[jTNC2] = ( + P.Const_TNC2 + + P("cost") * X(f"{dest_label}_tnc_pool_fare_{peaky}") / 100 # cost in dollars + + P("ovtt_dist") * X(f"{dest_label}_tnc_pool_wait_time_{peaky}")/X(f"{dest_label}_auto_dist_{peaky}") + + P("totaltime") * X(f"{dest_label}_tnc_pool_wait_time_{peaky}") + + P("totaltime") * X(f"{dest_label}_auto_time_{peaky}") + + P("unavail") * X(f"1-{dest_label}_auto_avail_{purpose}") + ) + utility_destination + m.utility_co[jTAXI] = ( + P.Const_TAXI + + P("cost") * X(f"{dest_label}_taxi_fare_{peaky}") / 100 # cost in dollars + + P("ovtt_dist") * X(f"{dest_label}_taxi_wait_time_{peaky}")/X(f"{dest_label}_auto_dist_{peaky}") + + P("totaltime") * X(f"{dest_label}_taxi_wait_time_{peaky}") + + P("totaltime") * X(f"{dest_label}_auto_time_{peaky}") + + P("unavail") * X(f"1-{dest_label}_auto_avail_{purpose}") + ) + utility_destination + + if purpose.upper()[-1] == 'H': + m.utility_co[jTNC1] += P("cost") * X(f"{dest_label}_auto_toll_hiinc_PEAK") / 100 # cost in dollars + m.utility_co[jTNC2] += P("cost") * X(f"{dest_label}_auto_toll_hiinc_PEAK") / 2 / 100 # cost in dollars + m.utility_co[jTAXI] += P("cost") * X(f"{dest_label}_auto_toll_hiinc_PEAK") / 100 # cost in dollars + elif purpose.upper()[-1] == 'L': + m.utility_co[jTNC1] += P("cost") * X(f"{dest_label}_auto_toll_loinc_PEAK") / 100 # cost in dollars + m.utility_co[jTNC2] += P("cost") * X(f"{dest_label}_auto_toll_loinc_PEAK") / 2 / 100 # cost in dollars + m.utility_co[jTAXI] += P("cost") * X(f"{dest_label}_auto_toll_loinc_PEAK") / 100 # cost in dollars + else: + m.utility_co[jTNC1] += P("cost") * X(f"{dest_label}_auto_toll_OFFPEAK") / 100 # cost in dollars + m.utility_co[jTNC2] += P("cost") * X(f"{dest_label}_auto_toll_OFFPEAK") / 2 / 100 # cost in dollars + m.utility_co[jTAXI] += P("cost") * X(f"{dest_label}_auto_toll_OFFPEAK") / 100 # cost in dollars + + + m.utility_co[jWALK] = ( + P.Const_WALK + #+ P("walk_time") * X(f"{dest_label}_auto_dist_OFFPEAK") * 20 # minutes per mile + + piecewise_linear(f"{dest_label}_auto_dist_OFFPEAK", "walk_time", breaks = [0.5,1.0]) * 20 # minutes per mile + + P("walk_intrazonal") * X(f"o_zone == {dest_label}") + + P("walk_areatype2") * X(f"fmax(ozone_areatype, {dest_label}_areatype)==2") + + P("walk_areatype3") * X(f"fmax(ozone_areatype, {dest_label}_areatype)==3") + + P("walk_areatype4") * X(f"fmax(ozone_areatype, {dest_label}_areatype)==4") + ) + utility_destination + m.utility_co[jBIKE] = ( + P.Const_BIKE + + P("bike_time") * X(f"{dest_label}_auto_dist_OFFPEAK") * 5 # minutes per mile + + P("bike_intrazonal") * X(f"o_zone == {dest_label}") + ) + utility_destination + m.utility_co[jTRANSIT] = ( + P.Const_Transit + + P("cost") * X(f"{dest_label}_transit_fare_{peaky}") / 100 # cost in dollars + + P("totaltime") * X(f"{dest_label}_transit_ovtt_{peaky}") + + P("cost") * X(f"{dest_label}_transit_approach_cost_{peaky}") / 100 # cost in dollars + + P("totaltime") * X(f"{dest_label}_transit_approach_drivetime_{peaky}") + + P("totaltime") * X(f"{dest_label}_transit_approach_walktime_{peaky}") + + P("totaltime") * X(f"{dest_label}_transit_approach_waittime_{peaky}") + + P("unavail") * X(f"1-{dest_label}_transit_avail_{purpose}") + + P("ovtt_dist") * X(f"{dest_label}_transit_ovtt_{peaky}")/X(f"{dest_label}_auto_dist_{peaky}") + + P("ovtt_dist") * X(f"{dest_label}_transit_approach_walktime_{peaky}")/X(f"{dest_label}_auto_dist_{peaky}") + + P("ovtt_dist") * X(f"{dest_label}_transit_approach_waittime_{peaky}")/X(f"{dest_label}_auto_dist_{peaky}") + + P("transit_intrazonal") * X(f"o_zone == {dest_label}") + + ) + utility_destination + if 'W' not in purpose.upper(): + m.utility_co[jTRANSIT] += ( + + P("transit_walk_is_short") * X(f"hard_sigmoid({dest_label}_transit_approach_walktime_{peaky}, 4.0, 2.0)") + + P("transit_areatype3") * X(f"fmax(ozone_areatype, {dest_label}_areatype)==3") + ) + else: + m.utility_co[jTRANSIT] += ( + + P("transit_areatype2") * X(f"fmin(ozone_areatype, {dest_label}_areatype)==2") + + P("transit_areatype3") * X(f"fmin(ozone_areatype, {dest_label}_areatype)==3") + + P("transit_areatype4") * X(f"fmin(ozone_areatype, {dest_label}_areatype)==4") + + P("metra_longtrip") * X(f"{dest_label}_Metra_drive_{peaky}") + ) + + if purpose.upper() in {'NH', 'NHB'}: + m.utility_co[jTRANSIT] += ( + + P("totaltime") * X(f"piece({dest_label}_transit_ivtt_{peaky}, None, 20)") + + P("ivtt_longtransit") * X(f"piece({dest_label}_transit_ivtt_{peaky}, 20, None)") + ) + else: + m.utility_co[jTRANSIT] += ( + + P("totaltime") * X(f"{dest_label}_transit_ivtt_{peaky}") + ) + + ## IMPORTANT be sure to change `nests_per_dest` elsewhere (i.e. estimation code) + # if/when the number of nests per destination is altered here + + private_car = m.graph.new_node( + parameter="Mu-PrivateCar", + children=[jAUTO, jHOV2, jHOV3], + name=f"privatecar-{dest_label}", + ) + hired_car = m.graph.new_node( + parameter="Mu-HiredCar", + children=[jTAXI, jTNC1, jTNC2], + name=f"hiredcar-{dest_label}", + ) + m.graph.new_node( + parameter="Mu-Dest", + children=[private_car, hired_car, jTRANSIT, jWALK, jBIKE], + name=f"{dest_label}", + ) + + +def _lock_value(self, name, value, note=None, change_check=True): + """ + Set a fixed value for a model parameter. + + Parameters with a fixed value (i.e., with "holdfast" set to 1) + will not be changed during estimation by the likelihood + maximization algorithm. + + Parameters + ---------- + name : str + The name of the parameter to set to a fixed value. + value : float + The numerical value to set for the parameter. + note : str, optional + A note as to why this parameter is set to a fixed value. + This will not affect the mathematical treatment of the + parameter in any way, but may be useful for reporting. + change_check : bool, default True + Whether to trigger a check to see if any parameter frame + values have changed. Can be set to false to skip this + check if you know that the values have not changed or want + to delay this check for later, but this may result in + problems if the check is needed but not triggered before + certain other modeling tasks are performed. + + """ + name = str(name) + if value == 'null': + value = self.pf.loc[name, 'nullvalue'] + self.set_value(name, value, holdfast=1, initvalue=value, nullvalue=value, minimum=value, maximum=value) + if note is not None: + self._frame.loc[name, 'note'] = note + if change_check: + self._check_if_frame_values_changed() + + +def purpose_peakiness(purpose): + from .purposes import purposes_to_peaky + if purposes_to_peaky[purpose]: + return 'PEAK' + else: + return 'OFFPEAK' + + +def model_choice_availability(purpose, n_sampled_dests, include_actual_dest=False): + """ + Build a dictionary that has expressions for availability of each mode to each destination. + + Parameters + ---------- + purpose : str + The trip purpose, which in turn determines the available skims used. + n_sampled_dests : int + The number of destinations that will be used. In estimation, this + is the number of destinations to be sampled. In application, this + is the total number of destinations, as sampling is not used. + include_actual_dest : bool + Whether to include the "actual" destination. This destination is + included in estimation, where it is used to populate the actually + chosen alternative. In appplication, the "actual" destination is + not applicable and should be turned off. + + Returns + ------- + Dict[int, str] + """ + + peaky = purpose_peakiness(purpose) + n_modes = len(mode9codes) + + # Define the alternative availability for each alternative in this model. + av = {} + dzone_has_nonzero_attractions = f"actualdest_log_attractions_{purpose} > -666" + if include_actual_dest: + av[mode9codes.AUTO] = dzone_has_nonzero_attractions + av[mode9codes.HOV2] = dzone_has_nonzero_attractions + av[mode9codes.HOV3] = dzone_has_nonzero_attractions + av[mode9codes.TNC1] = dzone_has_nonzero_attractions + av[mode9codes.TNC2] = dzone_has_nonzero_attractions + av[mode9codes.TAXI] = dzone_has_nonzero_attractions + av[mode9codes.TRANSIT] = ( + f"(actualdest_transit_ivtt_{peaky} < 999) " + f"& (actualdest_transit_approach_walktime_{peaky} < 999) " + f"& (actualdest_transit_approach_drivetime_{peaky} < 999) " + f"& ({dzone_has_nonzero_attractions})" + ) + av[mode9codes.WALK] = f"(actualdest_log_attractions_{purpose} > -666)&(actualdest_auto_dist_OFFPEAK < 3)" + av[mode9codes.BIKE] = f"(actualdest_log_attractions_{purpose} > -666)&(actualdest_auto_dist_OFFPEAK < 12)" + num = n_modes + for i in range(n_sampled_dests): + altdest_has_nonzero_attractions = f"altdest{i + 1:04d}_auto_avail_{purpose}" + av[num + mode9codes.AUTO] = altdest_has_nonzero_attractions + av[num + mode9codes.HOV2] = altdest_has_nonzero_attractions + av[num + mode9codes.HOV3] = altdest_has_nonzero_attractions + av[num + mode9codes.TNC1] = altdest_has_nonzero_attractions + av[num + mode9codes.TNC2] = altdest_has_nonzero_attractions + av[num + mode9codes.TAXI] = altdest_has_nonzero_attractions + av[num + mode9codes.TRANSIT] = f"altdest{i + 1:04d}_transit_avail_{purpose}" + av[num + mode9codes.WALK] = f"altdest{i + 1:04d}_walk_avail_{purpose}" + av[num + mode9codes.BIKE] = f"altdest{i + 1:04d}_bike_avail_{purpose}" + num += n_modes + + return av + + +def model_builder( + purpose, + include_actual_dest=True, + n_sampled_dests=5, + parameter_values=None, + constraints=True, + n_threads=-1, + application_mode=False, + explicit_av=True, +): + """ + Construct a larch Model for mode and destination choice. + + This function creates the structure of the model and sets parameter + values within that structure if given. To ensure consistency, the + same code is used to contruct models for estimation and for application, + although slight changes in structure are applied based on the arguments + as documented below. + + Parameters + ---------- + purpose : str + include_actual_dest : bool + The "actual" observed destination is included for estimation, but + not in application. + n_sampled_dests : int + For estimation, only a subset of destinations are sampled using a + weighted importance sampling. In application, this is set to the + full number of zones and no sampling weights are applied. + parameter_values : Mapping + The values to use for model parameters. Typically not provided here + for estimation, but should be provided for application. + constraints : bool + Whether to include estimation constraints in the model specification. + In application, parameters are not changed so constraints are + unnecessary. + n_threads : int, default -1 + Number of threads to use for computation. Set to -1 to use threads for + all processessor cores. + application_mode + explicit_av + + Returns + ------- + + """ + + + log.debug(f"model_builder({purpose}, n_sampled_dests={n_sampled_dests})") + + n_modes = len(mode9names) + + alt_codes, alt_names = alt_codes_and_names( + n_sampled_dests=n_sampled_dests, + include_actual_dest=include_actual_dest, + ) + from larch.numba import DataFrames + dummy_dfs = DataFrames( + alt_codes=alt_codes, + alt_names=alt_names, + ) + + if explicit_av: + av = model_choice_availability(purpose, n_sampled_dests, include_actual_dest) + + import larch.numba + m = larch.numba.Model( + dataservice=dummy_dfs, + n_threads=n_threads, + ) + + m.title = f"{purpose} Mode & Destination" + + if explicit_av: + m.availability_co_vars = av + + if include_actual_dest: + model_utility_for_dest( + m, + dest_number=-1, + purpose=purpose, + n_modes=n_modes, + ) + + for i in range(n_sampled_dests): + model_utility_for_dest( + m, + dest_number=i, + purpose=purpose, + n_modes=n_modes, + ) + + m.unmangle() + _lock_value(m, "samp_af", value=1.0) + _lock_value(m, "log_attraction", value=1.0) + _lock_value(m, "unavail", value=-999) + + # initial setting of nesting parameters + m.set_value("Mu-HiredCar", 0.4) + m.set_value("Mu-Dest", 0.7) + + m.set_value("cost", maximum=-0.00001) + # m.set_value("auto_time", maximum=-0.01, minimum=-0.03) + # m.set_value("tnc_time", maximum=-0.01, minimum=-0.03) + # m.set_value("transit_ivtt", maximum=-0.01, minimum=-0.03) + m.set_value("totaltime", maximum=-0.01, minimum=-0.03) + if "ivtt_longtransit" in m: + m.set_value("ivtt_longtransit", maximum=-0.0001, minimum=-0.03) + m.set_value("ovtt_dist", maximum=-0.001) + if parameter_values is None: + m.set_values( + cost=-0.0001, + # auto_time=-0.01, + tnc_time=-0.02, + totaltime=-0.015, + ovtt_dist=-0.03, + Const_TNC1=-1.0, + Const_TNC2=-1.0, + Const_Transit=-1.0, + intrazonal=-0.1, + ) + else: + m.set_values(**parameter_values) + + if constraints: + from larch.model.constraints import RatioBound + if purpose=='HBWL': + vot_constraint = RatioBound(P("totaltime"), P("cost"), min_ratio=0.0001, max_ratio=0.5, scale=1) + elif purpose=='HBWH': + vot_constraint = RatioBound(P("totaltime"), P("cost"), min_ratio=0.5, max_ratio=1.5, scale=1) + else: + vot_constraint = RatioBound(P("totaltime"), P("cost"), min_ratio=0.0001, max_ratio=1.0, scale=1) + + m.constraints = [ + # RatioBound(P("ovtt"), P("totaltime"), min_ratio=1.5, max_ratio=3.0, scale=1), + RatioBound(P("Mu-HiredCar"), P("Mu-Dest"), min_ratio=1e-5, max_ratio=0.75, scale=1), + RatioBound(P("Mu-PrivateCar"), P("Mu-Dest"), min_ratio=1e-5, max_ratio=0.75, scale=1), + vot_constraint, + ] + + if application_mode: + m._preload_tree_structure() + + m.set_cap() + return m + + diff --git a/src/Mode-Dest-TOD/cmap_modedest/cmap_logging.py b/src/Mode-Dest-TOD/cmap_modedest/cmap_logging.py new file mode 100644 index 0000000..4962486 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/cmap_logging.py @@ -0,0 +1,121 @@ +import os +import logging +from logging.handlers import RotatingFileHandler +LOGGER_NAME = 'CMAP' +LOG_FORMAT = '[{elapsedTime}] {name:s}:{levelname:s}: {message:s}' +WORKERLOG_FORMAT = '[{asctime}][{elapsedTime}] {name:s}:{levelname:s}: {message:s}' + +def format_elapsed_time(duration_milliseconds): + hours, rem = divmod(duration_milliseconds/1000, 3600) + minutes, seconds = divmod(rem, 60) + if hours: + return ("{:0>2}:{:0>2}:{:05.2f}".format(int(hours),int(minutes),seconds)) + else: + return ("{:0>2}:{:05.2f}".format(int(minutes),seconds)) + + +class ElapsedTimeFormatter(logging.Formatter): + def format(self, record): + record.elapsedTime = format_elapsed_time(record.relativeCreated) + return super(ElapsedTimeFormatter, self).format(record) + +def getLogger(name=None): + return logging.getLogger(name or LOGGER_NAME) + +def getSubLogger(subname): + return logging.getLogger(f"{LOGGER_NAME}.{subname}") + +def log_to_stderr(level=30, log_dir=None): + """ + Turn on logging and add a handler which prints to stderr + + Parameters + ---------- + level : int + minimum level of the messages that will be logged + """ + import time + logger = logging.getLogger(LOGGER_NAME) + + # avoid creation of multiple stream handlers for logging to console + for entry in logger.handlers: + if isinstance(entry, logging.StreamHandler) and (entry.formatter._fmt == LOG_FORMAT): + return logger + + formatter = ElapsedTimeFormatter(LOG_FORMAT, style='{') + handler = logging.StreamHandler() + handler.setLevel(level) + handler.setFormatter(formatter) + logger.addHandler(handler) + if log_dir is not None: + # also log to a file + filehandler = RotatingFileHandler( + filename=os.path.join(log_dir, f"{time.strftime('cmap_trip_log_master_%Y%m%d_%H%M%S')}.log"), + mode='a', + maxBytes=1_000_000, + backupCount=10, + ) + filehandler.setLevel(level) + filehandler.setFormatter(formatter) + logger.addHandler(filehandler) + else: + filehandler = None + logger.propagate = False + logger.setLevel(level) + + larch_logger = logging.getLogger("Larch") + if filehandler is not None: + larch_logger.addHandler(filehandler) + larch_logger.addHandler(handler) + larch_logger.setLevel(level) + + return logger + + +def log_df(df, logger=None, level=20, verbose=0, indent=" "): + from io import StringIO + if logger is None or isinstance(logger, str): + from logging import getLogger + logger = getLogger(logger) + with StringIO() as buffer: + df.info(verbose=verbose, buf=buffer) + info = buffer.getvalue() + if indent: + import textwrap + info = textwrap.indent(info, indent, lambda line: True) + logger.log(level, info) + + +def get_worker_log(log_dir, level=20): + """ + Turn on logging and add a handler which writes to a process-specific log file + + Parameters + ---------- + level : int + minimum level of the messages that will be logged + """ + + os.makedirs(log_dir, exist_ok=True) + + logger = logging.getLogger(LOGGER_NAME) + + # avoid creation of multiple stream handlers for logging to worker log + for entry in logger.handlers: + if isinstance(entry, RotatingFileHandler) and (entry.formatter._fmt == WORKERLOG_FORMAT): + return logger + + formatter = ElapsedTimeFormatter(WORKERLOG_FORMAT, style='{') + handler = RotatingFileHandler( + filename=os.path.join(log_dir, f"cmap_trip_log_{os.getpid()}.log"), + mode='a', + maxBytes=1_000_000, + backupCount=10, + ) + handler.setLevel(level) + handler.setFormatter(formatter) + logger.addHandler(handler) + logger.propagate = False + logger.setLevel(level) + + return logger diff --git a/src/Mode-Dest-TOD/cmap_modedest/configuration.py b/src/Mode-Dest-TOD/cmap_modedest/configuration.py new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/__init__.py new file mode 100644 index 0000000..fd1c057 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/__init__.py @@ -0,0 +1,267 @@ +import cloudpickle +import numpy as np +import pandas as pd +import tempfile +import larch +from ..addict import Dict +from pathlib import Path +try: + from sharrow import Flow +except ImportError: + Flow = type(np) + +try: + from geopandas import GeoDataFrame +except ImportError: + GeoDataFrame = () + +from .filepaths import FileNames, PathAttr +from .skims_handler import DictSkims +from logging import getLogger +log = getLogger("CMAP") + +class DataHandler: + + serial_dir = PathAttr() + + def __init__( + self, + filenames=None, + serial_dir=None, + tg_detail=False, + tripclass='typical', + backfill_uncompressed_skims=False, + **kwargs, + ): + + self._jedi_names = set() + + self.artifacts = {} + # artifacts tell how to reload things if they are not cached + # this makes it easier to pass this DataHandler to subprocesses, + # as we don't need to serialize data that is already serialized. + + self._cache = {} + # the _cache is where we store things that we have already loaded + # in this process, so they are available in RAM already. + + log.info("loading filenames") + if filenames is None: + filenames = FileNames(**kwargs) + + if serial_dir is None: + log.debug("create serial temp dir") + self._temporary_dir = tempfile.TemporaryDirectory() + serial_dir = self._temporary_dir.name + + log.debug("serial_dir init") + self.serial_dir = serial_dir + + log.debug("filenames init") + self.filenames = filenames + + log.info("loading hhv_types") + from .household_types import load_household_types + self['hhv_types'] = load_household_types() + + log.info("loading distr") + from .distr_handler import load_distr + self['distr'] = load_distr(filenames) + self._jedi_names.add('distr') + + log.info("loading m01") + from .m01_handler import load_m01 + self['m01'] = load_m01(filenames) + self._jedi_names.add('m01') + + log.info("loading m023") + from .m023_handler import load_m023 + self['m023'] = load_m023(filenames) + self._jedi_names.add('m023') + + log.info("loading shapes") + from .shp_handler import load_zone_shapes + self['zone_shp'] = load_zone_shapes(filenames) + self._jedi_names.add('zone_shp') + + log.info("loading skims") + from .skims_handler import load_skims + self['skims'] = load_skims( + filenames, self, backfill_uncompressed_skims=backfill_uncompressed_skims, + ) + self._jedi_names.add('skims') + + log.info("loading tg") + from .tg_handler import load_tg, load_hh_enum + tripgens = load_tg(filenames, with_detail=tg_detail) + self['tripclass'] = tripclass + for k, tg in tripgens.items(): + # self[f'trip_attractions8_{k}'] = tg.trip_attractions8 + # self[f'trip_productions8_{k}'] = tg.trip_productions8 + # self[f'zone_productions8_{k}'] = tg.zone_productions8 + self[f'trip_attractions5_{k}'] = tg.trip_attractions5 # needed + # self[f'trip_productions5_{k}'] = tg.trip_productions5 + self[f'zone_productions5_{k}'] = tg.zone_productions5 # needed + # if tg_detail: + # self[f'trip_attractions_detail_{k}'] = tg.trip_attractions_detail + # self[f'trip_productions_detail_{k}'] = tg.trip_productions_detail + self._jedi_names.add('tripclass') + self._jedi_names.add('trip_attractions5') + self._jedi_names.add('zone_productions5') + + log.info("loading hh enumeration") + hh_enum, hh_tabulation = load_hh_enum(filenames) + self['hh_enum'] = hh_enum + self['hh_tabulation'] = hh_tabulation + self._jedi_names.add('hh_enum') + self._jedi_names.add('hh_tabulation') + + log.info("loading parking") + from .parking_handler import load_cbd_parking + parking = load_cbd_parking(filenames) + self['cbd_parking_prices'] = parking.cbd_parking_prices + self['cbd_parking_price_prob'] = parking.cbd_parking_price_prob + self['cbd_parking'] = parking.cbd_parking + self['cbd_parking2'] = parking.cbd_parking2 + self['CBD_PARKING_ZONES'] = parking.CBD_PARKING_ZONES + self._jedi_names.add('cbd_parking_prices') + self._jedi_names.add('cbd_parking_price_prob') + self._jedi_names.add('cbd_parking') + self._jedi_names.add('cbd_parking2') + self._jedi_names.add('CBD_PARKING_ZONES') + + log.info("loading visitor trip tables") + from .visitors import load_visitor_trips + visitor_trip_growth = self.cfg.get("visitor_trips_growth_factor", 1.0) + self['visitor_trips'] = load_visitor_trips(filenames, scale_factor=visitor_trip_growth) + self._jedi_names.add('visitor_trips') + + log.info("loading of data handlers complete") + + def __dir__(self): + return self._jedi_names | self.__dict__.keys() + + @property + def cfg(self): + return self.filenames.cfg + + @property + def choice_model_params(self): + return self.filenames.choice_model_params + + def __getstate__(self): + return { + 'artifacts': self.artifacts, + 'filenames': self.filenames, + '_serial_dir': self._serial_dir, + } + + def __setstate__(self, state): + self._cache = {} + self.artifacts = state['artifacts'] + self.filenames = state['filenames'] + self._serial_dir = state['_serial_dir'] + + def __setitem__(self, key, value): + self._cache[key] = value + if not isinstance(key, str): + raise ValueError("keys must be str") + if isinstance(value, GeoDataFrame): + filename = self.serial_dir / f"{key}.pkl" + with open(filename, "wb") as f: + cloudpickle.dump(value, f) + self.artifacts[key] = ('pickle', filename) + elif isinstance(value, pd.DataFrame): + filename = self.serial_dir / f"{key}.pq" + try: + value.to_parquet(filename) + except ValueError: + filename = self.serial_dir / f"{key}.h5" + value.to_hdf(filename, key) + self.artifacts[key] = ('DataFrame.h5', filename) + else: + self.artifacts[key] = ('DataFrame', filename) + elif isinstance(value, pd.Series): + filename = self.serial_dir / f"{key}.spq" + pd.DataFrame(value).to_parquet(filename) + self.artifacts[key] = ('Series', filename) + elif isinstance(value, np.ndarray): + filename = self.serial_dir / f"{key}.nm" + mm = np.memmap( + filename, + dtype=value.dtype, + mode='w+', + shape=value.shape, + ) + mm[:] = value[:] + self.artifacts[key] = ('array', filename, value.dtype, value.shape) + elif isinstance(value, larch.OMX): + filename = value.filename + self.artifacts[key] = ('OMX', filename) + elif isinstance(value, DictSkims): + filename = self.serial_dir / f"{key}.pkl" + with open(filename, "wb") as f: + cloudpickle.dump(value, f) + self.artifacts[key] = ('DictSkims', filename) + elif isinstance(value, Dict): + self.artifacts[key] = ('Dict', set(value.keys())) + for k1, v1 in value.items(): + self[f"{key}.{k1}"] = v1 + elif isinstance(value, Flow): + pass # Flow objects are thread-local + else: + filename = self.serial_dir / f"{key}.pkl" + with open(filename, "wb") as f: + cloudpickle.dump(value, f) + self.artifacts[key] = ('pickle', filename) + + def __getitem__(self, key): + if key == 'trip_attractions5': + return self[f'trip_attractions5_{self.tripclass}'] + elif key == 'zone_productions5': + return self[f'zone_productions5_{self.tripclass}'] + if key in self._cache: + return self._cache[key] + art = self.artifacts[key] + if art[0] == 'DataFrame': + result = pd.read_parquet(art[1]) + elif art[0] == 'DataFrame.h5': + result = pd.read_hdf(art[1], key) + elif art[0] == 'Series': + result = pd.read_parquet(art[1]).iloc[:,0] + elif art[0] == 'array': + result = np.memmap( + art[1], + dtype=art[2], + mode='r+', + shape=art[3], + ) + elif art[0] == 'OMX': + result = larch.OMX(art[1], 'r') + elif art[0] == 'Dict': + result = Dict() + for k1 in art[1]: + result[k1] = self[f"{key}.{k1}"] + elif art[0] == 'pickle': + with open(art[1], "rb") as f: + result = cloudpickle.load(f) + elif art[0] == 'DictSkims': + with open(art[1], "rb") as f: + result = cloudpickle.load(f) + from .skims_handler import _load_skims_step_2 + _load_skims_step_2(result, self) + else: + raise TypeError(art[0]) + self._cache[key] = result + return result + + def __getattr__(self, item): + try: + return self[item] + except: + raise AttributeError(item) + + @property + def n_internal_zones(self): + return len(self.m01) + diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/distr_handler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/distr_handler.py new file mode 100644 index 0000000..47f7201 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/distr_handler.py @@ -0,0 +1,28 @@ +import logging +log = logging.getLogger('CMAP') +import pandas as pd +from ..addict import Dict + +def read_distr(filename): + raw = pd.read_csv(filename, header=None, index_col=0) + raw.columns = pd.MultiIndex.from_product( + [ + ['metra','ctarail','bus','feederbus','pnr'], + ['p1','p2','p3'], + ], + names = ['submode', 'param'] + ) + raw.index.name = 'zone' + result = raw.stack('submode') + return result + +def load_distr(filenames): + distr = Dict() + log.info(f"reading HW distr file from: {filenames.HW_DISTR}") + distr.HW = read_distr(filenames.HW_DISTR) + log.info(f"reading HO distr file from: {filenames.HO_DISTR}") + distr.HO = read_distr(filenames.HO_DISTR) + log.info(f"reading NH distr file from: {filenames.NH_DISTR}") + distr.NH = read_distr(filenames.NH_DISTR) + return distr + diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/filepaths.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/filepaths.py new file mode 100644 index 0000000..6ff5d17 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/filepaths.py @@ -0,0 +1,284 @@ +from pathlib import Path +import os +import glob +import time +import pandas as pd +import numpy as np +import yaml +from ..addict import Dict +from ..util import search_path + +import logging +log = logging.getLogger('CMAP') + +_here = os.path.abspath(os.path.dirname(__file__)) +emme_database_dir = os.path.normpath(os.path.join(_here, "../tests/data")) + + +class PathAttr: + + def __set_name__(self, owner, name): + self.public_name = name + self.private_name = '_' + name + + def __init__(self, can_null=True, change_callback=None): + self.can_null = can_null + self.change_callback = change_callback + + def __get__(self, obj, objtype): + return getattr(obj, self.private_name) + + def __set__(self, obj, value): + if value is None: + if not self.can_null: + raise ValueError(f'cannot set {self.private_name[1:]} to None') + else: + value = Path(value) + try: + prior = getattr(obj, self.private_name) + except AttributeError: + self.on_change(obj, value) + else: + if prior != value: + self.on_change(obj, value) + log.debug(f"setattr {self.private_name} = {value}") + setattr(obj, self.private_name, value) + + def on_change(self, obj, new_value): + log.debug(f"on_change {self.public_name}") + if self.change_callback: + self.change_callback(obj, new_value) + + +def _changed_emme_database_dir(filenames, new_db_dir): + cfgfile = new_db_dir / f"cmap_trip_config.yaml" + with open(cfgfile, 'r') as f: + filenames.cfg = Dict(yaml.load(f, Loader=yaml.SafeLoader)) + +def _make_dirs(filenames, new_dir): + if new_dir and not os.path.exists(new_dir): + os.makedirs(new_dir) + + +class FileNames: + + emme_database_dir = PathAttr(can_null=False, change_callback=_changed_emme_database_dir) + emmemat_dir = PathAttr(can_null=True) + cache_dir = PathAttr(change_callback=_make_dirs) + zone_shapefile = PathAttr() + + def __init__( + self, + emme_database_dir, + cache_dir=None, + emmemat_dir=None, + zone_shapefile=None, + ): + self._memory_mapped_skim = {} + self.emme_database_dir = emme_database_dir + self.emmemat_dir = emmemat_dir + self.cache_dir = cache_dir + self.zone_shapefile = zone_shapefile + self._temporary_dir = None + if self.choice_model_param_file and os.path.exists(self.choice_model_param_file): + with open(self.choice_model_param_file, 'r') as f: + self.choice_model_params = Dict(yaml.load(f, Loader=yaml.SafeLoader)) + else: + self.choice_model_params = Dict() + + + def __getattr__(self, item): + + def _log_path_search(label, *args): + pth = search_path(*args) + log.debug(f"FILEPATH({label})={pth}") + return pth + + if item == 'temp_dir': + if self._temporary_dir is None: + import tempfile + self._temporary_dir = tempfile.TemporaryDirectory() + return Path(self._temporary_dir.name) + if item[-6:] == "_DISTR": + return _log_path_search( + item, + self.emme_database_dir / f"{item}.TXT", + self.emme_database_dir / f"defaults_base_year/{item}.TXT", + ) + if item[-4:] == "_M01": + return _log_path_search( + item, + self.emme_database_dir / f"{item}.TXT", + self.emme_database_dir / f"defaults_base_year/{item}.TXT", + ) + if item[-5:] == "_M023": + return _log_path_search( + item, + self.emme_database_dir / f"{item}.TXT", + self.emme_database_dir / f"defaults_base_year/{item}.TXT", + ) + if item[-9:] == "_CBDPARK0": + return _log_path_search( + item, + self.emme_database_dir / f"{item[:-1]}.TXT", + self.emme_database_dir / f"defaults_base_year/{item[:-1]}.TXT", + ) + if item[-8:] == "_CBDPARK": + return self.cache_dir / f"__{item}.TXT" + if item[-9:] == "_CBDPARK2": + return self.cache_dir / f"__{item}.TXT" + if item[-6:] == "_skims": + raise NotImplementedError + # if self.omx_skims_dir: + # return self.omx_skims_dir / f"{item}.omx" + # else: + # return self.emme_database_dir / f"{item}.omx" + if item[:2] == "mf": + if self.emmemat_dir: + return self.emmemat_dir / f"{item}.emx" + else: + return self.emme_database_dir / "emmemat" / f"{item}.emx" + if item != "_memory_mapped_skim" and item in self._memory_mapped_skim: + return self._memory_mapped_skim[item] + if item[:6] == "map_mf": + if self.emmemat_dir: + pth = self.emmemat_dir / f"{item[4:]}.emx" + else: + pth = self.emme_database_dir / "emmemat" / f"{item[4:]}.emx" + mapped_skim = np.memmap(pth, dtype='f4', mode='r') + nzones = int(np.sqrt(mapped_skim.shape[0])) + mapped_skim = self._memory_mapped_skim[item] = mapped_skim.reshape([nzones,nzones]) + return mapped_skim + if item == "config": + return self._emme_database_dir / f"cmap_trip_config.yaml" + if item == "choice_model_param_file": + result = search_path( + self.emme_database_dir / f"choice_model_params.yaml", + self.cache_dir / f"choice_model_params.yaml", + ) + if result is None: + result = self.cache_dir / f"choice_model_params.yaml" + return result + if item == "tod_model_param_file": + return search_path( + self.emme_database_dir / f"tod_model_params.yaml", + self.cache_dir / f"tod_model_params.yaml", + ) + if item == "zone_districts": + return search_path( + self.emme_database_dir / f"CMAP_Zone_Districts.csv.gz", + self.cache_dir / f"CMAP_Zone_Districts.csv.gz", + ) + if item == "emmemat": + if self.emmemat_dir: + return self.emmemat_dir + else: + return self.emme_database_dir/"emmemat" + if item == "value_of_time_buckets": + return search_path( + self.emme_database_dir / f"value_of_time_buckets.csv", + self.cache_dir / f"value_of_time_buckets.csv", + ) + raise AttributeError(item) + + @property + def tripgen_sas(self): + return latest_matching( + self.emme_database_dir / "tg/sas/data/tg*.sas7bdat" + ) or latest_matching( + self.emme_database_dir / "tg*.sas7bdat" + ) or latest_matching( + self.cache_dir / "tg*.sas7bdat" + ) + + @property + def hh_enum(self): + return latest_matching( + self.emme_database_dir / "TG_HHENUM_OUTPUT.TXT.gz" + ) or latest_matching( + self.cache_dir / "TG_HHENUM_OUTPUT.TXT.gz" + ) or latest_matching( + self.emme_database_dir / "TG_HHENUM_OUTPUT.TXT" + ) or latest_matching( + self.cache_dir / "TG_HHENUM_OUTPUT.TXT" + ) or latest_matching( + self.emme_database_dir / "defaults_base_year/TG_HHENUM_OUTPUT.TXT.gz" + ) + + def save(self, name, data): + try: + if isinstance(data, pd.DataFrame): + if self.cache_dir: + pth = self.cache_dir / f"{name}.pq" + else: + pth = f"{name}.pq" + data.to_parquet(pth) + else: + raise TypeError(str(type(data))) + except Exception as err: + import warnings + warnings.warn(f"failed to save {name}: {err}") + + def load(self, name): + if self.cache_dir: + pth = self.cache_dir / f"{name}.pq" + else: + pth = f"{name}.pq" + if os.path.exists(pth): + return pd.read_parquet(pth) + # else file does not exist + return None + + # def use_emmemat_archive(self, archive_file): + # import zipfile + # import tempfile + # self.temp_emmemat_dir = tempfile.TemporaryDirectory() + # with zipfile.ZipFile(archive_file, 'r') as zip_ref: + # zip_ref.extractall(self.temp_emmemat_dir.name) + # self.emmemat_dir = self.temp_emmemat_dir.name + + + +def _insensitive_glob(pattern): + def either(c): + return '[%s%s]' % (c.lower(), c.upper()) if c.isalpha() else c + return ''.join(map(either, pattern)) + + +def latest_matching(pattern, echo=False, case_insensitive=False, expanduser=True): + """Get the most recently modified file matching the glob pattern + + Parameters + ---------- + pattern : str + A glob pattern to match on + echo : bool, default False + If true, print the last modified time for each matching file + case_insensitive : bool, default False + Tf true, the glob pattern will be modified to be case insensitive. + expanduser : bool, default true + Should each pattern be passed through the `os.path.expanduser` function? + + Returns + ------- + str + The filename of the most recently modified file matching the glob pattern + + """ + if expanduser: + pattern = os.path.expanduser(pattern) + if case_insensitive: + pattern = _insensitive_glob(pattern) + files = glob.glob(pattern) + propose = None + propose_mtime = 0 + for file in files: + (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime) = os.stat(file) + if echo: + print (file,"last modified: %s" % time.ctime(mtime)) + if mtime > propose_mtime: + propose_mtime = mtime + propose = file + return propose + + diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.csv b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.csv new file mode 100644 index 0000000..9ca1106 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.csv @@ -0,0 +1,625 @@ +CODE,N_CHILDREN,N_WORKERS,N_ADULTS,N_VEHICLES,HOUSEHOLDER_AGE +1,0,0,1,0,<35 +2,0,0,2,0,<35 +3,0,0,3,0,<35 +4,0,0,4+,0,<35 +5,0,1,1,0,<35 +6,0,1,2,0,<35 +7,0,1,3,0,<35 +8,0,1,4+,0,<35 +9,0,2,2,0,<35 +10,0,2,3,0,<35 +11,0,2,4+,0,<35 +12,0,3+,3,0,<35 +13,0,3+,4+,0,<35 +14,1,0,1,0,<35 +15,1,0,2,0,<35 +16,1,0,3,0,<35 +17,1,0,4+,0,<35 +18,1,1,1,0,<35 +19,1,1,2,0,<35 +20,1,1,3,0,<35 +21,1,1,4+,0,<35 +22,1,2,2,0,<35 +23,1,2,3,0,<35 +24,1,2,4+,0,<35 +25,1,3+,3,0,<35 +26,1,3+,4+,0,<35 +27,2,0,1,0,<35 +28,2,0,2,0,<35 +29,2,0,3,0,<35 +30,2,0,4+,0,<35 +31,2,1,1,0,<35 +32,2,1,2,0,<35 +33,2,1,3,0,<35 +34,2,1,4+,0,<35 +35,2,2,2,0,<35 +36,2,2,3,0,<35 +37,2,2,4+,0,<35 +38,2,3+,3,0,<35 +39,2,3+,4+,0,<35 +40,3+,0,1,0,<35 +41,3+,0,2,0,<35 +42,3+,0,3,0,<35 +43,3+,0,4+,0,<35 +44,3+,1,1,0,<35 +45,3+,1,2,0,<35 +46,3+,1,3,0,<35 +47,3+,1,4+,0,<35 +48,3+,2,2,0,<35 +49,3+,2,3,0,<35 +50,3+,2,4+,0,<35 +51,3+,3+,3,0,<35 +52,3+,3+,4+,0,<35 +53,0,0,1,1,<35 +54,0,0,2,1,<35 +55,0,0,3,1,<35 +56,0,0,4+,1,<35 +57,0,1,1,1,<35 +58,0,1,2,1,<35 +59,0,1,3,1,<35 +60,0,1,4+,1,<35 +61,0,2,2,1,<35 +62,0,2,3,1,<35 +63,0,2,4+,1,<35 +64,0,3+,3,1,<35 +65,0,3+,4+,1,<35 +66,1,0,1,1,<35 +67,1,0,2,1,<35 +68,1,0,3,1,<35 +69,1,0,4+,1,<35 +70,1,1,1,1,<35 +71,1,1,2,1,<35 +72,1,1,3,1,<35 +73,1,1,4+,1,<35 +74,1,2,2,1,<35 +75,1,2,3,1,<35 +76,1,2,4+,1,<35 +77,1,3+,3,1,<35 +78,1,3+,4+,1,<35 +79,2,0,1,1,<35 +80,2,0,2,1,<35 +81,2,0,3,1,<35 +82,2,0,4+,1,<35 +83,2,1,1,1,<35 +84,2,1,2,1,<35 +85,2,1,3,1,<35 +86,2,1,4+,1,<35 +87,2,2,2,1,<35 +88,2,2,3,1,<35 +89,2,2,4+,1,<35 +90,2,3+,3,1,<35 +91,2,3+,4+,1,<35 +92,3+,0,1,1,<35 +93,3+,0,2,1,<35 +94,3+,0,3,1,<35 +95,3+,0,4+,1,<35 +96,3+,1,1,1,<35 +97,3+,1,2,1,<35 +98,3+,1,3,1,<35 +99,3+,1,4+,1,<35 +100,3+,2,2,1,<35 +101,3+,2,3,1,<35 +102,3+,2,4+,1,<35 +103,3+,3+,3,1,<35 +104,3+,3+,4+,1,<35 +105,0,0,1,2,<35 +106,0,0,2,2,<35 +107,0,0,3,2,<35 +108,0,0,4+,2,<35 +109,0,1,1,2,<35 +110,0,1,2,2,<35 +111,0,1,3,2,<35 +112,0,1,4+,2,<35 +113,0,2,2,2,<35 +114,0,2,3,2,<35 +115,0,2,4+,2,<35 +116,0,3+,3,2,<35 +117,0,3+,4+,2,<35 +118,1,0,1,2,<35 +119,1,0,2,2,<35 +120,1,0,3,2,<35 +121,1,0,4+,2,<35 +122,1,1,1,2,<35 +123,1,1,2,2,<35 +124,1,1,3,2,<35 +125,1,1,4+,2,<35 +126,1,2,2,2,<35 +127,1,2,3,2,<35 +128,1,2,4+,2,<35 +129,1,3+,3,2,<35 +130,1,3+,4+,2,<35 +131,2,0,1,2,<35 +132,2,0,2,2,<35 +133,2,0,3,2,<35 +134,2,0,4+,2,<35 +135,2,1,1,2,<35 +136,2,1,2,2,<35 +137,2,1,3,2,<35 +138,2,1,4+,2,<35 +139,2,2,2,2,<35 +140,2,2,3,2,<35 +141,2,2,4+,2,<35 +142,2,3+,3,2,<35 +143,2,3+,4+,2,<35 +144,3+,0,1,2,<35 +145,3+,0,2,2,<35 +146,3+,0,3,2,<35 +147,3+,0,4+,2,<35 +148,3+,1,1,2,<35 +149,3+,1,2,2,<35 +150,3+,1,3,2,<35 +151,3+,1,4+,2,<35 +152,3+,2,2,2,<35 +153,3+,2,3,2,<35 +154,3+,2,4+,2,<35 +155,3+,3+,3,2,<35 +156,3+,3+,4+,2,<35 +157,0,0,1,3+,<35 +158,0,0,2,3+,<35 +159,0,0,3,3+,<35 +160,0,0,4+,3+,<35 +161,0,1,1,3+,<35 +162,0,1,2,3+,<35 +163,0,1,3,3+,<35 +164,0,1,4+,3+,<35 +165,0,2,2,3+,<35 +166,0,2,3,3+,<35 +167,0,2,4+,3+,<35 +168,0,3+,3,3+,<35 +169,0,3+,4+,3+,<35 +170,1,0,1,3+,<35 +171,1,0,2,3+,<35 +172,1,0,3,3+,<35 +173,1,0,4+,3+,<35 +174,1,1,1,3+,<35 +175,1,1,2,3+,<35 +176,1,1,3,3+,<35 +177,1,1,4+,3+,<35 +178,1,2,2,3+,<35 +179,1,2,3,3+,<35 +180,1,2,4+,3+,<35 +181,1,3+,3,3+,<35 +182,1,3+,4+,3+,<35 +183,2,0,1,3+,<35 +184,2,0,2,3+,<35 +185,2,0,3,3+,<35 +186,2,0,4+,3+,<35 +187,2,1,1,3+,<35 +188,2,1,2,3+,<35 +189,2,1,3,3+,<35 +190,2,1,4+,3+,<35 +191,2,2,2,3+,<35 +192,2,2,3,3+,<35 +193,2,2,4+,3+,<35 +194,2,3+,3,3+,<35 +195,2,3+,4+,3+,<35 +196,3+,0,1,3+,<35 +197,3+,0,2,3+,<35 +198,3+,0,3,3+,<35 +199,3+,0,4+,3+,<35 +200,3+,1,1,3+,<35 +201,3+,1,2,3+,<35 +202,3+,1,3,3+,<35 +203,3+,1,4+,3+,<35 +204,3+,2,2,3+,<35 +205,3+,2,3,3+,<35 +206,3+,2,4+,3+,<35 +207,3+,3+,3,3+,<35 +208,3+,3+,4+,3+,<35 +209,0,0,1,0,35-64 +210,0,0,2,0,35-64 +211,0,0,3,0,35-64 +212,0,0,4+,0,35-64 +213,0,1,1,0,35-64 +214,0,1,2,0,35-64 +215,0,1,3,0,35-64 +216,0,1,4+,0,35-64 +217,0,2,2,0,35-64 +218,0,2,3,0,35-64 +219,0,2,4+,0,35-64 +220,0,3+,3,0,35-64 +221,0,3+,4+,0,35-64 +222,1,0,1,0,35-64 +223,1,0,2,0,35-64 +224,1,0,3,0,35-64 +225,1,0,4+,0,35-64 +226,1,1,1,0,35-64 +227,1,1,2,0,35-64 +228,1,1,3,0,35-64 +229,1,1,4+,0,35-64 +230,1,2,2,0,35-64 +231,1,2,3,0,35-64 +232,1,2,4+,0,35-64 +233,1,3+,3,0,35-64 +234,1,3+,4+,0,35-64 +235,2,0,1,0,35-64 +236,2,0,2,0,35-64 +237,2,0,3,0,35-64 +238,2,0,4+,0,35-64 +239,2,1,1,0,35-64 +240,2,1,2,0,35-64 +241,2,1,3,0,35-64 +242,2,1,4+,0,35-64 +243,2,2,2,0,35-64 +244,2,2,3,0,35-64 +245,2,2,4+,0,35-64 +246,2,3+,3,0,35-64 +247,2,3+,4+,0,35-64 +248,3+,0,1,0,35-64 +249,3+,0,2,0,35-64 +250,3+,0,3,0,35-64 +251,3+,0,4+,0,35-64 +252,3+,1,1,0,35-64 +253,3+,1,2,0,35-64 +254,3+,1,3,0,35-64 +255,3+,1,4+,0,35-64 +256,3+,2,2,0,35-64 +257,3+,2,3,0,35-64 +258,3+,2,4+,0,35-64 +259,3+,3+,3,0,35-64 +260,3+,3+,4+,0,35-64 +261,0,0,1,1,35-64 +262,0,0,2,1,35-64 +263,0,0,3,1,35-64 +264,0,0,4+,1,35-64 +265,0,1,1,1,35-64 +266,0,1,2,1,35-64 +267,0,1,3,1,35-64 +268,0,1,4+,1,35-64 +269,0,2,2,1,35-64 +270,0,2,3,1,35-64 +271,0,2,4+,1,35-64 +272,0,3+,3,1,35-64 +273,0,3+,4+,1,35-64 +274,1,0,1,1,35-64 +275,1,0,2,1,35-64 +276,1,0,3,1,35-64 +277,1,0,4+,1,35-64 +278,1,1,1,1,35-64 +279,1,1,2,1,35-64 +280,1,1,3,1,35-64 +281,1,1,4+,1,35-64 +282,1,2,2,1,35-64 +283,1,2,3,1,35-64 +284,1,2,4+,1,35-64 +285,1,3+,3,1,35-64 +286,1,3+,4+,1,35-64 +287,2,0,1,1,35-64 +288,2,0,2,1,35-64 +289,2,0,3,1,35-64 +290,2,0,4+,1,35-64 +291,2,1,1,1,35-64 +292,2,1,2,1,35-64 +293,2,1,3,1,35-64 +294,2,1,4+,1,35-64 +295,2,2,2,1,35-64 +296,2,2,3,1,35-64 +297,2,2,4+,1,35-64 +298,2,3+,3,1,35-64 +299,2,3+,4+,1,35-64 +300,3+,0,1,1,35-64 +301,3+,0,2,1,35-64 +302,3+,0,3,1,35-64 +303,3+,0,4+,1,35-64 +304,3+,1,1,1,35-64 +305,3+,1,2,1,35-64 +306,3+,1,3,1,35-64 +307,3+,1,4+,1,35-64 +308,3+,2,2,1,35-64 +309,3+,2,3,1,35-64 +310,3+,2,4+,1,35-64 +311,3+,3+,3,1,35-64 +312,3+,3+,4+,1,35-64 +313,0,0,1,2,35-64 +314,0,0,2,2,35-64 +315,0,0,3,2,35-64 +316,0,0,4+,2,35-64 +317,0,1,1,2,35-64 +318,0,1,2,2,35-64 +319,0,1,3,2,35-64 +320,0,1,4+,2,35-64 +321,0,2,2,2,35-64 +322,0,2,3,2,35-64 +323,0,2,4+,2,35-64 +324,0,3+,3,2,35-64 +325,0,3+,4+,2,35-64 +326,1,0,1,2,35-64 +327,1,0,2,2,35-64 +328,1,0,3,2,35-64 +329,1,0,4+,2,35-64 +330,1,1,1,2,35-64 +331,1,1,2,2,35-64 +332,1,1,3,2,35-64 +333,1,1,4+,2,35-64 +334,1,2,2,2,35-64 +335,1,2,3,2,35-64 +336,1,2,4+,2,35-64 +337,1,3+,3,2,35-64 +338,1,3+,4+,2,35-64 +339,2,0,1,2,35-64 +340,2,0,2,2,35-64 +341,2,0,3,2,35-64 +342,2,0,4+,2,35-64 +343,2,1,1,2,35-64 +344,2,1,2,2,35-64 +345,2,1,3,2,35-64 +346,2,1,4+,2,35-64 +347,2,2,2,2,35-64 +348,2,2,3,2,35-64 +349,2,2,4+,2,35-64 +350,2,3+,3,2,35-64 +351,2,3+,4+,2,35-64 +352,3+,0,1,2,35-64 +353,3+,0,2,2,35-64 +354,3+,0,3,2,35-64 +355,3+,0,4+,2,35-64 +356,3+,1,1,2,35-64 +357,3+,1,2,2,35-64 +358,3+,1,3,2,35-64 +359,3+,1,4+,2,35-64 +360,3+,2,2,2,35-64 +361,3+,2,3,2,35-64 +362,3+,2,4+,2,35-64 +363,3+,3+,3,2,35-64 +364,3+,3+,4+,2,35-64 +365,0,0,1,3+,35-64 +366,0,0,2,3+,35-64 +367,0,0,3,3+,35-64 +368,0,0,4+,3+,35-64 +369,0,1,1,3+,35-64 +370,0,1,2,3+,35-64 +371,0,1,3,3+,35-64 +372,0,1,4+,3+,35-64 +373,0,2,2,3+,35-64 +374,0,2,3,3+,35-64 +375,0,2,4+,3+,35-64 +376,0,3+,3,3+,35-64 +377,0,3+,4+,3+,35-64 +378,1,0,1,3+,35-64 +379,1,0,2,3+,35-64 +380,1,0,3,3+,35-64 +381,1,0,4+,3+,35-64 +382,1,1,1,3+,35-64 +383,1,1,2,3+,35-64 +384,1,1,3,3+,35-64 +385,1,1,4+,3+,35-64 +386,1,2,2,3+,35-64 +387,1,2,3,3+,35-64 +388,1,2,4+,3+,35-64 +389,1,3+,3,3+,35-64 +390,1,3+,4+,3+,35-64 +391,2,0,1,3+,35-64 +392,2,0,2,3+,35-64 +393,2,0,3,3+,35-64 +394,2,0,4+,3+,35-64 +395,2,1,1,3+,35-64 +396,2,1,2,3+,35-64 +397,2,1,3,3+,35-64 +398,2,1,4+,3+,35-64 +399,2,2,2,3+,35-64 +400,2,2,3,3+,35-64 +401,2,2,4+,3+,35-64 +402,2,3+,3,3+,35-64 +403,2,3+,4+,3+,35-64 +404,3+,0,1,3+,35-64 +405,3+,0,2,3+,35-64 +406,3+,0,3,3+,35-64 +407,3+,0,4+,3+,35-64 +408,3+,1,1,3+,35-64 +409,3+,1,2,3+,35-64 +410,3+,1,3,3+,35-64 +411,3+,1,4+,3+,35-64 +412,3+,2,2,3+,35-64 +413,3+,2,3,3+,35-64 +414,3+,2,4+,3+,35-64 +415,3+,3+,3,3+,35-64 +416,3+,3+,4+,3+,35-64 +417,0,0,1,0,>65 +418,0,0,2,0,>65 +419,0,0,3,0,>65 +420,0,0,4+,0,>65 +421,0,1,1,0,>65 +422,0,1,2,0,>65 +423,0,1,3,0,>65 +424,0,1,4+,0,>65 +425,0,2,2,0,>65 +426,0,2,3,0,>65 +427,0,2,4+,0,>65 +428,0,3+,3,0,>65 +429,0,3+,4+,0,>65 +430,1,0,1,0,>65 +431,1,0,2,0,>65 +432,1,0,3,0,>65 +433,1,0,4+,0,>65 +434,1,1,1,0,>65 +435,1,1,2,0,>65 +436,1,1,3,0,>65 +437,1,1,4+,0,>65 +438,1,2,2,0,>65 +439,1,2,3,0,>65 +440,1,2,4+,0,>65 +441,1,3+,3,0,>65 +442,1,3+,4+,0,>65 +443,2,0,1,0,>65 +444,2,0,2,0,>65 +445,2,0,3,0,>65 +446,2,0,4+,0,>65 +447,2,1,1,0,>65 +448,2,1,2,0,>65 +449,2,1,3,0,>65 +450,2,1,4+,0,>65 +451,2,2,2,0,>65 +452,2,2,3,0,>65 +453,2,2,4+,0,>65 +454,2,3+,3,0,>65 +455,2,3+,4+,0,>65 +456,3+,0,1,0,>65 +457,3+,0,2,0,>65 +458,3+,0,3,0,>65 +459,3+,0,4+,0,>65 +460,3+,1,1,0,>65 +461,3+,1,2,0,>65 +462,3+,1,3,0,>65 +463,3+,1,4+,0,>65 +464,3+,2,2,0,>65 +465,3+,2,3,0,>65 +466,3+,2,4+,0,>65 +467,3+,3+,3,0,>65 +468,3+,3+,4+,0,>65 +469,0,0,1,1,>65 +470,0,0,2,1,>65 +471,0,0,3,1,>65 +472,0,0,4+,1,>65 +473,0,1,1,1,>65 +474,0,1,2,1,>65 +475,0,1,3,1,>65 +476,0,1,4+,1,>65 +477,0,2,2,1,>65 +478,0,2,3,1,>65 +479,0,2,4+,1,>65 +480,0,3+,3,1,>65 +481,0,3+,4+,1,>65 +482,1,0,1,1,>65 +483,1,0,2,1,>65 +484,1,0,3,1,>65 +485,1,0,4+,1,>65 +486,1,1,1,1,>65 +487,1,1,2,1,>65 +488,1,1,3,1,>65 +489,1,1,4+,1,>65 +490,1,2,2,1,>65 +491,1,2,3,1,>65 +492,1,2,4+,1,>65 +493,1,3+,3,1,>65 +494,1,3+,4+,1,>65 +495,2,0,1,1,>65 +496,2,0,2,1,>65 +497,2,0,3,1,>65 +498,2,0,4+,1,>65 +499,2,1,1,1,>65 +500,2,1,2,1,>65 +501,2,1,3,1,>65 +502,2,1,4+,1,>65 +503,2,2,2,1,>65 +504,2,2,3,1,>65 +505,2,2,4+,1,>65 +506,2,3+,3,1,>65 +507,2,3+,4+,1,>65 +508,3+,0,1,1,>65 +509,3+,0,2,1,>65 +510,3+,0,3,1,>65 +511,3+,0,4+,1,>65 +512,3+,1,1,1,>65 +513,3+,1,2,1,>65 +514,3+,1,3,1,>65 +515,3+,1,4+,1,>65 +516,3+,2,2,1,>65 +517,3+,2,3,1,>65 +518,3+,2,4+,1,>65 +519,3+,3+,3,1,>65 +520,3+,3+,4+,1,>65 +521,0,0,1,2,>65 +522,0,0,2,2,>65 +523,0,0,3,2,>65 +524,0,0,4+,2,>65 +525,0,1,1,2,>65 +526,0,1,2,2,>65 +527,0,1,3,2,>65 +528,0,1,4+,2,>65 +529,0,2,2,2,>65 +530,0,2,3,2,>65 +531,0,2,4+,2,>65 +532,0,3+,3,2,>65 +533,0,3+,4+,2,>65 +534,1,0,1,2,>65 +535,1,0,2,2,>65 +536,1,0,3,2,>65 +537,1,0,4+,2,>65 +538,1,1,1,2,>65 +539,1,1,2,2,>65 +540,1,1,3,2,>65 +541,1,1,4+,2,>65 +542,1,2,2,2,>65 +543,1,2,3,2,>65 +544,1,2,4+,2,>65 +545,1,3+,3,2,>65 +546,1,3+,4+,2,>65 +547,2,0,1,2,>65 +548,2,0,2,2,>65 +549,2,0,3,2,>65 +550,2,0,4+,2,>65 +551,2,1,1,2,>65 +552,2,1,2,2,>65 +553,2,1,3,2,>65 +554,2,1,4+,2,>65 +555,2,2,2,2,>65 +556,2,2,3,2,>65 +557,2,2,4+,2,>65 +558,2,3+,3,2,>65 +559,2,3+,4+,2,>65 +560,3+,0,1,2,>65 +561,3+,0,2,2,>65 +562,3+,0,3,2,>65 +563,3+,0,4+,2,>65 +564,3+,1,1,2,>65 +565,3+,1,2,2,>65 +566,3+,1,3,2,>65 +567,3+,1,4+,2,>65 +568,3+,2,2,2,>65 +569,3+,2,3,2,>65 +570,3+,2,4+,2,>65 +571,3+,3+,3,2,>65 +572,3+,3+,4+,2,>65 +573,0,0,1,3+,>65 +574,0,0,2,3+,>65 +575,0,0,3,3+,>65 +576,0,0,4+,3+,>65 +577,0,1,1,3+,>65 +578,0,1,2,3+,>65 +579,0,1,3,3+,>65 +580,0,1,4+,3+,>65 +581,0,2,2,3+,>65 +582,0,2,3,3+,>65 +583,0,2,4+,3+,>65 +584,0,3+,3,3+,>65 +585,0,3+,4+,3+,>65 +586,1,0,1,3+,>65 +587,1,0,2,3+,>65 +588,1,0,3,3+,>65 +589,1,0,4+,3+,>65 +590,1,1,1,3+,>65 +591,1,1,2,3+,>65 +592,1,1,3,3+,>65 +593,1,1,4+,3+,>65 +594,1,2,2,3+,>65 +595,1,2,3,3+,>65 +596,1,2,4+,3+,>65 +597,1,3+,3,3+,>65 +598,1,3+,4+,3+,>65 +599,2,0,1,3+,>65 +600,2,0,2,3+,>65 +601,2,0,3,3+,>65 +602,2,0,4+,3+,>65 +603,2,1,1,3+,>65 +604,2,1,2,3+,>65 +605,2,1,3,3+,>65 +606,2,1,4+,3+,>65 +607,2,2,2,3+,>65 +608,2,2,3,3+,>65 +609,2,2,4+,3+,>65 +610,2,3+,3,3+,>65 +611,2,3+,4+,3+,>65 +612,3+,0,1,3+,>65 +613,3+,0,2,3+,>65 +614,3+,0,3,3+,>65 +615,3+,0,4+,3+,>65 +616,3+,1,1,3+,>65 +617,3+,1,2,3+,>65 +618,3+,1,3,3+,>65 +619,3+,1,4+,3+,>65 +620,3+,2,2,3+,>65 +621,3+,2,3,3+,>65 +622,3+,2,4+,3+,>65 +623,3+,3+,3,3+,>65 +624,3+,3+,4+,3+,>65 \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.py new file mode 100644 index 0000000..7b55f95 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/household_types.py @@ -0,0 +1,23 @@ +import os +import pandas as pd + +def load_household_types(): + + hhv_cats = { + 'N_CHILDREN': ['0', '1', '2', '3+'], + 'N_WORKERS': ['0', '1', '2', '3+'], + 'N_ADULTS': ['1', '2', '3', '4+'], + 'N_VEHICLES': ['0', '1', '2', '3+'], + 'HOUSEHOLDER_AGE': ['<35', '35-64', '>65'], + } + + hhv_types = pd.read_csv( + os.path.join(os.path.dirname(__file__), "household_types.csv"), + index_col=0, + ) + + for k, v in hhv_cats.items(): + hhv_types[k] = hhv_types[k].astype(pd.CategoricalDtype(v, ordered=True)) + + return hhv_types + diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/m01_handler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/m01_handler.py new file mode 100755 index 0000000..ca5e0bf --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/m01_handler.py @@ -0,0 +1,171 @@ + +import logging +log = logging.getLogger('CMAP') +import pandas as pd +import numpy as np +from ..addict import Dict +from .filepaths import latest_matching +from ..util import search_path + +def read_m01(filename): + raw = pd.read_csv(filename, header=None, index_col=0) + + columns = [ + 'zone_type', + 'pnr_parking_cost', + 'zone_income', + 'pnr_flag', + 'first_wait_bus_peak', + 'first_wait_bus_offpeak', + 'first_wait_feeder_peak', + 'first_wait_feeder_offpeak', + ] + + # autocc column only appears in HW files + if len(raw.columns) == len(columns)+1: + columns.append('autocc') + + raw.columns = columns + raw.index.name = 'zone' + return raw + + +def load_m01(filenames): + m01 = Dict() + + m01.HW = read_m01(filenames.ALLPURPOSE_M01) + # There is only one unique m01 file + # the others are simply copies + # m01.HO = read_m01(filenames.PDHO_M01) + # m01.NH = read_m01(filenames.PDNH_M01) + + m01.HW['taxi_wait_pk'] = m01.HW.zone_type.map(filenames.cfg.taxi.wait_time.peak) + m01.HW['taxi_wait_op'] = m01.HW.zone_type.map(filenames.cfg.taxi.wait_time.offpeak) + + m01.HW['tnc_solo_wait_pk'] = m01.HW.zone_type.map(filenames.cfg.tnc.wait_time.peak) + m01.HW['tnc_solo_wait_op'] = m01.HW.zone_type.map(filenames.cfg.tnc.wait_time.offpeak) + m01.HW['tnc_pool_wait_pk'] = m01.HW.zone_type.map(filenames.cfg.tnc_pooled.wait_time.peak) + m01.HW['tnc_pool_wait_op'] = m01.HW.zone_type.map(filenames.cfg.tnc_pooled.wait_time.offpeak) + + return m01.HW + + +def attach_areatypes(dh, df, prefix, suffix, targetzone): + """ + Attach area type and default auto propensity + + Parameters + ---------- + dh + df + prefix + suffix + targetzone + + Returns + ------- + + """ + m01 = dh.m01 + + if isinstance(targetzone, str): + targetzone = np.asarray(df[targetzone]) + + if prefix and prefix[-1]!="_": + prefix = f"{prefix}_" + + if suffix and suffix[0]!="_": + suffix = f"_{suffix}" + + def _map(x, y): + if isinstance(x, pd.Series): + return x.map(y) + else: + return y[x] + + areatype = m01['zone_type'] + + # auto propensity is reloaded every time we attach to ensure it is up-to-date + auto_propensity_file = search_path( + dh.filenames.cache_dir / "computed_auto_propensity.csv", + dh.filenames.emme_database_dir / "computed_auto_propensity.csv", + dh.filenames.emme_database_dir / "defaults_base_year/default_auto_propensity.csv", + dh.filenames.emme_database_dir / "defaults_base_year/default_auto_propensity.csv.gz", + ) + autopropensity = pd.read_csv(auto_propensity_file, index_col=0)['auto_propensity'] + df[f'{prefix}areatype{suffix}'] = np.asarray(_map(targetzone,areatype)) + df[f'{prefix}autopropensity{suffix}'] = np.asarray(_map(targetzone,autopropensity)) + return df + + +def attach_hired_car_waits(dh, df, prefix, origin_zone): + """ + Attach taxi and TNC wait times to a dataframe. + + Parameters + ---------- + dh : DataHandler + df : DataFrame + New columns will be added to this dataframe. + prefix : str + This prefix will be added to the new columns. + origin_zone : str or pd.Series or int + The origin zone for each row in `df`, given as the column + name or a separate indexed-alike Series. + + Returns + ------- + df : DataFrame + """ + m01 = dh.m01 + + if isinstance(origin_zone, str): + origin_zone = df[origin_zone] + + if prefix and prefix[-1]!="_": + prefix = f"{prefix}_" + + def _map(x, y): + if isinstance(x, pd.Series): + return x.map(y) + else: + return y[x] + + # Add taxi and TNC wait time data + taxi_wait_pk = m01['taxi_wait_pk'] + taxi_wait_op = m01['taxi_wait_op'] + df[f'{prefix}taxi_wait_time_PEAK'] = _map(origin_zone,taxi_wait_pk) + df[f'{prefix}taxi_wait_time_OFFPEAK'] = _map(origin_zone,taxi_wait_op) + # df[f'{prefix}taxi_wait_time'] = ( + # origin_zone.map(taxi_wait_pk) * trips.in_peak + # + origin_zone.map(taxi_wait_op) * ~trips.in_peak + # ) + tnc_solo_wait_pk = m01['tnc_solo_wait_pk'] + tnc_solo_wait_op = m01['tnc_solo_wait_op'] + df[f'{prefix}tnc_solo_wait_time_PEAK'] = _map(origin_zone,tnc_solo_wait_pk) + df[f'{prefix}tnc_solo_wait_time_OFFPEAK'] = _map(origin_zone,tnc_solo_wait_op) + # df[f'{prefix}tnc_solo_wait_time'] = ( + # origin_zone.map(tnc_solo_wait_pk) * trips.in_peak + # + origin_zone.map(tnc_solo_wait_op) * ~trips.in_peak + # ) + tnc_pool_wait_pk = m01['tnc_pool_wait_pk'] + tnc_pool_wait_op = m01['tnc_pool_wait_op'] + df[f'{prefix}tnc_pool_wait_time_PEAK'] = _map(origin_zone,tnc_pool_wait_pk) + df[f'{prefix}tnc_pool_wait_time_OFFPEAK'] = _map(origin_zone,tnc_pool_wait_op) + # df[f'{prefix}tnc_pool_wait_time'] = ( + # origin_zone.map(tnc_pool_wait_pk) * trips.in_peak + # + origin_zone.map(tnc_pool_wait_op) * ~trips.in_peak + # ) + return df + +def sample_hh_income_cats(dh, otaz, n, income_breaks='5', random_state=None, sigma=1.2, trunc_min=None, trunc_max=None): + from ..incomes import random_incomes + return random_incomes( + median_income=dh.m01.zone_income[otaz]*100, + replications=n, + random_state=random_state, + sigma=sigma, + bins=income_breaks, + trunc_min=trunc_min, + trunc_max=trunc_max, + ) diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/m023_handler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/m023_handler.py new file mode 100644 index 0000000..74fb202 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/m023_handler.py @@ -0,0 +1,39 @@ +import pandas as pd +import numpy as np +from ..addict import Dict + +def read_m023(filename): + m023 = Dict() + with open(filename, 'rt') as f: + line = f.readline().split() + m023.CTA_BUS_BOARDING_FARE = int(line[0]) + m023.CTA_RAIL_BOARDING_FARE = int(line[1]) + m023.CTA_FIRST_XFER_FARE = int(line[2]) + m023.CTA_CBD_LINK_UP_FARE = int(line[3]) + + line = f.readline().split() + m023.FEEDER_BUS_BOARDING_FARE = int(line[0]) + m023.FEEDER_BUS_CBD_FARE = int(line[1]) + + line = f.readline().split() + m023.PACE_BUS_BOARDING_FARE = int(line[0]) + m023.PACE_BUS_FIRST_XFER_FARE = int(line[1]) + + line = f.readline().split() + m023.AUTO_OPERATING_COST_BY_SPEED = [int(j) for j in line[:8]] + line = f.readline().split() + m023.AUTO_OPERATING_COST_BY_SPEED.extend([int(j) for j in line[:8]]) + m023.AUTO_OPERATING_COST_BY_SPEED = np.asarray(m023.AUTO_OPERATING_COST_BY_SPEED) + + line = f.readline().split() + m023.AUTO_OPERATING_COST_BY_ZONETYPE = [int(j) for j in line[:4]] + m023.AUTO_OPERATING_COST_BY_ZONETYPE = np.asarray(m023.AUTO_OPERATING_COST_BY_ZONETYPE) + + return m023 + + +def load_m023(filenames): + + m023 = read_m023(filenames.ALLPURPOSE_M023) + return m023 + diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/pa_trip_types.csv b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/pa_trip_types.csv new file mode 100644 index 0000000..91101cd --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/pa_trip_types.csv @@ -0,0 +1,50 @@ +trip_type,description,purpose_category,pair_type +1,worker home-based work low-income,HBWL,PA +2,worker home-based work hi-income,HBWH,PA +3,worker home-based work-related,HBW,PA +4,worker home-based school,HBW,PA +5,worker home-based nonhome/work at residence,HBOR,PA +6,worker home-based nonhome/work not at residence,HBO,PA +7,worker home-based shop,HBS,PA +8,worker work-based nonhome/work at residence,NHBR,PA +9,worker work-based nonhome/work not at residence,NHB,PA +10,worker work-based shop,NHBS,PA +11,worker work-based work,NHB,PA +12,worker nonhome/work at residence nonhome/work at residence,NHBR,OD +13,worker nonhome/work at residence nonhome/work not at residence,NHB,OD +14,worker nonhome/work at residence shop,NHBS,OD +15,worker nonhome/work not at residence nonhome/work at residence,NHBR,OD +16,worker nonhome/work not at residence nonhome/work not at residence,NHB,OD +17,worker nonhome/work not at residence shop,NHBS,OD +18,worker shop nonhome/work at residence,NHBR,OD +19,worker shop nonhome/work not at residence,NHB,OD +20,worker shop shop,NHBS,OD +21,non-working adult home-based school,HBW,PA +22,non-working adult home-based nonhome at residence,HBOR,PA +23,non-working adult home-based nonhome not at residence,HBO,PA +24,non-working adult home-based shop,HBS,PA +25,non-working adult nonhome at residence nonhome at residence,NHBR,OD +26,non-working adult nonhome at residence nonhome not at residence,NHB,OD +27,non-working adult nonhome at residence shop,NHBS,OD +28,non-working adult nonhome not at residence nonhome at residence,NHBR,OD +29,non-working adult nonhome not at residence nonhome not at residence,NHB,OD +30,non-working adult nonhome not at residence shop,NHBS,OD +31,non-working adult shop nonhome at residence,NHBR,OD +32,non-working adult shop nonhome not at residence,NHB,OD +33,non-working adult shop shop,NHBS,OD +34,child home-based school,EXCLUDE,PA +35,child home-based nonhome at residence,HBOR,PA +36,child home-based nonhome not at residence,HBO,PA +37,child home-based shop,HBS,PA +38,child school nonhome at residence,NHBR,PA +39,child school nonhome not at residence,NHB,PA +40,child school shop,NHBS,PA +41,child nonhome at residence nonhome at residence,NHBR,OD +42,child nonhome at residence nonhome not at residence,NHB,OD +43,child nonhome at residence shop,NHBS,OD +44,child nonhome not at residence nonhome at residence,NHBR,OD +45,child nonhome not at residence nonhome not at residence,NHB,OD +46,child nonhome not at residence shop,NHBS,OD +47,child shop nonhome at residence,NHBR,OD +48,child shop nonhome not at residence,NHB,OD +49,child shop shop,NHBS,OD \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/parking_handler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/parking_handler.py new file mode 100644 index 0000000..6b3136a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/parking_handler.py @@ -0,0 +1,74 @@ +import os + +import numpy as np +import pandas as pd +from ..addict import Dict + +def load_cbd_parking(filenames): + + if os.path.exists(filenames.HW_CBDPARK0): + # split the HW_CBDPARK file into its two primary parts + with open(filenames.HW_CBDPARK0, 'rt') as f: + lines = f.readlines() + def secondpart(line): + beginning = line.split(",", 1)[0] + try: + beginning = int(beginning) + except: + return 0 + if beginning < 10_000: + return 0 + return 1 + with open(filenames.HW_CBDPARK, 'wt') as f: + f.write("".join(i for i in lines if not secondpart(i))) + with open(filenames.HW_CBDPARK2, 'wt') as f: + f.write("".join(i for i in lines if secondpart(i))) + + cbd_parking = pd.read_csv( + filenames.HW_CBDPARK, + header=None, + names=['ZoneID', 'CumProb', 'ThresholdPrice', 'SavePrice', 'WalkSeconds'], + ) + cbd_parking.CumProb /= 10000. + # cbd_parking['SumPrice'] = cbd_parking.ThresholdPrice + cbd_parking.SavePrice + cbd_parking['rownum'] = cbd_parking.groupby(['ZoneID']).cumcount() + + def decumulate(x): + x_ = np.array(x) + x_[1:] -= x[:-1] + return x_ + cbd_parking['Prob'] = cbd_parking.groupby("ZoneID")['CumProb'].transform(decumulate) + cbd_parking['WeightedPrice'] = cbd_parking['Prob'] * cbd_parking['ThresholdPrice'] + cbd_parking_prices = cbd_parking.set_index(["ZoneID",'rownum']).ThresholdPrice.unstack() + cbd_parking_price_prob = cbd_parking.set_index(["ZoneID",'rownum']).Prob.unstack() + + for zone_to, zone_source in filenames.cfg.parking_costs.cbd_nearby.items(): + cbd_parking_prices.loc[zone_to] = cbd_parking_prices.loc[zone_source] + cbd_parking_price_prob.loc[zone_to] = cbd_parking_price_prob.loc[zone_source] + + cbd_parking_prices.sort_index(inplace=True) + cbd_parking_price_prob.sort_index(inplace=True) + + CBD_PARKING_ZONES = dict(zip(cbd_parking_prices.index, np.arange(len(cbd_parking_prices.index)))) + + cbd_parking2 = pd.read_csv( + filenames.HW_CBDPARK2, + header=None, + names=[ + 'IncomeCeiling', + 'FreeParkingPct', + 'TransitPct', + 'AutoOcc1Pct', + 'AutoOcc2Pct', + 'AutoOcc3Pct', + 'AutoOcc4Pct', + ], + ) + + parking = Dict() + parking.cbd_parking = cbd_parking + parking.cbd_parking_prices = cbd_parking_prices + parking.cbd_parking_price_prob = cbd_parking_price_prob + parking.cbd_parking2 = cbd_parking2 + parking.CBD_PARKING_ZONES = CBD_PARKING_ZONES + return parking diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/shp_handler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/shp_handler.py new file mode 100644 index 0000000..7ede3c6 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/shp_handler.py @@ -0,0 +1,11 @@ + +import geopandas as gpd + + +def load_zone_shapes(filenames): + zone_shp = gpd.read_file( + filenames.zone_shapefile + ).set_index('zone17') + return zone_shp + + diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/skims_handler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/skims_handler.py new file mode 100644 index 0000000..d4bba73 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/skims_handler.py @@ -0,0 +1,226 @@ +import numpy as np +import logging +log = logging.getLogger('CMAP') + + +""" +# Mode Choice Model Impedances + +## Highway Costs + +### Times and distances + +Skims: +HBW trips + Times – mf44 (SOV AM peak), mf76 (HOV AM peak) + Distances - mf45 (SOV AM peak), mf77 (HOV AM peak) + +HBO/NHB trips +Times – mf46 (SOV midday) +Distances - mf47 (SOV midday) + +### Parking Costs + +HBW trips to the Central Area – Monte Carlo simulation using +costs from MCHW_CBDPARK.TXT + +All other trips – zonal Park and Ride cost from MCxx_M01.TXT + +Hours of parking: HBW=10, HBO=6, NHB=3 + +### Auto Operating Costs + +Supplied by MCxx_M023.TXT in 5 MPH increments + +## Transit Costs + +Times and fares Skims: +HBW trips +In-vehicle time – mf822 (AM peak) +Out of vehicle time – mf823 (AM peak) [walk transfer but not access/egress] +Headway – mf838 (AM peak) +Fare – mf828 (AM peak) + +HBO/NHB trips +In-vehicle time – mf922 (midday) +Out of vehicle time – mf923 (midday) [walk transfer but not access/egress] +Headway – mf938 (midday) +Fare – mf928 (midday) + +Access/egress are simulated for each traveler. + First mode and last mode are obtained from transit skims + (mf829|mf929 and mf831|mf931) – these are used to determine + which of the 5 access/egress modes (walk, bus, feeder bus, P&R, K&R) + are simulated. That information is used to pull the appropriate data + from MCxx_DISTR: average zonal distance and standard deviation of + the modes to simulate actual distance. + +""" + +from ..addict import Dict +import larch +import os +from os.path import join as pj +from ..skims import read_skims + + +class DictSkims(Dict): + # defines special pickling + def __getstate__(self): + return self.get('filename', None) + def __setstate__(self, state): + self.update(_load_skims(state)) + def __reduce__(self): + return ( + type(self), + (), + self.__getstate__(), + ) + + +def load_skims(filenames, dh=None, backfill_uncompressed_skims=False): + from ..util import search_path + return _load_skims( + search_path(filenames.emmemat), + dh=dh, + backfill_uncompressed_skims=backfill_uncompressed_skims, + ) + + +def _load_skims( + filename_emmemat, + dh=None, + backfill_uncompressed_skims=False, + use_compressed_skims=None, +): + try: + if use_compressed_skims is None: + if dh is None: + use_compressed_skims = False + else: + use_compressed_skims = dh.cfg.get("use_compressed_skims", False) + + skims = DictSkims() + log.debug(f"filename emmemat = {filename_emmemat}") + skims.filename = filename_emmemat + skims.raw = read_skims( + filename_emmemat, + backfill_uncompressed_skims=backfill_uncompressed_skims, + use_compressed_skims=use_compressed_skims, + ) + + skims.raw['mf45'] = skims.raw['mf45'].load() + skims.raw['mf47'] = skims.raw['mf47'].load() + + skims.auto.col_mapping = dict( + am_time='mf44', + am_dist='mf45', + am_toll_loinc='mf111', + am_toll_hiinc='mf114', + md_time='mf46', + md_dist='mf47', + md_toll='mf117', + am_time_hov='mf76', + am_dist_hov='mf77', + am_toll_hov_loinc='mf112', + am_toll_hov_hiinc='mf115', + am_opcost='am_opcost', + am_opcost_hov='am_opcost_hov', + md_opcost='md_opcost', + ) + + skims.transit_pk.col_mapping = Dict( + ivtt= 'mf822', + ovtt= 'mf823', + headway= 'mf838', + fare= 'mf828', + firstmode= 'mf829', + prioritymode='mf830', + lastmode= 'mf831', + ) + + skims.transit_op.col_mapping = Dict( + ivtt= 'mf922', + ovtt= 'mf923', + headway= 'mf938', + fare= 'mf928', + firstmode= 'mf929', + prioritymode='mf930', + lastmode= 'mf931', + ) + + if dh is not None: + skims = _load_skims_step_2(skims, dh) + return skims + except: + log.exception("exception in _load_skims") + raise + +def _load_skims_step_2(skims, dh): + """ + Some post-processing when `dh` is available + + Parameters + ---------- + skims + dh + + Returns + ------- + skimss + """ + try: + try: + skims.raw['mf829'] + except KeyError: + if dh is None: + raise ValueError("no data_handler defined, and transit skim convolution is needed") + from ..transit_skim_convolution import skim_convol + dh['skims'] = skims + skim_convol(dh, peak=True) + + try: + skims.raw['mf929'] + except KeyError: + if dh is None: + raise ValueError("no data_handler defined, and transit skim convolution is needed") + from ..transit_skim_convolution import skim_convol + dh['skims'] = skims + skim_convol(dh, peak=False) + + # skims.first_mode_peak = skims.transit_pk.raw[pick_in(skims.transit_pk.raw, 'mf829_$', 'mf829')][:].astype(np.int8)+1 + # skims.priority_mode_peak = skims.transit_pk.raw[pick_in(skims.transit_pk.raw, 'mf830_$', 'mf830')][:].astype(np.int8)+1 + # skims.last_mode_peak = skims.transit_pk.raw[pick_in(skims.transit_pk.raw, 'mf831_$', 'mf831')][:].astype(np.int8)+1 + # skims.first_mode_offpeak = skims.transit_op.raw[pick_in(skims.transit_op.raw, 'mf929_$', 'mf929')][:].astype(np.int8)+1 + # skims.priority_mode_offpeak = skims.transit_op.raw[pick_in(skims.transit_op.raw, 'mf930_$', 'mf930')][:].astype(np.int8)+1 + # skims.last_mode_offpeak = skims.transit_op.raw[pick_in(skims.transit_op.raw, 'mf931_$', 'mf931')][:].astype(np.int8)+1 + skims.first_mode_peak = skims.raw['mf829'].load().values.astype(np.int8)+1 + skims.priority_mode_peak = skims.raw['mf830'].load().values.astype(np.int8)+1 + skims.last_mode_peak = skims.raw['mf831'].load().values.astype(np.int8)+1 + + skims.first_mode_offpeak = skims.raw['mf929'].load().values.astype(np.int8)+1 + skims.priority_mode_offpeak = skims.raw['mf930'].load().values.astype(np.int8)+1 + skims.last_mode_offpeak = skims.raw['mf931'].load().values.astype(np.int8)+1 + + def to_speed_bucket(_d, _t): + return np.where( + skims.raw[skims.auto.col_mapping[_t]].load(), + np.round(np.ceil( + skims.raw[skims.auto.col_mapping[_d]].load() / + skims.raw[skims.auto.col_mapping[_t]].load() * 60. / 5. + )), + 0 + ).astype(np.uint8) + def to_opcost(_d, _t): + return ( + dh.m023.AUTO_OPERATING_COST_BY_SPEED[to_speed_bucket(_d, _t)] / 100. + * skims.raw[skims.auto.col_mapping[_d]].load() + ) + skims.raw['am_opcost'] = to_opcost('am_dist', 'am_time') + skims.raw['am_opcost_hov'] = to_opcost('am_dist_hov', 'am_time_hov') + skims.raw['md_opcost'] = to_opcost('md_dist', 'md_time') + + return skims + except: + log.exception("exception in _load_skims") + raise diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/tabler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/tabler.py new file mode 100644 index 0000000..b3daa55 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/tabler.py @@ -0,0 +1 @@ +from sharrow import Table \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/tg_handler.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/tg_handler.py new file mode 100644 index 0000000..5fc2d18 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/tg_handler.py @@ -0,0 +1,129 @@ +import os.path +import numpy as np +import pandas as pd +import gzip +from ..addict import Dict +from ..util import search_path +import logging + + + +def load_hh_enum(filenames): + + hhv = pd.read_csv( + filenames.hh_enum, + header=None, + names=["subzone", 'zone', 'hhvtype'] + ) + tabulation = ( + hhv + .groupby(["zone","hhvtype"]) + .size() + .unstack() + .reindex(pd.RangeIndex(1, 3633, name='TAZ')) + .reindex(pd.RangeIndex(1, 625, name='hhvtype'), axis=1) + .fillna(0) + ) + return hhv, tabulation + + + +def load_tg(filenames, with_detail=False): + + + pa_trip_types = pd.read_csv( + os.path.join(os.path.dirname(__file__), "pa_trip_types.csv"), + index_col=0, + ) + purpose_categories = pa_trip_types.purpose_category + + trip49_filenames = {} + trip49_filenames['typical'] = search_path( + filenames.cache_dir / "TRIP49_PA_OUT.TXT.gz", + filenames.cache_dir / "TRIP49_PA_OUT.TXT", + filenames.emme_database_dir / "TRIP49_PA_OUT.TXT.gz", + filenames.emme_database_dir / "TRIP49_PA_OUT.TXT", + filenames.emme_database_dir / "defaults_base_year/TRIP49_PA_OUT.TXT.gz", + filenames.emme_database_dir / "defaults_base_year/TRIP49_PA_OUT.TXT", + ) + # secondary WFH trip generation + trip49_filenames['wfh'] = search_path( + filenames.cache_dir / "TRIP49_PA_WFH_OUT.TXT.gz", + filenames.cache_dir / "TRIP49_PA_WFH_OUT.TXT", + filenames.emme_database_dir / "TRIP49_PA_WFH_OUT.TXT.gz", + filenames.emme_database_dir / "TRIP49_PA_WFH_OUT.TXT", + filenames.emme_database_dir / "defaults_base_year/TRIP49_PA_WFH_OUT.TXT.gz", + filenames.emme_database_dir / "defaults_base_year/TRIP49_PA_WFH_OUT.TXT", + ) + + log = logging.getLogger('CMAP') + result = {} + for tripclass, trip49_filename in trip49_filenames.items(): + + log.info(f"reading {tripclass} trip generation from: {trip49_filename}") + + if os.path.splitext(trip49_filename)[1] == '.gz': + f = gzip.open(trip49_filename, 'rb') + else: + f = open(trip49_filename, 'rb') + try: + trip49 = pd.read_fwf( + f, + widths=[6, 6, 2, 9, 9], + names=['subzone', 'zone', 'trip_type', 'productions', 'attractions'], + ) + finally: + f.close() + + trip49["purpose_category"] = trip49["trip_type"].map(purpose_categories) + + # Certain trip types are NHB but generated as P-A, convert them to O-D + nhb_pa = (pa_trip_types['purpose_category'].isin(['NHB', 'NHBR', 'NHBS'])) & (pa_trip_types['pair_type'] == 'PA') + trip49["mix_PA"] = trip49["trip_type"].map(nhb_pa) + mixed_PA = (trip49['productions'] + trip49['attractions']) / 2 + trip49.loc[trip49["mix_PA"], 'productions'] = mixed_PA.loc[trip49["mix_PA"]] + trip49.loc[trip49["mix_PA"], 'attractions'] = mixed_PA.loc[trip49["mix_PA"]] + + trip49z = trip49.groupby(["zone", "purpose_category"])[['productions', 'attractions']].sum() + prodns = trip49z['productions'].unstack().fillna(0.0) + attrns = trip49z['attractions'].unstack().fillna(0.0) + + if with_detail: + trip49z_detail = trip49.groupby(["zone", "trip_type"])[['productions', 'attractions']].sum() + prodns_detail = trip49z_detail['productions'].unstack().fillna(0.0) + attrns_detail = trip49z_detail['attractions'].unstack().fillna(0.0) + + for xns in (prodns, attrns): + # There are high and low income work purposes. We push all the non-income bound + # home-based mandatory purposes into income-related groups based on the relative + # share in the income-bound values + income_generic_mandatory = xns["HBW"] + lo_income_share_mandatory = (xns["HBWL"] / (xns["HBWL"] + xns["HBWH"])).where((xns["HBWL"] + xns["HBWH"])>0, 0) + hi_income_share_mandatory = 1 - lo_income_share_mandatory + xns["HBWL"] += income_generic_mandatory * lo_income_share_mandatory + xns["HBWH"] += income_generic_mandatory * hi_income_share_mandatory + xns.drop(columns=['HBW', 'EXCLUDE'], inplace=True) + + pd.concat([prodns.stack().rename("productions"), attrns.stack().rename("attractions")], axis=1).to_csv( + filenames.cache_dir / "trips_PA_by_purpose.csv" + ) + + tg = Dict() + tg.trip_attractions8 = attrns.copy() + tg.trip_productions8 = prodns.copy() + tg.zone_productions8 = prodns.round().astype(int).copy() + + for xns in (prodns, attrns): + xns['HBO'] = xns['HBO'] + xns['HBOR'] + xns['NHB'] = xns['NHB'] + xns['NHBR'] + xns['NHBS'] + xns.drop(columns=['HBOR', 'NHBR', 'NHBS'], inplace=True) + + tg.trip_attractions5 = attrns + tg.trip_productions5 = prodns + tg.zone_productions5 = prodns.round().astype(int) + if with_detail: + tg.trip_attractions_detail = attrns_detail + tg.trip_productions_detail = prodns_detail + result[tripclass] = tg + + return result diff --git a/src/Mode-Dest-TOD/cmap_modedest/data_handlers/visitors.py b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/visitors.py new file mode 100644 index 0000000..0c0612b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/data_handlers/visitors.py @@ -0,0 +1,39 @@ +import numpy as np +import pandas as pd +import logging +from ..util import search_path + + +def load_visitor_trips(filenames, scale_factor=1.0): + """ + Generate visitor trips. + + The raw visitor table includes fractional trips. + This function converts to integer trips by making + random draws from the trip table. + + Parameters + ---------- + filenames : Filenames + scale_factor : float, default 1.0 + + Returns + ------- + trips : pd.DataFrame + A square trip table with integer O-D trips by visitors + """ + filename = search_path( + filenames.cache_dir / "CMAP_TripTable_VisitorsWeekday.csv.gz", + filenames.emme_database_dir / "CMAP_TripTable_VisitorsWeekday.csv.gz", + filenames.emme_database_dir / "defaults_base_year/CMAP_TripTable_VisitorsWeekday.csv.gz", + ) + logging.getLogger('CMAP').info(f"reading visitor trip table from: {filename}") + trips = pd.read_csv(filename) + n = trips['trips'].sum() + trip_wt = trips['trips'] / n + n_trips = int(np.round(n * scale_factor)) + visit_trips = np.random.default_rng(42).choice(len(trips), n_trips, p=trip_wt) + trips.drop(columns=['trips'], inplace=True) + trips['visitor_trips'] = pd.Series(visit_trips).value_counts() + trips.fillna(0, inplace=True) + return trips.pivot("start_taz", "end_taz", "visitor_trips").fillna(0).astype(int) diff --git a/src/Mode-Dest-TOD/cmap_modedest/deadheading.py b/src/Mode-Dest-TOD/cmap_modedest/deadheading.py new file mode 100644 index 0000000..8ac89c9 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/deadheading.py @@ -0,0 +1,144 @@ +import numpy as np +import pandas as pd +import warnings +from .time_of_day_model import time_period_names, time_period_codes + +import logging +log = logging.getLogger('CMAP') + +def compute_deadhead_trip_table( + dh, + trips, + intrazonal_factor=0.5, + traveltime_factor=-1.0, + stats=False, +): + """ + Compute a trip table of deadhead trips taken by taxis and TNCs. + + Parameters + ---------- + dh : DataHandler + trips : dask.DataFrame + The assembled primary trips (not including hired car deadheading) + as a dask DataFrame. + intrazonal_factor : float + The pseudo-value of travel time for intrazonal trips, which include + implied travel time as well as a constant adjustment. + traveltime_factor : float, default -1.0 + A parameter to calibrate the overall length of deadhead trips, used as + the coefficient in a gravity model. + stats : bool + Display length distribution of deadhead trips, when in a Jupyter + notebook. + + Returns + ------- + DataFrame + """ + result = {} + random_generator = np.random.default_rng([12345,67890]) + + for tname, tcode in zip(time_period_names, time_period_codes): + log.info(f"compute_deadhead_trip_table: {tname}") + + # We try this twice, as there is a rare sync problem in numexpr that + # makes this fail. + try: + trips_by_od = ( + trips + .query("mode in (4,5,6)") + .query(f"timeperiod in ('{tname}',)") + .groupby(["o_zone", "d_zone"])['trips'] + .sum() + .compute() + .unstack(0) + .fillna(0) + ).reindex( + index=dh.skims.raw[f'mf46{tcode}'].indexes['otaz'], + columns=dh.skims.raw[f'mf46{tcode}'].indexes['dtaz'], + ).fillna(0) + except KeyError: + import numexpr.necompiler + numexpr.necompiler._numexpr_cache.clear() + trips_by_od = ( + trips + .query("mode in (4,5,6)") + .query(f"timeperiod in ('{tname}',)") + .groupby(["o_zone", "d_zone"])['trips'] + .sum() + .compute() + .unstack(0) + .fillna(0) + ).reindex( + index=dh.skims.raw[f'mf46{tcode}'].indexes['otaz'], + columns=dh.skims.raw[f'mf46{tcode}'].indexes['dtaz'], + ).fillna(0) + + deadhead_dests = trips_by_od.sum() # hired car trip origins + deadhead_origs = trips_by_od.sum(1) # hired car trip destinations + + auto_travel_time = dh.skims.raw[f'mf46{tcode}'].values + intrazonal_value = np.eye(auto_travel_time.shape[0]) * intrazonal_factor + wgt_matrix = np.exp(traveltime_factor*(auto_travel_time + intrazonal_value)) + + # Fratar the deadhead weights to the deadhead productions and attractions + for iter in range(10): + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=RuntimeWarning) + w = np.nan_to_num(wgt_matrix / wgt_matrix.sum(0)) * np.expand_dims(deadhead_dests, 0) + wgt_matrix = np.nan_to_num(w / np.expand_dims(w.sum(1), 1)) * np.expand_dims(deadhead_origs, 1) + + chx = {} + + triptable = np.zeros(wgt_matrix.shape, dtype=np.int32) + + for row in range(wgt_matrix.shape[0]): + rowsum = wgt_matrix[row].sum() + n = int(np.round(rowsum)) + if n: + chx[row] = random_generator.choice(wgt_matrix.shape[1], size=n, p=wgt_matrix[row] / rowsum) + for k in chx[row]: + triptable[row, k] += 1 + + triptable = pd.DataFrame( + triptable, + index=dh.skims.raw[f'mf46{tcode}'].indexes['otaz'], + columns=dh.skims.raw[f'mf46{tcode}'].indexes['dtaz'], + ).fillna(0) + triptable.index.name = 'o_zone' + triptable.columns.name = 'd_zone' + triptable = triptable.stack().fillna(0).reset_index() + + triptable['timeperiod'] = tname + triptable['mode'] = 1 + triptable['purpose'] = 'DEAD' + triptable['a_zone'] = triptable['d_zone'] + + triptable = triptable.set_index([ + 'purpose', 'mode', 'o_zone', 'd_zone', 'a_zone', 'timeperiod' + ]) + + result[tname] = triptable.loc[triptable.iloc[:,0] > 0].copy() + result[tname].columns = ['trips'] + + if stats: + import matplotlib.pyplot as plt + from xmle import Show + from IPython.display import display + + tt = dh.skims.raw[[f'mf46{tcode}']].at_df( + result[tname] + .reset_index()[['o_zone', 'd_zone']] + .rename(columns=dict(o_zone='otaz', d_zone='dtaz')) + ) + rr = result[tname].copy() + rr['time'] = tt[f'mf46{tcode}'].values + fig, ax = plt.subplots() + ax.hist(rr['time'], weights=rr['trips']) + ax.set_title(tname) + ax.set_xlabel("minutes") + display(Show(fig)) + plt.close() + + return pd.concat([r for r in result.values()]) diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/__init__.py new file mode 100644 index 0000000..c523523 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/__init__.py @@ -0,0 +1,12 @@ +import larch +from larch import P,X,PX +import os +import pandas as pd +import numpy as np +import cmap_modedest +from ..addict import Dict +from pathlib import Path + +from ..util import resource_usage, start_memory_tracing, ping_memory_tracing + + diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_choice.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_choice.py new file mode 100644 index 0000000..f36f588 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_choice.py @@ -0,0 +1,863 @@ +import numpy as np +import pandas as pd +import os +from ..addict import Dict +import larch as larch +from larch import P,X +from larch.util.figures import distribution_figure, share_figure +from larch.util.data_expansion import piecewise_linear +from IPython.display import display, HTML + +import logging +log = logging.getLogger('CMAP') + +def L(*args): + if len(args)==1 and isinstance(args[0], str) and args[0][0]=="#": + log.info(args[0]) + else: + s = "\n".join(str(i) for i in args) + s = "\n"+s + log.info(s.replace("\n","\n ")) + + +from ..transit_approach import transit_approach +from .est_data import dh +from ..choice_model import model_builder + +from .est_config import mode_modeled, n_sampled_dests +from .est_survey import trips +from .est_sample_dest import sample_dest_zones_and_data +from ..util import resource_usage +from ..modecodes import mode9names + + +L( + "###### data statistics ######", + trips['tripPurpose'].value_counts(), + trips.mode3.value_counts() +) + +L("###### sample_dest_zones_and_data ######") + +# Null out invalid data # now in survey_data +# transit_cols = ['ivtt','ovtt','headway','fare','firstmode','lastmode'] +# for a in transit_cols: +# to_nan = trips[f'transit_{a}'] > 999 +# trips.loc[to_nan,f'transit_{a}'] = np.nan + + +L("## ae_approach_los ##") +from .est_survey import ae_approach_los + +trip_approach_distances, ae_los = ae_approach_los(trips) + +L("## sample_dest_zones_and_data ##") +TRIP_ALTS_CACHE_FILE = f"trip_alts_n{n_sampled_dests}_vx14" + +trip_alt_df = dh.filenames.load(TRIP_ALTS_CACHE_FILE) +if trip_alt_df is None: + trip_alt_df = sample_dest_zones_and_data( + trips, + n_zones=dh.n_internal_zones, + n_sampled_dests=n_sampled_dests, + keep_trips_cols=[ + 'd_zone', + 'mode5', + 'mode5code', + 'mode7', + 'mode7code', + 'mode9', + 'mode9code', + 'incomeLevel', + 'tripCat', + 'tripPurpose', + 'auto_dist', + 'auto_time', + 'auto_parking_cost', + 'transit_fare', + 'transit_ivtt', + 'transit_ovtt', + 'transit_headway', + 'transit_approach_cost', + 'transit_approach_drivetime', + 'transit_approach_walktime', + 'transit_approach_waittime', + 'taxi_wait_time', + 'taxi_fare', + 'tnc_solo_wait_time', + 'tnc_pool_wait_time', + 'tnc_solo_fare', + 'tnc_pool_fare', + 'hhinc_dollars', + 'timeperiod', + 'mode_and_time', + 'actualdest', + 'ozone_areatype', + 'ozone_autopropensity', + 'autopropensity', + 'areatype', + 'hhveh', + 'hhsize', + 'hhadults', + 'paFlip', + 'auto_time_hov', + 'auto_toll', + 'auto_toll_hiinc', + 'auto_toll_loinc', + 'auto_toll_hov_loinc', + 'auto_toll_hov_hiinc', + 'auto_opcost', + 'auto_opcost_hov', + ] + ) + + # + # display(HTML(f"

auto_dist statistics

")) + # display(trip_alt_df['auto_dist'].statistics()) + # + # display(HTML(f"

altdest0001_auto_dist statistics

")) + # display(trip_alt_df['altdest0001_auto_dist'].statistics()) + # + + + L("## invalid_walktime ##") + for peaky in ['PEAK', 'OFFPEAK']: + invalid_walktime = trip_alt_df[f'actualdest_transit_approach_walktime_{peaky}'] > 180 + trip_alt_df.loc[invalid_walktime, f'actualdest_transit_approach_walktime_{peaky}'] = np.nan + + L("## invalid_drivetime ##") + for peaky in ['PEAK', 'OFFPEAK']: + invalid_drivetime = trip_alt_df[f'actualdest_transit_approach_drivetime_{peaky}'] > 180 + trip_alt_df.loc[invalid_drivetime, f'actualdest_transit_approach_drivetime_{peaky}'] = np.nan + + for i in range(n_sampled_dests): + for peaky in ['PEAK', 'OFFPEAK']: + L(f"# approach simulate for altdest{i + 1:04d} {peaky} ") + # q = (trips.tripPurpose == purpose) + # _trips_by_purpose = trip_alt_df[q] + result_purpose = transit_approach( + dh, + trip_alt_df.o_zone, + trip_alt_df[f'altdest{i + 1:04d}'], + 'HW' if peaky=='PEAK' else 'HO', + replication=1, + approach_distances=None, + trace=False, + random_state=123 + i, + ) + for key in ['drivetime', 'walktime', 'cost', 'waittime']: + v = result_purpose[key][:, 0].astype(float) + if key in ['drivetime', 'walktime', 'waittime']: + v[v > 180] = np.nan + trip_alt_df.loc[:, f'altdest{i + 1:04d}_transit_approach_{key}_{peaky}'] = v + + dh.filenames.save(TRIP_ALTS_CACHE_FILE, trip_alt_df) + +from ..choice_model import alt_codes_and_names + +alt_codes, alt_names = alt_codes_and_names( + n_sampled_dests=n_sampled_dests, + include_actual_dest=True, +) + + +dats = Dict() +mods = Dict() +mods_preload = Dict() + +from ..purposes import purposes5, purposes_to_peaky +purposes = purposes5 + + +altdest_tags = lambda suffix: [ + f'altdest{i + 1:04d}_{suffix}' + for i in range(n_sampled_dests) +] + +altdest_tags_div = lambda suffix1, suffix2: [ + f'altdest{i + 1:04d}_{suffix1}/altdest{i + 1:04d}_{suffix2}' + for i in range(n_sampled_dests) +] + + +# `ca_folds` defines how ca_folded (see below) is built +ca_folds = { + "nAttractions_HBWH": ['actualdest_log_attractions_HBWH'] + altdest_tags("log_attractions_HBWH"), + "nAttractions_HBWL": ['actualdest_log_attractions_HBWL'] + altdest_tags("log_attractions_HBWL"), + "nAttractions_HBS": ['actualdest_log_attractions_HBS'] + altdest_tags("log_attractions_HBS"), + "nAttractions_HBO": ['actualdest_log_attractions_HBO'] + altdest_tags("log_attractions_HBO"), + "nAttractions_NHB": ['actualdest_log_attractions_NHB'] + altdest_tags("log_attractions_NHB"), + "auto_dist_OFFPEAK": ['actualdest_auto_dist_OFFPEAK'] + altdest_tags("auto_dist_OFFPEAK"), + "auto_dist_PEAK": ['actualdest_auto_dist_PEAK'] + altdest_tags("auto_dist_PEAK"), + "auto_time_OFFPEAK": ['actualdest_auto_time_OFFPEAK'] + altdest_tags("auto_time_OFFPEAK"), + "auto_time_PEAK": ['actualdest_auto_time_PEAK'] + altdest_tags("auto_time_PEAK"), + "transit_ivtt_PEAK": ['actualdest_transit_ivtt_PEAK'] + altdest_tags("transit_ivtt_PEAK"), + "transit_ivtt_OFFPEAK": ['actualdest_transit_ivtt_OFFPEAK'] + altdest_tags("transit_ivtt_OFFPEAK"), + "transit_ovtt_OFFPEAK": ['actualdest_transit_ovtt_OFFPEAK'] + altdest_tags("transit_ovtt_OFFPEAK"), + "transit_approach_waittime_OFFPEAK": ['actualdest_transit_approach_waittime_OFFPEAK'] + altdest_tags("transit_approach_waittime_OFFPEAK"), + "transit_approach_walktime_OFFPEAK": ['actualdest_transit_approach_walktime_OFFPEAK'] + altdest_tags("transit_approach_walktime_OFFPEAK"), +} + +# TODO check data on transit_approach_waittime_OFFPEAK + +# `ca_folded` will contain, by purpose, destination-specific data for later analysis +ca_folded = Dict() + +cached_model_filename = lambda purpose: dh.filenames.cache_dir / f"choicemodel_{purpose}_hc.xlsx" +cached_model_filereport = lambda purpose: dh.filenames.cache_dir / f"choicemodel_{purpose}_hc_report.xlsx" + +for purpose in purposes: + + # define filter for this trip purpose + q = (trip_alt_df['tripCat'] == purpose) + + # assemble quantitative (size) factors + # We use the attractions defined in the model's Trip Generation step. + log.debug(f"size_of_altdests for {purpose}") + size_of_altdests = [ + np.log(np.fmax( + dh.trip_attractions5.loc[ + trip_alt_df[q][f"altdest{i + 1:04d}"], + purpose, + ].reset_index( + drop=True + ), + 1e-300, # nonzero but tiny + )).rename( + f'altdest{i + 1:04d}_log_attractions_{purpose}' + ) + for i in range(n_sampled_dests) + ] + + log.debug(f"actualdest_log_attractions for {purpose}") + _df = pd.concat( + [ + trip_alt_df[q].reset_index(), + np.log(np.fmax( + dh.trip_attractions5.loc[ + trips[q].d_zone, + purpose, + ].reset_index( + drop=True + ), + 1e-300, # nonzero but tiny + )).rename( + f'actualdest_log_attractions_{purpose}' + ), + ] + size_of_altdests, + axis=1, + ) + + peaky = 'PEAK' if 'W' in purpose else 'OFFPEAK' + + positive_attractions = (_df[f'actualdest_log_attractions_{purpose}'] > -666) + _df[f'actualdest_transit_avail_{purpose}'] = ( + (_df[f'actualdest_transit_ivtt_{peaky}'] < 999) + & (_df[f'actualdest_transit_approach_walktime_{peaky}'] < 999) + & (_df[f'actualdest_transit_approach_drivetime_{peaky}'] < 999) + & positive_attractions + ) + _df[f'actualdest_auto_avail_{purpose}'] = positive_attractions + _df[f'actualdest_walk_avail_{purpose}'] = positive_attractions & (_df[f'actualdest_auto_dist_OFFPEAK'] < 3) + _df[f'actualdest_bike_avail_{purpose}'] = positive_attractions & (_df[f'actualdest_auto_dist_OFFPEAK'] < 12) + for i in range(n_sampled_dests): + positive_attractions = (_df[f'altdest{i + 1:04d}_log_attractions_{purpose}'] > -666) + _df[f'altdest{i + 1:04d}_transit_avail_{purpose}'] = ( + ( _df[f'altdest{i + 1:04d}_transit_ivtt_{peaky}'] < 999) + & (_df[f'altdest{i + 1:04d}_transit_ovtt_{peaky}'] < 999) + & (_df[f'altdest{i + 1:04d}_transit_approach_walktime_{peaky}'] < 999) + & (_df[f'altdest{i + 1:04d}_transit_approach_drivetime_{peaky}'] < 999) + & positive_attractions + ) + _df[f'altdest{i + 1:04d}_auto_avail_{purpose}'] = positive_attractions + _df[f'altdest{i + 1:04d}_walk_avail_{purpose}'] = positive_attractions & (_df[f'altdest{i + 1:04d}_auto_dist_OFFPEAK'] < 3) + _df[f'altdest{i + 1:04d}_bike_avail_{purpose}'] = positive_attractions & (_df[f'altdest{i + 1:04d}_auto_dist_OFFPEAK'] < 12) + # Build IDCA folded data for later analysis + _ca_folded = {} + for k, v in ca_folds.items(): + if 'nAttractions' in k: + if purpose not in k: + continue + folder = np.exp(_df[v]) + else: + folder = _df[v] + folder.columns = range(len(v)) + _ca_folded[k] = folder.stack().rename(k) + ca_folded[purpose] = pd.DataFrame(_ca_folded) + + ca_folded[purpose]['walktime_dist'] = ( + ca_folded[purpose]['transit_approach_walktime_OFFPEAK'] + / ca_folded[purpose]['auto_dist_OFFPEAK'] + ) + + # Model's actual data + dfs = dats[purpose] = larch.DataFrames( + co=_df, + alt_codes=alt_codes, + alt_names=alt_names, + ch='mode9code', + # av=pd.DataFrame({ + # k: _df.eval(v) + # for k, v in av.items() + # }).astype(np.int8), + ) + + cached_model_file = cached_model_filename(purpose) + if 0 and os.path.exists(cached_model_file) and purpose != "NHB": + m = mods[purpose] = larch.Model.load( + cached_model_file + ) + mods_preload[purpose] = True + else: + m = mods[purpose] = model_builder( + purpose, + include_actual_dest=True, + n_sampled_dests=n_sampled_dests, + parameter_values=None, + constraints=True, + ) + mods_preload[purpose] = False + m.dataservice = dfs + m.load_data() + m.diagnosis = m.doctor(repair_ch_av="-") + + + + +L("## model parameter estimation ##") + +Pr = Dict() + +nests_per_dest = 3 # CHANGE ME if/when the number of nests per destination is altered in `model_builder` + + + +figures = Dict() + +def dest_profiler( + purpose, +): + n_modes = len(mode9names) + _offset = (n_sampled_dests + 1) * n_modes + nests_per_dest-1 + _ch = mods[purpose].dataframes.data_ch_cascade(mods[purpose].graph)\ + .iloc[:, _offset:-1:nests_per_dest].stack().values + _av = mods[purpose].dataframes.data_av_cascade(mods[purpose].graph)\ + .iloc[:, _offset:-1:nests_per_dest].stack().values + + if purposes_to_peaky[purpose]: + + figdef = Dict() + figdef[f'auto_dist_PEAK'].bins = 50 + figdef[f'auto_dist_PEAK'].range = (0, 50) + # figdef[f'auto_dist_{peaky}'].xscale = {'value':'symlog', 'linthresh':2, 'linscale':0.3} + # figdef[f'auto_dist_{peaky}'].xmajorticks = [0, 1, 2, 5, 10, 20, 50] + # figdef[f'auto_dist_{peaky}'].xminorticks = np.concatenate([ + # np.arange(0, 10), + # np.arange(10, 20, 2), + # np.arange(20, 50, 3), + # ]) + + figdef[f'auto_time_PEAK'].bins = 90 + figdef[f'auto_time_PEAK'].range = (0, 90) + # figdef[f'auto_time_{peaky}'].xscale = {'value':'symlog', 'linthresh':2, 'linscale':0.3} + # figdef[f'auto_time_{peaky}'].xmajorticks = [0, 1, 2, 5, 10, 20, 50] + # figdef[f'auto_time_{peaky}'].xminorticks = np.concatenate([ + # np.arange(0, 10), + # np.arange(10, 20, 2), + # np.arange(20, 50, 3), + # np.arange(50, 90, 5), + # ]) + else: + figdef = Dict() + figdef[f'auto_dist_OFFPEAK'].bins = 50 + figdef[f'auto_dist_OFFPEAK'].range = (0, 50) + figdef[f'auto_time_OFFPEAK'].bins = 60 + figdef[f'auto_time_OFFPEAK'].range = (0, 60) + + for x in figdef: + tag = x.replace("_OFFPEAK","").replace("_PEAK","") + figures.distribution[purpose][tag] = distribution_figure( + ca_folded[purpose][x], + probability=Pr.ByDest[purpose].stack().values, + choices=_ch, + availability=_av, + xlabel=None, + ylabel='Relative Frequency', + style='hist', + bins=figdef[x].bins, + pct_bins=20, + range=figdef[x].range, + prob_label="Modeled", + obs_label="Observed", + bw_method=None, + discrete=None, + ax=None, + format='png', + #header=f"{purpose} / {x} Distribution", + accumulator=True, + xscale=figdef[x].xscale or None, + xmajorticks=figdef[x].xmajorticks or None, + xminorticks=figdef[x].xminorticks or None, + coincidence_ratio=True, + ) + display(HTML(f"

{mods[purpose].title} Destinations by {tag}

")) + display(figures.distribution[purpose][tag]) + + + + +def transit_profiler_X( + purpose, +): + n_modes = len(mode9names) + _offset = (n_sampled_dests + 1) * n_modes + nests_per_dest-1 + _ch = mods[purpose].dataframes.data_ch_cascade(mods[purpose].graph)\ + .iloc[:, :(n_sampled_dests + 1) * n_modes] + _ch.columns = pd.MultiIndex.from_product([ + np.arange(n_sampled_dests + 1), + mode9names, + ], names=['dest', 'mode']) + _ch = _ch.xs("TRANSIT", axis=1, level="mode").stack().values + + _av = mods[purpose].dataframes.data_av_cascade(mods[purpose].graph)\ + .iloc[:, :(n_sampled_dests + 1) * n_modes] + _av.columns = pd.MultiIndex.from_product([ + np.arange(n_sampled_dests + 1), + mode9names, + ], names=['dest', 'mode']) + _av = _av.xs("TRANSIT", axis=1, level="mode").stack().values + + if purposes_to_peaky[purpose]: + + figdef = Dict() + figdef[f'auto_dist_PEAK'].bins = 50 + figdef[f'auto_dist_PEAK'].range = (0, 50) + figdef[f'transit_ivtt_PEAK'].bins = int(120/5) + figdef[f'transit_ivtt_PEAK'].range = (0, 120) + else: + figdef = Dict() + figdef[f'auto_dist_OFFPEAK'].bins = 30 + figdef[f'auto_dist_OFFPEAK'].range = (0, 30) + figdef[f'transit_ivtt_OFFPEAK'].bins = int(120/5) + figdef[f'transit_ivtt_OFFPEAK'].range = (0, 120) + + for x in figdef: + tag = x.replace("_OFFPEAK","").replace("_PEAK","") + figures.transit_dist[purpose][tag] = distribution_figure( + ca_folded[purpose][x], + probability=Pr.ByMode[purpose].xs("TRANSIT", axis=1, level="mode").stack().values, + choices=_ch, + availability=_av, + xlabel=None, + ylabel='Relative Frequency', + style='hist', + bins=figdef[x].bins, + pct_bins=20, + range=figdef[x].range, + prob_label="Modeled", + obs_label="Observed", + bw_method=None, + discrete=None, + ax=None, + format='png', + #header=f"{purpose} / {x} Distribution", + accumulator=True, + xscale=figdef[x].xscale or None, + xmajorticks=figdef[x].xmajorticks or None, + xminorticks=figdef[x].xminorticks or None, + coincidence_ratio=True, + ) + display(HTML(f"

{mods[purpose].title} Transit Usage by {tag}

")) + display(figures.transit_dist[purpose][tag]) + + + + +def mode_usage_profiler( + purpose, + modename, + figdef, +): + n_modes = len(mode9names) + _offset = (n_sampled_dests + 1) * n_modes + nests_per_dest-1 + _ch = mods[purpose].dataframes.data_ch_cascade(mods[purpose].graph)\ + .iloc[:, :(n_sampled_dests + 1) * n_modes] + _ch.columns = pd.MultiIndex.from_product([ + np.arange(n_sampled_dests + 1), + mode9names, + ], names=['dest', 'mode']) + _ch = _ch.xs(modename, axis=1, level="mode").stack().values + + _av = mods[purpose].dataframes.data_av_cascade(mods[purpose].graph)\ + .iloc[:, :(n_sampled_dests + 1) * n_modes] + _av.columns = pd.MultiIndex.from_product([ + np.arange(n_sampled_dests + 1), + mode9names, + ], names=['dest', 'mode']) + _av = _av.xs(modename, axis=1, level="mode").stack().values + + for x in figdef: + tag = x.replace("_OFFPEAK","").replace("_PEAK","") + figures[f'{modename}_dist'][purpose][tag] = distribution_figure( + ca_folded[purpose][x], + probability=Pr.ByMode[purpose].xs(modename, axis=1, level="mode").stack().values, + choices=_ch, + availability=_av, + xlabel=None, + ylabel='Relative Frequency', + style='hist', + bins=figdef[x].bins, + pct_bins=20, + range=figdef[x].range, + prob_label="Modeled", + obs_label="Observed", + bw_method=None, + discrete=None, + ax=None, + format='png', + #header=f"{purpose} / {x} Distribution", + accumulator=True, + xscale=figdef[x].xscale or None, + xmajorticks=figdef[x].xmajorticks or None, + xminorticks=figdef[x].xminorticks or None, + coincidence_ratio=True, + ) + display(HTML(f"

{mods[purpose].title} {modename} Usage by {tag}

")) + display(figures[f'{modename}_dist'][purpose][tag]) + + +def walk_profiler(purpose): + figdef = Dict() + figdef[f'auto_dist_OFFPEAK'].bins = 20 + figdef[f'auto_dist_OFFPEAK'].range = (0, 5) + return mode_usage_profiler(purpose, "WALK", figdef) + +def transit_profiler(purpose): + figdef = Dict() + if purposes_to_peaky[purpose]: + figdef[f'auto_dist_PEAK'].bins = 50 + figdef[f'auto_dist_PEAK'].range = (0, 50) + figdef[f'transit_ivtt_PEAK'].bins = int(120/5) + figdef[f'transit_ivtt_PEAK'].range = (0, 120) + else: + figdef[f'auto_dist_OFFPEAK'].bins = 30 + figdef[f'auto_dist_OFFPEAK'].range = (0, 30) + figdef[f'transit_ivtt_OFFPEAK'].bins = int(120/5) + figdef[f'transit_ivtt_OFFPEAK'].range = (0, 120) + return mode_usage_profiler(purpose, "TRANSIT", figdef) + + + +def value_of_time_profiler(purpose): + m = mods[purpose] + time_params = [ + 'ivtt', + 'totaltime', + 'auto_time', + 'tnc_time', + 'transit_ivtt', + 'transit_ovtt', + 'ovtt', + 'walk_time', + 'bike_time', + 'walk_time[1]: up to 0.5', + 'walk_time[2]: 0.5 to 1.0', + 'walk_time[3]: over 1.0', + ] + result = {} + for t in time_params: + if t in m: + result[t] = ((P(t) * 60) / (P.cost)).set_fmt("${:.2f}/hr").string(m) + result = pd.DataFrame(pd.Series(result, name='Value of Time')) + figures.vot[purpose] = result + display(result) + +def mode_share_profiler( + purpose, +): + d_codes = np.arange(n_sampled_dests+1) + + _pr = Pr.ByMode[purpose].stack(0) + # _pr = _pr.stack([0,2]).sum(1).unstack() + + _ch = mods[purpose].dataframes.data_ch.copy() + _ch.columns=pd.MultiIndex.from_product([ + d_codes, + mode9names, + ]) + _ch = _ch.stack(0) + # _ch = _ch.stack([0,2]).sum(1).unstack() + + peaky = 'PEAK' if purposes_to_peaky[purpose] else 'OFFPEAK' + + figdef = Dict() + figdef[f'auto_dist_{peaky}'].bins = np.logspace(np.log10(1),np.log10(51),10)-1 + # np.concatenate([ + # np.arange(0, 10, 1), # first 1 mile bins to 10 miles + # np.arange(10, 20, 2), # then 2 mile bins to 20 miles + # np.arange(20, 51, 5), # then 5 mile bins to 50 miles + # ]) + + for x in figdef: + tag = x.replace("_OFFPEAK","").replace("_PEAK","") + figures.share[purpose][tag] = share_figure( + x=ca_folded[purpose][x], + probability=_pr.fillna(0), + choices=_ch, + style='stacked', + bins=figdef[x].bins, + format='png', + #header=f"{purpose} Mode Share by {x}" + xscale={'value':'symlog', 'linthresh':2, 'linscale':0.5}, + xmajorticks=[0, 1, 2, 5, 10, 20, 50], + xminorticks=np.concatenate([ + np.arange(0, 10), + np.arange(10, 20, 2), + np.arange(20, 50, 3), + ]), + ) + display(HTML(f"

{mods[purpose].title} Mode Shares by {tag}

")) + display(figures.share[purpose][tag]) + + + +def mode_choice_summary(m): + ch_av_summary = m.dataframes.choice_avail_summary().iloc[:-1] + for k in ['available', 'available weighted', 'available unweighted']: + try: + ch_av_summary[k] = ch_av_summary[k].astype(int) + except KeyError: + pass + pr_summary = m.probability(return_dataframe=True).sum() + ch_av_summary['model prob'] = pr_summary + ch_av_summary.index = pd.MultiIndex.from_product( + [ + np.arange(n_sampled_dests + 1), + mode9names, + ], + names=['dest', 'mode'], + ) + result = ch_av_summary.groupby('mode').sum() + display(HTML(f"

{m.title} Mode Choices Summary

")) + display(result) + return result + +def estimation(n_mu_dest_search_grids=5, n_mu_car_search_grids=5, purposes=None, force_reestimate=False): + + if purposes is None: + from ..purposes import purposes5 + purposes = purposes5 + + for purpose, m in mods.items(): + + if purposes is not None and purpose not in purposes: continue + + m.dataframes.autoscale_weights() + display(HTML(f"

{m.title}

")) + if not mods_preload[purpose] or force_reestimate: + holdfast_cache = m.pf.holdfast.copy() + minimums_cache = m.pf.minimum.copy() + maximums_cache = m.pf.maximum.copy() + # GRID SEARCH on MU + r = None + + n_search_grids = n_mu_dest_search_grids*n_mu_car_search_grids + search_grid_num = 1 + + for mu_Dest in np.linspace(0.25, 1.0, n_mu_dest_search_grids): + for mu_HiredCar in np.linspace(0.05, mu_Dest*0.75, n_mu_car_search_grids): # force some mu on hired car + m.set_values("init") + m.lock_value("Mu-Dest", mu_Dest) + m.lock_value("Mu-HiredCar", mu_HiredCar) + m.lock_value("Mu-PrivateCar", mu_HiredCar) + r = m.maximize_loglike( + prior_result=r, + return_dashboard=True, + method='SLSQP', + options={'maxiter': 1000}, + bhhh_start=5, + iteration_number_tail=f" Grid Search {search_grid_num}/{n_search_grids}" + ) + search_grid_num += 1 + m.pf['holdfast'] = holdfast_cache + m.pf['minimum'] = minimums_cache + m.pf['maximum'] = maximums_cache + m.set_values("best", respect_holdfast=False) + # small perturbation to encourage a little movement + log.info(f"loglike currently {r.get('loglike', 'missing')}") + + m.set_value('Const_WALK', m['Const_WALK'].value * 0.5) + m.set_value('Const_Transit', m['Const_Transit'].value * 0.5) + m.set_value('Const_HOV2', m['Const_HOV2'].value * 0.5) + m.set_value('Const_HOV3', m['Const_HOV3'].value * 0.5) + m.set_value('Const_TAXI', m['Const_TAXI'].value * 0.5) + m.set_value('Const_TNC1', m['Const_TNC1'].value * 0.5) + m.set_value('Const_TNC2', m['Const_TNC2'].value * 0.5) + + log.info(f"loglike perturbed {m.loglike()}") + + + log.info(f"Unlocked Estimation from iteration number {r.get('iteration_number', 'NO ITER NUM')}") + # final maximize from grid search best, probably minimal improvement from here + r = m.maximize_loglike( + prior_result=r, + return_dashboard=True, + method='SLSQP', + options={'maxiter': 1000}, + ) + log.info(f"Final Estimation at iteration number {r.get('iteration_number', 'NO ITER NUM')}") + + # # holdfast_cache = mods.HBO.pf.holdfast.copy() + # # mu_params = [i for i in mods.HBO.pf.index if 'Mu-' in i] + # # m.pf.loc[mu_params, 'holdfast'] = 1 + # # m.constraint_intensity = 100.0 + # # r = m.maximize_loglike(method='SLSQP', options={'maxiter': 20}, bhhh_start=5, return_dashboard=True) + # # m.pf['holdfast'] = holdfast_cache + # # m.constraint_intensity = 0.0 + # m.maximize_loglike( + # method='SLSQP', + # options={'maxiter':1000}, + # #prior_result=r, + # bhhh_start=5, + # ) + m.calculate_parameter_covariance() + m.to_xlsx( + cached_model_filename(purpose) + ) + summary = m.most_recent_estimation_result.copy() + summary.pop('x', None) + summary.pop('d_loglike', None) + summary.pop('nit', None) + display(larch.util.dictx(summary).__xml__()) + display(m.estimation_statistics()) + _pr = m.probability(return_dataframe='names', include_nests=True) + n_elemental_alts = (n_sampled_dests+1)*len(mode9names) + Pr.ByDest[purpose] = _pr.iloc[:,n_elemental_alts+nests_per_dest-1:-1:nests_per_dest] + Pr.ByMode[purpose] = _pr.iloc[:,:n_elemental_alts] + Pr.ByMode[purpose].columns = pd.MultiIndex.from_product([ + np.arange(n_sampled_dests+1), + mode9names, + ], names=['dest','mode']) + + display(HTML(f"

{m.title}

")) + display(m.parameter_summary()) + + try: + mode_choice_summary_table = mode_choice_summary(m) + except: + log.exception("exception in mode_choice_summary") + mode_choice_summary_success = False + else: + mode_choice_summary_success = True + + try: + dest_profiler(purpose) + except: + log.exception("exception in dest_profiler") + dest_profiler_success = False + else: + dest_profiler_success = True + + try: + mode_share_profiler(purpose) + except: + log.exception("exception in mode_share_profiler") + mode_share_profiler_success = False + else: + mode_share_profiler_success = True + + try: + transit_profiler(purpose) + except: + log.exception("exception in transit_profiler") + transit_profiler_success = False + else: + transit_profiler_success = True + + try: + walk_profiler(purpose) + except: + log.exception("exception in walk_profiler") + walk_profiler_success = False + else: + walk_profiler_success = True + + try: + value_of_time_profiler(purpose) + except: + log.exception("exception in value_of_time_profiler") + value_of_time_profiler_success = False + else: + value_of_time_profiler_success = True + + xl = m.to_xlsx( + cached_model_filereport(purpose), + save_now=False + ) + try: + if dest_profiler_success: + xl.add_content_tab( + figures.distribution[purpose]['auto_dist'], + sheetname="Figures", + heading="Destination Probabilities by Distance", + ) + xl.add_content_tab( + figures.distribution[purpose]['auto_time'], + sheetname="Figures", + heading="Destination Probabilities by Auto Travel Time", + ) + if mode_share_profiler_success: + xl.add_content_tab( + figures.share[purpose]['auto_dist'], + sheetname="Figures", + heading="Mode Choice by Distance", + ) + if mode_choice_summary_success: + xl.add_content_tab( + mode_choice_summary_table, + sheetname="Applied", + heading="Mode Choice Summary", + ) + if transit_profiler_success: + xl.add_content_tab( + figures.TRANSIT_dist[purpose]['auto_dist'], + sheetname="Figures", + heading="Transit Usage by Distance", + ) + xl.add_content_tab( + figures.TRANSIT_dist[purpose]['transit_ivtt'], + sheetname="Figures", + heading="Transit Usage by Transit IVTT", + ) + else: + log.warning("transit_profiler_success is False") + if walk_profiler_success: + xl.add_content_tab( + figures.WALK_dist[purpose]['auto_dist'], + sheetname="Figures", + heading="Total Walking by Distance", + ) + if value_of_time_profiler_success: + xl.add_content_tab( + figures.vot[purpose], + sheetname="Figures", + heading="Value of Time", + ) + finally: + xl.save() + + with open(dh.filenames.choice_model_param_file, 'w', encoding="utf-8") as cmp_yaml: + print("---", file=cmp_yaml) + for purpose in purposes: + print(f"{purpose}:", file=cmp_yaml) + for k, v in mods[purpose].pf.value.items(): + if ':' in k: + k = f'"{k}"' + print(f' {k:24s}: {v}', file=cmp_yaml) + print("", file=cmp_yaml) + print("...", file=cmp_yaml) + + return mods + +resource_usage.check() +L("## est_choice complete ##") diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_config.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_config.py new file mode 100644 index 0000000..c2a3ca9 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_config.py @@ -0,0 +1,137 @@ +from ..util import search_path + +## CONFIG ## + +n_sampled_dests = 25 +# The number of destination to sample during estimation +# This has no effect on application, where there is no sampling used. + +EstimationDir = search_path( + "~/Cambridge Systematics/PROJ CMAP Trip-Based - General/Estimation", + "~/OneDrive/Cambridge Systematics/PROJ CMAP Trip-Based - General/Estimation", + "other/possible/path/to/Estimation", +) +# Add local paths to the "Estimation" directory here. +# The contents of this directory itself are not to be published on GitHub + +EstimationSkimsDir = search_path( + "~/LocalGit/cmap-trip-model/Database/emmemat", + "~/Git/cmap-trip-model/Database/emmemat", +) + +############ + + +mode_complete = { + 101:'Walk', + 102:'My own bike', + 103:'Divvy bike', + 104:'Zagster bike', + 201:'Motorcycle/moped', + 202:'Auto / van / truck (as the driver) ', + 203:'Auto / van / truck (as the passenger) ', + 301:'Carpool/vanpool', + 401:'School bus', + 500:'Rail and Bus', + 501:'Bus (CTA, PACE, Huskie Line, Indiana)', + 502:'Dial-a-Ride', + 503:'Call-n-Ride', + 504:'Paratransit', + 505:'Train (CTA, METRA, South Shore Line)', + 506:'Local transit (NIRPC region)', + 509:'Transit (specific mode not reported or imputed)', + 601:'Private shuttle bus', + 701:'Taxi', + 702:'Private limo', + 703:'Private car', + 704:'Uber/Lyft', + 705:'Via/Uber Pool/Lyft Line (shared ride)', + 801:'Airplane', + 997:'[$MODE2_O]', +} + +mode_modeled = { + 101: None, # 'Walk', + 102: None, # 'My own bike', + 103: None, # 'Divvy bike', + 104: None, # 'Zagster bike', + 201: 'AUTO', + 202: 'AUTO', + 203: 'AUTO', + 301: 'AUTO', + 401: None, # 'School bus', + 500: 'TRANSIT', + 501: 'TRANSIT', + 502: None, # 'Dial-a-Ride', + 503: None, # 'Call-n-Ride', + 504: None, # 'Paratransit', + 505: 'TRANSIT', + 506: 'TRANSIT', + 509: 'TRANSIT', + 601: None, # 'Private shuttle bus', + 701: 'TNC', # 'Taxi', + 702: None, # 'Private limo', + 703: None, # 'Private car', + 704: 'TNC', # 'Uber/Lyft', + 705: 'TNC', # 'Via/Uber Pool/Lyft Line (shared ride)', + 801: None, # Airplane + 997: None, # Fill-in-the-blank +} + + +mode_modeled5 = { + 101: None, # 'Walk', + 102: None, # 'My own bike', + 103: None, # 'Divvy bike', + 104: None, # 'Zagster bike', + 201: 'AUTO', + 202: 'AUTO', + 203: 'AUTO', + 301: 'AUTO', + 401: None, # 'School bus', + 500: 'TRANSIT', + 501: 'TRANSIT', + 502: None, # 'Dial-a-Ride', + 503: None, # 'Call-n-Ride', + 504: None, # 'Paratransit', + 505: 'TRANSIT', + 506: 'TRANSIT', + 509: 'TRANSIT', + 601: None, # 'Private shuttle bus', + 701: 'TAXI', # 'Taxi', + 702: None, # 'Private limo', + 703: None, # 'Private car', + 704: 'TNC1', # 'Uber/Lyft', + 705: 'TNC2', # 'Via/Uber Pool/Lyft Line (shared ride)', + 801: None, # Airplane + 997: None, # Fill-in-the-blank +} + + +mode_modeled7 = { + 101: 'WALK', # 'Walk', + 102: 'BIKE', # 'My own bike', + 103: 'BIKE', # 'Divvy bike', + 104: 'BIKE', # 'Zagster bike', + 201: 'AUTO', + 202: 'AUTO', + 203: 'AUTO', + 301: 'AUTO', + 401: None, # 'School bus', + 500: 'TRANSIT', + 501: 'TRANSIT', + 502: None, # 'Dial-a-Ride', + 503: None, # 'Call-n-Ride', + 504: None, # 'Paratransit', + 505: 'TRANSIT', + 506: 'TRANSIT', + 509: 'TRANSIT', + 601: None, # 'Private shuttle bus', + 701: 'TAXI', # 'Taxi', + 702: None, # 'Private limo', + 703: None, # 'Private car', + 704: 'TNC1', # 'Uber/Lyft', + 705: 'TNC2', # 'Via/Uber Pool/Lyft Line (shared ride)', + 801: None, # Airplane + 997: None, # Fill-in-the-blank +} \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_data.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_data.py new file mode 100644 index 0000000..a584775 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_data.py @@ -0,0 +1,25 @@ +import os +import cmap_modedest + +from .est_logging import L +from .est_config import EstimationDir, EstimationSkimsDir + +L("###### Set Directories and Prep Data ######") + +from ..data_handlers import DataHandler + + +dh = DataHandler( + emme_database_dir=os.path.join(cmap_modedest.__path__[0], "../tests/data"), + #omx_skims_dir=EstimationDir/"SkimsForEstimation", + cache_dir=EstimationDir/"cache", + zone_shapefile=EstimationDir/"../GIS/From CMAP/zones17.shp", + #emmemat_archive=EstimationDir/"SkimsForEstimation/emmemat.zip", + emmemat_dir=EstimationSkimsDir, + tg_detail=True, +) + +dh.SURVEY_DATA_DIR = EstimationDir/"../HTS/preproc" +dh.AE_DATA_DIR = EstimationDir/"../HTS/cmap-proc" + +L("Data Handlers Ready") diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_logging.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_logging.py new file mode 100644 index 0000000..b240d38 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_logging.py @@ -0,0 +1,13 @@ +import cmap_modedest + +log = cmap_modedest.log_to_stderr(level=10) + + +def L(*args): + """Short logging function for estimation""" + if len(args) == 1 and isinstance(args[0], str) and args[0][0] == "#": + log.info(args[0]) + else: + s = "\n".join(str(i) for i in args) + s = "\n"+s + log.info(s.replace("\n", "\n ")) diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_sample_dest.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_sample_dest.py new file mode 100644 index 0000000..1c78d21 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_sample_dest.py @@ -0,0 +1,270 @@ +import numpy as np +import pandas as pd +import cmap_modedest +import sharrow as sh + +from .est_data import dh +skims = dh.skims +aggregate_attractions = np.fmin( + dh.trip_attractions5.sum(1), + np.percentile(dh.trip_attractions5.sum(1), 99.5), +) +zone_shp = dh.zone_shp +m01 = dh.m01 +from ..tnc_costs import taxi_cost, tnc_solo_cost, tnc_pool_cost +from ..purposes import purposes5, purposes3, purposes8, purposesA + +log = cmap_modedest.log_to_stderr(level=10) + + +def default_weighting_by_distance(distances): + return 1 / distances ** 2 + + +def sample_dest_zones(trips, n_zones, n_sampled_dests=20, wgt_func=None): + """ + Sample destinations for a set of origins. + + Parameters + ---------- + trips : DataFrame + n_zones : int + n_sampled_dests : int + wgt_func : callable, optional + This callable takes a 1-d array of distances to candidate + destination zones as input, and returns a same-shape array + of sampling weights. If not provided, the default scheme is + used, see `default_weighting_by_distance`. + + Returns + ------- + trip_alt_dest : array[len(trips), n_sampled_dests] of int + trip_alt_wgts : array[len(trips), n_sampled_dests] of float + trip_obs_wgts : array[len(trips)] of float + """ + if wgt_func is None: + wgt_func = default_weighting_by_distance + trip_alt_dest = np.zeros([len(trips), n_sampled_dests], dtype=np.int32) + trip_alt_wgts = np.zeros([len(trips), n_sampled_dests], dtype=np.float32) + trip_obs_wgts = np.zeros([len(trips)], dtype=np.float32) + for zone_index in range(n_zones): + zone_id = zone_index+1 + trips_from_this_zone = trips['o_zone'] == zone_id + n_trips_from_this_zone = trips_from_this_zone.sum() + if n_trips_from_this_zone == 0: + continue + zone_rgen = np.random.default_rng(zone_id) + from ..skims.names import skim_tags + distances = skims.raw[skim_tags.auto_md_dist].load()[zone_index, :n_zones] + distances[zone_index] = float(np.sqrt(zone_shp.loc[[zone_id]].area)/5280) + #distances = np.fmax(distances, 0.33) + zone_weight = wgt_func(distances).astype(np.float64) + zone_weight *= aggregate_attractions + zone_weight /= zone_weight.sum() + samp_dest = zone_rgen.choice( + n_zones, + size=(n_trips_from_this_zone,n_sampled_dests), + p=zone_weight, + ) + trip_alt_dest[trips_from_this_zone] = samp_dest+1 + trip_alt_wgts[trips_from_this_zone] = zone_weight.values[samp_dest] + trip_obs_wgts[trips_from_this_zone] = zone_weight.values[trips.loc[trips_from_this_zone, 'd_zone']-1] + return trip_alt_dest, trip_alt_wgts, trip_obs_wgts + + +def sample_dest_zones_and_data( + trips, + n_zones, + n_sampled_dests=20, + wgt_func=None, + ozone_col='o_zone', + labeler=lambda i: f'altdest{i + 1:04d}', + keep_trips_cols=(), +): + log.debug("sample_dest_zones()") + trip_alt_dest, trip_alt_wgts, trip_obs_wgts = sample_dest_zones( + trips, n_zones, n_sampled_dests, wgt_func, + ) + + _keep_trips_cols = [] + for k in keep_trips_cols: + if k in trips.columns: + _keep_trips_cols.append(k) + k = f"actualdest_{k}" + if k in trips.columns: + _keep_trips_cols.append(k) + for t in ['PEAK', 'OFFPEAK']: + if f"{k}_{t}" in trips.columns: + _keep_trips_cols.append(f"{k}_{t}") + for purpose in purposesA: + if f"{k}_{purpose}" in trips.columns: + _keep_trips_cols.append(f"{k}_{purpose}") + for purpose3 in purposes3: + if f"{k}_{purpose3}" in trips.columns: + _keep_trips_cols.append(f"{k}_{purpose3}") + + trip_alt_dest_df = trips[[ozone_col, 'in_peak', *_keep_trips_cols]] + + log.debug("trip_alt_dest_df.join()") + trip_alt_dest_df = trip_alt_dest_df.join( + pd.DataFrame( + trip_alt_dest, + index=trips.index, + columns=[labeler(i) for i in range(trip_alt_dest.shape[1])], + ) + ) + trip_alt_dest_df['actualdest_samp_wgt'] = trip_obs_wgts + trip_alt_dest_df = trip_alt_dest_df.join( + pd.DataFrame( + trip_alt_wgts, + index=trips.index, + columns=[f'{labeler(i)}_samp_wgt' for i in range(trip_alt_dest.shape[1])], + ), + ) + + flipY = trips.paFlip + flipN = 1-trips.paFlip + + from .est_survey import attach_selected_skims_sh + for i in range(n_sampled_dests): + + origin_zone = trip_alt_dest_df.o_zone * flipN + trip_alt_dest_df[labeler(i)] * flipY + destin_zone = trip_alt_dest_df.o_zone * flipY + trip_alt_dest_df[labeler(i)] * flipN + + # attach auto skims + log.debug(f"attach auto skims <{i}>") + flow = sh.SharedData( + ['otaz', 'dtaz', 'in_peak'], + skims=dh.skims.raw + ).setup_flow({ + f'{labeler(i)}_auto_time': f'skims.mf44 if in_peak else skims.mf46', + f'{labeler(i)}_auto_dist': f'skims.mf45 if in_peak else skims.mf47', + f'{labeler(i)}_auto_op_dist': 'skims.mf47', + f'{labeler(i)}_auto_time_PEAK': 'skims.mf44', + f'{labeler(i)}_auto_time_hov_PEAK': 'skims.mf76', + f'{labeler(i)}_auto_time_OFFPEAK': 'skims.mf46', + f'{labeler(i)}_auto_dist_PEAK': 'skims.mf45', + f'{labeler(i)}_auto_dist_OFFPEAK': 'skims.mf47', + f'{labeler(i)}_auto_toll_loinc_PEAK': f'skims.mf111', + f'{labeler(i)}_auto_toll_hiinc_PEAK': f'skims.mf114', + f'{labeler(i)}_auto_toll_OFFPEAK': f'skims.mf117', + f'{labeler(i)}_auto_toll_hov_loinc_PEAK': f'skims.mf112', + f'{labeler(i)}_auto_toll_hov_hiinc_PEAK': f'skims.mf115', + f'{labeler(i)}_auto_opcost_PEAK': 'skims.am_opcost', + f'{labeler(i)}_auto_opcost_hov_PEAK': 'skims.am_opcost_hov', + f'{labeler(i)}_auto_opcost_OFFPEAK': 'skims.md_opcost', + }) + auto_cols = flow.load( + trip_alt_dest_df[['o_zone', labeler(i), 'in_peak']].rename( + columns={'o_zone':'otaz', labeler(i):'dtaz'} + ), + as_dataframe=True, + ) + trip_alt_dest_df = pd.concat([trip_alt_dest_df, auto_cols], axis=1) + + # add areatypes + from ..data_handlers.m01_handler import attach_areatypes + trip_alt_dest_df = attach_areatypes(dh, trip_alt_dest_df, labeler(i), '', labeler(i)) # altdest0000_areatype + + # set intrazonal auto_dist + intrazonal = (trip_alt_dest_df['o_zone'] == trip_alt_dest_df[labeler(i)]) + intrazonal_zone_area = dh.zone_shp.loc[trip_alt_dest_df.loc[intrazonal, labeler(i)]].Shape_Area # square feet + intrazonal_dist = np.sqrt(intrazonal_zone_area).to_numpy() / 5280 * 0.667 + trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_auto_dist_OFFPEAK'] = intrazonal_dist + trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_auto_dist_PEAK'] = intrazonal_dist + + # set intrazonal auto_time + trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_auto_time_PEAK'] = ( + trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_auto_dist_PEAK'] + * 60 / (trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_areatype'].map( + lambda y: dh.cfg.intrazonal_auto_speed.peak.get(y, 15))) + ) + trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_auto_time_OFFPEAK'] = ( + trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_auto_dist_OFFPEAK'] + * 60 / (trip_alt_dest_df.loc[intrazonal, f'{labeler(i)}_areatype'].map( + lambda y: dh.cfg.intrazonal_auto_speed.offpeak.get(y, 15))) + ) + + # Add taxi and TNC wait time data + from ..data_handlers.m01_handler import attach_hired_car_waits + trip_alt_dest_df = attach_hired_car_waits(dh, trip_alt_dest_df, labeler(i), origin_zone) + # Add taxi and TNC fare data + for t in ['PEAK', 'OFFPEAK']: + trip_alt_dest_df[f'{labeler(i)}_taxi_fare_{t}'] = taxi_cost( + dh, + trip_alt_dest_df[f'{labeler(i)}_auto_time_{t}'], + trip_alt_dest_df[f'{labeler(i)}_auto_dist_{t}'], + origin_zone, + destin_zone, + ) + trip_alt_dest_df[f'{labeler(i)}_tnc_solo_fare_{t}'] = tnc_solo_cost( + dh, + trip_alt_dest_df[f'{labeler(i)}_auto_time_{t}'], + trip_alt_dest_df[f'{labeler(i)}_auto_dist_{t}'], + origin_zone, + destin_zone, + 1 if (t=='PEAK') else 0, + ) + trip_alt_dest_df[f'{labeler(i)}_tnc_pool_fare_{t}'] = tnc_pool_cost( + dh, + trip_alt_dest_df[f'{labeler(i)}_auto_time_{t}'], + trip_alt_dest_df[f'{labeler(i)}_auto_dist_{t}'], + origin_zone, + destin_zone, + 1 if (t=='PEAK') else 0, + ) + + # attach transit skims + log.debug(f"attach transit skims <{i}>") + skim_tags = ('ivtt','ovtt','headway','fare','firstmode','prioritymode','lastmode') + + transit_joint = {} + for k in skim_tags: + _pk = dh.skims.transit_pk.col_mapping[k] + _op = dh.skims.transit_op.col_mapping[k] + transit_joint[f'{labeler(i)}_transit_{k}'] = f"skims.{_pk} if in_peak else skims.{_op}" + transit_joint[f'{labeler(i)}_transit_{k}_PEAK'] = f"skims.{_pk}" + transit_joint[f'{labeler(i)}_transit_{k}_OFFPEAK'] = f"skims.{_op}" + flow = sh.SharedData( + ['otaz', 'dtaz', 'in_peak'], + skims=dh.skims.raw + ).setup_flow(transit_joint) + new_cols = flow.load( + trip_alt_dest_df[['o_zone', labeler(i), 'in_peak']].rename(columns={'o_zone':'otaz', labeler(i):'dtaz'}), + as_dataframe=True, + ) + trip_alt_dest_df = pd.concat([trip_alt_dest_df, new_cols], axis=1) + + if np.any(trip_alt_dest_df.isna()): + print(trip_alt_dest_df.isna().sum()) + pass + else: + pass + + # clipping to set invalid skim values to NaN?, facilitates more useful statistics. + log.debug(f"clipping to set invalid skim values to NaN <{i}>") + for j in ['ivtt', 'ovtt', 'headway', 'fare']: + x = trip_alt_dest_df[f'{labeler(i)}_transit_{j}'] + trip_alt_dest_df.loc[x>9999, f'{labeler(i)}_transit_{j}'] = np.nan + for t in ['PEAK', 'OFFPEAK']: + varname = f'{labeler(i)}_transit_{j}_{t}' + x = trip_alt_dest_df[varname] + trip_alt_dest_df.loc[x > 9999, varname] = np.nan + + # parking costs + from ..parking_costs import parking_cost_v2 + from ..purposes import purposes_to_3 + for purpose in purposes5: + _parking_cost, _free_parking = parking_cost_v2( + dh, + destin_zone, + trip_alt_dest_df['hhinc_dollars'], + dh.cfg.default_activity_durations[purposes_to_3[purpose]], + purposes_to_3[purpose], + random_state=hash(purpose) + 1, + ) + trip_alt_dest_df[f'{labeler(i)}_auto_parking_cost_{purpose}'] = _parking_cost + trip_alt_dest_df[f'{labeler(i)}_auto_parking_free_{purpose}'] = _free_parking + + return trip_alt_dest_df + diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_skims_convol.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_skims_convol.py new file mode 100644 index 0000000..d9664a6 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_skims_convol.py @@ -0,0 +1,29 @@ +import os + +from .est_logging import L +from .est_data import dh +filenames = dh.filenames + +L("###### Skims Convolution ######") +from cmap_modedest.transit_skim_convolution import skim_convol +emmemat_in_dir = os.path.dirname(filenames.mf822) + +filenames.pk_transit_skims = filenames.cache_dir / "peak.omx" +if not os.path.exists(filenames.pk_transit_skims): + skim_convol( + dh, + peak=True, + ) +else: + L("# using cached peak skims") + +filenames.op_transit_skims = filenames.cache_dir / "offpeak.omx" +if not os.path.exists(filenames.op_transit_skims): + skim_convol( + dh, + peak=False, + ) +else: + L("# using cached offpeak skims") + + diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_survey.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_survey.py new file mode 100644 index 0000000..cec5e4e --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_survey.py @@ -0,0 +1,565 @@ +import logging +log = logging.getLogger('CMAP') +import re +from ..addict import Dict + +import pandas as pd +import numpy as np +from os.path import join as pj +from .est_config import mode_modeled, mode_modeled5, mode_modeled7 +from ..incomes import income_levels_1, income_levels_2 +from ..timeperiods import hours_by_timeperiod +from ..purposes import purposes_to_3, purposes5 + +import cmap_modedest +from .est_data import dh +from cmap_modedest.modecodes import ( + N_DIST_TO_TYPES, + DIST_TO_BUS, + DIST_TO_CTA_RAIL, + DIST_TO_METRA, + DIST_TO_FEEDER_BUS, + DIST_TO_PARK_N_RIDE_STATION, +) +from cmap_modedest.transit_approach import N_TRIP_ENDS, transit_approach +cfg = dh.cfg +skims = dh.skims + + +TRIPS_CACHE_FILE = "trips_with_ae_vx24" + +hh = pd.read_csv(dh.SURVEY_DATA_DIR / 'household.csv') +ae = pd.read_csv(dh.AE_DATA_DIR / 'access_egress.csv') + +core_cbd_zones = [ + 1, 2, 3, 4, 5, 6, + 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, + 20, 21, 22, 23, 24, + 26, 27, 28, 29, 30, + 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, + 43, 44, 45, 46, 47, +] + +trips = dh.filenames.load(TRIPS_CACHE_FILE) +if trips is None: + + trips = pd.read_csv(dh.SURVEY_DATA_DIR / 'trips.csv') + trips.info() + + raw_place = pd.read_csv(dh.SURVEY_DATA_DIR / "../RawData/place.csv") + trips = trips.join( + raw_place[['sampno', 'placeno', 'perno', 'companions']].set_index(['sampno', 'placeno', 'perno']), + on=['sampno', 'placeno', 'perno'] + ) + trips.info() + + # attach tpurp from origin end of trip + trips['previous_placeno'] = trips.placeno - 1 + trips = trips.join( + raw_place + [['sampno', 'placeno', 'perno', 'tpurp']] + .rename(columns={'tpurp': 'previous_tpurp'}) + .set_index(['sampno', 'placeno', 'perno']), + on=['sampno', 'previous_placeno', 'perno'], + ) + trips.info() + + + raw_person = pd.read_csv(dh.SURVEY_DATA_DIR / "../RawData/person.csv") + raw_person["is_adult"] = ((raw_person['age'] >= 18) | (raw_person['aage'] >= 5) | (raw_person['age18'] == 1)) + hhadults = raw_person.groupby("sampno")["is_adult"].sum().rename("hhadults") + trips = trips.join(hhadults, on="sampno") + + from ..modecodes import mode7names, mode9names + + # Convert trips to 3 modes only (auto, transit, tnc), and drop all other trips + trips['mode3'] = trips['mode'].map(mode_modeled).astype('category') + trips['mode5'] = trips['mode'].map(mode_modeled5).astype('category') + trips['mode7'] = trips['mode'].map(mode_modeled7).astype(pd.CategoricalDtype(mode7names)) + trips['mode9'] = trips['mode'].map(mode_modeled7) + trips.loc[(trips.companions == 1) & (trips.mode7 == 'AUTO'),'mode9'] = "HOV2" + trips.loc[(trips.companions >= 2) & (trips.mode7 == 'AUTO'),'mode9'] = "HOV3" + trips['mode9'] = trips['mode9'].astype(pd.CategoricalDtype(mode9names)) + + trips_filter = ~trips['mode9'].isna() + + trips = trips.merge(ae, how='left', on=['sampno', 'perno', 'placeno']) + + # identify home-based other trips that are actually home-based shopping trips + is_HBShop = (trips['tripCat'] == 'HBO') & ( + ( + (trips['previous_tpurp'] == 1) & (trips['tpurp'].isin([8, 9, 10])) + ) | ( + (trips['tpurp'] == 1) & (trips['previous_tpurp'].isin([8, 9, 10])) + ) + ) + trips.loc[is_HBShop, 'tripCat'] = 'HBS' + + oz = 'o_zone' + dz = 'd_zone' + pz = 'p_zone' + az = 'a_zone' + + + # develop production & attraction zones + trips[pz] = trips[oz] + trips[az] = trips[dz] + + flip_pa = (trips['PA'] == 0) + # trips.loc[flip_pa, [pz,az]] = trips.loc[flip_pa, [az,pz]].values + trips_filter &= ~trips[pz].isna() + trips_filter &= ~trips[az].isna() + + # Filter trips based on rules + trips = trips[trips_filter].copy() + + # Convert zone codes to integers + trips[[pz,az,oz,dz]] = trips[[pz,az,oz,dz]].astype(int) + + # Convert tripCat to category + trips['tripCat'] = trips['tripCat'].astype('category') + + trips['tripPurpose'] = trips['tripCat'].map(purposes_to_3) + + # hour_re = re.compile(r'.*\s([0-9]+):[0-9]+:[0-9]+') + # def get_hour(y): + # match = hour_re.match(y) + # if match: + # return int(match.group(1)) + # else: + # return -1 + trips['arrHalfHour'] = np.floor(trips['arrHour']*2)/2 + trips['depHalfHour'] = np.floor(trips['depHour']*2)/2 + trips['in_am_peak'] = trips['depHour'].between(6.5,9.5) | trips['arrHour'].between(6.5,9.5) + trips['in_pm_peak'] = trips['depHour'].between(14.5,19) | trips['arrHour'].between(14.5,19) + trips['in_peak'] = trips['in_am_peak'] | trips['in_pm_peak'] + + trips['timeperiod'] = np.floor(trips.depHour).astype(int).map(hours_by_timeperiod) + + hhinc_dollars = trips.hhinc.map(income_levels_1) + hhinc_dollars = hhinc_dollars.fillna(trips.hhinc2.map(income_levels_2)) + hhinc_dollars = hhinc_dollars.fillna(57_999) + trips['hhinc_dollars'] = hhinc_dollars + + # Append skims to trips + for k, s in skims.items(): + if k not in ('auto', 'transit_pk', 'transit_op'): continue + log.debug(f"adding skims for {k}") + trips_1 = skims.raw[list(s.col_mapping.values())].iat_df( + pd.DataFrame({ + 'otaz': trips[pz] - 1, + 'dtaz': trips[az] - 1, + }) + ) + renames = dict([(value, f"{k}_{key}") for key, value in s.col_mapping.items()]) + trips_2 = trips_1[s.col_mapping.values()].rename(columns=renames) + trips = pd.concat([trips, trips_2], axis=1) + + # Append reverse transit skims to trips + for k, s in skims.items(): + if k not in ('transit_pk', 'transit_op'): continue + log.debug(f"adding reverse skims for {k}") + trips_1 = skims.raw[list(s.col_mapping.values())].iat_df( + pd.DataFrame({ + 'otaz': trips[az] - 1, + 'dtaz': trips[pz] - 1, + }) + ) + renames = dict([(value, f"{k}_{key}_reverse") for key, value in s.col_mapping.items()]) + trips_2 = trips_1[s.col_mapping.values()].rename(columns=renames) + trips = pd.concat([trips, trips_2], axis=1) + + # Match time period skims + peak = trips['in_peak'] + hw = trips['tripPurpose'] == 'HW' + auto_cols = ['time','dist'] + for a in auto_cols: + trips[f'auto_{a}'] = trips[f'auto_md_{a}'] + trips.loc[peak,f'auto_{a}'] = trips.loc[peak,f'auto_am_{a}'] + trips[f'actualdest_auto_{a}'] = trips[f'auto_{a}'] + trips[f'actualdest_auto_{a}_OFFPEAK' ] = trips[f'auto_md_{a}'] + trips[f'actualdest_auto_{a}_PEAK' ] = trips[f'auto_am_{a}'] + + trips[f'actualdest_auto_time_hov_PEAK'] = trips[f'auto_am_time_hov'] + trips[f'actualdest_auto_toll_loinc_PEAK'] = trips[f'auto_am_toll_loinc'] + trips[f'actualdest_auto_toll_hiinc_PEAK'] = trips[f'auto_am_toll_hiinc'] + trips[f'actualdest_auto_toll_OFFPEAK'] = trips[f'auto_md_toll'] + trips[f'actualdest_auto_toll_hov_loinc_PEAK'] = trips[f'auto_am_toll_hov_loinc'] + trips[f'actualdest_auto_toll_hov_hiinc_PEAK'] = trips[f'auto_am_toll_hov_hiinc'] + + trips[f'actualdest_auto_opcost_PEAK'] = trips[f'auto_am_opcost'] + trips[f'actualdest_auto_opcost_hov_PEAK'] = trips[f'auto_am_opcost_hov'] + trips[f'actualdest_auto_opcost_OFFPEAK'] = trips[f'auto_md_opcost'] + + # add areatypes + log.debug(f"attach areatypes") + from ..data_handlers.m01_handler import attach_areatypes + trips = attach_areatypes(dh, trips, 'actualdest', '', 'd_zone') # actualdest_areatype + trips = attach_areatypes(dh, trips, 'ozone', '', 'o_zone') # ozone_areatype + + # set intrazonal auto_dist + log.debug(f"set intrazonal auto_dist") + intrazonal = (trips['o_zone'] == trips['d_zone']) + intrazonal_zone_area = dh.zone_shp.loc[trips.loc[intrazonal, 'o_zone']].Shape_Area # square feet + intra_dist = np.sqrt(intrazonal_zone_area).to_numpy() / 5280 * 0.667 + trips.loc[intrazonal, f'actualdest_auto_dist_OFFPEAK'] = intra_dist + trips.loc[intrazonal, f'actualdest_auto_dist_PEAK'] = intra_dist + + # set intrazonal auto_time + trips.loc[intrazonal, f'actualdest_auto_time_PEAK'] = ( + trips.loc[intrazonal, f'actualdest_auto_dist_PEAK'] + * 60/(trips.loc[intrazonal, 'actualdest_areatype'].map(lambda y: dh.cfg.intrazonal_auto_speed.peak.get(y, 15))) + ) + trips.loc[intrazonal, f'actualdest_auto_time_OFFPEAK'] = ( + trips.loc[intrazonal, f'actualdest_auto_dist_OFFPEAK'] + * 60/(trips.loc[intrazonal, 'actualdest_areatype'].map(lambda y: dh.cfg.intrazonal_auto_speed.offpeak.get(y, 15))) + ) + + transit_cols = ['ivtt','ovtt','headway','fare','firstmode','lastmode','prioritymode'] + for a in transit_cols: + trips[f'transit_{a}'] = trips[f'transit_op_{a}'] + trips.loc[peak,f'transit_{a}'] = trips.loc[peak,f'transit_pk_{a}'] + # convert invalid to nan + to_nan = trips[f'transit_{a}'] >= 9999 + trips.loc[to_nan,f'transit_{a}'] = np.nan + to_nan = trips[f'transit_pk_{a}'] >= 9999 + trips.loc[to_nan,f'transit_pk_{a}'] = np.nan + to_nan = trips[f'transit_op_{a}'] >= 9999 + trips.loc[to_nan,f'transit_op_{a}'] = np.nan + trips[f'actualdest_transit_{a}'] = trips[f'transit_{a}'] + trips[f'actualdest_transit_{a}_OFFPEAK'] = trips[f'transit_op_{a}'] + trips[f'actualdest_transit_{a}_PEAK' ] = trips[f'transit_pk_{a}'] + + # trips = trips.drop([f'auto_am_{a}' for a in auto_cols], axis=1) + # trips = trips.drop([f'auto_md_{a}' for a in auto_cols], axis=1) + # trips = trips.drop([f'transit_pk_{a}' for a in transit_cols], axis=1) + # trips = trips.drop([f'transit_op_{a}' for a in transit_cols], axis=1) + + + # attach transit_approach model data + for t in ['single', 'max', 'mean']: + trips[f'ae_drivetime_{t}'] = 0 + trips[f'ae_walktime_{t}'] = 0 + trips[f'ae_cost_{t}'] = 0 + trips[f'ae_waittime_{t}'] = 0 + + #trips[f'actualdest_auto_parking_cost'] = 0 # Check this is never used + from ..transit_approach import transit_approach + from ..parking_costs import parking_cost_v2 + + for purpose in ['HW','HO','NH']: + # HW gets peak period + # HO gets off-peak period + # NH gets off-peak period AND cannot use park-and-ride + q = (trips.tripPurpose == purpose) + _trips_by_purpose = trips[q] + result_purpose = transit_approach( + dh, + _trips_by_purpose.o_zone, + _trips_by_purpose.d_zone, + purpose, + replication=50, + approach_distances=None, + trace=False, + random_state=hash(purpose), + ) + + for key in ['drivetime', 'walktime', 'cost', 'waittime']: + trips.loc[q, f'ae_{key}_max'] = result_purpose[key].max(1) + trips.loc[q, f'ae_{key}_mean'] = result_purpose[key].mean(1) + trips.loc[q, f'ae_{key}_single'] = result_purpose[key][:,0] + + for purpose in purposes5: + + # Attach parking costs + _parking_cost, _free_parking = parking_cost_v2( + dh, + trips.d_zone, + trips.hhinc_dollars, + cfg.default_activity_durations[purposes_to_3[purpose]], + purposes_to_3[purpose], + random_state=hash(purpose)+1, + ) + trips[f'actualdest_auto_parking_cost_{purpose}'] = _parking_cost + trips[f'actualdest_auto_parking_free_{purpose}'] = _free_parking + + trips[f'actualdest_auto_parking_free_{purpose}'] = trips[f'actualdest_auto_parking_free_{purpose}'].fillna(0) + + # for n in trips.index: + # out = transit_approach( + # trips.o_zone[n], trips.d_zone[n], 'HW' if trips.in_peak[n] else 'HO', replication=50 + # ) + # trips.loc[n, 'ae_drivetime_max'] = out.drivetime.max() + # trips.loc[n, 'ae_walktime_max'] = out.walktime.max() + # trips.loc[n, 'ae_cost_max'] = out.cost.max() + # trips.loc[n, 'ae_waittime_max'] = out.waittime.max() + # trips.loc[n, 'ae_drivetime_mean'] = out.drivetime.mean() + # trips.loc[n, 'ae_walktime_mean'] = out.walktime.mean() + # trips.loc[n, 'ae_cost_mean'] = out.cost.mean() + # trips.loc[n, 'ae_waittime_mean'] = out.waittime.mean() + # trips.loc[n, 'ae_drivetime_single'] = out.drivetime[0] + # trips.loc[n, 'ae_walktime_single'] = out.walktime[0] + # trips.loc[n, 'ae_cost_single'] = out.cost[0] + # trips.loc[n, 'ae_waittime_single'] = out.waittime[0] + + trips['touches_core_cbd'] = trips['o_zone'].isin(core_cbd_zones) | trips['d_zone'].isin(core_cbd_zones) + trips['transit_trip_not_in_skim'] = trips.eval("~(0 < transit_ivtt < 999) and mode3=='TRANSIT'") + trips['crow_distance'] = np.sqrt((trips.X_coord1 - trips.X_coord2)**2 + (trips.Y_coord1 - trips.Y_coord2)**2) / 5280 + + flipY = trips.paFlip + flipN = 1 - trips.paFlip + + trips_origin = trips.o_zone * flipN + trips.d_zone * flipY + + from ..data_handlers.m01_handler import attach_hired_car_waits + + trips = attach_hired_car_waits(dh, trips, 'actualdest', trips_origin) + + # taxi_wait_pk = dh.m01['taxi_wait_pk'] + # taxi_wait_op = dh.m01['taxi_wait_op'] + # trips['actualdest_taxi_wait_time_PEAK'] = trips_origin.map(taxi_wait_pk) + # trips['actualdest_taxi_wait_time_OFFPEAK'] = trips_origin.map(taxi_wait_op) + # trips['actualdest_taxi_wait_time'] = ( + # trips['actualdest_taxi_wait_time_PEAK'] * trips.in_peak + # + trips['actualdest_taxi_wait_time_OFFPEAK'] * ~trips.in_peak + # ) + # + # tnc_solo_wait_pk = dh.m01['tnc_solo_wait_pk'] + # tnc_solo_wait_op = dh.m01['tnc_solo_wait_op'] + # trips['actualdest_tnc_solo_wait_time_PEAK'] = trips_origin.map(tnc_solo_wait_pk) + # trips['actualdest_tnc_solo_wait_time_OFFPEAK'] = trips_origin.map(tnc_solo_wait_op) + # trips['actualdest_tnc_solo_wait_time'] = ( + # trips['actualdest_tnc_solo_wait_time_PEAK'] * trips.in_peak + # + trips['actualdest_tnc_solo_wait_time_OFFPEAK'] * ~trips.in_peak + # ) + # + # tnc_pool_wait_pk = dh.m01['tnc_pool_wait_pk'] + # tnc_pool_wait_op = dh.m01['tnc_pool_wait_op'] + # trips['actualdest_tnc_pool_wait_time_PEAK'] = trips_origin.map(tnc_pool_wait_pk) + # trips['actualdest_tnc_pool_wait_time_OFFPEAK'] = trips_origin.map(tnc_pool_wait_op) + # trips['actualdest_tnc_pool_wait_time'] = ( + # trips['actualdest_tnc_pool_wait_time_PEAK'] * trips.in_peak + # + trips['actualdest_tnc_pool_wait_time_OFFPEAK'] * ~trips.in_peak + # ) + + from ..tnc_costs import tnc_solo_cost, taxi_cost, tnc_pool_cost, peak_tnc_pricing + + for t in ['PEAK', 'OFFPEAK']: + + trips[f'actualdest_taxi_fare_{t}'] = taxi_cost( + dh, + trips[f'actualdest_auto_time_{t}'], + trips[f'actualdest_auto_dist_{t}'], + trips['o_zone'], + trips['d_zone'], + ) + + trips[f'actualdest_tnc_solo_fare_{t}'] = tnc_solo_cost( + dh, + trips[f'actualdest_auto_time_{t}'], + trips[f'actualdest_auto_dist_{t}'], + trips['o_zone'], + trips['d_zone'], + 1 if (t=='PEAK') else 0, + ) + + trips[f'actualdest_tnc_pool_fare_{t}'] = tnc_pool_cost( + dh, + trips[f'actualdest_auto_time_{t}'], + trips[f'actualdest_auto_dist_{t}'], + trips['o_zone'], + trips['d_zone'], + 1 if (t=='PEAK') else 0, + ) + + trips['actualdest'] = trips['d_zone'] + trips['mode3code'] = trips.mode3.cat.codes + 1 + trips['mode5code'] = trips.mode5.cat.codes + 1 + trips['mode7code'] = trips.mode7.cat.codes + 1 + trips['mode9code'] = trips.mode9.cat.codes + 1 + + trips['mode_and_time'] = trips.mode5code + trips.timeperiod * 5 + + dh.filenames.save(TRIPS_CACHE_FILE, trips) + +# columns not compatible with Parquet +trips['crow_distance_q5'] = pd.qcut(trips.crow_distance, 5) + + + +def attach_selected_skims( + od_df, + o_col, + d_col, + omx, + skim_cols, +): + """ + Attach selected columns from an OMX file to a DataFrame. + + Parameters + ---------- + od_df : pandas.DataFrame + o_col, d_col : str + Names of the O and D columns in `od_df`. + omx : OMX + skim_cols : Tuple[str, Dict[str, str]] + Top level keys of this pseudo-dict give filters on `od_df` that + ideally give a mutually exclusive and collectively exhaustive + partition. Top level values are dicts, from which the keys + are the skim columns to pull for this partition group and the + values are the names of the ultimate columns to attach. + Final column value names in all partition groups should be + the same to populate a common set of columns in the output. + + Returns + ------- + pandas.DataFrame + """ + cols_to_add = {} + for filter_qry, use_cols in skim_cols: + for c in use_cols.values(): + if c not in od_df.columns: + cols_to_add[c] = np.nan + df = od_df.assign(**cols_to_add) + for filter_qry, use_cols in skim_cols: + if filter_qry: + group = od_df.query(filter_qry) + else: + group = od_df + s = omx.get_rc_dataframe( + group[o_col] - 1, + group[d_col] - 1, + use_cols, + ) + df.update(s) + return df + + +def attach_selected_skims_sh( + od_df, + o_col, + d_col, + dataset, + skim_cols, +): + """ + Attach selected columns from an OMX file to a DataFrame. + + Parameters + ---------- + od_df : pandas.DataFrame + o_col, d_col : str + Names of the O and D columns in `od_df`. + dataset : sharrow.Dataset + skim_cols : Tuple[str, Dict[str, str]] + Top level keys of this pseudo-dict give filters on `od_df` that + ideally give a mutually exclusive and collectively exhaustive + partition. Top level values are dicts, from which the keys + are the skim columns to pull for this partition group and the + values are the names of the ultimate columns to attach. + Final column value names in all partition groups should be + the same to populate a common set of columns in the output. + + Returns + ------- + pandas.DataFrame + """ + cols_to_add = {} + for filter_qry, use_cols in skim_cols: + for c in use_cols.values(): + if c not in od_df.columns: + cols_to_add[c] = np.nan + df = od_df.assign(**cols_to_add) + for filter_qry, use_cols in skim_cols: + if filter_qry: + group = od_df.query(filter_qry) + else: + group = od_df + s = dataset[list(use_cols.keys())].iat_df(pd.DataFrame(dict( + otaz=group[o_col].values - 1, + dtaz=group[d_col].values - 1, + ))).rename(columns=use_cols) + df.update(s) + return df + +# pMode == 3 +# walk -> DIST_TO_BUS +# +# pMode == 6 +# bus -> DIST_TO_BUS +# walk -> DIST_TO_CTA_RAIL +# pnr -> DIST_TO_PARK_N_RIDE_STATION +# +# pMode == 7 +# bus -> DIST_TO_BUS +# walk -> DIST_TO_METRA +# pnr -> DIST_TO_PARK_N_RIDE_STATION +# feeder -> DIST_TO_FEEDER_BUS + +def ae_approach_los(trips): + approach_distances = np.full([len(trips), N_DIST_TO_TYPES, N_TRIP_ENDS], 999.0) + fm3 = trips.transit_firstmode == 3 + approach_distances[fm3, DIST_TO_BUS, 0] = trips[fm3].walkAccDistance + fm6 = trips.transit_firstmode == 6 + approach_distances[fm6, DIST_TO_BUS, 0] = trips[fm6].busAccDistance + approach_distances[fm6, DIST_TO_CTA_RAIL, 0] = trips[fm6].walkAccDistance + approach_distances[fm6, DIST_TO_PARK_N_RIDE_STATION, 0] = trips[fm6].pnrAccDistance + fm7 = trips.transit_firstmode == 7 + approach_distances[fm7, DIST_TO_BUS, 0] = trips[fm7].busAccDistance + approach_distances[fm7, DIST_TO_METRA, 0] = trips[fm7].walkAccDistance + approach_distances[fm7, DIST_TO_PARK_N_RIDE_STATION, 0] = trips[fm7].pnrAccDistance + approach_distances[fm7, DIST_TO_FEEDER_BUS, 0] = trips[fm7].feederAccDistance + + lm3 = trips.transit_lastmode == 3 + approach_distances[lm3, DIST_TO_BUS, 1] = trips[lm3].walkEgrDistance + lm6 = trips.transit_lastmode == 6 + approach_distances[lm6, DIST_TO_BUS, 1] = trips[lm6].busEgrDistance + approach_distances[lm6, DIST_TO_CTA_RAIL, 1] = trips[lm6].walkEgrDistance + lm7 = trips.transit_lastmode == 7 + approach_distances[lm7, DIST_TO_BUS, 1] = trips[lm7].busEgrDistance + approach_distances[lm7, DIST_TO_METRA, 1] = trips[lm7].walkEgrDistance + + result = Dict() + for peaky in ['PEAK','OFFPEAK']: + # q = (trips.tripPurpose == purpose3) + # _trips_by_purpose = trips[q] + result[peaky] = transit_approach( + dh, + trips.o_zone, + trips.d_zone, + 'HW' if peaky=='PEAK' else 'HO', + replication=1, + approach_distances=approach_distances, + trace=False, + random_state=123, + ) + + for key in ['drivetime', 'walktime', 'cost', 'waittime']: + trips[f'transit_approach_{key}_{peaky}'] = result[peaky][key].reshape(-1) + trips[f'actualdest_transit_approach_{key}_{peaky}'] = result[peaky][key].reshape(-1) + trips[f'transit_approach_acc_mode_{peaky}'] = result[peaky]['approach_mode'][...,0].reshape(-1) + trips[f'transit_approach_egr_mode_{peaky}'] = result[peaky]['approach_mode'][...,1].reshape(-1) + + ad = pd.DataFrame( + approach_distances.reshape([-1, 10]), + columns=[ + 'acc_DIST_TO_BUS', + 'egr_DIST_TO_BUS', + 'acc_DIST_TO_CTA_RAIL', + 'egr_DIST_TO_CTA_RAIL', + 'acc_DIST_TO_METRA', + 'egr_DIST_TO_METRA', + 'acc_DIST_TO_FEEDER_BUS', + 'egr_DIST_TO_FEEDER_BUS', + 'acc_DIST_TO_PARK_N_RIDE_STATION', + 'egr_DIST_TO_PARK_N_RIDE_STATION', + ], + index=trips.index, + ) + for c in ad.columns: + trips[c] = ad[c] + + return approach_distances, result diff --git a/src/Mode-Dest-TOD/cmap_modedest/estimation/est_timeofday.py b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_timeofday.py new file mode 100644 index 0000000..2bb06f8 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/estimation/est_timeofday.py @@ -0,0 +1,60 @@ +import numpy as np +import pandas as pd +from pathlib import Path +from larch.numba import P, X, Model, OMX, DataFrames +# from larch import P, X, Model, OMX, DataFrames +from IPython.display import display, HTML +from larch.util.data_expansion import piecewise_linear + +from ..time_of_day_model import tod_model_builder + +def estimate_tod(dh, mods, to_pickle=True): + cached_todmodel_filename = lambda purpose: dh.filenames.cache_dir / f"choicemodel_{purpose}_timeofday.xlsx" + + tod_models = {} + tod_skims = dh.skims.raw[[f'mf46{j}' for j in range(1,9)]] + + for purpose, mode_dest_model in mods.items(): + co = mode_dest_model.dataservice.data_co.query("mode9 in ('AUTO','HOV2','HOV3','TAXI','TNC1','TNC2')").copy() + co['timeperiod1'] = co['timeperiod'] + 1 + co = co.join( + tod_skims.iat_df( + pd.DataFrame({ + 'otaz': co['o_zone'] - 1, + 'dtaz': co['d_zone'] - 1, + }) + ) + ) + tod_model = tod_model_builder(purpose, data_co=co, ch_name='timeperiod1') + tod_model.estimate() + display(HTML(f"

{tod_model.title}

")) + display(tod_model.parameter_summary()) + display(tod_model.estimation_statistics()) + + xl = tod_model.to_xlsx( + cached_todmodel_filename(purpose), + save_now=True + ) + tod_models[purpose] = tod_model + + if to_pickle: + if to_pickle is True: + to_pickle = dh.filenames.cache_dir / "tod_models.pkl" + import cloudpickle + with open(to_pickle, "wb") as f: + cloudpickle.dump(tod_models, f) + + # save cached parameters + param_yaml_file = dh.filenames.cache_dir / "tod_model_parameters.yaml" + with open(param_yaml_file, 'w', encoding="utf-8") as cmp_yaml: + print("---", file=cmp_yaml) + for purpose in tod_models.keys(): + print(f"{purpose}:", file=cmp_yaml) + for k, v in tod_models[purpose].pf.value.items(): + if ':' in k: + k = f'"{k}"' + print(f' {k:24s}: {v}', file=cmp_yaml) + print("", file=cmp_yaml) + print("...", file=cmp_yaml) + + return tod_models \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__init__.py new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/__init__.py new file mode 100644 index 0000000..d81e905 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/__init__.py @@ -0,0 +1,467 @@ +import numba +import numpy as np + +from .f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM import o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM +from .f_transit_ivtt_PEAK import transit_ivtt_PEAK +from .f_transit_ivtt_OFFPEAK import transit_ivtt_OFFPEAK +from .f_transit_ovtt_PEAK import transit_ovtt_PEAK +from .f_transit_ovtt_OFFPEAK import transit_ovtt_OFFPEAK +from .f_transit_fare_PEAK import transit_fare_PEAK +from .f_transit_fare_OFFPEAK import transit_fare_OFFPEAK +from .f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW import piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW +from .f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI import piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI +from .f_autopropensity import autopropensity +from .f_auto_time_PEAK import auto_time_PEAK +from .f_auto_dist_PEAK import auto_dist_PEAK +from .f_auto_time_OFFPEAK import auto_time_OFFPEAK +from .f_auto_dist_OFFPEAK import auto_dist_OFFPEAK +from .f_auto_opcost_PEAK import auto_opcost_PEAK +from .f_auto_opcost_hov_PEAK import auto_opcost_hov_PEAK +from .f_auto_opcost_OFFPEAK import auto_opcost_OFFPEAK +from .f_auto_toll_hiinc_PEAK import auto_toll_hiinc_PEAK +from .f_auto_toll_loinc_PEAK import auto_toll_loinc_PEAK +from .f_auto_toll_hov_hiinc_PEAK import auto_toll_hov_hiinc_PEAK +from .f_auto_toll_hov_loinc_PEAK import auto_toll_hov_loinc_PEAK +from .f_auto_toll_OFFPEAK import auto_toll_OFFPEAK +from .f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W import piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W +from .f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET import piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET +from .f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD import piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD +from .f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P import piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P +from .f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK import piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK +from .f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD import piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD +from .f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ import piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ +from .f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX import piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX +from .f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS import piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS +from .f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B import piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B +from .f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R import piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R +from .f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63 import piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63 +from .f_taxi_fare_PEAK import taxi_fare_PEAK +from .f_taxi_fare_OFFPEAK import taxi_fare_OFFPEAK +from .f_tnc_solo_fare_PEAK import tnc_solo_fare_PEAK +from .f_tnc_solo_fare_OFFPEAK import tnc_solo_fare_OFFPEAK +from .f_tnc_pool_fare_PEAK import tnc_pool_fare_PEAK +from .f_tnc_pool_fare_OFFPEAK import tnc_pool_fare_OFFPEAK +from .f_taxi_wait_time_PEAK import taxi_wait_time_PEAK +from .f_taxi_wait_time_OFFPEAK import taxi_wait_time_OFFPEAK +from .f_tnc_solo_wait_time_PEAK import tnc_solo_wait_time_PEAK +from .f_tnc_solo_wait_time_OFFPEAK import tnc_solo_wait_time_OFFPEAK +from .f_tnc_pool_wait_time_PEAK import tnc_pool_wait_time_PEAK +from .f_tnc_pool_wait_time_OFFPEAK import tnc_pool_wait_time_OFFPEAK +from .f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2 import taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2 +from .f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6 import taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6 +from .f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS import tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS +from .f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO import tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO +from .f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV import tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV +from .f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB import tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB +from .f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR import fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR +from .f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN import fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN +from .f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL import fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL +from .f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID import fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID +from .f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF import fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF +from .f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI import fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI +from .f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7 import fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7 +from .f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX import fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX +from .f_log_attractions_HBWH import log_attractions_HBWH +from .f_log_attractions_HBWL import log_attractions_HBWL +from .f_log_attractions_HBS import log_attractions_HBS +from .f_log_attractions_HBO import log_attractions_HBO +from .f_log_attractions_NHB import log_attractions_NHB +from .f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V import log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V +from .f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD import log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD +from .f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL import log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL +from .f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ import log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ +from .f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM import log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM + + +@numba.jit(cache=True, parallel=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def runner(argarray, inputarray, __attractions__HBO, __attractions__HBS, __attractions__HBWH, __attractions__HBWL, __attractions__NHB, __auto_skims__am_dist, __auto_skims__am_opcost, __auto_skims__am_opcost_hov, __auto_skims__am_time, __auto_skims__am_toll_hiinc, __auto_skims__am_toll_hov_hiinc, __auto_skims__am_toll_hov_loinc, __auto_skims__am_toll_loinc, __auto_skims__md_dist, __auto_skims__md_opcost, __auto_skims__md_time, __auto_skims__md_toll, __d_autopropensity__autopropensity, __dzone__zone_type, __ozone__taxi_wait_op, __ozone__taxi_wait_pk, __ozone__tnc_pool_wait_op, __ozone__tnc_pool_wait_pk, __ozone__tnc_solo_wait_op, __ozone__tnc_solo_wait_pk, __ozone__zone_type, __transit_op__fare, __transit_op__ivtt, __transit_op__ovtt, __transit_pk__fare, __transit_pk__ivtt, __transit_pk__ovtt, dtype=np.float64, min_shape_0=0): + out_size = max(argarray.shape[0], min_shape_0) + if out_size != argarray.shape[0]: + result = np.zeros((out_size, 70), dtype=dtype) + else: + result = np.empty((out_size, 70), dtype=dtype) + if out_size > 1000: + for j in numba.prange(out_size): + result[j, 0] = o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM(argarray[j], inputarray[j], result[j], ) + result[j, 1] = transit_ivtt_PEAK(argarray[j], inputarray[j], result[j], __transit_pk__ivtt) + result[j, 2] = transit_ivtt_OFFPEAK(argarray[j], inputarray[j], result[j], __transit_op__ivtt) + result[j, 3] = transit_ovtt_PEAK(argarray[j], inputarray[j], result[j], __transit_pk__ovtt) + result[j, 4] = transit_ovtt_OFFPEAK(argarray[j], inputarray[j], result[j], __transit_op__ovtt) + result[j, 5] = transit_fare_PEAK(argarray[j], inputarray[j], result[j], __transit_pk__fare) + result[j, 6] = transit_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __transit_op__fare) + result[j, 7] = piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW(argarray[j], inputarray[j], result[j], ) + result[j, 8] = piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI(argarray[j], inputarray[j], result[j], ) + result[j, 9] = autopropensity(argarray[j], inputarray[j], result[j], __d_autopropensity__autopropensity) + result[j, 10] = auto_time_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_time) + result[j, 11] = auto_dist_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 12] = auto_time_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_time) + result[j, 13] = auto_dist_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 14] = auto_opcost_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_opcost) + result[j, 15] = auto_opcost_hov_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_opcost_hov) + result[j, 16] = auto_opcost_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_opcost) + result[j, 17] = auto_toll_hiinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_hiinc) + result[j, 18] = auto_toll_loinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_loinc) + result[j, 19] = auto_toll_hov_hiinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_hov_hiinc) + result[j, 20] = auto_toll_hov_loinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_hov_loinc) + result[j, 21] = auto_toll_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_toll) + result[j, 22] = piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 23] = piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 24] = piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 25] = piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 26] = piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 27] = piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 28] = piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 29] = piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 30] = piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 31] = piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 32] = piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 33] = piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 34] = taxi_fare_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __auto_skims__am_time) + result[j, 35] = taxi_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __auto_skims__md_time) + result[j, 36] = tnc_solo_fare_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __auto_skims__am_time) + result[j, 37] = tnc_solo_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __auto_skims__md_time) + result[j, 38] = tnc_pool_fare_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __auto_skims__am_time) + result[j, 39] = tnc_pool_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __auto_skims__md_time) + result[j, 40] = taxi_wait_time_PEAK(argarray[j], inputarray[j], result[j], __ozone__taxi_wait_pk) + result[j, 41] = taxi_wait_time_OFFPEAK(argarray[j], inputarray[j], result[j], __ozone__taxi_wait_op) + result[j, 42] = tnc_solo_wait_time_PEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_solo_wait_pk) + result[j, 43] = tnc_solo_wait_time_OFFPEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_solo_wait_op) + result[j, 44] = tnc_pool_wait_time_PEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_pool_wait_pk) + result[j, 45] = tnc_pool_wait_time_OFFPEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_pool_wait_op) + result[j, 46] = taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __ozone__taxi_wait_pk) + result[j, 47] = taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __ozone__taxi_wait_op) + result[j, 48] = tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __ozone__tnc_solo_wait_pk) + result[j, 49] = tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __ozone__tnc_solo_wait_op) + result[j, 50] = tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __ozone__tnc_pool_wait_pk) + result[j, 51] = tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __ozone__tnc_pool_wait_op) + result[j, 52] = fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 53] = fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 54] = fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 55] = fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 56] = fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 57] = fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 58] = fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 59] = fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 60] = log_attractions_HBWH(argarray[j], inputarray[j], result[j], __attractions__HBWH) + result[j, 61] = log_attractions_HBWL(argarray[j], inputarray[j], result[j], __attractions__HBWL) + result[j, 62] = log_attractions_HBS(argarray[j], inputarray[j], result[j], __attractions__HBS) + result[j, 63] = log_attractions_HBO(argarray[j], inputarray[j], result[j], __attractions__HBO) + result[j, 64] = log_attractions_NHB(argarray[j], inputarray[j], result[j], __attractions__NHB) + result[j, 65] = log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V(argarray[j], inputarray[j], result[j], __attractions__HBWH) + result[j, 66] = log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD(argarray[j], inputarray[j], result[j], __attractions__HBWL) + result[j, 67] = log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL(argarray[j], inputarray[j], result[j], __attractions__HBS) + result[j, 68] = log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ(argarray[j], inputarray[j], result[j], __attractions__HBO) + result[j, 69] = log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM(argarray[j], inputarray[j], result[j], __attractions__NHB) + else: + for j in range(out_size): + result[j, 0] = o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM(argarray[j], inputarray[j], result[j], ) + result[j, 1] = transit_ivtt_PEAK(argarray[j], inputarray[j], result[j], __transit_pk__ivtt) + result[j, 2] = transit_ivtt_OFFPEAK(argarray[j], inputarray[j], result[j], __transit_op__ivtt) + result[j, 3] = transit_ovtt_PEAK(argarray[j], inputarray[j], result[j], __transit_pk__ovtt) + result[j, 4] = transit_ovtt_OFFPEAK(argarray[j], inputarray[j], result[j], __transit_op__ovtt) + result[j, 5] = transit_fare_PEAK(argarray[j], inputarray[j], result[j], __transit_pk__fare) + result[j, 6] = transit_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __transit_op__fare) + result[j, 7] = piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW(argarray[j], inputarray[j], result[j], ) + result[j, 8] = piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI(argarray[j], inputarray[j], result[j], ) + result[j, 9] = autopropensity(argarray[j], inputarray[j], result[j], __d_autopropensity__autopropensity) + result[j, 10] = auto_time_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_time) + result[j, 11] = auto_dist_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 12] = auto_time_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_time) + result[j, 13] = auto_dist_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 14] = auto_opcost_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_opcost) + result[j, 15] = auto_opcost_hov_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_opcost_hov) + result[j, 16] = auto_opcost_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_opcost) + result[j, 17] = auto_toll_hiinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_hiinc) + result[j, 18] = auto_toll_loinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_loinc) + result[j, 19] = auto_toll_hov_hiinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_hov_hiinc) + result[j, 20] = auto_toll_hov_loinc_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_toll_hov_loinc) + result[j, 21] = auto_toll_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_toll) + result[j, 22] = piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 23] = piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 24] = piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 25] = piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 26] = piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 27] = piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD(argarray[j], inputarray[j], result[j], __auto_skims__am_dist) + result[j, 28] = piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 29] = piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 30] = piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 31] = piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 32] = piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 33] = piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63(argarray[j], inputarray[j], result[j], __auto_skims__md_dist) + result[j, 34] = taxi_fare_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __auto_skims__am_time) + result[j, 35] = taxi_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __auto_skims__md_time) + result[j, 36] = tnc_solo_fare_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __auto_skims__am_time) + result[j, 37] = tnc_solo_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __auto_skims__md_time) + result[j, 38] = tnc_pool_fare_PEAK(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __auto_skims__am_time) + result[j, 39] = tnc_pool_fare_OFFPEAK(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __auto_skims__md_time) + result[j, 40] = taxi_wait_time_PEAK(argarray[j], inputarray[j], result[j], __ozone__taxi_wait_pk) + result[j, 41] = taxi_wait_time_OFFPEAK(argarray[j], inputarray[j], result[j], __ozone__taxi_wait_op) + result[j, 42] = tnc_solo_wait_time_PEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_solo_wait_pk) + result[j, 43] = tnc_solo_wait_time_OFFPEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_solo_wait_op) + result[j, 44] = tnc_pool_wait_time_PEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_pool_wait_pk) + result[j, 45] = tnc_pool_wait_time_OFFPEAK(argarray[j], inputarray[j], result[j], __ozone__tnc_pool_wait_op) + result[j, 46] = taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __ozone__taxi_wait_pk) + result[j, 47] = taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __ozone__taxi_wait_op) + result[j, 48] = tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __ozone__tnc_solo_wait_pk) + result[j, 49] = tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __ozone__tnc_solo_wait_op) + result[j, 50] = tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV(argarray[j], inputarray[j], result[j], __auto_skims__am_dist, __ozone__tnc_pool_wait_pk) + result[j, 51] = tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB(argarray[j], inputarray[j], result[j], __auto_skims__md_dist, __ozone__tnc_pool_wait_op) + result[j, 52] = fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 53] = fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 54] = fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 55] = fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 56] = fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 57] = fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 58] = fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 59] = fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX(argarray[j], inputarray[j], result[j], __dzone__zone_type, __ozone__zone_type) + result[j, 60] = log_attractions_HBWH(argarray[j], inputarray[j], result[j], __attractions__HBWH) + result[j, 61] = log_attractions_HBWL(argarray[j], inputarray[j], result[j], __attractions__HBWL) + result[j, 62] = log_attractions_HBS(argarray[j], inputarray[j], result[j], __attractions__HBS) + result[j, 63] = log_attractions_HBO(argarray[j], inputarray[j], result[j], __attractions__HBO) + result[j, 64] = log_attractions_NHB(argarray[j], inputarray[j], result[j], __attractions__NHB) + result[j, 65] = log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V(argarray[j], inputarray[j], result[j], __attractions__HBWH) + result[j, 66] = log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD(argarray[j], inputarray[j], result[j], __attractions__HBWL) + result[j, 67] = log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL(argarray[j], inputarray[j], result[j], __attractions__HBS) + result[j, 68] = log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ(argarray[j], inputarray[j], result[j], __attractions__HBO) + result[j, 69] = log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM(argarray[j], inputarray[j], result[j], __attractions__NHB) + return result + +def _map_index(dim_name, values): + raise KeyError(dim_name) + + +def set_shared_data(transit_pk, transit_op, auto_skims, ozone, dzone, attractions, o_autopropensity, d_autopropensity): + global name_space + name_space = {} + name_space['__transit_pk__ivtt'] = transit_pk['ivtt'] + name_space['__transit_pk__ovtt'] = transit_pk['ovtt'] + name_space['__transit_pk__headway'] = transit_pk['headway'] + name_space['__transit_pk__fare'] = transit_pk['fare'] + name_space['__transit_pk__firstmode'] = transit_pk['firstmode'] + name_space['__transit_pk__prioritymode'] = transit_pk['prioritymode'] + name_space['__transit_pk__lastmode'] = transit_pk['lastmode'] + name_space['__transit_op__ivtt'] = transit_op['ivtt'] + name_space['__transit_op__ovtt'] = transit_op['ovtt'] + name_space['__transit_op__headway'] = transit_op['headway'] + name_space['__transit_op__fare'] = transit_op['fare'] + name_space['__transit_op__firstmode'] = transit_op['firstmode'] + name_space['__transit_op__prioritymode'] = transit_op['prioritymode'] + name_space['__transit_op__lastmode'] = transit_op['lastmode'] + name_space['__auto_skims__am_time'] = auto_skims['am_time'] + name_space['__auto_skims__am_dist'] = auto_skims['am_dist'] + name_space['__auto_skims__am_toll_loinc'] = auto_skims['am_toll_loinc'] + name_space['__auto_skims__am_toll_hiinc'] = auto_skims['am_toll_hiinc'] + name_space['__auto_skims__md_time'] = auto_skims['md_time'] + name_space['__auto_skims__md_dist'] = auto_skims['md_dist'] + name_space['__auto_skims__md_toll'] = auto_skims['md_toll'] + name_space['__auto_skims__am_time_hov'] = auto_skims['am_time_hov'] + name_space['__auto_skims__am_dist_hov'] = auto_skims['am_dist_hov'] + name_space['__auto_skims__am_toll_hov_loinc'] = auto_skims['am_toll_hov_loinc'] + name_space['__auto_skims__am_toll_hov_hiinc'] = auto_skims['am_toll_hov_hiinc'] + name_space['__auto_skims__am_opcost'] = auto_skims['am_opcost'] + name_space['__auto_skims__am_opcost_hov'] = auto_skims['am_opcost_hov'] + name_space['__auto_skims__md_opcost'] = auto_skims['md_opcost'] + name_space['__ozone__zone_type'] = ozone['zone_type'] + name_space['__ozone__pnr_parking_cost'] = ozone['pnr_parking_cost'] + name_space['__ozone__zone_income'] = ozone['zone_income'] + name_space['__ozone__pnr_flag'] = ozone['pnr_flag'] + name_space['__ozone__first_wait_bus_peak'] = ozone['first_wait_bus_peak'] + name_space['__ozone__first_wait_bus_offpeak'] = ozone['first_wait_bus_offpeak'] + name_space['__ozone__first_wait_feeder_peak'] = ozone['first_wait_feeder_peak'] + name_space['__ozone__first_wait_feeder_offpeak'] = ozone['first_wait_feeder_offpeak'] + name_space['__ozone__autocc'] = ozone['autocc'] + name_space['__ozone__taxi_wait_pk'] = ozone['taxi_wait_pk'] + name_space['__ozone__taxi_wait_op'] = ozone['taxi_wait_op'] + name_space['__ozone__tnc_solo_wait_pk'] = ozone['tnc_solo_wait_pk'] + name_space['__ozone__tnc_solo_wait_op'] = ozone['tnc_solo_wait_op'] + name_space['__ozone__tnc_pool_wait_pk'] = ozone['tnc_pool_wait_pk'] + name_space['__ozone__tnc_pool_wait_op'] = ozone['tnc_pool_wait_op'] + name_space['__dzone__zone_type'] = dzone['zone_type'] + name_space['__dzone__pnr_parking_cost'] = dzone['pnr_parking_cost'] + name_space['__dzone__zone_income'] = dzone['zone_income'] + name_space['__dzone__pnr_flag'] = dzone['pnr_flag'] + name_space['__dzone__first_wait_bus_peak'] = dzone['first_wait_bus_peak'] + name_space['__dzone__first_wait_bus_offpeak'] = dzone['first_wait_bus_offpeak'] + name_space['__dzone__first_wait_feeder_peak'] = dzone['first_wait_feeder_peak'] + name_space['__dzone__first_wait_feeder_offpeak'] = dzone['first_wait_feeder_offpeak'] + name_space['__dzone__autocc'] = dzone['autocc'] + name_space['__dzone__taxi_wait_pk'] = dzone['taxi_wait_pk'] + name_space['__dzone__taxi_wait_op'] = dzone['taxi_wait_op'] + name_space['__dzone__tnc_solo_wait_pk'] = dzone['tnc_solo_wait_pk'] + name_space['__dzone__tnc_solo_wait_op'] = dzone['tnc_solo_wait_op'] + name_space['__dzone__tnc_pool_wait_pk'] = dzone['tnc_pool_wait_pk'] + name_space['__dzone__tnc_pool_wait_op'] = dzone['tnc_pool_wait_op'] + name_space['__attractions__HBO'] = attractions['HBO'] + name_space['__attractions__HBS'] = attractions['HBS'] + name_space['__attractions__HBWH'] = attractions['HBWH'] + name_space['__attractions__HBWL'] = attractions['HBWL'] + name_space['__attractions__NHB'] = attractions['NHB'] + name_space['__o_autopropensity__autopropensity'] = o_autopropensity['autopropensity'] + name_space['__d_autopropensity__autopropensity'] = d_autopropensity['autopropensity'] + + +meta_match_names_idx = {'otaz_idx': 0, 'dtaz_idx': 1} + + +import numpy as np +import numba as nb +import pandas as pd +import pyarrow as pa +import xarray as xr +import sharrow as sh +import inspect +import warnings +from contextlib import suppress + + + + +def load_raw(args, inputs, name_space, runner, dtype=None): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', category=nb.NumbaExperimentalFeatureWarning) + if len(args): + assembled_args = np.stack(args).T + else: + assembled_args = None + if len(inputs): + assembled_inputs = np.stack(inputs).T + else: + assembled_inputs = np.empty([assembled_args.shape[0], 0], dtype=np.float32) + if assembled_args is None: + assembled_args = np.empty([assembled_inputs.shape[0], 0], dtype=np.float32) + try: + named_args = ['__attractions__HBO', '__attractions__HBS', '__attractions__HBWH', '__attractions__HBWL', '__attractions__NHB', '__auto_skims__am_dist', '__auto_skims__am_opcost', '__auto_skims__am_opcost_hov', '__auto_skims__am_time', '__auto_skims__am_toll_hiinc', '__auto_skims__am_toll_hov_hiinc', '__auto_skims__am_toll_hov_loinc', '__auto_skims__am_toll_loinc', '__auto_skims__md_dist', '__auto_skims__md_opcost', '__auto_skims__md_time', '__auto_skims__md_toll', '__d_autopropensity__autopropensity', '__dzone__zone_type', '__ozone__taxi_wait_op', '__ozone__taxi_wait_pk', '__ozone__tnc_pool_wait_op', '__ozone__tnc_pool_wait_pk', '__ozone__tnc_solo_wait_op', '__ozone__tnc_solo_wait_pk', '__ozone__zone_type', '__transit_op__fare', '__transit_op__ivtt', '__transit_op__ovtt', '__transit_pk__fare', '__transit_pk__ivtt', '__transit_pk__ovtt'] + arguments = [] + for arg in named_args: + next_arg = name_space[arg] + if isinstance(next_arg, xr.DataArray): + next_arg = next_arg.load() + arguments.append(np.asarray(next_arg)) + if dtype is not None: + return runner(assembled_args, assembled_inputs, *arguments, dtype=dtype) + else: + return runner(assembled_args, assembled_inputs, *arguments) + except nb.TypingError: + raise + except KeyError as err: + # raise the inner key error which is more helpful + context = getattr(err, "__context__", None) + if context: + raise context + else: + raise err + + +def load( + source, + as_dataframe=False, + as_table=False, + dtype=None, +): + if source is None: + raise ValueError("no base table or source table") + indexes = _get_indexes(source)[0] + inputs = _get_inputs(source) + result = load_raw(indexes, inputs, name_space, runner=runner, dtype=dtype) + if as_dataframe: + index = getattr(source, 'index', None) + return pd.DataFrame(result, index=index, columns=function_names) + elif as_table: + return pa.table({k: result[:, n] for n, k in enumerate(function_names)}) + return result + + +def merge(source, dtype=None): + """ + Merge the data created by this flow into the source. + + Parameters + ---------- + source : Dataset or Table or DataFrame + dtype : str or dtype + The loaded data will be generated with this dtype. + + Returns + ------- + merged : Dataset or Table or DataFrame + The same data type as `source` is returned. + """ + assert isinstance(source, (xr.Dataset, pa.Table, pd.DataFrame, sh.Table)) + new_cols = load(source, dtype=dtype) + if isinstance(source, (pa.Table, sh.Table)): + for n, k in enumerate(function_names): + source = source.append_column(k, [new_cols[:, n]]) + else: + for n, k in enumerate(function_names): + source[k] = new_cols[:, n] + return source + + +def _get_indexes(source_table, cache_dynamic_indexes=None): + if cache_dynamic_indexes is None: + cache_dynamic_indexes = True + + def geti(i): + nonlocal source_table + if i is not None: + try: + return np.asarray(source_table[i]) + except KeyError: + if i[:10] == '__dynamic_': + if "@" in i: + i_complete = i + i, i_from = i.split("@", 1) + else: + i_complete = i + i_from = i[10:] + index_to_map = None + with suppress(KeyError): + index_to_map = source_table[i_from] + if index_to_map is None: + if isinstance(source_table, pd.DataFrame): + if i_from == "index" and source_table.index.names == [None]: + index_to_map = source_table.index + elif i_from in source_table.index.names: + index_to_map = source_table.index.get_level_values(i_from) + if index_to_map is None: + raise KeyError(i_complete) + indexed_vals = _map_index(i[10:], index_to_map) + if cache_dynamic_indexes: + if isinstance(source_table, (pa.Table)): + source_table = source_table.append_column(i_complete, [indexed_vals]) + else: + source_table[i_complete] = indexed_vals + return indexed_vals + else: + idx = getattr(source_table, 'index', None) + if idx is not None: + if i in idx.names: + return np.asarray(idx.get_level_values(i)) + if i == 'index' and len(idx.names)==1: + return np.asarray(idx) + raise + else: + return np.arange(source_table.shape[0]) + index_keys = meta_match_names_idx.keys() + return tuple(geti(i) for i in index_keys), source_table + + +def _get_inputs(source_table, dtype=np.float32): + input_keys = input_name_positions.keys() + return tuple( + np.asarray(source_table[i], dtype=dtype) + for i in input_keys + ) + + + +input_name_positions = {'dtaz': 0, 'otaz': 1} +function_names = ['o_zone == dtaz', 'transit_ivtt_PEAK', 'transit_ivtt_OFFPEAK', 'transit_ovtt_PEAK', 'transit_ovtt_OFFPEAK', 'transit_fare_PEAK', 'transit_fare_OFFPEAK', 'piece(transit_ivtt_OFFPEAK, None, 20)', 'piece(transit_ivtt_OFFPEAK, 20, None)', 'autopropensity', 'auto_time_PEAK', 'auto_dist_PEAK', 'auto_time_OFFPEAK', 'auto_dist_OFFPEAK', 'auto_opcost_PEAK', 'auto_opcost_hov_PEAK', 'auto_opcost_OFFPEAK', 'auto_toll_hiinc_PEAK', 'auto_toll_loinc_PEAK', 'auto_toll_hov_hiinc_PEAK', 'auto_toll_hov_loinc_PEAK', 'auto_toll_OFFPEAK', 'piece(auto_dist_PEAK,None,0.5)', 'piece(auto_dist_PEAK,0.5,1.0)', 'piece(auto_dist_PEAK,1.0,None)', 'piece(auto_dist_PEAK,None,5)', 'piece(auto_dist_PEAK,5,10)', 'piece(auto_dist_PEAK,10,None)', 'piece(auto_dist_OFFPEAK,None,0.5)', 'piece(auto_dist_OFFPEAK,0.5,1.0)', 'piece(auto_dist_OFFPEAK,1.0,None)', 'piece(auto_dist_OFFPEAK,None,5)', 'piece(auto_dist_OFFPEAK,5,10)', 'piece(auto_dist_OFFPEAK,10,None)', 'taxi_fare_PEAK', 'taxi_fare_OFFPEAK', 'tnc_solo_fare_PEAK', 'tnc_solo_fare_OFFPEAK', 'tnc_pool_fare_PEAK', 'tnc_pool_fare_OFFPEAK', 'taxi_wait_time_PEAK', 'taxi_wait_time_OFFPEAK', 'tnc_solo_wait_time_PEAK', 'tnc_solo_wait_time_OFFPEAK', 'tnc_pool_wait_time_PEAK', 'tnc_pool_wait_time_OFFPEAK', 'taxi_wait_time_PEAK/auto_dist_PEAK', 'taxi_wait_time_OFFPEAK/auto_dist_OFFPEAK', 'tnc_solo_wait_time_PEAK/auto_dist_PEAK', 'tnc_solo_wait_time_OFFPEAK/auto_dist_OFFPEAK', 'tnc_pool_wait_time_PEAK/auto_dist_PEAK', 'tnc_pool_wait_time_OFFPEAK/auto_dist_OFFPEAK', 'fmax(ozone_areatype, areatype)==1', 'fmax(ozone_areatype, areatype)==2', 'fmax(ozone_areatype, areatype)==3', 'fmax(ozone_areatype, areatype)==4', 'fmin(ozone_areatype, areatype)==1', 'fmin(ozone_areatype, areatype)==2', 'fmin(ozone_areatype, areatype)==3', 'fmin(ozone_areatype, areatype)==4', 'log_attractions_HBWH', 'log_attractions_HBWL', 'log_attractions_HBS', 'log_attractions_HBO', 'log_attractions_NHB', 'log_attractions_HBWH > -666', 'log_attractions_HBWL > -666', 'log_attractions_HBS > -666', 'log_attractions_HBO > -666', 'log_attractions_NHB > -666'] + +# Greetings, tinkerer! The `defs_hash` included here is a safety +# measure to prevent unknowing users creating a mess by modifying +# the code in this module so that it no longer matches the expected +# variable definitions. If you want to modify this code, you should +# delete this hash to allow the code to run without any checks, but +# you do so at your own risk. +defs_hash = 'XUCQEOOTEO3UREF2YYT73XUJ24======' diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/__init__.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/__init__.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_funcs.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_funcs.py new file mode 100644 index 0000000..4a2efbf --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_funcs.py @@ -0,0 +1,6 @@ +import numba +import numpy as np +import pickle + +taxi_cost = pickle.loads(b'\x80\x05\x95\x17\x05\x00\x00\x00\x00\x00\x00\x8c\x14numba.core.serialize\x94\x8c\x0ecustom_rebuild\x94\x93\x94h\x00\x8c\x18_unpickle__CustomPickled\x94\x93\x94B\xbf\x04\x00\x00\x80\x04\x95\xb4\x04\x00\x00\x00\x00\x00\x00\x8c\x13numba.core.registry\x94\x8c\rCPUDispatcher\x94\x93\x94}\x94(\x8c\x04uuid\x94\x8c$6003875c-d52d-11eb-8449-acde48001122\x94\x8c\x07py_func\x94\x8c\x14numba.core.serialize\x94\x8c\x11_rebuild_function\x94\x93\x94(K\x04C\x04a\r\r\n\x94B"\x03\x00\x00\xe3\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x03\x00\x00\x00C\x00\x00\x00s^\x00\x00\x00|\x04j\x00|\x00|\x04j\x01\x14\x00\x17\x00|\x01|\x04j\x02\x14\x00\x17\x00}\x05|\x04j\x03rZd\x01}\x06t\x04|\x04j\x05j\x06\x83\x01D\x00]\x1a}\x07|\x04j\x05|\x07\x19\x00|\x02k\x02r0d\x02}\x06\x01\x00qLq0|\x06rZ|\x05|\x04j\x037\x00}\x05|\x05S\x00)\x03\xe1U\x01\x00\x00\n Compute taxi fare.\n\n A single set of rates (Chicago medallion rates for in-city trips)\n is used; fares for taxi trips outside Chicago are close to this\n rate and rare enough that more precision is unneeded.\n\n Parameters\n ----------\n auto_time, auto_dist : array-like\n\n Returns\n -------\n fare : array-like\n FT)\x07\xda\tflag_pull\xda\nper_minute\xda\x08per_mile\xda\x12airport_pickup_fee\xda\x05range\xda\x14airport_pickup_zones\xda\x04size)\x08\xda\tauto_time\xda\tauto_dist\xda\x06o_zone\xda\x06d_zone\xda\x10taxi_cost_struct\xda\x04cost\xda\x0ebucket_applies\xda\x01i\xa9\x00r\x11\x00\x00\x00\xfa`/Users/jeffnewman/LocalGit/cmap_trip-based_model/src/Mode-Dest-TOD/cmap_modedest/fast/tnc_los.py\xda\ttaxi_cost \x00\x00\x00s\x1e\x00\x00\x00\x00\x12\x04\x01\x08\xff\x02\x02\x08\xfe\x02\xff\x02\x05\x06\x01\x04\x01\x10\x01\x0e\x01\x04\x01\x06\x01\x04\x01\n\x02\x94\x87\x94}\x94(\x8c\x05range\x94\x8c\x08builtins\x94\x8c\x05range\x94\x93\x94\x8c\x08__name__\x94\x8c\x1acmap_modedest.fast.tnc_los\x94u\x8c\ttaxi_cost\x94NNt\x94R\x94h\x07\x8c\x12_function_setstate\x94\x93\x94h\x16}\x94\x8c\x05cells\x94)s\x86R0\x8c\x06locals\x94}\x94\x8c\rtargetoptions\x94}\x94(\x8c\x08nopython\x94\x88\x8c\x0bboundscheck\x94Nu\x8c\timpl_kind\x94\x8c\x06direct\x94\x8c\x0bcan_compile\x94\x88\x8c\x04sigs\x94]\x94u\x86\x94.\x94\x85\x94R\x94\x85\x94R\x94.') +tnc_cost = pickle.loads(b'\x80\x05\x95\xf2\x05\x00\x00\x00\x00\x00\x00\x8c\x14numba.core.serialize\x94\x8c\x0ecustom_rebuild\x94\x93\x94h\x00\x8c\x18_unpickle__CustomPickled\x94\x93\x94B\x9a\x05\x00\x00\x80\x04\x95\x8f\x05\x00\x00\x00\x00\x00\x00\x8c\x13numba.core.registry\x94\x8c\rCPUDispatcher\x94\x93\x94}\x94(\x8c\x04uuid\x94\x8c$60039bfc-d52d-11eb-8449-acde48001122\x94\x8c\x07py_func\x94\x8c\x14numba.core.serialize\x94\x8c\x11_rebuild_function\x94\x93\x94(K\x04C\x04a\r\r\n\x94B\xe5\x03\x00\x00\xe3\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x03\x00\x00\x00C\x00\x00\x00s\xcc\x00\x00\x00|\x04j\x00|\x00\x14\x00|\x04j\x01|\x01\x14\x00\x17\x00|\x04j\x02\x17\x00}\x05t\x03|\x05|\x04j\x04\x83\x02|\x04j\x05\x17\x00}\x05|\x04j\x06rzd\x01}\x06t\x07|\x04j\x08j\t\x83\x01D\x00](}\x07|\x04j\x08|\x07\x19\x00|\x02k\x02sb|\x04j\x08|\x07\x19\x00|\x03k\x02rBd\x02}\x06\x01\x00qlqB|\x06rz|\x05|\x04j\x067\x00}\x05|\x04j\nr\xc8d\x01}\x06t\x07|\x04j\x0bj\t\x83\x01D\x00](}\x07|\x04j\x0b|\x07\x19\x00|\x02k\x02s\xb0|\x04j\x0b|\x07\x19\x00|\x03k\x02r\x90d\x02}\x06\x01\x00q\xbaq\x90|\x06r\xc8|\x05|\x04j\n7\x00}\x05|\x05S\x00)\x03\xe1n\x01\x00\x00\n Compute the TNC cost.\n\n Parameters\n ----------\n auto_time, auto_dist : float\n The auto travel time and distance for a set of trips.\n o_zone, d_zone : int\n Zone numbers for origin and destination\n tnc_cost_struct : TncCostStruct\n Use the correct struct for peak/offpeak and solo/shared.\n\n Returns\n -------\n float\n FT)\x0c\xda\nper_minute\xda\x08per_mile\xda\tbase_fare\xda\x03max\xda\x08min_fare\xda\x0bbooking_fee\xda\x0bspecial_fee\xda\x05range\xda\rspecial_zones\xda\x04size\xda\x0cdowntown_fee\xda\x0edowntown_zones)\x08\xda\tauto_time\xda\tauto_dist\xda\x06o_zone\xda\x06d_zone\xda\x0ftnc_cost_struct\xda\x04cost\xda\x0ebucket_applies\xda\x01i\xa9\x00r\x16\x00\x00\x00\xfa`/Users/jeffnewman/LocalGit/cmap_trip-based_model/src/Mode-Dest-TOD/cmap_modedest/fast/tnc_los.py\xda\x08tnc_costA\x00\x00\x00s0\x00\x00\x00\x00\x13\x08\x01\x08\xff\x02\x02\x04\xfe\x02\xff\x02\x05\x12\x02\x06\x01\x04\x01\x10\x01\x1c\x01\x04\x01\x06\x01\x04\x01\n\x02\x06\x01\x04\x01\x10\x01\x1c\x01\x04\x01\x06\x01\x04\x01\n\x02\x94\x87\x94}\x94(\x8c\x03max\x94\x8c\x08builtins\x94\x8c\x03max\x94\x93\x94\x8c\x05range\x94\x8c\x08builtins\x94\x8c\x05range\x94\x93\x94\x8c\x08__name__\x94\x8c\x1acmap_modedest.fast.tnc_los\x94u\x8c\x08tnc_cost\x94NNt\x94R\x94h\x07\x8c\x12_function_setstate\x94\x93\x94h\x1a}\x94\x8c\x05cells\x94)s\x86R0\x8c\x06locals\x94}\x94\x8c\rtargetoptions\x94}\x94(\x8c\x08nopython\x94\x88\x8c\x0bboundscheck\x94Nu\x8c\timpl_kind\x94\x8c\x06direct\x94\x8c\x0bcan_compile\x94\x88\x8c\x04sigs\x94]\x94u\x86\x94.\x94\x85\x94R\x94\x85\x94R\x94.') diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_funcs.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_funcs.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_vars.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_vars.py new file mode 100644 index 0000000..4f90f20 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_vars.py @@ -0,0 +1,7 @@ +import pickle + +taxi_cost_struct = pickle.loads(b'\x80\x05\x95\xd9\x00\x00\x00\x00\x00\x00\x00\x8c\x1acmap_modedest.fast.tnc_los\x94\x8c\x0eTaxiCostStruct\x94\x93\x94(ME\x01G@D\xd5`A\x897LK\xe1M\x90\x01\x8c\x12numpy.core.numeric\x94\x8c\x0b_frombuffer\x94\x93\x94(\x96 \x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x00\xee\x01\x00\x00\x00\x00\x00\x00\xf3\x01\x00\x00\x00\x00\x00\x00\x94\x8c\x05numpy\x94\x8c\x05dtype\x94\x93\x94\x8c\x02i8\x94\x89\x88\x87\x94R\x94(K\x03\x8c\x01<\x94NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00t\x94bK\x04\x85\x94\x8c\x01C\x94t\x94R\x94t\x94\x81\x94.') +tnc_solo_peak_struct = pickle.loads(b'\x80\x05\x95\xd1\x02\x00\x00\x00\x00\x00\x00\x8c\x1acmap_modedest.fast.tnc_los\x94\x8c\rTncCostStruct\x94\x93\x94(K\x88K\x1cKmM\xe5\x01M\x01\x01M\xf4\x01K\x00\x8c\x12numpy.core.numeric\x94\x8c\x0b_frombuffer\x94\x93\x94(\x968\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x00\xee\x01\x00\x00\x00\x00\x00\x00\xf3\x01\x00\x00\x00\x00\x00\x00p\x00\x00\x00\x00\x00\x00\x00q\x00\x00\x00\x00\x00\x00\x00\x94\x8c\x05numpy\x94\x8c\x05dtype\x94\x93\x94\x8c\x02i8\x94\x89\x88\x87\x94R\x94(K\x03\x8c\x01<\x94NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00t\x94bK\x07\x85\x94\x8c\x01C\x94t\x94R\x94h\x05(\x96\xc8\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\x00\x00\x00\x00\'\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x009\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x94h\x0cK9\x85\x94h\x10t\x94R\x94t\x94\x81\x94.') +tnc_solo_offpeak_struct = pickle.loads(b'\x80\x05\x95\xd1\x02\x00\x00\x00\x00\x00\x00\x8c\x1acmap_modedest.fast.tnc_los\x94\x8c\rTncCostStruct\x94\x93\x94(K\x88K\x1cKmM\xe5\x01M\x01\x01M\xf4\x01K\x00\x8c\x12numpy.core.numeric\x94\x8c\x0b_frombuffer\x94\x93\x94(\x968\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x00\xee\x01\x00\x00\x00\x00\x00\x00\xf3\x01\x00\x00\x00\x00\x00\x00p\x00\x00\x00\x00\x00\x00\x00q\x00\x00\x00\x00\x00\x00\x00\x94\x8c\x05numpy\x94\x8c\x05dtype\x94\x93\x94\x8c\x02i8\x94\x89\x88\x87\x94R\x94(K\x03\x8c\x01<\x94NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00t\x94bK\x07\x85\x94\x8c\x01C\x94t\x94R\x94h\x05(\x96\xc8\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\x00\x00\x00\x00\'\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x009\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x94h\x0cK9\x85\x94h\x10t\x94R\x94t\x94\x81\x94.') +tnc_pool_peak_struct = pickle.loads(b'\x80\x05\x95\xd0\x02\x00\x00\x00\x00\x00\x00\x8c\x1acmap_modedest.fast.tnc_los\x94\x8c\rTncCostStruct\x94\x93\x94(KDK\x00KjK\x00M\x01\x01M\xf4\x01K\x00\x8c\x12numpy.core.numeric\x94\x8c\x0b_frombuffer\x94\x93\x94(\x968\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x00\xee\x01\x00\x00\x00\x00\x00\x00\xf3\x01\x00\x00\x00\x00\x00\x00p\x00\x00\x00\x00\x00\x00\x00q\x00\x00\x00\x00\x00\x00\x00\x94\x8c\x05numpy\x94\x8c\x05dtype\x94\x93\x94\x8c\x02i8\x94\x89\x88\x87\x94R\x94(K\x03\x8c\x01<\x94NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00t\x94bK\x07\x85\x94\x8c\x01C\x94t\x94R\x94h\x05(\x96\xc8\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\x00\x00\x00\x00\'\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x009\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x94h\x0cK9\x85\x94h\x10t\x94R\x94t\x94\x81\x94.') +tnc_pool_offpeak_struct = pickle.loads(b'\x80\x05\x95\xd0\x02\x00\x00\x00\x00\x00\x00\x8c\x1acmap_modedest.fast.tnc_los\x94\x8c\rTncCostStruct\x94\x93\x94(KDK\x00KjK\x00M\x01\x01M\xf4\x01K\x00\x8c\x12numpy.core.numeric\x94\x8c\x0b_frombuffer\x94\x93\x94(\x968\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x00~\x00\x00\x00\x00\x00\x00\x00\xee\x01\x00\x00\x00\x00\x00\x00\xf3\x01\x00\x00\x00\x00\x00\x00p\x00\x00\x00\x00\x00\x00\x00q\x00\x00\x00\x00\x00\x00\x00\x94\x8c\x05numpy\x94\x8c\x05dtype\x94\x93\x94\x8c\x02i8\x94\x89\x88\x87\x94R\x94(K\x03\x8c\x01<\x94NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00t\x94bK\x07\x85\x94\x8c\x01C\x94t\x94R\x94h\x05(\x96\xc8\x01\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00\x07\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00\x00\t\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00\x00\x00\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x0e\x00\x00\x00\x00\x00\x00\x00\x0f\x00\x00\x00\x00\x00\x00\x00\x10\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00\x00\x00\x00\x00\x12\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x14\x00\x00\x00\x00\x00\x00\x00\x15\x00\x00\x00\x00\x00\x00\x00\x16\x00\x00\x00\x00\x00\x00\x00\x17\x00\x00\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\x00\x19\x00\x00\x00\x00\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x00\x00\x1f\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x00\x00\x00"\x00\x00\x00\x00\x00\x00\x00#\x00\x00\x00\x00\x00\x00\x00$\x00\x00\x00\x00\x00\x00\x00%\x00\x00\x00\x00\x00\x00\x00&\x00\x00\x00\x00\x00\x00\x00\'\x00\x00\x00\x00\x00\x00\x00(\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00\x00\x00\x00\x00*\x00\x00\x00\x00\x00\x00\x00+\x00\x00\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x00\x00\x00-\x00\x00\x00\x00\x00\x00\x00.\x00\x00\x00\x00\x00\x00\x00/\x00\x00\x00\x00\x00\x00\x001\x00\x00\x00\x00\x00\x00\x002\x00\x00\x00\x00\x00\x00\x003\x00\x00\x00\x00\x00\x00\x004\x00\x00\x00\x00\x00\x00\x007\x00\x00\x00\x00\x00\x00\x008\x00\x00\x00\x00\x00\x00\x009\x00\x00\x00\x00\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00=\x00\x00\x00\x00\x00\x00\x00>\x00\x00\x00\x00\x00\x00\x00?\x00\x00\x00\x00\x00\x00\x00\x94h\x0cK9\x85\x94h\x10t\x94R\x94t\x94\x81\x94.') diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_vars.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/extra_vars.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_OFFPEAK.py new file mode 100644 index 0000000..a50153a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_dist_OFFPEAK( + _args, + _inputs, + _outputs, + __auto_skims__md_dist +): + return __auto_skims__md_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_PEAK.py new file mode 100644 index 0000000..53e50be --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_dist_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_dist +): + return __auto_skims__am_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_dist_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_OFFPEAK.py new file mode 100644 index 0000000..4107f13 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_opcost_OFFPEAK( + _args, + _inputs, + _outputs, + __auto_skims__md_opcost +): + return __auto_skims__md_opcost[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_PEAK.py new file mode 100644 index 0000000..043d805 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_opcost_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_opcost +): + return __auto_skims__am_opcost[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_hov_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_hov_PEAK.py new file mode 100644 index 0000000..3cb9fcc --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_hov_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_opcost_hov_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_opcost_hov +): + return __auto_skims__am_opcost_hov[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_hov_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_opcost_hov_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_OFFPEAK.py new file mode 100644 index 0000000..fcface8 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_time_OFFPEAK( + _args, + _inputs, + _outputs, + __auto_skims__md_time +): + return __auto_skims__md_time[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_PEAK.py new file mode 100644 index 0000000..308ec21 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_time_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_time +): + return __auto_skims__am_time[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_time_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_OFFPEAK.py new file mode 100644 index 0000000..c169b1c --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_toll_OFFPEAK( + _args, + _inputs, + _outputs, + __auto_skims__md_toll +): + return np.fmax(__auto_skims__md_toll[_args[0], _args[1]], 0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hiinc_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hiinc_PEAK.py new file mode 100644 index 0000000..61d7089 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hiinc_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_toll_hiinc_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_toll_hiinc +): + return np.fmax(__auto_skims__am_toll_hiinc[_args[0], _args[1]], 0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hiinc_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hiinc_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_hiinc_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_hiinc_PEAK.py new file mode 100644 index 0000000..d77ec33 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_hiinc_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_toll_hov_hiinc_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_toll_hov_hiinc +): + return np.fmax(__auto_skims__am_toll_hov_hiinc[_args[0], _args[1]], 0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_hiinc_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_hiinc_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_loinc_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_loinc_PEAK.py new file mode 100644 index 0000000..22c7941 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_loinc_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_toll_hov_loinc_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_toll_hov_loinc +): + return np.fmax(__auto_skims__am_toll_hov_loinc[_args[0], _args[1]], 0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_loinc_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_hov_loinc_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_loinc_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_loinc_PEAK.py new file mode 100644 index 0000000..bda3b6a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_loinc_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_toll_loinc_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_toll_loinc +): + return np.fmax(__auto_skims__am_toll_loinc[_args[0], _args[1]], 0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_loinc_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_auto_toll_loinc_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_autopropensity.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_autopropensity.py new file mode 100644 index 0000000..26d0d4d --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_autopropensity.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def autopropensity( + _args, + _inputs, + _outputs, + __d_autopropensity__autopropensity +): + return __d_autopropensity__autopropensity[_args[1],] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_autopropensity.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_autopropensity.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py new file mode 100644 index 0000000..78cb643 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return max(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 1 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___1_OWXSNW5EFKHSRO2IUCB6DHTR.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py new file mode 100644 index 0000000..63aa595 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return max(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 2 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___2_FIT25FYRGELBEONPX2MTPZFN.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py new file mode 100644 index 0000000..fffecee --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return max(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 3 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___3_LIPIKNXA6ZB3PUNRJBVIHATL.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py new file mode 100644 index 0000000..576db9b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return max(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 4 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmax_ozone_areatype__areatype___4_J3D56DXM2MR6NEMIQ6ALSFID.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py new file mode 100644 index 0000000..14d4e60 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return min(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 1 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___1_OTNZJFEFZT7N3JG6YKEUWGTF.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py new file mode 100644 index 0000000..1e743ea --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return min(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 2 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___2_FY4D7BMCO2N4QRIA6QIIWTZI.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py new file mode 100644 index 0000000..c7c4a5d --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return min(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 3 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___3_34BD5WGYZOPLALWPB2MCWKA7.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX.py new file mode 100644 index 0000000..44f26be --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX( + _args, + _inputs, + _outputs, + __dzone__zone_type, __ozone__zone_type +): + return min(__ozone__zone_type[_args[0],], __dzone__zone_type[_args[1],]) == 4 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_fmin_ozone_areatype__areatype___4_64S6AODYPVZP57LTAC522OHX.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO.py new file mode 100644 index 0000000..ad7884f --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBO( + _args, + _inputs, + _outputs, + __attractions__HBO +): + return log(__attractions__HBO[_args[1],]) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py new file mode 100644 index 0000000..bcdbdeb --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ( + _args, + _inputs, + _outputs, + __attractions__HBO +): + return log(__attractions__HBO[_args[1],]) > -666 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBO____666_5VORECHSLO2A6MKP5I3SGJVQ.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS.py new file mode 100644 index 0000000..50a1cb5 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBS( + _args, + _inputs, + _outputs, + __attractions__HBS +): + return log(__attractions__HBS[_args[1],]) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py new file mode 100644 index 0000000..dac95e3 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL( + _args, + _inputs, + _outputs, + __attractions__HBS +): + return log(__attractions__HBS[_args[1],]) > -666 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBS____666_L3ZMVRT365KFSBLEDVABFEGL.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH.py new file mode 100644 index 0000000..2e92b51 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBWH( + _args, + _inputs, + _outputs, + __attractions__HBWH +): + return log(__attractions__HBWH[_args[1],]) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py new file mode 100644 index 0000000..638cd9e --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V( + _args, + _inputs, + _outputs, + __attractions__HBWH +): + return log(__attractions__HBWH[_args[1],]) > -666 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWH____666_GW3RKVJQOVET3XE7MYE2MA7V.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL.py new file mode 100644 index 0000000..bf302cc --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBWL( + _args, + _inputs, + _outputs, + __attractions__HBWL +): + return log(__attractions__HBWL[_args[1],]) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py new file mode 100644 index 0000000..03e9d24 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD( + _args, + _inputs, + _outputs, + __attractions__HBWL +): + return log(__attractions__HBWL[_args[1],]) > -666 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_HBWL____666_IQGLCTAX7EZOXKEFCIBK33BD.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB.py new file mode 100644 index 0000000..a76ad09 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_NHB( + _args, + _inputs, + _outputs, + __attractions__NHB +): + return log(__attractions__NHB[_args[1],]) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py new file mode 100644 index 0000000..529c3ff --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM( + _args, + _inputs, + _outputs, + __attractions__NHB +): + return log(__attractions__NHB[_args[1],]) > -666 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_log_attractions_NHB____666_3GFB7KMY3JN5TSJE4MRRR2HM.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py new file mode 100644 index 0000000..8d0d860 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM( + _args, + _inputs, + _outputs, + +): + return _inputs[1] == _inputs[0] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_o_zone____dtaz_HXCH5HUPIDPV3EWONWFXBZHM.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py new file mode 100644 index 0000000..11bc0b9 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX( + _args, + _inputs, + _outputs, + __auto_skims__md_dist +): + return piece(__auto_skims__md_dist[_args[0], _args[1]], 0.5, 1.0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_0_5_1_0__HZLL3YOGUR763JRQHG7SM6TX.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py new file mode 100644 index 0000000..0d67afc --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63( + _args, + _inputs, + _outputs, + __auto_skims__md_dist +): + return piece(__auto_skims__md_dist[_args[0], _args[1]], 10, None) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_10_None__6EE7X5PWAQKBS6WQUONWVI63.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py new file mode 100644 index 0000000..cbe8bc9 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS( + _args, + _inputs, + _outputs, + __auto_skims__md_dist +): + return piece(__auto_skims__md_dist[_args[0], _args[1]], 1.0, None) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_1_0_None__FBK6GF2KEWWDN7AL3ENVH3VS.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py new file mode 100644 index 0000000..d93d41c --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R( + _args, + _inputs, + _outputs, + __auto_skims__md_dist +): + return piece(__auto_skims__md_dist[_args[0], _args[1]], 5, 10) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_5_10__5RQTWWGPPCPP6EQU6ZV5MX2R.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py new file mode 100644 index 0000000..55a397b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ( + _args, + _inputs, + _outputs, + __auto_skims__md_dist +): + return piece(__auto_skims__md_dist[_args[0], _args[1]], None, 0.5) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_0_5__537AWC5AWFXLM3TRB3PPSGYZ.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py new file mode 100644 index 0000000..8aa0e5c --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B( + _args, + _inputs, + _outputs, + __auto_skims__md_dist +): + return piece(__auto_skims__md_dist[_args[0], _args[1]], None, 5) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_OFFPEAK_None_5__YWXA4HRZAVEZKC7EV5M2AX3B.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py new file mode 100644 index 0000000..f3e83e1 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET( + _args, + _inputs, + _outputs, + __auto_skims__am_dist +): + return piece(__auto_skims__am_dist[_args[0], _args[1]], 0.5, 1.0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_0_5_1_0__4K5ZPM55FQJVFMWKUPZIQ2ET.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py new file mode 100644 index 0000000..5cdfe54 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD( + _args, + _inputs, + _outputs, + __auto_skims__am_dist +): + return piece(__auto_skims__am_dist[_args[0], _args[1]], 10, None) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_10_None__L3GKJNRUTTFCDUYV65K7KFQD.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py new file mode 100644 index 0000000..aaadc74 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD( + _args, + _inputs, + _outputs, + __auto_skims__am_dist +): + return piece(__auto_skims__am_dist[_args[0], _args[1]], 1.0, None) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_1_0_None__FMBHM5APW4TIH6B5EKSKSXYD.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py new file mode 100644 index 0000000..552904b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK( + _args, + _inputs, + _outputs, + __auto_skims__am_dist +): + return piece(__auto_skims__am_dist[_args[0], _args[1]], 5, 10) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_5_10__DSXTFACXD5HSWU7YKUPQEGAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py new file mode 100644 index 0000000..869dc31 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W( + _args, + _inputs, + _outputs, + __auto_skims__am_dist +): + return piece(__auto_skims__am_dist[_args[0], _args[1]], None, 0.5) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_0_5__NZ6HG4EJYEENT2OAOBDF3W5W.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py new file mode 100644 index 0000000..b605969 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P( + _args, + _inputs, + _outputs, + __auto_skims__am_dist +): + return piece(__auto_skims__am_dist[_args[0], _args[1]], None, 5) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_auto_dist_PEAK_None_5__7D72ALZRBNSP634JYUY7IV5P.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py new file mode 100644 index 0000000..4e77239 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI( + _args, + _inputs, + _outputs, + +): + return piece(_outputs[2], 20, None) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__20__None__2SYXPZCTOY3PKAO2L4ALLHLI.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py new file mode 100644 index 0000000..59e58bd --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW( + _args, + _inputs, + _outputs, + +): + return piece(_outputs[2], None, 20) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_piece_transit_ivtt_OFFPEAK__None__20__54N5BOFSYCN6SMRBKXM4V4TW.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_OFFPEAK.py new file mode 100644 index 0000000..07b281b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def taxi_fare_OFFPEAK( + _args, + _inputs, + _outputs, + __auto_skims__md_dist, __auto_skims__md_time +): + return taxi_cost(__auto_skims__md_time[_args[0], _args[1]], __auto_skims__md_dist[_args[0], _args[1]], _inputs[1], _inputs[0], taxi_cost_struct) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_PEAK.py new file mode 100644 index 0000000..2dc2c8b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def taxi_fare_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_dist, __auto_skims__am_time +): + return taxi_cost(__auto_skims__am_time[_args[0], _args[1]], __auto_skims__am_dist[_args[0], _args[1]], _inputs[1], _inputs[0], taxi_cost_struct) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_fare_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py new file mode 100644 index 0000000..f40744c --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def taxi_wait_time_OFFPEAK( + _args, + _inputs, + _outputs, + __ozone__taxi_wait_op +): + return __ozone__taxi_wait_op[_args[0],] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py new file mode 100644 index 0000000..0156f1a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6( + _args, + _inputs, + _outputs, + __auto_skims__md_dist, __ozone__taxi_wait_op +): + return __ozone__taxi_wait_op[_args[0],] / __auto_skims__md_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_OFFPEAK_auto_dist_OFFPEAK_HC62HOLRZIWJJDAOIFX5XHV6.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK.py new file mode 100644 index 0000000..8a09c16 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def taxi_wait_time_PEAK( + _args, + _inputs, + _outputs, + __ozone__taxi_wait_pk +): + return __ozone__taxi_wait_pk[_args[0],] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py new file mode 100644 index 0000000..585a40a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2( + _args, + _inputs, + _outputs, + __auto_skims__am_dist, __ozone__taxi_wait_pk +): + return __ozone__taxi_wait_pk[_args[0],] / __auto_skims__am_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_taxi_wait_time_PEAK_auto_dist_PEAK_CBYSKDURSGAJ4RHX2ASS76Q2.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py new file mode 100644 index 0000000..90bf1df --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_pool_fare_OFFPEAK( + _args, + _inputs, + _outputs, + __auto_skims__md_dist, __auto_skims__md_time +): + return tnc_cost(__auto_skims__md_time[_args[0], _args[1]], __auto_skims__md_dist[_args[0], _args[1]], _inputs[1], _inputs[0], tnc_pool_offpeak_struct) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_PEAK.py new file mode 100644 index 0000000..68906b3 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_pool_fare_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_dist, __auto_skims__am_time +): + return tnc_cost(__auto_skims__am_time[_args[0], _args[1]], __auto_skims__am_dist[_args[0], _args[1]], _inputs[1], _inputs[0], tnc_pool_peak_struct) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_fare_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py new file mode 100644 index 0000000..a190a78 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_pool_wait_time_OFFPEAK( + _args, + _inputs, + _outputs, + __ozone__tnc_pool_wait_op +): + return __ozone__tnc_pool_wait_op[_args[0],] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py new file mode 100644 index 0000000..88e23d4 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB( + _args, + _inputs, + _outputs, + __auto_skims__md_dist, __ozone__tnc_pool_wait_op +): + return __ozone__tnc_pool_wait_op[_args[0],] / __auto_skims__md_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_OFFPEAK_auto_dist_OFFPEAK_FNBOP5IL57Q6SQM4VB7EXQBB.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py new file mode 100644 index 0000000..8e749a2 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_pool_wait_time_PEAK( + _args, + _inputs, + _outputs, + __ozone__tnc_pool_wait_pk +): + return __ozone__tnc_pool_wait_pk[_args[0],] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py new file mode 100644 index 0000000..90bfa02 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV( + _args, + _inputs, + _outputs, + __auto_skims__am_dist, __ozone__tnc_pool_wait_pk +): + return __ozone__tnc_pool_wait_pk[_args[0],] / __auto_skims__am_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_pool_wait_time_PEAK_auto_dist_PEAK_NHA453KUTMUKTUCSMA2XQQZV.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py new file mode 100644 index 0000000..83a3231 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_solo_fare_OFFPEAK( + _args, + _inputs, + _outputs, + __auto_skims__md_dist, __auto_skims__md_time +): + return tnc_cost(__auto_skims__md_time[_args[0], _args[1]], __auto_skims__md_dist[_args[0], _args[1]], _inputs[1], _inputs[0], tnc_solo_offpeak_struct) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_PEAK.py new file mode 100644 index 0000000..d6256cf --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_solo_fare_PEAK( + _args, + _inputs, + _outputs, + __auto_skims__am_dist, __auto_skims__am_time +): + return tnc_cost(__auto_skims__am_time[_args[0], _args[1]], __auto_skims__am_dist[_args[0], _args[1]], _inputs[1], _inputs[0], tnc_solo_peak_struct) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_fare_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py new file mode 100644 index 0000000..8e40c74 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_solo_wait_time_OFFPEAK( + _args, + _inputs, + _outputs, + __ozone__tnc_solo_wait_op +): + return __ozone__tnc_solo_wait_op[_args[0],] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py new file mode 100644 index 0000000..ea179b2 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO( + _args, + _inputs, + _outputs, + __auto_skims__md_dist, __ozone__tnc_solo_wait_op +): + return __ozone__tnc_solo_wait_op[_args[0],] / __auto_skims__md_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_OFFPEAK_auto_dist_OFFPEAK_CA5RZWRWZJWFNZATH2HHD3TO.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py new file mode 100644 index 0000000..d3a8667 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_solo_wait_time_PEAK( + _args, + _inputs, + _outputs, + __ozone__tnc_solo_wait_pk +): + return __ozone__tnc_solo_wait_pk[_args[0],] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py new file mode 100644 index 0000000..7c55798 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS( + _args, + _inputs, + _outputs, + __auto_skims__am_dist, __ozone__tnc_solo_wait_pk +): + return __ozone__tnc_solo_wait_pk[_args[0],] / __auto_skims__am_dist[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_tnc_solo_wait_time_PEAK_auto_dist_PEAK_2EZZEATSM4EAHST74DMGSFSS.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_OFFPEAK.py new file mode 100644 index 0000000..e401cfc --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_fare_OFFPEAK( + _args, + _inputs, + _outputs, + __transit_op__fare +): + return __transit_op__fare[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_PEAK.py new file mode 100644 index 0000000..3f1b119 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_fare_PEAK( + _args, + _inputs, + _outputs, + __transit_pk__fare +): + return __transit_pk__fare[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_fare_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_OFFPEAK.py new file mode 100644 index 0000000..5862f24 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_ivtt_OFFPEAK( + _args, + _inputs, + _outputs, + __transit_op__ivtt +): + return __transit_op__ivtt[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_PEAK.py new file mode 100644 index 0000000..09e64ce --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_ivtt_PEAK( + _args, + _inputs, + _outputs, + __transit_pk__ivtt +): + return __transit_pk__ivtt[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ivtt_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_OFFPEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_OFFPEAK.py new file mode 100644 index 0000000..d149882 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_OFFPEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_ovtt_OFFPEAK( + _args, + _inputs, + _outputs, + __transit_op__ovtt +): + return __transit_op__ovtt[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_OFFPEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_OFFPEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_PEAK.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_PEAK.py new file mode 100644 index 0000000..3a13606 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_PEAK.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid +from .extra_funcs import * +from .extra_vars import * + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_ovtt_PEAK( + _args, + _inputs, + _outputs, + __transit_pk__ovtt +): + return __transit_pk__ovtt[_args[0], _args[1]] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_PEAK.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S1/f_transit_ovtt_PEAK.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/__init__.py new file mode 100644 index 0000000..a7c1930 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/__init__.py @@ -0,0 +1,312 @@ +import numba +import numpy as np + +from .f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX import transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX +from .f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S import transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S +from .f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J import transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J +from .f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP import transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP +from .f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73 import transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73 +from .f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM import transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM +from .f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2 import transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2 +from .f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V import transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V +from .f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST import hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST +from .f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO import hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO +from .f_auto_parking_cost_HBWH import auto_parking_cost_HBWH +from .f_auto_parking_cost_HBWL import auto_parking_cost_HBWL +from .f_auto_parking_cost_HBO import auto_parking_cost_HBO +from .f_auto_parking_cost_HBS import auto_parking_cost_HBS +from .f_auto_parking_cost_NHB import auto_parking_cost_NHB +from .f_auto_parking_cost_HBOR import auto_parking_cost_HBOR +from .f_auto_parking_cost_NHBR import auto_parking_cost_NHBR +from .f_auto_parking_cost_NHBS import auto_parking_cost_NHBS +from .f_samp_wgt import samp_wgt +from .f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL import log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL +from .f_transit_avail_HBWH import transit_avail_HBWH +from .f_transit_avail_HBWL import transit_avail_HBWL +from .f_transit_avail_HBS import transit_avail_HBS +from .f_transit_avail_HBO import transit_avail_HBO +from .f_transit_avail_NHB import transit_avail_NHB +from .f_auto_avail_HBWH import auto_avail_HBWH +from .f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3 import _1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3 +from .f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE import _1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE +from .f_auto_avail_HBWL import auto_avail_HBWL +from .f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63 import _1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63 +from .f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2 import _1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2 +from .f_auto_avail_HBS import auto_avail_HBS +from .f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX import _1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX +from .f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6 import _1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6 +from .f_auto_avail_HBO import auto_avail_HBO +from .f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX import _1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX +from .f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY import _1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY +from .f_auto_avail_NHB import auto_avail_NHB +from .f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6 import _1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6 +from .f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF import _1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF + + +@numba.jit(cache=True, parallel=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def runner(argarray, inputarray, dtype=np.float64, min_shape_0=0): + out_size = max(argarray.shape[0], min_shape_0) + if out_size != argarray.shape[0]: + result = np.zeros((out_size, 40), dtype=dtype) + else: + result = np.empty((out_size, 40), dtype=dtype) + if out_size > 1000: + for j in numba.prange(out_size): + result[j, 0] = transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX(argarray[j], inputarray[j], result[j], ) + result[j, 1] = transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S(argarray[j], inputarray[j], result[j], ) + result[j, 2] = transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J(argarray[j], inputarray[j], result[j], ) + result[j, 3] = transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP(argarray[j], inputarray[j], result[j], ) + result[j, 4] = transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73(argarray[j], inputarray[j], result[j], ) + result[j, 5] = transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM(argarray[j], inputarray[j], result[j], ) + result[j, 6] = transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2(argarray[j], inputarray[j], result[j], ) + result[j, 7] = transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V(argarray[j], inputarray[j], result[j], ) + result[j, 8] = hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST(argarray[j], inputarray[j], result[j], ) + result[j, 9] = hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO(argarray[j], inputarray[j], result[j], ) + result[j, 10] = auto_parking_cost_HBWH(argarray[j], inputarray[j], result[j], ) + result[j, 11] = auto_parking_cost_HBWL(argarray[j], inputarray[j], result[j], ) + result[j, 12] = auto_parking_cost_HBO(argarray[j], inputarray[j], result[j], ) + result[j, 13] = auto_parking_cost_HBS(argarray[j], inputarray[j], result[j], ) + result[j, 14] = auto_parking_cost_NHB(argarray[j], inputarray[j], result[j], ) + result[j, 15] = auto_parking_cost_HBOR(argarray[j], inputarray[j], result[j], ) + result[j, 16] = auto_parking_cost_NHBR(argarray[j], inputarray[j], result[j], ) + result[j, 17] = auto_parking_cost_NHBS(argarray[j], inputarray[j], result[j], ) + result[j, 18] = samp_wgt(argarray[j], inputarray[j], result[j], ) + result[j, 19] = log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL(argarray[j], inputarray[j], result[j], ) + result[j, 20] = transit_avail_HBWH(argarray[j], inputarray[j], result[j], ) + result[j, 21] = transit_avail_HBWL(argarray[j], inputarray[j], result[j], ) + result[j, 22] = transit_avail_HBS(argarray[j], inputarray[j], result[j], ) + result[j, 23] = transit_avail_HBO(argarray[j], inputarray[j], result[j], ) + result[j, 24] = transit_avail_NHB(argarray[j], inputarray[j], result[j], ) + result[j, 25] = auto_avail_HBWH(argarray[j], inputarray[j], result[j], ) + result[j, 26] = _1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3(argarray[j], inputarray[j], result[j], ) + result[j, 27] = _1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE(argarray[j], inputarray[j], result[j], ) + result[j, 28] = auto_avail_HBWL(argarray[j], inputarray[j], result[j], ) + result[j, 29] = _1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63(argarray[j], inputarray[j], result[j], ) + result[j, 30] = _1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2(argarray[j], inputarray[j], result[j], ) + result[j, 31] = auto_avail_HBS(argarray[j], inputarray[j], result[j], ) + result[j, 32] = _1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX(argarray[j], inputarray[j], result[j], ) + result[j, 33] = _1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6(argarray[j], inputarray[j], result[j], ) + result[j, 34] = auto_avail_HBO(argarray[j], inputarray[j], result[j], ) + result[j, 35] = _1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX(argarray[j], inputarray[j], result[j], ) + result[j, 36] = _1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY(argarray[j], inputarray[j], result[j], ) + result[j, 37] = auto_avail_NHB(argarray[j], inputarray[j], result[j], ) + result[j, 38] = _1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6(argarray[j], inputarray[j], result[j], ) + result[j, 39] = _1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF(argarray[j], inputarray[j], result[j], ) + else: + for j in range(out_size): + result[j, 0] = transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX(argarray[j], inputarray[j], result[j], ) + result[j, 1] = transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S(argarray[j], inputarray[j], result[j], ) + result[j, 2] = transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J(argarray[j], inputarray[j], result[j], ) + result[j, 3] = transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP(argarray[j], inputarray[j], result[j], ) + result[j, 4] = transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73(argarray[j], inputarray[j], result[j], ) + result[j, 5] = transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM(argarray[j], inputarray[j], result[j], ) + result[j, 6] = transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2(argarray[j], inputarray[j], result[j], ) + result[j, 7] = transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V(argarray[j], inputarray[j], result[j], ) + result[j, 8] = hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST(argarray[j], inputarray[j], result[j], ) + result[j, 9] = hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO(argarray[j], inputarray[j], result[j], ) + result[j, 10] = auto_parking_cost_HBWH(argarray[j], inputarray[j], result[j], ) + result[j, 11] = auto_parking_cost_HBWL(argarray[j], inputarray[j], result[j], ) + result[j, 12] = auto_parking_cost_HBO(argarray[j], inputarray[j], result[j], ) + result[j, 13] = auto_parking_cost_HBS(argarray[j], inputarray[j], result[j], ) + result[j, 14] = auto_parking_cost_NHB(argarray[j], inputarray[j], result[j], ) + result[j, 15] = auto_parking_cost_HBOR(argarray[j], inputarray[j], result[j], ) + result[j, 16] = auto_parking_cost_NHBR(argarray[j], inputarray[j], result[j], ) + result[j, 17] = auto_parking_cost_NHBS(argarray[j], inputarray[j], result[j], ) + result[j, 18] = samp_wgt(argarray[j], inputarray[j], result[j], ) + result[j, 19] = log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL(argarray[j], inputarray[j], result[j], ) + result[j, 20] = transit_avail_HBWH(argarray[j], inputarray[j], result[j], ) + result[j, 21] = transit_avail_HBWL(argarray[j], inputarray[j], result[j], ) + result[j, 22] = transit_avail_HBS(argarray[j], inputarray[j], result[j], ) + result[j, 23] = transit_avail_HBO(argarray[j], inputarray[j], result[j], ) + result[j, 24] = transit_avail_NHB(argarray[j], inputarray[j], result[j], ) + result[j, 25] = auto_avail_HBWH(argarray[j], inputarray[j], result[j], ) + result[j, 26] = _1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3(argarray[j], inputarray[j], result[j], ) + result[j, 27] = _1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE(argarray[j], inputarray[j], result[j], ) + result[j, 28] = auto_avail_HBWL(argarray[j], inputarray[j], result[j], ) + result[j, 29] = _1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63(argarray[j], inputarray[j], result[j], ) + result[j, 30] = _1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2(argarray[j], inputarray[j], result[j], ) + result[j, 31] = auto_avail_HBS(argarray[j], inputarray[j], result[j], ) + result[j, 32] = _1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX(argarray[j], inputarray[j], result[j], ) + result[j, 33] = _1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6(argarray[j], inputarray[j], result[j], ) + result[j, 34] = auto_avail_HBO(argarray[j], inputarray[j], result[j], ) + result[j, 35] = _1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX(argarray[j], inputarray[j], result[j], ) + result[j, 36] = _1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY(argarray[j], inputarray[j], result[j], ) + result[j, 37] = auto_avail_NHB(argarray[j], inputarray[j], result[j], ) + result[j, 38] = _1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6(argarray[j], inputarray[j], result[j], ) + result[j, 39] = _1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF(argarray[j], inputarray[j], result[j], ) + return result + +def _map_index(dim_name, values): + raise KeyError(dim_name) + + +def set_shared_data(): + global name_space + name_space = {} + + +meta_match_names_idx = {} + + +import numpy as np +import numba as nb +import pandas as pd +import pyarrow as pa +import xarray as xr +import sharrow as sh +import inspect +import warnings +from contextlib import suppress + + + + +def load_raw(args, inputs, name_space, runner, dtype=None): + with warnings.catch_warnings(): + warnings.filterwarnings('ignore', category=nb.NumbaExperimentalFeatureWarning) + if len(args): + assembled_args = np.stack(args).T + else: + assembled_args = None + if len(inputs): + assembled_inputs = np.stack(inputs).T + else: + assembled_inputs = np.empty([assembled_args.shape[0], 0], dtype=np.float32) + if assembled_args is None: + assembled_args = np.empty([assembled_inputs.shape[0], 0], dtype=np.float32) + try: + named_args = [] + arguments = [] + for arg in named_args: + next_arg = name_space[arg] + if isinstance(next_arg, xr.DataArray): + next_arg = next_arg.load() + arguments.append(np.asarray(next_arg)) + if dtype is not None: + return runner(assembled_args, assembled_inputs, *arguments, dtype=dtype) + else: + return runner(assembled_args, assembled_inputs, *arguments) + except nb.TypingError: + raise + except KeyError as err: + # raise the inner key error which is more helpful + context = getattr(err, "__context__", None) + if context: + raise context + else: + raise err + + +def load( + source, + as_dataframe=False, + as_table=False, + dtype=None, +): + if source is None: + raise ValueError("no base table or source table") + indexes = _get_indexes(source)[0] + inputs = _get_inputs(source) + result = load_raw(indexes, inputs, name_space, runner=runner, dtype=dtype) + if as_dataframe: + index = getattr(source, 'index', None) + return pd.DataFrame(result, index=index, columns=function_names) + elif as_table: + return pa.table({k: result[:, n] for n, k in enumerate(function_names)}) + return result + + +def merge(source, dtype=None): + """ + Merge the data created by this flow into the source. + + Parameters + ---------- + source : Dataset or Table or DataFrame + dtype : str or dtype + The loaded data will be generated with this dtype. + + Returns + ------- + merged : Dataset or Table or DataFrame + The same data type as `source` is returned. + """ + assert isinstance(source, (xr.Dataset, pa.Table, pd.DataFrame, sh.Table)) + new_cols = load(source, dtype=dtype) + if isinstance(source, (pa.Table, sh.Table)): + for n, k in enumerate(function_names): + source = source.append_column(k, [new_cols[:, n]]) + else: + for n, k in enumerate(function_names): + source[k] = new_cols[:, n] + return source + + +def _get_indexes(source_table, cache_dynamic_indexes=None): + if cache_dynamic_indexes is None: + cache_dynamic_indexes = True + + def geti(i): + nonlocal source_table + if i is not None: + try: + return np.asarray(source_table[i]) + except KeyError: + if i[:10] == '__dynamic_': + if "@" in i: + i_complete = i + i, i_from = i.split("@", 1) + else: + i_complete = i + i_from = i[10:] + index_to_map = None + with suppress(KeyError): + index_to_map = source_table[i_from] + if index_to_map is None: + if isinstance(source_table, pd.DataFrame): + if i_from == "index" and source_table.index.names == [None]: + index_to_map = source_table.index + elif i_from in source_table.index.names: + index_to_map = source_table.index.get_level_values(i_from) + if index_to_map is None: + raise KeyError(i_complete) + indexed_vals = _map_index(i[10:], index_to_map) + if cache_dynamic_indexes: + if isinstance(source_table, (pa.Table)): + source_table = source_table.append_column(i_complete, [indexed_vals]) + else: + source_table[i_complete] = indexed_vals + return indexed_vals + else: + idx = getattr(source_table, 'index', None) + if idx is not None: + if i in idx.names: + return np.asarray(idx.get_level_values(i)) + if i == 'index' and len(idx.names)==1: + return np.asarray(idx) + raise + else: + return np.arange(source_table.shape[0]) + index_keys = meta_match_names_idx.keys() + return tuple(geti(i) for i in index_keys), source_table + + +def _get_inputs(source_table, dtype=np.float32): + input_keys = input_name_positions.keys() + return tuple( + np.asarray(source_table[i], dtype=dtype) + for i in input_keys + ) + + + +input_name_positions = {'auto_dist_OFFPEAK': 0, 'auto_dist_PEAK': 1, 'log_attractions_HBO': 2, 'log_attractions_HBS': 3, 'log_attractions_HBWH': 4, 'log_attractions_HBWL': 5, 'log_attractions_NHB': 6, 'transit_approach_drivetime_OFFPEAK': 7, 'transit_approach_drivetime_PEAK': 8, 'transit_approach_waittime_OFFPEAK': 9, 'transit_approach_waittime_PEAK': 10, 'transit_approach_walktime_OFFPEAK': 11, 'transit_approach_walktime_PEAK': 12, 'transit_ivtt_OFFPEAK': 13, 'transit_ivtt_PEAK': 14, 'transit_ovtt_OFFPEAK': 15, 'transit_ovtt_PEAK': 16} +function_names = ['transit_approach_drivetime_PEAK/auto_dist_PEAK', 'transit_approach_waittime_PEAK/auto_dist_PEAK', 'transit_approach_walktime_PEAK/auto_dist_PEAK', 'transit_ovtt_PEAK/auto_dist_PEAK', 'transit_approach_drivetime_OFFPEAK/auto_dist_OFFPEAK', 'transit_approach_waittime_OFFPEAK/auto_dist_OFFPEAK', 'transit_approach_walktime_OFFPEAK/auto_dist_OFFPEAK', 'transit_ovtt_OFFPEAK/auto_dist_OFFPEAK', 'hard_sigmoid(transit_approach_walktime_PEAK, 4.0, 2.0)', 'hard_sigmoid(transit_approach_walktime_OFFPEAK, 4.0, 2.0)', 'auto_parking_cost_HBWH', 'auto_parking_cost_HBWL', 'auto_parking_cost_HBO', 'auto_parking_cost_HBS', 'auto_parking_cost_NHB', 'auto_parking_cost_HBOR', 'auto_parking_cost_NHBR', 'auto_parking_cost_NHBS', 'samp_wgt', 'log(1/samp_wgt)', 'transit_avail_HBWH', 'transit_avail_HBWL', 'transit_avail_HBS', 'transit_avail_HBO', 'transit_avail_NHB', 'auto_avail_HBWH', '1-auto_avail_HBWH', '1-transit_avail_HBWH', 'auto_avail_HBWL', '1-auto_avail_HBWL', '1-transit_avail_HBWL', 'auto_avail_HBS', '1-auto_avail_HBS', '1-transit_avail_HBS', 'auto_avail_HBO', '1-auto_avail_HBO', '1-transit_avail_HBO', 'auto_avail_NHB', '1-auto_avail_NHB', '1-transit_avail_NHB'] + +# Greetings, tinkerer! The `defs_hash` included here is a safety +# measure to prevent unknowing users creating a mess by modifying +# the code in this module so that it no longer matches the expected +# variable definitions. If you want to modify this code, you should +# delete this hash to allow the code to run without any checks, but +# you do so at your own risk. +defs_hash = 'JLORNT6V2GU5GKGOGY25DSK2SA======' diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/__init__.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/__init__.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py new file mode 100644 index 0000000..196f0d0 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[34] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBO_EKWWH33ZEA3VXLR4UYBVLRUX.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py new file mode 100644 index 0000000..6021d18 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[31] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBS_JA6SY3LPJJDVZQF7IFNL4EWX.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py new file mode 100644 index 0000000..50955fe --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[25] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWH_RSSCN3EFDQ2CM4RPVZVAP7K3.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py new file mode 100644 index 0000000..7bae017 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[28] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_HBWL_VWN3Q4WQRAVVJ5ZTYY4OHM63.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py new file mode 100644 index 0000000..01950cd --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[37] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_auto_avail_NHB_XHHWLREMVWOEBM6NUQF7EFH6.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py new file mode 100644 index 0000000..62e033c --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[23] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBO_K3RWOEPC3IXNAPRPQQJCHORY.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py new file mode 100644 index 0000000..8e1bdce --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[22] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBS_5CZV3HKDPQJDWZME2XMN7NW6.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py new file mode 100644 index 0000000..905c093 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[20] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWH_NMEWQX35KIWZJMZ5IZZTZHOE.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py new file mode 100644 index 0000000..132b894 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[21] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_HBWL_MPZ7IOPMILS7SZEG5T2D6HG2.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py new file mode 100644 index 0000000..15d6136 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def _1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF( + _args, + _inputs, + _outputs, + +): + return 1 - _outputs[24] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f__1_transit_avail_NHB_WN7OPNQOSVQ544PG5Q2ZGTNF.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBO.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBO.py new file mode 100644 index 0000000..97f64e8 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBO.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_avail_HBO( + _args, + _inputs, + _outputs, + +): + return _inputs[2] > -9998 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBO.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBO.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBS.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBS.py new file mode 100644 index 0000000..efa8332 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBS.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_avail_HBS( + _args, + _inputs, + _outputs, + +): + return _inputs[3] > -9998 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBS.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBS.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWH.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWH.py new file mode 100644 index 0000000..003f33a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWH.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_avail_HBWH( + _args, + _inputs, + _outputs, + +): + return _inputs[4] > -9998 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWH.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWH.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWL.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWL.py new file mode 100644 index 0000000..2c4dd9b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWL.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_avail_HBWL( + _args, + _inputs, + _outputs, + +): + return _inputs[5] > -9998 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWL.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_HBWL.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_NHB.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_NHB.py new file mode 100644 index 0000000..212f7a2 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_NHB.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_avail_NHB( + _args, + _inputs, + _outputs, + +): + return _inputs[6] > -9998 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_NHB.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_avail_NHB.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBO.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBO.py new file mode 100644 index 0000000..e672b1f --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBO.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_HBO( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBO.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBO.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBOR.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBOR.py new file mode 100644 index 0000000..66268b7 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBOR.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_HBOR( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBOR.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBOR.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBS.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBS.py new file mode 100644 index 0000000..df6d3ab --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBS.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_HBS( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBS.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBS.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWH.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWH.py new file mode 100644 index 0000000..0191aa2 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWH.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_HBWH( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWH.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWH.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWL.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWL.py new file mode 100644 index 0000000..bb94bb2 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWL.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_HBWL( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWL.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_HBWL.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHB.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHB.py new file mode 100644 index 0000000..d08c175 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHB.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_NHB( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHB.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHB.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBR.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBR.py new file mode 100644 index 0000000..47c2972 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBR.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_NHBR( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBR.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBR.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBS.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBS.py new file mode 100644 index 0000000..2b02df6 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBS.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def auto_parking_cost_NHBS( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBS.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_auto_parking_cost_NHBS.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py new file mode 100644 index 0000000..fac81d8 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO( + _args, + _inputs, + _outputs, + +): + return hard_sigmoid(_inputs[11], 4.0, 2.0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_OFFPEAK__4_0__2_0__FPYQ4GNCVUNJNUMJTUIBMLKO.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py new file mode 100644 index 0000000..e0bd3be --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST( + _args, + _inputs, + _outputs, + +): + return hard_sigmoid(_inputs[12], 4.0, 2.0) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_hard_sigmoid_transit_approach_walktime_PEAK__4_0__2_0__AJ26DYAVZX7MOBOG5SOJABST.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py new file mode 100644 index 0000000..571d66e --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL( + _args, + _inputs, + _outputs, + +): + return 0.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_log_1_samp_wgt__PLSMOODNF77UOPHIVH6I2WBL.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_samp_wgt.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_samp_wgt.py new file mode 100644 index 0000000..24f6e4a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_samp_wgt.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def samp_wgt( + _args, + _inputs, + _outputs, + +): + return 1.0 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_samp_wgt.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_samp_wgt.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py new file mode 100644 index 0000000..ec46953 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73( + _args, + _inputs, + _outputs, + +): + return _inputs[7] / _inputs[0] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_OFFPEAK_auto_dist_OFFPEAK_U2242PIA3ZL4MJS726HCCG73.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py new file mode 100644 index 0000000..607fb27 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX( + _args, + _inputs, + _outputs, + +): + return _inputs[8] / _inputs[1] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_drivetime_PEAK_auto_dist_PEAK_SVETJXGBSVYEYM7OVBAQW2PX.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py new file mode 100644 index 0000000..79f01ca --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM( + _args, + _inputs, + _outputs, + +): + return _inputs[9] / _inputs[0] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_OFFPEAK_auto_dist_OFFPEAK_22UIGWVENT7RTALQKKOHEPXM.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py new file mode 100644 index 0000000..1d62e39 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S( + _args, + _inputs, + _outputs, + +): + return _inputs[10] / _inputs[1] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_waittime_PEAK_auto_dist_PEAK_YHJNF2B3VEICSZL64Y2XLV4S.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py new file mode 100644 index 0000000..71aa571 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2( + _args, + _inputs, + _outputs, + +): + return _inputs[11] / _inputs[0] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_OFFPEAK_auto_dist_OFFPEAK_ITAE2YOSBIY76DBTPIPT6QD2.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py new file mode 100644 index 0000000..3c18880 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J( + _args, + _inputs, + _outputs, + +): + return _inputs[12] / _inputs[1] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_approach_walktime_PEAK_auto_dist_PEAK_T52CC4SUBMFSLGDNMCSO7A7J.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBO.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBO.py new file mode 100644 index 0000000..1486d27 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBO.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_avail_HBO( + _args, + _inputs, + _outputs, + +): + return (_inputs[13] < 999) & (_inputs[11] < 999) & (_inputs[7] < 999) & (_inputs[2] > -9998) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBO.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBO.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBS.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBS.py new file mode 100644 index 0000000..cfd01f6 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBS.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_avail_HBS( + _args, + _inputs, + _outputs, + +): + return (_inputs[13] < 999) & (_inputs[11] < 999) & (_inputs[7] < 999) & (_inputs[3] > -9998) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBS.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBS.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWH.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWH.py new file mode 100644 index 0000000..3a39e56 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWH.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_avail_HBWH( + _args, + _inputs, + _outputs, + +): + return (_inputs[14] < 999) & (_inputs[12] < 999) & (_inputs[8] < 999) & (_inputs[4] > -9998) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWH.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWH.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWL.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWL.py new file mode 100644 index 0000000..9ae5ea4 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWL.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_avail_HBWL( + _args, + _inputs, + _outputs, + +): + return (_inputs[14] < 999) & (_inputs[12] < 999) & (_inputs[8] < 999) & (_inputs[5] > -9998) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWL.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_HBWL.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_NHB.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_NHB.py new file mode 100644 index 0000000..a6d4ee2 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_NHB.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_avail_NHB( + _args, + _inputs, + _outputs, + +): + return (_inputs[13] < 999) & (_inputs[11] < 999) & (_inputs[7] < 999) & (_inputs[6] > -9998) diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_NHB.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_avail_NHB.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py new file mode 100644 index 0000000..530c3d6 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V( + _args, + _inputs, + _outputs, + +): + return _inputs[15] / _inputs[0] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_OFFPEAK_auto_dist_OFFPEAK_IY4UAVBMS2HPHNYZJLSMWG3V.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py new file mode 100644 index 0000000..f9af209 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py @@ -0,0 +1,16 @@ + +import numba +import numpy as np +from numpy import log, exp, log1p, expm1 +from sharrow.maths import piece, hard_sigmoid + + + +@numba.jit(cache=True, error_model='numpy', boundscheck=False, nopython=True, fastmath=True) +def transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP( + _args, + _inputs, + _outputs, + +): + return _inputs[16] / _inputs[1] diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py.lock b/src/Mode-Dest-TOD/cmap_modedest/fast/__sc/S2/f_transit_ovtt_PEAK_auto_dist_PEAK_UIAXX4VIE5PP53PJMCSMEFOP.py.lock new file mode 100755 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/application_data.py b/src/Mode-Dest-TOD/cmap_modedest/fast/application_data.py new file mode 100644 index 0000000..8d839fe --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/application_data.py @@ -0,0 +1,335 @@ +import larch +import numpy as np +from numba import njit, vectorize +import pandas as pd +import pyarrow as pa +from sharrow import Dataset, SharedData, Table, local_cache + +from .tnc_los import tnc_los_functions, taxi_cost, tnc_cost +from ..cmap_logging import getLogger, getSubLogger +from ..purposes import purposesA +log = getLogger() + +def application_data(dh): + """ + This function precompiles the application data flow. + + It includes a bunch of random data formatted the same manner as the real + data will be, so that the code can be optimized ahead of time. + + Parameters + ---------- + dh + + Returns + ------- + sharrow.Flow + """ + log = getSubLogger("fast.application_data") + + log.info("preparing application data") + + #taxi_cost, tnc_solo_cost, tnc_pool_cost = \ + tnc_los_functions(dh) + + otazi, dtazi = np.random.choice(3000, 60000), np.random.choice(3000, 60000) + + tbl = Table({ + 'otaz_idx': otazi, + 'dtaz_idx': dtazi, + 'otaz': otazi + 1, + 'dtaz': dtazi + 1, + 'chooser_row': np.arange(otazi.size) + }) + + ozones = Dataset.from_dataframe( + dh.m01.set_index( + dh.m01.index.rename("otaz"), + ), + ).squash_index(otaz='otaz_idx') + + attractions = Dataset.from_dataframe( + dh.trip_attractions5.astype(np.float64).set_index( + dh.trip_attractions5.index.rename("dtaz"), + ), + ).squash_index(dtaz='dtaz_idx') + + omx_auto = dh.skims.raw.select_and_rename( + {v:k for k,v in dh.skims.auto.col_mapping.items()} + ).squash_index(otaz='otaz_idx', dtaz='dtaz_idx') + + # inject intrazonal distance into auto skims + # set intrazonal auto_dist + intrazonal_zone_area = dh.zone_shp.area # square feet + intrazonal_dist = np.sqrt(intrazonal_zone_area) / 5280 * 0.667 + np.fill_diagonal( + omx_auto['am_dist'].values, + intrazonal_dist, + ) + np.fill_diagonal( + omx_auto['md_dist'].values, + intrazonal_dist, + ) + + omx_transit_pk = dh.skims.raw.select_and_rename( + {v:k for k,v in dh.skims.transit_pk.col_mapping.items()} + ).squash_index(otaz='otaz_idx', dtaz='dtaz_idx') + + omx_transit_op = dh.skims.raw.select_and_rename( + {v:k for k,v in dh.skims.transit_op.col_mapping.items()} + ).squash_index(otaz='otaz_idx', dtaz='dtaz_idx') + + # load lastest computed autopropensity as a pd.DataFrame + from ..data_handlers.m01_handler import attach_areatypes + autopropensity = attach_areatypes( + dh, + pd.DataFrame(index=dh.m01.index), + "", + "", + targetzone=dh.m01.index, + )[['autopropensity']] + o_autopropensity = Dataset.from_dataframe( + autopropensity.set_index( + autopropensity.index.rename("otaz"), + ) + ).squash_index(otaz='otaz_idx') + d_autopropensity = Dataset.from_dataframe( + autopropensity.set_index( + autopropensity.index.rename("dtaz"), + ) + ).squash_index(dtaz='dtaz_idx') + + + tg = SharedData( + tbl, + **{ + 'transit_pk': omx_transit_pk, + 'transit_op': omx_transit_op, + 'auto_skims': omx_auto, + 'ozone': ozones, + 'dzone': ozones.set_match_names({"otaz_idx":'dtaz_idx'}), + 'attractions': attractions, + 'o_autopropensity': o_autopropensity, + 'd_autopropensity': d_autopropensity, + }, + extra_funcs=( + taxi_cost, tnc_cost, + ), + extra_vars=dict( + taxi_cost_struct=dh.cfg['taxi_cost_struct'], + tnc_solo_peak_struct=dh.cfg['tnc_cost_struct_solo_peak'], + tnc_solo_offpeak_struct=dh.cfg['tnc_cost_struct_solo_peak'], + tnc_pool_peak_struct=dh.cfg['tnc_cost_struct_pool_peak'], + tnc_pool_offpeak_struct=dh.cfg['tnc_cost_struct_pool_peak'], + ), + ) + + log.info("setup application data flow") + ss = tg.setup_flow({ + + 'o_zone == dtaz': 'otaz == dtaz', #### fails dtype + + 'transit_ivtt_PEAK' : 'transit_pk.ivtt', + 'transit_ivtt_OFFPEAK': 'transit_op.ivtt', + 'transit_ovtt_PEAK' : 'transit_pk.ovtt', + 'transit_ovtt_OFFPEAK': 'transit_op.ovtt', + 'transit_fare_PEAK' : 'transit_pk.fare', + 'transit_fare_OFFPEAK': 'transit_op.fare', + + 'piece(transit_ivtt_OFFPEAK, None, 20)': 'piece(transit_ivtt_OFFPEAK, None, 20)', + 'piece(transit_ivtt_OFFPEAK, 20, None)': 'piece(transit_ivtt_OFFPEAK, 20, None)', + 'autopropensity': 'd_autopropensity.autopropensity', + + 'auto_time_PEAK': 'auto_skims.am_time', + 'auto_dist_PEAK': 'auto_skims.am_dist', + 'auto_time_OFFPEAK': 'auto_skims.md_time', + 'auto_dist_OFFPEAK': 'auto_skims.md_dist', + 'auto_opcost_PEAK': 'auto_skims.am_opcost', + 'auto_opcost_hov_PEAK': 'auto_skims.am_opcost_hov', + 'auto_opcost_OFFPEAK': 'auto_skims.md_opcost', + 'auto_toll_hiinc_PEAK': 'np.fmax(auto_skims.am_toll_hiinc, 0)', + 'auto_toll_loinc_PEAK': 'np.fmax(auto_skims.am_toll_loinc, 0)', + 'auto_toll_hov_hiinc_PEAK': 'np.fmax(auto_skims.am_toll_hov_hiinc, 0)', + 'auto_toll_hov_loinc_PEAK': 'np.fmax(auto_skims.am_toll_hov_loinc, 0)', + 'auto_toll_OFFPEAK': 'np.fmax(auto_skims.md_toll, 0)', + + 'piece(auto_dist_PEAK,None,0.5)': 'piece(auto_skims.am_dist,None,0.5)', + 'piece(auto_dist_PEAK,0.5,1.0)' : 'piece(auto_skims.am_dist,0.5,1.0)', + 'piece(auto_dist_PEAK,1.0,None)': 'piece(auto_skims.am_dist,1.0,None)', + 'piece(auto_dist_PEAK,None,5)' : 'piece(auto_skims.am_dist,None,5)', + 'piece(auto_dist_PEAK,5,10)' : 'piece(auto_skims.am_dist,5,10)', + 'piece(auto_dist_PEAK,10,None)' : 'piece(auto_skims.am_dist,10,None)', + + 'piece(auto_dist_OFFPEAK,None,0.5)': 'piece(auto_skims.md_dist,None,0.5)', + 'piece(auto_dist_OFFPEAK,0.5,1.0)' : 'piece(auto_skims.md_dist,0.5,1.0)', + 'piece(auto_dist_OFFPEAK,1.0,None)': 'piece(auto_skims.md_dist,1.0,None)', + 'piece(auto_dist_OFFPEAK,None,5)' : 'piece(auto_skims.md_dist,None,5)', + 'piece(auto_dist_OFFPEAK,5,10)' : 'piece(auto_skims.md_dist,5,10)', + 'piece(auto_dist_OFFPEAK,10,None)' : 'piece(auto_skims.md_dist,10,None)', + + 'taxi_fare_PEAK': 'taxi_cost(auto_skims.am_time, auto_skims.am_dist, otaz, dtaz, taxi_cost_struct)', + 'taxi_fare_OFFPEAK': 'taxi_cost(auto_skims.md_time, auto_skims.md_dist, otaz, dtaz, taxi_cost_struct)', + 'tnc_solo_fare_PEAK': 'tnc_cost(auto_skims.am_time, auto_skims.am_dist, otaz, dtaz, tnc_solo_peak_struct)', + 'tnc_solo_fare_OFFPEAK': 'tnc_cost(auto_skims.md_time, auto_skims.md_dist, otaz, dtaz, tnc_solo_offpeak_struct)', + 'tnc_pool_fare_PEAK': 'tnc_cost(auto_skims.am_time, auto_skims.am_dist, otaz, dtaz, tnc_pool_peak_struct)', + 'tnc_pool_fare_OFFPEAK': 'tnc_cost(auto_skims.md_time, auto_skims.md_dist, otaz, dtaz, tnc_pool_offpeak_struct)', + + 'taxi_wait_time_PEAK' : 'ozone.taxi_wait_pk', + 'taxi_wait_time_OFFPEAK' : 'ozone.taxi_wait_op', + 'tnc_solo_wait_time_PEAK' : 'ozone.tnc_solo_wait_pk', + 'tnc_solo_wait_time_OFFPEAK': 'ozone.tnc_solo_wait_op', + 'tnc_pool_wait_time_PEAK' : 'ozone.tnc_pool_wait_pk', + 'tnc_pool_wait_time_OFFPEAK': 'ozone.tnc_pool_wait_op', + + 'taxi_wait_time_PEAK/auto_dist_PEAK' : 'ozone.taxi_wait_pk/auto_skims.am_dist', + 'taxi_wait_time_OFFPEAK/auto_dist_OFFPEAK' : 'ozone.taxi_wait_op/auto_skims.md_dist', + 'tnc_solo_wait_time_PEAK/auto_dist_PEAK' : 'ozone.tnc_solo_wait_pk/auto_skims.am_dist', + 'tnc_solo_wait_time_OFFPEAK/auto_dist_OFFPEAK': 'ozone.tnc_solo_wait_op/auto_skims.md_dist', + 'tnc_pool_wait_time_PEAK/auto_dist_PEAK' : 'ozone.tnc_pool_wait_pk/auto_skims.am_dist', + 'tnc_pool_wait_time_OFFPEAK/auto_dist_OFFPEAK': 'ozone.tnc_pool_wait_op/auto_skims.md_dist', + + 'fmax(ozone_areatype, areatype)==1': 'max(ozone.zone_type, dzone.zone_type)==1', + 'fmax(ozone_areatype, areatype)==2': 'max(ozone.zone_type, dzone.zone_type)==2', + 'fmax(ozone_areatype, areatype)==3': 'max(ozone.zone_type, dzone.zone_type)==3', + 'fmax(ozone_areatype, areatype)==4': 'max(ozone.zone_type, dzone.zone_type)==4', + + 'fmin(ozone_areatype, areatype)==1': 'min(ozone.zone_type, dzone.zone_type)==1', + 'fmin(ozone_areatype, areatype)==2': 'min(ozone.zone_type, dzone.zone_type)==2', + 'fmin(ozone_areatype, areatype)==3': 'min(ozone.zone_type, dzone.zone_type)==3', + 'fmin(ozone_areatype, areatype)==4': 'min(ozone.zone_type, dzone.zone_type)==4', + + 'log_attractions_HBWH': 'log(attractions.HBWH)', + 'log_attractions_HBWL': 'log(attractions.HBWL)', + 'log_attractions_HBS': 'log(attractions.HBS)', + 'log_attractions_HBO': 'log(attractions.HBO)', + 'log_attractions_NHB': 'log(attractions.NHB)', + # 'log_attractions_HBOR': 'log(attractions.HBOR)', + # 'log_attractions_NHBR': 'log(attractions.NHBR)', + # 'log_attractions_NHBS': 'log(attractions.NHBS)', + + 'log_attractions_HBWH > -666': 'log(attractions.HBWH) > -666', + 'log_attractions_HBWL > -666': 'log(attractions.HBWL) > -666', + 'log_attractions_HBS > -666': 'log(attractions.HBS) > -666', + 'log_attractions_HBO > -666': 'log(attractions.HBO) > -666', + 'log_attractions_NHB > -666': 'log(attractions.NHB) > -666', + # 'log_attractions_HBOR > -666': 'log(attractions.HBOR) > -666', + # 'log_attractions_NHBR > -666': 'log(attractions.NHBR) > -666', + # 'log_attractions_NHBS > -666': 'log(attractions.NHBS) > -666', + + }, dtype="float64", cache_dir=local_cache(), name="S1") + + try: + log.debug("load first run") + df = ss.load(tbl, as_dataframe=True, dtype=np.float64) + log.debug("load second run") + df2 = ss.load(tbl, as_dataframe=True, dtype=np.float64) + log.debug("check first and second run are equal") + try: + pd.testing.assert_frame_equal(df, df2) + except AssertionError as err: + log.exception(err) + # from ..cmap_logging import log_df + # log_df(df2, logger=log, verbose=1, level=10) + + return ss + finally: + log.info("application_data flow ready") + + + + +def application_data2(dh, in_table): + log = getSubLogger("fast.application_data2") + log.info("prepare application_data2") + + coldefs = { + + 'transit_approach_drivetime_PEAK/auto_dist_PEAK': f'transit_approach_drivetime_PEAK/auto_dist_PEAK', + 'transit_approach_waittime_PEAK/auto_dist_PEAK': f'transit_approach_waittime_PEAK/auto_dist_PEAK', + 'transit_approach_walktime_PEAK/auto_dist_PEAK': f'transit_approach_walktime_PEAK/auto_dist_PEAK', + 'transit_ovtt_PEAK/auto_dist_PEAK': f'transit_ovtt_PEAK/auto_dist_PEAK', + + 'transit_approach_drivetime_OFFPEAK/auto_dist_OFFPEAK': f'transit_approach_drivetime_OFFPEAK/auto_dist_OFFPEAK', + 'transit_approach_waittime_OFFPEAK/auto_dist_OFFPEAK': f'transit_approach_waittime_OFFPEAK/auto_dist_OFFPEAK', + 'transit_approach_walktime_OFFPEAK/auto_dist_OFFPEAK': f'transit_approach_walktime_OFFPEAK/auto_dist_OFFPEAK', + 'transit_ovtt_OFFPEAK/auto_dist_OFFPEAK': f'transit_ovtt_OFFPEAK/auto_dist_OFFPEAK', + + 'hard_sigmoid(transit_approach_walktime_PEAK, 4.0, 2.0)': f'hard_sigmoid(transit_approach_walktime_PEAK, 4.0, 2.0)', + 'hard_sigmoid(transit_approach_walktime_OFFPEAK, 4.0, 2.0)': f'hard_sigmoid(transit_approach_walktime_OFFPEAK, 4.0, 2.0)', + + # # TODO fix auto parking cost + # # _parking_cost, _free_parking = parking_cost_v2( + + 'auto_parking_cost_HBWH': '0.0', + 'auto_parking_cost_HBWL': '0.0', + 'auto_parking_cost_HBO': '0.0', + 'auto_parking_cost_HBS': '0.0', + 'auto_parking_cost_NHB': '0.0', + 'auto_parking_cost_HBOR': '0.0', + 'auto_parking_cost_NHBR': '0.0', + 'auto_parking_cost_NHBS': '0.0', + + 'samp_wgt': '1.0', + 'log(1/samp_wgt)': '0.0', + + 'transit_avail_HBWH': ( + "(transit_ivtt_PEAK < 999)" + "& (transit_approach_walktime_PEAK < 999)" + "& (transit_approach_drivetime_PEAK < 999)" + "& (log_attractions_HBWH > -9998)" + ), + 'transit_avail_HBWL': ( + "(transit_ivtt_PEAK < 999)" + "& (transit_approach_walktime_PEAK < 999)" + "& (transit_approach_drivetime_PEAK < 999)" + "& (log_attractions_HBWL > -9998)" + ), + 'transit_avail_HBS': ( + "(transit_ivtt_OFFPEAK < 999)" + "& (transit_approach_walktime_OFFPEAK < 999)" + "& (transit_approach_drivetime_OFFPEAK < 999)" + "& (log_attractions_HBS > -9998)" + ), + 'transit_avail_HBO': ( + "(transit_ivtt_OFFPEAK < 999)" + "& (transit_approach_walktime_OFFPEAK < 999)" + "& (transit_approach_drivetime_OFFPEAK < 999)" + "& (log_attractions_HBO > -9998)" + ), + 'transit_avail_NHB': ( + "(transit_ivtt_OFFPEAK < 999)" + "& (transit_approach_walktime_OFFPEAK < 999)" + "& (transit_approach_drivetime_OFFPEAK < 999)" + "& (log_attractions_NHB > -9998)" + ), + } + + for purpose in purposesA: + coldefs.update({ + f'auto_avail_{purpose}': f'log_attractions_{purpose} > -9998', + f'1-auto_avail_{purpose}': f'1-auto_avail_{purpose}', + f'1-transit_avail_{purpose}': f'1-transit_avail_{purpose}', + }) + + log.info("setup application data step 2 flow") + processor = SharedData(in_table).setup_flow( + coldefs, + cache_dir=local_cache(), + name="S2", + dtype="float64", + ) + + try: + log.debug("load first hit") + df = processor.load(in_table, as_dataframe=True) + log.debug("load second hit") + df2 = processor.load(in_table, as_dataframe=True) + log.debug("check first and second hits are equal") + try: + pd.testing.assert_frame_equal(df, df2) + except AssertionError as err: + log.exception(err) + return processor + finally: + log.info("application_data2 flow ready") + diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/parking_cost.py b/src/Mode-Dest-TOD/cmap_modedest/fast/parking_cost.py new file mode 100644 index 0000000..c4f8c91 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/parking_cost.py @@ -0,0 +1,102 @@ +import numpy as np +import numba as nb + +def compile_parking_cost_v2(dh): + + cbd_parking_price_prob_array = np.zeros([dh.cbd_parking_price_prob.index.max(), 5], dtype=np.float32) + for dtaz, priceprob in dh.cbd_parking_price_prob.iterrows(): + cbd_parking_price_prob_array[dtaz-1, :] = priceprob.to_numpy() + + cbd_parking_prices_array = np.zeros([dh.cbd_parking_price_prob.index.max(), 5], dtype=np.float32) + for dtaz, prices in dh.cbd_parking_prices.iterrows(): + cbd_parking_prices_array[dtaz-1, :] = prices.to_numpy() + + zone_type_array = dh.m01.zone_type.to_numpy().astype(np.int32) + + default_parking_costs_array = np.zeros([ + 4, # purposes + 4, # zonetypes + ]) + + default_parking_costs_array[0, 0] = dh.cfg.parking_costs.defaults.HW[1] + default_parking_costs_array[0, 1] = dh.cfg.parking_costs.defaults.HW[2] + default_parking_costs_array[0, 2] = dh.cfg.parking_costs.defaults.HW[3] + default_parking_costs_array[0, 3] = dh.cfg.parking_costs.defaults.HW[4] + + default_parking_costs_array[1, 0] = dh.cfg.parking_costs.defaults.HW[1] + default_parking_costs_array[1, 1] = dh.cfg.parking_costs.defaults.HW[2] + default_parking_costs_array[1, 2] = dh.cfg.parking_costs.defaults.HW[3] + default_parking_costs_array[1, 3] = dh.cfg.parking_costs.defaults.HW[4] + + default_parking_costs_array[2, 0] = dh.cfg.parking_costs.defaults.HO[1] + default_parking_costs_array[2, 1] = dh.cfg.parking_costs.defaults.HO[2] + default_parking_costs_array[2, 2] = dh.cfg.parking_costs.defaults.HO[3] + default_parking_costs_array[2, 3] = dh.cfg.parking_costs.defaults.HO[4] + + default_parking_costs_array[3, 0] = dh.cfg.parking_costs.defaults.NH[1] + default_parking_costs_array[3, 1] = dh.cfg.parking_costs.defaults.NH[2] + default_parking_costs_array[3, 2] = dh.cfg.parking_costs.defaults.NH[3] + default_parking_costs_array[3, 3] = dh.cfg.parking_costs.defaults.NH[4] + + IncomeCeiling = dh.cbd_parking2.IncomeCeiling.to_numpy() + FreeParkingPct = dh.cbd_parking2.FreeParkingPct.to_numpy() + + @nb.njit + def parking_cost_v2( + DEST, + INCOME, + HOURS, + purpose, + random_seed=None, + ): + + """ + Draw a parking cost from the random distribution in the destination zone. + + Parameters + ---------- + DEST : int + TAZ ID for destination + INCOME : float + HOURS : float + Number of hours of parking to pay for + purpose : int + 0:'HW', 1:'HW, 2:'HO', 3:'NH' + random_seed : int, optional + + Returns + ------- + CAPK, WALK3, INTOCC, BLK, SI : array, shape[ITER] + parking cost, walktime, vehicle occupancy, blocks walked, savings rate + """ + + if random_seed is not None: + np.random.seed(random_seed) + + rand_free_parking = np.random.rand() * 100. # Free Parking randomizer + rand_parking_price = np.random.rand() # Parking Rate randomizer + #RAN5 = np.random.rand() * 100. # Auto Occupancy randomizer + + hourly_cost = 0 + if DEST <= cbd_parking_price_prob_array.shape[0]: + for i in range(5): + rand_parking_price -= cbd_parking_price_prob_array[DEST-1, i] + if rand_parking_price < 0: + hourly_cost = cbd_parking_prices_array[DEST-1, i] + break + + if hourly_cost == 0: + dest_zone_type = zone_type_array[DEST-1] + hourly_cost = default_parking_costs_array[purpose, dest_zone_type-1] + + free_parking = False + for j2 in range(5): + if INCOME <= IncomeCeiling[j2]: + if rand_free_parking <= FreeParkingPct[j2]: + hourly_cost = 0.0 + free_parking = True + break + + return hourly_cost*HOURS, free_parking + + return parking_cost_v2 \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/random_generator.py b/src/Mode-Dest-TOD/cmap_modedest/fast/random_generator.py new file mode 100644 index 0000000..7fc05c1 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/random_generator.py @@ -0,0 +1,42 @@ +import numba as nb +import numbers +import numpy as np + +@nb.njit +def check_random_generator(seed): + """ + Turn a seed into a numpy RandomState instance + + Parameters + ---------- + seed : None | int | instance of Generator + If seed is None, return a default Generator. + If seed is an int, return a new Generator instance seeded with seed. + If seed is already a Generator instance, return it. + Otherwise raise ValueError. + """ + if seed is not None: + return default_rng() + if isinstance(seed, numbers.Integral): + return default_rng(SeedSequence(seed % 1<<32)) + if isinstance(seed, Generator): + return seed + raise ValueError('%r cannot be used to seed a random generator instance' % seed) + + +@nb.njit +def multichoices(probs, samplesizes, seeds=None): + choice_table = np.zeros(probs.shape, dtype=np.int32) + for i in range(probs.shape[0]): + if seeds is not None: + np.random.seed(seeds[i]) + pr = probs[i] + samplesize = samplesizes[i] + for k in range(samplesize): + rando = np.random.random() + for j in range(probs.shape[1]): + rando -= pr[j] + if rando < 0: + choice_table[i, j] += 1 + break + return choice_table diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/tnc_los.py b/src/Mode-Dest-TOD/cmap_modedest/fast/tnc_los.py new file mode 100644 index 0000000..1b05655 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/tnc_los.py @@ -0,0 +1,388 @@ +import numba as nb +import numpy as np +import pandas as pd +import yaml +from ..addict import Dict +from collections import namedtuple +from typing import NamedTuple + +zone_to_cents_t = nb.types.DictType(nb.int32, nb.float32) + + +class TaxiCostStruct(NamedTuple): + flag_pull: float + per_minute: float + per_mile: float + airport_pickup_fee: float + airport_pickup_zones: np.ndarray + + +class TncCostStruct(NamedTuple): + base_fare: float + per_minute: float + per_mile: float + min_fare: float + booking_fee: float + special_fee: float + downtown_fee: float + special_zones: np.ndarray + downtown_zones: np.ndarray + + +@nb.njit(cache=True) +def taxi_cost(auto_time, auto_dist, o_zone, d_zone, taxi_cost_struct): + """ + Compute taxi fare. + + A single set of rates (Chicago medallion rates for in-city trips) + is used; fares for taxi trips outside Chicago are close to this + rate and rare enough that more precision is unneeded. + + Parameters + ---------- + auto_time, auto_dist : array-like + + Returns + ------- + fare : array-like + """ + cost = ( + taxi_cost_struct.flag_pull + + auto_time * taxi_cost_struct.per_minute + + auto_dist * taxi_cost_struct.per_mile + ) + if taxi_cost_struct.airport_pickup_fee: + bucket_applies = False + for i in range(taxi_cost_struct.airport_pickup_zones.size): + if taxi_cost_struct.airport_pickup_zones[i] == o_zone: + bucket_applies = True + break + if bucket_applies: + cost += taxi_cost_struct.airport_pickup_fee + + return cost + +@nb.njit(cache=True) +def tnc_cost(auto_time, auto_dist, o_zone, d_zone, tnc_cost_struct): + """ + Compute the TNC cost. + + Parameters + ---------- + auto_time, auto_dist : float + The auto travel time and distance for a set of trips. + o_zone, d_zone : int + Zone numbers for origin and destination + tnc_cost_struct : TncCostStruct + Use the correct struct for peak/offpeak and solo/shared. + + Returns + ------- + float + """ + cost = ( + tnc_cost_struct.per_minute * auto_time + + tnc_cost_struct.per_mile * auto_dist + + tnc_cost_struct.base_fare + ) + cost = max(cost, tnc_cost_struct.min_fare) + tnc_cost_struct.booking_fee + + if tnc_cost_struct.special_fee: + bucket_applies = False + for i in range(tnc_cost_struct.special_zones.size): + if tnc_cost_struct.special_zones[i] == o_zone or tnc_cost_struct.special_zones[i] == d_zone: + bucket_applies = True + break + if bucket_applies: + cost += tnc_cost_struct.special_fee + + if tnc_cost_struct.downtown_fee: + bucket_applies = False + for i in range(tnc_cost_struct.downtown_zones.size): + if tnc_cost_struct.downtown_zones[i] == o_zone or tnc_cost_struct.downtown_zones[i] == d_zone: + bucket_applies = True + break + if bucket_applies: + cost += tnc_cost_struct.downtown_fee + + return cost + + +### CONFIG ### + +def tnc_los_functions(dh): + + with open(dh.filenames.config, 'rt') as yf: + cfg = Dict(yaml.safe_load(yf)) + cfg.freeze() + + taxi_cost_flag_pull = cfg.taxi.cost.flag_pull + taxi_cost_per_minute = cfg.taxi.cost.per_minute + taxi_cost_per_mile = cfg.taxi.cost.per_mile + + tnc_cost_peak_per_minute = cfg.tnc.cost.peak.per_minute + tnc_cost_peak_per_mile = cfg.tnc.cost.peak.per_mile + tnc_cost_peak_base_fare = cfg.tnc.cost.peak.base_fare + tnc_cost_peak_min_fare = cfg.tnc.cost.peak.min_fare + tnc_cost_peak_booking_fee = cfg.tnc.cost.peak.booking_fee + tnc_cost_offpeak_per_minute = cfg.tnc.cost.offpeak.per_minute + tnc_cost_offpeak_per_mile = cfg.tnc.cost.offpeak.per_mile + tnc_cost_offpeak_base_fare = cfg.tnc.cost.offpeak.base_fare + tnc_cost_offpeak_min_fare = cfg.tnc.cost.offpeak.min_fare + tnc_cost_offpeak_booking_fee= cfg.tnc.cost.offpeak.booking_fee + + tnc_surcharge_rates = {} + for k,v in cfg.tnc.surcharge_rates.items(): + tnc_surcharge_rates[k] = np.float32(v) + + tnc_surcharge_zones = {} + for k, v in cfg.tnc.surcharge_zones.items(): + tnc_surcharge_zones[k] = np.asarray(v, dtype=np.int32) + + tnc_surcharges = tuple( + (k, tnc_surcharge_rates[k], tnc_surcharge_zones[k]) + for k in tnc_surcharge_zones + ) + + tncpool_cost_peak_per_minute = cfg.tnc_pooled.cost.peak.per_minute + tncpool_cost_peak_per_mile = cfg.tnc_pooled.cost.peak.per_mile + tncpool_cost_peak_base_fare = cfg.tnc_pooled.cost.peak.base_fare + tncpool_cost_peak_min_fare = cfg.tnc_pooled.cost.peak.min_fare + tncpool_cost_peak_booking_fee = cfg.tnc_pooled.cost.peak.booking_fee + tncpool_cost_offpeak_per_minute = cfg.tnc_pooled.cost.offpeak.per_minute + tncpool_cost_offpeak_per_mile = cfg.tnc_pooled.cost.offpeak.per_mile + tncpool_cost_offpeak_base_fare = cfg.tnc_pooled.cost.offpeak.base_fare + tncpool_cost_offpeak_min_fare = cfg.tnc_pooled.cost.offpeak.min_fare + tncpool_cost_offpeak_booking_fee= cfg.tnc_pooled.cost.offpeak.booking_fee + + tncpool_surcharge_rates = {} + for k,v in cfg.tnc_pooled.surcharge_rates.items(): + tncpool_surcharge_rates[k] = np.float32(v) + + tncpool_surcharge_zones = {} + for k, v in cfg.tnc_pooled.surcharge_zones.items(): + tncpool_surcharge_zones[k] = np.asarray(v, dtype=np.int32) + + tncpool_surcharges = tuple( + (k, tncpool_surcharge_rates[k], tncpool_surcharge_zones[k]) + for k in tncpool_surcharge_zones + ) + + dh.cfg['taxi_cost_struct'] = TaxiCostStruct( + flag_pull = cfg.taxi.cost.flag_pull, + per_minute = cfg.taxi.cost.per_minute, + per_mile = cfg.taxi.cost.per_mile, + airport_pickup_fee = cfg.taxi.cost.airport_departure, + airport_pickup_zones=np.asarray(cfg.taxi.cost.airport_zones), + ) + + dh.cfg['tnc_cost_struct_solo_peak'] = TncCostStruct( + base_fare=cfg.tnc.cost.peak.base_fare, + per_minute=cfg.tnc.cost.peak.per_minute, + per_mile=cfg.tnc.cost.peak.per_mile, + min_fare=cfg.tnc.cost.peak.min_fare, + booking_fee=cfg.tnc.cost.peak.booking_fee, + special_fee=cfg.tnc.surcharge_rates.special, + special_zones=np.asarray(cfg.tnc.surcharge_zones.special), + downtown_fee=cfg.tnc.surcharge_rates.downtown, + downtown_zones=np.asarray(cfg.tnc.surcharge_zones.downtown), + ) + + dh.cfg['tnc_cost_struct_solo_offpeak'] = TncCostStruct( + base_fare=cfg.tnc.cost.offpeak.base_fare, + per_minute=cfg.tnc.cost.offpeak.per_minute, + per_mile=cfg.tnc.cost.offpeak.per_mile, + min_fare=cfg.tnc.cost.offpeak.min_fare, + booking_fee=cfg.tnc.cost.offpeak.booking_fee, + special_fee=cfg.tnc.surcharge_rates.special, + special_zones=np.asarray(cfg.tnc.surcharge_zones.special), + downtown_fee=cfg.tnc.surcharge_rates.downtown, + downtown_zones=np.asarray(cfg.tnc.surcharge_zones.downtown), + ) + + dh.cfg['tnc_cost_struct_pool_peak'] = TncCostStruct( + base_fare=cfg.tnc_pooled.cost.peak.base_fare, + per_minute=cfg.tnc_pooled.cost.peak.per_minute, + per_mile=cfg.tnc_pooled.cost.peak.per_mile, + min_fare=cfg.tnc_pooled.cost.peak.min_fare, + booking_fee=cfg.tnc_pooled.cost.peak.booking_fee, + special_fee=cfg.tnc_pooled.surcharge_rates.special, + special_zones=np.asarray(cfg.tnc_pooled.surcharge_zones.special), + downtown_fee=cfg.tnc_pooled.surcharge_rates.downtown, + downtown_zones=np.asarray(cfg.tnc_pooled.surcharge_zones.downtown), + ) + + dh.cfg['tnc_cost_struct_pool_offpeak'] = TncCostStruct( + base_fare=cfg.tnc_pooled.cost.offpeak.base_fare, + per_minute=cfg.tnc_pooled.cost.offpeak.per_minute, + per_mile=cfg.tnc_pooled.cost.offpeak.per_mile, + min_fare=cfg.tnc_pooled.cost.offpeak.min_fare, + booking_fee=cfg.tnc_pooled.cost.offpeak.booking_fee, + special_fee=cfg.tnc_pooled.surcharge_rates.special, + special_zones=np.asarray(cfg.tnc_pooled.surcharge_zones.special), + downtown_fee=cfg.tnc_pooled.surcharge_rates.downtown, + downtown_zones=np.asarray(cfg.tnc_pooled.surcharge_zones.downtown), + ) + + + ############## + # + # @nb.njit(cache=True) + # def taxi_cost(auto_time, auto_dist, taxi_cost_struct): + # """ + # Compute taxi fare. + # + # A single set of rates (Chicago medallion rates for in-city trips) + # is used; fares for taxi trips outside Chicago are close to this + # rate and rare enough that more precision is unneeded. + # + # Parameters + # ---------- + # auto_time, auto_dist : array-like + # + # Returns + # ------- + # fare : array-like + # """ + # return ( + # taxi_cost_struct.flag_pull + # + auto_time * taxi_cost_struct.per_minute + # + auto_dist * taxi_cost_struct.per_mile + # ) + # + # + # @nb.njit + # def tnc_cost(auto_time, auto_dist, o_zone, d_zone, tnc_cost_struct): + # """ + # Compute the TNC cost. + # + # Parameters + # ---------- + # auto_time, auto_dist : float + # The auto travel time and distance for a set of trips. + # o_zone, d_zone : int + # Zone numbers for origin and destination + # tnc_cost_struct : TncCostStruct + # Use the correct struct for peak/offpeak and solo/shared. + # + # Returns + # ------- + # float + # """ + # cost = ( + # tnc_cost_struct.per_minute * auto_time + # + tnc_cost_struct.per_mile * auto_dist + # + tnc_cost_struct.base_fare + # ) + # cost = max(cost, tnc_cost_struct.min_fare) + tnc_cost_struct.booking_fee + # + # if tnc_cost_struct.special_fee: + # bucket_applies = False + # for i in range(tnc_cost_struct.special_zones.size): + # if tnc_cost_struct.special_zones[i] == o_zone or tnc_cost_struct.special_zones[i] == d_zone: + # bucket_applies = True + # break + # if bucket_applies: + # cost += tnc_cost_struct.special_fee + # + # if tnc_cost_struct.downtown_fee: + # bucket_applies = False + # for i in range(tnc_cost_struct.downtown_zones.size): + # if tnc_cost_struct.downtown_zones[i] == o_zone or tnc_cost_struct.downtown_zones[i] == d_zone: + # bucket_applies = True + # break + # if bucket_applies: + # cost += tnc_cost_struct.downtown_fee + # + # return cost + # + # + # + # @nb.njit + # def tnc_solo_cost(auto_time, auto_dist, o_zone, d_zone, peak): + # """ + # Compute the solo rider TNC cost. + # + # Parameters + # ---------- + # auto_time, auto_dist : float + # The auto travel time and distance for a set of trips. + # o_zone, d_zone : int + # Zone numbers for origin and destination + # peak : bool + # Whether this trip is peak or offpeak. + # + # Returns + # ------- + # float + # """ + # if peak: + # cost = ( + # tnc_cost_peak_per_minute * auto_time + # + tnc_cost_peak_per_mile * auto_dist + # + tnc_cost_peak_base_fare + # ) + # cost = max(cost, tnc_cost_peak_min_fare) + tnc_cost_peak_booking_fee + # else: + # cost = ( + # tnc_cost_offpeak_per_minute * auto_time + # + tnc_cost_offpeak_per_mile * auto_dist + # + tnc_cost_offpeak_base_fare + # ) + # cost = max(cost, tnc_cost_offpeak_min_fare) + tnc_cost_offpeak_booking_fee + # + # for bucket_name, bucket_price, bucket_zones in tnc_surcharges: + # if bucket_price: + # bucket_applies = False + # for i in range(bucket_zones.size): + # if bucket_zones[i] == o_zone or bucket_zones[i] == d_zone: + # bucket_applies = True + # if bucket_applies: + # cost += bucket_price + # return cost + # + # + # @nb.njit + # def tnc_pool_cost(auto_time, auto_dist, o_zone, d_zone, peak): + # """ + # Compute the solo rider TNC cost. + # + # Parameters + # ---------- + # auto_time, auto_dist : float + # The auto travel time and distance for a set of trips. + # o_zone, d_zone : int + # Zone numbers for origin and destination + # peak : bool + # Whether this trip is peak or offpeak. + # + # Returns + # ------- + # float + # """ + # if peak: + # cost = ( + # tncpool_cost_peak_per_minute * auto_time + # + tncpool_cost_peak_per_mile * auto_dist + # + tncpool_cost_peak_base_fare + # ) + # cost = max(cost, tncpool_cost_peak_min_fare) + tncpool_cost_peak_booking_fee + # else: + # cost = ( + # tncpool_cost_offpeak_per_minute * auto_time + # + tncpool_cost_offpeak_per_mile * auto_dist + # + tncpool_cost_offpeak_base_fare + # ) + # cost = max(cost, tncpool_cost_offpeak_min_fare) + tncpool_cost_offpeak_booking_fee + # + # for bucket_name, bucket_price, bucket_zones in tncpool_surcharges: + # if bucket_price: + # bucket_applies = False + # for i in range(bucket_zones.size): + # if bucket_zones[i] == o_zone or bucket_zones[i] == d_zone: + # bucket_applies = True + # if bucket_applies: + # cost += bucket_price + # return cost + # + # return taxi_cost, tnc_solo_cost, tnc_pool_cost \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/transit/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/fast/transit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/transit/access_egress_distance.py b/src/Mode-Dest-TOD/cmap_modedest/fast/transit/access_egress_distance.py new file mode 100644 index 0000000..211afd7 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/transit/access_egress_distance.py @@ -0,0 +1,165 @@ +import numpy as np +import numba as nb + +from ...modecodes import * +FRONT_END = 0 +BACK_END = 1 +N_TRIP_ENDS = 2 + + +@nb.njit +def trunc_normal(loc, scale): + rv = np.float32(np.random.normal(loc, scale)) + return max(rv, 0.06) + + +@nb.njit +def sloped_linear(x_min, x_max, ratio=1.0): + if ratio == 1.0: + return np.float32(np.random.uniform(x_min, x_max)) + else: + span = x_max - x_min + if span != 0: + slope = (1.0-ratio)/span + else: + slope = (1.0-ratio) + area =.5*(1+ratio)*span + y = np.float32(np.random.uniform(0.0, 1.0)) * area + zp = np.sqrt(ratio * ratio + 2 * slope * y) + if slope: + return ((zp - ratio) / slope) + x_min + else: + return (zp - ratio) + x_min + + +@nb.njit +def simulate_ae_dist(p1,p2,p3): + + # use_normal = (p3 == 101) + if p3 == 101: + return trunc_normal(p1,p2) + + # use_slopey = (p3 < 101) + if p3 < 101: + return sloped_linear(p1, p2, p3) + + #use_nan = (p3 == 999) + return 255.0 + + + +def compile_simulate_approach_distances( + dh, +): + """ + + Parameters + ---------- + zone : array-like + Zone id (1-based) + attached_mode : int + Number for first or last mode (as matches this approach) + trip_purpose : {'HW','HO','NH'} + Trip purpose, used to select DISTR table and possibly filter + approach modes + trip_end : {0,1} + Zero if approach to first mode, one if approach from last mode + out : array-like + Output array must already exist, as a float dtype, + with shape [replications, N_APPROACH_MODES, ] + + """ + # random_state = check_random_state(random_state) + + distr_array = np.stack([ + dh.distr['HW'], + dh.distr['HO'], + dh.distr['NH'], + ]).reshape((3,-1,5,3)).astype(np.float32) + + _BUS = dh.distr['HW'].loc[1].index.get_loc('bus') + _CTARAIL = dh.distr['HW'].loc[1].index.get_loc('ctarail') + _FEEDERBUS = dh.distr['HW'].loc[1].index.get_loc('feederbus') + _METRA = dh.distr['HW'].loc[1].index.get_loc('metra') + _PNR = dh.distr['HW'].loc[1].index.get_loc('pnr') + + @nb.njit(parallel=True) + def simulate_approach_distances_arr( + zone, + attached_mode, + trip_purpose, + trip_end, + out, + ): + """ + + Parameters + ---------- + zone : int + attached_mode : int + trip_purpose : int + trip_end : int + out : array[float32], shape=(5,) + + Returns + ------- + + """ + assert out.shape[-1] == 5, "last dimension must be 5" + if trip_purpose == 'HW': + distr_ = distr_array[0,zone-1] + elif trip_purpose == 'HO': + distr_ = distr_array[1,zone-1] + else: #if trip_purpose == 'NH': + distr_ = distr_array[2,zone-1] + for J in range(N_DIST_TO_TYPES): + # OBTAIN APPROACH DISTANCES TO FIVE MODES + if (J == DIST_TO_BUS): + distr_params = distr_[_BUS] + elif (J == DIST_TO_CTA_RAIL) and (attached_mode == TransitModeCode_CTA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS CTA RAIL + distr_params = distr_[_CTARAIL] + elif (J == DIST_TO_METRA) and (attached_mode == TransitModeCode_METRA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + distr_params = distr_[_METRA] + elif (J == DIST_TO_FEEDER_BUS) and (attached_mode == TransitModeCode_METRA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + distr_params = distr_[_FEEDERBUS] + elif (J == DIST_TO_PARK_N_RIDE_STATION) and (trip_end == FRONT_END): + # PARK AND RIDE STATION DISTANCE OBTAINED WHEN TRIP END IS FRONT + distr_params = distr_[_PNR] + else: + distr_params = np.full(3, 999, dtype=np.float32) + if out.ndim == 2: + for k in range(out.shape[0]): + out[k,J] = simulate_ae_dist( + distr_params[0], + distr_params[1], + distr_params[2], + ) + else: + out[J] = simulate_ae_dist( + distr_params[0], + distr_params[1], + distr_params[2], + ) + + @nb.njit(parallel=True) + def simulate_approach_distances_multi( + zones, + attached_modes, + trip_purpose, + trip_end, + outs, + ): + assert zones.shape[0] == attached_modes.shape[0] == outs.shape[0] + for i in nb.prange(zones.shape[0]): + simulate_approach_distances_arr( + zones[i], + attached_modes[i], + trip_purpose, + trip_end, + outs[i], + ) + + return simulate_approach_distances_arr, simulate_approach_distances_multi \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/fast/transit/approach.py b/src/Mode-Dest-TOD/cmap_modedest/fast/transit/approach.py new file mode 100644 index 0000000..a33cc51 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/fast/transit/approach.py @@ -0,0 +1,836 @@ + +import numpy as np +import numba as nb +import logging +from ...addict import Dict +from typing import Generator +from collections import namedtuple + +log = logging.getLogger('CMAP') + +from .access_egress_distance import compile_simulate_approach_distances +from ...ae_distance_sim import simulate_ae_dist +from ...purposes import purposes_to_3 + +# trip types +HW = 'HW' # HOME PRODUCTIONS TO WORK ATTRACTIONS +HO = 'HO' # HOME PRODUCTIONS TO NON-WORK/NON-HOME ATTRACTIONS +NH = 'NH' # NON-HOME PRODUCTIONS TO NON-HOME ATTRACTIONS + +ITER = 50 # NUMBER OF TRIPS USED TO COMPUTE AVERAGE IMPEDANCES + +from ...modecodes import ( + APPROACH_WALK, + APPROACH_BUS, + APPROACH_PARK_N_RIDE, + APPROACH_KISS_N_RIDE, + APPROACH_FEEDER_BUS, + N_APPROACH_MODES, + APPROACH_MODE_NAMES, + DIST_TO_BUS, + DIST_TO_CTA_RAIL, + DIST_TO_METRA, + DIST_TO_FEEDER_BUS, + DIST_TO_PARK_N_RIDE_STATION, + N_DIST_TO_TYPES, + TransitModeCode_CTA_RAIL, + TransitModeCode_METRA_RAIL, + TransitModeCode_CTA_EXPRESS_BUS, + TransitModeCode_CTA_REGULAR_BUS, + TransitModeCode_PACE_BUS, +) + + + +FRONT_END = 0 +BACK_END = 1 +N_TRIP_ENDS = 2 + +SPDWLK = np.float32(30.) +# SPDWLK = SYSTEM-WIDE SPEED OF WALKING, +# DEFAULT IS 30 TENTHS OF A MILE PER HOUR + +SPEEDS = np.array([7., 15., 20., 30., 5., 10., 12., 17.]) +# SPEEDS = SPEEDS OF APPROACH AUTO AND BUS BY ZONE AREA TYPE +# AUTO APPROACH SPEEDS: +# ZONE TYPE 1 (CHICAGO CBD) DEFAULT IS 7 MPH +# ZONE TYPE 2 (CHICAGO REMAINDER) DEFAULT IS 15 MPH +# ZONE TYPE 3 (DENSE SUBURB) DEFAULT IS 20 MPH +# ZONE TYPE 4 (SPARSE SUBURB) DEFAULT IS 30 MPH +# BUS APPROACH SPEEDS: +# ZONE TYPE 1 (CHICAGO CBD) DEFAULT IS 5 MPH +# ZONE TYPE 2 (CHICAGO REMAINDER) DEFAULT IS 10 MPH +# ZONE TYPE 3 (DENSE SUBURB) DEFAULT IS 12 MPH +# ZONE TYPE 4 (SPARSE SUBURB) DEFAULT IS 17 MPH + +DRVOT = 14 +# DRVOT = DRIVER'S VALUE OF TIME, DEFAULT IS 14 CENTS/MIN + +OVT_IVT_RATIO = 2.0 + + + +AFC1 = 35 # AUTO FIXED COSTS FOR AUTO DRIVER IN CENTS +AFC2 = 20 # AUTO FIXED COSTS FOR AUTO PASSENGER IN CENTS + +# W2PNR = WALK TIME TO STATION FROM PARK AND RIDE LOT, +# DEFAULT IS 2 MINUTES +W2PNR = 2 + +TransitApproachStruct = namedtuple('TransitApproachStruct', [ + 'fwbus_pk', + 'fwfdr_pk', + 'fwbus_op', + 'fwfdr_op', + 'ZTYPE', + 'FM_pk', + 'LM_pk', + 'FM_op', + 'LM_op', + 'FEEDER_BUS_BOARDING_FARE', + 'FEEDER_BUS_CBD_FARE', + 'CTA_CBD_LINK_UP_FARE', + 'CTA_FIRST_XFER_FARE', + 'PACE_BUS_FIRST_XFER_FARE', + 'PNRAVL', + 'PRCOST', + 'AUTO_OPERATING_COST_BY_ZONETYPE', + 'distr_array', + 'distr_BUS', + 'distr_CTARAIL', + 'distr_FEEDERBUS', + 'distr_METRA', + 'distr_PNR', +]) + +# class TransitApproachStruct(_TransitApproachStruct): +# def __new__(cls, *args, **kwargs): +# if len(args) == 1 and len(kwargs) == 0: +# if isinstance(args[0], cls): +# return args[0] +# elif isinstance(args[0], Generator): +# return super().__new__(cls, *args[0]) +# return super().__new__(cls, *args, **kwargs) + + +def compile_transit_approach( + dh, +): + """ + Replaces TRAPP fortran. + + Parameters + ---------- + dh : DataHandler + ozone, dzone : int or array-like + Zone ID numbers. If array-like, should be arrays of the same shape. + TPTYPE : {'HW', 'HO', 'NH'} + Trip type + replication : int + Number of simulation replications + + Returns + ------- + Dict + Containing: + - drivetime : array of int32, shape [replication] + simulated in vehicle (drive) approach times, in minutes + - walktime : array of int32, shape [replication] + simulated out of vehicle (walk) approach times, in minutes + - cost : array of int32, shape [replication] + simulated approach costs, in cents + - waittime : array of int32, shape [replication] + simulated approach waiting times + - approach_mode : array of int8, shape [replication, 2] + simulated best approach modes + = approach_distances : array of float32, shape [replication, N_DIST_TO_TYPES, N_TRIP_ENDS] + + Notes + ----- + When ozone, dzone are given as arrays, all returned arrays have one extra front + dimension matching these arrays. + + """ + + PACE_BUS_BOARDING_FARE = dh.m023.PACE_BUS_BOARDING_FARE + PACE_BUS_FIRST_XFER_FARE = dh.m023.PACE_BUS_FIRST_XFER_FARE + FEEDER_BUS_BOARDING_FARE = dh.m023.FEEDER_BUS_BOARDING_FARE + FEEDER_BUS_CBD_FARE = dh.m023.FEEDER_BUS_CBD_FARE + + CTA_FIRST_XFER_FARE = dh.m023.CTA_FIRST_XFER_FARE + CTA_CBD_LINK_UP_FARE = dh.m023.CTA_CBD_LINK_UP_FARE + + AUTO_OPERATING_COST_BY_ZONETYPE = dh.m023.AUTO_OPERATING_COST_BY_ZONETYPE # AVERAGE OPERATING COST PER MILE FOR AUTO, BY ZONE TYPE + + m01_df = dh.m01 + + ZTYPE = m01_df['zone_type'].to_numpy() + fwbus_pk = m01_df['first_wait_bus_peak'].to_numpy().astype(np.float32) # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr_pk = m01_df['first_wait_feeder_peak'].to_numpy().astype(np.float32) # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + fwbus_op = m01_df['first_wait_bus_offpeak'].to_numpy().astype(np.float32) # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr_op = m01_df['first_wait_feeder_offpeak'].to_numpy().astype(np.float32) # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + PNRAVL = m01_df['pnr_flag'].astype(bool).to_numpy() # park-n-ride available, by zone + PRCOST = m01_df['pnr_parking_cost'].to_numpy().astype(np.float32) # park-n-ride cost, by zone + + FM_pk = dh.skims.first_mode_peak.astype(np.int32) + LM_pk = dh.skims.last_mode_peak.astype(np.int32) + FM_op = dh.skims.first_mode_offpeak.astype(np.int32) + LM_op = dh.skims.last_mode_offpeak.astype(np.int32) + + # simulate_approach_distances, simulate_approach_distances2 = compile_simulate_approach_distances(dh) + distr_array = np.stack([ + dh.distr['HW'], + dh.distr['HO'], + dh.distr['NH'], + ]).reshape((3,-1,5,3)).astype(np.float32) + + distr_BUS = dh.distr['HW'].loc[1].index.get_loc('bus') + distr_CTARAIL = dh.distr['HW'].loc[1].index.get_loc('ctarail') + distr_FEEDERBUS = dh.distr['HW'].loc[1].index.get_loc('feederbus') + distr_METRA = dh.distr['HW'].loc[1].index.get_loc('metra') + distr_PNR = dh.distr['HW'].loc[1].index.get_loc('pnr') + + + + trapp_struct = TransitApproachStruct( + fwbus_pk= fwbus_pk, + fwfdr_pk= fwfdr_pk, + fwbus_op= fwbus_op, + fwfdr_op= fwfdr_op, + ZTYPE= ZTYPE, + FM_pk= FM_pk, + LM_pk= LM_pk, + FM_op= FM_op, + LM_op= LM_op, + FEEDER_BUS_BOARDING_FARE= FEEDER_BUS_BOARDING_FARE, + FEEDER_BUS_CBD_FARE= FEEDER_BUS_CBD_FARE, + CTA_CBD_LINK_UP_FARE= CTA_CBD_LINK_UP_FARE, + CTA_FIRST_XFER_FARE= CTA_FIRST_XFER_FARE, + PACE_BUS_FIRST_XFER_FARE= PACE_BUS_FIRST_XFER_FARE, + PNRAVL= PNRAVL, + PRCOST= PRCOST, + AUTO_OPERATING_COST_BY_ZONETYPE= AUTO_OPERATING_COST_BY_ZONETYPE, + distr_array=distr_array, + distr_BUS = distr_BUS, + distr_CTARAIL = distr_CTARAIL, + distr_FEEDERBUS = distr_FEEDERBUS, + distr_METRA = distr_METRA, + distr_PNR = distr_PNR, + ) + + + return trapp_struct + + +def transit_approach_distances( + trapp_struct, + ozone, + dzone, + TPTYPE, + n_reps=50, + random_seed=None, +): + if random_seed is not None: + try: + seed_base = np.int32(random_seed) + except TypeError: + if isinstance(random_seed, np.random.Generator): + seed_base = random_seed.integers(0, 2147483647, dtype=np.int32) + else: + raise + else: + seed_base = np.int32(0) + TPTYPE = purposes_to_3.get(TPTYPE, 'NH') + approach_distances = np.zeros((ozone.shape[0], n_reps, 5, 2), dtype=np.float32) + seeds = np.zeros(ozone.shape[0], dtype=np.int32) + _transit_approach_distances(trapp_struct, ozone, dzone, TPTYPE, seed_base, approach_distances, seeds) + return approach_distances, seeds + + +@nb.njit(parallel=True, cache=True) +def _transit_approach_distances( + trapp_struct, + ozone, + dzone, + TPTYPE, + seed_base, + approach_distances, + seeded, +): + # struct data + ZTYPE = trapp_struct.ZTYPE + FM_pk = trapp_struct.FM_pk + LM_pk = trapp_struct.LM_pk + FM_op = trapp_struct.FM_op + LM_op = trapp_struct.LM_op + distr_array = trapp_struct.distr_array + distr_BUS = trapp_struct.distr_BUS + distr_CTARAIL = trapp_struct.distr_CTARAIL + distr_FEEDERBUS = trapp_struct.distr_FEEDERBUS + distr_METRA = trapp_struct.distr_METRA + distr_PNR = trapp_struct.distr_PNR + + assert approach_distances.shape[-2:] == (5,2), \ + "last dimensions approach_distances must be (5,2)" + + for z in nb.prange(ozone.shape[0]): + + ozone_idx = ozone[z]-1 + dzone_idx = dzone[z]-1 + + seed = np.int32(seed_base) + (np.int32(ozone_idx) << 14) + np.int32(dzone_idx) + seeded[z] = seed + np.random.seed(seed) + + # + # GET ZONE TYPES + # + ozone_type = ZTYPE[ozone_idx] + dzone_type = ZTYPE[dzone_idx] + # + # GET INTERCHANGE ATTRIBUTES + # FM=FIRST MODE,LM=LAST MODE,PM=PRIORITY MODE + # + if TPTYPE == 0: + FM = FM_pk[ozone_idx, dzone_idx] + LM = LM_pk[ozone_idx, dzone_idx] + else: + FM = FM_op[ozone_idx, dzone_idx] + LM = LM_op[ozone_idx, dzone_idx] + # + # INET TRANSIT NETWORK STORES SOME SUBURBAN BUS LINES (MODE=6) + # AS MODE=5 DUE TO ARRAY SIZE LIMITS. IF MODE=5 AND + # ZONE TYPE NO. 1 IS OUTSIDE OF CHICAGO, THEN CHANGE MODE TO 6. + # + + if (FM == 5) and (ozone_type > 2): + FM = 6 + if (LM == 5) and (dzone_type > 2): + LM = 6 + + # + # GET APPROACH DISTANCES FOR FIRST AND LAST MODES + # + for trip_end in [0,1]: + if trip_end == 0: + zone = ozone[z] + attached_mode = FM + else: + zone = dzone[z] + attached_mode = LM + if TPTYPE == 'HW': + distr_ = distr_array[0, zone - 1] + elif TPTYPE == 'HO': + distr_ = distr_array[1, zone - 1] + else: # if TPTYPE == 'NH': + distr_ = distr_array[2, zone - 1] + for J in range(N_DIST_TO_TYPES): + # OBTAIN APPROACH DISTANCES TO FIVE MODES + if (J == DIST_TO_BUS): + distr_params = distr_[distr_BUS] + elif (J == DIST_TO_CTA_RAIL) and (attached_mode == TransitModeCode_CTA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS CTA RAIL + distr_params = distr_[distr_CTARAIL] + elif (J == DIST_TO_METRA) and (attached_mode == TransitModeCode_METRA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + distr_params = distr_[distr_METRA] + elif (J == DIST_TO_FEEDER_BUS) and (attached_mode == TransitModeCode_METRA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + distr_params = distr_[distr_FEEDERBUS] + elif (J == DIST_TO_PARK_N_RIDE_STATION) and (trip_end == FRONT_END): + # PARK AND RIDE STATION DISTANCE OBTAINED WHEN TRIP END IS FRONT + distr_params = distr_[distr_PNR] + else: + distr_params = np.full(3, 999, dtype=np.float32) + for k in range(approach_distances.shape[1]): + if distr_params[2] == 101: # use_normal = (p3 == 101) + rv = np.random.normal(distr_params[0], distr_params[1]) + approach_distances[z, k, J, trip_end] = np.float32(min(max(rv, 0.06), 200.0)) + elif distr_params[2] < 101: # use_slopey = (p3 < 101) + x_min = distr_params[0] + x_max = distr_params[1] + ratio = distr_params[2] + if ratio == 1.0: + approach_distances[z, k, J, trip_end] = np.float32(min(np.random.uniform(x_min, x_max), 200.0)) + else: + span = x_max - x_min + if span != 0: + slope = (1.0 - ratio) / span + else: + slope = (1.0 - ratio) + area = .5 * (1 + ratio) * span + y = np.float32(np.random.uniform(0.0, 1.0)) * area + zp = np.sqrt(ratio * ratio + 2 * slope * y) + if slope: + rv = ((zp - ratio) / slope) + x_min + else: + rv = (zp - ratio) + x_min + approach_distances[z, k, J, trip_end] = min(max(rv, 0.06), 200.0) + else: # use_nan = (p3 == 999) + approach_distances[z, k, J, trip_end] = 255.0 + + +@nb.njit(cache=True) +def transit_approach( + trapp_struct, + ozone, + dzone, + TPTYPE, + approach_distances, + out, +): + # struct data + fwbus_pk = trapp_struct.fwbus_pk # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr_pk = trapp_struct.fwfdr_pk # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + fwbus_op = trapp_struct.fwbus_op # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr_op = trapp_struct.fwfdr_op # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + ZTYPE = trapp_struct.ZTYPE + FM_pk = trapp_struct.FM_pk + LM_pk = trapp_struct.LM_pk + FM_op = trapp_struct.FM_op + LM_op = trapp_struct.LM_op + FEEDER_BUS_BOARDING_FARE = trapp_struct.FEEDER_BUS_BOARDING_FARE + FEEDER_BUS_CBD_FARE = trapp_struct.FEEDER_BUS_CBD_FARE + CTA_CBD_LINK_UP_FARE = trapp_struct.CTA_CBD_LINK_UP_FARE + CTA_FIRST_XFER_FARE = trapp_struct.CTA_FIRST_XFER_FARE + PACE_BUS_FIRST_XFER_FARE = trapp_struct.PACE_BUS_FIRST_XFER_FARE + PNRAVL = trapp_struct.PNRAVL + PRCOST = trapp_struct.PRCOST + AUTO_OPERATING_COST_BY_ZONETYPE = trapp_struct.AUTO_OPERATING_COST_BY_ZONETYPE + + # random_state = check_random_state(random_state or ozone+dzone) + replication = approach_distances.shape[1] + + # if trace: + # log.log(trace, f"transit_approach({ozone},{dzone},{TPTYPE},{replication})") + + # convert inputs to length-1 vectors if not already vectors + # ozone = np.asanyarray(ozone) + # dzone = np.asanyarray(dzone) + vector_len = ozone.shape[0] + assert vector_len == dzone.shape[0] + + ozone_idx = ozone-1 + dzone_idx = dzone-1 + + # ZTYPE = m01_df['zone_type'].to_numpy() + # fwbus_pk = m01_df['first_wait_bus_peak'].to_numpy() # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + # fwfdr_pk = m01_df['first_wait_feeder_peak'].to_numpy() # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + # fwbus_op = m01_df['first_wait_bus_offpeak'].to_numpy() # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + # fwfdr_op = m01_df['first_wait_feeder_offpeak'].to_numpy() # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + # PNRAVL = m01_df['pnr_flag'].astype(bool).to_numpy() # park-n-ride available, by zone + # PRCOST = m01_df['pnr_parking_cost'].to_numpy() # park-n-ride cost, by zone + + if TPTYPE == HW: + fwbus = fwbus_pk # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr = fwfdr_pk # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + else: + fwbus = fwbus_op # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr = fwfdr_op # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + + # -- INITIALIZE VALUES -- + approach_cost = np.zeros((vector_len, replication, N_APPROACH_MODES), dtype=np.float32) + approach_waittime = np.zeros((vector_len, replication, N_APPROACH_MODES), dtype=np.float32) + approach_drivetime = np.zeros((vector_len, replication, N_APPROACH_MODES), dtype=np.float32) + approach_walktime = np.zeros((vector_len, replication, N_APPROACH_MODES), dtype=np.float32) + TVAR4 = np.zeros((vector_len, replication, 5), dtype=np.float32) + + best_approach_mode = np.zeros((vector_len,replication, N_TRIP_ENDS), dtype=np.int8) + best_cost = np.zeros((vector_len, replication, N_TRIP_ENDS), dtype=np.int32) + best_waittime = np.zeros((vector_len, replication, N_TRIP_ENDS), dtype=np.int32) + best_walktime = np.zeros((vector_len, replication, N_TRIP_ENDS), dtype=np.int32) + best_drivetime = np.zeros((vector_len, replication, N_TRIP_ENDS), dtype=np.int32) + # + # GET ZONE TYPES + # + ozone_type = ZTYPE[ozone_idx] + dzone_type = ZTYPE[dzone_idx] + # + # GET INTERCHANGE ATTRIBUTES + # FM=FIRST MODE,LM=LAST MODE,PM=PRIORITY MODE + # + FM = np.empty(ozone_idx.size, dtype=np.int8) + LM = np.empty(ozone_idx.size, dtype=np.int8) + if TPTYPE == 'HW': + for i in range(ozone_idx.size): + FM[i] = FM_pk[ozone_idx[i], dzone_idx[i]] + LM[i] = LM_pk[ozone_idx[i], dzone_idx[i]] + else: + for i in range(ozone_idx.size): + FM[i] = FM_op[ozone_idx[i], dzone_idx[i]] + LM[i] = LM_op[ozone_idx[i], dzone_idx[i]] + # + # INET TRANSIT NETWORK STORES SOME SUBURBAN BUS LINES (MODE=6) + # AS MODE=5 DUE TO ARRAY SIZE LIMITS. IF MODE=5 AND + # ZONE TYPE NO. 1 IS OUTSIDE OF CHICAGO, THEN CHANGE MODE TO 6. + # + + FM[(FM == 5) & (ozone_type > 2)] = 6 + LM[(LM == 5) & (ozone_type > 2)] = 6 + + # + # GET APPROACH DISTANCES FOR FIRST AND LAST MODES + # + + assert approach_distances.shape == (vector_len, replication, N_DIST_TO_TYPES, N_TRIP_ENDS) + + # CHECK FIRST/LAST MODES AND COMPUTE APPROACH TIME AND COST + # + # ARRAYS approach_walktime,APCOST,approach_drivetime CONTAIN TIME TO WALK,APPROACH COST, + # AND IN-VEHICLE APPROACH TIME RESPECTIVELY. THESE ARRAYS HAVE FIVE + # ELEMENTS FOR FIVE POSSIBLE APPROACH MODES.( 1-WALK,2-BUS, + # 3-PARK & RIDE,4-KISS & RIDE,AND 5-FEEDER BUS) + # + + for I in range(N_TRIP_ENDS): + # I=1 GET VALUES FOR ORIGIN + # I=2 GET VALUES FOR DESTINATION + if (I == FRONT_END): + Z = ozone + M = FM + else: # I == BACK_END + Z = dzone + M = LM + + ZTYPE_Z = ZTYPE[Z-1] + + # + # IN THIS CASE WE ARE MAKING THE STATION PARKING COST FOR HOME BASED OTHER AND + # NON-HOME BASED TRIPS EQUAL TO 60 PERCENT OF HOME BASED WORK + # CHANGE MADE 12/8/93 BY GWS NEXT LINE + # IF(TPTYPE.NE.1) PRCOST(Z) = PRCOST(Z) * 0.6 + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # NONWORK PARK AND RIDE PARKING COST IS NOW READ FROM M01. IN MANY + # CASES THE NONWORK PNR COSTS ARE HIGHER THAN WORK DUE TO + # DISCOUNTING OF MONTHLY PARKING FEES. + # + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # SET HIGH STARTING VALUE OF TVAR5 + TVAR5 = np.full((vector_len, replication), 1.E10) + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # IN CALCULATING TVAR4 AND TVAR5 + # IN-VEHICLE TIME = DRVOT = 20 CENTS/MIN + # OUT-OF-VEHICLE TIME = 40 CENTS/MIN + # PASSENGER TIME = 0.5 DRIVER TIME + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # + # FOLLOWING SECTION ADDED BY EASH TO SIMPLIFY LOGIC + # IF M IS BUS (MODE<7) THEN ONLY POSSIBLE APPROACH COST IS TIME TO + # WALK TO BUS. OTHER APPROACH COSTS AND TIMES ARE LINE=HAUL. + t1 = (M < TransitModeCode_CTA_RAIL) + if np.any(t1): + J = APPROACH_WALK + approach_walktime[t1,:,J] = approach_distances[t1,:, DIST_TO_BUS, I] / SPDWLK * 600. + # INCREASE WALK TIME IN CHICAGO CBD FOR WORK TRIPS + cbd_work = t1 & (ZTYPE_Z == 1) & (TPTYPE == HW) + approach_walktime[cbd_work,:,J] *= 1.20 + + # if (ZTYPE_Z == 1 and TPTYPE == HW): + # approach_walktime[:, 0] = approach_walktime[:, 0] * 1.20 + TVAR4[t1,:, J] = approach_walktime[t1,:, 0] * DRVOT * 2.0 + TVAR5[t1,:] = TVAR4[t1,:, J] + best_approach_mode.reshape((vector_len,replication,N_TRIP_ENDS))[t1,:, I] = 0 + best_drivetime[t1,:, I] = 0 + best_walktime[t1,:, I] = approach_walktime[t1,:, 0] + .5 + best_cost[t1, :, I] = 0 + best_waittime[t1,:, I] = 0 + for J in [APPROACH_BUS, APPROACH_PARK_N_RIDE, APPROACH_KISS_N_RIDE, APPROACH_FEEDER_BUS]: + TVAR4[t1,:, J] = 0.0 + approach_cost[t1, :, J] = 0.0 + approach_waittime[t1, :, J] = 0.0 + approach_drivetime[t1,:, J] = 0.0 + approach_walktime[t1,:, J] = 0.0 + + t = (M >= TransitModeCode_CTA_RAIL) + if np.any(t): + # REMAINDER OF SUBROUTINE FOR RAIL TRANSIT/COMMUTER RAIL ONLY + # GET VALUES FOR FIVE ALTERNATIVES + for J in range(5): + TVAR4[t,:, J] = 0.0 + approach_cost[t, :, J] = 0.0 + approach_waittime[t,:,J] = 0.0 + approach_drivetime[t,:, J] = 0.0 + approach_walktime[t,:, J] = 0.0 + + K = np.maximum(0, M - 6).astype(np.int8) # 0 for BUS, 1 for CTA RAIL(7-1), 2 for METRA(8-1) + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=0(WALK).COMPUTE WALKING TIME TO FIRST MODE.NO COST OR IN-VEHICLE TIME + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + if J == APPROACH_WALK: + + for _kt in range(approach_distances.shape[2]): + kt = t & (K == _kt) + approach_walktime[kt,:, J] = approach_distances[kt, :, _kt, I] / SPDWLK * 600. + # INCREASE WALK TIME IN CHICAGO CBD FOR WORK TRIPS + cbd_work = t & (ZTYPE_Z == 1) & (TPTYPE == HW) + approach_walktime[cbd_work,:, J] *= 1.20 + # if (ZTYPE_Z == 1 and TPTYPE == HW): + # approach_walktime[:, J] = approach_walktime[:, J] * 1.20 + TVAR4[t,:, J] = approach_walktime[t,:, J] * DRVOT * 2.0 + # ADD APPROACH TIMES AND COSTS - EVERYTHING SHOULD NOW BE IN CENTS + TVAR4[t,:, J] += approach_cost[t, :, J] + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=1(BUS) FIRST MODE. COMPUTE WALKING TIME, COST, AND IN-VEHICLE TIME + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + elif J == APPROACH_BUS or (J == APPROACH_FEEDER_BUS and I == FRONT_END): + + if J == APPROACH_FEEDER_BUS: + approach_walktime[t, :, J] = approach_distances[t,:, DIST_TO_FEEDER_BUS, I] * 600.0 / SPDWLK + approach_waittime[t, :, J] = np.expand_dims(fwfdr[Z-1][t], 1) # broadcast + else: + approach_walktime[t,:, J] = approach_distances[t,:, DIST_TO_BUS, I] * 600.0 / SPDWLK + # INCREASE WALK TIME IN CHICAGO CBD + approach_walktime[t & (ZTYPE_Z == 1), :, J] *= 1.20 + approach_waittime[t,:,J] = np.expand_dims(fwbus[Z-1][t],1) # broadcast + for _kt in range(approach_distances.shape[2]): + kt = t & (K == _kt) + approach_drivetime[kt,:, J] = approach_distances[kt,:, _kt, I] / np.expand_dims(SPEEDS[ZTYPE_Z[kt]-1 + 4],1) * 60. # broadcast + TVAR4[t,:, J] = ( + approach_walktime[t,:, J] * OVT_IVT_RATIO + + approach_drivetime[t,:, J] + + approach_waittime[t,:,J] * OVT_IVT_RATIO + ) * DRVOT + + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # + # COST COMPUTATIONS FOR APPROACH BUS + # REVISED BY EASH 12/4/93 TO REFLECT CURRENT FARES + # ==== ORIGIN ==== + if (I == FRONT_END): + # FIRST MODE SUBURBAN RAIL - CHECK ZONE TYPE AT ORIGIN + # --- SUBURBAN ORIGIN, PACE BUS --- + s = t & (FM == TransitModeCode_METRA_RAIL) & (ozone_type > 2) + if np.any(s): + # PACE BUS - METRA RAIL, ADDED FARE IS PACE FEEDER BUS FARE + approach_cost[s & (LM == TransitModeCode_METRA_RAIL), :, J] = FEEDER_BUS_BOARDING_FARE + # PACE BUS - METRA RAIL - CTA, NO ADDED FARE, LINKUP > FEEDER BUS + # already zero # approach_cost[s & (LM == TransitModeCode_CTA_RAIL), :, J] = 0 + # PACE BUS - METRA RAIL - PACE, ADDED FARE IS LINKUP LESS FEEDER BUS + approach_cost[s & (LM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + + # --- CHICAGO ORIGIN, CTA BUS --- + s = t & (FM == TransitModeCode_METRA_RAIL) & (ozone_type <= 2) + if np.any(s): + # CTA BUS - METRA RAIL, ADDED FARE IS LINKUP FARE (SINGLE RIDE) + approach_cost[s & (LM == TransitModeCode_METRA_RAIL), :, J] = CTA_CBD_LINK_UP_FARE + # CTA BUS - METRA RAIL - CTA, ADDED FARE IS CTA TRANSFER + approach_cost[s & (LM == TransitModeCode_CTA_RAIL), :, J] = CTA_FIRST_XFER_FARE + # CTA BUS - METRA RAIL - PACE, ADDED FARE IS LINKUP LESS FEEDER BUS + approach_cost[s & (LM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + + # FIRST MODE CTA RAIL + # WHEN THIS IS TRUE A FULL FARE AND TRANSFER HAVE + # BEEN PAID, SO NO ADDED FARE IS NEEDED FOR BUS + + + # ORIGIN OTHER THAN CHICAGO, ADDED FARE IS NOW AN RTA TRANSFER + s = t & (FM < TransitModeCode_CTA_RAIL) & (ozone_type > 2) + if np.any(s): + approach_cost[s, :, J] = PACE_BUS_FIRST_XFER_FARE + + # CHICAGO ORIGIN, ADDED FARE IS CTA TRANSFER + s = t & (FM < TransitModeCode_CTA_RAIL) & (ozone_type <= 2) + if np.any(s): + approach_cost[s, :, J] = CTA_FIRST_XFER_FARE + + TVAR4[t, :, J] += approach_cost[t, :, J] + + + # ==== DESTINATION ==== + else: + # LAST MODE SUBURBAN RAIL + s = t & (LM == TransitModeCode_METRA_RAIL) & (dzone_type > 2) + if np.any(s): + # SUBURBAN DESTINATION, PACE BUS + # METRA RAIL - PACE BUS, ADDED FARE IS PACE FEEDER BUS FARE + approach_cost[s & (FM == TransitModeCode_METRA_RAIL), :, J] = FEEDER_BUS_BOARDING_FARE + # CTA - METRA RAIL - PACE BUS, NO ADDED FARE, LINKUP > FEEDER BUS + # PACE - METRA RAIL - PACE BUS, ADDED FARE IS LINKUP LESS FEEDER BUS + approach_cost[s & (FM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + s = t & (LM == TransitModeCode_METRA_RAIL) & (dzone_type <= 2) + if np.any(s): + # CHICAGO DESTINATION, CTA BUS + # METRA - CTA BUS, ADDED COST IS LINKUP FARE (SINGLE RIDE) + approach_cost[s & (FM == TransitModeCode_METRA_RAIL), :, J] = CTA_CBD_LINK_UP_FARE + # CTA - METRA - CTA BUS, ADDED COST IS CTA TRANSFER + approach_cost[s & (FM == TransitModeCode_CTA_RAIL), :, J] = CTA_FIRST_XFER_FARE + # PACE - METRA - CTA BUS, ADDED COST IS LINKUP MINUS FEEDER BUS + approach_cost[s & (FM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + # ADD CTA TRANSFER IF NOT ALREADY PAID BUT IT WAS USED + s = t & (LM < TransitModeCode_CTA_RAIL) & (dzone_type > 2) + if np.any(s): + approach_cost[s, :, J] = CTA_FIRST_XFER_FARE * ( + (best_approach_mode[s,:, FRONT_END]==APPROACH_BUS) + |(best_approach_mode[s,:, FRONT_END]==APPROACH_FEEDER_BUS) + ) + + TVAR4[t, :, J] += approach_cost[t, :, J] + + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=2(PARK & RIDE) FIRST MODE. PARK & RIDE FOR APPROACH TO RAPID TRANSIT AND SUBURBAN RAIL ROAD + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + elif (J == APPROACH_PARK_N_RIDE and I == FRONT_END): + approach_drivetime[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] / np.expand_dims(SPEEDS[ZTYPE_Z[t] - 1],1) * 60. # broadcast + approach_walktime[t,:, J] = W2PNR + # APPROACH COST=PER MILE COST + FIXED COST + approach_cost[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] * np.expand_dims(AUTO_OPERATING_COST_BY_ZONETYPE[ZTYPE_Z[t] - 1],1) # broadcast + # OPERATING COST MAY NOT BE LESS THAN 5 CENTS + approach_cost[t,:, J] = np.fmax(approach_cost[t,:, J], 5.0) + + approach_cost[t,:, J] = approach_cost[t,:, J] + AFC1 + # ADD HALF OF THE PARKING COST IF PARK-&-RIDE AVAILABLE + _tz = t&PNRAVL[Z-1] + approach_cost[_tz,:, J] += np.expand_dims(PRCOST[Z-1][_tz],1) / 2 # broadcast + # IF NO PARK-&-RIDE FACILITY AVAILABLE INCREASE WALK TIME + approach_walktime[~_tz,:, J] = 3 * W2PNR + + TVAR4[t,:, J] = ( + approach_walktime[t,:, J] * DRVOT * 2.0 + + approach_drivetime[t,:, J] * DRVOT + + approach_cost[t,:, J] + ) + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=3(KISS & RIDE) FIRST MODE. KISS & RIDE FOR APPROACH TO RAPID TRANSIT AND SUBURBAN RAIL ROAD + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + elif (J == APPROACH_KISS_N_RIDE and I == FRONT_END): + approach_drivetime[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] / np.expand_dims(SPEEDS[ZTYPE_Z[t] - 1],1) * 60. # broadcast + approach_walktime[t,:, J] = W2PNR + approach_cost[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] * np.expand_dims(AUTO_OPERATING_COST_BY_ZONETYPE[ZTYPE_Z[t] - 1],1) # broadcast + approach_cost[t,:, J] = np.fmin(approach_cost[t,:, J], 5.0) + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # ASSUMPTION IS THAT KISS AND RIDE REQUIRES A SPECIAL + # TRIP FROM HOME. DRIVER AND PASSENGER TIME VALUES NOW EQUAL. + # APCOST[J]=APCOST[J]*2.+AFC2+(DRVOT*approach_drivetime[J]*2.)/10 + approach_cost[t,:, J] = approach_cost[t,:, J] * 2. + AFC2 + TVAR4[t,:, J] = ( + approach_walktime[t,:, J] * OVT_IVT_RATIO + + approach_drivetime[t,:, J] * 2 # KISSING DRIVER + + approach_drivetime[t,:, J] + ) * DRVOT + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + TVAR4[t,:, J] += approach_cost[t,:, J] + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # EVALUATE APPROACH MODES AND SELECT THE BEST + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # FOLLOWING CODE CHANGED BY EASH 12/6/93 TO REFLECT + # NEW TRIP TYPES + # TPTYPE = 1 HOME PRODUCTIONS TO WORK ATTRACTIONS + # TPTYPE = 2 HOME PRODUCTIONS TO NON-WORK/NON-HOME ATTRACTIONS + # TPTYPE = 3 NON-HOME PRODUCTIONS TO NON-HOME ATTRACTIONS + for J in range(N_APPROACH_MODES): + # NO KISS-&-RIDE FOR NON-WORK TRIPS + if (TPTYPE != HW and J == APPROACH_KISS_N_RIDE): + continue + # NO PARK-AND RIDE OR KISS-&-RIDE AT THE WORK/OTHER + # ATTRACTION END FOR HOME BASED TRIPS + if (TPTYPE != NH and I == BACK_END and (J == APPROACH_PARK_N_RIDE or J == APPROACH_KISS_N_RIDE)): + continue + # NO PARK-&-RIDE OR KISS AND RIDE FOR NON-HOME TO NON-HOME TRIPS + if (TPTYPE == NH and (J == APPROACH_PARK_N_RIDE or J == APPROACH_KISS_N_RIDE)): + continue + # -- FIND LOWEST COST APPROACH + for _i1 in range(TVAR4.shape[0]): + for _i2 in range(TVAR4.shape[1]): + if (TVAR4[_i1, _i2, J] > 0) and (TVAR4[_i1, _i2, J] < TVAR5[_i1, _i2]): + TVAR5[_i1, _i2] = TVAR4[_i1, _i2, J] + best_approach_mode[_i1, _i2, I] = J + best_drivetime[_i1, _i2, I] = approach_drivetime[_i1, _i2, J] + .5 + best_walktime[_i1, _i2, I] = approach_walktime[_i1, _i2, J] + .5 + best_cost[_i1, _i2, I] = approach_cost[_i1, _i2, J] + .5 + best_waittime[_i1, _i2, I] = approach_waittime[_i1, _i2, J] + .5 + + # if trace: + # log.log(trace, f" DIRECTION {I} APPROACH TYPE {J} {APPROACH_MODE_NAMES.get(J)}") + # log.log(trace, f" drivetime {approach_drivetime[:5,:5, J]}") + # log.log(trace, f" walktime {approach_walktime[:5,:5, J]}") + # log.log(trace, f" cost {approach_cost[:5,:5, J]}") + # log.log(trace, f" waittime {approach_waittime[:5,:5,J]}") + # log.log(trace, f" gen cost {TVAR4[:5,:5, J]}") + # if trace: + # log.log(trace, f" DIRECTION {I} BEST APPROACH TYPE {best_approach_mode[:5,I]}") + + + # ADD ORIGIN AND DESTINATION QUANTITIES AND PASS BACK TO TRIPS + + ae_drivetime = best_drivetime[:,:, 0] + best_drivetime[:,:, 1] + ae_walktime = best_walktime[:,:, 0] + best_walktime[:,:, 1] + ae_cost = best_cost[:,:, 0] + best_cost[:,:, 1] + ae_waittime = best_waittime[:,:, 0] + best_waittime[:,:, 1] + + ae_drivetime = ae_drivetime.reshape((vector_len,replication)) + ae_walktime = ae_walktime.reshape((vector_len,replication)) + ae_cost = ae_cost.reshape((vector_len,replication)) + ae_waittime = ae_waittime.reshape((vector_len,replication)) + best_approach_mode = best_approach_mode.reshape((vector_len,replication,N_TRIP_ENDS)) + + out[:,:,0] = ae_drivetime + out[:,:,1] = ae_walktime + out[:,:,2] = ae_cost + out[:,:,3] = ae_waittime + out[:,:,4] = best_approach_mode[:,:,0] + out[:,:,5] = best_approach_mode[:,:,1] + + # return ( + # ae_drivetime, + # ae_walktime, + # ae_cost, + # ae_waittime, + # best_approach_mode, + # ) + +@nb.njit(parallel=True, cache=True) +def transit_approach_parallel( + trapp_struct, + ozone, + dzone, + TPTYPE, + approach_distances, +): + out = np.zeros((ozone.size, approach_distances.shape[1], 6), dtype=np.int32) + slices = ozone.size // 100 + (1 if ozone.size % 100 else 0) + for i in nb.prange(slices): + s = slice(i*100, (i+1)*100) + transit_approach( + trapp_struct, + ozone[s], + dzone[s], + TPTYPE, + approach_distances[s], + out[s], + ) + return ( + out[:, :, 0], + out[:, :, 1], + out[:, :, 2], + out[:, :, 3], + out[:, :, 4:], + ) + +def transit_approach_wrap( + trapp_struct, + ozone, + dzone, + TPTYPE, + approach_distances, +): + out_tuple = transit_approach_parallel( + trapp_struct, + ozone, + dzone, + TPTYPE, + approach_distances, + ) + out = Dict() + out.drivetime = out_tuple[0] + out.walktime = out_tuple[1] + out.cost = out_tuple[2] + out.waittime = out_tuple[3] + out.approach_mode = out_tuple[4] + return out + +#return transit_approach_wrap, transit_approach_distances \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/hh_sampling.py b/src/Mode-Dest-TOD/cmap_modedest/hh_sampling.py new file mode 100644 index 0000000..72e5486 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/hh_sampling.py @@ -0,0 +1,25 @@ +import numpy as np +import pandas as pd +from cmap_modedest.random_states import check_random_generator + + +def sample_hh_from_zone(dh, zone, n_hh, random_state=None, attr=('N_ADULTS', 'N_VEHICLES')): + pool = dh.hh_tabulation.loc[zone] + hhv_types = dh.hhv_types + pool_sum = pool.sum() + if pool_sum: + hhv_prob = pool / pool_sum + else: + # No households in this zone to enumerate, sample from region instead to avoid NaNs + pool = dh.hh_tabulation.sum() + pool_sum = pool.sum() + hhv_prob = pool / pool_sum + prng = check_random_generator(random_state) + draws = prng.choice(624, size=n_hh, p=hhv_prob) + result = pd.DataFrame(-1, dtype=np.int8, columns=attr, index=pd.RangeIndex(n_hh)) + for i, a in enumerate(attr): + if a == 'N_ADULTS': + result.values[:, i] = hhv_types[a].cat.codes.iloc[draws] + 1 + else: + result.values[:, i] = hhv_types[a].cat.codes.iloc[draws] + return result diff --git a/src/Mode-Dest-TOD/cmap_modedest/incomes.py b/src/Mode-Dest-TOD/cmap_modedest/incomes.py new file mode 100644 index 0000000..08eb695 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/incomes.py @@ -0,0 +1,99 @@ +import numpy as np +import pandas as pd +from scipy.stats import lognorm + +from .random_states import check_random_generator + +income_levels_1 = { + 1 : 12_000, # Less than $15,000 + 2 : 20_000, # $15,000 to $24,999 + 3 : 27_500, # $25,000 to $29,999 + 4 : 32_500, # $30,000 to $34,999 + 5 : 42_500, # $35,000 to $49,999 + 6 : 55_000, # $50,000 to $59,999 + 7 : 65_000, # $60,000 to $74,999 + 8 : 85_000, # $75,000 to $99,999 + 9 : 120_000, # $100,000 to $149,999 + 10 : 170_000, # $150,000 or more +} + +income_levels_2 = { + 1 : 25_001, # Less than $30,000 + 2 : 40_001, # $30,000 to $59,999 + 3 : 70_001, # $60,000 to $99,999 + 4 : 125_001, # $100,000 to $149,999 + 5 : 175_001, # $150,000 or more +} + + + +def random_incomes( + median_income, + replications, + random_state=None, + sigma=0.42, + bins=None, + trunc_max=None, + trunc_min=None, +): + """ + Draw random income levels from a log-normal distribution + + Parameters + ---------- + median_income : numeric + replications : int + Size of resulting array + random_state : RandomState + sigma : float, default 0.42 + The standard deviation of the underlying normal distribution. + The default of 0.42 is retained from prior versions of the CMAP + trip-based model, although a bug in that model resulted in a + downward bias in the random draws. + bins : array-like or '5', optional, + If provided, digitize into these bins. + + Returns + ------- + ndarray + """ + random_generator = check_random_generator(random_state) + y = lognorm(sigma, scale=median_income).rvs( + replications, + random_state=random_generator, + ) + # resample from acceptable draws when truncated + if trunc_max is not None: + acceptable = y[(y <= trunc_max)] + acceptable_size = acceptable.size + if acceptable_size == 0: + acceptable = [trunc_max] + swaps = random_generator.choice(acceptable, y.size-acceptable_size) + y[(y > trunc_max)] = swaps + if trunc_min is not None: + acceptable = y[(y >= trunc_min)] + acceptable_size = acceptable.size + if acceptable.size == 0: + acceptable = [trunc_min] + swaps = random_generator.choice(acceptable, y.size-acceptable_size) + y[(y < trunc_min)] = swaps + if bins == '5': + bins = [ + -np.inf, + 30_000, + 60_000, + 100_000, + 150_000, + np.inf, + ] + if bins == '4': + bins = [ + -np.inf, + 30_000, + 60_000, + 150_000, + np.inf, + ] + if bins is not None: + return np.digitize(y, bins) + return y \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/modecodes.py b/src/Mode-Dest-TOD/cmap_modedest/modecodes.py new file mode 100644 index 0000000..8524a96 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/modecodes.py @@ -0,0 +1,60 @@ +import numpy as np +from .addict import Dict + +mode5names = ['AUTO', 'TAXI', 'TNC1', 'TNC2', 'TRANSIT'] +mode5codes = Dict(zip( + mode5names, + np.arange(len(mode5names)) + 1, +)) + +mode7names = ['AUTO', 'TAXI', 'TNC1', 'TNC2', 'TRANSIT', 'WALK', 'BIKE'] +mode7codes = Dict(zip( + mode7names, + np.arange(len(mode7names)) + 1, +)) + +mode9names = ['AUTO', 'HOV2', 'HOV3', 'TAXI', 'TNC1', 'TNC2', 'TRANSIT', 'WALK', 'BIKE'] +mode9codes = Dict(zip( + mode9names, + np.arange(len(mode9names)) + 1, +)) + + +TransitModeCode_CTA_REGULAR_BUS = 4 +TransitModeCode_CTA_EXPRESS_BUS = 5 +TransitModeCode_PACE_BUS = 6 +TransitModeCode_CTA_RAIL = 7 +TransitModeCode_METRA_RAIL = 8 + +N_TRANSIT_MODES = 8 + + +APPROACH_WALK = 0 +APPROACH_BUS = 1 +APPROACH_PARK_N_RIDE = 2 +APPROACH_KISS_N_RIDE = 3 +APPROACH_FEEDER_BUS = 4 + +N_APPROACH_MODES = 5 +APPROACH_MODE_NAMES = { + APPROACH_WALK: 'Walk', + APPROACH_BUS: 'Bus', + APPROACH_PARK_N_RIDE: 'PnR', + APPROACH_KISS_N_RIDE: 'KnR', + APPROACH_FEEDER_BUS: 'Feeder', +} + +DIST_TO_BUS = 0 +DIST_TO_CTA_RAIL = 1 +DIST_TO_METRA = 2 +DIST_TO_FEEDER_BUS = 3 +DIST_TO_PARK_N_RIDE_STATION = 4 + +N_DIST_TO_TYPES = 5 +DIST_TO_NAMES = { + DIST_TO_BUS: 'to Bus', + DIST_TO_CTA_RAIL: 'to El', + DIST_TO_METRA: 'to Metra', + DIST_TO_FEEDER_BUS: 'to Feeder', + DIST_TO_PARK_N_RIDE_STATION: 'to PnR', +} \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/numexpr_patch.py b/src/Mode-Dest-TOD/cmap_modedest/numexpr_patch.py new file mode 100644 index 0000000..59dd7a5 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/numexpr_patch.py @@ -0,0 +1,31 @@ + +# Numexpr's caching sometimes fails on dask multi-threaded + + +class CacheDictSafe(dict): + """ + A dictionary that prevents itself from growing too much. + """ + + def __init__(self, maxentries): + self.maxentries = maxentries + super(CacheDictSafe, self).__init__(self) + + def __setitem__(self, key, value): + # Protection against growing the cache too much + if len(self) > self.maxentries * 2: + # The cache is overflowing, wipe it completely + super(CacheDictSafe, self).clear() + if len(self) > self.maxentries: + # Remove a 10% of (arbitrary) elements from the cache + entries_to_remove = self.maxentries // 10 + for k in list(self.keys())[:entries_to_remove]: + try: + super(CacheDictSafe, self).__delitem__(k) + except KeyError: + pass + super(CacheDictSafe, self).__setitem__(key, value) + + +import numexpr as ne +ne.necompiler._numexpr_cache = CacheDictSafe(256) diff --git a/src/Mode-Dest-TOD/cmap_modedest/parking_costs.py b/src/Mode-Dest-TOD/cmap_modedest/parking_costs.py new file mode 100644 index 0000000..924b198 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/parking_costs.py @@ -0,0 +1,371 @@ +import numpy as np +import pandas as pd +from .random_states import check_random_generator + +# cbd_parking = pd.read_csv( +# filenames.HW_CBDPARK, +# header=None, +# names=['ZoneID', 'CumProb', 'ThresholdPrice', 'SavePrice', 'WalkSeconds'], +# ) +# cbd_parking.CumProb /= 10000. +# # cbd_parking['SumPrice'] = cbd_parking.ThresholdPrice + cbd_parking.SavePrice +# cbd_parking['rownum'] = cbd_parking.groupby(['ZoneID']).cumcount() +# _z = cbd_parking.ZoneID.value_counts().sort_index().index +# CBD_PARKING_ZONES = dict(zip(_z, np.arange(len(_z)))) +# +# +# def decumulate(x): +# x_ = np.array(x) +# x_[1:] -= x[:-1] +# return x_ +# cbd_parking['Prob'] = cbd_parking.groupby("ZoneID")['CumProb'].transform(decumulate) +# cbd_parking['WeightedPrice'] = cbd_parking['Prob'] * cbd_parking['ThresholdPrice'] +# cbd_parking_prices = cbd_parking.set_index(["ZoneID",'rownum']).ThresholdPrice.unstack() +# cbd_parking_price_prob = cbd_parking.set_index(["ZoneID",'rownum']).Prob.unstack() +# +# +# +# +# cbd_parking2 = pd.read_csv( +# filenames.HW_CBDPARK2, +# header=None, +# names=[ +# 'IncomeCeiling', +# 'FreeParkingPct', +# 'TransitPct', +# 'AutoOcc1Pct', +# 'AutoOcc2Pct', +# 'AutoOcc3Pct', +# 'AutoOcc4Pct', +# ], +# ) + + +# def parking_cost_cbd( +# ORIG, +# DEST, +# INCOME, +# HOURS, +# random_state=None, +# ): +# """ +# This function tries to exactly replicate the FORTRAN PRKCBD, right or wrong +# +# Parameters +# ---------- +# ORIG, DEST : int +# TAZ ID for origin, destination +# INCOME : array-like, shape[ITER] +# HOURS : numeric +# Number of hours of parking to pay for +# CBD_PARKING_ZONES : Mapping +# Maps destination zone numbers to CBD parking zone numbers +# random_state +# +# Returns +# ------- +# CAPK, WALK3, INTOCC, BLK, SI : array, shape[ITER] +# parking cost, walktime, vehicle occupancy, blocks walked, savings rate +# """ +# global CBD_PARKING_ZONES +# random_state = check_random_generator(random_state) +# +# ITER = INCOME.shape[0] +# +# J6 = np.zeros(ITER) +# J7 = np.ones(ITER) +# J3 = np.zeros(ITER, dtype=int) +# L = np.zeros(ITER, dtype=int) +# +# RAN2 = random_state.random(size=ITER) +# RAN3 = random_state.random(size=ITER) * 100. # Free Parking randomizer +# RAN4 = random_state.random(size=ITER) +# RAN5 = random_state.random(size=ITER) * 100. # Auto Occupancy randomizer +# +# # ORIG = pd.Series(ORIG) +# # DEST = pd.Series(DEST) +# +# PZONE = CBD_PARKING_ZONES[DEST] +# FREEPRK = np.empty(ITER) +# for j2 in reversed(range(5)): +# k = INCOME 1] = 0 +# J6[J7 == 0] = 1 +# +# VT = INCOME/2400. +# +# # Baseline free parking +# CAPK = np.zeros(ITER, dtype=int) +# WALK3 = np.full(ITER, 3.0) +# HC = np.zeros(ITER) +# SI = np.zeros(ITER) +# WK = np.zeros(ITER) +# BLK = np.zeros(ITER) +# +# paid_parking = (RAN3 > FREEPRK) +# HC[paid_parking] = ( +# J7 * CBDPRK.ThresholdPrice.iloc[0] + # when using first row +# J6 * (HCPT1 + (HCPT2-HCPT1)*(HCPT3-RAN2)/(HCPT3_4)) # when using other rows +# )[paid_parking] +# SI[paid_parking] = CBDPRK.SavePrice[J3].values[paid_parking] +# WK[paid_parking] = np.fmax(CBDPRK.WalkSeconds[J3].values[paid_parking], 180) +# BLK[paid_parking] = SI[paid_parking] / (VT[paid_parking] * WK[paid_parking] / 60.) # BLK IS BLOCKS WALKED +# BLK[paid_parking] = np.clip(BLK[paid_parking], 0.25, 6.0) +# WALK3[paid_parking] = (BLK[paid_parking] * WK[paid_parking]) / 60. +# CAPK[paid_parking] = np.clip(HC[paid_parking] * HOURS - BLK[paid_parking] * SI[paid_parking], 0.0, None) +# +# INTOCC = np.zeros(ITER, dtype=np.int8) +# RAN5 -= cbd_parking2.loc[L, 'AutoOcc1Pct'].values +# INTOCC[(INTOCC==0) & (RAN5 < 0)] = 1 +# RAN5 -= cbd_parking2.loc[L, 'AutoOcc2Pct'].values +# INTOCC[(INTOCC==0) & (RAN5 < 0)] = 2 +# RAN5 -= cbd_parking2.loc[L, 'AutoOcc3Pct'].values +# INTOCC[(INTOCC==0) & (RAN5 < 0)] = 3 +# INTOCC[(INTOCC==0)] = 4 +# +# return CAPK, WALK3, INTOCC, BLK, SI +# + +def parking_cost_v2( + dh, + DEST, + INCOME, + HOURS, + purpose, + random_state=None, +): + + """ + Draw a parking cost from the random distribution in the destination zone. + + Parameters + ---------- + DEST : array-like, shape[ITER] + TAZ ID for destination + INCOME : array-like, shape[ITER] + HOURS : numeric + Number of hours of parking to pay for + random_state + + Returns + ------- + CAPK, WALK3, INTOCC, BLK, SI : array, shape[ITER] + parking cost, walktime, vehicle occupancy, blocks walked, savings rate + """ + global CBD_PARKING_ZONES, cbd_parking_price_prob, cbd_parking_prices + random_state = check_random_generator(random_state) + + DEST = pd.Series(DEST) + ITER = DEST.size + + rand_free_parking = random_state.random(size=ITER) * 100. # Free Parking randomizer + rand_parking_price = random_state.random(size=ITER) # Parking Rate randomizer + RAN5 = random_state.random(size=ITER) * 100. # Auto Occupancy randomizer + + price_probs = dh.cbd_parking_price_prob.reindex(DEST.values) + prices = dh.cbd_parking_prices.reindex(DEST.values) + parking_price_row = np.full(ITER, -1, dtype=np.int8) + for i in range(5): + rand_parking_price -= price_probs.iloc[:,0] + parking_price_row[(parking_price_row < 0) & (rand_parking_price < 0)] = i + + # Assemble the randomly selected parking-price columns into one Series. + # It will have NaN values for zones outside the CBD parking model + parking_price_1 = pd.Series( + prices.values[range(len(parking_price_row)), parking_price_row], + index=DEST.index, + ) + + # Assemble default hourly pricing to use for trips based on zone type + # This Series is len(Zones) not len(Trips) + zonetype_price = dh.m01.zone_type.map(dh.cfg.parking_costs.defaults[purpose]) + + # Fill in NaNs with default values. + parking_price_2 = DEST.map(zonetype_price) + parking_price = parking_price_1.fillna(parking_price_2) + + # Find free parking rate based on income group + income_group = np.zeros(ITER, dtype=int) + FREEPRK = np.zeros(ITER) + for j2 in reversed(range(5)): + k = INCOME 1] = 0 + # J6[J7 == 0] = 1 + # + # VT = INCOME/2400. + # + # # Baseline free parking + # CAPK = np.zeros(ITER, dtype=int) + # WALK3 = np.full(ITER, 3.0) + # HC = np.zeros(ITER) + # SI = np.zeros(ITER) + # WK = np.zeros(ITER) + # BLK = np.zeros(ITER) + # + # paid_parking = (RAN3 > FREEPRK) + # HC[paid_parking] = ( + # J7 * CBDPRK.ThresholdPrice.iloc[0] + # when using first row + # J6 * (HCPT1 + (HCPT2-HCPT1)*(HCPT3-RAN2)/(HCPT3_4)) # when using other rows + # )[paid_parking] + # SI[paid_parking] = CBDPRK.SavePrice[J3].values[paid_parking] + # WK[paid_parking] = np.fmax(CBDPRK.WalkSeconds[J3].values[paid_parking], 180) + # BLK[paid_parking] = SI[paid_parking] / (VT[paid_parking] * WK[paid_parking] / 60.) # BLK IS BLOCKS WALKED + # BLK[paid_parking] = np.clip(BLK[paid_parking], 0.25, 6.0) + # WALK3[paid_parking] = (BLK[paid_parking] * WK[paid_parking]) / 60. + # CAPK[paid_parking] = np.clip(HC[paid_parking] * HOURS - BLK[paid_parking] * SI[paid_parking], 0.0, None) + # + # INTOCC = np.zeros(ITER, dtype=np.int8) + # RAN5 -= cbd_parking2.loc[L, 'AutoOcc1Pct'].values + # INTOCC[(INTOCC==0) & (RAN5 < 0)] = 1 + # RAN5 -= cbd_parking2.loc[L, 'AutoOcc2Pct'].values + # INTOCC[(INTOCC==0) & (RAN5 < 0)] = 2 + # RAN5 -= cbd_parking2.loc[L, 'AutoOcc3Pct'].values + # INTOCC[(INTOCC==0) & (RAN5 < 0)] = 3 + # INTOCC[(INTOCC==0)] = 4 + # + # return CAPK, WALK3, INTOCC, BLK, SI + + +def parking_cost_v3( + dh, + DEST, + HOURS, + purpose, + random_state=None, +): + + """ + Draw a parking cost from the random distribution in the destination zone. + + Parameters + ---------- + dh : DataHandler + DEST : array-like, shape[ITER] + TAZ ID for destination + HOURS : numeric + Number of hours of parking to pay for + purpose : str + Used to determine the default price per hour by zonetype. + + random_state + + Returns + ------- + CAPK, WALK3, INTOCC, BLK, SI : array, shape[ITER] + parking cost, walktime, vehicle occupancy, blocks walked, savings rate + """ + global CBD_PARKING_ZONES, cbd_parking_price_prob, cbd_parking_prices + random_state = check_random_generator(random_state) + + DEST = pd.Series(DEST.reshape(-1)) + ITER = DEST.size + + rand_free_parking = random_state.random(size=ITER) * 100. # Free Parking randomizer + rand_parking_price = random_state.random(size=ITER) # Parking Rate randomizer + + price_probs = dh.cbd_parking_price_prob.reindex(DEST.values) + prices = dh.cbd_parking_prices.reindex(DEST.values) + parking_price_row = np.full(ITER, -1, dtype=np.int8) + for i in range(5): + rand_parking_price -= price_probs.iloc[:,0] + parking_price_row[(parking_price_row < 0) & (rand_parking_price < 0)] = i + + # Assemble the randomly selected parking-price columns into one Series. + # It will have NaN values for zones outside the CBD parking model + parking_price_1 = pd.Series( + prices.values[range(len(parking_price_row)), parking_price_row], + index=DEST.index, + ) + + # Assemble default hourly pricing to use for trips based on zone type + # This Series is len(Zones) not len(Trips) + zonetype_price = dh.m01.zone_type.map(dh.cfg.parking_costs.defaults[purpose]) + + # Fill in NaNs with default values. + parking_price_2 = DEST.map(zonetype_price) + parking_price = parking_price_1.fillna(parking_price_2) + + # Scale up based on number of hours of parking + parking_price *= HOURS + + return parking_price + + +def parking_is_free( + dh, + INCOME, + random_state=None, +): + + """ + Draw a parking cost from the random distribution in the destination zone. + + Parameters + ---------- + dh : DataHandler + INCOME : array-like, shape[ITER] + Income groups for each draw, used to find if parking is actually free + Values are categories 1 to 5 + random_state + + Returns + ------- + paid_parking : array, shape[ITER] + 1 if parking is paid, 0 if free + """ + random_state = check_random_generator(random_state) + rand_free_parking = random_state.random(size=INCOME.size) * 100. # Free Parking randomizer + + # Find free parking rate based on income group + FREEPRK = dh.cbd_parking2.FreeParkingPct.iloc[INCOME-1] + + # random draw if the traveler gets free parking + paid_parking = (rand_free_parking > FREEPRK) + + return paid_parking diff --git a/src/Mode-Dest-TOD/cmap_modedest/purposes.py b/src/Mode-Dest-TOD/cmap_modedest/purposes.py new file mode 100644 index 0000000..55b0387 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/purposes.py @@ -0,0 +1,60 @@ + +purposes5 = ( + 'HBWH', # Home-based Work, High Income + 'HBWL', # Home-based Work, Low Income + 'HBS', # Home-based Shopping + 'HBO', # Home-based Other Purpose Not Enumerated + 'NHB', # Non-home-based +) + +purposes8 = ( + 'HBWH', # Home-based Work, High Income + 'HBWL', # Home-based Work, Low Income + 'HBS', # Home-based Shopping + 'HBO', # Home-based Other Purpose Not Enumerated + 'HBOR', # Home-based Other Purpose Not Enumerated, at a residence + 'NHB', # Non-home-based not shopping + 'NHBS', # Non-home-based shopping + 'NHBR', # Non-home-based, at a residence +) + +purposes3 = ( + 'HW', # Home-based Work + 'HO', # Home-based Other Purpose Not Work + 'NH', # Non-home-based +) + +purposesA = purposes5 + +purposes_to_peaky = dict( + HBWH=1, + HBWL=1, + HBS=0, + HBO=0, + NHB=0, + HBOR=0, + NHBR=0, + NHBS=0, +) + +purposes_to_3 = dict( + HBWH='HW', + HBWL='HW', + HBS='HO', + HBO='HO', + NHB='NH', + HBOR='HO', + NHBR='NH', + NHBS='NH', +) + +purposes_to_5 = dict( + HBWH='HBWH', + HBWL='HBWL', + HBS='HBS', + HBO='HBO', + NHB='NHB', + HBOR='HBO', + NHBR='NHB', + NHBS='NHB', +) \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/random_states.py b/src/Mode-Dest-TOD/cmap_modedest/random_states.py new file mode 100644 index 0000000..7b76a0e --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/random_states.py @@ -0,0 +1,46 @@ +import numbers +import numpy as np + +def check_random_state(seed): + """ + Turn a seed into a numpy RandomState instance + + Parameters + ---------- + seed : None | int | instance of RandomState + If seed is None, return the RandomState singleton used by np.random. + If seed is an int, return a new RandomState instance seeded with seed. + If seed is already a RandomState instance, return it. + Otherwise raise ValueError. + """ + if seed is None or seed is np.random: + return np.random.RandomState() + if isinstance(seed, numbers.Integral): + return np.random.RandomState(seed % 1<<32) + if isinstance(seed, np.random.RandomState): + return seed + raise ValueError('%r cannot be used to seed a numpy.random.RandomState' + ' instance' % seed) + + +def check_random_generator(seed=None): + """ + Create a random generator. + + Parameters + ---------- + seed + + Returns + ------- + np.random.Generator + """ + if seed is None: + raise ValueError("True random seeding disallowed for CMAP trip based model") + try: + return np.random.default_rng(seed) + except TypeError: + if isinstance(seed, np.random.RandomState): + return np.random.default_rng(seed.get_state()[1]) + else: + raise \ No newline at end of file diff --git a/src/Mode-Dest-TOD/cmap_modedest/runtime.py b/src/Mode-Dest-TOD/cmap_modedest/runtime.py new file mode 100644 index 0000000..4d67614 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/runtime.py @@ -0,0 +1,40 @@ +import os +import cmap_modedest +from pathlib import Path + +from .data_handlers import DataHandler + + +import cmap_modedest + +log = cmap_modedest.log_to_stderr(level=10) + + +def log_info(*args): + """Short logging function for estimation""" + if len(args) == 1 and isinstance(args[0], str) and args[0][0] == "#": + log.info(args[0]) + else: + s = "\n".join(str(i) for i in args) + s = "\n"+s + log.info(s.replace("\n", "\n ")) + + +def working_dir(*candidate_emme_database_dirs, backfill_uncompressed_skims=False, **kwargs): + for emme_database_dir in candidate_emme_database_dirs: + emme_database_dir = os.path.expanduser(emme_database_dir) + if os.path.exists(emme_database_dir): break + else: + raise FileNotFoundError(candidate_emme_database_dirs) + emme_database_dir = Path(emme_database_dir) + os.makedirs(emme_database_dir/"emmemat", exist_ok=True) # must exist even if empty + log_info("###### Set Directories and Prep Data ######") + dh = DataHandler( + emme_database_dir=emme_database_dir, + cache_dir=emme_database_dir/"cache", + zone_shapefile=emme_database_dir/"data/distr/zone17.shp", + backfill_uncompressed_skims=backfill_uncompressed_skims, + **kwargs, + ) + log_info("Data Handlers Ready") + return dh diff --git a/src/Mode-Dest-TOD/cmap_modedest/skims/__init__.py b/src/Mode-Dest-TOD/cmap_modedest/skims/__init__.py new file mode 100644 index 0000000..26edd5b --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/skims/__init__.py @@ -0,0 +1,57 @@ +import os +import zarr +from pathlib import Path +from .compression import read_compressed_skims, read_uncompressed_skims, write_compressed_skims, write_uncompressed_skims +from ..cmap_logging import getLogger + +def read_skims( + directory, + backfill_compressed_skims=False, + backfill_uncompressed_skims=False, + use_compressed_skims=False, +): + """ + + Parameters + ---------- + directory : Path-like + Where to read skims from, omitting any ".zarr" suffix. + backfill_compressed_skims : bool, default False + Write skims that only appear in the uncompressed directory into the + zarr directory. + backfill_uncompressed_skims : bool, default False + Write skims that only appear in the compressed zarr directory into the + uncompressed directory. + use_compressed_skims : bool, default False + Whether to allow the usage of compressed skims at all. + + Returns + ------- + sh.Dataset + """ + appended_names = [] + skims = None + try: + if use_compressed_skims: + skims = read_compressed_skims(directory) + except zarr.errors.GroupNotFoundError as err: + pass + except FileNotFoundError as err: + backfill_compressed_skims = False + try: + skims, appended_names = read_uncompressed_skims(directory, skims) + except (FileNotFoundError, NotADirectoryError) as err2: + if skims is None: + raise err2 + if backfill_compressed_skims and appended_names: + write_compressed_skims( + skims[appended_names], + os.fspath(Path(directory).with_suffix(".zarr")) + ) + if backfill_uncompressed_skims: + write_uncompressed_skims( + skims, + directory, + ) + + return skims diff --git a/src/Mode-Dest-TOD/cmap_modedest/skims/compression.py b/src/Mode-Dest-TOD/cmap_modedest/skims/compression.py new file mode 100644 index 0000000..fc1a917 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/skims/compression.py @@ -0,0 +1,191 @@ +import os +import xarray as xr +import sharrow as sh +import numpy as np +import pandas as pd +import zarr +from pathlib import Path +import logging + +log = logging.getLogger('CMAP') + + +def compress_skim_dir(directory, output="zarr"): + """ + Compress the `emmemat` skims directory using zarr. + + Parameters + ---------- + directory : path to emmemat directory + output : {"zarr.zip", "zarr"} + File format to use for compression. Zarr.zip puts all the + piece in one big zip directory, while plain Zarr uses the + native file system to store a bunch of pieces. Both methods + use the same compression. + + Returns + ------- + Dataset + """ + + if output not in ("zarr", "zarr.zip"): + raise NotImplementedError(output) + + if output == "zarr": + if not os.path.exists(directory+".zarr"): + os.makedirs(directory+".zarr") + elif output == "zarr.zip": + if os.path.exists(directory+".zarr.zip"): + raise FileExistsError(directory+".zarr.zip") + + master = {} + for f in os.walk(directory): + for fi in f[2]: + if ".emx" in fi: + arr = np.fromfile(fi, dtype='f4') + side = int(np.sqrt(arr.size)) + arr = arr.reshape(side, side) + tazrange = pd.RangeIndex(1, side+1) + master[fi.replace(".emx", "")] = xr.DataArray( + arr, + dims=['otaz', 'dtaz'], + coords={'otaz': tazrange, 'dtaz': tazrange} + ) + + master = sh.Dataset(master) + + if output == "zarr": + master.to_zarr(directory+".zarr", mode='a') + elif output == "zarr.zip": + with zarr.ZipStore(directory+".zarr.zip", mode='w') as store: + master.to_zarr(store) + return master + + +def read_uncompressed_skims(directory, dataset=None, overload=True): + """ + Read emmemat skims into a Dataset. + + Parameters + ---------- + directory : Path-like + path to emmemat directory + dataset : Dataset, optional + Append to these skims. Only skims not already available + will be loaded. + overload : bool, default True + Whether to overload existing skims in `dataset`. If False, + the existing skims (generally, those loaded from the compressed + skims) have priority and are retained. If True, any uncompressed + skims have priority and existing data is overwritten in memory. + + Returns + ------- + sh.Dataset + Loaded skims + appended_names : List + Names of uncompressed skims that were added + """ + appended_names = [] + if not os.path.isdir(directory): + raise NotADirectoryError(directory) + if dataset is None: + master = {} + else: + master = dataset + log.info(f'reading uncompressed skims from {directory}') + for f in os.walk(directory): + for fi in f[2]: + if ".emx" in fi and (fi.replace(".emx", "") not in master or overload): + arr = np.memmap(os.path.join(f[0], fi), dtype='f4', mode='c') + side = int(np.sqrt(arr.size)) + arr = arr.reshape(side, side) + tazrange = pd.RangeIndex(1, side+1) + master[fi.replace(".emx", "")] = xr.DataArray( + arr, + dims=['otaz', 'dtaz'], + coords={'otaz': tazrange, 'dtaz': tazrange} + ) + appended_names.append(fi.replace(".emx", "")) + if len(master) == 0: + log.error(f'no uncompressed skims read from {directory}') + raise FileNotFoundError(directory) + log.info(f"{len(appended_names)} uncompressed skims were added to the skims dataset") + return sh.Dataset(master), appended_names + + +def read_compressed_skims(zarr_directory): + """ + Read previously compressed skims. + + Compressed skims must be stored in a directory ending with a .zarr extension. + + Parameters + ---------- + zarr_directory + + Returns + ------- + Dataset + """ + result = None + if zarr_directory is None: + log.warning("no `zarr_directory` given") + raise ValueError("no `zarr_directory` given") + zarr_directory = Path(zarr_directory) + if os.path.isdir(zarr_directory.with_suffix(".zarr")): + log.info(f'reading compressed skims from {zarr_directory.with_suffix(".zarr")}') + result = sh.Dataset.from_zarr(zarr_directory.with_suffix(".zarr")) + elif os.path.isfile(zarr_directory.with_suffix(".zarr.zip")): + log.info(f'reading compressed skims from {zarr_directory.with_suffix(".zarr.zip")}') + result = sh.Dataset.from_zarr(zarr_directory.with_suffix(".zarr.zip")) + if result is not None: + log.info(f"{len(result.data_vars)} compressed skims were added to the skims dataset") + return result + raise FileNotFoundError(zarr_directory) + + +def write_uncompressed_skims(skims, directory, overwrite=False): + """ + Writes the .emx files for EMME in the emmemat directory. + + Parameters + ---------- + skims : Dataset + directory : Path-like + uncompressed skims will go here + overwrite : bool, default False + Whether to overwrite existing uncompressed skims. + """ + os.makedirs(directory, exist_ok=True) + for k in skims: + filename = os.path.join(directory, f"{k}.emx") + if not os.path.exists(filename) or overwrite: + skims[k].values.tofile(filename) + + +def write_compressed_skims(skims, output="emmemat.zarr"): + """ + Compress the `emmemat` skims directory using zarr. + + Parameters + ---------- + directory : path to emmemat directory + output : str, ends with {"zarr.zip", "zarr"} + File format to use for compression. Zarr.zip puts all the + piece in one big zip directory, while plain Zarr uses the + native file system to store a bunch of pieces. Both methods + use the same compression. + """ + known_exts = (".zarr", ".zarr.zip") + if not any(output.endswith(k) for k in known_exts): + raise NotImplementedError(output) + if output.endswith(".zarr"): + skims.to_zarr(output, mode='a') + elif output.endswith(".zarr.zip"): + if os.path.exists(output): + raise FileExistsError(output) + with zarr.ZipStore(output, mode='w') as store: + skims.to_zarr(store) + + diff --git a/src/Mode-Dest-TOD/cmap_modedest/skims/names.py b/src/Mode-Dest-TOD/cmap_modedest/skims/names.py new file mode 100644 index 0000000..8fdd177 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/skims/names.py @@ -0,0 +1,15 @@ +from ..addict import Dict + +skim_names = Dict( + mf44='auto_am_time', + mf45='auto_am_dist', + mf46='auto_md_time', + mf47='auto_md_dist', + mf76='auto_am_time_hov', + mf77='auto_am_dist_hov', +) + +skim_tags = Dict({v:k for k,v in skim_names.items()}) + +skim_names.freeze() +skim_tags.freeze() diff --git a/src/Mode-Dest-TOD/cmap_modedest/time_of_day_model.py b/src/Mode-Dest-TOD/cmap_modedest/time_of_day_model.py new file mode 100644 index 0000000..d04a6fd --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/time_of_day_model.py @@ -0,0 +1,130 @@ +import os +from larch.numba import Model, P, X +import yaml +from .addict import Dict + +from .cmap_logging import getLogger, get_worker_log +from .purposes import purposes5 + +time_period_names = ['EA', 'AM1', 'AM2', 'AM3', 'MD', 'PM1', 'PM2', 'PM3'] +time_period_codes = [ 1, 2, 3, 4, 5, 6, 7, 8 ] + +def tod_model_builder( + purpose, + data_co=None, + ch_name=None, + model_parameters=None, +): + from larch.numba import DataFrames + if model_parameters is None: + model_parameters = {} + + d = DataFrames( + co=data_co, + ch=ch_name, + alt_codes=time_period_codes, + alt_names=time_period_names, + av=1, + ) + + tod_model = Model(d) + tod_model.title = f"{purpose} Time of Day Choice" + + for tname, tcode in zip(time_period_names, time_period_codes): + tod_model.utility_co[tcode] = ( + + P(f"ASC_{tname}") + + P.time * X(f"mf46{tcode}") + + P(f"hiredcar_{tname}") * X("mode9 in ('TAXI','TNC1','TNC2')") + ) + if purpose[:2].upper() == "HB": + if purpose.upper() == "HBS": + tod_model.utility_co[tcode] += ( + + P(f"ASC_{tname}_r") * X("paFlip") + # no reverse-trip hired car parameters, insufficient survey data + ) + else: + tod_model.utility_co[tcode] += ( + + P(f"ASC_{tname}_r") * X("paFlip") + + P(f"hiredcar_{tname}_r") * X("mode9 in ('TAXI','TNC1','TNC2')") * X("paFlip") + ) + + tod_model.lock_value('ASC_AM2', 0.0) + tod_model.lock_value('hiredcar_AM2', 0.0) + if purpose.upper() == "HBS": + tod_model.lock_value('ASC_AM2_r', 0.0) + elif purpose[:2].upper() == "HB": + tod_model.lock_value('ASC_AM2_r', 0.0) + tod_model.lock_value('hiredcar_AM2_r', 0.0) + tod_model.set_cap() + + if purpose == 'NHB': + tod_model.set_value('time', -0.02, maximum=-0.02) + + for k,v in model_parameters.items(): + tod_model.set_value(k, v) + + return tod_model + + + + +time_of_day_simulator_global = Dict() + + +def time_of_day_simulator_initialize(dh, cache=True): + global time_of_day_simulator_global + + log = get_worker_log( + os.path.join(dh.filenames.cache_dir, 'logs'), + level=10, + ) + + log.debug(f"time_of_day_simulator_initialize(cache={cache}") + n_zones = dh.n_internal_zones + choice_model_params = dh.choice_model_params + + if len(choice_model_params) == 0: + raise ValueError("no choice_model_params") + + pickle_name = dh.filenames.cache_dir / f"tod_models_{n_zones}.pkl" + tod_param_file = dh.filenames.tod_model_param_file + if tod_param_file and os.path.exists(tod_param_file): + with open(tod_param_file, 'r') as f: + tod_model_params = Dict(yaml.load(f, Loader=yaml.SafeLoader)) # TODO addicty + else: + tod_model_params = Dict() + + if len(time_of_day_simulator_global) == 0: + log.debug("time_of_day_simulator_initialize: preloaded tod_simulator not available") + if os.path.exists(pickle_name): + import cloudpickle + with open(pickle_name, 'rb') as pkl_f: + log.debug("time_of_day_simulator_initialize: loading pickled tod_simulator") + time_of_day_simulator_global = cloudpickle.load(pkl_f) + cache = False + else: + log.debug("time_of_day_simulator_initialize: pickled tod_simulator not available") + + if time_of_day_simulator_global: + log.info("time_of_day_simulator_initialize: using existing tod_simulator") + tod_simulator = time_of_day_simulator_global + else: + log.info("time_of_day_simulator_initialize: creating fresh tod_simulator") + tod_simulator = Dict() + for purpose in purposes5: + tod_simulator[purpose] = tod_model_builder( + purpose=purpose, + model_parameters=tod_model_params.get(purpose, {}), + ) + time_of_day_simulator_global = tod_simulator + + if cache and not os.path.exists(pickle_name): + import cloudpickle + with open(pickle_name, 'wb') as pkl_f: + log.debug("time_of_day_simulator_initialize: pickling tod_simulator for future reload") + cloudpickle.dump( + time_of_day_simulator_global, + pkl_f, + ) + + return tod_simulator diff --git a/src/Mode-Dest-TOD/cmap_modedest/timeperiods.py b/src/Mode-Dest-TOD/cmap_modedest/timeperiods.py new file mode 100644 index 0000000..3e18d1f --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/timeperiods.py @@ -0,0 +1,51 @@ + + +# 1. The ten hour late evening-early morning off-peak period (8:00 p.m. to 6:00 a.m.); +# 2. The shoulder hour preceding the AM peak hour (6:00 to 7:00 a.m.); +# 3. The AM peak two hours (7:00 to 9:00 a.m.); +# 4. The shoulder hour following the AM peak period (9:00 to 10:00 a.m); +# 5. A five hour midday period (10:00 a.m. to 2:00 p.m.); +# 6. The two hour shoulder period preceding the PM peak period (2:00 to 4:00 p.m.); +# 7. The PM peak two hours (4:00 to 6:00 p.m.), and; +# 8. The two hour shoulder period following the PM peak period (6:00 to 8:00 p.m.). + +timeperiod_names = [ + 'NIGHT', + 'AM_PRE', + 'AM_PEAK', + 'AM_POST', + 'MIDDAY', + 'PM_PRE', + 'PM_PEAK', + 'PM_POST', +] + +timeperiods = {i:name for i, name in enumerate(timeperiod_names)} + +hours_by_timeperiod = { + 0: 0, + 1: 0, + 2: 0, + 3: 0, + 4: 0, + 5: 0, + 6: 1, + 7: 2, + 8: 2, + 9: 3, + 10: 4, + 11: 4, + 12: 4, + 13: 4, + 14: 4, + 15: 5, + 16: 5, + 17: 6, + 18: 6, + 19: 7, + 20: 7, + 21: 0, + 22: 0, + 23: 0, +} + diff --git a/src/Mode-Dest-TOD/cmap_modedest/tnc_costs.py b/src/Mode-Dest-TOD/cmap_modedest/tnc_costs.py new file mode 100644 index 0000000..55a76db --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/tnc_costs.py @@ -0,0 +1,124 @@ +import numpy as np +import pandas as pd + +peak_tnc_pricing = { + 'OFFPEAK': 0, + 'PEAK': 1, +} + + +def taxi_cost(dh, auto_time, auto_dist, o_zone, d_zone): + """ + Compute taxi fare. + + A single set of rates (Chicago medallion rates for in-city trips) + is used; fares for taxi trips outside Chicago are close to this + rate and rare enough that more precision is unneeded. + + Parameters + ---------- + auto_time, auto_dist : array-like + + Returns + ------- + fare : array-like + """ + return ( + dh.cfg.taxi.cost.flag_pull + + auto_time * dh.cfg.taxi.cost.per_minute + + auto_dist * dh.cfg.taxi.cost.per_mile + ) + + +def tnc_solo_cost(dh, auto_time, auto_dist, o_zone, d_zone, peak): + """ + Compute the solo rider TNC cost. + + Parameters + ---------- + auto_time, auto_dist : array-like of float + The auto travel time and distance for a set of trips. + Shapes must match. + o_zone, d_zone : pd.Series of int + Zone numbers for origin and destination + Shapes must match `auto_time`. + peak : pd.Series of bool + Whether each trip is peak or offpeak. + Shapes must match `auto_time`. + + Returns + ------- + ndarray + Same shape as inputs + """ + + peak_fare = ( + dh.cfg.tnc.cost.peak.per_minute * auto_time + + dh.cfg.tnc.cost.peak.per_mile * auto_dist + + dh.cfg.tnc.cost.peak.base_fare + ) + peak_fare = np.fmax(peak_fare, dh.cfg.tnc.cost.peak.min_fare) + dh.cfg.tnc.cost.peak.booking_fee + + offpeak_fare = ( + dh.cfg.tnc.cost.offpeak.per_minute * auto_time + + dh.cfg.tnc.cost.offpeak.per_mile * auto_dist + + dh.cfg.tnc.cost.offpeak.base_fare + ) + offpeak_fare = np.fmax(offpeak_fare, dh.cfg.tnc.cost.offpeak.min_fare) + dh.cfg.tnc.cost.offpeak.booking_fee + + cost = peak_fare * peak + offpeak_fare * (1-peak) + for bucket_name, bucket_price in dh.cfg.tnc.surcharge_rates.items(): + if bucket_price: + bucket_applies = ( + np.isin(o_zone, dh.cfg.tnc.surcharge_zones[bucket_name]) + | np.isin(d_zone, dh.cfg.tnc.surcharge_zones[bucket_name]) + ).astype(float) + cost += bucket_applies * bucket_price + return cost + + +def tnc_pool_cost(dh, auto_time, auto_dist, o_zone, d_zone, peak): + """ + Compute the pooled rider TNC cost. + + Parameters + ---------- + auto_time, auto_dist : array-like of float + The auto travel time and distance for a set of trips/ + Shapes must match. + o_zone, d_zone : pd.Series of int + Zone numbers for origin and destination + Shapes must match `auto_time`. + peak : pd.Series of bool + Whether each trip is peak or offpeak. + Shapes must match `auto_time`. + + Returns + ------- + ndarray + Same shape as inputs + """ + + peak_fare = ( + dh.cfg.tnc_pooled.cost.peak.per_minute * auto_time + + dh.cfg.tnc_pooled.cost.peak.per_mile * auto_dist + + dh.cfg.tnc_pooled.cost.peak.base_fare + ) + peak_fare = np.fmax(peak_fare, dh.cfg.tnc_pooled.cost.peak.min_fare) + dh.cfg.tnc_pooled.cost.peak.booking_fee + + offpeak_fare = ( + dh.cfg.tnc_pooled.cost.offpeak.per_minute * auto_time + + dh.cfg.tnc_pooled.cost.offpeak.per_mile * auto_dist + + dh.cfg.tnc_pooled.cost.offpeak.base_fare + ) + offpeak_fare = np.fmax(offpeak_fare, dh.cfg.tnc_pooled.cost.offpeak.min_fare) + dh.cfg.tnc_pooled.cost.offpeak.booking_fee + + cost = peak_fare * peak + offpeak_fare * (1-peak) + for bucket_name, bucket_price in dh.cfg.tnc_pooled.surcharge_rates.items(): + if bucket_price: + bucket_applies = ( + np.isin(o_zone, dh.cfg.tnc_pooled.surcharge_zones[bucket_name]) + | np.isin(d_zone, dh.cfg.tnc_pooled.surcharge_zones[bucket_name]) + ).astype(float) + cost += bucket_applies * bucket_price + return cost diff --git a/src/Mode-Dest-TOD/cmap_modedest/transit_approach.py b/src/Mode-Dest-TOD/cmap_modedest/transit_approach.py new file mode 100644 index 0000000..349aaee --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/transit_approach.py @@ -0,0 +1,731 @@ +import numpy as np +import logging +from .addict import Dict +log = logging.getLogger('CMAP') + +from .ae_distance_sim import simulate_ae_dist +from .random_states import check_random_generator + +# trip types +HW = 'HW' # HOME PRODUCTIONS TO WORK ATTRACTIONS +HO = 'HO' # HOME PRODUCTIONS TO NON-WORK/NON-HOME ATTRACTIONS +NH = 'NH' # NON-HOME PRODUCTIONS TO NON-HOME ATTRACTIONS + +ITER = 50 # NUMBER OF TRIPS USED TO COMPUTE AVERAGE IMPEDANCES + +from .modecodes import ( + APPROACH_WALK, + APPROACH_BUS, + APPROACH_PARK_N_RIDE, + APPROACH_KISS_N_RIDE, + APPROACH_FEEDER_BUS, + N_APPROACH_MODES, + APPROACH_MODE_NAMES, + DIST_TO_BUS, + DIST_TO_CTA_RAIL, + DIST_TO_METRA, + DIST_TO_FEEDER_BUS, + DIST_TO_PARK_N_RIDE_STATION, + N_DIST_TO_TYPES, + TransitModeCode_CTA_RAIL, + TransitModeCode_METRA_RAIL, + TransitModeCode_CTA_EXPRESS_BUS, + TransitModeCode_CTA_REGULAR_BUS, + TransitModeCode_PACE_BUS, +) + + + +FRONT_END = 0 +BACK_END = 1 +N_TRIP_ENDS = 2 + +SPDWLK = 30 +# SPDWLK = SYSTEM-WIDE SPEED OF WALKING, +# DEFAULT IS 30 TENTHS OF A MILE PER HOUR + +SPEEDS = np.array([7, 15, 20, 30, 5, 10, 12, 17]) +# SPEEDS = SPEEDS OF APPROACH AUTO AND BUS BY ZONE AREA TYPE +# AUTO APPROACH SPEEDS: +# ZONE TYPE 1 (CHICAGO CBD) DEFAULT IS 7 MPH +# ZONE TYPE 2 (CHICAGO REMAINDER) DEFAULT IS 15 MPH +# ZONE TYPE 3 (DENSE SUBURB) DEFAULT IS 20 MPH +# ZONE TYPE 4 (SPARSE SUBURB) DEFAULT IS 30 MPH +# BUS APPROACH SPEEDS: +# ZONE TYPE 1 (CHICAGO CBD) DEFAULT IS 5 MPH +# ZONE TYPE 2 (CHICAGO REMAINDER) DEFAULT IS 10 MPH +# ZONE TYPE 3 (DENSE SUBURB) DEFAULT IS 12 MPH +# ZONE TYPE 4 (SPARSE SUBURB) DEFAULT IS 17 MPH + +DRVOT = 14 +# DRVOT = DRIVER'S VALUE OF TIME, DEFAULT IS 14 CENTS/MIN + +OVT_IVT_RATIO = 2.0 + + + +AFC1 = 35 # AUTO FIXED COSTS FOR AUTO DRIVER IN CENTS +AFC2 = 20 # AUTO FIXED COSTS FOR AUTO PASSENGER IN CENTS + +# W2PNR = WALK TIME TO STATION FROM PARK AND RIDE LOT, +# DEFAULT IS 2 MINUTES +W2PNR = 2 + + +def _simulate_approach_distances( + dh, + zone, + attached_mode, + trip_purpose, + trip_end, + out, + random_state=None, +): + """ + + Parameters + ---------- + dh : DataHandler + zone : int + Zone id (1-based) + attached_mode : int + Number for first or last mode (as matches this approach) + trip_purpose : {'HW','HO','NH'} + Trip purpose, used to select DISTR table and possibly filter + approach modes + trip_end : {0,1} + Zero if approach to first mode, one if approach from last mode + out : array-like + Output array must already exist, as a float dtype, + with shape [replications, N_APPROACH_MODES, ] + + """ + if not isinstance(zone, int): + return _simulate_approach_distances_arr( + dh, + zone, + attached_mode, + trip_purpose, + trip_end, + out, + random_state=random_state, + ) + random_state = check_random_generator(random_state) + replication = list(out.shape[:-1]) + distr = dh.distr + if replication[0] == 1: + replication = replication[1:] + for J in range(N_DIST_TO_TYPES): + # OBTAIN APPROACH DISTANCES TO FIVE MODES + if (J == DIST_TO_BUS): + distr_params = distr[trip_purpose].loc[(zone, 'bus')] + elif (J == DIST_TO_CTA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS CTA RAIL + if attached_mode == TransitModeCode_CTA_RAIL: + distr_params = distr[trip_purpose].loc[(zone, 'ctarail')] + else: + distr_params = (999,999,999) + elif (J == DIST_TO_METRA): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + if attached_mode == TransitModeCode_METRA_RAIL: + distr_params = distr[trip_purpose].loc[(zone, 'metra')] + else: + distr_params = (999, 999, 999) + elif (J == DIST_TO_FEEDER_BUS): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + if attached_mode == TransitModeCode_METRA_RAIL: + distr_params = distr[trip_purpose].loc[(zone, 'feederbus')] + else: + distr_params = (999, 999, 999) + elif (J == DIST_TO_PARK_N_RIDE_STATION): + # PARK AND RIDE STATION DISTANCE OBTAINED WHEN TRIP END IS FRONT + if trip_end == FRONT_END: + distr_params = distr[trip_purpose].loc[(zone, 'pnr')] + else: + distr_params = (999, 999, 999) + else: + raise ValueError(J) + if distr_params[2] != 999: + out[...,J] = simulate_ae_dist(*distr_params, replication=replication, random_state=random_state) + else: + out[...,J] = 255.0 + + +def _simulate_approach_distances_arr( + dh, + zone, + attached_mode, + trip_purpose, + trip_end, + out, + random_state=None, +): + """ + + Parameters + ---------- + zone : array-like + Zone id (1-based) + attached_mode : int + Number for first or last mode (as matches this approach) + trip_purpose : {'HW','HO','NH'} + Trip purpose, used to select DISTR table and possibly filter + approach modes + trip_end : {0,1} + Zero if approach to first mode, one if approach from last mode + out : array-like + Output array must already exist, as a float dtype, + with shape [replications, N_APPROACH_MODES, ] + + """ + random_state = check_random_generator(random_state) + replication = list(out.shape[1:-1]) + distr_df = dh.distr[trip_purpose].unstack().loc[zone] + for J in range(N_DIST_TO_TYPES): + # OBTAIN APPROACH DISTANCES TO FIVE MODES + if (J == DIST_TO_BUS): + distr_params = distr_df.xs('bus', level='submode', axis=1).copy() + elif (J == DIST_TO_CTA_RAIL): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS CTA RAIL + distr_params = distr_df.xs('ctarail', level='submode', axis=1).copy() + distr_params.loc[attached_mode != TransitModeCode_CTA_RAIL,:] = 999 + elif (J == DIST_TO_METRA): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + distr_params = distr_df.xs('metra', level='submode', axis=1).copy() + distr_params.loc[attached_mode != TransitModeCode_METRA_RAIL,:] = 999 + elif (J == DIST_TO_FEEDER_BUS): + # DISTANCE OBTAINED ONLY IF FIRST/LAST MODE IS METRA + distr_params = distr_df.xs('feederbus', level='submode', axis=1).copy() + distr_params.loc[attached_mode != TransitModeCode_METRA_RAIL,:] = 999 + elif (J == DIST_TO_PARK_N_RIDE_STATION): + # PARK AND RIDE STATION DISTANCE OBTAINED WHEN TRIP END IS FRONT + if trip_end == FRONT_END: + distr_params = distr_df.xs('pnr', level='submode', axis=1).copy() + else: + distr_params.loc[:,:] = 999 + else: + raise ValueError(J) + _temp = simulate_ae_dist( + distr_params.p1, + distr_params.p2, + distr_params.p3, + replication=replication, + random_state=random_state, + ) + out[..., J] = _temp + + +# def simulate_approach_distances_222(ozone, dzone, firstmode, lastmode, trip_purpose): +# DOND = np.full([ITER, N_APPROACH_MODES, N_TRIP_ENDS], 255.) +# for I in range(N_TRIP_ENDS): +# +# # C I=1 OBTAIN DISTANCES FOR ORIGIN +# # C I=2 OBTAIN DISTANCES FOR DESTINATION +# if I == FRONT_END: +# Z=ozone +# M=firstmode +# else: +# Z=dzone +# M=lastmode +# +# +# for J in range(N_APPROACH_MODES): +# # C +# # C OBTAIN APPROACH DISTANCES TO FIVE MODES +# DOND[:,J,I]=255. +# +# if (J == APPROACH_WALK): +# distr_params = distr[trip_purpose].loc[(ozone, 3)] +# elif (J == APPROACH_BUS): +# distr_params = distr[trip_purpose].loc[(ozone, 2)] +# elif (J == APPROACH_PARK_N_RIDE): +# distr_params = distr[trip_purpose].loc[(ozone, 1)] +# elif (J == APPROACH_KISS_N_RIDE): +# distr_params = distr[trip_purpose].loc[(ozone, 4)] +# else: # (J == FEEDER_BUS): +# distr_params = distr[trip_purpose].loc[(ozone, 5)] +# +# DOND[:,J,I] = simulate_ae_dist(*distr_params, replication=ITER) +# +# return DOND + + +def _IS_CTA(m): + return ( + m == TransitModeCode_CTA_RAIL + or m == TransitModeCode_CTA_REGULAR_BUS + or m == TransitModeCode_CTA_EXPRESS_BUS + ) + + +from numba import jit, njit, prange + +def transit_approach( + dh, + ozone, + dzone, + TPTYPE, + replication=None, + approach_distances=None, + trace=False, + random_state=None, +): + """ + Replaces TRAPP fortran. + + Parameters + ---------- + dh : DataHandler + ozone, dzone : int or array-like + Zone ID numbers. If array-like, should be arrays of the same shape. + TPTYPE : {'HW', 'HO', 'NH'} + Trip type + replication : int + Number of simulation replications + + Returns + ------- + Dict + Containing: + - drivetime : array of int32, shape [replication] + simulated in vehicle (drive) approach times, in minutes + - walktime : array of int32, shape [replication] + simulated out of vehicle (walk) approach times, in minutes + - cost : array of int32, shape [replication] + simulated approach costs, in cents + - waittime : array of int32, shape [replication] + simulated approach waiting times + - approach_mode : array of int8, shape [replication, 2] + simulated best approach modes + = approach_distances : array of float32, shape [replication, N_DIST_TO_TYPES, N_TRIP_ENDS] + + Notes + ----- + When ozone, dzone are given as arrays, all returned arrays have one extra front + dimension matching these arrays. + + """ + random_state = check_random_generator(random_state or [ozone, dzone]) + + PACE_BUS_BOARDING_FARE = dh.m023.PACE_BUS_BOARDING_FARE + PACE_BUS_FIRST_XFER_FARE = dh.m023.PACE_BUS_FIRST_XFER_FARE + FEEDER_BUS_BOARDING_FARE = dh.m023.FEEDER_BUS_BOARDING_FARE + FEEDER_BUS_CBD_FARE = dh.m023.FEEDER_BUS_CBD_FARE + + CTA_FIRST_XFER_FARE = dh.m023.CTA_FIRST_XFER_FARE + CTA_CBD_LINK_UP_FARE = dh.m023.CTA_CBD_LINK_UP_FARE + + AUTO_OPERATING_COST_BY_ZONETYPE = dh.m023.AUTO_OPERATING_COST_BY_ZONETYPE # AVERAGE OPERATING COST PER MILE FOR AUTO, BY ZONE TYPE + + if replication is None: + replication = ITER + + if trace: + log.log(trace, f"transit_approach({ozone},{dzone},{TPTYPE},{replication})") + + # convert inputs to length-1 vectors if not already vectors + if isinstance(ozone, int): + ozone_ = ozone + ozone = np.array([ozone]) + else: + ozone_ = ozone = np.asanyarray(ozone) + if isinstance(dzone, int): + dzone_ = dzone + dzone = np.array([dzone]) + else: + dzone_ = dzone = np.asanyarray(dzone) + vector_len = ozone.shape[0] + assert vector_len == dzone.shape[0] + + ozone_idx = ozone-1 + dzone_idx = dzone-1 + + m01_df = dh.m01 + ZTYPE = m01_df['zone_type'] # integers 1-4 + if TPTYPE == HW: + fwbus = m01_df['first_wait_bus_peak'] # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr = m01_df['first_wait_feeder_peak'] # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + else: + fwbus = m01_df['first_wait_bus_offpeak'] # FIRST WAIT FOR BUS IN APPROACH SUBMODEL + fwfdr = m01_df['first_wait_feeder_offpeak'] # FIRST WAIT FOR FEEDER BUS IN APPROACH SUBMODEL + PNRAVL = m01_df['pnr_flag'].astype(bool) # park-n-ride available, by zone + PRCOST = m01_df['pnr_parking_cost'] # park-n-ride cost, by zone + + # -- INITIALIZE VALUES -- + approach_cost = np.zeros([vector_len, replication, N_APPROACH_MODES], dtype=np.float32) + approach_waittime = np.zeros([vector_len, replication, N_APPROACH_MODES], dtype=np.float32) + approach_drivetime = np.zeros([vector_len, replication, N_APPROACH_MODES], dtype=np.float32) + approach_walktime = np.zeros([vector_len, replication, N_APPROACH_MODES], dtype=np.float32) + TVAR4 = np.zeros([vector_len, replication, 5], dtype=np.float32) + + best_approach_mode = np.zeros([vector_len*replication, N_TRIP_ENDS], dtype=np.int8) + best_cost = np.zeros([vector_len*replication, N_TRIP_ENDS], dtype=np.int32) + best_waittime = np.zeros([vector_len*replication, N_TRIP_ENDS], dtype=np.int32) + best_walktime = np.zeros([vector_len* replication, N_TRIP_ENDS], dtype=np.int32) + best_drivetime = np.zeros([vector_len* replication, N_TRIP_ENDS], dtype=np.int32) + # + # GET ZONE TYPES + # + ozone_type = ZTYPE.iloc[ozone_idx] + dzone_type = ZTYPE.iloc[dzone_idx] + # + # GET INTERCHANGE ATTRIBUTES + # FM=FIRST MODE,LM=LAST MODE,PM=PRIORITY MODE + # + if TPTYPE == 'HW': + FM = dh.skims.first_mode_peak[ozone_idx, dzone_idx] + LM = dh.skims.last_mode_peak[ozone_idx, dzone_idx] + else: + FM = dh.skims.first_mode_offpeak[ozone_idx, dzone_idx] + LM = dh.skims.last_mode_offpeak[ozone_idx, dzone_idx] + # + # INET TRANSIT NETWORK STORES SOME SUBURBAN BUS LINES (MODE=6) + # AS MODE=5 DUE TO ARRAY SIZE LIMITS. IF MODE=5 AND + # ZONE TYPE NO. 1 IS OUTSIDE OF CHICAGO, THEN CHANGE MODE TO 6. + # + + FM[(FM == 5) & (ozone_type > 2)] = 6 + LM[(LM == 5) & (ozone_type > 2)] = 6 + + # + # GET APPROACH DISTANCES FOR FIRST AND LAST MODES + # + + #### CALL ADIST(ozone,dzone,FM,LM) + if approach_distances is not None: + if replication == 1 and len(approach_distances.shape) == 3: + approach_distances = np.expand_dims(approach_distances, axis=1) + assert approach_distances.shape == (vector_len, replication, N_DIST_TO_TYPES, N_TRIP_ENDS) + else: + approach_distances = np.empty([vector_len, replication, N_DIST_TO_TYPES, N_TRIP_ENDS]) + _simulate_approach_distances( + dh, + ozone_, + attached_mode=FM, + trip_purpose=TPTYPE, + trip_end=0, + out=approach_distances[:,:,:,0], + random_state=random_state, + ) + _simulate_approach_distances( + dh, + dzone_, + attached_mode=LM, + trip_purpose=TPTYPE, + trip_end=1, + out=approach_distances[:,:,:,1], + random_state=random_state, + ) + if trace: + log.log(trace, f" PRODUCTION APPROACH DISTANCES") + log.log(trace, f" to Bus {approach_distances[:5,:5,DIST_TO_BUS,0]}") + log.log(trace, f" to El {approach_distances[:5,:5,DIST_TO_CTA_RAIL,0]}") + log.log(trace, f" to Metra {approach_distances[:5,:5,DIST_TO_METRA,0]}") + log.log(trace, f" to feeder {approach_distances[:5,:5,DIST_TO_FEEDER_BUS,0]}") + log.log(trace, f" to PnR {approach_distances[:5,:5,DIST_TO_PARK_N_RIDE_STATION,0]}") + log.log(trace, f" ATTRACTION APPROACH DISTANCES") + log.log(trace, f" to Bus {approach_distances[:5,:5,DIST_TO_BUS,1]}") + log.log(trace, f" to El {approach_distances[:5,:5,DIST_TO_CTA_RAIL,1]}") + log.log(trace, f" to Metra {approach_distances[:5,:5,DIST_TO_METRA,1]}") + log.log(trace, f" to feeder {approach_distances[:5,:5,DIST_TO_FEEDER_BUS,1]}") + log.log(trace, f" to PnR {approach_distances[:5,:5,DIST_TO_PARK_N_RIDE_STATION,1]}") + + + # CHECK FIRST/LAST MODES AND COMPUTE APPROACH TIME AND COST + # + # ARRAYS approach_walktime,APCOST,approach_drivetime CONTAIN TIME TO WALK,APPROACH COST, + # AND IN-VEHICLE APPROACH TIME RESPECTIVELY. THESE ARRAYS HAVE FIVE + # ELEMENTS FOR FIVE POSSIBLE APPROACH MODES.( 1-WALK,2-BUS, + # 3-PARK & RIDE,4-KISS & RIDE,AND 5-FEEDER BUS) + # + + for I in range(N_TRIP_ENDS): + # I=1 GET VALUES FOR ORIGIN + # I=2 GET VALUES FOR DESTINATION + if (I == FRONT_END): + Z = ozone + M = FM + else: # I == BACK_END + Z = dzone + M = LM + + ZTYPE_Z = ZTYPE[Z].values + + # + # IN THIS CASE WE ARE MAKING THE STATION PARKING COST FOR HOME BASED OTHER AND + # NON-HOME BASED TRIPS EQUAL TO 60 PERCENT OF HOME BASED WORK + # CHANGE MADE 12/8/93 BY GWS NEXT LINE + # IF(TPTYPE.NE.1) PRCOST(Z) = PRCOST(Z) * 0.6 + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # NONWORK PARK AND RIDE PARKING COST IS NOW READ FROM M01. IN MANY + # CASES THE NONWORK PNR COSTS ARE HIGHER THAN WORK DUE TO + # DISCOUNTING OF MONTHLY PARKING FEES. + # + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # SET HIGH STARTING VALUE OF TVAR5 + TVAR5 = np.full([vector_len*replication], 1.E10) + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # IN CALCULATING TVAR4 AND TVAR5 + # IN-VEHICLE TIME = DRVOT = 20 CENTS/MIN + # OUT-OF-VEHICLE TIME = 40 CENTS/MIN + # PASSENGER TIME = 0.5 DRIVER TIME + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # + # FOLLOWING SECTION ADDED BY EASH TO SIMPLIFY LOGIC + # IF M IS BUS (MODE<7) THEN ONLY POSSIBLE APPROACH COST IS TIME TO + # WALK TO BUS. OTHER APPROACH COSTS AND TIMES ARE LINE=HAUL. + t = (M < TransitModeCode_CTA_RAIL) + if np.any(t): + J = APPROACH_WALK + approach_walktime[t,:,J] = approach_distances[t,:, DIST_TO_BUS, I] / SPDWLK * 600. + # INCREASE WALK TIME IN CHICAGO CBD FOR WORK TRIPS + cbd_work = t & (ZTYPE_Z == 1) & (TPTYPE == HW) + approach_walktime[cbd_work,:,J] *= 1.20 + + # if (ZTYPE_Z == 1 and TPTYPE == HW): + # approach_walktime[:, 0] = approach_walktime[:, 0] * 1.20 + TVAR4[t,:, J] = approach_walktime[t,:, 0] * DRVOT * 2.0 + TVAR5.reshape([vector_len,replication])[t,:] = TVAR4[t,:, J] + best_approach_mode.reshape([vector_len,replication,N_TRIP_ENDS])[t,:, I] = 0 + best_drivetime.reshape([vector_len,replication,N_TRIP_ENDS])[t,:, I] = 0 + best_walktime.reshape([vector_len,replication,N_TRIP_ENDS])[t,:, I] = approach_walktime[t,:, 0] + .5 + best_cost.reshape([vector_len,replication,N_TRIP_ENDS])[t,:, I] = 0 + best_waittime.reshape([vector_len,replication,N_TRIP_ENDS])[t,:, I] = 0 + for J in [APPROACH_BUS, APPROACH_PARK_N_RIDE, APPROACH_KISS_N_RIDE, APPROACH_FEEDER_BUS]: + TVAR4[t,:, J] = 0. + approach_cost[t, :, J] = 0. + approach_waittime[t, :, J] = 0. + approach_drivetime[t,:, J] = 0. + approach_walktime[t,:, J] = 0. + + t = (M >= TransitModeCode_CTA_RAIL) + if np.any(t): + # REMAINDER OF SUBROUTINE FOR RAIL TRANSIT/COMMUTER RAIL ONLY + # GET VALUES FOR FIVE ALTERNATIVES + for J in range(5): + TVAR4[t,:, J] = 0. + approach_cost[t, :, J] = 0. + approach_waittime[t,:,J] = 0. + approach_drivetime[t,:, J] = 0. + approach_walktime[t,:, J] = 0. + + K = np.fmax(0, M - 6).astype(int) # 0 for BUS, 1 for CTA RAIL(7-1), 2 for METRA(8-1) + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=0(WALK).COMPUTE WALKING TIME TO FIRST MODE.NO COST OR IN-VEHICLE TIME + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + if J == APPROACH_WALK: + approach_walktime[t,:, J] = approach_distances[t,:, K[t], I] / SPDWLK * 600. + # INCREASE WALK TIME IN CHICAGO CBD FOR WORK TRIPS + cbd_work = t & (ZTYPE_Z == 1) & (TPTYPE == HW) + approach_walktime[cbd_work,:, J] *= 1.20 + # if (ZTYPE_Z == 1 and TPTYPE == HW): + # approach_walktime[:, J] = approach_walktime[:, J] * 1.20 + TVAR4[t,:, J] = approach_walktime[t,:, J] * DRVOT * 2.0 + # ADD APPROACH TIMES AND COSTS - EVERYTHING SHOULD NOW BE IN CENTS + TVAR4[t,:, J] += approach_cost[t, :, J] + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=1(BUS) FIRST MODE. COMPUTE WALKING TIME, COST, AND IN-VEHICLE TIME + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + elif J == APPROACH_BUS or (J == APPROACH_FEEDER_BUS and I == FRONT_END): + + if J == APPROACH_FEEDER_BUS: + approach_walktime[t,:, J] = approach_distances[t,:, DIST_TO_FEEDER_BUS, I] / SPDWLK * 600. + approach_waittime[t,:,J] = fwfdr[Z][t].values[:,np.newaxis] + else: + approach_walktime[t,:, J] = approach_distances[t,:, DIST_TO_BUS, I] / SPDWLK * 600. + # INCREASE WALK TIME IN CHICAGO CBD + approach_walktime[t & (ZTYPE_Z == 1), :, J] *= 1.20 + approach_waittime[t,:,J] = fwbus[Z][t].values[:,np.newaxis] + approach_drivetime[t,:, J] = approach_distances[t,:, K[t], I] / SPEEDS[ZTYPE_Z[t]-1 + 4, np.newaxis] * 60. + TVAR4[t,:, J] = ( + approach_walktime[t,:, J] * OVT_IVT_RATIO + + approach_drivetime[t,:, J] + + approach_waittime[t,:,J] * OVT_IVT_RATIO + ) * DRVOT + + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # + # COST COMPUTATIONS FOR APPROACH BUS + # REVISED BY EASH 12/4/93 TO REFLECT CURRENT FARES + # ==== ORIGIN ==== + if (I == FRONT_END): + # FIRST MODE SUBURBAN RAIL - CHECK ZONE TYPE AT ORIGIN + # --- SUBURBAN ORIGIN, PACE BUS --- + s = t & (FM == TransitModeCode_METRA_RAIL) & (ozone_type > 2) + if np.any(s): + # PACE BUS - METRA RAIL, ADDED FARE IS PACE FEEDER BUS FARE + approach_cost[s & (LM == TransitModeCode_METRA_RAIL), :, J] = FEEDER_BUS_BOARDING_FARE + # PACE BUS - METRA RAIL - CTA, NO ADDED FARE, LINKUP > FEEDER BUS + # already zero # approach_cost[s & (LM == TransitModeCode_CTA_RAIL), :, J] = 0 + # PACE BUS - METRA RAIL - PACE, ADDED FARE IS LINKUP LESS FEEDER BUS + approach_cost[s & (LM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + + # --- CHICAGO ORIGIN, CTA BUS --- + s = t & (FM == TransitModeCode_METRA_RAIL) & (ozone_type <= 2) + if np.any(s): + # CTA BUS - METRA RAIL, ADDED FARE IS LINKUP FARE (SINGLE RIDE) + approach_cost[s & (LM == TransitModeCode_METRA_RAIL), :, J] = CTA_CBD_LINK_UP_FARE + # CTA BUS - METRA RAIL - CTA, ADDED FARE IS CTA TRANSFER + approach_cost[s & (LM == TransitModeCode_CTA_RAIL), :, J] = CTA_FIRST_XFER_FARE + # CTA BUS - METRA RAIL - PACE, ADDED FARE IS LINKUP LESS FEEDER BUS + approach_cost[s & (LM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + + # FIRST MODE CTA RAIL + # WHEN THIS IS TRUE A FULL FARE AND TRANSFER HAVE + # BEEN PAID, SO NO ADDED FARE IS NEEDED FOR BUS + + + # ORIGIN OTHER THAN CHICAGO, ADDED FARE IS NOW AN RTA TRANSFER + s = t & (FM < TransitModeCode_CTA_RAIL) & (ozone_type > 2) + if np.any(s): + approach_cost[s, :, J] = PACE_BUS_FIRST_XFER_FARE + + # CHICAGO ORIGIN, ADDED FARE IS CTA TRANSFER + s = t & (FM < TransitModeCode_CTA_RAIL) & (ozone_type <= 2) + if np.any(s): + approach_cost[s, :, J] = CTA_FIRST_XFER_FARE + + TVAR4[t, :, J] += approach_cost[t, :, J] + + + # ==== DESTINATION ==== + else: + # LAST MODE SUBURBAN RAIL + s = t & (LM == TransitModeCode_METRA_RAIL) & (dzone_type > 2) + if np.any(s): + # SUBURBAN DESTINATION, PACE BUS + # METRA RAIL - PACE BUS, ADDED FARE IS PACE FEEDER BUS FARE + approach_cost[s & (FM == TransitModeCode_METRA_RAIL), :, J] = FEEDER_BUS_BOARDING_FARE + # CTA - METRA RAIL - PACE BUS, NO ADDED FARE, LINKUP > FEEDER BUS + # PACE - METRA RAIL - PACE BUS, ADDED FARE IS LINKUP LESS FEEDER BUS + approach_cost[s & (FM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + s = t & (LM == TransitModeCode_METRA_RAIL) & (dzone_type <= 2) + if np.any(s): + # CHICAGO DESTINATION, CTA BUS + # METRA - CTA BUS, ADDED COST IS LINKUP FARE (SINGLE RIDE) + approach_cost[s & (FM == TransitModeCode_METRA_RAIL), :, J] = CTA_CBD_LINK_UP_FARE + # CTA - METRA - CTA BUS, ADDED COST IS CTA TRANSFER + approach_cost[s & (FM == TransitModeCode_CTA_RAIL), :, J] = CTA_FIRST_XFER_FARE + # PACE - METRA - CTA BUS, ADDED COST IS LINKUP MINUS FEEDER BUS + approach_cost[s & (FM == TransitModeCode_PACE_BUS), :, J] = FEEDER_BUS_CBD_FARE + # ADD CTA TRANSFER IF NOT ALREADY PAID BUT IT WAS USED + s = t & (LM < TransitModeCode_CTA_RAIL) & (dzone_type > 2) + if np.any(s): + approach_cost[s, J] = CTA_FIRST_XFER_FARE * ( + (best_approach_mode[:, FRONT_END]==APPROACH_BUS) + |(best_approach_mode[:, FRONT_END]==APPROACH_FEEDER_BUS) + ) + + TVAR4[t, :, J] += approach_cost[t, :, J] + + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=2(PARK & RIDE) FIRST MODE. PARK & RIDE FOR APPROACH TO RAPID TRANSIT AND SUBURBAN RAIL ROAD + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + elif (J == APPROACH_PARK_N_RIDE and I == FRONT_END): + approach_drivetime[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] / SPEEDS[ZTYPE_Z[t] - 1, np.newaxis] * 60. + approach_walktime[t,:, J] = W2PNR + # APPROACH COST=PER MILE COST + FIXED COST + approach_cost[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] * AUTO_OPERATING_COST_BY_ZONETYPE[ZTYPE_Z[t] - 1,np.newaxis] + # OPERATING COST MAY NOT BE LESS THAN 5 CENTS + approach_cost[t,:, J] = np.fmax(approach_cost[t,:, J], 5.0) + + approach_cost[t,:, J] = approach_cost[t,:, J] + AFC1 + # ADD HALF OF THE PARKING COST IF PARK-&-RIDE AVAILABLE + _tz = t&PNRAVL[Z] + approach_cost[_tz,:, J] += PRCOST[Z].values[_tz,np.newaxis] / 2 + # IF NO PARK-&-RIDE FACILITY AVAILABLE INCREASE WALK TIME + approach_walktime[~_tz,:, J] = 3 * W2PNR + + TVAR4[t,:, J] = ( + approach_walktime[t,:, J] * DRVOT * 2.0 + + approach_drivetime[t,:, J] * DRVOT + + approach_cost[t,:, J] + ) + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # J=3(KISS & RIDE) FIRST MODE. KISS & RIDE FOR APPROACH TO RAPID TRANSIT AND SUBURBAN RAIL ROAD + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + elif (J == APPROACH_KISS_N_RIDE and I == FRONT_END): + approach_drivetime[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] / SPEEDS[ZTYPE_Z[t] - 1, np.newaxis] * 60. + approach_walktime[t,:, J] = W2PNR + approach_cost[t,:, J] = approach_distances[t,:, DIST_TO_PARK_N_RIDE_STATION, I] * AUTO_OPERATING_COST_BY_ZONETYPE[ZTYPE_Z[t] - 1, np.newaxis] + approach_cost[t,:, J] = np.fmin(approach_cost[t,:, J], 5.0) + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + # ASSUMPTION IS THAT KISS AND RIDE REQUIRES A SPECIAL + # TRIP FROM HOME. DRIVER AND PASSENGER TIME VALUES NOW EQUAL. + # APCOST[J]=APCOST[J]*2.+AFC2+(DRVOT*approach_drivetime[J]*2.)/10 + approach_cost[t,:, J] = approach_cost[t,:, J] * 2. + AFC2 + TVAR4[t,:, J] = ( + approach_walktime[t,:, J] * OVT_IVT_RATIO + + approach_drivetime[t,:, J] * 2 # KISSING DRIVER + + approach_drivetime[t,:, J] + ) * DRVOT + # ******************* RWE CHANGE FOR I290 AUGUST-SEPT 2009 ************ + TVAR4[t,:, J] += approach_cost[t,:, J] + + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # EVALUATE APPROACH MODES AND SELECT THE BEST + # = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = + # FOLLOWING CODE CHANGED BY EASH 12/6/93 TO REFLECT + # NEW TRIP TYPES + # TPTYPE = 1 HOME PRODUCTIONS TO WORK ATTRACTIONS + # TPTYPE = 2 HOME PRODUCTIONS TO NON-WORK/NON-HOME ATTRACTIONS + # TPTYPE = 3 NON-HOME PRODUCTIONS TO NON-HOME ATTRACTIONS + for J in range(N_APPROACH_MODES): + # NO KISS-&-RIDE FOR NON-WORK TRIPS + if (TPTYPE != HW and J == APPROACH_KISS_N_RIDE): + continue + # NO PARK-AND RIDE OR KISS-&-RIDE AT THE WORK/OTHER + # ATTRACTION END FOR HOME BASED TRIPS + if (TPTYPE != NH and I == BACK_END and (J == APPROACH_PARK_N_RIDE or J == APPROACH_KISS_N_RIDE)): + continue + # NO PARK-&-RIDE OR KISS AND RIDE FOR NON-HOME TO NON-HOME TRIPS + if (TPTYPE == NH and (J == APPROACH_PARK_N_RIDE or J == APPROACH_KISS_N_RIDE)): + continue + # -- FIND LOWEST COST APPROACH + TVAR4_J = TVAR4[:,:, J].reshape(-1) + low_cost = (TVAR4_J < TVAR5) & (TVAR4_J > 0) + TVAR5[low_cost] = TVAR4_J[low_cost] + best_approach_mode[low_cost, I] = J + best_drivetime[low_cost, I] = approach_drivetime.reshape([-1,N_APPROACH_MODES])[low_cost, J] + .5 + best_walktime[low_cost, I] = approach_walktime.reshape([-1,N_APPROACH_MODES])[low_cost, J] + .5 + best_cost[low_cost, I] = approach_cost.reshape([-1,N_APPROACH_MODES])[low_cost, J] + .5 + best_waittime[low_cost, I] = approach_waittime.reshape([-1,N_APPROACH_MODES])[low_cost,J] + .5 + if trace: + log.log(trace, f" DIRECTION {I} APPROACH TYPE {J} {APPROACH_MODE_NAMES.get(J)}") + log.log(trace, f" drivetime {approach_drivetime[:5,:5, J]}") + log.log(trace, f" walktime {approach_walktime[:5,:5, J]}") + log.log(trace, f" cost {approach_cost[:5,:5, J]}") + log.log(trace, f" waittime {approach_waittime[:5,:5,J]}") + log.log(trace, f" gen cost {TVAR4[:5,:5, J]}") + if trace: + log.log(trace, f" DIRECTION {I} BEST APPROACH TYPE {best_approach_mode[:5,I]}") + + + # ADD ORIGIN AND DESTINATION QUANTITIES AND PASS BACK TO TRIPS + + ae_drivetime = best_drivetime[:, 0] + best_drivetime[:, 1] + ae_walktime = best_walktime[:, 0] + best_walktime[:, 1] + ae_cost = best_cost[:, 0] + best_cost[:, 1] + ae_waittime = best_waittime[:, 0] + best_waittime[:, 1] + + if not isinstance(ozone_, int): + ae_drivetime = ae_drivetime.reshape([vector_len,replication]) + ae_walktime = ae_walktime.reshape([vector_len,replication]) + ae_cost = ae_cost.reshape([vector_len,replication]) + ae_waittime = ae_waittime.reshape([vector_len,replication]) + best_approach_mode = best_approach_mode.reshape([vector_len,replication,N_TRIP_ENDS]) + approach_distances = approach_distances.reshape([vector_len, replication, N_DIST_TO_TYPES, N_TRIP_ENDS]) + + out = Dict() + out.drivetime = ae_drivetime + out.walktime = ae_walktime + out.cost = ae_cost + out.waittime = ae_waittime + out.approach_mode = best_approach_mode + out.approach_distances = approach_distances + return out + diff --git a/src/Mode-Dest-TOD/cmap_modedest/transit_skim_convolution.py b/src/Mode-Dest-TOD/cmap_modedest/transit_skim_convolution.py new file mode 100644 index 0000000..1ce0d25 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/transit_skim_convolution.py @@ -0,0 +1,265 @@ +import os +import numpy as np +import xarray as xr +# from array import * +from .addict import Dict + +import logging +log = logging.getLogger("CMAP") + +def skim_convol( + dh, + peak=True, + cutoff=0.4, + zone_types=None, +): + """ + Perform matrix convolution of transit skims. + + This function is based on the original TRANSIT_SKIM_FINAL_MATRICES1.PY + + Parameters + ---------- + dh : DataHandler + peak : bool, default True + Whether to process the peak or offpeak skims. + cutoff : float, default 0.4 + Park-and-ride skim routing is ignored if the transit generalized + cost exceeds this fraction of the congested drive-to-destination + cost. This prevents, for example, transit paths where the traveler + drives a long distance to a park-and-ride lot, then boards transit + for a short hop to the final destination. + New for the 2020 model update: When the final destination is in the + Chicago CBD, this cutoff is ignored when there is no valid non-PnR + path, so the traveler is permitted to drive unlimited distances to + access outlying transit (generally outlying Metra stations). + zone_types : array-like, optional + The zone type codes for zones in the model, used to filter for + Chicago CBD zones to apply the new cutoff rules. If not given, the + zone types are loaded from the package-default M01 HW file (see + m01_handler for details). + + """ + report_dir = dh.filenames.emme_database_dir / "report" + os.makedirs(report_dir, exist_ok=True) + + if peak: + # -- Input Matrix Numbers -- + inputmtx = Dict( + auto =44, ##0 AM peak hwy time matrix (mf44) + fmode=803, ##1 skimmed first mode (mf803) + pmode=804, ##2 skimmed priority mode (mf804) + lmode=805, ##3 skimmed last mode (mf805) + inveh=808, ##4 skimmed in-vehicle minutes (mf808) + trnfr=809, ##5 skimmed transfer link minutes (mf809) + twait=810, ##6 skimmed total wait minutes (mf810) + fwait=811, ##7 skimmed first wait minutes (mf811) + afare=818, ##8 skimmed final average fare (mf818) + cghwy=819, ##9 congested hwy generalized cost matrix (mf819) + tcost=820, #10 indexed transit generalized cost (mf820) + kzone=821, #11 intermediate zone matrix (mf821) + ) + # -- Output Matrix Numbers -- + outputmtx = Dict( + mfinvehi=822, ###0 indexed in-vehicle minutes (mf822) + mftrnfri=823, ###1 indexed walk transfer minutes (mf823) + mftwaiti=824, ###2 indexed total wait minutes (mf824) + mffwaiti=825, ###3 indexed first wait minutes (mf825) + mfafarei=828, ###4 indexed final average fare (mf828) + mffmodei=829, ###5 indexed first mode (mf829) + mfpmodei=830, ###6 indexed priority mode (mf830) + mflmodei=831, ###7 indexed last mode (mf831) + mfacosti=832, ###8 indexed auto generalized cost (mf832) + mfautrni=833, ###9 indexed auto min. to transit (mf833) + mfratioi=834, ##10 indexed transit/auto only (mf834) + ) + else: + # -- Input Matrix Numbers -- + inputmtx = Dict( + auto =46, ### midday hwy time matrix (mf46) + fmode=903, ### skimmed first mode (mf903) + pmode=904, ### skimmed priority mode (mf904) + lmode=905, ### skimmed last mode (mf905) + inveh=908, ### skimmed in-vehicle minutes (mf908) + trnfr=909, ### skimmed transfer link minutes (mf909) + twait=910, ### skimmed total wait minutes (mf910) + fwait=911, ### skimmed first wait minutes (mf911) + afare=918, ### skimmed final average fare (mf918) + cghwy=919, ### congested hwy generalized cost matrix (mf919) + tcost=920, ### indexed transit generalized cost (mf920) + kzone=921, ### intermediate zone matrix (mf921) + ) + # -- Output Matrix Numbers -- + outputmtx = Dict( + mfinvehi=922, ### indexed in-vehicle minutes (mf922) + mftrnfri=923, ### indexed walk transfer minutes (mf923) + mftwaiti=924, ### indexed total wait minutes (mf924) + mffwaiti=925, ### indexed first wait minutes (mf925) + mfafarei=928, ### indexed final average fare (mf928) + mffmodei=929, ### indexed first mode (mf929) + mfpmodei=930, ### indexed priority mode (mf930) + mflmodei=931, ### indexed last mode (mf931) + mfacosti=932, ### indexed auto generalized cost (mf932) + mfautrni=933, ### indexed auto min. to transit (mf933) + mfratioi=934, ### indexed transit/auto only (mf934) + ) + + # -- Input Matrices -- + # mfauto = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[0]) + ".emx" ) + # mffmode = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[1]) + ".emx" ) + # mfpmode = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[2]) + ".emx" ) + # mflmode = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[3]) + ".emx" ) + # mfinveh = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[4]) + ".emx" ) + # mftrnfr = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[5]) + ".emx" ) + # mftwait = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[6]) + ".emx" ) + # mffwait = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[7]) + ".emx" ) + # mfafare = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[8]) + ".emx" ) + # mfcghwy = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[9]) + ".emx" ) + # mftcost = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[10]) + ".emx" ) + # mfkzone = os.path.join(emmemat_in_dir, "mf" + str(inputmtx[11]) + ".emx" ) + # # -- Output Matrices -- + # if emmemat_out_dir: + # mfinvehi = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[0]) + ".emx" ) + # mftrnfri = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[1]) + ".emx" ) + # mftwaiti = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[2]) + ".emx" ) + # mffwaiti = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[3]) + ".emx" ) + # mfafarei = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[4]) + ".emx" ) + # mffmodei = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[5]) + ".emx" ) + # mfpmodei = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[6]) + ".emx" ) + # mflmodei = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[7]) + ".emx" ) + # mfacosti = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[8]) + ".emx" ) + # mfautrni = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[9]) + ".emx" ) + # mfratioi = os.path.join(emmemat_out_dir, "mf" + str(outputmtx[10]) + ".emx" ) + + # -- Others -- + stats = os.path.join(report_dir, f"transit_skim_stats{8 if peak else 9}.txt") + + if os.path.exists(stats): + os.remove(stats) + + # --------------------------------------------------------------- + # Store matrix values in arrays. + # --------------------------------------------------------------- + # -- Input Matrices -- + auto = dh.skims.raw[f"mf{inputmtx.auto }"].values.astype(np.float32).reshape(-1) # np.fromfile(mfauto, dtype='f4') ## -- float, 4 bytes + kzone = dh.skims.raw[f"mf{inputmtx.kzone}"].values.astype(np.float32).reshape(-1) + tcost = dh.skims.raw[f"mf{inputmtx.tcost}"].values.astype(np.float32).reshape(-1) + inveh = dh.skims.raw[f"mf{inputmtx.inveh}"].values.astype(np.float32).reshape(-1) + trnfr = dh.skims.raw[f"mf{inputmtx.trnfr}"].values.astype(np.float32).reshape(-1) + twait = dh.skims.raw[f"mf{inputmtx.twait}"].values.astype(np.float32).reshape(-1) + fwait = dh.skims.raw[f"mf{inputmtx.fwait}"].values.astype(np.float32).reshape(-1) + afare = dh.skims.raw[f"mf{inputmtx.afare}"].values.astype(np.float32).reshape(-1) + fmode = dh.skims.raw[f"mf{inputmtx.fmode}"].values.astype(np.float32).reshape(-1) + pmode = dh.skims.raw[f"mf{inputmtx.pmode}"].values.astype(np.float32).reshape(-1) + lmode = dh.skims.raw[f"mf{inputmtx.lmode}"].values.astype(np.float32).reshape(-1) + cghwy = dh.skims.raw[f"mf{inputmtx.cghwy}"].values.astype(np.float32).reshape(-1) + + mcent = int(np.sqrt(auto.shape[0])) + + if zone_types is None: + zone_types = dh.m01.zone_type.values + assert zone_types.size <= mcent + cbd_zone_indexes = np.where(zone_types == 1)[0] + dzone_inside_cbd = np.zeros([mcent,mcent], dtype=bool) + dzone_inside_cbd[:,cbd_zone_indexes] = True + dzone_inside_cbd = dzone_inside_cbd.reshape(-1) + + ## -- create leg1 (p-k) indices + indxloc = np.arange(mcent*mcent) ## -- array of consecutive numbers representing element index values + leg1pt1 = np.floor_divide(indxloc,mcent) * mcent ## -- portion of element index defining origin zone (division results in integer value) + leg1indx = np.add(leg1pt1,kzone.astype('i4')-1,dtype='i4') ## -- add portion of element index defining destination zone + log.info( + f"Kzone 1-1: {kzone[0]}, Index 1-1: {leg1indx[0]}, " + f"Kzone 121-2: {kzone[437882]}, Index 121-2: {leg1indx[437882]} \n" + ) + + ## -- create leg2 (k-q) indices + leg2pt1 = np.multiply(kzone.astype('i4')-1,mcent) + leg2pt2 = np.mod(indxloc,mcent) + leg2indx = np.add(leg2pt1,leg2pt2,dtype='i4') + log.info( + f"Kzone 1-1: {kzone[0]}, Index 1-1: {leg2indx[0]}, " + f"Kzone 121-2: {kzone[437882]}, Index 121-2: {leg2indx[437882]} \n" + ) + + # --------------------------------------------------------------- + # Create indexed matrices. + # --------------------------------------------------------------- + log.debug(f"Create indexed matrices") + autoval = np.where(kzone>0, auto [leg1indx], kzone) ## -- hwy time matrix + tcostval = np.where(kzone>0, tcost[leg1indx], kzone) ## -- indexed transit generalized cost + invehval = np.where(kzone>0, inveh[leg2indx], kzone) ## -- skimmed in-vehicle minutes + trnfrval = np.where(kzone>0, trnfr[leg2indx], kzone) ## -- skimmed transfer link minutes + twaitval = np.where(kzone>0, twait[leg2indx], kzone) ## -- skimmed total wait minutes + fwaitval = np.where(kzone>0, fwait[leg2indx], kzone) ## -- skimmed first wait minutes + afareval = np.where(kzone>0, afare[leg2indx], kzone) ## -- skimmed final average fare + fmodeval = np.where(kzone>0, fmode[leg2indx], kzone) ## -- skimmed first mode + pmodeval = np.where(kzone>0, pmode[leg2indx], kzone) ## -- skimmed priority mode + lmodeval = np.where(kzone>0, lmode[leg2indx], kzone) ## -- skimmed last mode + threshold= np.where(cghwy>0, np.divide(tcostval,cghwy), cghwy) ## -- ratio of indexed transit cost to auto only cost + + log.debug(f"Swap original matrix value back in if the threshold exceeds the cutoff value") + # -- Swap original matrix value back in if the threshold exceeds the cutoff value + swap = (threshold>cutoff) + # -- NEW 12/2020: but keep the park-and-ride indexed values if the destination zone + # is inside the CBD and the original values are invalid + prevent_swap = (dzone_inside_cbd) & (inveh > 999) + swap &= ~prevent_swap + autoval = np.where(swap, 0, autoval) + tcostval = np.where(swap, 0, tcostval) + invehval = np.where(swap, inveh, invehval) + trnfrval = np.where(swap, trnfr, trnfrval) + twaitval = np.where(swap, twait, twaitval) + fwaitval = np.where(swap, fwait, fwaitval) + afareval = np.where(swap, afare, afareval) + fmodeval = np.where(swap, fmode, fmodeval) + pmodeval = np.where(swap, pmode, pmodeval) + lmodeval = np.where(swap, lmode, lmodeval) + + + # --------------------------------------------------------------- + # Write final matrix values into files. + # --------------------------------------------------------------- + # -- Arrays to write out + mtxlist = { + outputmtx.mfinvehi: invehval, ###0 + outputmtx.mftrnfri: trnfrval, ###1 + outputmtx.mftwaiti: twaitval, ###2 + outputmtx.mffwaiti: fwaitval, ###3 + outputmtx.mfafarei: afareval, ###4 + outputmtx.mffmodei: fmodeval, ###5 + outputmtx.mfpmodei: pmodeval, ###6 + outputmtx.mflmodei: lmodeval, ###7 + outputmtx.mfacosti: tcostval, ###8 + outputmtx.mfautrni: autoval, ###9 + outputmtx.mfratioi: threshold, ##10 + } + with open(stats, 'a') as outFl: + for mf_num, vals in mtxlist.items(): + arr = dh.skims.raw[f"mf{mf_num}"] = xr.DataArray( + vals.reshape([mcent, mcent]), + dims=['otaz', 'dtaz'], + coords=dh.skims.raw.indexes, + ) + log.info(f"mf{mf_num} computed") + outFl.write(f"mf{mf_num} computed.\n") + # arr = arr.values.reshape(-1) + # arr_statistics = ( + # f"\t-- Minimum = {min(arr):.4f}\n" + # f"\t-- Maximum = {max(arr):0.4f}\n" + # f"\t-- Mean = {sum(arr) / len(arr):0.4f}\n" + # f"\t-- Sum = {sum(arr):0.4f}\n\n" + # ) + # outFl.write(arr_statistics) + # log.info(arr_statistics) + + revised_skims = dh.skims.raw[[f"mf{mf_num}" for mf_num in mtxlist.keys()]] + revised_skims.to_zarr( + dh.skims.filename + if os.path.splitext(dh.skims.filename) == ".zarr" else + dh.skims.filename.with_suffix(".zarr"), + mode='a', + ) + + + log.info("-- TRANSIT SKIM MATRICES CREATED --") diff --git a/src/Mode-Dest-TOD/cmap_modedest/util.py b/src/Mode-Dest-TOD/cmap_modedest/util.py new file mode 100644 index 0000000..74d322a --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/util.py @@ -0,0 +1,138 @@ +import os +import gc as _gc +import timeit +try: + import resource +except ModuleNotFoundError: + resource = None +import time +import numpy as np +import pandas as pd +try: + import psutil +except: + psutil = None + +# nano micro milli kilo mega giga tera peta exa zeta yotta +tiers = ['n', 'µ', 'm', '', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'] + + +def si_units(x, kind='B', f="{:.3g} {}{}"): + tier = 3 + shift = 1024 if kind=='B' else 1000 + if x > 0: + while x > 1024 and tier < len(tiers): + x /= shift + tier += 1 + while x < 1 and tier >= 0: + x *= shift + tier -= 1 + return f.format(x,tiers[tier],kind) + + +class MemoryUsage: + + def __init__(self): + self.memory_history = [0,] + self.max_memory_history = [0,] + self.pid = os.getpid() # the current process identifier, to track memory usage + if psutil is None: + raise ModuleNotFoundError("pstil") + self.check() + + def check(self, silent=False, gc=False, time_checkpoint=None): + if gc: + _gc.collect() + now_memory = psutil.Process(self.pid).memory_info().rss + if resource: + max_memory = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + marginal_max = max_memory - self.max_memory_history[-1] + else: + max_memory = None + marginal_max = None + marginal_usage = now_memory - self.memory_history[-1] + if time_checkpoint: + time_note = si_units(time.time()-time_checkpoint, kind='s') + ": " + else: + time_note = "" + if not silent: + print(f"{time_note}Net {si_units(marginal_usage)}, Total {si_units(now_memory)}") + self.memory_history.append(now_memory) + self.max_memory_history.append(max_memory) + + def __enter__(self): + _gc.collect() + _gc.disable() + self._context_start_time = time.time() + self.check(silent=True, gc=False) + + def __exit__(self, exc_type, exc_val, exc_tb): + self.check(time_checkpoint=self._context_start_time) + _gc.enable() + _gc.collect() + + +resource_usage = MemoryUsage() + + +def start_memory_tracing(): + '''More intensive memory tracing''' + import tracemalloc + tracemalloc.start() + + +def stop_memory_tracing(): + import tracemalloc + tracemalloc.stop() + + +def ping_memory_tracing(): + import tracemalloc + current, peak = tracemalloc.get_traced_memory() + print(f"Current memory usage is {si_units(current)}; Peak was {si_units(peak)}") + + +def timing(stmt, setup='pass', repeat=10, globals=None, quiet=False): + t = timeit.Timer( + stmt, + setup=setup, + globals=globals, + ) + n, duration = t.autorange() + timings = np.asarray([duration]+t.repeat(repeat-1, n)) / n + _mean = si_units(np.mean(timings), 's') + _std = si_units(np.std(timings), 's') + _min = si_units(min(timings), 's') + _max = si_units(max(timings), 's') + if not quiet: + if n > 1: + print(f"{_mean} ± {_std} per loop (mean ± std of {repeat} runs, {n} loops each), {_min} to {_max}") + else: + print(f"{_mean} ± {_std} per run (mean ± std of {repeat} runs), {_min} to {_max}") + return timings + + +def search_path(*paths): + """Search and return the first path that exists.""" + from pathlib import Path + for pth in paths: + if os.path.exists(pth): + return Path(pth) + pth = os.path.expanduser(pth) + if os.path.exists(pth): + return Path(pth) + pth = os.path.expandvars(pth) + if os.path.exists(pth): + return Path(pth) + + +from contextlib import contextmanager + +@contextmanager +def profiler(): + from pyinstrument import Profiler + profiler = Profiler() + profiler.start() + yield + profiler.stop() + print(profiler.output_text(unicode=True, color=True)) diff --git a/src/Mode-Dest-TOD/cmap_modedest/validation.py b/src/Mode-Dest-TOD/cmap_modedest/validation.py new file mode 100644 index 0000000..6286e43 --- /dev/null +++ b/src/Mode-Dest-TOD/cmap_modedest/validation.py @@ -0,0 +1,96 @@ +import pandas as pd +import numpy as np +from pathlib import Path +import dask.dataframe as dd +from .modecodes import mode9codes, mode9names + + +def attach_superdistricts_to_trip_table(dh, trip_table): + if isinstance(trip_table, dd.DataFrame): + trip_table = trip_table.compute() + if 'o_zone' not in trip_table.columns: + trip_table = trip_table.reset_index() + if 'o_district' not in trip_table: + zone_info = pd.read_csv( + dh.filenames.zone_districts, + index_col=0, + ) + trip_table['o_district'] = trip_table['o_zone'].map(zone_info.district) + trip_table['d_district'] = trip_table['d_zone'].map(zone_info.district) + if 'o_superdistrict' not in trip_table: + super_districts = dh.cfg.super_districts + trip_table['o_superdistrict'] = trip_table['o_district'].map(super_districts) + trip_table['d_superdistrict'] = trip_table['d_district'].map(super_districts) + return trip_table + +def superdistrict_flow_summary(dh, trip_table, dimensions): + trip_table = attach_superdistricts_to_trip_table(dh, trip_table) + + summary_table = trip_table.groupby([ + *dimensions, + "o_superdistrict", + "d_superdistrict", + ])['trips'].sum().unstack(-1).fillna(0) + + z = slice(None) + summary_output = [] + + for k in dh.cfg.super_district_flow_summaries: + v1, v2 = k.split("-") + temp = ( + summary_table + .loc[(*tuple([z]*len(dimensions)), list(v1)), list(v2)] + .sum(1) + .groupby(summary_table.index.names[:-1]) + .sum() + .rename(k) + ) + if v1 != v2: + temp = temp.add( + summary_table + .loc[(*tuple([z]*len(dimensions)), list(v2)), list(v1)] + .sum(1) + .groupby(summary_table.index.names[:-1]) + .sum(), + fill_value=0, + ).rename(k) + summary_output.append(temp) + + return pd.concat(summary_output, axis=1).fillna(0) + + +def to_excel(df, *args, **kwargs): + if isinstance(df, dd.DataFrame): + df = df.compute() + return df.to_excel(*args, **kwargs) + +def validation_aggregation(dh, trips, to_dir=None): + + if to_dir is None: + to_dir = dh.filenames.cache_dir + to_dir = Path(to_dir) + + if isinstance(trips, dd.DataFrame): + trips = trips.compute() + + trips = attach_superdistricts_to_trip_table(dh, trips) + internal_trips = trips.query("o_superdistrict != 'X'").query("d_superdistrict != 'X'") + + agg1 = internal_trips.groupby(['purpose', 'mode', 'hh_autos'])[['trips']].sum().unstack(-1) + agg2 = internal_trips.groupby(['purpose', 'mode', 'hh_inc5'])[['trips']].sum().unstack(-1) + agg3 = internal_trips.groupby(['purpose', 'mode', 'timeperiod'])[['trips']].sum().unstack(-1) + agg4 = superdistrict_flow_summary(dh, trips, ['purpose', 'mode']).T + agg4.index.name = 'segments' + agg5 = agg4.unstack().reset_index().pivot(index=['purpose', 'segments'], columns='mode') + agg5.columns = pd.MultiIndex.from_arrays([ + agg5.columns.get_level_values(1), + mode9names, + ], names=['modecode', 'modename']) + agg5pct = agg5.div(agg5.sum(1), axis=0).style.format("{:.2%}") + + with pd.ExcelWriter(to_dir / 'validation_data.xlsx', engine='xlsxwriter') as writer: + to_excel(agg1, writer, sheet_name='Autos', merge_cells=False) + to_excel(agg2, writer, sheet_name='Incomes', merge_cells=False) + to_excel(agg3, writer, sheet_name='TimePeriod', merge_cells=False) + to_excel(agg4, writer, sheet_name='FlowsByPurp&Mode', merge_cells=False) + to_excel(agg5pct, writer, sheet_name='FlowsByPurp&Mode%', merge_cells=False) diff --git a/src/Mode-Dest-TOD/nesting-tree.png b/src/Mode-Dest-TOD/nesting-tree.png new file mode 100644 index 0000000000000000000000000000000000000000..148f40679d2a52f2ceedee98a9f6582d6e67d6dd GIT binary patch literal 43030 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 z�dbXD5?++_d7?3t>r*noVuoWmq&@yz-iU3AC!v zh{C{M(~_%Y?8!P0fn4dNIxS4FN(nlRiA1em@E;;9Go#g`gV6X zkh(ewZO1+2xIs!Q6%h_^&aL`AgvVMi%MQ@`u^`A~unOD#dgYyF!_IAZw4N*KL?e@7 zO(DkSiI>>MDK694Ap~<;VW5Z$db0{YVB7UVTP4TjG?%Hju2N>gW3wGTf6>$WDaBvU zk6(~fq1CK%b2>5W3;3SYnorf!`rbV+Vha!_2YnL98AqTED%vjM9~o4o_+qyHl~6U=6QWBbl!j05XpjiSHVCg7iGnosG1}V22cl zpenZOH9y4bsE@>;2)JAfrF(O-H;-Gb{;=x(Xld7l3P)2S_t_Gqx&evTNXTQ^xC-;j4Q9D z(OZ6+Sz=W?y_tGT^hYU=bRt9WyR$4*M>5Wbv{>6RKbBL{M_50y%(@;=*N(rkL|DB zIPKO0;g2V?nYv?-l9l>(h=ZG5$Qaxvbtij$9g~q@ro!J5O?{~bR=q`&Xf28n8e((Q z0{k%F{2^8gT)!5?_AIbOb~7QwnNRvOS?j@+roeENhI*4EGVt481~xqmAf>E|4QW^7 z{~V;JW`OLbQHfW7#U-6SxGK1p{;4vp`rNwQk7xY@nBia=9Y1xHSCZg)-`Y!lA#zR- zDsS$YRcLXS8ucax1JdVKr-tMFAY@U`?o$X$>q(HF4lxX87EwH8ghwN;N8X=<-G&P= zZY6_(2l#BkfyCHWv0pmLENJIS<_@n;bL%e>q;Oj*hy$(CAbu-*#4d)}-W)YADlA#B zUP9@}9BsoBuFMdC~f zF>7H~1LpGU5=7gap+_g5)l!p8I(w5O0R_BBIGW9`25oEGp7yI#&3| zc=}QxEl-!vzO$Cl3nku2zG_wCx&i*d*M)D8u-v$AMakQ)#=)kB*s##0kHJju6)SPQ ztlMtZZb3+sV?8d0_gaJ~*oMmG)Tli{~S#*^Ye1N2I9 zxf>D{a%Jbb7-T-;)+CjKn%XAmAlRdIc67Zilj-qjrZYOs9eghoNcyoA$2_C-=~9bxDPFRajLh64YzxYY@xsJ+?iagSwl*yoTNezs zhOa_cZBy4w`0#dl!mMR81m@Qb6`Wm`;=$zA?bluPm_UqZ?wbeW-tu>mB!P>c*xsT z%i4F*B`rCb@*N_cQ!(Ak^Zr71hLbs`66oo&U|*`-dw7 z_LjdBsAB%lysRoZ(4`xU<@Y@;k`C;q6;`yrZPMUQeZhW)!T6#AT|QkX3>n3do=cEy zs?saCV1WoL%|ZI*VjxRW0*Pf|^E2>{s3{N}IT$G(#>IkPLD-rH@&B4@^}j^jlY~GN zg$mHOucMQp1SoXz`n;`A;c0^2Ll)_k z|LX7mj*8R`27_Lh#mbBVsuC}o8zU4bjDObA!E1xmAD18)g24zRIv~a>j{8ll*M>et zC@aKxcV(Js*eh?OU02v+h;oJt%9|66PKcFzmutVy{qrR_x#jAe@oS#{gPMlMNMMAo z9rH&NJIOA$f`s^Z`yW+`g7f_5dq|wd*nOz8A{ z2ce$3y95xabc0_CY;`;W@$Lm#q9}ph2RZ29oT0mvhdJa|W%g0$JR&xCI(31vJU<}e zMdXIh`B2Wn{n$`b*{rF6=^eB5Jpe1<{R_bv-AAC~vgt&+q-4*i7c)^HBcKE5PIc-v znJJKAo6tK$nQwD#RglT17Zwl!3I2$MF(z< zm$W_T@pzoRisskP7C8oZ`~=1;X*eSvEA9PS#ilAO)R6aoa^?O40zw8UA^b^c?DHh@ zWS{{sHRWn=N(eg?7M(5*ASr48I{PA=-#0p$YA&^|?;p;`3?8qbx932iu2!XKPBn?#l(v zg&!N`OL$ALhndsjZ=Me9&sv|Ya4up2GOQ5TqCCq9tBzMvihm+;$0jK>ac}a^+hvZ{ zaYuh*ko0=1U!S9Buv)&_`x}aV5)(*z5Ua)mo&D7IL;$G6JpeinqPJ;_yYnyGX1*DN zz_Hyy_UraXU~hXoGo6)qL?t@HD!JKp$8iI5d(F?w+uJ42NWRlq@T|_0KGrXFlCCBL z9c&3^i`pzJCPQXTX_}{jb`$|aBbU!b>vneX@Bq})nZvstu(FVm$vtdnbjC#!c`@z^ zGdxP@8iC<2mRCpb%`_V!ZV34Fw4{sV$pf!V==wcVIlC4;@S714TwC|rD6xRsZldN56SVr*t$ zr6dKb6wqBwRqPCDA5&_X(-f-5ITJGqsan@%P1e*3QO820oTE=gUgX8QEWvP4uCNG+ z|0z2Blc4vXB>Ekn9XvI7;lMR@wkrqL_5<%)1d;lBkDs=uTYg4-H{&bs50SjkD6Xrx z4AWb4-uZRp#aaw^RSG0CtY2T9rzS$bvd@f+P=&Bm^NF%4d*sD3@LPUHy>wv39!a~+ z^`S4hqj(|p^9Xnlf`JFq!3-_eBr7dvsSyki{vHR`1`JwbV{HsR&AMt)L_B)E6_EqObjgq#sxS36gzds5IDH(;_*>+5( z?(bJH)(uodJeJevpDoI;bE3Sn!R8O0dqwm`>_z->lLWwJa(IdBs^1)jP7)xKpq+G;mg zHNz<`Qv$L#AkOyvq4A5L@z3sfkC9#UqbfsHpLXW^$z+I(1U%@~3pNVwf|Ra7 zk`IgFdlU8dFS`yoHO(O#lx%pO{zx!a9Aw`^>RsUp=W?!!Lrom&5s_MMk6-5{sB#}= zQ?K_(mriDx4`_9lqWFL@+u2CcH#q#dT@!iaofIo%hi`!kD!Nij3dmP+~ZwJW8oQG~O9&+!`pQkGtaIJ%HK&mA{1+GObkasFQl_ zZ?RUFxMd{EdK+%^?E0}(c07vjMXAANl?rjqHCC9_vBTB%xtgPsi-A|><+0ne=2W1- z=`f|li^uLb&GGYU`brL$oUYfs^NK#R!JWV<(dJ455mLc?KJF!(7`Mwwe4(zFSY%1_ zu(>&}vaJOVcJZp9@@=mGPf8*=HoHv%gmKe~{fu$U;{6?-4w>*NOK24TqbOezv#u;x zae$Ljps$ir+>9O1K9>LV^ygoluYOib8HBs(-ho;mgtsqaH21f#wxj-IR{Jxp zi6msCHFPZnB_2ZSjLAR)OzP~Fm2~laFMOipsgCwxJ9!fQ$zr=)Me{bO_E)-tb!&I3@x%%72gN*s;bmnj)uMigQA*0Ie*D4Fkx2^ z4D+K5B>J93SZ{6_SOx?x4i1-jpD{U6PocZA1Z;gW>ufw^QlAHER{OPHSH6k#*LZDv z{A%CzLyeD{9F}=*I%vnjos+JDa@x!4Ksg;$ShVJL83hX4TjJvi#qxNdl&i?lh_H!$ zUpXWWlc~HtoMGKJQv-8cJJBCo85P0dXODWDuX4;02YL->`|s}5_NVG&u|$sc8|&rm zCP8^^CVmpTkDM`NN395fWjkW?7&d$sUCIJApRSOh&P0d9E$%E|q);E>pv@ihsdUek z!K#Gwls^BKZJW@jQOP_2ElsMIl5J*Df$;~e3Us~IWidR+{+axpK=?bJ8GAJD3+8_z zFhc}Tcb$=EBKpUy|5c3zY&|smTisPCiUyd7`~R@+f!9f*et|jW6qv~We&Z_?0H?FF z#S;EAKUkVrKxm33F8n_#Xo3L%oSvK{mio_podV>nY%?rLQQ^Nkw*QB>vp;1?n4t#b z18Y1Z^)D%*DlRHIGe!wt5`-8T9kp)eR3ZJWqGIwm9)LuOghm!ElNxBYu153c`sAR$ z;wo+oN3;b2?6-5IJNt8BjMynXO9ohN9?9eobe(xR(dn31NpyTl|DVA=MNuGy8S`R6 z3;#paf4|5=M)^HEBUb|kw%F~{H3kl=D;)ys^?(3xl)TBo=EBPpq z*N+t8Q0AJ`f6y+ujI1C&tsFnP{Ta6>u=fF|ygzW6z({nlfUS?{1&4&N(ejBJ$$(8M z{BRn`vc(9Cn4C6xNp4E&oC)a8SxWaRCCnudc>fKST_HLm{mdb{{=(-~F#EGOTn zNkR(ot%91G`r3u|u1@e7VXyaF$Y0HXQ80F%aQNURSAa9rdwqGn_`$wrW=KX#Dw30v zlc(M4(xPCFKW;I|&?PB38mEsTjKgd93P{V!CKOoc3YIRM0{DWGjxyTLcv-{!xjOq0C4OOSOuD=9 zYYHf#=g0_nJndYa zUg&p@;#micbB9oue~BEJApH)`!9>M;2g4!&LJY6#`&?gVHYGUDu?e^2#3HTGy9W;B zQIkT=p1Okpy1}F`fV2~BR$7u{gTt!jcj>-dFePQ%dO=C_dmh$)~=5 z6^a(X2%T+~Q(Dx^^Pl8&Udht%LID1KgZ&lVX^Z-%dC*9B3p3R3NvawGqVRWyJF=N6wyZzu^^H zpgV!6eX--~!J;_r+hxK(ygaiw!M^};_M64KggM){;8PqB|F^aIBm)HR@}*J9{}E6G zw1p#b?xit_VeY~O>?J~sjuy$?@4q?FfN1jFmFe+?a*(sDI?Szg1aQXGao4I)O-(6G zcUV)KCr{_hvzDf1jjzmnRZK6X9I9rVn$GsNG>=aDt@G6f+MA_Pz~z*e0P>s2PntNa)AXE&Pe`nBfnyiD46&dn9qbatga0>)Jpw z2mfo0)?8uY*2R9T@pO|yhs4k~HQy)mW*+`a?_`b_>E?}*HA_=fy5#`^I+QmPClZ!8 z5-ygJpjnYlR~Ut{v5^k<$A0PoY$vntzsX_LzIR2Zg ziQuwXRRIY!<&1}g+Ba($j>k!(2bnwW9fap;k->I>T7LM(P{}_;#RPEjDM}gf4q)3Y zh|e1|D-wYyc^)~mu$>Tue#SHsmv*JqIUe8_h#a zUmK7Vknk!9Y`J|n%d+;`*Wcl zV4+6VEeYJyIz#}}p}YMGOa?3-aF(FU5XOjG^6Kh~$1QBk=ebDoGY{Zr&qj0eM(mDd zbtPU*U3}{he&rMs6aoLaBqt6T|$t< zVrz)?(YBly3Y>DMf&;%$`kYJAmyY}5b+5D2pJbN%Wq@#|)Sr+I-uuyVKUM|J++*BrEr zx7~5cbRYxykDHNq#>13xtoc`^21_DfJTx>l4Hr#ZT%tN%4kV{1YjKv{W4o?vBO)ez zE&J=_BPX(;ZNgg7a|w4$H&8mv0nI}@5IacGMZ%t5R@c_P26J_7PLl;f93DQtVOyD| z01qQKZ3*l8&|%|1gRh6PXH*9~FOq#eML4=K^5^X>A5{SayLlm4PG&Q*LAO9H(|21W z3W>}Ujx;Ii)}-zVCHpYf2m6}xl)po=n+xXZ9x8UTD%@ndcZB|6Wpx9jn|2n zx+wJ6qU+M@y!!j)J8{+g#aB|m@b}=pTP1A4#q|fq3jqgZ%2{Gss_dfKP|~cxEz!|x zj~YXt7M|<=BhyU7lZd@Dpv(TN!-M0RR{^+k(W0BUKi9m}4K=beZ}O;8-?w(zWcl&@ zg316GFMTST%1pm`DcFryr57p2{q95_b@=^@-SXgv8u!(w`2$omG)Y$7oB>b4$q0=&oG7+Mk$#z>?dhJr}Hk#iRSP0-wZNeb&k# zD-l!pl;+sgNn(EeSGia-7#yFPx*+Xm#MeLl@WT_V5>|Qy18Iq(r zIjuyu@dvM5Og7^~GcvhhM1&6-jxeZ#GDm}G6AWcGU*QfRH3xD>HcKiRIT3j6$B(z; zIRINcs)674JNZg_y&5 zHc}y$Q{nr%9LE6($#sj(Af{dV-3tRrbTD`Kkb`V z(pMHUrS4k=9;UHKCKtkZdq8b`EURC24;)CLKAz05u*${uw6`m!Nz5pxK@bIXab+ra zg=XOKtjK7&jDoSxu8O5P8~au@Zj#I+mAR-MZPn|osXmF}AT+c3Do9^gD_v*D~hc-@Eo$yHLZKxdld? z4v;!z-)wDTtPJL|kqaODXjyaIycZj56jJsYB>3bIDoEbj*l$V$S&(ybX}IvOhMz=o zRaUiKJ6aeN_r4nKdg&a8mSE9c6}eR_roQ_xafVglW~Wb(NO8KE_7=g7#$4c-3KR$i zq|82cAI!ORbaX!fYB*kpvC{ra&v!Z)#%Lu#Lbl2qd*G`-mfdpCvM>8pIZ<-*Q=8fC zS1D5oxy{6)4}2n+IwW{MEc&CEbIJFQXksk3{>&PTY>}^8Sn0HwYfth}7>sO2IKZRz zlf2O#3OrY@-i?o)W(@4;P=Y!mutD-K)1#xy91_6f@-dBf!^m}uT|(&dNuNChy*y|E zUNadw82OvUmYQ6r!G=GFOZV*D<7EcLlW&OkMjix*I62{^UF2ZJP7{n6tIh16im+>6 z5HjH5=kF6^^_WFMpaN(4D!d1Ob3>ZPh6!6*{4fvdkDG9`f{@qo=*o%`Mi$eW%6BMwE6;r;o*LzhZ zl9W~l71*$yQx-M)t8)@OTU{kNmMh6_?pqKnfdZlZOGrqG8dCo@Z`O@l;@W1AAs**9 zuAnU82?K_@`hK)|^aim6ZRL2Mf zOEZ&39Jlx@DMqG9oj514$;hsk!snXeWuLHL6nw1pb_m`3GSo0C(@dJX7pQIn7I}fj zTxLsf9dkA(hH?E5)(B8_tf!{X7P*NpxyenERP^6j!0P+@vioqZ--?Qf8JOBKar}B8 zP@hh&x=7jz?cEyLo5=yXnSL``GL$nz&x$`3#uRO^fpiPrw~$K%e-}JV=q69}lpEsO z+#wo!$ATWp$#jfoW+(fk`Guq$l^NsI*C<^x(|zp}7kl`Yn?8Q@KN`)0!wxJ*&-#2l z&?zg4?BgrayJ17}-EBGuG4_QY#rPnf14Va&TV|M>^m8oMfyoIS{IR`5$z5y0{wy)_ zv1ts+5^F@;*?IYngnV-?ENwkcG+@m?kf_>vzTro0s>bvgK1}KR027ajce=(ZRhqIc zbv;*k&^q?;Wl{rU_?@0~QG3)01&k zZ!zJmx^66h2r>L&qn8Qa(mF2?dSs-Bd~YOk`zCqAYdcCblD0`A=ox~MR!&e?Q26cc zBb)XIG6uyfebiomTIsq`Jog;SD=*7}@Ma=6w7pcP6rtIBFW^wyaHorVi?VRHX)4~-e0iDh(gHb`dQK?X>wmZ%b z=c5h%y63mq2WK{0pKYLzZhY-$RVW&7``Pm&m`C1PEO`DiMv23Qd`;)t&P*i{yuV+w ziQd4NMQcD!hA#G+{JRC){?XY|x?p}6*x+P<2gOkL{QSJFwWLS*jL!~5!<(RnEv0~v z`^^GHmAcG?KyNLtU1p{ zkvre%6F0mhKoQ0goSbYS^NO|y_HL3Yv|?CdZ?)FFOQwqlrA3wI zgNW2&Bfl!?-Oq~_Lk1i7YH(vK>%!9`i$`u zVG2`fXW=px((=mSZ|bY(se@;RbNs}OXk2;_0i1Oe8rVmCn9&c5c5TqN!$m13Pq>)9 zhz({<-!i*%n0|S_Jb09$XLt84j*hWrvW(&uD5lvrK!A1;Sva~~H&-AwHv5c70 z<*+)3g!a9a4T$q|#n5fa6;p6?b1z9uchD1M@HDrrE=MHsBH=k9ZLf)?R$6=WfW#m} z^)aQegxU#o!5>>S{^om4*lU%gwVI8I+ORzu4HF6 zCL(JaDCi^~La_D^W6TU69hXGVamDR7Ep1=QQ5!I}r>>PcKIdFK>omVTr8Z!&cv!i~ zSIeXN==*vs_rB5(Cc*R;kr_I4Muc)9MvpT%fm0pm&w$XscR&;lhdV^T1H#AO`P4}7 zZ2P&MWF708K;nzd^7)1s$E4UqIGaQnNugZ567gzlC8G)U-8~P}|!JJWIgQnRh=Q&$UXrRa%f$g)^D9i9ius| zZ`znD9g_UI(KN^BN5(Il4tZmzNF3W%N&VckwKemn)NU6}MP52^gYos5uEaX!2p2p7D6dHO<_JZe_h$+I6noIUDSoLvB^oPX zdNuuW9JMNJwt?K*TUNBLDWSj~ZD!;$?SD@ct4P5@XkG2{-OmLh?i$-e&=h=k`fhI} z+!MtRsu(a#+d87tN51jKt8JqPApp@}ZMw9z1=7dBVK?X#FLkx*V@(}TvCjWKIi~SJ zpdm@uzhWI=;bVY>w_gs$#~Xh|hWIbRLHIDp`2yt3Uxf6}FQ!5uJS==gvv3L%eyKme z)rdfN_@F_nf$ARt6}aZ#f`flt1UOO&;7AE|2ygTI)_U7 z?|p3&@%8WCz0;4<22GPC+s-#C1WD4c8TmYe!;Hio#x#eWF!pU&>QIetxjiwZ$zPGL zEIvkFj7%e-hy6{}+-0m}Iw%@}`prIHZ3_9a? zP@D|hF$^yjwj8f?sh(^7RtkcI*AWlyM_uP=vR6}b2pb8hZpZkjzx`a;#as<-qgfHB zg0^96eQ>g)WgC$OTh}2!qiy04U@_&@t<#ZD2~g?fAWnO=EgoaXYqrA9Q%Rw|2*?C4 z*Nx~RGl~4n%U;=*x<9ukkTUtoP?LM|-u*X&Im82=Vs*7y&;R!Q>D~mCFjzaW)cMmy z$KQ6~D##(&7)?N|k)yf z&ak4eu<+-45=*=Es(KHVHT+qkUBj=dhBWOYfu|Rx_1?9Zo!4(~oo4j9eu*h4MNcec z%OmVy^7tyZHZtYh`P88w3*7raPLeQWZ3^tnr^7&%cvI4aN__ z_^brs`opo}WwC{3gi)OaC+DYEYQ;r_jq({d8XQQ9=PKZaTs6ps%ioF!SV!5F`kJ2n zez5R`#OjX@Zzhh-U2!>^1yi+C^Wco9jE40@xGDBC8b}tANd=*L*W+8WKaXyVR~g72 zI>(KB9<})9xM%U{!iX?FtftD+wJx((Y2q6KRR`(Iysay~n#0D3Izj!9nxGtL9;-sN zOh*VYJ{Z8Ix3_#Z8~J;v*h#{=x`p#vWr7C z;8J9mgc50p_>I(z09}Osc8s6~mvY5~bKY}LG>5o3L{7rPQ5N2unkQ-WV$rg`DB+Tq zA=jCK0so`~$`Z%1$Cu-eW_gwe_*9_rvMNZ&a<`dlq%KbgP;0_K&pK2*b%kcqEobUA zV@MAdCOO+RTaK?4VW_c`VSxy(15_+hl@%bzKLW9sfeg#}- z%c5Fxxr4qh>uWta^+l^hX*M;$Al-qAJxR>xGOh0SxEpiF?ffQ3d5#as_6*;SW#gao z8oHW-fFfsW{$#*H!6*oeXW?W}N#g+YcigT0j8hX&f@czgnmM>ld5CO?=krK;4RP>~ zT(qnc%6_#}G`*gTMGKjdUQaY9W=z8xO&cWD1MTtF7 zr;y;UpOPoK2w1qjPiV8D{~S$P{1FI|9QZeJ_x~>J_utOk%CP-6aTgR$aVV!>sK4}L TwY7r){3-pRdZ*~NX~_QpDeXV6 literal 0 HcmV?d00001 diff --git a/src/Mode-Dest-TOD/requirements.txt b/src/Mode-Dest-TOD/requirements.txt new file mode 100644 index 0000000..cb569c0 --- /dev/null +++ b/src/Mode-Dest-TOD/requirements.txt @@ -0,0 +1,5 @@ +numpy +scipy +pandas +addict>=2.2 +larch diff --git a/src/Mode-Dest-TOD/setup.py b/src/Mode-Dest-TOD/setup.py new file mode 100644 index 0000000..26db817 --- /dev/null +++ b/src/Mode-Dest-TOD/setup.py @@ -0,0 +1,62 @@ +""" +CMAP Trip-based Model Code +""" + +# Always prefer setuptools over distutils +from setuptools import setup, find_packages +# To use a consistent encoding +from codecs import open +import os +import re + +here = os.path.abspath(os.path.dirname(__file__)) + +def version(path): + """Obtain the packge version from a python file e.g. pkg/__init__.py + See . + """ + with open(os.path.join(here, path), encoding='utf-8') as f: + version_file = f.read() + version_match = re.search(r"""^__version__ = ['"]([^'"]*)['"]""", + version_file, re.M) + if version_match: + return version_match.group(1) + raise RuntimeError("Unable to find version string.") + +VERSION = version('cmap_modedest/__init__.py') + +# Get the long description from the README file +with open(os.path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() + +with open('requirements.txt') as f: + requirements_lines = f.readlines() +install_requires = [r.strip() for r in requirements_lines] + +setup( + name='cmap_modedest', + version=VERSION, + + description='CMAP Trip-based model', + long_description=long_description, + + url='https://github.com/CMAP-REPOS/cmap_trip-based_model', + + # You can just specify the packages manually here if your project is + # simple. Or you can use find_packages(). + packages=find_packages(exclude=['contrib', 'docs', 'tests']), + + # List run-time dependencies here. These will be installed by pip when + # your project is installed. For an analysis of "install_requires" vs pip's + # requirements files see: + # https://packaging.python.org/en/latest/requirements.html + + install_requires=install_requires, + + entry_points={ + "console_scripts": [ + "cmap_modedest = cmap_modedest.__main__:main" + ] + }, + +) diff --git a/src/Mode-Dest-TOD/sharrow/.idea/sharrow_lite.iml b/src/Mode-Dest-TOD/sharrow/.idea/sharrow_lite.iml new file mode 100644 index 0000000..32effd1 --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/.idea/sharrow_lite.iml @@ -0,0 +1,12 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Mode-Dest-TOD/sharrow/LICENSE b/src/Mode-Dest-TOD/sharrow/LICENSE new file mode 100644 index 0000000..7026335 --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021, Jeffrey Newman +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/Mode-Dest-TOD/sharrow/README.md b/src/Mode-Dest-TOD/sharrow/README.md new file mode 100644 index 0000000..285f345 --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/README.md @@ -0,0 +1,4 @@ +# sharrow + +This pre-release library is independently developed from the CMAP trip-based model, +and is included here to ensure that the CMAP model links against the correct version. \ No newline at end of file diff --git a/src/Mode-Dest-TOD/sharrow/requirements.txt b/src/Mode-Dest-TOD/sharrow/requirements.txt new file mode 100644 index 0000000..25ff221 --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/requirements.txt @@ -0,0 +1,5 @@ +numpy>=1.19 +pandas>=1.2 +pyarrow>=3.0.0 +xarray>=0.17.0 +numba>=0.53 diff --git a/src/Mode-Dest-TOD/sharrow/setup.py b/src/Mode-Dest-TOD/sharrow/setup.py new file mode 100644 index 0000000..6fac007 --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/setup.py @@ -0,0 +1,64 @@ + +# Always prefer setuptools over distutils +from setuptools import setup, find_packages +# To use a consistent encoding +from codecs import open +from os import path +import os +import re +from setuptools import setup, find_packages + +def version(path): + """Obtain the packge version from a python file e.g. pkg/__init__.py + See . + """ + here = os.path.abspath(os.path.dirname(__file__)) + with open(os.path.join(here, path), encoding='utf-8') as f: + version_file = f.read() + version_match = re.search(r"""^__version__ = ['"]([^'"]*)['"]""", + version_file, re.M) + if version_match: + return version_match.group(1) + raise RuntimeError("Unable to find version string.") + +VERSION = version('sharrow/__init__.py') + +here = path.abspath(path.dirname(__file__)) + +# Get the long description from the README file +with open(path.join(here, 'README.md'), encoding='utf-8') as f: + long_description = f.read() + +with open('requirements.txt') as f: + requirements_lines = f.readlines() +install_requires = [r.strip() for r in requirements_lines] + +setup( + name='sharrow', + version=VERSION, + + description='shared data formats for transportation modeling', + long_description=long_description, + + # The project's main homepage. + url='https://github.com/jpn--/sharrow', + + # Author details + author='Jeffrey Newman', + author_email='jeff@newman.me', + + # Choose your license + license='GPLv3', + + # See https://pypi.python.org/pypi?%3Aaction=list_classifiers + classifiers=[ + 'Programming Language :: Python :: 3.9', + ], + + # You can just specify the packages manually here if your project is + # simple. Or you can use find_packages(). + packages=find_packages(exclude=['contrib', 'docs', 'tests']), + + install_requires=install_requires, + +) diff --git a/src/Mode-Dest-TOD/sharrow/sharrow/__init__.py b/src/Mode-Dest-TOD/sharrow/sharrow/__init__.py new file mode 100644 index 0000000..d168061 --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/sharrow/__init__.py @@ -0,0 +1,19 @@ +__version__ = "2021.4" + +import os +from .interface import SharedData +from .dataset import Dataset +from .local_dir import local_cache +from .tables import concat_tables, Table +from xarray import DataArray + +try: + _pro = int(os.environ.get("SHARROW_PRO", "1")) +except: + _pro = True + +if _pro: + try: + from sharrow_pro import * + except ImportError: + pass diff --git a/src/Mode-Dest-TOD/sharrow/sharrow/dataset.py b/src/Mode-Dest-TOD/sharrow/sharrow/dataset.py new file mode 100644 index 0000000..612ad8c --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/sharrow/dataset.py @@ -0,0 +1,457 @@ +import numpy as np +import xarray as xr +import pandas as pd + + +def one_based(n): + return pd.RangeIndex(1, n + 1) + + +def zero_based(n): + return pd.RangeIndex(0, n) + + +class Dataset(xr.Dataset): + + __slots__ = () + + def update(self, other): + super().update(other) + if isinstance(other, Dataset): + match_names = self.match_names + match_names.update(other.match_names) + self.match_names = match_names + return self # deprecated return for consistency until xarray 0.19 + + @classmethod + def from_table( + cls, tbl, index_name="index", index=None, + ): + """ + Convert a pyarrow.Table into an xarray.Dataset + + Parameters + ---------- + tbl : Table + Table from which to use data and indices. + index_name : str, default 'index' + This name will be given to the default dimension index, if + none is given. Ignored if `index` is given explicitly. + index : Index-like, optional + Use this index instead of a default RangeIndex. + + Returns + ------- + New Dataset. + """ + if len(set(tbl.column_names)) != len(tbl.column_names): + raise ValueError("cannot convert Table with non-unique columns") + if index is None: + index = pd.RangeIndex(len(tbl), name=index_name) + else: + if len(index) != len(tbl): + raise ValueError( + f"length of index ({len(index)}) does not match length of table ({len(tbl)})" + ) + if isinstance(index, pd.MultiIndex) and not index.is_unique: + raise ValueError( + "cannot attach a non-unique MultiIndex and convert into xarray" + ) + arrays = [ + (tbl.column_names[n], np.asarray(tbl.column(n))) + for n in range(len(tbl.column_names)) + ] + result = cls() + if isinstance(index, pd.MultiIndex): + dims = tuple( + name if name is not None else "level_%i" % n + for n, name in enumerate(index.names) + ) + for dim, lev in zip(dims, index.levels): + result[dim] = (dim, lev) + else: + index_name = index.name if index.name is not None else "index" + dims = (index_name,) + result[index_name] = (dims, index) + + result._set_numpy_data_from_dataframe(index, arrays, dims) + return result + + @classmethod + def from_omx( + cls, omx, index_names=("otaz", "dtaz"), indexes="one-based", renames=None, + ): + # handle both larch.OMX and openmatrix.open_file versions + if "larch" in type(omx).__module__: + omx_data = omx.data + omx_shape = omx.shape + else: + omx_data = omx.root["data"] + omx_shape = omx.shape() + + arrays = {} + if renames is None: + for k in omx_data._v_children: + arrays[k] = omx_data[k][:] + elif isinstance(renames, dict): + for new_k, old_k in renames.items(): + arrays[new_k] = omx_data[old_k][:] + else: + for k in renames: + arrays[k] = omx_data[k][:] + d = { + "dims": index_names, + "data_vars": {k: {"dims": index_names, "data": arrays[k]} for k in arrays}, + } + if indexes == "one-based": + indexes = { + index_names[0]: one_based(omx_shape[0]), + index_names[1]: one_based(omx_shape[1]), + } + elif indexes == "zero-based": + indexes = { + index_names[0]: zero_based(omx_shape[0]), + index_names[1]: zero_based(omx_shape[1]), + } + if indexes is not None: + d["coords"] = { + index_name: {"dims": index_name, "data": index} + for index_name, index in indexes.items() + } + return cls.from_dict(d) + + @classmethod + def from_amx( + cls, amx, index_names=("otaz", "dtaz"), indexes="one-based", renames=None, + ): + arrays = {} + if renames is None: + for k in amx.list_matrices(): + arrays[k] = amx[k][:] + elif isinstance(renames, dict): + for new_k, old_k in renames.items(): + arrays[new_k] = amx[old_k] + else: + for k in renames: + arrays[k] = amx[k] + d = { + "dims": index_names, + "data_vars": {k: {"dims": index_names, "data": arrays[k]} for k in arrays}, + } + if indexes == "one-based": + indexes = {index_names[i]: "1" for i in range(len(index_names))} + elif indexes == "zero-based": + indexes = {index_names[i]: "0" for i in range(len(index_names))} + if isinstance(indexes, (list, tuple)): + indexes = dict(zip(index_names, indexes)) + if isinstance(indexes, dict): + for n, i in enumerate(index_names): + if indexes.get(i) == "1": + indexes[i] = one_based(amx.shape[n]) + elif indexes.get(i) == "0": + indexes[i] = zero_based(amx.shape[n]) + if indexes is not None: + d["coords"] = { + index_name: {"dims": index_name, "data": index} + for index_name, index in indexes.items() + } + return cls.from_dict(d) + + @classmethod + def from_zarr(cls, store, *args, **kwargs): + return cls(xr.open_zarr(store, *args, **kwargs)) + + def to_zarr(self, *args, **kwargs): + """ + Write dataset contents to a zarr group. + + Parameters + ---------- + store : MutableMapping, str or Path, optional + Store or path to directory in file system. If given with a + ".zarr.zip" extension, and keyword arguments limited to 'mode' and + 'compression', then a ZipStore will be created, populated, and then + immediately closed. + chunk_store : MutableMapping, str or Path, optional + Store or path to directory in file system only for Zarr array chunks. + Requires zarr-python v2.4.0 or later. + mode : {"w", "w-", "a", None}, optional + Persistence mode: "w" means create (overwrite if exists); + "w-" means create (fail if exists); + "a" means override existing variables (create if does not exist). + If ``append_dim`` is set, ``mode`` can be omitted as it is + internally set to ``"a"``. Otherwise, ``mode`` will default to + `w-` if not set. + synchronizer : object, optional + Zarr array synchronizer. + group : str, optional + Group path. (a.k.a. `path` in zarr terminology.) + encoding : dict, optional + Nested dictionary with variable names as keys and dictionaries of + variable specific encodings as values, e.g., + ``{"my_variable": {"dtype": "int16", "scale_factor": 0.1,}, ...}`` + compute : bool, optional + If True write array data immediately, otherwise return a + ``dask.delayed.Delayed`` object that can be computed to write + array data later. Metadata is always updated eagerly. + consolidated : bool, optional + If True, apply zarr's `consolidate_metadata` function to the store + after writing metadata. + append_dim : hashable, optional + If set, the dimension along which the data will be appended. All + other dimensions on overriden variables must remain the same size. + region : dict, optional + Optional mapping from dimension names to integer slices along + dataset dimensions to indicate the region of existing zarr array(s) + in which to write this dataset's data. For example, + ``{'x': slice(0, 1000), 'y': slice(10000, 11000)}`` would indicate + that values should be written to the region ``0:1000`` along ``x`` + and ``10000:11000`` along ``y``. + + Two restrictions apply to the use of ``region``: + + - If ``region`` is set, _all_ variables in a dataset must have at + least one dimension in common with the region. Other variables + should be written in a separate call to ``to_zarr()``. + - Dimensions cannot be included in both ``region`` and + ``append_dim`` at the same time. To create empty arrays to fill + in with ``region``, use a separate call to ``to_zarr()`` with + ``compute=False``. See "Appending to existing Zarr stores" in + the reference documentation for full details. + compression : int, optional + Only used for ".zarr.zip" files. By default zarr uses blosc + compression for chunks, so adding another layer of compression here + is typically redundant. + + References + ---------- + https://zarr.readthedocs.io/ + + Notes + ----- + Zarr chunking behavior: + If chunks are found in the encoding argument or attribute + corresponding to any DataArray, those chunks are used. + If a DataArray is a dask array, it is written with those chunks. + If not other chunks are found, Zarr uses its own heuristics to + choose automatic chunk sizes. + """ + if ( + len(args) == 1 + and isinstance(args[0], str) + and args[0].endswith(".zarr.zip") + ): + if {"compression", "mode"}.issuperset(kwargs.keys()): + import zarr + + with zarr.ZipStore(args[0], **kwargs) as store: + self.to_zarr(store) + return + return super().to_zarr(*args, **kwargs) + + def iat(self, *, _names=None, _load=False, _index_name=None, **idxs): + loaders = {} + if _index_name is None: + _index_name = "index" + for k, v in idxs.items(): + loaders[k] = xr.DataArray(v, dims=[_index_name]) + if _names: + ds = self[_names] + else: + ds = self + if _load: + ds = ds.load() + return ds.isel(**loaders) + + def at(self, *, _names=None, _load=False, _index_name=None, **idxs): + loaders = {} + if _index_name is None: + _index_name = "index" + for k, v in idxs.items(): + loaders[k] = xr.DataArray(v, dims=[_index_name]) + if _names: + ds = self[_names] + else: + ds = self + if _load: + ds = ds.load() + return ds.sel(**loaders) + + def at_df(self, df): + """ + Extract values by label on the coordinates indicated by columns of a DataFrame. + + Parameters + ---------- + df : pd.DataFrame or Mapping[str, array-like] + The columns (or keys) of `df` should match the named dimensions of + this Dataset. The resulting extracted DataFrame will have one row + per row of `df`, columns matching the data variables in this dataset, + and each value is looked up by the labels. + + Returns + ------- + pd.DataFrame + """ + result = self.at(**df).reset_coords(drop=True).to_dataframe() + if isinstance(df, pd.DataFrame): + result.index = df.index + return result + + def iat_df(self, df): + """ + Extract values by position on the coordinates indicated by columns of a DataFrame. + + Parameters + ---------- + df : pd.DataFrame or Mapping[str, array-like] + The columns (or keys) of `df` should match the named dimensions of + this Dataset. The resulting extracted DataFrame will have one row + per row of `df`, columns matching the data variables in this dataset, + and each value is looked up by the positions. + + Returns + ------- + pd.DataFrame + """ + result = self.iat(**df).reset_coords(drop=True).to_dataframe() + if isinstance(df, pd.DataFrame): + result.index = df.index + return result + + def select_and_rename(self, name_dict=None, **names): + """ + Select and rename variables from this Dataset + + Parameters + ---------- + name_dict, **names: dict + The keys or keyword arguments give the current names of the + variables that will be selected out of this Dataset. The values + give the new names of the same variables in the resulting Dataset. + + Returns + ------- + Dataset + """ + if name_dict is None: + name_dict = names + else: + name_dict.update(names) + return self[list(name_dict.keys())].rename(name_dict) + + def squash_index(self, indexes_dict=None, *, set_match_names=True, **indexes): + if indexes_dict is None: + indexes_dict = indexes + else: + indexes_dict.update(indexes) + ds = self.reset_index(list(indexes_dict.keys()), drop=True) + ds = ds.rename(**indexes_dict) + if set_match_names: + ds = ds.set_match_names({v: v for v in indexes_dict.values()}) + return ds + + def _repr_html_(self): + html = super()._repr_html_() + html = html.replace("xarray.Dataset", "sharrow.Dataset") + return html + + def __repr__(self): + r = super().__repr__() + r = r.replace("xarray.Dataset", "sharrow.Dataset") + return r + + @property + def match_names(self): + """ + A mapping + + If a match_name target begins with an '@', the match is a dynamic + match, where the particular index-position values are created based + on data in the main or other source[s]. This allows for match columns + that do not exist yet, including columns where the key column exists + but is a label-based or offset-based match that needs to be processed + into index-position values. + + """ + result = {} + for k in self.attrs.keys(): + if k.startswith("match_names_"): + result[k[12:]] = self.attrs.get(k) + for k in self.indexes.keys(): + if k not in result: + result[k] = None + return result + + @match_names.setter + def match_names(self, names): + if names is None: + existing_match_name_keys = list(self.match_names.keys()) + for k in existing_match_name_keys: + del self.attrs[k] + return + if isinstance(names, str): + dims = list(self.dims.keys()) + assert len(dims) == 1 + names = {dims[0]: names} + for k in names.keys(): + if k not in self.dims: + raise ValueError(f"'{k}' not in dims") + for k, v in names.items(): + if v is not None: + self.attrs[f"match_names_{k}"] = v + elif f"match_names_{k}" in self.attrs: + del self.attrs[f"match_names_{k}"] + + def set_match_names(self, names): + """ + Create a copy of this dataset with the given match_names for flowing. + + Parameters + ---------- + names : Sequence[str] or Mapping[str,str] + + Returns + ------- + sharrow.shared.Dataset + """ + result = self.copy() + result.match_names = names + return result + + def keep_dims(self, keep_dims, *, errors="raise"): + """ + Keep only certain dimensions and associated variables from this dataset. + + Parameters + ---------- + keep_dims : hashable or iterable of hashable + Dimension or dimensions to keep. + errors : {"raise", "ignore"}, optional + If 'raise' (default), raises a ValueError error if any of the + dimensions passed are not in the dataset. If 'ignore', any given + labels that are in the dataset are dropped and no error is raised. + + Returns + ------- + obj : Dataset + The dataset without the given dimensions (or any variables + containing those dimensions) + errors : {"raise", "ignore"}, optional + If 'raise' (default), raises a ValueError error if + any of the dimensions passed are not + in the dataset. If 'ignore', any given dimensions that are in the + dataset are dropped and no error is raised. + """ + if isinstance(keep_dims, str): + keep_dims = {keep_dims} + else: + keep_dims = set(keep_dims) + all_dims = set(self.dims) + if errors == "raise": + missing_dims = keep_dims - all_dims + if missing_dims: + raise ValueError( + "Dataset does not contain the dimensions: %s" % missing_dims + ) + return self.drop_dims([i for i in all_dims if i not in keep_dims]) diff --git a/src/Mode-Dest-TOD/sharrow/sharrow/interface.py b/src/Mode-Dest-TOD/sharrow/sharrow/interface.py new file mode 100644 index 0000000..f8fcd92 --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/sharrow/interface.py @@ -0,0 +1,90 @@ +import os +import sys +import importlib +import hashlib +import base64 +import pandas as pd +import pyarrow as pa +import xarray as xr + +from .dataset import Dataset + + +class SharedData: + def __init__( + self, main=None, extra_funcs=(), extra_vars=None, **datasets, + ): + """ + SharedData establishes a domain to evaluate data flows. + + Parameters + ---------- + main : Dataset or Table or DataFrame or Sequence[str], optional + This is the main set of data that defines this object. + Only the main data can be replaced with similarly formatted + other data when flowing results. + **datasets : Dict[str, Dataset] + Other `Dataset` inputs for flowing data can be provided. + The flow closes on any other data (i.e. it is immutable and cannot + be replaced when flowing). Although "main" can be certain non-Dataset + types (i.e. a DataFrame or a Table), datasets must be + given as `Dataset` objects with appropriate `match_names` set. + """ + self.main = main + self.datasets = datasets + try: + from sharrow_pro import Table + except ImportError: + table_types = (pa.Table,) + else: + table_types = (pa.Table, Table) + for k in self.datasets: + arr = self.datasets[k] + if not isinstance(arr, Dataset): + if isinstance(arr, pd.DataFrame): + arr = Dataset.from_dataframe(arr) + elif isinstance(arr, table_types): + arr = Dataset.from_table(arr) + elif isinstance(arr, xr.Dataset): + arr = Dataset(arr) + self.datasets[k] = arr + + def setup_flow( + self, definition_spec, cache_dir, name, dtype="float32", + ): + """ + + Parameters + ---------- + definition_spec : Dict[str,str] + Gives the names and definitions for the columns to + create in our generated table. + + Returns + ------- + module + """ + if not os.path.isdir(cache_dir): + raise NotADirectoryError(cache_dir) + if not os.path.isdir(os.path.join(cache_dir, name)): + raise ModuleNotFoundError(name) + if not os.path.isfile(os.path.join(cache_dir, name, "__init__.py")): + raise ModuleNotFoundError(name) + + sys.path.insert(0, str(cache_dir)) + importlib.invalidate_caches() + module = importlib.import_module(name) + sys.path = sys.path[1:] + module.set_shared_data(**self.datasets) + + if definition_spec and hasattr(module, 'defs_hash'): + defs_hash = hashlib.md5() + for k, v in definition_spec.items(): + defs_hash.update(k.encode("utf8")) + defs_hash.update(v.encode("utf8")) + if module.defs_hash != (base64.b32encode(defs_hash.digest())).decode(): + raise ValueError( + "definitions are not consistent with precompiled data flows" + ) + + return module diff --git a/src/Mode-Dest-TOD/sharrow/sharrow/local_dir.py b/src/Mode-Dest-TOD/sharrow/sharrow/local_dir.py new file mode 100644 index 0000000..cc40ffd --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/sharrow/local_dir.py @@ -0,0 +1,6 @@ +import os +import inspect + + +def local_cache(dirname="__sc"): + return os.path.join(os.path.dirname(inspect.stack()[1][1]), dirname,) diff --git a/src/Mode-Dest-TOD/sharrow/sharrow/logging.py b/src/Mode-Dest-TOD/sharrow/sharrow/logging.py new file mode 100644 index 0000000..c3bb39f --- /dev/null +++ b/src/Mode-Dest-TOD/sharrow/sharrow/logging.py @@ -0,0 +1,142 @@ +import logging +import sys +from contextlib import contextmanager +import time + +LOGGER_NAME = "SHARROW" +FILE_LOG_FORMAT = "%(name)s.%(levelname)s: %(message)s" +CONSOLE_LOG_FORMAT = "[%(asctime)s] %(name)s.%(levelname)s: %(message)s" +DEFAULT_LOG_LEVEL = logging.DEBUG + + +def timesize_single(t): + if t < 60: + return f"{t:.2f}s" + elif t < 3600: + return f"{t / 60:.2f}m" + elif t < 86400: + return f"{t / 3600:.2f}h" + else: + return f"{t / 86400:.2f}d" + + +def timesize_stack(t): + if t < 60: + return f"{t:.2f}s" + elif t < 3600: + return f"{t // 60:.0f}m {timesize_stack(t % 60)}" + elif t < 86400: + return f"{t // 3600:.0f}h {timesize_stack(t % 3600)}" + else: + return f"{t // 86400:.0f}d {timesize_stack(t % 86400)}" + + +def log_to_console(level=None): + if level is None: + level = DEFAULT_LOG_LEVEL + + logger = logging.getLogger(LOGGER_NAME) + + # avoid creation of multiple stream handlers for logging to console + for entry in logger.handlers: + if (isinstance(entry, logging.StreamHandler)) and ( + entry.formatter._fmt == CONSOLE_LOG_FORMAT + ): + return logger + + console_handler = logging.StreamHandler(stream=sys.stderr) + console_handler.setLevel(level) + console_handler.setFormatter(logging.Formatter(CONSOLE_LOG_FORMAT)) + logger.addHandler(console_handler) + if level < logger.getEffectiveLevel(): + logger.setLevel(level) + + return logger + + +def log_to_file(filename, level=None): + if level is None: + level = DEFAULT_LOG_LEVEL + + logger = logging.getLogger(LOGGER_NAME) + + # avoid creation of multiple file handlers for logging to the same file + for entry in logger.handlers: + if (isinstance(entry, logging.FileHandler)) and ( + entry.baseFilename == filename + ): + return logger + + file_handler = logging.FileHandler(filename) + file_handler.setLevel(level) + file_handler.setFormatter(logging.Formatter(FILE_LOG_FORMAT)) + logger.addHandler(file_handler) + + return logger + + +logger = log = log_to_console() + + +@contextmanager +def timing_log(label=""): + start_time = time.time() + log.critical(f"
GvNRh}tfSiy-@C7jK10 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

p1HTKwF76B8k@aELSsCkWb%0FMqe6m~9WJ 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≪F!Tde2a25=W1Os*tPvS@Sh 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

T|>o#Ml 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

Y{@GQM&ZSP-p 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