GCC Code Coverage Report


Directory: ./
File: src/iguana/algorithms/clas12/rga/FiducialFilterPass2/Algorithm.h
Date: 2025-11-25 17:57:04
Coverage Exec Excl Total
Lines: 100.0% 7 0 7
Functions: 100.0% 4 0 4
Branches: 42.9% 6 0 14

Line Branch Exec Source
1 #pragma once
2
3 #include "iguana/algorithms/Algorithm.h"
4
5 namespace iguana::clas12::rga {
6
7 /// @algo_brief{Filter the `REC::Particle` bank using subsystem-specific fiducial cuts}
8 /// @algo_type_filter
9 ///
10 /// RGA fiducial filter:
11 ///
12 /// - PCal-only edge cuts on lv & lw with strictness thresholds
13 /// - Forward Tagger annulus + low efficiency hole vetoes
14 /// - Central detector (CVT) fiducial:
15 /// - require edge > edge_min (default 0) and vetoes on gaps between CVT sectors
16 /// - Drift Chamber (DC) fiducial:
17 /// - three region edge thresholds with separate inbending/outbending track logic
18 ///
19 /// **References:**
20 ///
21 /// - https://clas12-docdb.jlab.org/DocDB/0012/001240/001/rga_fiducial_cuts.pdf
22 ///
23 /// **NOTE:** this algorithm has multiple `Run(hipo::bank bank1, ...)` functions, which
24 /// take `hipo::bank` parameters, and some parameters may be optional, since you may
25 /// be reading data which lack certain banks. If you use these functions, take a look at all them
26 /// to decide which one best suits your use case.
27 ///
28 /// @begin_doc_config{clas12/rga/FiducialFilterPass2}
29 /// @config_param{calorimeter.strictness | int | calorimeter cut strictness}
30 /// @config_param{forward_tagger.radius | list[double] | FT allowed radial window (cm)}
31 /// @config_param{forward_tagger.holes_flat | list[double] | FT circular holes (radius, x, y)}
32 /// @config_param{cvt.edge_layers | list[int] | layers to apply the edge>edge_min test to (all); missing layers are treated as pass}
33 /// @config_param{cvt.edge_min | double | edge > 0 to ensure tracks inside CVT}
34 /// @config_param{cvt.phi_forbidden_deg | list[double] | forbidden phi wedges in degrees (open intervals)}
35 /// @config_param{dc.theta_small_deg | double | theta boundary (degrees) for the special inbending case}
36 /// @config_param{dc.thresholds_out | list[double] | outbending thresholds [Region1, Region2, Region3] (cm)}
37 /// @config_param{dc.thresholds_in_smallTheta | list[double] | inbending thresholds when theta < theta_small_deg (cm)}
38 /// @config_param{dc.thresholds_in_largeTheta | list[double] | inbending thresholds when theta >= theta_small_deg (cm)}
39 /// @end_doc
40 class FiducialFilterPass2 : public Algorithm
41 {
42
6/14
✓ Branch 2 → 3 taken 2 times.
✗ Branch 2 → 6 not taken.
✗ Branch 5 → 7 not taken.
✓ Branch 5 → 8 taken 2 times.
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 32 not taken.
✓ Branch 10 → 11 taken 2 times.
✗ Branch 10 → 17 not taken.
✓ Branch 17 → 18 taken 2 times.
✗ Branch 17 → 40 not taken.
✓ Branch 24 → 25 taken 2 times.
✗ Branch 24 → 40 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 39 not taken.
18 DEFINE_IGUANA_ALGORITHM(FiducialFilterPass2, clas12::rga::FiducialFilterPass2)
43
44 private:
45 2 struct FTParams {
46 float rmin = 0;
47 float rmax = 0;
48 std::vector<std::array<float, 3>> holes; // {R,cx,cy}
49 };
50 struct CVTParams {
51 std::vector<int> edge_layers; // e.g. {1,3,5,7,12}
52 double edge_min = 0.0; // > edge_min
53 std::vector<double> phi_forbidden_deg;
54 };
55 struct DCParams {
56 // thresholds (cm)
57 double theta_small_deg = 10.0; // tighter boundary for inbending
58 // inbending, theta < theta_small_deg
59 double in_small_e1 = 10.0, in_small_e2 = 10.0, in_small_e3 = 10.0;
60 // inbending, theta >= theta_small_deg
61 double in_large_e1 = 3.0, in_large_e2 = 3.0, in_large_e3 = 10.0;
62 // outbending (any theta)
63 double out_e1 = 3.0, out_e2 = 3.0, out_e3 = 10.0;
64 };
65
66 public:
67
68 void Start(hipo::banklist& banks) override;
69 bool Run(hipo::banklist& banks) const override;
70 1 void Stop() override {}
71
72 /// @run_function
73 /// @param [in,out] particle `REC::Particle` bank, which will be filtered
74 /// @param [in] conf `RUN::config` bank
75 /// @param [in] cal pointer to `REC::Calorimeter` bank; it is a _pointer_ since it is _optional_ (use `nullptr` for "unused")
76 /// @param [in] traj pointer to `REC::Traj` bank; it is a _pointer_ since it is _optional_ (use `nullptr` for "unused")
77 /// @param [in] ft pointer to `REC::ForwardTagger` bank; it is a _pointer_ since it is _optional_ (use `nullptr` for "unused")
78 /// @returns `false` if all particles are filtered out
79 bool Run(
80 hipo::bank& particle,
81 hipo::bank const& conf,
82 hipo::bank const* cal,
83 hipo::bank const* traj,
84 hipo::bank const* ft) const;
85
86 /// @run_function
87 /// @param [in,out] particle `REC::Particle` bank, which will be filtered
88 /// @param [in] conf `RUN::config` bank
89 /// @param [in] cal `REC::Calorimeter` bank
90 /// @param [in] traj `REC::Traj` bank
91 /// @returns `false` if all particles are filtered out
92 bool Run(
93 hipo::bank& particle,
94 hipo::bank const& conf,
95 hipo::bank const& cal,
96 hipo::bank const& traj) const
97 {
98 return Run(particle, conf, &cal, &traj, nullptr);
99 }
100
101 /// @run_function
102 /// @param [in,out] particle `REC::Particle` bank, which will be filtered
103 /// @param [in] conf `RUN::config` bank
104 /// @param [in] cal `REC::Calorimeter` bank
105 /// @param [in] traj `REC::Traj` bank
106 /// @param [in] ft `REC::ForwardTagger` bank
107 /// @returns `false` if all particles are filtered out
108 bool Run(
109 hipo::bank& particle,
110 hipo::bank const& conf,
111 hipo::bank const& cal,
112 hipo::bank const& traj,
113 hipo::bank const& ft) const
114 {
115 return Run(particle, conf, &cal, &traj, &ft);
116 }
117
118 /// @returns calorimeter strictness
119 int CalStrictness() const { return m_cal_strictness; }
120 /// @returns FT configuration parameters
121 FTParams const& FT() const { return u_ft_params; }
122 /// @returns CVT configuration parameters
123 CVTParams const& CVT() const { return m_cvt; }
124 /// @returns DC configuration parameters
125 DCParams const& DC() const { return m_dc; }
126
127 private:
128 // bank indices and presence flags
129 hipo::banklist::size_type b_particle{};
130 hipo::banklist::size_type b_config{};
131 hipo::banklist::size_type b_calor{};
132 hipo::banklist::size_type b_ft{};
133 hipo::banklist::size_type b_traj{};
134 bool m_have_calor = false;
135 bool m_have_ft = false;
136 bool m_have_traj = false;
137
138 // FT params (loaded from YAML)
139 FTParams u_ft_params{};
140
141 // core filter functions
142 struct CalHit {
143 int sector = 0;
144 float lv = 0, lw = 0, lu = 0;
145 };
146 1662 struct CalLayers {
147 std::vector<CalHit> L1;
148 bool has_any = false;
149 };
150
151 static CalLayers CollectCalHitsForTrack(hipo::bank const& cal, int pindex);
152 static bool PassCalStrictness(CalLayers const& h, int strictness);
153 bool PassFTFiducial(int track_index, hipo::bank const* ftBank) const;
154 bool PassCVTFiducial(int track_index, hipo::bank const* trajBank) const;
155 bool PassDCFiducial(int track_index, hipo::bank const& particleBank,
156 hipo::bank const& configBank, hipo::bank const* trajBank) const;
157 bool Filter(int track_index, hipo::bank const& particleBank, hipo::bank const& configBank,
158 hipo::bank const* calBank, hipo::bank const* trajBank, hipo::bank const* ftBank) const;
159
160 // ---- Config loading
161 void LoadConfig();
162
163 // CVT/DC params;
164 int m_cal_strictness = 1;
165 CVTParams m_cvt{};
166 DCParams m_dc{};
167 };
168
169 }
170