00001
00002
00003
00004
00005
00015
00016
00017
00018
00019
00020
00021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00022
00023 #include "DataFormats/VertexReco/interface/Vertex.h"
00024 #include "RecoTauTag/Pi0Tau/interface/Pi0Algo.h"
00025
00026 #include "Math/GenVector/VectorUtil.h"
00027
00028 #include <iostream>
00029 #include <algorithm>
00030 #include <cmath>
00031
00032
00033 using namespace reco;
00034
00035
00036
00037
00038 Pi0Algo::Pi0Algo(reco::TrackRef seedTrack){
00039 coneSize_ = 0.524;
00040 use3DAngle_ = false;
00041 ecalEntrance_ = 129.0;
00042 massRes_ = 0.03;
00043 seedTrack_ = seedTrack;
00044 pi0Collection_.clear();
00045 }
00046
00047
00048 Pi0Algo::~Pi0Algo()
00049 {
00050 pi0Collection_.clear();
00051 }
00052
00053
00054 void Pi0Algo::fillPi0sUsingPF(edm::Handle<reco::PFCandidateCollection> &pFCandidateHandle){
00055
00056 LogDebug("Pi0Algo") << "The validity of seedTrack is " << (seedTrack_.isNull() ? 0 : 1) << "\n";
00057
00058 if(seedTrack_.isNull()){
00059 LogDebug("Pi0Algo") << "seedTrack is not valid";
00060 return;
00061 }
00062
00063 LogDebug("Pi0Algo") << "vertex of seedTrack : ("
00064 << seedTrack_->vertex().x() << ","
00065 << seedTrack_->vertex().y() << ","
00066 << seedTrack_->vertex().z() << ")\n";
00067
00068 if(!pFCandidateHandle.isValid()) {
00069 LogDebug("Pi0Algo") << "PFCandidateCollection is not valid";
00070 return;
00071 }
00072
00073 const reco::PFCandidateCollection& pFCandidateCollection = *(pFCandidateHandle.product());
00074
00075 reco::PFCandidateRefVector photonCands;
00076 int icand = 0;
00077 for(reco::PFCandidateCollection::const_iterator ic = pFCandidateCollection.begin();
00078 ic != pFCandidateCollection.end(); ++ic) {
00079 const reco::PFCandidate *cand = &(*ic);
00080 reco::PFCandidateRef candRef(pFCandidateHandle,icand);
00081 icand++;
00082 if(cand->particleId() != reco::PFCandidate::gamma) continue;
00083
00084 double dist = use3DAngle_ ? ROOT::Math::VectorUtil::Angle(seedTrack_->momentum(),cand->momentum()) :
00085 ROOT::Math::VectorUtil::DeltaR(seedTrack_->momentum(),cand->momentum());
00086
00087 if(dist > coneSize_) continue;
00088 photonCands.push_back(candRef);
00089 }
00090
00091 LogDebug("Pi0Algo") << " size of photonCandidates : " << photonCands.size() << "\n";
00092
00093 reco::PFCandidateRefVector usedPhotons;
00094 int nPhotons = photonCands.size();
00095 for(reco::PFCandidateRefVector::const_iterator ip = photonCands.begin();
00096 ip != photonCands.end(); ++ip){
00097 const reco::PFCandidateRef candRef = *ip;
00098 reco::PFCandidateRefVector pi0Cands;
00099 if(binary_search(usedPhotons.begin(),usedPhotons.end(),candRef)) continue;
00100 else {
00101 usedPhotons.push_back(candRef);
00102 pi0Cands.push_back(candRef);
00103 }
00104
00105 int type = reco::Pi0::UnResolved;
00106
00107 math::XYZPoint pos = calculatePositionAtEcal(candRef->p4());
00108 math::XYZTLorentzVector p4 = calculateMomentumWRT(candRef->p4(),seedTrack_->vertex());
00109
00110 LogDebug("Pi0Algo") << "Compare original and calculated photon momentum and position ------------\n"
00111 << " The position at ecal : ("
00112 << pos.x() << ","
00113 << pos.y() << ","
00114 << pos.z() << ")\n"
00115 << " The original momentum : ("
00116 << candRef->p4().px() << ","
00117 << candRef->p4().py() << ","
00118 << candRef->p4().pz() << ","
00119 << candRef->p4().energy() << ")\n"
00120 << " The corrected momentum : ("
00121 << p4.px() << ","
00122 << p4.py() << ","
00123 << p4.pz() << ","
00124 << p4.energy() << ")\n";
00125
00126
00127
00128
00129 double minMass = 999.0;
00130 reco::PFCandidateRef pho2;
00131 if((nPhotons > 1) && (ip != photonCands.end())){
00132 for(reco::PFCandidateRefVector::const_iterator ip2 = ip+1;
00133 ip2 != photonCands.end(); ++ip2){
00134 reco::PFCandidateRef candRef2 = *ip2;
00135 if(binary_search(usedPhotons.begin(),usedPhotons.end(),candRef2)) continue;
00136 math::XYZTLorentzVector sum = p4 + calculateMomentumWRT(candRef2->p4(),seedTrack_->vertex());
00137 double massDiff = std::abs(sum.M()-PI0MASS);
00138 if(massDiff < minMass){
00139 minMass = massDiff;
00140 pho2 = candRef2;
00141 }
00142 }
00143 }
00144
00145 LogDebug("Pi0Algo") << "minMass of two photons : " << minMass << "\n";
00146
00147 if(pho2.isNull()){
00148 reco::Pi0 pi0(type,p4.energy(),pos,p4,pi0Cands);
00149 pi0Collection_.push_back(pi0);
00150 }
00151 else if(minMass < massRes_){
00152 usedPhotons.push_back(pho2);
00153 pi0Cands.push_back(pho2);
00154 math::XYZPoint pos2 = calculatePositionAtEcal(pho2->p4());
00155 math::XYZPoint avPos(0.5*(pos.x()+pos2.x()),0.5*(pos.y()+pos2.y()),0.5*(pos.z()+pos2.z()));
00156 math::XYZTLorentzVector sumP4 = p4 + calculateMomentumWRT(pho2->p4(),seedTrack_->vertex());
00157 type = reco::Pi0::Resolved;
00158 reco::Pi0 pi0(type,sumP4.energy(),avPos,sumP4,pi0Cands);
00159 pi0Collection_.push_back(pi0);
00160
00161 LogDebug("Pi0Algo") << "Found resolved photons -----------------------\n"
00162 << "pos : (" << pos.x() << "," << pos.y() << "," << pos.z() << ")\n"
00163 << "pos2 : (" << pos2.x() << "," << pos2.y() << "," << pos2.z() << ")\n"
00164 << "avPos : (" << avPos.x() << "," << avPos.y() << "," << avPos.z() << ")\n"
00165 << "sumP4 : (" << sumP4.px() << "," << sumP4.py() << "," << sumP4.pz() << "," << sumP4.energy() << ")\n";
00166
00167 }
00168
00169 pi0Cands.clear();
00170 }
00171
00172
00173
00174 photonCands.clear();
00175 usedPhotons.clear();
00176
00177 }
00178
00179
00180 math::XYZPoint Pi0Algo::calculatePositionAtEcal(const math::XYZTLorentzVector &momentum) const {
00181
00182
00183
00184
00185
00186 double phi = momentum.phi();
00187 double theta = momentum.theta();
00188
00189
00190
00191
00192
00193 math::XYZPoint pos(ecalEntrance_*std::cos(phi),ecalEntrance_*std::sin(phi),ecalEntrance_/std::tan(theta));
00194
00195 return pos;
00196 }
00197
00198
00199 math::XYZTLorentzVector Pi0Algo::calculateMomentumWRT(const math::XYZTLorentzVector &momentum, const math::XYZPoint &vertex) const {
00200
00201 math::XYZVector dir = calculatePositionAtEcal(momentum) - vertex;
00202 math::XYZVector pos = dir.unit() * momentum.energy();
00203
00204 math::XYZTLorentzVector p4(pos.x(),pos.y(),pos.z(),momentum.energy());
00205
00206 return p4;
00207 }