gondola_core/tracker/
online_calibration.rs1use crate::prelude::*;
5
6use std::io::BufRead;
7#[cfg(feature="pybindings")]
8use std::path::PathBuf;
9
10#[cfg_attr(feature="pybindings", pyclass)]
14pub struct TrackerOnlineCalibration {
15 pub tf_map : HashMap<u32,TrackerStripTransferFunction>,
16 pub ped_map : HashMap<u32,f32>,
17 pub pulser_map : HashMap<u32,bool>
18}
19
20impl TrackerOnlineCalibration {
21
22 pub fn new() -> Self {
23 Self {
24 tf_map : HashMap::<u32,TrackerStripTransferFunction>::new(),
25 ped_map : HashMap::<u32,f32>::new(),
26 pulser_map : HashMap::<u32,bool>::new()
27 }
28 }
29
30 pub fn from_default() -> Self {
33 let cali_path = env::var("GONDOLA_TRK_ONLINE_CAL").unwrap_or_else(|_| "".to_string());
34 Self::from_file(&cali_path)
35 }
36
37 pub fn from_file<P: AsRef<Path>>(path: P) -> Self {
39 let mut cali = Self::new();
40 let file_res = File::open(path);
41 match file_res {
42 Err(_err) => {
43 error!("Unable to open file!");
44 return cali;
45 }
46 Ok(file) => {
47 let reader = BufReader::new(file);
48 for line in reader.lines().skip(5) {
52 let line = line.unwrap();
53 let trimmed = line.trim();
54 if trimmed.is_empty() {
55 continue;
56 }
57 let row: Vec<f32> = trimmed
58 .split(',')
59 .map(|s| s.trim().parse::<f32>().unwrap_or(0.0))
60 .collect();
61 let mut strip = TrackerStrip::new();
62 strip.layer = row[0] as i32;
63 strip.row = row[1] as i32;
64 strip.module = row[2] as i32;
65 strip.channel = row[3] as i32;
66 let mut tf = TrackerStripTransferFunction::new();
67 let strip_id = strip.get_stripid();
68 tf.strip_id = strip_id as i32;
69 tf.pol_a2_0 = row[4];
70 tf.pol_a2_1 = row[5];
71 tf.pol_a2_2 = row[6];
72 tf.pol_b3_0 = row[7];
73 tf.pol_b3_1 = row[8];
74 tf.pol_b3_2 = row[9];
75 tf.pol_b3_3 = row[10];
76 tf.pol_c3_0 = row[11];
77 tf.pol_c3_1 = row[12];
78 tf.pol_c3_2 = row[13];
79 tf.pol_c3_3 = row[14];
80 tf.pol_d3_0 = row[15];
81 tf.pol_d3_1 = row[16];
82 tf.pol_d3_2 = row[17];
83 tf.pol_d3_3 = row[18];
84 let pedestal = row[19];
85 let is_puls = row[20] > 0.0;
86 cali.tf_map.insert(strip_id, tf);
87 cali.pulser_map.insert(strip_id, is_puls);
88 cali.ped_map.insert(strip_id, pedestal as f32);
89 }
91 }
92 }
93 cali
94 }
95
96 pub fn calibrate(&self, hit : &mut TrackerHit) {
101 let strip_id = hit.get_stripid();
102 let scale : f32 = 0.841/1000.0;
103 let mut adc : f32 = hit.adc as f32 - self.ped_map[&strip_id];
104 if adc > 1500.0 {
105 adc = 1500.0;
106 }
107 hit.energy = scale*self.tf_map[&strip_id].evaluate(adc);
108 }
109
110 pub fn is_pulsed(&self, hit : &TrackerHit) -> bool {
111 self.pulser_map[&hit.get_stripid()]
112 }
113}
114
115#[cfg(feature="pybindings")]
116#[pymethods]
117impl TrackerOnlineCalibration {
118
119 #[new]
120 fn new_py() -> Self {
121 Self::new()
122 }
123
124 #[pyo3(name="calibrate")]
133 fn calibrate_py(&self, hit : &mut TrackerHit) {
134 self.calibrate(hit);
135 }
136
137 #[pyo3(name="is_pulsed")]
138 fn is_pulsed_py(&self, hit : &TrackerHit) -> bool {
139 self.is_pulsed(hit)
140 }
141
142 #[staticmethod]
147 #[pyo3(name="from_default")]
148 pub fn from_default_py() -> PyResult<Self> {
149 let cali_path = env::var("GONDOLA_TRK_ONLINE_CAL").unwrap_or_else(|_| "".to_string());
150 Ok(Self::from_file(&cali_path))
151 }
152
153 #[staticmethod]
154 #[pyo3(name="from_file")]
155 fn from_file_py(path: String) -> PyResult<Self> {
156 let path_buf = PathBuf::from(path);
158 Ok(Self::from_file(path_buf))
159 }
160}
161