Skip to main content

gammalooprs/graph/
global.rs

1use eyre::Context;
2use linnet::parser::GlobalData;
3use symbolica::atom::Atom;
4
5use crate::{feyngen::diagram_generator::evaluate_overall_factor, graph::GroupId};
6
7use super::{
8    Graph,
9    parse::{ParseGraph, StripParse, ToQuoted},
10};
11
12#[derive(Clone, Debug)]
13pub struct ParseData {
14    pub name: String,
15    pub overall_factor: Atom,
16    pub projectors: Option<Atom>,
17    pub num: Atom,
18    pub parameters: Vec<Atom>,
19    pub group_id: Option<GroupId>,
20    pub is_group_master: bool,
21}
22
23impl Default for ParseData {
24    fn default() -> Self {
25        ParseData {
26            name: String::new(),
27            overall_factor: Atom::one(),
28            projectors: None,
29            parameters: Vec::new(),
30            num: Atom::one(),
31            group_id: None,
32            is_group_master: false,
33        }
34    }
35}
36
37impl ParseData {
38    pub(crate) fn with_overall_factor(self, overall_factor: Atom) -> Self {
39        ParseData {
40            name: self.name,
41            overall_factor,
42            projectors: self.projectors,
43            num: self.num,
44            parameters: self.parameters,
45            group_id: self.group_id,
46            is_group_master: self.is_group_master,
47        }
48    }
49
50    pub(crate) fn with_projectors(self, polarizations: Atom) -> Self {
51        ParseData {
52            name: self.name,
53            overall_factor: self.overall_factor,
54            projectors: Some(polarizations),
55            num: self.num,
56            parameters: self.parameters,
57            group_id: self.group_id,
58            is_group_master: self.is_group_master,
59        }
60    }
61
62    pub(crate) fn with_num(self, num: Atom) -> Self {
63        ParseData {
64            name: self.name,
65            overall_factor: self.overall_factor,
66            projectors: self.projectors,
67            num,
68            parameters: self.parameters,
69            group_id: self.group_id,
70            is_group_master: self.is_group_master,
71        }
72    }
73}
74
75impl From<linnet::parser::GlobalData> for ParseData {
76    fn from(value: linnet::parser::GlobalData) -> Self {
77        let mut parse_data = ParseData {
78            name: value.name,
79            ..Default::default()
80        };
81
82        if let Some(factor) = value.statements.get("overall_factor") {
83            parse_data = parse_data
84                .with_overall_factor(factor.strip_parse().context("overall_factor").unwrap());
85        }
86
87        if let Some(polarizations) = value.statements.get("projector") {
88            parse_data = parse_data
89                .with_projectors(polarizations.strip_parse().context("projector").unwrap());
90        }
91
92        if let Some(factor) = value.statements.get("num") {
93            parse_data = parse_data.with_num(factor.strip_parse().context("num").unwrap());
94        }
95
96        if let Some(is_group_master) = value.statements.get("is_group_master") {
97            parse_data.is_group_master = is_group_master
98                .strip_parse()
99                .context("is_group_master")
100                .unwrap();
101        }
102
103        if let Some(group_id) = value.statements.get("group_id") {
104            parse_data.group_id =
105                Some(GroupId(group_id.strip_parse().context("group_id").unwrap()));
106        }
107
108        if let Some(params) = value.statements.get("params") {
109            let params: String = params.strip_parse().context("params").unwrap();
110            parse_data.parameters = params
111                .split(';')
112                .map(str::trim)
113                .filter(|param| !param.is_empty())
114                .map(|param| {
115                    param
116                        .strip_parse()
117                        .with_context(|| format!("params entry {param}"))
118                        .unwrap()
119                })
120                .collect();
121        }
122
123        parse_data
124    }
125}
126
127impl Graph {
128    pub(crate) fn global_data(&self) -> GlobalData {
129        let mut g = GlobalData::from(());
130
131        // println!("Name: {}", self.name);
132        g.add_name(self.name.clone());
133
134        g.statements
135            .insert("num".to_string(), self.global_prefactor.num.to_quoted());
136
137        g.statements.insert(
138            "projector".to_string(),
139            self.global_prefactor.projector.to_quoted(),
140        );
141        // g.statements.insert(
142        //     "overall_factor".to_string(),
143        //     self.global_prefactor.color.to_canonical_string(),
144        // );
145        g.statements.insert(
146            "overall_factor".to_string(),
147            self.overall_factor.to_quoted(),
148        );
149
150        g.statements.insert(
151            "overall_factor_evaluated".to_string(),
152            evaluate_overall_factor(self.overall_factor.as_view()).to_quoted(),
153        );
154
155        if !self.param_builder.pairs.additional_params.params.is_empty() {
156            let params = self
157                .param_builder
158                .pairs
159                .additional_params
160                .params
161                .iter()
162                .map(ToQuoted::to_quoted)
163                .collect::<Vec<_>>()
164                .join(";");
165            g.statements.insert("params".to_string(), params);
166        }
167
168        g
169    }
170}
171
172impl ParseGraph {
173    pub(crate) fn global_data(&self) -> GlobalData {
174        let mut g = GlobalData::from(());
175
176        // println!("Name: {}", self.name);
177        g.add_name(self.global_data.name.clone());
178
179        g.statements
180            .insert("num".to_string(), self.global_data.num.to_quoted());
181        if let Some(proj) = &self.global_data.projectors {
182            g.statements
183                .insert("projector".to_string(), proj.to_quoted());
184        }
185
186        // g.statements.insert(
187        //     "overall_factor".to_string(),
188        //     self.global_prefactor.color.to_canonical_string(),
189        // );
190        g.statements.insert(
191            "overall_factor".to_string(),
192            self.global_data.overall_factor.to_quoted(),
193        );
194
195        if !self.global_data.parameters.is_empty() {
196            let params = self
197                .global_data
198                .parameters
199                .iter()
200                .map(ToQuoted::to_quoted)
201                .collect::<Vec<_>>()
202                .join(";");
203            g.statements.insert("params".to_string(), params);
204        }
205
206        g
207    }
208}
209
210#[cfg(test)]
211mod tests {
212    use linnet::{
213        half_edge::nodestore::NodeStorageVec,
214        parser::{DotGraph, DotVertexData},
215    };
216
217    use crate::{
218        dot,
219        graph::{Graph, parse::IntoGraph},
220        initialisation::test_initialise,
221        processes::DotExportSettings,
222    };
223
224    #[test]
225    fn params_roundtrip_in_global_data() {
226        test_initialise().unwrap();
227        match dot!(digraph params_roundtrip {
228            graph [
229                overall_factor = 1;
230                multiplicity_factor = 1;
231                params = "a;b;c";
232            ]
233            edge [pdg=1000]
234            ext [style=invis]
235            ext -> v4
236            ext -> v5
237            v6 -> ext
238            v5 -> v4 [lmb_index=0];
239            v6 -> v5;
240            v4 -> v6;
241        },"scalars")
242        {
243            Ok(g) => {
244                let g: Graph = g;
245                // g.to_dot_graph_with_settings().dot()
246                let serialized = g.dot_serialize(&DotExportSettings::default());
247                let parsed: DotGraph<NodeStorageVec<DotVertexData>> =
248                    DotGraph::from_string(serialized).unwrap();
249
250                assert_eq!(
251                    parsed.global_data.statements.get("params"),
252                    Some(&"a;b;c".to_string())
253                );
254            }
255            Err(e) => {
256                eprintln!("Graph parsing failed: {:?}", e);
257            }
258        }
259    }
260}