1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
/*!
* # Reservoirs - A library for modeling Bolin & Rodhe reservoirs.
* Bolin & Rodhe (1973) describe methods for characterizing the turnover rate of mass accumulating in a reservoir.
* The distribution of ages of particles in the reservoir constrain the possible input and output rates that could
* produce the observed record. The functions in this crate allow the user to compare synthetic accumulation records to
* observed records using the K-S and Kuiper statistics, to determine the best-fitting input/output pair for an observed record.
*
* In my research at Oregon State University, I estimate the transit times of stream sediments moving through headwater valleys
* of the Coast Range by fitting reservoir models to a record of charcoal ages sampled from stream bank deposits. Inherited age
* refers to the age of charcoal when it enters a stream deposit. If we do not account for inherited age in the model, then transit times
* become artificially inflated. I have added an inherited age capacity to reservoirs, and while this is not a traditional feature
* of Bolin & Rodhe reservoirs, it is useful for dealing with charcoal ages.
*
* This library includes the full code base used to estimate transit times for my ongoing dissertation, published here in the interest
* of academic transparency.
*
* - Please direct questions, comments or insults to the [github repository](https://github.com/crumplecup/reservoirs).
* - View the crate documentation on [docs.rs](https://docs.rs/reservoirs/).
*
* ## Quick Start
*
* To use reservoirs, add it to your `Cargo.toml`
* ```toml
* [dependencies]
* reservoirs = "^0.1.7"
* ```
*
* - Load the crate prelude in the preamble of your `main.rs`.
* - Load charcoal data from headwaters of the OCR:
* ```no_run
* use reservoirs::prelude::*;
*
* fn main() -> Result<(), ResError> {
* use reservoirs::prelude::*;
*
* // mean expected deposit age and inherited age by facies
* let dep = Sample::read("https://github.com/crumplecup/reservoirs/blob/master/examples/dep.csv")?;
* let iat = Sample::read("https://github.com/crumplecup/reservoirs/blob/master/examples/iat.csv")?;
*
* // subset mean ages of debris flows
* let df: Vec<f64> = dep.iter()
* .filter(|x| x.facies == "DF")
* .map(|x| x.age)
* .collect();
* // subset inherited ages
* let ia: Vec<f64> = iat.iter()
* .map(|x| x.age)
* .collect();
*
* let mut debris_flows = Reservoir::new()
* .input(&0.687)?
* .output(&0.687)?
* .inherit(&ia);
*
* // model parameters
* let period = 30000.0; // run simulations for 30000 years
* let runs = 1000; // run 1000 simulated accumulations per candidate pair for goodness-of-fit
* let bins = 500; // split observation into bins for deriving CDF
*
* // create reservoir model using builder pattern
* let mut model = Model::new(debris_flows)
* .runs(runs);
*
* // sample a stereotypical record from 1000 runs of 30000 years
* let eg = model.stereotype(bins);
* // compare the CDF of the synthetic example to the observed debris-flow deposit record
* plot::comp_cdf(&eg, &df, "examples/df_cdf.png");
*
* Ok(())
* }
* ```
* ![](https://github.com/crumplecup/reservoirs/blob/master/examples/df_cdf.png?raw=true)
*
*
*
* Create reservoirs using a builder pattern. First make a 'blank' reservoir using
* [new](reservoir/struct.Reservoir.html#method.new),
* then assign it features using the [input](reservoir/struct.Reservoir.html#method.input),
* [output](reservoir/struct.Reservoir.html#method.output) and
* [inherit](reservoir/struct.Reservoir.html#method.inherit) methods.
*
* ```rust
* use reservoirs::prelude::*;
*
* fn main() -> Result<(), ResError> {
* // build step by step
* let mut res = Reservoir::new();
* res = res.input(&0.78)?;
* res = res.output(&0.78)?;
* res = res.inherit(&vec![10.0, 20.0, 27.0, 100.3, 7000.0, 10000.0]);
*
* // or inline, same result
* let res_b = Reservoir::new()
* .input(&0.78)?
* .output(&0.78)?
* .inherit(&vec![10.0, 20.0, 27.0, 100.3, 7000.0, 10000.0]);
*
* Ok(())
*}
* ```
*/
#![warn(missing_docs)]
#![forbid(unsafe_code)]
mod errors;
/// Plotting functions for reservoir models.
pub mod plot;
/// Structs and methods related to simulating reservoir models.
pub mod reservoir;
/// Basic utility functions, largely reinventing the wheel.
pub mod utils;
/// Standard import of useful features of reservoirs.
pub mod prelude {
pub use crate::errors::ResError;
pub use crate::plot;
pub use crate::reservoir::{Bootstrap, Fluvial, Model, ModelManager, Reservoir, Sample};
pub use crate::utils;
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}