CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/RecoTauTag/RecoTau/src/RecoTauConstructor.cc

Go to the documentation of this file.
00001 #include "RecoTauTag/RecoTau/interface/RecoTauConstructor.h"
00002 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00003 #include <boost/foreach.hpp>
00004 #include <boost/bind.hpp>
00005 
00006 namespace reco { namespace tau {
00007 
00008 
00009 
00010 RecoTauConstructor::RecoTauConstructor(const PFJetRef& jet,
00011     const edm::Handle<PFCandidateCollection>& pfCands,
00012     bool copyGammasFromPiZeros):pfCands_(pfCands) {
00013 
00014   // Initialize tau
00015   tau_.reset(new PFTau());
00016 
00017   copyGammas_ = copyGammasFromPiZeros;
00018   // Initialize our Accessors
00019   collections_[std::make_pair(kSignal, kChargedHadron)] =
00020       &tau_->selectedSignalPFChargedHadrCands_;
00021   collections_[std::make_pair(kSignal, kGamma)] =
00022       &tau_->selectedSignalPFGammaCands_;
00023   collections_[std::make_pair(kSignal, kNeutralHadron)] =
00024       &tau_->selectedSignalPFNeutrHadrCands_;
00025   collections_[std::make_pair(kSignal, kAll)] =
00026       &tau_->selectedSignalPFCands_;
00027 
00028   collections_[std::make_pair(kIsolation, kChargedHadron)] =
00029       &tau_->selectedIsolationPFChargedHadrCands_;
00030   collections_[std::make_pair(kIsolation, kGamma)] =
00031       &tau_->selectedIsolationPFGammaCands_;
00032   collections_[std::make_pair(kIsolation, kNeutralHadron)] =
00033       &tau_->selectedIsolationPFNeutrHadrCands_;
00034   collections_[std::make_pair(kIsolation, kAll)] =
00035       &tau_->selectedIsolationPFCands_;
00036 
00037   // Build our temporary sorted collections, since you can't use stl sorts on
00038   // RefVectors
00039   BOOST_FOREACH(const CollectionMap::value_type &colkey, collections_) {
00040     // Build an empty list for each collection
00041     sortedCollections_[colkey.first] = SortedListPtr(
00042         new SortedListPtr::element_type);
00043   }
00044 
00045   tau_->setjetRef(jet);
00046 }
00047 
00048 void RecoTauConstructor::addPFCand(Region region, ParticleType type,
00049     const PFCandidateRef& ref) {
00050   if (region == kSignal) {
00051     // Keep track of the four vector of the signal vector products added so far.
00052     // If a photon add it if we are not using PiZeros to build the gammas
00053     if ( (type != kGamma) || !copyGammas_ )
00054       p4_ += ref->p4();
00055   }
00056   getSortedCollection(region, type)->push_back(ref);
00057   // Add to global collection
00058   getSortedCollection(region, kAll)->push_back(ref);
00059 }
00060 
00061 void RecoTauConstructor::reserve(Region region, ParticleType type, size_t size){
00062   getSortedCollection(region, type)->reserve(size);
00063   getCollection(region, type)->reserve(size);
00064   // Reserve global collection as well
00065   getSortedCollection(region, kAll)->reserve(
00066       getSortedCollection(region, kAll)->size() + size);
00067   getCollection(region, kAll)->reserve(
00068       getCollection(region, kAll)->size() + size);
00069 }
00070 
00071 void RecoTauConstructor::reservePiZero(Region region, size_t size) {
00072   if(region == kSignal) {
00073     tau_->signalPiZeroCandidates_.reserve(size);
00074     // If we are building the gammas with the pizeros, resize that
00075     // vector as well
00076     if(copyGammas_)
00077       reserve(kSignal, kGamma, 2*size);
00078   } else {
00079     tau_->isolationPiZeroCandidates_.reserve(size);
00080     if(copyGammas_)
00081       reserve(kIsolation, kGamma, 2*size);
00082   }
00083 }
00084 
00085 void RecoTauConstructor::addPiZero(Region region, const RecoTauPiZero& piZero) {
00086   if(region == kSignal) {
00087     tau_->signalPiZeroCandidates_.push_back(piZero);
00088     // Copy the daughter gammas into the gamma collection if desired
00089     if(copyGammas_) {
00090       // If we are using the pizeros to build the gammas, make sure we update
00091       // the four vector correctly.
00092       p4_ += piZero.p4();
00093       addPFCands(kSignal, kGamma, piZero.daughterPtrVector().begin(),
00094           piZero.daughterPtrVector().end());
00095     }
00096   } else {
00097     tau_->isolationPiZeroCandidates_.push_back(piZero);
00098     if(copyGammas_) {
00099       addPFCands(kIsolation, kGamma, piZero.daughterPtrVector().begin(),
00100           piZero.daughterPtrVector().end());
00101     }
00102   }
00103 }
00104 
00105 PFCandidateRefVector*
00106 RecoTauConstructor::getCollection(Region region, ParticleType type) {
00107     return collections_[std::make_pair(region, type)];
00108 }
00109 
00110 RecoTauConstructor::SortedListPtr
00111 RecoTauConstructor::getSortedCollection(Region region, ParticleType type) {
00112   return sortedCollections_[std::make_pair(region, type)];
00113 }
00114 
00115 // Trivial converter needed for polymorphism
00116 PFCandidateRef RecoTauConstructor::convertToRef(
00117     const PFCandidateRef& pfRef) const {
00118   return pfRef;
00119 }
00120 
00121 namespace {
00122 // Make sure the two products come from the same EDM source
00123 template<typename T1, typename T2>
00124 void checkMatchedProductIds(const T1& t1, const T2& t2) {
00125     if (t1.id() != t2.id()) {
00126       throw cms::Exception("MismatchedPFCandSrc") << "Error: the input tag"
00127           << " for the PF candidate collection provided to the RecoTauBuilder "
00128           << " does not match the one that was used to build the source jets."
00129           << " Please update the pfCandSrc paramters for the PFTau builders.";
00130     }
00131 }
00132 }
00133 
00134 // Convert from a Ptr to a Ref
00135 PFCandidateRef RecoTauConstructor::convertToRef(
00136     const PFCandidatePtr& pfPtr) const {
00137   if(pfPtr.isNonnull()) {
00138     checkMatchedProductIds(pfPtr, pfCands_);
00139     return PFCandidateRef(pfCands_, pfPtr.key());
00140   } else return PFCandidateRef();
00141 }
00142 
00143 // Convert from a CandidatePtr to a Ref
00144 PFCandidateRef RecoTauConstructor::convertToRef(
00145     const CandidatePtr& candPtr) const {
00146   if(candPtr.isNonnull()) {
00147     checkMatchedProductIds(candPtr, pfCands_);
00148     return PFCandidateRef(pfCands_, candPtr.key());
00149   } else return PFCandidateRef();
00150 }
00151 
00152 namespace {
00153 template<typename T> bool ptDescending(const T& a, const T& b) {
00154   return a.pt() > b.pt();
00155 }
00156 template<typename T> bool ptDescendingRef(const T& a, const T& b) {
00157   return a->pt() > b->pt();
00158 }
00159 }
00160 
00161 void RecoTauConstructor::sortAndCopyIntoTau() {
00162   // The pizeros are a special case, as we can sort them in situ
00163   std::sort(tau_->signalPiZeroCandidates_.begin(),
00164             tau_->signalPiZeroCandidates_.end(),
00165             ptDescending<RecoTauPiZero>);
00166   std::sort(tau_->isolationPiZeroCandidates_.begin(),
00167             tau_->isolationPiZeroCandidates_.end(),
00168             ptDescending<RecoTauPiZero>);
00169 
00170   // Sort each of our sortable collections, and copy them into the final
00171   // tau RefVector.
00172   BOOST_FOREACH(const CollectionMap::value_type &colkey, collections_) {
00173     SortedListPtr sortedCollection = sortedCollections_[colkey.first];
00174     std::sort(sortedCollection->begin(),
00175               sortedCollection->end(),
00176               ptDescendingRef<PFCandidateRef>);
00177     // Copy into the real tau collection
00178     std::for_each(
00179         sortedCollection->begin(), sortedCollection->end(),
00180         boost::bind(&PFCandidateRefVector::push_back, colkey.second, _1));
00181   }
00182 }
00183 
00184 std::auto_ptr<reco::PFTau> RecoTauConstructor::get(bool setupLeadingObjects) {
00185   // Copy the sorted collections into the interal tau refvectors
00186   sortAndCopyIntoTau();
00187 
00188   // Setup all the important member variables of the tau
00189   // Set charge of tau
00190   tau_->setCharge(
00191       sumPFCandCharge(getCollection(kSignal, kChargedHadron)->begin(),
00192                       getCollection(kSignal, kChargedHadron)->end()));
00193 
00194   // Set PDG id
00195   tau_->setPdgId(tau_->charge() < 0 ? 15 : -15);
00196 
00197   // Set P4
00198   tau_->setP4(p4_);
00199 //  tau_->setP4(
00200 //      sumPFCandP4(
00201 //        getCollection(kSignal, kAll)->begin(),
00202 //        getCollection(kSignal, kAll)->end()
00203 //        )
00204 //      );
00205 
00206   // Set charged isolation quantities
00207   tau_->setisolationPFChargedHadrCandsPtSum(
00208       sumPFCandPt(
00209         getCollection(kIsolation, kChargedHadron)->begin(),
00210         getCollection(kIsolation, kChargedHadron)->end()
00211         )
00212       );
00213 
00214   // Set gamma isolation quantities
00215   tau_->setisolationPFGammaCandsEtSum(
00216       sumPFCandPt(
00217         getCollection(kIsolation, kGamma)->begin(),
00218         getCollection(kIsolation, kGamma)->end()
00219         )
00220       );
00221   // Set em fraction
00222   tau_->setemFraction(sumPFCandPt(
00223           getCollection(kSignal, kGamma)->begin(),
00224           getCollection(kSignal, kGamma)->end()) / tau_->pt());
00225 
00226   if(setupLeadingObjects)
00227   {
00228     typedef PFCandidateRefVector::const_iterator Iter;
00229     // Find the highest PT object in the signal cone
00230     Iter leadingCand = leadPFCand(
00231         getCollection(kSignal, kAll)->begin(),
00232         getCollection(kSignal, kAll)->end()
00233         );
00234 
00235     if(leadingCand != getCollection(kSignal, kAll)->end())
00236       tau_->setleadPFCand(*leadingCand);
00237 
00238     // Hardest charged object in signal cone
00239     Iter leadingChargedCand = leadPFCand(
00240         getCollection(kSignal, kChargedHadron)->begin(),
00241         getCollection(kSignal, kChargedHadron)->end()
00242         );
00243 
00244     if(leadingChargedCand != getCollection(kSignal, kChargedHadron)->end())
00245       tau_->setleadPFChargedHadrCand(*leadingChargedCand);
00246 
00247     // Hardest gamma object in signal cone
00248     Iter leadingGammaCand = leadPFCand(
00249         getCollection(kSignal, kGamma)->begin(),
00250         getCollection(kSignal, kGamma)->end()
00251         );
00252 
00253     if(leadingGammaCand != getCollection(kSignal, kGamma)->end())
00254       tau_->setleadPFNeutralCand(*leadingGammaCand);
00255   }
00256   return tau_;
00257 }
00258 }} // end namespace reco::tau