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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
use std::collections::{HashMap, BTreeMap};

use particle_id::ParticleID;
use petgraph::prelude::DiGraph;

/// Scattering event
#[derive(Clone, Debug, Default)]
pub struct Event {
    /// Event id
    pub id: Option<i32>,
    /// Global information about the current event sample
    pub sample_info: SampleInfo,
    /// Event weights
    pub weights: Vec<WeightInfo>,
    /// Scale settings
    pub scales: Scales,
    /// Value of the QCD coupling α_s
    pub alpha_s: Option<f64>,
    /// Value of the QED coupling α
    pub alpha: Option<f64>,
    /// ID of the process this event belongs to
    pub process_id: Option<i32>,
    /// Particles involved in the scattering
    pub particles: Vec<Particle>,
    /// Optional event information
    pub info: String,
    /// Optional additional structured information
    pub attr: HashMap<String, String>,
    /// Multiparton interaction
    pub mpi: Option<i32>,
    pub random_states: Vec<i32>,
    /// Information for heavy ion collisions
    pub heavy_ion_info: Option<HeavyIonInfo>,
    /// Event topology
    ///
    /// Edge weights correspond to the index in the `particles` vector.
    pub topology: DiGraph<Vertex, usize>,
    /// STRIPPER-XML reweighting information
    pub reweights: Vec<Reweight>,
}

/// Global information about an event sample
#[derive(Clone, Debug, Default, PartialEq)]
pub struct SampleInfo {
    /// Generators used to produce the sample
    pub generators: Vec<String>,
    /// Number of events
    pub nevents: Option<usize>,
    /// Collider beam information
    pub beam: [Beam; 2],
    /// Parton Distribution Functions used
    pub pdf: [Option<i32>; 2],
    /// Cross sections for the various subprocesses
    pub cross_sections: Vec<CrossSection>,
    /// Subprocess IDs
    pub process_ids: Vec<i32>,
    /// How to interprete the event weights
    pub weight_type: Option<i32>,
    /// Optional run information
    pub info: String,
    /// Optional additional structured information
    pub attr: HashMap<String, String>,
}

/// Event weight information
#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct WeightInfo {
    /// The weight itself
    pub weight: Option<f64>,
    /// Weight name
    pub name: Option<String>,
    /// Factor multiplying the central renormalisation scale
    pub mu_r_factor: Option<f64>,
    /// Factor multiplying the central factorisation scale
    pub mu_f_factor: Option<f64>,
    /// PDF id
    pub pdf: Option<i32>,
    /// PDF id for second beam, if different from first beam
    pub pdf2: Option<i32>,

}

// Scales associated with event
#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct Scales {
    /// The renormalisation scale
    pub mu_r: Option<f64>,
    /// The factorisation scale
    pub mu_f: Option<f64>,
    /// The suggested parton shower starting scale
    pub mu_ps: Option<f64>,
}

/// A particle
#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct Particle {
    /// Particle type
    pub id:  Option<ParticleID>,
    /// Four-momentum
    pub p: Option<[f64; 4]>,
    /// Mass
    pub m: Option<f64>,
    /// Status
    pub status: Option<Status>,
    /// Spin angle
    pub spin: Option<f64>,
    /// Colour flow (LHEF)
    pub col: Option<[i32; 2]>,
    /// Colour flow (HepMC)
    pub flows: BTreeMap<i32, i32>,
    /// Lifetime
    pub lifetime: Option<f64>,
    /// θ polarisation angle
    pub theta: Option<f64>,
    /// φ polarisation angle
    pub phi: Option<f64>,
}

/// Beam information
#[derive(Copy, Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct Beam {
    /// Particle type
    pub id: Option<ParticleID>,
    /// Energy in GeV
    pub energy: Option<f64>,
}

#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct CrossSection {
    /// Mean value for the cross section
    pub mean: f64,
    /// Cross section errors
    pub err: Option<f64>,
}

#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub enum Status {
    /// Incoming particle
    Incoming,
    /// Outgoing particle
    Outgoing,
    /// Intermediate space-like propagator defining an x and Q^2 which should be preserved
    IntermediateSpacelike,
    /// Intermediate resonance, mass should be preserved
    IntermediateResonance,
    /// Intermediate resonance, for documentation only
    IntermediateDoc,
    /// Incoming beam particles at time t = −∞
    IncomingBeam,
    /// Unknown
    Unknown(i32),
}

#[derive(Clone, Debug, Default, PartialEq, PartialOrd)]
pub struct Vertex {
    pub status: Option<i32>,
    pub x: Option<f64>,
    pub y: Option<f64>,
    pub z: Option<f64>,
    pub t: Option<f64>,
    pub weights: Vec<f64>,
}

/// Information for heavy ion collisions
#[derive(Debug, PartialEq, PartialOrd, Default, Copy, Clone)]
pub struct HeavyIonInfo {
    pub ncoll_hard: Option<i32>,
    pub npart_proj: Option<i32>,
    pub npart_targ: Option<i32>,
    pub ncoll: Option<i32>,
    pub spectator_neutrons: Option<i32>,
    pub spectator_protons: Option<i32>,
    pub n_nwounded_collisions: Option<i32>,
    pub nwounded_n_collisions: Option<i32>,
    pub nwounded_nwounded_collisions: Option<i32>,
    pub impact_parameter: Option<f64>,
    pub event_plane_angle: Option<f64>,
    pub eccentricity: Option<f64>,
    pub sigma_inel_nn: Option<f64>,
}

/// STRIPPER-XML reweighting information
#[derive(Clone, Debug, PartialEq, PartialOrd)]
pub struct Reweight {
    pub channel: u32,
    pub x1: f64,
    pub x2: f64,
    pub log_coeff: Vec<f64>,
}