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