GCC Code Coverage Report


Directory: ./
File: src/iguana/algorithms/clas12/PhotonGBTFilter/Algorithm.cc
Date: 2025-11-25 17:57:04
Coverage Exec Excl Total
Lines: 92.4% 220 0 238
Functions: 100.0% 12 0 12
Branches: 72.0% 190 0 264

Line Branch Exec Source
1 #include "Algorithm.h"
2 #include "iguana/algorithms/TypeDefs.h"
3 #include "models/RGA_inbending_pass1.cpp"
4 #include "models/RGA_inbending_pass2.cpp"
5 #include "models/RGA_outbending_pass1.cpp"
6 #include "models/RGA_outbending_pass2.cpp"
7 #include "models/RGC_Summer2022_pass1.cpp"
8
9 namespace iguana::clas12 {
10
11 REGISTER_IGUANA_ALGORITHM(PhotonGBTFilter);
12
13 // Map for the GBT Models to use depending on pass and run number
14 std::map<std::tuple<int, int, int>, std::function<double(std::vector<float> const&)>> const PhotonGBTFilter::modelMap = {
15 {{5032, 5332, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass1(data); }}, // Fall2018 RGA Inbending
16 {{5032, 5332, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass2(data); }}, // Fall2018 RGA Inbending
17 {{5333, 5666, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_outbending_pass1(data); }}, // Fall2018 RGA Outbending
18 {{5333, 5666, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_outbending_pass2(data); }}, // Fall2018 RGA Outbending
19 2564 {{6616, 6783, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass1(data); }}, // Spring2019 RGA Inbending
20 {{6616, 6783, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass2(data); }}, // Spring2019 RGA Inbending
21 {{6156, 6603, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass1(data); }}, // Spring2019 RGB Inbending
22 {{6156, 6603, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass2(data); }}, // Spring2019 RGB Inbending
23 {{11093, 11283, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_outbending_pass1(data); }}, // Fall2019 RGB Outbending
24 {{11093, 11283, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_outbending_pass2(data); }}, // Fall2019 RGB Outbending
25 {{11284, 11300, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass1(data); }}, // Fall2019 RGB BAND Inbending
26 {{11284, 11300, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass2(data); }}, // Fall2019 RGB BAND Inbending
27 {{11323, 11571, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass1(data); }}, // Spring2020 RGB Inbending
28 {{11323, 11571, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass2(data); }}, // Spring2020 RGB Inbending
29 {{16042, 16772, 1}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGC_Summer2022_pass1(data); }}, // Summer2022 RGC Inbending
30 {{16042, 16772, 2}, [](std::vector<float> const& data) { return ApplyCatboostModel_RGC_Summer2022_pass1(data); }} // Summer2022 RGC Inbending (no pass2 currently)
31 };
32
33 2 void PhotonGBTFilter::Start(hipo::banklist& banks)
34 {
35
36 2 ParseYAMLConfig();
37
38
2/4
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 43 not taken.
✓ Branch 5 → 6 taken 2 times.
✗ Branch 5 → 8 not taken.
2 b_particle = GetBankIndex(banks, "REC::Particle");
39
2/4
✓ Branch 11 → 12 taken 2 times.
✗ Branch 11 → 49 not taken.
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 15 taken 2 times.
2 b_calorimeter = GetBankIndex(banks, "REC::Calorimeter");
40
2/4
✓ Branch 18 → 19 taken 2 times.
✗ Branch 18 → 55 not taken.
✓ Branch 19 → 20 taken 2 times.
✗ Branch 19 → 22 not taken.
2 b_config = GetBankIndex(banks, "RUN::config");
41
42
3/6
✓ Branch 25 → 26 taken 2 times.
✗ Branch 25 → 67 not taken.
✓ Branch 26 → 27 taken 2 times.
✗ Branch 26 → 61 not taken.
✓ Branch 27 → 28 taken 2 times.
✗ Branch 27 → 30 not taken.
4 o_pass = GetOptionScalar<int>("pass");
43
3/6
✓ Branch 34 → 35 taken 2 times.
✗ Branch 34 → 75 not taken.
✓ Branch 35 → 36 taken 2 times.
✗ Branch 35 → 69 not taken.
✓ Branch 36 → 37 taken 2 times.
✗ Branch 36 → 39 not taken.
4 o_threshold = GetOptionScalar<double>("threshold");
44 2 }
45
46 2000 bool PhotonGBTFilter::Run(hipo::banklist& banks) const
47 {
48
1/2
✓ Branch 8 → 9 taken 2000 times.
✗ Branch 8 → 25 not taken.
2000 return Run(
49
3/8
✓ Branch 6 → 7 taken 2000 times.
✗ Branch 6 → 31 not taken.
✓ Branch 7 → 8 taken 2000 times.
✗ Branch 7 → 25 not taken.
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 17 taken 2000 times.
✗ Branch 31 → 32 not taken.
✗ Branch 31 → 34 not taken.
4000 GetBank(banks, b_particle, "REC::Particle"),
50
3/8
✓ Branch 4 → 5 taken 2000 times.
✗ Branch 4 → 37 not taken.
✓ Branch 5 → 6 taken 2000 times.
✗ Branch 5 → 31 not taken.
✓ Branch 19 → 20 taken 2000 times.
✗ Branch 19 → 22 not taken.
✗ Branch 37 → 38 not taken.
✗ Branch 37 → 40 not taken.
4000 GetBank(banks, b_calorimeter, "REC::Calorimeter"),
51
1/2
✓ Branch 3 → 4 taken 2000 times.
✗ Branch 3 → 37 not taken.
4000 GetBank(banks, b_config, "RUN::config"));
52 }
53
54 2000 bool PhotonGBTFilter::Run(
55 hipo::bank& particleBank,
56 hipo::bank const& caloBank,
57 hipo::bank const& configBank) const
58 {
59 2000 int runnum = configBank.getInt("run", 0);
60
61 // Get CaloMap for the event
62 2000 auto calo_map = GetCaloMap(caloBank);
63
64 // dump the bank
65
2/4
✓ Branch 4 → 5 taken 2000 times.
✗ Branch 4 → 45 not taken.
✓ Branch 7 → 8 taken 2000 times.
✗ Branch 7 → 30 not taken.
4000 ShowBank(particleBank, Logger::Header("INPUT PARTICLES"));
66
67 // Loop over each photon in the particleBank to classify it
68 // Here we loop over the particleBank RowList
69 // This ensures we are only concerned with filtering photons that passed upstream filters
70
3/6
✓ Branch 13 → 14 taken 2000 times.
✗ Branch 13 → 45 not taken.
✓ Branch 14 → 15 taken 2000 times.
✗ Branch 14 → 45 not taken.
✓ Branch 15 → 16 taken 2000 times.
✗ Branch 15 → 36 not taken.
2000 particleBank.getMutableRowList().filter([this, &caloBank, &calo_map, runnum](auto bank, auto row) {
71 13986 auto pid = bank.getInt("pid", row);
72
2/2
✓ Branch 3 → 4 taken 3678 times.
✓ Branch 3 → 8 taken 10308 times.
13986 if(pid != 22)
73 return true;
74
1/2
✓ Branch 5 → 6 taken 3678 times.
✗ Branch 5 → 9 not taken.
7356 return Filter(bank, caloBank, calo_map, row, runnum);
75 });
76
77 // dump the modified bank
78
2/4
✓ Branch 18 → 19 taken 2000 times.
✗ Branch 18 → 45 not taken.
✓ Branch 21 → 22 taken 2000 times.
✗ Branch 21 → 39 not taken.
4000 ShowBank(particleBank, Logger::Header("OUTPUT PARTICLES"));
79
1/2
✓ Branch 27 → 28 taken 2000 times.
✗ Branch 27 → 45 not taken.
2000 return !particleBank.getRowList().empty();
80 }
81
82 9240 bool PhotonGBTFilter::PidPurityPhotonFilter(float const E, float const Epcal, float const theta) const
83 {
84 // Apply standard pid cuts on the photon, compatible to how the models were trained
85 // 1. Minimum photon energy cut of 200 MeV
86 // 2. Photon must have deposited energy in the PCal
87 // 3. Photon must be in the Forward Detector
88
6/6
✓ Branch 2 → 3 taken 7788 times.
✓ Branch 2 → 6 taken 1452 times.
✓ Branch 3 → 4 taken 7404 times.
✓ Branch 3 → 6 taken 384 times.
✓ Branch 5 → 6 taken 40 times.
✓ Branch 5 → 7 taken 7364 times.
9240 if(E < 0.2 || Epcal <= 0 || !(ForwardDetectorFilter(theta)))
89 1876 return false;
90 return true;
91 }
92
93 20669 bool PhotonGBTFilter::ForwardDetectorFilter(float const theta) const
94 {
95 // Apply forward detector cut
96
4/4
✓ Branch 2 → 3 taken 20219 times.
✓ Branch 2 → 4 taken 450 times.
✓ Branch 3 → 4 taken 118 times.
✓ Branch 3 → 5 taken 20101 times.
20669 if(theta * 180 / M_PI < 5 || theta * 180 / M_PI > 35)
97 568 return false;
98 return true;
99 }
100
101 3678 bool PhotonGBTFilter::Filter(hipo::bank const& particleBank, hipo::bank const& caloBank, std::map<int, PhotonGBTFilter::calo_row_data> calo_map, int const row, int const runnum) const
102 {
103
104 // Set variables native to the photon we are classifying
105 3678 double gPx = particleBank.getFloat("px", row);
106 3678 double gPy = particleBank.getFloat("py", row);
107 3678 double gPz = particleBank.getFloat("pz", row);
108
109 // Set ML features intrinsic to the photon of interest
110 3678 double gE = sqrt(gPx * gPx + gPy * gPy + gPz * gPz);
111 3678 double gTheta = acos(gPz / gE);
112 3678 double gEpcal = calo_map[row].pcal_e;
113 3678 double gm2u = calo_map[row].pcal_m2u;
114 3678 double gm2v = calo_map[row].pcal_m2v;
115
116 // Apply PID purity cuts on the photon
117 // If they do not pass, then these photons are incompatible with the trained GBT model
118
2/2
✓ Branch 9 → 11 taken 2564 times.
✓ Branch 9 → 151 taken 1114 times.
3678 if(PidPurityPhotonFilter(gE, gEpcal, gTheta) == false)
119 return false;
120
121 // Define the variables "m_g" , "m_ch" , "m_nh"
122 // Should not be changed because the model was trained with this specific set of inputs
123 int const m_g = 3; // Number of neighboring gammas
124 int const m_ch = 2; // Number of neighboring charged hadrons (protons, pions, kaons)
125 int const m_nh = 2; // Number of neighboring neutral hadrons (neutrons)
126
127 double R_e = 0;
128 double dE_e = 0;
129
130 double R_gamma[m_g]; // Angular distance between calo shower centers
131 double dE_gamma[m_g]; // Energy difference
132 double Epcal_gamma[m_g]; // Energy deposited in the pcal
133 double m2u_gamma[m_g]; // Shower shape variables
134 double m2v_gamma[m_g]; // Shower shape variables
135
136 double R_ch[m_ch]; // Angular distance between calo shower centers
137 double dE_ch[m_ch]; // Energy difference
138 double Epcal_ch[m_ch]; // Energy deposited in the pcal
139 double m2u_ch[m_ch]; // Shower shape variables
140 double m2v_ch[m_ch]; // Shower shape variables
141
142 double R_nh[m_nh]; // Angular distance between calo shower centers
143 double dE_nh[m_nh]; // Energy difference
144 double Epcal_nh[m_nh]; // Energy deposited in the pcal
145 double m2u_nh[m_nh]; // Shower shape variables
146 double m2v_nh[m_nh]; // Shower shape variables
147
148 double num_photons_0_1, num_photons_0_2, num_photons_0_35;
149
150 // Initialize the arrays
151
2/2
✓ Branch 11 → 10 taken 7692 times.
✓ Branch 11 → 13 taken 2564 times.
10256 for(int i = 0; i < m_g; ++i) {
152 7692 R_gamma[i] = 0;
153 7692 dE_gamma[i] = 0;
154 7692 Epcal_gamma[i] = 0;
155 7692 m2u_gamma[i] = 0;
156 7692 m2v_gamma[i] = 0;
157 }
158
2/2
✓ Branch 13 → 12 taken 5128 times.
✓ Branch 13 → 15 taken 2564 times.
7692 for(int i = 0; i < m_ch; ++i) {
159 5128 R_ch[i] = 0;
160 5128 dE_ch[i] = 0;
161 5128 Epcal_ch[i] = 0;
162 5128 m2u_ch[i] = 0;
163 5128 m2v_ch[i] = 0;
164 }
165
2/2
✓ Branch 15 → 14 taken 5128 times.
✓ Branch 15 → 16 taken 2564 times.
7692 for(int i = 0; i < m_nh; ++i) {
166 5128 R_nh[i] = 0;
167 5128 dE_nh[i] = 0;
168 5128 Epcal_nh[i] = 0;
169 5128 m2u_nh[i] = 0;
170 5128 m2v_nh[i] = 0;
171 }
172
173 // Set the number of photons within R<0.1, R<0.2, R<0.35
174 num_photons_0_1 = 0;
175 num_photons_0_2 = 0;
176 num_photons_0_35 = 0;
177
178
179 // Get 3-vector that points to the photon of interest's location in the calorimeter
180 2564 auto calo_POI = calo_map.at(row);
181 2564 ROOT::Math::XYZVector vPOI = GetParticleCaloVector(calo_POI);
182
183
184 // Build nearest neighbor event structure
185 // Loop over particles in the event
186 // Here we loop over particleBank.getRows(), which ignores upstream filters
187 // This is critical as the GBTs were trained on identifying nearest neighbors for the whole REC::Particle bank
188 // Only considering nearest neighbor particles that pass upstream filters would call the accuracy of the model into question
189
2/2
✓ Branch 95 → 19 taken 22304 times.
✓ Branch 95 → 96 taken 2564 times.
24868 for(int inner_row = 0; inner_row < particleBank.getRows(); inner_row++) {
190 // Skip over the particle if it is photon we are trying to classify
191
2/2
✓ Branch 19 → 20 taken 2564 times.
✓ Branch 19 → 21 taken 19740 times.
22304 if(inner_row == row)
192 11812 continue;
193
194 // Check if the key exists in the calo_map
195 // This skips over REC::Particle entries without a REC::Calorimeter entry
196
2/2
✓ Branch 30 → 31 taken 8244 times.
✓ Branch 30 → 32 taken 11496 times.
19740 if(calo_map.find(inner_row) == calo_map.end())
197 8244 continue;
198 11496 auto calo_PART = calo_map.at(inner_row);
199
200 11496 auto pid = particleBank.getInt("pid", inner_row);
201
2/2
✓ Branch 34 → 35 taken 70 times.
✓ Branch 34 → 36 taken 11426 times.
11496 auto mass = particle::get(particle::mass, pid);
202
203 // Skip over particle if its mass was undefined
204
2/2
✓ Branch 34 → 35 taken 70 times.
✓ Branch 34 → 36 taken 11426 times.
11496 if(!mass.has_value())
205 70 continue;
206 11426 auto px = particleBank.getFloat("px", inner_row);
207 11426 auto py = particleBank.getFloat("py", inner_row);
208 11426 auto pz = particleBank.getFloat("pz", inner_row);
209 11426 auto p = sqrt(px * px + py * py + pz * pz);
210 11426 auto E = sqrt(p * p + mass.value() * mass.value());
211 11426 auto th = acos(pz / p);
212 // Skip over particle if it is not in the forward detector (necessary for model compatibility)
213
2/2
✓ Branch 40 → 41 taken 172 times.
✓ Branch 40 → 42 taken 11254 times.
11426 if(ForwardDetectorFilter(th) == false)
214 172 continue;
215
216 // Get 3-vector that points to the neighboring particle's location in the calorimeter
217 11254 ROOT::Math::XYZVector vPART = GetParticleCaloVector(calo_PART);
218
219 // Get angular distance between photon of interest and particle
220 double R = ROOT::Math::VectorUtil::Angle(vPOI, vPART);
221
222 // Logic for filling nearest neighbor variables
223
2/2
✓ Branch 44 → 45 taken 5562 times.
✓ Branch 44 → 63 taken 5692 times.
11254 if(pid == 22) { // photon
224
225 // Apply Photon Purity Cuts to ensure this neighbor can be used in classification
226
2/2
✓ Branch 46 → 47 taken 762 times.
✓ Branch 46 → 48 taken 4800 times.
5562 if(PidPurityPhotonFilter(E, calo_PART.pcal_e, th) == false)
227 762 continue;
228
229
2/2
✓ Branch 48 → 49 taken 820 times.
✓ Branch 48 → 50 taken 3980 times.
4800 if(R < 0.1)
230 820 num_photons_0_1++;
231
2/2
✓ Branch 50 → 51 taken 504 times.
✓ Branch 50 → 52 taken 3476 times.
3980 if(R < 0.2)
232 1324 num_photons_0_2++;
233
2/2
✓ Branch 52 → 53 taken 1656 times.
✓ Branch 52 → 54 taken 2640 times.
4296 if(R < 0.35)
234 2160 num_photons_0_35++;
235
236
2/2
✓ Branch 62 → 55 taken 7200 times.
✓ Branch 62 → 92 taken 256 times.
7456 for(int i = 0; i < m_g; ++i) {
237
4/4
✓ Branch 55 → 56 taken 1614 times.
✓ Branch 55 → 57 taken 5586 times.
✓ Branch 57 → 56 taken 2930 times.
✓ Branch 57 → 61 taken 2656 times.
7200 if(R < R_gamma[i] || R_gamma[i] == 0) {
238 int j = m_g - 1;
239
2/2
✓ Branch 59 → 58 taken 7200 times.
✓ Branch 59 → 60 taken 4544 times.
11744 while(j > i) {
240 7200 R_gamma[j] = R_gamma[j - 1];
241 7200 dE_gamma[j] = dE_gamma[j - 1];
242 7200 Epcal_gamma[j] = Epcal_gamma[j - 1];
243 7200 m2u_gamma[j] = m2u_gamma[j - 1];
244 7200 m2v_gamma[j] = m2v_gamma[j - 1];
245 j--;
246 }
247 4544 R_gamma[i] = R;
248 4544 dE_gamma[i] = gE - E;
249 4544 Epcal_gamma[i] = calo_PART.pcal_e;
250 4544 m2u_gamma[i] = calo_PART.pcal_m2u;
251 4544 m2v_gamma[i] = calo_PART.pcal_m2v;
252 4544 break;
253 }
254 }
255 }
256
2/2
✓ Branch 63 → 64 taken 308 times.
✓ Branch 63 → 68 taken 5384 times.
5692 else if(pid == 11) { // electron
257
3/4
✓ Branch 64 → 65 taken 306 times.
✓ Branch 64 → 67 taken 2 times.
✗ Branch 65 → 66 not taken.
✓ Branch 65 → 67 taken 306 times.
308 if(R < R_e || R_e == 0) {
258 R_e = R;
259 308 dE_e = gE - E;
260 }
261 }
262
10/10
✓ Branch 68 → 69 taken 5190 times.
✓ Branch 68 → 70 taken 194 times.
✓ Branch 69 → 70 taken 1666 times.
✓ Branch 69 → 71 taken 3524 times.
✓ Branch 71 → 70 taken 602 times.
✓ Branch 71 → 72 taken 2922 times.
✓ Branch 72 → 70 taken 16 times.
✓ Branch 72 → 73 taken 2906 times.
✓ Branch 73 → 70 taken 14 times.
✓ Branch 73 → 82 taken 2892 times.
5384 else if(pid == 2212 || pid == -2212 || pid == 211 || pid == -211 || pid == 321 || pid == -321) { // charged hadron
263
2/2
✓ Branch 81 → 74 taken 2946 times.
✓ Branch 81 → 92 taken 64 times.
3010 for(int i = 0; i < m_ch; ++i) {
264
4/4
✓ Branch 74 → 75 taken 444 times.
✓ Branch 74 → 76 taken 2502 times.
✓ Branch 76 → 75 taken 1984 times.
✓ Branch 76 → 80 taken 518 times.
2946 if(R < R_ch[i] || R_ch[i] == 0) {
265 int j = m_ch - 1;
266
2/2
✓ Branch 78 → 77 taken 2038 times.
✓ Branch 78 → 79 taken 2428 times.
4466 while(j > i) {
267 2038 R_ch[j] = R_ch[j - 1];
268 2038 dE_ch[j] = dE_ch[j - 1];
269 2038 Epcal_ch[j] = Epcal_ch[j - 1];
270 2038 m2u_ch[j] = m2u_ch[j - 1];
271 2038 m2v_ch[j] = m2v_ch[j - 1];
272 j--;
273 }
274 2428 R_ch[i] = R;
275 2428 dE_ch[i] = gE - E;
276 2428 Epcal_ch[i] = calo_PART.pcal_e;
277 2428 m2u_ch[i] = calo_PART.pcal_m2u;
278 2428 m2v_ch[i] = calo_PART.pcal_m2v;
279 2428 break;
280 }
281 }
282 }
283
1/2
✓ Branch 82 → 90 taken 2892 times.
✗ Branch 82 → 91 not taken.
2892 else if(pid == 2112 || pid == -2112) { // neutral hadron
284
2/2
✓ Branch 90 → 83 taken 3734 times.
✓ Branch 90 → 92 taken 264 times.
3998 for(int i = 0; i < m_nh; ++i) {
285
4/4
✓ Branch 83 → 84 taken 776 times.
✓ Branch 83 → 85 taken 2958 times.
✓ Branch 85 → 84 taken 1852 times.
✓ Branch 85 → 89 taken 1106 times.
3734 if(R < R_nh[i] || R_nh[i] == 0) {
286 int j = m_nh - 1;
287
2/2
✓ Branch 87 → 86 taken 2050 times.
✓ Branch 87 → 88 taken 2628 times.
4678 while(j > i) {
288 2050 R_nh[j] = R_nh[j - 1];
289 2050 dE_nh[j] = dE_nh[j - 1];
290 2050 Epcal_nh[j] = Epcal_nh[j - 1];
291 2050 m2u_nh[j] = m2u_nh[j - 1];
292 2050 m2v_nh[j] = m2v_nh[j - 1];
293 j--;
294 }
295 2628 R_nh[i] = R;
296 2628 dE_nh[i] = gE - E;
297 2628 Epcal_nh[i] = calo_PART.pcal_e;
298 2628 m2u_nh[i] = calo_PART.pcal_m2u;
299 2628 m2v_nh[i] = calo_PART.pcal_m2v;
300 2628 break;
301 }
302 }
303 }
304 else { // unrecognized OR uncompatible particle type for the trained model
305 continue;
306 }
307 }
308
309 // Create and populate input_data vector for the ML model
310 std::vector<float> input_data = {
311 static_cast<float>(gE), static_cast<float>(gEpcal), static_cast<float>(gTheta),
312 2564 static_cast<float>(gm2u), static_cast<float>(gm2v), static_cast<float>(R_e),
313 2564 static_cast<float>(dE_e)};
314
315
316
2/2
✓ Branch 100 → 98 taken 7692 times.
✓ Branch 100 → 103 taken 2564 times.
10256 for(int i = 0; i < m_g; ++i)
317
1/2
✓ Branch 98 → 99 taken 7692 times.
✗ Branch 98 → 152 not taken.
7692 input_data.push_back(static_cast<float>(R_gamma[i]));
318
2/2
✓ Branch 103 → 101 taken 7692 times.
✓ Branch 103 → 106 taken 2564 times.
10256 for(int i = 0; i < m_g; ++i)
319
1/2
✓ Branch 101 → 102 taken 7692 times.
✗ Branch 101 → 152 not taken.
7692 input_data.push_back(static_cast<float>(dE_gamma[i]));
320
2/2
✓ Branch 106 → 104 taken 7692 times.
✓ Branch 106 → 109 taken 2564 times.
10256 for(int i = 0; i < m_g; ++i)
321
1/2
✓ Branch 104 → 105 taken 7692 times.
✗ Branch 104 → 152 not taken.
7692 input_data.push_back(static_cast<float>(Epcal_gamma[i]));
322
2/2
✓ Branch 109 → 107 taken 7692 times.
✓ Branch 109 → 112 taken 2564 times.
10256 for(int i = 0; i < m_g; ++i)
323
1/2
✓ Branch 107 → 108 taken 7692 times.
✗ Branch 107 → 152 not taken.
7692 input_data.push_back(static_cast<float>(m2u_gamma[i]));
324
2/2
✓ Branch 112 → 110 taken 7692 times.
✓ Branch 112 → 115 taken 2564 times.
10256 for(int i = 0; i < m_g; ++i)
325
1/2
✓ Branch 110 → 111 taken 7692 times.
✗ Branch 110 → 152 not taken.
7692 input_data.push_back(static_cast<float>(m2v_gamma[i]));
326
327
328
2/2
✓ Branch 115 → 113 taken 5128 times.
✓ Branch 115 → 118 taken 2564 times.
7692 for(int i = 0; i < m_ch; ++i)
329
1/2
✓ Branch 113 → 114 taken 5128 times.
✗ Branch 113 → 152 not taken.
5128 input_data.push_back(static_cast<float>(R_ch[i]));
330
2/2
✓ Branch 118 → 116 taken 5128 times.
✓ Branch 118 → 121 taken 2564 times.
7692 for(int i = 0; i < m_ch; ++i)
331
1/2
✓ Branch 116 → 117 taken 5128 times.
✗ Branch 116 → 152 not taken.
5128 input_data.push_back(static_cast<float>(dE_ch[i]));
332
2/2
✓ Branch 121 → 119 taken 5128 times.
✓ Branch 121 → 124 taken 2564 times.
7692 for(int i = 0; i < m_ch; ++i)
333
1/2
✓ Branch 119 → 120 taken 5128 times.
✗ Branch 119 → 152 not taken.
5128 input_data.push_back(static_cast<float>(Epcal_ch[i]));
334
2/2
✓ Branch 124 → 122 taken 5128 times.
✓ Branch 124 → 127 taken 2564 times.
7692 for(int i = 0; i < m_ch; ++i)
335
1/2
✓ Branch 122 → 123 taken 5128 times.
✗ Branch 122 → 152 not taken.
5128 input_data.push_back(static_cast<float>(m2u_ch[i]));
336
2/2
✓ Branch 127 → 125 taken 5128 times.
✓ Branch 127 → 130 taken 2564 times.
7692 for(int i = 0; i < m_ch; ++i)
337
1/2
✓ Branch 125 → 126 taken 5128 times.
✗ Branch 125 → 152 not taken.
5128 input_data.push_back(static_cast<float>(m2v_ch[i]));
338
339
340
2/2
✓ Branch 130 → 128 taken 5128 times.
✓ Branch 130 → 133 taken 2564 times.
7692 for(int i = 0; i < m_nh; ++i)
341
1/2
✓ Branch 128 → 129 taken 5128 times.
✗ Branch 128 → 152 not taken.
5128 input_data.push_back(static_cast<float>(R_nh[i]));
342
2/2
✓ Branch 133 → 131 taken 5128 times.
✓ Branch 133 → 136 taken 2564 times.
7692 for(int i = 0; i < m_nh; ++i)
343
1/2
✓ Branch 131 → 132 taken 5128 times.
✗ Branch 131 → 152 not taken.
5128 input_data.push_back(static_cast<float>(dE_nh[i]));
344
2/2
✓ Branch 136 → 134 taken 5128 times.
✓ Branch 136 → 139 taken 2564 times.
7692 for(int i = 0; i < m_nh; ++i)
345
1/2
✓ Branch 134 → 135 taken 5128 times.
✗ Branch 134 → 152 not taken.
5128 input_data.push_back(static_cast<float>(Epcal_nh[i]));
346
2/2
✓ Branch 139 → 137 taken 5128 times.
✓ Branch 139 → 142 taken 2564 times.
7692 for(int i = 0; i < m_nh; ++i)
347
1/2
✓ Branch 137 → 138 taken 5128 times.
✗ Branch 137 → 152 not taken.
5128 input_data.push_back(static_cast<float>(m2u_nh[i]));
348
2/2
✓ Branch 142 → 140 taken 5128 times.
✓ Branch 142 → 143 taken 2564 times.
7692 for(int i = 0; i < m_nh; ++i)
349
1/2
✓ Branch 140 → 141 taken 5128 times.
✗ Branch 140 → 152 not taken.
5128 input_data.push_back(static_cast<float>(m2v_nh[i]));
350
351
352
1/2
✓ Branch 143 → 144 taken 2564 times.
✗ Branch 143 → 152 not taken.
2564 input_data.push_back(static_cast<float>(num_photons_0_1));
353
1/2
✓ Branch 144 → 145 taken 2564 times.
✗ Branch 144 → 152 not taken.
2564 input_data.push_back(static_cast<float>(num_photons_0_2));
354
1/4
✓ Branch 145 → 146 taken 2564 times.
✗ Branch 145 → 152 not taken.
✗ Branch 152 → 153 not taken.
✗ Branch 152 → 155 not taken.
2564 input_data.push_back(static_cast<float>(num_photons_0_35));
355
356
1/2
✓ Branch 146 → 147 taken 2564 times.
✗ Branch 146 → 152 not taken.
2564 return ClassifyPhoton(input_data, runnum);
357 }
358
359 2564 bool PhotonGBTFilter::ClassifyPhoton(std::vector<float> const& input_data, int const runnum) const
360 {
361 2564 auto modelFunction = getModelFunction(runnum);
362 double sigmoid_x = modelFunction(input_data);
363 2564 double prediction = 1 / (1 + exp(-sigmoid_x));
364
1/2
✓ Branch 6 → 7 taken 2564 times.
✗ Branch 6 → 8 not taken.
5128 return (prediction > o_threshold);
365 }
366
367 2000 std::map<int, PhotonGBTFilter::calo_row_data> PhotonGBTFilter::GetCaloMap(hipo::bank const& bank) const
368 {
369 std::map<int, PhotonGBTFilter::calo_row_data> calo_map;
370 // Loop over REC::Calorimeter rows
371 // Here we use bank.getRows() to purposefully ignore upstream filters
372
2/2
✓ Branch 40 → 3 taken 12258 times.
✓ Branch 40 → 41 taken 2000 times.
14258 for(int row = 0; row < bank.getRows(); row++) {
373 12258 auto pindex = bank.getShort("pindex", row);
374 12258 auto x = bank.getFloat("x", row);
375 12258 auto y = bank.getFloat("y", row);
376 12258 auto z = bank.getFloat("z", row);
377 12258 auto m2u = bank.getFloat("m2u", row);
378 12258 auto m2v = bank.getFloat("m2v", row);
379 12258 auto layer = bank.getInt("layer", row);
380 12258 auto e = bank.getFloat("energy", row);
381
382 // Ensure an entry exists in the map for the given pindex
383
2/2
✓ Branch 20 → 21 taken 7572 times.
✓ Branch 20 → 23 taken 4686 times.
12258 if(calo_map.find(pindex) == calo_map.end()) {
384
1/2
✓ Branch 21 → 22 taken 7572 times.
✗ Branch 21 → 42 not taken.
7572 calo_map[pindex] = PhotonGBTFilter::calo_row_data();
385 }
386
387
3/4
✓ Branch 23 → 24 taken 6292 times.
✓ Branch 23 → 31 taken 3706 times.
✓ Branch 23 → 35 taken 2260 times.
✗ Branch 23 → 39 not taken.
12258 switch(layer) {
388 6292 case 1: // pcal
389
1/2
✓ Branch 24 → 25 taken 6292 times.
✗ Branch 24 → 42 not taken.
6292 calo_map[pindex].pcal_x = x;
390
1/2
✓ Branch 25 → 26 taken 6292 times.
✗ Branch 25 → 42 not taken.
6292 calo_map[pindex].pcal_y = y;
391
1/2
✓ Branch 26 → 27 taken 6292 times.
✗ Branch 26 → 42 not taken.
6292 calo_map[pindex].pcal_z = z;
392
1/2
✓ Branch 27 → 28 taken 6292 times.
✗ Branch 27 → 42 not taken.
6292 calo_map[pindex].pcal_e = e;
393
1/2
✓ Branch 28 → 29 taken 6292 times.
✗ Branch 28 → 42 not taken.
6292 calo_map[pindex].pcal_m2u = m2u;
394
1/2
✓ Branch 29 → 30 taken 6292 times.
✗ Branch 29 → 42 not taken.
6292 calo_map[pindex].pcal_m2v = m2v;
395 6292 break;
396 3706 case 4: // ecin
397
1/2
✓ Branch 31 → 32 taken 3706 times.
✗ Branch 31 → 42 not taken.
3706 calo_map[pindex].ecin_x = x;
398
1/2
✓ Branch 32 → 33 taken 3706 times.
✗ Branch 32 → 42 not taken.
3706 calo_map[pindex].ecin_y = y;
399
1/2
✓ Branch 33 → 34 taken 3706 times.
✗ Branch 33 → 42 not taken.
3706 calo_map[pindex].ecin_z = z;
400 3706 break;
401 2260 case 7: // ecout
402
1/2
✓ Branch 35 → 36 taken 2260 times.
✗ Branch 35 → 42 not taken.
2260 calo_map[pindex].ecout_x = x;
403
1/2
✓ Branch 36 → 37 taken 2260 times.
✗ Branch 36 → 42 not taken.
2260 calo_map[pindex].ecout_y = y;
404
1/2
✓ Branch 37 → 38 taken 2260 times.
✗ Branch 37 → 42 not taken.
2260 calo_map[pindex].ecout_z = z;
405 2260 break;
406 }
407 }
408 2000 return calo_map;
409 }
410
411 13818 ROOT::Math::XYZVector PhotonGBTFilter::GetParticleCaloVector(PhotonGBTFilter::calo_row_data calo_row) const
412 {
413 // Determine the 3-vector location of where the photon of interest's calo deposition is
414 // First we check the pcal coords, then ecin, then ecout
415 ROOT::Math::XYZVector v;
416
2/2
✓ Branch 2 → 3 taken 2004 times.
✓ Branch 2 → 6 taken 11814 times.
13818 if(calo_row.pcal_x == 0) {
417
2/2
✓ Branch 3 → 4 taken 756 times.
✓ Branch 3 → 5 taken 1248 times.
2004 if(calo_row.ecin_x == 0) {
418 756 v.SetXYZ(calo_row.ecout_x, calo_row.ecout_y, calo_row.ecout_z);
419 }
420 else {
421 1248 v.SetXYZ(calo_row.ecin_x, calo_row.ecin_y, calo_row.ecin_z);
422 }
423 }
424 else {
425 11814 v.SetXYZ(calo_row.pcal_x, calo_row.pcal_y, calo_row.pcal_z);
426 }
427 13818 return v;
428 }
429
430 2564 std::function<double(std::vector<float> const&)> PhotonGBTFilter::getModelFunction(int runnum) const
431 {
432
433
1/2
✓ Branch 8 → 3 taken 17948 times.
✗ Branch 8 → 9 not taken.
17948 for(auto const& entry : modelMap) {
434
4/6
✓ Branch 3 → 4 taken 17948 times.
✗ Branch 3 → 7 not taken.
✓ Branch 4 → 5 taken 2564 times.
✓ Branch 4 → 7 taken 15384 times.
✓ Branch 5 → 6 taken 2564 times.
✗ Branch 5 → 7 not taken.
17948 if(runnum >= std::get<0>(entry.first) && runnum <= std::get<1>(entry.first) && o_pass == std::get<2>(entry.first)) {
435 2564 return entry.second;
436 }
437 }
438
439 // Default to RGA inbending pass1 if no match found
440 m_log->Warn("Run Number {} with pass {} has no matching PhotonGBT model...Defaulting to RGA inbending pass1...", runnum, o_pass);
441 return [](std::vector<float> const& data) { return ApplyCatboostModel_RGA_inbending_pass1(data); };
442 }
443
444 1 void PhotonGBTFilter::Stop()
445 {
446 1 }
447
448 }
449