CMS 3D CMS Logo

IsolatedPixelTrackCandidateProducer.cc
Go to the documentation of this file.
1 #include <vector>
2 #include <memory>
3 #include <algorithm>
4 #include <cmath>
5 
6 // Class header file
9 // Framework
17 //
18 
19 // Math
20 #include "Math/GenVector/VectorUtil.h"
21 #include "Math/GenVector/PxPyPzE4D.h"
23 
27 
28 //magF
32 
33 //for ECAL geometry
39 
40 //#define DebugLog
41 
43  : tok_hlt_(consumes<trigger::TriggerFilterObjectWithRefs>(config.getParameter<edm::InputTag>("L1GTSeedLabel"))),
44  tok_l1_(consumes<l1extra::L1JetParticleCollection>(config.getParameter<edm::InputTag>("L1eTauJetsSource"))),
45  tok_vert_(consumes<reco::VertexCollection>(config.getParameter<edm::InputTag>("VertexLabel"))),
46  toks_pix_(
47  edm::vector_transform(config.getParameter<std::vector<edm::InputTag> >("PixelTracksSources"),
48  [this](edm::InputTag const& tag) { return consumes<reco::TrackCollection>(tag); })),
49  bfield_(config.getParameter<std::string>("MagFieldRecordName")),
50  prelimCone_(config.getParameter<double>("ExtrapolationConeSize")),
51  pixelIsolationConeSizeAtEC_(config.getParameter<double>("PixelIsolationConeSizeAtEC")),
52  vtxCutSeed_(config.getParameter<double>("MaxVtxDXYSeed")),
53  vtxCutIsol_(config.getParameter<double>("MaxVtxDXYIsol")),
54  tauAssocCone_(config.getParameter<double>("tauAssociationCone")),
55  tauUnbiasCone_(config.getParameter<double>("tauUnbiasCone")),
56  minPTrackValue_(config.getParameter<double>("minPTrack")),
57  maxPForIsolationValue_(config.getParameter<double>("maxPTrackForIsolation")),
58  ebEtaBoundary_(config.getParameter<double>("EBEtaBoundary")),
59  rEB_(-1),
60  zEE_(-1),
61  bfVal_(0) {
62  // Register the product
63  produces<reco::IsolatedPixelTrackCandidateCollection>();
64 }
65 
67 
70  std::vector<edm::InputTag> tracksrc = {edm::InputTag("hltPixelTracks")};
71  desc.add<edm::InputTag>("L1eTauJetsSource", edm::InputTag("hltCaloStage2Digis", "Tau"));
72  desc.add<double>("tauAssociationCone", 0.0);
73  desc.add<double>("tauUnbiasCone", 1.2);
74  desc.add<std::vector<edm::InputTag> >("PixelTracksSources", tracksrc);
75  desc.add<double>("ExtrapolationConeSize", 1.0);
76  desc.add<double>("PixelIsolationConeSizeAtEC", 40);
77  desc.add<edm::InputTag>("L1GTSeedLabel", edm::InputTag("hltL1sIsoTrack"));
78  desc.add<double>("MaxVtxDXYSeed", 101.0);
79  desc.add<double>("MaxVtxDXYIsol", 101.0);
80  desc.add<edm::InputTag>("VertexLabel", edm::InputTag("hltTrimmedPixelVertices"));
81  desc.add<std::string>("MagFieldRecordName", "VolumeBasedMagneticField");
82  desc.add<double>("minPTrack", 5.0);
83  desc.add<double>("maxPTrackForIsolation", 3.0);
84  desc.add<double>("EBEtaBoundary", 1.479);
85  descriptions.add("isolPixelTrackProd", desc);
86 }
87 
90  theEventSetup.get<CaloGeometryRecord>().get(pG);
91 
92  const double rad(dynamic_cast<const EcalBarrelGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal, EcalBarrel))
93  ->avgRadiusXYFrontFaceCenter());
94  const double zz(dynamic_cast<const EcalEndcapGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal, EcalEndcap))
95  ->avgAbsZFrontFaceCenter());
96 
97  rEB_ = rad;
98  zEE_ = zz;
99 
101  theEventSetup.get<IdealMagneticFieldRecord>().get(vbfField);
102  const VolumeBasedMagneticField* vbfCPtr = dynamic_cast<const VolumeBasedMagneticField*>(&(*vbfField));
103  GlobalVector BField = vbfCPtr->inTesla(GlobalPoint(0, 0, 0));
104  bfVal_ = BField.mag();
105 }
106 
108  auto trackCollection = std::make_unique<reco::IsolatedPixelTrackCandidateCollection>();
109 
110  //create vector of refs from input collections
111  std::vector<reco::TrackRef> pixelTrackRefs;
112 #ifdef DebugLog
113  edm::LogInfo("HcalIsoTrack") << "IsolatedPixelTrakCandidate: with" << toks_pix_.size()
114  << " candidates to start with\n";
115 #endif
116  for (unsigned int iPix = 0; iPix < toks_pix_.size(); iPix++) {
118  theEvent.getByToken(toks_pix_[iPix], iPixCol);
119  for (reco::TrackCollection::const_iterator pit = iPixCol->begin(); pit != iPixCol->end(); pit++) {
120  pixelTrackRefs.push_back(reco::TrackRef(iPixCol, pit - iPixCol->begin()));
121  }
122  }
123 
125  theEvent.getByToken(tok_l1_, l1eTauJets);
126 
128  theEvent.getByToken(tok_vert_, pVert);
129 
130  double drMaxL1Track_ = tauAssocCone_;
131 
132  int ntr = 0;
133  std::vector<seedAtEC> VecSeedsatEC;
134  //loop to select isolated tracks
135  for (unsigned iS = 0; iS < pixelTrackRefs.size(); iS++) {
136  bool vtxMatch = false;
137  //associate to vertex (in Z)
138  reco::VertexCollection::const_iterator vitSel;
139  double minDZ = 1000;
140  bool found(false);
141  for (reco::VertexCollection::const_iterator vit = pVert->begin(); vit != pVert->end(); vit++) {
142  if (std::abs(pixelTrackRefs[iS]->dz(vit->position())) < minDZ) {
143  minDZ = std::abs(pixelTrackRefs[iS]->dz(vit->position()));
144  vitSel = vit;
145  found = true;
146  }
147  }
148  //cut on dYX:
149  if (found) {
150  if (std::abs(pixelTrackRefs[iS]->dxy(vitSel->position())) < vtxCutSeed_)
151  vtxMatch = true;
152  } else {
153  vtxMatch = true;
154  }
155 
156  //check taujet matching
157  bool tmatch = false;
158  l1extra::L1JetParticleCollection::const_iterator selj;
159  for (l1extra::L1JetParticleCollection::const_iterator tj = l1eTauJets->begin(); tj != l1eTauJets->end(); tj++) {
160  if (reco::deltaR(pixelTrackRefs[iS]->momentum().eta(),
161  pixelTrackRefs[iS]->momentum().phi(),
162  tj->momentum().eta(),
163  tj->momentum().phi()) > drMaxL1Track_)
164  continue;
165  selj = tj;
166  tmatch = true;
167  } //loop over L1 tau
168 
169  //propagate seed track to ECAL surface:
170  std::pair<double, double> seedCooAtEC;
171  // in case vertex is found:
172  if (found)
173  seedCooAtEC = GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(),
174  pixelTrackRefs[iS]->phi(),
175  pixelTrackRefs[iS]->pt(),
176  pixelTrackRefs[iS]->charge(),
177  vitSel->z());
178  //in case vertex is not found:
179  else
180  seedCooAtEC = GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(),
181  pixelTrackRefs[iS]->phi(),
182  pixelTrackRefs[iS]->pt(),
183  pixelTrackRefs[iS]->charge(),
184  0);
185  seedAtEC seed(iS, (tmatch || vtxMatch), seedCooAtEC.first, seedCooAtEC.second);
186  VecSeedsatEC.push_back(seed);
187  }
188 #ifdef DebugLog
189  edm::LogInfo("HcalIsoTrack") << "IsolatedPixelTrakCandidate: " << VecSeedsatEC.size() << " seeds after propagation\n";
190 #endif
191 
192  for (unsigned int i = 0; i < VecSeedsatEC.size(); i++) {
193  unsigned int iSeed = VecSeedsatEC[i].index;
194  if (!VecSeedsatEC[i].ok)
195  continue;
196  if (pixelTrackRefs[iSeed]->p() < minPTrackValue_)
197  continue;
198  l1extra::L1JetParticleCollection::const_iterator selj;
199  for (l1extra::L1JetParticleCollection::const_iterator tj = l1eTauJets->begin(); tj != l1eTauJets->end(); tj++) {
200  if (reco::deltaR(pixelTrackRefs[iSeed]->momentum().eta(),
201  pixelTrackRefs[iSeed]->momentum().phi(),
202  tj->momentum().eta(),
203  tj->momentum().phi()) > drMaxL1Track_)
204  continue;
205  selj = tj;
206  } //loop over L1 tau
207  double maxP = 0;
208  double sumP = 0;
209  for (unsigned int j = 0; j < VecSeedsatEC.size(); j++) {
210  if (i == j)
211  continue;
212  unsigned int iSurr = VecSeedsatEC[j].index;
213  //define preliminary cone around seed track impact point from which tracks will be extrapolated:
214  if (reco::deltaR(pixelTrackRefs[iSeed]->eta(),
215  pixelTrackRefs[iSeed]->phi(),
216  pixelTrackRefs[iSurr]->eta(),
217  pixelTrackRefs[iSurr]->phi()) > prelimCone_)
218  continue;
219  double minDZ2(1000);
220  bool found(false);
221  reco::VertexCollection::const_iterator vitSel2;
222  for (reco::VertexCollection::const_iterator vit = pVert->begin(); vit != pVert->end(); vit++) {
223  if (std::abs(pixelTrackRefs[iSurr]->dz(vit->position())) < minDZ2) {
224  minDZ2 = std::abs(pixelTrackRefs[iSurr]->dz(vit->position()));
225  vitSel2 = vit;
226  found = true;
227  }
228  }
229  //cut ot dXY:
230  if (found && std::abs(pixelTrackRefs[iSurr]->dxy(vitSel2->position())) > vtxCutIsol_)
231  continue;
232  //calculate distance at ECAL surface and update isolation:
233  if (getDistInCM(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi, VecSeedsatEC[j].eta, VecSeedsatEC[j].phi) <
235  sumP += pixelTrackRefs[iSurr]->p();
236  if (pixelTrackRefs[iSurr]->p() > maxP)
237  maxP = pixelTrackRefs[iSurr]->p();
238  }
239  }
240  if (maxP < maxPForIsolationValue_) {
242  pixelTrackRefs[iSeed], l1extra::L1JetParticleRef(l1eTauJets, selj - l1eTauJets->begin()), maxP, sumP);
243  newCandidate.setEtaPhiEcal(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi);
244  trackCollection->push_back(newCandidate);
245  ntr++;
246  }
247  }
248  // put the product in the event
249  theEvent.put(std::move(trackCollection));
250 #ifdef DebugLog
251  edm::LogInfo("HcalIsoTrack") << "IsolatedPixelTrackCandidate: Final # of candiates " << ntr << "\n";
252 #endif
253 }
254 
255 double IsolatedPixelTrackCandidateProducer::getDistInCM(double eta1, double phi1, double eta2, double phi2) {
256  double Rec;
257  double theta1 = 2 * atan(exp(-eta1));
258  double theta2 = 2 * atan(exp(-eta2));
259  if (std::abs(eta1) < 1.479)
260  Rec = rEB_; //radius of ECAL barrel
261  else if (std::abs(eta1) > 1.479 && std::abs(eta1) < 7.0)
262  Rec = tan(theta1) * zEE_; //distance from IP to ECAL endcap
263  else
264  return 1000;
265 
266  //|vect| times tg of acos(scalar product)
267  double angle =
268  acos((sin(theta1) * sin(theta2) * (sin(phi1) * sin(phi2) + cos(phi1) * cos(phi2)) + cos(theta1) * cos(theta2)));
269  if (angle < M_PI_2)
270  return std::abs((Rec / sin(theta1)) * tan(angle));
271  else
272  return 1000;
273 }
274 
276  double etaIP, double phiIP, double pT, int charge, double vtxZ) {
277  double deltaPhi = 0;
278  double etaEC = 100;
279  double phiEC = 100;
280 
281  double Rcurv = 9999999;
282  if (bfVal_ != 0)
283  Rcurv = pT * 33.3 * 100 / (bfVal_ * 10); //r(m)=pT(GeV)*33.3/B(kG)
284 
285  double ecDist = zEE_; //distance to ECAL andcap from IP (cm), 317 - ecal (not preshower), preshower -300
286  double ecRad = rEB_; //radius of ECAL barrel (cm)
287  double theta = 2 * atan(exp(-etaIP));
288  double zNew = 0;
289  if (theta > M_PI_2)
290  theta = M_PI - theta;
291  if (std::abs(etaIP) < ebEtaBoundary_) {
292  if ((0.5 * ecRad / Rcurv) > 1) {
293  etaEC = 10000;
294  deltaPhi = 0;
295  } else {
296  deltaPhi = -charge * asin(0.5 * ecRad / Rcurv);
297  double alpha1 = 2 * asin(0.5 * ecRad / Rcurv);
298  double z = ecRad / tan(theta);
299  if (etaIP > 0)
300  zNew = z * (Rcurv * alpha1) / ecRad + vtxZ; //new z-coordinate of track
301  else
302  zNew = -z * (Rcurv * alpha1) / ecRad + vtxZ; //new z-coordinate of track
303  double zAbs = std::abs(zNew);
304  if (zAbs < ecDist) {
305  etaEC = -log(tan(0.5 * atan(ecRad / zAbs)));
306  deltaPhi = -charge * asin(0.5 * ecRad / Rcurv);
307  }
308  if (zAbs > ecDist) {
309  zAbs = (std::abs(etaIP) / etaIP) * ecDist;
310  double Zflight = std::abs(zAbs - vtxZ);
311  double alpha = (Zflight * ecRad) / (z * Rcurv);
312  double Rec = 2 * Rcurv * sin(alpha / 2);
313  deltaPhi = -charge * alpha / 2;
314  etaEC = -log(tan(0.5 * atan(Rec / ecDist)));
315  }
316  }
317  } else {
318  zNew = (std::abs(etaIP) / etaIP) * ecDist;
319  double Zflight = std::abs(zNew - vtxZ);
320  double Rvirt = std::abs(Zflight * tan(theta));
321  double Rec = 2 * Rcurv * sin(Rvirt / (2 * Rcurv));
322  deltaPhi = -(charge) * (Rvirt / (2 * Rcurv));
323  etaEC = -log(tan(0.5 * atan(Rec / ecDist)));
324  }
325 
326  if (zNew < 0)
327  etaEC = -etaEC;
328  phiEC = phiIP + deltaPhi;
329 
330  if (phiEC < -M_PI)
331  phiEC += M_2_PI;
332  if (phiEC > M_PI)
333  phiEC -= M_2_PI;
334 
335  std::pair<double, double> retVal(etaEC, phiEC);
336  return retVal;
337 }
std::pair< double, double > GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ)
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:49
float alpha
Definition: AMPTWrapper.h:95
const std::vector< edm::EDGetTokenT< reco::TrackCollection > > toks_pix_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
void beginRun(const edm::Run &, const edm::EventSetup &) override
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
GlobalVector inTesla(const GlobalPoint &g) const override
Field value ad specified global point, in Tesla.
const edm::EDGetTokenT< l1extra::L1JetParticleCollection > tok_l1_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
IsolatedPixelTrackCandidateProducer(const edm::ParameterSet &ps)
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
Geom::Theta< T > theta() const
#define M_PI_2
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
Definition: config.py:1
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
T mag() const
Definition: PV3DBase.h:67
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void setEtaPhiEcal(double eta, double phi)
eta, phi at ECAL surface
ParameterDescriptionBase * add(U const &iLabel, T const &value)
#define M_PI
constexpr auto deltaR(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:28
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const edm::EDGetTokenT< reco::VertexCollection > tok_vert_
fixed size matrix
HLT enums.
T get() const
Definition: EventSetup.h:71
double getDistInCM(double eta1, double phi1, double eta2, double phi2)
void produce(edm::Event &evt, const edm::EventSetup &es) override
def move(src, dest)
Definition: eostools.py:511
Definition: Run.h:45
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11