CMS 3D CMS Logo

Stub.cc
Go to the documentation of this file.
7 
12 
13 #include <iostream>
14 
15 using namespace std;
16 
17 namespace tmtt {
18 
19  //=== Hybrid L1 tracking: stub constructor.
20 
21  Stub::Stub(const Settings* settings,
22  unsigned int idStub,
23  double phi,
24  double r,
25  double z,
26  double bend,
27  unsigned int iphi,
28  double alpha,
29  unsigned int layerId,
30  unsigned int iPhiSec,
31  bool psModule,
32  bool barrel,
33  bool tiltedBarrel,
34  float stripPitch,
35  float stripLength,
36  unsigned int nStrips)
37  : index_in_vStubs_(idStub), // A unique ID to label the stub.
38  phi_(phi),
39  r_(r),
40  z_(z),
41  bend_(bend),
42  iphi_(iphi),
43  alpha_(alpha),
44  digitalStub_(std::make_unique<DigitalStub>(settings, r, phi, z, iPhiSec)),
45  layerId_(layerId),
46  layerIdReduced_(TrackerModule::calcLayerIdReduced(layerId)),
47  stripPitch_(stripPitch),
48  stripLength_(stripLength),
49  nStrips_(nStrips),
50  psModule_(psModule),
51  barrel_(barrel),
52  tiltedBarrel_(tiltedBarrel) {}
53 
54  //=== TMTT L1 tracking: stub constructor.
55 
56  Stub::Stub(const TTStubRef& ttStubRef,
57  unsigned int index_in_vStubs,
58  const Settings* settings,
59  const TrackerTopology* trackerTopology,
60  const TrackerModule* trackerModule,
61  const DegradeBend* degradeBend,
62  const StubKiller* stubKiller)
63  : ttStubRef_(ttStubRef),
64  settings_(settings),
65  index_in_vStubs_(index_in_vStubs),
66  assocTP_(nullptr), // Initialize in case job is using no MC truth info.
67  lastDigiStep_(Stub::DigiStage::NONE),
68  digitizeWarningsOn_(true),
69  trackerModule_(trackerModule), // Info about tracker module containing stub
70  degradeBend_(degradeBend), // Used to degrade stub bend information.
71  // Module related variables (need to be stored for Hybrid)
72  layerId_(trackerModule->layerId()),
73  layerIdReduced_(trackerModule->layerIdReduced()),
74  tiltAngle_(trackerModule->tiltAngle()),
75  stripPitch_(trackerModule->stripPitch()),
76  stripLength_(trackerModule->stripLength()),
77  nStrips_(trackerModule->nStrips()),
78  psModule_(trackerModule->psModule()),
79  barrel_(trackerModule->barrel()),
80  tiltedBarrel_(trackerModule->tiltedBarrel()) {
81  // Get coordinates of stub.
83 
84  const PixelGeomDetUnit* specDet = trackerModule_->specDet();
85  const PixelTopology* specTopol = trackerModule_->specTopol();
86  MeasurementPoint measurementPoint = ttStubRef_->clusterRef(0)->findAverageLocalCoordinatesCentered();
87  LocalPoint clustlp = specTopol->localPosition(measurementPoint);
88  GlobalPoint pos = specDet->surface().toGlobal(clustlp);
89 
90  phi_ = pos.phi();
91  r_ = pos.perp();
92  z_ = pos.z();
93 
94  // Get the coordinates of the two clusters that make up this stub, measured in units of strip pitch, and measured
95  // in the local frame of the sensor. They have a granularity of 0.5*pitch.
96  for (unsigned int iClus = 0; iClus <= 1; iClus++) { // Loop over two clusters in stub.
97  localU_cluster_[iClus] = ttStubP->clusterRef(iClus)->findAverageLocalCoordinatesCentered().x();
98  localV_cluster_[iClus] = ttStubP->clusterRef(iClus)->findAverageLocalCoordinatesCentered().y();
99  }
100 
101  // Get location of stub in module in units of strip number (or pixel number along finest granularity axis).
102  // Range from 0 to (nStrips - 1) inclusive.
103  // N.B. Since iphi is integer, this degrades the granularity by a factor 2. This seems silly, but track fit wants it.
104  iphi_ = localU_cluster_[0]; // granularity 1*strip (unclear why we want to degrade it ...)
105 
106  // Determine alpha correction for non-radial strips in endcap 2S modules.
107  // (If true hit at larger r than stub r by deltaR, then stub phi needs correcting by +alpha*deltaR).
108  alpha_ = 0.;
109  if ((not barrel()) && (not psModule())) {
110  float fracPosInModule = (float(iphi_) - 0.5 * float(nStrips())) / float(nStrips());
111  float phiRelToModule = trackerModule_->sensorWidth() * fracPosInModule / r_;
112  if (z_ < 0)
113  phiRelToModule *= -1;
115  phiRelToModule *= -1; // Module flipped.
116  // If true hit at larger r than stub r by deltaR, then stub phi needs correcting by +alpha*deltaR.
117  alpha_ = -phiRelToModule / r_;
118  }
119 
120  // Calculate variables giving ratio of track intercept angle to stub bend.
121  this->calcDphiOverBend();
122 
123  // Get stub bend that is available in front-end electronics, where bend is displacement between
124  // two hits in stubs in units of strip pitch.
125  bendInFrontend_ = ttStubRef_->bendFE();
126  if ((not barrel()) && pos.z() > 0)
127  bendInFrontend_ *= -1;
128  if (barrel())
129  bendInFrontend_ *= -1;
130 
131  // Get stub bend that is available in off-detector electronics, allowing for degredation of
132  // bend resolution due to bit encoding by FE chip if required.
133  numMergedBend_ = 1; // Number of bend values merged into single degraded one.
134  if (settings->degradeBendRes() == 2) {
135  float degradedBend; // degraded bend
136  // This returns values of degradedBend & numMergedBend_
137  this->degradeResolution(bendInFrontend_, degradedBend, numMergedBend_);
138  bend_ = degradedBend;
139  } else if (settings->degradeBendRes() == 1) {
140  bend_ = ttStubRef_->bendBE(); // Degraded bend from official CMS recipe.
141  if ((not barrel()) && pos.z() > 0)
142  bend_ *= -1;
143  if (barrel())
144  bend_ *= -1;
145  } else {
147  }
148 
149  // Fill frontendPass_ flag, indicating if frontend readout electronics will output this stub.
150  this->setFrontend(stubKiller);
151 
152  // Calculate bin range along q/Pt axis of r-phi Hough transform array consistent with bend of this stub.
153  this->calcQoverPtrange();
154 
155  // Initialize truth info to false in case job is using no MC truth info.
156  for (unsigned int iClus = 0; iClus <= 1; iClus++) {
157  assocTPofCluster_[iClus] = nullptr;
158  }
159  }
160 
161  //=== Calculate bin range along q/Pt axis of r-phi Hough transform array consistent with bend of this stub.
162 
164  // First determine bin range along q/Pt axis of HT array
165  // (Use "int" as nasty things happen if multiply "int" and "unsigned int").
166  const int nbinsPt = (int)settings_->houghNbinsPt();
167  const int min_array_bin = 0;
168  const int max_array_bin = nbinsPt - 1;
169  // Now calculate range of q/Pt bins allowed by bend filter.
170  float qOverPtMin = this->qOverPtOverBend() * (this->bend() - this->bendCut());
171  float qOverPtMax = this->qOverPtOverBend() * (this->bend() + this->bendCut());
172  int houghNbinsPt = settings_->houghNbinsPt();
173  const float houghMaxInvPt = 1. / settings_->houghMinPt();
174  float qOverPtBinSize = (2. * houghMaxInvPt) / houghNbinsPt;
175  if (settings_->shape() == 2 || settings_->shape() == 1 || settings_->shape() == 3) // Non-square HT cells.
176  qOverPtBinSize = 2. * houghMaxInvPt / (houghNbinsPt - 1);
177  // Convert to bin number along q/Pt axis of HT array.
178  // N.B. For square HT cells, setting "tmp = -0.5" causeas cell to be accepted if q/Pt at its centre is consistent
179  // with the stub bend. Instead using "tmp = 0.0" accepts cells if q/Pt at any point in cell is consistent with bend.
180  // So if you use change from -0.5 to 0.0, you have to tighten the bend cut (by ~0.05) to get similar performance.
181  // Decision to set tmp = 0.0 taken in softare & GP firmware on 9th August 2016.
182 
183  float tmp = (settings_->shape() == 2 || settings_->shape() == 1 || settings_->shape() == 3) ? 1. : 0.;
184  int min_bin = std::floor(-tmp + (qOverPtMin + houghMaxInvPt) / qOverPtBinSize);
185  int max_bin = std::floor(tmp + (qOverPtMax + houghMaxInvPt) / qOverPtBinSize);
186 
187  // Limit it to range of HT array.
188  min_bin = max(min_bin, min_array_bin);
189  max_bin = min(max_bin, max_array_bin);
190  // If min_bin > max_bin at this stage, it means that the Pt estimated from the bend is below the cutoff for track-finding.
191  // Keep min_bin > max_bin, so such stubs can be rejected, but set both variables to values inside the HT bin range.
192  if (min_bin > max_bin) {
193  min_bin = max_array_bin;
194  max_bin = min_array_bin;
195  }
196  min_qOverPt_bin_ = (unsigned int)min_bin;
197  max_qOverPt_bin_ = (unsigned int)max_bin;
198  }
199 
200  //=== Digitize stub for input to Geographic Processor, with digitized phi coord. measured relative to closest phi sector.
201  //=== (This approximation is valid if their are an integer number of digitisation bins inside each phi nonant).
202 
203  void Stub::digitize(unsigned int iPhiSec, Stub::DigiStage digiStep) {
204  if (settings_->enableDigitize()) {
205  bool updated = true;
206  if (not digitalStub_) {
207  // Digitize stub if not yet done.
208  digitalStub_ =
209  std::make_unique<DigitalStub>(settings_, phi_, r_, z_, min_qOverPt_bin_, max_qOverPt_bin_, bend_, iPhiSec);
210  } else {
211  // If digitization already done, redo phi digi if phi sector has changed.
212  updated = digitalStub_->changePhiSec(iPhiSec);
213  }
214 
215  // Save CPU by only updating if something has changed.
216  if (updated || digiStep != lastDigiStep_) {
217  lastDigiStep_ = digiStep;
218 
219  // Replace stub coords with those degraded by digitization process.
220  if (digiStep == DigiStage::GP) {
221  phi_ = digitalStub_->phi_GP();
222  } else {
223  phi_ = digitalStub_->phi_HT_TF();
224  }
225  if (digiStep == DigiStage::GP || digiStep == DigiStage::HT) {
226  r_ = digitalStub_->r_GP_HT();
227  } else {
228  r_ = digitalStub_->r_SF_TF();
229  }
230  z_ = digitalStub_->z();
231  bend_ = digitalStub_->bend();
232 
233  // Update data members that depend on updated coords.
234  // (Logically part of digitisation, so disable warnings)
235  digitizeWarningsOn_ = false;
236  if (digiStep == DigiStage::GP)
237  this->calcDphiOverBend();
238  if (digiStep == DigiStage::HT)
239  this->calcQoverPtrange();
240  digitizeWarningsOn_ = true;
241  }
242  }
243  }
244 
245  //=== Degrade assumed stub bend resolution.
246  //=== And return an integer indicating how many values of bend are merged into this single one.
247 
248  void Stub::degradeResolution(float bend, float& degradedBend, unsigned int& num) const {
249  // If TMTT code is tightening official CMS FE stub window cuts, then calculate TMTT stub windows.
250  float windowFE;
251  if (settings_->killLowPtStubs()) {
252  // Window size corresponding to Pt cut used for tracking.
253  float invPtMax = 1. / (settings_->houghMinPt());
254  windowFE = invPtMax / std::abs(this->qOverPtOverBend());
255  // Increase half-indow size to allow for resolution in bend.
256  windowFE += this->bendCutInFrontend();
257  } else {
258  windowFE = rejectedStubBend_; // TMTT is not tightening windows.
259  }
260 
261  degradeBend_->degrade(bend, psModule(), trackerModule_->detId(), windowFE, degradedBend, num);
262  }
263 
264  //=== Set flag indicating if stub will be output by front-end readout electronics
265  //=== (where we can reconfigure the stub window size and rapidity cut).
266 
267  void Stub::setFrontend(const StubKiller* stubKiller) {
268  frontendPass_ = true; // Did stub pass cuts applied in front-end chip
269  stubFailedDegradeWindow_ = false; // Did it only fail cuts corresponding to windows encoded in DegradeBend.h?
270  // Don't use stubs at large eta, since it is impossible to form L1 tracks from them, so they only contribute to combinatorics.
271  if (std::abs(this->eta()) > settings_->maxStubEta())
272  frontendPass_ = false;
273  // Don't use stubs whose Pt is significantly below the Pt cut used in the L1 tracking, allowing for uncertainty in q/Pt due to stub bend resolution.
274  const float qOverPtCut = 1. / settings_->houghMinPt();
275  if (settings_->killLowPtStubs()) {
276  // Apply this cut in the front-end electronics.
277  if (std::abs(this->bendInFrontend()) - this->bendCutInFrontend() > qOverPtCut / this->qOverPtOverBend())
278  frontendPass_ = false;
279  }
280 
281  if (frontendPass_ && this->bend() == rejectedStubBend_) {
282  throw cms::Exception(
283  "BadConfig: FE stub bend window sizes provided in cfg ES source are tighter than those to make the stubs. "
284  "Please fix them");
285  }
286 
287  if (settings_->killLowPtStubs()) {
288  // Reapply the same cut using the degraded bend information available in the off-detector electronics.
289  // The reason is that the bend degredation can move the Pt below the Pt cut, making the stub useless to the off-detector electronics.
290  if (std::abs(this->bend()) - this->bendCut() > qOverPtCut / this->qOverPtOverBend())
291  frontendPass_ = false;
292  }
293 
294  // Emulate stubs in dead tracker regions..
296  if (killScenario != StubKiller::KillOptions::none) {
297  bool kill = stubKiller->killStub(ttStubRef_.get());
298  if (kill)
299  frontendPass_ = false;
300  }
301  }
302 
303  //=== Function to calculate approximation for dphiOverBendCorrection aka B
304  double Stub::approxB() {
305  if (tiltedBarrel()) {
307  } else {
308  return barrel() ? 1 : std::abs(z_) / r_;
309  }
310  }
311 
312  //=== Calculate variables giving ratio of track intercept angle to stub bend.
313 
315  // Uses stub (r,z) instead of module (r,z). Logically correct but has negligable effect on results.
316  if (settings_->useApproxB()) {
317  float dphiOverBendCorrection_approx_ = approxB();
318  dphiOverBend_ = trackerModule_->pitchOverSep() * dphiOverBendCorrection_approx_;
319  } else {
320  float dphiOverBendCorrection_ = std::abs(cos(this->theta() - trackerModule_->tiltAngle()) / sin(this->theta()));
321  dphiOverBend_ = trackerModule_->pitchOverSep() * dphiOverBendCorrection_;
322  }
323  }
324 
325  //=== Note which tracking particle(s), if any, produced this stub.
326  //=== The 1st argument is a map relating TrackingParticles to TP.
327 
328  void Stub::fillTruth(const map<edm::Ptr<TrackingParticle>, const TP*>& translateTP,
329  const edm::Handle<TTStubAssMap>& mcTruthTTStubHandle,
330  const edm::Handle<TTClusterAssMap>& mcTruthTTClusterHandle) {
331  //--- Fill assocTP_ info. If both clusters in this stub were produced by the same single tracking particle, find out which one it was.
332 
333  bool genuine = mcTruthTTStubHandle->isGenuine(ttStubRef_); // Same TP contributed to both clusters?
334  assocTP_ = nullptr;
335 
336  // Require same TP contributed to both clusters.
337  if (genuine) {
338  edm::Ptr<TrackingParticle> tpPtr = mcTruthTTStubHandle->findTrackingParticlePtr(ttStubRef_);
339  if (translateTP.find(tpPtr) != translateTP.end()) {
340  assocTP_ = translateTP.at(tpPtr);
341  // N.B. Since not all tracking particles are stored in InputData::vTPs_, sometimes no match will be found.
342  }
343  }
344 
345  // Fill assocTPs_ info.
346 
347  if (settings_->stubMatchStrict()) {
348  // We consider only stubs in which this TP contributed to both clusters.
349  if (assocTP_ != nullptr)
350  assocTPs_.insert(assocTP_);
351 
352  } else {
353  // We consider stubs in which this TP contributed to either cluster.
354 
355  for (unsigned int iClus = 0; iClus <= 1; iClus++) { // Loop over both clusters that make up stub.
356  const TTClusterRef& ttClusterRef = ttStubRef_->clusterRef(iClus);
357 
358  // Now identify all TP's contributing to either cluster in stub.
359  vector<edm::Ptr<TrackingParticle> > vecTpPtr = mcTruthTTClusterHandle->findTrackingParticlePtrs(ttClusterRef);
360 
361  for (const edm::Ptr<TrackingParticle>& tpPtr : vecTpPtr) {
362  if (translateTP.find(tpPtr) != translateTP.end()) {
363  assocTPs_.insert(translateTP.at(tpPtr));
364  // N.B. Since not all tracking particles are stored in InputData::vTPs_, sometimes no match will be found.
365  }
366  }
367  }
368  }
369 
370  //--- Also note which tracking particles produced the two clusters that make up the stub
371 
372  for (unsigned int iClus = 0; iClus <= 1; iClus++) { // Loop over both clusters that make up stub.
373  const TTClusterRef& ttClusterRef = ttStubRef_->clusterRef(iClus);
374 
375  bool genuineCluster = mcTruthTTClusterHandle->isGenuine(ttClusterRef); // Only 1 TP made cluster?
376  assocTPofCluster_[iClus] = nullptr;
377 
378  // Only consider clusters produced by just one TP.
379  if (genuineCluster) {
380  edm::Ptr<TrackingParticle> tpPtr = mcTruthTTClusterHandle->findTrackingParticlePtr(ttClusterRef);
381 
382  if (translateTP.find(tpPtr) != translateTP.end()) {
383  assocTPofCluster_[iClus] = translateTP.at(tpPtr);
384  // N.B. Since not all tracking particles are stored in InputData::vTPs_, sometimes no match will be found.
385  }
386  }
387  }
388  }
389 } // namespace tmtt
const edm::Ref< edmNew::DetSetVector< TTCluster< T > >, TTCluster< T > > & clusterRef(unsigned int hitStackMember) const
Clusters composing the Stub – see https://twiki.cern.ch/twiki/bin/viewauth/CMS/SLHCTrackerTriggerSWT...
Definition: TTStub.h:150
Stub(const Settings *settings, unsigned int idStub, double phi, double r, double z, double bend, unsigned int iphi, double alpha, unsigned int layerId, unsigned int iPhiSec, bool psModule, bool barrel, bool tiltedBarrel, float stripPitch, float stripLength, unsigned int nStrips)
Definition: Stub.cc:21
float eta() const
Definition: Stub.h:111
float theta() const
Definition: Stub.h:110
float bendInFrontend() const
Definition: Stub.h:123
float dphiOverBend_
Definition: Stub.h:243
float alpha
Definition: AMPTWrapper.h:105
DigiStage lastDigiStep_
Definition: Stub.h:270
bool killStub(const TTStub< Ref_Phase2TrackerDigi_ > *stub) const
Definition: StubKiller.cc:110
bool enableDigitize() const
Definition: Settings.h:80
unsigned int min_qOverPt_bin_
Definition: Stub.h:244
float bend() const
Definition: Stub.h:126
unsigned int shape() const
Definition: Settings.h:147
virtual LocalPoint localPosition(const MeasurementPoint &) const =0
bool killLowPtStubs() const
Definition: Settings.h:66
std::array< bool, 2 > genuineCluster() const
Definition: Stub.h:173
unsigned int nStrips() const
Definition: Stub.h:209
std::unique_ptr< DigitalStub > digitalStub_
Definition: Stub.h:269
const Settings * settings_
Definition: Stub.h:233
bool outerModuleAtSmallerR() const
Definition: TrackerModule.h:62
double bApprox_intercept() const
Definition: Settings.h:105
const DetId & detId() const
Definition: TrackerModule.h:44
unsigned int iphi_
Definition: Stub.h:251
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
unsigned int killScenario() const
Definition: Settings.h:343
float qOverPtOverBend() const
Definition: Stub.h:148
void degrade(float bend, bool psModule, const DetId &stDetId, float windowFEnew, float &degradedBend, unsigned int &numInGroup) const
Definition: DegradeBend.cc:24
std::array< const TP *, 2 > assocTPofCluster_
Definition: Stub.h:267
nStrips
1.2 is to make the matching window safely the two nearest strips 0.35 is the size of an ME0 chamber i...
bool stubMatchStrict() const
Definition: Settings.h:241
bool useApproxB() const
Definition: Settings.h:103
double approxB()
Definition: Stub.cc:304
unsigned int houghNbinsPt() const
Definition: Settings.h:137
bool genuine() const
Definition: Stub.h:167
Definition: TP.h:23
const DegradeBend * degradeBend_
Definition: Stub.h:277
unsigned int numMergedBend_
Definition: Stub.h:261
float r_
Definition: Stub.h:240
std::array< float, 2 > localV_cluster_
Definition: Stub.h:249
void fillTruth(const std::map< edm::Ptr< TrackingParticle >, const TP *> &translateTP, const edm::Handle< TTStubAssMap > &mcTruthTTStubHandle, const edm::Handle< TTClusterAssMap > &mcTruthTTClusterHandle)
Definition: Stub.cc:328
unsigned int max_qOverPt_bin_
Definition: Stub.h:245
void calcQoverPtrange()
Definition: Stub.cc:163
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
float alpha_
Definition: Stub.h:252
float tiltAngle() const
Definition: TrackerModule.h:75
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
DigiStage
Definition: Stub.h:89
Class to store the L1 Track Trigger stubs.
Definition: TTStub.h:22
double bApprox_gradient() const
Definition: Settings.h:104
bool barrel() const
Definition: Stub.h:201
std::set< const TP * > assocTPs_
Definition: Stub.h:265
float z_
Definition: Stub.h:241
const PixelTopology * specTopol() const
Definition: TrackerModule.h:51
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
void setFrontend(const StubKiller *stubKiller)
Definition: Stub.cc:267
std::array< float, 2 > localU_cluster_
Definition: Stub.h:248
bool digitizeWarningsOn_
Definition: Stub.h:271
bool tiltedBarrel() const
Definition: Stub.h:203
const float rejectedStubBend_
Definition: Stub.h:291
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
double maxStubEta() const
Definition: Settings.h:64
float phi_
Definition: Stub.h:239
=== This is the base class for the linearised chi-squared track fit algorithms.
Definition: Array2D.h:16
const TP * assocTP_
Definition: Stub.h:264
TTStubRef ttStubRef_
Definition: Stub.h:231
float pitchOverSep() const
Definition: TrackerModule.h:91
void calcDphiOverBend()
Definition: Stub.cc:314
double houghMinPt() const
Definition: Settings.h:135
float bendCutInFrontend() const
Definition: Stub.h:124
float bendCut() const
Definition: Stub.h:128
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
float bend_
Definition: Stub.h:242
bool frontendPass_
Definition: Stub.h:255
const TrackerModule * trackerModule_
Definition: Stub.h:274
void digitize(unsigned int iPhiSec, DigiStage digiStep)
Definition: Stub.cc:203
tmp
align.sh
Definition: createJobs.py:716
bool stubFailedDegradeWindow_
Definition: Stub.h:257
const PixelGeomDetUnit * specDet() const
Definition: TrackerModule.h:50
float sensorWidth() const
Definition: TrackerModule.h:77
unsigned int degradeBendRes() const
Definition: Settings.h:62
bool psModule() const
Definition: Stub.h:196
float bendInFrontend_
Definition: Stub.h:259
void degradeResolution(float bend, float &degradedBend, unsigned int &num) const
Definition: Stub.cc:248