CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/RecoTauTag/RecoTau/interface/RecoTauCrossCleaning.h

Go to the documentation of this file.
00001 #ifndef RecoTauTag_RecoTau_RecoTauCrossCleaning_h
00002 #define RecoTauTag_RecoTau_RecoTauCrossCleaning_h
00003 
00004 #include <boost/foreach.hpp>
00005 
00006 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
00007 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
00008 
00009 namespace reco { namespace tau { namespace xclean {
00010 
00012 template<typename PtrIter>
00013 class CrossCleanPiZeros {
00014   public:
00015     typedef std::vector<RecoTauPiZero> PiZeroList;
00016 
00017     CrossCleanPiZeros(PtrIter signalTracksBegin, PtrIter signalTracksEnd) {
00018       // Get the list of objects we need to clean
00019       for (PtrIter i = signalTracksBegin; i != signalTracksEnd; ++i) {
00020         toRemove_.insert(reco::CandidatePtr(*i));
00021       }
00022     }
00023 
00027     PiZeroList operator()(const std::vector<RecoTauPiZero> &input) const {
00028       PiZeroList output;
00029       output.reserve(input.size());
00030       BOOST_FOREACH(const RecoTauPiZero& piZero, input) {
00031         const RecoTauPiZero::daughters& daughters = piZero.daughterPtrVector();
00032         std::set<reco::CandidatePtr> toCheck(daughters.begin(), daughters.end());
00033         std::vector<reco::CandidatePtr> cleanDaughters;
00034         std::set_difference(toCheck.begin(), toCheck.end(),
00035             toRemove_.begin(), toRemove_.end(), std::back_inserter(cleanDaughters));
00036         if (cleanDaughters.size() == daughters.size()) {
00037           // We don't need to clean anything, just add a pointer to current cnad
00038           output.push_back(piZero);
00039         } else {
00040           // Otherwise rebuild
00041           RecoTauPiZero newPiZero = piZero;
00042           newPiZero.clearDaughters();
00043           // Add our cleaned daughters.
00044           BOOST_FOREACH(const reco::CandidatePtr& ptr, cleanDaughters) {
00045             newPiZero.addDaughter(ptr);
00046           }
00047           // Check if the pizero is not empty.  If empty, forget it.
00048           if (newPiZero.numberOfDaughters()) {
00049             p4Builder_.set(newPiZero);
00050             // Make our ptr container take ownership.
00051             output.push_back(newPiZero);
00052           }
00053         }
00054       }
00055       return output;
00056     }
00057 
00058   private:
00059     AddFourMomenta p4Builder_;
00060     std::set<reco::CandidatePtr> toRemove_;
00061 };
00062 
00063 // Predicate to filter PFCandPtrs (and those compatible to this type) by the
00064 // particle id
00065 class FilterPFCandByParticleId {
00066   public:
00067     FilterPFCandByParticleId(int particleId):
00068       id_(particleId){};
00069     template<typename PFCandCompatiblePtrType>
00070       bool operator()(const PFCandCompatiblePtrType& ptr) const {
00071         PFCandidatePtr pfptr(ptr);
00072         return ptr->particleId() == id_;
00073       }
00074   private:
00075     int id_;
00076 };
00077 
00078 // Determine if a candidate is contained in a collection of PiZeros.
00079 class CrossCleanPtrs {
00080   public:
00081     CrossCleanPtrs(const std::vector<reco::RecoTauPiZero> &piZeros) {
00082       BOOST_FOREACH(const PFCandidatePtr &ptr, flattenPiZeros(piZeros)) {
00083         toRemove_.insert(CandidatePtr(ptr));
00084       }
00085     }
00086 
00087     template<typename AnyPtr>
00088     bool operator() (const AnyPtr& ptr) const {
00089       if (toRemove_.count(CandidatePtr(ptr)))
00090         return false;
00091       else
00092         return true;
00093     }
00094   private:
00095     std::set<CandidatePtr> toRemove_;
00096 };
00097 
00098 // Create the AND of two predicates
00099 template<typename P1, typename P2>
00100 class PredicateAND {
00101   public:
00102     PredicateAND(const P1& p1, const P2& p2):
00103       p1_(p1),p2_(p2){}
00104 
00105     template<typename AnyPtr>
00106     bool operator() (const AnyPtr& ptr) const {
00107       return p1_(ptr) && p2_(ptr);
00108     }
00109   private:
00110     const P1& p1_;
00111     const P2& p2_;
00112 };
00113 
00114 // Helper function to infer template type
00115 template<typename P1, typename P2>
00116 PredicateAND<P1, P2> makePredicateAND(const P1& p1, const P2& p2) {
00117   return PredicateAND<P1, P2>(p1, p2);
00118 }
00119 
00120 }}}
00121 #endif