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 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,
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, 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, 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, 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 operator()() {
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 bool new_result{false};
166 if (m_navigation){
167 new_result = m_navigation->getRecentFeatureDataOrElementLink( m_te, link, m_label, *m_sourceTE, sourceLabel );
168 }
169 if (new_result) {
170 if (m_teName.empty() || m_teName == Trig::getTEName(**m_sourceTE)) {
171 if (link.cptr()) {
172 // Helper to deref link
173 auto get_ptr = [](const auto& link) {
174 if constexpr(std::is_same_v<FEATURE,container_type>)
175 return link.cptr();
176 else
177 return *link;
178 };
179
181 (*m_data, get_ptr(link),
182 *m_sourceTE, sourceLabel, m_condition, m_navigation,link);
183 }
184 }
185 }
186 *m_result = *m_result && new_result;
187 }
188 }
189
190 const HLT::TriggerElement* m_te{nullptr};
191 std::vector<Trig::Feature<REQUESTED> >* m_data{nullptr};
192 const std::string m_label;
193 unsigned int m_condition{0};
194 std::string m_teName;
196 bool* m_result{nullptr};
198 };
199
204 template<class T>
205 void collect(const HLT::TriggerElement* te, std::vector<Trig::Feature<T> >& data,
206 std::string_view label, unsigned int condition, const std::string& teName,
207 const HLT::TrigNavStructure* navstructure) {
208
209 auto navigation = dynamic_cast<const HLT::NavigationCore*>(navstructure);
210
211 if (condition == TrigDefs::Physics && !te->getActiveState() ) return;
212
213 const HLT::TriggerElement* sourceTE{};
214 bool result = true;
215#ifndef __GCCXML__
216 using object_type = Features2Object_t<T>;
217 using feature_list = Object2Features_t<object_type>;
218 get_links<T,TypeInfo_EDM> link_getter{te, &data, {label.begin(), label.end()}, condition, teName, navigation, &result, &sourceTE};
219 feature_list::for_each(link_getter);
220#endif
221
222 if (result){
223 /*do nothing anymore*/
224 } else {
225 // getRecentFeature returned false -> bifurcation?
226 const std::vector<HLT::TriggerElement*> bif_tes = navigation->getDirectPredecessors(sourceTE);
227 if ( bif_tes.size() <= 1 ) {
228 return; // that means it is plain error (it will be printed by the Navigation)
229 } else {
230 // bifurcation point
231 for( const HLT::TriggerElement* predecesor_te : bif_tes )
232 collect(predecesor_te, data, {label.begin(), label.end()}, condition, teName, navigation);
233 }
234 }
235 }
236
237
238 template<>
239 void collect<Muon_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<Muon_ROI> >& data, std::string_view, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
240
241 template<>
242 void collect<EmTau_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<EmTau_ROI> >& data, std::string_view, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
243
244 template<>
245 void collect<Jet_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<Jet_ROI> >& data, std::string_view, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
246
247 template<>
248 void collect<xAOD::EmTauRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::EmTauRoI> >& data, std::string_view, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
249
250 template<>
251 void collect<xAOD::MuonRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::MuonRoI> >& data, std::string_view, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
252
253 template<>
254 void collect<xAOD::JetRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::JetRoI> >& data, std::string_view, unsigned int, const std::string&, const HLT::TrigNavStructure* navigation);
255
256 // ==============
257 //
258 // This section deals with the TrigPassFlags creation
259 //
260 // ==============
261
262 // access by container, stored as container
263 template<isDataVector CONT> TrigPassFlags
264 build_flags (const CONT *orig_cont, const CONT* cont, const TrigPassFlags * orig_tpf) {
265
266 TrigPassFlags tpf(cont->size(), orig_tpf->flagSize());
267
268 if(orig_cont->size() != orig_tpf->size()) {
269 //std::cout << "WARNING: original constainer size (" << orig_cont->size() << ") different for size of TrigPassFlags (" << orig_tpf->size() << ")." << std::endl;
270 return tpf;
271 }
272
273 unsigned int currentPos=0;
274 for(const typename CONT::base_value_type* obj : *cont) {
275 const auto orig_obj = std::find(orig_cont->begin(),orig_cont->end(),obj);
276
277 if(orig_obj == orig_cont->end()) {
278 //std::cout << "WARNING: object in reduced container can' be found in original." << std::endl;
279 } else {
280 size_t idx = orig_obj-orig_cont->begin();
281 tpf.setFlag(currentPos, orig_tpf->getFlag(idx));
282 }
283 currentPos++;
284 }
285
286 return tpf;
287 }
288
289 template<class T> TrigPassFlags
290 build_flags (const T *orig, const T* feature, const TrigPassFlags * orig_tpf) {
291 if(orig != feature) return TrigPassFlags(); // a problem TODO: print a ERROR
292
293 TrigPassFlags tpf(1, orig_tpf->flagSize());
294 tpf.setFlag(0,orig_tpf->getFlag(0));
295 return tpf;
296 }
297
298 // access by single object, stored as container
299 template<class T, class STORED> TrigPassFlags
300 build_flags2(const STORED* orig_cont, const T* obj, const TrigPassFlags * orig_tpf)
301 {
302 if(orig_cont->size() != orig_tpf->size()) {
303 //std::cout << "WARNING: original constainer size (" << orig_cont->size() << ") different for size of TrigPassFlags (" << orig_tpf->size() << ")." << std::endl;
304 return TrigPassFlags();
305 }
306
307 TrigPassFlags tpf(1, orig_tpf->flagSize());
308
309 const auto orig_obj = std::find(orig_cont->begin(),orig_cont->end(), obj);
310
311 if(orig_obj == orig_cont->end()) {
312 //std::cout << "WARNING: object in reduced container can' be found in original." << std::endl;
313 } else {
314 size_t idx = orig_obj-orig_cont->begin();
315 tpf.setFlag(0, orig_tpf->getFlag(idx));
316 }
317 return tpf;
318 }
319
320 template<class T> TrigPassFlags
321 getFlags(const Trig::Feature<T>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation ) {
322
323 using STORED = TrigDec::ClassTraits<T>::type;
324
325 const STORED* orig{};
326 const HLT::TriggerElement* sourceTE{};
327 std::string sourceLabel;
328 if (navigation->getRecentFeature(f.te(), orig, f.label(), sourceTE, sourceLabel)) {
329 if constexpr (std::is_same_v<T,STORED>)
330 return build_flags(orig, f.cptr(), orig_tpf);
331 else
332 return build_flags2(orig, f.cptr(), orig_tpf);
333 }
334 return TrigPassFlags();
335
336 }
337
338 // specialization for types without getRecentFeature implementation
339 template<> TrigPassFlags getFlags(const Trig::Feature<EmTau_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
340 template<> TrigPassFlags getFlags(const Trig::Feature<Muon_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
341 template<> TrigPassFlags getFlags(const Trig::Feature<Jet_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
342
343 } // EOF namespace FeatureAccessImpl
344
345} // EOF namespace Trig
346
347#endif
348
349
350#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.
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.
const T * use_or_construct(const T *source, const HLT::TriggerElement *te, unsigned int condition, const HLT::NavigationCore *navigation)
void collect< Jet_ROI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< Jet_ROI > > &data, std::string_view, 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 collect< xAOD::JetRoI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< xAOD::JetRoI > > &data, std::string_view, unsigned int condition, const std::string &, const HLT::TrigNavStructure *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)
TrigPassFlags build_flags(const CONT *orig_cont, const CONT *cont, const TrigPassFlags *orig_tpf)
void collect< xAOD::EmTauRoI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< xAOD::EmTauRoI > > &data, std::string_view, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
void collect< Muon_ROI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< Muon_ROI > > &data, std::string_view, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
void collect(const HLT::TriggerElement *te, std::vector< Trig::Feature< T > > &data, std::string_view 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...
const TrigPassBits * getBits(size_t sz, const HLT::TriggerElement *te, const HLT::NavigationCore *navigation)
void collect< xAOD::MuonRoI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< xAOD::MuonRoI > > &data, std::string_view, unsigned int condition, const std::string &, const HLT::TrigNavStructure *navigation)
TrigPassFlags build_flags2(const STORED *orig_cont, const T *obj, const TrigPassFlags *orig_tpf)
void collect< EmTau_ROI >(const HLT::TriggerElement *te, std::vector< Trig::Feature< EmTau_ROI > > &data, std::string_view, 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.