00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <algorithm>
00015 #include <memory>
00016
00017 #include "RecoTauTag/RecoTau/interface/RecoTauPiZeroPlugins.h"
00018
00019 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
00020 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
00021 #include "DataFormats/VertexReco/interface/Vertex.h"
00022 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00023 #include "DataFormats/TauReco/interface/RecoTauPiZero.h"
00024 #include "DataFormats/JetReco/interface/PFJet.h"
00025 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
00026 #include "DataFormats/Math/interface/deltaPhi.h"
00027
00028 #include "RecoTauTag/RecoTau/interface/RecoTauCommonUtilities.h"
00029 #include "RecoTauTag/RecoTau/interface/RecoTauQualityCuts.h"
00030 #include "RecoTauTag/RecoTau/interface/RecoTauVertexAssociator.h"
00031 #include "RecoTauTag/RecoTau/interface/CombinatoricGenerator.h"
00032
00033
00034
00035 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00036 #include "DataFormats/TrackReco/interface/Track.h"
00037
00038
00039 namespace reco { namespace tau {
00040
00041 namespace {
00042
00043 math::XYZTLorentzVector applyMassConstraint(
00044 const math::XYZTLorentzVector& vec,double mass) {
00045 double factor = sqrt(vec.energy()*vec.energy()-mass*mass)/vec.P();
00046 return math::XYZTLorentzVector(
00047 vec.px()*factor,vec.py()*factor,vec.pz()*factor,vec.energy());
00048 }
00049 }
00050
00051 class RecoTauPiZeroStripPlugin2 : public RecoTauPiZeroBuilderPlugin
00052 {
00053 public:
00054 explicit RecoTauPiZeroStripPlugin2(const edm::ParameterSet&);
00055 virtual ~RecoTauPiZeroStripPlugin2();
00056
00057 return_type operator()(const reco::PFJet&) const;
00058
00059 virtual void beginEvent();
00060
00061 private:
00062 typedef std::vector<reco::PFCandidatePtr> PFCandPtrs;
00063 void addCandsToStrip(RecoTauPiZero&, PFCandPtrs&, const std::vector<bool>&, std::set<size_t>&, bool&) const;
00064
00065 RecoTauVertexAssociator vertexAssociator_;
00066
00067 RecoTauQualityCuts* qcuts_;
00068 bool applyElecTrackQcuts_;
00069 double minGammaEtStripSeed_;
00070 double minGammaEtStripAdd_;
00071
00072 double minStripEt_;
00073
00074 std::vector<int> inputPdgIds_;
00075 double etaAssociationDistance_;
00076 double phiAssociationDistance_;
00077
00078 bool updateStripAfterEachDaughter_;
00079 int maxStripBuildIterations_;
00080
00081
00082 bool combineStrips_;
00083 int maxStrips_;
00084 double combinatoricStripMassHypo_;
00085
00086 AddFourMomenta p4Builder_;
00087 };
00088
00089 RecoTauPiZeroStripPlugin2::RecoTauPiZeroStripPlugin2(const edm::ParameterSet& pset)
00090 : RecoTauPiZeroBuilderPlugin(pset),
00091 vertexAssociator_(pset.getParameter<edm::ParameterSet>("qualityCuts")),
00092 qcuts_(0)
00093 {
00094 LogTrace("RecoTauPiZeroStripPlugin2") << "<RecoTauPiZeroStripPlugin2::RecoTauPiZeroStripPlugin2>:" ;
00095
00096 minGammaEtStripSeed_ = pset.getParameter<double>("minGammaEtStripSeed");
00097 LogTrace("RecoTauPiZeroStripPlugin2") << " minGammaEtStripSeed = " << minGammaEtStripSeed_ ;
00098 minGammaEtStripAdd_ = pset.getParameter<double>("minGammaEtStripAdd");
00099 LogTrace("RecoTauPiZeroStripPlugin2") << " minGammaEtStripAdd = " << minGammaEtStripAdd_ ;
00100
00101 minStripEt_ = pset.getParameter<double>("minStripEt");
00102 LogTrace("RecoTauPiZeroStripPlugin2") << " minStripEt = " << minStripEt_ ;
00103
00104 edm::ParameterSet qcuts_pset = pset.getParameterSet("qualityCuts").getParameterSet("signalQualityCuts");
00105
00106
00107
00108 applyElecTrackQcuts_ = pset.getParameter<bool>("applyElecTrackQcuts");
00109 if ( !applyElecTrackQcuts_ ) {
00110 qcuts_pset.addParameter<double>("minTrackPt", std::min(minGammaEtStripSeed_, minGammaEtStripAdd_));
00111 qcuts_pset.addParameter<double>("maxTrackChi2", 1.e+9);
00112 qcuts_pset.addParameter<double>("maxTransverseImpactParameter", 1.e+9);
00113 qcuts_pset.addParameter<double>("maxDeltaZ", 1.);
00114 qcuts_pset.addParameter<double>("minTrackVertexWeight", -1.);
00115 qcuts_pset.addParameter<unsigned>("minTrackPixelHits", 0);
00116 qcuts_pset.addParameter<unsigned>("minTrackHits", 0);
00117 }
00118
00119 qcuts_pset.addParameter<double>("minGammaEt", std::min(minGammaEtStripSeed_, minGammaEtStripAdd_));
00120 qcuts_ = new RecoTauQualityCuts(qcuts_pset);
00121
00122 inputPdgIds_ = pset.getParameter<std::vector<int> >("stripCandidatesParticleIds");
00123 etaAssociationDistance_ = pset.getParameter<double>("stripEtaAssociationDistance");
00124 phiAssociationDistance_ = pset.getParameter<double>("stripPhiAssociationDistance");
00125
00126 updateStripAfterEachDaughter_ = pset.getParameter<bool>("updateStripAfterEachDaughter");
00127 maxStripBuildIterations_ = pset.getParameter<int>("maxStripBuildIterations");
00128
00129 combineStrips_ = pset.getParameter<bool>("makeCombinatoricStrips");
00130 if ( combineStrips_ ) {
00131 maxStrips_ = pset.getParameter<int>("maxInputStrips");
00132 combinatoricStripMassHypo_ = pset.getParameter<double>("stripMassWhenCombining");
00133 }
00134 }
00135
00136 RecoTauPiZeroStripPlugin2::~RecoTauPiZeroStripPlugin2()
00137 {
00138 delete qcuts_;
00139 }
00140
00141
00142 void RecoTauPiZeroStripPlugin2::beginEvent()
00143 {
00144 vertexAssociator_.setEvent(*evt());
00145 }
00146
00147 void RecoTauPiZeroStripPlugin2::addCandsToStrip(RecoTauPiZero& strip, PFCandPtrs& cands, const std::vector<bool>& candFlags,
00148 std::set<size_t>& candIdsCurrentStrip, bool& isCandAdded) const
00149 {
00150 size_t numCands = cands.size();
00151 for ( size_t candId = 0; candId < numCands; ++candId ) {
00152 if ( (!candFlags[candId]) && candIdsCurrentStrip.find(candId) == candIdsCurrentStrip.end() ) {
00153 reco::PFCandidatePtr cand = cands[candId];
00154 if ( fabs(strip.eta() - cand->eta()) < etaAssociationDistance_ &&
00155 fabs(strip.phi() - cand->phi()) < phiAssociationDistance_ ) {
00156 LogTrace("RecoTauPiZeroStripPlugin2") << "--> candId = " << candId << " has been added." ;
00157 strip.addDaughter(cand);
00158 if ( updateStripAfterEachDaughter_ ) p4Builder_.set(strip);
00159 isCandAdded = true;
00160 candIdsCurrentStrip.insert(candId);
00161 }
00162 }
00163 }
00164 }
00165
00166 void markCandsInStrip(std::vector<bool>& candFlags, const std::set<size_t>& candIds)
00167 {
00168 for ( std::set<size_t>::const_iterator candId = candIds.begin();
00169 candId != candIds.end(); ++candId ) {
00170 candFlags[*candId] = true;
00171 }
00172 }
00173
00174 namespace {
00175 const reco::TrackBaseRef getTrack(const PFCandidate& cand)
00176 {
00177 if ( cand.trackRef().isNonnull() ) return reco::TrackBaseRef(cand.trackRef());
00178 else if ( cand.gsfTrackRef().isNonnull() ) return reco::TrackBaseRef(cand.gsfTrackRef());
00179 else return reco::TrackBaseRef();
00180 }
00181 }
00182
00183 RecoTauPiZeroStripPlugin2::return_type RecoTauPiZeroStripPlugin2::operator()(const reco::PFJet& jet) const
00184 {
00185 PiZeroVector output;
00186
00187
00188 qcuts_->setPV(vertexAssociator_.associatedVertex(jet));
00189 PFCandPtrs candsVector = qcuts_->filterRefs(pfCandidates(jet, inputPdgIds_));
00190
00191
00192 PFCandPtrs seedCands;
00193 PFCandPtrs addCands;
00194 int idx = 0;
00195 for ( PFCandPtrs::iterator cand = candsVector.begin();
00196 cand != candsVector.end(); ++cand ) {
00197 LogTrace("RecoTauPiZeroStripPlugin2") << "PFGamma (" << idx << "): Et = " << (*cand)->et() << ","
00198 << " eta = " << (*cand)->eta() << ", phi = " << (*cand)->phi();
00199 if ( (*cand)->et() > minGammaEtStripSeed_ ) {
00200 LogTrace("RecoTauPiZeroStripPlugin2") << " --> assigning seedCandId = " << seedCands.size() ;
00201 #ifdef EDM_ML_DEBUG
00202 const reco::TrackBaseRef candTrack = getTrack(*cand);
00203 if ( candTrack.isNonnull() ) {
00204 LogTrace("RecoTauPiZeroStripPlugin2") << "has Track: pt = " << candTrack->pt() << " +/- " << candTrack->ptError() << ","
00205 << " eta = " << candTrack->eta() << ", phi = " << candTrack->phi() << ","
00206 << " charge = " << candTrack->charge() ;
00207 LogTrace("RecoTauPiZeroStripPlugin2") << " chi2 = " << candTrack->normalizedChi2() ;
00208 LogTrace("RecoTauPiZeroStripPlugin2") << " dIP = " << std::abs(candTrack->dxy(vertexAssociator_.associatedVertex(jet)->position())) ;
00209 LogTrace("RecoTauPiZeroStripPlugin2") << " dZ = " << std::abs(candTrack->dz(vertexAssociator_.associatedVertex(jet)->position())) ;
00210 LogTrace("RecoTauPiZeroStripPlugin2") << " vtxAssocWeight = " << vertexAssociator_.associatedVertex(jet)->trackWeight(candTrack) ;
00211 LogTrace("RecoTauPiZeroStripPlugin2") << " numPxlHits = " << candTrack->hitPattern().numberOfValidPixelHits() ;
00212 LogTrace("RecoTauPiZeroStripPlugin2") << " numTrkHits = " << candTrack->hitPattern().numberOfValidHits() ;
00213 }
00214 #endif
00215 LogTrace("RecoTauPiZeroStripPlugin2") << "ECAL Et: calibrated = " << (*cand)->ecalEnergy()*sin((*cand)->theta()) << ","
00216 << " raw = " << (*cand)->rawEcalEnergy()*sin((*cand)->theta()) ;
00217 LogTrace("RecoTauPiZeroStripPlugin2") << "HCAL Et: calibrated = " << (*cand)->hcalEnergy()*sin((*cand)->theta()) << ","
00218 << " raw = " << (*cand)->rawHcalEnergy()*sin((*cand)->theta()) ;
00219 seedCands.push_back(*cand);
00220 } else if ( (*cand)->et() > minGammaEtStripAdd_ ) {
00221 LogTrace("RecoTauPiZeroStripPlugin2") << " --> assigning addCandId = " << addCands.size();
00222 addCands.push_back(*cand);
00223 }
00224 LogTrace("RecoTauPiZeroStripPlugin2") ;
00225 ++idx;
00226 }
00227
00228 std::vector<bool> seedCandFlags(seedCands.size());
00229 std::vector<bool> addCandFlags(addCands.size());
00230
00231 std::set<size_t> seedCandIdsCurrentStrip;
00232 std::set<size_t> addCandIdsCurrentStrip;
00233
00234 size_t idxSeed = 0;
00235 while ( idxSeed < seedCands.size() ) {
00236 LogTrace("RecoTauPiZeroStripPlugin2") << "idxSeed = " << idxSeed ;
00237
00238 seedCandIdsCurrentStrip.clear();
00239 addCandIdsCurrentStrip.clear();
00240
00241 std::auto_ptr<RecoTauPiZero> strip(new RecoTauPiZero(*seedCands[idxSeed], RecoTauPiZero::kStrips));
00242 strip->addDaughter(seedCands[idxSeed]);
00243 seedCandIdsCurrentStrip.insert(idxSeed);
00244
00245 bool isCandAdded;
00246 int stripBuildIteration = 0;
00247 do {
00248 isCandAdded = false;
00249
00250 LogTrace("RecoTauPiZeroStripPlugin2") << " adding seedCands to strip..." ;
00251 addCandsToStrip(*strip, seedCands, seedCandFlags, seedCandIdsCurrentStrip, isCandAdded);
00252 LogTrace("RecoTauPiZeroStripPlugin2") << " adding addCands to strip..." ;
00253 addCandsToStrip(*strip, addCands, addCandFlags, addCandIdsCurrentStrip, isCandAdded);
00254
00255 if ( !updateStripAfterEachDaughter_ ) p4Builder_.set(*strip);
00256
00257 ++stripBuildIteration;
00258 } while ( isCandAdded && (stripBuildIteration < maxStripBuildIterations_ || maxStripBuildIterations_ == -1) );
00259
00260 if ( strip->et() > minStripEt_ ) {
00261 LogTrace("RecoTauPiZeroStripPlugin2") << "Strip: Et = " << strip->et() << ","
00262 << " eta = " << strip->eta() << ", phi = " << strip->phi()
00263 << " --> building it !!" ;
00264
00265
00266 if ( strip->daughterPtr(0).isNonnull() ) strip->setVertex(strip->daughterPtr(0)->vertex());
00267 output.push_back(strip);
00268
00269
00270 markCandsInStrip(seedCandFlags, seedCandIdsCurrentStrip);
00271 markCandsInStrip(addCandFlags, addCandIdsCurrentStrip);
00272 } else {
00273 LogTrace("RecoTauPiZeroStripPlugin2") << "Strip: Et = " << strip->et() << ","
00274 << " eta = " << strip->eta() << ", phi = " << strip->phi()
00275 << " --> discarding it !!" ;
00276 }
00277
00278 ++idxSeed;
00279 while ( idxSeed < seedCands.size() && seedCandFlags[idxSeed] ) {
00280 ++idxSeed;
00281 }
00282 }
00283
00284
00285 if ( combineStrips_ && output.size() > 1 ) {
00286 PiZeroVector stripCombinations;
00287
00288 output.sort(output.begin(), output.end(),
00289 boost::bind(&RecoTauPiZero::pt, _1) >
00290 boost::bind(&RecoTauPiZero::pt, _2));
00291
00292 PiZeroVector::const_iterator end_iter = takeNElements(
00293 output.begin(), output.end(), maxStrips_);
00294
00295
00296 for ( PiZeroVector::const_iterator first = output.begin();
00297 first != end_iter-1; ++first ) {
00298 for ( PiZeroVector::const_iterator second = first+1;
00299 second != end_iter; ++second ) {
00300 Candidate::LorentzVector firstP4 = first->p4();
00301 Candidate::LorentzVector secondP4 = second->p4();
00302
00303 firstP4 = applyMassConstraint(firstP4, combinatoricStripMassHypo_);
00304 secondP4 = applyMassConstraint(secondP4, combinatoricStripMassHypo_);
00305 Candidate::LorentzVector totalP4 = firstP4 + secondP4;
00306
00307 std::auto_ptr<RecoTauPiZero> combinedStrips(
00308 new RecoTauPiZero(0, totalP4,
00309 Candidate::Point(0, 0, 0),
00310
00311 111, 10001, true, RecoTauPiZero::kUndefined));
00312
00313
00314 BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
00315 first->daughterPtrVector()) {
00316 combinedStrips->addDaughter(gamma);
00317 }
00318 BOOST_FOREACH(const RecoTauPiZero::daughters::value_type& gamma,
00319 second->daughterPtrVector()) {
00320 combinedStrips->addDaughter(gamma);
00321 }
00322
00323 if ( combinedStrips->daughterPtr(0).isNonnull() )
00324 combinedStrips->setVertex(combinedStrips->daughterPtr(0)->vertex());
00325
00326 stripCombinations.push_back(combinedStrips);
00327 }
00328 }
00329
00330
00331 output.transfer(output.end(), stripCombinations);
00332 }
00333
00334 return output.release();
00335 }
00336 }}
00337
00338 #include "FWCore/Framework/interface/MakerMacros.h"
00339 DEFINE_EDM_PLUGIN(RecoTauPiZeroBuilderPluginFactory,
00340 reco::tau::RecoTauPiZeroStripPlugin2, "RecoTauPiZeroStripPlugin2");