Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/populate criteria #42

Merged
merged 4 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
reqwest = { version = "0.12", default-features = false, features = ["stream", "default-tls"] }
tower-http = { version = "0.6", features = ["cors"] }

[dev-dependencies]
pretty_assertions = "1.4.0"

[build-dependencies]
build-data = "0.2.1"

Expand Down
71 changes: 54 additions & 17 deletions src/catalogue.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{collections::BTreeMap, sync::Arc, time::Duration};
use serde::Deserialize;
use serde::Serialize;
use std::{collections::BTreeMap, sync::Arc, time::Duration};

use reqwest::Url;
use serde_json::{json, Value};
Expand All @@ -15,10 +15,10 @@ pub type CriteriaGroups = BTreeMap<String, CriteriaGroup>;

#[derive(Serialize, Deserialize, Debug, Clone)]
struct CatalogueCriterion {
key: String,
key: String,
name: String,
description: String,
count: u64
count: u64,
}

fn get_element<'a>(
Expand All @@ -36,11 +36,9 @@ fn get_element<'a>(
fn get_stratifier<'a>(
counts: &'a CriteriaGroups,
key1: &'a str,
key2: &'a str
key2: &'a str,
) -> Option<&'a Criteria> {
counts
.get(key1)
.and_then(|group| group.get(key2))
counts.get(key1).and_then(|group| group.get(key2))
}
enola-dkfz marked this conversation as resolved.
Show resolved Hide resolved

