stripper_xml/
normalization.rs1use serde::{Deserialize, Serialize, Serializer};
2
3use crate::ParseErr;
4
5#[derive(Deserialize, Serialize)]
6#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
7pub struct Normalization {
8 #[serde(rename = "@name")]
9 pub name: String,
10 #[serde(rename = "XSection")]
12 pub xsection: XSection,
13 #[serde(rename = "Contribution")]
14 pub contribution: Contribution,
15 #[serde(rename = "NumberOfRejectedEvents")]
16 pub number_of_rejected_events: String,
17}
18
19#[derive(Deserialize, Serialize)]
53#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
54#[serde(rename_all = "PascalCase")]
55pub struct XSection {
56 #[serde(rename = "XSPos", alias = "XSNeg")]
58 pub xs_pos: XSScale,
59 #[serde(alias = "MaxWeightNeg")]
60 pub max_weight_pos: f64,
61 #[serde(alias = "TotalEventsNeg")]
62 pub total_events_pos: u64,
63 #[serde(alias = "AcceptedEventsNeg")]
64 pub accepted_events_pos: u64,
65 #[serde(alias = "FactorNeg")]
66 pub factor_pos: String,
67}
68
69#[derive(Deserialize, Serialize)]
70#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
71pub struct Contribution {
72 #[serde(rename = "@name")]
73 pub name: String,
74 pub xsection: XSScale,
75 pub rw: Reweight,
76}
77
78#[derive(Deserialize, Serialize)]
79#[derive(Clone, Debug, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
80pub struct Reweight {
81 pub rwentry: Vec<String>,
82}
83
84#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
85pub struct XSScale (pub [f64; 2]);
86
87impl<'de> Deserialize<'de> for XSScale {
88 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
89 where
90 D: serde::Deserializer<'de> {
91 let xs_scale_str = String::deserialize(deserializer)?;
92 let mut entries = xs_scale_str.split(',');
93 let mut xs_scale = [0.; 2];
94 for q in &mut xs_scale {
95 let Some(p) = entries.next() else {
96 return Err(serde::de::Error::custom(
97 ParseErr::NumEntries(xs_scale_str, 2)
98 ));
99 };
100 *q = p.parse().map_err(serde::de::Error::custom)?;
101 }
102 if entries.next().is_some() {
103 return Err(serde::de::Error::custom(
104 ParseErr::NumEntries(xs_scale_str, 2)
105 ));
106 }
107 Ok(Self(xs_scale))
108 }
109}
110
111impl Serialize for XSScale {
112 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
113 where
114 S: Serializer,
115 {
116 let p = self.0;
117 serializer.serialize_str(
118 &format!("{},{}", p[0], p[1])
119 )
120 }
121}
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn deser_xsection_neg() {
129 pub const REF_XS: &str = r#"<XSection>
130 <XSNeg> 687.103,0.978277 </XSNeg>
131 <MaxWeightNeg> 796475 </MaxWeightNeg>
132 <TotalEventsNeg> 488338734 </TotalEventsNeg>
133 <AcceptedEventsNeg> 493310 </AcceptedEventsNeg>
134 <FactorNeg> 803.98,1.14468 </FactorNeg>
135</XSection>"#;
136 let _xs: XSection = quick_xml::de::from_str(REF_XS).unwrap();
137 }
138
139 #[test]
140 fn deser_xsection_pos() {
141 pub const REF_XS: &str = r#"<XSection>
142 <XSPos> 687.103,0.978277 </XSPos>
143 <MaxWeightPos> 796475 </MaxWeightPos>
144 <TotalEventsPos> 488338734 </TotalEventsPos>
145 <AcceptedEventsPos> 493310 </AcceptedEventsPos>
146 <FactorPos> 803.98,1.14468 </FactorPos>
147</XSection>"#;
148 let _xs: XSection = quick_xml::de::from_str(REF_XS).unwrap();
149 }
150
151 #[test]
152 fn deser_normalization() {
153 pub const REF_NORM: &str = r#"<?xml version="1.0" encoding="UTF-8"?>
154<Normalization name="Cm">
155<!--
156File generated with STRIPPER v0.1 for online data base
157-->
158<XSection>
159 <XSNeg> 687.103,0.978277 </XSNeg>
160 <MaxWeightNeg> 796475 </MaxWeightNeg>
161 <TotalEventsNeg> 488338734 </TotalEventsNeg>
162 <AcceptedEventsNeg> 493310 </AcceptedEventsNeg>
163 <FactorNeg> 803.98,1.14468 </FactorNeg>
164</XSection>
165<Contribution name="Cm">
166 <xsection> 687.103,0.978277</xsection>
167 <rw>
168 <rwentry> x1 </rwentry>
169 <rwentry> x2 </rwentry>
170 <rwentry> log(muR**2) </rwentry>
171 <rwentry> log(muF**2) </rwentry>
172 </rw>
173</Contribution>
174<NumberOfRejectedEvents> 0 , 100</NumberOfRejectedEvents>
175</Normalization>
176"#;
177 let norm: Normalization = quick_xml::de::from_str(REF_NORM).unwrap();
178 assert_eq!(norm.name, "Cm");
179 assert_eq!(norm.contribution.name, "Cm");
180 assert_eq!(norm.contribution.xsection.0, [687.103,0.978277]);
181 assert_eq!(
182 norm.contribution.rw.rwentry,
183 ["x1", "x2", "log(muR**2)", "log(muF**2)"]
184 );
185 let XSection {
186 xs_pos,
187 max_weight_pos,
188 total_events_pos,
189 accepted_events_pos,
190 factor_pos
191 } = norm.xsection;
192 assert_eq!(xs_pos, XSScale([687.103, 0.978277]));
193 assert_eq!(max_weight_pos, 796475.);
194 assert_eq!(accepted_events_pos, 493310);
195 assert_eq!(total_events_pos, 488338734);
196 assert_eq!(factor_pos, "803.98,1.14468");
197 }
198}