4 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
8 #ifndef TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
9 #define TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
14 #include "TrigNavigation/Holder.h"
15 #include "TrigNavigation/Holder.icc"
16 #include "CxxUtils/checker_macros.h"
17 #include "CxxUtils/no_sanitize_undefined.h"
19 /*****************************************************************************
21 * COMPILE TYPE OBJECTS REGISTRATION
23 *****************************************************************************/
24 #include <type_traits>
27 /////////////////////////////////////////////////////////////////////////////
29 __attribute__((__used__))
30 bool HLT::NavigationCore::getFeatures( const TriggerElement* te,
31 std::vector<const T*>& features, const std::string& label,
32 std::map<const T*, std::string>* /*labels*/) const {
35 class_id_type clid = ClassID_traits<T>::ID();
36 ATH_MSG_DEBUG("getFeatures: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
37 <<" to TE: " << te->getId()
38 << " label: \"" << label << "\"");
40 TriggerElement::FeatureVec features_access_helpers;
41 bool single = false; bool recursively = false;
42 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
46 for(auto& fea : features_access_helpers) {
47 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
48 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
50 if ( holder->get(obj, objectIndex) == false ) {
51 ATH_MSG_WARNING("getFeatures: problems while getting objects #" << objectIndex
52 << " from the holder: " << *holder);
54 features.push_back(obj);
60 /////////////////////////////////////////////////////////////////////////////
62 __attribute__((__used__))
63 bool HLT::NavigationCore::getFeature NO_SANITIZE_UNDEFINED ( const TriggerElement* te, const T*& feature, const std::string& label, std::string& sourcelabel) const {
67 class_id_type clid = ClassID_traits<T>::ID();
69 ATH_MSG_DEBUG("getFeature: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
70 <<" to TE: " << te->getId()
71 << " label: \"" << label << "\"");
73 TriggerElement::FeatureVec features_access_helpers;
74 bool single = true; bool recursively = false;
75 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, m_unspecifiedTE, sourcelabel)) {
78 // remove following after testing
79 if ( features_access_helpers.size() > 1 ) {
80 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors");
84 if ( features_access_helpers.empty() )
87 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
88 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
90 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
95 if ( holder->get(feature, objectIndex) == false ) {
96 ATH_MSG_WARNING("getFeature: problems while getting objects #" << objectIndex
97 << " from the holder: " << *holder);
105 __attribute__((__used__))
106 bool HLT::NavigationCore::getFeature( const TriggerElement* te,
107 const ConstDataVector<T>*& feature,
108 const std::string& label, std::string& sourcelabel) const {
109 const T* dv = nullptr;
110 if (!getFeature (te, dv, label, sourcelabel))
113 feature = ConstDataVector<T>::fromDataVector (dv);
114 return feature != nullptr;
118 /////////////////////////////////////////////////////////////////////////////
119 template<class C, class T>
120 __attribute__((__used__))
121 bool HLT::NavigationCore::getFeaturesLinks( const TriggerElement* te, ElementLinkVector<C>& links, const std::string& label) const {
123 class_id_type clid = ClassID_traits<T>::ID();
125 ATH_MSG_DEBUG("getFeaturesLinks: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
126 << " to TE: " << te->getId()
127 << " label: \"" << label << "\"");
129 TriggerElement::FeatureVec features_access_helpers;
130 bool single = false; bool recursively = false;
131 if (!getFeatureAccessors(te,clid, label, single, features_access_helpers, recursively)) {
135 for(auto& fea : features_access_helpers) {
136 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
137 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
139 if ( holder->get(links, objectIndex) == false ) {
140 ATH_MSG_WARNING("getFeaturesLinks: problems while getting objects #" << objectIndex
141 << " from the holder: " << *holder);
148 /////////////////////////////////////////////////////////////////////////////
150 __attribute__((__used__))
151 bool HLT::NavigationCore::getRecentFeatures( const TriggerElement* te,
152 std::vector<const T*>& features, const std::string& label,
153 std::map<const T*, std::string>* /*labels*/) const {
155 class_id_type clid = ClassID_traits<T>::ID();
158 ATH_MSG_DEBUG("getRecentFeatures: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
159 << " in TE: " << te->getId()
160 << " label: \"" << label << "\"");
162 TriggerElement::FeatureVec features_access_helpers;
163 bool single = false; bool recursively = true;
165 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
169 // type specific code
170 for( auto& fea : features_access_helpers) {
171 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
172 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
174 if ( holder->get(obj, objectIndex) == false ) {
175 ATH_MSG_WARNING("getRecentFeatures: problems while getting objects #" << objectIndex
176 << " from the holder: " << *holder);
178 features.push_back(obj);
184 /////////////////////////////////////////////////////////////////////////////
186 __attribute__((__used__))
187 bool HLT::NavigationCore::getRecentFeature( const TriggerElement* te,
188 const T*& feature, const std::string& label,
189 const TriggerElement*& source, std::string& sourcelabel ) const {
191 // important! set pointer to NULL to signify nothing was found, it will later be reset to sth else eventually
194 class_id_type clid = ClassID_traits<T>::ID();
196 ATH_MSG_DEBUG("getRecentFeature: looking for CLID: " << ClassID_traits<T>::ID() << "(" << ClassID_traits<T>::typeName() << ")"
197 << " in TE: " << te->getId()
198 << " label: \"" << label << "\"");
200 TriggerElement::FeatureVec features_access_helpers;
201 bool single = true; bool recursively = true;
203 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
206 // remove following after testing
207 if ( features_access_helpers.size() > 1 ) {
208 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
211 if ( features_access_helpers.empty() )
214 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
215 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
216 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
218 if ( holder->get(feature, objectIndex) == false ) {
219 ATH_MSG_WARNING("getRecentFeature: problems while getting objects #" << objectIndex
220 << " from the holder: " << *holder);
227 /////////////////////////////////////////////////////////////////////////////
228 template<class C, class T>
229 __attribute__((__used__))
230 bool HLT::NavigationCore::getRecentFeaturesLinks( const TriggerElement* te,
231 ElementLinkVector<C>& links, const std::string& label ) const {
234 class_id_type clid = ClassID_traits<T>::ID();
236 ATH_MSG_DEBUG("getRecentFeaturesLinks: looking for CLID: " << ClassID_traits<T>::ID()
237 << "(" << ClassID_traits<T>::typeName() << ")"
238 << " in TE: " << te->getId()
239 << " label: \"" << label << "\"");
241 TriggerElement::FeatureVec features_access_helpers;
242 bool single = false; bool recursively = true;
244 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
248 for(auto& fea : features_access_helpers) {
249 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
250 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
252 if ( holder->get(links, objectIndex) == false ) {
253 ATH_MSG_WARNING("getRecentFeaturesLinks: problems while getting objects #" << objectIndex
254 << " from the holder: " << *holder);
260 //helper struct to get the container type if template argument is datalink or the element type if template arg is ElementLink
262 template<class LinkType>
265 template<class CONTAINERTYPE>
266 struct link_to_type<DataLink<CONTAINERTYPE> >{
267 typedef CONTAINERTYPE container_type;
268 typedef typename DataLink<CONTAINERTYPE>::value_type type;
271 template<class CONTAINERTYPE>
272 struct link_to_type<ElementLink<CONTAINERTYPE> >{
273 typedef CONTAINERTYPE container_type;
274 typedef typename ElementLink<CONTAINERTYPE>::ElementType ptr2constT_type; // is a const T* if T is the feature type
275 typedef typename std::remove_pointer<ptr2constT_type>::type constT_type; // is a const T
276 typedef typename std::remove_const<constT_type>::type type; // is a T
280 /////////////////////////////////////////////////////////////////////////////
281 template<class LinkType>
282 __attribute__((__used__))
283 bool HLT::NavigationCore::getRecentFeatureDataOrElementLink( const TriggerElement* te, LinkType& link, const std::string& label,
284 const TriggerElement*& source, std::string& sourcelabel) const {
289 typedef typename link_to_type<LinkType>::type T;
290 class_id_type clid = ClassID_traits<T>::ID();
291 ATH_MSG_DEBUG("getRecentFeatureDataOrElementLink: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
292 << " in TE: " << te->getId()
293 << " label: \"" << label << "\"");
295 TriggerElement::FeatureVec features_access_helpers;
296 bool single = true; bool recursively = true;
297 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
298 ATH_MSG_INFO("looking for FAs failed. Returning false! Details CLID: " << ClassID_traits<T>::ID() <<
299 "(" << ClassID_traits<T>::typeName() << ")"
300 << " in TE: " << te->getId() << " label: \"" << label << "\"");
304 // remove following after testing
305 if ( features_access_helpers.size() > 1 ) {
306 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
309 if ( features_access_helpers.empty() )
312 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
313 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
314 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
316 //apparently must use function pointer to get all the types resolved properly
317 typedef typename link_to_type<LinkType>::container_type containertype;
318 bool (HLTNavDetails::Holder<T>::*funcptr) (LinkType&, HLT::TriggerElement::ObjectIndex&) =
319 &HLTNavDetails::Holder<T>::template getWithLink<containertype>;
321 if ( (holder->*funcptr)(link, objectIndex) == false ) {
322 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
323 << " from the holder: " << *holder);
328 /////////////////////////////////////////////////////////////////////////////
329 template<class C, class T>
330 __attribute__((__used__))
331 bool HLT::NavigationCore::getRecentFeatureLink( const TriggerElement* te,
332 ElementLink<C>& link, const std::string& label,
333 const TriggerElement*& source,
334 std::string& sourcelabel) const {
337 class_id_type clid = ClassID_traits<T>::ID();
340 ATH_MSG_DEBUG("getRecentFeatureLink: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
341 << " in TE: " << te->getId()
342 << " label: \"" << label << "\"");
344 if( std::is_same<C, T>::value )
348 TriggerElement::FeatureVec features_access_helpers;
349 bool single = true; bool recursively = true;
351 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
354 // remove following after testing
355 if ( features_access_helpers.size() > 1 ) {
356 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
359 if ( features_access_helpers.empty() )
362 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
363 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
364 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
366 ElementLinkVector<C> links;
367 if ( holder->get(links, objectIndex) == false ) {
368 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
369 << " from the holder: " << *holder);
371 if ( links.size() != 1 ) {
372 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
373 << " from the holder: " << *holder << " links vector has size "
374 << links.size() << " while shoudl have size == 1");
384 /////////////////////////////////////////////////////////////////////////////
386 __attribute__((__used__))
387 bool HLT::NavigationCore::getFeaturesInRoI( const TriggerElement* te,
388 std::vector<const T*>& features, const std::string& label,
389 std::map<const T*, std::string>* labels) const {
390 // easy, jump to the RoI (if not RoI node) and loop over all TEs attached to it
391 const TriggerElement* roi(0);
392 if ( TrigNavStructure::isRoINode(te) )
394 else if ( te->getRelated(TriggerElement::sameRoIRelation).size() == 1 ) // means we do not support topological TEs here
395 roi = *(te->getRelated(TriggerElement::sameRoIRelation).begin());
399 bool oneRetStatus = false;
400 bool allRetStatus = false;
401 for ( const TriggerElement* te : roi->getRelated(TriggerElement::sameRoIRelation) ) {
402 oneRetStatus = getFeatures(te, features, label, labels ); // the features will be paked to the end of the vector (see push_back in getFeatures)
403 allRetStatus = allRetStatus || oneRetStatus; // that's OK if at least one call returns some feature
408 /////////////////////////////////////////////////////////////////////////////
409 template<class C, class T>
410 __attribute__((__used__))
411 bool HLT::NavigationCore::getAllFeatures( ElementLinkVector<C>& features, const std::string& label ) const {
412 std::lock_guard<std::recursive_mutex> lock(getMutex());
413 const TrigHolderStructure& holderstorage = getHolderStorage();
415 CLID clid = ClassID_traits<T>::ID();
416 ATH_MSG_DEBUG("getAllFeatures: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
417 << " label: \"" << label << "\"");
419 for ( auto& iholder : holderstorage.getHoldersOfClid(clid) ) {
420 if ( label == iholder->label() || label == "" ) {
421 HLTNavDetails::Holder<T>* holder = getHolder<T>(iholder->label(), nextSubTypeIndex(clid, label));
422 ATH_MSG_VERBOSE("getAllFeatures: getting from: " << *holder);
423 if ( holder->get(features) == false ) {
424 ATH_MSG_WARNING("getAllFeatures: failed with the holder of clid: " << clid <<
425 "(" << ClassID_traits<T>::typeName() << ")" << " label: \"" << label << "\"");
434 /////////////////////////////////////////////////////////////////////////////
436 __attribute__((__used__))
437 HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder NO_SANITIZE_UNDEFINED (const std::string& label, uint16_t suggestedIndex) const {
440 CLID clid = ClassID_traits<T>::ID();
441 ATH_MSG_DEBUG("Getting holder for type: " << clid << " label: " << label);
443 HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, label));
449 // take an appropriate action if this is the first feature of that type#label to be attached/retrieved
450 HLTNavDetails::IHolder* baseholder;
451 if ( createHolder(baseholder, clid, label, suggestedIndex) ) { // create fresh holder
452 ATH_MSG_DEBUG("getHolder: predefined holder got");
455 ATH_MSG_ERROR("getHolder: predefined holder does not exist, load EDM classes for: "
456 << ClassID_traits<T>::typeName() << " CLID " << ClassID_traits<T>::ID());
459 holder = static_cast<HLTNavDetails::Holder<T>*>(baseholder);
461 // registerHolder is thread-safe via a mutex:
462 auto nc_this ATLAS_THREAD_SAFE = const_cast<HLT::NavigationCore*>(this);
463 nc_this->registerHolder(holder);
468 /////////////////////////////////////////////////////////////////////////////
470 __attribute__((__used__))
471 HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder NO_SANITIZE_UNDEFINED (uint16_t subTypeIndex ) const {
473 CLID clid = ClassID_traits<T>::ID();
474 ATH_MSG_DEBUG("Getting holder for type: " << clid);
475 HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, subTypeIndex));
480 /////////////////////////////////////////////////////////////////////////////
481 // 2012-09-14 new stuff for composite obejcts
483 #include "TrigNavigation/NavigationInit.h"
490 template<class T, class C, bool get_by_contianer, bool get_by_object>
493 template<class T, class C>
494 struct get< T, C, false, false>{
495 static const T* do_it(const TrigFeatureLink&, const HLT::NavigationCore* ){
496 return 0; // here compile time error shoudl be generated
500 template<class T, class C>
501 struct get< T, C, false, true>{
502 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
503 HLTNavDetails::Holder<T>* holder = nav->getHolder<T>(fl.subTypeIndex());
504 //std::cerr << " Holder acquired " << __LINE__ << std::endl;
506 holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
507 // std::cerr << " object retrieved " << __LINE__ << std::endl;
513 template<class T, class C>
514 struct get< T, C, true, false>{
515 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
516 HLTNavDetails::Holder<C>* holder = const_cast<HLT::NavigationCore*>(nav)->getHolder<C>(fl.subTypeIndex());
517 //std::cerr << " Holder acquired " << __LINE__ << " " << fl.clid() << " " << fl.subTypeIndex() << " " << holder << " " << ClassID_traits<C>::ID() << std::endl;
519 holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
520 //std::cerr << " object retrieved " << __LINE__ << std::endl;
521 if ( ptr and ptr->size() == 1) {
529 template<class T, class C>
530 struct get< T, C, true, true> {
531 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
532 if ( fl.clid() == ClassID_traits<C>::ID() ) {
533 return get<T,C, true, false>::do_it(fl, nav);
534 } else if ( fl.clid() == ClassID_traits<T>::ID() ) {
535 return get<T,C, false, true>::do_it(fl, nav);
543 __attribute__((__used__))
544 const T* HLT::NavigationCore::featureLink2Object( const TrigFeatureLink& fl) const {
548 typedef typename Object2Features<T>::type list_of_possible_features;
549 typedef typename Object2Container<T>::type container;
551 // std::cerr << " in the list " << HLT::tool::rtti_real_name(typeid(list_of_possible_features).name()) << std::endl;
552 // std::cerr << " container " << HLT::tool::rtti_real_name(typeid(container).name()) << std::endl;
553 // std::cerr << " has T " << list_of_possible_features::template has<T>::result << std::endl;
554 // std::cerr << " has container " << list_of_possible_features::template has<container>::result << std::endl;
556 const T* ptr = HLT::get<T, container,
557 list_of_possible_features::template has<container>::result,
558 list_of_possible_features::template has<T>::result>::do_it(fl, this);
566 __attribute__((__used__))
567 TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
568 const T* obj) const {
570 //typedef typename Features2Container<T>::type Container;
572 return TrigFeatureLink();
573 TriggerElement::FeatureVec features_access_helpers;
574 std::string sourcelabel;
575 if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, true, m_unspecifiedTE, sourcelabel ) == false ) {
576 return TrigFeatureLink();
579 // remove following after testing
580 if ( features_access_helpers.size() > 1 ) {
581 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors" );
584 if ( features_access_helpers.empty() )
585 return TrigFeatureLink();
587 const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
588 return TrigFeatureLink(ClassID_traits<T>::ID(), oindex.subTypeIndex(), oindex.objectsBegin());
593 __attribute__((__used__))
594 TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
595 const typename Container2Object<C>::type* obj,
596 const C* container) const {
598 TriggerElement::FeatureVec features_access_helpers;
599 std::string sourcelabel;
600 if ( getFeatureAccessors(te, ClassID_traits<C>::ID(), label, true, features_access_helpers, true, m_unspecifiedTE, sourcelabel ) == false ) {
601 return TrigFeatureLink();
603 // remove following after testing
604 if ( features_access_helpers.size() > 1 ) {
605 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors" );
608 if ( features_access_helpers.empty() )
609 return TrigFeatureLink();
611 const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
612 typename C::const_iterator lookup = std::find(container->begin(), container->end(),obj);
613 if ( lookup == container->end() )
614 return TrigFeatureLink();
616 const unsigned offset = lookup - container->begin();
617 return TrigFeatureLink(ClassID_traits<C>::ID(), oindex.subTypeIndex(), oindex.objectsBegin()+offset);