pub fn spawn_thing(catalogue_url: Url, prism_url: Url) -> Arc<Mutex<Value>> {
Expand Down Expand Up @@ -116,12 +114,12 @@ fn recurse(json: &mut Value, counts: &mut CriteriaGroups) {
let group_key = obj.get("key").expect("Got JSON element with childCategories but without (group) key. Please check json.").as_str()
.expect("Got JSON where a criterion key was not a string. Please check json.").to_owned();

//TODO consolidate catalogue and MeasureReport group names
let group_key = if group_key == "patient" {
//TODO consolidate catalogue and MeasureReport group names, also between projects
let group_key = if group_key == "patient" || group_key == "donor" {
"patients"
} else if group_key == "tumor_classification" {
"diagnosis"
} else if group_key == "biosamples" {
} else if group_key == "biosamples" || group_key == "sample" {
"specimen"
} else {
&group_key
Expand All @@ -139,6 +137,13 @@ fn recurse(json: &mut Value, counts: &mut CriteriaGroups) {
let stratifier_key = child_cat.get("key").expect("Got JSON element with childCategory that does not contain a (stratifier) key. Please check json.").as_str()
.expect("Got JSON where a criterion key was not a string. Please check json.").to_owned();

//TODO consolidate catalogue and MeasureReport group names, also between projects
let stratifier_key = if stratifier_key == "gender" {
"Gender"
} else {
&stratifier_key
};

let criteria = child_cat
.get_mut("criteria")
.expect("Got JSON element with childCategory that does not contain a criteria array. Please check json.")
Expand Down Expand Up @@ -171,18 +176,24 @@ fn recurse(json: &mut Value, counts: &mut CriteriaGroups) {
}
}
} else {
let criteria_counts_maybe = get_stratifier(counts, &group_key, &stratifier_key);
if let Some(criteria_counts) = criteria_counts_maybe{
//TODO consolidate catalogue and MeasureReport group names, also between projects
let group_key = if stratifier_key == "diagnosis" {
"diagnosis"
} else {
&group_key
};
let criteria_counts_maybe =
get_stratifier(counts, &group_key, &stratifier_key);
if let Some(criteria_counts) = criteria_counts_maybe {
for criterion_count in criteria_counts {
let (key, count) = (criterion_count.0, criterion_count.1);
let catalogue_criterion = CatalogueCriterion {
key: key.clone(),
name: key.clone(),
description: "".into(),
count: count.clone()
key: key.clone(),
name: key.clone(),
description: "".into(),
count: count.clone(),
};
criteria.push(json!(catalogue_criterion));

}
}
}
Expand All @@ -192,3 +203,29 @@ fn recurse(json: &mut Value, counts: &mut CriteriaGroups) {
_ => {}
}
}

#[cfg(test)]
mod test {
use super::*;

const CATALOGUE_BBMRI_NO_DIAGNOSES: &str =
include_str!("resources/test/catalogue_bbmri_no_diagnoses.json");
const CATALOGUE_BBMRI: &str = include_str!("resources/test/catalogue_bbmri.json");
const CRITERIA_GROUPS_BBMRI: &str = include_str!("resources/test/criteria_groups_bbmri.json");

#[test]
fn test_recurse_bbmri() {
let mut criteria_groups: CriteriaGroups =
serde_json::from_str(&CRITERIA_GROUPS_BBMRI).expect("Not valid criteria groups");

let mut catalogue =
serde_json::from_str(&CATALOGUE_BBMRI_NO_DIAGNOSES).expect("Not valid json");

recurse(&mut catalogue, &mut criteria_groups);

pretty_assertions::assert_eq!(
CATALOGUE_BBMRI,
serde_json::to_string(&catalogue).expect("Failed to serialize JSON")
);
}
}
1 change: 1 addition & 0 deletions src/resources/test/catalogue_bbmri.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"childCategories":[{"criteria":[{"count":43,"description":"male","key":"male","name":"male"},{"count":31,"description":"female","key":"female","name":"female"},{"description":"other","key":"other","name":"other"},{"description":"unknown","key":"sex_uncharted","name":"unknown"}],"fieldType":"single-select","infoButtonText":["The gender search criterion represents the administrative gender of the patient."],"key":"gender","name":"Gender","system":"","type":"EQUALS"},{"criteria":[{"count":26,"description":"","key":"C34.0","name":"C34.0"},{"count":28,"description":"","key":"C34.2","name":"C34.2"},{"count":25,"description":"","key":"C34.8","name":"C34.8"},{"count":27,"description":"","key":"C78.0","name":"C78.0"},{"count":25,"description":"","key":"D38.6","name":"D38.6"},{"count":25,"description":"","key":"R91","name":"R91"}],"fieldType":"autocomplete","infoButtonText":["If diagnosis is selected, the search returns all specimens from all patients who have at least one Condition resource OR Specimen resource with one of the selected diagnoses."],"key":"diagnosis","name":"Diagnosis ICD-10","system":"http://fhir.de/CodeSystem/dimdi/icd-10-gm","type":"EQUALS"},{"criteria":[],"fieldType":"number","infoButtonText":["The donor age at diagnosis criterion represents the age of the patient at the time of diagnosis, calculated as the difference between the date of disease onset and the patient's date of birth. That's why the age stratifier, which shows today's age, also shows some ages that are outside the selected range."],"key":"diagnosis_age_donor","name":"Diagnosis age donor (years)","system":"","type":"BETWEEN"},{"criteria":[],"fieldType":"date","infoButtonText":["Date of diagnosis represents the date when the donor was diagnosed."],"key":"date_of_diagnosis","name":"Date of diagnosis","system":"","type":"BETWEEN"}],"key":"donor","name":"Donor/Clinical Information"},{"childCategories":[{"criteria":[],"fieldType":"number","infoButtonText":["The donor age criterion represents the patient's age today"],"key":"donor_age","name":"Donor Age","system":"","type":"BETWEEN"},{"criteria":[{"count":62,"description":"Serum","key":"blood-serum","name":"Serum"},{"description":"Tissue snap frozen","key":"tissue-frozen","name":"Tissue snap frozen"},{"description":"Whole Blood","key":"whole-blood","name":"Whole Blood"},{"count":62,"description":"Plasma","key":"blood-plasma","name":"Plasma"},{"description":"Other derivative","key":"derivative-other","name":"Other derivative"},{"description":"Other tissue storage","key":"tissue-other","name":"Other tissue storage"},{"description":"Peripheral blood cells","key":"peripheral-blood-cells-vital","name":"Peripheral blood cells"},{"description":"Urine","key":"urine","name":"Urine"},{"description":"RNA","key":"rna","name":"RNA"},{"description":"Other liquid biosample","key":"liquid-other","name":"Other liquid biosample"},{"description":"Buffy coat","key":"buffy-coat","name":"Buffy coat"},{"description":"DNA","key":"dna","name":"DNA"},{"description":"Liquor/CSF","key":"csf-liquor","name":"Liquor/CSF"},{"description":"Faeces","key":"stool-faeces","name":"Faeces"},{"description":"Bone marrow","key":"bone-marrow","name":"Bone marrow"},{"description":"Tissue (FFPE)","key":"tissue-ffpe","name":"Tissue (FFPE)"},{"description":"Saliva","key":"saliva","name":"Saliva"},{"description":"Ascites","key":"ascites","name":"Ascites"},{"description":"Swab","key":"swab","name":"Swab"},{"description":"Dried whole blood","key":"dried-whole-blood","name":"Dried whole blood"}],"fieldType":"single-select","infoButtonText":["If sample types are selected, only samples of those types will be displayed"],"key":"sample_kind","name":"Sample type","system":"","type":"EQUALS"},{"criteria":[],"fieldType":"date","infoButtonText":["If a sampling date range is selected, only those samples collected within that date range will be displayed. Samples that don't have this information will not be displayed."],"key":"sampling_date","name":"Sampling date","system":"","type":"BETWEEN"},{"criteria":[{"description":"RT","key":"temperatureRoom","name":"RT"},{"description":"2°C to 10°C","key":"temperature2to10","name":"2°C to 10°C"},{"description":"4°C","key":"four_degrees","name":"4°C"},{"description":"Minus 18°C to minus 35°C","key":"temperature-18to-35","name":"Minus 18°C to minus 35°C"},{"description":"Minus 60°C to minus 85°C","key":"temperature-60to-85","name":"Minus 60°C to minus 85°C"},{"description":"Gaseous nitrogen","key":"temperatureGN","name":"Gaseous nitrogen"},{"description":"Liquid nitrogen","key":"temperatureLN","name":"Liquid nitrogen"},{"description":"Other storage temperature","key":"temperatureOther","name":"Other storage temperature"},{"description":"Uncharted storage temperature","key":"storage_temperature_uncharted","name":"Uncharted storage temperature"}],"fieldType":"single-select","infoButtonText":["If storage temperatures are selected, only those samples stored at one of those temperatures will be displayed. Samples that don't have this information will not be displayed."],"key":"storage_temperature","name":"Storage temperature","system":"","type":"EQUALS"}],"key":"sample","name":"Sample"}]
Loading
Loading