Skip to content

Commit

Permalink
Merge branch 'fastsim-2' of github.com:NREL/fastsim into fastsim-2
Browse files Browse the repository at this point in the history
  • Loading branch information
calbaker committed Dec 20, 2023
2 parents e039f04 + 75e60fb commit a3d7f94
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 125 deletions.
63 changes: 39 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,24 @@


# Description
This is the python/rust flavor of [NREL's FASTSim<sup>TM</sup>](https://www.nrel.gov/transportation/fastsim.html), which is based on the original Excel implementation. Effort will be made to keep the core methodology between this software and the Excel flavor in line with one another.

This is the python/rust flavor of [NREL's FASTSim<sup>TM</sup>](https://www.nrel.gov/transportation/fastsim.html), which is based on the original Excel implementation. Effort will be made to keep the core methodology between this software and the Excel flavor in line with one another.

All classes and methods are self-documented.

# Installation

## Python
## Python

Set up and activate a python environment (compatible with Python 3.8 - 3.10; we recommend Python 3.10) with the following steps.
### [Anaconda](https://www.anaconda.com/)

### [Anaconda](https://www.anaconda.com/)

1. Create: `conda create -n fastsim python=3.10`
1. Activate: `conda activate fastsim`

### [venv](https://docs.python.org/3/library/venv.html)

There is some variation based on your Operating System:

- PowerShell (windows):
Expand All @@ -32,10 +37,13 @@ There is some variation based on your Operating System:
1. Activate: `fastsim-venv/Scripts/activate.bat`

## FASTSim

### Via PyPI

In an active Python environment created above, run `pip install fastsim`.

### Building from Scratch

Developers might want to install the code in place so that FASTSim files can be editable (the `-e` flag for pip provides this behavior). This option can be handy since FASTSim will be installed in place from the installation location and any updates will be propagated each time FASTSim is freshly imported. To do this, you'll need to have the [Rust toolchain](https://www.rust-lang.org/tools/install) installed.

- Option 1: run `sh build_and_test.sh` in root folder.
Expand All @@ -46,19 +54,23 @@ Developers might want to install the code in place so that FASTSim files can be
1. Run `pytest -v python/fastsim/tests/`

# Usage
To see and run examples, navigate to `./python/fastsim/demos` and run the various *demo.py files to see fastsim use cases. There are other examples in fastsim/tests.

To see and run examples, navigate to `./python/fastsim/demos` and run the various *demo.py files to see fastsim use cases. There are other examples in fastsim/tests.

# Adding FASTSim as a Depency in Rust

## Via GitHub

Add this line:
`fastsim-core = { git = "https://github.nrel.gov/MBAP/fastsim", branch = "rust-port" }`
to your Cargo.toml file, modifying the `branch` key as appropriate.

## Via Cargo

This has not been implemented yet.

# List of Abbreviations

cur = current time step
prev = previous time step
cyc = drive cycle
Expand All @@ -85,12 +97,14 @@ in = component input
out = component output

# Known Issues

Rust versions of classes have limited Language Server Protocol integration, and we are actively working on fixing this.

# Release Notes

2.1.1 -- license changed to Apache 2.0, default cycle grade and road type to zero if not provided, defaults to regenerative braking parameters, optional documentation fields now generated in Rust
2.1.0 -- release and installation improvements, RustVehicle init cleanup, calibration improvements
2.0.11 - 2.0.22 -- PyPI fixes. Also, Rust version is now >100x faster than Python version.
2.0.11 - 2.0.22 -- PyPI fixes. Also, Rust version is now >100x faster than Python version.
2.0.10 -- logging fixes, proc macro reorganization, some CAVs performance fixes
2.0.9 -- support for mac ARM/RISC architecture
2.0.8 -- performance improvements
Expand Down Expand Up @@ -118,24 +132,25 @@ Rust versions of classes have limited Language Server Protocol integration, and
1.0.4 -- bug fix with custom engine curve
1.0.3 -- bug fixes, faster testing
1.0.2 -- forced type np.float64 on vehicle mass attributes
1.0.1 -- Added `vehYear` attribute to vehicle and other minor changes.
1.0.0 -- Implemented unittest package. Fixed energy audit calculations to be based on achieved speed. Updated this file. Improved documentation. Vehicle can be instantiated as dict.
0.1.5 -- Updated to be compatible with ADOPT
0.1.4 -- Bug fix: `mcEffMap` is now robust to having zero as first element
0.1.3 -- Bug fix: `fastsim.vehicle.Vehicle` method `set_init_calcs` no longer overrides `fcEffMap`.
0.1.2 -- Fixes os-dependency of xlwings by not running stuff that needs xlwings. Improvements in functional test. Refinment utomated typying of jitclass objects.
0.1.1 -- Now includes label fuel economy and/or battery kW-hr/mi values that match excel and test for benchmarking against Excel values and CPU time.
1.0.1 -- Added `vehYear` attribute to vehicle and other minor changes.
1.0.0 -- Implemented unittest package. Fixed energy audit calculations to be based on achieved speed. Updated this file. Improved documentation. Vehicle can be instantiated as dict.
0.1.5 -- Updated to be compatible with ADOPT
0.1.4 -- Bug fix: `mcEffMap` is now robust to having zero as first element
0.1.3 -- Bug fix: `fastsim.vehicle.Vehicle` method `set_init_calcs` no longer overrides `fcEffMap`.
0.1.2 -- Fixes os-dependency of xlwings by not running stuff that needs xlwings. Improvements in functional test. Refinment utomated typying of jitclass objects.
0.1.1 -- Now includes label fuel economy and/or battery kW-hr/mi values that match excel and test for benchmarking against Excel values and CPU time.

# Contributors
Chad Baker -- [email protected]
Aaron Brooker -- [email protected]
Kyle Carow -- [email protected]
Jeffrey Gonder -- [email protected]
Jacob Holden -- [email protected]
Jinghu Hu -- [email protected]
Jason Lustbader -- [email protected]
Sean Lopp -- [email protected]
Matthew Moniot -- [email protected]
Grant Payne -- [email protected]
Laurie Ramroth -- [email protected]
Eric Wood -- [email protected]

Chad Baker -- <[email protected]>
Aaron Brooker -- <[email protected]>
Kyle Carow -- <[email protected]>
Jeffrey Gonder -- <[email protected]>
Jacob Holden -- <[email protected]>
Jinghu Hu -- <[email protected]>
Jason Lustbader -- <[email protected]>
Sean Lopp -- <[email protected]>
Matthew Moniot -- <[email protected]>
Grant Payne -- <[email protected]>
Laurie Ramroth -- <[email protected]>
Eric Wood -- <[email protected]>
18 changes: 8 additions & 10 deletions build_and_test.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# build and test with local version of `fastsim-proc-macros`
echo "Testing rust" && \
(cd rust/fastsim-core/ && cargo test) && \
(cd rust/fastsim-cli/ && cargo test) && \
pip install -qe ".[dev]" && \
echo "Running python tests" && \
pytest -v python/fastsim/tests/ && \
echo "Verifying that demos run" && \
pytest -v python/fastsim/demos/ && \
echo "Complete success!"
echo "Testing rust" &&
(cd rust && cargo test) &&
pip install -qe ".[dev]" &&
echo "Running python tests" &&
pytest -v python/fastsim/tests/ &&
echo "Verifying that demos run" &&
pytest -v python/fastsim/demos/ &&
echo "Complete success!"
60 changes: 23 additions & 37 deletions rust/fastsim-cli/src/bin/vehicle-import-cli.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use anyhow::{self, Context};
use clap::Parser;
use fastsim_core::vehicle_utils::{
get_default_cache_url, get_fastsim_data_dir, import_and_save_all_vehicles_from_file,
};
use fastsim_core::utils::create_project_subdir;
use fastsim_core::vehicle_utils::{get_default_cache_url, import_and_save_all_vehicles_from_file};
use std::fs;
use std::path::Path;
use std::path::{Path, PathBuf};

// eliminate db path items; instead, assume we have a config directory on the OS which we'll get via the directories crate
// - if the config directory (fastsim_cache) doesn't exist:
Expand All @@ -24,37 +24,28 @@ struct Args {
cache_url: Option<String>,
}

fn run_import(args: &Args) {
fn run_import(args: &Args) -> anyhow::Result<()> {
// confirm paths exist for all input files
let input_file_path = Path::new(&args.input_file_path);
if !input_file_path.exists() {
panic!("input file path does not exist: {}", args.input_file_path);
}
anyhow::ensure!(
input_file_path.exists(),
"input file path does not exist: {}",
args.input_file_path
);
let data_dir_path = match &args.data_dir_path {
Some(data_dir_str) => {
let dd_path = Path::new(data_dir_str);
if !dd_path.exists() {
panic!("No data directory at {}", data_dir_str);
}
dd_path.to_path_buf()
}
None => {
if let Some(fastsim_data_dir) = get_fastsim_data_dir() {
fastsim_data_dir
} else {
panic!("Could not create/retrieve FASTSim directory and no other data directory provided");
}
let dd_path = PathBuf::from(data_dir_str);
anyhow::ensure!(dd_path.exists(), "No data directory at {}", data_dir_str);
dd_path
}
None => create_project_subdir("fe_label_data")?,
};
let output_dir_path = Path::new(&args.output_dir_path);
if !output_dir_path.exists() {
// create output directory if it doesn't exist
let r = fs::create_dir(output_dir_path);
if r.is_err() {
panic!("Could not create directory {}", args.output_dir_path);
}
fs::create_dir(output_dir_path)?;
} else if !output_dir_path.is_dir() {
panic!(
anyhow::bail!(
"Output dir exists but is not a directory: {}",
args.output_dir_path
);
Expand All @@ -66,23 +57,18 @@ fn run_import(args: &Args) {
get_default_cache_url()
}
};
let result = import_and_save_all_vehicles_from_file(
import_and_save_all_vehicles_from_file(
input_file_path,
data_dir_path.as_path(),
output_dir_path,
Some(cache_url),
);
if result.is_err() {
println!(
"Error with importing and saving all vehicles from file: {:?}",
result.err()
);
} else {
println!("Successfully ran vehicle import");
}
)
.with_context(|| "Error with importing and saving all vehicles from file")?;
println!("Successfully ran vehicle import");
Ok(())
}

pub fn main() {
pub fn main() -> anyhow::Result<()> {
let args = Args::parse();
run_import(&args);
run_import(&args)
}
11 changes: 11 additions & 0 deletions rust/fastsim-core/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Module containing miscellaneous utility functions.

use directories::ProjectDirs;
use itertools::Itertools;
use lazy_static::lazy_static;
use ndarray::*;
Expand Down Expand Up @@ -514,6 +515,16 @@ pub fn tire_code_to_radius<S: AsRef<str>>(tire_code: S) -> anyhow::Result<f64> {
Ok(radius_mm / 1000.0)
}

/// Creates/gets an OS-specific data directory and returns the path.
pub fn create_project_subdir<P: AsRef<Path>>(subpath: P) -> anyhow::Result<PathBuf> {
let proj_dirs = ProjectDirs::from("gov", "NREL", "fastsim").ok_or_else(|| {
anyhow!("Could not build path to project directory: \"gov.NREL.fastsim\"")
})?;
let path = PathBuf::from(proj_dirs.config_dir()).join(subpath);
std::fs::create_dir_all(path.as_path())?;
Ok(path)
}

#[cfg(feature = "pyo3")]
pub mod array_wrappers {
use crate::proc_macros::add_pyo3_api;
Expand Down
Loading

0 comments on commit a3d7f94

Please sign in to comment.