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
use std::collections::BTreeMap;

use serde::{Serialize, Deserialize};
use strum::EnumString;

/// Scattering event
#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize)]
pub struct Event {
    pub number: i32,
    pub mpi: i32,
    pub scale: f64,
    pub alpha_qcd: f64,
    pub alpha_qed: f64,
    pub signal_process_id: i32,
    pub signal_process_vertex: i32,
    pub random_states: Vec<i32>,
    pub weights: Vec<f64>,
    pub weight_names: Vec<String>,
    pub vertices: Vec<Vertex>,
    pub xs: CrossSection,
    pub pdf_info: PdfInfo,
    pub energy_unit: EnergyUnit,
    pub length_unit: LengthUnit,
    pub heavy_ion_info: Option<HeavyIonInfo>,
}

/// Interaction vertex
#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize)]
pub struct Vertex {
    pub barcode: i32,
    pub status: i32,
    pub x: f64,
    pub y: f64,
    pub z: f64,
    pub t: f64,
    pub weights: Vec<f64>,
    pub particles_in: Vec<Particle>,
    pub particles_out: Vec<Particle>,
}

/// Particle
#[derive(Debug, PartialEq, Default, Clone, Serialize, Deserialize)]
pub struct Particle {
    pub id: i32,
    pub p: FourVector,
    pub m: f64,
    pub status: i32,
    pub theta: f64,
    pub phi: f64,
    pub flows: BTreeMap<i32, i32>,
    pub end_vtx: i32,
}

/// Simple Lorentz vector with components (t, x, y, z)
#[derive(Debug, PartialEq, PartialOrd, Default, Copy, Clone, Serialize, Deserialize)]
pub struct FourVector(pub [f64; 4]);

impl FourVector {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn txyz(t: f64, x: f64, y: f64, z: f64) -> Self {
        FourVector { 0: [t, x, y, z] }
    }
}

impl std::ops::Index<usize> for FourVector {
    type Output = f64;

    fn index(&self, idx: usize) -> &Self::Output {
        &self.0[idx]
    }
}

impl std::ops::IndexMut<usize> for FourVector {
    fn index_mut(&mut self, idx: usize) -> &mut Self::Output {
        &mut self.0[idx]
    }
}

/// Cross section with error
#[derive(Debug, PartialEq, PartialOrd, Default, Copy, Clone, Serialize, Deserialize)]
pub struct CrossSection {
    pub cross_section: f64,
    pub cross_section_error: f64,
}

impl std::fmt::Display for CrossSection {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{} ± {}", self.cross_section, self.cross_section_error)
    }
}

/// PDF information
#[derive(Debug, PartialEq, PartialOrd, Default, Copy, Clone, Serialize, Deserialize)]
pub struct PdfInfo {
    pub parton_id: [i32; 2],
    pub x: [f64; 2],
    pub scale: f64,
    pub xf: [f64; 2],
    pub pdf_id: [i32; 2],
}

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

/// Energy units
#[derive(EnumString, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Serialize, Deserialize)]
pub enum EnergyUnit {
    MEV,
    GEV
}

impl std::default::Default for EnergyUnit {
    fn default() -> Self {
        Self::GEV
    }
}

/// Length units
#[derive(EnumString, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone, Serialize, Deserialize)]
pub enum LengthUnit {
    MM,
    CM
}

impl std::default::Default for LengthUnit {
    fn default() -> Self {
        Self::CM
    }
}