ATLAS Offline Software
Loading...
Searching...
No Matches
FeatureCollectAthena.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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 <concepts>
24#include <string>
25#include <type_traits>
26
28
35
38
39// for template specializations
40
47
50
51#include "xAODTrigger/MuonRoI.h"
53
54#include "xAODTrigger/JetRoI.h"
56
57// for smart type information
58
60
61namespace Trig {
62
66
67 namespace FeatureAccessImpl {
68 // function declaration (see cxx for the deifinition) wanted to have this freedom in case of patches needed
69 const TrigPassBits* getBits(size_t sz, const HLT::TriggerElement* te,
70 const std::string& label, const HLT::NavigationCore* navigation );
71
72 const TrigPassFlags* getFlags(size_t sz, const HLT::TriggerElement* te,
73 const std::string& label, const HLT::NavigationCore* navigation );
74
75 // Detect DataVector type by existence of ElementProxy
76 template<typename T>
77 concept isDataVector = requires {
78 typename T::ElementProxy;
79 };
80
81 template<class T>
82 const T* use_or_construct(const T* source, const HLT::TriggerElement* te, const std::string& label,
83 unsigned int condition, const HLT::NavigationCore* navigation ) {
84
85 if constexpr(!isDataVector<T>) {
86 return source;
87 }
88 else {
89 const TrigPassBits* bits{nullptr};
90 if ( condition == TrigDefs::Physics ) {// only passing objects
91 bits = getBits(source->size(), te, label , navigation);
92 }
93 if ( bits ) { // the actual filtering
94 auto destination = new ConstDataVector<T>(SG::VIEW_ELEMENTS);
95
96 for(const typename T::base_value_type *obj : *source) {
97 if ( HLT::isPassing(bits, obj, source) ) // if bits are missing or obj is realy marked as passing
98 destination->push_back(obj);
99 }
100 return destination->asDataVector();
101 }
102 return source;
103 }
104 }
105
106
107 // The "flatten" option is for the case that requested and stored are the same types
108 // (e.g. requested is egamma_container and stored is egamma_container or
109 // requested is TrigRoiDescriptor and stored is TrigRoiDescriptor).
110 // The actual data storage may be yet different. In the second case it is TrigRoiDescriptorCollection.
111 // Here we have two cases, if the requested object is DataVector and the Physics flag is requested
112 // we need to do the additional filtering. We guess that this is the case by sniffing the object T
113 // with the has_traits template. This filtering is done as follows. New container is created with
114 // the VIEW_ELEMENTS mode and only selected objects are inserted into it.
115
116 template<class T, class STORED, bool flatten, class LINK>
117 void insert_and_flatten(std::vector<Trig::Feature<T> >& destination, const STORED* source,
118 const HLT::TriggerElement* te, const std::string& label,
119 unsigned int condition, const HLT::NavigationCore* navigation, const LINK& lnk) {
120
121 if constexpr(flatten) {
122 const TrigPassBits* bits{nullptr};
123 if ( condition == TrigDefs::Physics ) {// only passing objects
124 bits = getBits(source->size(), te, label , navigation);
125 }
126
127 for(const T* obj : *source) {
128 if ( bits==nullptr || HLT::isPassing(bits, obj, source) ) {// if no bits or obj is marked as passing
129 destination.push_back(Trig::Feature<T>(obj, te, label,
130 false, // do not delete
132 }
133 }
134 }
135 else {
136 const T* possibly_reduced_container = use_or_construct<T>(source, te, label, condition, navigation);
137
138 destination.push_back(Trig::Feature<T>(possibly_reduced_container, te, label,
139 // true: Feature<T> deletes container at deletion
140 possibly_reduced_container != source,
141 lnk));
142 }
143 }
144
145 template<class REQUESTED,class EDMLIST>
146 struct get_links {
147
148 template<class FEATURE>
149 void do_it() {
150
151 using container_type = Features2Container_t<FEATURE,EDMLIST>;
152 using object_type = Features2Object_t<FEATURE,EDMLIST>;
154
155 constexpr bool do_flatten = (! std::is_same_v<REQUESTED,container_type>) && std::is_same_v<FEATURE,container_type>;
156 constexpr bool do_retrieve = ! (std::is_same_v<REQUESTED,container_type> && std::is_same_v<FEATURE,object_type>);
157
158 if constexpr( !do_retrieve ) {
159 // no retrieve -> do nothing
160 }
161 else {
162 // do retrieve
163 std::string sourceLabel;
164 link_type link;
165 const bool new_result = m_navigation->getRecentFeatureDataOrElementLink( m_te, link, m_label, *m_sourceTE, sourceLabel );
166
167 if (new_result) {
168 if (m_teName.empty() || m_teName == Trig::getTEName(**m_sourceTE)) {
169 if (link.cptr()) {
170 // Helper to deref link
171 auto get_ptr = [](const auto& link) {
172 if constexpr(std::is_same_v<FEATURE,container_type>)
173 return link.cptr();
174 else
175 return *link;
176 };
177
179 (*m_data, get_ptr(link),
180 *m_sourceTE, sourceLabel, m_condition, m_navigation,link);
181 }
182 }
183 }
184 *m_result = *m_result && new_result;
185 }
186 }
187
188 const HLT::TriggerElement* m_te{nullptr};
189 std::vector<Trig::Feature<REQUESTED> >* m_data{nullptr};
190 const std::string m_label;
191 unsigned int m_condition{0};
192 std::string m_teName;
194 bool* m_result{nullptr};
196 };
197
202 template<class T>
203 void collect(const HLT::TriggerElement* te, std::vector<Trig::Feature<T> >& data,
204 const std::string& label, unsigned int condition, const std::string& teName,
205 const HLT::TrigNavStructure* navstructure) {
206
207 auto navigation = dynamic_cast<const HLT::NavigationCore*>(navstructure);
208
209 if (condition == TrigDefs::Physics && !te->getActiveState() ) return;
210
211 const HLT::TriggerElement* sourceTE{};
212 bool result = true;
213#ifndef __GCCXML__
214 using object_type = Features2Object_t<T>;
215 using feature_list = Object2Features_t<object_type>;
216 get_links<T,TypeInfo_EDM> link_getter{te, &data, label, condition, teName, navigation, &result, &sourceTE};
218#endif
219
220 if (result){
221 /*do nothing anymore*/
222 } else {
223 // getRecentFeature returned false -> bifurcation?
224 const std::vector<HLT::TriggerElement*> bif_tes = navigation->getDirectPredecessors(sourceTE);
225 if ( bif_tes.size() <= 1 ) {
226 return; // that means it is plain error (it will be printed by the Navigation)
227 } else {
228 // bifurcation point
229 for( const HLT::TriggerElement* predecesor_te : bif_tes )
230 collect(predecesor_te, data, label, condition, teName, navigation);
231 }
232 }
233 }
234
235
236 template<>
237 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);
238
239 template<>
240 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);
241
242 template<>
243 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);
244
245 template<>
246 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);
247
248 template<>
249 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);
250
251 template<>
252 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);
253
254 // ==============
255 //
256 // This section deals with the TrigPassFlags creation
257 //
258 // ==============
259
260 // access by container, stored as container
261 template<isDataVector CONT> TrigPassFlags
262 build_flags (const CONT *orig_cont, const CONT* cont, const TrigPassFlags * orig_tpf) {
263
264 TrigPassFlags tpf(cont->size(), orig_tpf->flagSize());
265
266 if(orig_cont->size() != orig_tpf->size()) {
267 //std::cout << "WARNING: original constainer size (" << orig_cont->size() << ") different for size of TrigPassFlags (" << orig_tpf->size() << ")." << std::endl;
268 return tpf;
269 }
270
271 unsigned int currentPos=0;
272 for(const typename CONT::base_value_type* obj : *cont) {
273 const auto orig_obj = std::find(orig_cont->begin(),orig_cont->end(),obj);
274
275 if(orig_obj == orig_cont->end()) {
276 //std::cout << "WARNING: object in reduced container can' be found in original." << std::endl;
277 } else {
278 size_t idx = orig_obj-orig_cont->begin();
279 tpf.setFlag(currentPos, orig_tpf->getFlag(idx));
280 }
281 currentPos++;
282 }
283
284 return tpf;
285 }
286
287 template<class T> TrigPassFlags
288 build_flags (const T *orig, const T* feature, const TrigPassFlags * orig_tpf) {
289 if(orig != feature) return TrigPassFlags(); // a problem TODO: print a ERROR
290
291 TrigPassFlags tpf(1, orig_tpf->flagSize());
292 tpf.setFlag(0,orig_tpf->getFlag(0));
293 return tpf;
294 }
295
296 // access by single object, stored as container
297 template<class T, class STORED> TrigPassFlags
298 build_flags2(const STORED* orig_cont, const T* obj, const TrigPassFlags * orig_tpf)
299 {
300 if(orig_cont->size() != orig_tpf->size()) {
301 //std::cout << "WARNING: original constainer size (" << orig_cont->size() << ") different for size of TrigPassFlags (" << orig_tpf->size() << ")." << std::endl;
302 return TrigPassFlags();
303 }
304
305 TrigPassFlags tpf(1, orig_tpf->flagSize());
306
307 const auto orig_obj = std::find(orig_cont->begin(),orig_cont->end(), obj);
308
309 if(orig_obj == orig_cont->end()) {
310 //std::cout << "WARNING: object in reduced container can' be found in original." << std::endl;
311 } else {
312 size_t idx = orig_obj-orig_cont->begin();
313 tpf.setFlag(0, orig_tpf->getFlag(idx));
314 }
315 return tpf;
316 }
317
318 template<class T> TrigPassFlags
319 getFlags(const Trig::Feature<T>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation ) {
320
321 using STORED = TrigDec::ClassTraits<T>::type;
322
323 const STORED* orig{};
324 const HLT::TriggerElement* sourceTE{};
325 std::string sourceLabel;
326 if (navigation->getRecentFeature(f.te(), orig, f.label(), sourceTE, sourceLabel)) {
327 if constexpr (std::is_same_v<T,STORED>)
328 return build_flags(orig, f.cptr(), orig_tpf);
329 else
330 return build_flags2(orig, f.cptr(), orig_tpf);
331 }
332 return TrigPassFlags();
333
334 }
335
336 // specialization for types without getRecentFeature implementation
337 template<> TrigPassFlags getFlags(const Trig::Feature<EmTau_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
338 template<> TrigPassFlags getFlags(const Trig::Feature<Muon_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
339 template<> TrigPassFlags getFlags(const Trig::Feature<Jet_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
340
341 } // EOF namespace FeatureAccessImpl
342
343} // EOF namespace Trig
344
345#endif
346
347
348#endif //XAOD_ANALYSIS
DataVector adapter that acts like it holds const pointers.
Object2Features< FEATURE, EDMLIST >::type Object2Features_t
Features2Object< FEATURE, EDMLIST >::type Features2Object_t
Features2Container< FEATURE, EDMLIST >::type Features2Container_t
std::conditional_t< std::is_same_v< REQUESTED, CONTAINER >, DataLink< CONTAINER >, ElementLink< CONTAINER > > Features2LinkHelper_t
Get link type for feature.
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)
void insert_and_flatten(std::vector< Trig::Feature< T > > &destination, const STORED *source, const HLT::TriggerElement *te, const std::string &label, unsigned int condition, const HLT::NavigationCore *navigation, const LINK &lnk)
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)
TrigPassFlags build_flags(const CONT *orig_cont, const CONT *cont, const TrigPassFlags *orig_tpf)
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)
const T * use_or_construct(const T *source, const HLT::TriggerElement *te, const std::string &label, unsigned int condition, const HLT::NavigationCore *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.