CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoTauTag/TauTagTools/interface/PFTauDiscriminantBase.h

Go to the documentation of this file.
00001 #ifndef RecoTauTag_TauTagTools_PFTauDiscriminantBase
00002 #define RecoTauTag_TauTagTools_PFTauDiscriminantBase
00003 
00004 #include "DataFormats/TauReco/interface/PFTauDecayMode.h"
00005 #include "DataFormats/Math/interface/deltaR.h"
00006 #include "CommonTools/Utils/interface/Angle.h"
00007 #include "RecoTauTag/TauTagTools/interface/PFTauDiscriminantManager.h"
00008 #include "PhysicsTools/MVAComputer/interface/AtomicId.h"
00009 #include "PhysicsTools/MVAComputer/interface/Variable.h"
00010 #include "TMath.h"
00011 #include "TTree.h"
00012 #include <string>
00013 #include <algorithm>
00014 #include <vector>
00015 
00016 /*  Class: PFTauDiscriminants::Discriminant
00017  *
00018  *  Author: Evan K. Friis, UC Davis friis@physics.ucdavis.edu
00019  *
00020  *  Description:
00021  *      Abstract base class to hold PFTauDecayMode descriminant functions
00022  *      is called by a PFTauDiscriminantManager.
00023  *      Handles TTree branching of the specific requirements of various variables
00024  *      Can construct CMSSW MVA framework input for a given tau object
00025  *      Variables can be multiple, or optional.  Also supports a "NULL TYPE" for 
00026  *      matching reconstruction failures to reconstruction success.
00027  *
00028  *      Implementing discriminants of type T should inherit from DicriminantBase< TYPE >
00029  *      where TYPE is either a simple data type (e.g. 'F' for float, 'I':int)
00030  *      or any complex type for which ROOT dictionaries exists and have a double() operator.
00031  *      OR any STL collection of said types.
00032  *      See RecoTauTag/TauTagTools/interface/Discriminants.h for examples of implementation.
00033  */
00034 
00035 
00036 namespace PFTauDiscriminants {
00037 
00038 class PFTauDiscriminantManager;
00039 
00040 class Discriminant {
00041    public:
00042       explicit Discriminant(std::string name, std::string rootTypeName, bool branchAsSimpleDataType):
00043          discriminantName_(PhysicsTools::AtomicId(name)),
00044          rootTypeName_(rootTypeName),
00045          branchAsSimpleDataType_(branchAsSimpleDataType)
00046       {};
00047       virtual ~Discriminant(){};
00048       virtual void                      compute(PFTauDiscriminantManager *input)=0;
00049       virtual void                      setNullResult(PFTauDiscriminantManager *input)=0;
00050       std::string                       name()         const {return discriminantName_;}
00051       PhysicsTools::AtomicId            theAtomicId()  const {return discriminantName_;}
00052       std::string                       rootTypeName() const {return rootTypeName_;}
00053 
00055       virtual void       branchTree(TTree* theTree) = 0; 
00056       virtual void       fillMVA(std::vector<PhysicsTools::Variable::Value>& mvaHolder) const = 0;
00057 
00058    protected:
00060       bool               branchSimply() const { return branchAsSimpleDataType_; }
00061 
00062    private:
00063       PhysicsTools::AtomicId                      discriminantName_;
00064       std::string                                 rootTypeName_;
00065       bool                                        branchAsSimpleDataType_;
00066 };
00067 
00068 template<class T>
00069 class DiscriminantBase : public Discriminant {
00070    public:
00071       explicit  DiscriminantBase(std::string name, std::string rootTypeName, 
00072                         bool branchAsSimpleDataType, bool isMultiple, T defaultValue):Discriminant(name, rootTypeName, branchAsSimpleDataType),isMultiple_(isMultiple),defaultValue_(defaultValue){
00073          resultPtr_ = &result_;
00074       };
00075 
00076       virtual  ~DiscriminantBase(){};
00077       typedef typename std::vector<T>::const_iterator myVectorIterator;
00078       
00079       virtual void setNullResult(PFTauDiscriminantManager *input) //can be overriden in the derived classes if desired (for example, to use edm::Event info)
00080       {
00081          result_.clear();
00082          singleResult_ = defaultValue_;
00083       }
00084 
00087       void compute(PFTauDiscriminantManager* input)
00088       {
00089          result_.clear();
00090 
00091          if (input)
00092             doComputation(input, result_); 
00093          else
00094             edm::LogError("DiscriminantBase") << "Error in DiscriminantBase - trying to compute discriminants on null PFTauDecayMode pointer!";
00095 
00096          size_t numberOfResultsReturned = result_.size();
00097          if(!numberOfResultsReturned) //if there are no results, ROOT branches of simple variables must be filled w/ the default value
00098          {
00099             singleResult_ = defaultValue_;
00100          } else
00101          {
00102             if(!isMultiple_ && numberOfResultsReturned > 1)
00103             {
00104                edm::LogWarning("PFTauDiscriminants::DiscriminantBase") << "Warning, multiple discriminant values recieved for a non-multiple branch, taking only the first!"; 
00105             }
00106             singleResult_ = result_[0];
00107          }
00108       }
00109 
00110       //adds a branch to the tree corresponding to this variable
00111       void branchTree(TTree* theTree) {
00112          if (!this->branchSimply())
00113          {
00114             edm::LogInfo("PFTauDiscriminantBase") << "Branching TTree: " << theTree->GetName() << " with full class name (bronch)";
00115             theTree->Branch(name().c_str(), rootTypeName().c_str(), &resultPtr_); 
00116          }
00117          else
00118          {
00119             edm::LogInfo("PFTauDiscriminantBase") << "Branching TTree: " << theTree->GetName() << " with struct style branch (leaflist)";
00120             std::stringstream branchType;
00121             branchType << name() << "/" << rootTypeName(); //eg D, F, I, etc
00122             theTree->Branch(this->name().c_str(), &singleResult_, branchType.str().c_str());
00123          }
00124       }
00125       //fills a vector of values for the MVA framework
00126       void fillMVA(std::vector<PhysicsTools::Variable::Value>& mvaHolder) const {
00127          if (isMultiple_)
00128          {
00129             for(myVectorIterator aResult = result_.begin(); aResult != result_.end(); ++aResult)
00130             {
00131                mvaHolder.push_back(PhysicsTools::Variable::Value(theAtomicId(), static_cast<double>(*aResult)));
00132             }
00133          }
00134          else
00135          {
00136             mvaHolder.push_back(PhysicsTools::Variable::Value(theAtomicId(), static_cast<double>(singleResult_)));
00137          }
00138       }
00139       
00140    protected:
00141       virtual void      doComputation(PFTauDiscriminantManager* input, std::vector<T>& result)=0;
00142    private:
00143       bool              isMultiple_;
00144       T                 defaultValue_;
00145       T                 singleResult_;
00146       std::vector<T>    result_;
00147       std::vector<T>*   resultPtr_;
00148 };
00149 }
00150 #endif