From ab5bb8960802c945e2888d50b431a2c060d79141 Mon Sep 17 00:00:00 2001
From: Udo Eisenbarth <u.eisenbarth@gsi.de>
Date: Mon, 5 Jun 2023 13:54:51 +0200
Subject: [PATCH] Add PA doublepass grpah example.

Add "inverted" flag to OpticNode.
---
 examples/pa_doublepass_graph.rs | 38 +++++++++++++++++++++++++++++++++
 src/optic_node.rs               | 23 +++++++++++++++++---
 2 files changed, 58 insertions(+), 3 deletions(-)
 create mode 100644 examples/pa_doublepass_graph.rs

diff --git a/examples/pa_doublepass_graph.rs b/examples/pa_doublepass_graph.rs
new file mode 100644
index 00000000..7da3894f
--- /dev/null
+++ b/examples/pa_doublepass_graph.rs
@@ -0,0 +1,38 @@
+use opossum::nodes::NodeDummy;
+use opossum::optic_node::OpticNode;
+use opossum::optic_scenery::OpticScenery;
+
+use std::fs::File;
+use std::io::Write;
+
+fn main() {
+    let mut scenery = OpticScenery::new();
+    scenery.set_description("PreAmp Doublepass section".into());
+    let n1 = scenery.add_node(OpticNode::new("TFP", Box::new(NodeDummy)));
+    let n2 = scenery.add_node(OpticNode::new("19mm amp", Box::new(NodeDummy)));
+    let n3 = scenery.add_node(OpticNode::new("Faraday", Box::new(NodeDummy)));
+    let n4 = scenery.add_node(OpticNode::new("0° mirror", Box::new(NodeDummy)));
+
+    let mut node= OpticNode::new("Faraday", Box::new(NodeDummy));
+    node.set_inverted(true);
+    let n3i=scenery.add_node(node);
+
+    let mut node= OpticNode::new("19mm amp", Box::new(NodeDummy));
+    node.set_inverted(true);
+    let n2i=scenery.add_node(node);
+
+    let mut node= OpticNode::new("TFP", Box::new(NodeDummy));
+    node.set_inverted(true);    
+    let n1i=scenery.add_node(node);
+
+    scenery.connect_nodes(n1, n2).unwrap();
+    scenery.connect_nodes(n2, n3).unwrap();
+    scenery.connect_nodes(n3, n4).unwrap();
+    scenery.connect_nodes(n4, n3i).unwrap();
+    scenery.connect_nodes(n3i, n2i).unwrap();
+    scenery.connect_nodes(n2i, n1i).unwrap();
+
+    let path = "graph.dot";
+    let mut output = File::create(path).unwrap();
+    write!(output, "{}", scenery.to_dot()).unwrap();
+}
diff --git a/src/optic_node.rs b/src/optic_node.rs
index 07bd1227..96213682 100644
--- a/src/optic_node.rs
+++ b/src/optic_node.rs
@@ -3,7 +3,7 @@ use std::fmt::Debug;
 pub struct OpticNode {
     name: String,
     node: Box<dyn Optical>,
-
+    inverted: bool
 }
 
 impl OpticNode {
@@ -19,7 +19,7 @@ impl OpticNode {
     /// let node=OpticNode::new("My node", Box::new(NodeDummy));
     /// ```
     pub fn new(name: &str, node: Box<dyn Optical>) -> Self {
-        Self { name: name.into(), node}
+        Self { name: name.into(), node: node, inverted: false}
     }
     /// Sets the name of this [`OpticNode`].
     pub fn set_name(&mut self, name: String) {
@@ -32,12 +32,23 @@ impl OpticNode {
     /// Returns a string representation of the [`OpticNode`] in `graphviz` format. This function is normally called by the top-level `to_dot`function within 
     /// `OpticScenery`.
     pub fn to_dot(&self) -> String {
-        format!("[label=\"{}\"]\n", self.name)
+        let is_inverted= if self.inverted==true {" (inv)"} else {""};
+        format!("[label=\"{}{}\"]\n", self.name, is_inverted)
     }
     /// Returns the concrete node type as string representation.
     pub fn node_type(&self) -> &str {
         self.node.node_type()
     }
+    /// Mark the [`OpticNode`] as inverted.
+    /// 
+    /// This means that the node is used in "reverse" direction. All output port become input parts and vice versa.
+    pub fn set_inverted(&mut self, inverted: bool) {
+        self.inverted = inverted;
+    }
+    /// Returns if the [`OpticNode`] is used in reversed direction.
+    pub fn inverted(&self) -> bool {
+        self.inverted
+    }
 }
 
 impl Debug for OpticNode {
@@ -80,6 +91,12 @@ mod test {
         assert_eq!(node.to_dot(), "[label=\"Test\"]\n".to_owned())
     }
     #[test]
+    fn to_dot_inverted() {
+        let mut node = OpticNode::new("Test", Box::new(NodeDummy));
+        node.set_inverted(true);
+        assert_eq!(node.to_dot(), "[label=\"Test (inv)\"]\n".to_owned())
+    }
+    #[test]
     fn node_type() {
         let node = OpticNode::new("Test", Box::new(NodeDummy));
         assert_eq!(node.node_type(), "dummy");
-- 
GitLab