Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:27:02

0001 #ifndef RecoTauTag_RecoTau_RecoTauCommonUtilities_h
0002 #define RecoTauTag_RecoTau_RecoTauCommonUtilities_h
0003 
0004 /*
0005  * RecoTauCommonUtilities - utilities for extracting PFCandidates from
0006  * PFJets and summing over collections of PFCandidates.
0007  *
0008  * Author: Evan K. Friis (UC Davis)
0009  *
0010  */
0011 
0012 #include <vector>
0013 #include <algorithm>
0014 #include <numeric>
0015 
0016 #include "DataFormats/Candidate/interface/CandidateFwd.h"
0017 #include "DataFormats/Candidate/interface/Candidate.h"
0018 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0019 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0020 #include "DataFormats/TauReco/interface/PFTau.h"
0021 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0022 
0023 // Boost helpers
0024 #include <boost/iterator/transform_iterator.hpp>
0025 #include <boost/iterator/indirect_iterator.hpp>
0026 #include <boost/mem_fn.hpp>
0027 
0028 #include <boost/type_traits/is_base_of.hpp>
0029 
0030 namespace reco {
0031   namespace tau {
0032 
0033     class SortPFCandsDescendingPt {
0034     public:
0035       bool operator()(const CandidatePtr& a, const CandidatePtr& b) const { return a->pt() > b->pt(); }
0036     };
0037 
0038     /// Filter a collection of objects that are convertible to CandidatePtrs
0039     /// by PFCandidate ID
0040     template <typename Iterator>
0041     std::vector<CandidatePtr> filterPFCandidates(const Iterator& begin,
0042                                                  const Iterator& end,
0043                                                  int pdgId,
0044                                                  bool sort = true) {
0045       std::vector<CandidatePtr> output;
0046       for (Iterator iter = begin; iter != end; ++iter) {
0047         reco::CandidatePtr ptr(*iter);
0048         if (std::abs(ptr->pdgId()) == pdgId)
0049           output.push_back(ptr);
0050       }
0051       if (sort)
0052         std::sort(output.begin(), output.end(), SortPFCandsDescendingPt());
0053       return output;
0054     }
0055 
0056     /// Extract pfCandidates of a given particle Id from a PFJet.  If sort is true,
0057     /// candidates will be sorted by descending PT. Internally translates to pdgId
0058     std::vector<CandidatePtr> pfCandidates(const Jet& jet, int particleId, bool sort = true);
0059 
0060     /// Extract pfCandidates of a that match a list of particle Ids from a PFJet
0061     std::vector<CandidatePtr> pfCandidates(const Jet& jet, const std::vector<int>& particleIds, bool sort = true);
0062 
0063     /// Extract pfCandidates of a given PDG Id from a PFJet.  If sort is true,
0064     /// candidates will be sorted by descending PT
0065     std::vector<CandidatePtr> pfCandidatesByPdgId(const Jet& jet, int pdgId, bool sort = true);
0066 
0067     /// Extract pfCandidates of a that match a list of PDG Ids from a PFJet
0068     std::vector<CandidatePtr> pfCandidatesByPdgId(const Jet& jet, const std::vector<int>& pdgIds, bool sort = true);
0069 
0070     /// Extract all non-neutral candidates from a PFJet
0071     std::vector<CandidatePtr> pfChargedCands(const Jet& jet, bool sort = true);
0072 
0073     /// Extract all pfGammas from a PFJet
0074     std::vector<CandidatePtr> pfGammas(const Jet& jet, bool sort = true);
0075 
0076     /// Flatten a list of pi zeros into a list of there constituent PFCandidates
0077     std::vector<CandidatePtr> flattenPiZeros(const std::vector<RecoTauPiZero>::const_iterator&,
0078                                              const std::vector<RecoTauPiZero>::const_iterator&);
0079     std::vector<CandidatePtr> flattenPiZeros(const std::vector<RecoTauPiZero>&);
0080 
0081     /// Convert a BaseView (View<T>) to a TRefVector
0082     template <typename RefVectorType, typename BaseView>
0083     RefVectorType castView(const edm::Handle<BaseView>& view) {
0084       typedef typename RefVectorType::value_type OutputRef;
0085       // Double check at compile time that the inheritance is okay.  It can still
0086       // fail at runtime if you pass it the wrong collection.
0087       static_assert((boost::is_base_of<typename BaseView::value_type, typename RefVectorType::member_type>::value));
0088       RefVectorType output;
0089       size_t nElements = view->size();
0090       output.reserve(nElements);
0091       // Cast each of our Refs
0092       for (size_t i = 0; i < nElements; ++i) {
0093         output.push_back(view->refAt(i).template castTo<OutputRef>());
0094       }
0095       return output;
0096     }
0097 
0098     /*
0099  *Given a range over a container of type C, return a new 'end' iterator such
0100  *that at max <N> elements are taken.  If there are less than N elements in the
0101  *array, leave the <end>  as it is
0102  */
0103     template <typename InputIterator>
0104     InputIterator takeNElements(const InputIterator& begin, const InputIterator& end, size_t N) {
0105       size_t input_size = end - begin;
0106       return (N > input_size) ? end : begin + N;
0107     }
0108 
0109     /// Sum the four vectors in a collection of PFCandidates
0110     template <typename InputIterator, typename FunctionPtr, typename ReturnType>
0111     ReturnType sumPFVector(InputIterator begin, InputIterator end, FunctionPtr func, ReturnType init) {
0112       ReturnType output = init;
0113       for (InputIterator cand = begin; cand != end; ++cand) {
0114         //#define CALL_MEMBER_FN(object,ptrToMember)  ((object).*(ptrToMember))
0115         output += ((**cand).*(func))();
0116       }
0117       return output;
0118     }
0119 
0120     template <typename InputIterator>
0121     reco::Candidate::LorentzVector sumPFCandP4(InputIterator begin, InputIterator end) {
0122       return sumPFVector(begin, end, &Candidate::p4, reco::Candidate::LorentzVector());
0123     }
0124 
0125     /// Sum the pT of a collection of PFCandidates
0126     template <typename InputIterator>
0127     double sumPFCandPt(InputIterator begin, InputIterator end) {
0128       return sumPFVector(begin, end, &Candidate::pt, 0.0);
0129     }
0130 
0131     /// Sum the charge of a collection of PFCandidates
0132     template <typename InputIterator>
0133     int sumPFCandCharge(InputIterator begin, InputIterator end) {
0134       return sumPFVector(begin, end, &Candidate::charge, 0);
0135     }
0136 
0137     template <typename InputIterator>
0138     InputIterator leadCand(InputIterator begin, InputIterator end) {
0139       double max_pt = 0;
0140       InputIterator max_cand = begin;
0141       for (InputIterator cand = begin; cand != end; ++cand) {
0142         if ((*cand)->pt() > max_pt) {
0143           max_pt = (*cand)->pt();
0144           max_cand = cand;
0145         }
0146       }
0147       return max_cand;
0148     }
0149 
0150     math::XYZPointF atECALEntrance(const reco::Candidate* part, double bField);
0151 
0152   }  // namespace tau
0153 }  // namespace reco
0154 #endif