Skip to content

Commit

Permalink
feat: multiple scenarios (#63)
Browse files Browse the repository at this point in the history
- checks on scenario folders
- function for creating sub scenarios of an original scenario (multiple scenario)
- "multiple" key to parameters.schema.json
- now generating multiple scenarios when "multiple" parameter is present
- black style
  • Loading branch information
leo-desbureaux-tellae authored Aug 9, 2022
1 parent f1a2400 commit 4f29856
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 6 deletions.
7 changes: 6 additions & 1 deletion starling_sim/model_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from starling_sim.models.FF_VS.model import Model as FF_VS_model
from starling_sim.simulation_scenario import SimulationScenario
from starling_sim.utils.paths import model_import_path
from starling_sim.utils.utils import create_sub_scenarios

import logging
import time
Expand Down Expand Up @@ -120,7 +121,7 @@ def get_model_class(model_code, pkg):
def launch_simulation(scenario_path, pkg):
"""
Realises the initialisation, setup, run and output of the simulation
using the given parameters file. Displays logs of execution times
using the given parameters file. Displays log of execution times
:param scenario_path: path to scenario folder
:param pkg: name of the source package
Expand All @@ -134,6 +135,10 @@ def launch_simulation(scenario_path, pkg):
# read simulation parameters
simulation_scenario.get_scenario_parameters()

if "multiple" in simulation_scenario:
create_sub_scenarios(simulation_scenario)
exit(0)

# init the simulator
logging.info(
"Initializing simulator for the model code "
Expand Down
7 changes: 7 additions & 0 deletions starling_sim/schemas/parameters.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,13 @@
"description": "Seed used for the generation of random events",
"default": 42
},
"multiple": {
"advanced": true,
"type": "integer",
"title": "Multiple scenario",
"description": "Number of sub scenarios to generate",
"minimum": 1
},
"user_routing_parameters": {
"advanced": true,
"type": "object",
Expand Down
20 changes: 16 additions & 4 deletions starling_sim/simulation_scenario.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,21 @@ def _set_scenario_folders(self, scenario_folder_path: str):

# check scenario folder
self.scenario_folder = os.path.join(scenario_folder_path, "")
if not os.path.exists(self.scenario_folder):
raise ValueError("The scenario folder does not exist : {}".format(self.scenario_folder))
if not (os.path.exists(self.scenario_folder) and os.path.isdir(self.scenario_folder)):
raise ValueError(
"The scenario folder does not exist or is not a folder : {}".format(
self.scenario_folder
)
)

# check inputs folder
self.inputs_folder = paths.scenario_inputs_folder(self.scenario_folder)
if not os.path.exists(self.inputs_folder):
raise ValueError("The inputs folder does not exist : {}".format(self.inputs_folder))
if not (os.path.exists(self.inputs_folder) and os.path.isdir(self.inputs_folder)):
raise ValueError(
"The inputs folder does not exist or is not a folder : {}".format(
self.inputs_folder
)
)

# create outputs folder if it does not exist
if "OUTPUT_FOLDER" in os.environ:
Expand All @@ -85,6 +93,10 @@ def get_scenario_parameters(self):
except (FileNotFoundError, json.JSONDecodeError) as e:
raise ValueError("Error while loading the scenario parameters : {}".format(str(e)))

# check scenario folder against scenario name
if os.path.basename(os.path.dirname(self.scenario_folder)) != self.parameters["scenario"]:
raise ValueError("The scenario folder must be named after the scenario name")

# parameters validation
schema = json_load(paths.schemas_folder() + self.BASE_PARAM_SCHEMA)
validate_against_schema(self.parameters, schema)
Expand Down
59 changes: 58 additions & 1 deletion starling_sim/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@
from shapely.geometry import Polygon, LineString
from numbers import Integral
from jsonschema import Draft7Validator, Draft4Validator, validators, ValidationError, RefResolver
from starling_sim.utils.paths import schemas_folder, gtfs_feeds_folder, osm_graphs_folder
from starling_sim.utils.paths import (
schemas_folder,
gtfs_feeds_folder,
osm_graphs_folder,
scenario_inputs_folder,
PARAMETERS_FILENAME,
INPUT_FOLDER_NAME,
)

pd.set_option("display.expand_frame_repr", False)

Expand Down Expand Up @@ -1064,3 +1071,53 @@ def get_git_revision_hash() -> str:
Get current git commit hash
"""
return subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii").strip()


# multiple scenarios


def create_sub_scenarios(simulation_scenario):

nb_scenarios = simulation_scenario["multiple"]
scenarios_folder = os.path.join(simulation_scenario.scenario_folder, "scenarios")
create_if_not_exists(scenarios_folder)

# set random seed
np.random.seed(simulation_scenario["seed"])
seeds = np.random.randint(100000, size=nb_scenarios)

sub_scenario_name_format = "{base_scenario}-{index}"

for i in range(nb_scenarios):

sub_scenario_name = sub_scenario_name_format.format(
base_scenario=simulation_scenario.name, index=i + 1
)
sub_scenario_folder = os.path.join(scenarios_folder, sub_scenario_name)
sub_scenario_inputs_folder = scenario_inputs_folder(sub_scenario_folder)

if os.path.exists(sub_scenario_folder):
print("Scenario {} already created".format(sub_scenario_name))
continue
else:
print("Creating scenario " + sub_scenario_name)

# create sub scenario folders
create_if_not_exists(sub_scenario_folder)
create_if_not_exists(sub_scenario_inputs_folder)

# sub scenario inputs
sub_parameters = simulation_scenario.copy_parameters()
sub_parameters["scenario"] = sub_scenario_name
sub_parameters["seed"] = int(seeds[i])
del sub_parameters["multiple"]
json_pretty_dump(
sub_parameters, os.path.join(sub_scenario_inputs_folder, PARAMETERS_FILENAME)
)

# create symlinks to original inputs
for input_file in os.listdir(simulation_scenario.inputs_folder):
if input_file == PARAMETERS_FILENAME:
continue
input_filepath = os.path.join("..", "..", "..", INPUT_FOLDER_NAME, input_file)
os.symlink(input_filepath, os.path.join(sub_scenario_inputs_folder, input_file))

0 comments on commit 4f29856

Please sign in to comment.