CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
IsolatedPixelTrackCandidateL1TProducer.cc
Go to the documentation of this file.
1 /* \class IsolatedPixelTrackCandidateL1TProducer
2  *
3  *
4  */
5 
6 #include <vector>
7 #include <memory>
8 #include <algorithm>
9 #include <cmath>
10 
17 // L1Extra
20 // l1t
29 //vertices
32 
33 // Framework
44 
45 // Math
46 #include "Math/GenVector/VectorUtil.h"
47 #include "Math/GenVector/PxPyPzE4D.h"
49 
50 //magF
54 
55 //for ECAL geometry
61 
62 //#define EDM_ML_DEBUG
63 
65 public:
68 
69  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
70 
71  void beginRun(const edm::Run&, const edm::EventSetup&) override;
72  void produce(edm::Event& evt, const edm::EventSetup& es) override;
73 
74  double getDistInCM(double eta1, double phi1, double eta2, double phi2);
75  std::pair<double, double> GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ);
76 
77 private:
78  struct seedAtEC {
79  seedAtEC(unsigned int i, bool f, double et, double fi) : index(i), ok(f), eta(et), phi(fi) {}
80  unsigned int index;
81  bool ok;
82  double eta, phi;
83  };
84 
88  const std::vector<edm::EDGetTokenT<reco::TrackCollection> > toks_pix_;
91 
93  const double prelimCone_;
95  const double vtxCutSeed_;
96  const double vtxCutIsol_;
97  const double tauAssocCone_;
98  const double tauUnbiasCone_;
99  const double minPTrackValue_;
101  const double ebEtaBoundary_;
102 
103  // these are read from the EventSetup, cannot be const
104  double rEB_;
105  double zEE_;
106  double bfVal_;
107 };
108 
110  : tok_hlt_(consumes<trigger::TriggerFilterObjectWithRefs>(config.getParameter<edm::InputTag>("L1GTSeedLabel"))),
111  tok_l1_(consumes<l1t::TauBxCollection>(config.getParameter<edm::InputTag>("L1eTauJetsSource"))),
112  tok_vert_(consumes<reco::VertexCollection>(config.getParameter<edm::InputTag>("VertexLabel"))),
113  toks_pix_(
114  edm::vector_transform(config.getParameter<std::vector<edm::InputTag> >("PixelTracksSources"),
115  [this](edm::InputTag const& tag) { return consumes<reco::TrackCollection>(tag); })),
116  tok_bFieldH_(esConsumes<MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun>()),
117  tok_geom_(esConsumes<CaloGeometry, CaloGeometryRecord, edm::Transition::BeginRun>()),
118  bfield_(config.getParameter<std::string>("MagFieldRecordName")),
119  prelimCone_(config.getParameter<double>("ExtrapolationConeSize")),
120  pixelIsolationConeSizeAtEC_(config.getParameter<double>("PixelIsolationConeSizeAtEC")),
121  vtxCutSeed_(config.getParameter<double>("MaxVtxDXYSeed")),
122  vtxCutIsol_(config.getParameter<double>("MaxVtxDXYIsol")),
123  tauAssocCone_(config.getParameter<double>("tauAssociationCone")),
124  tauUnbiasCone_(config.getParameter<double>("tauUnbiasCone")),
125  minPTrackValue_(config.getParameter<double>("minPTrack")),
126  maxPForIsolationValue_(config.getParameter<double>("maxPTrackForIsolation")),
127  ebEtaBoundary_(config.getParameter<double>("EBEtaBoundary")),
128  rEB_(-1),
129  zEE_(-1),
130  bfVal_(0) {
131  // Register the product
132  produces<reco::IsolatedPixelTrackCandidateCollection>();
133 }
134 
136 
139  std::vector<edm::InputTag> tracksrc = {edm::InputTag("hltPixelTracks")};
140  desc.add<edm::InputTag>("L1eTauJetsSource", edm::InputTag("hltGtStage2Digis", "Tau"));
141  desc.add<double>("tauAssociationCone", 0.0);
142  desc.add<double>("tauUnbiasCone", 1.2);
143  desc.add<std::vector<edm::InputTag> >("PixelTracksSources", tracksrc);
144  desc.add<double>("ExtrapolationConeSize", 1.0);
145  desc.add<double>("PixelIsolationConeSizeAtEC", 40);
146  desc.add<edm::InputTag>("L1GTSeedLabel", edm::InputTag("hltL1sV0SingleJet60"));
147  desc.add<double>("MaxVtxDXYSeed", 101.0);
148  desc.add<double>("MaxVtxDXYIsol", 101.0);
149  desc.add<edm::InputTag>("VertexLabel", edm::InputTag("hltTrimmedPixelVertices"));
150  desc.add<std::string>("MagFieldRecordName", "VolumeBasedMagneticField");
151  desc.add<double>("minPTrack", 5.0);
152  desc.add<double>("maxPTrackForIsolation", 3.0);
153  desc.add<double>("EBEtaBoundary", 1.479);
154  descriptions.add("isolPixelTrackProdL1T", desc);
155 }
156 
158  const CaloGeometry* pG = &theEventSetup.getData(tok_geom_);
159 
160  const double rad(dynamic_cast<const EcalBarrelGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal, EcalBarrel))
161  ->avgRadiusXYFrontFaceCenter());
162  const double zz(dynamic_cast<const EcalEndcapGeometry*>(pG->getSubdetectorGeometry(DetId::Ecal, EcalEndcap))
163  ->avgAbsZFrontFaceCenter());
164 
165  rEB_ = rad;
166  zEE_ = zz;
167 
168  const MagneticField* vbfField = &theEventSetup.getData(tok_bFieldH_);
169  const VolumeBasedMagneticField* vbfCPtr = dynamic_cast<const VolumeBasedMagneticField*>(&(*vbfField));
170  GlobalVector BField = vbfCPtr->inTesla(GlobalPoint(0, 0, 0));
171  bfVal_ = BField.mag();
172 #ifdef EDM_ML_DEBUG
173  edm::LogVerbatim("IsoTrack") << "rEB " << rEB_ << " zEE " << zEE_ << " B " << bfVal_;
174 #endif
175 }
176 
178  auto trackCollection = std::make_unique<reco::IsolatedPixelTrackCandidateCollection>();
179 
180  //create vector of refs from input collections
181  std::vector<reco::TrackRef> pixelTrackRefs;
182 
183  for (unsigned int iPix = 0; iPix < toks_pix_.size(); iPix++) {
185  theEvent.getByToken(toks_pix_[iPix], iPixCol);
186  for (reco::TrackCollection::const_iterator pit = iPixCol->begin(); pit != iPixCol->end(); pit++) {
187  pixelTrackRefs.push_back(reco::TrackRef(iPixCol, pit - iPixCol->begin()));
188  }
189  }
190 
192  theEvent.getByToken(tok_l1_, l1eTauJets);
193 
195  theEvent.getByToken(tok_vert_, pVert);
196 
197  double ptTriggered = -10;
198  double etaTriggered = -100;
199  double phiTriggered = -100;
200 
202  theEvent.getByToken(tok_hlt_, l1trigobj);
203 
204  std::vector<edm::Ref<l1t::TauBxCollection> > l1tauobjref;
205  std::vector<edm::Ref<l1t::JetBxCollection> > l1jetobjref;
206 
207  // l1trigobj->getObjects(trigger::TriggerTau, l1tauobjref);
208  l1trigobj->getObjects(trigger::TriggerL1Tau, l1tauobjref);
209  // l1trigobj->getObjects(trigger::TriggerJet, l1jetobjref);
210  l1trigobj->getObjects(trigger::TriggerL1Jet, l1jetobjref);
211 
212  for (const auto& p : l1tauobjref) {
213  if (p->pt() > ptTriggered) {
214  ptTriggered = p->pt();
215  phiTriggered = p->phi();
216  etaTriggered = p->eta();
217  }
218  }
219  for (const auto& p : l1jetobjref) {
220  if (p->pt() > ptTriggered) {
221  ptTriggered = p->pt();
222  phiTriggered = p->phi();
223  etaTriggered = p->eta();
224  }
225  }
226 #ifdef EDM_ML_DEBUG
227  edm::LogVerbatim("IsoTrack") << "Sizes " << l1tauobjref.size() << ":" << l1jetobjref.size() << " Trig " << ptTriggered
228  << ":" << etaTriggered << ":" << phiTriggered;
229 #endif
230  double drMaxL1Track_ = tauAssocCone_;
231  int ntr = 0;
232  std::vector<seedAtEC> VecSeedsatEC;
233  //loop to select isolated tracks
234  for (unsigned iS = 0; iS < pixelTrackRefs.size(); iS++) {
235  bool vtxMatch = false;
236  //associate to vertex (in Z)
237  reco::VertexCollection::const_iterator vitSel;
238  double minDZ = 1000;
239  bool found(false);
240  for (reco::VertexCollection::const_iterator vit = pVert->begin(); vit != pVert->end(); vit++) {
241  if (std::abs(pixelTrackRefs[iS]->dz(vit->position())) < minDZ) {
242  minDZ = std::abs(pixelTrackRefs[iS]->dz(vit->position()));
243  vitSel = vit;
244  found = true;
245  }
246  }
247  //cut on dYX:
248  if (found) {
249  if (std::abs(pixelTrackRefs[iS]->dxy(vitSel->position())) < vtxCutSeed_)
250  vtxMatch = true;
251  } else {
252  vtxMatch = true;
253  }
254 #ifdef EDM_ML_DEBUG
255  edm::LogVerbatim("IsoTrack") << "minZD " << minDZ << " Found " << found << ":" << vtxMatch;
256 #endif
257  //select tracks not matched to triggered L1 jet
258  double R = reco::deltaR(etaTriggered, phiTriggered, pixelTrackRefs[iS]->eta(), pixelTrackRefs[iS]->phi());
259 #ifdef EDM_ML_DEBUG
260  edm::LogVerbatim("IsoTrack") << "Distance to L1 " << R << ":" << tauUnbiasCone_ << " Result "
261  << (R < tauUnbiasCone_);
262 #endif
263  if (R < tauUnbiasCone_)
264  continue;
265 
266  //check taujet matching
267  bool tmatch = false;
269  for (l1t::TauBxCollection::const_iterator tj = l1eTauJets->begin(); tj != l1eTauJets->end(); tj++) {
270  if (reco::deltaR(pixelTrackRefs[iS]->momentum().eta(),
271  pixelTrackRefs[iS]->momentum().phi(),
272  tj->momentum().eta(),
273  tj->momentum().phi()) > drMaxL1Track_)
274  continue;
275  selj = tj;
276  tmatch = true;
277  } //loop over L1 tau
278 #ifdef EDM_ML_DEBUG
279  edm::LogVerbatim("IsoTrack") << "tMatch " << tmatch;
280 #endif
281  //propagate seed track to ECAL surface:
282  std::pair<double, double> seedCooAtEC;
283  // in case vertex is found:
284  if (found)
285  seedCooAtEC = GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(),
286  pixelTrackRefs[iS]->phi(),
287  pixelTrackRefs[iS]->pt(),
288  pixelTrackRefs[iS]->charge(),
289  vitSel->z());
290  //in case vertex is not found:
291  else
292  seedCooAtEC = GetEtaPhiAtEcal(pixelTrackRefs[iS]->eta(),
293  pixelTrackRefs[iS]->phi(),
294  pixelTrackRefs[iS]->pt(),
295  pixelTrackRefs[iS]->charge(),
296  0);
297  seedAtEC seed(iS, (tmatch || vtxMatch), seedCooAtEC.first, seedCooAtEC.second);
298  VecSeedsatEC.push_back(seed);
299 #ifdef EDM_ML_DEBUG
300  edm::LogVerbatim("IsoTrack") << "Seed " << seedCooAtEC.first << seedCooAtEC.second;
301 #endif
302  }
303  for (unsigned int i = 0; i < VecSeedsatEC.size(); i++) {
304  unsigned int iSeed = VecSeedsatEC[i].index;
305  if (!VecSeedsatEC[i].ok)
306  continue;
307  if (pixelTrackRefs[iSeed]->p() < minPTrackValue_)
308  continue;
310  for (l1t::TauBxCollection::const_iterator tj = l1eTauJets->begin(); tj != l1eTauJets->end(); tj++) {
311  if (reco::deltaR(pixelTrackRefs[iSeed]->momentum().eta(),
312  pixelTrackRefs[iSeed]->momentum().phi(),
313  tj->momentum().eta(),
314  tj->momentum().phi()) > drMaxL1Track_)
315  continue;
316  selj = tj;
317  } //loop over L1 tau
318  double maxP = 0;
319  double sumP = 0;
320  for (unsigned int j = 0; j < VecSeedsatEC.size(); j++) {
321  if (i == j)
322  continue;
323  unsigned int iSurr = VecSeedsatEC[j].index;
324  //define preliminary cone around seed track impact point from which tracks will be extrapolated:
325  if (reco::deltaR(pixelTrackRefs[iSeed]->eta(),
326  pixelTrackRefs[iSeed]->phi(),
327  pixelTrackRefs[iSurr]->eta(),
328  pixelTrackRefs[iSurr]->phi()) > prelimCone_)
329  continue;
330  double minDZ2(1000);
331  bool found(false);
332  reco::VertexCollection::const_iterator vitSel2;
333  for (reco::VertexCollection::const_iterator vit = pVert->begin(); vit != pVert->end(); vit++) {
334  if (std::abs(pixelTrackRefs[iSurr]->dz(vit->position())) < minDZ2) {
335  minDZ2 = std::abs(pixelTrackRefs[iSurr]->dz(vit->position()));
336  vitSel2 = vit;
337  found = true;
338  }
339  }
340  //cut ot dXY:
341  if (found && std::abs(pixelTrackRefs[iSurr]->dxy(vitSel2->position())) > vtxCutIsol_)
342  continue;
343  //calculate distance at ECAL surface and update isolation:
344  if (getDistInCM(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi, VecSeedsatEC[j].eta, VecSeedsatEC[j].phi) <
346  sumP += pixelTrackRefs[iSurr]->p();
347  if (pixelTrackRefs[iSurr]->p() > maxP)
348  maxP = pixelTrackRefs[iSurr]->p();
349  }
350  }
351  if (maxP < maxPForIsolationValue_) {
353  pixelTrackRefs[iSeed], l1t::TauRef(l1eTauJets, selj - l1eTauJets->begin()), maxP, sumP);
354  newCandidate.setEtaPhiEcal(VecSeedsatEC[i].eta, VecSeedsatEC[i].phi);
355  trackCollection->push_back(newCandidate);
356  ntr++;
357  }
358  }
359 #ifdef EDM_ML_DEBUG
360  edm::LogVerbatim("IsoTrack") << "Number of Isolated Track " << ntr;
361 #endif
362  // put the product in the event
363  theEvent.put(std::move(trackCollection));
364 }
365 
366 double IsolatedPixelTrackCandidateL1TProducer::getDistInCM(double eta1, double phi1, double eta2, double phi2) {
367  double Rec;
368  double theta1 = 2 * atan(exp(-eta1));
369  double theta2 = 2 * atan(exp(-eta2));
370  if (std::abs(eta1) < 1.479)
371  Rec = rEB_; //radius of ECAL barrel
372  else if (std::abs(eta1) > 1.479 && std::abs(eta1) < 7.0)
373  Rec = tan(theta1) * zEE_; //distance from IP to ECAL endcap
374  else
375  return 1000;
376 
377  //|vect| times tg of acos(scalar product)
378  double angle =
379  acos((sin(theta1) * sin(theta2) * (sin(phi1) * sin(phi2) + cos(phi1) * cos(phi2)) + cos(theta1) * cos(theta2)));
380  if (angle < M_PI_2)
381  return std::abs((Rec / sin(theta1)) * tan(angle));
382  else
383  return 1000;
384 }
385 
387  double etaIP, double phiIP, double pT, int charge, double vtxZ) {
388  double deltaPhi = 0;
389  double etaEC = 100;
390  double phiEC = 100;
391 
392  double Rcurv = 9999999;
393  if (bfVal_ != 0)
394  Rcurv = pT * 33.3 * 100 / (bfVal_ * 10); //r(m)=pT(GeV)*33.3/B(kG)
395 
396  double ecDist = zEE_; //distance to ECAL andcap from IP (cm), 317 - ecal (not preshower), preshower -300
397  double ecRad = rEB_; //radius of ECAL barrel (cm)
398  double theta = 2 * atan(exp(-etaIP));
399  double zNew = 0;
400  if (theta > M_PI_2)
401  theta = M_PI - theta;
402  if (std::abs(etaIP) < ebEtaBoundary_) {
403  if ((0.5 * ecRad / Rcurv) > 1) {
404  etaEC = 10000;
405  deltaPhi = 0;
406  } else {
407  deltaPhi = -charge * asin(0.5 * ecRad / Rcurv);
408  double alpha1 = 2 * asin(0.5 * ecRad / Rcurv);
409  double z = ecRad / tan(theta);
410  if (etaIP > 0)
411  zNew = z * (Rcurv * alpha1) / ecRad + vtxZ; //new z-coordinate of track
412  else
413  zNew = -z * (Rcurv * alpha1) / ecRad + vtxZ; //new z-coordinate of track
414  double zAbs = std::abs(zNew);
415  if (zAbs < ecDist) {
416  etaEC = -log(tan(0.5 * atan(ecRad / zAbs)));
417  deltaPhi = -charge * asin(0.5 * ecRad / Rcurv);
418  }
419  if (zAbs > ecDist) {
420  zAbs = (std::abs(etaIP) / etaIP) * ecDist;
421  double Zflight = std::abs(zAbs - vtxZ);
422  double alpha = (Zflight * ecRad) / (z * Rcurv);
423  double Rec = 2 * Rcurv * sin(alpha / 2);
424  deltaPhi = -charge * alpha / 2;
425  etaEC = -log(tan(0.5 * atan(Rec / ecDist)));
426  }
427  }
428  } else {
429  zNew = (std::abs(etaIP) / etaIP) * ecDist;
430  double Zflight = std::abs(zNew - vtxZ);
431  double Rvirt = std::abs(Zflight * tan(theta));
432  double Rec = 2 * Rcurv * sin(Rvirt / (2 * Rcurv));
433  deltaPhi = -(charge) * (Rvirt / (2 * Rcurv));
434  etaEC = -log(tan(0.5 * atan(Rec / ecDist)));
435  }
436 
437  if (zNew < 0)
438  etaEC = -etaEC;
439  phiEC = phiIP + deltaPhi;
440 
441  if (phiEC < -M_PI)
442  phiEC += M_2_PI;
443  if (phiEC > M_PI)
444  phiEC -= M_2_PI;
445 
446  std::pair<double, double> retVal(etaEC, phiEC);
447  return retVal;
448 }
451 
zEE_(-1)
Log< level::Info, true > LogVerbatim
const CaloSubdetectorGeometry * getSubdetectorGeometry(const DetId &id) const
access the subdetector geometry for the given subdetector directly
Definition: CaloGeometry.cc:34
void produce(edm::Event &evt, const edm::EventSetup &es) override
float alpha
Definition: AMPTWrapper.h:105
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
static std::vector< std::string > checklist log
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
tauAssocCone_(config.getParameter< double >("tauAssociationCone"))
GlobalVector inTesla(const GlobalPoint &g) const override
Field value ad specified global point, in Tesla.
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
void beginRun(const edm::Run &, const edm::EventSetup &) override
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
tok_bFieldH_(esConsumes< MagneticField, IdealMagneticFieldRecord, edm::Transition::BeginRun >())
double getDistInCM(double eta1, double phi1, double eta2, double phi2)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
Geom::Theta< T > theta() const
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > tok_geom_
#define M_PI_2
vtxCutIsol_(config.getParameter< double >("MaxVtxDXYIsol"))
Exp< T >::type exp(const T &t)
Definition: Exp.h:22
rEB_(-1)
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
std::vector< Vertex > VertexCollection
Definition: Vertex.h:12
BXVector< Tau > TauBxCollection
Definition: Tau.h:10
const edm::EDGetTokenT< reco::VertexCollection > tok_vert_
bool getData(T &iHolder) const
Definition: EventSetup.h:128
std::vector< T >::const_iterator const_iterator
Definition: BXVector.h:18
T mag() const
Definition: PV3DBase.h:64
const edm::EDGetTokenT< l1t::TauBxCollection > tok_l1_
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
def move
Definition: eostools.py:511
const std::vector< edm::EDGetTokenT< reco::TrackCollection > > toks_pix_
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
std::pair< double, double > GetEtaPhiAtEcal(double etaIP, double phiIP, double pT, int charge, double vtxZ)
minPTrackValue_(config.getParameter< double >("minPTrack"))
vtxCutSeed_(config.getParameter< double >("MaxVtxDXYSeed"))
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:30
prelimCone_(config.getParameter< double >("ExtrapolationConeSize"))
tuple trackCollection
void add(std::string const &label, ParameterSetDescription const &psetDescription)
tuple config
parse the configuration file
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > tok_bFieldH_
bfield_(config.getParameter< std::string >("MagFieldRecordName"))
tauUnbiasCone_(config.getParameter< double >("tauUnbiasCone"))
pixelIsolationConeSizeAtEC_(config.getParameter< double >("PixelIsolationConeSizeAtEC"))
maxPForIsolationValue_(config.getParameter< double >("maxPTrackForIsolation"))
ebEtaBoundary_(config.getParameter< double >("EBEtaBoundary"))
Definition: Run.h:45
tok_geom_(esConsumes< CaloGeometry, CaloGeometryRecord, edm::Transition::BeginRun >())
T angle(T x1, T y1, T z1, T x2, T y2, T z2)
Definition: angle.h:11
const edm::EDGetTokenT< trigger::TriggerFilterObjectWithRefs > tok_hlt_