Tech Meeting 2024 Q1 - Run with(out) ini
files#
The technical meeting that took place on 2024.04.03 related to the Q1 sprints covered the following topics:
Running an analysis whilst modifying the
.ini
configuration files.Usage of enumerations within
ra2ce
.Discussion on long term views for
ra2ce
subprojects.Walk-through, on how to add new analyses to the current solution.
This jupyter notebook will covers the first point.
1. Running an analysis whilst modifying the .ini
configuration files#
It is entirely possible to generate a ra2ce analysis (or just a network) without having to generate .ini
files. However, most of the times we will only want to modify a few properties of a given network.ini
or analysis.ini
file. At the current version v0.8.1
we can solve both options as follows:
Load the
.ini
files and then modify them at our own choice.Fully creating a
Ra2ceHandler
instance based on python objects (NetworkConfigData
andAnalysisConfigData
).
1.1. Modify existing configurations from code#
Given our most common use case, we want to load a network and analysis and potentially modifying some of its properties. This was already accomplished in the “ra2ce hackathon 2024 Q1”.
To achieve it, simply use the regular Ra2ceHandler
with your desired ini
files and then access the corresponding NetworkConfigData
and AnalysisConfigData
properties. See the example below.
Initialize the Ra2ce handler with valid
.ini
files.
[ ]:
from pathlib import Path
from ra2ce.ra2ce_handler import Ra2ceHandler
# Define the location of our example test data.
_root_dir = Path("...", "data", "damages_analysis")
assert _root_dir.exists()
_network_file = _root_dir.joinpath("network.ini")
assert _network_file.exists()
_analysis_file = _root_dir.joinpath("analysis.ini")
assert _analysis_file.exists()
# Initialize handler
_handler = Ra2ceHandler(_network_file, _analysis_file)
In addition, we can verify if the analysis and network are correctly set.
[ ]:
from ra2ce.network.network_config_data.network_config_data import NetworkConfigData
from ra2ce.analysis.analysis_config_data.analysis_config_data import AnalysisConfigData
assert isinstance(_handler.input_config.network_config.config_data, NetworkConfigData)
assert isinstance(_handler.input_config.analysis_config.config_data, AnalysisConfigData)
Configure the network and analyses
[ ]:
_handler.configure()
Run the analysis.
[ ]:
_handler.run_analysis()
1.2. Create Ra2ce Handler without ini
files#
DISCLAIMER! This functionality will be streamlined as resolution of issue #389
This step, however longer than required, will demonstrate how to emulate the usage of ini
files. We relate the .ini
files as:
network.ini
toNetworkConfigData
,analysis.ini
toAnalysisConfigData
.
Both ConfigData
items are python objects (dataclasses
) as such, it is entirely possible to manually manipulate them via code, therefore avoiding the need of definition and usage of their related ini
files.
Initialize the objects representing the
.ini
files.
[ ]:
from ra2ce.network.network_config_data.network_config_data import NetworkConfigData
from ra2ce.analysis.analysis_config_data.analysis_config_data import AnalysisConfigData
_network_config_data = NetworkConfigData()
_analysis_config_data = AnalysisConfigData()
(Optional) Initialize logger.
[ ]:
from ra2ce.ra2ce_logging import Ra2ceLogger
# Initialize logger.
_output_logger_path = Path("..", "data", "logging")
if _output_logger_path.exists():
import shutil
shutil.rmtree(_output_logger_path)
_output_logger_path.mkdir(parents=True)
Ra2ceLogger(logging_dir=_output_logger_path, logger_name="RA2CE")
Put said objects together in the config wrapper.
[ ]:
# Define network config wrapper
from ra2ce.network.network_config_wrapper import NetworkConfigWrapper
_network_config_wrapper = NetworkConfigWrapper()
_network_config_wrapper.config_data = _network_config_data
_network_config_wrapper.configure()
# Define analysis config wrapper
from ra2ce.analysis.analysis_config_wrapper import AnalysisConfigWrapper
_analysis_config_wrapper = AnalysisConfigWrapper()
_analysis_config_wrapper.config_data = _analysis_config_data
_analysis_config_wrapper.config_data.network = _network_config_wrapper.config_data.network
_analysis_config_wrapper.config_data.origins_destinations = (
_network_config_wrapper.config_data.origins_destinations
)
_analysis_config_wrapper.graph_files = _network_config_wrapper.graph_files
_analysis_config_wrapper.configure()
# Initialize wrapper
from ra2ce.configuration.config_wrapper import ConfigWrapper
_config_wrapper = ConfigWrapper()
_config_wrapper.analysis_config = _analysis_config_wrapper
_config_wrapper.network_config = _network_config_wrapper
_config_wrapper.configure()
Run analysis
[ ]:
# Run analysis
from ra2ce.runners import AnalysisRunnerFactory
_runner = AnalysisRunnerFactory.get_runner(_config_wrapper)
_runner.run(_config_wrapper.analysis_config)
1.3. Create Ra2ce Handler without ini
files - after #389#
In this example the network and analysis configuration are read from file before creation of the Ra2ceHandler
. This can be replaced by any other way of creating your configuration, e.g. by creating it from scratch by NetworkConfigWData()
and AnalysisConfigData()
. The handler doesn’t need file at creation time. The analysis should yield the same results as example_damages.ipynb
. Note that the logfile isn’t created.
[ ]:
from pathlib import Path
from ra2ce.analysis.analysis_config_data.analysis_config_data_reader import AnalysisConfigDataReader
from ra2ce.network.network_config_data.network_config_data_reader import NetworkConfigDataReader
from ra2ce.ra2ce_handler import Ra2ceHandler
from ra2ce.runners import AnalysisRunnerFactory
# Initialize configuration (replace this with your own configuration)
_data_dir = Path("..", "data", "damages_analysis")
_network_ini = _data_dir.joinpath("network.ini")
_network = NetworkConfigDataReader().read(_network_ini)
_network.root_path = _data_dir.parent
_network.input_path = _data_dir.joinpath("input")
_network.static_path = _data_dir.joinpath("static")
_network.output_path = _data_dir.joinpath("output")
_analysis_ini = _data_dir.joinpath("analysis.ini")
_analysis = AnalysisConfigDataReader().read(_analysis_ini)
# Initialize handler from configuration
_handler = Ra2ceHandler.from_config(_network, _analysis)
# Configure handler
_handler.configure()
# Run analysis
_runner = AnalysisRunnerFactory.get_runner(_handler.input_config)
_runner.run(_handler.input_config.analysis_config)
1.4. Run an analysis with one line of code!#
From issue #460 it is possible to simply run an anlysis without having to do the two extra steps .configure()
and .run_analysis()
.
We can now chose to: - 1. Run directly an analysis providing two files with (Ra2ceHandler.run_with_ini_files(Path, Path)
). - 2. Run an analysis by providing two configuration files (Ra2ceHandler.run_with_config_data(NetworkConfigData, AnalysisConfigData)
).
1.4.1. Run an analysis providing two files.#
[ ]:
from pathlib import Path
from ra2ce.ra2ce_handler import Ra2ceHandler, AnalysisResultWrapper
from ra2ce.analysis.analysis_config_data.analysis_config_data_reader import AnalysisConfigDataReader
from ra2ce.network.network_config_data.network_config_data_reader import NetworkConfigDataReader
# Initialize configuration (replace this with your own configuration)
_data_dir = Path("..", "data", "single_link_redun")
# Network file
_network_ini = _data_dir.joinpath("network.ini")
assert _network_ini.exists()
# Analysis file
_analysis_ini = _data_dir.joinpath("analyses.ini")
assert _analysis_ini.exists()
# Get directly the results without extra steps.
_results = Ra2ceHandler.run_with_ini_files(_network_ini, _analysis_ini)
assert any(_results)
assert all(isinstance(_result_wrapper, AnalysisResultWrapper) for _result_wrapper in _results)
1.4.2. Run an anlysis providing NetworkConfigData
and AnalysisConfigData
#
[ ]:
from pathlib import Path
from ra2ce.ra2ce_handler import Ra2ceHandler, AnalysisResultWrapper
from ra2ce.analysis.analysis_config_data.analysis_config_data_reader import AnalysisConfigDataReader, AnalysisConfigData
from ra2ce.network.network_config_data.network_config_data_reader import NetworkConfigDataReader, NetworkConfigData
# Initialize configuration (replace this with your own configuration)
_data_dir = Path("..", "data", "single_link_redun")
# NOTE! For simplicity we just load "valid" ini files instead of generating our own
# config data.
# Network file
_network_config_data = NetworkConfigDataReader().read(_data_dir.joinpath("network.ini"))
assert isinstance(_network_config_data, NetworkConfigData)
# Analysis file
_analysis_config_data = AnalysisConfigDataReader().read(_data_dir.joinpath("analyses.ini"))
assert isinstance(_analysis_config_data, AnalysisConfigData)
# Get directly the results without extra steps.
_results = Ra2ceHandler.run_with_config_data(_network_config_data, _analysis_config_data)
assert any(_results)
assert all(isinstance(_result_wrapper, AnalysisResultWrapper) for _result_wrapper in _results)