diff --git a/src/main/java/de/tum/bgu/msm/MitoModelGermany.java b/src/main/java/de/tum/bgu/msm/MitoModelGermany.java
new file mode 100644
index 00000000..ca8745ec
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/MitoModelGermany.java
@@ -0,0 +1,125 @@
+package de.tum.bgu.msm;
+
+import de.tum.bgu.msm.data.DataSet;
+import de.tum.bgu.msm.data.travelTimes.SkimTravelTimes;
+import de.tum.bgu.msm.io.input.readers.*;
+import de.tum.bgu.msm.resources.Properties;
+import de.tum.bgu.msm.resources.Resources;
+import de.tum.bgu.msm.util.ImplementationConfig;
+import de.tum.bgu.msm.util.MitoUtil;
+import org.apache.log4j.Logger;
+
+import java.util.Random;
+
+/**
+ * Implements the Microsimulation Transport Orchestrator (MITO)
+ *
+ * @author Rolf Moeckel
+ * Created on Sep 18, 2016 in Munich, Germany
+ *
+ * To run MITO, the following data need either to be passed in from another program or
+ * need to be read from files and passed in (using method initializeStandAlone):
+ * - zones
+ * - autoTravelTimes
+ * - transitTravelTimes
+ * - timoHouseholds
+ * - retailEmplByZone
+ * - officeEmplByZone
+ * - otherEmplByZone
+ * - totalEmplByZone
+ * - sizeOfZonesInAcre
+ */
+public final class MitoModelGermany {
+
+ private static final Logger logger = Logger.getLogger(MitoModelGermany.class);
+ private final String scenarioName;
+
+ private DataSet dataSet;
+
+ private MitoModelGermany(DataSet dataSet, String scenarioName) {
+ this.dataSet = dataSet;
+ this.scenarioName = scenarioName;
+ MitoUtil.initializeRandomNumber();
+ }
+
+ public static MitoModelGermany standAloneModel(String propertiesFile, ImplementationConfig config) {
+ logger.info(" Creating standalone version of MITO ");
+ Resources.initializeResources(propertiesFile);
+ MitoModelGermany model = new MitoModelGermany(new DataSet(), Resources.instance.getString(Properties.SCENARIO_NAME));
+ model.readStandAlone(config);
+ return model;
+ }
+
+ public static MitoModelGermany initializeModelFromSilo(String propertiesFile, DataSet dataSet, String scenarioName) {
+ logger.info(" Initializing MITO from SILO");
+ Resources.initializeResources(propertiesFile);
+ MitoModelGermany model = new MitoModelGermany(dataSet, scenarioName);
+ new OmxSkimsReader(dataSet).readOnlyTransitTravelTimes();
+ new OmxSkimsReader(dataSet).readSkimDistancesNMT();
+ new OmxSkimsReader(dataSet).readSkimDistancesAuto();
+ model.readAdditionalData();
+ return model;
+ }
+
+ public void run() {
+ long startTime = System.currentTimeMillis();
+ logger.info("Started the Microsimulation Transport Orchestrator (MITO)");
+
+ TravelDemandGeneratorGermany ttd = new TravelDemandGeneratorGermany.Builder(dataSet).build();
+ ttd.generateTravelDemand(scenarioName);
+ printOutline(startTime);
+ }
+
+ private void readStandAlone(ImplementationConfig config) {
+ dataSet.setYear(Resources.instance.getInt(Properties.SCENARIO_YEAR));
+ new ZonesReader(dataSet).read();
+ if (Resources.instance.getBoolean(Properties.REMOVE_TRIPS_AT_BORDER)) {
+ new BorderDampersReader(dataSet).read();
+ }
+ //new JobReader(dataSet, config.getJobTypeFactory()).read();
+ new SchoolsReader(dataSet).read();
+ new HouseholdsReaderGermany(dataSet).read();
+ //new HouseholdsCoordReader(dataSet).read();
+ //new PersonsReader(dataSet).read();
+ //the class called Synthetic population reader: could it be renamed to PersonJobReader?
+ new SyntheticPopulationReaderGermany(dataSet, config.getJobTypeFactory()).read();
+ dataSet.setTravelTimes(new SkimTravelTimes());
+ new OmxSkimsReader(dataSet).read();
+ readAdditionalData();
+ }
+
+ private void readAdditionalData() {
+ new TripAttractionRatesReader(dataSet).read();
+ new ModeChoiceInputReader(dataSet).read();
+ new EconomicStatusReader(dataSet).read();
+ new TimeOfDayDistributionsReader(dataSet).read();
+ new CalibrationDataReader(dataSet).read();
+ new CalibrationRegionMapReader(dataSet).read();
+
+ }
+
+ private void printOutline(long startTime) {
+ String trips = MitoUtil.customFormat(" " + "###,###", dataSet.getTrips().size());
+ logger.info("A total of " + trips.trim() + " microscopic trips were generated");
+ logger.info("Completed the Microsimulation Transport Orchestrator (MITO)");
+ float endTime = MitoUtil.rounder(((System.currentTimeMillis() - startTime) / 60000.f), 1);
+ int hours = (int) (endTime / 60);
+ int min = (int) (endTime - 60 * hours);
+ logger.info("Runtime: " + hours + " hours and " + min + " minutes.");
+ }
+
+ public DataSet getData() {
+ return dataSet;
+ }
+
+ public String getScenarioName() {
+ return scenarioName;
+ }
+
+ public void setRandomNumberGenerator(Random random) {
+ MitoUtil.initializeRandomNumber(random);
+ }
+
+
+
+}
diff --git a/src/main/java/de/tum/bgu/msm/TravelDemandGeneratorGermany.java b/src/main/java/de/tum/bgu/msm/TravelDemandGeneratorGermany.java
new file mode 100644
index 00000000..a2f4c7d8
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/TravelDemandGeneratorGermany.java
@@ -0,0 +1,276 @@
+package de.tum.bgu.msm;
+
+import de.tum.bgu.msm.data.DataSet;
+import de.tum.bgu.msm.data.Purpose;
+import de.tum.bgu.msm.io.output.SummarizeData;
+import de.tum.bgu.msm.io.output.SummarizeDataToVisualize;
+import de.tum.bgu.msm.io.output.TripGenerationWriter;
+import de.tum.bgu.msm.modules.Module;
+import de.tum.bgu.msm.modules.modeChoice.ModeChoice;
+import de.tum.bgu.msm.modules.plansConverter.MatsimPopulationGenerator;
+import de.tum.bgu.msm.modules.scaling.TripScaling;
+import de.tum.bgu.msm.modules.timeOfDay.TimeOfDayChoice;
+import de.tum.bgu.msm.modules.travelTimeBudget.TravelTimeBudgetModule;
+//import de.tum.bgu.msm.modules.tripDistribution.DestinationUtilityCalculatorFactoryImpl2;
+import de.tum.bgu.msm.modules.tripDistribution.DestinationUtilityCalculatorFactoryImplGermany;
+import de.tum.bgu.msm.modules.tripDistribution.TripDistribution;
+import de.tum.bgu.msm.modules.tripGeneration.TripGeneration;
+import de.tum.bgu.msm.modules.tripGeneration.TripsByPurposeGeneratorFactoryPersonBasedHurdle;
+import de.tum.bgu.msm.resources.Properties;
+import de.tum.bgu.msm.resources.Resources;
+import org.apache.log4j.Logger;
+
+import java.util.List;
+
+/**
+ * Generates travel demand for the Microscopic Transport Orchestrator (MITO)
+ *
+ * @author Rolf Moeckel
+ * Created on Sep 18, 2016 in Munich, Germany
+ */
+public final class TravelDemandGeneratorGermany {
+
+ private static final Logger logger = Logger.getLogger(TravelDemandGeneratorGermany.class);
+ private final DataSet dataSet;
+
+ private final Module tripGenerationMandatory;
+ private final Module personTripAssignmentMandatory;
+ private final Module travelTimeBudgetMandatory;
+ private final Module distributionMandatory;
+ private final Module modeChoiceMandatory;
+ private final Module tripGenerationDiscretionary;
+ private final Module personTripAssignmentDiscretionary;
+ private final Module travelTimeBudgetDiscretionary;
+ private final Module distributionDiscretionary;
+ private final Module modeChoiceDiscretionary;
+ private final Module timeOfDayChoiceMandatory;
+ private final Module timeOfDayChoiceDiscretionary;
+ private final Module tripScaling;
+ private final Module matsimPopulationGenerator;
+ private final Module longDistanceTraffic;
+
+ private TravelDemandGeneratorGermany(
+ DataSet dataSet,
+ Module tripGenerationMandatory,
+ Module personTripAssignmentMandatory,
+ Module travelTimeBudgetMandatory,
+ Module distributionMandatory,
+ Module modeChoiceMandatory,
+ Module timeOfDayChoiceMandatory,
+ Module tripGenerationDiscretionary,
+ Module personTripAssignmentDiscretionary,
+ Module travelTimeBudgetDiscretionary,
+ Module distributionDiscretionary,
+ Module modeChoiceDiscretionary,
+ Module timeOfDayChoiceDiscretionary,
+ Module tripScaling,
+ Module matsimPopulationGenerator,
+ Module longDistanceTraffic) {
+
+ this.dataSet = dataSet;
+ this.tripGenerationMandatory = tripGenerationMandatory;
+ this.personTripAssignmentMandatory = personTripAssignmentMandatory;
+ this.travelTimeBudgetMandatory = travelTimeBudgetMandatory;
+ this.distributionMandatory = distributionMandatory;
+ this.modeChoiceMandatory = modeChoiceMandatory;
+ this.timeOfDayChoiceMandatory = timeOfDayChoiceMandatory;
+ this.tripGenerationDiscretionary = tripGenerationDiscretionary;
+ this.personTripAssignmentDiscretionary = personTripAssignmentDiscretionary;
+ this.travelTimeBudgetDiscretionary = travelTimeBudgetDiscretionary;
+ this.distributionDiscretionary = distributionDiscretionary;
+ this.modeChoiceDiscretionary = modeChoiceDiscretionary;
+ this.timeOfDayChoiceDiscretionary = timeOfDayChoiceDiscretionary;
+ this.tripScaling = tripScaling;
+ this.matsimPopulationGenerator = matsimPopulationGenerator;
+ this.longDistanceTraffic = longDistanceTraffic;
+ }
+
+
+ public static class Builder {
+
+ private final DataSet dataSet;
+
+ private Module tripGenerationMandatory;
+ private Module personTripAssignmentMandatory;
+ private Module travelTimeBudgetMandatory;
+ private Module distributionMandatory;
+ private Module modeChoiceMandatory;
+ private Module timeOfDayChoiceMandatory;
+
+ private Module tripGenerationDiscretionary;
+ private Module personTripAssignmentDiscretionary;
+ private Module travelTimeBudgetDiscretionary;
+ private Module distributionDiscretionary;
+ private Module modeChoiceDiscretionary;
+ private Module timeOfDayChoiceDiscretionary;
+
+ private Module tripScaling;
+ private Module matsimPopulationGenerator;
+ private Module longDistanceTraffic;
+
+ public Builder(DataSet dataSet) {
+ this.dataSet = dataSet;
+ //from here
+ List purposes = Purpose.getAllPurposes();
+ tripGenerationMandatory = new TripGeneration(dataSet, new TripsByPurposeGeneratorFactoryPersonBasedHurdle(), Purpose.getMandatoryPurposes());
+ //personTripAssignmentMandatory = new PersonTripAssignment(dataSet, Purpose.getMandatoryPurposes());
+ travelTimeBudgetMandatory = new TravelTimeBudgetModule(dataSet, Purpose.getMandatoryPurposes());
+ distributionMandatory = new TripDistribution(dataSet, Purpose.getMandatoryPurposes(), false,
+ new DestinationUtilityCalculatorFactoryImplGermany());
+ modeChoiceMandatory = new ModeChoice(dataSet, Purpose.getMandatoryPurposes());
+ timeOfDayChoiceMandatory = new TimeOfDayChoice(dataSet, Purpose.getMandatoryPurposes());
+
+ tripGenerationDiscretionary = new TripGeneration(dataSet, new TripsByPurposeGeneratorFactoryPersonBasedHurdle(), Purpose.getDiscretionaryPurposes());
+ //personTripAssignmentDiscretionary = new PersonTripAssignment(dataSet, Purpose.getDiscretionaryPurposes());
+ travelTimeBudgetDiscretionary = new TravelTimeBudgetModule(dataSet, Purpose.getDiscretionaryPurposes());
+ distributionDiscretionary = new TripDistribution(dataSet, Purpose.getDiscretionaryPurposes(), false,
+ new DestinationUtilityCalculatorFactoryImplGermany());
+ modeChoiceDiscretionary = new ModeChoice(dataSet, Purpose.getDiscretionaryPurposes());
+ timeOfDayChoiceDiscretionary = new TimeOfDayChoice(dataSet, Purpose.getDiscretionaryPurposes());
+ //until here it must be divided into two blocks - mandatory and discretionary
+
+ tripScaling = new TripScaling(dataSet, purposes);
+ matsimPopulationGenerator = new MatsimPopulationGenerator(dataSet, purposes);
+ }
+
+ public TravelDemandGeneratorGermany build() {
+ return new TravelDemandGeneratorGermany(dataSet,
+ tripGenerationMandatory,
+ personTripAssignmentMandatory,
+ travelTimeBudgetMandatory,
+ distributionMandatory,
+ modeChoiceMandatory,
+ timeOfDayChoiceMandatory,
+ tripGenerationDiscretionary,
+ personTripAssignmentDiscretionary,
+ travelTimeBudgetDiscretionary,
+ distributionDiscretionary,
+ modeChoiceDiscretionary,
+ timeOfDayChoiceDiscretionary,
+ tripScaling,
+ matsimPopulationGenerator,
+ longDistanceTraffic);
+ }
+
+ public void setTripGeneration(Module tripGeneration) {
+ this.tripGenerationMandatory = tripGeneration;
+ }
+
+ public void setPersonTripAssignment(Module personTripAssignment) {
+ this.personTripAssignmentMandatory = personTripAssignment;
+ }
+
+ public void setTravelTimeBudget(Module travelTimeBudget) {
+ this.travelTimeBudgetMandatory = travelTimeBudget;
+ }
+
+ public void setDistribution(Module distribution) {
+ this.distributionMandatory = distribution;
+ }
+
+ public void setModeChoice(Module modeChoice) {
+ this.modeChoiceMandatory = modeChoice;
+ }
+
+ public void setTimeOfDayChoiceMandatory(Module timeOfDayChoiceMandatory) {
+ this.timeOfDayChoiceMandatory = timeOfDayChoiceMandatory;
+ }
+
+ public void setTripScaling(Module tripScaling) {
+ this.tripScaling = tripScaling;
+ }
+
+ public void setMatsimPopulationGenerator(Module matsimPopulationGenerator) {
+ this.matsimPopulationGenerator = matsimPopulationGenerator;
+ }
+
+ public void setLongDistanceTraffic(Module longDistanceTraffic) {
+ this.longDistanceTraffic = longDistanceTraffic;
+ }
+
+ public DataSet getDataSet() {
+ return dataSet;
+ }
+
+ public Module getTripGeneration() {
+ return tripGenerationMandatory;
+ }
+
+ public Module getPersonTripAssignment() {
+ return personTripAssignmentMandatory;
+ }
+
+ public Module getTravelTimeBudget() {
+ return travelTimeBudgetMandatory;
+ }
+
+ public Module getDistribution() {
+ return distributionMandatory;
+ }
+
+ public Module getModeChoice() {
+ return modeChoiceMandatory;
+ }
+
+ public Module getTimeOfDayChoiceMandatory() {
+ return timeOfDayChoiceMandatory;
+ }
+
+ public Module getTripScaling() {
+ return tripScaling;
+ }
+
+ public Module getMatsimPopulationGenerator() {
+ return matsimPopulationGenerator;
+ }
+
+ public Module getLongDistanceTraffic() {
+ return longDistanceTraffic;
+ }
+ }
+
+
+
+ public void generateTravelDemand(String scenarioName) {
+
+ logger.info("Running Module: Microscopic Trip Generation");
+
+ tripGenerationMandatory.run();
+ logger.info("Running Module: Travel Time Budget Calculation");
+ travelTimeBudgetMandatory.run();
+ logger.info("Running Module: Microscopic Trip Distribution");
+ distributionMandatory.run();
+ logger.info("Running Module: Trip to Mode Assignment (Mode Choice)");
+ modeChoiceMandatory.run();
+ logger.info("Running time of day choice");
+ timeOfDayChoiceMandatory.run();
+
+ tripGenerationDiscretionary.run();
+ logger.info("Running Module: Travel Time Budget Calculation");
+ travelTimeBudgetDiscretionary.run();
+ ((TravelTimeBudgetModule) travelTimeBudgetDiscretionary).adjustDiscretionaryPurposeBudgets();
+ logger.info("Running Module: Microscopic Trip Distribution");
+ distributionDiscretionary.run();
+ logger.info("Running Module: Trip to Mode Assignment (Mode Choice)");
+ modeChoiceDiscretionary.run();
+ logger.info("Running time of day choice");
+ timeOfDayChoiceDiscretionary.run();
+
+
+ logger.info("Running trip scaling");
+ tripScaling.run();
+
+ matsimPopulationGenerator.run();
+
+ TripGenerationWriter.writeTripsByPurposeAndZone(dataSet, scenarioName);
+ SummarizeDataToVisualize.writeFinalSummary(dataSet, scenarioName);
+
+ if (Resources.instance.getBoolean(Properties.PRINT_MICRO_DATA, true)) {
+ SummarizeData.writeOutSyntheticPopulationWithTrips(dataSet);
+ SummarizeData.writeOutTrips(dataSet, scenarioName);
+ }
+ if (Resources.instance.getBoolean(Properties.CREATE_CHARTS, true)) {
+ SummarizeData.writeCharts(dataSet, scenarioName);
+ }
+ }
+}
diff --git a/src/main/java/de/tum/bgu/msm/data/MitoGender.java b/src/main/java/de/tum/bgu/msm/data/MitoGender.java
index c322d2a7..f1debcc3 100644
--- a/src/main/java/de/tum/bgu/msm/data/MitoGender.java
+++ b/src/main/java/de/tum/bgu/msm/data/MitoGender.java
@@ -1,9 +1,12 @@
package de.tum.bgu.msm.data;
+import java.util.Random;
+
public enum MitoGender {
MALE,
FEMALE;
+
public static MitoGender valueOf(int code) {
if(code == 2) {
return FEMALE;
@@ -14,4 +17,67 @@ public static MitoGender valueOf(int code) {
}
}
+ //// added by Alona, to assign drivers license
+ public static Random rand; // was private
+ public static double getRandomNumberAsDouble() {
+ return rand.nextDouble();
+ }
+
+ public static boolean obtainLicense(MitoGender gender, int age){
+ boolean license = true; // true - to assign license to everyone
+ int row = 1;
+ int threshold = 0;
+ if (age > 17) {
+ if (age < 29) {
+ if (gender == MitoGender.MALE) {
+ threshold = 86;
+ } else {
+ threshold = 87;
+ }
+ } else if (age < 39) {
+ if (gender == MitoGender.MALE) {
+ threshold = 95;
+ } else {
+ threshold = 94;
+ }
+ } else if (age < 49) {
+ if (gender == MitoGender.MALE) {
+ threshold = 97;
+ } else {
+ threshold = 95;
+ }
+ } else if (age < 59) {
+ if (gender == MitoGender.MALE) {
+ threshold = 96;
+ } else {
+ threshold = 89;
+ }
+ } else if (age < 64) {
+ if (gender == MitoGender.MALE) {
+ threshold = 95;
+ } else {
+ threshold = 86;
+ }
+ } else if (age < 74) {
+ if (gender == MitoGender.MALE) {
+ threshold = 95;
+ } else {
+ threshold = 71;
+ }
+ } else {
+ if (gender == MitoGender.MALE) {
+ threshold = 88;
+ } else {
+ threshold = 44;
+ }
+ }
+ //if (getRandomNumberAsDouble() * 100 < threshold) {
+ //license = true;
+ //}
+ }
+ return license;
+ }
+
+ //
+
}
diff --git a/src/main/java/de/tum/bgu/msm/data/Mode.java b/src/main/java/de/tum/bgu/msm/data/Mode.java
index 077a10da..441f7b3b 100644
--- a/src/main/java/de/tum/bgu/msm/data/Mode.java
+++ b/src/main/java/de/tum/bgu/msm/data/Mode.java
@@ -2,6 +2,9 @@
import org.matsim.api.core.v01.TransportMode;
+import java.util.Arrays;
+import java.util.Collection;
+
public enum Mode implements Id {
autoDriver,
autoPassenger,
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/BorderDampersReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/BorderDampersReader.java
index 304f06f0..03f24f18 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/BorderDampersReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/BorderDampersReader.java
@@ -37,5 +37,6 @@ protected void processRecord(String[] record) {
} else {
logger.warn("Damper of " + damper + " refers to non-existing zone " + zone + ". Ignoring it.");
}
+ //return null;
}
}
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationDataReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationDataReader.java
index 4abdbd6b..cfc83383 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationDataReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationDataReader.java
@@ -6,7 +6,6 @@
import de.tum.bgu.msm.resources.Resources;
import de.tum.bgu.msm.util.MitoUtil;
-import java.nio.file.Paths;
import java.util.HashMap;
public class CalibrationDataReader extends AbstractCsvReader {
@@ -48,6 +47,7 @@ protected void processRecord(String[] record) {
dataSet.getModeChoiceCalibrationData().getCalibrationFactors().get(region).putIfAbsent(purpose, new HashMap<>());
dataSet.getModeChoiceCalibrationData().getCalibrationFactors().get(region).get(purpose).put(mode, factor);
+ //return null;
}
@Override
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationRegionMapReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationRegionMapReader.java
index 9c22f3d1..647fd247 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationRegionMapReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/CalibrationRegionMapReader.java
@@ -5,8 +5,6 @@
import de.tum.bgu.msm.resources.Resources;
import de.tum.bgu.msm.util.MitoUtil;
-import java.nio.file.Paths;
-
public class CalibrationRegionMapReader extends AbstractCsvReader {
private int zoneIndex;
@@ -28,6 +26,7 @@ protected void processRecord(String[] record) {
String region = record[regionIndex];
dataSet.getModeChoiceCalibrationData().getZoneToRegionMap().put(zone, region);
+ //return null;
}
@Override
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/EconomicStatusReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/EconomicStatusReader.java
index f998e228..ef4900fc 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/EconomicStatusReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/EconomicStatusReader.java
@@ -96,6 +96,7 @@ protected void processRecord(String[] record) {
economicStatusDefinition.put(hhSizeFactor + "_Inc6000-6600", codeInc6000_6600);
economicStatusDefinition.put(hhSizeFactor + "_Inc6600-7000", codeInc6600_7000);
economicStatusDefinition.put(hhSizeFactor + "_Inc7000+", codeInc7000plus);
+ //return null;
}
private int getEconomicStatus(MitoHousehold hh) {
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/ExternalZonesReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/ExternalZonesReader.java
index ee780217..e1a05633 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/ExternalZonesReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/ExternalZonesReader.java
@@ -63,6 +63,7 @@ protected void processRecord(String[] record) {
feature = null;
}
zones.put(id, new ExternalFlowZone(id, coordinates, type, feature));
+ //return null;
}
@Override
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/GenericCsvReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/GenericCsvReader.java
index 2a025866..52dc75cc 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/GenericCsvReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/GenericCsvReader.java
@@ -37,6 +37,7 @@ protected void processRecord(String[] record) {
table.put(currentRow, i, record[i]);
}
currentRow++;
+ //return null;
}
@Override
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/HouseholdsCoordReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/HouseholdsCoordReader.java
index dfbc2b4c..32725ac9 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/HouseholdsCoordReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/HouseholdsCoordReader.java
@@ -8,8 +8,13 @@
import de.tum.bgu.msm.util.MitoUtil;
import org.apache.log4j.Logger;
import org.locationtech.jts.geom.Coordinate;
+import org.matsim.api.core.v01.network.Node;
+import org.opengis.feature.simple.SimpleFeature;
import java.nio.file.Path;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Created by Qin on 02.07.2018.
@@ -20,6 +25,9 @@ public class HouseholdsCoordReader extends AbstractCsvReader {
private int posCoordX = -1;
private int posCoordY = -1;
private int posTAZId = -1;
+ private final Map> nodesByZone = new ConcurrentHashMap<>();
+
+ private SimpleFeature shapeFeature; // Alona added
private static final Logger logger = Logger.getLogger(HouseholdsCoordReader.class);
@@ -46,6 +54,7 @@ protected void processHeader(String[] header) {
protected void processRecord(String[] record) {
int hhId = Integer.parseInt(record[posHHId]);
+
//vacant dwellings
if (hhId > 0) {
MitoHousehold hh = dataSet.getHouseholds().get(hhId);
@@ -58,6 +67,8 @@ protected void processRecord(String[] record) {
if(zone == null) {
logger.warn(String.format("Household %d is supposed to live in zone %d but this zone does not exist.", hhId, taz));
}
+
+
Coordinate homeLocation = new Coordinate(
Double.parseDouble(record[posCoordX]), Double.parseDouble(record[posCoordY]));
hh.setHomeLocation(homeLocation);
@@ -65,4 +76,5 @@ protected void processRecord(String[] record) {
zone.addHousehold();
}
}
+
}
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/HouseholdsReaderGermany.java b/src/main/java/de/tum/bgu/msm/io/input/readers/HouseholdsReaderGermany.java
new file mode 100644
index 00000000..f5880f6b
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/HouseholdsReaderGermany.java
@@ -0,0 +1,86 @@
+package de.tum.bgu.msm.io.input.readers;
+
+import de.tum.bgu.msm.data.DataSet;
+import de.tum.bgu.msm.data.MitoHousehold;
+import de.tum.bgu.msm.data.MitoZone;
+import de.tum.bgu.msm.io.input.AbstractCsvReader;
+import de.tum.bgu.msm.resources.Resources;
+import de.tum.bgu.msm.util.MitoUtil;
+import org.apache.log4j.Logger;
+import org.locationtech.jts.geom.Coordinate;
+
+import java.nio.file.Path;
+
+/**
+ * Created by Nico on 17.07.2017.
+ */
+public class HouseholdsReaderGermany extends AbstractCsvReader {
+
+ private int posId = -1;
+ private int posTaz = -1;
+ private int posHHSize = -1;
+ private int posAutos = -1;
+ private int posCoordX = -1;
+ private int posCoordY = -1;
+
+ private static final Logger logger = Logger.getLogger(HouseholdsReaderGermany.class);
+
+ public HouseholdsReaderGermany(DataSet dataSet) {
+ super(dataSet);
+ }
+
+ public int getPosTaz () {
+ return this.posTaz;
+ }
+
+ @Override
+ public void read() {
+ logger.info(" Reading household micro data from ascii file");
+ Path filePath = Resources.instance.getHouseholdsFilePath();
+ super.read(filePath, ",");
+ }
+
+ @Override
+ protected void processHeader(String[] header) {
+ posId = MitoUtil.findPositionInArray("hhid", header);
+ posTaz = MitoUtil.findPositionInArray("zone", header);
+ posHHSize = MitoUtil.findPositionInArray("hhSize", header);
+ posAutos = MitoUtil.findPositionInArray("autos", header);
+ posCoordX = MitoUtil.findPositionInArray("coordX", header);
+ posCoordY = MitoUtil.findPositionInArray("coordY", header);
+ }
+
+ @Override
+ protected void processRecord(String[] record) {
+ int id = Integer.parseInt(record[posId]);
+ int autos = Integer.parseInt(record[posAutos]);
+ MitoHousehold hh = new MitoHousehold(id, 0, autos);
+ dataSet.addHousehold(hh);
+
+ //int hhId = Integer.parseInt(record[posHHId]);
+
+
+ //vacant dwellings
+ if (id > 0) {
+ //MitoHousehold hh = dataSet.getHouseholds().get(id);
+ if (hh == null) {
+ logger.warn(String.format("Household %d does not exist in mito.", id));
+ return;
+ }
+ int taz = Integer.parseInt(record[posTaz]);
+ MitoZone zone = dataSet.getZones().get(taz);
+ if(zone == null) {
+ logger.warn(String.format("Household %d is supposed to live in zone %d but this zone does not exist.", id, taz));
+ }
+
+ //Coordinate homeLocation = new Coordinate().getRandomCoord();
+ //Coordinate homeLocation = zone.getRandomCoord(MitoUtil.getRandomObject());
+
+ Coordinate homeLocation = new Coordinate(
+ Double.parseDouble(record[posCoordX]), Double.parseDouble(record[posCoordY]));
+ hh.setHomeLocation(homeLocation);
+ hh.setHomeZone(zone);
+ zone.addHousehold();
+ }
+ }
+}
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/JobReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/JobReader.java
index 1209bd50..72747534 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/JobReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/JobReader.java
@@ -59,14 +59,15 @@ protected void processRecord(String[] record) {
MitoZone zone = dataSet.getZones().get(zoneId);
if (zone == null) {
logger.warn(String.format("Job %d refers to non-existing zone %d! Ignoring it.", id, zoneId));
- return;
+ //return null;
}
try {
zone.addEmployeeForType(factory.getType(type.toUpperCase().replaceAll("\"","")));
} catch (IllegalArgumentException e) {
- logger.error("Job Type " + type + " used in job microdata but is not defined");
+ //logger.error("Job Type " + type + " used in job microdata but is not defined");
}
+
Coordinate coordinate = (new Coordinate(Double.parseDouble(record[posJobCoordX]),
Double.parseDouble(record[posJobCoordY])));
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/OmxSkimsReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/OmxSkimsReader.java
index aa998dde..b1788390 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/OmxSkimsReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/OmxSkimsReader.java
@@ -44,16 +44,16 @@ public void readOnlyTransitTravelTimes(){
}
private void readTravelTimeSkims() {
- ((SkimTravelTimes) dataSet.getTravelTimes()).readSkim("car", Resources.instance.getRelativePath(Properties.AUTO_PEAK_SKIM).toString(), "timeByTime", 1/60.);
+ ((SkimTravelTimes) dataSet.getTravelTimes()).readSkim("car", Resources.instance.getRelativePath(Properties.AUTO_PEAK_SKIM).toString(), "mat1", 1/60.);
((SkimTravelTimes) dataSet.getTravelTimes()).readSkim("bus", Resources.instance.getRelativePath(Properties.BUS_TRAVEL_TIME_SKIM).toString(), "mat1", 1/60.);
((SkimTravelTimes) dataSet.getTravelTimes()).readSkim("tramMetro", Resources.instance.getRelativePath(Properties.TRAM_METRO_TRAVEL_TIME_SKIM).toString(), "mat1", 1/60.);
((SkimTravelTimes) dataSet.getTravelTimes()).readSkim("train", Resources.instance.getRelativePath(Properties.TRAIN_TRAVEL_TIME_SKIM).toString(), "mat1", 1/60.);
}
private void readTravelDistances(){
- IndexedDoubleMatrix2D distanceSkimAuto = AbstractOmxReader.readAndConvertToDoubleMatrix(Resources.instance.getRelativePath(Properties.AUTO_TRAVEL_DISTANCE_SKIM).toString(),"distanceByTime", 1. / 1000.);
+ IndexedDoubleMatrix2D distanceSkimAuto = AbstractOmxReader.readAndConvertToDoubleMatrix(Resources.instance.getRelativePath(Properties.AUTO_TRAVEL_DISTANCE_SKIM).toString(),"mat1", 1. / 1000.);
dataSet.setTravelDistancesAuto(new MatrixTravelDistances(distanceSkimAuto));
- IndexedDoubleMatrix2D distanceSkimNMT = AbstractOmxReader.readAndConvertToDoubleMatrix(Resources.instance.getRelativePath(Properties.NMT_TRAVEL_DISTANCE_SKIM).toString(),"distanceByDistance", 1. / 1000.);
+ IndexedDoubleMatrix2D distanceSkimNMT = AbstractOmxReader.readAndConvertToDoubleMatrix(Resources.instance.getRelativePath(Properties.NMT_TRAVEL_DISTANCE_SKIM).toString(),"mat1", 1. / 1000.);
dataSet.setTravelDistancesNMT(new MatrixTravelDistances(distanceSkimNMT));
}
}
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/PersonsReader.java b/src/main/java/de/tum/bgu/msm/io/input/readers/PersonsReader.java
index c19e880a..8e539518 100644
--- a/src/main/java/de/tum/bgu/msm/io/input/readers/PersonsReader.java
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/PersonsReader.java
@@ -69,7 +69,7 @@ public void processRecord(String[] record) {
if(!dataSet.getHouseholds().containsKey(hhid)) {
logger.warn("Person " + id + " refers to non-existing household " + hhid + ". Ignoring this person.");
- return;
+ //return null;
}
MitoHousehold hh = dataSet.getHouseholds().get(hhid);
@@ -84,7 +84,11 @@ public void processRecord(String[] record) {
final int workplace = Integer.parseInt(record[posWorkplaceId]);
final int school = Integer.parseInt(record[posSchoolId]);
- final boolean driversLicense = Boolean.parseBoolean(record[posLicence]);
+ //final boolean driversLicense = Boolean.parseBoolean(record[posLicence]);
+ final boolean driversLicense = MitoGender.obtainLicense(mitoGender, age); // new, added by Alona, Quick fix for drivers license
+
+
+
//mito uses monthly income, while SILO uses annual income
int monthlyIncome_EUR = Integer.parseInt(record[posIncome])/12;
@@ -97,14 +101,14 @@ public void processRecord(String[] record) {
if(dataSet.getJobs().containsKey(workplace)) {
occupation = (dataSet.getJobs().get(workplace));
} else {
- logger.warn("Person " + id + " declared as student does not have a valid school!");
+ logger.warn("Person " + id + " declared as worker does not have a valid job!");
}
break;
case STUDENT:
if(dataSet.getSchools().containsKey(school)) {
occupation = (dataSet.getSchools().get(school));
} else {
- logger.warn("Person " + id + " declared as student does not have a valid school!");
+ //logger.warn("Person " + id + " declared as student does not have a valid school!");
}
break;
case UNEMPLOYED:
diff --git a/src/main/java/de/tum/bgu/msm/io/input/readers/SyntheticPopulationReaderGermany.java b/src/main/java/de/tum/bgu/msm/io/input/readers/SyntheticPopulationReaderGermany.java
new file mode 100644
index 00000000..17013e38
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/io/input/readers/SyntheticPopulationReaderGermany.java
@@ -0,0 +1,189 @@
+package de.tum.bgu.msm.io.input.readers;
+
+import de.tum.bgu.msm.data.*;
+import de.tum.bgu.msm.data.jobTypes.JobTypeFactory;
+import de.tum.bgu.msm.io.input.AbstractCsvReader;
+import de.tum.bgu.msm.resources.Resources;
+import org.apache.log4j.Logger;
+import org.locationtech.jts.geom.Coordinate;
+
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+
+
+public class SyntheticPopulationReaderGermany extends AbstractCsvReader {
+
+ private static final Logger logger = Logger.getLogger(SyntheticPopulationReaderGermany.class);
+ private final JobTypeFactory factory;
+
+ // Person
+ private int posId = -1;
+ private int posHhId = -1;
+ private int posAge = -1;
+ private int posSex = -1;
+ private int posOccupation = -1;
+ private int posWorkplaceId = -1;
+ private int posLicence = -1;
+ private int posIncome = -1;
+ private int posType = -1;
+ private int posSchoolId = -1;
+ private int posJobId = -1;
+ private int posZone = -1;
+ private int posJobCoordX = -1;
+ private int posJobCoordY = -1;
+ //private int posWorker = -1; // question
+
+ private int occupationCounter = 0;
+
+
+ // constructor
+ public SyntheticPopulationReaderGermany(DataSet dataSet, JobTypeFactory factory) {
+ super(dataSet);
+ this.factory = factory;
+ }
+
+
+ @Override
+ public void read() {
+ logger.info(" Reading person micro data from ascii file");
+ Path filePath = Resources.instance.getPersonsFilePath();
+ super.read(filePath, ",");
+ int noIncomeHouseholds = 0;
+ for(MitoHousehold household: dataSet.getHouseholds().values()) {
+ if(household.getMonthlyIncome_EUR() == 0) {
+ noIncomeHouseholds++;
+ }
+ }
+ if(noIncomeHouseholds > 0) {
+ logger.warn("There are " + noIncomeHouseholds + " households with no income after reading all persons.");
+ }
+ logger.info("There are " + occupationCounter + " persons without occupation (student or worker).");
+ }
+
+ @Override
+ public void processHeader(String[] header) {
+ List headerList = Arrays.asList(header);
+ posId = headerList.indexOf("id");
+ //posWorker = headerList.indexOf("id"); //
+ posHhId = headerList.indexOf("hhid");
+ posAge = headerList.indexOf("age");
+ posSex = headerList.indexOf("gender");
+ posOccupation = headerList.indexOf("occupation");
+ posLicence = headerList.indexOf("driversLicense");
+ posWorkplaceId = headerList.indexOf("JobId");
+ posIncome = headerList.indexOf("income");
+ //jobType
+ posType = headerList.indexOf("jobType");
+ posSchoolId = headerList.indexOf("schoolId");
+ //jobId
+ posJobId = headerList.indexOf("JobId");
+ //jobZone
+ posZone = headerList.indexOf("zone");
+ //jobCoordX & jobCoordY
+ posJobCoordX = headerList.indexOf("jobCoordX");
+ posJobCoordY = headerList.indexOf("jobCoordY");
+
+
+ }
+
+ @Override
+ public void processRecord(String[] record) {
+
+ final int id = Integer.parseInt(record[posId]);
+ final int hhid = Integer.parseInt(record[posHhId]);
+
+ if(!dataSet.getHouseholds().containsKey(hhid)) {
+ logger.warn("Person " + id + " refers to non-existing household " + hhid + ". Ignoring this person.");
+ //return null;
+ }
+ MitoHousehold hh = dataSet.getHouseholds().get(hhid);
+
+ final int age = Integer.parseInt(record[posAge]);
+
+ final int genderCode = Integer.parseInt(record[posSex]);
+ MitoGender mitoGender = MitoGender.valueOf(genderCode);
+
+ final int occupationCode = Integer.parseInt(record[posOccupation]);
+ MitoOccupationStatus mitoOccupationStatus = MitoOccupationStatus.valueOf(occupationCode);
+
+
+ //int workplace = -1;
+ //try{
+ // workplace = Integer.parseInt(record[posWorkplaceId]);
+ // } catch (Exception e ){
+ //logger.warn("No Work ID");
+ //}
+
+ //final int workplace = Integer.parseInt(record[posWorkplaceId]);
+ final int school = Integer.parseInt(record[posSchoolId]);
+
+ final boolean driversLicense = Boolean.parseBoolean(record[posLicence]);
+ //final boolean driversLicense = MitoGender.obtainLicense(mitoGender, age); // new, added by Alona, Quick fix for drivers license
+
+
+ //mito uses monthly income, while SILO uses annual income
+ int monthlyIncome_EUR = Integer.parseInt(record[posIncome])/12;
+ hh.addIncome(monthlyIncome_EUR);
+
+ MitoOccupation occupation = null;
+
+ switch (mitoOccupationStatus) {
+ case WORKER:
+ //if(dataSet.getJobs().containsKey(workplace)) {
+ int jobId = Integer.parseInt(record[posJobId]);
+ int zoneId = Integer.parseInt(record[posZone]);
+ String type = record[posType];
+ MitoZone zone = dataSet.getZones().get(zoneId);
+ if (zone == null) {
+ logger.warn(String.format("Job %d refers to non-existing zone %d! Ignoring it.",jobId, zoneId));
+ //return null;
+ }
+ try {
+ zone.addEmployeeForType(factory.getType(type.toUpperCase().replaceAll("\"","")));
+ } catch (IllegalArgumentException e) {
+ //logger.error("Job Type " + type + " used in job microdata but is not defined");
+ }
+
+ //Coordinate coordinate = zone.getRandomCoord(MitoUtil.getRandomObject());
+ Coordinate coordinate = (new Coordinate(Double.parseDouble(record[posJobCoordX]),
+ Double.parseDouble(record[posJobCoordY])));
+
+ //Coordinate coordinate = new Coordinate(Double.parseDouble(record[posJobCoordX]), Double.parseDouble(record[posJobCoordY]));
+
+ MitoJob job = new MitoJob(zone, coordinate, jobId);
+ dataSet.addJob(job);
+
+ int workplace = Integer.parseInt(record[posWorkplaceId]);
+ occupation = (dataSet.getJobs().get(workplace));
+
+ /*} else {
+ logger.warn("Person " + id + " declared as worker does not have a valid job!");
+ }*/
+ break;
+ case STUDENT:
+ if(dataSet.getSchools().containsKey(school)) {
+ occupation = (dataSet.getSchools().get(school));
+ } else {
+ //logger.warn("Person " + id + " declared as student does not have a valid school!");
+ }
+ break;
+ case UNEMPLOYED:
+ default:
+ logger.debug("Person " + id + " does not have an occupation.");
+ occupationCounter++;
+ break;
+ }
+ MitoPerson pp = new MitoPerson(id, mitoOccupationStatus, occupation, age, mitoGender, driversLicense);
+
+ //int worker = Integer.parseInt(record[posOccupation]); //int worker = Integer.parseInt(record[posWorker]);
+
+ //if (worker == 1) {
+
+
+ //MitoPerson pp = new MitoPerson(id, mitoOccupationStatus, occupation, age, mitoGender, driversLicense);
+
+ hh.addPerson(pp);
+ dataSet.addPerson(pp);
+ }
+}
diff --git a/src/main/java/de/tum/bgu/msm/modules/tripDistribution/DestinationUtilityCalculatorFactoryImplGermany.java b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/DestinationUtilityCalculatorFactoryImplGermany.java
new file mode 100644
index 00000000..02957ab4
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/DestinationUtilityCalculatorFactoryImplGermany.java
@@ -0,0 +1,11 @@
+package de.tum.bgu.msm.modules.tripDistribution;
+
+import de.tum.bgu.msm.data.Purpose;
+
+public class DestinationUtilityCalculatorFactoryImplGermany implements DestinationUtilityCalculatorFactory {
+
+ @Override
+ public DestinationUtilityCalculator createDestinationUtilityCalculator(Purpose purpose, double travelDistanceCalibrationK, double impendanceCalibrationK){
+ return new DestinationUtilityCalculatorImplGermany(purpose,travelDistanceCalibrationK, impendanceCalibrationK);
+ }
+}
diff --git a/src/main/java/de/tum/bgu/msm/modules/tripDistribution/DestinationUtilityCalculatorImplGermany.java b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/DestinationUtilityCalculatorImplGermany.java
new file mode 100644
index 00000000..22e82376
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/DestinationUtilityCalculatorImplGermany.java
@@ -0,0 +1,91 @@
+package de.tum.bgu.msm.modules.tripDistribution;
+
+import de.tum.bgu.msm.data.Purpose;
+
+public class DestinationUtilityCalculatorImplGermany implements DestinationUtilityCalculator {
+
+ private final static double TRAVEL_DISTANCE_PARAM_HBW = -0.01 * 0.545653257377378;
+ private final static double IMPEDANCE_PARAM_HBW = 20;
+
+ private final static double TRAVEL_DISTANCE_PARAM_HBE = -0.01 * 1.09211334287783;
+ private final static double IMPEDANCE_PARAM_HBE = 20;
+
+ private final static double TRAVEL_DISTANCE_PARAM_HBS = -0.01 * 1.382831732;
+ private final static double IMPEDANCE_PARAM_HBS = 20;
+
+ private final static double TRAVEL_DISTANCE_PARAM_HBO = -0.01 * 1.02679034779653;
+ private final static double IMPEDANCE_PARAM_HBO = 20;
+
+ private final static double TRAVEL_DISTANCE_PARAM_HBR = -0.01 * 0.874195571671594;
+ private final static double IMPEDANCE_PARAM_HBR = 20;
+
+ private final static double travelDistanceParamNhbw = -0.01 * 0.993491317833469;
+ private final static double impedanceParamNhbw = 20;
+
+ private final static double travelDistanceParamNhbo = -0.01 * 0.853890986777326;
+ private final static double impedanceParamNhbo = 20;
+
+ private double distanceParam;
+ private double impedanceParam;
+ private double maxDistance_km;
+ private double attractionParam = 1.;
+
+ DestinationUtilityCalculatorImplGermany(Purpose purpose, double travelDistanceCalibrationK, double impendanceCalibrationK) {
+ switch (purpose) {
+ case HBW:
+ distanceParam = TRAVEL_DISTANCE_PARAM_HBW;
+ impedanceParam = IMPEDANCE_PARAM_HBW;
+ //maxDistance_km = 200.0;
+ break;
+ case HBE:
+ distanceParam = TRAVEL_DISTANCE_PARAM_HBE;
+ impedanceParam = IMPEDANCE_PARAM_HBE;
+ //maxDistance_km = 200.0;
+ break;
+ case HBS:
+ distanceParam = TRAVEL_DISTANCE_PARAM_HBS;
+ impedanceParam = IMPEDANCE_PARAM_HBS;
+ //maxDistance_km = 40.;
+ break;
+ case HBO:
+ distanceParam = TRAVEL_DISTANCE_PARAM_HBO;
+ impedanceParam = IMPEDANCE_PARAM_HBO;
+ //maxDistance_km = 40.;
+ break;
+ case HBR:
+ distanceParam = TRAVEL_DISTANCE_PARAM_HBR;
+ impedanceParam = IMPEDANCE_PARAM_HBR;
+ //maxDistance_km = 40.;
+ break;
+ case NHBW:
+ distanceParam = travelDistanceParamNhbw;
+ impedanceParam = impedanceParamNhbw;
+ //maxDistance_km = 40.;
+ break;
+ case NHBO:
+ distanceParam = travelDistanceParamNhbo;
+ impedanceParam = impedanceParamNhbo;
+ //maxDistance_km = 40.;
+ break;
+ case AIRPORT:
+ default:
+ throw new RuntimeException("not implemented!");
+ }
+
+ distanceParam = distanceParam * travelDistanceCalibrationK;
+ impedanceParam = impedanceParam * impendanceCalibrationK;
+
+ }
+
+ @Override
+ public double calculateUtility(double attraction, double travelDistance) {
+ if(attraction == 0) {
+ return 0.;
+ }
+ //if(travelDistance > maxDistance_km){
+ // return 0.;
+ //}
+ double impedance = impedanceParam * Math.exp(distanceParam * travelDistance);
+ return Math.exp(impedance) * Math.pow(attraction, attractionParam);
+ }
+}
diff --git a/src/main/java/de/tum/bgu/msm/modules/tripDistribution/TripDistributionCalibration.java b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/TripDistributionCalibration.java
index 256b3865..7e45874a 100644
--- a/src/main/java/de/tum/bgu/msm/modules/tripDistribution/TripDistributionCalibration.java
+++ b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/TripDistributionCalibration.java
@@ -1,24 +1,18 @@
package de.tum.bgu.msm.modules.tripDistribution;
-import com.google.common.math.Quantiles;
import de.tum.bgu.msm.data.DataSet;
import de.tum.bgu.msm.data.MitoOccupationStatus;
import de.tum.bgu.msm.data.MitoTrip;
import de.tum.bgu.msm.data.Purpose;
import de.tum.bgu.msm.modules.Module;
import de.tum.bgu.msm.resources.Resources;
-import org.apache.commons.math.exception.MathIllegalNumberException;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
-import java.security.Principal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.DoubleStream;
public class TripDistributionCalibration extends Module {
diff --git a/src/main/java/de/tum/bgu/msm/modules/tripDistribution/TripDistributionCalibrationGermany.java b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/TripDistributionCalibrationGermany.java
new file mode 100644
index 00000000..b97df95b
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/TripDistributionCalibrationGermany.java
@@ -0,0 +1,132 @@
+package de.tum.bgu.msm.modules.tripDistribution;
+
+import de.tum.bgu.msm.data.DataSet;
+import de.tum.bgu.msm.data.MitoOccupationStatus;
+import de.tum.bgu.msm.data.MitoTrip;
+import de.tum.bgu.msm.data.Purpose;
+import de.tum.bgu.msm.modules.Module;
+import de.tum.bgu.msm.resources.Resources;
+
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+public class TripDistributionCalibrationGermany extends Module {
+
+ private Map observedAverageDistances = new HashMap<>();
+ private Map simulatedAverageDistances = new HashMap<>();
+ private Map travelDistanceParameters;
+ private Map impendanceParameters;
+ private PrintWriter pw = null;
+ private int iteration;
+
+ public TripDistributionCalibrationGermany(DataSet dataSet, List purposes,
+ Map travelDistanceParameters,
+ Map impendanceParameters) {
+
+ super(dataSet, purposes);
+ iteration = 0;
+ observedAverageDistances.put(Purpose.HBE, 7.29);
+ observedAverageDistances.put(Purpose.HBW, 18.1);
+ observedAverageDistances.put(Purpose.HBO, 7.96);
+ observedAverageDistances.put(Purpose.HBR, 9.76);
+ observedAverageDistances.put(Purpose.HBS, 6.46);
+ observedAverageDistances.put(Purpose.NHBO, 7.47);
+ observedAverageDistances.put(Purpose.NHBW, 9.54);
+
+ String purposesString = "";
+ for (Purpose purpose : purposes) {
+ purposesString += "_" + purpose.toString();
+ }
+
+ this.impendanceParameters = impendanceParameters;
+ this.travelDistanceParameters = travelDistanceParameters;
+
+ String path = Resources.instance.getBaseDirectory().toString() + "/scenOutput/";
+
+ try {
+ pw = new PrintWriter(path + "dc_calibration" + purposesString + ".csv");
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ }
+ pw.println("iteration,purpose,observed,simulated,factorDistance,factorImpedance");
+
+ }
+
+
+ public void update(int iteration) {
+
+ for (Purpose purpose : purposes) {
+
+ int count = 0;
+ double sum = 0;
+ List tripsThisPurpose =
+ dataSet.getTrips().values().stream().filter(t -> t.getTripPurpose().equals(purpose)).collect(Collectors.toList());
+
+ if (Purpose.getMandatoryPurposes().contains(purpose)) {
+ tripsThisPurpose.removeIf(trip -> trip.getPerson().getMitoOccupationStatus().equals(MitoOccupationStatus.WORKER) ||
+ trip.getPerson().getMitoOccupationStatus().equals(MitoOccupationStatus.STUDENT));
+ }
+
+
+ for (MitoTrip trip : tripsThisPurpose) {
+ if (dataSet.getTravelDistancesAuto().
+ getTravelDistance(trip.getTripOrigin().getZoneId(), trip.getTripDestination().getZoneId()) < 2000) {
+ count++;
+ sum += dataSet.getTravelDistancesAuto().
+ getTravelDistance(trip.getTripOrigin().getZoneId(), trip.getTripDestination().getZoneId());
+ }
+ }
+
+ double avg = sum / count;
+
+ //double[] distances = tripsThisPurpose.stream().mapToDouble(this::getDistanceOfThisTrip).toArray();
+
+
+ //double avg = Quantiles.median().compute(distances);
+
+
+ simulatedAverageDistances.put(purpose, avg);
+ double ratio = avg / observedAverageDistances.get(purpose); //greater than 1 if the model simulates too long trips
+ // - in this case, the parameter of distance needs to be larger (more negative)
+ ratio = Math.max(ratio, 0.5);
+ ratio = Math.min(ratio, 2);
+
+
+ travelDistanceParameters.put(purpose, travelDistanceParameters.get(purpose) * ratio);
+ pw.println(iteration + "," +
+ purpose + "," +
+ observedAverageDistances.get(purpose) + "," +
+ simulatedAverageDistances.get(purpose) + "," +
+ travelDistanceParameters.get(purpose) + "," +
+ impendanceParameters.get(purpose));
+
+ }
+
+ }
+
+ private double getDistanceOfThisTrip(MitoTrip trip) {
+ return dataSet.getTravelDistancesAuto().
+ getTravelDistance(trip.getTripOrigin().getZoneId(), trip.getTripDestination().getZoneId());
+ }
+
+
+ @Override
+ public void run() {
+ }
+
+ public Map getTravelDistanceParameters() {
+ return travelDistanceParameters;
+ }
+
+ public Map getImpendanceParameters() {
+ return impendanceParameters;
+ }
+
+ public void close() {
+ pw.close();
+ }
+}
diff --git a/src/main/java/de/tum/bgu/msm/modules/tripDistribution/destinationChooser/HbeHbwDistribution.java b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/destinationChooser/HbeHbwDistribution.java
index d5d71b76..7a987c1d 100644
--- a/src/main/java/de/tum/bgu/msm/modules/tripDistribution/destinationChooser/HbeHbwDistribution.java
+++ b/src/main/java/de/tum/bgu/msm/modules/tripDistribution/destinationChooser/HbeHbwDistribution.java
@@ -69,13 +69,14 @@ public Void call() {
private void findDestination(MitoHousehold household, MitoTrip trip) {
if (isFixedByOccupation(trip)) {
- trip.setTripDestination(trip.getPerson().getOccupation());
+ trip.setTripDestination(trip.getPerson().getOccupation());
} else {
TripDistribution.randomOccupationDestinationTrips.incrementAndGet();
IndexedDoubleMatrix1D probabilities = baseProbabilities.viewRow(household.getHomeZone().getId());
final int internalIndex = MitoUtil.select(probabilities.toNonIndexedArray(), random, probabilities.zSum());
final MitoZone destination = zonesCopy.get(probabilities.getIdForInternalIndex(internalIndex));
trip.setTripDestination(destination);
+
}
}
diff --git a/src/main/java/de/tum/bgu/msm/modules/tripGeneration/TripsByPurposeGeneratorSampleEnumeration.java b/src/main/java/de/tum/bgu/msm/modules/tripGeneration/TripsByPurposeGeneratorSampleEnumeration.java
index d022a9b9..e09858a0 100644
--- a/src/main/java/de/tum/bgu/msm/modules/tripGeneration/TripsByPurposeGeneratorSampleEnumeration.java
+++ b/src/main/java/de/tum/bgu/msm/modules/tripGeneration/TripsByPurposeGeneratorSampleEnumeration.java
@@ -63,7 +63,7 @@ private void generateTripsForHousehold(MitoHousehold hh, double scaleFactorForGe
return;
}
if (MitoUtil.getSum(tripFrequencies) == 0) {
- logger.info("No trips for this hhType/Purpose: " + hhType.getId() + "/" + purpose);
+ //logger.info("No trips for this hhType/Purpose: " + hhType.getId() + "/" + purpose);
return;
}
diff --git a/src/main/java/de/tum/bgu/msm/run/MitoGermany.java b/src/main/java/de/tum/bgu/msm/run/MitoGermany.java
new file mode 100644
index 00000000..6abe340d
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/run/MitoGermany.java
@@ -0,0 +1,57 @@
+package de.tum.bgu.msm.run;
+
+import de.tum.bgu.msm.MitoModelGermany;
+import de.tum.bgu.msm.data.DataSet;
+import de.tum.bgu.msm.resources.Properties;
+import de.tum.bgu.msm.resources.Resources;
+import de.tum.bgu.msm.trafficAssignment.CarSkimUpdater;
+import de.tum.bgu.msm.trafficAssignment.ConfigureMatsim;
+import de.tum.bgu.msm.util.munich.MunichImplementationConfig;
+import org.apache.log4j.Logger;
+import org.matsim.core.config.Config;
+import org.matsim.core.config.ConfigUtils;
+import org.matsim.core.controler.Controler;
+import org.matsim.core.scenario.MutableScenario;
+import org.matsim.core.scenario.ScenarioUtils;
+
+public class MitoGermany {
+
+ private static final Logger logger = Logger.getLogger(MitoGermany.class);
+
+ public static void main(String[] args) {
+ logger.info("Started the Microsimulation Transport Orchestrator (MITO) based on 2017 models");
+ MitoModelGermany model = MitoModelGermany.standAloneModel(args[0], MunichImplementationConfig.get());
+ model.run();
+ final DataSet dataSet = model.getData();
+
+ boolean runAssignment = Resources.instance.getBoolean(Properties.RUN_TRAFFIC_ASSIGNMENT, false);
+
+ if (runAssignment) {
+ logger.info("Running traffic assignment in MATsim");
+
+ Config config;
+ if (args.length > 1 && args[1] != null) {
+ config = ConfigUtils.loadConfig(args[1]);
+ ConfigureMatsim.setDemandSpecificConfigSettings(config);
+ } else {
+ logger.warn("Using a fallback config with default values as no initial config has been provided.");
+ config = ConfigureMatsim.configureMatsim();
+ }
+
+ String outputSubDirectory = "scenOutput/" + model.getScenarioName() + "/" + dataSet.getYear();
+ config.controler().setOutputDirectory(Resources.instance.getBaseDirectory().toString() + "/" + outputSubDirectory + "/trafficAssignment");
+
+ MutableScenario matsimScenario = (MutableScenario) ScenarioUtils.loadScenario(config);
+ matsimScenario.setPopulation(dataSet.getPopulation());
+
+ Controler controler = new Controler(matsimScenario);
+ controler.run();
+
+ if (Resources.instance.getBoolean(Properties.PRINT_OUT_SKIM, false)) {
+ CarSkimUpdater skimUpdater = new CarSkimUpdater(controler, model.getData(), model.getScenarioName());
+ skimUpdater.run();
+ }
+ }
+ }
+}
+
diff --git a/src/main/java/de/tum/bgu/msm/run/calibration/CalibrateDestinationChoiceGermany.java b/src/main/java/de/tum/bgu/msm/run/calibration/CalibrateDestinationChoiceGermany.java
new file mode 100644
index 00000000..7374b477
--- /dev/null
+++ b/src/main/java/de/tum/bgu/msm/run/calibration/CalibrateDestinationChoiceGermany.java
@@ -0,0 +1,249 @@
+package de.tum.bgu.msm.run.calibration;
+
+import de.tum.bgu.msm.data.DataSet;
+import de.tum.bgu.msm.data.Purpose;
+import de.tum.bgu.msm.data.travelTimes.SkimTravelTimes;
+import de.tum.bgu.msm.io.input.readers.*;
+import de.tum.bgu.msm.modules.Module;
+import de.tum.bgu.msm.modules.modeChoice.ModeChoice;
+import de.tum.bgu.msm.modules.timeOfDay.TimeOfDayChoice;
+import de.tum.bgu.msm.modules.travelTimeBudget.TravelTimeBudgetModule;
+import de.tum.bgu.msm.modules.tripDistribution.DestinationUtilityCalculatorFactoryImplGermany;
+import de.tum.bgu.msm.modules.tripDistribution.TripDistribution;
+import de.tum.bgu.msm.modules.tripDistribution.TripDistributionCalibrationGermany;
+import de.tum.bgu.msm.modules.tripGeneration.TripGeneration;
+import de.tum.bgu.msm.modules.tripGeneration.TripsByPurposeGeneratorFactoryPersonBasedHurdle;
+import de.tum.bgu.msm.resources.Properties;
+import de.tum.bgu.msm.resources.Resources;
+import de.tum.bgu.msm.util.ImplementationConfig;
+import de.tum.bgu.msm.util.MitoUtil;
+import de.tum.bgu.msm.util.munich.MunichImplementationConfig;
+import org.apache.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+
+/**
+ * Implements the Microsimulation Transport Orchestrator (MITO)
+ *
+ * @author Rolf Moeckel
+ * Created on Sep 18, 2016 in Munich, Germany
+ *
+ * To run MITO, the following data need either to be passed in from another program or
+ * need to be read from files and passed in (using method initializeStandAlone):
+ * - zones
+ * - autoTravelTimes
+ * - transitTravelTimes
+ * - timoHouseholds
+ * - retailEmplByZone
+ * - officeEmplByZone
+ * - otherEmplByZone
+ * - totalEmplByZone
+ * - sizeOfZonesInAcre
+ */
+public final class CalibrateDestinationChoiceGermany {
+
+ private static final Logger logger = Logger.getLogger(CalibrateDestinationChoiceGermany.class);
+ private final String scenarioName;
+
+ private DataSet dataSet;
+
+ public static void main(String[] args) {
+ CalibrateDestinationChoiceGermany model = CalibrateDestinationChoiceGermany.standAloneModel(args[0], MunichImplementationConfig.get());
+ model.run();
+ }
+
+ private CalibrateDestinationChoiceGermany(DataSet dataSet, String scenarioName) {
+ this.dataSet = dataSet;
+ this.scenarioName = scenarioName;
+ MitoUtil.initializeRandomNumber();
+ }
+
+ public static CalibrateDestinationChoiceGermany standAloneModel(String propertiesFile, ImplementationConfig config) {
+ logger.info(" Creating standalone version of MITO ");
+ Resources.initializeResources(propertiesFile);
+ CalibrateDestinationChoiceGermany model = new CalibrateDestinationChoiceGermany(new DataSet(), Resources.instance.getString(Properties.SCENARIO_NAME));
+ model.readStandAlone(config);
+ return model;
+ }
+
+ public static CalibrateDestinationChoiceGermany initializeModelFromSilo(String propertiesFile, DataSet dataSet, String scenarioName) {
+ logger.info(" Initializing MITO from SILO");
+ Resources.initializeResources(propertiesFile);
+ CalibrateDestinationChoiceGermany model = new CalibrateDestinationChoiceGermany(dataSet, scenarioName);
+ new OmxSkimsReader(dataSet).readOnlyTransitTravelTimes();
+ new OmxSkimsReader(dataSet).readSkimDistancesNMT();
+ new OmxSkimsReader(dataSet).readSkimDistancesAuto();
+ model.readAdditionalData();
+ return model;
+ }
+
+ public void run() {
+ long startTime = System.currentTimeMillis();
+ logger.info("Started the Microsimulation Transport Orchestrator (MITO)");
+ Module tripGenerationMandatory;
+ Module personTripAssignmentMandatory;
+ Module travelTimeBudgetMandatory;
+ Module distributionMandatory;
+ Module modeChoiceMandatory;
+ Module timeOfDayChoiceMandatory;
+
+ Module tripGenerationDiscretionary;
+ Module personTripAssignmentDiscretionary;
+ Module travelTimeBudgetDiscretionary;
+ Module distributionDiscretionary;
+ Module modeChoiceDiscretionary;
+ Module timeOfDayChoiceDiscretionary;
+
+ List purposes = Purpose.getAllPurposes();
+ tripGenerationMandatory = new TripGeneration(dataSet, new TripsByPurposeGeneratorFactoryPersonBasedHurdle(), Purpose.getMandatoryPurposes());
+ tripGenerationMandatory.run();
+
+ travelTimeBudgetMandatory = new TravelTimeBudgetModule(dataSet, Purpose.getMandatoryPurposes());
+ travelTimeBudgetMandatory.run();
+
+ Map travelDistanceCalibrationParameters = new HashMap<>();
+ Map impedanceCalibrationParameters = new HashMap<>();
+
+ Purpose.getMandatoryPurposes().forEach(p -> {
+ travelDistanceCalibrationParameters.put(p, 1.0);
+ impedanceCalibrationParameters.put(p, 1.0);
+ });
+
+ distributionMandatory = new TripDistribution(dataSet, Purpose.getMandatoryPurposes(),
+ travelDistanceCalibrationParameters,
+ impedanceCalibrationParameters, false, new DestinationUtilityCalculatorFactoryImplGermany());
+ distributionMandatory.run();
+
+ TripDistributionCalibrationGermany tripDistributionCalibrationMandatory =
+ new TripDistributionCalibrationGermany(dataSet, Purpose.getMandatoryPurposes(),
+ travelDistanceCalibrationParameters, impedanceCalibrationParameters);
+
+ int iterations = 20;
+ for (int iteration = 0; iteration < iterations; iteration++) {
+ tripDistributionCalibrationMandatory.update(iteration);
+ distributionMandatory = new TripDistribution(dataSet, Purpose.getMandatoryPurposes(),
+ tripDistributionCalibrationMandatory.getTravelDistanceParameters(),
+ tripDistributionCalibrationMandatory.getImpendanceParameters(), false, new DestinationUtilityCalculatorFactoryImplGermany());
+ distributionMandatory.run();
+ }
+
+ tripDistributionCalibrationMandatory.close();
+
+ modeChoiceMandatory = new ModeChoice(dataSet, Purpose.getMandatoryPurposes());
+ modeChoiceMandatory.run();
+
+ timeOfDayChoiceMandatory = new TimeOfDayChoice(dataSet, Purpose.getMandatoryPurposes());
+ timeOfDayChoiceMandatory.run();
+
+ tripGenerationDiscretionary = new TripGeneration(dataSet, new TripsByPurposeGeneratorFactoryPersonBasedHurdle(), Purpose.getDiscretionaryPurposes());
+ //personTripAssignmentDiscretionary = new PersonTripAssignment(dataSet, Purpose.getDiscretionaryPurposes());
+ travelTimeBudgetDiscretionary = new TravelTimeBudgetModule(dataSet, Purpose.getDiscretionaryPurposes());
+
+ modeChoiceDiscretionary = new ModeChoice(dataSet, Purpose.getDiscretionaryPurposes());
+ timeOfDayChoiceDiscretionary = new TimeOfDayChoice(dataSet, Purpose.getDiscretionaryPurposes());
+
+
+ tripGenerationDiscretionary.run();
+ //logger.info("Running Module: Person to Trip Assignment");
+ //personTripAssignmentDiscretionary.run();
+ logger.info("Running Module: Travel Time Budget Calculation");
+ travelTimeBudgetDiscretionary.run();
+ ((TravelTimeBudgetModule) travelTimeBudgetDiscretionary).adjustDiscretionaryPurposeBudgets();
+ logger.info("Running Module: Microscopic Trip Distribution");
+
+
+ Map travelDistanceCalibrationParametersDisc = new HashMap<>();
+ Map impedanceCalibrationParametersDisc = new HashMap<>();
+
+ Purpose.getDiscretionaryPurposes().forEach(p -> {
+ travelDistanceCalibrationParametersDisc.put(p, 1.0);
+ impedanceCalibrationParametersDisc.put(p, 1.0);
+ });
+
+ distributionDiscretionary = new TripDistribution(dataSet, Purpose.getDiscretionaryPurposes(),
+ travelDistanceCalibrationParametersDisc,
+ impedanceCalibrationParametersDisc, false,
+ new DestinationUtilityCalculatorFactoryImplGermany());
+ distributionDiscretionary.run();
+
+
+ TripDistributionCalibrationGermany tripDistributionCalibrationDiscretionary =
+ new TripDistributionCalibrationGermany(dataSet, Purpose.getDiscretionaryPurposes(),
+ travelDistanceCalibrationParametersDisc, impedanceCalibrationParametersDisc);
+
+ for (int iteration = 0; iteration < iterations; iteration++) {
+ tripDistributionCalibrationDiscretionary.update(iteration);
+ distributionDiscretionary = new TripDistribution(dataSet, Purpose.getDiscretionaryPurposes(),
+ tripDistributionCalibrationDiscretionary.getTravelDistanceParameters(),
+ tripDistributionCalibrationDiscretionary.getImpendanceParameters(), false,
+ new DestinationUtilityCalculatorFactoryImplGermany());
+ distributionDiscretionary.run();
+ }
+
+ tripDistributionCalibrationDiscretionary.close();
+
+
+
+ logger.info("Running Module: Trip to Mode Assignment (Mode Choice)");
+ modeChoiceDiscretionary.run();
+ logger.info("Running time of day choice");
+ timeOfDayChoiceDiscretionary.run();
+
+
+ }
+
+ private void readStandAlone(ImplementationConfig config) {
+ dataSet.setYear(Resources.instance.getInt(Properties.SCENARIO_YEAR));
+ new ZonesReader(dataSet).read();
+ if (Resources.instance.getBoolean(Properties.REMOVE_TRIPS_AT_BORDER)) {
+ new BorderDampersReader(dataSet).read();
+ }
+ //new JobReader(dataSet, config.getJobTypeFactory()).read();
+ new SchoolsReader(dataSet).read();
+ new HouseholdsReaderGermany(dataSet).read();
+ //new HouseholdsCoordReader(dataSet).read();
+ //new PersonsReader(dataSet).read();
+ //the class called Synthetic population reader: could it be renamed to PersonJobReader?
+ new SyntheticPopulationReaderGermany(dataSet, config.getJobTypeFactory()).read();
+ dataSet.setTravelTimes(new SkimTravelTimes());
+ new OmxSkimsReader(dataSet).read();
+ readAdditionalData();
+ }
+
+ private void readAdditionalData() {
+ new TripAttractionRatesReader(dataSet).read();
+ new ModeChoiceInputReader(dataSet).read();
+ new EconomicStatusReader(dataSet).read();
+ new TimeOfDayDistributionsReader(dataSet).read();
+ new CalibrationDataReader(dataSet).read();
+ new CalibrationRegionMapReader(dataSet).read();
+
+ }
+
+ private void printOutline(long startTime) {
+ String trips = MitoUtil.customFormat(" " + "###,###", dataSet.getTrips().size());
+ logger.info("A total of " + trips.trim() + " microscopic trips were generated");
+ logger.info("Completed the Microsimulation Transport Orchestrator (MITO)");
+ float endTime = MitoUtil.rounder(((System.currentTimeMillis() - startTime) / 60000.f), 1);
+ int hours = (int) (endTime / 60);
+ int min = (int) (endTime - 60 * hours);
+ logger.info("Runtime: " + hours + " hours and " + min + " minutes.");
+ }
+
+ public DataSet getData() {
+ return dataSet;
+ }
+
+ public String getScenarioName() {
+ return scenarioName;
+ }
+
+ public void setRandomNumberGenerator(Random random) {
+ MitoUtil.initializeRandomNumber(random);
+ }
+
+
+}
diff --git a/src/main/java/de/tum/bgu/msm/trafficAssignment/TripCSVToMATSimPlan.java b/src/main/java/de/tum/bgu/msm/trafficAssignment/TripCSVToMATSimPlan.java
index 9f79c25c..d18beec0 100644
--- a/src/main/java/de/tum/bgu/msm/trafficAssignment/TripCSVToMATSimPlan.java
+++ b/src/main/java/de/tum/bgu/msm/trafficAssignment/TripCSVToMATSimPlan.java
@@ -1,6 +1,10 @@
package de.tum.bgu.msm.trafficAssignment;
+import de.tum.bgu.msm.data.MitoTrip;
import de.tum.bgu.msm.data.Purpose;
+import de.tum.bgu.msm.resources.Properties;
+import de.tum.bgu.msm.resources.Resources;
+import de.tum.bgu.msm.util.MitoUtil;
import org.matsim.api.core.v01.Coord;
import org.matsim.api.core.v01.Id;
import org.matsim.api.core.v01.Scenario;
@@ -17,180 +21,295 @@
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
+import java.util.Random;
import java.util.Set;
public class TripCSVToMATSimPlan {
- // This class will read trip lists in CSV from MITO and creates a MATSim XML
- // plan file
- private static String delimiter = ",";
-
- private static String filename;
- private static PopulationFactory factory;
- private static Network carNetwork;
-
- public static void main(String[] args) {
- // TODO add logging
- filename = args[0];
- String networkFile = args[1];
-
- Config config = ConfigUtils.createConfig();
- config.network().setInputFile(networkFile);
-
- Scenario scenario = ScenarioUtils.loadScenario(config);
- TransportModeNetworkFilter filter = new TransportModeNetworkFilter(scenario.getNetwork());
- Set modesCar = new HashSet<>();
- modesCar.add("car");
- carNetwork = NetworkUtils.createNetwork();
- filter.filter(carNetwork, modesCar);
-
- Population population = PopulationUtils.createPopulation(config);
- factory = population.getFactory();
-
- try {
- FileReader in = null;
- BufferedReader br = null;
- try {
- in = new FileReader(filename);
- br = new BufferedReader(in);
-
- String line;
- int i = 0;
- br.readLine(); // skip CSV header
- while ((line = br.readLine()) != null) {
- Person p = createPersonFromTrip(i++, line);
- if (p != null) {
- population.addPerson(p);
- }
- }
- } finally {
- if (br != null) {
- br.close();
- }
-
- if (in != null) {
- in.close();
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
-
- PopulationWriter popwriter = new PopulationWriter(population);
- popwriter.write(filename + ".xml.gz");
-
- System.out.println("done.");
- }
-
- private static Person createPersonFromTrip(int i, String line) {
- Trip t = new Trip(line);
-
- String mode = decodeMode(t.mode);
- Id matsimId = Id.createPersonId(t.person + "_" + i);
-
- Person p = factory.createPerson(Id.createPersonId(matsimId));
- Plan plan = factory.createPlan();
-
- Purpose purpose = Purpose.valueOf(t.purpose);
- boolean roundTrip = !(purpose.equals(Purpose.NHBW) || purpose.equals(Purpose.NHBO));
-
- String firstActivityType = getOriginActivity(purpose);
- Coord firstCoord = new Coord(t.originX, t.originY);
-
- Activity firstAct = factory.createActivityFromCoord(firstActivityType, firstCoord);
- firstAct.setLinkId(NetworkUtils.getNearestLink(carNetwork, firstCoord).getId());
-
- firstAct.setEndTime(t.departure_time);
- plan.addActivity(firstAct);
-
- Leg firstLeg = factory.createLeg(mode);
- firstLeg.setDepartureTime(t.departure_time);
- plan.addLeg(firstLeg);
-
- String secondActivityType = getDestinationActivity(purpose);
- Coord secondCoord = new Coord(t.destinationX, t.destinationY);
-
- Activity secondAct = factory.createActivityFromCoord(secondActivityType, secondCoord);
- secondAct.setLinkId(NetworkUtils.getNearestLink(carNetwork, secondCoord).getId());
- secondAct.setStartTime(t.departure_time + 1); // TODO include MITO's travel time estimations
-
- if (roundTrip) {
- secondAct.setEndTime(t.departure_time_return);
- plan.addActivity(secondAct);
- }
-
- if (roundTrip) {
- Leg secondLeg = factory.createLeg(mode);
- secondLeg.setDepartureTime(t.departure_time_return);
- plan.addLeg(secondLeg);
-
- Activity thirdAct = factory.createActivityFromCoord(firstActivityType, firstCoord);
- thirdAct.setLinkId(NetworkUtils.getNearestLink(carNetwork, firstCoord).getId());
- thirdAct.setStartTime(t.departure_time_return + 1); // TODO include MITO's travel time estimations
- plan.addActivity(thirdAct);
- }
-
- p.addPlan(plan);
- p.setSelectedPlan(plan);
- return p;
- }
-
- private static String getDestinationActivity(Purpose purpose) {
- return "";
- }
-
- private static String getOriginActivity(Purpose purpose) {
- return "";
- }
-
- private static String decodeMode(String encodedMode) {
- switch (encodedMode) {
- case "autoDriver":
- return "car";
- case "autoPassenger":
- return "car_passenger";
- case "train":
- case "bus":
- case "tramOrMetro":
- return "pt";
- case "bicycle":
- return "bike";
- default:
- return encodedMode;
- }
- }
-
- public final static class Trip {
- public final double originX;
- public final double originY;
- public final double destinationX;
- public final double destinationY;
- public final String purpose;
- public final String person;
- public final double distance;
- public final String mode;
- public final double departure_time;
- public final double departure_time_return;
-
- public Trip(String line) {
- String[] data = line.split(delimiter);
- this.originX = Double.parseDouble(data[2]);
- this.originY = Double.parseDouble(data[3]);
- this.destinationX = Double.parseDouble(data[5]);
- this.destinationY = Double.parseDouble(data[6]);
- this.purpose = data[7];
- this.person = data[8];
- this.distance = Double.parseDouble(data[9]);
- this.mode = data[14];
- // departure time comes in minutes, needed as seconds
- this.departure_time = Double.parseDouble(data[15]) * 60;
-
- if (data.length >= 17) {
- this.departure_time_return = Double.parseDouble(data[16]) * 60;
- }
- else {
- this.departure_time_return = -1;
- }
- }
- }
+ private static final double SPEED_WALK_KMH = 5.;
+ private static final double SPEED_BICYCLE_KMH = 12.;
+ // This class will read trip lists in CSV from MITO and creates a MATSim XML
+ // plan file
+ private static String delimiter = ",";
+
+ private static String filename;
+ private static PopulationFactory factory;
+ private static Network carNetwork;
+
+ private static double scaleFactor = 0.20;
+ private static Random random = new Random(0);
+
+ private static int posId;
+ private static int posOriginX;
+ private static int posOriginY;
+ private static int posDestinationX;
+ private static int posDestinationY;
+ private static int posPurpose;
+ private static int posPersonId;
+ private static int posMode;
+ private static int posDistance;
+ private static int posTimeCar;
+ private static int posTimeTrain;
+ private static int posTimeMetroTram;
+ private static int posTimeBus;
+ private static int posDepartureTime;
+ private static int posDepartureTimeReturn;
+
+ private static Set modesCar = new HashSet<>();
+ private static Set modesAssignment = new HashSet<>();
+
+ public static void main(String[] args) {
+ // TODO add logging
+ filename = args[0];
+ //String networkFile = args[1];
+
+ Config config = ConfigUtils.createConfig();
+ //config.network().setInputFile(networkFile);
+
+
+
+ Scenario scenario = ScenarioUtils.loadScenario(config);
+ TransportModeNetworkFilter filter = new TransportModeNetworkFilter(scenario.getNetwork());
+
+ modesCar.add("car");
+ modesAssignment.add("car");
+ carNetwork = NetworkUtils.createNetwork();
+ filter.filter(carNetwork, modesCar);
+
+ Population population = PopulationUtils.createPopulation(config);
+ factory = population.getFactory();
+
+ try {
+ FileReader in = null;
+ BufferedReader br = null;
+ try {
+ in = new FileReader(filename);
+ br = new BufferedReader(in);
+
+ String line;
+ int i = 0;
+ String[] header = br.readLine().split(delimiter); // read CSV header to find names and positions
+
+ posId = MitoUtil.findPositionInArray("id", header);
+ posOriginX = MitoUtil.findPositionInArray("originX", header);
+ posOriginY = MitoUtil.findPositionInArray("originY", header);
+ posDestinationX = MitoUtil.findPositionInArray("destinationX", header);
+ posDestinationY = MitoUtil.findPositionInArray("destinationY", header);
+ posPurpose = MitoUtil.findPositionInArray("purpose", header);
+ posPersonId = MitoUtil.findPositionInArray("person", header);
+ posMode = MitoUtil.findPositionInArray("mode", header);
+ posDistance = MitoUtil.findPositionInArray("distance", header);
+ posTimeCar = MitoUtil.findPositionInArray("time_auto", header);
+ posTimeTrain = MitoUtil.findPositionInArray("time_train", header);
+ posTimeMetroTram = MitoUtil.findPositionInArray("time_tram_metro", header);
+ posTimeBus = MitoUtil.findPositionInArray("time_bus", header);
+ posDepartureTime = MitoUtil.findPositionInArray("departure_time", header);
+ posDepartureTimeReturn = MitoUtil.findPositionInArray("departure_time_return", header);
+
+
+ while ((line = br.readLine()) != null) {
+ Person p = createPersonFromTrip(i++, line);
+ if (p != null) {
+ population.addPerson(p);
+ }
+ }
+ } finally {
+ if (br != null) {
+ br.close();
+ }
+
+ if (in != null) {
+ in.close();
+ }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ PopulationWriter popwriter = new PopulationWriter(population);
+ popwriter.write("externalDemand/sd_trips" + ".xml.gz");
+
+ System.out.println("done.");
+ }
+
+ private static Person createPersonFromTrip(int i, String line) {
+
+ Trip t = new Trip(line);
+
+ String mode = decodeMode(t.mode);
+
+ if (mode.equals("null")) {
+ return null;
+ //not a valid trip record
+ }
+
+ if (random.nextDouble() > scaleFactor){
+ return null;
+ }
+
+ if (!modesAssignment.contains(mode)){
+ return null;
+ }
+
+ Id matsimId = Id.createPersonId(t.person + "_" + i);
+
+ Person p = factory.createPerson(Id.createPersonId(matsimId));
+ Plan plan = factory.createPlan();
+
+ Purpose purpose = Purpose.valueOf(t.purpose);
+ boolean roundTrip = !(purpose.equals(Purpose.NHBW) || purpose.equals(Purpose.NHBO));
+
+ String firstActivityType = getOriginActivity(purpose);
+ Coord firstCoord = new Coord(t.originX, t.originY);
+
+ Activity firstAct = factory.createActivityFromCoord(firstActivityType, firstCoord);
+ //firstAct.setLinkId(NetworkUtils.getNearestLink(carNetwork, firstCoord).getId());
+
+ firstAct.setEndTime(t.departure_time);
+ plan.addActivity(firstAct);
+
+ Leg firstLeg = factory.createLeg(mode);
+ firstLeg.setDepartureTime(t.departure_time);
+ plan.addLeg(firstLeg);
+
+ String secondActivityType = getDestinationActivity(purpose);
+ Coord secondCoord = new Coord(t.destinationX, t.destinationY);
+
+ Activity secondAct = factory.createActivityFromCoord(secondActivityType, secondCoord);
+ //secondAct.setLinkId(NetworkUtils.getNearestLink(carNetwork, secondCoord).getId());
+ double arrivalTime = t.departure_time + Math.min(getEstimatedTravelTime(t), 3600 * 4);
+ secondAct.setStartTime(arrivalTime);
+ plan.addActivity(secondAct);
+
+ if (roundTrip) {
+ double departure_time_return = t.departure_time_return;
+ //make sure the arrival time is earlier than the departure time
+ departure_time_return = Math.min(departure_time_return, arrivalTime + 1);
+
+ secondAct.setEndTime(departure_time_return);
+ Leg secondLeg = factory.createLeg(mode);
+ secondLeg.setDepartureTime(departure_time_return);
+ plan.addLeg(secondLeg);
+
+ Activity thirdAct = factory.createActivityFromCoord(firstActivityType, firstCoord);
+ //thirdAct.setLinkId(NetworkUtils.getNearestLink(carNetwork, firstCoord).getId());
+ thirdAct.setStartTime(departure_time_return + Math.min(getEstimatedTravelTime(t), 3600 * 4));
+ plan.addActivity(thirdAct);
+ }
+
+ p.addPlan(plan);
+ p.setSelectedPlan(plan);
+ return p;
+ }
+
+ private static String getOriginActivity(Purpose purpose){
+
+ if (purpose.equals(Purpose.NHBW)){
+ return "work";
+ } else if (purpose.equals(Purpose.NHBO)){
+ return "other";
+ } else {
+ return "home";
+ }
+ }
+
+ private static String getDestinationActivity(Purpose purpose){
+
+ if (purpose.equals(Purpose.HBW)){
+ return "work";
+ } else if (purpose.equals(Purpose.HBE)){
+ return "education";
+ } else if (purpose.equals(Purpose.HBS)){
+ return "shopping";
+ } else {
+ return "other";
+ }
+ }
+
+ private static String decodeMode(String encodedMode) {
+ switch (encodedMode) {
+ case "autoDriver":
+ case "auto":
+ return "car";
+ case "autoPassenger":
+ return "car_passenger";
+ case "train":
+ case "bus":
+ case "tramOrMetro":
+ return "pt";
+ case "bicycle":
+ return "bike";
+ default:
+ return encodedMode;
+ }
+ }
+
+ private static double getEstimatedTravelTime(Trip trip) {
+ switch (trip.mode) {
+ case "autoDriver":
+ case "auto":
+ case "autoPassenger":
+ return trip.timeCar_s;
+ case "train":
+ return trip.timeTrain_s;
+ case "tramOrMetro":
+ return trip.timeTramMetro_s;
+ case "bus":
+ return trip.timeBus_s;
+ case "walk":
+ return trip.distance / SPEED_WALK_KMH * 3600;
+ case "bicycle":
+ return trip.distance / SPEED_BICYCLE_KMH * 3600;
+ default:
+ throw new RuntimeException("The mode " + trip.mode + " is not recognized");
+ }
+ }
+
+ public final static class Trip {
+ public final long id;
+ public final double originX;
+ public final double originY;
+ public final double destinationX;
+ public final double destinationY;
+ public final String purpose;
+ public final String person;
+ public final double distance;
+ public final String mode;
+ public final double timeCar_s;
+ public final double timeBus_s;
+ public final double timeTramMetro_s;
+ public final double timeTrain_s;
+ public double departure_time;
+ public double departure_time_return;
+
+
+ public Trip(String line) {
+ String[] data = line.split(delimiter);
+ this.originX = Double.parseDouble(data[posOriginX]);
+ this.originY = Double.parseDouble(data[posOriginY]);
+ this.destinationX = Double.parseDouble(data[posDestinationX]);
+ this.destinationY = Double.parseDouble(data[posDestinationY]);
+ this.purpose = data[posPurpose];
+ this.person = data[posPersonId];
+ this.distance = Double.parseDouble(data[posDistance]);
+ this.mode = data[posMode];
+ try {
+ this.departure_time = Double.parseDouble(data[posDepartureTime]) * 60;
+ } catch (NumberFormatException e) {
+ this.departure_time = 0.;
+ }
+ try {
+ this.departure_time_return = Double.parseDouble(data[posDepartureTimeReturn]) * 60;
+ } catch (NumberFormatException e) {
+ this.departure_time_return = -1.;
+ }
+ this.timeCar_s = Double.parseDouble(data[posTimeCar]) * 60;
+ this.timeTrain_s = Double.parseDouble(data[posTimeTrain]) * 60;
+ this.timeTramMetro_s = Double.parseDouble(data[posTimeMetroTram]) * 60;
+ this.timeBus_s = Double.parseDouble(data[posTimeBus]) * 60;
+ this.id = Long.parseLong(data[posId]);
+ }
+
+
+ }
}
diff --git a/src/main/resources/de/tum/bgu/msm/modules/modeChoice/ModeChoiceShortDistance b/src/main/resources/de/tum/bgu/msm/modules/modeChoice/ModeChoiceShortDistance
new file mode 100644
index 00000000..b50c3a6b
--- /dev/null
+++ b/src/main/resources/de/tum/bgu/msm/modules/modeChoice/ModeChoiceShortDistance
@@ -0,0 +1,874 @@
+nestingCoefficient = 0.25;
+
+fuelCostEurosPerKm = 0.07;
+transitFareEurosPerKm = 0.12;
+
+TNCCostEurosPerKm = 1.20;
+
+VOT1500_HBW_HBE_autoD = 4.63 / 60;
+VOT5600_HBW_HBE_autoD = 8.94 / 60;
+VOT7000_HBW_HBE_autoD = 12.15 / 60;
+VOT1500_HBW_HBE_autoP = 7.01 / 60;
+VOT5600_HBW_HBE_autoP = 13.56 / 60;
+VOT7000_HBW_HBE_autoP = 18.43 / 60;
+VOT1500_HBW_HBE_transit = 8.94 / 60;
+VOT5600_HBW_HBE_transit = 17.30 / 60;
+VOT7000_HBW_HBE_transit = 23.50 / 60;
+
+VOT1500_HBW_HBE_TNC = 7.98 / 60;
+VOT5600_HBW_HBE_TNC = 15.43 / 60;
+VOT7000_HBW_HBE_TNC = 20.97 / 60;
+
+VOT1500_other_autoD = 3.26 / 60;
+VOT5600_other_autoD = 6.30 / 60;
+VOT7000_other_autoD = 8.56 / 60;
+VOT1500_other_autoP = 4.30 / 60;
+VOT5600_other_autoP = 8.31 / 60;
+VOT7000_other_autoP = 11.30 / 60;
+VOT1500_other_transit = 5.06 / 60;
+VOT5600_other_transit = 9.78 / 60;
+VOT7000_other_transit = 13.29 / 60;
+
+VOT1500_other_TNC = 4.68 / 60;
+VOT5600_other_TNC = 9.05 / 60;
+VOT7000_other_TNC = 12.30 / 60;
+
+///////////////////////////////////////////////// HBW Mode Choice /////////////////////////////////////////////////////
+
+// Beta coefficients for modes in the order:[AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk]
+interceptHBW = [0.0, 0.53, 2.78, 3.12, 3.11, 3.06, 6.30];
+ageHBW = [0.0, -0.0037, 0.0, -0.016, -0.017, -0.014, 0.0];
+maleHBW = [0.0, -0.16, 0.22, -0.28, -0.25, -0.18, 0.0];
+driversLicenseHBW = [0.0, -1.03, -1.86, -2.25, -2.09, -2.14, -2.16];
+hhSizeHBW = [0.0, 0.063, 0.25, 0.17, 0.18, 0.15, 0.0];
+hhAutosHBW = [0.0, -0.16, -1.11, -1.27, -1.26, -1.29, -0.73];
+distToRailStopHBW = [0.0, 0.0, 0.0, -0.36, -0.39, -0.40, 0.0];
+coreCityHBW = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
+mediumSizedCityHBW = [0.0, 0.0, -0.29, -0.70, -0.75, -1.05, -0.59];
+townOrRuralCommunityHBW = [0.0, 0.071, -0.39, -0.86, -0.88, -1.22, -0.89];
+generalizedCostHBW = [-0.0088, -0.0088, 0.0, -0.0088, -0.0088, -0.0088, 0.0];
+tripLengthHBW = [0.0, 0.0, -0.32, 0.0, 0.0, 0.0, -2.02];
+isMunichTripHBW = [0.0, 0.04, 0.63, 0.77, 0.76, 0.77, 2.32];
+
+
+var calculateHBWProbabilities = function (hh, person, originZone, destinationZone, travelTimes, accessTimes, travelDistanceAuto, travelDistanceNMT, peakHour) {
+
+ timeAutoD = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "car");
+ timeAutoP = timeAutoD;
+ timeBus = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "bus");
+ timeTrain = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "train");
+ timeTramMetro = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "tramMetro");
+
+ monthlyIncome_EUR = hh.getMonthlyIncome_EUR();
+ age = person.getAge();
+ gender = person.getMitoGender();
+ driversLicense = person.hasDriversLicense();
+ hhSize = hh.getHhSize();
+ hhAutos = hh.getAutos();
+ distToRailStop = originZone.getDistanceToNearestRailStop();
+ areaType = originZone.getAreaTypeSG();
+ isMunichTrip = originZone.isMunichZone();
+
+
+ if (monthlyIncome_EUR <= 1500) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_HBW_HBE_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_HBW_HBE_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_HBW_HBE_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_HBW_HBE_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_HBW_HBE_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT1500_HBW_HBE_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 1500 && monthlyIncome_EUR <= 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_HBW_HBE_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_HBW_HBE_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_HBW_HBE_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_HBW_HBE_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_HBW_HBE_transit;
+ gcSTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT5600_HBW_HBE_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_HBW_HBE_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_HBW_HBE_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_HBW_HBE_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_HBW_HBE_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_HBW_HBE_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT7000_HBW_HBE_TNC; // change in VOT and cost
+ }
+
+ utilityAutoD = interceptHBW[0] + ageHBW[0] * age + maleHBW[0] * (gender.name().equals("MALE")) +
+ driversLicenseHBW[0] * driversLicense + hhSizeHBW[0] * hhSize + hhAutosHBW[0] * hhAutos +
+ distToRailStopHBW[0] * distToRailStop + coreCityHBW[0] * (areaType.name().equals("CORE_CITY")) +
+ mediumSizedCityHBW[0] * (areaType.name().equals("MEDIUM_SIZE_CITY")) +
+ townOrRuralCommunityHBW[0] * (areaType.name().equals("TOWN") || areaType.name().equals("RURAL")) +
+ generalizedCostHBW[0] * gcAutoD + isMunichTripHBW[0] * isMunichTrip;
+
+ utilityAutoP = interceptHBW[1] + ageHBW[1] * age + maleHBW[1] * (gender.name().equals("MALE")) +
+ driversLicenseHBW[1] * driversLicense + hhSizeHBW[1] * hhSize + hhAutosHBW[1] * hhAutos +
+ distToRailStopHBW[1] * distToRailStop + coreCityHBW[1] * (areaType.name().equals("CORE_CITY")) +
+ mediumSizedCityHBW[1] * (areaType.name().equals("MEDIUM_SIZE_CITY")) +
+ townOrRuralCommunityHBW[1] * (areaType.name().equals("TOWN") || areaType.name().equals("RURAL")) +
+ generalizedCostHBW[1] * gcAutoP + isMunichTripHBW[1] * isMunichTrip;
+
+ utilityBicycle = interceptHBW[2] + ageHBW[2] * age + maleHBW[2] * (gender.name().equals("MALE")) +
+ driversLicenseHBW[2] * driversLicense + hhSizeHBW[2] * hhSize + hhAutosHBW[2] * hhAutos +
+ distToRailStopHBW[2] * distToRailStop + coreCityHBW[2] * (areaType.name().equals("CORE_CITY")) +
+ mediumSizedCityHBW[2] * (areaType.name().equals("MEDIUM_SIZE_CITY")) +
+ townOrRuralCommunityHBW[2] * (areaType.name().equals("TOWN") || areaType.name().equals("RURAL")) +
+ tripLengthHBW[2] * travelDistanceNMT + isMunichTripHBW[2] * isMunichTrip;
+
+ utilityBus = interceptHBW[3] + ageHBW[3] * age + maleHBW[3] * (gender.name().equals("MALE")) +
+ driversLicenseHBW[3] * driversLicense + hhSizeHBW[3] * hhSize + hhAutosHBW[3] * hhAutos +
+ distToRailStopHBW[3] * distToRailStop + coreCityHBW[3] * (areaType.name().equals("CORE_CITY")) +
+ mediumSizedCityHBW[3] * (areaType.name().equals("MEDIUM_SIZE_CITY") || areaType.name().equals("RURAL")) +
+ townOrRuralCommunityHBW[3] * (areaType.name().equals("TOWN")) +
+ generalizedCostHBW[3] * gcBus + isMunichTripHBW[3] * isMunichTrip;
+
+ utilityTrain = interceptHBW[4] + ageHBW[4] * age + maleHBW[4] * (gender.name().equals("MALE")) +
+ driversLicenseHBW[4] * driversLicense + hhSizeHBW[4] * hhSize + hhAutosHBW[4] * hhAutos +
+ distToRailStopHBW[4] * distToRailStop + coreCityHBW[4] * (areaType.name().equals("CORE_CITY")) +
+ mediumSizedCityHBW[4] * (areaType.name().equals("MEDIUM_SIZE_CITY") || areaType.name().equals("RURAL")) +
+ townOrRuralCommunityHBW[4] * (areaType.name().equals("TOWN")) +
+ generalizedCostHBW[4] * gcTrain + isMunichTripHBW[4] * isMunichTrip;
+
+ utilityTramMetro = interceptHBW[5] + ageHBW[5] * age + maleHBW[5] * (gender.name().equals("MALE")) +
+ driversLicenseHBW[5] * driversLicense + hhSizeHBW[5] * hhSize + hhAutosHBW[5] * hhAutos +
+ distToRailStopHBW[5] * distToRailStop + coreCityHBW[5] * (areaType.name().equals("CORE_CITY")) +
+ mediumSizedCityHBW[5] * (areaType.name().equals("MEDIUM_SIZE_CITY")) +
+ townOrRuralCommunityHBW[5] * (areaType.name().equals("TOWN") || areaType.name().equals("RURAL")) +
+ generalizedCostHBW[5] * gcTramMetro + isMunichTripHBW[5] * isMunichTrip;
+
+ utilityWalk = interceptHBW[6] + ageHBW[6] * age + maleHBW[6] * (gender.name().equals("MALE")) +
+ driversLicenseHBW[6] * driversLicense + hhSizeHBW[6] * hhSize + hhAutosHBW[6] * hhAutos +
+ distToRailStopHBW[6] * distToRailStop + coreCityHBW[6] * (areaType.name().equals("CORE_CITY")) +
+ mediumSizedCityHBW[6] * (areaType.name().equals("MEDIUM_SIZE_CITY")) +
+ townOrRuralCommunityHBW[6] * (areaType.name().equals("TOWN") || areaType.name().equals("RURAL")) +
+ tripLengthHBW[6] * travelDistanceNMT + isMunichTripHBW[6] * isMunichTrip;
+
+ utilityTNC = utilityBus + generalizedCostHBW[3] * (gcTNC - gcBus);
+
+ expsumNestAuto = Math.exp(utilityAutoD / nestingCoefficient) + Math.exp(utilityAutoP / nestingCoefficient);
+ expsumNestTransit = Math.exp(utilityBus / nestingCoefficient) + Math.exp(utilityTrain / nestingCoefficient) + Math.exp(utilityTramMetro / nestingCoefficient);
+ expsumNestNMT = Math.exp(utilityBicycle / nestingCoefficient) + Math.exp(utilityWalk / nestingCoefficient);
+ expsumTopLevel = Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) + Math.exp(utilityTNC) + Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) + Math.exp(nestingCoefficient * Math.log(expsumNestTransit));
+
+ if (expsumNestAuto > 0) {
+ probabilityAutoD = (Math.exp(utilityAutoD / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ probabilityAutoP = (Math.exp(utilityAutoP / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ } else {
+ probabilityAutoD = 0.0;
+ probabilityAutoP = 0.0;
+ }
+
+ if (expsumNestTransit > 0) {
+ probabilityBus = (Math.exp(utilityBus / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTrain = (Math.exp(utilityTrain / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTramMetro = (Math.exp(utilityTramMetro / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ } else {
+ probabilityBus = 0.0;
+ probabilityTrain = 0.0;
+ probabilityTramMetro = 0.0;
+ }
+
+ if (expsumNestNMT > 0) {
+ probabilityBicycle = (Math.exp(utilityBicycle / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) / expsumTopLevel);
+ probabilityWalk = (Math.exp(utilityWalk / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestWalk)) / expsumTopLevel);
+ } else {
+ probabilityBicycle = 0.0;
+ probabilityWalk = 0.0;
+ }
+
+ probabilityTNC = Math.exp(utilityTNC) / expsumTopLevel;
+
+ return Java.to([probabilityAutoD, probabilityAutoP, probabilityBicycle, probabilityBus, probabilityTrain, probabilityTramMetro, probabilityWalk, probabilityTNC], "double[]");
+
+}
+
+
+///////////////////////////////////////////////// HBE Mode Choice /////////////////////////////////////////////////////
+
+// Beta coefficients for modes in the order - [AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk]
+interceptHBE = [0.0, 1.41, 2.15, 3.00, 2.72, 3.02, 4.23];
+maleHBE = [0.0, -0.17, 0.0, -0.14, -0.15, -0.15, 0.0];
+driversLicenseHBE = [0.0, -1.26, -0.43, -1.23, -0.75, -0.77, -0.55];
+hhAutosHBE = [0.0, -0.11, -0.56, -0.52, -0.56, -0.70, -0.68];
+distToRailStopHBE = [0.0, 0.0, 0.0, -0.28, -0.26, -0.46, 0.0];
+generalizedCostHBE = [-0.0025, -0.0025, 0.0, -0.0025, -0.0025, -0.0025, 0.0];
+tripLengthHBE = [0.0, 0.0, -0.42, 0.0, 0.0, 0.0, -1.71];
+isMunichTripHBE = [0.0, 0.02, 0.25, 0.07, 0.08, 0.06, -0.49];
+
+var calculateHBEProbabilities = function (hh, person, originZone, destinationZone, travelTimes, accessTimes, travelDistanceAuto, travelDistanceNMT, peakHour) {
+ timeAutoD = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "car");
+ timeAutoP = timeAutoD;
+ timeBus = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "bus");
+ timeTrain = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "train");
+ timeTramMetro = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "tramMetro");
+
+ monthlyIncome_EUR = hh.getMonthlyIncome_EUR();
+ gender = person.getMitoGender();
+ driversLicense = person.hasDriversLicense();
+ hhAutos = hh.getAutos();
+ distToRailStop = originZone.getDistanceToNearestRailStop();
+ isMunichTrip = originZone.isMunichZone();
+
+ if (monthlyIncome_EUR <= 1500) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_HBW_HBE_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_HBW_HBE_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_HBW_HBE_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_HBW_HBE_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_HBW_HBE_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT1500_HBW_HBE_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 1500 && monthlyIncome_EUR <= 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_HBW_HBE_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_HBW_HBE_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_HBW_HBE_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_HBW_HBE_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_HBW_HBE_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT5600_HBW_HBE_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_HBW_HBE_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_HBW_HBE_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_HBW_HBE_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_HBW_HBE_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_HBW_HBE_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT7000_HBW_HBE_TNC; // change in VOT and cost
+ }
+
+ utilityAutoD = interceptHBE[0] + maleHBE[0] * (gender.name().equals("MALE")) + driversLicenseHBE[0] * driversLicense +
+ hhAutosHBE[0] * hhAutos + distToRailStopHBE[0] * distToRailStop + generalizedCostHBE[0] * gcAutoD + isMunichTripHBE[0] * isMunichTrip;
+
+ utilityAutoP = interceptHBE[1] + maleHBE[1] * (gender.name().equals("MALE")) + driversLicenseHBE[1] * driversLicense +
+ hhAutosHBE[1] * hhAutos + distToRailStopHBE[1] * distToRailStop + generalizedCostHBE[1] * gcAutoP + isMunichTripHBE[1] * isMunichTrip;
+
+ utilityBicycle = interceptHBE[2] + maleHBE[2] * (gender.name().equals("MALE")) + driversLicenseHBE[2] * driversLicense +
+ hhAutosHBE[2] * hhAutos + distToRailStopHBE[2] * distToRailStop + tripLengthHBE[2] * travelDistanceNMT + isMunichTripHBE[2] * isMunichTrip;
+
+ utilityBus = interceptHBE[3] + maleHBE[3] * (gender.name().equals("MALE")) + driversLicenseHBE[3] * driversLicense +
+ hhAutosHBE[3] * hhAutos + distToRailStopHBE[3] * distToRailStop + generalizedCostHBE[3] * gcBus + isMunichTripHBE[3] * isMunichTrip;
+
+ utilityTrain = interceptHBE[4] + maleHBE[4] * (gender.name().equals("MALE")) + driversLicenseHBE[4] * driversLicense +
+ hhAutosHBE[4] * hhAutos + distToRailStopHBE[4] * distToRailStop + generalizedCostHBE[4] * gcTrain + isMunichTripHBE[4] * isMunichTrip;
+
+ utilityTramMetro = interceptHBE[5] + maleHBE[5] * (gender.name().equals("MALE")) + driversLicenseHBE[5] * driversLicense +
+ hhAutosHBE[5] * hhAutos + distToRailStopHBE[5] * distToRailStop + generalizedCostHBE[5] * gcTramMetro + isMunichTripHBE[5] * isMunichTrip;
+
+ utilityWalk = interceptHBE[6] + maleHBE[6] * (gender.name().equals("MALE")) + driversLicenseHBE[6] * driversLicense +
+ hhAutosHBE[6] * hhAutos + distToRailStopHBE[6] * distToRailStop + tripLengthHBE[6] * travelDistanceNMT + isMunichTripHBE[6] * isMunichTrip;
+
+ utilityTNC = utilityBus + generalizedCostHBE[3] * (gcTNC - gcBus);
+
+ expsumNestAuto = Math.exp(utilityAutoD / nestingCoefficient) + Math.exp(utilityAutoP / nestingCoefficient);
+ expsumNestTransit = Math.exp(utilityBus / nestingCoefficient) + Math.exp(utilityTrain / nestingCoefficient) + Math.exp(utilityTramMetro / nestingCoefficient);
+ expsumNestNMT = Math.exp(utilityBicycle / nestingCoefficient) + Math.exp(utilityWalk / nestingCoefficient);
+ expsumTopLevel = Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) + Math.exp(utilityTNC) + Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) + Math.exp(nestingCoefficient * Math.log(expsumNestTransit));
+
+ if (expsumNestAuto > 0) {
+ probabilityAutoD = (Math.exp(utilityAutoD / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ probabilityAutoP = (Math.exp(utilityAutoP / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ } else {
+ probabilityAutoD = 0.0;
+ probabilityAutoP = 0.0;
+ }
+
+ if (expsumNestTransit > 0) {
+ probabilityBus = (Math.exp(utilityBus / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTrain = (Math.exp(utilityTrain / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTramMetro = (Math.exp(utilityTramMetro / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ } else {
+ probabilityBus = 0.0;
+ probabilityTrain = 0.0;
+ probabilityTramMetro = 0.0;
+ }
+
+ if (expsumNestNMT > 0) {
+ probabilityBicycle = (Math.exp(utilityBicycle / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) / expsumTopLevel);
+ probabilityWalk = (Math.exp(utilityWalk / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestWalk)) / expsumTopLevel);
+ } else {
+ probabilityBicycle = 0.0;
+ probabilityWalk = 0.0;
+ }
+
+ probabilityTNC = Math.exp(utilityTNC) / expsumTopLevel;
+
+ return Java.to([probabilityAutoD, probabilityAutoP, probabilityBicycle, probabilityBus, probabilityTrain, probabilityTramMetro, probabilityWalk, probabilityTNC], "double[]");
+
+}
+//print(utilityAutoD + ";" + utilityAutoP + ";" +
+//utilityBicycle + ";" + utilityBus + ";" + utilityTramMetro + ";"
+//+ utilityTrain + ";" + utilityWalk + ";" + utilityAVP + ";" + utilityAVS + ";" +
+//utilityUAM + ";" );
+
+//print(probabilityPrivateAV + ";" + probabilityAutoD + ";" +
+//probabilityAutoP + ";" + probabilitySharedAV + ";" + probabilityBus + ";"
+//+ probabilityTrain + ";" + probabilityTramMetro + ";" + probabilityBicycle + ";" + probabilityWalk + ";" +
+//probabilityUAM + ";" );
+
+
+///////////////////////////////////////////////// HBS Mode Choice /////////////////////////////////////////////////////
+
+// Beta coefficients for modes in the order: [AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk]
+interceptHBS = [0.0, 0.92, 2.50, 1.61, 1.17, 1.67, 6.35];
+maleHBS = [0.0, -0.47, -0.14, -0.62, -0.47, -0.53, -0.15];
+driversLicenseHBS = [0.0, -1.43, -1.86, -2.43, -2.46, -2.39, -2.10];
+hhAutosHBS = [0.0, -0.03, -0.81, -1.88, -1.73, -1.88, -0.86];
+distToRailStopHBS = [0.0, 0.0, 0.0, -0.87, -0.68, -1.02, 0.0];
+hhChildrenHBS = [0.0, -0.051, 0.0, 0.0, 0.0, 0.0, -0.17];
+generalizedCostHBS_Sq = [-0.0000068, -0.0000068, 0.0, -0.0000068, -0.0000068, -0.0000068, 0.0];
+tripLengthHBS = [0.0, 0.0, -0.42, 0.0, 0.0, 0.0, -1.46];
+isMunichTripHBS = [0.0, 0.05, 1.16, 1.35, 1.32, 1.36, 1.942];
+
+var calculateHBSProbabilities = function (hh, person, originZone, destinationZone, travelTimes, accessTimes, travelDistanceAuto, travelDistanceNMT, peakHour) {
+
+ var dataSet = Java.type('de.tum.bgu.msm.data.DataSet');
+ hhChildren = dataSet.getChildrenForHousehold(hh);
+ timeAutoD = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "car");
+ timeAutoP = timeAutoD;
+ timeBus = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "bus");
+ timeTrain = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "train");
+ timeTramMetro = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "tramMetro");
+
+ monthlyIncome_EUR = hh.getMonthlyIncome_EUR();
+ gender = person.getMitoGender();
+ driversLicense = person.hasDriversLicense();
+ hhAutos = hh.getAutos();
+ distToRailStop = originZone.getDistanceToNearestRailStop();
+ isMunichTrip = originZone.isMunichZone();
+
+ if (monthlyIncome_EUR <= 1500) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT1500_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 1500 && monthlyIncome_EUR <= 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT5600_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT7000_other_TNC; // change in VOT and cost
+ }
+
+ utilityAutoD = interceptHBS[0] + maleHBS[0] * (gender.name().equals("MALE")) + driversLicenseHBS[0] * driversLicense +
+ hhAutosHBS[0] * hhAutos + distToRailStopHBS[0] * distToRailStop + hhChildrenHBS[0] * hhChildren +
+ generalizedCostHBS_Sq[0] * Math.pow(gcAutoD, 2) + isMunichTripHBS[0] * isMunichTrip;
+
+ utilityAutoP = interceptHBS[1] + maleHBS[1] * (gender.name().equals("MALE")) + driversLicenseHBS[1] * driversLicense +
+ hhAutosHBS[1] * hhAutos + distToRailStopHBS[1] * distToRailStop + hhChildrenHBS[1] * hhChildren +
+ generalizedCostHBS_Sq[1] * Math.pow(gcAutoP, 2) + isMunichTripHBS[1] * isMunichTrip;
+
+ utilityBicycle = interceptHBS[2] + maleHBS[2] * (gender.name().equals("MALE")) + driversLicenseHBS[2] * driversLicense +
+ hhAutosHBS[2] * hhAutos + distToRailStopHBS[2] * distToRailStop + hhChildrenHBS[2] * hhChildren +
+ tripLengthHBS[2] * travelDistanceNMT + isMunichTripHBS[2] * isMunichTrip;
+
+ utilityBus = interceptHBS[3] + maleHBS[3] * (gender.name().equals("MALE")) + driversLicenseHBS[3] * driversLicense +
+ hhAutosHBS[3] * hhAutos + distToRailStopHBS[3] * distToRailStop + hhChildrenHBS[3] * hhChildren +
+ generalizedCostHBS_Sq[3] * Math.pow(gcBus, 2) + isMunichTripHBS[3] * isMunichTrip;
+
+ utilityTrain = interceptHBS[4] + maleHBS[4] * (gender.name().equals("MALE")) + driversLicenseHBS[4] * driversLicense +
+ hhAutosHBS[4] * hhAutos + distToRailStopHBS[4] * distToRailStop + hhChildrenHBS[4] * hhChildren +
+ generalizedCostHBS_Sq[4] * Math.pow(gcTrain, 2) + isMunichTripHBS[4] * isMunichTrip;
+
+ utilityTramMetro = interceptHBS[5] + maleHBS[5] * (gender.name().equals("MALE")) + driversLicenseHBS[5] * driversLicense +
+ hhAutosHBS[5] * hhAutos + distToRailStopHBS[5] * distToRailStop + hhChildrenHBS[5] * hhChildren +
+ generalizedCostHBS_Sq[5] * Math.pow(gcTramMetro, 2) + isMunichTripHBS[5] * isMunichTrip;
+
+ utilityWalk = interceptHBS[6] + maleHBS[6] * (gender.name().equals("MALE")) + driversLicenseHBS[6] * driversLicense +
+ hhAutosHBS[6] * hhAutos + distToRailStopHBS[6] * distToRailStop + hhChildrenHBS[6] * hhChildren +
+ tripLengthHBS[6] * travelDistanceNMT + isMunichTripHBS[6] * isMunichTrip;
+
+ utilityTNC = utilityBus + generalizedCostHBS_Sq[3] * (Math.pow(gcTNC, 2) - Math.pow(gcBus, 2));
+
+ expsumNestAuto = Math.exp(utilityAutoD / nestingCoefficient) + Math.exp(utilityAutoP / nestingCoefficient);
+ expsumNestTransit = Math.exp(utilityBus / nestingCoefficient) + Math.exp(utilityTrain / nestingCoefficient) + Math.exp(utilityTramMetro / nestingCoefficient);
+ expsumNestNMT = Math.exp(utilityBicycle / nestingCoefficient) + Math.exp(utilityWalk / nestingCoefficient);
+ expsumTopLevel = Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) + Math.exp(utilityTNC) + Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) + Math.exp(nestingCoefficient * Math.log(expsumNestTransit));
+
+ if (expsumNestAuto > 0) {
+ probabilityAutoD = (Math.exp(utilityAutoD / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ probabilityAutoP = (Math.exp(utilityAutoP / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ } else {
+ probabilityAutoD = 0.0;
+ probabilityAutoP = 0.0;
+ }
+
+ if (expsumNestTransit > 0) {
+ probabilityBus = (Math.exp(utilityBus / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTrain = (Math.exp(utilityTrain / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTramMetro = (Math.exp(utilityTramMetro / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ } else {
+ probabilityBus = 0.0;
+ probabilityTrain = 0.0;
+ probabilityTramMetro = 0.0;
+ }
+
+ if (expsumNestNMT > 0) {
+ probabilityBicycle = (Math.exp(utilityBicycle / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) / expsumTopLevel);
+ probabilityWalk = (Math.exp(utilityWalk / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestWalk)) / expsumTopLevel);
+ } else {
+ probabilityBicycle = 0.0;
+ probabilityWalk = 0.0;
+ }
+
+ probabilityTNC = Math.exp(utilityTNC) / expsumTopLevel;
+
+ return Java.to([probabilityAutoD, probabilityAutoP, probabilityBicycle, probabilityBus, probabilityTrain, probabilityTramMetro, probabilityWalk, probabilityTNC], "double[]");
+
+}
+
+///////////////////////////////////////////////// HBO Mode Choice /////////////////////////////////////////////////////
+
+// Beta coefficients for modes in the order: [AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk]
+interceptHBO = [0.0, 1.04, 1.25, 1.47, 1.22, 1.59, 4.09];
+maleHBO = [0.0, -0.27, 0.17, -0.13, 0.0, -0.063, -0.13];
+driversLicenseHBO = [0.0, -1.34, -1.51, -1.91, -1.66, -1.74, -1.30];
+hhAutosHBO = [0.0, -0.029, -0.57, -1.54, -1.56, -1.72, -0.30];
+hhSizeHBO = [0.0, 0.0, 0.0, -0.11, -0.11, -0.15, -0.19];
+distToRailStopHBO = [0.0, 0.0, 0.0, -0.61, -0.57, -0.58, -0.065];
+generalizedCostHBO = [-0.0012, -0.0012, 0.0, -0.0012, -0.0012, -0.0012, 0.0];
+tripLengthHBO = [0.0, 0.0, -0.15, 0.0, 0.0, 0.0, -0.68];
+isMunichTripHBO = [0.0, 0.14, 0.61, 1.25, 1.23, 1.25, 0.34];
+
+var calculateHBOProbabilities = function (hh, person, originZone, destinationZone, travelTimes, accessTimes, travelDistanceAuto, travelDistanceNMT, peakHour) {
+
+ timeAutoD = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "car");
+ timeAutoP = timeAutoD;
+ timeBus = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "bus");
+ timeTrain = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "train");
+ timeTramMetro = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "tramMetro");
+
+ monthlyIncome_EUR = hh.getMonthlyIncome_EUR();
+ gender = person.getMitoGender();
+ driversLicense = person.hasDriversLicense();
+ hhAutos = hh.getAutos();
+ hhSize = hh.getHhSize();
+ distToRailStop = originZone.getDistanceToNearestRailStop();
+ isMunichTrip = originZone.isMunichZone();
+
+ if (monthlyIncome_EUR <= 1500) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT1500_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 1500 && monthlyIncome_EUR <= 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT5600_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT7000_other_TNC; // change in VOT and cost
+ }
+
+ utilityAutoD = interceptHBO[0] + maleHBO[0] * (gender.name().equals("MALE")) + driversLicenseHBO[0] * driversLicense +
+ hhAutosHBO[0] * hhAutos + hhSizeHBO[0] * hhSize + distToRailStopHBO[0] * distToRailStop +
+ generalizedCostHBO[0] * gcAutoD + isMunichTripHBO[0] * isMunichTrip;
+
+ utilityAutoP = interceptHBO[1] + maleHBO[1] * (gender.name().equals("MALE")) + driversLicenseHBO[1] * driversLicense +
+ hhAutosHBO[1] * hhAutos + hhSizeHBO[1] * hhSize + distToRailStopHBO[1] * distToRailStop +
+ generalizedCostHBO[1] * gcAutoP + isMunichTripHBO[1] * isMunichTrip;
+
+ utilityBicycle = interceptHBO[2] + maleHBO[2] * (gender.name().equals("MALE")) + driversLicenseHBO[2] * driversLicense +
+ hhAutosHBO[2] * hhAutos + hhSizeHBO[2] * hhSize + distToRailStopHBO[2] * distToRailStop +
+ tripLengthHBO[2] * travelDistanceNMT + isMunichTripHBO[2] * isMunichTrip;
+
+ utilityBus = interceptHBO[3] + maleHBO[3] * (gender.name().equals("MALE")) + driversLicenseHBO[3] * driversLicense +
+ hhAutosHBO[3] * hhAutos + hhSizeHBO[3] * hhSize + distToRailStopHBO[3] * distToRailStop +
+ generalizedCostHBO[3] * gcBus + isMunichTripHBO[3] * isMunichTrip;
+
+ utilityTrain = interceptHBO[4] + maleHBO[4] * (gender.name().equals("MALE")) + driversLicenseHBO[4] * driversLicense +
+ hhAutosHBO[4] * hhAutos + hhSizeHBO[4] * hhSize + distToRailStopHBO[4] * distToRailStop +
+ generalizedCostHBO[4] * gcTrain + isMunichTripHBO[4] * isMunichTrip;
+
+ utilityTramMetro = interceptHBO[5] + maleHBO[5] * (gender.name().equals("MALE")) + driversLicenseHBO[5] * driversLicense +
+ hhAutosHBO[5] * hhAutos + hhSizeHBO[5] * hhSize + distToRailStopHBO[5] * distToRailStop +
+ generalizedCostHBO[5] * gcTramMetro + isMunichTripHBO[5] * isMunichTrip;
+
+ utilityWalk = interceptHBO[6] + maleHBO[6] * (gender.name().equals("MALE")) + driversLicenseHBO[6] * driversLicense +
+ hhAutosHBO[6] * hhAutos + hhSizeHBO[6] * hhSize + distToRailStopHBO[6] * distToRailStop +
+ tripLengthHBO[6] * travelDistanceNMT + isMunichTripHBO[6] * isMunichTrip;
+
+ utilityTNC = utilityBus + generalizedCostHBO[3] * (gcTNC - gcBus);
+
+ expsumNestAuto = Math.exp(utilityAutoD / nestingCoefficient) + Math.exp(utilityAutoP / nestingCoefficient);
+ expsumNestTransit = Math.exp(utilityBus / nestingCoefficient) + Math.exp(utilityTrain / nestingCoefficient) + Math.exp(utilityTramMetro / nestingCoefficient);
+ expsumNestNMT = Math.exp(utilityBicycle / nestingCoefficient) + Math.exp(utilityWalk / nestingCoefficient);
+ expsumTopLevel = Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) + Math.exp(utilityTNC) + Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) + Math.exp(nestingCoefficient * Math.log(expsumNestTransit));
+
+ if (expsumNestAuto > 0) {
+ probabilityAutoD = (Math.exp(utilityAutoD / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ probabilityAutoP = (Math.exp(utilityAutoP / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ } else {
+ probabilityAutoD = 0.0;
+ probabilityAutoP = 0.0;
+ }
+
+ if (expsumNestTransit > 0) {
+ probabilityBus = (Math.exp(utilityBus / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTrain = (Math.exp(utilityTrain / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTramMetro = (Math.exp(utilityTramMetro / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ } else {
+ probabilityBus = 0.0;
+ probabilityTrain = 0.0;
+ probabilityTramMetro = 0.0;
+ }
+
+ if (expsumNestNMT > 0) {
+ probabilityBicycle = (Math.exp(utilityBicycle / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) / expsumTopLevel);
+ probabilityWalk = (Math.exp(utilityWalk / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestWalk)) / expsumTopLevel);
+ } else {
+ probabilityBicycle = 0.0;
+ probabilityWalk = 0.0;
+ }
+
+ probabilityTNC = Math.exp(utilityTNC) / expsumTopLevel;
+
+ return Java.to([probabilityAutoD, probabilityAutoP, probabilityBicycle, probabilityBus, probabilityTrain, probabilityTramMetro, probabilityWalk, probabilityTNC], "double[]");
+
+}
+
+///////////////////////////////////////////////// NHBW Mode Choice /////////////////////////////////////////////////////
+
+// Beta coefficients for modes in the order: [AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk]
+interceptNHBW = [0.0, 0.58, 1.99, 0.72, 1.11, 1.02, 7.22];
+ageNHBW = [0.0, -0.0045, 0.0, 0.0, -0.0059, 0.0, -0.011];
+driversLicenseNHBW = [0.0, -0.94, -1.56, -1.61, -1.67, -1.37, -1.43];
+hhAutosNHBW = [0.0, -0.11, -1.12, -1.23, -1.44, -1.52, -0.47];
+distToRailStopNHBW = [0.0, 0.0, 0.0, -0.24, 0.0, -0.16, -0.37];
+generalizedCostNHBW = [-0.0034, -0.0034, 0.0, -0.0034, -0.0034, -0.0034, 0.0];
+tripLengthNHBW = [0.0, 0.0, -0.28, 0.0, 0.0, 0.0, -1.54];
+
+var calculateNHBWProbabilities = function (hh, person, originZone, destinationZone, travelTimes, accessTimes, travelDistanceAuto, travelDistanceNMT, peakHour) {
+
+ timeAutoD = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "car");
+ timeAutoP = timeAutoD;
+ timeBus = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "bus");
+ timeTrain = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "train");
+ timeTramMetro = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "tramMetro");
+
+ monthlyIncome_EUR = hh.getMonthlyIncome_EUR();
+ age = person.getAge();
+ driversLicense = person.hasDriversLicense();
+ hhAutos = hh.getAutos();
+ distToRailStop = originZone.getDistanceToNearestRailStop();
+
+ if (monthlyIncome_EUR <= 1500) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT1500_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 1500 && monthlyIncome_EUR <= 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT5600_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT7000_other_TNC; // change in VOT and cost
+ }
+
+ utilityAutoD = interceptNHBW[0] + ageNHBW[0] * age + driversLicenseNHBW[0] * driversLicense +
+ hhAutosNHBW[0] * hhAutos + distToRailStopNHBW[0] * distToRailStop + generalizedCostNHBW[0] * gcAutoD;
+
+ utilityAutoP = interceptNHBW[1] + ageNHBW[1] * age + driversLicenseNHBW[1] * driversLicense +
+ hhAutosNHBW[1] * hhAutos + distToRailStopNHBW[1] * distToRailStop + generalizedCostNHBW[1] * gcAutoP;
+
+ utilityBicycle = interceptNHBW[2] + ageNHBW[2] * age + driversLicenseNHBW[2] * driversLicense +
+ hhAutosNHBW[2] * hhAutos + distToRailStopNHBW[2] * distToRailStop + tripLengthNHBW[2] * travelDistanceNMT;
+
+ utilityBus = interceptNHBW[3] + ageNHBW[3] * age + driversLicenseNHBW[3] * driversLicense +
+ hhAutosNHBW[3] * hhAutos + distToRailStopNHBW[3] * distToRailStop + generalizedCostNHBW[3] * gcBus;
+
+ utilityTrain = interceptNHBW[4] + ageNHBW[4] * age + driversLicenseNHBW[4] * driversLicense +
+ hhAutosNHBW[4] * hhAutos + distToRailStopNHBW[4] * distToRailStop + generalizedCostNHBW[4] * gcTrain;
+
+ utilityTramMetro = interceptNHBW[5] + ageNHBW[5] * age + driversLicenseNHBW[5] * driversLicense +
+ hhAutosNHBW[5] * hhAutos + distToRailStopNHBW[5] * distToRailStop + generalizedCostNHBW[5] * gcTramMetro;
+
+ utilityWalk = interceptNHBW[6] + ageNHBW[6] * age + driversLicenseNHBW[6] * driversLicense +
+ hhAutosNHBW[6] * hhAutos + distToRailStopNHBW[6] * distToRailStop + tripLengthNHBW[6] * travelDistanceNMT;
+
+ utilityTNC = utilityBus + generalizedCostNHBW[3] * (gcTNC - gcBus);
+
+ expsumNestAuto = Math.exp(utilityAutoD / nestingCoefficient) + Math.exp(utilityAutoP / nestingCoefficient);
+ expsumNestTransit = Math.exp(utilityBus / nestingCoefficient) + Math.exp(utilityTrain / nestingCoefficient) + Math.exp(utilityTramMetro / nestingCoefficient);
+ expsumNestNMT = Math.exp(utilityBicycle / nestingCoefficient) + Math.exp(utilityWalk / nestingCoefficient);
+ expsumTopLevel = Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) + Math.exp(utilityTNC) + Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) + Math.exp(nestingCoefficient * Math.log(expsumNestTransit));
+
+ if (expsumNestAuto > 0) {
+ probabilityAutoD = (Math.exp(utilityAutoD / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ probabilityAutoP = (Math.exp(utilityAutoP / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ } else {
+ probabilityAutoD = 0.0;
+ probabilityAutoP = 0.0;
+ }
+
+ if (expsumNestTransit > 0) {
+ probabilityBus = (Math.exp(utilityBus / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTrain = (Math.exp(utilityTrain / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTramMetro = (Math.exp(utilityTramMetro / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ } else {
+ probabilityBus = 0.0;
+ probabilityTrain = 0.0;
+ probabilityTramMetro = 0.0;
+ }
+
+ if (expsumNestNMT > 0) {
+ probabilityBicycle = (Math.exp(utilityBicycle / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) / expsumTopLevel);
+ probabilityWalk = (Math.exp(utilityWalk / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestWalk)) / expsumTopLevel);
+ } else {
+ probabilityBicycle = 0.0;
+ probabilityWalk = 0.0;
+ }
+
+ probabilityTNC = Math.exp(utilityTNC) / expsumTopLevel;
+
+ return Java.to([probabilityAutoD, probabilityAutoP, probabilityBicycle, probabilityBus, probabilityTrain, probabilityTramMetro, probabilityWalk, probabilityTNC], "double[]");
+
+}
+
+
+///////////////////////////////////////////////// NHBO Mode Choice /////////////////////////////////////////////////////
+
+// Beta coefficients for modes in the order: [AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk]
+interceptNHBO = [0.0, 1.21, 0.93, 0.68, 0.64, 0.84, 2.99];
+maleNHBO = [0.0, -0.24, 0.0, -0.20, -0.23, -0.18, -0.073];
+driversLicenseNHBO = [0.0, -1.40, -1.49, -2.02, -1.74, -1.77, -1.44];
+hhAutosNHBO = [0.0, -0.029, -0.73, -0.80, -0.85, -0.86, -0.40];
+distToRailStopNHBO = [0.0, 0.0, 0.0, -0.40, -0.44, -0.48, 0.0];
+agglomerationUrbanNHBO = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
+ruralNHBO = [0.0, 0.0, 0.0, -0.70, -0.91, -1.12, 0.0];
+generalizedCostNHBO_Sq = [-0.000017, -0.000017, 0.0, -0.000017, -0.000017, -0.000017, 0.0];
+tripLengthNHBO = [0.0, 0.0, -0.15, 0.0, 0.0, 0.0, -0.57];
+
+var calculateNHBOProbabilities = function (hh, person, originZone, destinationZone, travelTimes, accessTimes, travelDistanceAuto, travelDistanceNMT, travelCostUAM, peakHour) {
+
+ timeAutoD = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "car");
+ timeAutoP = timeAutoD;
+ timeBus = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "bus");
+ timeTrain = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "train");
+ timeTramMetro = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "tramMetro");
+
+ monthlyIncome_EUR = hh.getMonthlyIncome_EUR();
+ gender = person.getMitoGender();
+ driversLicense = person.hasDriversLicense();
+ hhAutos = hh.getAutos();
+ distToRailStop = originZone.getDistanceToNearestRailStop();
+ areaType = originZone.getAreaTypeR();
+
+ if (monthlyIncome_EUR <= 1500) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT1500_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT1500_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT1500_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 1500 && monthlyIncome_EUR <= 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT5600_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT5600_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT5600_other_TNC; // change in VOT and cost
+ } else if (monthlyIncome_EUR > 5600) {
+ gcAutoD = timeAutoD + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoD;
+ gcAutoP = timeAutoP + (travelDistanceAuto * fuelCostEurosPerKm) / VOT7000_other_autoP;
+ gcBus = timeBus + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTrain = timeTrain + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTramMetro = timeTramMetro + (travelDistanceAuto * transitFareEurosPerKm) / VOT7000_other_transit;
+ gcTNC = timeAutoD + (travelDistanceAuto * TNCCostEurosPerKm) / VOT7000_other_TNC; // change in VOT and cost
+ }
+
+ utilityAutoD = interceptNHBO[0] + maleNHBO[0] * (gender.name().equals("MALE")) + driversLicenseNHBO[0] * driversLicense +
+ hhAutosNHBO[0] * hhAutos + distToRailStopNHBO[0] * distToRailStop +
+ agglomerationUrbanNHBO[0] * (areaType.name().equals("AGGLOMERATION") + areaType.name().equals("URBAN")) +
+ ruralNHBO[0] * (areaType.name().equals("RURAL")) + generalizedCostNHBO_Sq[0] * Math.pow(gcAutoD, 2);
+
+ utilityAutoP = interceptNHBO[1] + maleNHBO[1] * (gender.name().equals("MALE")) + driversLicenseNHBO[1] * driversLicense +
+ hhAutosNHBO[1] * hhAutos + distToRailStopNHBO[1] * distToRailStop +
+ agglomerationUrbanNHBO[1] * (areaType.name().equals("AGGLOMERATION") + areaType.name().equals("URBAN")) +
+ ruralNHBO[1] * (areaType.name().equals("RURAL")) + generalizedCostNHBO_Sq[1] * Math.pow(gcAutoP, 2);
+
+ utilityBicycle = interceptNHBO[2] + maleNHBO[2] * (gender.name().equals("MALE")) + driversLicenseNHBO[2] * driversLicense +
+ hhAutosNHBO[2] * hhAutos + distToRailStopNHBO[2] * distToRailStop +
+ agglomerationUrbanNHBO[2] * (areaType.name().equals("AGGLOMERATION") + areaType.name().equals("URBAN")) +
+ ruralNHBO[2] * (areaType.name().equals("RURAL")) + tripLengthNHBO[2] * travelDistanceNMT;
+
+ utilityBus = interceptNHBO[3] + maleNHBO[3] * (gender.name().equals("MALE")) + driversLicenseNHBO[3] * driversLicense +
+ hhAutosNHBO[3] * hhAutos + distToRailStopNHBO[3] * distToRailStop +
+ agglomerationUrbanNHBO[3] * (areaType.name().equals("AGGLOMERATION") + areaType.name().equals("URBAN")) +
+ ruralNHBO[3] * (areaType.name().equals("RURAL")) + generalizedCostNHBO_Sq[3] * Math.pow(gcBus, 2);
+
+ utilityTrain = interceptNHBO[4] + maleNHBO[4] * (gender.name().equals("MALE")) + driversLicenseNHBO[4] * driversLicense +
+ hhAutosNHBO[4] * hhAutos + distToRailStopNHBO[4] * distToRailStop +
+ agglomerationUrbanNHBO[4] * (areaType.name().equals("AGGLOMERATION") + areaType.name().equals("URBAN")) +
+ ruralNHBO[4] * (areaType.name().equals("RURAL")) + generalizedCostNHBO_Sq[4] * Math.pow(gcTrain, 2);
+
+ utilityTramMetro = interceptNHBO[5] + maleNHBO[5] * (gender.name().equals("MALE")) + driversLicenseNHBO[5] * driversLicense +
+ hhAutosNHBO[5] * hhAutos + distToRailStopNHBO[5] * distToRailStop +
+ agglomerationUrbanNHBO[5] * (areaType.name().equals("AGGLOMERATION") + areaType.name().equals("URBAN")) +
+ ruralNHBO[5] * (areaType.name().equals("RURAL")) + generalizedCostNHBO_Sq[5] * Math.pow(gcTramMetro, 2);
+
+ utilityWalk = interceptNHBO[6] + maleNHBO[6] * (gender.name().equals("MALE")) + driversLicenseNHBO[6] * driversLicense +
+ hhAutosNHBO[6] * hhAutos + distToRailStopNHBO[6] * distToRailStop +
+ agglomerationUrbanNHBO[6] * (areaType.name().equals("AGGLOMERATION") + areaType.name().equals("URBAN")) +
+ ruralNHBO[6] * (areaType.name().equals("RURAL")) + tripLengthNHBO[6] * travelDistanceNMT;
+
+ utilityTNC = utilityBus + generalizedCostNHBO_Sq[3] * (Math.pow(gcTNC, 2) - Math.pow(gcBus, 2));
+
+ expsumNestAuto = Math.exp(utilityAutoD / nestingCoefficient) + Math.exp(utilityAutoP / nestingCoefficient);
+ expsumNestTransit = Math.exp(utilityBus / nestingCoefficient) + Math.exp(utilityTrain / nestingCoefficient) + Math.exp(utilityTramMetro / nestingCoefficient);
+ expsumNestNMT = Math.exp(utilityBicycle / nestingCoefficient) + Math.exp(utilityWalk / nestingCoefficient);
+ expsumTopLevel = Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) + Math.exp(utilityTNC) + Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) + Math.exp(nestingCoefficient * Math.log(expsumNestTransit));
+
+ if (expsumNestAuto > 0) {
+ probabilityAutoD = (Math.exp(utilityAutoD / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ probabilityAutoP = (Math.exp(utilityAutoP / nestingCoefficient) / expsumNestAuto) * (Math.exp(nestingCoefficient * Math.log(expsumNestAuto)) / expsumTopLevel);
+ } else {
+ probabilityAutoD = 0.0;
+ probabilityAutoP = 0.0;
+ }
+
+ if (expsumNestTransit > 0) {
+ probabilityBus = (Math.exp(utilityBus / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTrain = (Math.exp(utilityTrain / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ probabilityTramMetro = (Math.exp(utilityTramMetro / nestingCoefficient) / expsumNestTransit) * (Math.exp(nestingCoefficient * Math.log(expsumNestTransit)) / expsumTopLevel);
+ } else {
+ probabilityBus = 0.0;
+ probabilityTrain = 0.0;
+ probabilityTramMetro = 0.0;
+ }
+
+ if (expsumNestNMT > 0) {
+ probabilityBicycle = (Math.exp(utilityBicycle / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestNMT)) / expsumTopLevel);
+ probabilityWalk = (Math.exp(utilityWalk / nestingCoefficient) / expsumNestNMT) * (Math.exp(nestingCoefficient * Math.log(expsumNestWalk)) / expsumTopLevel);
+ } else {
+ probabilityBicycle = 0.0;
+ probabilityWalk = 0.0;
+ }
+
+ probabilityTNC = Math.exp(utilityTNC) / expsumTopLevel;
+
+ return Java.to([probabilityAutoD, probabilityAutoP, probabilityBicycle, probabilityBus, probabilityTrain, probabilityTramMetro, probabilityWalk, probabilityTNC], "double[]");
+
+}
+
+
+
+//AIRPORT
+
+/*var calculateAIRPORTUtilities = function (hh, person, originZone, destinationZone, travelTimes, travelDistanceAuto, travelDistanceNMT, peakHour) {
+
+ asc_autoDriver = 0.;
+ asc_autoPassenger = 0.706154;
+ asc_bus = 1.890414;
+ asc_train = 2.028797;
+ asc_sharedAV = 1.282504;
+
+ //times are in minutes
+ beta_time = -0.0002 * 60;
+ exp_time_autoDriver = 0;
+ exp_time_autoPassenger = 0;
+ exp_time_bus = 0;
+ exp_time_train = 0;
+ exp_time_sharedAV = 0;
+
+ //distance is in minutes
+ beta_distance = -0.00002;
+ exp_distance_autoDriver = 0;
+ exp_distance_autoPassenger = 0;
+ exp_distance_bus = 0;
+ exp_distance_train = 0;
+ exp_distance_sharedAV = 0;
+
+ //generalized cost in minutes and values of time
+ b_gcost_all = -0.018834;
+ VOT_AIRPORT_autoDriver = 63./60;
+ VOT_AIRPORT_autoPassengerAndOther = 83.1 / 60;
+ VOT_AIRPORT_publicTransport = 97.8 / 60;
+
+ //Order of variables in the return variable autoDriver, autoPassenger bus, train, sharedAV
+
+ travelTimeCar = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "car");
+ u_autoDriver = asc_autoDriver +
+ exp_time_autoDriver * Math.exp(beta_time * travelTimeCar) +
+ exp_distance_autoDriver * Math.exp(beta_distance * travelDistanceAuto) +
+ b_gcost_all * (travelTimeCar + travelDistanceAuto * fuelCostEurosPerKm / VOT_AIRPORT_autoDriver);
+
+ u_autoPassenger = asc_autoPassenger +
+ exp_time_autoPassenger * Math.exp(beta_time * travelTimeCar) +
+ exp_distance_autoPassenger * Math.exp(beta_distance * travelDistanceAuto) +
+ b_gcost_all * (travelTimeCar + travelDistanceAuto * fuelCostEurosPerKm / VOT_AIRPORT_autoPassengerAndOther);
+
+ travelTimeBus = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "bus");
+ u_bus = asc_bus +
+ exp_time_bus * Math.exp(beta_time * travelTimeBus) +
+ exp_distance_bus * Math.exp(beta_distance * travelDistanceAuto) +
+ b_gcost_all * (travelTimeBus + travelDistanceAuto * transitFareEurosPerKm / VOT_AIRPORT_publicTransport);
+
+ travelTimeTrain = travelTimes.getTravelTime(originZone, destinationZone, peakHour, "train");
+ u_train = asc_train +
+ exp_time_train * Math.exp(beta_time * travelTimeTrain) +
+ exp_distance_train * Math.exp(beta_distance * travelDistanceAuto) +
+ b_gcost_all * (travelTimeTrain + travelDistanceAuto * transitFareEurosPerKm / VOT_AIRPORT_publicTransport);
+
+ u_sharedAV = asc_sharedAV +
+ exp_time_sharedAV * Math.exp(beta_time * travelTimeCar) +
+ exp_distance_sharedAV * Math.exp(beta_distance * travelDistanceAuto) +
+ b_gcost_all * (travelTimeCar + travelDistanceAuto*sharedAVCostEurosPerKm / VOT_AIRPORT_autoPassengerAndOther);
+
+ return [Math.exp(u_autoDriver), Math.exp(u_autoPassenger), Math.exp(u_bus), Math.exp(u_train), Math.exp(u_sharedAV)];
+}
+
+
+var calculateAIRPORTProbabilities = function (hh, person, originZone, destinationZone, travelTimes, accessTimes,
+ travelDistanceAuto, travelDistanceNMT, peakHour) {
+
+
+ //Order of variables in the return variable [AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk, sharedAV]
+ //calculate utilities for each mode
+ utilities = calculateAIRPORTUtilities(hh, person, originZone, destinationZone, travelTimes, travelDistanceAuto, travelDistanceNMT, peakHour);
+
+ sum_u = utilities[0] + utilities[1] + utilities[2] + utilities[3] + utilities[4];
+
+ probabilityAutoD = utilities[0] / sum_u;
+ probabilityAutoP = utilities[1] / sum_u;
+ probabilityBus = utilities[2] / sum_u;
+ probabilityTrain = utilities[3] / sum_u;
+ probabilitySharedAV = utilities[4] / sum_u;
+
+ return Java.to([probabilityAutoD, probabilityAutoP, 0., probabilityBus, probabilityTrain, 0., 0., probabilitySharedAV], "double[]");
+
+}
+
+var returnLogsumAIRPORT = function (hh, person, originZone, destinationZone, travelTimes, accessTimes,
+ travelDistanceAuto, travelDistanceNMT, travelCostUAM, peakHour, handlingTime, uamFareEurosPerKm) {
+
+ //Order of variables in the return variable [AutoD, AutoP, Bicycle, Bus, Train, TramMetro, Walk, privateAV, sharedAV, UAM]
+ utilities = calculateAIRPORTUtilities(hh, person, originZone, destinationZone, travelTimes, travelDistanceAuto, travelDistanceNMT, peakHour);
+
+ sum_u = utilities[0] + utilities[1] + utilities[2] + utilities[3] + utilities[4];
+
+ return Math.log(sum_u);
+}*/
\ No newline at end of file