4 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
8 #ifndef TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
9 #define TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
12 #include "TrigNavigation/Holder.h"
13 #include "TrigNavigation/Holder.icc"
14 #include "CxxUtils/checker_macros.h"
15 #include "CxxUtils/no_sanitize_undefined.h"
17 /*****************************************************************************
19 * COMPILE TYPE OBJECTS REGISTRATION
21 *****************************************************************************/
22 #include <type_traits>//remove_pointer, remove_const
25 /////////////////////////////////////////////////////////////////////////////
27 __attribute__((__used__))
28 bool HLT::NavigationCore::getFeatures( const TriggerElement* te,
29 std::vector<const T*>& features, const std::string& label,
30 std::map<const T*, std::string>* /*labels*/) const {
33 class_id_type clid = ClassID_traits<T>::ID();
34 ATH_MSG_DEBUG("getFeatures: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
35 <<" to TE: " << te->getId()
36 << " label: \"" << label << "\"");
38 TriggerElement::FeatureVec features_access_helpers;
39 bool single = false; bool recursively = false;
40 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
44 for(auto& fea : features_access_helpers) {
45 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
46 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
48 if ( holder->get(obj, objectIndex) == false ) {
49 ATH_MSG_WARNING("getFeatures: problems while getting objects #" << objectIndex
50 << " from the holder: " << *holder);
52 features.push_back(obj);
58 /////////////////////////////////////////////////////////////////////////////
60 __attribute__((__used__))
61 bool HLT::NavigationCore::getFeature NO_SANITIZE_UNDEFINED ( const TriggerElement* te, const T*& feature, const std::string& label, std::string& sourcelabel) const {
65 class_id_type clid = ClassID_traits<T>::ID();
67 ATH_MSG_DEBUG("getFeature: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
68 <<" to TE: " << te->getId()
69 << " label: \"" << label << "\"");
71 TriggerElement::FeatureVec features_access_helpers;
72 bool single = true; bool recursively = false;
73 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, m_unspecifiedTE, sourcelabel)) {
76 // remove following after testing
77 if ( features_access_helpers.size() > 1 ) {
78 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors");
82 if ( features_access_helpers.empty() )
85 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
86 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
88 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
93 if ( holder->get(feature, objectIndex) == false ) {
94 ATH_MSG_WARNING("getFeature: problems while getting objects #" << objectIndex
95 << " from the holder: " << *holder);
103 __attribute__((__used__))
104 bool HLT::NavigationCore::getFeature( const TriggerElement* te,
105 const ConstDataVector<T>*& feature,
106 const std::string& label, std::string& sourcelabel) const {
107 const T* dv = nullptr;
108 if (!getFeature (te, dv, label, sourcelabel))
111 feature = ConstDataVector<T>::fromDataVector (dv);
112 return feature != nullptr;
116 /////////////////////////////////////////////////////////////////////////////
117 template<class C, class T>
118 __attribute__((__used__))
119 bool HLT::NavigationCore::getFeaturesLinks( const TriggerElement* te, ElementLinkVector<C>& links, const std::string& label) const {
121 class_id_type clid = ClassID_traits<T>::ID();
123 ATH_MSG_DEBUG("getFeaturesLinks: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
124 << " to TE: " << te->getId()
125 << " label: \"" << label << "\"");
127 TriggerElement::FeatureVec features_access_helpers;
128 bool single = false; bool recursively = false;
129 if (!getFeatureAccessors(te,clid, label, single, features_access_helpers, recursively)) {
133 for(auto& fea : features_access_helpers) {
134 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
135 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
137 if ( holder->get(links, objectIndex) == false ) {
138 ATH_MSG_WARNING("getFeaturesLinks: problems while getting objects #" << objectIndex
139 << " from the holder: " << *holder);
146 /////////////////////////////////////////////////////////////////////////////
148 __attribute__((__used__))
149 bool HLT::NavigationCore::getRecentFeatures( const TriggerElement* te,
150 std::vector<const T*>& features, const std::string& label,
151 std::map<const T*, std::string>* /*labels*/) const {
153 class_id_type clid = ClassID_traits<T>::ID();
156 ATH_MSG_DEBUG("getRecentFeatures: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
157 << " in TE: " << te->getId()
158 << " label: \"" << label << "\"");
160 TriggerElement::FeatureVec features_access_helpers;
161 bool single = false; bool recursively = true;
163 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
167 // type specific code
168 for( auto& fea : features_access_helpers) {
169 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
170 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
172 if ( holder->get(obj, objectIndex) == false ) {
173 ATH_MSG_WARNING("getRecentFeatures: problems while getting objects #" << objectIndex
174 << " from the holder: " << *holder);
176 features.push_back(obj);
182 /////////////////////////////////////////////////////////////////////////////
184 __attribute__((__used__))
185 bool HLT::NavigationCore::getRecentFeature( const TriggerElement* te,
186 const T*& feature, const std::string& label,
187 const TriggerElement*& source, std::string& sourcelabel ) const {
189 // important! set pointer to NULL to signify nothing was found, it will later be reset to sth else eventually
192 class_id_type clid = ClassID_traits<T>::ID();
194 ATH_MSG_DEBUG("getRecentFeature: looking for CLID: " << ClassID_traits<T>::ID() << "(" << ClassID_traits<T>::typeName() << ")"
195 << " in TE: " << te->getId()
196 << " label: \"" << label << "\"");
198 TriggerElement::FeatureVec features_access_helpers;
199 bool single = true; bool recursively = true;
201 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
204 // remove following after testing
205 if ( features_access_helpers.size() > 1 ) {
206 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
209 if ( features_access_helpers.empty() )
212 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
213 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
214 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
216 if ( holder->get(feature, objectIndex) == false ) {
217 ATH_MSG_WARNING("getRecentFeature: problems while getting objects #" << objectIndex
218 << " from the holder: " << *holder);
225 /////////////////////////////////////////////////////////////////////////////
226 template<class C, class T>
227 __attribute__((__used__))
228 bool HLT::NavigationCore::getRecentFeaturesLinks( const TriggerElement* te,
229 ElementLinkVector<C>& links, const std::string& label ) const {
232 class_id_type clid = ClassID_traits<T>::ID();
234 ATH_MSG_DEBUG("getRecentFeaturesLinks: looking for CLID: " << ClassID_traits<T>::ID()
235 << "(" << ClassID_traits<T>::typeName() << ")"
236 << " in TE: " << te->getId()
237 << " label: \"" << label << "\"");
239 TriggerElement::FeatureVec features_access_helpers;
240 bool single = false; bool recursively = true;
242 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively)) {
246 for(auto& fea : features_access_helpers) {
247 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
248 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
250 if ( holder->get(links, objectIndex) == false ) {
251 ATH_MSG_WARNING("getRecentFeaturesLinks: problems while getting objects #" << objectIndex
252 << " from the holder: " << *holder);
258 //helper struct to get the container type if template argument is datalink or the element type if template arg is ElementLink
260 template<class LinkType>
263 template<class CONTAINERTYPE>
264 struct link_to_type<DataLink<CONTAINERTYPE> >{
265 typedef CONTAINERTYPE container_type;
266 typedef typename DataLink<CONTAINERTYPE>::value_type type;
269 template<class CONTAINERTYPE>
270 struct link_to_type<ElementLink<CONTAINERTYPE> >{
271 typedef CONTAINERTYPE container_type;
272 typedef typename ElementLink<CONTAINERTYPE>::ElementType ptr2constT_type; // is a const T* if T is the feature type
273 typedef typename std::remove_pointer<ptr2constT_type>::type constT_type; // is a const T
274 typedef typename std::remove_const<constT_type>::type type; // is a T
278 /////////////////////////////////////////////////////////////////////////////
279 template<class LinkType>
280 __attribute__((__used__))
281 bool HLT::NavigationCore::getRecentFeatureDataOrElementLink( const TriggerElement* te, LinkType& link, const std::string& label,
282 const TriggerElement*& source, std::string& sourcelabel) const {
287 typedef typename link_to_type<LinkType>::type T;
288 class_id_type clid = ClassID_traits<T>::ID();
289 ATH_MSG_DEBUG("getRecentFeatureDataOrElementLink: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
290 << " in TE: " << te->getId()
291 << " label: \"" << label << "\"");
293 TriggerElement::FeatureVec features_access_helpers;
294 bool single = true; bool recursively = true;
295 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
296 ATH_MSG_INFO("looking for FAs failed. Returning false! Details CLID: " << ClassID_traits<T>::ID() <<
297 "(" << ClassID_traits<T>::typeName() << ")"
298 << " in TE: " << te->getId() << " label: \"" << label << "\"");
302 // remove following after testing
303 if ( features_access_helpers.size() > 1 ) {
304 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
307 if ( features_access_helpers.empty() )
310 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
311 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
312 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
314 //apparently must use function pointer to get all the types resolved properly
315 typedef typename link_to_type<LinkType>::container_type containertype;
316 bool (HLTNavDetails::Holder<T>::*funcptr) (LinkType&, HLT::TriggerElement::ObjectIndex&) =
317 &HLTNavDetails::Holder<T>::template getWithLink<containertype>;
319 if ( (holder->*funcptr)(link, objectIndex) == false ) {
320 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
321 << " from the holder: " << *holder);
326 /////////////////////////////////////////////////////////////////////////////
327 template<class C, class T>
328 __attribute__((__used__))
329 bool HLT::NavigationCore::getRecentFeatureLink( const TriggerElement* te,
330 ElementLink<C>& link, const std::string& label,
331 const TriggerElement*& source,
332 std::string& sourcelabel) const {
335 class_id_type clid = ClassID_traits<T>::ID();
338 ATH_MSG_DEBUG("getRecentFeatureLink: looking for CLID: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
339 << " in TE: " << te->getId()
340 << " label: \"" << label << "\"");
342 if( std::is_same<C, T>::value )
346 TriggerElement::FeatureVec features_access_helpers;
347 bool single = true; bool recursively = true;
349 if (!getFeatureAccessors(te, clid, label, single, features_access_helpers, recursively, source, sourcelabel)) {
352 // remove following after testing
353 if ( features_access_helpers.size() > 1 ) {
354 ATH_MSG_WARNING("getRecentFeature: logic error, got: " << features_access_helpers.size() << " features from: getRecentFeaturesImpl" );
357 if ( features_access_helpers.empty() )
360 const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
361 TriggerElement::ObjectIndex objectIndex(fea.getIndex());
362 HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
364 ElementLinkVector<C> links;
365 if ( holder->get(links, objectIndex) == false ) {
366 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
367 << " from the holder: " << *holder);
369 if ( links.size() != 1 ) {
370 ATH_MSG_WARNING("getRecentFeatureLink: problems while getting objects #" << objectIndex
371 << " from the holder: " << *holder << " links vector has size "
372 << links.size() << " while shoudl have size == 1");
382 /////////////////////////////////////////////////////////////////////////////
384 __attribute__((__used__))
385 bool HLT::NavigationCore::getFeaturesInRoI( const TriggerElement* te,
386 std::vector<const T*>& features, const std::string& label,
387 std::map<const T*, std::string>* labels) const {
388 // easy, jump to the RoI (if not RoI node) and loop over all TEs attached to it
389 const TriggerElement* roi(0);
390 if ( TrigNavStructure::isRoINode(te) )
392 else if ( te->getRelated(TriggerElement::sameRoIRelation).size() == 1 ) // means we do not support topological TEs here
393 roi = *(te->getRelated(TriggerElement::sameRoIRelation).begin());
397 bool oneRetStatus = false;
398 bool allRetStatus = false;
399 for ( const TriggerElement* te : roi->getRelated(TriggerElement::sameRoIRelation) ) {
400 oneRetStatus = getFeatures(te, features, label, labels ); // the features will be paked to the end of the vector (see push_back in getFeatures)
401 allRetStatus = allRetStatus || oneRetStatus; // that's OK if at least one call returns some feature
406 /////////////////////////////////////////////////////////////////////////////
407 template<class C, class T>
408 __attribute__((__used__))
409 bool HLT::NavigationCore::getAllFeatures( ElementLinkVector<C>& features, const std::string& label ) const {
410 std::lock_guard<std::recursive_mutex> lock(getMutex());
411 const TrigHolderStructure& holderstorage = getHolderStorage();
413 CLID clid = ClassID_traits<T>::ID();
414 ATH_MSG_DEBUG("getAllFeatures: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
415 << " label: \"" << label << "\"");
417 for ( auto& iholder : holderstorage.getHoldersOfClid(clid) ) {
418 if ( label == iholder->label() || label == "" ) {
419 HLTNavDetails::Holder<T>* holder = getHolder<T>(iholder->label(), nextSubTypeIndex(clid, label));
420 ATH_MSG_VERBOSE("getAllFeatures: getting from: " << *holder);
421 if ( holder->get(features) == false ) {
422 ATH_MSG_WARNING("getAllFeatures: failed with the holder of clid: " << clid <<
423 "(" << ClassID_traits<T>::typeName() << ")" << " label: \"" << label << "\"");
432 /////////////////////////////////////////////////////////////////////////////
434 __attribute__((__used__))
435 HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder NO_SANITIZE_UNDEFINED (const std::string& label, uint16_t suggestedIndex) const {
438 CLID clid = ClassID_traits<T>::ID();
439 ATH_MSG_DEBUG("Getting holder for type: " << clid << " label: " << label);
441 HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, label));
447 // take an appropriate action if this is the first feature of that type#label to be attached/retrieved
448 HLTNavDetails::IHolder* baseholder;
449 if ( createHolder(baseholder, clid, label, suggestedIndex) ) { // create fresh holder
450 ATH_MSG_DEBUG("getHolder: predefined holder got");
453 ATH_MSG_ERROR("getHolder: predefined holder does not exist, load EDM classes for: "
454 << ClassID_traits<T>::typeName() << " CLID " << ClassID_traits<T>::ID());
457 holder = static_cast<HLTNavDetails::Holder<T>*>(baseholder);
459 // registerHolder is thread-safe via a mutex:
460 auto nc_this ATLAS_THREAD_SAFE = const_cast<HLT::NavigationCore*>(this);
461 nc_this->registerHolder(holder);
466 /////////////////////////////////////////////////////////////////////////////
468 __attribute__((__used__))
469 HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder NO_SANITIZE_UNDEFINED (uint16_t subTypeIndex ) const {
471 CLID clid = ClassID_traits<T>::ID();
472 ATH_MSG_DEBUG("Getting holder for type: " << clid);
473 HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, subTypeIndex));
478 /////////////////////////////////////////////////////////////////////////////
479 // 2012-09-14 new stuff for composite obejcts
481 //#include "TrigNavigation/NavigationInit.h"
488 template<class T, class C, bool get_by_contianer, bool get_by_object>
491 template<class T, class C>
492 struct get< T, C, false, false>{
493 static const T* do_it(const TrigFeatureLink&, const HLT::NavigationCore* ){
494 return 0; // here compile time error shoudl be generated
498 template<class T, class C>
499 struct get< T, C, false, true>{
500 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
501 HLTNavDetails::Holder<T>* holder = nav->getHolder<T>(fl.subTypeIndex());
502 //std::cerr << " Holder acquired " << __LINE__ << std::endl;
504 holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
505 // std::cerr << " object retrieved " << __LINE__ << std::endl;
511 template<class T, class C>
512 struct get< T, C, true, false>{
513 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
514 HLTNavDetails::Holder<C>* holder = const_cast<HLT::NavigationCore*>(nav)->getHolder<C>(fl.subTypeIndex());
515 //std::cerr << " Holder acquired " << __LINE__ << " " << fl.clid() << " " << fl.subTypeIndex() << " " << holder << " " << ClassID_traits<C>::ID() << std::endl;
517 holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
518 //std::cerr << " object retrieved " << __LINE__ << std::endl;
519 if ( ptr and ptr->size() == 1) {
527 template<class T, class C>
528 struct get< T, C, true, true> {
529 static const T* do_it(const TrigFeatureLink&fl, const HLT::NavigationCore* nav){
530 if ( fl.clid() == ClassID_traits<C>::ID() ) {
531 return get<T,C, true, false>::do_it(fl, nav);
532 } else if ( fl.clid() == ClassID_traits<T>::ID() ) {
533 return get<T,C, false, true>::do_it(fl, nav);
541 __attribute__((__used__))
542 const T* HLT::NavigationCore::featureLink2Object( const TrigFeatureLink& fl) const {
546 typedef typename Object2Features<T>::type list_of_possible_features;
547 typedef typename Object2Container<T>::type container;
549 // std::cerr << " in the list " << HLT::tool::rtti_real_name(typeid(list_of_possible_features).name()) << std::endl;
550 // std::cerr << " container " << HLT::tool::rtti_real_name(typeid(container).name()) << std::endl;
551 // std::cerr << " has T " << list_of_possible_features::template has<T>::result << std::endl;
552 // std::cerr << " has container " << list_of_possible_features::template has<container>::result << std::endl;
554 const T* ptr = HLT::get<T, container,
555 list_of_possible_features::template has<container>::result,
556 list_of_possible_features::template has<T>::result>::do_it(fl, this);
564 __attribute__((__used__))
565 TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
566 const T* obj) const {
568 //typedef typename Features2Container<T>::type Container;
570 return TrigFeatureLink();
571 TriggerElement::FeatureVec features_access_helpers;
572 std::string sourcelabel;
573 if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, true, m_unspecifiedTE, sourcelabel ) == false ) {
574 return TrigFeatureLink();
577 // remove following after testing
578 if ( features_access_helpers.size() > 1 ) {
579 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors" );
582 if ( features_access_helpers.empty() )
583 return TrigFeatureLink();
585 const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
586 return TrigFeatureLink(ClassID_traits<T>::ID(), oindex.subTypeIndex(), oindex.objectsBegin());
591 __attribute__((__used__))
592 TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
593 const typename Container2Object<C>::type* obj,
594 const C* container) const {
596 TriggerElement::FeatureVec features_access_helpers;
597 std::string sourcelabel;
598 if ( getFeatureAccessors(te, ClassID_traits<C>::ID(), label, true, features_access_helpers, true, m_unspecifiedTE, sourcelabel ) == false ) {
599 return TrigFeatureLink();
601 // remove following after testing
602 if ( features_access_helpers.size() > 1 ) {
603 ATH_MSG_WARNING("getFeature: logic error, got: " << features_access_helpers.size() << " features from: getFeatureAccessors" );
606 if ( features_access_helpers.empty() )
607 return TrigFeatureLink();
609 const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
610 typename C::const_iterator lookup = std::find(container->begin(), container->end(),obj);
611 if ( lookup == container->end() )
612 return TrigFeatureLink();
614 const unsigned offset = lookup - container->begin();
615 return TrigFeatureLink(ClassID_traits<C>::ID(), oindex.subTypeIndex(), oindex.objectsBegin()+offset);