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