From 142ebb2ec7e2b4297b55ee1a620ec8fe4aad8eab Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Wed, 22 May 2024 08:47:16 -0600 Subject: [PATCH 1/8] added several `log::debug` --- rust/altrios-core/src/consist/consist_model.rs | 6 +++++- rust/altrios-core/src/meet_pass/est_times/mod.rs | 6 ++++++ rust/altrios-core/src/train/speed_limit_train_sim.rs | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/rust/altrios-core/src/consist/consist_model.rs b/rust/altrios-core/src/consist/consist_model.rs index ed5a7d39..2d866f07 100644 --- a/rust/altrios-core/src/consist/consist_model.rs +++ b/rust/altrios-core/src/consist/consist_model.rs @@ -331,7 +331,11 @@ impl Consist { // maybe put logic for toggling `engine_on` here for (i, (loco, pwr_out)) in self.loco_vec.iter_mut().zip(pwr_out_vec.iter()).enumerate() { - log::info!("Solving locomotive #{}", i); + log::info!( + "Solving locomotive #{}\n`pwr_out: `{} MW", + i, + pwr_out.get::().format_eng(None) + ); loco.solve_energy_consumption(*pwr_out, dt, engine_on) .map_err(|err| { err.context(format!( diff --git a/rust/altrios-core/src/meet_pass/est_times/mod.rs b/rust/altrios-core/src/meet_pass/est_times/mod.rs index 1ec4e406..aa653fd8 100644 --- a/rust/altrios-core/src/meet_pass/est_times/mod.rs +++ b/rust/altrios-core/src/meet_pass/est_times/mod.rs @@ -491,6 +491,7 @@ pub fn make_est_times>( let time_depart = speed_limit_train_sim.state.time; // Push initial fake nodes + log::debug!("{}", format_dbg!("Push initial fake nodes.")); est_times.push(EstTime { idx_next: 1, ..Default::default() @@ -502,6 +503,7 @@ pub fn make_est_times>( }); // Add origin estimated times + log::debug!("{}", format_dbg!("Add origin estimated times.")); for orig in origs { ensure!( orig.offset == si::Length::ZERO, @@ -520,6 +522,7 @@ pub fn make_est_times>( ..Default::default() }; + log::debug!("{}", format_dbg!()); insert_est_time( &mut est_times, &mut est_alt, @@ -535,6 +538,7 @@ pub fn make_est_times>( ..Default::default() }, ); + log::debug!("{}", format_dbg!()); insert_est_time( &mut est_times, &mut est_alt, @@ -565,6 +569,7 @@ pub fn make_est_times>( } // Fix distances for different origins + log::debug!("{}", format_dbg!("Fix distances for different origins")); { let mut est_idx_fix = 1; while est_idx_fix != EST_IDX_NA { @@ -580,6 +585,7 @@ pub fn make_est_times>( let mut est_idxs_end = Vec::::with_capacity(8); // Iterate and process all saved sims + log::debug!("{}", format_dbg!("Iterate and process all saved sims")); while let Some(mut sim) = saved_sims.pop() { let mut has_split = false; ensure!( diff --git a/rust/altrios-core/src/train/speed_limit_train_sim.rs b/rust/altrios-core/src/train/speed_limit_train_sim.rs index 942c447e..561209df 100644 --- a/rust/altrios-core/src/train/speed_limit_train_sim.rs +++ b/rust/altrios-core/src/train/speed_limit_train_sim.rs @@ -293,6 +293,11 @@ impl SpeedLimitTrainSim { self.train_res .update_res(&mut self.state, &self.path_tpc, &Dir::Fwd)?; self.solve_required_pwr()?; + log::debug!( + "{}\ntime step: {}", + format_dbg!(), + self.state.time.get::().format_eng(None) + ); self.loco_con.solve_energy_consumption( self.state.pwr_whl_out, self.state.dt, From b64197a3806eee385f8376cf90e562a05d7f7b82 Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Wed, 22 May 2024 18:06:08 -0600 Subject: [PATCH 2/8] changed to `with_context` from `ok_or...` --- rust/altrios-core/src/consist/consist_model.rs | 4 ++-- .../src/consist/locomotive/battery_electric_loco.rs | 2 +- .../altrios-core/src/consist/locomotive/hybrid_loco.rs | 2 +- .../src/consist/locomotive/locomotive_model.rs | 9 +++++---- rust/altrios-core/src/track/link/link_impl.rs | 10 ++++++---- rust/altrios-core/src/track/path_track/path_tpc.rs | 2 +- rust/altrios-core/src/train/speed_limit_train_sim.rs | 10 +++++++++- rust/altrios-core/src/train/train_config.rs | 4 ++-- 8 files changed, 27 insertions(+), 16 deletions(-) diff --git a/rust/altrios-core/src/consist/consist_model.rs b/rust/altrios-core/src/consist/consist_model.rs index 2d866f07..32e7b6ba 100644 --- a/rust/altrios-core/src/consist/consist_model.rs +++ b/rust/altrios-core/src/consist/consist_model.rs @@ -182,7 +182,7 @@ impl Consist { |f_sum, (i, loco)| -> anyhow::Result { Ok(loco .force_max()? - .ok_or_else(|| anyhow!("Locomotive {i} does not have `force_max` set"))? + .with_context(|| anyhow!("Locomotive {i} does not have `force_max` set"))? + f_sum) }, ) @@ -504,7 +504,7 @@ impl Mass for Consist { |m_acc, (i, loco)| -> anyhow::Result { let loco_mass = loco .mass()? - .ok_or_else(|| anyhow!("Locomotive {i} does not have `mass` set"))?; + .with_context(|| anyhow!("Locomotive {i} does not have `mass` set"))?; let new_mass: si::Mass = loco_mass + m_acc; Ok(new_mass) }, diff --git a/rust/altrios-core/src/consist/locomotive/battery_electric_loco.rs b/rust/altrios-core/src/consist/locomotive/battery_electric_loco.rs index f363c330..e522f6ec 100644 --- a/rust/altrios-core/src/consist/locomotive/battery_electric_loco.rs +++ b/rust/altrios-core/src/consist/locomotive/battery_electric_loco.rs @@ -80,7 +80,7 @@ impl LocoTrait for BatteryElectricLoco { ) -> anyhow::Result<()> { // TODO: proposed interface location to feed in the catenary self.res.set_cur_pwr_out_max( - pwr_aux.ok_or(anyhow!(format_dbg!("`pwr_aux` not provided")))?, + pwr_aux.with_context(|| anyhow!(format_dbg!("`pwr_aux` not provided")))?, None, None, )?; diff --git a/rust/altrios-core/src/consist/locomotive/hybrid_loco.rs b/rust/altrios-core/src/consist/locomotive/hybrid_loco.rs index cd8ff3a1..538cb697 100644 --- a/rust/altrios-core/src/consist/locomotive/hybrid_loco.rs +++ b/rust/altrios-core/src/consist/locomotive/hybrid_loco.rs @@ -97,7 +97,7 @@ impl LocoTrait for Box { dt: si::Time, ) -> anyhow::Result<()> { self.res.set_cur_pwr_out_max( - pwr_aux.ok_or(anyhow!(format_dbg!("`pwr_aux` not provided")))?, + pwr_aux.with_context(|| anyhow!(format_dbg!("`pwr_aux` not provided")))?, None, None, )?; diff --git a/rust/altrios-core/src/consist/locomotive/locomotive_model.rs b/rust/altrios-core/src/consist/locomotive/locomotive_model.rs index 32167d13..69311774 100644 --- a/rust/altrios-core/src/consist/locomotive/locomotive_model.rs +++ b/rust/altrios-core/src/consist/locomotive/locomotive_model.rs @@ -171,13 +171,13 @@ impl LocoParams { fn from_hash(mut params: HashMap<&str, f64>) -> anyhow::Result { let pwr_aux_offset_watts = params .remove("pwr_aux_offset_watts") - .ok_or_else(|| anyhow!("Must provide 'pwr_aux_offset_watts'."))?; + .with_context(|| anyhow!("Must provide 'pwr_aux_offset_watts'."))?; let pwr_aux_traction_coeff_ratio = params .remove("pwr_aux_traction_coeff_ratio") - .ok_or_else(|| anyhow!("Must provide 'pwr_aux_traction_coeff_ratio'."))?; + .with_context(|| anyhow!("Must provide 'pwr_aux_traction_coeff_ratio'."))?; let force_max_newtons = params .remove("force_max_newtons") - .ok_or_else(|| anyhow!("Must provide 'force_max_newtons'."))?; + .with_context(|| anyhow!("Must provide 'force_max_newtons'."))?; let mass_kg = params.remove("mass_kg"); ensure!( params.is_empty(), @@ -655,7 +655,8 @@ impl Locomotive { } pub fn force_max(&self) -> anyhow::Result> { - self.check_force_max()?; + self.check_force_max() + .with_context(|| anyhow!(format_dbg!()))?; Ok(self.force_max) } diff --git a/rust/altrios-core/src/track/link/link_impl.rs b/rust/altrios-core/src/track/link/link_impl.rs index c95ab7a4..eafc80dd 100644 --- a/rust/altrios-core/src/track/link/link_impl.rs +++ b/rust/altrios-core/src/track/link/link_impl.rs @@ -69,10 +69,12 @@ impl Link { self.speed_set = Some( self.speed_sets .get(&train_type) - .ok_or(anyhow!( - "No value found for train_type: {:?} in `speed_sets`.", - train_type - ))? + .with_context(|| { + anyhow!( + "No value found for train_type: {:?} in `speed_sets`.", + train_type + ) + })? .clone(), ); self.speed_sets = HashMap::new(); diff --git a/rust/altrios-core/src/track/path_track/path_tpc.rs b/rust/altrios-core/src/track/path_track/path_tpc.rs index 2a600b9c..9662c43d 100644 --- a/rust/altrios-core/src/track/path_track/path_tpc.rs +++ b/rust/altrios-core/src/track/path_track/path_tpc.rs @@ -383,7 +383,7 @@ fn extract_speed_set<'a>( speed_sets .iter() .find(|&sps| sps.0 == &train_params.train_type) - .ok_or_else(|| { + .with_context(|| { anyhow!( "`speed_set` is `None` and `train_params.train_type` {:?} not found in `speed_sets.keys()` {:?}", train_params.train_type, diff --git a/rust/altrios-core/src/train/speed_limit_train_sim.rs b/rust/altrios-core/src/train/speed_limit_train_sim.rs index 561209df..ac8ff669 100644 --- a/rust/altrios-core/src/train/speed_limit_train_sim.rs +++ b/rust/altrios-core/src/train/speed_limit_train_sim.rs @@ -296,7 +296,7 @@ impl SpeedLimitTrainSim { log::debug!( "{}\ntime step: {}", format_dbg!(), - self.state.time.get::().format_eng(None) + self.state.time.get::().format_eng(Some(9)) ); self.loco_con.solve_energy_consumption( self.state.pwr_whl_out, @@ -323,6 +323,14 @@ impl SpeedLimitTrainSim { || (self.state.offset < self.path_tpc.offset_end() && self.state.speed != si::Velocity::ZERO) { + log::debug!( + "{}", + format_dbg!( + self.state.offset < self.path_tpc.offset_end() - 1000.0 * uc::FT + || (self.state.offset < self.path_tpc.offset_end() + && self.state.speed != si::Velocity::ZERO) + ) + ); self.step()?; } Ok(()) diff --git a/rust/altrios-core/src/train/train_config.rs b/rust/altrios-core/src/train/train_config.rs index 647fb94d..04bcd190 100644 --- a/rust/altrios-core/src/train/train_config.rs +++ b/rust/altrios-core/src/train/train_config.rs @@ -426,7 +426,7 @@ impl TrainSimBuilder { // `self.origin_id` verified to be `Some` earlier location_map .get(self.origin_id.as_ref().unwrap()) - .ok_or_else(|| { + .with_context(|| { anyhow!(format!( "{}\n`origin_id`: \"{}\" not found in `location_map` keys: {:?}", format_dbg!(), @@ -437,7 +437,7 @@ impl TrainSimBuilder { // `self.destination_id` verified to be `Some` earlier location_map .get(self.destination_id.as_ref().unwrap()) - .ok_or_else(|| { + .with_context(|| { anyhow!(format!( "{}\n`destination_id`: \"{}\" not found in `location_map` keys: {:?}", format_dbg!(), From 5d1fd059fa0d295289e76fc7f92651778cec316d Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Tue, 18 Jun 2024 14:36:09 -0600 Subject: [PATCH 3/8] incremental progress toward better error message --- rust/altrios-core/src/track/link/link_impl.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rust/altrios-core/src/track/link/link_impl.rs b/rust/altrios-core/src/track/link/link_impl.rs index c95ab7a4..d8da342f 100644 --- a/rust/altrios-core/src/track/link/link_impl.rs +++ b/rust/altrios-core/src/track/link/link_impl.rs @@ -323,7 +323,11 @@ impl SerdeAPI for Network { })?; let mut network = match Self::from_reader(file, extension) { Ok(network) => network, - Err(err) => NetworkOld::from_file(filepath).with_context(|| err)?.into(), + Err(err) => NetworkOld::from_file(filepath) + .map_err(|old_err| { + anyhow!("attempting to load as `Network`:\n{}\nattempting to load as `NetworkOld`:\n{}", err, old_err) + })? + .into(), }; network.init()?; From d29105ca1effaf5810f8a947e7a99ee803d45d46 Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Tue, 18 Jun 2024 15:22:41 -0600 Subject: [PATCH 4/8] Error provides more useful information ```RuntimeError: attempting to load as `Network`: Combo error: - Link at index = 9 must be valid! - Headings must be valid! - Offsets must be sorted and unique! Invalid offsets: [[58917.834013887914 m^1, 57017.834013887914 m^1]] - Link validation unfinished! - Links validation unfinished! attempting to load as `NetworkOld`: .[0]: missing field `speed_sets` at line 2 column 11 ``` --- rust/altrios-core/src/track/link/elev.rs | 10 +++++++++- rust/altrios-core/src/track/link/heading.rs | 10 +++++++++- rust/altrios-core/src/track/link/link_impl.rs | 2 +- rust/altrios-core/src/track/path_track/link_point.rs | 10 +++++++++- .../src/track/path_track/path_res_coeff.rs | 10 +++++++++- 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/rust/altrios-core/src/track/link/elev.rs b/rust/altrios-core/src/track/link/elev.rs index bcf6308c..68d95332 100644 --- a/rust/altrios-core/src/track/link/elev.rs +++ b/rust/altrios-core/src/track/link/elev.rs @@ -64,7 +64,15 @@ impl ObjState for [Elev] { errors.push(anyhow!("There must be at least two elevations!")); } if !self.windows(2).all(|w| w[0].offset < w[1].offset) { - errors.push(anyhow!("Offsets must be sorted and unique!")); + let err_pairs: Vec> = self + .windows(2) + .filter(|w| w[0].offset >= w[1].offset) + .map(|w| vec![w[0].offset, w[1].offset]) + .collect(); + errors.push(anyhow!( + "Offsets must be sorted and unique! Invalid offsets: {:?}", + err_pairs + )); } errors.make_err() } diff --git a/rust/altrios-core/src/track/link/heading.rs b/rust/altrios-core/src/track/link/heading.rs index 554bd448..90029b4e 100644 --- a/rust/altrios-core/src/track/link/heading.rs +++ b/rust/altrios-core/src/track/link/heading.rs @@ -73,7 +73,15 @@ impl ObjState for [Heading] { errors.push(anyhow!("There must be at least two headings!")); } if !self.windows(2).all(|w| w[0].offset < w[1].offset) { - errors.push(anyhow!("Offsets must be sorted and unique!")); + let err_pairs: Vec> = self + .windows(2) + .filter(|w| w[0].offset >= w[1].offset) + .map(|w| vec![w[0].offset, w[1].offset]) + .collect(); + errors.push(anyhow!( + "Offsets must be sorted and unique! Invalid offsets: {:?}", + err_pairs + )); } errors.make_err() } diff --git a/rust/altrios-core/src/track/link/link_impl.rs b/rust/altrios-core/src/track/link/link_impl.rs index d8da342f..0b60018b 100644 --- a/rust/altrios-core/src/track/link/link_impl.rs +++ b/rust/altrios-core/src/track/link/link_impl.rs @@ -325,7 +325,7 @@ impl SerdeAPI for Network { Ok(network) => network, Err(err) => NetworkOld::from_file(filepath) .map_err(|old_err| { - anyhow!("attempting to load as `Network`:\n{}\nattempting to load as `NetworkOld`:\n{}", err, old_err) + anyhow!("\nattempting to load as `Network`:\n{}\nattempting to load as `NetworkOld`:\n{}", err, old_err) })? .into(), }; diff --git a/rust/altrios-core/src/track/path_track/link_point.rs b/rust/altrios-core/src/track/path_track/link_point.rs index e3b6797f..e3052a02 100644 --- a/rust/altrios-core/src/track/path_track/link_point.rs +++ b/rust/altrios-core/src/track/path_track/link_point.rs @@ -97,7 +97,15 @@ impl ObjState for [LinkPoint] { } if !self.windows(2).all(|w| w[0].offset < w[1].offset) { - errors.push(anyhow!("Link point offsets must be sorted and unique!")); + let err_pairs: Vec> = self + .windows(2) + .filter(|w| w[0].offset >= w[1].offset) + .map(|w| vec![w[0].offset, w[1].offset]) + .collect(); + errors.push(anyhow!( + "Link point offsets must be sorted and unique! Invalid offsets: {:?}", + err_pairs + )); } errors.make_err() diff --git a/rust/altrios-core/src/track/path_track/path_res_coeff.rs b/rust/altrios-core/src/track/path_track/path_res_coeff.rs index 1a24a2be..f544d431 100644 --- a/rust/altrios-core/src/track/path_track/path_res_coeff.rs +++ b/rust/altrios-core/src/track/path_track/path_res_coeff.rs @@ -72,7 +72,15 @@ impl ObjState for [PathResCoeff] { errors.push(anyhow!("There must be at least two path res coeffs!")); } if !self.windows(2).all(|w| w[0].offset < w[1].offset) { - errors.push(anyhow!("Offsets must be sorted and unique!")); + let err_pairs: Vec> = self + .windows(2) + .filter(|w| w[0].offset >= w[1].offset) + .map(|w| vec![w[0].offset, w[1].offset]) + .collect(); + errors.push(anyhow!( + "Offsets must be sorted and unique! Invalid offsets: {:?}", + err_pairs + )); } if !self .windows(2) From fdd19ef4df2ce05b332c02090fda793ff3e5b825 Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Thu, 20 Jun 2024 10:29:52 -0600 Subject: [PATCH 5/8] locked down numpy version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 63d4cd31..4041d144 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ classifiers = [ ] dependencies = [ "pandas>=2", - "numpy", + "numpy==1.24", "pymoo==0.6", "openpyxl", "xlrd", From 6100dfd8edcf73513a5532da4e7fa4db526b37a0 Mon Sep 17 00:00:00 2001 From: StevenGotGame Date: Fri, 21 Jun 2024 13:31:21 -0500 Subject: [PATCH 6/8] Update venv instructions in README for windows --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4450f0c5..44620499 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,10 @@ The Advanced Locomotive Technology and Rail Infrastructure Optimization System ( 1. Setup a python environment. ALTRIOS can work with Python 3.9, or 3.10, but we recommend 3.10 for better performance and user experience. Create a python environment for ALTRIOS with either of two methods: - Option 1 -- [Python Venv](https://docs.python.org/3/library/venv.html) 1. Navigate to the ALTRIOS folder you just cloned or any folder you'd like for using ALTRIOS. Remember the folder you use! - 1. Assuming you have Python 3.10 installed, run `python3.10 -m venv altrios-venv` in your terminal enviroment (we recommend PowerShell in Windows, which comes pre-installed). This tells Python 3.10 to use the `venv` module to create a virtual environment (which will be ignored by git if named `altrios-venv`) in the `ALTRIOS/altrios-venv/`. + 1. Assuming you have Python 3.10 installed, run `(path to your python3.10 e.g. ~/AppData/Local/Programs/Python/Python310/python.exe) -m venv altrios-venv` in your terminal enviroment (we recommend PowerShell in Windows, which comes pre-installed). This tells Python 3.10 to use the `venv` module to create a virtual environment (which will be ignored by git if named `altrios-venv`) in the `ALTRIOS/altrios-venv/`. 1. Activate the environment you just created to install packages or anytime you're running ALTRIOS: - Mac and Linux: `source altrios-venv/bin/activate` - - Windows: `altrios-venv/Scripts/activate.bat` in a windows command prompt or power shell or `source ./altrios-venv/scripts/activate` in git bash terminal + - Windows: `altrios-venv/Scripts/activate.bat` in a windows command prompt or power shell or `source altrios-venv/Scripts/activate` in git bash terminal - When the environment is activated, your terminal session will have a decorator that looks like `(altrios-venv)`. - Option 2 -- Anaconda: 1. Open an Anaconda prompt (in Windows, we recommend Anaconda Powershell Prompt) and run the command `conda create -n altrios python=3.10` to create an Anaconda environment named `altrios`. @@ -33,6 +33,7 @@ The Advanced Locomotive Technology and Rail Infrastructure Optimization System ( #### ALTRIOS Setup With your Python environment activated, run `pip install altrios`. +If you choose to opt in developer version, run `python -m pip install “.[dev]”` Congratulations, you've completed installation! Whenever you need to use ALTRIOS, be sure to activate your python environment created above. From 6dfdd855aaf67a5e5dc7f28071476354c87c6fe8 Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Fri, 21 Jun 2024 17:25:31 -0600 Subject: [PATCH 7/8] changed from maturin to pip for robustness --- build_and_test.sh | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build_and_test.sh b/build_and_test.sh index 47bf6904..65aad72a 100644 --- a/build_and_test.sh +++ b/build_and_test.sh @@ -1,10 +1,8 @@ # assumes a python environment has been created and activated echo "Testing rust" && \ (cd rust/ && cargo test --workspace) && \ -# pip install -qe ".[dev]" && \ -# assumes `pip install -qe ".[dev]"` has been run already echo "Building python API" && \ -maturin develop --release && \ +pip install -qe ".[dev]" && \ echo "Running python tests" && \ pytest -v python/altrios/tests && \ echo "Verifying that demos run" && \ From cb8a1a5b0c46c4751ec2244fec1c1cdf7fd8da02 Mon Sep 17 00:00:00 2001 From: Chad Baker Date: Thu, 27 Jun 2024 12:31:44 -0600 Subject: [PATCH 8/8] updated to show both windows and mac and changed UIUC to UT --- README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 44620499..1fddc7a5 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![Model Framework Schematic](https://raw.githubusercontent.com/NREL/altrios/main/.github/images/ALTRIOS_schematic_Alfred_Hicks.png) -The Advanced Locomotive Technology and Rail Infrastructure Optimization System ([ALTRIOS](https://www.nrel.gov/transportation/altrios.html)) is a unique, fully integrated, open-source software tool to evaluate strategies for deploying advanced locomotive technologies and associated infrastructure for cost-effective decarbonization. ALTRIOS simulates freight-demand driven train scheduling, mainline meet-pass planning, locomotive dynamics, train dynamics, energy conversion efficiencies, and energy storage dynamics of line-haul train operations. Because new locomotives represent a significant long-term capital investment and new technologies must be thoroughly demonstrated before deployment, this tool provides guidance on the risk/reward tradeoffs of different technology rollout strategies. An open, integrated simulation tool is invaluable for identifying future research needs and making decisions on technology development, routes, and train selection. ALTRIOS was developed as part of a collaborative effort by a team comprising The National Renewable Energy Laboratory (NREL), University of Illinois Urbana-Champaign (UIUC), Southwest Research Institute (SwRI), and BNSF Railway. +The Advanced Locomotive Technology and Rail Infrastructure Optimization System ([ALTRIOS](https://www.nrel.gov/transportation/altrios.html)) is a unique, fully integrated, open-source software tool to evaluate strategies for deploying advanced locomotive technologies and associated infrastructure for cost-effective decarbonization. ALTRIOS simulates freight-demand driven train scheduling, mainline meet-pass planning, locomotive dynamics, train dynamics, energy conversion efficiencies, and energy storage dynamics of line-haul train operations. Because new locomotives represent a significant long-term capital investment and new technologies must be thoroughly demonstrated before deployment, this tool provides guidance on the risk/reward tradeoffs of different technology rollout strategies. An open, integrated simulation tool is invaluable for identifying future research needs and making decisions on technology development, routes, and train selection. ALTRIOS was developed as part of a collaborative effort by a team comprising The National Renewable Energy Laboratory (NREL), University of Texas (UT), Southwest Research Institute (SwRI), and BNSF Railway. ## Installation @@ -21,13 +21,18 @@ The Advanced Locomotive Technology and Rail Infrastructure Optimization System ( 1. Setup a python environment. ALTRIOS can work with Python 3.9, or 3.10, but we recommend 3.10 for better performance and user experience. Create a python environment for ALTRIOS with either of two methods: - Option 1 -- [Python Venv](https://docs.python.org/3/library/venv.html) 1. Navigate to the ALTRIOS folder you just cloned or any folder you'd like for using ALTRIOS. Remember the folder you use! - 1. Assuming you have Python 3.10 installed, run `(path to your python3.10 e.g. ~/AppData/Local/Programs/Python/Python310/python.exe) -m venv altrios-venv` in your terminal enviroment (we recommend PowerShell in Windows, which comes pre-installed). This tells Python 3.10 to use the `venv` module to create a virtual environment (which will be ignored by git if named `altrios-venv`) in the `ALTRIOS/altrios-venv/`. + 1. Assuming you have Python 3.10 installed, run + - `(path to your python3.10 e.g. ~/AppData/Local/Programs/Python/Python310/python.exe) -m venv altrios-venv` in Windows + - `python3.10 -m venv altrios-venv` in Mac/Unix/Linux + in your terminal enviroment (we recommend PowerShell in Windows, which comes pre-installed). + + This tells Python 3.10 to use the `venv` module to create a virtual environment (which will be ignored by git if named `altrios-venv`) in the `ALTRIOS/altrios-venv/`. 1. Activate the environment you just created to install packages or anytime you're running ALTRIOS: - Mac and Linux: `source altrios-venv/bin/activate` - Windows: `altrios-venv/Scripts/activate.bat` in a windows command prompt or power shell or `source altrios-venv/Scripts/activate` in git bash terminal - When the environment is activated, your terminal session will have a decorator that looks like `(altrios-venv)`. - Option 2 -- Anaconda: - 1. Open an Anaconda prompt (in Windows, we recommend Anaconda Powershell Prompt) and run the command `conda create -n altrios python=3.10` to create an Anaconda environment named `altrios`. + 1. Open an Anaconda prompt (in Windows, we recommend _Anaconda_ Powershell Prompt) and run the command `conda create -n altrios python=3.10` to create an Anaconda environment named `altrios`. 1. Activate the environment to install packages or anytime you're running ALTRIOS: run `conda activate altrios`. #### ALTRIOS Setup