GCC Code Coverage Report


Directory: ./
File: examples/iguana_ex_cpp_01_action_functions.cc
Date: 2025-11-25 17:57:04
Coverage Exec Excl Total
Lines: 100.0% 54 0 54
Functions: 100.0% 1 0 1
Branches: 52.9% 72 0 136

Line Branch Exec Source
1 /// @begin_doc_example{cpp}
2 /// @file iguana_ex_cpp_01_action_functions.cc
3 /// @brief Example using Iguana action functions on data from bank rows. This is useful for
4 /// users who do not have the `hipo::bank` objects, instead only having the numerical data from them.
5 /// @par Usage
6 /// ```bash
7 /// iguana_ex_cpp_01_action_functions [HIPO_FILE] [NUM_EVENTS]
8 ///
9 /// HIPO_FILE the HIPO file to analyze
10 ///
11 /// NUM_EVENTS the number of events to analyze;
12 /// set to zero to analyze all events
13 /// ```
14 ///
15 /// @note while this example _does_ use `hipo::bank` objects to read HIPO data, it demonstrates
16 /// using action functions called with the data _from_ these banks. We only use `hipo::bank` to
17 /// _obtain_ these data, since it is convenient that we don't have to use another HIPO reader,
18 /// which would introduce another build dependency to this program.
19 ///
20 /// @end_doc_example
21 #include <hipo4/reader.h>
22 #include <iguana/algorithms/clas12/EventBuilderFilter/Algorithm.h>
23 #include <iguana/algorithms/clas12/SectorFinder/Algorithm.h>
24 #include <iguana/algorithms/clas12/rga/MomentumCorrection/Algorithm.h>
25
26 /// main function
27 1 int main(int argc, char** argv)
28 {
29
30 // parse arguments
31
1/2
✓ Branch 2 → 3 taken 1 time.
✗ Branch 2 → 12 not taken.
1 char const* inFileName = argc > 1 ? argv[1] : "data.hipo";
32
1/2
✓ Branch 3 → 4 taken 1 time.
✗ Branch 3 → 12 not taken.
1 int const numEvents = argc > 2 ? std::stoi(argv[2]) : 3;
33
34 // read input file
35
1/2
✓ Branch 13 → 14 taken 1 time.
✗ Branch 13 → 193 not taken.
1 hipo::reader reader(inFileName, {0});
36
37 // set list of banks to be read
38
1/2
✓ Branch 17 → 18 taken 1 time.
✗ Branch 17 → 295 not taken.
2 hipo::banklist banks = reader.getBanks({"REC::Particle",
39 "RUN::config",
40 "REC::Track",
41 "REC::Calorimeter",
42
1/2
✓ Branch 18 → 19 taken 1 time.
✗ Branch 18 → 197 not taken.
1 "REC::Scintillator"});
43
44 // get bank index, for each bank we want to use after Iguana algorithms run
45
2/4
✓ Branch 20 → 21 taken 1 time.
✗ Branch 20 → 293 not taken.
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 199 not taken.
1 auto b_particle = iguana::tools::GetBankIndex(banks, "REC::Particle");
46
2/4
✓ Branch 27 → 28 taken 1 time.
✗ Branch 27 → 293 not taken.
✓ Branch 28 → 29 taken 1 time.
✗ Branch 28 → 205 not taken.
1 auto b_config = iguana::tools::GetBankIndex(banks, "RUN::config");
47
2/4
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 293 not taken.
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 211 not taken.
1 auto b_track = iguana::tools::GetBankIndex(banks, "REC::Track");
48
2/4
✓ Branch 41 → 42 taken 1 time.
✗ Branch 41 → 293 not taken.
✓ Branch 42 → 43 taken 1 time.
✗ Branch 42 → 217 not taken.
1 auto b_calorimeter = iguana::tools::GetBankIndex(banks, "REC::Calorimeter");
49
2/4
✓ Branch 48 → 49 taken 1 time.
✗ Branch 48 → 293 not taken.
✓ Branch 49 → 50 taken 1 time.
✗ Branch 49 → 223 not taken.
1 auto b_scintillator = iguana::tools::GetBankIndex(banks, "REC::Scintillator");
50
51 // set the concurrency model to single-threaded, since this example is single-threaded;
52 // not doing this will use the thread-safe model, `"memoize"`
53
2/4
✓ Branch 55 → 56 taken 1 time.
✗ Branch 55 → 293 not taken.
✓ Branch 56 → 57 taken 1 time.
✗ Branch 56 → 229 not taken.
1 iguana::GlobalConcurrencyModel = "single";
54
55 // create the algorithms
56
1/2
✓ Branch 62 → 63 taken 1 time.
✗ Branch 62 → 293 not taken.
1 iguana::clas12::EventBuilderFilter algo_eventbuilder_filter; // filter by Event Builder PID (a filter algorithm)
57
1/2
✓ Branch 63 → 64 taken 1 time.
✗ Branch 63 → 291 not taken.
1 iguana::clas12::SectorFinder algo_sector_finder; // get the sector for each particle (a creator algorithm)
58
1/2
✓ Branch 64 → 65 taken 1 time.
✗ Branch 64 → 289 not taken.
1 iguana::clas12::rga::MomentumCorrection algo_momentum_correction; // momentum corrections (a transformer algorithm)
59
60 // set log levels
61
2/4
✓ Branch 65 → 66 taken 1 time.
✗ Branch 65 → 287 not taken.
✓ Branch 66 → 67 taken 1 time.
✗ Branch 66 → 235 not taken.
1 algo_eventbuilder_filter.SetOption("log", "info");
62
2/4
✓ Branch 72 → 73 taken 1 time.
✗ Branch 72 → 287 not taken.
✓ Branch 73 → 74 taken 1 time.
✗ Branch 73 → 241 not taken.
1 algo_sector_finder.SetOption("log", "info");
63
2/4
✓ Branch 79 → 80 taken 1 time.
✗ Branch 79 → 287 not taken.
✓ Branch 80 → 81 taken 1 time.
✗ Branch 80 → 247 not taken.
1 algo_momentum_correction.SetOption("log", "info");
64
65 // set algorithm options
66 // NOTE: this can also be done in a config file
67
4/10
✓ Branch 86 → 87 taken 1 time.
✗ Branch 86 → 287 not taken.
✓ Branch 87 → 88 taken 1 time.
✗ Branch 87 → 259 not taken.
✓ Branch 88 → 89 taken 1 time.
✗ Branch 88 → 253 not taken.
✓ Branch 97 → 98 taken 1 time.
✗ Branch 97 → 100 not taken.
✗ Branch 259 → 260 not taken.
✗ Branch 259 → 262 not taken.
2 algo_eventbuilder_filter.SetOption<std::vector<int>>("pids", {11, 211, -211});
68
69 // start the algorithms
70
1/2
✓ Branch 100 → 101 taken 1 time.
✗ Branch 100 → 287 not taken.
1 algo_eventbuilder_filter.Start();
71
1/2
✓ Branch 101 → 102 taken 1 time.
✗ Branch 101 → 287 not taken.
1 algo_sector_finder.Start();
72
1/2
✓ Branch 102 → 173 taken 1 time.
✗ Branch 102 → 287 not taken.
1 algo_momentum_correction.Start();
73
74 // run the algorithms on each event
75 int iEvent = 0;
76
5/8
✓ Branch 173 → 174 taken 101 times.
✗ Branch 173 → 287 not taken.
✓ Branch 174 → 175 taken 101 times.
✗ Branch 174 → 178 not taken.
✓ Branch 175 → 176 taken 101 times.
✗ Branch 175 → 177 not taken.
✓ Branch 176 → 177 taken 100 times.
✓ Branch 176 → 178 taken 1 time.
101 while(reader.next(banks) && (numEvents == 0 || iEvent++ < numEvents)) {
77
78 // get the banks for this event
79
1/2
✓ Branch 177 → 103 taken 100 times.
✗ Branch 177 → 287 not taken.
100 auto& particleBank = banks.at(b_particle);
80
1/2
✓ Branch 103 → 104 taken 100 times.
✗ Branch 103 → 287 not taken.
100 auto& configBank = banks.at(b_config);
81
1/2
✓ Branch 104 → 105 taken 100 times.
✗ Branch 104 → 287 not taken.
100 auto& trackBank = banks.at(b_track);
82
1/2
✓ Branch 105 → 106 taken 100 times.
✗ Branch 105 → 287 not taken.
100 auto& calorimeterBank = banks.at(b_calorimeter);
83
1/2
✓ Branch 106 → 107 taken 100 times.
✗ Branch 106 → 287 not taken.
100 auto& scintillatorBank = banks.at(b_scintillator);
84
85 // show the particle bank
86 // particleBank.show();
87
88 // print the event number
89
1/2
✓ Branch 109 → 110 taken 100 times.
✗ Branch 109 → 263 not taken.
200 fmt::print("evnum = {}\n", configBank.getInt("event", 0));
90
91 // we'll need information from all the rows of REC::Track,Calorimeter,Scintilator,
92 // in order to get the sector information for each particle
93 // FIXME: there are vectorized accessors, but we cannot use them yet; see https://github.com/gavalian/hipo/issues/72
94 // until then, we fill `std::vector`s manually
95 std::vector<int> trackBank_sectors;
96 std::vector<int> trackBank_pindices;
97 std::vector<int> calorimeterBank_sectors;
98 std::vector<int> calorimeterBank_pindices;
99 std::vector<int> scintillatorBank_sectors;
100 std::vector<int> scintillatorBank_pindices;
101
3/4
✓ Branch 109 → 110 taken 100 times.
✗ Branch 109 → 263 not taken.
✓ Branch 116 → 111 taken 271 times.
✓ Branch 116 → 117 taken 100 times.
371 for(auto const& r : trackBank.getRowList()) {
102
1/2
✓ Branch 112 → 113 taken 271 times.
✗ Branch 112 → 263 not taken.
271 trackBank_sectors.push_back(trackBank.getByte("sector", r));
103
1/2
✓ Branch 114 → 115 taken 271 times.
✗ Branch 114 → 263 not taken.
271 trackBank_pindices.push_back(trackBank.getShort("pindex", r));
104 }
105
3/4
✓ Branch 117 → 118 taken 100 times.
✗ Branch 117 → 263 not taken.
✓ Branch 124 → 119 taken 585 times.
✓ Branch 124 → 125 taken 100 times.
685 for(auto const& r : calorimeterBank.getRowList()) {
106
1/2
✓ Branch 120 → 121 taken 585 times.
✗ Branch 120 → 263 not taken.
585 calorimeterBank_sectors.push_back(calorimeterBank.getByte("sector", r));
107
1/2
✓ Branch 122 → 123 taken 585 times.
✗ Branch 122 → 263 not taken.
585 calorimeterBank_pindices.push_back(calorimeterBank.getShort("pindex", r));
108 }
109
3/4
✓ Branch 125 → 126 taken 100 times.
✗ Branch 125 → 263 not taken.
✓ Branch 132 → 127 taken 637 times.
✓ Branch 132 → 133 taken 100 times.
737 for(auto const& r : scintillatorBank.getRowList()) {
110
1/2
✓ Branch 128 → 129 taken 637 times.
✗ Branch 128 → 263 not taken.
637 scintillatorBank_sectors.push_back(scintillatorBank.getByte("sector", r));
111
1/4
✓ Branch 130 → 131 taken 637 times.
✗ Branch 130 → 263 not taken.
✗ Branch 263 → 264 not taken.
✗ Branch 263 → 266 not taken.
637 scintillatorBank_pindices.push_back(scintillatorBank.getShort("pindex", r));
112 }
113
114 // loop over bank rows
115
3/4
✓ Branch 133 → 134 taken 100 times.
✗ Branch 133 → 263 not taken.
✓ Branch 153 → 135 taken 683 times.
✓ Branch 153 → 154 taken 100 times.
783 for(auto const& row : particleBank.getRowList()) {
116
117 // check the PID with EventBuilderFilter
118 683 auto pid = particleBank.getInt("pid", row);
119
3/4
✓ Branch 136 → 137 taken 683 times.
✗ Branch 136 → 263 not taken.
✓ Branch 137 → 138 taken 201 times.
✓ Branch 137 → 152 taken 482 times.
683 if(algo_eventbuilder_filter.Filter(pid)) {
120
121 // get the sector for this particle; this is using a vector action function, so
122 // many of its arguments are of type `std::vector`
123
1/2
✓ Branch 138 → 139 taken 201 times.
✗ Branch 138 → 263 not taken.
201 auto sector = algo_sector_finder.GetStandardSector(
124 trackBank_sectors,
125 trackBank_pindices,
126 calorimeterBank_sectors,
127 calorimeterBank_pindices,
128 scintillatorBank_sectors,
129 scintillatorBank_pindices,
130 row);
131
132 // correct the particle momentum
133
1/2
✓ Branch 143 → 144 taken 201 times.
✗ Branch 143 → 263 not taken.
402 auto [px, py, pz] = algo_momentum_correction.Transform(
134 201 particleBank.getFloat("px", row),
135 201 particleBank.getFloat("py", row),
136 201 particleBank.getFloat("pz", row),
137 sector,
138 pid,
139 configBank.getFloat("torus", 0));
140
141 // then print the result
142
1/2
✓ Branch 145 → 146 taken 201 times.
✗ Branch 145 → 263 not taken.
201 fmt::print("Analysis Particle PDG = {}\n", pid);
143 201 fmt::print(" sector = {}\n", sector);
144
1/2
✓ Branch 150 → 151 taken 201 times.
✗ Branch 150 → 263 not taken.
402 fmt::print(" p_old = ({:11.5f}, {:11.5f}, {:11.5f})\n", particleBank.getFloat("px", row), particleBank.getFloat("py", row), particleBank.getFloat("pz", row));
145 201 fmt::print(" p_new = ({:11.5f}, {:11.5f}, {:11.5f})\n", px, py, pz);
146 }
147 }
148 }
149
150 // stop the algorithms
151
1/2
✓ Branch 178 → 179 taken 1 time.
✗ Branch 178 → 287 not taken.
1 algo_eventbuilder_filter.Stop();
152
1/2
✓ Branch 179 → 180 taken 1 time.
✗ Branch 179 → 287 not taken.
1 algo_sector_finder.Stop();
153
1/2
✓ Branch 180 → 181 taken 1 time.
✗ Branch 180 → 287 not taken.
1 algo_momentum_correction.Stop();
154 return 0;
155 1 }
156