00001 #include <vector>
00002 #include <memory>
00003 #include <algorithm>
00004
00005
00006 #include "Calibration/HcalIsolatedTrackReco/interface/IsolatedPixelTrackCandidateProducer.h"
00007 #include "DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidateFwd.h"
00008
00009 #include "DataFormats/Common/interface/Handle.h"
00010 #include "FWCore/Framework/interface/ESHandle.h"
00011 #include "FWCore/Framework/interface/ESTransientHandle.h"
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013 #include "FWCore/Utilities/interface/Exception.h"
00014
00015 #include "DataFormats/Common/interface/TriggerResults.h"
00016
00017 #include "DataFormats/L1Trigger/interface/L1EmParticle.h"
00018 #include "DataFormats/L1Trigger/interface/L1JetParticleFwd.h"
00020
00021 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
00022
00023 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
00024 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
00025 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMapRecord.h"
00026
00027
00028 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMapFwd.h"
00029 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMap.h"
00030
00031
00032 #include "Math/GenVector/VectorUtil.h"
00033 #include "Math/GenVector/PxPyPzE4D.h"
00034 #include "DataFormats/Math/interface/deltaR.h"
00035
00036
00037 #include "DataFormats/VertexReco/interface/Vertex.h"
00038 #include "DataFormats/VertexReco/interface/VertexFwd.h"
00039
00040 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00041 #include "DetectorDescription/Core/interface/DDLogicalPart.h"
00042 #include "DetectorDescription/Core/interface/DDSolid.h"
00043
00044
00045 #include "MagneticField/Engine/interface/MagneticField.h"
00046 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00047 #include "MagneticField/VolumeBasedEngine/interface/VolumeBasedMagneticField.h"
00048
00049
00050 #include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h"
00051 #include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h"
00052 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00053 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00054 #include "Geometry/Records/interface/CaloGeometryRecord.h"
00055
00056
00057 IsolatedPixelTrackCandidateProducer::IsolatedPixelTrackCandidateProducer(const edm::ParameterSet& config){
00058
00059 l1eTauJetsSource_ = config.getParameter<edm::InputTag>("L1eTauJetsSource");
00060 tauAssocCone_ = config.getParameter<double>("tauAssociationCone");
00061 tauUnbiasCone_ = config.getParameter<double>("tauUnbiasCone");
00062 pixelTracksSources_ = config.getParameter<std::vector<edm::InputTag> >("PixelTracksSources");
00063 prelimCone_ = config.getParameter<double>("ExtrapolationConeSize");
00064 pixelIsolationConeSizeAtEC_ = config.getParameter<double>("PixelIsolationConeSizeAtEC");
00065 hltGTseedlabel_ = config.getParameter<edm::InputTag>("L1GTSeedLabel");
00066 vtxCutSeed_ = config.getParameter<double>("MaxVtxDXYSeed");
00067 vtxCutIsol_ = config.getParameter<double>("MaxVtxDXYIsol");
00068 vertexLabel_ = config.getParameter<edm::InputTag>("VertexLabel");
00069 bfield_ = config.getParameter<std::string>("MagFieldRecordName");
00070 minPTrackValue_ = config.getParameter<double>("minPTrack");
00071 maxPForIsolationValue_ = config.getParameter<double>("maxPTrackForIsolation");
00072 ebEtaBoundary_ = config.getParameter<double>("EBEtaBoundary");
00073 rEB_ = zEE_ = -1;
00074
00075
00076 produces< reco::IsolatedPixelTrackCandidateCollection >();
00077 }
00078
00079 IsolatedPixelTrackCandidateProducer::~IsolatedPixelTrackCandidateProducer() {
00080
00081 }
00082
00083 void IsolatedPixelTrackCandidateProducer::beginJob () {}
00084
00085 void IsolatedPixelTrackCandidateProducer::beginRun(edm::Run &run, const edm::EventSetup &theEventSetup)
00086 {
00087
00088 edm::ESHandle<CaloGeometry> pG;
00089 theEventSetup.get<CaloGeometryRecord>().get(pG);
00090
00091 const double rad (dynamic_cast<const EcalBarrelGeometry*>( pG->getSubdetectorGeometry(DetId::Ecal, EcalBarrel ))->avgRadiusXYFrontFaceCenter() ) ;
00092
00093 const double zz (dynamic_cast<const EcalEndcapGeometry*>( pG->getSubdetectorGeometry(DetId::Ecal, EcalEndcap ))->avgAbsZFrontFaceCenter() ) ;
00094
00095 rEB_=rad;
00096 zEE_=zz;
00097
00098 }
00099
00100 void IsolatedPixelTrackCandidateProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
00101
00102 reco::IsolatedPixelTrackCandidateCollection* trackCollection=new reco::IsolatedPixelTrackCandidateCollection;
00103
00104
00105 std::vector<reco::TrackRef> pixelTrackRefs;
00106
00107 for (unsigned int iPix=0; iPix<pixelTracksSources_.size(); iPix++)
00108 {
00109 edm::Handle<reco::TrackCollection> iPixCol;
00110 theEvent.getByLabel(pixelTracksSources_[iPix],iPixCol);
00111 for (reco::TrackCollection::const_iterator pit=iPixCol->begin(); pit!=iPixCol->end(); pit++)
00112 {
00113 pixelTrackRefs.push_back(reco::TrackRef(iPixCol,pit-iPixCol->begin()));
00114 }
00115 }
00116
00117 edm::Handle<l1extra::L1JetParticleCollection> l1eTauJets;
00118 theEvent.getByLabel(l1eTauJetsSource_,l1eTauJets);
00119
00120 edm::Handle<reco::VertexCollection> pVert;
00121 theEvent.getByLabel(vertexLabel_,pVert);
00122
00123 double ptTriggered = -10;
00124 double etaTriggered = -100;
00125 double phiTriggered = -100;
00126
00127 edm::Handle<trigger::TriggerFilterObjectWithRefs> l1trigobj;
00128 theEvent.getByLabel(hltGTseedlabel_, l1trigobj);
00129
00130 std::vector< edm::Ref<l1extra::L1JetParticleCollection> > l1tauobjref;
00131 std::vector< edm::Ref<l1extra::L1JetParticleCollection> > l1jetobjref;
00132 std::vector< edm::Ref<l1extra::L1JetParticleCollection> > l1forjetobjref;
00133
00134 l1trigobj->getObjects(trigger::TriggerL1TauJet, l1tauobjref);
00135 l1trigobj->getObjects(trigger::TriggerL1CenJet, l1jetobjref);
00136 l1trigobj->getObjects(trigger::TriggerL1ForJet, l1forjetobjref);
00137
00138 for (unsigned int p=0; p<l1tauobjref.size(); p++)
00139 {
00140 if (l1tauobjref[p]->pt()>ptTriggered)
00141 {
00142 ptTriggered = l1tauobjref[p]->pt();
00143 phiTriggered = l1tauobjref[p]->phi();
00144 etaTriggered = l1tauobjref[p]->eta();
00145 }
00146 }
00147 for (unsigned int p=0; p<l1jetobjref.size(); p++)
00148 {
00149 if (l1jetobjref[p]->pt()>ptTriggered)
00150 {
00151 ptTriggered = l1jetobjref[p]->pt();
00152 phiTriggered = l1jetobjref[p]->phi();
00153 etaTriggered = l1jetobjref[p]->eta();
00154 }
00155 }
00156 for (unsigned int p=0; p<l1forjetobjref.size(); p++)
00157 {
00158 if (l1forjetobjref[p]->pt()>ptTriggered)
00159 {
00160 ptTriggered=l1forjetobjref[p]->pt();
00161 phiTriggered=l1forjetobjref[p]->phi();
00162 etaTriggered=l1forjetobjref[p]->eta();
00163 }
00164 }
00165
00166 double minPTrack_ = minPTrackValue_;
00167 double drMaxL1Track_ = tauAssocCone_;
00168
00169 int ntr = 0;
00170
00171
00172 for (unsigned iSeed=0; iSeed<pixelTrackRefs.size(); iSeed++)
00173 {
00174 if(pixelTrackRefs[iSeed]->p()<minPTrack_) continue;
00175
00176 bool good = false;
00177 bool vtxMatch = false;
00178
00179
00180 reco::VertexCollection::const_iterator vitSel;
00181 double minDZ = 100;
00182 for (reco::VertexCollection::const_iterator vit=pVert->begin(); vit!=pVert->end(); vit++)
00183 {
00184 if (fabs(pixelTrackRefs[iSeed]->dz(vit->position()))<minDZ)
00185 {
00186 minDZ = fabs(pixelTrackRefs[iSeed]->dz(vit->position()));
00187 vitSel = vit;
00188 }
00189 }
00190
00191 if (minDZ!=100&&fabs(pixelTrackRefs[iSeed]->dxy(vitSel->position()))<vtxCutSeed_) vtxMatch=true;
00192 if (minDZ==100) vtxMatch=true;
00193
00194
00195 double R=deltaR(etaTriggered, phiTriggered, pixelTrackRefs[iSeed]->eta(), pixelTrackRefs[iSeed]->phi());
00196 if (R<tauUnbiasCone_) continue;
00197
00198
00199 bool tmatch=false;
00200 l1extra::L1JetParticleCollection::const_iterator selj;
00201 for (l1extra::L1JetParticleCollection::const_iterator tj=l1eTauJets->begin(); tj!=l1eTauJets->end(); tj++)
00202 {
00203 if(ROOT::Math::VectorUtil::DeltaR(pixelTrackRefs[iSeed]->momentum(),tj->momentum()) > drMaxL1Track_) continue;
00204 selj = tj;
00205 tmatch = true;
00206 }
00207
00208
00209 std::pair<double,double> seedCooAtEC;
00210
00211 if (minDZ!=100) seedCooAtEC=GetEtaPhiAtEcal(theEventSetup, pixelTrackRefs[iSeed]->eta(), pixelTrackRefs[iSeed]->phi(), pixelTrackRefs[iSeed]->pt(), pixelTrackRefs[iSeed]->charge(), vitSel->z());
00212
00213 else seedCooAtEC=GetEtaPhiAtEcal(theEventSetup, pixelTrackRefs[iSeed]->eta(), pixelTrackRefs[iSeed]->phi(), pixelTrackRefs[iSeed]->pt(), pixelTrackRefs[iSeed]->charge(), 0);
00214
00215
00216 double maxP = 0;
00217 double sumP = 0;
00218 for (unsigned iSurr=0; iSurr<pixelTrackRefs.size(); iSurr++)
00219 {
00220 if(iSeed==iSurr) continue;
00221
00222 if (deltaR(seedCooAtEC.first, seedCooAtEC.second, pixelTrackRefs[iSurr]->eta(), pixelTrackRefs[iSurr]->phi())>prelimCone_) continue;
00223
00224 double minDZ2=100;
00225 reco::VertexCollection::const_iterator vitSel2;
00226 for (reco::VertexCollection::const_iterator vit=pVert->begin(); vit!=pVert->end(); vit++)
00227 {
00228 if (fabs(pixelTrackRefs[iSurr]->dz(vit->position()))<minDZ2)
00229 {
00230 minDZ2 = fabs(pixelTrackRefs[iSurr]->dz(vit->position()));
00231 vitSel2 = vit;
00232 }
00233 }
00234
00235 if (minDZ2!=100&&fabs(pixelTrackRefs[iSurr]->dxy(vitSel2->position()))>vtxCutIsol_) continue;
00236
00237 std::pair<double,double> cooAtEC;
00238
00239 if (minDZ2!=100) cooAtEC=GetEtaPhiAtEcal(theEventSetup, pixelTrackRefs[iSurr]->eta(), pixelTrackRefs[iSurr]->phi(), pixelTrackRefs[iSurr]->pt(), pixelTrackRefs[iSurr]->charge(), vitSel2->z());
00240
00241 else cooAtEC=GetEtaPhiAtEcal(theEventSetup, pixelTrackRefs[iSurr]->eta(), pixelTrackRefs[iSurr]->phi(), pixelTrackRefs[iSurr]->pt(), pixelTrackRefs[iSurr]->charge(), 0);
00242
00243
00244 if (getDistInCM(seedCooAtEC.first, seedCooAtEC.second, cooAtEC.first, cooAtEC.second)<pixelIsolationConeSizeAtEC_)
00245 {
00246 sumP+=pixelTrackRefs[iSurr]->p();
00247 if(pixelTrackRefs[iSurr]->p()>maxP) maxP=pixelTrackRefs[iSurr]->p();
00248 }
00249 }
00250
00251 if (tmatch||vtxMatch) good=true;
00252
00253 if (good&&maxP<maxPForIsolationValue_)
00254 {
00255 reco::IsolatedPixelTrackCandidate newCandidate(pixelTrackRefs[iSeed], l1extra::L1JetParticleRef(l1eTauJets,selj-l1eTauJets->begin()), maxP, sumP);
00256 trackCollection->push_back(newCandidate);
00257 ntr++;
00258 }
00259 }
00260
00261
00262 std::auto_ptr< reco::IsolatedPixelTrackCandidateCollection > outCollection(trackCollection);
00263 theEvent.put(outCollection);
00264
00265 }
00266
00267
00268 double IsolatedPixelTrackCandidateProducer::getDistInCM(double eta1, double phi1, double eta2, double phi2)
00269 {
00270 double Rec;
00271 double theta1=2*atan(exp(-eta1));
00272 double theta2=2*atan(exp(-eta2));
00273 if (fabs(eta1)<1.479) Rec=129;
00274 else if (fabs(eta1)>1.479&&fabs(eta1)<7.0) Rec=tan(theta1)*317;
00275 else return 1000;
00276
00277
00278 double angle=acos((sin(theta1)*sin(theta2)*(sin(phi1)*sin(phi2)+cos(phi1)*cos(phi2))+cos(theta1)*cos(theta2)));
00279 if (angle<acos(-1)/2) return fabs((Rec/sin(theta1))*tan(angle));
00280 else return 1000;
00281 }
00282
00283
00284 std::pair<double,double>
00285 IsolatedPixelTrackCandidateProducer::GetEtaPhiAtEcal(const edm::EventSetup& iSetup, double etaIP, double phiIP, double pT, int charge, double vtxZ)
00286 {
00287 edm::ESHandle<MagneticField> vbfField;
00288 iSetup.get<IdealMagneticFieldRecord>().get(vbfField);
00289 const VolumeBasedMagneticField* vbfCPtr = dynamic_cast<const VolumeBasedMagneticField*>(&(*vbfField));
00290 GlobalVector BField=vbfCPtr->inTesla(GlobalPoint(0,0,0));
00291
00292
00293
00294 double bfVal=BField.mag();
00295
00296 double deltaPhi=0;
00297 double etaEC = 100;
00298 double phiEC = 100;
00299
00300 double Rcurv = 9999999;
00301 if (bfVal!=0) Rcurv=pT*33.3*100/(bfVal*10);
00302
00303 double ecDist = zEE_;
00304 double ecRad = rEB_;
00305 double theta=2*atan(exp(-etaIP));
00306 double zNew=0;
00307 if (theta>0.5*acos(-1)) theta=acos(-1)-theta;
00308 if (fabs(etaIP)<ebEtaBoundary_)
00309 {
00310 if ((0.5*ecRad/Rcurv)>1)
00311 {
00312 etaEC=10000;
00313 deltaPhi=0;
00314 }
00315 else
00316 {
00317 deltaPhi =-charge*asin(0.5*ecRad/Rcurv);
00318 double alpha1 = 2*asin(0.5*ecRad/Rcurv);
00319 double z = ecRad/tan(theta);
00320 if (etaIP>0) zNew = z*(Rcurv*alpha1)/ecRad+vtxZ;
00321 else zNew =-z*(Rcurv*alpha1)/ecRad+vtxZ;
00322 double zAbs=fabs(zNew);
00323 if (zAbs<ecDist)
00324 {
00325 etaEC = -log(tan(0.5*atan(ecRad/zAbs)));
00326 deltaPhi = -charge*asin(0.5*ecRad/Rcurv);
00327 }
00328 if (zAbs>ecDist)
00329 {
00330 zAbs = (fabs(etaIP)/etaIP)*ecDist;
00331 double Zflight = fabs(zAbs-vtxZ);
00332 double alpha = (Zflight*ecRad)/(z*Rcurv);
00333 double Rec = 2*Rcurv*sin(alpha/2);
00334 deltaPhi =-charge*alpha/2;
00335 etaEC =-log(tan(0.5*atan(Rec/ecDist)));
00336 }
00337 }
00338 }
00339 else
00340 {
00341 zNew = (fabs(etaIP)/etaIP)*ecDist;
00342 double Zflight = fabs(zNew-vtxZ);
00343 double Rvirt = fabs(Zflight*tan(theta));
00344 double Rec = 2*Rcurv*sin(Rvirt/(2*Rcurv));
00345 deltaPhi =-(charge)*(Rvirt/(2*Rcurv));
00346 etaEC =-log(tan(0.5*atan(Rec/ecDist)));
00347 }
00348
00349 if (zNew<0) etaEC=-etaEC;
00350 phiEC = phiIP+deltaPhi;
00351
00352 if (phiEC<-acos(-1)) phiEC = 2*acos(-1)+phiEC;
00353 if (phiEC>acos(-1)) phiEC =-2*acos(-1)+phiEC;
00354
00355 std::pair<double,double> retVal(etaEC,phiEC);
00356 return retVal;
00357 }
00358
00359