Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:46

0001 #ifndef RecoTauTag_RecoTau_RecoTauCrossCleaning_h
0002 #define RecoTauTag_RecoTau_RecoTauCrossCleaning_h
0003 
0004 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
0005 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
0006 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0007 #include "DataFormats/TauReco/interface/PFRecoTauChargedHadron.h"
0008 #include "DataFormats/Candidate/interface/CompositePtrCandidate.h"
0009 
0010 namespace reco::tau::xclean {
0011 
0012   /// Transform a pizero to remove given candidates
0013   template <typename PtrIter>
0014   class CrossCleanPiZeros {
0015   public:
0016     typedef std::vector<RecoTauPiZero> PiZeroList;
0017 
0018     CrossCleanPiZeros(const PtrIter& chargedHadronsBegin,
0019                       const PtrIter& chargedHadronsEnd,
0020                       int mode = kRemoveChargedAndNeutralDaughterOverlaps)
0021         : mode_(mode) {
0022       initialize(chargedHadronsBegin, chargedHadronsEnd);
0023     }
0024 
0025     void initialize(const PtrIter& chargedHadronsBegin, const PtrIter& chargedHadronsEnd) {
0026       // CV: make sure this never gets called.
0027       assert(0);
0028     }
0029 
0030     /// Return a vector of pointers to pizeros.  PiZeros that needed cleaning
0031     /// are cloned, modified, and owned by this class.  The un-modified pointers
0032     /// point to objects in the [input] vector.
0033     PiZeroList operator()(const std::vector<RecoTauPiZero>& input) const {
0034       PiZeroList output;
0035       output.reserve(input.size());
0036       for (auto const& piZero : input) {
0037         const RecoTauPiZero::daughters& daughters = piZero.daughterPtrVector();
0038         std::set<reco::CandidatePtr> toCheck(daughters.begin(), daughters.end());
0039         std::vector<reco::CandidatePtr> cleanDaughters;
0040         std::set_difference(
0041             toCheck.begin(), toCheck.end(), toRemove_.begin(), toRemove_.end(), std::back_inserter(cleanDaughters));
0042         if (cleanDaughters.size() == daughters.size()) {
0043           // We don't need to clean anything, just add a pointer to current pizero
0044           output.push_back(piZero);
0045         } else {
0046           // Otherwise rebuild
0047           RecoTauPiZero newPiZero = piZero;
0048           newPiZero.clearDaughters();
0049           // Add our cleaned daughters.
0050           for (auto const& ptr : cleanDaughters) {
0051             newPiZero.addDaughter(ptr);
0052           }
0053           // Check if the pizero is not empty.  If empty, forget it.
0054           if (newPiZero.numberOfDaughters()) {
0055             p4Builder_.set(newPiZero);
0056             // Make our ptr container take ownership.
0057             output.push_back(newPiZero);
0058           }
0059         }
0060       }
0061       return output;
0062     }
0063 
0064     enum { kRemoveChargedDaughterOverlaps, kRemoveChargedAndNeutralDaughterOverlaps };
0065 
0066   private:
0067     int mode_;
0068     AddFourMomenta p4Builder_;
0069     std::set<reco::CandidatePtr> toRemove_;
0070   };
0071 
0072   // Determine if a candidate is contained in a collection of charged hadrons or pizeros.
0073   template <typename PtrIter>
0074   class CrossCleanPtrs {
0075   public:
0076     CrossCleanPtrs(const PtrIter& particlesBegin, const PtrIter& particlesEnd) {
0077       initialize(particlesBegin, particlesEnd);
0078     }
0079 
0080     void initialize(const PtrIter& particlesBegin, const PtrIter& particlesEnd) {
0081       // CV: make sure this never gets called.
0082       assert(0);
0083     }
0084 
0085     template <typename AnyPtr>
0086     bool operator()(const AnyPtr& ptr) const {
0087       if (toRemove_.count(CandidatePtr(ptr)))
0088         return false;
0089       else
0090         return true;
0091     }
0092 
0093   private:
0094     std::set<CandidatePtr> toRemove_;
0095   };
0096 
0097   // Predicate to filter PFCandPtrs (and those compatible to this type) by the
0098   // particle id
0099   class FilterPFCandByParticleId {
0100   public:
0101     FilterPFCandByParticleId(int particleId) : id_(particleId){};
0102     template <typename PFCandCompatiblePtrType>
0103     bool operator()(const PFCandCompatiblePtrType& ptr) const {
0104       return ptr->particleId() == id_;
0105     }
0106 
0107   private:
0108     int id_;
0109   };
0110 
0111   // Predicate to filter CandPtrs by the abs(pdgId)
0112   class FilterCandByAbsPdgId {
0113   public:
0114     FilterCandByAbsPdgId(int pdgId) : id_(pdgId){};
0115     template <typename CandCompatiblePtrType>
0116     bool operator()(const CandCompatiblePtrType& ptr) const {
0117       return std::abs(ptr->pdgId()) == id_;
0118     }
0119 
0120   private:
0121     int id_;
0122   };
0123 
0124   // Create the AND of two predicates
0125   template <typename P1, typename P2>
0126   class PredicateAND {
0127   public:
0128     PredicateAND(const P1& p1, const P2& p2) : p1_(p1), p2_(p2) {}
0129 
0130     template <typename AnyPtr>
0131     bool operator()(const AnyPtr& ptr) const {
0132       return (p1_(ptr) && p2_(ptr));
0133     }
0134 
0135   private:
0136     const P1& p1_;
0137     const P2& p2_;
0138   };
0139 
0140   // Helper function to infer template type
0141   template <typename P1, typename P2>
0142   PredicateAND<P1, P2> makePredicateAND(const P1& p1, const P2& p2) {
0143     return PredicateAND<P1, P2>(p1, p2);
0144   }
0145 
0146 }  // namespace reco::tau::xclean
0147 
0148 #endif