CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoBTau/JetTagComputer/interface/GenericMVAComputer.h

Go to the documentation of this file.
00001 #ifndef RecoBTau_BTauComputer_GenericMVAComputer_h
00002 #define RecoBTau_BTauComputer_GenericMVAComputer_h
00003 
00004 #include <iterator>
00005 #include <vector>
00006 
00007 #include "DataFormats/BTauReco/interface/TaggingVariable.h"
00008 #include "PhysicsTools/MVAComputer/interface/AtomicId.h"
00009 #include "PhysicsTools/MVAComputer/interface/Calibration.h"
00010 #include "PhysicsTools/MVAComputer/interface/MVAComputer.h"
00011 
00012 // overload MVAComputer and replace eval() methods to work on TaggingVariable
00013 class GenericMVAComputer : public PhysicsTools::MVAComputer {
00014     public:
00015         // forward declarations;
00016         template<typename Iter_t> class TaggingVariableIterator;
00017         class TaggingVariableMapping;
00018 
00019         GenericMVAComputer(const PhysicsTools::Calibration::MVAComputer *calib) :
00020                 PhysicsTools::MVAComputer(calib) {}
00021 
00022         // create wrapping iterator
00023         template<typename Iter_t>
00024         inline TaggingVariableIterator<Iter_t> iterator(Iter_t iter) const
00025         { return TaggingVariableIterator<Iter_t>(&mapping, iter); }
00026 
00027         // overload eval method to work on containers of TaggingVariable
00028         template<typename Iter_t>
00029         inline double eval(Iter_t first, Iter_t last) const
00030         {
00031                 typedef TaggingVariableIterator<Iter_t> Wrapped_t;
00032                 return PhysicsTools::MVAComputer::template eval<Wrapped_t>(
00033                         iterator<Iter_t>(first), iterator<Iter_t>(last));
00034         }
00035 
00036         template<typename Container_t>
00037         inline double eval(const Container_t &values) const
00038         {
00039                 typedef typename Container_t::const_iterator Iter_t;
00040                 return this->template eval<Iter_t>(values.begin(), values.end());
00041         }
00042 
00043         // iterator wrapper with on-the-fly TaggingVariableName -> AtomicId mapping
00044         //
00045         // Notice that this tells the computer to completely inline it
00046         // this is reasonable since inlining it means that the optimizer
00047         // will not produce any additional code for the wrapper
00048         // (it is entirely optimized away), except for the actual mapping
00049         // which is no more than a simple array lookup.
00050         //
00051         // The result will be inlined into the eval() template of MVAComputer
00052         // which will be instantiated as one single tightly-integrated
00053         // function.
00054         template<typename Iter_t>
00055         class TaggingVariableIterator {
00056             public:
00057                 // class implementing MVAComputer::Variable::Value interface
00058                 struct Value {
00059                     public:
00060                         // the actual operator doing the mapping
00061                         inline PhysicsTools::AtomicId getName() const
00062                         { return mapping->getAtomicId(iter->first); }
00063 
00064                         inline double getValue() const
00065                         { return iter->second; }
00066 
00067                         operator PhysicsTools::Variable::Value() const
00068                         {
00069                                 return PhysicsTools::Variable::Value(
00070                                                 getName(), getValue());
00071                         }
00072 
00073                     protected:
00074                         friend class TaggingVariableIterator;
00075 
00076                         inline Value(TaggingVariableMapping *mapping,
00077                                      const Iter_t &iter) :
00078                                 mapping(mapping), iter(iter) {}
00079 
00080                     private:
00081                         // pointer to the current mapping
00082                         TaggingVariableMapping  *mapping;
00083                         // iterator to reco::TaggingVariable in orig. container
00084                         Iter_t                  iter;
00085                 };
00086 
00087                 typedef std::forward_iterator_tag                               iterator_category;
00088                 typedef Value                                                   value_type;
00089                 typedef typename std::iterator_traits<Iter_t>::difference_type  difference_type;
00090                 typedef const Value                                             *pointer;
00091                 typedef const Value                                             &reference;
00092 
00093                 inline ~TaggingVariableIterator() {}
00094 
00095                 // methods to make class a standard forward iterator
00096 
00097                 inline const Value &operator * () const { return value; }
00098                 inline Value &operator * () { return value; }
00099 
00100                 inline const Value *operator -> () const { return &value; }
00101                 inline Value *operator -> () { return &value; }
00102 
00103                 inline bool operator == (const TaggingVariableIterator &other) const
00104                 { return value.iter == other.value.iter; }
00105                 inline bool operator != (const TaggingVariableIterator &other) const
00106                 { return value.iter != other.value.iter; }
00107                 inline bool operator < (const TaggingVariableIterator &other) const
00108                 { return value.iter < other.value.iter; }
00109 
00110                 inline TaggingVariableIterator &operator ++ ()
00111                 { ++value.iter; return *this; }
00112 
00113                 inline TaggingVariableIterator operator ++ (int dummy)
00114                 { TaggingVariableIterator orig = *this; ++value.iter; return orig; }
00115 
00116             protected:
00117                 friend class GenericMVAComputer;
00118                 inline TaggingVariableIterator(TaggingVariableMapping *mapping,
00119                                                const Iter_t &iter) :
00120                         value(mapping, iter) {}
00121 
00122             private:
00123                 // holds the current "value"
00124                 // it's really only an iterator that points the original
00125                 // current TaggingVariable plus required methods
00126                 Value                   value;
00127         };
00128 
00129         // TaggingVariableName -> PhysicsTools::AtomicId mapping
00130         class TaggingVariableMapping {
00131             public:
00132                 typedef PhysicsTools::AtomicId          AtomicId;
00133                 typedef reco::TaggingVariableName       TaggingName;
00134 
00135                 TaggingVariableMapping();
00136                 ~TaggingVariableMapping() {}
00137 
00138                 inline AtomicId getAtomicId(TaggingName taggingName) const
00139                 { return taggingVarToAtomicId[taggingName]; }
00140 
00141             private:
00142                 std::vector<AtomicId>   taggingVarToAtomicId;
00143         };
00144 
00145     private:
00146         static TaggingVariableMapping   mapping;
00147 };
00148 
00149 #endif // RecoBTau_BTauComputer_GenericMVAComputer_h