1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
use std::fmt::Display;
use rusqlite::Row;
use crate::{LimitType, PdgFootnote, PdgId};
/// Bibliographic reference for a PDG measurement.
#[derive(Clone, Debug)]
pub struct PdgReference {
/// PDG document identifier.
pub document_id: String,
/// Publication venue or collaboration name, when available.
pub publication_name: Option<String>,
/// Publication year, when available.
pub publication_year: Option<isize>,
/// Digital object identifier, when available.
pub doi: Option<String>,
/// INSPIRE record identifier, when available.
pub inspire_id: Option<String>,
/// Publication title, when available.
pub title: Option<String>,
}
/// Experimental or observational measurement supporting a PDG data entry.
#[derive(Clone, Debug)]
pub struct PdgMeasurement {
/// PDG identifier measured by this row.
pub pdgid: PdgId,
/// Bibliographic reference for the measurement.
pub reference: PdgReference,
/// Event count reported by the measurement.
pub event_count: Option<String>,
/// Confidence level associated with the measurement.
pub confidence_level: Option<f64>,
/// Location or experiment place label.
pub place: Option<String>,
/// Measurement technique label.
pub technique: Option<String>,
/// Charge selector or charge state label.
pub charge: Option<String>,
/// Whether the measurement is marked by a PDG change bar.
pub changebar: bool,
/// PDG comment attached to the measurement.
pub comment: Option<String>,
/// Sort key used by the PDG tables.
pub sort: isize,
/// Values reported by this measurement.
pub values: Vec<PdgMeasurementValue>,
/// Footnotes attached to this measurement.
pub footnotes: Vec<PdgFootnote>,
pub(crate) id: isize,
}
impl TryFrom<&Row<'_>> for PdgMeasurement {
type Error = rusqlite::Error;
fn try_from(row: &Row<'_>) -> Result<Self, Self::Error> {
Ok(Self {
id: row.get(0)?,
pdgid: row.get(1)?,
event_count: row.get(2)?,
confidence_level: row.get(3)?,
place: row.get(4)?,
technique: row.get(5)?,
charge: row.get(6)?,
changebar: row.get(7)?,
comment: row.get(8)?,
sort: row.get(9)?,
reference: PdgReference {
document_id: row.get(10)?,
publication_name: row.get(11)?,
publication_year: row.get(12)?,
doi: row.get(13)?,
inspire_id: row.get(14)?,
title: row.get(15)?,
},
values: Vec::new(),
footnotes: Vec::new(),
})
}
}
/// Individual value reported by a [`PdgMeasurement`].
#[derive(Clone, Debug)]
pub struct PdgMeasurementValue {
/// Column name for multi-column measurement rows.
pub column_name: Option<String>,
/// Raw value text from the measurement table.
pub value_text: Option<String>,
/// Unit text from the measurement table.
pub unit_text: Option<String>,
/// Display-ready value text.
pub display_value_text: Option<String>,
/// Power-of-ten exponent used when displaying the value.
pub display_power_of_ten: Option<isize>,
/// Whether the display value should be interpreted as a percentage.
pub display_in_percent: Option<bool>,
/// Limit or range type for this value.
pub limit_type: Option<LimitType>,
/// Whether this value is used in the PDG average.
pub used_in_average: bool,
/// Whether this value is used in a PDG fit.
pub used_in_fit: bool,
/// Parsed numeric central value.
pub value: Option<f64>,
/// Positive total uncertainty.
pub error_positive: Option<f64>,
/// Negative total uncertainty.
pub error_negative: Option<f64>,
/// Positive statistical uncertainty.
pub stat_error_positive: Option<f64>,
/// Negative statistical uncertainty.
pub stat_error_negative: Option<f64>,
/// Positive systematic uncertainty.
pub syst_error_positive: Option<f64>,
/// Negative systematic uncertainty.
pub syst_error_negative: Option<f64>,
/// Sort key used by the PDG tables.
pub sort: isize,
}
impl TryFrom<&Row<'_>> for PdgMeasurementValue {
type Error = rusqlite::Error;
fn try_from(row: &Row<'_>) -> Result<Self, Self::Error> {
Ok(Self {
column_name: row.get(0)?,
value_text: row.get(1)?,
unit_text: row.get(2)?,
display_value_text: row.get(3)?,
display_power_of_ten: row.get(4)?,
display_in_percent: row.get(5)?,
limit_type: row.get(6)?,
used_in_average: row.get(7)?,
used_in_fit: row.get(8)?,
value: row.get(9)?,
error_positive: row.get(10)?,
error_negative: row.get(11)?,
stat_error_positive: row.get(12)?,
stat_error_negative: row.get(13)?,
syst_error_positive: row.get(14)?,
syst_error_negative: row.get(15)?,
sort: row.get(16)?,
})
}
}
impl Display for PdgMeasurementValue {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
self.display_value_text
.clone()
.unwrap_or_else(|| "NULL".to_string())
)?;
if self.display_in_percent.unwrap_or_default() {
write!(f, "%")?;
} else if self.display_power_of_ten.unwrap_or_default() != 0 {
write!(f, "E{}", self.display_power_of_ten.unwrap_or_default())?;
}
if let Some(unit_text) = &self.unit_text
&& !unit_text.is_empty()
{
write!(f, " {unit_text}")?;
}
Ok(())
}
}