ATLAS Offline Software
RingerProcedureWrapper.icc
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // $Id: RingerProcedureWrapper.icc 791627 2017-01-10 04:45:53Z wsfreund $
6 #ifndef RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_ICC
7 #define RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_ICC
8 
9 //#undef NDEBUG
10 
11 #include<iostream>
12 // STL includes:
13 #include <vector>
14 #include <stdexcept>
15 
16 // Local includes:
17 #include "RingerProcedureWrapper.h"
18 #include "RingerSelectorTools/RingerSelectorToolsDefs.h"
19 #include "RingerSelectorTools/tools/VariableDependency.h"
20 #include "RingerSelectorTools/tools/TrackPatternsHolder.h"
21 #include "RingerSelectorTools/tools/IOHelperFcns.h"
22 
23 /**
24  * @brief Namespace dedicated for Ringer utilities
25  **/
26 namespace Ringer {
27 
28 namespace WrapperHelperFcns {
29 
30 // =============================================================================
31 /**
32  * @brief Returns eta bin number which is within region.
33  *
34  * Vector Dimension: [etBin][etaBin]:
35  **/
36 template<class vecType>
37 size_t findEtaBin( const float eta,
38  const typename std::vector< std::vector <
39  vecType*
40  >
41  > &varDepCol )
42 {
43  std::vector< vecType* > firstRow = varDepCol[0];
44  for (size_t idx = 0; idx < firstRow.size(); ++idx){
45  if (firstRow[idx]->isWithinEtaRange(eta)){
46  return idx;
47  }
48  }
49  throw std::runtime_error(std::string( "eta ") +
50  std::to_string(eta) + " is not inside Ringer Procedure range.");
51 }
52 
53 // =============================================================================
54 /**
55  * @brief Returns Et bin number which is within region.
56  *
57  * Vector Dimension: [etBin][etaBin]:
58  **/
59 template<class vecType>
60 size_t findEtBin( const float et,
61  const std::vector<
62  std::vector <
63  vecType*
64  >
65  > &varDepCol )
66 {
67  for (size_t idx = 0; idx < varDepCol.size(); ++idx){
68  if ( varDepCol[idx][0]->isWithinEtRange(et) ){
69  return idx;
70  }
71  }
72  throw std::runtime_error(std::string( "Et ") +
73  std::to_string(et) + " is not inside Ringer Procedure range.");
74 }
75 
76 // =============================================================================
77 template < typename vecType >
78 void checkCollection( const std::vector< std::vector<vecType*> > &vec,
79  EtaDependency etaDependency, EtDependency etDependency )
80 {
81  if (vec.empty()){
82  throw std::runtime_error(std::string(
83  "Dependency collection cannot be empty."));
84  }
85  if ( !static_cast<bool>(etDependency) && (vec.size() != 1) ) {
86  throw std::runtime_error(std::string(
87  "Cannot have EtIndependent vector with size different from unit."));
88  }
89  for ( size_t etIdx = 0; etIdx < vec.size() ; ++etIdx){
90  size_t etaSize = vec[etIdx].size();
91  if ( !etaSize ){
92  throw std::runtime_error(std::string(
93  "Dependency collection cannot have an empty vector."));
94  }
95  if ( !static_cast<bool>(etaDependency) && (etaSize != 1) ) {
96  throw std::runtime_error(std::string(
97  "Cannot have EtaIndependent vector with size "
98  "different from unit."));
99  }
100  for ( size_t etaIdx = 0; etaIdx < etaSize; ++etaIdx){
101  if( !vec[etIdx][etaIdx] ){
102  throw std::runtime_error(std::string(
103  "Dependency collection holden object is invalid."));
104  }
105  if ( etaDependency != vec[etIdx][etaIdx]->etaDep() ){
106  if ( etDependency != vec[etIdx][etaIdx]->etDep() ){
107  throw std::runtime_error(std::string(
108  "Wrong eta and Et dependency. EtaDependency should be ") +
109  toStr(etaDependency) + " and is " +
110  toStr(vec[etIdx][etaIdx]->etaDep()) + ", as well as EtDependency "
111  "should be " + toStr(etDependency) + " and is " +
112  toStr(vec[etIdx][etaIdx]->etDep()) + "." );
113  } else {
114  throw std::runtime_error(std::string(
115  "Wrong eta dependency. EtaDependency should be ") +
116  toStr(etaDependency) + " and is " +
117  toStr(vec[etIdx][etaIdx]->etaDep()) + "." );
118  }
119  }
120  if ( etDependency != vec[etIdx][etaIdx]->etDep() ){
121  throw std::runtime_error(std::string(
122  "Wrong Et dependency. EtDependency should be ") +
123  toStr(etDependency) + " and is " +
124  toStr(vec[etIdx][etaIdx]->etDep()) + "." );
125  }
126  }
127  }
128 }
129 
130 // =============================================================================
131 template < typename vecType >
132 void checkCollection(
133  const std::vector< std::vector< std::vector<vecType*> > > &vec,
134  EtaDependency etaDependency, EtDependency etDependency)
135 {
136  if (vec.empty()){
137  throw std::runtime_error(std::string(
138  "Dependency collection cannot be empty."));
139  }
140  for ( size_t segIdx = 0; segIdx < vec.size(); ++segIdx){
141  size_t etSize = vec[segIdx].size();
142  if (!etSize){
143  throw std::runtime_error(std::string(
144  "Dependency collection cannot have an"
145  " empty vector<vector>."));
146  }
147  checkCollection(vec[segIdx], etaDependency, etDependency);
148  }
149 }
150 
151 // =============================================================================
152 template < typename vecType >
153 void setCollectionMsgStream(
154  MsgStream *stream,
155  const std::vector< std::vector<vecType*> > &vec )
156 {
157  for ( size_t etIdx = 0; etIdx < vec.size() ; ++etIdx){
158  size_t etaSize = vec[etIdx].size();
159  for ( size_t etaIdx = 0; etaIdx < etaSize; ++etaIdx){
160  vec[etIdx][etaIdx]->setMsgStream(stream);
161  }
162  }
163 }
164 
165 // =============================================================================
166 template < typename vecType >
167 void setCollectionMsgStream(
168  MsgStream *stream,
169  const std::vector< std::vector< std::vector<vecType*> > > &vec )
170 {
171  for ( size_t segIdx = 0; segIdx < vec.size(); ++segIdx) {
172  setCollectionMsgStream(stream,vec[segIdx]);
173  }
174 }
175 
176 // =============================================================================
177 /**
178  * @brief Ensure that segType is NoSegmentation, otherwise throws runtime_error
179  **/
180 inline
181 void ensureNoSegmentationOnlyFcn(const SegmentationType segType)
182 {
183  // XXX This shouldn't be a runtime_error, but it seems I would need to
184  // implement a RingerProcedureWrapper for each segType (check if this
185  // hypothesis is true), which would demand more time that I afford.
186  if (segType != SegmentationType::NoSegmentation ){
187  throw std::runtime_error(std::string(
188  "Cannot use this method for other"
189  " SegmentationType then NoSegmentation."));
190  }
191 }
192 
193 // =============================================================================
194 /**
195  * @brief Insert toBeCopied vector values to newHolder end
196  **/
197 inline
198 void insertVecToVecEnd(
199  const std::vector<float> &toBeCopied,
200  std::vector<float> &newHolder)
201 {
202  newHolder.insert(newHolder.end(), toBeCopied.begin(), toBeCopied.end());
203 }
204 
205 // =============================================================================
206 /**
207  * @brief Execute segmented pre-processor unified routine
208  **/
209 inline
210 void executeSegmentedPP(
211  std::vector<float> &input,
212  const PreProcessing::IPreProcessor *proc,
213  std::vector<float> &transformVec)
214 {
215  // Transform input:
216  proc->execute(input);
217  // Concatenate it to global transformation vector:
218  insertVecToVecEnd(input, transformVec);
219  // Clear input vector:
220  input.clear();
221 }
222 
223 // =============================================================================
224 /**
225  * @brief Execute segmented discriminator unified routine
226  **/
227 inline
228 void executeSegmentedDiscr(
229  std::vector<float> &input,
230  const Discrimination::IDiscriminator *discr,
231  std::vector<float> &output)
232 {
233  // Get this procedure output into another vector:
234  std::vector<float> localOutput;
235  localOutput.reserve(output.capacity());
236  // Execute on it:
237  discr->execute(input,localOutput);
238  // Concatenate it to global output vec:
239  insertVecToVecEnd(localOutput, output);
240  // Clear input vector:
241  input.clear();
242 }
243 
244 // =============================================================================
245 /**
246  * @brief Get Calorimeter segment from transformVec
247  **/
248 inline
249 void getCaloSegmentFromTransformVec(
250  const unsigned nRings,
251  const std::vector<float> &transformVec,
252  std::vector<float> &transformVecSegment)
253 {
254  transformVecSegment.clear();
255  for ( size_t idx = 0; idx < nRings; ++idx )
256  {
257  transformVecSegment.push_back(transformVec[idx]);
258  }
259 }
260 
261 // =============================================================================
262 /**
263  * @brief Get Calorimeter segment from transformVec
264  **/
265 template<typename segment_t>
266 inline
267 void getCaloSegmentFromTransformVec(
268  const xAOD::RingSetConf::RawConfCollection &rawConfCol,
269  const segment_t segment,
270  const std::vector<float> &transformVec,
271  std::vector<float> &transformVecSegment)
272 {
273 
274  transformVecSegment.clear();
275 
276  // Get the start and end indexes from the required segment:
277  unsigned startIdx(0), endIdx(0);
278  xAOD::RingSetConf::getEdges(rawConfCol,segment,startIdx,endIdx);
279 
280  for (unsigned idx = startIdx; idx < endIdx; ++idx ) {
281  transformVecSegment.push_back(transformVec[idx]);
282  }
283 }
284 
285 // =============================================================================
286 /**
287  * @brief Get Track segment from transformVec
288  **/
289 inline
290 void getTrackSegmentFromTransformVec(
291  const unsigned nRings,
292  const std::vector<float> &transformVec,
293  std::vector<float> &transformVecSegment)
294 {
295  transformVecSegment.clear();
296  for ( size_t idx = nRings; idx < transformVec.size(); ++idx ) {
297  transformVecSegment.push_back(transformVec[idx]);
298  }
299 }
300 
301 
302 // =============================================================================
303 /**
304  * These macros can be used if we want to declare a specific type wrapper, so
305  * that it can have it dedicated compiled code. Although its wrapper calling
306  * method will be determined during runtime (it is holded though its
307  * interface), it will have its code specifically compiled for this type. This
308  * means that it execute its collection methods through statically determined
309  * methods are can also benefit of inline methods.
310  *
311  * However, it shouldn't be used for every type created, as it will increase
312  * compile time and library size.
313  *
314  * Besides, there is no garantee that there will be speed gain or that it won't
315  * be negligible.
316  *
317  * If you use the READ_ALL_DEP_WRAPPER macro, it will declare all possible
318  * dependent types for that class: you should pass this wrapper the variables
319  * that are read on the file.
320  *
321  * Instead using the READ_ALL_DEP_WRAPPER, when you need to declare only one
322  * specific template type for reading, you can otherwise use READ_WRAPPER. In
323  * this case, the passing parameters are not variables, but rather the template
324  * values.
325  *
326  * If you want to declare all eta/et dependent cases for a procedure type,
327  * you can use the READ_ETA_ET_DEP_WRAPPER, where it defines for the etaDep and
328  * etDep variables all possible variations. The segType however must be a
329  * value determined at compile time.
330  *
331  * Otherwise you want to declare segment dependent cases, which are not eta/et
332  * dependent, use READ_SEG_DEP_WRAPPER inserting segType as the variable and
333  * eta/et as compile time values, such as EtaIndependent and EtIndependent.
334  **/
335 #define READ_WRAPPER(vec, wrapType, segType, etaDep, etDep, configDir, version) \
336  vec.push_back( Ringer::RingerProcedureWrapper<wrapType, \
337  etaDep, etDep, segType >::read(configDir,version) );
338 
339 // =============================================================================
340 #define READ_ETA_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, \
341  configDir, version) \
342  switch( etaDep ) \
343  { \
344  case Ringer::EtaDependent: \
345  READ_WRAPPER(vec, wrapType, segType, Ringer::EtaDependent, etDep, \
346  configDir, version) \
347  break; \
348  case Ringer::EtaIndependent: \
349  READ_WRAPPER(vec, wrapType, segType, Ringer::EtaIndependent, etDep, \
350  configDir, version) \
351  break; \
352  default: \
353  throw std::runtime_error(std::string("Unknown Eta dependency.")); \
354  }
355 
356 // =============================================================================
357 #define READ_SEG_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, configDir, \
358  version) \
359  switch( segType ) \
360  { \
361  case Ringer::NoSegmentation: \
362  READ_WRAPPER(vec, wrapType, Ringer::NoSegmentation, etaDep, etDep, \
363  configDir, version) \
364  break; \
365  case Ringer::TrackCalPatTypeSegmentation: \
366  READ_WRAPPER(vec, wrapType, Ringer::TrackCalPatTypeSegmentation, etaDep, \
367  etDep, configDir, version) \
368  break; \
369  case Ringer::TrackCalSegmentation: \
370  READ_WRAPPER(vec, wrapType, Ringer::TrackCalSegmentation, etaDep, etDep, \
371  configDir, version) \
372  break; \
373  case Ringer::TrackCalJointLayers: \
374  READ_ETA_ET_DEP_WRAPPER(vec, wrapType, Ringer::TrackCalJointLayers, \
375  etaDep, etDep, configDir, version) \
376  break; \
377  case Ringer::TrackCalJointSections: \
378  READ_ETA_ET_DEP_WRAPPER(vec, wrapType, Ringer::TrackCalJointSections, \
379  etaDep, etDep, configDir, version) \
380  break; \
381  default: \
382  throw std::runtime_error(std::string("Unknown segmentation type")); \
383  }
384 
385 // =============================================================================
386 #define READ_ETA_ET_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, \
387  configDir, version) \
388  switch( etDep ) \
389  { \
390  case Ringer::EtDependent: \
391  READ_ETA_DEP_WRAPPER(vec, wrapType, segType, etaDep, Ringer::EtDependent,\
392  configDir, version) \
393  break; \
394  case Ringer::EtIndependent: \
395  READ_ETA_DEP_WRAPPER(vec, wrapType, segType, etaDep, \
396  Ringer::EtIndependent, configDir, version) \
397  break; \
398  default: \
399  throw std::runtime_error(std::string("Unknown Et dependency.")); \
400  }
401 
402 // =============================================================================
403 #define READ_ALL_DEP_WRAPPER(vec, wrapType, segType, etaDep, etDep, \
404  configDir, version ) \
405  switch( segType ) \
406  { \
407  case Ringer::NoSegmentation: \
408  READ_ETA_ET_DEP_WRAPPER(vec, wrapType, Ringer::NoSegmentation, etaDep, \
409  etDep, configDir, version ) \
410  break; \
411  case Ringer::TrackCalPatTypeSegmentation: \
412  READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \
413  Ringer::TrackCalPatTypeSegmentation, \
414  etaDep, etDep, configDir, version ) \
415  break; \
416  case Ringer::TrackCalSegmentation: \
417  READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \
418  Ringer::TrackCalSegmentation, etaDep, \
419  etDep, configDir, version ) \
420  break; \
421  case Ringer::TrackCalJointLayers: \
422  READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \
423  Ringer::TrackCalJointLayers, etaDep, \
424  etDep, configDir, version) \
425  break; \
426  case Ringer::TrackCalJointSections: \
427  READ_ETA_ET_DEP_WRAPPER(vec, wrapType, \
428  Ringer::TrackCalJointSections, etaDep, \
429  etDep, configDir, version) \
430  break; \
431  default: \
432  throw std::runtime_error(std::string("Unknown segmentation type")); \
433  }
434 
435 
436 } // WrapperUtils namespace
437 
438 } // Ringer namespace
439 
440 #include "RingerSelectorTools/procedures/RingerPreProcessorWrapper.icc"
441 #include "RingerSelectorTools/procedures/RingerDiscriminatorWrapper.icc"
442 #include "RingerSelectorTools/procedures/RingerThresholdWrapper.icc"
443 
444 #endif // RINGERSELECTORTOOLS_PROCEDURES_RINGERPROCEDUREWRAPPER_ICC