00001 #include "RecoTauTag/RecoTau/interface/PFRecoTauDecayModeDeterminator.h"
00002
00003 PFRecoTauDecayModeDeterminator::PFRecoTauDecayModeDeterminator(const ParameterSet& iConfig):chargedPionMass(0.13957),neutralPionMass(0.13497){
00004 PFTauProducer_ = iConfig.getParameter<InputTag>("PFTauProducer");
00005 maxPhotonsToMerge_ = iConfig.getParameter<uint32_t>("maxPhotonsToMerge");
00006 maxPiZeroMass_ = iConfig.getParameter<double>("maxPiZeroMass");
00007 mergeLowPtPhotonsFirst_ = iConfig.getParameter<bool>("mergeLowPtPhotonsFirst");
00008 refitTracks_ = iConfig.getParameter<bool>("refitTracks");
00009 filterTwoProngs_ = iConfig.getParameter<bool>("filterTwoProngs");
00010 filterPhotons_ = iConfig.getParameter<bool>("filterPhotons");
00011 minPtFractionForSecondProng_ = iConfig.getParameter<double>("minPtFractionForSecondProng");
00012 minPtFractionForGammas_ = iConfig.getParameter<double>("minPtFractionForThirdGamma");
00013
00014 vertexFitter_ = new PFCandCommonVertexFitter<KalmanVertexFitter>(iConfig);
00015 produces<PFTauDecayModeAssociation>();
00016 }
00017
00018 PFRecoTauDecayModeDeterminator::~PFRecoTauDecayModeDeterminator()
00019 {
00020
00021 }
00022
00023
00024
00025
00026
00027 void PFRecoTauDecayModeDeterminator::mergePiZeroes(compCandList& input, compCandRevIter seed)
00028 {
00029
00030
00031 if(seed == input.rend())
00032 return;
00033 compCandRevIter bestMatchSoFar;
00034 LorentzVector combinationCandidate;
00035 float closestInvariantMassDifference = maxPiZeroMass_ + 1;
00036 bool foundACompatibleMatch = false;
00037
00038 compCandRevIter potentialMatch = seed;
00039 ++potentialMatch;
00040 for(; potentialMatch != input.rend(); ++potentialMatch)
00041 {
00042
00043 LorentzVector seedFourVector = seed->p4();
00044 LorentzVector toAddFourVect = potentialMatch->p4();
00045 combinationCandidate = seedFourVector + toAddFourVect;
00046 float combinationCandidateMass = combinationCandidate.M();
00047 float differenceToTruePiZeroMass = abs(combinationCandidateMass - neutralPionMass);
00048 if(combinationCandidateMass < maxPiZeroMass_ && differenceToTruePiZeroMass < closestInvariantMassDifference)
00049 {
00050 closestInvariantMassDifference = differenceToTruePiZeroMass;
00051 bestMatchSoFar = potentialMatch;
00052 foundACompatibleMatch = true;
00053 }
00054 }
00055
00056 if(foundACompatibleMatch && seed->numberOfDaughters() < maxPhotonsToMerge_)
00057 {
00058
00059 if(bestMatchSoFar->numberOfDaughters() > 0)
00060 {
00061 const Candidate* photonToAdd = (*bestMatchSoFar).daughter(0);
00062 seed->addDaughter(*photonToAdd);
00063 }
00064 addP4.set(*seed);
00065
00066 input.erase( (++bestMatchSoFar).base() );
00067 mergePiZeroes(input, seed);
00068 } else
00069 {
00070
00071 addP4.set(*seed);
00072 ++seed;
00073 mergePiZeroes(input, seed);
00074 }
00075 }
00076
00077 void PFRecoTauDecayModeDeterminator::produce(Event& iEvent,const EventSetup& iSetup){
00078
00079 ESHandle<TransientTrackBuilder> myTransientTrackBuilder;
00080 ESHandle<MagneticField> myMF;
00081
00082 if (refitTracks_)
00083 {
00084 iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder",myTransientTrackBuilder);
00085 iSetup.get<IdealMagneticFieldRecord>().get(myMF);
00086 }
00087
00088 Handle<PFTauCollection> thePFTauCollection;
00089 iEvent.getByLabel(PFTauProducer_,thePFTauCollection);
00090
00091 auto_ptr<PFTauDecayModeAssociation> result(new PFTauDecayModeAssociation(PFTauRefProd(thePFTauCollection)));
00092
00093 size_t numberOfPFTaus = thePFTauCollection->size();
00094 for(size_t iPFTau = 0; iPFTau < numberOfPFTaus; ++iPFTau)
00095 {
00096
00097 PFTauRef pfTauRef(thePFTauCollection, iPFTau);
00098 PFTau myPFTau = *pfTauRef;
00099
00100
00101 const PFCandidateRefVector& theChargedHadronCandidates = myPFTau.signalPFChargedHadrCands();
00102 const PFCandidateRefVector& theGammaCandidates = myPFTau.signalPFGammaCands();
00103
00104 LorentzVector totalFourVector;
00105
00106
00107 vector<ShallowCloneCandidate> chargedCandidates;
00108 list<CompositeCandidate> gammaCandidates;
00109 VertexCompositeCandidate chargedCandsToAdd;
00110
00111 for( PFCandidateRefVector::const_iterator iCharged = theChargedHadronCandidates.begin();
00112 iCharged != theChargedHadronCandidates.end();
00113 ++iCharged)
00114 {
00115
00116 chargedCandsToAdd.addDaughter(ShallowCloneCandidate(CandidateBaseRef(*iCharged)));
00117 Candidate* justAdded = chargedCandsToAdd.daughter(chargedCandsToAdd.numberOfDaughters()-1);
00118 totalFourVector += justAdded->p4();
00119 justAdded->setMass(chargedPionMass);
00120 }
00121 for( PFCandidateRefVector::const_iterator iGamma = theGammaCandidates.begin();
00122 iGamma != theGammaCandidates.end();
00123 ++iGamma)
00124 {
00125 CompositeCandidate potentialPiZero;
00126 potentialPiZero.addDaughter(ShallowCloneCandidate(CandidateBaseRef(*iGamma)));
00127 addP4.set(potentialPiZero);
00128 totalFourVector += potentialPiZero.p4();
00129 gammaCandidates.push_back(potentialPiZero);
00130 }
00131
00132
00133 if (mergeLowPtPhotonsFirst_)
00134 gammaCandidates.sort(candDescendingSorter);
00135 else
00136 gammaCandidates.sort(candAscendingSorter);
00137
00138 mergePiZeroes(gammaCandidates, gammaCandidates.rbegin());
00139
00140 CompositeCandidate mergedPiZerosToAdd;
00141 for( list<CompositeCandidate>::iterator iGamma = gammaCandidates.begin();
00142 iGamma != gammaCandidates.end();
00143 ++iGamma)
00144 {
00145 iGamma->setMass(neutralPionMass);
00146 mergedPiZerosToAdd.addDaughter(*iGamma);
00147 }
00148 addP4.set(mergedPiZerosToAdd);
00149
00150 CompositeCandidate filteredStuff;
00151
00152
00153 if (refitTracks_ && chargedCandsToAdd.numberOfDaughters() > 1)
00154 {
00155 vertexFitter_->set(myMF.product());
00156 vertexFitter_->set(chargedCandsToAdd);
00157 }
00158
00159 addP4.set(chargedCandsToAdd);
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 PFTauDecayMode myDecayModeTau(chargedCandsToAdd, mergedPiZerosToAdd, filteredStuff);
00171 myDecayModeTau.setPFTauRef(pfTauRef);
00172 result->setValue(iPFTau, myDecayModeTau);
00173 }
00174 iEvent.put(result);
00175 }