Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:59:08

0001 /* \class IsolatedPixelTrackCandidateL1TProducer
0002  *
0003  *  
0004  */
0005 
0006 #include <vector>
0007 #include <memory>
0008 #include <algorithm>
0009 #include <cmath>
0010 
0011 #include "DataFormats/Common/interface/Handle.h"
0012 #include "DataFormats/Common/interface/Ref.h"
0013 #include "DataFormats/DetId/interface/DetId.h"
0014 #include "DataFormats/TrackReco/interface/Track.h"
0015 #include "DataFormats/HcalIsolatedTrack/interface/IsolatedPixelTrackCandidate.h"
0016 #include "DataFormats/Common/interface/TriggerResults.h"
0017 // L1Extra
0018 #include "DataFormats/L1Trigger/interface/L1EmParticle.h"
0019 #include "DataFormats/L1Trigger/interface/L1JetParticle.h"
0020 // l1t
0021 #include "DataFormats/L1Trigger/interface/Jet.h"
0022 #include "DataFormats/L1Trigger/interface/Tau.h"
0023 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
0024 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0025 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMapRecord.h"
0026 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMapFwd.h"
0027 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerObjectMap.h"
0028 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
0029 //vertices
0030 #include "DataFormats/VertexReco/interface/Vertex.h"
0031 #include "DataFormats/VertexReco/interface/VertexFwd.h"
0032 
0033 // Framework
0034 #include "FWCore/Framework/interface/Frameworkfwd.h"
0035 #include "FWCore/Framework/interface/stream/EDProducer.h"
0036 #include "FWCore/Framework/interface/Event.h"
0037 #include "FWCore/Framework/interface/EventSetup.h"
0038 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0039 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0040 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0041 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0042 #include "FWCore/Utilities/interface/Exception.h"
0043 #include "FWCore/Utilities/interface/transform.h"
0044 
0045 // Math
0046 #include "Math/GenVector/VectorUtil.h"
0047 #include "Math/GenVector/PxPyPzE4D.h"
0048 #include "DataFormats/Math/interface/deltaR.h"
0049 
0050 //magF
0051 #include "MagneticField/VolumeBasedEngine/interface/VolumeBasedMagneticField.h"
0052 #include "MagneticField/Engine/interface/MagneticField.h"
0053 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0054 
0055 //for ECAL geometry
0056 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0057 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0058 #include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h"
0059 #include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h"
0060 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
0061 
0062 //#define EDM_ML_DEBUG
0063 
0064 class IsolatedPixelTrackCandidateL1TProducer : public edm::stream::EDProducer<> {
0065 public:
0066   IsolatedPixelTrackCandidateL1TProducer(const edm::ParameterSet& ps);
0067   ~IsolatedPixelTrackCandidateL1TProducer() override;
0068 
0069   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0070 
0071   void beginRun(const edm::Run&, const edm::EventSetup&) override;
0072   void produce(edm::Event& evt, const edm::EventSetup& es) override;
0073 
0074   double getDistInCM(double eta1, double phi1, double eta2, double phi2);
0075   std::pair<double, double> GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ);
0076 
0077 private:
0078   struct seedAtEC {
0079     seedAtEC(unsigned int i, bool f, double et, double fi) : index(i), ok(f), eta(et), phi(fi) {}
0080     unsigned int index;
0081     bool ok;
0082     double eta, phi;
0083   };
0084 
0085   const edm::EDGetTokenT<trigger::TriggerFilterObjectWithRefs> tok_hlt_;
0086   const edm::EDGetTokenT<l1t::TauBxCollection> tok_l1_;
0087   const edm::EDGetTokenT<reco::VertexCollection> tok_vert_;
0088   const std::vector<edm::EDGetTokenT<reco::TrackCollection> > toks_pix_;
0089   const edm::ESGetToken<MagneticField, IdealMagneticFieldRecord> tok_bFieldH_;
0090   const edm::ESGetToken<CaloGeometry, CaloGeometryRecord> tok_geom_;
0091 
0092   const std::string bfield_;
0093   const double prelimCone_;
0094   const double pixelIsolationConeSizeAtEC_;
0095   const double vtxCutSeed_;
0096   const double vtxCutIsol_;
0097   const double tauAssocCone_;
0098   const double tauUnbiasCone_;
0099   const double minPTrackValue_;
0100   const double maxPForIsolationValue_;
0101   const double ebEtaBoundary_;
0102 
0103   // these are read from the EventSetup, cannot be const
0104   double rEB_;
0105   double zEE_;
0106   double bfVal_;
0107 };
0108 
0109 IsolatedPixelTrackCandidateL1TProducer::IsolatedPixelTrackCandidateL1TProducer(const edm::ParameterSet& config)
0110     : tok_hlt_(consumes<trigger::TriggerFilterObjectWithRefs>(config.getParameter<edm::InputTag>("L1GTSeedLabel"))),
0111       tok_l1_(consumes<l1t::TauBxCollection>(config.getParameter<edm::InputTag>("L1eTauJetsSource"))),
0112       tok_vert_(consumes<reco::VertexCollection>(config.getParameter<edm::InputTag>("VertexLabel"))),
0113       toks_pix_(
0114           edm::vector_transform(config.getParameter<std::vector<edm::InputTag> >("PixelTracksSources"),
0115                                 [this](edm::InputTag const& tag) { return consumes<reco::TrackCollection>(tag); })),
0116       tok_bFieldH_(esConsumes<MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun>()),
0117       tok_geom_(esConsumes<CaloGeometry, CaloGeometryRecord, edm::Transition::BeginRun>()),
0118       bfield_(config.getParameter<std::string>("MagFieldRecordName")),
0119       prelimCone_(config.getParameter<double>("ExtrapolationConeSize")),
0120       pixelIsolationConeSizeAtEC_(config.getParameter<double>("PixelIsolationConeSizeAtEC")),
0121       vtxCutSeed_(config.getParameter<double>("MaxVtxDXYSeed")),
0122       vtxCutIsol_(config.getParameter<double>("MaxVtxDXYIsol")),
0123       tauAssocCone_(config.getParameter<double>("tauAssociationCone")),
0124       tauUnbiasCone_(config.getParameter<double>("tauUnbiasCone")),
0125       minPTrackValue_(config.getParameter<double>("minPTrack")),
0126       maxPForIsolationValue_(config.getParameter<double>("maxPTrackForIsolation")),
0127       ebEtaBoundary_(config.getParameter<double>("EBEtaBoundary")),
0128       rEB_(-1),
0129       zEE_(-1),
0130       bfVal_(0) {
0131   // Register the product
0132   produces<reco::IsolatedPixelTrackCandidateCollection>();
0133 }
0134 
0135 IsolatedPixelTrackCandidateL1TProducer::~IsolatedPixelTrackCandidateL1TProducer() {}
0136 
0137 void IsolatedPixelTrackCandidateL1TProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0138   edm::ParameterSetDescription desc;
0139   std::vector<edm::InputTag> tracksrc = {edm::InputTag("hltPixelTracks")};
0140   desc.add<edm::InputTag>("L1eTauJetsSource", edm::InputTag("hltGtStage2Digis", "Tau"));
0141   desc.add<double>("tauAssociationCone", 0.0);
0142   desc.add<double>("tauUnbiasCone", 1.2);
0143   desc.add<std::vector<edm::InputTag> >("PixelTracksSources", tracksrc);
0144   desc.add<double>("ExtrapolationConeSize", 1.0);
0145   desc.add<double>("PixelIsolationConeSizeAtEC", 40);
0146   desc.add<edm::InputTag>("L1GTSeedLabel", edm::InputTag("hltL1sV0SingleJet60"));
0147   desc.add<double>("MaxVtxDXYSeed", 101.0);
0148   desc.add<double>("MaxVtxDXYIsol", 101.0);
0149   desc.add<edm::InputTag>("VertexLabel", edm::InputTag("hltTrimmedPixelVertices"));
0150   desc.add<std::string>("MagFieldRecordName", "VolumeBasedMagneticField");
0151   desc.add<double>("minPTrack", 5.0);
0152   desc.add<double>("maxPTrackForIsolation", 3.0);
0153   desc.add<double>("EBEtaBoundary", 1.479);
0154   descriptions.add("isolPixelTrackProdL1T", desc);
0155 }
0156 
0157 void IsolatedPixelTrackCandidateL1TProducer::beginRun(const edm::Run& run, const edm::EventSetup& theEventSetup) {
0158   const CaloGeometry* pG = &theEventSetup.getData(tok_geom_);
0159 
0160   const double rad(dynamic_cast<const EcalBarrelGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal, EcalBarrel))
0161                        ->avgRadiusXYFrontFaceCenter());
0162   const double zz(dynamic_cast<const EcalEndcapGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal, EcalEndcap))
0163                       ->avgAbsZFrontFaceCenter());
0164 
0165   rEB_ = rad;
0166   zEE_ = zz;
0167 
0168   const MagneticField* vbfField = &theEventSetup.getData(tok_bFieldH_);
0169   const VolumeBasedMagneticField* vbfCPtr = dynamic_cast<const VolumeBasedMagneticField*>(&(*vbfField));
0170   GlobalVector BField = vbfCPtr->inTesla(GlobalPoint(0, 0, 0));
0171   bfVal_ = BField.mag();
0172 #ifdef EDM_ML_DEBUG
0173   edm::LogVerbatim("IsoTrack") << "rEB " << rEB_ << " zEE " << zEE_ << " B " << bfVal_;
0174 #endif
0175 }
0176 
0177 void IsolatedPixelTrackCandidateL1TProducer::produce(edm::Event& theEvent, const edm::EventSetup& theEventSetup) {
0178   auto trackCollection = std::make_unique<reco::IsolatedPixelTrackCandidateCollection>();
0179 
0180   //create vector of refs from input collections
0181   std::vector<reco::TrackRef> pixelTrackRefs;
0182 
0183   for (unsigned int iPix = 0; iPix < toks_pix_.size(); iPix++) {
0184     const edm::Handle<reco::TrackCollection>& iPixCol = theEvent.getHandle(toks_pix_[iPix]);
0185     for (reco::TrackCollection::const_iterator pit = iPixCol->begin(); pit != iPixCol->end(); pit++) {
0186       pixelTrackRefs.push_back(reco::TrackRef(iPixCol, pit - iPixCol->begin()));
0187     }
0188   }
0189 
0190   const edm::Handle<l1t::TauBxCollection>& l1eTauJets = theEvent.getHandle(tok_l1_);
0191 
0192   const edm::Handle<reco::VertexCollection>& pVert = theEvent.getHandle(tok_vert_);
0193 
0194   double ptTriggered = -10;
0195   double etaTriggered = -100;
0196   double phiTriggered = -100;
0197 
0198   const edm::Handle<trigger::TriggerFilterObjectWithRefs>& l1trigobj = theEvent.getHandle(tok_hlt_);
0199 
0200   std::vector<edm::Ref<l1t::TauBxCollection> > l1tauobjref;
0201   std::vector<edm::Ref<l1t::JetBxCollection> > l1jetobjref;
0202 
0203   //  l1trigobj->getObjects(trigger::TriggerTau, l1tauobjref);
0204   l1trigobj->getObjects(trigger::TriggerL1Tau, l1tauobjref);
0205   //  l1trigobj->getObjects(trigger::TriggerJet, l1jetobjref);
0206   l1trigobj->getObjects(trigger::TriggerL1Jet, l1jetobjref);
0207 
0208   for (const auto& p : l1tauobjref) {
0209     if (p->pt() > ptTriggered) {
0210       ptTriggered = p->pt();
0211       phiTriggered = p->phi();
0212       etaTriggered = p->eta();
0213     }
0214   }
0215   for (const auto& p : l1jetobjref) {
0216     if (p->pt() > ptTriggered) {
0217       ptTriggered = p->pt();
0218       phiTriggered = p->phi();
0219       etaTriggered = p->eta();
0220     }
0221   }
0222 #ifdef EDM_ML_DEBUG
0223   edm::LogVerbatim("IsoTrack") << "Sizes " << l1tauobjref.size() << ":" << l1jetobjref.size() << " Trig " << ptTriggered
0224                                << ":" << etaTriggered << ":" << phiTriggered;
0225 #endif
0226   double drMaxL1Track_ = tauAssocCone_;
0227 #ifdef EDM_ML_DEBUG
0228   int ntr = 0;
0229 #endif
0230   std::vector<seedAtEC> VecSeedsatEC;
0231   //loop to select isolated tracks
0232   for (unsigned iS = 0; iS < pixelTrackRefs.size(); iS++) {
0233     bool vtxMatch = false;
0234     //associate to vertex (in Z)
0235     reco::VertexCollection::const_iterator vitSel;
0236     double minDZ = 1000;
0237     bool found(false);
0238     for (reco::VertexCollection::const_iterator vit = pVert->begin(); vit != pVert->end(); vit++) {
0239       if (std::abs(pixelTrackRefs[iS]->dz(vit->position())) < minDZ) {
0240         minDZ = std::abs(pixelTrackRefs[iS]->dz(vit->position()));
0241         vitSel = vit;
0242         found = true;
0243       }
0244     }
0245     //cut on dYX:
0246     if (found) {
0247       if (std::abs(pixelTrackRefs[iS]->dxy(vitSel->position())) < vtxCutSeed_)
0248         vtxMatch = true;
0249     } else {
0250       vtxMatch = true;
0251     }
0252 #ifdef EDM_ML_DEBUG
0253     edm::LogVerbatim("IsoTrack") << "minZD " << minDZ << " Found " << found << ":" << vtxMatch;
0254 #endif
0255     //select tracks not matched to triggered L1 jet
0256     double R = reco::deltaR(etaTriggered, phiTriggered, pixelTrackRefs[iS]->eta(), pixelTrackRefs[iS]->phi());
0257 #ifdef EDM_ML_DEBUG
0258     edm::LogVerbatim("IsoTrack") << "Distance to L1 " << R << ":" << tauUnbiasCone_ << " Result "
0259                                  << (R < tauUnbiasCone_);
0260 #endif
0261     if (R < tauUnbiasCone_)
0262       continue;
0263 
0264     //check taujet matching
0265     bool tmatch = false;
0266     l1t::TauBxCollection::const_iterator selj;
0267     for (l1t::TauBxCollection::const_iterator tj = l1eTauJets->begin(); tj != l1eTauJets->end(); tj++) {
0268       if (reco::deltaR(pixelTrackRefs[iS]->momentum().eta(),
0269                        pixelTrackRefs[iS]->momentum().phi(),
0270                        tj->momentum().eta(),
0271                        tj->momentum().phi()) > drMaxL1Track_)
0272         continue;
0273       selj = tj;
0274       tmatch = true;
0275     }  //loop over L1 tau
0276 #ifdef EDM_ML_DEBUG
0277     edm::LogVerbatim("IsoTrack") << "tMatch " << tmatch;
0278 #endif
0279     //propagate seed track to ECAL surface:
0280     std::pair<double, double> seedCooAtEC;
0281     // in case vertex is found:
0282     if (found)
0283       seedCooAtEC = GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(),
0284                                     pixelTrackRefs[iS]->phi(),
0285                                     pixelTrackRefs[iS]->pt(),
0286                                     pixelTrackRefs[iS]->charge(),
0287                                     vitSel->z());
0288     //in case vertex is not found:
0289     else
0290       seedCooAtEC = GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(),
0291                                     pixelTrackRefs[iS]->phi(),
0292                                     pixelTrackRefs[iS]->pt(),
0293                                     pixelTrackRefs[iS]->charge(),
0294                                     0);
0295     seedAtEC seed(iS, (tmatch || vtxMatch), seedCooAtEC.first, seedCooAtEC.second);
0296     VecSeedsatEC.push_back(seed);
0297 #ifdef EDM_ML_DEBUG
0298     edm::LogVerbatim("IsoTrack") << "Seed " << seedCooAtEC.first << seedCooAtEC.second;
0299 #endif
0300   }
0301   for (unsigned int i = 0; i < VecSeedsatEC.size(); i++) {
0302     unsigned int iSeed = VecSeedsatEC[i].index;
0303     if (!VecSeedsatEC[i].ok)
0304       continue;
0305     if (pixelTrackRefs[iSeed]->p() < minPTrackValue_)
0306       continue;
0307     l1t::TauBxCollection::const_iterator selj;
0308     for (l1t::TauBxCollection::const_iterator tj = l1eTauJets->begin(); tj != l1eTauJets->end(); tj++) {
0309       if (reco::deltaR(pixelTrackRefs[iSeed]->momentum().eta(),
0310                        pixelTrackRefs[iSeed]->momentum().phi(),
0311                        tj->momentum().eta(),
0312                        tj->momentum().phi()) > drMaxL1Track_)
0313         continue;
0314       selj = tj;
0315     }  //loop over L1 tau
0316     double maxP = 0;
0317     double sumP = 0;
0318     for (unsigned int j = 0; j < VecSeedsatEC.size(); j++) {
0319       if (i == j)
0320         continue;
0321       unsigned int iSurr = VecSeedsatEC[j].index;
0322       //define preliminary cone around seed track impact point from which tracks will be extrapolated:
0323       if (reco::deltaR(pixelTrackRefs[iSeed]->eta(),
0324                        pixelTrackRefs[iSeed]->phi(),
0325                        pixelTrackRefs[iSurr]->eta(),
0326                        pixelTrackRefs[iSurr]->phi()) > prelimCone_)
0327         continue;
0328       double minDZ2(1000);
0329       bool found(false);
0330       reco::VertexCollection::const_iterator vitSel2;
0331       for (reco::VertexCollection::const_iterator vit = pVert->begin(); vit != pVert->end(); vit++) {
0332         if (std::abs(pixelTrackRefs[iSurr]->dz(vit->position())) < minDZ2) {
0333           minDZ2 = std::abs(pixelTrackRefs[iSurr]->dz(vit->position()));
0334           vitSel2 = vit;
0335           found = true;
0336         }
0337       }
0338       //cut ot dXY:
0339       if (found && std::abs(pixelTrackRefs[iSurr]->dxy(vitSel2->position())) > vtxCutIsol_)
0340         continue;
0341       //calculate distance at ECAL surface and update isolation:
0342       if (getDistInCM(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi, VecSeedsatEC[j].eta, VecSeedsatEC[j].phi) <
0343           pixelIsolationConeSizeAtEC_) {
0344         sumP += pixelTrackRefs[iSurr]->p();
0345         if (pixelTrackRefs[iSurr]->p() > maxP)
0346           maxP = pixelTrackRefs[iSurr]->p();
0347       }
0348     }
0349     if (maxP < maxPForIsolationValue_) {
0350       reco::IsolatedPixelTrackCandidate newCandidate(
0351           pixelTrackRefs[iSeed], l1t::TauRef(l1eTauJets, selj - l1eTauJets->begin()), maxP, sumP);
0352       newCandidate.setEtaPhiEcal(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi);
0353       trackCollection->push_back(newCandidate);
0354 #ifdef EDM_ML_DEBUG
0355       ntr++;
0356 #endif
0357     }
0358   }
0359 #ifdef EDM_ML_DEBUG
0360   edm::LogVerbatim("IsoTrack") << "Number of Isolated Track " << ntr;
0361 #endif
0362   // put the product in the event
0363   theEvent.put(std::move(trackCollection));
0364 }
0365 
0366 double IsolatedPixelTrackCandidateL1TProducer::getDistInCM(double eta1, double phi1, double eta2, double phi2) {
0367   double Rec;
0368   double theta1 = 2 * atan(exp(-eta1));
0369   double theta2 = 2 * atan(exp(-eta2));
0370   if (std::abs(eta1) < 1.479)
0371     Rec = rEB_;  //radius of ECAL barrel
0372   else if (std::abs(eta1) > 1.479 && std::abs(eta1) < 7.0)
0373     Rec = tan(theta1) * zEE_;  //distance from IP to ECAL endcap
0374   else
0375     return 1000;
0376 
0377   //|vect| times tg of acos(scalar product)
0378   double angle =
0379       acos((sin(theta1) * sin(theta2) * (sin(phi1) * sin(phi2) + cos(phi1) * cos(phi2)) + cos(theta1) * cos(theta2)));
0380   if (angle < M_PI_2)
0381     return std::abs((Rec / sin(theta1)) * tan(angle));
0382   else
0383     return 1000;
0384 }
0385 
0386 std::pair<double, double> IsolatedPixelTrackCandidateL1TProducer::GetEtaPhiAtEcal(
0387     double etaIP, double phiIP, double pT, int charge, double vtxZ) {
0388   double deltaPhi = 0;
0389   double etaEC = 100;
0390   double phiEC = 100;
0391 
0392   double Rcurv = 9999999;
0393   if (bfVal_ != 0)
0394     Rcurv = pT * 33.3 * 100 / (bfVal_ * 10);  //r(m)=pT(GeV)*33.3/B(kG)
0395 
0396   double ecDist = zEE_;  //distance to ECAL andcap from IP (cm), 317 - ecal (not preshower), preshower -300
0397   double ecRad = rEB_;   //radius of ECAL barrel (cm)
0398   double theta = 2 * atan(exp(-etaIP));
0399   double zNew = 0;
0400   if (theta > M_PI_2)
0401     theta = M_PI - theta;
0402   if (std::abs(etaIP) < ebEtaBoundary_) {
0403     if ((0.5 * ecRad / Rcurv) > 1) {
0404       etaEC = 10000;
0405       deltaPhi = 0;
0406     } else {
0407       deltaPhi = -charge * asin(0.5 * ecRad / Rcurv);
0408       double alpha1 = 2 * asin(0.5 * ecRad / Rcurv);
0409       double z = ecRad / tan(theta);
0410       if (etaIP > 0)
0411         zNew = z * (Rcurv * alpha1) / ecRad + vtxZ;  //new z-coordinate of track
0412       else
0413         zNew = -z * (Rcurv * alpha1) / ecRad + vtxZ;  //new z-coordinate of track
0414       double zAbs = std::abs(zNew);
0415       if (zAbs < ecDist) {
0416         etaEC = -log(tan(0.5 * atan(ecRad / zAbs)));
0417         deltaPhi = -charge * asin(0.5 * ecRad / Rcurv);
0418       }
0419       if (zAbs > ecDist) {
0420         zAbs = (std::abs(etaIP) / etaIP) * ecDist;
0421         double Zflight = std::abs(zAbs - vtxZ);
0422         double alpha = (Zflight * ecRad) / (z * Rcurv);
0423         double Rec = 2 * Rcurv * sin(alpha / 2);
0424         deltaPhi = -charge * alpha / 2;
0425         etaEC = -log(tan(0.5 * atan(Rec / ecDist)));
0426       }
0427     }
0428   } else {
0429     zNew = (std::abs(etaIP) / etaIP) * ecDist;
0430     double Zflight = std::abs(zNew - vtxZ);
0431     double Rvirt = std::abs(Zflight * tan(theta));
0432     double Rec = 2 * Rcurv * sin(Rvirt / (2 * Rcurv));
0433     deltaPhi = -(charge) * (Rvirt / (2 * Rcurv));
0434     etaEC = -log(tan(0.5 * atan(Rec / ecDist)));
0435   }
0436 
0437   if (zNew < 0)
0438     etaEC = -etaEC;
0439   phiEC = phiIP + deltaPhi;
0440 
0441   if (phiEC < -M_PI)
0442     phiEC += M_2_PI;
0443   if (phiEC > M_PI)
0444     phiEC -= M_2_PI;
0445 
0446   std::pair<double, double> retVal(etaEC, phiEC);
0447   return retVal;
0448 }
0449 #include "FWCore/PluginManager/interface/ModuleDef.h"
0450 #include "FWCore/Framework/interface/MakerMacros.h"
0451 
0452 DEFINE_FWK_MODULE(IsolatedPixelTrackCandidateL1TProducer);