Support for excluding common entities and excluding custom ones
This commit is contained in:
@ -272,11 +272,20 @@ LiteralSeparatorEdge: presets::EdgeDisplay = {
|
||||
};
|
||||
|
||||
NodeDisplay: presets::NodeDisplay = {
|
||||
"Hide" => presets::NodeDisplay::Display(graph::GraphMapNodes::Hide),
|
||||
"Entities" => presets::NodeDisplay::Display(graph::GraphMapNodes::Entities),
|
||||
"Hide" =>
|
||||
presets::NodeDisplay::Display(graph::GraphMapNodes::Hide),
|
||||
"Entities" =>
|
||||
presets::NodeDisplay::Display(graph::GraphMapNodes::Entities),
|
||||
"MaskEntities" <mask: Set> =>
|
||||
presets::NodeDisplay::Display(graph::GraphMapNodes::MaskEntities{mask}),
|
||||
"Context" => presets::NodeDisplay::Display(graph::GraphMapNodes::Context)
|
||||
"Context" =>
|
||||
presets::NodeDisplay::Display(graph::GraphMapNodes::Context),
|
||||
"UncommonEntities" =>
|
||||
presets::NodeDisplay::UncommonEntities,
|
||||
"MaskUncommonentities" <mask: Set> =>
|
||||
presets::NodeDisplay::MaskUncommonEntities(mask),
|
||||
"ExcludeEntities" <mask: Set> =>
|
||||
presets::NodeDisplay::Display(graph::GraphMapNodes::ExcludeEntities{mask})
|
||||
}
|
||||
|
||||
/// Node display formatters separated by arbitrary strings in quotes
|
||||
|
||||
@ -41,6 +41,20 @@ pub fn digraph(
|
||||
Ok(graph)
|
||||
}
|
||||
|
||||
|
||||
pub fn common_entities(
|
||||
graph: &RSgraph
|
||||
) -> RSset {
|
||||
graph.node_references().fold(
|
||||
None,
|
||||
|acc, node|
|
||||
match acc {
|
||||
None => Some(node.1.available_entities.clone()),
|
||||
Some(acc) => Some(node.1.available_entities.intersection(&acc))
|
||||
}
|
||||
).unwrap_or(RSset::new())
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// helper functions
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -54,6 +68,7 @@ pub enum GraphMapNodes {
|
||||
Hide,
|
||||
Entities,
|
||||
MaskEntities { mask: RSset },
|
||||
ExcludeEntities { mask: RSset },
|
||||
Context,
|
||||
}
|
||||
|
||||
@ -108,6 +123,20 @@ impl GraphMapNodesTy {
|
||||
}
|
||||
)
|
||||
},
|
||||
ExcludeEntities { mask } => {
|
||||
Box::new(
|
||||
move |_, node: &RSsystem| {
|
||||
let masked_entities =
|
||||
node.available_entities
|
||||
.subtraction(&mask);
|
||||
format!("{}",
|
||||
translator::RSsetDisplay::from(
|
||||
&translator,
|
||||
&masked_entities)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
Context => {
|
||||
Box::new(
|
||||
move |_, node: &RSsystem|
|
||||
|
||||
@ -62,6 +62,8 @@ impl Default for SaveOptions {
|
||||
pub enum NodeDisplay {
|
||||
Separator(String),
|
||||
Display(graph::GraphMapNodes),
|
||||
UncommonEntities,
|
||||
MaskUncommonEntities(RSset)
|
||||
}
|
||||
|
||||
|
||||
@ -539,6 +541,7 @@ pub fn bisimilar(
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn generate_node_pringting_fn<'a>(
|
||||
node_display: &'a Vec<NodeDisplay>,
|
||||
graph: &graph::RSgraph,
|
||||
translator: Rc<Translator>,
|
||||
) -> Box<dyn Fn(petgraph::prelude::NodeIndex, &'a RSsystem) -> String + 'a> {
|
||||
// The type cannot be aliased since rust doesnt like generics.
|
||||
@ -557,11 +560,43 @@ fn generate_node_pringting_fn<'a>(
|
||||
(accumulator)(i, n)
|
||||
+ &graph::GraphMapNodesTy::from(d.clone(), val.clone()).get()(i, n)
|
||||
})
|
||||
}
|
||||
},
|
||||
NodeDisplay::Separator(s) => {
|
||||
// we have a string so simply add it at the end
|
||||
Box::new(move |i, n| (accumulator)(i, n) + s)
|
||||
},
|
||||
// ad hoc since graph information is not available in the graph
|
||||
// function generation
|
||||
NodeDisplay::UncommonEntities => {
|
||||
let common_entities = graph::common_entities(graph);
|
||||
let val = translator.clone();
|
||||
Box::new(move |i, n| {
|
||||
(accumulator)(i, n)
|
||||
+ &graph::GraphMapNodesTy::from(
|
||||
graph::GraphMapNodes::ExcludeEntities {
|
||||
mask: common_entities.clone()
|
||||
},
|
||||
val.clone()
|
||||
).get()(i, n)
|
||||
}
|
||||
)
|
||||
},
|
||||
// ad hoc since graph information is not available in the graph
|
||||
// function generation
|
||||
NodeDisplay::MaskUncommonEntities(mask) => {
|
||||
let common_entities = graph::common_entities(graph);
|
||||
let val = translator.clone();
|
||||
Box::new(move |i, n| {
|
||||
(accumulator)(i, n)
|
||||
+ &graph::GraphMapNodesTy::from(
|
||||
graph::GraphMapNodes::ExcludeEntities {
|
||||
mask: common_entities.union(mask)
|
||||
},
|
||||
val.clone()
|
||||
).get()(i, n)
|
||||
}
|
||||
)
|
||||
},
|
||||
};
|
||||
}
|
||||
accumulator
|
||||
@ -666,6 +701,7 @@ pub fn dot(
|
||||
// fine...
|
||||
let modified_graph = graph.map(
|
||||
generate_node_pringting_fn(&node_display,
|
||||
graph,
|
||||
Rc::clone(&rc_translator)),
|
||||
generate_edge_pringting_fn(&edge_display,
|
||||
Rc::clone(&rc_translator)),
|
||||
@ -707,6 +743,7 @@ pub fn graphml(
|
||||
// map each value to the corresponding value we want to display
|
||||
let modified_graph = graph.map(
|
||||
generate_node_pringting_fn(&node_display,
|
||||
graph,
|
||||
Rc::clone(&rc_translator)),
|
||||
generate_edge_pringting_fn(&edge_display,
|
||||
rc_translator),
|
||||
|
||||
@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
/// Basic set of entities.
|
||||
#[derive(Clone, Debug, PartialOrd, Eq, Ord, Hash, Serialize, Deserialize)]
|
||||
#[derive(Clone, Debug, PartialOrd, Eq, Ord, Serialize, Deserialize)]
|
||||
pub struct RSset {
|
||||
pub identifiers: BTreeSet<IdType>,
|
||||
}
|
||||
@ -79,7 +79,7 @@ impl RSset {
|
||||
RSset { identifiers: res }
|
||||
}
|
||||
|
||||
/// returns the new set a \ b
|
||||
/// returns the new set a ∖ b
|
||||
pub fn subtraction(&self, b: &RSset) -> RSset {
|
||||
// TODO maybe find more efficient way without copy/clone
|
||||
let res: BTreeSet<_> = self
|
||||
@ -123,6 +123,12 @@ impl PartialEq for RSset {
|
||||
}
|
||||
}
|
||||
|
||||
impl Hash for RSset {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.identifiers.hash(state)
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for RSset {
|
||||
type Item = IdType;
|
||||
type IntoIter = std::collections::btree_set::IntoIter<Self::Item>;
|
||||
@ -564,7 +570,8 @@ impl PartialEq for RSlabel {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.available_entities == other.available_entities &&
|
||||
self.context == other.context &&
|
||||
self.t == other.t &&
|
||||
// self.t == other.t && // no need since its the union of the above
|
||||
// // elements
|
||||
self.reactants == other.reactants &&
|
||||
self.reactants_absent == other.reactants_absent &&
|
||||
self.inhibitors == other.inhibitors &&
|
||||
|
||||
Reference in New Issue
Block a user