CMS 3D CMS Logo

Stub.cc
Go to the documentation of this file.
2 
3 #include <cmath>
4 #include <iterator>
5 #include <algorithm>
6 #include <utility>
7 
8 using namespace edm;
9 using namespace std;
10 
11 namespace trackerDTC {
12 
13  Stub::Stub(const ParameterSet& iConfig, const Setup& setup, SensorModule* sm, const TTStubRef& ttStubRef)
14  : setup_(&setup), sm_(sm), ttStubRef_(ttStubRef), hybrid_(iConfig.getParameter<bool>("UseHybrid")), valid_(true) {
15  regions_.reserve(setup.numOverlappingRegions());
16  // get stub local coordinates
17  const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered();
18 
19  // convert to uniformed local coordinates
20 
21  // column number in pitch units
22  col_ = (int)floor(pow(-1, sm->signCol()) * (mp.y() - sm->numColumns() / 2) / setup.baseCol());
23  // row number in half pitch units
24  row_ = (int)floor(pow(-1, sm->signRow()) * (mp.x() - sm->numRows() / 2) / setup.baseRow());
25  // bend number in quarter pitch units
26  bend_ = (int)floor(pow(-1, sm->signBend()) * (ttStubRef->bendBE()) / setup.baseBend());
27  // reduced row number for look up
28  rowLUT_ = (int)floor((double)row_ / pow(2., setup.widthRow() - setup.dtcWidthRowLUT()));
29  // sub row number inside reduced row number
30  rowSub_ = row_ - (rowLUT_ + .5) * pow(2, setup.widthRow() - setup.dtcWidthRowLUT());
31 
32  // convert local to global coordinates
33 
34  const double y = (col_ + .5) * setup.baseCol() * sm->pitchCol();
35  // radius of a column of strips/pixel in cm
36  d_ = sm->r() + y * sm->sin();
37  // stub z in cm
38  z_ = digi(sm->z() + y * sm->cos(), setup.baseZ());
39 
40  const double x0 = rowLUT_ * setup.baseRow() * setup.dtcNumMergedRows() * sm->pitchRow();
41  const double x1 = (rowLUT_ + 1) * setup.baseRow() * setup.dtcNumMergedRows() * sm->pitchRow();
42  const double x = (rowLUT_ + .5) * setup.baseRow() * setup.dtcNumMergedRows() * sm->pitchRow();
43  // stub r in cm
44  r_ = sqrt(d_ * d_ + x * x);
45 
46  const double phi0 = sm->phi() + atan2(x0, d_);
47  const double phi1 = sm->phi() + atan2(x1, d_);
48  const double c = (phi0 + phi1) / 2.;
49  const double m = (phi1 - phi0) / setup.dtcNumMergedRows();
50 
51  // intercept of linearized stub phi in rad
52  c_ = digi(c, setup.basePhi());
53  // slope of linearized stub phi in rad / strip
54  m_ = digi(m, setup.dtcBaseM());
55 
56  if (hybrid_) {
57  if (abs(z_ / r_) > setup.hybridMaxCot())
58  // did not pass eta cut
59  valid_ = false;
60  } else {
61  // extrapolated z at radius T assuming z0=0
62  const double zT = setup.chosenRofZ() * z_ / r_;
63  // extrapolated z0 window at radius T
64  const double dZT = setup.beamWindowZ() * abs(1. - setup.chosenRofZ() / r_);
65  double zTMin = zT - dZT;
66  double zTMax = zT + dZT;
67  if (zTMin >= setup.maxZT() || zTMax < -setup.maxZT())
68  // did not pass "eta" cut
69  valid_ = false;
70  else {
71  zTMin = max(zTMin, -setup.maxZT());
72  zTMax = min(zTMax, setup.maxZT());
73  }
74  // range of stub cot(theta)
75  cot_ = {zTMin / setup.chosenRofZ(), zTMax / setup.chosenRofZ()};
76  }
77 
78  // stub r w.r.t. chosenRofPhi in cm
79  static const double chosenRofPhi = hybrid_ ? setup.hybridChosenRofPhi() : setup.chosenRofPhi();
80  r_ = digi(r_ - chosenRofPhi, setup.baseR());
81 
82  // radial (cylindrical) component of sensor separation
83  const double dr = sm->sep() / (sm->cos() - sm->sin() * z_ / d_);
84  // converts bend into qOverPt in 1/cm
85  const double qOverPtOverBend = sm->pitchRow() / dr / d_;
86  // qOverPt in 1/cm
87  const double qOverPt = bend_ * setup.baseBend() * qOverPtOverBend;
88  // qOverPt uncertainty in 1/cm
89  const double dQoverPt = setup.bendCut() * qOverPtOverBend;
90  const double minPt = hybrid_ ? setup.hybridMinPt() : setup.minPt();
91  const double maxQoverPt = setup.invPtToDphi() / minPt - setup.dtcBaseQoverPt() / 2.;
92  double qOverPtMin = digi(qOverPt - dQoverPt, setup.dtcBaseQoverPt());
93  double qOverPtMax = digi(qOverPt + dQoverPt, setup.dtcBaseQoverPt());
94  if (qOverPtMin >= maxQoverPt || qOverPtMax < -maxQoverPt)
95  // did not pass pt cut
96  valid_ = false;
97  else {
98  qOverPtMin = max(qOverPtMin, -maxQoverPt);
99  qOverPtMax = min(qOverPtMax, maxQoverPt);
100  }
101  // range of stub qOverPt in 1/cm
102  qOverPt_ = {qOverPtMin, qOverPtMax};
103 
104  // stub phi w.r.t. detector region centre in rad
105  phi_ = c_ + rowSub_ * m_;
106 
107  // range of stub extrapolated phi to radius chosenRofPhi in rad
108  phiT_.first = phi_ + r_ * qOverPt_.first;
109  phiT_.second = phi_ + r_ * qOverPt_.second;
110  if (phiT_.first > phiT_.second)
111  swap(phiT_.first, phiT_.second);
112 
113  if (phiT_.first < 0.)
114  regions_.push_back(0);
115  if (phiT_.second >= 0.)
116  regions_.push_back(1);
117 
118  // apply data format specific manipulations
119  if (!hybrid_)
120  return;
121 
122  // stub r w.r.t. an offset in cm
123  r_ -= sm->offsetR() - chosenRofPhi;
124  // stub z w.r.t. an offset in cm
125  z_ -= sm->offsetZ();
126  if (sm->type() == SensorModule::Disk2S) {
127  // encoded r
128  r_ = sm->encodedR() + (sm->side() ? -col_ : (col_ + sm->numColumns() / 2));
129  r_ = (r_ + 0.5) * setup.hybridBaseR(sm->type());
130  }
131 
132  // encode bend
133  const vector<double>& encodingBend = setup.encodingBend(sm->windowSize(), sm->psModule());
134  const auto pos = find(encodingBend.begin(), encodingBend.end(), abs(ttStubRef->bendBE()));
135  const int uBend = distance(encodingBend.begin(), pos);
136  bend_ = pow(-1, signbit(bend_)) * uBend;
137  }
138 
139  // returns bit accurate representation of Stub
141 
142  // returns true if stub belongs to region
143  bool Stub::inRegion(int region) const { return find(regions_.begin(), regions_.end(), region) != regions_.end(); }
144 
145  // truncates double precision to f/w integer equivalent
146  double Stub::digi(double value, double precision) const { return (floor(value / precision) + .5) * precision; }
147 
148  // returns 64 bit stub in hybrid data format
150  const SensorModule::Type type = sm_->type();
151  // stub phi w.r.t. processing region centre in rad
152  const double phi = phi_ - (region - .5) * setup_->baseRegion() +
153  0.5 * setup_->hybridBasePhi(type) * (1 << setup_->hybridWidthPhi(type));
154 
155  // convert stub variables into bit vectors
156  const TTBV hwR(r_, setup_->hybridBaseR(type), setup_->hybridWidthR(type), true);
157  const TTBV hwPhi(phi, setup_->hybridBasePhi(type), setup_->hybridWidthPhi(type), true);
158  const TTBV hwZ(z_, setup_->hybridBaseZ(type), setup_->hybridWidthZ(type), true);
159  const TTBV hwAlpha(row_, setup_->hybridBaseAlpha(type), setup_->hybridWidthAlpha(type), true);
160  const TTBV hwBend(bend_, setup_->hybridWidthBend(type), true);
161  const TTBV hwLayer(sm_->encodedLayerId(), setup_->hybridWidthLayer());
162  const TTBV hwGap(0, setup_->hybridNumUnusedBits(type));
163  const TTBV hwValid(1, 1);
164  // assemble final bitset
165  return TTDTC::BV(hwGap.str() + hwR.str() + hwZ.str() + hwPhi.str() + hwAlpha.str() + hwBend.str() + hwLayer.str() +
166  hwValid.str());
167  }
168 
170  int layerM = sm_->layerId();
171  // convert unique layer id [1-6,11-15] into reduced layer id [0-6]
172  // a fiducial track may not cross more then 7 detector layers, for stubs from a given track the reduced layer id is actually unique
173  int layer(-1);
174  if (layerM == 1)
175  layer = 0;
176  else if (layerM == 2)
177  layer = 1;
178  else if (layerM == 6 || layerM == 11)
179  layer = 2;
180  else if (layerM == 5 || layerM == 12)
181  layer = 3;
182  else if (layerM == 4 || layerM == 13)
183  layer = 4;
184  else if (layerM == 14)
185  layer = 5;
186  else if (layerM == 3 || layerM == 15)
187  layer = 6;
188  // assign stub to phi sectors within a processing region, to be generalized
189  TTBV sectorsPhi(0, setup_->numOverlappingRegions() * setup_->numSectorsPhi());
190  if (phiT_.first < 0.) {
191  if (phiT_.first < -setup_->baseSector())
192  sectorsPhi.set(0);
193  else
194  sectorsPhi.set(1);
195  if (phiT_.second < 0. && phiT_.second >= -setup_->baseSector())
196  sectorsPhi.set(1);
197  }
198  if (phiT_.second >= 0.) {
199  if (phiT_.second < setup_->baseSector())
200  sectorsPhi.set(2);
201  else
202  sectorsPhi.set(3);
203  if (phiT_.first >= 0. && phiT_.first < setup_->baseSector())
204  sectorsPhi.set(2);
205  }
206  // assign stub to eta sectors within a processing region
207  pair<int, int> setcorEta({0, setup_->numSectorsEta() - 1});
208  for (int bin = 0; bin < setup_->numSectorsEta(); bin++)
209  if (asinh(cot_.first) < setup_->boundarieEta(bin + 1)) {
210  setcorEta.first = bin;
211  break;
212  }
213  for (int bin = setcorEta.first; bin < setup_->numSectorsEta(); bin++)
214  if (asinh(cot_.second) < setup_->boundarieEta(bin + 1)) {
215  setcorEta.second = bin;
216  break;
217  }
218  // stub phi w.r.t. processing region centre in rad
219  const double phi = phi_ - (region - .5) * setup_->baseRegion();
220  // convert stub variables into bit vectors
221  const TTBV hwValid(1, 1);
222  const TTBV hwGap(0, setup_->dtcNumUnusedBits());
223  const TTBV hwLayer(layer, setup_->widthLayer());
224  const TTBV hwSectorEtaMin(setcorEta.first, setup_->widthSectorEta());
225  const TTBV hwSectorEtaMax(setcorEta.second, setup_->widthSectorEta());
226  const TTBV hwR(r_, setup_->baseR(), setup_->widthR(), true);
227  const TTBV hwPhi(phi, setup_->basePhi(), setup_->widthPhiDTC(), true);
228  const TTBV hwZ(z_, setup_->baseZ(), setup_->widthZ(), true);
229  const TTBV hwQoverPtMin(qOverPt_.first, setup_->htBaseQoverPt(), setup_->htWidthQoverPt(), true);
230  const TTBV hwQoverPtMax(qOverPt_.second, setup_->htBaseQoverPt(), setup_->htWidthQoverPt(), true);
231  TTBV hwSectorPhis(0, setup_->numSectorsPhi());
232  for (int sectorPhi = 0; sectorPhi < setup_->numSectorsPhi(); sectorPhi++)
233  hwSectorPhis[sectorPhi] = sectorsPhi[region * setup_->numSectorsPhi() + sectorPhi];
234  // assemble final bitsetTTDTC::BV(hwGap.str() + hwValid.str() + hwR.str() + hwPhi.str() + hwZ.str() + hwQoverPtMin.str() +
235  return TTDTC::BV(hwGap.str() + hwValid.str() + hwR.str() + hwPhi.str() + hwZ.str() + hwQoverPtMin.str() +
236  hwQoverPtMax.str() + hwSectorEtaMin.str() + hwSectorEtaMax.str() + hwSectorPhis.str() +
237  hwLayer.str());
238  }
239 
240 } // namespace trackerDTC
const Setup * setup_
Definition: Stub.h:37
int numSectorsPhi() const
Definition: Setup.h:269
int widthR() const
Definition: Setup.h:124
double offsetR() const
Definition: SensorModule.h:67
double hybridBaseR(SensorModule::Type type) const
Definition: Setup.h:163
double r_
Definition: Stub.h:57
Bit vector used by Track Trigger emulators. Mainly used to convert integers into arbitrary (within ma...
Definition: TTBV.h:18
int widthZ() const
Definition: Setup.h:128
double baseR() const
Definition: Setup.h:132
int rowSub_
Definition: Stub.h:55
double baseSector() const
Definition: Setup.h:279
int hybridWidthPhi(SensorModule::Type type) const
Definition: Setup.h:155
int htWidthQoverPt() const
Definition: Setup.h:300
int widthPhiDTC() const
Definition: Setup.h:260
std::bitset< TTBV::S > BV
Definition: TTDTC.h:20
T x() const
Definition: PV2DBase.h:43
bool hybrid_
Definition: Stub.h:43
bool inRegion(int region) const
Definition: Stub.cc:143
static const uint16_t valid_
Definition: Constants.h:17
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
std::vector< int > regions_
Definition: Stub.h:75
double phi_
Definition: Stub.h:59
int dtcNumUnusedBits() const
Definition: Setup.h:138
double c_
Definition: Stub.h:65
double m_
Definition: Stub.h:63
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
double pitchCol() const
Definition: SensorModule.h:55
double htBaseQoverPt() const
Definition: Setup.h:306
constexpr std::array< uint8_t, layerIndexSize > layer
T y() const
Definition: PV2DBase.h:44
int hybridWidthR(SensorModule::Type type) const
Definition: Setup.h:151
int widthSectorEta() const
Definition: Setup.h:285
double d_
Definition: Stub.h:67
bool valid_
Definition: Stub.h:45
std::string str() const
Definition: TTBV.h:211
T sqrt(T t)
Definition: SSEVec.h:19
double pitchRow() const
Definition: SensorModule.h:53
int hybridWidthZ(SensorModule::Type type) const
Definition: Setup.h:153
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double hybridBasePhi(SensorModule::Type type) const
Definition: Setup.h:165
double hybridBaseZ(SensorModule::Type type) const
Definition: Setup.h:167
Definition: value.py:1
Class to process and provide run-time constants used by Track Trigger emulators.
Definition: Setup.h:42
double basePhi() const
Definition: Setup.h:136
TTDTC::BV formatHybrid(int region) const
Definition: Stub.cc:149
TTBV & set()
Definition: TTBV.h:156
int rowLUT_
Definition: Stub.h:53
std::pair< double, double > phiT_
Definition: Stub.h:73
std::pair< double, double > qOverPt_
Definition: Stub.h:69
TTDTC::BV frame(int region) const
Definition: Stub.cc:140
double baseZ() const
Definition: Setup.h:134
int encodedLayerId() const
Definition: SensorModule.h:65
SensorModule * sm_
Definition: Stub.h:39
double hybridBaseAlpha(SensorModule::Type type) const
Definition: Setup.h:169
int numSectorsEta() const
Definition: Setup.h:271
TTStubRef ttStubRef() const
Definition: Stub.h:18
int hybridWidthLayer() const
Definition: Setup.h:161
Definition: DTC.h:10
HLT enums.
double z_
Definition: Stub.h:61
double digi(double value, double precision) const
Definition: Stub.cc:146
std::pair< double, double > cot_
Definition: Stub.h:71
float x
double offsetZ() const
Definition: SensorModule.h:69
int hybridNumUnusedBits(SensorModule::Type type) const
Definition: Setup.h:171
int numOverlappingRegions() const
Definition: Setup.h:222
int hybridWidthBend(SensorModule::Type type) const
Definition: Setup.h:159
TTDTC::BV formatTMTT(int region) const
Definition: Stub.cc:169
int widthLayer() const
Definition: Setup.h:130
double baseRegion() const
Definition: Setup.h:99
int hybridWidthAlpha(SensorModule::Type type) const
Definition: Setup.h:157
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
double boundarieEta(int eta) const
Definition: Setup.h:277