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