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
00015 tau_.reset(new PFTau());
00016
00017 copyGammas_ = copyGammasFromPiZeros;
00018
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
00038
00039 BOOST_FOREACH(const CollectionMap::value_type &colkey, collections_) {
00040
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
00052
00053 if ( (type != kGamma) || !copyGammas_ )
00054 p4_ += ref->p4();
00055 }
00056 getSortedCollection(region, type)->push_back(ref);
00057
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
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
00075
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
00089 if(copyGammas_) {
00090
00091
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
00116 PFCandidateRef RecoTauConstructor::convertToRef(
00117 const PFCandidateRef& pfRef) const {
00118 return pfRef;
00119 }
00120
00121 namespace {
00122
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
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
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
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
00171
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
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
00186 sortAndCopyIntoTau();
00187
00188
00189
00190 tau_->setCharge(
00191 sumPFCandCharge(getCollection(kSignal, kChargedHadron)->begin(),
00192 getCollection(kSignal, kChargedHadron)->end()));
00193
00194
00195 tau_->setPdgId(tau_->charge() < 0 ? 15 : -15);
00196
00197
00198 tau_->setP4(p4_);
00199
00200
00201
00202
00203
00204
00205
00206
00207 tau_->setisolationPFChargedHadrCandsPtSum(
00208 sumPFCandPt(
00209 getCollection(kIsolation, kChargedHadron)->begin(),
00210 getCollection(kIsolation, kChargedHadron)->end()
00211 )
00212 );
00213
00214
00215 tau_->setisolationPFGammaCandsEtSum(
00216 sumPFCandPt(
00217 getCollection(kIsolation, kGamma)->begin(),
00218 getCollection(kIsolation, kGamma)->end()
00219 )
00220 );
00221
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
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
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
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 }}