Line | Branch | Exec | Source |
---|---|---|---|
1 | #pragma once | ||
2 | |||
3 | #include "iguana/algorithms/Algorithm.h" | ||
4 | |||
5 | namespace iguana::clas12 { | ||
6 | |||
7 | /// @brief_algo Filter the `REC::Particle` bank using subsystem-specific fiducial cuts | ||
8 | /// | ||
9 | /// RGA fiducial filter: | ||
10 | /// | ||
11 | /// - PCal-only edge cuts on lv & lw with strictness thresholds | ||
12 | /// - Forward Tagger annulus + low efficiency hole vetoes | ||
13 | /// - Central detector (CVT) fiducial: | ||
14 | /// - require edge > edge_min (default 0) and vetoes on gaps between CVT sectors | ||
15 | /// - Drift Chamber (DC) fiducial: | ||
16 | /// - three region edge thresholds with separate inbending/outbending track logic | ||
17 | /// | ||
18 | /// @begin_doc_algo{clas12::RGAFiducialFilter | Filter} | ||
19 | /// @input_banks{REC::Particle, RUN::config, REC::Calorimeter, REC::ForwardTagger, REC::Traj} | ||
20 | /// @output_banks{REC::Particle} | ||
21 | /// @end_doc | ||
22 | /// | ||
23 | /// @begin_doc_config{clas12/RGAFiducialFilter} | ||
24 | /// @config_param{calorimeter.strictness | int | calorimeter cut strictness} | ||
25 | /// @config_param{forward_tagger.radius | list[double] | FT allowed radial window (cm)} | ||
26 | /// @config_param{forward_tagger.holes_flat | list[double] | FT circular holes (radius, x, y)} | ||
27 | /// @config_param{cvt.edge_layers | list[int] | layers to apply the edge>edge_min test to (all); missing layers are treated as pass} | ||
28 | /// @config_param{cvt.edge_min | double | edge > 0 to ensure tracks inside CVT} | ||
29 | /// @config_param{cvt.phi_forbidden_deg | list[double] | forbidden phi wedges in degrees (open intervals)} | ||
30 | /// @config_param{dc.theta_small_deg | double | theta boundary (degrees) for the special inbending case} | ||
31 | /// @config_param{dc.thresholds_out | list[double] | outbending thresholds [Region1, Region2, Region3] (cm)} | ||
32 | /// @config_param{dc.thresholds_in_smallTheta | list[double] | inbending thresholds when theta < theta_small_deg (cm)} | ||
33 | /// @config_param{dc.thresholds_in_largeTheta | list[double] | inbending thresholds when theta >= theta_small_deg (cm)} | ||
34 | /// @end_doc | ||
35 | class RGAFiducialFilter : public Algorithm { | ||
36 |
6/14✓ Branch 0 (2→3) taken 2 times.
✗ Branch 1 (2→6) not taken.
✗ Branch 2 (5→7) not taken.
✓ Branch 3 (5→8) taken 2 times.
✓ Branch 4 (9→10) taken 2 times.
✗ Branch 5 (9→32) not taken.
✓ Branch 6 (10→11) taken 2 times.
✗ Branch 7 (10→17) not taken.
✓ Branch 8 (17→18) taken 2 times.
✗ Branch 9 (17→40) not taken.
✓ Branch 10 (24→25) taken 2 times.
✗ Branch 11 (24→40) not taken.
✗ Branch 12 (32→33) not taken.
✗ Branch 13 (32→39) not taken.
|
18 | DEFINE_IGUANA_ALGORITHM(RGAFiducialFilter, clas12::RGAFiducialFilter) |
37 | |||
38 | private: | ||
39 | 2 | struct FTParams { | |
40 | float rmin = 0; | ||
41 | float rmax = 0; | ||
42 | std::vector<std::array<float,3>> holes; // {R,cx,cy} | ||
43 | }; | ||
44 | struct CVTParams { | ||
45 | std::vector<int> edge_layers; // e.g. {1,3,5,7,12} | ||
46 | double edge_min = 0.0; // > edge_min | ||
47 | std::vector<double> phi_forbidden_deg; | ||
48 | }; | ||
49 | struct DCParams { | ||
50 | // thresholds (cm) | ||
51 | double theta_small_deg = 10.0; // tighter boundary for inbending | ||
52 | // inbending, theta < theta_small_deg | ||
53 | double in_small_e1 = 10.0, in_small_e2 = 10.0, in_small_e3 = 10.0; | ||
54 | // inbending, theta >= theta_small_deg | ||
55 | double in_large_e1 = 3.0, in_large_e2 = 3.0, in_large_e3 = 10.0; | ||
56 | // outbending (any theta) | ||
57 | double out_e1 = 3.0, out_e2 = 3.0, out_e3 = 10.0; | ||
58 | }; | ||
59 | |||
60 | public: | ||
61 | // algorithm API | ||
62 | void Start(hipo::banklist& banks) override; | ||
63 | void Run (hipo::banklist& banks) const override; | ||
64 | 1 | void Stop () override {} | |
65 | |||
66 | /// @returns calorimeter strictness | ||
67 | int CalStrictness() const { return m_cal_strictness; } | ||
68 | /// @returns FT configuration parameters | ||
69 | const FTParams& FT() const { return u_ft_params; } | ||
70 | /// @returns CVT configuration parameters | ||
71 | const CVTParams& CVT() const { return m_cvt; } | ||
72 | /// @returns DC configuration parameters | ||
73 | const DCParams& DC() const { return m_dc; } | ||
74 | |||
75 | private: | ||
76 | // bank indices and presence flags | ||
77 | hipo::banklist::size_type b_particle{}; | ||
78 | hipo::banklist::size_type b_config{}; | ||
79 | hipo::banklist::size_type b_calor{}; | ||
80 | hipo::banklist::size_type b_ft{}; | ||
81 | hipo::banklist::size_type b_traj{}; | ||
82 | bool m_have_calor = false; | ||
83 | bool m_have_ft = false; | ||
84 | bool m_have_traj = false; | ||
85 | |||
86 | // FT params (loaded from YAML) | ||
87 | FTParams u_ft_params{}; | ||
88 | |||
89 | // core filter functions | ||
90 | struct CalHit { int sector=0; float lv=0, lw=0, lu=0; }; | ||
91 | 1662 | struct CalLayers { std::vector<CalHit> L1; bool has_any=false; }; | |
92 | |||
93 | static CalLayers CollectCalHitsForTrack(const hipo::bank& cal, int pindex); | ||
94 | static bool PassCalStrictness(const CalLayers& h, int strictness); | ||
95 | bool PassFTFiducial (int track_index, const hipo::bank* ftBank) const; | ||
96 | bool PassCVTFiducial(int track_index, const hipo::bank* trajBank) const; | ||
97 | bool PassDCFiducial(int track_index, const hipo::bank& particleBank, | ||
98 | const hipo::bank& configBank, const hipo::bank* trajBank) const; | ||
99 | bool Filter(int track_index, const hipo::bank& particleBank, const hipo::bank& configBank, | ||
100 | const hipo::bank* calBank, const hipo::bank* ftBank, const hipo::bank* trajBank) const; | ||
101 | |||
102 | // ---- Config loading | ||
103 | void LoadConfig(); | ||
104 | |||
105 | // CVT/DC params; | ||
106 | int m_cal_strictness = 1; | ||
107 | CVTParams m_cvt{}; | ||
108 | DCParams m_dc{}; | ||
109 | }; | ||
110 | |||
111 | } | ||
112 |