CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoTauTag/TauTagTools/src/PFTauDiscriminantManager.cc

Go to the documentation of this file.
00001 #include "RecoTauTag/TauTagTools/interface/PFTauDiscriminantManager.h"
00002 
00003 namespace PFTauDiscriminants
00004 {
00005 using namespace std;
00006 using namespace reco;
00007 
00008 typedef std::vector<const reco::Candidate*> candPtrVector;
00009 
00010 PFTauDiscriminantManager::PFTauDiscriminantManager()
00011 {
00012    iAmSignal_           = false;
00013    iAmNull_             = false;
00014    eventWeight_         = 1.0;
00015    currentTauDecayMode_ = NULL;
00016    eventData_           = NULL;
00017    mainTrack_           = NULL;
00018 }
00019 
00020 void
00021 PFTauDiscriminantManager::addDiscriminant(Discriminant* const discriminant)
00022 {
00023    if (!discriminant)
00024    {
00025       edm::LogError("PFTauDiscriminantManager") << "Error adding a discriminant, null pointer!";
00026       return;
00027    }
00028    string            discriminantName = discriminant->name();
00029    myDiscriminants_.insert(make_pair(discriminantName, discriminant));
00030 }
00031 
00032 void 
00033 PFTauDiscriminantManager::clearCache()
00034 {
00035    mainTrack_ = NULL;
00036    signalObjectsSortedByPt_.clear();
00037    signalObjectsSortedByDR_.clear();
00038    outlierObjectsSortedByPt_.clear();
00039    outlierObjectsSortedByDR_.clear();
00040 }
00041 
00042 bool
00043 PFTauDiscriminantManager::setTau(const reco::PFTauDecayMode& theTau, bool prePass, bool preFail)
00044 {
00045    currentTauDecayMode_ = &theTau;
00046    iAmNull_             = false;
00047    prePass_             = prePass;
00048    preFail_             = preFail;
00049    //reset cached collections
00050    clearCache();
00051    
00052    for(discriminantHolder::iterator aDiscriminant  = myDiscriminants_.begin();
00053                                     aDiscriminant != myDiscriminants_.end();
00054                                   ++aDiscriminant)
00055    {
00056       Discriminant* const theAlgo  = aDiscriminant->second;
00057       if (!theAlgo)
00058       {
00059          string theName  = aDiscriminant->first;
00060          edm::LogError("PFTauDiscriminantManager") << "Error filling discriminant " << theName <<", null pointer!";
00061          return false;
00062       }
00063       theAlgo->compute(this);
00064    }
00065    return true;
00066 }
00067 
00068 void 
00069 PFTauDiscriminantManager::setEvent(const edm::Event& iEvent, double eventWeight)
00070 {
00071    eventData_           = &iEvent;
00072    eventWeight_         = eventWeight;
00073 }
00074 
00075 bool
00076 PFTauDiscriminantManager::setNullResult()
00077 {
00078    currentTauDecayMode_ = NULL;
00079    iAmNull_             = true;
00080    prePass_             = false;
00081    preFail_             = false;
00082    //reset cached collections
00083    clearCache();
00084 
00085    for(discriminantHolder::iterator aDiscriminant  = myDiscriminants_.begin();
00086                                     aDiscriminant != myDiscriminants_.end();
00087                                   ++aDiscriminant)
00088    {
00089       Discriminant* const theAlgo  = aDiscriminant->second;
00090       if (!theAlgo)
00091       {
00092          string theName  = aDiscriminant->first;
00093          edm::LogError("PFTauDiscriminantManager") << "Error filling discriminant " << theName <<", null pointer!";
00094          return false;
00095       }
00096       theAlgo->setNullResult(this);
00097    }
00098    return true;
00099 }
00100 
00101 
00102 
00103 void PFTauDiscriminantManager::fillSignalObjects(candPtrVector& toFill)
00104 {
00105    toFill.clear();
00106    if (currentTauDecayMode_ == NULL)
00107    {
00108       edm::LogError("PFTauDiscriminantManager") << "Trying to get signal objects from null PFTauDecayMode object!  Returning empty vector...";
00109       return;
00110    }
00111    candPtrVector tempChargedVector = currentTauDecayMode_->chargedPionCandidates();
00112    candPtrVector tempNeutralVector = currentTauDecayMode_->neutralPionCandidates();
00113    toFill.insert(toFill.end(), tempChargedVector.begin(), tempChargedVector.end());
00114    toFill.insert(toFill.end(), tempNeutralVector.begin(), tempNeutralVector.end());
00115 }
00116 
00117 void PFTauDiscriminantManager::fillOutlierObjects(candPtrVector& toFill)
00118 {
00119    toFill.clear();
00120    if (currentTauDecayMode_ == NULL)
00121    {
00122       edm::LogError("PFTauDiscriminantManager") << "Trying to get QCD objects from null PFTauDecayMode object!  Returning empty vector...";
00123       return;
00124    }
00125 
00126    // add in filtered objects (created in PFRecoTauDecayModeDeterminator) i.e filtered 2-prongs
00127    // note that this uses the underlying PFCandidates, to be consistent w/ the rest of the objects
00128    PFCandidateRefVector theFilteredObjects = currentTauDecayMode_->filteredPFCandidates();
00129    
00130    for(PFCandidateRefVector::const_iterator iFilteredCand  = theFilteredObjects.begin();
00131                                             iFilteredCand != theFilteredObjects.end();
00132                                           ++iFilteredCand)
00133    {
00134       const PFCandidate* pfCand = iFilteredCand->get();
00135       const Candidate* castedCand = static_cast<const Candidate*>(pfCand);
00136       if (castedCand)
00137          toFill.push_back(castedCand);
00138    }
00139 
00140    // get associated PFTau from PFTauDecayMode
00141    const PFTau* originalTau = currentTauDecayMode_->pfTauRef().get();
00142    if(originalTau) //this may be null by design if there is no associated PFTau (e.g. if DecayMode is constructed from MC truth)
00143    {
00144       const PFCandidateRefVector& theOutliers = originalTau->isolationPFCands();
00145       for(PFCandidateRefVector::const_iterator iIsoCand  = theOutliers.begin();
00146                                                iIsoCand != theOutliers.end();
00147                                              ++iIsoCand)
00148       {
00149          const PFCandidate* pfCand = iIsoCand->get();
00150          const Candidate* castedCand = static_cast<const Candidate*>(pfCand);
00151          if (castedCand)
00152             toFill.push_back(castedCand);
00153       }
00154    }
00155 }
00156 
00157 const reco::Candidate*
00158 PFTauDiscriminantManager::mainTrack() 
00159 {
00160    if (mainTrack_ == NULL) //otherwise already cached or d.n.e
00161    {
00162       if (!this->getDecayMode())
00163       {
00164          edm::LogError("PFTauDiscriminantManager") << "In ::mainTrack(), trying to access a null PFTauDecayMode - returning null pointer for main track";
00165          return NULL;
00166       }
00167 
00168       std::vector<const reco::Candidate*> myChargedCandidates = getDecayMode()->chargedPionCandidates();
00169       size_t nTracks = myChargedCandidates.size();
00170       if (!nTracks) 
00171       {
00172          // ...removing this warning for now, not sure what to do about this case (as it shoudl be permissible to pass a jet->pftau->pfTauDecayMode of all gammas??)
00173          //edm::LogError("PFTauDiscriminantManager") << "In ::mainTrack(), associated PFTauDecayMode has no associated tracks, returning null pointer.";
00174          return NULL;
00175       }
00176 
00177       //if there are more than three tracks, only take the top three, by Pt
00178       TauTagTools::sortByAscendingPt<reco::Candidate> ptSorter;
00179       sort(myChargedCandidates.begin(), myChargedCandidates.end(), ptSorter);
00180       size_t maxTracks = (nTracks > 3) ? 3 : nTracks;
00181       int    charge    = 0;
00182 
00183       if (maxTracks < 3) //two or one track, returning higher Pt track
00184          mainTrack_ = myChargedCandidates[0];
00185       else
00186       {
00187          for(size_t iTrack = 0; iTrack < maxTracks; ++iTrack)
00188             charge += myChargedCandidates[iTrack]->charge();
00189 
00190          for(size_t iTrack = 0; iTrack < maxTracks; ++iTrack)
00191          {
00192             int currentCharge = myChargedCandidates[iTrack]->charge();
00193             if (currentCharge != charge)
00194             {
00195                mainTrack_ = myChargedCandidates[iTrack];
00196                break;
00197             }
00198          }
00199       }
00200    }
00201    return mainTrack_;
00202 }
00203    
00204 
00205 
00206 candPtrVector
00207 PFTauDiscriminantManager::filterByCharge(const candPtrVector& input, bool isCharged) const
00208 {
00209    candPtrVector output;
00210    for(candPtrVector::const_iterator iCandidate  = input.begin();
00211                                      iCandidate != input.end();
00212                                    ++iCandidate)
00213    {
00214       bool chargeType = (*iCandidate)->charge();
00215       if( chargeType == isCharged ) 
00216          output.push_back(*iCandidate);
00217    }
00218    return output;
00219 }
00220 
00221 const std::vector<const reco::Candidate*>&
00222 PFTauDiscriminantManager::signalObjectsSortedByPt()
00223 {
00224    // return already computed vector if has already been computed or is empty (due to null tau)
00225    if(!signalObjectsSortedByPt_.empty() || iAmNull_)  
00226    {
00227       return signalObjectsSortedByPt_;
00228    }
00229    else
00230    {  
00231       TauTagTools::sortByAscendingPt<reco::Candidate> mySorter;
00232       fillSignalObjects(signalObjectsSortedByPt_);
00233       sort(signalObjectsSortedByPt_.begin(), signalObjectsSortedByPt_.end(), mySorter);
00234    }
00235    return signalObjectsSortedByPt_;
00236 }
00237 
00238 const std::vector<const reco::Candidate*>&
00239 PFTauDiscriminantManager::signalObjectsSortedByDR()
00240 {
00241    // return already computed vector if has already been computed or is empty (due to null tau)
00242    if(!signalObjectsSortedByDR_.empty() || iAmNull_)  
00243    {
00244       return signalObjectsSortedByDR_;
00245    }
00246    else
00247    {  
00248       if (currentTauDecayMode_ == NULL)
00249       {
00250          edm::LogError("PFTauDiscriminantManager") << "Trying to get signal objects from null PFTauDecayMode object!  Returning empty vector...";
00251          return signalObjectsSortedByDR_;
00252       }
00253       math::XYZVector signalAxisVector = currentTauDecayMode_->momentum();
00254       TauTagTools::sortByOpeningAngleAscending<reco::Candidate> mySorter(signalAxisVector, TauTagTools::computeDeltaR);
00255       fillSignalObjects(signalObjectsSortedByDR_);
00256       sort(signalObjectsSortedByDR_.begin(), signalObjectsSortedByDR_.end(), mySorter);
00257    }
00258    return signalObjectsSortedByDR_;
00259 }
00260 
00261 const std::vector<const reco::Candidate*>&
00262 PFTauDiscriminantManager::outlierObjectsSortedByPt()
00263 {
00264    if(!outlierObjectsSortedByPt_.empty() || iAmNull_)
00265    {
00266       return outlierObjectsSortedByPt_;
00267    }
00268    else
00269    {
00270       fillOutlierObjects(outlierObjectsSortedByPt_);
00271       TauTagTools::sortByAscendingPt<reco::Candidate> mySorter;
00272       sort(outlierObjectsSortedByPt_.begin(), outlierObjectsSortedByPt_.end(), mySorter);
00273    }
00274    return outlierObjectsSortedByPt_;
00275 }
00276 
00277 const std::vector<const reco::Candidate*>&
00278 PFTauDiscriminantManager::outlierObjectsSortedByDR()
00279 {
00280    if(!outlierObjectsSortedByDR_.empty() || iAmNull_)
00281    {
00282       return outlierObjectsSortedByDR_;
00283    }
00284    else
00285    {
00286       if (currentTauDecayMode_ == NULL)
00287       {
00288          edm::LogError("PFTauDiscriminantManager") << "Trying to get outlier objects from null PFTauDecayMode object!  Returning empty vector...";
00289          return outlierObjectsSortedByDR_;
00290       }
00291       math::XYZVector signalAxisVector = currentTauDecayMode_->momentum();
00292       fillOutlierObjects(outlierObjectsSortedByDR_);
00293       TauTagTools::sortByOpeningAngleAscending<reco::Candidate> mySorter(signalAxisVector, TauTagTools::computeDeltaR);
00294       sort(outlierObjectsSortedByDR_.begin(), outlierObjectsSortedByDR_.end(), mySorter);
00295    }
00296    return outlierObjectsSortedByDR_;
00297 }
00298 
00299 
00300 bool
00301 PFTauDiscriminantManager::branchTree(TTree* treeToBranch, bool addTargetBranch, bool addWeightBranch)
00302 {
00303    if(!treeToBranch)
00304    {
00305       edm::LogError("PFTauDiscriminantManager") << "Error: trying to branch ttree - TTree pointer is null!";
00306       return false;
00307    }
00308 
00309    //add magic variables _TARGET_ (for sig/bkg) and _WEIGHT_, and ISNULL for non-existence
00310    if (addTargetBranch)
00311       treeToBranch->Branch("__TARGET__", &iAmSignal_,  "__TARGET__/O");  //needs bugfix in MVA framework code..
00312    if (addWeightBranch)
00313       treeToBranch->Branch("__WEIGHT__", &eventWeight_,"__WEIGHT__/D");
00314    // note: Target and Weight are normally added after the fact, in the training code.
00315 
00316    treeToBranch->Branch("__ISNULL__",  &iAmNull_,"__ISNULL__/O");
00317    treeToBranch->Branch("__PREPASS__", &prePass_,"__PREPASS__/O");
00318    treeToBranch->Branch("__PREFAIL__", &preFail_,"__PREFAIL__/O");
00319 
00320    //loop over all the variables and make a branch for each one
00321    for(discriminantHolder::iterator iVariable  = myDiscriminants_.begin();
00322                                     iVariable != myDiscriminants_.end();
00323                                   ++iVariable)
00324    {
00325       Discriminant * theDiscriminant = iVariable->second;
00326       edm::LogInfo("PFTauDiscriminantManager") << "Branching for discriminant w/ name: " << theDiscriminant->name();
00327       theDiscriminant->branchTree(treeToBranch);
00328    }
00329    return true;
00330 }
00331 
00332 void
00333 PFTauDiscriminantManager::buildMVAComputerLink(std::vector<PhysicsTools::Variable::Value>& toFill)
00334 {
00335    for(discriminantHolder::iterator iVariable  = myDiscriminants_.begin();
00336                                     iVariable != myDiscriminants_.end();
00337                                   ++iVariable)
00338    {
00339       Discriminant * theDiscriminant = iVariable->second;
00340       theDiscriminant->fillMVA(toFill);
00341    }
00342 }
00343 
00344 vector<const reco::Candidate*>
00345 PFTauDiscriminantManager::getLeafDaughters(const reco::Candidate* input) 
00346 {
00347    std::vector<const reco::Candidate*> output;
00348 
00349    //check for validity
00350    if(!input)   
00351       return output;
00352 
00353    size_t nDaughters = input->numberOfDaughters();
00354    if(!nDaughters)      //this is a leaf
00355       output.push_back(input);
00356    else                 //recurse down this objects daughters
00357    {
00358       for(size_t iDaughter = 0; iDaughter < nDaughters; ++iDaughter)
00359       {
00360          std::vector<const reco::Candidate*> leafsOnThisBranch = getLeafDaughters(input->daughter(iDaughter));
00361          output.insert(output.end(), leafsOnThisBranch.begin(), leafsOnThisBranch.end());
00362       }
00363    }
00364    return output;
00365 }
00366 
00367 PFTauDiscriminantManager::~PFTauDiscriminantManager()
00368 {
00369 }
00370 
00371 
00372 
00373 } //end namespace
00374 
00375 
00376