diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 491c5f1f..b6bd2dad 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -16,10 +16,10 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v4 with: - distribution: "adopt" - java-version: "11" + distribution: "corretto" + java-version: "17" - uses: actions/cache@v2 env: CACHE_NUMBER: 0 diff --git a/matsim/runtime/eqasim.py b/matsim/runtime/eqasim.py index aebf8a44..9b649bcb 100644 --- a/matsim/runtime/eqasim.py +++ b/matsim/runtime/eqasim.py @@ -5,9 +5,9 @@ import matsim.runtime.java as java import matsim.runtime.maven as maven -DEFAULT_EQASIM_VERSION = "1.3.1" +DEFAULT_EQASIM_VERSION = "1.5.0" DEFAULT_EQASIM_BRANCH = "develop" -DEFAULT_EQASIM_COMMIT = "7cbe85b" +DEFAULT_EQASIM_COMMIT = "f1af717" def configure(context): context.stage("matsim.runtime.git") diff --git a/matsim/simulation/prepare.py b/matsim/simulation/prepare.py index 61bea131..17ad23d1 100644 --- a/matsim/simulation/prepare.py +++ b/matsim/simulation/prepare.py @@ -133,26 +133,35 @@ def execute(context): "--factor", str(0.8) ]) - # Route population - eqasim.run(context, "org.eqasim.core.scenario.routing.RunPopulationRouting", [ - "--config-path", "%sconfig.xml" % context.config("output_prefix"), - "--output-path", "%spopulation.xml.gz" % context.config("output_prefix"), - "--threads", context.config("processes"), - "--config:plans.inputPlansFile", "prepared_population.xml.gz" - ]) - assert os.path.exists("%s/%spopulation.xml.gz" % (context.path(), context.config("output_prefix"))) # Optionally, perform mode choice if context.config("mode_choice"): - eqasim.run(context, "org.eqasim.ile_de_france.RunModeChoice", [ + eqasim.run(context, "org.eqasim.ile_de_france.standalone_mode_choice.RunStandaloneModeChoice", [ "--config-path", "%sconfig.xml" % context.config("output_prefix"), - "--output-plans-path", "%spopulation.xml.gz" % context.config("output_prefix"), + "--config:standaloneModeChoice.outputDirectory", "mode_choice", + "--config:standaloneModeChoice.removePersonsWithNoValidAlternatives", "true", "--config:global.numberOfThreads", context.config("processes"), - "--output-csv-path", "%stripModes.csv" % context.config("output_prefix") + "--write-output-csv-trips", "true", + "--skip-scenario-check", "true", + "--config:plans.inputPlansFile", "prepared_population.xml.gz" + ]) + + assert os.path.exists("%s/mode_choice/output_plans.xml.gz" % context.path()) + assert os.path.exists("%s/mode_choice/output_trips.csv" % context.path()) + assert os.path.exists("%s/mode_choice/output_pt_legs.csv" % context.path()) + + shutil.copy("%s/mode_choice/output_plans.xml.gz" % context.path(), + "%s/%spopulation.xml.gz" % (context.path(), context.config("output_prefix"))) + else: + # Route population + eqasim.run(context, "org.eqasim.core.scenario.routing.RunPopulationRouting", [ + "--config-path", "%sconfig.xml" % context.config("output_prefix"), + "--output-path", "%spopulation.xml.gz" % context.config("output_prefix"), + "--threads", context.config("processes"), + "--config:plans.inputPlansFile", "prepared_population.xml.gz" ]) - assert os.path.exists("%s/%stripModes.csv" % (context.path(), context.config("output_prefix"))) - assert os.path.exists("%s/%spopulation.xml.gz" % (context.path(), context.config("output_prefix"))) + assert os.path.exists("%s/%spopulation.xml.gz" % (context.path(), context.config("output_prefix"))) # Validate scenario eqasim.run(context, "org.eqasim.core.scenario.validation.RunScenarioValidator", [ diff --git a/matsim/writers.py b/matsim/writers.py index 3979d47d..da99084f 100644 --- a/matsim/writers.py +++ b/matsim/writers.py @@ -94,15 +94,18 @@ def end_person(self): self._write_line('') def start_attributes(self): - self._require_scope(self.PERSON_SCOPE) + # We don't require any scope here because attributes can be almost anywhere self._write_line('') self.indent += 1 + # And we need to remember which scope we were in before starting the attributes + self._pre_attributes_scope = self.scope self.scope = self.ATTRIBUTES_SCOPE def end_attributes(self): self._require_scope(self.ATTRIBUTES_SCOPE) self.indent -= 1 - self.scope = self.PERSON_SCOPE + # Resetting the scope that we were in before starting the attributes + self.scope = self._pre_attributes_scope self._write_line('') def add_attribute(self, name, type, value): @@ -143,7 +146,11 @@ def add_leg(self, mode, departure_time, travel_time): self._write('mode="%s" ' % mode) self._write('dep_time="%s" ' % self.time(departure_time)) self._write('trav_time="%s" ' % self.time(travel_time)) - self._write('/>\n') + self._write('>\n') + self.start_attributes() + self.add_attribute('routingMode', 'java.lang.String', mode) + self.end_attributes() + self._write_line('') class HouseholdsWriter(XmlWriter): HOUSEHOLDS_SCOPE = 0 diff --git a/synthesis/output.py b/synthesis/output.py index 7ac6295e..d25a5dc5 100644 --- a/synthesis/output.py +++ b/synthesis/output.py @@ -1,3 +1,4 @@ +import shutil import geopandas as gpd import pandas as pd import shapely.geometry as geo @@ -131,15 +132,19 @@ def execute(context): if context.config("mode_choice"): df_mode_choice = pd.read_csv( - "{}/{}tripModes.csv".format(context.path("matsim.simulation.prepare"), output_prefix), + "{}/mode_choice/output_trips.csv".format(context.path("matsim.simulation.prepare"), output_prefix), delimiter = ";") - - df_mode_choice = df_mode_choice.rename(columns = { - "personId": "person_id", "tripId": "trip_index", "mode" : "mode"}) - + + df_mode_choice = df_mode_choice.rename(columns={"person_trip_id": "trip_index"}) + columns_to_keep = ["person_id", "trip_index"] + columns_to_keep.extend([c for c in df_trips.columns if c not in df_mode_choice.columns]) + df_trips = df_trips[columns_to_keep] df_trips = pd.merge(df_trips, df_mode_choice, on = [ "person_id", "trip_index"], how="left", validate = "one_to_one") + shutil.copy("%s/mode_choice/output_pt_legs.csv" % (context.path("matsim.simulation.prepare")), + "%s/%spt_legs.csv" % (output_path, output_prefix)) + assert not np.any(df_trips["mode"].isna()) df_trips.to_csv("%s/%strips.csv" % (output_path, output_prefix), sep = ";", index = None, lineterminator = "\n") diff --git a/tests/test_determinism.py b/tests/test_determinism.py index bf43e5ed..80efb725 100644 --- a/tests/test_determinism.py +++ b/tests/test_determinism.py @@ -133,7 +133,7 @@ def _test_determinism_matsim(index, data_path, tmpdir): #"ile_de_france_network.xml.gz": "5f10ec295b49d2bb768451c812955794", "ile_de_france_households.xml.gz": "64a0c9fab72aad51bc6adb926a1c9d44", #"ile_de_france_facilities.xml.gz": "5ad41afff9ae5c470082510b943e6778", - "ile_de_france_config.xml": "f374807f12a5151fe1efb6e9904e1a56" + "ile_de_france_config.xml": "481fac5fb3e7b90810caa38ff460c00a" } # activities.gpkg, trips.gpkg, meta.json,