00001 #ifndef XAOD_ANALYSIS
00002
00003
00004 #ifndef TRIGGER_DECISION_TOOL_FeatureCollectAthena_H
00005 #define TRIGGER_DECISION_TOOL_FeatureCollectAthena_H
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <string>
00020 #include <set>
00021 #include "boost/foreach.hpp"
00022 #include "boost/type_traits/is_same.hpp"
00023 #include "boost/shared_ptr.hpp"
00024 #include "boost/lexical_cast.hpp"
00025
00026 #include "TrigNavigation/NavigationCore.h"
00027 #include "TrigNavigation/NavigationCore.icc"
00028 #include "TrigDecisionTool/Conditions.h"
00029 #include "TrigDecisionTool/TDTUtilities.h"
00030 #include "TrigDecisionTool/ClassTraits.h"
00031
00032 #include "TrigSteeringEvent/TrigPassBits.h"
00033 #include "TrigSteeringEvent/TrigPassFlags.h"
00034
00035
00036
00037 #include "TrigSteeringEvent/TrigPassBits.h"
00038 #include "TrigSteeringEvent/TrigPassFlags.h"
00039
00040 #include "AnalysisTriggerEvent/Muon_ROI.h"
00041 #include "AnalysisTriggerEvent/EmTau_ROI.h"
00042 #include "AnalysisTriggerEvent/Jet_ROI.h"
00043 #include "AnalysisTriggerEvent/JetET_ROI.h"
00044 #include "AnalysisTriggerEvent/EnergySum_ROI.h"
00045 #include "AnalysisTriggerEvent/LVL1_ROI.h"
00046
00047 #include "xAODTrigger/EmTauRoI.h"
00048 #include "xAODTrigger/EmTauRoIContainer.h"
00049
00050 #include "xAODTrigger/MuonRoI.h"
00051 #include "xAODTrigger/MuonRoIContainer.h"
00052
00053 #include "xAODTrigger/JetRoI.h"
00054 #include "xAODTrigger/JetRoIContainer.h"
00055
00056
00057
00058 #include "TrigStorageDefinitions/EDM_TypeInfo.h"
00059
00060
00061 #include "TrigDecisionTool/Feature.h"
00062
00063 namespace Trig {
00064
00069 namespace FeatureAccessImpl {
00070
00071 const TrigPassBits* getBits(size_t sz, const HLT::TriggerElement* te, const std::string& label, HLT::NavigationCore* navigation );
00072
00073 const TrigPassFlags* getFlags(size_t sz, const HLT::TriggerElement* te, const std::string& label, HLT::NavigationCore* navigation );
00074
00075
00076
00077 template<typename T>
00078 struct isDataVector {
00079 private:
00080
00081 typedef char true_type;
00082 struct false_type { char dummy[2]; };
00083
00084
00085 template<typename U> static true_type trait_test_helper(typename U::ElementProxy*);
00086 template<typename U> static false_type trait_test_helper(...);
00087 public:
00088 static const bool value=sizeof(trait_test_helper<T>(0))==sizeof(true_type);
00089 };
00090
00091
00092
00093 template<class T>
00094 const typename boost::disable_if_c<isDataVector<T>::value, T>::type*
00095 use_or_construct(const T* source, const HLT::TriggerElement*, const std::string&, unsigned int, HLT::NavigationCore* ) {
00096 return source;
00097 }
00098
00099
00100 template<class T>
00101 const typename
00102 boost::enable_if_c<isDataVector<T>::value, T>::type*
00103 use_or_construct(const T* source, const HLT::TriggerElement* te, const std::string& label, unsigned int condition, HLT::NavigationCore* navigation ) {
00104
00105 const TrigPassBits* bits(0);
00106 if ( condition == TrigDefs::Physics ) {
00107 bits = getBits(source->size(), te, label , navigation);
00108 }
00109 if ( bits ) {
00110 T* destination = new T();
00111 destination->clear(SG::VIEW_ELEMENTS);
00112
00113
00114
00115
00116 BOOST_FOREACH(const typename T::base_value_type *obj, *source) {
00117 if ( HLT::isPassing(bits, obj, source) )
00118 destination->push_back(const_cast<typename T::value_type>(obj));
00119 }
00120 return destination;
00121 }
00122
00123 return source;
00124 }
00125
00126
00127
00128
00129
00130 template<class T, class CONT, bool flatten, class LINK> struct insert_and_flatten;
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 template<class T, class STORED,class LINK>
00141 struct insert_and_flatten<T,STORED, false, LINK> {
00142 static void do_it(std::vector<Trig::Feature<T> >& destination, const STORED* source, const HLT::TriggerElement* te, const std::string& label,
00143 unsigned int condition, HLT::NavigationCore* navigation, const LINK& lnk) {
00144
00145 const T* possibly_reduced_possibly_container = use_or_construct<T>(source, te, label, condition, navigation);
00146 destination.push_back(Trig::Feature<T>(possibly_reduced_possibly_container, te, label, possibly_reduced_possibly_container != source,lnk));
00147 }
00148 };
00149
00150
00151
00152 template<class T, class CONT, class LINK>
00153 struct insert_and_flatten<T, CONT, true, LINK> {
00154 static void do_it(std::vector<Trig::Feature<T> >& destination, const CONT* source, const HLT::TriggerElement* te, const std::string& label,
00155 unsigned int condition, HLT::NavigationCore* navigation,const LINK& lnk) {
00156 (void)lnk;
00157
00158
00159
00160 const TrigPassBits* bits(0);
00161 if ( condition == TrigDefs::Physics ) {
00162
00163 bits =getBits(source->size(), te, label , navigation);
00164 }
00165
00166 BOOST_FOREACH(const T* obj, *source) {
00167 if ( bits==0 || HLT::isPassing(bits, obj, source) ) {
00168
00169 destination.push_back(Trig::Feature<T>(obj, te, label,false,ElementLink<typename LINK::value_type>(obj,*source)));
00170 }
00171 }
00172 }
00173 };
00174
00175 template<class LINK, bool is_container> struct print_features;
00176
00177 template<class LINK> struct print_features<LINK,true>{
00178 typedef const typename LINK::value_type* ptr_type;
00179 static ptr_type get_ptr(const LINK& link){return link.cptr();}
00180 static void do_it(const LINK& link, bool ){
00181
00182 for(unsigned int j=0;j<link.cptr()->size();++j){
00183
00184 }
00185
00186 }
00187 };
00188
00189 template<class LINK> struct print_features<LINK,false>{
00190 typedef typename LINK::ElementType ptr_type;
00191 static ptr_type get_ptr(const LINK& link){return *link;}
00192 static void do_it(const LINK& ,bool ){
00193
00194
00195 }
00196 };
00197
00198 struct true_type{};
00199 struct false_type{};
00200 template <bool retrieve> struct get_type;
00201 template <> struct get_type<true>{typedef true_type type;};
00202 template <> struct get_type<false>{typedef false_type type;};
00203
00204 template<class REQUESTED,class EDMLIST>
00205 struct get_links {
00206 get_links():m_te(nullptr),
00207 m_data(nullptr),
00208 m_condition(0),
00209 m_navigation(nullptr),
00210 m_result(),
00211 m_sourceTE(0)
00212 {}
00213 get_links( const HLT::TriggerElement* te,
00214 std::vector<Trig::Feature<REQUESTED> >* data,
00215 const std::string& label, unsigned int condition,
00216 const std::string& teName,
00217 HLT::NavigationCore* navigation,
00218 bool* result,
00219 const HLT::TriggerElement** sourceTE):
00220 m_te(te), m_data(data), m_label(label), m_condition(condition), m_teName(teName), m_navigation(navigation), m_result(result), m_sourceTE(sourceTE){}
00221
00222
00223 template<class FEATURE>
00224 void do_it() const {
00225
00226
00227
00228 typedef typename Features2Container<FEATURE,EDMLIST>::type container_type;
00229 typedef typename Features2Object<FEATURE,EDMLIST>::type object_type;
00230
00231 const bool do_flatten = (! boost::is_same<REQUESTED,container_type>::value) && boost::is_same<FEATURE,container_type>::value;
00232 const bool do_retrieve = ! (boost::is_same<REQUESTED,container_type>::value && boost::is_same<FEATURE,object_type>::value);
00233
00234
00235 _do_it<FEATURE,do_flatten>(typename get_type<do_retrieve>::type());
00236 }
00237
00238 template<class FEATURE,bool do_flatten>
00239 void _do_it(false_type dummy = false_type()) const {(void)dummy;;}
00240
00241 template<class FEATURE,bool do_flatten>
00242 void _do_it(true_type dummy = true_type()) const {
00243 (void)dummy;
00244
00245
00246 std::string sourceLabel;
00247
00248 typedef typename Features2Container<FEATURE,EDMLIST>::type container_type;
00249
00250 typedef typename Features2LinkHelper<FEATURE,container_type>::type link_type;
00251
00252
00253
00254
00255
00256 link_type link;
00257 bool new_result = m_navigation->getRecentFeatureDataOrElementLink( m_te, link, m_label, *m_sourceTE, sourceLabel );
00258
00259 if (new_result) {
00260 if (m_teName == "" || m_teName == Trig::getTEName(**m_sourceTE)) {
00261 if (link.cptr()) {
00262
00263
00264 insert_and_flatten<REQUESTED,FEATURE, do_flatten,link_type>::do_it(*m_data,
00265 print_features<link_type,boost::is_same<FEATURE,container_type>::value>::get_ptr(link),
00266 *m_sourceTE, sourceLabel, m_condition, m_navigation,link);
00267 }
00268 }
00269 }
00270 *m_result = *m_result && new_result;
00271 }
00272
00273 const HLT::TriggerElement* m_te;
00274 std::vector<Trig::Feature<REQUESTED> >* m_data;
00275 const std::string m_label;
00276 unsigned int m_condition;
00277 std::string m_teName;
00278 HLT::NavigationCore* m_navigation;
00279 bool* m_result;
00280 const HLT::TriggerElement** m_sourceTE;
00281 };
00282
00287 template<class T>
00288 void collect(const HLT::TriggerElement* te, std::vector<Trig::Feature<T> >& data, const std::string& label, unsigned int condition,
00289 const std::string& teName, HLT::TrigNavStructure* navstructure) {
00290
00291 auto navigation = dynamic_cast<HLT::NavigationCore*>(navstructure);
00292
00293
00294
00295 if (condition == TrigDefs::Physics && !te->getActiveState() ) return;
00296 const HLT::TriggerElement* sourceTE(0);
00297 std::string sourceLabel;
00298
00299
00300 bool result = true;
00301 #ifndef __GCCXML__
00302
00303 typedef typename Features2Object<T>::type object_type;
00304 typedef typename Object2Features<object_type>::type feature_list;
00305 get_links<T,TypeInfo_EDM> link_getter( te, &data, label, condition, teName, navigation, &result, &sourceTE);
00306 HLT::TypeInformation::for_each_type<feature_list,get_links<T,TypeInfo_EDM> >::do_it(&link_getter);
00307 #endif
00308
00309 if (result){
00310 } else {
00311
00312 const std::vector<HLT::TriggerElement*> bif_tes = navigation->getDirectPredecessors(sourceTE);
00313 if ( bif_tes.size() <= 1 ) {
00314 return;
00315 } else {
00316
00317 BOOST_FOREACH( const HLT::TriggerElement* predecesor_te, bif_tes )
00318 collect(predecesor_te, data, label, condition, teName, navigation);
00319 }
00320 }
00321
00322 }
00323
00324
00325 template<>
00326 void collect<Muon_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<Muon_ROI> >& data, const std::string&, unsigned int, const std::string&, HLT::TrigNavStructure* navigation);
00327
00328 template<>
00329 void collect<EmTau_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<EmTau_ROI> >& data, const std::string&, unsigned int, const std::string&, HLT::TrigNavStructure* navigation);
00330
00331 template<>
00332 void collect<Jet_ROI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<Jet_ROI> >& data, const std::string&, unsigned int, const std::string&, HLT::TrigNavStructure* navigation);
00333
00334 template<>
00335 void collect<xAOD::EmTauRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::EmTauRoI> >& data, const std::string&, unsigned int, const std::string&, HLT::TrigNavStructure* navigation);
00336
00337 template<>
00338 void collect<xAOD::MuonRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::MuonRoI> >& data, const std::string&, unsigned int, const std::string&, HLT::TrigNavStructure* navigation);
00339
00340 template<>
00341 void collect<xAOD::JetRoI>(const HLT::TriggerElement* te, std::vector<Trig::Feature<xAOD::JetRoI> >& data, const std::string&, unsigned int, const std::string&, HLT::TrigNavStructure* navigation);
00342
00343
00344
00345
00346
00347
00348
00349
00350 template<class CONT> TrigPassFlags
00351 build_flags (const typename boost::enable_if_c<isDataVector<CONT>::value, CONT>::type *orig_cont, const CONT* cont, const TrigPassFlags * orig_tpf) {
00352 TrigPassFlags tpf(cont->size(), orig_tpf->flagSize());
00353
00354 if(orig_cont->size() != orig_tpf->size()) {
00355
00356 return tpf;
00357 }
00358
00359 unsigned int currentPos=0;
00360 BOOST_FOREACH(const typename CONT::base_value_type* obj, *cont) {
00361 typename CONT::const_iterator orig_obj = std::find(orig_cont->begin(),orig_cont->end(),obj);
00362
00363 if(orig_obj == orig_cont->end()) {
00364
00365 } else {
00366 size_t idx = orig_obj-orig_cont->begin();
00367 tpf.setFlag(currentPos, orig_tpf->getFlag(idx));
00368 }
00369 currentPos++;
00370 }
00371
00372 return tpf;
00373 }
00374
00375
00376 template<class T> TrigPassFlags
00377 build_flags (const typename boost::disable_if_c<isDataVector<T>::value, T>::type *orig, const T* feature, const TrigPassFlags * orig_tpf) {
00378 if(orig != feature) return TrigPassFlags();
00379
00380 TrigPassFlags tpf(1, orig_tpf->flagSize());
00381 tpf.setFlag(0,orig_tpf->getFlag(0));
00382 return tpf;
00383 }
00384
00385
00386
00387
00388 template<class T, class STORED> TrigPassFlags
00389 build_flags2(const STORED* orig_cont, const T* obj, const TrigPassFlags * orig_tpf)
00390 {
00391 if(orig_cont->size() != orig_tpf->size()) {
00392
00393 return TrigPassFlags();
00394 }
00395
00396 TrigPassFlags tpf(1, orig_tpf->flagSize());
00397
00398 typename STORED::const_iterator orig_obj = std::find(orig_cont->begin(),orig_cont->end(), obj);
00399
00400 if(orig_obj == orig_cont->end()) {
00401
00402 } else {
00403 size_t idx = orig_obj-orig_cont->begin();
00404 tpf.setFlag(0, orig_tpf->getFlag(idx));
00405 }
00406 return tpf;
00407 }
00408
00409
00410
00411
00412
00413 template<class T, class STORED, bool same> struct getFlagsHelper;
00414
00415
00416 template<class T, class STORED> struct getFlagsHelper<T, STORED, true> {
00417 static TrigPassFlags do_build(const STORED* orig_feat, const T* feat, const TrigPassFlags * orig_tpf) {
00418 return build_flags(orig_feat, feat, orig_tpf);
00419 }
00420 };
00421
00422
00423
00424 template<class T, class STORED> struct getFlagsHelper<T, STORED, false> {
00425 static TrigPassFlags do_build(const STORED* orig_feat, const T* feat, const TrigPassFlags * orig_tpf) {
00426 return build_flags2(orig_feat, feat, orig_tpf);
00427 }
00428 };
00429
00430
00431
00432
00433
00434 template<class T> TrigPassFlags
00435 getFlags(const Trig::Feature<T>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation ) {
00436
00437 typedef typename TrigDec::ClassTraits<T>::type STORED;
00438
00439 const STORED* orig(0);
00440 const HLT::TriggerElement* sourceTE(0);
00441 std::string sourceLabel("");
00442 if (navigation->getRecentFeature(f.te(), orig, f.label(), sourceTE, sourceLabel)) {
00443 TrigPassFlags tpf = getFlagsHelper<T,STORED, boost::is_same<T,STORED>::value>::do_build(orig, f.cptr(), orig_tpf);
00444 return tpf;
00445 }
00446 return TrigPassFlags();
00447
00448 }
00449
00450
00451 template<> TrigPassFlags getFlags(const Trig::Feature<EmTau_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
00452 template<> TrigPassFlags getFlags(const Trig::Feature<Muon_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
00453 template<> TrigPassFlags getFlags(const Trig::Feature<Jet_ROI>& f, const TrigPassFlags *orig_tpf, HLT::NavigationCore* navigation );
00454
00455 }
00456
00457 }
00458
00459 #endif
00460
00461
00462 #endif //XAOD_ANALYSIS