GCC Code Coverage Report


Directory: ./
File: examples/iguana_ex_cpp_01_action_functions.cc
Date: 2025-09-03 22:39:58
Exec Total Coverage
Lines: 53 53 100.0%
Functions: 1 1 100.0%
Branches: 71 134 53.0%

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