Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
name: Build

on: [push]
on:
push:
branches: ["main"]

env:
CARGO_TERM_COLOR: always
Expand Down
20 changes: 14 additions & 6 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[package]
version = "0.9.2"
version = "0.9.3"
name = "react-rs"
edition = "2024"

Expand Down
45 changes: 26 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
<h1 align="center"><b> REACT_RS </b></h1>

[![Test](https://github.com/DNYFZR/react-rs/actions/workflows/test.yml/badge.svg)](https://github.com/DNYFZR/react-rs/actions/workflows/test.yml) [![Build](https://github.com/DNYFZR/react-rs/actions/workflows/build.yml/badge.svg)](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**

Expand All @@ -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
Expand All @@ -60,27 +63,27 @@ 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
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(
Expand All @@ -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 :
Expand All @@ -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.
7 changes: 1 addition & 6 deletions tests/test_weibull.py
Original file line number Diff line number Diff line change
@@ -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 = [
{
Expand Down
Loading