CMS 3D CMS Logo

OmtfAngleConverter.cc
Go to the documentation of this file.
1 /*
2  * OmtfAngleConverter.cpp
3  *
4  * Created on: Jan 14, 2019
5  * Author: kbunkow
6  */
7 
9 
12 
15 
19 
24 
25 namespace {
26  template <typename T>
27  int sgn(T val) {
28  return (T(0) < val) - (val < T(0));
29  }
30 
31  //DT eta bins in the wheel +2
32  const std::vector<float> bounds = {1.24, 1.14353, 1.09844, 1.05168, 1.00313, 0.952728, 0.90037, 0.8};
33  // 0.8 -> 73
34  // 0.85 -> 78
35  // 0.9265 -> 85
36  // 0.9779 -> 89.9 -> 90
37  // 1.0274 -> 94.4 -> 94
38  // 1.07506 -> 98.9 -> 99
39  // 1.121 -> 103
40  // 1.2 -> 110
41  // 1.25 -> 115
42  //
43  // other (1.033) -> 1.033 -> 95
44 
45  int etaVal2Bit(float eta) { return bounds.rend() - std::lower_bound(bounds.rbegin(), bounds.rend(), fabs(eta)); }
46 
47  int etaBit2Code(unsigned int bit) {
48  int code = 73;
49  switch (bit) {
50  case 0: {
51  code = 115;
52  break;
53  }
54  case 1: {
55  code = 110;
56  break;
57  }
58  case 2: {
59  code = 103;
60  break;
61  }
62  case 3: {
63  code = 99;
64  break;
65  }
66  case 4: {
67  code = 94;
68  break;
69  }
70  case 5: {
71  code = 90;
72  break;
73  }
74  case 6: {
75  code = 85;
76  break;
77  }
78  case 7: {
79  code = 78;
80  break;
81  }
82  case 8: {
83  code = 73;
84  break;
85  }
86  default: {
87  code = 95;
88  break;
89  }
90  }
91  return code;
92  }
93 
94  int etaVal2Code(double etaVal) {
95  int sign = sgn(etaVal);
96  int bit = etaVal2Bit(fabs(etaVal));
97  int code = etaBit2Code(bit);
98  return sign * code;
99  }
100 
101  int etaKeyWG2Code(const CSCDetId &detId, uint16_t keyWG) {
102  signed int etaCode = 121;
103  if (detId.station() == 1 && detId.ring() == 2) {
104  if (keyWG < 49)
105  etaCode = 121;
106  else if (keyWG <= 57)
107  etaCode = etaBit2Code(0);
108  else if (keyWG <= 63)
109  etaCode = etaBit2Code(1);
110  } else if (detId.station() == 1 && detId.ring() == 3) {
111  if (keyWG <= 2)
112  etaCode = etaBit2Code(2);
113  else if (keyWG <= 8)
114  etaCode = etaBit2Code(3);
115  else if (keyWG <= 15)
116  etaCode = etaBit2Code(4);
117  else if (keyWG <= 23)
118  etaCode = etaBit2Code(5);
119  else if (keyWG <= 31)
120  etaCode = etaBit2Code(6);
121  } else if ((detId.station() == 2 || detId.station() == 3) && detId.ring() == 2) {
122  if (keyWG < 24)
123  etaCode = 121;
124  else if (keyWG <= 29)
125  etaCode = etaBit2Code(0);
126  else if (keyWG <= 43)
127  etaCode = etaBit2Code(1);
128  else if (keyWG <= 49)
129  etaCode = etaBit2Code(2);
130  else if (keyWG <= 56)
131  etaCode = etaBit2Code(3);
132  else if (keyWG <= 63)
133  etaCode = etaBit2Code(4);
134  }
135 
136  if (detId.endcap() == 2)
137  etaCode *= -1;
138  return etaCode;
139  }
140 
141 } //namespace
142 
144 
148  const L1MuDTChambThContainer *dtThDigis,
149  int bxNum) const {
150  //const DTChamberId dTChamberId(aDigi.whNum(),aDigi.stNum(),aDigi.scNum()+1);
151  DTTrigGeom trig_geom(_geodt->chamber(dTChamberId), false);
152 
153  // super layer one is the theta superlayer in a DT chamber
154  // station 4 does not have a theta super layer
155  // the BTI index from the theta trigger is an OR of some BTI outputs
156  // so, we choose the BTI that's in the middle of the group
157  // as the BTI that we get theta from
158  // TODO:::::>>> need to make sure this ordering doesn't flip under wheel sign
159  const int NBTI_theta = ((dTChamberId.station() != 4) ? trig_geom.nCell(2) : trig_geom.nCell(3));
160 
161  const L1MuDTChambThDigi *theta_segm =
162  dtThDigis->chThetaSegm(dTChamberId.wheel(), dTChamberId.station(), dTChamberId.sector() - 1, bxNum);
163 
164  int bti_group = -1;
165  if (theta_segm) {
166  for (unsigned int i = 0; i < 7; ++i)
167  if (theta_segm->position(i) && bti_group < 0)
168  bti_group = i;
169  else if (theta_segm->position(i) && bti_group > -1)
170  bti_group = 511;
171  }
172 
173  int iEta = 0;
174  if (bti_group == 511)
175  iEta = 95;
176  else if (bti_group == -1 && dTChamberId.station() == 1)
177  iEta = 92;
178  else if (bti_group == -1 && dTChamberId.station() == 2)
179  iEta = 79;
180  else if (bti_group == -1 && dTChamberId.station() == 3)
181  iEta = 75;
182  else if (dTChamberId.station() != 4 && bti_group >= 0) {
183  unsigned bti_actual = bti_group * NBTI_theta / 7 + NBTI_theta / 14 + 1;
184  DTBtiId thetaBTI = DTBtiId(dTChamberId, 2, bti_actual);
185  GlobalPoint theta_gp = trig_geom.CMSPosition(thetaBTI);
186  iEta = etaVal2Code(fabs(theta_gp.eta()));
187  }
188  int signEta = sgn(dTChamberId.wheel());
189  iEta *= signEta;
190  return iEta;
191 }
192 
195 int OmtfAngleConverter::getGlobalEta(unsigned int rawid, const CSCCorrelatedLCTDigi &aDigi) const {
199 
200  // a lot of this is transcription and consolidation of the CSC
201  // global phi calculation code
202  // this works directly with the geometry
203  // rather than using the old phi luts
204  const CSCDetId id(rawid);
205  // we should change this to weak_ptrs at some point
206  // requires introducing std::shared_ptrs to geometry
207  auto chamb = _geocsc->chamber(id);
208  auto layer_geom = chamb->layer(CSCConstants::KEY_ALCT_LAYER)->geometry();
209  auto layer = chamb->layer(CSCConstants::KEY_ALCT_LAYER);
210 
211  const uint16_t halfstrip = aDigi.getStrip();
212  //const uint16_t pattern = aDigi.getPattern();
213  const uint16_t keyWG = aDigi.getKeyWG();
214  //const unsigned maxStrips = layer_geom->numberOfStrips();
215 
216  // so we can extend this later
217  // assume TMB2007 half-strips only as baseline
218  double offset = 0.0;
219  //K.B. CSCPatternLUT is removed since CMSSW_11_2_1, but it looks that this offset is effectively not needed here
220  //offset = CSCPatternLUT::get2007Position(pattern);
221 
222  const unsigned halfstrip_offs = unsigned(0.5 + halfstrip + offset);
223  const unsigned strip = halfstrip_offs / 2 + 1; // geom starts from 1
224 
225  // the rough location of the hit at the ALCT key layer
226  // we will refine this using the half strip information
227  const LocalPoint coarse_lp = layer_geom->stripWireGroupIntersection(strip, keyWG);
228  const GlobalPoint coarse_gp = layer->surface().toGlobal(coarse_lp);
229 
230  // the strip width/4.0 gives the offset of the half-strip
231  // center with respect to the strip center
232  const double hs_offset = layer_geom->stripPhiPitch() / 4.0;
233 
234  // determine handedness of the chamber
235  const bool ccw = isCSCCounterClockwise(layer);
236  // we need to subtract the offset of even half strips and add the odd ones
237  const double phi_offset = ((halfstrip_offs % 2 ? 1 : -1) * (ccw ? -hs_offset : hs_offset));
238 
239  // the global eta calculation uses the middle of the strip
240  // so no need to increment it
241  const GlobalPoint final_gp(
242  GlobalPoint::Polar(coarse_gp.theta(), (coarse_gp.phi().value() + phi_offset), coarse_gp.mag()));
243 
244  // LogTrace("l1tOmtfEventPrint")<<id<<" st: " << id.station()<< "ri: "<<id.ring()<<" eta: " << final_gp.eta()
245  // <<" etaCode_simple: " << etaVal2Code( final_gp.eta() )<< " KW: "<<keyWG <<" etaKeyWG2Code: "<<etaKeyWG2Code(id,keyWG)<< std::endl;
246  // int station = (id.endcap()==1) ? id.station() : -id.station();
247  // LogTrace("l1tOmtfEventPrint")<<"ETA_CSC: " << station <<" "<<id.ring()<<" "<< final_gp.eta()<<" "<<keyWG <<" "<< etaKeyWG2Code(id,keyWG) << std::endl;
248 
249  return etaKeyWG2Code(id, keyWG);
250 }
253 int OmtfAngleConverter::getGlobalEtaRpc(unsigned int rawid, const unsigned int &strip) const {
254  const RPCDetId id(rawid);
255  auto roll = _georpc->roll(id);
256  const LocalPoint lp = roll->centreOfStrip((int)strip);
257  const GlobalPoint gp = roll->toGlobal(lp);
258 
259  return etaVal2Code(gp.eta());
260 }
261 
int station() const
Return the station number.
Definition: DTChamberId.h:42
edm::ESHandle< DTGeometry > _geodt
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:30
L1MuDTChambThDigi const * chThetaSegm(int wheel, int stat, int sect, int bx) const
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:100
virtual int getGlobalEtaRpc(unsigned int rawid, const unsigned int &aDigi) const
Convert local eta coordinate to global digital microGMT scale.
float sgn(float val)
Definition: FWPFMaths.cc:9
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
virtual int getGlobalEta(const DTChamberId dTChamberId, const L1MuDTChambThContainer *dtThDigis, int bxNum) const
edm::ESHandle< RPCGeometry > _georpc
T eta() const
Definition: PV3DBase.h:73
int position(const int i) const
const RPCRoll * roll(RPCDetId id) const
Return a roll given its id.
Definition: RPCGeometry.cc:50
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:44
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer
T mag() const
Definition: PV3DBase.h:64
uint16_t getStrip(uint16_t n=2) const
return the key halfstrip from 0,159
int station() const
Definition: CSCDetId.h:79
int endcap() const
Definition: CSCDetId.h:85
edm::ESHandle< CSCGeometry > _geocsc
uint16_t getKeyWG() const
return the key wire group. counts from 0.
int wheel() const
Return the wheel number.
Definition: DTChamberId.h:39
int sector() const
Definition: DTChamberId.h:49
virtual bool isCSCCounterClockwise(const CSCLayer *layer) const
Check orientation of strips in given CSC chamber.
int ring() const
Definition: CSCDetId.h:68
T1 value() const
Explicit access to value in case implicit conversion not OK.
Definition: Phi.h:75
long double T
const DTChamber * chamber(const DTChamberId &id) const
Return a DTChamber given its id.
Definition: DTGeometry.cc:90
Geom::Theta< T > theta() const
Definition: PV3DBase.h:72