GCC Code Coverage Report


Directory: ./
File: src/iguana/algorithms/AlgorithmSequence.h
Date: 2025-11-25 17:57:04
Coverage Exec Excl Total
Lines: 80.8% 21 0 26
Functions: 87.5% 7 0 8
Branches: 35.1% 33 0 94

Line Branch Exec Source
1 #pragma once
2
3 #include "Algorithm.h"
4
5 namespace iguana {
6
7 /// @algo_brief{An algorithm that can run a sequence of algorithms}
8 ///
9 /// This algorithm requires the use of `hipo::banklist`; there are neither `Run` functions which take
10 /// individual `hipo::bank` parameters nor action functions. If you do not use `hipo::banklist`, you
11 /// should use individual algorithms instead of this sequencing algorithm.
12 ///
13 /// Use the `Add` function to add algorithms to the sequence; the order is important, since
14 /// the `Start`, `Run`, and `Stop` methods will sequentially call the corresponding algorithms' methods,
15 /// in the same order that the algorithms were added to the sequence by `Add`.
16 ///
17 /// If an algorithm's `Run` function returns `false`, _i.e._, its "event-level" filter returns `false`, then `AlgorithmSequence`'s
18 /// `Run` function will stop immediately and return `false`.
19 ///
20 /// @par Custom Event Filters
21 /// If an algorithm's event-level filter is not adequate for your needs, and you want to tighten or override
22 /// an algorithm's event-level filter, _i.e._, you want more control over how that algorithm's `Run` function return
23 /// value is used, we recommond defining _two_ `AlgorithmSequence` instances. For example, suppose you want a tighter
24 /// event-level filter from or after `algo2` in the sequence `algo1`, `algo2`, `algo3`, `algo4`; you may implement this by
25 /// using _two_ sequences, where the first ends at `algo2`:
26 /// @code
27 /// // define sequences
28 /// iguana::AlgorithmSequence seq1
29 /// seq1.Add("algo1");
30 /// seq1.Add("algo2");
31 /// iguana::AlgorithmSequence seq2
32 /// seq2.Add("algo3");
33 /// seq2.Add("algo4");
34 /// // start them
35 /// seq1.Start(banks);
36 /// seq2.Start(banks);
37 /// @endcode
38 /// Then, in your event loop, call your tighter filter between the sequences' `Run` calls:
39 /// @code
40 /// if(!seq1.Run(banks)) continue;
41 /// if( /*your event filter */) continue;
42 /// if(!seq2.Run(banks)) continue;
43 /// @endcode
44 ///
45 class AlgorithmSequence : public Algorithm
46 {
47
48
6/14
✓ Branch 2 → 3 taken 27 times.
✗ Branch 2 → 6 not taken.
✗ Branch 5 → 7 not taken.
✓ Branch 5 → 8 taken 27 times.
✓ Branch 9 → 10 taken 27 times.
✗ Branch 9 → 32 not taken.
✓ Branch 10 → 11 taken 27 times.
✗ Branch 10 → 17 not taken.
✓ Branch 17 → 18 taken 27 times.
✗ Branch 17 → 40 not taken.
✓ Branch 24 → 25 taken 27 times.
✗ Branch 24 → 40 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 39 not taken.
198 DEFINE_IGUANA_ALGORITHM(AlgorithmSequence, seq)
49
50 public:
51
52 void Start(hipo::banklist& banks) override;
53 bool Run(hipo::banklist& banks) const override;
54 void Stop() override;
55
56 /// Create and add an algorithm to the sequence, by name.
57 ///
58 /// **Example**
59 /// @code
60 /// Add("iguana::MyAlgorithm", "my_algorithm_name");
61 /// @endcode
62 /// @param algo_class_name the name of the algorithm class
63 /// @param algo_instance_name a user-specified unique name for this algorithm instance;
64 /// if not specified, `algo_class_name` will be used
65
7/18
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 137 not taken.
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 298 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 137 not taken.
✓ Branch 28 → 29 taken 6 times.
✗ Branch 28 → 108 not taken.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 298 not taken.
✓ Branch 37 → 38 taken 16 times.
✗ Branch 37 → 108 not taken.
✓ Branch 44 → 45 taken 16 times.
✗ Branch 44 → 108 not taken.
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 298 not taken.
✓ Branch 60 → 61 taken 1 time.
✗ Branch 60 → 298 not taken.
73 void Add(std::string const& algo_class_name, std::string const& algo_instance_name = "");
66
67 /// Create and add an algorithm to the sequence.
68 ///
69 /// **Example**
70 /// @code
71 /// Add<iguana::MyAlgorithm>("my_algorithm_name");
72 /// @endcode
73 /// @param algo_instance_name a user-specified unique name for this algorithm instance;
74 /// if not specified, the class name will be used
75 template <class ALGORITHM>
76 void Add(std::string_view algo_instance_name = "")
77 {
78 if(algo_instance_name == "")
79 Add(std::make_unique<ALGORITHM>());
80 else
81 Add(std::make_unique<ALGORITHM>(algo_instance_name));
82 }
83
84 /// Add an existing algorithm to the sequence. The `AlgorithmSequence` instance will take ownership of the algorithm
85 /// (if it is an `lvalue`, you will have to `std::move` it).
86 ///
87 /// **Example**
88 /// @code
89 /// Add(std::make_unique<iguana::MyAlgorithm>("my_algorithm_name"));
90 /// @endcode
91 /// @param algo the algorithm
92 void Add(algo_t&& algo);
93
94 /// Get an algorithm by its instance name
95 ///
96 /// **Example**
97 /// @code
98 /// Get<iguana::MyAlgorithm>("my_algorithm_name");
99 /// @endcode
100 /// @param algo_instance_name the instance name of the algorithm
101 /// @return a reference to the algorithm
102 template <class ALGORITHM = Algorithm>
103 1906 ALGORITHM* Get(std::string const& algo_instance_name)
104 {
105
2/4
iguana::Algorithm* iguana::AlgorithmSequence::Get<iguana::Algorithm>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✓ Branch 5 → 6 taken 67 times.
✗ Branch 5 → 8 not taken.
iguana::clas12::PhotonGBTFilter* iguana::AlgorithmSequence::Get<iguana::clas12::PhotonGBTFilter>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✓ Branch 5 → 6 taken 1839 times.
✗ Branch 5 → 9 not taken.
1906 if(auto it{m_algo_names.find(algo_instance_name)}; it != m_algo_names.end())
106
1/2
✓ Branch 7 → 8 taken 1839 times.
✗ Branch 7 → 13 not taken.
1906 return dynamic_cast<ALGORITHM*>(m_sequence[it->second].get());
107 m_log->Error("cannot find algorithm '{}' in sequence", algo_instance_name);
108 throw std::runtime_error("cannot Get algorithm");
109 }
110
111 /// Set an algorithm option
112 /// @see `Algorithm::SetOption`
113 /// @param algo_instance_name the algorithm instance name
114 /// @param key the option name
115 /// @param val the option value
116 template <typename OPTION_TYPE>
117 11 void SetOption(std::string const& algo_instance_name, std::string const& key, const OPTION_TYPE val)
118 {
119
17/40
void iguana::AlgorithmSequence::SetOption<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >):
✓ Branch 6 → 7 taken 2 times.
✗ Branch 6 → 18 not taken.
void iguana::AlgorithmSequence::SetOption<std::vector<int, std::allocator<int> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<int, std::allocator<int> >):
✓ Branch 4 → 5 taken 8 times.
✗ Branch 4 → 12 not taken.
✓ Branch 35 → 36 taken 2 times.
✗ Branch 35 → 151 not taken.
✗ Branch 35 → 177 not taken.
✓ Branch 36 → 37 taken 2 times.
✗ Branch 36 → 151 not taken.
✗ Branch 36 → 177 not taken.
✓ Branch 62 → 63 taken 1 time.
✗ Branch 62 → 228 not taken.
✓ Branch 63 → 64 taken 1 time.
✗ Branch 63 → 228 not taken.
✓ Branch 77 → 78 taken 1 time.
✗ Branch 77 → 240 not taken.
✓ Branch 78 → 79 taken 1 time.
✗ Branch 78 → 240 not taken.
✓ Branch 92 → 93 taken 1 time.
✗ Branch 92 → 252 not taken.
✓ Branch 93 → 94 taken 1 time.
✗ Branch 93 → 252 not taken.
void iguana::AlgorithmSequence::SetOption<std::vector<double, std::allocator<double> > >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::vector<double, std::allocator<double> >):
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 12 not taken.
None:
✓ Branch 22 → 23 taken 1 time.
✗ Branch 22 → 106 not taken.
✓ Branch 23 → 24 taken 1 time.
✗ Branch 23 → 106 not taken.
✓ Branch 35 → 36 taken 1 time.
✗ Branch 35 → 226 not taken.
✓ Branch 36 → 37 taken 1 time.
✗ Branch 36 → 226 not taken.
✓ Branch 49 → 50 taken 16 times.
✗ Branch 49 → 102 not taken.
✓ Branch 50 → 51 taken 16 times.
✗ Branch 50 → 102 not taken.
✗ Branch 53 → 54 not taken.
✗ Branch 53 → 131 not taken.
✗ Branch 54 → 55 not taken.
✗ Branch 54 → 131 not taken.
36 Get<Algorithm>(algo_instance_name)->SetOption(key, val);
120 34 }
121
122 /// Set the name of this sequence
123 /// @param name the new name
124 void SetName(std::string_view name);
125
126 /// Get the list of created bank names, for creator-type algorithms
127 /// @see `AlgorithmSequence::GetCreatedBankName` for algorithms which create only one bank
128 /// @param algo_instance_name the algorithm instance name
129 /// @returns the list of new bank names
130 std::vector<std::string> GetCreatedBankNames(std::string const& algo_instance_name) const noexcept(false);
131
132 /// Get the created bank name, for creator-type algorithms which create only one new bank
133 /// @see `AlgorithmSequence::GetCreatedBankNames` for algorithms which create more than one new bank
134 /// @param algo_instance_name the algorithm instance name
135 /// @returns the new bank name
136 std::string GetCreatedBankName(std::string const& algo_instance_name) const noexcept(false);
137
138 /// Print the names of the algorithms in this sequence
139 /// @param level the log level of the printout
140 void PrintSequence(Logger::Level level = Logger::info) const;
141
142 /// @brief Set a custom configuration file for each algorithm in the sequence
143 ///
144 /// Use this function if you have a single configuration file for all the
145 /// algorithms in your sequence
146 /// @param name the configuration file name
147 void SetConfigFileForEachAlgorithm(std::string const& name);
148
149 /// @brief Set a custom configuration file directory for each algorithm in the sequence
150 ///
151 /// Use this function if you have a single configuration file directory for all the
152 /// algorithms in your sequence
153 /// @param name the directory name
154 void SetConfigDirectoryForEachAlgorithm(std::string const& name);
155
156 /// @brief Call a function for each algorithm in the sequence
157 ///
158 /// Use as:
159 /// ```cpp
160 /// ForEachAlgorithm([](auto& algo){ algo->...; });
161 /// ```
162 /// @param func the function to call for each algorithm `algo`
163 void ForEachAlgorithm(std::function<void(algo_t&)> func);
164
165 /// Get the index of a bank in a `hipo::banklist`; throws an exception if the bank is not found
166 /// @param banks the list of banks this algorithm will use
167 /// @param bank_name the name of the bank
168 /// @param algo_instance_name the algorithm instance name,
169 /// to disambiguate the case where two algorithms create a bank with the same name (_cf._ `variant` parameter of tools::GetBankIndex)
170 /// @returns the `hipo::banklist` index of the bank
171 /// @see tools::GetBankIndex for a function that is independent of algorithm
172 /// @see GetCreatedBankIndex, a convenience method for _Iguana-created_ banks
173 hipo::banklist::size_type GetBankIndex(
174 hipo::banklist& banks,
175 std::string const& bank_name,
176 std::string const& algo_instance_name) const noexcept(false);
177
178 /// Get the index of an _Iguana-created_ bank in a `hipo::banklist`; throws an exception if the bank is not found, or if the algorithm
179 /// creates more than one bank
180 /// @param banks the list of banks this algorithm will use
181 /// @param algo_instance_name the algorithm instance name,
182 /// to disambiguate the case where two algorithms create a bank with the same name (_cf._ `variant` parameter of tools::GetBankIndex)
183 /// @returns the `hipo::banklist` index of the bank
184 /// @see GetBankIndex for a more general method
185 hipo::banklist::size_type GetCreatedBankIndex(
186 hipo::banklist& banks,
187 std::string const& algo_instance_name) const noexcept(false);
188
189 private:
190
191 /// The sequence of algorithms
192 std::vector<algo_t> m_sequence;
193
194 /// Association of algorithm name to its index in the sequence
195 std::unordered_map<std::string, std::vector<algo_t>::size_type> m_algo_names;
196 };
197 }
198