update
This commit is contained in:
parent
e034d2387b
commit
83a9b08007
|
@ -1,6 +1,8 @@
|
||||||
use crate::types::{CustomUnit, Estimation, IngestionDose, StandardIngestionDose};
|
use crate::types::{
|
||||||
|
CustomUnitDose, CustomUnitIngestionDose, Estimation, IngestionDose, StandardIngestionDose,
|
||||||
|
};
|
||||||
|
|
||||||
fn add_standard_deviation(
|
pub fn add_standard_deviation(
|
||||||
expectation_x: f64,
|
expectation_x: f64,
|
||||||
standard_deviation_x: f64,
|
standard_deviation_x: f64,
|
||||||
expectation_y: f64,
|
expectation_y: f64,
|
||||||
|
@ -9,27 +11,21 @@ fn add_standard_deviation(
|
||||||
let sum_x = standard_deviation_x.powi(2) + expectation_x.powi(2);
|
let sum_x = standard_deviation_x.powi(2) + expectation_x.powi(2);
|
||||||
let sum_y = standard_deviation_y.powi(2) + expectation_y.powi(2);
|
let sum_y = standard_deviation_y.powi(2) + expectation_y.powi(2);
|
||||||
|
|
||||||
let expectations = expectation_x.powi(2) + expectation_y.powi(2);
|
let expectations = expectation_x.powi(2) * expectation_y.powi(2);
|
||||||
|
|
||||||
let product_variance = (sum_x * sum_y) - expectations;
|
let product_variance = (sum_x * sum_y) - expectations;
|
||||||
|
println!("{} {} {} {}", sum_x, sum_y, expectations, product_variance);
|
||||||
if product_variance > 0.0000001 {
|
if product_variance > 0.0000001 {
|
||||||
Some((product_variance.sqrt() * 100.0).round() / 100.0)
|
Some((product_variance.sqrt() * 100.0).round() / 100.0)
|
||||||
} else {
|
} else {
|
||||||
println!(
|
|
||||||
"{} {} {} {}",
|
|
||||||
expectation_x, standard_deviation_x, expectation_y, standard_deviation_y,
|
|
||||||
);
|
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn canonical_dose(dose: &IngestionDose, custom_unit: Option<&CustomUnit>) -> IngestionDose {
|
pub fn calulate_custom_unit_ingestion_dose(
|
||||||
if let IngestionDose::Custom(dose) = dose {
|
dose: &CustomUnitIngestionDose,
|
||||||
let custom_unit = custom_unit.expect("custom unit not provided when dose is type custom");
|
custom_unit_dose: &CustomUnitDose,
|
||||||
let custom_unit_dose = &custom_unit.dose;
|
) -> IngestionDose {
|
||||||
|
|
||||||
let estimation = match (&dose.estimation, &custom_unit_dose.estimation) {
|
let estimation = match (&dose.estimation, &custom_unit_dose.estimation) {
|
||||||
(
|
(
|
||||||
&Estimation::StandardDeviation(dose_standard_deviation),
|
&Estimation::StandardDeviation(dose_standard_deviation),
|
||||||
|
@ -59,14 +55,8 @@ pub fn canonical_dose(dose: &IngestionDose, custom_unit: Option<&CustomUnit>) ->
|
||||||
|
|
||||||
IngestionDose::Standard(StandardIngestionDose {
|
IngestionDose::Standard(StandardIngestionDose {
|
||||||
dose: dose.dose * custom_unit_dose.dose,
|
dose: dose.dose * custom_unit_dose.dose,
|
||||||
unit: custom_unit.original_unit.clone(),
|
unit: custom_unit_dose.original_unit.clone(),
|
||||||
|
contains_unknown: false,
|
||||||
estimation,
|
estimation,
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
dose.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn canonical_unit(dose: &IngestionDose, custom_unit: Option<&CustomUnit>) -> String {
|
|
||||||
canonical_dose(dose, custom_unit).unit()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
pub mod types;
|
|
||||||
pub mod helpers;
|
pub mod helpers;
|
||||||
|
pub mod types;
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
use chrono::{DateTime, TimeZone, Utc};
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::{Debug, Display};
|
use std::fmt::{Debug, Display};
|
||||||
|
use std::ops::Add;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub type AdministrationRoute = psychonaut_journal_types::AdministrationRoute;
|
pub type AdministrationRoute = psychonaut_journal_types::AdministrationRoute;
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Copy, Clone)]
|
||||||
pub enum Estimation {
|
pub enum Estimation {
|
||||||
Precise,
|
Precise,
|
||||||
Estimate,
|
Estimate,
|
||||||
|
@ -24,6 +25,23 @@ impl Estimation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Add for Estimation {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
match (self, rhs) {
|
||||||
|
(Estimation::StandardDeviation(x), Estimation::StandardDeviation(y)) => {
|
||||||
|
Estimation::StandardDeviation(x + y)
|
||||||
|
}
|
||||||
|
(Estimation::StandardDeviation(x), _) | (_, Estimation::StandardDeviation(x)) => {
|
||||||
|
Estimation::StandardDeviation(x)
|
||||||
|
}
|
||||||
|
(Estimation::Estimate, _) | (_, Estimation::Estimate) => Estimation::Estimate,
|
||||||
|
(Estimation::Precise, Estimation::Precise) => Estimation::Precise,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct UnknownIngestionDose {
|
pub struct UnknownIngestionDose {
|
||||||
pub unit: String,
|
pub unit: String,
|
||||||
|
@ -33,52 +51,60 @@ pub struct UnknownIngestionDose {
|
||||||
pub struct StandardIngestionDose {
|
pub struct StandardIngestionDose {
|
||||||
pub dose: f64,
|
pub dose: f64,
|
||||||
pub unit: String,
|
pub unit: String,
|
||||||
|
pub contains_unknown: bool,
|
||||||
pub estimation: Estimation,
|
pub estimation: Estimation,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl StandardIngestionDose {
|
impl Add<UnknownIngestionDose> for StandardIngestionDose {
|
||||||
pub fn is_estimate(&self) -> bool {
|
type Output = Self;
|
||||||
self.estimation.is_estimate()
|
|
||||||
|
fn add(self, _: UnknownIngestionDose) -> Self::Output {
|
||||||
|
StandardIngestionDose {
|
||||||
|
dose: self.dose,
|
||||||
|
unit: self.unit,
|
||||||
|
contains_unknown: true,
|
||||||
|
estimation: self.estimation,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for StandardIngestionDose {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
|
StandardIngestionDose {
|
||||||
|
dose: self.dose + rhs.dose,
|
||||||
|
unit: self.unit,
|
||||||
|
contains_unknown: self.contains_unknown || rhs.contains_unknown,
|
||||||
|
estimation: self.estimation + rhs.estimation,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<CustomUnitDose> for StandardIngestionDose {
|
||||||
|
fn from(value: CustomUnitDose) -> StandardIngestionDose {
|
||||||
|
StandardIngestionDose {
|
||||||
|
dose: value.dose,
|
||||||
|
unit: value.original_unit,
|
||||||
|
contains_unknown: false,
|
||||||
|
estimation: value.estimation,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CustomIngestionDose {
|
pub struct CustomUnitIngestionDose {
|
||||||
pub dose: f64,
|
pub dose: f64,
|
||||||
pub unit: String,
|
pub unit: String,
|
||||||
pub original_unit: String,
|
|
||||||
pub estimation: Estimation,
|
pub estimation: Estimation,
|
||||||
pub custom_unit_id: i64,
|
pub custom_unit_id: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CustomIngestionDose {
|
|
||||||
pub fn is_estimate(&self) -> bool {
|
|
||||||
self.estimation.is_estimate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum IngestionDose {
|
pub enum IngestionDose {
|
||||||
Unknown(UnknownIngestionDose),
|
Unknown(UnknownIngestionDose),
|
||||||
Standard(StandardIngestionDose),
|
Standard(StandardIngestionDose),
|
||||||
Custom(CustomIngestionDose),
|
CustomUnit(CustomUnitIngestionDose),
|
||||||
}
|
|
||||||
|
|
||||||
impl IngestionDose {
|
|
||||||
pub fn is_estimate(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
IngestionDose::Unknown(_) => false,
|
|
||||||
IngestionDose::Standard(dose) => dose.is_estimate(),
|
|
||||||
IngestionDose::Custom(dose) => dose.is_estimate(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn unit(&self) -> String {
|
|
||||||
match self {
|
|
||||||
IngestionDose::Unknown(dose) => dose.unit.clone(),
|
|
||||||
IngestionDose::Standard(dose) => dose.unit.clone(),
|
|
||||||
IngestionDose::Custom(dose) => dose.unit.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Debug, Clone)]
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
@ -136,6 +162,14 @@ pub struct Experience {
|
||||||
pub ingestions: Vec<Ingestion>,
|
pub ingestions: Vec<Ingestion>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct CustomUnitDose {
|
||||||
|
pub dose: f64,
|
||||||
|
pub unit: String,
|
||||||
|
pub original_unit: String,
|
||||||
|
pub estimation: Estimation,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct CustomUnit {
|
pub struct CustomUnit {
|
||||||
pub id: i64,
|
pub id: i64,
|
||||||
|
@ -143,8 +177,7 @@ pub struct CustomUnit {
|
||||||
pub substance_name: String,
|
pub substance_name: String,
|
||||||
|
|
||||||
pub administration_route: AdministrationRoute,
|
pub administration_route: AdministrationRoute,
|
||||||
pub dose: StandardIngestionDose,
|
pub dose: CustomUnitDose,
|
||||||
pub original_unit: String,
|
|
||||||
|
|
||||||
pub creation_time: DateTime<Utc>,
|
pub creation_time: DateTime<Utc>,
|
||||||
pub is_archived: bool,
|
pub is_archived: bool,
|
||||||
|
@ -163,9 +196,9 @@ impl Journal {
|
||||||
self.custom_units.get(&id).cloned()
|
self.custom_units.get(&id).cloned()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maybe_get_custom_unit_for(&self, ingestion: &Ingestion) -> Option<CustomUnit> {
|
pub fn maybe_custom_unit(&self, ingestion: &Ingestion) -> Option<CustomUnit> {
|
||||||
match &ingestion.dose {
|
match &ingestion.dose {
|
||||||
IngestionDose::Custom(dose) => self.get_custom_unit(dose.custom_unit_id),
|
IngestionDose::CustomUnit(dose) => self.get_custom_unit(dose.custom_unit_id),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -196,9 +229,10 @@ impl Journal {
|
||||||
substance_name: custom_unit.substance_name,
|
substance_name: custom_unit.substance_name,
|
||||||
|
|
||||||
administration_route: custom_unit.administration_route,
|
administration_route: custom_unit.administration_route,
|
||||||
dose: StandardIngestionDose {
|
dose: CustomUnitDose {
|
||||||
dose: custom_unit.dose,
|
dose: custom_unit.dose,
|
||||||
unit: custom_unit.unit,
|
unit: custom_unit.unit,
|
||||||
|
original_unit: custom_unit.original_unit,
|
||||||
estimation: if custom_unit.is_estimate {
|
estimation: if custom_unit.is_estimate {
|
||||||
if let Some(standard_deviation) =
|
if let Some(standard_deviation) =
|
||||||
custom_unit.estimate_standard_deviation
|
custom_unit.estimate_standard_deviation
|
||||||
|
@ -212,8 +246,6 @@ impl Journal {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
original_unit: custom_unit.original_unit,
|
|
||||||
|
|
||||||
creation_time: from_unix_millis(custom_unit.creation_time),
|
creation_time: from_unix_millis(custom_unit.creation_time),
|
||||||
is_archived: custom_unit.is_archived,
|
is_archived: custom_unit.is_archived,
|
||||||
},
|
},
|
||||||
|
@ -245,15 +277,14 @@ impl Journal {
|
||||||
dose: {
|
dose: {
|
||||||
if let Some(dose) = ingestion.dose {
|
if let Some(dose) = ingestion.dose {
|
||||||
if let Some(custom_unit_id) = ingestion.custom_unit_id {
|
if let Some(custom_unit_id) = ingestion.custom_unit_id {
|
||||||
IngestionDose::Custom(CustomIngestionDose {
|
let custom_unit = journal
|
||||||
dose,
|
|
||||||
unit: ingestion.unit.clone(),
|
|
||||||
original_unit: journal
|
|
||||||
.custom_units
|
.custom_units
|
||||||
.get(&custom_unit_id)
|
.get(&custom_unit_id)
|
||||||
.expect("custom unit not found")
|
.expect("custom unit not found");
|
||||||
.original_unit
|
|
||||||
.clone(),
|
IngestionDose::CustomUnit(CustomUnitIngestionDose {
|
||||||
|
dose,
|
||||||
|
unit: custom_unit.dose.unit.clone(),
|
||||||
estimation,
|
estimation,
|
||||||
custom_unit_id,
|
custom_unit_id,
|
||||||
})
|
})
|
||||||
|
@ -262,6 +293,7 @@ impl Journal {
|
||||||
dose,
|
dose,
|
||||||
unit: ingestion.unit,
|
unit: ingestion.unit,
|
||||||
estimation,
|
estimation,
|
||||||
|
contains_unknown: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -46,6 +46,8 @@ pub fn print_experience(
|
||||||
.first_experience_by_title(&args.experience_title)
|
.first_experience_by_title(&args.experience_title)
|
||||||
.expect("could not find experience");
|
.expect("could not find experience");
|
||||||
|
|
||||||
|
//println!("{:#?}", &experience);
|
||||||
|
|
||||||
println!("{}", format_experience_title(&experience));
|
println!("{}", format_experience_title(&experience));
|
||||||
|
|
||||||
let substance_filter = args.substance_filter.clone();
|
let substance_filter = args.substance_filter.clone();
|
||||||
|
|
|
@ -21,12 +21,14 @@ pub fn print_ingestion_log(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let custom_unit = journal.maybe_get_custom_unit_for(ingestion);
|
let custom_unit = journal.maybe_custom_unit(ingestion);
|
||||||
|
|
||||||
|
//println!("{:#?} {:#?}", &ingestion, &custom_unit);
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"{}|{}|{}|{}|{}",
|
"{}|{}|{}|{}|{}",
|
||||||
ingestion.substance_name,
|
ingestion.substance_name,
|
||||||
format_ingestion_dose(&ingestion.dose, custom_unit.as_ref()),
|
format_ingestion_dose(&ingestion.dose, custom_unit.as_ref().map(|f| &f.dose)),
|
||||||
format_ingestion_roa(ingestion, custom_unit.as_ref()),
|
format_ingestion_roa(ingestion, custom_unit.as_ref()),
|
||||||
ingestion.consumer,
|
ingestion.consumer,
|
||||||
format_ingestion_time(ingestion)
|
format_ingestion_time(ingestion)
|
||||||
|
|
|
@ -1,63 +1,60 @@
|
||||||
use journal::{
|
use journal::{
|
||||||
helpers::canonical_dose,
|
helpers::calulate_custom_unit_ingestion_dose,
|
||||||
types::{CustomUnit, Experience, Ingestion, IngestionDose, StandardIngestionDose},
|
types::{
|
||||||
|
CustomUnit, CustomUnitDose, Estimation, Experience, Ingestion, IngestionDose,
|
||||||
|
StandardIngestionDose,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn format_experience_title(experience: &Experience) -> String {
|
pub fn format_experience_title(experience: &Experience) -> String {
|
||||||
format!("{}: {}", experience.title, experience.creation_time)
|
format!("{}: {}", experience.title, experience.creation_time)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn format_ingestion_dose(dose: &IngestionDose, custom_unit: Option<&CustomUnit>) -> String {
|
pub fn format_ingestion_dose(
|
||||||
|
dose: &IngestionDose,
|
||||||
|
custom_unit_dose: Option<&CustomUnitDose>,
|
||||||
|
) -> String {
|
||||||
match dose {
|
match dose {
|
||||||
IngestionDose::Unknown(dose) => format!("Unknown {}", dose.unit),
|
IngestionDose::Unknown(dose) => format!("Unknown {}", dose.unit),
|
||||||
IngestionDose::Standard(dose) => {
|
IngestionDose::Standard(dose) => {
|
||||||
let is_estimate = match dose.estimation {
|
let is_estimate = dose.estimation.is_estimate();
|
||||||
journal::types::Estimation::Precise => false,
|
|
||||||
journal::types::Estimation::Estimate
|
|
||||||
| journal::types::Estimation::StandardDeviation(_) => true,
|
|
||||||
};
|
|
||||||
|
|
||||||
let estimate = if is_estimate { "~" } else { "" };
|
let estimate = if is_estimate { "~" } else { "" };
|
||||||
let standard_deviation =
|
let standard_deviation = {
|
||||||
if let journal::types::Estimation::StandardDeviation(standard_deviation) =
|
if let Estimation::StandardDeviation(standard_deviation) = dose.estimation {
|
||||||
dose.estimation
|
|
||||||
{
|
|
||||||
format!("±{}", (standard_deviation * 100.0).round() / 100.0)
|
format!("±{}", (standard_deviation * 100.0).round() / 100.0)
|
||||||
} else {
|
} else {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let dose_value = (dose.dose * 100.0).round() / 100.0;
|
let dose_value = (dose.dose * 100.0).round() / 100.0;
|
||||||
let unit = dose.unit.clone();
|
let unit = dose.unit.clone();
|
||||||
|
|
||||||
format!("{estimate}{dose_value}{standard_deviation} {unit}")
|
format!("{estimate}{dose_value}{standard_deviation} {unit}")
|
||||||
}
|
}
|
||||||
IngestionDose::Custom(dose) => {
|
IngestionDose::CustomUnit(dose) => {
|
||||||
let custom_unit: &CustomUnit = custom_unit.expect("custom unit required for dose type");
|
let custom_unit_dose = custom_unit_dose.expect("custom unit dose required");
|
||||||
|
|
||||||
let canonical_dose =
|
let ingestion_dose = calulate_custom_unit_ingestion_dose(dose, custom_unit_dose);
|
||||||
canonical_dose(&IngestionDose::Custom(dose.clone()), Some(custom_unit));
|
|
||||||
|
|
||||||
let canonical_dose = format_ingestion_dose(&canonical_dose, None);
|
let ingestion_dose = format_ingestion_dose(&ingestion_dose, None);
|
||||||
|
|
||||||
let custom_unit_dose_per = format_ingestion_dose(
|
let dose_per_unit = format_ingestion_dose(
|
||||||
&IngestionDose::Standard(StandardIngestionDose {
|
&IngestionDose::Standard(StandardIngestionDose::from(custom_unit_dose.clone())),
|
||||||
dose: custom_unit.dose.dose,
|
|
||||||
unit: custom_unit.original_unit.clone(),
|
|
||||||
estimation: custom_unit.dose.estimation.clone(),
|
|
||||||
}),
|
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
let custom_unit_dose = format_ingestion_dose(
|
let custom_unit_dose = format_ingestion_dose(
|
||||||
&IngestionDose::Standard(StandardIngestionDose {
|
&IngestionDose::Standard(StandardIngestionDose {
|
||||||
dose: dose.dose,
|
dose: dose.dose,
|
||||||
unit: custom_unit.dose.unit.clone(),
|
unit: custom_unit_dose.unit.clone(),
|
||||||
estimation: custom_unit.dose.estimation.clone(),
|
contains_unknown: false,
|
||||||
|
estimation: dose.estimation,
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
format!("{canonical_dose} ({custom_unit_dose_per} * {custom_unit_dose})")
|
format!("{ingestion_dose} ({dose_per_unit} * {custom_unit_dose})")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,4 +11,3 @@ pub fn load_journal(filename: &String) -> Result<Journal, Box<dyn std::error::Er
|
||||||
|
|
||||||
Ok(journal)
|
Ok(journal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue