RMA Kinetics
RMA Kinetics is a library of synthetic serum marker kinetic models. Specifically, we focus on a class of synthetic markers called Released Markers of Activity or RMAs.
The core library is written in Rust and high level Python bindings are available for more ergonomic analysis with existing tools such as numpy or scipy. For the Rust library documentation, please see the docs.rs page.
If you're interested in a graphical interface for running the models, please see our application docs.
Installation
git clone https://github.com/nsbuitrago/rma-kinetics-rs
cd rma-kinetics-rs
uv venv
uvx maturin develop --uv --features py -m crates/rma-kinetics/Cargo.toml
cargo add rma-kinetics
# Or Cargo.toml
[dependencies]
rma-kinetics = "<version>"
Please see the GitHub README.md for more details on building the library from source.
Usage
Running a model
There are three core model modules available, including constitutive, tetoff, and chemogenetic.
Each module at least contains a corresponding Model and State object.
For example, to run the default constitutive model over the time span 0-100 hours,
we create a new Model and State object and solve over the desired time span.
The default parameters of the constitutive model are akin to RMA expression in the CA1
region of the hippocampus under a human-synapsin promoter.
from rma_kinetics.models.constitutive import Model, State
from rma_kinetics.solvers import Dopri5
model = Model()
init_state = State()
solver = Dopri5()
t0 = 0; tf = 100; dt = 1
solution = model.solve(t0, tf, dt, init_state, solver)
print(f"Final plasma RMA concentration: {solution.plasma_rma[-1]}")
use rma_kinetics::models::constitutive::{Model, State};
use rma_kinetics::Solve;
use differential_equations::methods::ExplicitRungeKutta;
let model = Model::default();
let init_state = State::default();
let mut solver = ExplicitRungeKutta::dopri5();
let t0 = 0.;
let tf = 100.;
let dt = 1.;
let solution = model.solve(t0, tf, dt, init_state, &mut solver);
Please see the Models section for more details on a specific model.
Accessing solutions
Specific arrays can be accessed directly from the returned Solution object
for further analysis. In Python, the solve method returns a Solution
class, while in Rust we return a Solution struct from the differential_equations crate.
Below are some examples of accessing specific species from Solution.
plasma_rma = solution.plasma_rma # access the numpy array for plasma RMA
brain_rma = solution.brain_rma # etc.
let plasma_rma = solution.y
.iter()
.map(|state| state.plasma_rma).collect::<Vec<f64>>();
let brain_rma = solution.y
.iter()
.map(|state| state.brain_rma).collect::<Vec<f64>>();