diff --git a/src/_impl_bma_model.rs b/src/_impl_bma_model.rs index e707235..49aaf96 100644 --- a/src/_impl_bma_model.rs +++ b/src/_impl_bma_model.rs @@ -3,6 +3,7 @@ use crate::enums::VariableType; use crate::json_model::JsonBmaModel; use crate::traits::{JsonSerde, XmlSerde}; use crate::xml_model::XmlBmaModel; +use biodivine_lib_param_bn::{BooleanNetwork, RegulatoryGraph}; use std::collections::HashMap; impl<'de> JsonSerde<'de> for BmaModel { @@ -219,3 +220,49 @@ impl From for BmaModel { } } } + +impl BmaModel { + pub fn to_regulatory_graph(&self) -> Result { + let mut variables_map: HashMap = HashMap::new(); + for var in &self.model.variables { + let inserted = + variables_map.insert(var.id, format!("v_{}_{}", var.id, var.name.clone())); + if inserted.is_some() { + return Err(format!("Variable ID {} is not unique.", var.id)); + } + } + let variables = variables_map.clone().into_values().collect(); + let mut graph = RegulatoryGraph::new(variables); + + // add regulations + self.model + .relationships + .iter() + .try_for_each(|relationship| { + let regulator_id = relationship.from_variable; + let target_id = relationship.to_variable; + let regulator = variables_map + .get(®ulator_id) + .ok_or(format!("Regulator var {} does not exist.", regulator_id))?; + let target = variables_map + .get(&target_id) + .ok_or(format!("Target var {} does not exist.", target_id))?; + let monotonicity = Some(relationship.relationship_type.into()); + graph.add_regulation(regulator, target, true, monotonicity) + })?; + + Ok(graph) + } + + pub fn to_boolean_network(&self) -> Result { + let graph = self.to_regulatory_graph()?; + let bn = BooleanNetwork::new(graph); + + // add update functions + self.model.variables.iter().for_each(|_var| { + // todo - convert the formula to update functions + }); + + Ok(bn) + } +} diff --git a/src/bin/load_json.rs b/src/bin/load_json.rs index 896dc93..da27a86 100644 --- a/src/bin/load_json.rs +++ b/src/bin/load_json.rs @@ -16,10 +16,23 @@ fn test_parse_all_models_in_dir(models_dir: &str) { let json_data = read_to_string(&model_path) .unwrap_or_else(|_| panic!("Unable to read file: {}", model_path_str)); - let model = BmaModel::from_json_str(&json_data); - match model { - Ok(_) => { - println!("Successfully parsed model: `{model_path_str}`."); + let result_model = BmaModel::from_json_str(&json_data); + match result_model { + Ok(bma_model) => { + let result_bn = bma_model.to_boolean_network(); + match result_bn { + Ok(_) => { + println!("Successfully parsed and converted model: `{model_path_str}`."); + } + Err(e) => { + println!( + "Failed to convert model `{}` to BN: {:?}.", + model_path_str, e + ); + } + } + + println!("Successfully parsed and converted model: `{model_path_str}`."); } Err(e) => { println!("Failed to parse JSON file `{}`: {:?}.", model_path_str, e); diff --git a/src/bin/load_xml.rs b/src/bin/load_xml.rs index 9d813a7..472f863 100644 --- a/src/bin/load_xml.rs +++ b/src/bin/load_xml.rs @@ -16,13 +16,26 @@ fn test_parse_all_models_in_dir(models_dir: &str) { let xml_data = read_to_string(&model_path) .unwrap_or_else(|_| panic!("Unable to read file: {}", model_path_str)); - let model = BmaModel::from_xml_str(&xml_data); - match model { - Ok(_) => { - println!("Successfully parsed model: `{model_path_str}`."); + let result_model = BmaModel::from_xml_str(&xml_data); + match result_model { + Ok(bma_model) => { + let result_bn = bma_model.to_boolean_network(); + match result_bn { + Ok(_) => { + println!("Successfully parsed and converted model: `{model_path_str}`."); + } + Err(e) => { + println!( + "Failed to convert model `{}` to BN: {:?}.", + model_path_str, e + ); + } + } + + println!("Successfully parsed and converted model: `{model_path_str}`."); } Err(e) => { - println!("Failed to parse XML file `{}`: {:?}.", model_path_str, e); + println!("Failed to parse JSON file `{}`: {:?}.", model_path_str, e); } } } diff --git a/src/enums.rs b/src/enums.rs index c365a9e..47281e1 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -1,3 +1,4 @@ +use biodivine_lib_param_bn::Monotonicity; use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Clone, Copy)] @@ -12,3 +13,12 @@ pub enum RelationshipType { Activator, Inhibitor, } + +impl From for Monotonicity { + fn from(val: RelationshipType) -> Self { + match val { + RelationshipType::Activator => Monotonicity::Activation, + RelationshipType::Inhibitor => Monotonicity::Inhibition, + } + } +}