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 #[cfg(feature="database")]
398 pub fn accept(&mut self, ev : &mut TofEvent) -> bool {
399 if self.is_void() {
400 return true;
401 }
402 let nhits = ev.get_nhits() as u64;
405 self.hits_total += nhits;
406 self.nevents += 1;
407 ev.normalize_hit_times();
411 if self.only_causal_hits {
412 let rm_pids = ev.remove_non_causal_hits();
413 self.hits_rmvd_csl += rm_pids.len() as u64;
414 }
415 if self.ls_cleaning_t_err != NO_LIGHTSPEED_CUTS {
416 let rm_pids_ls = ev.lightspeed_cleaning(self.ls_cleaning_t_err as f32);
418 self.hits_rmvd_ls += rm_pids_ls.0.len() as u64;
419 }
420 let nhits_cbe = ev.get_nhits_cbe() as u64;
422 let nhits_umb = ev.get_nhits_umb() as u64;
423 let nhits_cor = ev.get_nhits_cor() as u64;
424 let clean_nhits = nhits_cbe + nhits_umb + nhits_cor;
425 if !((self.min_hit_all as u64 <= clean_nhits) && (clean_nhits <= self.max_hit_all as u64)) {
428 return false;
429 } else {
430 self.hit_all_acc += 1;
431 }
432 if !((self.min_hit_cbe as u64<= nhits_cbe) && (nhits_cbe <= self.max_hit_cbe as u64)) {
433 return false;
434 } else {
435 self.hit_cbe_acc += 1;
436 }
437 if !((self.min_hit_umb as u64 <= nhits_umb) && (nhits_umb <= self.max_hit_umb as u64)) {
438 return false;
439 } else {
440 self.hit_umb_acc += 1;
441 }
442 if !((self.min_hit_cor as u64 <= nhits_cor) && (nhits_cor <= self.max_hit_cor as u64)) {
443 return false;
444 } else {
445 self.hit_cor_acc += 1;
446 }
447 if self.fh_must_be_umb
451 || self.thru_going
452 || self.fhi_not_bot
453 || (self.min_cos_theta != 0.0)
454 || (self.max_cos_theta != 1.0)
455 || self.fho_must_panel7
456 || self.lh_must_panel2
457 || self.hit_high_edep {
458 ev.hits.sort_by(|a,b| a.event_t0.partial_cmp(&b.event_t0).unwrap_or(Ordering::Greater));
460 let hits_sorted = &ev.hits;
461 if hits_sorted.len() == 0 {
462 return false;
464 }
465 let first_pid = hits_sorted[0].paddle_id;
466 let last_pid = hits_sorted.last().expect("No HITS!").paddle_id;
467 let hits_inner: Vec<&TofHit> = hits_sorted.iter()
468 .filter(|k| k.paddle_id < 61)
469 .collect();
470 let hits_outer: Vec<&TofHit> = hits_sorted.iter()
471 .filter(|k| k.paddle_id > 60)
472 .collect();
473 if self.fh_must_be_umb {
475 if (first_pid < 61) || (first_pid > 108) {
476 return false;
477 } else {
478 self.fh_umb_acc += 1;
479 }
480 } else {
481 self.fh_umb_acc += 1;
482 }
483 if self.thru_going {
484 if (last_pid >= 13 && last_pid < 25) || 108 < last_pid {
486 self.thru_going_acc += 1;
487 } else {
488 return false;
489 }
490 } else {
491 self.thru_going_acc += 1;
492 }
493 if self.fhi_not_bot {
494 if hits_inner.len() == 0 {
495 self.fhi_not_bot_acc += 1;
496 } else if (12 < hits_inner[0].paddle_id) && (hits_inner[0].paddle_id < 25) {
497 return false;
498 } else {
499 self.fhi_not_bot_acc += 1;
500 }
501 } else {
502 self.fhi_not_bot_acc += 1;
503 }
504 if self.min_cos_theta != 0.0 || self.max_cos_theta != 1.0 {
505 let dist = hits_inner[0].distance(hits_outer[0])/1000.0;
506 let cos_theta = f32::abs(hits_inner[0].z - hits_outer[0].z)/(1000.0*dist);
507 if !((self.min_cos_theta <= cos_theta) && (cos_theta <= self.max_cos_theta)) {
508 return false;
509 } else {
510 self.cos_theta_acc += 1;
511 }
512 self.cos_theta_acc += 1;
513 }
514 if self.fho_must_panel7 {
515 if first_pid < 61 || first_pid >= 72 {
517 return false;
518 } else {
519 self.fho_must_panel7_acc += 1;
520 }
521 }
522 if self.lh_must_panel2 {
523 if last_pid < 13 || last_pid > 24 {
524 return false;
525 } else {
526 self.lh_must_panel2_acc += 1;
527 }
528 }
529 if self.hit_high_edep {
530 let mut found = false;
531 for h in hits_sorted {
532 if h.get_edep() > 20.0 {
533 self.lh_must_panel2_acc += 1;
534 found = true;
535 break;
536 }
537 }
538 if !found {
539 return false;
540 }
541 }
542 }
543 true
545 }
546
547 pub fn pretty_print_efficiency(&self) -> String {
549 let mut repr = String::from("-- -- -- -- -- -- -- -- -- -- --");
550 repr += &(format!("\n TOTAL EVENTS : {}", self.nevents));
551 repr += &(format!("\n {} <= NHit(UMB) <= {} : {:.2} %", self.min_hit_umb, self.max_hit_umb, 100.0*self.get_acc_frac_hit_umb()));
552 repr += &(format!("\n {} <= NHit(CBE) <= {} : {:.2} %", self.min_hit_cbe, self.max_hit_cbe, 100.0*self.get_acc_frac_hit_cbe()));
553 repr += &(format!("\n {} <= NHit(COR) <= {} : {:.2} %", self.min_hit_cor, self.max_hit_cor, 100.0*self.get_acc_frac_hit_cor()));
554 repr += &(format!("\n {} <= NHit(TOF) <= {} : {:.2} %", self.min_hit_all, self.max_hit_all, 100.0*self.get_acc_frac_hit_all()));
555 repr += &(format!("\n {} <= COS(THET) <= {} : {:.2} %", self.min_cos_theta, self.max_cos_theta, self.get_acc_frac_cos_theta()));
556 if self.only_causal_hits {
557 if self.hits_total > 0 {
558 repr += &(format!("\n Removed {:.2} % of hits due to causality cut!", 100.0*self.hits_rmvd_csl as f64/self.hits_total as f64));
559 }
560 }
561 if self.ls_cleaning_t_err != NO_LIGHTSPEED_CUTS {
562 if self.hits_total > 0 {
563 repr += &(format!("\n Removed {:.2} % of hits due to lightspeed cut!", 100.0*(self.hits_rmvd_ls as f64)/self.hits_total as f64));
564 }
565 }
566 if self.fh_must_be_umb {
567 repr += "\n First hit must be on UMB!";
568 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_fh_must_be_umb()));
569 }
570 if self.thru_going {
571 repr += "\n Require through-going track!";
572 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_thru_going()));
573 }
574 if self.fhi_not_bot {
575 repr += "\n Require first hit on the inner TOF can not be on the Bottom 12PP";
576 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_fhi_not_bot()));
577 }
578 if self.fho_must_panel7 {
579 repr += "\n Require first hit on the outer TOF must be on panel7";
580 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_fho_must_panel7()));
581 }
582 if self.lh_must_panel2 {
583 repr += "\n Require last hit must be on the bottom CBE panel";
584 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_lh_must_panel2()));
585 }
586 if self.hit_high_edep {
587 repr += "\n Require that one hit has an edep > 20MeV";
588 repr += &(format!("\n -- Accepted {:.2} %", 100.0*self.get_acc_frac_hit_high_edep()));
589 }
590 repr += "\n-- -- -- -- -- -- -- -- -- -- --";
591 repr
593 }
594}
595
596impl Default for TofCuts {
597 fn default() -> Self {
598 Self::new()
599 }
600}
601
602impl fmt::Display for TofCuts {
603 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
604 let mut repr = String::from("<TofCuts:");
605 if self.is_void() {
606 repr += " (void)>";
607 } else {
608 if self.only_causal_hits {
609 repr += &(format!("\n -- removes non-causal hits!"));
610 }
611 if self.ls_cleaning_t_err != NO_LIGHTSPEED_CUTS {
613 repr += "\n -- removes hits which are not correlated with the first hit!";
614 repr += &(format!("\n -- assumed timing error {}", self.ls_cleaning_t_err));
615 }
616 if self.fh_must_be_umb {
617 repr += "\n -- first hit must be on UMB";
618 }
619 if self.thru_going {
620 repr += "\n -- require last hit on CBE BOT or COR (thru-going tracks)";
621 }
622 if self.fhi_not_bot {
623 repr += "\n -- require that the first hit on the inner TOF is not on CBE BOT";
624 }
625 if self.fho_must_panel7 {
626 repr += "\n -- require that the first hit on the outer TOF is on panel7";
627 }
628 if self.lh_must_panel2 {
629 repr += "\n -- require that the last hit on the inner TOF is on CBE BOT";
630 }
631 if self.hit_high_edep {
632 repr += "\n -- require that at least one hit has an edep of > 29MeV";
633 }
634 repr += &(format!("\n {} <= NHit(UMB) <= {}", self.min_hit_umb, self.max_hit_umb));
635 repr += &(format!("\n {} <= NHit(CBE) <= {}", self.min_hit_cbe, self.max_hit_cbe));
636 repr += &(format!("\n {} <= NHit(COR) <= {}", self.min_hit_cor, self.max_hit_cor));
637 repr += &(format!("\n {} <= NHit(TOF) <= {}", self.min_hit_all, self.max_hit_all));
638 repr += &(format!("\n {} <= COS(THET) <= {}", self.min_cos_theta, self.max_cos_theta));
639 repr += ">";
640 }
641 write!(f, "{}", repr)
642 }
643}
644
645impl AddAssign for TofCuts {
646 fn add_assign(&mut self, other : Self) {
647 if !self.is_compatible(&other) {
648 panic!("Cuts are not compatible!");
650 }
651 self.nevents += other.nevents;
652 self.hit_cbe_acc += other.hit_cbe_acc;
653 self.hit_umb_acc += other.hit_umb_acc;
654 self.hit_cor_acc += other.hit_cor_acc;
655 self.hit_all_acc += other.hit_all_acc;
656 self.cos_theta_acc += other.cos_theta_acc;
657 self.hits_total += other.hits_total;
658 self.hits_rmvd_csl += other.hits_rmvd_csl;
659 self.hits_rmvd_ls += other.hits_rmvd_ls;
660 self.fh_umb_acc += other.fh_umb_acc;
661 self.thru_going_acc += other.thru_going_acc;
662 self.fhi_not_bot_acc += other.fhi_not_bot_acc;
663 self.fho_must_panel7_acc += other.fho_must_panel7_acc;
664 self.lh_must_panel2_acc += other.lh_must_panel2_acc;
665 self.hit_high_edep_acc += other.hit_high_edep_acc;
666 }
667}
668
669impl Add for TofCuts {
670
671 type Output = TofCuts;
672
673 fn add(self, other: Self) -> Self::Output {
674 let mut output = self.clone();
675 output += other;
676 return output;
677 }
678}
679
680#[cfg(feature="pybindings")]
681#[pymethods]
682impl TofCuts {
683
684 fn copy(&self) -> Self {
687 self.clone()
688 }
689
690 #[pyo3(name="is_compatible")]
691 fn is_compatible_py(&self, other : &Self) -> bool {
692 self.is_compatible(other)
693 }
694
695 #[pyo3(name = "clear_stats")]
696 fn clear_stats_py(&mut self) {
697 self.clear_stats();
698 }
699
700 #[cfg(feature="database")]
701 #[pyo3(name="accept")]
702 fn accept_py(&mut self, event : &mut TofEvent) -> bool {
703 self.accept(event)
704 }
705
706 #[getter]
707 fn get_min_hit_cor (&self) -> u8 {
708 self.min_hit_cor
709 }
710
711 #[setter]
712 fn set_min_hit_cor(&mut self, value : u8) -> PyResult<()> {
713 self.min_hit_cor = value;
714 Ok(())
715 }
716
717 fn __iadd__(&mut self, other : &TofCuts) {
718 self.add_assign(*other);
719 }
720
721 fn __add__(&self, other : &TofCuts) -> TofCuts {
722 let other_c = other.clone();
723 self.add(other_c)
724 }
725
726 #[pyo3(name="to_toml")]
727 fn to_toml_py(&self, filename : String) {
728 self.to_toml(filename);
729 }
730
731 #[staticmethod]
732 #[pyo3(name="from_toml")]
733 fn from_toml_py(filename : String) -> PyResult<Self> {
734 match Self::from_toml(&filename) {
735 Err(err) => {
736 return Err(PyValueError::new_err(err.to_string()));
737 }
738 Ok(cuts_) => {
739 return Ok(cuts_);
740 }
741 }
742 }
743
744 #[getter]
745 fn void(&self) -> bool {
746 self.is_void()
747 }
748
749 #[pyo3(name="pretty_print_efficiency")]
753 fn pretty_print_efficiency_py(&self) -> String {
754 self.pretty_print_efficiency()
755 }
756
757 #[getter]
758 fn get_min_hit_cbe (&self) -> u8 {
759 self.min_hit_cbe
760 }
761
762 #[setter]
763 fn set_min_hit_cbe(&mut self, value : u8) -> PyResult<()> {
764 self.min_hit_cbe = value;
765 Ok(())
766 }
767
768 #[getter]
769 fn get_min_hit_umb (&self) -> u8 {
770 self.min_hit_umb
771 }
772
773 #[setter]
774 fn set_min_hit_umb(&mut self, value : u8) -> PyResult<()> {
775 self.min_hit_umb = value;
776 Ok(())
777 }
778
779 #[getter]
780 fn get_max_hit_cor (&self) -> u8 {
781 self.max_hit_cor
782 }
783
784 #[setter]
785 fn set_max_hit_cor(&mut self, value : u8) -> PyResult<()> {
786 self.max_hit_cor = value;
787 Ok(())
788 }
789
790 #[getter]
791 fn get_max_hit_cbe (&self) -> u8 {
792 self.max_hit_cbe
793 }
794
795 #[setter]
796 fn set_max_hit_cbe(&mut self, value : u8) -> PyResult<()> {
797 self.max_hit_cbe = value;
798 Ok(())
799 }
800
801 #[getter]
802 fn get_max_hit_umb (&self) -> u8 {
803 self.max_hit_umb
804 }
805
806 #[setter]
807 fn set_max_hit_umb(&mut self, value : u8) -> PyResult<()> {
808 self.max_hit_umb = value;
809 Ok(())
810 }
811
812 #[getter]
813 fn get_min_hit_all (&self) -> u8 {
814 self.min_hit_all
815 }
816
817 #[setter]
818 fn set_min_hit_all(&mut self, value : u8) -> PyResult<()> {
819 self.min_hit_all = value;
820 Ok(())
821 }
822
823 #[getter]
824 fn get_max_hit_all (&self) -> u8 {
825 self.max_hit_all
826 }
827
828 #[setter]
829 fn set_max_hit_all(&mut self, value : u8) -> PyResult<()> {
830 self.max_hit_all = value;
831 Ok(())
832 }
833
834 #[getter]
835 fn get_min_cos_theta (&self) -> f32 {
836 self.min_cos_theta
837 }
838
839 #[setter]
840 fn set_min_cos_theta(&mut self, value : f32) -> PyResult<()> {
841 self.min_cos_theta = value;
842 Ok(())
843 }
844
845 #[getter]
846 fn get_max_cos_theta (&self) -> f32 {
847 self.max_cos_theta
848 }
849
850 #[setter]
851 fn set_max_cos_theta(&mut self, value : f32) -> PyResult<()> {
852 self.max_cos_theta = value;
853 Ok(())
854 }
855
856 #[getter]
857 fn get_only_causal_hits (&self) -> bool {
858 self.only_causal_hits
859 }
860
861 #[setter]
862 fn set_only_causal_hits(&mut self, value : bool) -> PyResult<()> {
863 self.only_causal_hits = value;
864 Ok(())
865 }
866
867 #[getter]
868 fn get_hit_cbe_acc (&self) -> u64 {
869 self.hit_cbe_acc
870 }
871
872 #[getter]
873 fn get_hit_umb_acc (&self) -> u64 {
874 self.hit_umb_acc
875 }
876
877 #[getter]
878 fn get_hit_cor_acc (&self) -> u64 {
879 self.hit_cor_acc
880 }
881
882 #[getter]
883 fn get_hit_all_acc (&self) -> u64 {
884 self.hit_all_acc
885 }
886
887 #[getter]
888 fn get_cos_theta_acc (&self) -> u64 {
889 self.cos_theta_acc
890 }
891
892 #[getter]
893 fn get_nevents (&self) -> u64 {
894 self.nevents
895 }
896
897 #[getter]
898 fn get_hits_total (&self) -> u64 {
899 self.hits_total
900 }
901
902 #[getter]
903 fn get_hits_rmvd_csl (&self) -> u64 {
904 self.hits_rmvd_csl
905 }
906
907 #[getter]
908 fn get_hits_rmvd_ls (&self) -> u64 {
909 self.hits_rmvd_ls
910 }
911
912 #[getter]
913 fn get_fh_must_be_umb (&self) -> bool {
914 self.fh_must_be_umb
915 }
916
917 #[setter]
918 fn set_fh_must_be_umb(&mut self, value : bool) -> PyResult<()> {
919 self.fh_must_be_umb = value;
920 Ok(())
921 }
922
923 #[getter]
924 fn get_fh_umb_acc (&self) -> u64 {
925 self.fh_umb_acc
926 }
927
928 #[getter]
929 fn get_ls_cleaning_t_err (&self) -> f64 {
930 self.ls_cleaning_t_err
931 }
932
933 #[setter]
934 fn set_ls_cleaning_t_err(&mut self, value : f64) -> PyResult<()> {
935 self.ls_cleaning_t_err = value;
936 Ok(())
937 }
938
939 #[getter]
940 fn get_thru_going (&self) -> bool {
941 self.thru_going
942 }
943
944 #[setter]
945 fn set_thru_going(&mut self, value : bool) -> PyResult<()> {
946 self.thru_going = value;
947 Ok(())
948 }
949
950 #[getter]
951 fn get_thru_going_acc (&self) -> u64 {
952 self.thru_going_acc
953 }
954
955 #[getter]
956 fn get_fhi_not_bot (&self) -> bool {
957 self.fhi_not_bot
958 }
959
960 #[setter]
961 fn set_fhi_not_bot(&mut self, value : bool) -> PyResult<()> {
962 self.fhi_not_bot = value;
963 Ok(())
964 }
965
966 #[getter]
967 fn get_fhi_not_bot_acc (&self) -> u64 {
968 self.fhi_not_bot_acc
969 }
970
971 #[getter]
972 fn get_fho_must_panel7 (&self) -> bool {
973 self.fho_must_panel7
974 }
975
976 #[setter]
977 fn set_fho_must_panel7(&mut self, value : bool) -> PyResult<()> {
978 self.fho_must_panel7 = value;
979 Ok(())
980 }
981
982 #[getter]
983 fn get_fho_must_panel7_acc(&self) -> u64 {
984 self.fho_must_panel7_acc
985 }
986
987 #[getter]
988 fn get_lh_must_panel2 (&self) -> bool {
989 self.lh_must_panel2
990 }
991
992 #[setter]
993 fn set_lh_must_panel2(&mut self, value : bool) -> PyResult<()> {
994 self.lh_must_panel2 = value;
995 Ok(())
996 }
997
998 #[getter]
999 fn get_lh_must_panel2_acc (&self) -> u64 {
1000 self.lh_must_panel2_acc
1001 }
1002
1003 #[getter]
1004 fn get_hit_high_edep (&self) -> bool {
1005 self.hit_high_edep
1006 }
1007
1008 #[setter]
1009 fn set_hit_high_edep(&mut self, value : bool) -> PyResult<()> {
1010 self.hit_high_edep = value;
1011 Ok(())
1012 }
1013
1014 #[getter]
1015 #[pyo3(name="acc_frac_hit_umb")]
1016 fn get_acc_frac_hit_umb_py(&self) -> f64 {
1017 self.get_acc_frac_hit_umb()
1018 }
1019
1020 #[getter]
1021 #[pyo3(name="acc_frac_hit_cbe")]
1022 fn get_acc_frac_hit_cbe_py(&self) -> f64 {
1023 self.get_acc_frac_hit_cbe()
1024 }
1025
1026 #[getter]
1027 #[pyo3(name="acc_frac_hit_cor")]
1028 fn get_acc_frac_hit_cor_py(&self) -> f64 {
1029 self.get_acc_frac_hit_cor()
1030 }
1031
1032 #[getter]
1033 #[pyo3(name="acc_frac_hit_all")]
1034 fn get_acc_frac_hit_all_py(&self) -> f64 {
1035 self.get_acc_frac_hit_all()
1036 }
1037
1038 #[getter]
1039 #[pyo3(name="acc_frac_cos_theta")]
1040 fn get_acc_frac_cos_theta_py(&self) -> f64 {
1041 self.get_acc_frac_cos_theta()
1042 }
1043
1044 #[getter]
1045 #[pyo3(name="acc_frac_fh_must_be_umb")]
1046 fn get_acc_frac_fh_must_be_umb_py(&self) -> f64 {
1047 self.get_acc_frac_fh_must_be_umb()
1048 }
1049
1050 #[getter]
1051 #[pyo3(name="get_frac_thru_going")]
1052 fn get_acc_frac_thru_going_py(&self) -> f64 {
1053 self.get_acc_frac_thru_going()
1054 }
1055
1056 #[getter]
1057 #[pyo3(name="acc_frac_fhi_not_bot")]
1058 fn get_acc_frac_fhi_not_bot_py(&self) -> f64 {
1059 self.get_acc_frac_fhi_not_bot()
1060 }
1061
1062 #[getter]
1063 #[pyo3(name="acc_frac_fho_must_panel7")]
1064 fn get_acc_frac_fho_must_panel7_py(&self) -> f64 {
1065 self.get_acc_frac_fho_must_panel7()
1066 }
1067
1068 #[getter]
1069 #[pyo3(name="acc_frac_lh_must_panel2")]
1070 fn get_acc_frac_lh_must_panel2_py(&self) -> f64 {
1071 self.get_acc_frac_lh_must_panel2()
1072 }
1073
1074 #[getter]
1075 fn get_hit_high_edep_acc (&self) -> u64 {
1076 self.hit_high_edep_acc
1077 }
1078}
1079
1080#[cfg(feature="pybindings")]
1081pythonize!(TofCuts);
1082