diff --git a/.gitignore b/.gitignore index 7e3359492..c2247e646 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ src/main/python/reporting/abm_reports*/* **/bin/**/* *.user *.pyc +*.hubstorinfo diff --git a/src/main/java/org/sandag/abm/airport/AirportDestChoiceModel.java b/src/main/java/org/sandag/abm/airport/AirportDestChoiceModel.java index b955ec3c3..bc3e6677a 100644 --- a/src/main/java/org/sandag/abm/airport/AirportDestChoiceModel.java +++ b/src/main/java/org/sandag/abm/airport/AirportDestChoiceModel.java @@ -20,7 +20,7 @@ public class AirportDestChoiceModel { - + private double[][] sizeTerms; // by // segment, // tazNumber @@ -390,7 +390,7 @@ public void calculateTazProbabilities(AirportDmuFactoryIf dmuFactory) * Random number * @return The chosen MGRA number */ - public int chooseMGRA(int purpose, int income, double randomNumber) + public int chooseMGRA(int purpose, int income, AirportParty party) { // first find a TAZ @@ -399,9 +399,10 @@ public int chooseMGRA(int purpose, int income, double randomNumber) double[] tazCumProb = tazProbabilities[segment]; double altProb = 0; double cumProb = 0; + double random = party.getRandom(); for (int i = 0; i < tazCumProb.length; ++i) { - if (tazCumProb[i] > randomNumber) + if (tazCumProb[i] > random) { alt = i; if (i != 0) @@ -427,14 +428,18 @@ public int chooseMGRA(int purpose, int income, double randomNumber) // mgra probabilities need to be scaled by the alternatives probability int mgraNumber = 0; double[] mgraCumProb = mgraProbabilities[segment][tazNumber]; + random = party.getRandom(); // get a new random number for mgra, instead of using the same one from taz for (int i = 0; i < mgraCumProb.length; ++i) { - cumProb += mgraCumProb[i] * altProb; - if (cumProb > randomNumber) + // cumProb += mgraCumProb[i] * altProb; + cumProb = mgraCumProb[i]; + if (cumProb > random) { mgraNumber = mgraArray[i]; + break; } } + // return the chosen MGRA number return mgraNumber; } @@ -448,17 +453,19 @@ public int chooseMGRA(int purpose, int income, double randomNumber) */ public void chooseOrigins(AirportParty[] airportParties) { - - // iterate through the array, choosing mgras and setting them + // iterate through the array, choosing mgras and setting them for (AirportParty party : airportParties) { - + int income = party.getIncome(); int purpose = party.getPurpose(); - double random = party.getRandom(); int mgra = -99; + if (purpose == AirportModelStructure.EMPLOYEE) + { + continue; + } if (purpose < AirportModelStructure.INTERNAL_PURPOSES) - mgra = chooseMGRA(purpose, income, random); + mgra = chooseMGRA(purpose, income, party); // if this is a departing travel party, the origin is the chosen // mgra, and the destination is the airport terminal diff --git a/src/main/java/org/sandag/abm/airport/AirportModeChoiceModel.java b/src/main/java/org/sandag/abm/airport/AirportModeChoiceModel.java index 3504a9181..5f320d28b 100644 --- a/src/main/java/org/sandag/abm/airport/AirportModeChoiceModel.java +++ b/src/main/java/org/sandag/abm/airport/AirportModeChoiceModel.java @@ -1,15 +1,18 @@ package org.sandag.abm.airport; import java.util.HashMap; + import org.apache.log4j.Logger; import org.sandag.abm.accessibilities.BestTransitPathCalculator; import org.sandag.abm.accessibilities.DriveTransitWalkSkimsCalculator; import org.sandag.abm.accessibilities.WalkTransitDriveSkimsCalculator; import org.sandag.abm.accessibilities.WalkTransitWalkSkimsCalculator; +import org.sandag.abm.application.SandagModelStructure; import org.sandag.abm.ctramp.CtrampApplication; import org.sandag.abm.ctramp.Util; import org.sandag.abm.modechoice.MgraDataManager; import org.sandag.abm.modechoice.TazDataManager; + import com.pb.common.calculator.VariableTable; import com.pb.common.newmodel.ChoiceModelApplication; import com.pb.common.util.Tracer; @@ -21,11 +24,13 @@ public class AirportModeChoiceModel private TazDataManager tazManager; private MgraDataManager mgraManager; - private ChoiceModelApplication driveAloneModel; - private ChoiceModelApplication shared2Model; - private ChoiceModelApplication shared3Model; + private ChoiceModelApplication[] driveAloneModel; + private ChoiceModelApplication[] shared2Model; + private ChoiceModelApplication[] shared3Model; private ChoiceModelApplication transitModel; private ChoiceModelApplication accessModel; + private ChoiceModelApplication mgraModel; + private ChoiceModelApplication rideHailModel; private Tracer tracer; private boolean trace; @@ -38,6 +43,9 @@ public class AirportModeChoiceModel protected WalkTransitWalkSkimsCalculator wtw; protected WalkTransitDriveSkimsCalculator wtd; protected DriveTransitWalkSkimsCalculator dtw; + + private boolean debugChoiceModel; + private int debugPartyID; /** * Constructor @@ -73,24 +81,46 @@ public AirportModeChoiceModel(HashMap rbMap, AirportDmuFactoryIf "airport.mc.transit.page")); int accessPage = Integer.parseInt(Util.getStringValueFromPropertyMap(rbMap, "airport.mc.accessMode.page")); + int mgraPage = Integer.parseInt(Util.getStringValueFromPropertyMap(rbMap, + "airport.mc.mgra.page")); + int rideHailPage = Integer.parseInt(Util.getStringValueFromPropertyMap(rbMap, + "airport.mc.ridehail.page")); logger.info("Creating Airport Model Mode Choice Application UECs"); // create a DMU AirportModelDMU dmu = dmuFactory.getAirportModelDMU(); - // create a ChoiceModelApplication object for drive-alone mode choice - driveAloneModel = new ChoiceModelApplication(airportModeUecFileName, daPage, dataPage, + // get MAX mgra to initialize mgra size array in dmu + int maxMgra = mgraManager.getMaxMgra(); + dmu.setMaxMgra(maxMgra); + + // fake choice model to get airport access MGRA input + mgraModel = new ChoiceModelApplication(airportModeUecFileName, mgraPage, dataPage, + rbMap, (VariableTable) dmu); + + solveModeMgra(dmu); + + // create ChoiceModelApplication objects for each airport mgra + driveAloneModel = new ChoiceModelApplication[dmu.mgra_index_map.size()]; + shared2Model = new ChoiceModelApplication[dmu.mgra_index_map.size()]; + shared3Model = new ChoiceModelApplication[dmu.mgra_index_map.size()]; + + for (int i = 0; i < dmu.mgra_index_map.size(); i++){ + // create a ChoiceModelApplication object for drive-alone mode choice + driveAloneModel[i] = new ChoiceModelApplication(airportModeUecFileName, daPage, dataPage, + rbMap, (VariableTable) dmu); + // create a ChoiceModelApplication object for shared 2 mode choice + shared2Model[i] = new ChoiceModelApplication(airportModeUecFileName, s2Page, dataPage, + rbMap, (VariableTable) dmu); + // create a ChoiceModelApplication object for shared 3+ mode choice + shared3Model[i] = new ChoiceModelApplication(airportModeUecFileName, s3Page, dataPage, + rbMap, (VariableTable) dmu); + } + + rideHailModel = new ChoiceModelApplication(airportModeUecFileName, rideHailPage, dataPage, rbMap, (VariableTable) dmu); - - // create a ChoiceModelApplication object for shared 2 mode choice - shared2Model = new ChoiceModelApplication(airportModeUecFileName, s2Page, dataPage, rbMap, - (VariableTable) dmu); - - // create a ChoiceModelApplication object for shared 3+ mode choice - shared3Model = new ChoiceModelApplication(airportModeUecFileName, s3Page, dataPage, rbMap, - (VariableTable) dmu); - + // create a ChoiceModelApplication object for transit mode choice transitModel = new ChoiceModelApplication(airportModeUecFileName, transitPage, dataPage, rbMap, (VariableTable) dmu); @@ -119,7 +149,19 @@ public AirportModeChoiceModel(HashMap rbMap, AirportDmuFactoryIf } } seek = Util.getBooleanValueFromPropertyMap(rbMap, "Seek"); + + if (Util.getStringValueFromPropertyMap(rbMap,"airport.debug") != "") + { + debugChoiceModel = Util.getBooleanValueFromPropertyMap(rbMap, "airport.debug"); + debugPartyID = Integer.parseInt(Util.getStringValueFromPropertyMap(rbMap, + "airport.debug.party.id")); + } + else + { + debugChoiceModel = false; + debugPartyID = -99; + } } /** @@ -142,6 +184,27 @@ public void initializeBestPathCalculators() logger.info("Finished Initializing Airport Model Best Path Calculators"); } + + /** + * get access mode MGRA from UEC user input + */ + public void solveModeMgra(AirportModelDMU dmu){ + mgraModel.computeUtilities(dmu, dmu.getDmuIndex()); + + int modeCount = mgraModel.getNumberOfAlternatives(); + double[] mgraValues = mgraModel.getUtilities(); + + HashMap modeMgraMap = new HashMap(); + + for (int m = 0; m < modeCount; m++){ + int mgraValue = (int)Math.round(mgraValues[m]); + modeMgraMap.put(m+1, mgraValue); + } + + dmu.setModeMgraMap(modeMgraMap); + dmu.setMgraIndexMap(); + dmu.setTravelTimeArraySize(); + } /** * Choose airport arrival mode and trip mode for this party. Store results @@ -157,8 +220,23 @@ public void chooseMode(AirportParty party, AirportModelDMU dmu) int origMgra = party.getOriginMGRA(); int destMgra = party.getDestinationMGRA(); + int direction = party.getDirection(); + int airportMgra = 0; + int airportMgra_index = 0; + int nonAirportMgra = 0; + int accessOrigMgra = 0; + int accessDestMgra = 0; + int accessOrigTaz = 0; + int accessDestTaz = 0; + if (direction == 0){ //departure + nonAirportMgra = origMgra; + } else { //arrival + nonAirportMgra = destMgra; + } + dmu.setNonAirportMgra(nonAirportMgra); + dmu.setDirection(direction); int origTaz = mgraManager.getTaz(origMgra); - int destTaz = mgraManager.getTaz(destMgra); + int destTaz = mgraManager.getTaz(destMgra); int period = party.getDepartTime(); int skimPeriod = AirportModelStructure.getSkimPeriodIndex(period) + 1; // The // skims @@ -172,6 +250,12 @@ public void chooseMode(AirportParty party, AirportModelDMU dmu) int[][] walkTransitTapPairs = wtw.getBestTapPairs(origMgra, destMgra, skimPeriod, debug, logger); party.setBestWtwTapPairs(walkTransitTapPairs); + + if (party.getPurpose() == AirportModelStructure.EMPLOYEE) + { + party.setAPtoTermBestWtwTapPairs(walkTransitTapPairs); + return; + } // drive transit tap pairs depend on direction; departing parties use // drive-transit-walk, else walk-transit-drive is used. @@ -194,69 +278,177 @@ public void chooseMode(AirportParty party, AirportModelDMU dmu) if (party.getDirection() == AirportModelStructure.ARRIVAL) inbound = true; dmu.setAirportParty(party); - dmu.setDmuIndexValues(party.getID(), origTaz, destTaz); + dmu.setDmuSkimAttributes(origMgra, destMgra, period, inbound, debug); // Solve trip mode level utilities - - // if 1-person party, solve for the drive-alone and 2-person logsums - if (party.getSize() == 1) + + for (int mode = 1; mode <= AirportModelStructure.ACCESS_MODES; mode++) { - driveAloneModel.computeUtilities(dmu, dmu.getDmuIndex()); - double driveAloneLogsum = driveAloneModel.getLogsum(); - dmu.setDriveAloneLogsum(driveAloneLogsum); - - shared2Model.computeUtilities(dmu, dmu.getDmuIndex()); - double shared2Logsum = shared2Model.getLogsum(); - dmu.setShared2Logsum(shared2Logsum); - - } else if (party.getSize() == 2) - { // if 2-person party solve for the - // shared 2 and shared 3+ logsums - shared2Model.computeUtilities(dmu, dmu.getDmuIndex()); - double shared2Logsum = shared2Model.getLogsum(); - dmu.setShared2Logsum(shared2Logsum); - - shared3Model.computeUtilities(dmu, dmu.getDmuIndex()); - double shared3Logsum = shared3Model.getLogsum(); - dmu.setShared3Logsum(shared3Logsum); - - } else - { // if 3+ person party, solve the shared 3+ logsums - shared3Model.computeUtilities(dmu, dmu.getDmuIndex()); - double shared3Logsum = shared3Model.getLogsum(); - dmu.setShared3Logsum(shared3Logsum); + airportMgra = dmu.mode_mgra_map.get(mode); + + airportMgra_index = dmu.mgra_index_map.get(airportMgra); + + if (airportMgra == -999) + { + continue; + } + + if (direction == 0){ //departure + accessOrigMgra = nonAirportMgra; + accessDestMgra = airportMgra; + } else { //arrival + accessOrigMgra = airportMgra; + accessDestMgra = nonAirportMgra; + } + + accessOrigTaz = mgraManager.getTaz(accessOrigMgra); + accessDestTaz = mgraManager.getTaz(accessDestMgra); + + dmu.setDmuIndexValues(party.getID(), accessOrigTaz, accessDestTaz); // should this be access point Taz? + + for (int los = 0; los < AirportModelStructure.LOS_TYPE; los++) + { + double travelTime = dmu.getModeTravelTime(nonAirportMgra, airportMgra_index, direction, los); + if (travelTime == 0) + { + if (los == AirportModelStructure.DA){ + driveAloneModel[airportMgra_index].computeUtilities(dmu, dmu.getDmuIndex()); + double driveAloneLogsum = driveAloneModel[airportMgra_index].getLogsum(); + dmu.setModeTravelTime(nonAirportMgra, airportMgra_index, direction, los, driveAloneLogsum); + } + else if (los == AirportModelStructure.SR2){ + shared2Model[airportMgra_index].computeUtilities(dmu, dmu.getDmuIndex()); + double shared2Logsum = shared2Model[airportMgra_index].getLogsum(); + dmu.setModeTravelTime(nonAirportMgra, airportMgra_index, direction, los, shared2Logsum); + } + else if (los == AirportModelStructure.SR3){ + shared3Model[airportMgra_index].computeUtilities(dmu, dmu.getDmuIndex()); + double shared3Logsum = shared3Model[airportMgra_index].getLogsum(); + dmu.setModeTravelTime(nonAirportMgra, airportMgra_index, direction, los, shared3Logsum); + } + } + } + + if (mode == AirportModelStructure.RIDEHAILING_LOC1) + { + rideHailModel.computeUtilities(dmu, dmu.getDmuIndex()); + dmu.setRidehailTravelDistanceLocation1(rideHailModel.getUtilities()[1]); + dmu.setRidehailTravelTimeLocation1(rideHailModel.getUtilities()[0]); + } + + if (mode == AirportModelStructure.RIDEHAILING_LOC2) + { + rideHailModel.computeUtilities(dmu, dmu.getDmuIndex()); + dmu.setRidehailTravelDistanceLocation2(rideHailModel.getUtilities()[1]); + dmu.setRidehailTravelTimeLocation2(rideHailModel.getUtilities()[0]); + } + } - // always solve for the transit logsum - transitModel.computeUtilities(dmu, dmu.getDmuIndex()); + + dmu.setDmuIndexValues(party.getID(), origTaz, destTaz); + transitModel.computeUtilities(dmu, dmu.getDmuIndex()); double transitLogsum = transitModel.getLogsum(); - dmu.setTransitLogsum(transitLogsum); - + dmu.setModeTravelTime(nonAirportMgra, airportMgra_index, direction, AirportModelStructure.Transit, transitLogsum); + // calculate access mode utility and choose access mode accessModel.computeUtilities(dmu, dmu.getDmuIndex()); int accessMode = accessModel.getChoiceResult(party.getRandom()); party.setArrivalMode((byte) accessMode); + + int airportAccessMGRA = dmu.mode_mgra_map.get(accessMode); + + if (accessMode == AirportModelStructure.SHUTTLE_VAN | accessMode == AirportModelStructure.HOTEL_COURTESY) + { + double terminal_logsum = 0; + double cmh_logsum = 0; + int size = party.getSize(); + if (size == 1) + { + terminal_logsum = dmu.getShared2LogsumHotelOrShuttleTerminal(); + cmh_logsum = dmu.getShared2LogsumHotelOrShuttleCentralMobilityHub(); + } + else + { + terminal_logsum = dmu.getShared3LogsumHotelOrShuttleTerminal(); + cmh_logsum = dmu.getShared3LogsumHotelOrShuttleCentralMobilityHub(); + } + + if (terminal_logsum >= cmh_logsum) + { + airportAccessMGRA = dmu.mode_mgra_map.get(AirportModelStructure.MGRAAlt_TERM); + } + else + { + airportAccessMGRA = dmu.mode_mgra_map.get(AirportModelStructure.MGRAAlt_CMH); + } + } + + party.setAirportAccessMGRA(airportAccessMGRA); + // add debug + if (debugChoiceModel & party.getID() == debugPartyID) + { + String choiceModelDescription = ""; + String decisionMakerLabel = ""; + String loggingHeader = ""; + String separator = ""; + + choiceModelDescription = String.format( + "Airport Mode Choice Model for: Purpose=%s, OrigMGRA=%d, DestMGRA=%d", + party.getPurpose(), party.getOriginMGRA(), party.getDestinationMGRA()); + decisionMakerLabel = String.format("partyID=%d, partySize=%d, purpose=%s, direction=%d", + party.getID(), party.getSize(), + party.getPurpose(), party.getDirection()); + loggingHeader = String.format("%s %s", choiceModelDescription, + decisionMakerLabel); + + logger.info(loggingHeader); + driveAloneModel[2].logUECResults(logger); + accessModel.logUECResults(logger); + transitModel.logUECResults(logger); + } + // choose trip mode int tripMode = 0; int occupancy = AirportModelStructure.getOccupancy(accessMode, party.getSize()); double randomNumber = party.getRandom(); - + if (accessMode != AirportModelStructure.TRANSIT) { + int chosenAirportMgra_index = dmu.mgra_index_map.get(airportAccessMGRA); if (occupancy == 1) { - int choice = driveAloneModel.getChoiceResult(randomNumber); + int choice = driveAloneModel[chosenAirportMgra_index].getChoiceResult(randomNumber); tripMode = choice; } else if (occupancy == 2) { - int choice = shared2Model.getChoiceResult(randomNumber); - tripMode = choice + 2; + int choice = shared2Model[chosenAirportMgra_index].getChoiceResult(randomNumber); + tripMode = choice + 2; } else if (occupancy > 2) { - int choice = shared3Model.getChoiceResult(randomNumber); + int choice = shared3Model[chosenAirportMgra_index].getChoiceResult(randomNumber); tripMode = choice + 3 + 2; } + + if (airportAccessMGRA != dmu.getTerminalMgra()) + { + if (direction == 0) + { + int[][] walkTransitTapPairs_AP2Term = wtw.getBestTapPairs(airportAccessMGRA, dmu.getTerminalMgra(), skimPeriod, debug, + logger); + party.setAPtoTermBestWtwTapPairs(walkTransitTapPairs_AP2Term); + } + else + { + int[][] walkTransitTapPairs_AP2Term = wtw.getBestTapPairs(dmu.getTerminalMgra(), airportAccessMGRA, skimPeriod, debug, + logger); + party.setAPtoTermBestWtwTapPairs(walkTransitTapPairs_AP2Term); + } + } + + + } else { int choice = transitModel.getChoiceResult(randomNumber); @@ -264,6 +456,7 @@ public void chooseMode(AirportParty party, AirportModelDMU dmu) else tripMode = choice + 15; } party.setMode((byte) tripMode); + } /** @@ -274,20 +467,37 @@ public void chooseMode(AirportParty party, AirportModelDMU dmu) * @param dmuFactory * A DMU Factory. */ - public void chooseModes(AirportParty[] airportParties, AirportDmuFactoryIf dmuFactory) + public void chooseModes(HashMap rbMap, AirportParty[] airportParties, AirportDmuFactoryIf dmuFactory) { + this.rbMap = rbMap; + tazManager = TazDataManager.getInstance(rbMap); + mgraManager = MgraDataManager.getInstance(rbMap); + AirportModelDMU dmu = dmuFactory.getAirportModelDMU(); + + int maxMgra = mgraManager.getMaxMgra(); + dmu.setMaxMgra(maxMgra); + + solveModeMgra(dmu); + + int terminalMgra = Integer.parseInt(Util.getStringValueFromPropertyMap(rbMap, + "airport.airportMgra")); + + // set terminal Mgra + dmu.setTerminalMgra(terminalMgra); + // iterate through the array, choosing mgras and setting them for (AirportParty party : airportParties) { int ID = party.getID(); - + if ((ID <= 5) || (ID % 100) == 0) logger.info("Choosing mode for party " + party.getID()); + + if (party.getPurpose() < AirportModelStructure.INTERNAL_PURPOSES | party.getPurpose() == AirportModelStructure.EMPLOYEE) chooseMode(party, dmu); - if (party.getPurpose() < AirportModelStructure.INTERNAL_PURPOSES) chooseMode(party, dmu); else { party.setArrivalMode((byte) -99); diff --git a/src/main/java/org/sandag/abm/airport/AirportModel.java b/src/main/java/org/sandag/abm/airport/AirportModel.java index 78d58d623..bb0ffae22 100644 --- a/src/main/java/org/sandag/abm/airport/AirportModel.java +++ b/src/main/java/org/sandag/abm/airport/AirportModel.java @@ -60,7 +60,7 @@ public void runModel() AirportModeChoiceModel modeChoiceModel = new AirportModeChoiceModel(rbMap, dmuFactory); modeChoiceModel.initializeBestPathCalculators(); - modeChoiceModel.chooseModes(parties, dmuFactory); + modeChoiceModel.chooseModes(rbMap, parties, dmuFactory); apm.writeOutputFile(rbMap); diff --git a/src/main/java/org/sandag/abm/airport/AirportModelDMU.java b/src/main/java/org/sandag/abm/airport/AirportModelDMU.java index 268f36aa2..83958b240 100644 --- a/src/main/java/org/sandag/abm/airport/AirportModelDMU.java +++ b/src/main/java/org/sandag/abm/airport/AirportModelDMU.java @@ -1,7 +1,11 @@ package org.sandag.abm.airport; import java.io.Serializable; +import java.util.Arrays; import java.util.HashMap; +import java.util.Set; +import java.util.TreeSet; + import org.apache.log4j.Logger; import org.sandag.abm.accessibilities.BestTransitPathCalculator; import org.sandag.abm.accessibilities.DriveTransitWalkSkimsCalculator; @@ -9,6 +13,7 @@ import org.sandag.abm.accessibilities.WalkTransitWalkSkimsCalculator; import org.sandag.abm.common.ConditionalDMU; import org.sandag.abm.modechoice.Modes; + import com.pb.common.calculator.IndexValues; import com.pb.common.calculator.VariableTable; @@ -80,6 +85,16 @@ public class AirportModelDMU public static final int OUT = 0; public static final int IN = 1; protected static final int NUM_DIR = 2; + + protected int NUM_A_MGRA; + + protected static final int NUM_LOS = 4; + + private int nonAirportMgra; + public int terminalMgra; + + + private int direction; // estimation file defines time periods as: // 1 | Early AM: 3:00 AM - 5:59 AM | @@ -139,10 +154,22 @@ public class AirportModelDMU private double shared2Logsum; private double shared3Logsum; private double transitLogsum; + + private double ridehailTravelDistanceLocation1; + private double ridehailTravelDistanceLocation2; + private double ridehailTravelTimeLocation1; + private double ridehailTravelTimeLocation2; - protected double[][][] transitSkim = new double[NUM_ACC_EGR][NUM_LOC_PREM][NUM_SKIMS]; + protected double[][][] transitSkim = new double[NUM_ACC_EGR][NUM_LOC_PREM][NUM_SKIMS]; protected Logger _logger = null; + + protected double[][][][] travel_time; + + public int maxMgra; + + public HashMap mode_mgra_map = new HashMap(); + public HashMap mgra_index_map = new HashMap(); public AirportModelDMU(Logger logger) { @@ -174,8 +201,8 @@ private void setupMethodIndexMap() methodIndexMap.put("getDriveAloneLogsum", 90); methodIndexMap.put("getShared2Logsum", 91); methodIndexMap.put("getShared3Logsum", 92); - methodIndexMap.put("getTransitLogsum", 93); - + //methodIndexMap.put("getTransitLogsum", 93); + methodIndexMap.put("getWtw_lb_LB_ivt", 100); methodIndexMap.put("getWtw_lb_fwait", 101); methodIndexMap.put("getWtw_lb_xwait", 102); @@ -282,6 +309,51 @@ private void setupMethodIndexMap() methodIndexMap.put("getDt_cr_WalkAuxTime", 202); methodIndexMap.put("getDt_cr_fare", 203); methodIndexMap.put("getDt_cr_xfers", 204); + + methodIndexMap.put("getDriveAloneLogsumParkLocation1", 20); + methodIndexMap.put("getShared2LogsumParkLocation1", 21); + methodIndexMap.put("getShared3LogsumParkLocation1", 22); + methodIndexMap.put("getDriveAloneLogsumParkLocation2", 23); + methodIndexMap.put("getShared2LogsumParkLocation2", 24); + methodIndexMap.put("getShared3LogsumParkLocation2", 25); + methodIndexMap.put("getDriveAloneLogsumParkLocation3", 26); + methodIndexMap.put("getShared2LogsumParkLocation3", 27); + methodIndexMap.put("getShared3LogsumParkLocation3", 28); + methodIndexMap.put("getDriveAloneLogsumParkLocation4", 29); + methodIndexMap.put("getShared2LogsumParkLocation4", 30); + methodIndexMap.put("getShared3LogsumParkLocation4", 31); + methodIndexMap.put("getDriveAloneLogsumParkLocation5", 32); + methodIndexMap.put("getShared2LogsumParkLocation5", 33); + methodIndexMap.put("getShared3LogsumParkLocation5", 34); + methodIndexMap.put("getShared2LogsumParkEscort", 35); + methodIndexMap.put("getShared3LogsumParkEscort", 36); + methodIndexMap.put("getDriveAloneLogsumRental", 37); + methodIndexMap.put("getShared2LogsumRental", 38); + methodIndexMap.put("getShared3LogsumRental", 39); + methodIndexMap.put("getShared2LogsumHotelOrShuttleTerminal", 40); + methodIndexMap.put("getShared3LogsumHotelOrShuttleTerminal", 41); + methodIndexMap.put("getShared2LogsumHotelOrShuttleCentralMobilityHub", 42); + methodIndexMap.put("getShared3LogsumHotelOrShuttleCentralMobilityHub", 43); + methodIndexMap.put("getShared2LogsumRidehailLocation1", 44); + methodIndexMap.put("getShared3LogsumRidehailLocation1", 45); + methodIndexMap.put("getShared2LogsumRidehailLocation2", 46); + methodIndexMap.put("getShared3LogsumRidehailLocation2", 47); + methodIndexMap.put("getTransitLogsum", 48); + methodIndexMap.put("getShared2LogsumCurbLocation1", 49); + methodIndexMap.put("getShared3LogsumCurbLocation1", 50); + methodIndexMap.put("getShared2LogsumCurbLocation2", 51); + methodIndexMap.put("getShared3LogsumCurbLocation2", 52); + methodIndexMap.put("getShared2LogsumCurbLocation3", 53); + methodIndexMap.put("getShared3LogsumCurbLocation3", 54); + methodIndexMap.put("getShared2LogsumCurbLocation4", 55); + methodIndexMap.put("getShared3LogsumCurbLocation4", 56); + methodIndexMap.put("getShared2LogsumCurbLocation5", 57); + methodIndexMap.put("getShared3LogsumCurbLocation5", 58); + methodIndexMap.put("getRidehailTravelDistanceLocation1", 59); + methodIndexMap.put("getRidehailTravelDistanceLocation2", 60); + methodIndexMap.put("getRidehailTravelTimeLocation1", 61); + methodIndexMap.put("getRidehailTravelTimeLocation2", 62); + CreateReverseMap(); } @@ -315,6 +387,400 @@ public void setDmuSkimCalculators(WalkTransitWalkSkimsCalculator myWtw, dtw = myDtw; } + public int getNonAirportMgra() { + return nonAirportMgra; + } + + public void setNonAirportMgra(int nonAirportMgra) { + this.nonAirportMgra = nonAirportMgra; + } + + public int getTerminalMgra() { + return terminalMgra; + } + + public void setTerminalMgra(int terminalMgra) { + this.terminalMgra = terminalMgra; + } + + public void setDirection(int direction) { + this.direction = direction; + } + + public void setMaxMgra(int maxMgra) { + this.maxMgra = maxMgra; + } + + public void setModeMgraMap(HashMap modeMgraMap){ + mode_mgra_map = modeMgraMap; + } + + public void setMgraIndexMap(){ + Integer[] mgraValueArray = mode_mgra_map.values().toArray(new Integer[0]); + + Set uniqueMgraValues = new TreeSet(); + uniqueMgraValues.addAll(Arrays.asList(mgraValueArray)); + + Integer[] uniqueMgraValueArray = uniqueMgraValues.toArray(new Integer[0]); + + for (int i = 0; i < uniqueMgraValueArray.length; i++){ + mgra_index_map.put(uniqueMgraValueArray[i], i); + } + } + + public void setTravelTimeArraySize(){ + NUM_A_MGRA = mgra_index_map.size(); + travel_time = new double[maxMgra + 1][NUM_A_MGRA][NUM_DIR][NUM_LOS]; + } + + /** + * Set the mode travel time array value for the access/egress mode, line-haul + * mode, LOS component + * + * @param nonAirportMgra + * Index for nonairport mgra + * @param airportMgra_index + * Index for airport Mgra + * @param direction + * The index for direction + * @param los + * The los type + * @param value + * The value to set in the array + */ + protected void setModeTravelTime(int nonAirportMgra, int airportMgra_index, int direction, int los, double value) + { + travel_time[nonAirportMgra][airportMgra_index][direction][los] = value; + } + + /** + * Get the mode travel time array value for the access/egress mode, line-haul + * mode, LOS component + * + * @param nonAirportMgra + * Index for nonairport mgra + * @param airportMgra_index + * Index for airport Mgra + * @param direction + * The index for direction + * @param los + * The los type + * @return The travel time value + */ + protected double getModeTravelTime(int nonAirportMgra, int airportMgra_index, int direction, int los) + { + return travel_time[nonAirportMgra][airportMgra_index][direction][los]; + } + + public double getDriveAloneLogsumParkLocation1() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC1); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.DA]; + } + + public double getShared2LogsumParkLocation1() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC1); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumParkLocation1() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC1); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getDriveAloneLogsumParkLocation2() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC2); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.DA]; + } + + public double getShared2LogsumParkLocation2() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC2); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumParkLocation2() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC2); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getDriveAloneLogsumParkLocation3() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC3); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.DA]; + } + + public double getShared2LogsumParkLocation3() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC3); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumParkLocation3() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC3); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getDriveAloneLogsumParkLocation4() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC4); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.DA]; + } + + public double getShared2LogsumParkLocation4() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC4); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumParkLocation4() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC4); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getDriveAloneLogsumParkLocation5() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC5); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.DA]; + } + + public double getShared2LogsumParkLocation5() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC5); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumParkLocation5() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_LOC5); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumParkEscort() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_ESC); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumParkEscort() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.PARK_ESC); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getDriveAloneLogsumRental() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.RENTAL); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.DA]; + } + + public double getShared2LogsumRental() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.RENTAL); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumRental() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.RENTAL); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumHotelOrShuttleTerminal() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.MGRAAlt_TERM); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumHotelOrShuttleTerminal() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.MGRAAlt_TERM); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumHotelOrShuttleCentralMobilityHub() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.MGRAAlt_CMH); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumHotelOrShuttleCentralMobilityHub() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.MGRAAlt_CMH); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumRidehailLocation1() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.RIDEHAILING_LOC1); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumRidehailLocation1() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.RIDEHAILING_LOC1); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumRidehailLocation2() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.RIDEHAILING_LOC2); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumRidehailLocation2() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.RIDEHAILING_LOC2); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getTransitLogsum() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.TRANSIT); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.Transit]; + } + + public double getShared2LogsumCurbLocation1() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC1); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumCurbLocation1() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC1); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumCurbLocation2() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC2); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumCurbLocation2() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC2); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumCurbLocation3() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC3); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumCurbLocation3() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC3); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumCurbLocation4() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC4); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumCurbLocation4() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC4); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public double getShared2LogsumCurbLocation5() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC5); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR2]; + } + + public double getShared3LogsumCurbLocation5() + { + int airportMgra = mode_mgra_map.get(AirportModelStructure.CURB_LOC5); + int airportMgra_index = mgra_index_map.get(airportMgra); + return travel_time[nonAirportMgra][airportMgra_index][direction][AirportModelStructure.SR3]; + } + + public void setRidehailTravelDistanceLocation1(double ridehailTravelDistance) + { + ridehailTravelDistanceLocation1 = ridehailTravelDistance; + } + + public void setRidehailTravelDistanceLocation2(double ridehailTravelDistance) + { + ridehailTravelDistanceLocation2 = ridehailTravelDistance; + } + + public void setRidehailTravelTimeLocation1(double ridehailTravelTime) + { + ridehailTravelTimeLocation1 = ridehailTravelTime; + } + + public void setRidehailTravelTimeLocation2(double ridehailTravelTime) + { + ridehailTravelTimeLocation2 = ridehailTravelTime; + } + + public double getRidehailTravelDistanceLocation1() { + return ridehailTravelDistanceLocation1; + } + + public double getRidehailTravelDistanceLocation2() { + return ridehailTravelDistanceLocation2; + } + + public double getRidehailTravelTimeLocation1() { + return ridehailTravelTimeLocation1; + } + + public double getRidehailTravelTimeLocation2() { + return ridehailTravelTimeLocation2; + } + /** * Set the transit skim array value for the access/egress mode, line-haul * mode, LOS component @@ -1096,11 +1562,11 @@ public void setShared3Logsum(double shared3Logsum) /** * @return the transitLogsum */ - public double getTransitLogsum() +/* public double getTransitLogsum() { return transitLogsum; } - +*/ /** * @param transitLogsum * the transitLogsum to set diff --git a/src/main/java/org/sandag/abm/airport/AirportModelStructure.java b/src/main/java/org/sandag/abm/airport/AirportModelStructure.java index cc96a99d7..cdf16a6e1 100644 --- a/src/main/java/org/sandag/abm/airport/AirportModelStructure.java +++ b/src/main/java/org/sandag/abm/airport/AirportModelStructure.java @@ -3,12 +3,13 @@ public final class AirportModelStructure { - public static final byte PURPOSES = 5; + public static final byte PURPOSES = 6; // employee is not really in the choice model public static final byte RESIDENT_BUSINESS = 0; public static final byte RESIDENT_PERSONAL = 1; public static final byte VISITOR_BUSINESS = 2; public static final byte VISITOR_PERSONAL = 3; public static final byte EXTERNAL = 4; + public static final byte EMPLOYEE = 5; public static final byte INTERNAL_PURPOSES = 4; @@ -29,17 +30,43 @@ public final class AirportModelStructure public static final int UPPER_PM = 29; public static final String[] MODEL_PERIOD_LABELS = {"EA", "AM", "MD", "PM", "EV"}; - public static final byte ACCESS_MODES = 9; - - public static final byte PARK_TMNL = 1; - public static final byte PARK_SANOFF = 2; - public static final byte PARK_PVTOFF = 3; - public static final byte PUDO_ESC = 4; - public static final byte PUDO_CURB = 5; - public static final byte RENTAL = 6; - public static final byte TAXI = 7; - public static final byte SHUTTLE_VAN = 8; - public static final byte TRANSIT = 9; + public static final int ACCESS_MODES = 17; + + public static final int PARK_LOC1 = 1; + public static final int PARK_LOC2 = 2; + public static final int PARK_LOC3 = 3; + public static final int PARK_LOC4 = 4; + public static final int PARK_LOC5 = 5; + public static final int PARK_ESC = 6; + public static final int RENTAL = 7; + public static final int SHUTTLE_VAN = 8; + public static final int HOTEL_COURTESY = 9; + public static final int RIDEHAILING_LOC1 = 10; + public static final int RIDEHAILING_LOC2 = 11; + public static final int TRANSIT = 12; + public static final int CURB_LOC1 = 13; + public static final int CURB_LOC2 = 14; + public static final int CURB_LOC3 = 15; + public static final int CURB_LOC4 = 16; + public static final int CURB_LOC5 = 17; + + public static final int MGRAAlt_TERM = 8; + public static final int MGRAAlt_CMH = 9; + + public static final int LOS_TYPE = 4; + + public static final int DA = 0; + public static final int SR2 = 1; + public static final int SR3 = 2; + public static final int Transit = 3; + + public static final int employeePark_MGRA_index = 1; + public static final int employeePark_stall_index = 2; + public static final int employeePark_terminalpct_index = 3; + public static final int employeePark_transitpct_index = 4; + + public static final int airport_travel_party_trip_leg_1 = 1; + public static final int airport_travel_party_trip_leg_2 = 2; private AirportModelStructure() { @@ -182,24 +209,40 @@ public static int getOccupancy(int accessMode, int partySize) switch (accessMode) { - case PARK_TMNL: + case PARK_LOC1: return partySize; - case PARK_SANOFF: + case PARK_LOC2: return partySize; - case PARK_PVTOFF: + case PARK_LOC3: return partySize; - case PUDO_ESC: - return partySize + 1; - case PUDO_CURB: + case PARK_LOC4: + return partySize; + case PARK_LOC5: + return partySize; + case PARK_ESC: return partySize + 1; case RENTAL: return partySize; - case TAXI: - return partySize + 1; case SHUTTLE_VAN: return partySize + 1; + case HOTEL_COURTESY: + return partySize + 1; + case RIDEHAILING_LOC1: + return partySize + 1; + case RIDEHAILING_LOC2: + return partySize + 1; case TRANSIT: return partySize; + case CURB_LOC1: + return partySize + 1; + case CURB_LOC2: + return partySize + 1; + case CURB_LOC3: + return partySize + 1; + case CURB_LOC4: + return partySize + 1; + case CURB_LOC5: + return partySize + 1; default: throw new RuntimeException( diff --git a/src/main/java/org/sandag/abm/airport/AirportParty.java b/src/main/java/org/sandag/abm/airport/AirportParty.java index cb6df65b3..be1e65905 100644 --- a/src/main/java/org/sandag/abm/airport/AirportParty.java +++ b/src/main/java/org/sandag/abm/airport/AirportParty.java @@ -23,7 +23,9 @@ public class AirportParty // following variables chosen via choice models private int originMGRA; private int destinationMGRA; - private byte mode; + private int airportAccessMGRA; + + private byte mode; private byte arrivalMode; // best tap pairs for transit path; dimensioned by ride mode, then boarding @@ -31,8 +33,14 @@ public class AirportParty private int[][] bestWtwTapPairs; private int[][] bestWtdTapPairs; private int[][] bestDtwTapPairs; + + private int[][] APtoTermBestWtwTapPairs; + private int AP2TerminalTransitMode; - /** + + + + /** * Public constructor. * * @param seed @@ -40,8 +48,7 @@ public class AirportParty */ public AirportParty(long seed) { - - random = new MersenneTwister(seed); + random = new MersenneTwister(seed); } /** @@ -162,6 +169,14 @@ public void setOriginMGRA(int originMGRA) { this.originMGRA = originMGRA; } + + public int getAirportAccessMGRA() { + return airportAccessMGRA; + } + + public void setAirportAccessMGRA(int airportAccessMGRA) { + this.airportAccessMGRA = airportAccessMGRA; + } /** * @return the trip mode @@ -342,4 +357,19 @@ public void setDestinationMGRA(int destinationMGRA) this.destinationMGRA = destinationMGRA; } + public int[] getAPtoTermBestWtwTapPairs(int rideMode) { + return APtoTermBestWtwTapPairs[rideMode]; + } + + public void setAPtoTermBestWtwTapPairs(int[][] aPtoTermBestWtwTapPairs) { + APtoTermBestWtwTapPairs = aPtoTermBestWtwTapPairs; + } + + public int getAP2TerminalTransitMode() { + return AP2TerminalTransitMode; + } + + public void setAP2TerminalTransitMode(int aP2TerminalTransitMode) { + AP2TerminalTransitMode = aP2TerminalTransitMode; + } } diff --git a/src/main/java/org/sandag/abm/airport/AirportPartyManager.java b/src/main/java/org/sandag/abm/airport/AirportPartyManager.java index 69619696e..77ca25c73 100644 --- a/src/main/java/org/sandag/abm/airport/AirportPartyManager.java +++ b/src/main/java/org/sandag/abm/airport/AirportPartyManager.java @@ -6,10 +6,18 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; +import java.util.List; +import java.util.ArrayList; +import java.io.FileNotFoundException; + import org.apache.log4j.Logger; import org.sandag.abm.application.SandagModelStructure; import org.sandag.abm.ctramp.CtrampApplication; import org.sandag.abm.ctramp.Util; +import org.sandag.abm.modechoice.Modes; + import com.pb.common.datafile.OLD_CSVFileReader; import com.pb.common.datafile.TableDataSet; import com.pb.common.util.ResourceUtil; @@ -20,6 +28,7 @@ public class AirportPartyManager private static Logger logger = Logger.getLogger("SandagTourBasedModel.class"); private AirportParty[] parties; + private int totalPassengerParty; private double[] purposeDistribution; private double[][] sizeDistribution; @@ -27,8 +36,12 @@ public class AirportPartyManager private double[][] incomeDistribution; private double[][] departureDistribution; private double[][] arrivalDistribution; + + public int airportMgra; SandagModelStructure sandagStructure; + + private Map> employeeParkingValuesMap = new HashMap<>(); /** * Constructor. Reads properties file and opens/stores all probability @@ -55,6 +68,8 @@ public AirportPartyManager(HashMap rbMap, float sampleRate) + Util.getStringValueFromPropertyMap(rbMap, "airport.departureTime.file"); String arriveFile = directory + Util.getStringValueFromPropertyMap(rbMap, "airport.arrivalTime.file"); + String employeeParkFile = directory + + Util.getStringValueFromPropertyMap(rbMap, "airport.employeePark.file"); // Read the distributions setPurposeDistribution(purposeFile); @@ -63,6 +78,8 @@ public AirportPartyManager(HashMap rbMap, float sampleRate) incomeDistribution = setDistribution(incomeDistribution, incomeFile); departureDistribution = setDistribution(departureDistribution, departFile); arrivalDistribution = setDistribution(arrivalDistribution, arriveFile); + + readCsvFile(employeeParkFile); // calculate total number of parties float enplanements = new Float(Util.getStringValueFromPropertyMap(rbMap, @@ -73,10 +90,19 @@ public AirportPartyManager(HashMap rbMap, float sampleRate) "airport.annualizationFactor")); float averageSize = new Float(Util.getStringValueFromPropertyMap(rbMap, "airport.averageSize")); + + airportMgra = Util.getIntegerValueFromPropertyMap(rbMap, + "airport.airportMgra"); + + int totalEmployees = 0; + for ( String key : employeeParkingValuesMap.keySet()) { + totalEmployees += (int) (employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_stall_index) * employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_terminalpct_index)); + } float directPassengers = (enplanements - connectingPassengers) / annualFactor; int totalParties = (int) (directPassengers / averageSize) * 2; - parties = new AirportParty[(int)(totalParties*sampleRate)]; + parties = new AirportParty[(int)(totalParties*sampleRate) + totalEmployees * 2]; + totalPassengerParty = (int) (totalParties*sampleRate); logger.info("Total airport parties: " + totalParties); } @@ -92,14 +118,16 @@ public AirportPartyManager(HashMap rbMap, float sampleRate) public void generateAirportParties() { - int departures = parties.length / 2; - int arrivals = parties.length - departures; + int departures = totalPassengerParty / 2; + int arrivals = departures; + int employees = (parties.length - departures - arrivals) / 2; int totalParties = 0; int totalPassengers = 0; + int totalEmployees = 0; for (int i = 0; i < departures; ++i) { - AirportParty party = new AirportParty(i * 101 + 1000); + AirportParty party = new AirportParty(i * 101 + 1000); // simulate from distributions party.setDirection(AirportModelStructure.DEPARTURE); @@ -127,7 +155,7 @@ public void generateAirportParties() for (int i = 0; i < arrivals; ++i) { - AirportParty party = new AirportParty(i * 101 + 1000); + AirportParty party = new AirportParty(i * 201 + 1000); // simulate from distributions party.setDirection(AirportModelStructure.ARRIVAL); @@ -153,9 +181,144 @@ public void generateAirportParties() } logger.info("Total passengers " + totalPassengers); + + for (String key : employeeParkingValuesMap.keySet()) + { + double num = employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_stall_index) * employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_terminalpct_index); + int stallNum = (int) num; + for (int s = 0; s < stallNum; s++) + { + AirportParty party = new AirportParty(s * 301 + 1000); + double stallMgra = employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_MGRA_index); + party.setOriginMGRA((int) stallMgra); + party.setDestinationMGRA(airportMgra); + + double transitToTerminalProb = employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_transitpct_index); + if (party.getRandom() < transitToTerminalProb) + { + party.setMode((byte) SandagModelStructure.WALK_TRANSIT_ALTS[0]); + } + else + { + party.setMode((byte) SandagModelStructure.WALK_ALTS[0]); + } + // simulate from distributions + byte period = (byte) chooseFromDistribution(AirportModelStructure.EMPLOYEE, departureDistribution, + party.getRandom()); + + party.setDirection(AirportModelStructure.DEPARTURE); + party.setPurpose(AirportModelStructure.EMPLOYEE); + party.setSize((byte) 1); + party.setNights((byte) -99); + party.setIncome((byte) -99); + party.setDepartTime(period); + party.setArrivalMode((byte) -99); + + parties[totalParties] = party; + ++totalParties; + party.setID(totalParties); + totalEmployees += 1; + } + } + + + for (String key : employeeParkingValuesMap.keySet()) + { + double num = employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_stall_index) *employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_terminalpct_index); + int stallNum = (int) num; + for (int s = 0; s < stallNum; s++) + { + AirportParty party = new AirportParty(s*101 + 1001); + double stallMgra = employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_MGRA_index); + party.setDestinationMGRA((int) stallMgra); + party.setOriginMGRA(airportMgra); + + double transitToTerminalProb = employeeParkingValuesMap.get(key).get(AirportModelStructure.employeePark_transitpct_index); + if (party.getRandom() < transitToTerminalProb) + { + party.setMode((byte) SandagModelStructure.WALK_TRANSIT_ALTS[0]); + } + else + { + party.setMode((byte) SandagModelStructure.WALK_ALTS[0]); + } + // simulate from distributions + byte period = (byte) chooseFromDistribution(AirportModelStructure.EMPLOYEE, arrivalDistribution, + party.getRandom()); + + party.setDirection(AirportModelStructure.ARRIVAL); + party.setPurpose(AirportModelStructure.EMPLOYEE); + party.setSize((byte) 1); + party.setNights((byte) -99); + party.setIncome((byte) -99); + party.setDepartTime(period); + party.setArrivalMode((byte) -99); + + parties[totalParties] = party; + ++totalParties; + party.setID(totalParties); + totalEmployees += 0; + } + } + logger.info("Total employees going to terminal" + totalEmployees); } - + + private void readCsvFile(String filePath) { + + //Map> employeeParkingValuesMap = new HashMap<>(); + + String employeeParkIndexString = "Name"; + + try (Scanner sc = new Scanner(new File(filePath))) { + + String[] record; + + // process the header record + record = sc.nextLine().split(",", -1); + Map fieldIndexMap; + fieldIndexMap = getFieldIndexMap( record ); + + int employeeParkingIndex = fieldIndexMap.get( employeeParkIndexString ); + + while (sc.hasNextLine()) + { + + record = sc.nextLine().split(",", -1); + String employeeParkingName = record[employeeParkingIndex]; + + // pre-allocate the ArrayList to hold values for this MAZ + List valueList = new ArrayList<>(); + while (valueList.size() < fieldIndexMap.size()) + valueList.add(null); + + // convert the record[] values to double for each specified field value and save in the ArrayList. + for ( String field : fieldIndexMap.keySet()) { + int index = fieldIndexMap.get( field ); + valueList.set( index, Double.valueOf( record[index] ) ); + } + + employeeParkingValuesMap.put( employeeParkingName, valueList ); + + } + } + catch (FileNotFoundException e) { + throw new RuntimeException( "Exception caught reading csv file: " + filePath, e ); + } + + } + + /** + * @param record String[] of field names read from the csv file header record. + * @return Map map of field names to field indices. + */ + private Map getFieldIndexMap( String[] record ) { + Map fldIdxMap = new HashMap<>(); + for ( int i=0; i < record.length; i++ ) + fldIdxMap.put(record[i], i); + return fldIdxMap; + } + /** * Read file containing probabilities by purpose. Store cumulative * distribution in purposeDistribution. @@ -329,22 +492,140 @@ public void writeOutputFile(HashMap rbMap) throw new RuntimeException(); } String headerString = new String( - "id,direction,purpose,size,income,nights,departTime,originMGRA,destinationMGRA,tripMode,arrivalMode,boardingTAP,alightingTAP\n"); + "travel_party_id,leg_id,direction,purpose,size,income,nights,departTime,originMGRA,destinationMGRA,tripMode,arrivalMode,boardingTAP,alightingTAP\n"); writer.print(headerString); // Iterate through the array, printing records to the file for (int i = 0; i < parties.length; ++i) { + // if employee + if (parties[i].getPurpose() == AirportModelStructure.EMPLOYEE) + { + String record; + if (parties[i].getMode() == SandagModelStructure.WALK_ALTS[0]) + { + record = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_1 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getOriginMGRA() + "," + + parties[i].getDestinationMGRA() + "," + parties[i].getMode() + "," + + parties[i].getArrivalMode() + "," + (int) 0 + "," + (int) 0 + "\n"); + } + else + { + int[] tapsAP2Terminal = getAccessToTerminalTapPair(parties[i]); + + record = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_1 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getOriginMGRA() + "," + + parties[i].getDestinationMGRA() + "," + parties[i].getAP2TerminalTransitMode() + "," + + parties[i].getArrivalMode() + "," + tapsAP2Terminal[0] + "," + tapsAP2Terminal[1] + "\n"); + } + + writer.print(record); + + continue; + } + int[] taps = getTapPair(parties[i]); + + int airportAccessMgra = parties[i].getAirportAccessMGRA(); + int accMode_null = -99; + + // if the arrival mode access point is transit, or it's an external trip + if (airportAccessMgra <= 0) + { + String record = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_1 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getOriginMGRA() + "," + + parties[i].getDestinationMGRA() + "," + parties[i].getMode() + "," + + parties[i].getArrivalMode() + "," + taps[0] + "," + taps[1] + "\n"); + + writer.print(record); + + continue; + } + + // if the arrival mode access point is not transit, two trip legs will be printed out + else + { + String record_Origin2Access = new String(); + String record_Access2Destination = new String(); + + if (parties[i].getDirection() == AirportModelStructure.DEPARTURE) + { + record_Origin2Access = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_1 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getOriginMGRA() + "," + + parties[i].getAirportAccessMGRA() + "," + parties[i].getMode() + "," + + parties[i].getArrivalMode() + "," + taps[0] + "," + taps[1] + "\n"); + + // if access point is airport terminal, connection mode is walk + if (airportAccessMgra == airportMgra) + { + record_Access2Destination = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_2 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getAirportAccessMGRA() + "," + + parties[i].getDestinationMGRA() + "," + SandagModelStructure.WALK_ALTS[0] + "," + + accMode_null + "," + taps[0] + "," + taps[1] + "\n"); + } + // else if access point is not airport terminal, connection mode is transit (APM) + else + { + + int[] tapsAP2Terminal = getAccessToTerminalTapPair(parties[i]); + + record_Access2Destination = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_2 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getAirportAccessMGRA() + "," + + parties[i].getDestinationMGRA() + "," + parties[i].getAP2TerminalTransitMode() + "," + + accMode_null + "," + tapsAP2Terminal[0] + "," + tapsAP2Terminal[1] + "\n"); + } + writer.print(record_Origin2Access); + writer.print(record_Access2Destination); + } + else + { + record_Access2Destination = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_2 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getAirportAccessMGRA() + "," + + parties[i].getDestinationMGRA() + "," + parties[i].getMode() + "," + + parties[i].getArrivalMode() + "," + taps[0] + "," + taps[1] + "\n"); + // if access point is airport terminal, connection mode is walk + if (airportAccessMgra == airportMgra) + { + record_Origin2Access = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_1 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getOriginMGRA() + "," + + parties[i].getAirportAccessMGRA() + "," + SandagModelStructure.WALK_ALTS[0] + "," + + accMode_null + "," + taps[0] + "," + taps[1] + "\n"); + } + // else if access point is not airport terminal, connection mode is transit (APM) + else + { + + int[] tapsAP2Terminal = getAccessToTerminalTapPair(parties[i]); + + record_Origin2Access = new String(parties[i].getID() + "," + AirportModelStructure.airport_travel_party_trip_leg_1 + "," + parties[i].getDirection() + "," + + parties[i].getPurpose() + "," + parties[i].getSize() + "," + + parties[i].getIncome() + "," + parties[i].getNights() + "," + + parties[i].getDepartTime() + "," + parties[i].getOriginMGRA() + "," + + parties[i].getAirportAccessMGRA() + "," + parties[i].getAP2TerminalTransitMode() + "," + + accMode_null + "," + tapsAP2Terminal[0] + "," + tapsAP2Terminal[1] + "\n"); + } + writer.print(record_Origin2Access); + writer.print(record_Access2Destination); + } + } - String record = new String(parties[i].getID() + "," + parties[i].getDirection() + "," - + parties[i].getPurpose() + "," + parties[i].getSize() + "," - + parties[i].getIncome() + "," + parties[i].getNights() + "," - + parties[i].getDepartTime() + "," + parties[i].getOriginMGRA() + "," - + parties[i].getDestinationMGRA() + "," + parties[i].getMode() + "," - + parties[i].getArrivalMode() + "," + taps[0] + "," + taps[1] + "\n"); - writer.print(record); } writer.close(); @@ -386,6 +667,43 @@ else if (sandagStructure.getTripModeIsKnrTransit(tripMode)) return taps; } + + public int[] getAccessToTerminalTapPair(AirportParty party) + { + + int[] taps = new int[2]; + + // APM is coded as light rail + int rideMode = sandagStructure.getRideModeIndexForTripMode(SandagModelStructure.WALK_LRT); + + // walk-LRT trip mode + int AP2TerminalTransitMode = SandagModelStructure.WALK_LRT; + + party.setAP2TerminalTransitMode(AP2TerminalTransitMode); + + taps = party.getAPtoTermBestWtwTapPairs(rideMode); + + // if there's no best path for light rail, loop through and find the available ride mode + if (taps == null) + { + for (int i = 0; i < SandagModelStructure.WALK_TRANSIT_ALTS.length; i++) + { + rideMode = sandagStructure.getRideModeIndexForTripMode(SandagModelStructure.WALK_TRANSIT_ALTS[i]); + taps = party.getAPtoTermBestWtwTapPairs(rideMode); + + if (taps != null) + { + AP2TerminalTransitMode = SandagModelStructure.WALK_TRANSIT_ALTS[i]; + + party.setAP2TerminalTransitMode(AP2TerminalTransitMode); + + break; + } + } + } + + return taps; + } /* public static void main(String[] args) { diff --git a/src/main/java/org/sandag/abm/airport/AirportTripTables.java b/src/main/java/org/sandag/abm/airport/AirportTripTables.java index b9cb4401d..288cfe46c 100644 --- a/src/main/java/org/sandag/abm/airport/AirportTripTables.java +++ b/src/main/java/org/sandag/abm/airport/AirportTripTables.java @@ -343,9 +343,19 @@ public void processTrips(int timePeriod, TableDataSet tripData) // party size is a variable in output file. it is used for transit // trips (person trips) float personTrips = (float) tripData.getValueAt(i, "size")/sampleRate; + + if (tripData.getValueAt(i, "purpose") == AirportModelStructure.EMPLOYEE) + { + personTrips = (float) tripData.getValueAt(i, "size"); + } // all auto trips are 1 per party float vehicleTrips = 1.0f/sampleRate; + + if (tripData.getValueAt(i, "purpose") == AirportModelStructure.EMPLOYEE) + { + vehicleTrips = 1.0f; + } // Store in matrix int mode = modeIndex[tripMode]; @@ -393,8 +403,11 @@ public void processTrips(int timePeriod, TableDataSet tripData) // generate another drive-alone trip in the opposite direction for // pickup/dropoff - if (accMode == AirportModelStructure.PUDO_CURB - || accMode == AirportModelStructure.PUDO_CURB) + if (accMode == AirportModelStructure.CURB_LOC1 + || accMode == AirportModelStructure.CURB_LOC2 + || accMode == AirportModelStructure.CURB_LOC3 + || accMode == AirportModelStructure.CURB_LOC4 + || accMode == AirportModelStructure.CURB_LOC5) { mode = 0; // auto mode if (SandagModelStructure.getTripModeIsPay(tripMode)) // if the