4 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
8 #ifndef TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
9 #define TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
13 #include <boost/mpl/if.hpp>
15 #include "TrigNavigation/Holder.h"
16 #include "TrigNavigation/Holder.icc"
17 #include "CxxUtils/checker_macros.h"
18 #include "CxxUtils/no_sanitize_undefined.h"
20 /*****************************************************************************
22 * COMPILE TYPE OBJECTS REGISTRATION
24 *****************************************************************************/
25 #include <type_traits>
28 /////////////////////////////////////////////////////////////////////////////
30 __attribute__((__used__))
31 bool HLT::NavigationCore::getFeatures( const TriggerElement* te,
32 std::vector<const T*>& features, const std::string& label,
33 std::map<const T*, std::string>* /*labels*/) const {
36 class_id_type clid = ClassID_traits<T>::ID();
37 ATH_MSG_DEBUG("getFeatures: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
38 <<" to TE: " << te->getId()
39 << " label: \"" << label << "\"");
41 TriggerElement::FeatureVec features_access_helpers;
42 bool single = false; bool recursively = false;
43 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
47 for(auto& fea : features_access_helpers) {
48 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
49 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
51 if ( holder->get(obj, objectIndex) == false ) {
52 ATH_MSG_WARNING("getFeatures: problems while getting objects #" << objectIndex
53 << " from the holder: " << *holder);
55 features.push_back(obj);
61 /////////////////////////////////////////////////////////////////////////////
63 __attribute__((__used__))
64 bool HLT::NavigationCore::getFeature NO_SANITIZE_UNDEFINED ( const TriggerElement* te, const T*& feature, const std::string& label, std::string& sourcelabel) const {
68 class_id_type clid = ClassID_traits<T>::ID();
70 ATH_MSG_DEBUG("getFeature: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
71 <<" to TE: " << te->getId()
72 << " label: \"" << label << "\"");
74 TriggerElement::FeatureVec features_access_helpers;
75 bool single = true; bool recursively = false;
76 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, m_unspecifiedTE, sourcelabel)) {
79 // remove following after testing
80 if ( features_access_helpers.size() > 1 ) {
81 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors");
85 if ( features_access_helpers.empty() )
88 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
89 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
91 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
96 if ( holder->get(feature, objectIndex) == false ) {
97 ATH_MSG_WARNING("getFeature: problems while getting objects #" << objectIndex
98 << " from the holder: " << *holder);
106 __attribute__((__used__))
107 bool HLT::NavigationCore::getFeature( const TriggerElement* te,
108 const ConstDataVector<T>*& feature,
109 const std::string& label, std::string& sourcelabel) const {
110 const T* dv = nullptr;
111 if (!getFeature (te, dv, label, sourcelabel))
114 feature = ConstDataVector<T>::fromDataVector (dv);
115 return feature != nullptr;
119 /////////////////////////////////////////////////////////////////////////////
120 template<class C, class T>
121 __attribute__((__used__))
122 bool HLT::NavigationCore::getFeaturesLinks( const TriggerElement* te, ElementLinkVector<C>& links, const std::string& label) const {
124 class_id_type clid = ClassID_traits<T>::ID();
126 ATH_MSG_DEBUG("getFeaturesLinks: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
127 << " to TE: " << te->getId()
128 << " label: \"" << label << "\"");
130 TriggerElement::FeatureVec features_access_helpers;
131 bool single = false; bool recursively = false;
132 if (!getFeatureAccessors(te,clid, label, single, features_access_helpers, recursively)) {
136 for(auto& fea : features_access_helpers) {
137 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
138 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
140 if ( holder->get(links, objectIndex) == false ) {
141 ATH_MSG_WARNING("getFeaturesLinks: problems while getting objects #" << objectIndex
142 << " from the holder: " << *holder);
149 /////////////////////////////////////////////////////////////////////////////
151 __attribute__((__used__))
152 bool HLT::NavigationCore::getRecentFeatures( const TriggerElement* te,
153 std::vector<const T*>& features, const std::string& label,
154 std::map<const T*, std::string>* /*labels*/) const {
156 class_id_type clid = ClassID_traits<T>::ID();
159 ATH_MSG_DEBUG("getRecentFeatures: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
160 << " in TE: " << te->getId()
161 << " label: \"" << label << "\"");
163 TriggerElement::FeatureVec features_access_helpers;
164 bool single = false; bool recursively = true;
166 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
170 // type specific code
171 for( auto& fea : features_access_helpers) {
172 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
173 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
175 if ( holder->get(obj, objectIndex) == false ) {
176 ATH_MSG_WARNING("getRecentFeatures: problems while getting objects #" << objectIndex
177 << " from the holder: " << *holder);
179 features.push_back(obj);
185 /////////////////////////////////////////////////////////////////////////////
187 __attribute__((__used__))
188 bool HLT::NavigationCore::getRecentFeature( const TriggerElement* te,
189 const T*& feature, const std::string& label,
190 const TriggerElement*& source, std::string& sourcelabel ) const {
192 // important! set pointer to NULL to signify nothing was found, it will later be reset to sth else eventually
195 class_id_type clid = ClassID_traits<T>::ID();
197 ATH_MSG_DEBUG("getRecentFeature: looking for CLID: " << ClassID_traits<T>::ID() << "(" << ClassID_traits<T>::typeName() << ")"
198 << " in TE: " << te->getId()
199 << " label: \"" << label << "\"");
201 TriggerElement::FeatureVec features_access_helpers;
202 bool single = true; bool recursively = true;
204 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
207 // remove following after testing
208 if ( features_access_helpers.size() > 1 ) {
209 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
212 if ( features_access_helpers.empty() )
215 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
216 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
217 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
219 if ( holder->get(feature, objectIndex) == false ) {
220 ATH_MSG_WARNING("getRecentFeature: problems while getting objects #" << objectIndex
221 << " from the holder: " << *holder);
228 /////////////////////////////////////////////////////////////////////////////
229 template<class C, class T>
230 __attribute__((__used__))
231 bool HLT::NavigationCore::getRecentFeaturesLinks( const TriggerElement* te,
232 ElementLinkVector<C>& links, const std::string& label ) const {
235 class_id_type clid = ClassID_traits<T>::ID();
237 ATH_MSG_DEBUG("getRecentFeaturesLinks: looking for CLID: " << ClassID_traits<T>::ID()
238 << "(" << ClassID_traits<T>::typeName() << ")"
239 << " in TE: " << te->getId()
240 << " label: \"" << label << "\"");
242 TriggerElement::FeatureVec features_access_helpers;
243 bool single = false; bool recursively = true;
245 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
249 for(auto& fea : features_access_helpers) {
250 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
251 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
253 if ( holder->get(links, objectIndex) == false ) {
254 ATH_MSG_WARNING("getRecentFeaturesLinks: problems while getting objects #" << objectIndex
255 << " from the holder: " << *holder);
261 //helper struct to get the container type if template argument is datalink or the element type if template arg is ElementLink
263 template<class LinkType>
266 template<class CONTAINERTYPE>
267 struct link_to_type<DataLink<CONTAINERTYPE> >{
268 typedef CONTAINERTYPE container_type;
269 typedef typename DataLink<CONTAINERTYPE>::value_type type;
272 template<class CONTAINERTYPE>
273 struct link_to_type<ElementLink<CONTAINERTYPE> >{
274 typedef CONTAINERTYPE container_type;
275 typedef typename ElementLink<CONTAINERTYPE>::ElementType ptr2constT_type; // is a const T* if T is the feature type
276 typedef typename std::remove_pointer<ptr2constT_type>::type constT_type; // is a const T
277 typedef typename std::remove_const<constT_type>::type type; // is a T
281 /////////////////////////////////////////////////////////////////////////////
282 template<class LinkType>
283 __attribute__((__used__))
284 bool HLT::NavigationCore::getRecentFeatureDataOrElementLink( const TriggerElement* te, LinkType& link, const std::string& label,
285 const TriggerElement*& source, std::string& sourcelabel) const {
290 typedef typename link_to_type<LinkType>::type T;
291 class_id_type clid = ClassID_traits<T>::ID();
292 ATH_MSG_DEBUG("getRecentFeatureDataOrElementLink: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
293 << " in TE: " << te->getId()
294 << " label: \"" << label << "\"");
296 TriggerElement::FeatureVec features_access_helpers;
297 bool single = true; bool recursively = true;
298 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
299 ATH_MSG_INFO("looking for FAs failed. Returning false! Details CLID: " << ClassID_traits<T>::ID() <<
300 "(" << ClassID_traits<T>::typeName() << ")"
301 << " in TE: " << te->getId() << " label: \"" << label << "\"");
305 // remove following after testing
306 if ( features_access_helpers.size() > 1 ) {
307 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
310 if ( features_access_helpers.empty() )
313 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
314 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
315 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
317 //apparently must use function pointer to get all the types resolved properly
318 typedef typename link_to_type<LinkType>::container_type containertype;
319 bool (HLTNavDetails::Holder<T>::*funcptr) (LinkType&, HLT::TriggerElement::ObjectIndex&) =
320 &HLTNavDetails::Holder<T>::template getWithLink<containertype>;
322 if ( (holder->*funcptr)(link, objectIndex) == false ) {
323 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
324 << " from the holder: " << *holder);
329 /////////////////////////////////////////////////////////////////////////////
330 template<class C, class T>
331 __attribute__((__used__))
332 bool HLT::NavigationCore::getRecentFeatureLink( const TriggerElement* te,
333 ElementLink<C>& link, const std::string& label,
334 const TriggerElement*& source,
335 std::string& sourcelabel) const {
338 class_id_type clid = ClassID_traits<T>::ID();
341 ATH_MSG_DEBUG("getRecentFeatureLink: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
342 << " in TE: " << te->getId()
343 << " label: \"" << label << "\"");
345 if( std::is_same<C, T>::value )
349 TriggerElement::FeatureVec features_access_helpers;
350 bool single = true; bool recursively = true;
352 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
355 // remove following after testing
356 if ( features_access_helpers.size() > 1 ) {
357 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
360 if ( features_access_helpers.empty() )
363 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
364 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
365 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
367 ElementLinkVector<C> links;
368 if ( holder->get(links, objectIndex) == false ) {
369 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
370 << " from the holder: " << *holder);
372 if ( links.size() != 1 ) {
373 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
374 << " from the holder: " << *holder << " links vector has size "
375 << links.size() << " while shoudl have size == 1");
385 /////////////////////////////////////////////////////////////////////////////
387 __attribute__((__used__))
388 bool HLT::NavigationCore::getFeaturesInRoI( const TriggerElement* te,
389 std::vector<const T*>& features, const std::string& label,
390 std::map<const T*, std::string>* labels) const {
391 // easy, jump to the RoI (if not RoI node) and loop over all TEs attached to it
392 const TriggerElement* roi(0);
393 if ( TrigNavStructure::isRoINode(te) )
395 else if ( te->getRelated(TriggerElement::sameRoIRelation).size() == 1 ) // means we do not support topological TEs here
396 roi = *(te->getRelated(TriggerElement::sameRoIRelation).begin());
400 bool oneRetStatus = false;
401 bool allRetStatus = false;
402 for ( const TriggerElement* te : roi->getRelated(TriggerElement::sameRoIRelation) ) {
403 oneRetStatus = getFeatures(te, features, label, labels ); // the features will be paked to the end of the vector (see push_back in getFeatures)
404 allRetStatus = allRetStatus || oneRetStatus; // that's OK if at least one call returns some feature
409 /////////////////////////////////////////////////////////////////////////////
410 template<class C, class T>
411 __attribute__((__used__))
412 bool HLT::NavigationCore::getAllFeatures( ElementLinkVector<C>& features, const std::string& label ) const {
413 std::lock_guard<std::recursive_mutex> lock(getMutex());
414 const TrigHolderStructure& holderstorage = getHolderStorage();
416 CLID clid = ClassID_traits<T>::ID();
417 ATH_MSG_DEBUG("getAllFeatures: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
418 << " label: \"" << label << "\"");
420 for ( auto& iholder : holderstorage.getHoldersOfClid(clid) ) {
421 if ( label == iholder->label() || label == "" ) {
422 HLTNavDetails::Holder<T>* holder = getHolder<T>(iholder->label(), nextSubTypeIndex(clid, label));
423 ATH_MSG_VERBOSE("getAllFeatures: getting from: " << *holder);
424 if ( holder->get(features) == false ) {
425 ATH_MSG_WARNING("getAllFeatures: failed with the holder of clid: " << clid <<
426 "(" << ClassID_traits<T>::typeName() << ")" << " label: \"" << label << "\"");
435 /////////////////////////////////////////////////////////////////////////////
437 __attribute__((__used__))
438 HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder NO_SANITIZE_UNDEFINED (const std::string& label, uint16_t suggestedIndex) const {
441 CLID clid = ClassID_traits<T>::ID();
442 ATH_MSG_DEBUG("Getting holder for type: " << clid << " label: " << label);
444 HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, label));
450 // take an appropriate action if this is the first feature of that type#label to be attached/retrieved
451 HLTNavDetails::IHolder* baseholder;
452 if ( createHolder(baseholder, clid, label, suggestedIndex) ) { // create fresh holder
453 ATH_MSG_DEBUG("getHolder: predefined holder got");
456 ATH_MSG_ERROR("getHolder: predefined holder does not exist, load EDM classes for: "
457 << ClassID_traits<T>::typeName() << " CLID " << ClassID_traits<T>::ID());
460 holder = static_cast<HLTNavDetails::Holder<T>*>(baseholder);
462 // registerHolder is thread-safe via a mutex:
463 auto nc_this ATLAS_THREAD_SAFE = const_cast<HLT::NavigationCore*>(this);
464 nc_this->registerHolder(holder);
469 /////////////////////////////////////////////////////////////////////////////
471 __attribute__((__used__))
472 HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder NO_SANITIZE_UNDEFINED (uint16_t subTypeIndex ) const {
474 CLID clid = ClassID_traits<T>::ID();
475 ATH_MSG_DEBUG("Getting holder for type: " << clid);
476 HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, subTypeIndex));
481 /////////////////////////////////////////////////////////////////////////////
482 // 2012-09-14 new stuff for composite obejcts
484 #include "TrigNavigation/NavigationInit.h"
491 template<class T, class C, bool get_by_contianer, bool get_by_object>
494 template<class T, class C>
495 struct get< T, C, false, false>{
496 static const T* do_it(const TrigFeatureLink&, const HLT::NavigationCore* ){
497 return 0; // here compile time error shoudl be generated
501 template<class T, class C>
502 struct get< T, C, false, true>{
503 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
504 HLTNavDetails::Holder<T>* holder = nav->getHolder<T>(fl.subTypeIndex());
505 //std::cerr << " Holder acquired " << __LINE__ << std::endl;
507 holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
508 // std::cerr << " object retrieved " << __LINE__ << std::endl;
514 template<class T, class C>
515 struct get< T, C, true, false>{
516 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
517 HLTNavDetails::Holder<C>* holder = const_cast<HLT::NavigationCore*>(nav)->getHolder<C>(fl.subTypeIndex());
518 //std::cerr << " Holder acquired " << __LINE__ << " " << fl.clid() << " " << fl.subTypeIndex() << " " << holder << " " << ClassID_traits<C>::ID() << std::endl;
520 holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
521 //std::cerr << " object retrieved " << __LINE__ << std::endl;
522 if ( ptr and ptr->size() == 1) {
530 template<class T, class C>
531 struct get< T, C, true, true> {
532 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
533 if ( fl.clid() == ClassID_traits<C>::ID() ) {
534 return get<T,C, true, false>::do_it(fl, nav);
535 } else if ( fl.clid() == ClassID_traits<T>::ID() ) {
536 return get<T,C, false, true>::do_it(fl, nav);
544 __attribute__((__used__))
545 const T* HLT::NavigationCore::featureLink2Object( const TrigFeatureLink& fl) const {
549 typedef typename Object2Features<T>::type list_of_possible_features;
550 typedef typename Object2Container<T>::type container;
552 // std::cerr << " in the list " << HLT::tool::rtti_real_name(typeid(list_of_possible_features).name()) << std::endl;
553 // std::cerr << " container " << HLT::tool::rtti_real_name(typeid(container).name()) << std::endl;
554 // std::cerr << " has T " << list_of_possible_features::template has<T>::result << std::endl;
555 // std::cerr << " has container " << list_of_possible_features::template has<container>::result << std::endl;
557 const T* ptr = HLT::get<T, container,
558 list_of_possible_features::template has<container>::result,
559 list_of_possible_features::template has<T>::result>::do_it(fl, this);
567 __attribute__((__used__))
568 TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
569 const T* obj) const {
571 //typedef typename Features2Container<T>::type Container;
573 return TrigFeatureLink();
574 TriggerElement::FeatureVec features_access_helpers;
575 std::string sourcelabel;
576 if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, true, m_unspecifiedTE, sourcelabel ) == false ) {
577 return TrigFeatureLink();
580 // remove following after testing
581 if ( features_access_helpers.size() > 1 ) {
582 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors" );
585 if ( features_access_helpers.empty() )
586 return TrigFeatureLink();
588 const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
589 return TrigFeatureLink(ClassID_traits<T>::ID(), oindex.subTypeIndex(), oindex.objectsBegin());
594 __attribute__((__used__))
595 TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
596 const typename Container2Object<C>::type* obj,
597 const C* container) const {
599 TriggerElement::FeatureVec features_access_helpers;
600 std::string sourcelabel;
601 if ( getFeatureAccessors(te, ClassID_traits<C>::ID(), label, true, features_access_helpers, true, m_unspecifiedTE, sourcelabel ) == false ) {
602 return TrigFeatureLink();
604 // remove following after testing
605 if ( features_access_helpers.size() > 1 ) {
606 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors" );
609 if ( features_access_helpers.empty() )
610 return TrigFeatureLink();
612 const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
613 typename C::const_iterator lookup = std::find(container->begin(), container->end(),obj);
614 if ( lookup == container->end() )
615 return TrigFeatureLink();
617 const unsigned offset = lookup - container->begin();
618 return TrigFeatureLink(ClassID_traits<C>::ID(), oindex.subTypeIndex(), oindex.objectsBegin()+offset);