GCC Code Coverage Report


Directory: ./
File: src/iguana/algorithms/clas12/RGAFiducialFilter/Algorithm.cc
Date: 2025-10-15 15:39:33
Exec Total Coverage
Lines: 165 201 82.1%
Functions: 13 14 92.9%
Branches: 243 440 55.2%

Line Branch Exec Source
1 #include "Algorithm.h"
2 #include "TypeDefs.h"
3
4 namespace iguana::clas12 {
5
6 REGISTER_IGUANA_ALGORITHM(RGAFiducialFilter, "clas12::RGAFiducialFilter");
7
8 6 static bool banklist_has(hipo::banklist& banks, const char* name) {
9
6/6
✓ Branch 0 (6→7) taken 16 times.
✓ Branch 1 (6→9) taken 5 times.
✓ Branch 2 (11→12) taken 19 times.
✓ Branch 3 (11→14) taken 2 times.
✓ Branch 4 (13→3) taken 21 times.
✓ Branch 5 (13→14) taken 4 times.
67 for (auto& b : banks) if (b.getSchema().getName() == name) return true;
10 return false;
11 }
12
13 27972 static bool traj_has_detector(const hipo::bank* trajBank, int pindex, int detector) {
14
2/2
✓ Branch 0 (2→3) taken 13986 times.
✓ Branch 1 (2→4) taken 13986 times.
27972 if (!trajBank) return false;
15 const auto& traj = *trajBank;
16 const int n = traj.getRows();
17
2/2
✓ Branch 0 (10→3) taken 11191 times.
✓ Branch 1 (10→5) taken 548979 times.
560170 for (int i=0; i<n; ++i) {
18
4/4
✓ Branch 0 (6→7) taken 53686 times.
✓ Branch 1 (6→9) taken 495293 times.
✓ Branch 2 (8→9) taken 50891 times.
✓ Branch 3 (8→11) taken 2795 times.
548979 if (traj.getInt("pindex", i) == pindex && traj.getInt("detector", i) == detector) {
19 return true;
20 }
21 }
22 return false;
23 }
24
25 2 void RGAFiducialFilter::LoadConfig() {
26
7/14
✓ Branch 0 (2→3) taken 2 times.
✗ Branch 1 (2→203) not taken.
✓ Branch 2 (4→5) taken 2 times.
✗ Branch 3 (4→198) not taken.
✓ Branch 4 (5→6) taken 2 times.
✗ Branch 5 (5→196) not taken.
✓ Branch 6 (6→7) taken 2 times.
✗ Branch 7 (6→190) not taken.
✗ Branch 8 (7→8) not taken.
✓ Branch 9 (7→10) taken 2 times.
✓ Branch 10 (14→15) taken 4 times.
✓ Branch 11 (14→17) taken 2 times.
✗ Branch 12 (199→200) not taken.
✗ Branch 13 (199→202) not taken.
10 m_cal_strictness = GetOptionScalar<int>("calorimeter.strictness", {"calorimeter", "strictness"});
27
1/2
✗ Branch 0 (17→18) not taken.
✓ Branch 1 (17→21) taken 2 times.
2 if (m_cal_strictness < 1 || m_cal_strictness > 3) {
28 throw std::runtime_error("[RGAFID] 'calorimeter.strictness' must be 1, 2, or 3");
29 }
30
31 {
32
6/12
✓ Branch 0 (23→24) taken 2 times.
✗ Branch 1 (23→218) not taken.
✓ Branch 2 (24→25) taken 2 times.
✗ Branch 3 (24→216) not taken.
✓ Branch 4 (25→26) taken 2 times.
✗ Branch 5 (25→210) not taken.
✓ Branch 6 (33→34) taken 4 times.
✓ Branch 7 (33→36) taken 2 times.
✗ Branch 8 (36→37) not taken.
✓ Branch 9 (36→38) taken 2 times.
✗ Branch 10 (219→220) not taken.
✗ Branch 11 (219→222) not taken.
8 auto radius = GetOptionVector<double>("forward_tagger.radius", {"forward_tagger","radius"});
33
1/2
✗ Branch 0 (38→39) not taken.
✓ Branch 1 (38→42) taken 2 times.
2 if (radius.size() != 2) {
34 throw std::runtime_error("[RGAFID] 'forward_tagger.radius' must be [rmin, rmax]");
35 }
36
1/2
✗ Branch 0 (44→45) not taken.
✓ Branch 1 (44→46) taken 2 times.
2 u_ft_params.rmin = static_cast<float>(radius[0]);
37
1/2
✓ Branch 0 (46→47) taken 2 times.
✗ Branch 1 (46→50) not taken.
2 u_ft_params.rmax = static_cast<float>(radius[1]);
38
3/6
✓ Branch 0 (46→47) taken 2 times.
✗ Branch 1 (46→50) not taken.
✓ Branch 2 (47→48) taken 2 times.
✗ Branch 3 (47→50) not taken.
✓ Branch 4 (48→49) taken 2 times.
✗ Branch 5 (48→50) not taken.
2 if (!(std::isfinite(u_ft_params.rmin) && std::isfinite(u_ft_params.rmax)) ||
39
1/2
✗ Branch 0 (49→50) not taken.
✓ Branch 1 (49→52) taken 2 times.
2 !(u_ft_params.rmin > 0.f && u_ft_params.rmax > u_ft_params.rmin)) {
40 throw std::runtime_error("[RGAFID] invalid forward_tagger.radius values");
41 }
42
43 u_ft_params.holes.clear();
44 std::vector<double> holes_flat;
45 try {
46
5/10
✓ Branch 0 (57→58) taken 2 times.
✗ Branch 1 (57→240) not taken.
✓ Branch 2 (58→59) taken 2 times.
✗ Branch 3 (58→238) not taken.
✓ Branch 4 (59→60) taken 2 times.
✗ Branch 5 (59→232) not taken.
✓ Branch 6 (71→72) taken 4 times.
✓ Branch 7 (71→74) taken 2 times.
✗ Branch 8 (241→242) not taken.
✗ Branch 9 (241→244) not taken.
8 holes_flat = GetOptionVector<double>("forward_tagger.holes_flat",
47 {"forward_tagger","holes_flat"});
48 } catch (const std::exception& e) {
49 const std::string msg = e.what();
50 if (msg.find("not found") == std::string::npos &&
51 msg.find("missing") == std::string::npos) {
52 throw;
53 }
54 holes_flat.clear();
55 }
56
57
2/4
✓ Branch 0 (75→76) taken 2 times.
✗ Branch 1 (75→79) not taken.
✓ Branch 2 (78→79) taken 2 times.
✗ Branch 3 (78→80) not taken.
4 if (!holes_flat.empty() && (holes_flat.size() % 3) != 0) {
58 throw std::runtime_error("[RGAFID] 'forward_tagger.holes_flat' must have 3N values");
59 }
60
2/4
✗ Branch 0 (79→83) not taken.
✓ Branch 1 (79→84) taken 2 times.
✓ Branch 2 (84→97) taken 2 times.
✗ Branch 3 (84→276) not taken.
2 u_ft_params.holes.reserve(holes_flat.size() / 3);
61
2/2
✓ Branch 0 (97→85) taken 8 times.
✓ Branch 1 (97→98) taken 2 times.
10 for (std::size_t i = 0; i + 2 < holes_flat.size(); i += 3) {
62 8 const float R = static_cast<float>(holes_flat[i + 0]);
63 8 const float cx = static_cast<float>(holes_flat[i + 1]);
64
1/2
✓ Branch 0 (88→89) taken 8 times.
✗ Branch 1 (88→93) not taken.
8 const float cy = static_cast<float>(holes_flat[i + 2]);
65
4/8
✓ Branch 0 (88→89) taken 8 times.
✗ Branch 1 (88→93) not taken.
✓ Branch 2 (89→90) taken 8 times.
✗ Branch 3 (89→93) not taken.
✓ Branch 4 (90→91) taken 8 times.
✗ Branch 5 (90→93) not taken.
✓ Branch 6 (91→92) taken 8 times.
✗ Branch 7 (91→93) not taken.
8 if (!(std::isfinite(R) && std::isfinite(cx) && std::isfinite(cy)) || R <= 0.f) {
66 throw std::runtime_error("[RGAFID] invalid FT hole triple in 'holes_flat'");
67 }
68
1/4
✓ Branch 0 (92→96) taken 8 times.
✗ Branch 1 (92→276) not taken.
✗ Branch 2 (276→277) not taken.
✗ Branch 3 (276→279) not taken.
8 u_ft_params.holes.push_back({R, cx, cy});
69 }
70 }
71
72 {
73
6/12
✓ Branch 0 (106→107) taken 2 times.
✗ Branch 1 (106→292) not taken.
✓ Branch 2 (107→108) taken 2 times.
✗ Branch 3 (107→290) not taken.
✓ Branch 4 (108→109) taken 2 times.
✗ Branch 5 (108→284) not taken.
✓ Branch 6 (120→121) taken 4 times.
✓ Branch 7 (120→123) taken 2 times.
✗ Branch 8 (123→124) not taken.
✓ Branch 9 (123→127) taken 2 times.
✗ Branch 10 (293→294) not taken.
✗ Branch 11 (293→296) not taken.
8 m_cvt.edge_layers = GetOptionVector<int>("cvt.edge_layers", {"cvt","edge_layers"});
74
1/2
✗ Branch 0 (123→124) not taken.
✓ Branch 1 (123→127) taken 2 times.
2 if (m_cvt.edge_layers.empty()) {
75 throw std::runtime_error("[RGAFID] 'cvt.edge_layers' must be non-empty");
76 }
77
7/14
✓ Branch 0 (129→130) taken 2 times.
✗ Branch 1 (129→312) not taken.
✓ Branch 2 (130→131) taken 2 times.
✗ Branch 3 (130→310) not taken.
✓ Branch 4 (131→132) taken 2 times.
✗ Branch 5 (131→304) not taken.
✓ Branch 6 (132→133) taken 2 times.
✗ Branch 7 (132→135) not taken.
✓ Branch 8 (139→140) taken 4 times.
✓ Branch 9 (139→142) taken 2 times.
✗ Branch 10 (142→143) not taken.
✓ Branch 11 (142→144) taken 2 times.
✗ Branch 12 (313→314) not taken.
✗ Branch 13 (313→316) not taken.
8 m_cvt.edge_min = GetOptionScalar<double>("cvt.edge_min", {"cvt","edge_min"});
78
79 m_cvt.phi_forbidden_deg.clear();
80 try {
81
5/10
✓ Branch 0 (146→147) taken 2 times.
✗ Branch 1 (146→330) not taken.
✓ Branch 2 (147→148) taken 2 times.
✗ Branch 3 (147→328) not taken.
✓ Branch 4 (148→149) taken 2 times.
✗ Branch 5 (148→322) not taken.
✓ Branch 6 (160→161) taken 4 times.
✓ Branch 7 (160→163) taken 2 times.
✗ Branch 8 (331→332) not taken.
✗ Branch 9 (331→334) not taken.
8 m_cvt.phi_forbidden_deg = GetOptionVector<double>("cvt.phi_forbidden_deg",
82 2 {"cvt","phi_forbidden_deg"});
83 } catch (const std::exception& e) {
84 const std::string msg = e.what();
85 if (msg.find("not found") == std::string::npos &&
86 msg.find("missing") == std::string::npos) {
87 throw;
88 }
89 m_cvt.phi_forbidden_deg.clear();
90 }
91
2/4
✓ Branch 0 (164→165) taken 2 times.
✗ Branch 1 (164→168) not taken.
✓ Branch 2 (167→168) taken 2 times.
✗ Branch 3 (167→169) not taken.
4 if (!m_cvt.phi_forbidden_deg.empty() && (m_cvt.phi_forbidden_deg.size() % 2) != 0) {
92 throw std::runtime_error("[RGAFID] 'cvt.phi_forbidden_deg' must have pairs (2N values)");
93 }
94 }
95
96 {
97
1/2
✗ Branch 0 (176→177) not taken.
✓ Branch 1 (176→179) taken 2 times.
2 m_dc.theta_small_deg =
98
5/10
✓ Branch 0 (173→174) taken 2 times.
✗ Branch 1 (173→374) not taken.
✓ Branch 2 (174→175) taken 2 times.
✗ Branch 3 (174→372) not taken.
✓ Branch 4 (175→176) taken 2 times.
✗ Branch 5 (175→366) not taken.
✓ Branch 6 (183→184) taken 4 times.
✓ Branch 7 (183→186) taken 2 times.
✗ Branch 8 (375→376) not taken.
✗ Branch 9 (375→378) not taken.
8 GetOptionScalar<double>("dc.theta_small_deg", {"dc","theta_small_deg"});
99
100 6 auto need3 = [&](const char* key) -> std::array<double,3> {
101
7/14
✓ Branch 0 (2→3) taken 6 times.
✗ Branch 1 (2→77) not taken.
✓ Branch 2 (4→5) taken 6 times.
✗ Branch 3 (4→72) not taken.
✓ Branch 4 (5→6) taken 6 times.
✗ Branch 5 (5→70) not taken.
✓ Branch 6 (8→9) taken 6 times.
✗ Branch 7 (8→58) not taken.
✓ Branch 8 (21→22) taken 12 times.
✓ Branch 9 (21→24) taken 6 times.
✗ Branch 10 (24→25) not taken.
✓ Branch 11 (24→26) taken 6 times.
✗ Branch 12 (73→74) not taken.
✗ Branch 13 (73→76) not taken.
36 auto v = GetOptionVector<double>(std::string("dc.")+key, {"dc", key});
102
1/2
✗ Branch 0 (26→27) not taken.
✓ Branch 1 (26→50) taken 6 times.
6 if (v.size() != 3) {
103 throw std::runtime_error(std::string("[RGAFID] 'dc.") + key + "' must be [e1,e2,e3]");
104 }
105
2/4
✗ Branch 0 (52→53) not taken.
✓ Branch 1 (52→54) taken 6 times.
✗ Branch 2 (54→55) not taken.
✓ Branch 3 (54→56) taken 6 times.
6 return {v[0], v[1], v[2]};
106 };
107
108 2 auto out = need3("thresholds_out");
109 2 auto in_s = need3("thresholds_in_smallTheta");
110 2 auto in_l = need3("thresholds_in_largeTheta");
111
112 2 m_dc.out_e1 = out[0]; m_dc.out_e2 = out[1]; m_dc.out_e3 = out[2];
113 2 m_dc.in_small_e1 = in_s[0]; m_dc.in_small_e2 = in_s[1]; m_dc.in_small_e3 = in_s[2];
114 2 m_dc.in_large_e1 = in_l[0]; m_dc.in_large_e2 = in_l[1]; m_dc.in_large_e3 = in_l[2];
115 }
116
0/14
✗ Branch 0 (204→205) not taken.
✗ Branch 1 (204→207) not taken.
✗ Branch 2 (224→225) not taken.
✗ Branch 3 (224→227) not taken.
✗ Branch 4 (246→247) not taken.
✗ Branch 5 (246→249) not taken.
✗ Branch 6 (298→299) not taken.
✗ Branch 7 (298→301) not taken.
✗ Branch 8 (318→319) not taken.
✗ Branch 9 (318→321) not taken.
✗ Branch 10 (336→337) not taken.
✗ Branch 11 (336→339) not taken.
✗ Branch 12 (380→381) not taken.
✗ Branch 13 (380→383) not taken.
2 }
117
118 2 void RGAFiducialFilter::Start(hipo::banklist& banks)
119 {
120
2/4
✓ Branch 0 (3→4) taken 2 times.
✗ Branch 1 (3→49) not taken.
✓ Branch 2 (4→5) taken 2 times.
✗ Branch 3 (4→7) not taken.
2 b_particle = GetBankIndex(banks, "REC::Particle");
121
2/4
✓ Branch 0 (10→11) taken 2 times.
✗ Branch 1 (10→55) not taken.
✓ Branch 2 (11→12) taken 2 times.
✗ Branch 3 (11→14) not taken.
2 b_config = GetBankIndex(banks, "RUN::config");
122
2/2
✓ Branch 0 (17→18) taken 1 times.
✓ Branch 1 (17→26) taken 1 times.
2 if (banklist_has(banks, "REC::Calorimeter")) {
123
2/4
✓ Branch 0 (19→20) taken 1 times.
✗ Branch 1 (19→61) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→23) taken 1 times.
1 b_calor = GetBankIndex(banks, "REC::Calorimeter");
124 1 m_have_calor = true;
125 }
126
1/2
✗ Branch 0 (27→28) not taken.
✓ Branch 1 (27→36) taken 2 times.
2 if (banklist_has(banks, "REC::ForwardTagger")) {
127 b_ft = GetBankIndex(banks, "REC::ForwardTagger");
128 m_have_ft = true;
129 }
130
2/2
✓ Branch 0 (37→38) taken 1 times.
✓ Branch 1 (37→46) taken 1 times.
2 if (banklist_has(banks, "REC::Traj")) {
131
2/4
✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→73) not taken.
✓ Branch 2 (40→41) taken 1 times.
✗ Branch 3 (40→43) not taken.
1 b_traj = GetBankIndex(banks, "REC::Traj");
132 1 m_have_traj = true;
133 }
134
135 2 ParseYAMLConfig();
136 2 LoadConfig();
137 2 }
138
139 2000 void RGAFiducialFilter::Run(hipo::banklist& banks) const {
140
1/2
✓ Branch 0 (3→4) taken 2000 times.
✗ Branch 1 (3→49) not taken.
2000 auto& particle = GetBank(banks, b_particle, "REC::Particle");
141
1/2
✓ Branch 0 (10→11) taken 2000 times.
✗ Branch 1 (10→55) not taken.
2000 auto& conf = GetBank(banks, b_config, "RUN::config");
142
3/4
✓ Branch 0 (16→17) taken 1000 times.
✓ Branch 1 (16→25) taken 1000 times.
✓ Branch 2 (18→19) taken 1000 times.
✗ Branch 3 (18→61) not taken.
2000 auto* cal = m_have_calor ? &GetBank(banks, b_calor, "REC::Calorimeter") : nullptr;
143
1/4
✗ Branch 0 (25→26) not taken.
✓ Branch 1 (25→34) taken 2000 times.
✗ Branch 2 (27→28) not taken.
✗ Branch 3 (27→67) not taken.
2000 auto* ft = m_have_ft ? &GetBank(banks, b_ft, "REC::ForwardTagger") : nullptr;
144
3/4
✓ Branch 0 (34→35) taken 1000 times.
✓ Branch 1 (34→43) taken 1000 times.
✓ Branch 2 (36→37) taken 1000 times.
✗ Branch 3 (36→73) not taken.
2000 auto* traj = m_have_traj ? &GetBank(banks, b_traj, "REC::Traj") : nullptr;
145
146
1/2
✓ Branch 0 (45→46) taken 2000 times.
✗ Branch 1 (45→79) not taken.
2000 particle.getMutableRowList().filter([this, &conf, cal, ft, traj](auto bank, auto row) {
147 13986 const bool keep = Filter(static_cast<int>(row), bank, conf, cal, ft, traj);
148
2/2
✓ Branch 0 (3→4) taken 350 times.
✓ Branch 1 (3→5) taken 13636 times.
13986 return keep ? 1 : 0;
149 });
150 2000 }
151
152 RGAFiducialFilter::CalLayers
153 1662 RGAFiducialFilter::CollectCalHitsForTrack(const hipo::bank& cal, int pindex) {
154 CalLayers out;
155 const int n = cal.getRows();
156
2/2
✓ Branch 0 (19→3) taken 13308 times.
✓ Branch 1 (19→20) taken 1662 times.
14970 for (int i=0; i<n; ++i) {
157
2/2
✓ Branch 0 (4→5) taken 10777 times.
✓ Branch 1 (4→6) taken 2531 times.
14177 if (cal.getInt("pindex", i) != pindex) continue;
158
2/2
✓ Branch 0 (7→8) taken 869 times.
✓ Branch 1 (7→9) taken 1662 times.
2531 if (cal.getInt("layer", i) != DetectorLayer::PCAL) continue; // PCal only
159 CalHit h;
160 1662 h.sector = cal.getInt ("sector", i);
161 1662 h.lv = cal.getFloat("lv", i);
162 1662 h.lw = cal.getFloat("lw", i);
163 1662 h.lu = cal.getFloat("lu", i);
164
1/2
✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→15) taken 1662 times.
1662 out.L1.push_back(h);
165 1662 out.has_any = true;
166 }
167 1662 return out;
168 }
169
170 1662 bool RGAFiducialFilter::PassCalStrictness(const CalLayers& H, int strictness) {
171
1/2
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 1662 times.
1662 if (!H.has_any) return true;
172
173 float min_lv = std::numeric_limits<float>::infinity();
174 float min_lw = std::numeric_limits<float>::infinity();
175
2/2
✓ Branch 0 (10→5) taken 1662 times.
✓ Branch 1 (10→11) taken 1662 times.
3324 for (auto const& hit : H.L1) {
176
1/2
✓ Branch 0 (5→6) taken 1662 times.
✗ Branch 1 (5→7) not taken.
1662 if (std::isfinite(hit.lv) && hit.lv < min_lv) min_lv = hit.lv;
177
1/2
✓ Branch 0 (7→8) taken 1662 times.
✗ Branch 1 (7→9) not taken.
1662 if (std::isfinite(hit.lw) && hit.lw < min_lw) min_lw = hit.lw;
178 }
179
180
1/4
✗ Branch 0 (11→12) not taken.
✓ Branch 1 (11→14) taken 1662 times.
✗ Branch 2 (12→13) not taken.
✗ Branch 3 (12→14) not taken.
1662 const float thr = (strictness==1 ? 9.0f : strictness==2 ? 13.5f : 18.0f);
181
4/4
✓ Branch 0 (14→15) taken 1628 times.
✓ Branch 1 (14→16) taken 34 times.
✓ Branch 2 (15→3) taken 1558 times.
✓ Branch 3 (15→16) taken 70 times.
1662 return !(min_lv < thr || min_lw < thr);
182 }
183
184 bool RGAFiducialFilter::PassFTFiducial(int pindex, const hipo::bank* ftBank) const {
185 if (!ftBank) return true;
186
187 const auto& ft = *ftBank;
188 const int n = ft.getRows();
189 for (int i=0; i<n; ++i) {
190 if (ft.getInt("pindex", i) != pindex) continue;
191
192 const double x = ft.getFloat("x", i);
193 const double y = ft.getFloat("y", i);
194 const double r = std::hypot(x, y);
195
196 if (r < u_ft_params.rmin) return false;
197 if (r > u_ft_params.rmax) return false;
198
199 for (auto const& H : u_ft_params.holes) {
200 const double R = H[0], cx = H[1], cy = H[2];
201 const double d = std::hypot(x-cx, y-cy);
202 if (d < R) return false;
203 }
204 return true;
205 }
206 return true;
207 }
208
209 360 bool RGAFiducialFilter::PassCVTFiducial(int pindex, const hipo::bank* trajBank) const {
210
1/2
✓ Branch 0 (2→3) taken 360 times.
✗ Branch 1 (2→61) not taken.
360 if (!trajBank) return true;
211
212 const auto& traj = *trajBank;
213 const int n = traj.getRows();
214
215 std::map<int, double> edge_at_layer;
216
217 double x12 = 0.0, y12 = 0.0;
218 bool saw12 = false;
219
220
2/2
✓ Branch 0 (28→4) taken 18776 times.
✓ Branch 1 (28→29) taken 360 times.
19136 for (int i = 0; i < n; ++i) {
221
2/2
✓ Branch 0 (5→6) taken 15558 times.
✓ Branch 1 (5→7) taken 3218 times.
20194 if (traj.getInt("pindex", i) != pindex) continue;
222
2/2
✓ Branch 0 (8→9) taken 1418 times.
✓ Branch 1 (8→10) taken 1800 times.
3218 if (traj.getInt("detector", i) != DetectorType::CVT) continue;
223
224 1800 const int layer = traj.getInt("layer", i);
225 1800 const double edge = static_cast<double>(traj.getFloat("edge", i));
226
227
1/2
✓ Branch 0 (16→17) taken 1800 times.
✗ Branch 1 (16→19) not taken.
1800 if (std::find(m_cvt.edge_layers.begin(), m_cvt.edge_layers.end(), layer) != m_cvt.edge_layers.end()) {
228
1/2
✓ Branch 0 (17→18) taken 1800 times.
✗ Branch 1 (17→62) not taken.
1800 edge_at_layer[layer] = edge;
229 }
230
231
2/2
✓ Branch 0 (19→20) taken 1440 times.
✓ Branch 1 (19→21) taken 360 times.
1800 if (layer == 12) {
232 360 const double x = static_cast<double>(traj.getFloat("x", i));
233
1/2
✗ Branch 0 (23→20) not taken.
✓ Branch 1 (23→24) taken 360 times.
360 const double y = static_cast<double>(traj.getFloat("y", i));
234
2/4
✗ Branch 0 (23→20) not taken.
✓ Branch 1 (23→24) taken 360 times.
✗ Branch 2 (24→20) not taken.
✓ Branch 3 (24→25) taken 360 times.
360 if (std::isfinite(x) && std::isfinite(y)) {
235 x12 = x; y12 = y; saw12 = true;
236 }
237 }
238 }
239
240
2/2
✓ Branch 0 (44→30) taken 1644 times.
✓ Branch 1 (44→45) taken 259 times.
1903 for (int L : m_cvt.edge_layers) {
241 auto it = edge_at_layer.find(L);
242
1/2
✗ Branch 0 (39→40) not taken.
✓ Branch 1 (39→41) taken 1644 times.
1644 if (it == edge_at_layer.end()) continue;
243
2/2
✓ Branch 0 (41→42) taken 101 times.
✓ Branch 1 (41→43) taken 1543 times.
1644 if (!(it->second > m_cvt.edge_min)) {
244 return false;
245 }
246 }
247
248
2/4
✓ Branch 0 (45→46) taken 259 times.
✗ Branch 1 (45→58) not taken.
✓ Branch 2 (46→47) taken 259 times.
✗ Branch 3 (46→58) not taken.
259 if (saw12 && !m_cvt.phi_forbidden_deg.empty()) {
249 259 double phi = std::atan2(y12, x12) * (180.0 / M_PI);
250
2/2
✓ Branch 0 (47→48) taken 128 times.
✓ Branch 1 (47→49) taken 131 times.
259 if (phi < 0) phi += 360.0;
251
3/4
✗ Branch 0 (55→56) not taken.
✓ Branch 1 (55→57) taken 1013 times.
✓ Branch 2 (57→50) taken 766 times.
✓ Branch 3 (57→58) taken 247 times.
1013 for (std::size_t i = 0; i + 1 < m_cvt.phi_forbidden_deg.size(); i += 2) {
252 766 const double lo = m_cvt.phi_forbidden_deg[i];
253 766 const double hi = m_cvt.phi_forbidden_deg[i + 1];
254
4/4
✓ Branch 0 (52→53) taken 445 times.
✓ Branch 1 (52→54) taken 321 times.
✓ Branch 2 (53→42) taken 12 times.
✓ Branch 3 (53→54) taken 433 times.
766 if (phi > lo && phi < hi) {
255 return false;
256 }
257 }
258 }
259
260 return true;
261 }
262
263 1542 bool RGAFiducialFilter::PassDCFiducial(int pindex, const hipo::bank& particleBank,
264 const hipo::bank& configBank, const hipo::bank* trajBank) const {
265
1/2
✓ Branch 0 (2→3) taken 1542 times.
✗ Branch 1 (2→45) not taken.
1542 if (!trajBank) return true;
266
267 1542 const int pid = particleBank.getInt("pid", pindex);
268
2/2
✓ Branch 0 (4→5) taken 1064 times.
✓ Branch 1 (4→6) taken 478 times.
1542 const bool isNeg = (pid== 11 || pid==-211 || pid==-321 || pid==-2212);
269
4/4
✓ Branch 0 (6→7) taken 658 times.
✓ Branch 1 (6→9) taken 884 times.
✓ Branch 2 (7→8) taken 501 times.
✓ Branch 3 (7→9) taken 157 times.
1542 const bool isPos = (pid==-11 || pid== 211 || pid== 321 || pid== 2212);
270
1/2
✓ Branch 0 (8→9) taken 501 times.
✗ Branch 1 (8→45) not taken.
501 if (!(isNeg || isPos)) return true;
271
272 1542 const float torus = configBank.getFloat("torus", 0);
273 const bool electron_out = (torus == 1.0f);
274
1/2
✓ Branch 0 (10→11) taken 1542 times.
✗ Branch 1 (10→12) not taken.
1542 const bool particle_inb = (electron_out ? isPos : isNeg);
275 const bool particle_out = !particle_inb;
276
277 1542 const double px = particleBank.getFloat("px", pindex);
278 1542 const double py = particleBank.getFloat("py", pindex);
279 1542 const double pz = particleBank.getFloat("pz", pindex);
280 1542 const double rho = std::hypot(px, py);
281
1/2
✗ Branch 0 (15→16) not taken.
✓ Branch 1 (15→17) taken 1542 times.
1542 const double theta = std::atan2(rho, (pz==0.0 ? 1e-12 : pz)) * (180.0 / M_PI);
282
283 double e1=0.0, e2=0.0, e3=0.0;
284 bool saw_dc = false;
285
286 const auto& traj = *trajBank;
287 const int n = traj.getRows();
288
2/2
✓ Branch 0 (32→18) taken 77915 times.
✓ Branch 1 (32→33) taken 1542 times.
79457 for (int i=0; i<n; ++i) {
289
2/2
✓ Branch 0 (19→20) taken 52972 times.
✓ Branch 1 (19→22) taken 24943 times.
77915 if (traj.getInt("pindex", i) != pindex) continue;
290
2/2
✓ Branch 0 (23→24) taken 20317 times.
✓ Branch 1 (23→25) taken 4626 times.
24943 if (traj.getInt("detector", i) != DetectorType::DC) continue;
291 saw_dc = true;
292 4626 const int layer = traj.getInt("layer", i);
293 4626 const double e = traj.getFloat("edge", i);
294
2/2
✓ Branch 0 (27→28) taken 3084 times.
✓ Branch 1 (27→31) taken 1542 times.
4626 if (layer== 6) e1 = e;
295
2/2
✓ Branch 0 (28→29) taken 1542 times.
✓ Branch 1 (28→31) taken 1542 times.
3084 else if (layer==18) e2 = e;
296
1/2
✓ Branch 0 (29→30) taken 1542 times.
✗ Branch 1 (29→31) not taken.
1542 else if (layer==36) e3 = e;
297 }
298
299
1/2
✓ Branch 0 (33→34) taken 1542 times.
✗ Branch 1 (33→45) not taken.
1542 if (!saw_dc) return true;
300
301 auto pass3 = [](double a1, double a2, double a3, double t1, double t2, double t3)->bool {
302
11/12
✓ Branch 0 (37→38) taken 15 times.
✗ Branch 1 (37→46) not taken.
✓ Branch 2 (38→45) taken 8 times.
✓ Branch 3 (38→46) taken 7 times.
✓ Branch 4 (40→41) taken 447 times.
✓ Branch 5 (40→46) taken 3 times.
✓ Branch 6 (41→45) taken 433 times.
✓ Branch 7 (41→46) taken 14 times.
✓ Branch 8 (43→44) taken 969 times.
✓ Branch 9 (43→46) taken 1 times.
✓ Branch 10 (44→45) taken 968 times.
✓ Branch 11 (44→46) taken 1 times.
1435 return (a1>t1 && a2>t2 && a3>t3);
303 };
304
305
2/2
✓ Branch 0 (34→35) taken 501 times.
✓ Branch 1 (34→42) taken 1041 times.
1542 if (particle_inb) {
306
2/2
✓ Branch 0 (35→36) taken 41 times.
✓ Branch 1 (35→39) taken 460 times.
501 if (theta < m_dc.theta_small_deg) {
307
2/2
✓ Branch 0 (36→37) taken 15 times.
✓ Branch 1 (36→46) taken 26 times.
41 return pass3(e1,e2,e3, m_dc.in_small_e1, m_dc.in_small_e2, m_dc.in_small_e3);
308 }
309
2/2
✓ Branch 0 (39→40) taken 450 times.
✓ Branch 1 (39→46) taken 10 times.
460 return pass3(e1,e2,e3, m_dc.in_large_e1, m_dc.in_large_e2, m_dc.in_large_e3);
310 } else if (particle_out) {
311
2/2
✓ Branch 0 (42→43) taken 970 times.
✓ Branch 1 (42→46) taken 71 times.
1041 return pass3(e1,e2,e3, m_dc.out_e1, m_dc.out_e2, m_dc.out_e3);
312 }
313 return true;
314 }
315
316 13986 bool RGAFiducialFilter::Filter(int track_index, const hipo::bank& particleBank,
317 const hipo::bank& configBank, const hipo::bank* calBank,
318 const hipo::bank* ftBank, const hipo::bank* trajBank) const {
319
320 13986 const int pid = particleBank.getInt("pid", track_index);
321 13986 const int strictness = m_cal_strictness;
322
323 27972 auto has_assoc = [&track_index](const hipo::bank* b)->bool {
324
2/2
✓ Branch 0 (2→3) taken 20979 times.
✓ Branch 1 (2→4) taken 6993 times.
27972 if (!b) return false;
325 const int n = b->getRows();
326
4/4
✓ Branch 0 (6→7) taken 34137 times.
✓ Branch 1 (6→9) taken 3786 times.
✓ Branch 2 (8→3) taken 3207 times.
✓ Branch 3 (8→5) taken 37923 times.
41130 for (int i=0;i<n;++i) if (b->getInt("pindex", i) == track_index) return true;
327 return false;
328 13986 };
329
330 13986 const bool hasCal = has_assoc(calBank);
331 13986 const bool hasFT = has_assoc(ftBank);
332 13986 const bool hasCVT = traj_has_detector(trajBank, track_index, DetectorType::CVT);
333 13986 const bool hasDC = traj_has_detector(trajBank, track_index, DetectorType::DC);
334
335 bool pass = true;
336
337
2/2
✓ Branch 0 (7→8) taken 1300 times.
✓ Branch 1 (7→25) taken 12686 times.
13986 if (pid == 11 || pid == -11) {
338
1/2
✗ Branch 0 (8→9) not taken.
✓ Branch 1 (8→12) taken 1300 times.
1300 if (hasFT) {
339 pass = pass && PassFTFiducial(track_index, ftBank);
340 } else {
341
2/2
✓ Branch 0 (12→13) taken 156 times.
✓ Branch 1 (12→19) taken 1144 times.
1300 if (hasCal) {
342 156 auto calhits = CollectCalHitsForTrack(*calBank, track_index);
343
1/2
✓ Branch 0 (14→15) taken 156 times.
✗ Branch 1 (14→52) not taken.
156 pass = pass && PassCalStrictness(calhits, strictness);
344 }
345
2/2
✓ Branch 0 (19→20) taken 156 times.
✓ Branch 1 (19→24) taken 1144 times.
1300 if (hasDC) {
346
4/4
✓ Branch 0 (20→11) taken 22 times.
✓ Branch 1 (20→21) taken 134 times.
✓ Branch 2 (22→11) taken 8 times.
✓ Branch 3 (22→23) taken 126 times.
156 pass = pass && PassDCFiducial(track_index, particleBank, configBank, trajBank);
347 }
348 }
349 1300 return pass;
350 }
351
352
2/2
✓ Branch 0 (25→26) taken 3678 times.
✓ Branch 1 (25→38) taken 9008 times.
12686 if (pid == 22) {
353
1/2
✗ Branch 0 (26→27) not taken.
✓ Branch 1 (26→29) taken 3678 times.
3678 if (hasFT) {
354 pass = pass && PassFTFiducial(track_index, ftBank);
355
2/2
✓ Branch 0 (29→30) taken 2172 times.
✓ Branch 1 (29→31) taken 1506 times.
3678 } else if (hasCal) {
356 1506 auto calhits = CollectCalHitsForTrack(*calBank, track_index);
357
1/2
✓ Branch 0 (32→33) taken 1506 times.
✗ Branch 1 (32→56) not taken.
1506 pass = pass && PassCalStrictness(calhits, strictness);
358 }
359 3678 return pass;
360 }
361
362
2/2
✓ Branch 0 (38→39) taken 6922 times.
✓ Branch 1 (38→41) taken 2086 times.
9008 if (pid== 211 || pid== 321 || pid== 2212 ||
363
4/4
✓ Branch 0 (39→40) taken 5558 times.
✓ Branch 1 (39→41) taken 1364 times.
✓ Branch 2 (40→41) taken 86 times.
✓ Branch 3 (40→51) taken 5472 times.
6922 pid==-211 || pid==-321 || pid==-2212) {
364
4/4
✓ Branch 0 (41→42) taken 3176 times.
✓ Branch 1 (41→43) taken 360 times.
✓ Branch 2 (44→42) taken 247 times.
✓ Branch 3 (44→45) taken 113 times.
3536 if (hasCVT) pass = pass && PassCVTFiducial(track_index, trajBank);
365
5/6
✓ Branch 0 (45→46) taken 1408 times.
✓ Branch 1 (45→50) taken 2128 times.
✓ Branch 2 (46→47) taken 1408 times.
✗ Branch 3 (46→49) not taken.
✓ Branch 4 (48→49) taken 125 times.
✓ Branch 5 (48→50) taken 1283 times.
3536 if (hasDC) pass = pass && PassDCFiducial(track_index, particleBank, configBank, trajBank);
366 3536 return pass;
367 }
368
369 return true;
370 }
371
372 }
373