diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index dea0f70..960788d 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -1,6 +1,8 @@
name: Build
-on: [push]
+on:
+ push:
+ branches: ["main"]
env:
CARGO_TERM_COLOR: always
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 86391d2..22243ce 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -17,19 +17,27 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- - uses: actions-rust-lang/setup-rust-toolchain@stable
- - uses: actions/setup-python@v6
+
+ - name: Setup Python
+ uses: actions/setup-python@v6
with:
python-version: "3.12"
- cache: pip
- - run: pip install -r pyproject.toml
- - name: Install app via Maturin
+ - name: Setup Python env
+ run: python -m venv .venv
+
+ - name: Setup Rust
+ uses: dtolnay/rust-toolchain@stable
+
+ - name: Build app via Maturin
uses: PyO3/maturin-action@v1
with:
- command: develop
+ command: build
args: --release
+ - name: Install app
+ run: python -m pip install target/wheels/react_rs*.whl
+
- name: Install Python test dependencies
run: pip install pytest mock codecov pydocstyle pytest-cov pylint pylint_junit
diff --git a/Cargo.toml b/Cargo.toml
index 70fbe66..0e057e8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
[package]
-version = "0.9.2"
+version = "0.9.3"
name = "react-rs"
edition = "2024"
diff --git a/README.md b/README.md
index 46deca2..f6bbdf1 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,24 @@
REACT_RS
+[](https://github.com/DNYFZR/react-rs/actions/workflows/test.yml) [](https://github.com/DNYFZR/react-rs/actions/workflows/build.yml)
+
## **Summary**
React_rs (reactors) is Python package with Rust backend functionality for executing Discrete Event simulations in a fast & cost efficient way.
-- Exposed Rust functions have a corresponding Python function in the [API definition](python/react_rs/__init__.py) which allows the application to convert the Rust polars DataFrame into a Python polars DataFrame & vice versa.
-
-- There are also native Python components to the package, which are in dedicated scripts in the [Python directory](python/react_rs).
-
The core functionality of the app is :
- Fit, adjust & generate of a range of Weibull model survival curves
-- Simulation of discrete events over a user-defined number of timesteps & simulations based on the survival curve in the probabilities column of the input dataset - these can be from the internal Weibull module, or from any other user-defined model
+- Simulation of discrete events over a user-defined number of timesteps & simulations based on the survival curve in the probabilities column of the input dataset
+
+ - Survival curves can be from the internal Weibull module, or from any other user-defined model, so long as there is a column in the input table & its name is defined under 'probs_col' (see example below)
-- Application of financial limits to simulation outputs, and reallocation of replacement events in line with these limits
+- Application of financial constraints to simulation outputs, with randomised reallocation of replacement events in line with each timestep limit
-- Event or cost based aggregations are summaries of the totals for each simulation & timestep
+- Event & cost based aggregations showing a summary of totals for each simulation & timestep
-- Profile based aggregation creates a summary of the count of items ages at each timestep within each simulation iteration
+- Profile based aggregation creates a count of item ages at each timestep within each iteration
## **Usage**
@@ -41,14 +41,17 @@ for model, params in model_config.items():
# Fit method auto-handles base model & adjustments to mean
wb.fit(model_name=model, **params)
-# Generate survival curve DataFrame under 'curves' attribute
+# Generate survival curve dictionary under 'curves' attribute
wb.generate()
-# Join survival curves DataFrame to input DataFrame
+# Join survival curves to input DataFrame
df = pl.read_parquet("./tests/data/input.parquet").join(
- pl.DataFrame({"model": wb.curves.keys(), "curve": wb.curves.values()}),
- "model",
- "left",
+ other=pl.DataFrame({
+ "model": wb.curves.keys(),
+ "curve": wb.curves.values()
+ }),
+ on="model",
+ how="left",
)
# Execute simulation in Rust
@@ -60,7 +63,7 @@ sim_result = react_rs.simulate(
probs_col="curve",
n_sims=100,
n_steps=50,
- parallel_limit=10,
+ parallel_limit=10, # control concurrent parallel operations
)
# Constrain simulation output in Rust
@@ -68,19 +71,19 @@ sim_result_constrained = react_rs.constrain(
df=sim_result,
constrain_steps=30, # limit steps taken through constraint system
iter_regex="step",
- cost_col="cost",
- constraints=[int(50e6) for _ in range(30)],
+ cost_col="cost", # name is standardised to 'cost' by simulate function
+ constraints=[int(50e6) for _ in range(30)],
partition_by="sim_id",
parallel_limit=10,
)
-# Aggregate simulation outputs
+# Aggregate simulation outputs)
sim_result_agg = react_rs.aggregate(
df=sim_result,
partition_by="sim_id",
iter_regex="step",
target_value=0,
- cost_col="cost", # None if events are req'd
+ cost_col="cost", # set to None if events are req'd
)
sim_result_const_agg = react_rs.aggregate(
@@ -107,6 +110,10 @@ sim_constrained_profile = react_rs.profile(
## **Development**
+- Exposed Rust functions have a corresponding Python function in the [API definition](python/react_rs/__init__.py) which mirrors the input structure of the Rust function & returns its output. Should there be an error while running the function, the Rust errors will be propogated back to the user.
+
+- There are native Python components to the package, which are in dedicated scripts in the [Python directory](python/react_rs).
+
### **Build**
The [build workflow](.github/workflows/build.yml) is configured to build for Windows, Linux & MacOS :
@@ -125,4 +132,4 @@ These tests call all of the functionality within the native Python code & the Ru
### **Notes**
-- When working on [__init__.py](python/react_rs/__init__.py), your IDE may highlight imports from the react_rs package with an error - this is normal and can be ignored.
+- If working on the [Python API](python/react_rs/__init__.py), your IDE may highlight imports from the react_rs package with an error - this is normal and can be ignored.
diff --git a/tests/test_weibull.py b/tests/test_weibull.py
index 609ef61..5bb2a21 100644
--- a/tests/test_weibull.py
+++ b/tests/test_weibull.py
@@ -1,12 +1,7 @@
# Weibull Module Test Script
-import sys
-
import numpy as np
import pytest
-
-sys.path.append("..")
-
-from python.react_rs._weibull import Weibull
+from react_rs import Weibull
test_case = [
{