ATLAS Offline Software
Loading...
Searching...
No Matches
FeatureCollectAthena.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef XAOD_ANALYSIS // Full Athena only
6
7// -*- c++ -*-
8#ifndef TRIGGER_DECISION_TOOL_FeatureCollectAthena_H
9#define TRIGGER_DECISION_TOOL_FeatureCollectAthena_H
10
11
12/**********************************************************************************
13 * @Project:
14 * @Package: TrigDecision
15 *
16 *
17 * @author Nicolas Berger <Nicolas.Berger@cern.ch> - LAPP Annecy
18 * @author Tomasz Bold <tomasz.bold@cern.ch> - UC Irvine, AGH-UST Krakow
19 * @author Lukas Heinrich <lukas.heinrich@cern.ch> - NYU
20 *
21 ***********************************************************************************/
22
23#include <string>
24#include <set>
25#include <type_traits>
26
28
34
37
38// for template specializations
39
46
49
50#include "xAODTrigger/MuonRoI.h"
52
53#include "xAODTrigger/JetRoI.h"
55
56// for smart type information
57
59
60
62
63namespace Trig {
64
68
69 namespace FeatureAccessImpl {
70 // function declaration (see cxx for the deifinition) wanted to have this freedom in case of patches needed
71 const TrigPassBits* getBits(size_t sz, const HLT::TriggerElement* te, const std::string& label, const HLT::NavigationCore* navigation );
72
73 const TrigPassFlags* getFlags(size_t sz, const HLT::TriggerElement* te, const std::string& label, const HLT::NavigationCore* navigation );
74
75
76 // compile time check if the type T displays type ElementProxy (this is specific to the DataVectors only)
77 template<typename T>
78 struct isDataVector {
79 private:
80 // these types are defined such that with the sizeof() function they can be evaluated at compile time
81 typedef char true_type;
82 struct false_type { char dummy[2]; };
83
84 // using SFINAE
85 template<typename U> static true_type trait_test_helper(typename U::ElementProxy*); // if U::ElementProxy does not exist, SFINAE means that this is not substituded
86 template<typename U> static false_type trait_test_helper(...);
87 public:
88 static const bool value=sizeof(trait_test_helper<T>(0))==sizeof(true_type); // evaluated at compule time
89 };
90
91
92 // is not substituded for DataVectors
93 template<class T>
94 const typename std::enable_if<!isDataVector<T>::value, T>::type*
95 use_or_construct(const T* source, const HLT::TriggerElement*, const std::string&, unsigned int, const HLT::NavigationCore* ) {
96 return source;
97 }
98
99 // is substituded for DataVectors
100 template<class T>
101 const typename
102 std::enable_if<isDataVector<T>::value, T>::type*
103 use_or_construct(const T* source, const HLT::TriggerElement* te, const std::string& label, unsigned int condition, const HLT::NavigationCore* navigation ) {
104
105 const TrigPassBits* bits(0);
106 if ( condition == TrigDefs::Physics ) {// only passing objects
107 bits = getBits(source->size(), te, label , navigation);
108 }
109 if ( bits ) { // the actual filtering
110 auto destination = new ConstDataVector<T>(SG::VIEW_ELEMENTS);
111
112 for(const typename T::base_value_type *obj : *source) {
113 if ( HLT::isPassing(bits, obj, source) ) // if bits are missing or obj is realy marked as passing
114 destination->push_back(obj);
115 }
116 return destination->asDataVector();
117 }
118 // else
119 return source;
120 }
121
122
123
124
125 //
126 template<class T, class CONT, bool flatten, class LINK> struct insert_and_flatten;
127
128 // The specialization below is for the case that requested and stored are the same types
129 // It means that requested type is egamma_container and stored is egamma_container
130 // or the requested is TrigRoiDescriptor and stored is TrigRoiDescriptor.
131 // The actual data storage may be yet diferent of course. In the second case it is TrigRoiDescriptorCollection.
132 // Here we have two cases, if the requested object is DataVector and the Physics flag is requested
133 // we need to do the additional filtering. We guess that this is the case sniffing the object T a bit with the has_traits template.
134 // This filtering is done as follows. New container is created with in the VIEW_ELEMENTS mode and only selected objects are inserted into it.
135
136 template<class T, class STORED,class LINK>
137 struct insert_and_flatten<T,STORED, false, LINK> {
138 static void do_it(std::vector<Trig::Feature<T> >& destination, const STORED* source, const HLT::TriggerElement* te, const std::string& label,
139 unsigned int condition, const HLT::NavigationCore* navigation, const LINK& lnk) {
140
141 const T* possibly_reduced_possibly_container = use_or_construct<T>(source, te, label, condition, navigation);
142 destination.push_back(Trig::Feature<T>(possibly_reduced_possibly_container, te, label, possibly_reduced_possibly_container != source,lnk)); // by 2nd to the last arg == true tell the Feature<T> to delete container at deletion
143 }
144 };
145
146
147 //
148 template<class T, class CONT, class LINK>
149 struct insert_and_flatten<T, CONT, true, LINK> {
150 static void do_it(std::vector<Trig::Feature<T> >& destination, const CONT* source, const HLT::TriggerElement* te, const std::string& label,
151 unsigned int condition, const HLT::NavigationCore* navigation,const LINK& /*lnk*/) {
152
153 //std::cout << "insert_and_flatten<true> " << label << " of container of size " << source->size() << std::endl;
154
155 const TrigPassBits* bits(0);
156 if ( condition == TrigDefs::Physics ) {// only passing objects
157 //std::cout << "asking for bits for " << label << std::endl;
158 bits =getBits(source->size(), te, label , navigation);
159 }
160
161 for(const T* obj : *source) {
162 if ( bits==0 || HLT::isPassing(bits, obj, source) ) {// if bits are missing or obj is realy marked as passing
163 //std::cout << "Pushing back new feature with obj " << obj << std::endl;
164 destination.push_back(Trig::Feature<T>(obj, te, label,false,ElementLink<typename LINK::value_type>(obj,*source)));
165 }
166 }
167 }
168 };
169
170 template<class LINK, bool is_container> struct print_features;
171
172 template<class LINK> struct print_features<LINK,true>{
173 typedef const typename LINK::value_type* ptr_type;
174 static ptr_type get_ptr(const LINK& link){return link.cptr();}
175 static void do_it(const LINK& link, bool /*do_flatten*/){
176 //std::cout << "container at" << link.cptr() << " has size " << link.cptr()->size() << std::endl;
177 for(unsigned int j=0;j<link.cptr()->size();++j){
178 //std::cout << " ----element " << j << ": " << link.cptr()->at(j) << std::endl;
179 }
180 //std::cout << " .. flatten ? " << (do_flatten ? "yes" : "no") << std::endl;
181 }
182 };
183
184 template<class LINK> struct print_features<LINK,false>{
185 typedef typename LINK::ElementType ptr_type;
186 static ptr_type get_ptr(const LINK& link){return *link;}
187 static void do_it(const LINK& /*link*/,bool /*do_flatten*/){
188 //std::cout << "link to element " << *link << std::endl;
189 //std::cout << " .. flatten ? " << (do_flatten ? "yes" : "no") << std::endl;
190 }
191 };
192
193 struct true_type{}; //different
194 struct false_type{}; //types, so we can overload
195 template <bool retrieve> struct get_type;
196 template <> struct get_type<true>{typedef true_type type;};
197 template <> struct get_type<false>{typedef false_type type;};
198
199 template<class REQUESTED,class EDMLIST>
200 struct get_links {
201 get_links():m_te(nullptr),
202 m_data(nullptr),
203 m_condition(0),
204 m_navigation(nullptr),
205 m_result(),
206 m_sourceTE(0)
207 {}//empty ctor but need to initialize reference member
209 std::vector<Trig::Feature<REQUESTED> >* data,
210 const std::string& label, unsigned int condition,
211 const std::string& teName,
212 const HLT::NavigationCore* navigation,
213 bool* result,
214 const HLT::TriggerElement** sourceTE):
215 m_te(te), m_data(data), m_label(label), m_condition(condition), m_teName(teName), m_navigation(navigation), m_result(result), m_sourceTE(sourceTE){}
216
217
218 template<class FEATURE>
219 void do_it() {
220 //std::cout << "TrigDecisionTool::Feature::get_links: getting links from navi for element in feature list: " << ClassID_traits<FEATURE>::typeName() << std::endl;
221 //std::cout << "TrigDecisionTool::Feature::get_links: type originally requested is: " << ClassID_traits<REQUESTED>::typeName() << std::endl;
222
223 typedef typename Features2Container<FEATURE,EDMLIST>::type container_type;
224 typedef typename Features2Object<FEATURE,EDMLIST>::type object_type;
225
226 const bool do_flatten = (! std::is_same<REQUESTED,container_type>::value) && std::is_same<FEATURE,container_type>::value;
227 const bool do_retrieve = ! (std::is_same<REQUESTED,container_type>::value && std::is_same<FEATURE,object_type>::value);
228 // std::cout << "flatten? (case when requested type is element of feature type) : " << (do_flatten ? "yes" : "no") << std::endl;
229 // std::cout << "retrieve? (don't retrueve when requested type in container but stored type is element): " << (do_retrieve ? "yes" : "no") << std::endl;
231 }
232
233 template<class FEATURE,bool do_flatten>
234 void _do_it(false_type dummy = false_type()) {(void)dummy;/* do nothing */;}
235
236 template<class FEATURE,bool do_flatten>
237 void _do_it(true_type /*dummy*/ = true_type()) {
238
239 //const HLT::TriggerElement* sourceTE(0);
240 std::string sourceLabel;
241
242 typedef typename Features2Container<FEATURE,EDMLIST>::type container_type;
243 //typedef typename Features2Object<FEATURE,EDMLIST>::type object_type;
245
246 //std::cout << "TrigDecisionTool::Feature::get_links: link_type is: " << typeid(link_type).name() << std::endl;
247
248
249
250 link_type link;
251 bool new_result = m_navigation->getRecentFeatureDataOrElementLink( m_te, link, m_label, *m_sourceTE, sourceLabel );
252
253 if (new_result) {
254 if (m_teName == "" || m_teName == Trig::getTEName(**m_sourceTE)) {
255 if (link.cptr()) {
256 //std::cout << "TrigDecisionTool::Feature::get_links: actually we got a feature here" << std::endl;
258 print_features<link_type,std::is_same<FEATURE,container_type>::value>::get_ptr(link),
259 *m_sourceTE, sourceLabel, m_condition, m_navigation,link);
260 }
261 }
262 }
263 *m_result = *m_result && new_result;
264 }
265
267 std::vector<Trig::Feature<REQUESTED> >* m_data;
268 const std::string m_label;
269 unsigned int m_condition;
270 std::string m_teName;
272 bool* m_result;
274 };
275
280 template<class T>
281 void collect(const HLT::TriggerElement* te, std::vector<Trig::Feature<T> >& data, const std::string& label, unsigned int condition,
282 const std::string& teName, const HLT::TrigNavStructure* navstructure) {
283
284 auto navigation = dynamic_cast<const HLT::NavigationCore*>(navstructure);
285
286 //std::cout << "Collecting " << label << " for TE " << te << std::endl;
287
288 if (condition == TrigDefs::Physics && !te->getActiveState() ) return;
289 const HLT::TriggerElement* sourceTE(0);
290 std::string sourceLabel;
291
292
293 bool result = true;
294#ifndef __GCCXML__
295 //typedef typename Features2Container<T>::type container_type;
296 typedef typename Features2Object<T>::type object_type;
297 typedef typename Object2Features<object_type>::type feature_list;
298 get_links<T,TypeInfo_EDM> link_getter( te, &data, label, condition, teName, navigation, &result, &sourceTE);
300#endif
301
302 if (result){/*do nothing anymore*/
303 } else {
304 // getRecentFeature returned false -> bifurcation?
305 const std::vector<HLT::TriggerElement*> bif_tes = navigation->getDirectPredecessors(sourceTE);
306 if ( bif_tes.size() <= 1 ) {
307 return; // that means it is plain error (it will be printed by the Navigation)
308 } else {
309 // bifurcation point
310 for( const HLT::TriggerElement* predecesor_te : bif_tes )
311 collect(predecesor_te, data, label, condition, teName, navigation);
312 }
313 }
314 //std::cout << "Size after collecting " << data.size() << std::endl;
315 }
316
317
318 template<>
319 void collect<Muon_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<Muon_ROI> >& data, const std::string&, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
320
321 template<>
322 void collect<EmTau_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<EmTau_ROI> >& data, const std::string&, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
323
324 template<>
325 void collect<Jet_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<Jet_ROI> >& data, const std::string&, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
326
327 template<>
328 void collect<xAOD::EmTauRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::EmTauRoI> >& data, const std::string&, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
329
330 template<>
331 void collect<xAOD::MuonRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::MuonRoI> >& data, const std::string&, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
332
333 template<>
334 void collect<xAOD::JetRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::JetRoI> >& data, const std::string&, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
335
336 // ==============
337 //
338 // This section deals with the TrigPassFlags creation
339 //
340 // ==============
341
342 // access by container, stored as container
343 template<class CONT> TrigPassFlags
344 build_flags (const typename std::enable_if<isDataVector<CONT>::value, CONT>::type *orig_cont, const CONT* cont, const TrigPassFlags * orig_tpf) {
345 TrigPassFlags tpf(cont->size(), orig_tpf->flagSize());
346
347 if(orig_cont->size() != orig_tpf->size()) {
348 //std::cout << "WARNING: original constainer size (" << orig_cont->size() << ") different for size of TrigPassFlags (" << orig_tpf->size() << ")." << std::endl;
349 return tpf;
350 }
351
352 unsigned int currentPos=0;
353 for(const typename CONT::base_value_type* obj : *cont) {
354 typename CONT::const_iterator orig_obj = std::find(orig_cont->begin(),orig_cont->end(),obj);
355
356 if(orig_obj == orig_cont->end()) {
357 //std::cout << "WARNING: object in reduced container can' be found in original." << std::endl;
358 } else {
359 size_t idx = orig_obj-orig_cont->begin();
360 tpf.setFlag(currentPos, orig_tpf->getFlag(idx));
361 }
362 currentPos++;
363 }
364
365 return tpf;
366 }
367
368
369 template<class T> TrigPassFlags
370 build_flags (const typename std::enable_if<!isDataVector<T>::value, T>::type *orig, const T* feature, const TrigPassFlags * orig_tpf) {
371 if(orig != feature) return TrigPassFlags(); // a problem TODO: print a ERROR
372
373 TrigPassFlags tpf(1, orig_tpf->flagSize());
374 tpf.setFlag(0,orig_tpf->getFlag(0));
375 return tpf;
376 }
377
378
379
380 // access by single object, stored as container
381 template<class T, class STORED> TrigPassFlags
382 build_flags2(const STORED* orig_cont, const T* obj, const TrigPassFlags * orig_tpf)
383 {
384 if(orig_cont->size() != orig_tpf->size()) {
385 //std::cout << "WARNING: original constainer size (" << orig_cont->size() << ") different for size of TrigPassFlags (" << orig_tpf->size() << ")." << std::endl;
386 return TrigPassFlags();
387 }
388
389 TrigPassFlags tpf(1, orig_tpf->flagSize());
390
391 typename STORED::const_iterator orig_obj = std::find(orig_cont->begin(),orig_cont->end(), obj);
392
393 if(orig_obj == orig_cont->end()) {
394 //std::cout << "WARNING: object in reduced container can' be found in original." << std::endl;
395 } else {
396 size_t idx = orig_obj-orig_cont->begin();
397 tpf.setFlag(0, orig_tpf->getFlag(idx));
398 }
399 return tpf;
400 }
401
402
403
404
405
406 template<class T, class STORED, bool same> struct getFlagsHelper;
407
408 // partial specialization for T==STORED
409 template<class T, class STORED> struct getFlagsHelper<T, STORED, true> {
410 static TrigPassFlags do_build(const STORED* orig_feat, const T* feat, const TrigPassFlags * orig_tpf) {
411 return build_flags(orig_feat, feat, orig_tpf);
412 }
413 };
414
415
416 // partial specialization for T!=STORED
417 template<class T, class STORED> struct getFlagsHelper<T, STORED, false> {
418 static TrigPassFlags do_build(const STORED* orig_feat, const T* feat, const TrigPassFlags * orig_tpf) {
419 return build_flags2(orig_feat, feat, orig_tpf);
420 }
421 };
422
423
424
425
426
427 template<class T> TrigPassFlags
428 getFlags(const Trig::Feature<T>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation ) {
429
430 typedef typename TrigDec::ClassTraits<T>::type STORED;
431
432 const STORED* orig(0);
433 const HLT::TriggerElement* sourceTE(0);
434 std::string sourceLabel("");
435 if (navigation->getRecentFeature(f.te(), orig, f.label(), sourceTE, sourceLabel)) {
436 TrigPassFlags tpf = getFlagsHelper<T,STORED, std::is_same<T,STORED>::value>::do_build(orig, f.cptr(), orig_tpf);
437 return tpf;
438 }
439 return TrigPassFlags();
440
441 }
442
443 // specialization for types without getRecentFeature implementation
444 template<> TrigPassFlags getFlags(const Trig::Feature<EmTau_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
445 template<> TrigPassFlags getFlags(const Trig::Feature<Muon_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
446 template<> TrigPassFlags getFlags(const Trig::Feature<Jet_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
447
448 } // EOF namespace FeatureAccessImpl
449
450} // EOF namespace Trig
451
452#endif
453
454
455#endif //XAOD_ANALYSIS
DataVector adapter that acts like it holds const pointers.
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
static Double_t sz
DataVector adapter that acts like it holds const pointers.
The NavigationCore class, adds on top of the TrigNavStructure the EDM read-only handling.
bool getRecentFeature(const TriggerElement *te, const T *&feature, const std::string &label="", const TriggerElement *&source=::HLT::TrigNavStructure::m_unspecifiedTE, std::string &sourcelabel=::HLT::TrigNavStructure::m_unspecifiedLabel) const
TriggerElement is the basic ingreedient of the interface between HLT algorithms and the navigation It...
bool getActiveState() const
get state of the TriggerElement
A Flag is an ordered collection of bits (vector<bool>) that can hold additional (boolean) information...
unsigned int flagSize() const
gets size of the flag vector for the object at index
const std::vector< bool > & getFlag(const unsigned int position) const
Returns the flag (vector<bool>) at index position.
unsigned int size() const
gets size of the container object vector
void setFlag(const unsigned int position, const std::vector< bool > &flag, const void *cont=0)
Set the flag at index position.
is basic vehicle of object access in TDT
Definition Feature.h:112
std::string label(const std::string &format, int i)
Definition label.h:19
bool isPassing(const TrigPassBits *bits, const T *obj, const CONTAINER *container)
Check the bit for the object in the associated bits object.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
This is the implementation of the Feature collection for Athena.
void collect< xAOD::EmTauRoI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< xAOD::EmTauRoI > > &data, const std::string &, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
void collect< EmTau_ROI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< EmTau_ROI > > &data, const std::string &, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
void collect(const HLT::TriggerElement *te, std::vector< Trig::Feature< T > > &data, const std::string &label, unsigned int condition, const std::string &teName, const HLT::TrigNavStructure *navstructure)
actual feature acceess implementation It has (thanks to the ClassTraits) functionality to flatten con...
void collect< Jet_ROI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< Jet_ROI > > &data, const std::string &, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
void collect< xAOD::MuonRoI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< xAOD::MuonRoI > > &data, const std::string &, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
const TrigPassFlags * getFlags(size_t size, const HLT::TriggerElement *te, const std::string &label, const HLT::NavigationCore *navigation)
const std::enable_if<!isDataVector< T >::value, T >::type * use_or_construct(const T *source, const HLT::TriggerElement *, const std::string &, unsigned int, const HLT::NavigationCore *)
TrigPassFlags build_flags(const typename std::enable_if< isDataVector< CONT >::value, CONT >::type *orig_cont, const CONT *cont, const TrigPassFlags *orig_tpf)
void collect< xAOD::JetRoI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< xAOD::JetRoI > > &data, const std::string &, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
const TrigPassBits * getBits(size_t sz, const HLT::TriggerElement *te, const std::string &, const HLT::NavigationCore *navigation)
TrigPassFlags build_flags2(const STORED *orig_cont, const T *obj, const TrigPassFlags *orig_tpf)
void collect< Muon_ROI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< Muon_ROI > > &data, const std::string &, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
The common trigger namespace for trigger analysis tools.
std::string getTEName(const HLT::TriggerElement &te)
converts TEid to TE name (this may not always work, it depends on the availability of config)
TrigPassBits_v1 TrigPassBits
Define the latest version of the trigger pass bits class.
master_search< typenameEDMLIST::map, HLT::TypeInformation::get_feat, FEATURE >::result::search_result::container type
lnk_helper< CONTAINER, isCont >::type type
master_search< typenameEDMLIST::map, HLT::TypeInformation::get_feat, FEATURE >::result::search_result::object type
master_search< typenameEDMLIST::map, HLT::TypeInformation::get_objt, OBJECT >::result::search_result::list_of_features type
static TrigPassFlags do_build(const STORED *orig_feat, const T *feat, const TrigPassFlags *orig_tpf)
static TrigPassFlags do_build(const STORED *orig_feat, const T *feat, const TrigPassFlags *orig_tpf)
static true_type trait_test_helper(typename U::ElementProxy *)
static false_type trait_test_helper(...)