GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 80.8% 21 / 0 / 26
Functions: 87.5% 7 / 0 / 8
Branches: 33.8% 25 / 0 / 74

src/iguana/algorithms/AlgorithmSequence.h
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 28 times.
✗ Branch 2 → 6 not taken.
✗ Branch 5 → 7 not taken.
✓ Branch 5 → 8 taken 28 times.
✓ Branch 9 → 10 taken 28 times.
✗ Branch 9 → 32 not taken.
✓ Branch 10 → 11 taken 28 times.
✗ Branch 10 → 17 not taken.
✓ Branch 17 → 18 taken 28 times.
✗ Branch 17 → 40 not taken.
✓ Branch 24 → 25 taken 28 times.
✗ Branch 24 → 40 not taken.
✗ Branch 32 → 33 not taken.
✗ Branch 32 → 39 not taken.
205 DEFINE_IGUANA_ALGORITHM(AlgorithmSequence, seq)
49
50 private: // hooks
51 void StartHook(hipo::banklist& banks) override;
52 bool RunHook(hipo::banklist& banks) const override;
53 void StopHook() override;
54
55 public:
56
57 /// Create and add an algorithm to the sequence, by name.
58 ///
59 /// **Example**
60 /// @code
61 /// Add("iguana::MyAlgorithm", "my_algorithm_name");
62 /// @endcode
63 /// @param algo_class_name the name of the algorithm class
64 /// @param algo_instance_name a user-specified unique name for this algorithm instance;
65 /// if not specified, `algo_class_name` will be used
66
7/18
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 121 not taken.
✓ Branch 21 → 22 taken 1 time.
✗ Branch 21 → 197 not taken.
✗ Branch 26 → 27 not taken.
✗ Branch 26 → 121 not taken.
✓ Branch 28 → 29 taken 8 times.
✗ Branch 28 → 92 not taken.
✓ Branch 34 → 35 taken 1 time.
✗ Branch 34 → 197 not taken.
✓ Branch 37 → 38 taken 17 times.
✗ Branch 37 → 92 not taken.
✓ Branch 44 → 45 taken 17 times.
✗ Branch 44 → 92 not taken.
✓ Branch 47 → 48 taken 1 time.
✗ Branch 47 → 197 not taken.
✓ Branch 60 → 61 taken 1 time.
✗ Branch 60 → 197 not taken.
79 void Add(std::string const& algo_class_name, std::string const& algo_instance_name = "");
67
68 /// Create and add an algorithm to the sequence.
69 ///
70 /// **Example**
71 /// @code
72 /// Add<iguana::MyAlgorithm>("my_algorithm_name");
73 /// @endcode
74 /// @param algo_instance_name a user-specified unique name for this algorithm instance;
75 /// if not specified, the class name will be used
76 template <class ALGORITHM>
77 void Add(std::string_view algo_instance_name = "")
78 {
79 if(algo_instance_name == "")
80 Add(std::make_unique<ALGORITHM>());
81 else
82 Add(std::make_unique<ALGORITHM>(algo_instance_name));
83 }
84
85 /// Add an existing algorithm to the sequence. The `AlgorithmSequence` instance will take ownership of the algorithm
86 /// (if it is an `lvalue`, you will have to `std::move` it).
87 ///
88 /// **Example**
89 /// @code
90 /// Add(std::make_unique<iguana::MyAlgorithm>("my_algorithm_name"));
91 /// @endcode
92 /// @param algo the algorithm
93 void Add(algo_t&& algo);
94
95 /// Get an algorithm by its instance name
96 ///
97 /// **Example**
98 /// @code
99 /// Get<iguana::MyAlgorithm>("my_algorithm_name");
100 /// @endcode
101 /// @param algo_instance_name the instance name of the algorithm
102 /// @return a reference to the algorithm
103 template <class ALGORITHM = Algorithm>
104 1901 ALGORITHM* Get(std::string const& algo_instance_name)
105 {
106
2/4
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.
iguana::Algorithm* iguana::AlgorithmSequence::Get<iguana::Algorithm>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&):
✓ Branch 5 → 6 taken 62 times.
✗ Branch 5 → 8 not taken.
1901 if(auto it{m_algo_names.find(algo_instance_name)}; it != m_algo_names.end())
107
1/2
✓ Branch 7 → 8 taken 1839 times.
✗ Branch 7 → 13 not taken.
1901 return dynamic_cast<ALGORITHM*>(m_sequence[it->second].get());
108 m_log->Error("cannot find algorithm '{}' in sequence", algo_instance_name);
109 throw std::runtime_error("cannot Get algorithm");
110 }
111
112 /// Set an algorithm option
113 /// @see `Algorithm::SetOption`
114 /// @param algo_instance_name the algorithm instance name
115 /// @param key the option name
116 /// @param val the option value
117 template <typename OPTION_TYPE>
118 8 void SetOption(std::string const& algo_instance_name, std::string const& key, const OPTION_TYPE val)
119 {
120
8/18
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.
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 6 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.
14 Get<Algorithm>(algo_instance_name)->SetOption(key, val);
121 12 }
122
123 /// @brief Set an algorithm log level
124 /// @see `Logger::Level` for available levels
125 /// @param algo_instance_name the algorithm instance name
126 /// @param lev the log level name
127 17 void SetLogLevel(std::string const& algo_instance_name, std::string const& lev)
128 {
129
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 17 times.
17 Get<Algorithm>(algo_instance_name)->SetLogLevel(lev);
130 17 }
131
132 /// Set the name of this sequence
133 /// @param name the new name
134 void SetName(std::string_view name);
135
136 /// Get the list of created bank names, for creator-type algorithms
137 /// @see `AlgorithmSequence::GetCreatedBankName` for algorithms which create only one bank
138 /// @param algo_instance_name the algorithm instance name
139 /// @returns the list of new bank names
140 std::vector<std::string> GetCreatedBankNames(std::string const& algo_instance_name) const noexcept(false);
141
142 /// Get the created bank name, for creator-type algorithms which create only one new bank
143 /// @see `AlgorithmSequence::GetCreatedBankNames` for algorithms which create more than one new bank
144 /// @param algo_instance_name the algorithm instance name
145 /// @returns the new bank name
146 std::string GetCreatedBankName(std::string const& algo_instance_name) const noexcept(false);
147
148 /// Print the names of the algorithms in this sequence
149 /// @param level the log level of the printout
150 void PrintSequence(Logger::Level level = Logger::info) const;
151
152 /// @brief Set a custom configuration file for each algorithm in the sequence
153 ///
154 /// Use this function if you have a single configuration file for all the
155 /// algorithms in your sequence
156 /// @param name the configuration file name
157 void SetConfigFileForEachAlgorithm(std::string const& name);
158
159 /// @brief Set a custom configuration file directory for each algorithm in the sequence
160 ///
161 /// Use this function if you have a single configuration file directory for all the
162 /// algorithms in your sequence
163 /// @param name the directory name
164 void SetConfigDirectoryForEachAlgorithm(std::string const& name);
165
166 /// @brief Call a function for each algorithm in the sequence
167 ///
168 /// Use as:
169 /// ```cpp
170 /// ForEachAlgorithm([](auto& algo){ algo->...; });
171 /// ```
172 /// @param func the function to call for each algorithm `algo`
173 void ForEachAlgorithm(std::function<void(algo_t&)> func);
174
175 /// Get the index of a bank in a `hipo::banklist`; throws an exception if the bank is not found
176 /// @param banks the list of banks this algorithm will use
177 /// @param bank_name the name of the bank
178 /// @param algo_instance_name the algorithm instance name,
179 /// to disambiguate the case where two algorithms create a bank with the same name (_cf._ `variant` parameter of tools::GetBankIndex)
180 /// @returns the `hipo::banklist` index of the bank
181 /// @see tools::GetBankIndex for a function that is independent of algorithm
182 /// @see GetCreatedBankIndex, a convenience method for _Iguana-created_ banks
183 hipo::banklist::size_type GetBankIndex(
184 hipo::banklist& banks,
185 std::string const& bank_name,
186 std::string const& algo_instance_name) const noexcept(false);
187
188 /// 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
189 /// creates more than one bank
190 /// @param banks the list of banks this algorithm will use
191 /// @param algo_instance_name the algorithm instance name,
192 /// to disambiguate the case where two algorithms create a bank with the same name (_cf._ `variant` parameter of tools::GetBankIndex)
193 /// @returns the `hipo::banklist` index of the bank
194 /// @see GetBankIndex for a more general method
195 hipo::banklist::size_type GetCreatedBankIndex(
196 hipo::banklist& banks,
197 std::string const& algo_instance_name) const noexcept(false);
198
199 private:
200
201 /// The sequence of algorithms
202 std::vector<algo_t> m_sequence;
203
204 /// Association of algorithm name to its index in the sequence
205 std::unordered_map<std::string, std::vector<algo_t>::size_type> m_algo_names;
206 };
207 }
208