1use std::ops::AddAssign;
5use std::ops::Add;
6use std::cmp::Ordering;
7use crate::prelude::*;
8
9const NO_LIGHTSPEED_CUTS : f64 = 42e9;
14
15#[derive(Debug, Clone, Copy, serde::Deserialize, serde::Serialize)]
22#[cfg_attr(feature="pybindings", pyclass)]
23pub struct TofCuts {
24 #[serde(skip_serializing)]
28 pub nevents : u64 ,
29 pub min_hit_cor : u8 ,
31 pub min_hit_cbe : u8 ,
33 pub min_hit_umb : u8 ,
35 pub max_hit_cor : u8 ,
36 pub max_hit_cbe : u8 ,
37 pub max_hit_umb : u8 ,
38 pub min_hit_all : u8 ,
39 pub max_hit_all : u8 ,
40 pub min_cos_theta : f32 ,
41 pub max_cos_theta : f32 ,
42 pub only_causal_hits : bool,
43 #[serde(skip_serializing)]
44 pub hit_cbe_acc : u64 ,
45 #[serde(skip_serializing)]
46 pub hit_umb_acc : u64 ,
47 #[serde(skip_serializing)]
48 pub hit_cor_acc : u64 ,
49 #[serde(skip_serializing)]
50 pub hit_all_acc : u64 ,
51 #[serde(skip_serializing)]
52 pub fh_umb_acc : u64 ,
53 #[serde(skip_serializing)]
54 pub cos_theta_acc : u64 ,
55 #[serde(skip_serializing)]
56 pub hits_total : u64 ,
57 #[serde(skip_serializing)]
58 pub hits_rmvd_csl : u64 ,
59 #[serde(skip_serializing)]
60 pub hits_rmvd_ls : u64 ,
61 pub fh_must_be_umb : bool,
62 #[serde(skip_serializing)]
63 pub ls_cleaning_t_err : f64 ,
64 pub thru_going : bool,
65 #[serde(skip_serializing)]
66 pub thru_going_acc : u64 ,
67 pub fhi_not_bot : bool,
68 #[serde(skip_serializing)]
69 pub fhi_not_bot_acc : u64 ,
70 pub fho_must_panel7 : bool,
71 #[serde(skip_serializing)]
72 pub fho_must_panel7_acc : u64 ,
73 pub lh_must_panel2 : bool,
74 #[serde(skip_serializing)]
75 pub lh_must_panel2_acc : u64 ,
76 pub hit_high_edep : bool,
77 #[serde(skip_serializing)]
78 pub hit_high_edep_acc : u64 ,
79}
80
81impl TofCuts {
82
83 pub fn new() -> Self {
84 Self {
85 min_hit_cor : 0 ,
86 min_hit_cbe : 0 ,
87 min_hit_umb : 0 ,
88 max_hit_cor : 161,
89 max_hit_cbe : 161,
90 max_hit_umb : 161,
91 min_hit_all : 0 ,
92 max_hit_all : 161,
93 min_cos_theta : 0.0,
94 max_cos_theta : 1.0,
95 only_causal_hits : false,
96 hit_cbe_acc : 0,
97 hit_umb_acc : 0,
98 hit_cor_acc : 0,
99 hit_all_acc : 0,
100 cos_theta_acc : 0,
101 nevents : 0,
102 hits_total : 0,
103 hits_rmvd_csl : 0,
104 hits_rmvd_ls : 0,
105 fh_must_be_umb : false,
106 fh_umb_acc : 0 ,
107 ls_cleaning_t_err : NO_LIGHTSPEED_CUTS ,
108 thru_going : false,
109 thru_going_acc : 0 ,
110 fhi_not_bot : false,
111 fhi_not_bot_acc : 0 ,
112 fho_must_panel7 : false,
113 fho_must_panel7_acc : 0 ,
114 lh_must_panel2 : false,
115 lh_must_panel2_acc : 0 ,
116 hit_high_edep : false,
117 hit_high_edep_acc : 0 ,
118 }
119 }
120
121 pub fn to_toml(&self, mut filename : String) {
123 if !filename.ends_with(".toml") {
124 filename += ".toml";
125 }
126 info!("Will write to file {}!", filename);
127 match File::create(&filename) {
128 Err(err) => {
129 error!("Unable to open file {}! {}", filename, err);
130 }
131 Ok(mut file) => {
132 match toml::to_string_pretty(&self) {
133 Err(err) => {
134 error!("Unable to serialize toml! {err}");
135 }
136 Ok(toml_string) => {
137 match file.write_all(toml_string.as_bytes()) {
138 Err(err) => error!("Unable to write to file {}! {}", filename, err),
139 Ok(_) => debug!("Wrote settings to {}!", filename)
140 }
141 }
142 }
143 }
144 }
145 }
146
147 pub fn from_toml(filename : &str) -> Result<Self, SerializationError> {
148 match File::open(filename) {
149 Err(err) => {
150 error!("Unable to open {}! {}", filename, err);
151 return Err(SerializationError::TomlDecodingError);
152 }
153 Ok(mut file) => {
154 let mut toml_string = String::from("");
155 match file.read_to_string(&mut toml_string) {
156 Err(err) => {
157 error!("Unable to read {}! {}", filename, err);
158 return Err(SerializationError::TomlDecodingError);
159 }
160 Ok(_) => {
161 match toml::from_str(&toml_string) {
162 Err(err) => {
163 error!("Can't interpret toml! {}", err);
164 return Err(SerializationError::TomlDecodingError);
165 }
166 Ok(cuts) => {
167 return Ok(cuts);
168 }
169 }
170 }
171 }
172 }
173 }
174 }
175
176 pub fn is_compatible(&self, other : &TofCuts) -> bool {
180 if self.only_causal_hits != other.only_causal_hits {
181 return false;
182 }
183 if self.min_hit_cor != other.min_hit_cor {
184 return false;
185 }
186 if self.min_hit_cbe != other.min_hit_cbe {
187 return false;
188 }
189 if self.min_hit_umb != other.min_hit_umb {
190 return false;
191 }
192 if self.max_hit_cor != other.max_hit_cor {
193 return false;
194 }
195 if self.max_hit_cbe != other.max_hit_cbe {
196 return false;
197 }
198 if self.max_hit_umb != other.max_hit_umb {
199 return false;
200 }
201 if self.min_hit_all != other.min_hit_all {
202 return false;
203 }
204 if self.max_hit_all != other.max_hit_all {
205 return false;
206 }
207 if self.ls_cleaning_t_err != other.ls_cleaning_t_err {
208 return false;
209 }
210 if self.fh_must_be_umb != other.fh_must_be_umb {
211 return false;
212 }
213 if self.thru_going != other.thru_going {
214 return false;
215 }
216 if self.fhi_not_bot != other.fhi_not_bot {
217 return false;
218 }
219 if self.min_cos_theta != other.min_cos_theta {
220 return false;
221 }
222 if self.max_cos_theta != other.max_cos_theta {
223 return false;
224 }
225 if self.fho_must_panel7 != other.fho_must_panel7 {
226 return false;
227 }
228 if self.lh_must_panel2 != other.lh_must_panel2 {
229 return false;
230 }
231 if self.hit_high_edep != other.hit_high_edep {
232 return false;
233 }
234 true
235 }
236
237
238 pub fn clear_stats(&mut self) {
240 self.hit_cbe_acc = 0;
241 self.hit_umb_acc = 0;
242 self.hit_cor_acc = 0;
243 self.hit_all_acc = 0;
244 self.cos_theta_acc = 0;
245 self.nevents = 0;
246 self.hits_total = 0;
247 self.hits_rmvd_csl = 0;
248 self.hits_rmvd_ls = 0;
249 self.fh_umb_acc = 0;
250 self.thru_going_acc = 0;
251 self.fhi_not_bot_acc = 0;
252 self.fho_must_panel7_acc = 0;
253 self.lh_must_panel2_acc = 0;
254 self.hit_high_edep_acc = 0;
255 }
256
257 pub fn is_void(&self) -> bool {
258 if self.min_hit_cor != 0 {
259 return false;
260 }
261 if self.min_hit_cbe != 0 {
262 return false;
263 }
264 if self.min_hit_umb != 0 {
265 return false;
266 }
267 if self.max_hit_cor != 161 {
268 return false;
269 }
270 if self.max_hit_cbe != 161 {
271 return false;
272 }
273 if self.max_hit_umb != 161 {
274 return false;
275 }
276 if self.min_hit_all != 0 {
277 return false;
278 }
279 if self.max_hit_all != 161 {
280 return false;
281 }
282 if self.only_causal_hits {
283 return false;
284 }
285 if self.ls_cleaning_t_err != NO_LIGHTSPEED_CUTS {
286 return false;
287 }
288 if self.fh_must_be_umb != false {
289 return false;
290 }
291 if self.thru_going != false {
292 return false;
293 }
294 if self.fhi_not_bot != false {
295 return false;
296 }
297 if self.min_cos_theta != 0.0 {
298 return false;
299 }
300 if self.max_cos_theta != 1.0 {
301 return false;
302 }
303 if self.fho_must_panel7 {
304 return false;
305 }
306 if self.lh_must_panel2 {
307 return false;
308 }
309 if self.hit_high_edep {
310 return false;
311 }
312 return true;
313 }
314
315 pub fn get_acc_frac_hit_umb(&self) -> f64 {
316 if self.nevents == 0 {
317 return 0.0;
318 }
319 self.hit_umb_acc as f64/(self.nevents as f64)
320 }
321
322 pub fn get_acc_frac_hit_cbe(&self) -> f64 {
323 if self.nevents == 0 {
324 return 0.0;
325 }
326 self.hit_cbe_acc as f64/(self.nevents as f64)
327 }
328
329 pub fn get_acc_frac_hit_cor(&self) -> f64 {
330 if self.nevents == 0 {
331 return 0.0;
332 }
333 self.hit_cor_acc as f64/(self.nevents as f64)
334 }
335
336 pub fn get_acc_frac_hit_all(&self) -> f64 {
337 if self.nevents == 0 {
338 return 0.0;
339 }
340 self.hit_all_acc as f64/(self.nevents as f64)
341 }
342
343 pub fn get_acc_frac_cos_theta(&self) -> f64 {
344 if self.nevents == 0 {
345 return 0.0;
346 }
347 self.cos_theta_acc as f64/(self.nevents as f64)
348 }
349
350 pub fn get_acc_frac_fh_must_be_umb(&self) -> f64 {
351 if self.nevents == 0 {
352 return 0.0;
353 }
354 self.fh_umb_acc as f64/(self.nevents as f64)
355 }
356
357 pub fn get_acc_frac_thru_going(&self) -> f64 {
358 if self.nevents == 0 {
359 return 0.0;
360 }
361 self.thru_going_acc as f64/(self.nevents as f64)
362 }
363
364 pub fn get_acc_frac_fhi_not_bot(&self) -> f64 {
365 if self.nevents == 0 {
366 return 0.0;
367 }
368 self.fhi_not_bot_acc as f64/(self.nevents as f64)
369 }
370
371 pub fn get_acc_frac_fho_must_panel7(&self) -> f64 {
372 if self.nevents == 0 {
373 return 0.0;
374 }
375 self.fho_must_panel7_acc as f64/(self.nevents as f64)
376 }
377
378 pub fn get_acc_frac_lh_must_panel2(&self) -> f64 {
379 if self.nevents == 0 {
380 return 0.0;
381 }
382 self.lh_must_panel2_acc as f64/(self.nevents as f64)
383 }
384
385 pub fn get_acc_frac_hit_high_edep(&self) -> f64 {
386 if self.nevents == 0 {
387 return 0.0;
388 }
389 self.hit_high_edep_acc as f64/(self.nevents as f64)
390 }
391
392
393 pub fn accept(&mut self, ev : &mut TofEvent) -> bool {
398 if self.is_void() {
399 return true;
400 }
401 let nhits = ev.get_nhits() as u64;
404 self.hits_total += nhits;
405 self.nevents += 1;
406 ev.normalize_hit_times();
410 if self.only_causal_hits {
411 let rm_pids = ev.remove_non_causal_hits();
412 self.hits_rmvd_csl += rm_pids.len() as u64;
413 }
414 if self.ls_cleaning_t_err != NO_LIGHTSPEED_CUTS {
415 let rm_pids_ls = ev.lightspeed_cleaning(self.ls_cleaning_t_err as f32);
417 self.hits_rmvd_ls += rm_pids_ls.0.len() as u64;
418 }
419 let nhits_cbe = ev.get_nhits_cbe() as u64;
421 let nhits_umb = ev.get_nhits_umb() as u64;
422 let nhits_cor = ev.get_nhits_cor() as u64;
423 let clean_nhits = nhits_cbe + nhits_umb + nhits_cor;
424 if !((self.min_hit_all as u64 <= clean_nhits) && (clean_nhits <= self.max_hit_all as u64)) {
427 return false;
428 } else {
429 self.hit_all_acc += 1;
430 }
431 if !((self.min_hit_cbe as u64<= nhits_cbe) && (nhits_cbe <= self.max_hit_cbe as u64)) {
432 return false;
433 } else {
434 self.hit_cbe_acc += 1;
435 }
436 if !((self.min_hit_umb as u64 <= nhits_umb) && (nhits_umb <= self.max_hit_umb as u64)) {
437 return false;
438 } else {
439 self.hit_umb_acc += 1;
440 }
441 if !((self.min_hit_cor as u64 <= nhits_cor) && (nhits_cor <= self.max_hit_cor as u64)) {
442 return false;
443 } else {
444 self.hit_cor_acc += 1;
445 }
446 if self.fh_must_be_umb
450 || self.thru_going
451 || self.fhi_not_bot
452 || (self.min_cos_theta != 0.0)
453 || (self.max_cos_theta != 1.0)
454 || self.fho_must_panel7
455 || self.lh_must_panel2
456 || self.hit_high_edep {
457 ev.hits.sort_by(|a,b| a.event_t0.partial_cmp(&b.event_t0).unwrap_or(Ordering::Greater));
459 let hits_sorted = &ev.hits;
460 if hits_sorted.len() == 0 {
461 return false;
463 }
464 let first_pid = hits_sorted[0].paddle_id;
465 let last_pid = hits_sorted.last().expect("No HITS!").paddle_id;
466 let hits_inner: Vec<&TofHit> = hits_sorted.iter()
467 .filter(|k| k.paddle_id < 61)
468 .collect();
469 let hits_outer: Vec<&TofHit> = hits_sorted.iter()
470 .filter(|k| k.paddle_id > 60)
471 .collect();
472 if self.fh_must_be_umb {
474 if (first_pid < 61) || (first_pid > 108) {
475 return false;
476 } else {
477 self.fh_umb_acc += 1;
478 }
479 } else {
480 self.fh_umb_acc += 1;
481 }
482 if self.thru_going {
483 if (last_pid >= 13 && last_pid < 25) || 108 < last_pid {
485 self.thru_going_acc += 1;
486 } else {
487 return false;
488 }
489 } else {
490 self.thru_going_acc += 1;
491 }
492 if self.fhi_not_bot {
493 if hits_inner.len() == 0 {
494 self.fhi_not_bot_acc += 1;
495 } else if (12 < hits_inner[0].paddle_id) && (hits_inner[0].paddle_id < 25) {
496 return false;
497 } else {
498 self.fhi_not_bot_acc += 1;
499 }
500 } else {
501 self.fhi_not_bot_acc += 1;
502 }
503 if self.min_cos_theta != 0.0 || self.max_cos_theta != 1.0 {
504 let dist = hits_inner[0].distance(hits_outer[0])/1000.0;
505 let cos_theta = f32::abs(hits_inner[0].z - hits_outer[0].z)/(1000.0*dist);
506 if !((self.min_cos_theta <= cos_theta) && (cos_theta <= self.max_cos_theta)) {
507 return false;
508 } else {
509 self.cos_theta_acc += 1;
510 }
511 self.cos_theta_acc += 1;
512 }
513 if self.fho_must_panel7 {
514 if first_pid < 61 || first_pid >= 72 {
516 return false;
517 } else {
518 self.fho_must_panel7_acc += 1;
519 }
520 }
521 if self.lh_must_panel2 {
522 if last_pid < 13 || last_pid > 24 {
523 return false;
524 } else {
525 self.lh_must_panel2_acc += 1;
526 }
527 }
528 if self.hit_high_edep {
529 let mut found = false;
530 for h in hits_sorted {
531 if h.get_edep() > 20.0 {
532 self.lh_must_panel2_acc += 1;
533 found = true;
534 break;
535 }
536 }
537 if !found {
538 return false;
539 }
540 }
541 }
542 true
544 }
545
546 pub fn pretty_print_efficiency(&self) -> String {
548 let mut repr = String::from("-- -- -- -- -- -- -- -- -- -- --");
549 repr += &(format!("\n TOTAL EVENTS : {}", self.nevents));
550 repr += &(format!("\n {} <= NHit(UMB) <= {} : {:.2} %", self.min_hit_umb, self.max_hit_umb, 100.0*self.get_acc_frac_hit_umb()));
551 repr += &(format!("\n {} <= NHit(CBE) <= {} : {:.2} %", self.min_hit_cbe, self.max_hit_cbe, 100.0*self.get_acc_frac_hit_cbe()));
552 repr += &(format!("\n {} <= NHit(COR) <= {} : {:.2} %", self.min_hit_cor, self.max_hit_cor, 100.0*self.get_acc_frac_hit_cor()));
553 repr += &(format!("\n {} <= NHit(TOF) <= {} : {:.2} %", self.min_hit_all, self.max_hit_all, 100.0*self.get_acc_frac_hit_all()));
554 repr += &(format!("\n {} <= COS(THET) <= {} : {:.2} %", self.min_cos_theta, self.max_cos_theta, self.get_acc_frac_cos_theta()));
555 if self.only_causal_hits {
556 if self.hits_total > 0 {
557 repr += &(format!("\n Removed {:.2} % of hits due to causality cut!", 100.0*self.hits_rmvd_csl as f64/self.hits_total as f64));
558 }
559 }
560 if self.ls_cleaning_t_err != NO_LIGHTSPEED_CUTS {
561 if self.hits_total > 0 {
562 repr += &(format!("\n Removed {:.2} % of hits due to lightspeed cut!", 100.0*(self.hits_rmvd_ls as f64)/self.hits_total as f64));
563 }
564 }
565 if self.fh_must_be_umb {
566 repr += "\n First hit must be on UMB!";
567 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_fh_must_be_umb()));
568 }
569 if self.thru_going {
570 repr += "\n Require through-going track!";
571 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_thru_going()));
572 }
573 if self.fhi_not_bot {
574 repr += "\n Require first hit on the inner TOF can not be on the Bottom 12PP";
575 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_fhi_not_bot()));
576 }
577 if self.fho_must_panel7 {
578 repr += "\n Require first hit on the outer TOF must be on panel7";
579 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_fho_must_panel7()));
580 }
581 if self.lh_must_panel2 {
582 repr += "\n Require last hit must be on the bottom CBE panel";
583 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_lh_must_panel2()));
584 }
585 if self.hit_high_edep {
586 repr += "\n Require that one hit has an edep > 20MeV";
587 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_hit_high_edep()));
588 }
589 repr += "\n-- -- -- -- -- -- -- -- -- -- --";
590 repr
592 }
593}
594
595impl Default for TofCuts {
596 fn default() -> Self {
597 Self::new()
598 }
599}
600
601impl fmt::Display for TofCuts {
602 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
603 let mut repr = String::from("<TofCuts:");
604 if self.is_void() {
605 repr += " (void)>";
606 } else {
607 if self.only_causal_hits {
608 repr += &(format!("\n -- removes non-causal hits!"));
609 }
610 if self.ls_cleaning_t_err != NO_LIGHTSPEED_CUTS {
612 repr += "\n -- removes hits which are not correlated with the first hit!";
613 repr += &(format!("\n -- assumed timing error {}", self.ls_cleaning_t_err));
614 }
615 if self.fh_must_be_umb {
616 repr += "\n -- first hit must be on UMB";
617 }
618 if self.thru_going {
619 repr += "\n -- require last hit on CBE BOT or COR (thru-going tracks)";
620 }
621 if self.fhi_not_bot {
622 repr += "\n -- require that the first hit on the inner TOF is not on CBE BOT";
623 }
624 if self.fho_must_panel7 {
625 repr += "\n -- require that the first hit on the outer TOF is on panel7";
626 }
627 if self.lh_must_panel2 {
628 repr += "\n -- require that the last hit on the inner TOF is on CBE BOT";
629 }
630 if self.hit_high_edep {
631 repr += "\n -- require that at least one hit has an edep of > 29MeV";
632 }
633 repr += &(format!("\n {} <= NHit(UMB) <= {}", self.min_hit_umb, self.max_hit_umb));
634 repr += &(format!("\n {} <= NHit(CBE) <= {}", self.min_hit_cbe, self.max_hit_cbe));
635 repr += &(format!("\n {} <= NHit(COR) <= {}", self.min_hit_cor, self.max_hit_cor));
636 repr += &(format!("\n {} <= NHit(TOF) <= {}", self.min_hit_all, self.max_hit_all));
637 repr += &(format!("\n {} <= COS(THET) <= {}", self.min_cos_theta, self.max_cos_theta));
638 repr += ">";
639 }
640 write!(f, "{}", repr)
641 }
642}
643
644impl AddAssign for TofCuts {
645 fn add_assign(&mut self, other : Self) {
646 if !self.is_compatible(&other) {
647 panic!("Cuts are not compatible!");
649 }
650 self.nevents += other.nevents;
651 self.hit_cbe_acc += other.hit_cbe_acc;
652 self.hit_umb_acc += other.hit_umb_acc;
653 self.hit_cor_acc += other.hit_cor_acc;
654 self.hit_all_acc += other.hit_all_acc;
655 self.cos_theta_acc += other.cos_theta_acc;
656 self.hits_total += other.hits_total;
657 self.hits_rmvd_csl += other.hits_rmvd_csl;
658 self.hits_rmvd_ls += other.hits_rmvd_ls;
659 self.fh_umb_acc += other.fh_umb_acc;
660 self.thru_going_acc += other.thru_going_acc;
661 self.fhi_not_bot_acc += other.fhi_not_bot_acc;
662 self.fho_must_panel7_acc += other.fho_must_panel7_acc;
663 self.lh_must_panel2_acc += other.lh_must_panel2_acc;
664 self.hit_high_edep_acc += other.hit_high_edep_acc;
665 }
666}
667
668impl Add for TofCuts {
669
670 type Output = TofCuts;
671
672 fn add(self, other: Self) -> Self::Output {
673 let mut output = self.clone();
674 output += other;
675 return output;
676 }
677}
678
679#[cfg(feature="pybindings")]
680#[pymethods]
681impl TofCuts {
682
683 fn copy(&self) -> Self {
686 self.clone()
687 }
688
689 #[pyo3(name="is_compatible")]
690 fn is_compatible_py(&self, other : &Self) -> bool {
691 self.is_compatible(other)
692 }
693
694 #[pyo3(name = "clear_stats")]
695 fn clear_stats_py(&mut self) {
696 self.clear_stats();
697 }
698
699 #[pyo3(name="accept")]
700 fn accept_py(&mut self, event : &mut TofEvent) -> bool {
701 self.accept(event)
702 }
703
704 #[getter]
705 fn get_min_hit_cor (&self) -> u8 {
706 self.min_hit_cor
707 }
708
709 #[setter]
710 fn set_min_hit_cor(&mut self, value : u8) -> PyResult<()> {
711 self.min_hit_cor = value;
712 Ok(())
713 }
714
715 fn __iadd__(&mut self, other : &TofCuts) {
716 self.add_assign(*other);
717 }
718
719 fn __add__(&self, other : &TofCuts) -> TofCuts {
720 let other_c = other.clone();
721 self.add(other_c)
722 }
723
724 #[pyo3(name="to_toml")]
725 fn to_toml_py(&self, filename : String) {
726 self.to_toml(filename);
727 }
728
729 #[staticmethod]
730 #[pyo3(name="from_toml")]
731 fn from_toml_py(filename : String) -> PyResult<Self> {
732 match Self::from_toml(&filename) {
733 Err(err) => {
734 return Err(PyValueError::new_err(err.to_string()));
735 }
736 Ok(cuts_) => {
737 return Ok(cuts_);
738 }
739 }
740 }
741
742 #[getter]
743 fn void(&self) -> bool {
744 self.is_void()
745 }
746
747 #[pyo3(name="pretty_print_efficiency")]
751 fn pretty_print_efficiency_py(&self) -> String {
752 self.pretty_print_efficiency()
753 }
754
755 #[getter]
756 fn get_min_hit_cbe (&self) -> u8 {
757 self.min_hit_cbe
758 }
759
760 #[setter]
761 fn set_min_hit_cbe(&mut self, value : u8) -> PyResult<()> {
762 self.min_hit_cbe = value;
763 Ok(())
764 }
765
766 #[getter]
767 fn get_min_hit_umb (&self) -> u8 {
768 self.min_hit_umb
769 }
770
771 #[setter]
772 fn set_min_hit_umb(&mut self, value : u8) -> PyResult<()> {
773 self.min_hit_umb = value;
774 Ok(())
775 }
776
777 #[getter]
778 fn get_max_hit_cor (&self) -> u8 {
779 self.max_hit_cor
780 }
781
782 #[setter]
783 fn set_max_hit_cor(&mut self, value : u8) -> PyResult<()> {
784 self.max_hit_cor = value;
785 Ok(())
786 }
787
788 #[getter]
789 fn get_max_hit_cbe (&self) -> u8 {
790 self.max_hit_cbe
791 }
792
793 #[setter]
794 fn set_max_hit_cbe(&mut self, value : u8) -> PyResult<()> {
795 self.max_hit_cbe = value;
796 Ok(())
797 }
798
799 #[getter]
800 fn get_max_hit_umb (&self) -> u8 {
801 self.max_hit_umb
802 }
803
804 #[setter]
805 fn set_max_hit_umb(&mut self, value : u8) -> PyResult<()> {
806 self.max_hit_umb = value;
807 Ok(())
808 }
809
810 #[getter]
811 fn get_min_hit_all (&self) -> u8 {
812 self.min_hit_all
813 }
814
815 #[setter]
816 fn set_min_hit_all(&mut self, value : u8) -> PyResult<()> {
817 self.min_hit_all = value;
818 Ok(())
819 }
820
821 #[getter]
822 fn get_max_hit_all (&self) -> u8 {
823 self.max_hit_all
824 }
825
826 #[setter]
827 fn set_max_hit_all(&mut self, value : u8) -> PyResult<()> {
828 self.max_hit_all = value;
829 Ok(())
830 }
831
832 #[getter]
833 fn get_min_cos_theta (&self) -> f32 {
834 self.min_cos_theta
835 }
836
837 #[setter]
838 fn set_min_cos_theta(&mut self, value : f32) -> PyResult<()> {
839 self.min_cos_theta = value;
840 Ok(())
841 }
842
843 #[getter]
844 fn get_max_cos_theta (&self) -> f32 {
845 self.max_cos_theta
846 }
847
848 #[setter]
849 fn set_max_cos_theta(&mut self, value : f32) -> PyResult<()> {
850 self.max_cos_theta = value;
851 Ok(())
852 }
853
854 #[getter]
855 fn get_only_causal_hits (&self) -> bool {
856 self.only_causal_hits
857 }
858
859 #[setter]
860 fn set_only_causal_hits(&mut self, value : bool) -> PyResult<()> {
861 self.only_causal_hits = value;
862 Ok(())
863 }
864
865 #[getter]
866 fn get_hit_cbe_acc (&self) -> u64 {
867 self.hit_cbe_acc
868 }
869
870 #[getter]
871 fn get_hit_umb_acc (&self) -> u64 {
872 self.hit_umb_acc
873 }
874
875 #[getter]
876 fn get_hit_cor_acc (&self) -> u64 {
877 self.hit_cor_acc
878 }
879
880 #[getter]
881 fn get_hit_all_acc (&self) -> u64 {
882 self.hit_all_acc
883 }
884
885 #[getter]
886 fn get_cos_theta_acc (&self) -> u64 {
887 self.cos_theta_acc
888 }
889
890 #[getter]
891 fn get_nevents (&self) -> u64 {
892 self.nevents
893 }
894
895 #[getter]
896 fn get_hits_total (&self) -> u64 {
897 self.hits_total
898 }
899
900 #[getter]
901 fn get_hits_rmvd_csl (&self) -> u64 {
902 self.hits_rmvd_csl
903 }
904
905 #[getter]
906 fn get_hits_rmvd_ls (&self) -> u64 {
907 self.hits_rmvd_ls
908 }
909
910 #[getter]
911 fn get_fh_must_be_umb (&self) -> bool {
912 self.fh_must_be_umb
913 }
914
915 #[setter]
916 fn set_fh_must_be_umb(&mut self, value : bool) -> PyResult<()> {
917 self.fh_must_be_umb = value;
918 Ok(())
919 }
920
921 #[getter]
922 fn get_fh_umb_acc (&self) -> u64 {
923 self.fh_umb_acc
924 }
925
926 #[getter]
927 fn get_ls_cleaning_t_err (&self) -> f64 {
928 self.ls_cleaning_t_err
929 }
930
931 #[setter]
932 fn set_ls_cleaning_t_err(&mut self, value : f64) -> PyResult<()> {
933 self.ls_cleaning_t_err = value;
934 Ok(())
935 }
936
937 #[getter]
938 fn get_thru_going (&self) -> bool {
939 self.thru_going
940 }
941
942 #[setter]
943 fn set_thru_going(&mut self, value : bool) -> PyResult<()> {
944 self.thru_going = value;
945 Ok(())
946 }
947
948 #[getter]
949 fn get_thru_going_acc (&self) -> u64 {
950 self.thru_going_acc
951 }
952
953 #[getter]
954 fn get_fhi_not_bot (&self) -> bool {
955 self.fhi_not_bot
956 }
957
958 #[setter]
959 fn set_fhi_not_bot(&mut self, value : bool) -> PyResult<()> {
960 self.fhi_not_bot = value;
961 Ok(())
962 }
963
964 #[getter]
965 fn get_fhi_not_bot_acc (&self) -> u64 {
966 self.fhi_not_bot_acc
967 }
968
969 #[getter]
970 fn get_fho_must_panel7 (&self) -> bool {
971 self.fho_must_panel7
972 }
973
974 #[setter]
975 fn set_fho_must_panel7(&mut self, value : bool) -> PyResult<()> {
976 self.fho_must_panel7 = value;
977 Ok(())
978 }
979
980 #[getter]
981 fn get_fho_must_panel7_acc(&self) -> u64 {
982 self.fho_must_panel7_acc
983 }
984
985 #[getter]
986 fn get_lh_must_panel2 (&self) -> bool {
987 self.lh_must_panel2
988 }
989
990 #[setter]
991 fn set_lh_must_panel2(&mut self, value : bool) -> PyResult<()> {
992 self.lh_must_panel2 = value;
993 Ok(())
994 }
995
996 #[getter]
997 fn get_lh_must_panel2_acc (&self) -> u64 {
998 self.lh_must_panel2_acc
999 }
1000
1001 #[getter]
1002 fn get_hit_high_edep (&self) -> bool {
1003 self.hit_high_edep
1004 }
1005
1006 #[setter]
1007 fn set_hit_high_edep(&mut self, value : bool) -> PyResult<()> {
1008 self.hit_high_edep = value;
1009 Ok(())
1010 }
1011
1012 #[getter]
1013 #[pyo3(name="acc_frac_hit_umb")]
1014 fn get_acc_frac_hit_umb_py(&self) -> f64 {
1015 self.get_acc_frac_hit_umb()
1016 }
1017
1018 #[getter]
1019 #[pyo3(name="acc_frac_hit_cbe")]
1020 fn get_acc_frac_hit_cbe_py(&self) -> f64 {
1021 self.get_acc_frac_hit_cbe()
1022 }
1023
1024 #[getter]
1025 #[pyo3(name="acc_frac_hit_cor")]
1026 fn get_acc_frac_hit_cor_py(&self) -> f64 {
1027 self.get_acc_frac_hit_cor()
1028 }
1029
1030 #[getter]
1031 #[pyo3(name="acc_frac_hit_all")]
1032 fn get_acc_frac_hit_all_py(&self) -> f64 {
1033 self.get_acc_frac_hit_all()
1034 }
1035
1036 #[getter]
1037 #[pyo3(name="acc_frac_cos_theta")]
1038 fn get_acc_frac_cos_theta_py(&self) -> f64 {
1039 self.get_acc_frac_cos_theta()
1040 }
1041
1042 #[getter]
1043 #[pyo3(name="acc_frac_fh_must_be_umb")]
1044 fn get_acc_frac_fh_must_be_umb_py(&self) -> f64 {
1045 self.get_acc_frac_fh_must_be_umb()
1046 }
1047
1048 #[getter]
1049 #[pyo3(name="get_frac_thru_going")]
1050 fn get_acc_frac_thru_going_py(&self) -> f64 {
1051 self.get_acc_frac_thru_going()
1052 }
1053
1054 #[getter]
1055 #[pyo3(name="acc_frac_fhi_not_bot")]
1056 fn get_acc_frac_fhi_not_bot_py(&self) -> f64 {
1057 self.get_acc_frac_fhi_not_bot()
1058 }
1059
1060 #[getter]
1061 #[pyo3(name="acc_frac_fho_must_panel7")]
1062 fn get_acc_frac_fho_must_panel7_py(&self) -> f64 {
1063 self.get_acc_frac_fho_must_panel7()
1064 }
1065
1066 #[getter]
1067 #[pyo3(name="acc_frac_lh_must_panel2")]
1068 fn get_acc_frac_lh_must_panel2_py(&self) -> f64 {
1069 self.get_acc_frac_lh_must_panel2()
1070 }
1071
1072 #[getter]
1073 fn get_hit_high_edep_acc (&self) -> u64 {
1074 self.hit_high_edep_acc
1075 }
1076}
1077
1078#[cfg(feature="pybindings")]
1079pythonize!(TofCuts);
1080