CMS 3D CMS Logo

CSCSectorReceiverLUT.cc
Go to the documentation of this file.
7 
12 
14 
16 
17 #include <fstream>
18 #include <cstring>
19 
22 
24  int endcap, int sector, int subsector, int station, const edm::ParameterSet& pset, bool TMB07)
25  : _endcap(endcap), _sector(sector), _subsector(subsector), _station(station), isTMB07(TMB07) {
26  LUTsFromFile = pset.getUntrackedParameter<bool>("ReadLUTs", false);
27  useMiniLUTs = pset.getUntrackedParameter<bool>("UseMiniLUTs", true);
28  isBinary = pset.getUntrackedParameter<bool>("Binary", false);
29 
30  me_global_eta = nullptr;
31  me_global_phi = nullptr;
32  mb_global_phi = nullptr;
33  if (LUTsFromFile && !useMiniLUTs) {
34  me_lcl_phi_file = pset.getUntrackedParameter<edm::FileInPath>(
35  "LocalPhiLUT",
36  edm::FileInPath(std::string("L1Trigger/CSCTrackFinder/LUTs/LocalPhiLUT" +
37  (isBinary ? std::string(".bin") : std::string(".dat")))));
38  me_gbl_phi_file = pset.getUntrackedParameter<edm::FileInPath>(
39  "GlobalPhiLUTME",
40  edm::FileInPath((std::string("L1Trigger/CSCTrackFinder/LUTs/GlobalPhiME") + encodeFileIndex() +
41  (isBinary ? std::string(".bin") : std::string(".dat")))));
42  if (station == 1)
43  mb_gbl_phi_file = pset.getUntrackedParameter<edm::FileInPath>(
44  "GlobalPhiLUTMB",
45  edm::FileInPath((std::string("L1Trigger/CSCTrackFinder/LUTs/GlobalPhiMB") + encodeFileIndex() +
46  (isBinary ? std::string(".bin") : std::string(".dat")))));
47  me_gbl_eta_file = pset.getUntrackedParameter<edm::FileInPath>(
48  "GlobalEtaLUTME",
49  edm::FileInPath((std::string("L1Trigger/CSCTrackFinder/LUTs/GlobalEtaME") + encodeFileIndex() +
50  (isBinary ? std::string(".bin") : std::string(".dat")))));
52  }
53 }
54 
56  : _endcap(lut._endcap),
57  _sector(lut._sector),
58  _subsector(lut._subsector),
59  _station(lut._station),
60  me_lcl_phi_file(lut.me_lcl_phi_file),
61  me_gbl_phi_file(lut.me_gbl_phi_file),
62  mb_gbl_phi_file(lut.mb_gbl_phi_file),
63  me_gbl_eta_file(lut.me_gbl_eta_file),
64  LUTsFromFile(lut.LUTsFromFile),
65  isBinary(lut.isBinary) {
66  if (lut.mb_global_phi) {
69  } else
70  mb_global_phi = nullptr;
71  if (lut.me_global_phi) {
74  } else
75  me_global_phi = nullptr;
76  if (lut.me_global_eta) {
79  } else
80  me_global_eta = nullptr;
81 }
82 
84  if (this != &lut) {
85  _endcap = lut._endcap;
86  _sector = lut._sector;
87  _subsector = lut._subsector;
88  _station = lut._station;
94  isBinary = lut.isBinary;
95 
96  if (lut.mb_global_phi) {
99  } else
100  mb_global_phi = nullptr;
101 
102  if (lut.me_global_phi) {
105  } else
106  me_global_phi = nullptr;
107 
108  if (lut.me_global_eta) {
111  } else
112  me_global_eta = nullptr;
113  }
114  return *this;
115 }
116 
118  if (me_lcl_phi_loaded) {
119  delete me_lcl_phi;
120  me_lcl_phi = nullptr;
121  me_lcl_phi_loaded = false;
122  }
123  if (me_global_eta) {
124  delete me_global_eta;
125  me_global_eta = nullptr;
126  }
127  if (me_global_phi) {
128  delete me_global_phi;
129  me_global_phi = nullptr;
130  }
131  if (mb_global_phi) {
132  delete mb_global_phi;
133  mb_global_phi = nullptr;
134  }
135 }
136 
138  lclphidat data;
139 
140  constexpr int maxPhiL = 1 << CSCBitWidths::kLocalPhiDataBitWidth;
141  double binPhiL = static_cast<double>(maxPhiL) / (2. * CSCConstants::MAX_NUM_STRIPS_RUN1);
142 
143  double patternOffset;
144 
145  patternOffset = CSCPatternBank::getLegacyPosition((theadd.pattern_type << 3) + theadd.clct_pattern);
146 
147  // The phiL value stored is for the center of the half-/di-strip.
148  if (theadd.strip < 2 * CSCConstants::MAX_NUM_STRIPS_RUN1)
149  if (theadd.pattern_type == 1 || isTMB07) // if halfstrip (Note: no distrips in TMB 2007 patterns)
150  data.phi_local = static_cast<unsigned>((0.5 + theadd.strip + patternOffset) * binPhiL);
151  else // if distrip
152  data.phi_local = static_cast<unsigned>((2 + theadd.strip + 4. * patternOffset) * binPhiL);
153  else {
154  throw cms::Exception("CSCSectorReceiverLUT") << "+++ Value of strip, " << theadd.strip << ", exceeds max allowed, "
155  << 2 * CSCConstants::MAX_NUM_STRIPS_RUN1 - 1 << " +++\n";
156  }
157 
158  if (data.phi_local >= maxPhiL) {
159  throw cms::Exception("CSCSectorReceiverLUT")
160  << "+++ Value of phi_local, " << data.phi_local << ", exceeds max allowed, " << maxPhiL - 1 << " +++\n";
161  }
162 
163  LogDebug("CSCSectorReceiver") << "endcap = " << _endcap << " station = " << _station << " maxPhiL = " << maxPhiL
164  << " binPhiL = " << binPhiL;
165  LogDebug("CSCSectorReceiver") << "strip # " << theadd.strip << " hs/ds = " << theadd.pattern_type
166  << " pattern = " << theadd.clct_pattern << " offset = " << patternOffset
167  << " phi_local = " << data.phi_local;
168 
170  data.phi_bend_local = 0;
171 
172  return data; //return LUT result
173 }
174 
176  // read data in from a file... Add this later.
177 }
178 
180  const int strip, const int pattern, const int quality, const int lr, const bool gangedME1a) const {
181  lclphiadd theadd;
182 
183  theadd.strip = strip;
184  theadd.clct_pattern = pattern & 0x7;
185  theadd.pattern_type = (pattern & 0x8) >> 3;
186  theadd.quality = quality;
187  theadd.lr = lr;
188  theadd.spare = 0;
189 
190  return localPhi(theadd, gangedME1a);
191 }
192 
193 lclphidat CSCSectorReceiverLUT::localPhi(unsigned address, const bool gangedME1a) const {
195  lclphiadd theadd(address);
196 
197  if (useMiniLUTs && isTMB07) {
199  } else if (LUTsFromFile)
200  result = me_lcl_phi[address];
201  else
202  result = calcLocalPhi(theadd);
203 
204  return result;
205 }
206 
209 
210  if (useMiniLUTs && isTMB07) {
212  } else if (LUTsFromFile)
213  result = me_lcl_phi[address.toint()];
214  else
215  result = calcLocalPhi(address);
216 
217  return result;
218 }
219 
221  const unsigned& strip,
222  const unsigned& wire_group) const {
223  double result = 0.0;
224  //CSCLayerGeometry* thegeom;
225  //LocalPoint lp;
226  //GlobalPoint gp;
227 
228  try {
229  //thegeom = const_cast<CSCLayerGeometry*>(thelayer->geometry());
230  //lp = thegeom->stripWireGroupIntersection(strip, wire_group);
231  //gp = thelayer->surface().toGlobal(lp);
232  result = thelayer->centerOfStrip(strip).phi(); //gp.phi();
233 
234  if (result < 0.)
235  result += 2. * M_PI;
236  } catch (edm::Exception& e) {
237  LogDebug("CSCSectorReceiverLUT|getGlobalPhiValue") << e.what();
238  }
239 
240  return result;
241 }
242 
244  gblphidat result(0);
245  const CSCChamber* thechamber = nullptr;
246  const CSCLayer* thelayer = nullptr;
247  const CSCLayerGeometry* layergeom = nullptr;
248  int cscid = address.cscid;
249  unsigned wire_group = address.wire_group;
250  unsigned local_phi = address.phi_local;
251  const double sectorOffset =
253 
254  //Number of global phi units per radian.
255  constexpr int maxPhiG = 1 << CSCBitWidths::kGlobalPhiDataBitWidth;
256  double binPhiG = static_cast<double>(maxPhiG) / CSCTFConstants::SECTOR_RAD;
257 
258  // We will use these to convert the local phi into radians.
259  constexpr unsigned int maxPhiL = 1 << CSCBitWidths::kLocalPhiDataBitWidth;
260  const double binPhiL = static_cast<double>(maxPhiL) / (2. * CSCConstants::MAX_NUM_STRIPS_RUN1);
261 
262  if (cscid < CSCTriggerNumbering::minTriggerCscId()) {
263  edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
264  << " warning: cscId " << cscid << " is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
266  throw cms::Exception("CSCSectorReceiverLUT")
267  << "+++ Value of CSC ID, " << cscid << ", is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
268  << CSCTriggerNumbering::maxTriggerCscId() << "] +++\n";
269  }
270 
271  if (cscid > CSCTriggerNumbering::maxTriggerCscId()) {
272  edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
273  << " warning: cscId " << cscid << " is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
275  throw cms::Exception("CSCSectorReceiverLUT")
276  << "+++ Value of CSC ID, " << cscid << ", is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
277  << CSCTriggerNumbering::maxTriggerCscId() << "] +++\n";
278  }
279 
280  if (wire_group >= 1 << 5) {
281  edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
282  << "warning: wire_group" << wire_group << " is out of bounds (1-" << ((1 << 5) - 1) << "]\n";
283  throw cms::Exception("CSCSectorReceiverLUT")
284  << "+++ Value of wire_group, " << wire_group << ", is out of bounds (1-" << ((1 << 5) - 1) << "] +++\n";
285  }
286 
287  if (local_phi >= maxPhiL) {
288  edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
289  << "warning: local_phi" << local_phi << " is out of bounds [0-" << maxPhiL << ")\n";
290  throw cms::Exception("CSCSectorReceiverLUT")
291  << "+++ Value of local_phi, " << local_phi << ", is out of bounds [0-, " << maxPhiL << ") +++\n";
292  }
293 
294  try {
297  CSCDetId detid(_endcap, _station, ring, chid, 0);
298  thechamber = const_cast<const CSCChamber*>(csc_g->chamber(detid));
299  if (thechamber) {
300  layergeom = thechamber->layer(CSCConstants::KEY_CLCT_LAYER)->geometry();
301  thelayer = thechamber->layer(CSCConstants::KEY_CLCT_LAYER);
302  const int nStrips = layergeom->numberOfStrips();
303  // PhiL is the strip number converted into some units between 0 and
304  // 1023. When we did the conversion in fillLocalPhiTable(), we did
305  // not know for which chamber we do it (and, therefore, how many strips
306  // it has), and always used the maximum possible number of strips
307  // per chamber, MAX_NUM_STRIPS_RUN1=80. Now, since we know the chamber id
308  // and how many strips the chamber has, we can re-adjust the scale.
309  //const double scale = static_cast<double>(CSCConstants::MAX_NUM_STRIPS_RUN1)/nStrips;
310 
311  int strip = 0, halfstrip = 0;
312 
313  halfstrip = static_cast<int>(local_phi / binPhiL);
314  strip = halfstrip / 2;
315 
316  // Find the phi width of the chamber and the position of its "left"
317  // (lower phi) edge (both in radians).
318  // Phi positions of the centers of the first and of the last strips
319  // in the chamber.
320  const double phi_f = getGlobalPhiValue(thelayer, 1, wire_group);
321  const double phi_l = getGlobalPhiValue(thelayer, nStrips, wire_group);
322  // Phi widths of the half-strips at both ends of the chamber;
323  // surprisingly, they are not the same.
324  const double hsWidth_f = fabs(getGlobalPhiValue(thelayer, 2, wire_group) - phi_f) / 2.;
325  const double hsWidth_l = fabs(phi_l - getGlobalPhiValue(thelayer, nStrips - 1, wire_group)) / 2.;
326 
327  // The "natural" match between the strips and phi values -- when
328  // a larger strip number corresponds to a larger phi value, i.e. strips
329  // are counted clockwise if we look at them from the inside of the
330  // detector -- is reversed for some stations. At the moment, these
331  // are stations 3 and 4 of the 1st endcap, and stations 1 and 2 of
332  // the 2nd endcap. Instead of using
333  // if ((theEndcap == 1 && theStation <= 2) ||
334  // (theEndcap == 2 && theStation >= 3)),
335  // we get the order from the phi values of the first and the last strip
336  // in a chamber, just in case the counting scheme changes in the future.
337  // Once we know how the strips are counted, we can go from the middle
338  // of the strips to their outer edges.
339  bool clockwiseOrder;
340  double leftEdge, rightEdge;
341  if (fabs(phi_f - phi_l) < M_PI) {
342  if (phi_f < phi_l)
343  clockwiseOrder = true;
344  else
345  clockwiseOrder = false;
346  } else { // the chamber crosses the phi = pi boundary
347  if (phi_f < phi_l)
348  clockwiseOrder = false;
349  else
350  clockwiseOrder = true;
351  }
352  if (clockwiseOrder) {
353  leftEdge = phi_f - hsWidth_f;
354  rightEdge = phi_l + hsWidth_l;
355  } else {
356  leftEdge = phi_l - hsWidth_l;
357  rightEdge = phi_f + hsWidth_f;
358  }
359  if (fabs(phi_f - phi_l) >= M_PI) {
360  rightEdge += 2. * M_PI;
361  }
362  //double chamberWidth = (rightEdge - leftEdge);
363 
364  // Chamber offset, relative to the edge of the sector.
365  //double chamberOffset = leftEdge - sectorOffset;
366  //if (chamberOffset < -M_PI) chamberOffset += 2*M_PI;
367 
368  double temp_phi = 0.0, strip_phi = 0.0, delta_phi = 0.0;
369  double distFromHalfStripCenter = 0.0, halfstripWidth = 0.0;
370 
371  if (strip < nStrips) {
372  // Approximate distance from the center of the half-strip to the center
373  // of this phil bin, in units of half-strip width.
374  distFromHalfStripCenter = (local_phi + 0.5) / binPhiL - halfstrip - 0.5;
375  // Half-strip width (in rad), calculated as the half-distance between
376  // the adjacent strips. Since in the current ORCA implementation
377  // the half-strip width changes from strip to strip, base the choice
378  // of the adjacent strip on the half-strip number.
379  if ((halfstrip % 2 == 0 && halfstrip != 0) || halfstrip == 2 * nStrips - 1) {
380  halfstripWidth = fabs(getGlobalPhiValue(thelayer, strip + 1, wire_group) -
381  getGlobalPhiValue(thelayer, strip, wire_group)) /
382  2.;
383  } else {
384  halfstripWidth = fabs(getGlobalPhiValue(thelayer, strip + 1, wire_group) -
385  getGlobalPhiValue(thelayer, strip + 2, wire_group)) /
386  2.;
387  }
388  // Correction for the strips crossing the 180 degree boundary.
389  if (halfstripWidth > M_PI / 2.)
390  halfstripWidth = M_PI - halfstripWidth;
391  // Phi at the center of the strip.
392  strip_phi = getGlobalPhiValue(thelayer, strip + 1, wire_group);
393  // Distance between the center of the strip and the phil position.
394  delta_phi = halfstripWidth * (((halfstrip % 2) - 0.5) + distFromHalfStripCenter);
395  if (clockwiseOrder)
396  temp_phi = strip_phi + delta_phi;
397  else
398  temp_phi = strip_phi - delta_phi;
399  } else {
400  // PhiL values that do not have corresponding strips (the chamber
401  // has less than 80 strips assumed in fillLocalPhi). It does not
402  // really matter what we do with these values; at the moment, just
403  // set them to the phis of the edges of the chamber.
404  if (clockwiseOrder)
405  temp_phi = rightEdge;
406  else
407  temp_phi = leftEdge;
408  }
409 
410  // Finally, subtract the sector offset and convert to the scale of
411  // the global phi.
412 
413  temp_phi -= sectorOffset;
414 
415  if (temp_phi < 0.)
416  temp_phi += 2. * M_PI;
417 
418  temp_phi *= binPhiG;
419 
420  if (temp_phi < 0.) {
421  result.global_phi = 0;
422  } else if (temp_phi >= maxPhiG) {
423  result.global_phi = maxPhiG - 1;
424  } else {
425  result.global_phi = static_cast<unsigned short>(temp_phi);
426  }
427 
428  LogDebug("CSCSectorReceiverLUT") << "local_phi = " << local_phi << " halfstrip = " << halfstrip
429  << " strip = " << strip
430  << " distFromHalfStripCenter = " << distFromHalfStripCenter
431  << " halfstripWidth = " << halfstripWidth
432  << " strip phi = " << strip_phi / (M_PI / 180.)
433  << " temp_phi = " << temp_phi * CSCTFConstants::SECTOR_DEG / maxPhiG
434  << " global_phi = " << result.global_phi << " "
435  << result.global_phi * CSCTFConstants::SECTOR_DEG / maxPhiG;
436  }
437  } catch (edm::Exception& e) {
438  edm::LogError("CSCSectorReceiverLUT|getGlobalPhiValue") << e.what();
439  }
440 
441  return result;
442 }
443 
444 gblphidat CSCSectorReceiverLUT::globalPhiME(int phi_local, int wire_group, int cscid, const bool gangedME1a) const {
446  gblphiadd theadd;
447  theadd.phi_local = phi_local;
448  theadd.wire_group = ((1 << 5) - 1) & (wire_group >> 2); // want 2-7 of wg
449  theadd.cscid = cscid;
450 
451  if (useMiniLUTs && isTMB07)
453  _endcap, _sector, _station, _subsector, theadd.toint(), gangedME1a);
454  else if (LUTsFromFile)
455  result = me_global_phi[theadd.toint()];
456  else
457  result = calcGlobalPhiME(theadd);
458 
459  return result;
460 }
461 
462 gblphidat CSCSectorReceiverLUT::globalPhiME(unsigned address, const bool gangedME1a) const {
464 
465  if (useMiniLUTs && isTMB07)
467  else if (LUTsFromFile)
468  result = me_global_phi[address];
469  else
470  result = calcGlobalPhiME(gblphiadd(address));
471 
472  return result;
473 }
474 
477 
478  if (useMiniLUTs && isTMB07)
480  _endcap, _sector, _station, _subsector, address.toint(), gangedME1a);
481  else if (LUTsFromFile)
482  result = me_global_phi[address.toint()];
483  else
484  result = calcGlobalPhiME(address);
485 
486  return result;
487 }
488 
490  gblphidat dtlut;
491 
492  // The following method was ripped from D. Holmes' LUT conversion program
493  // modifications from Darin and GP
494  int GlobalPhiMin = (_subsector == 1) ? 0x42 : 0x800; // (0.999023 : 31 in degrees)
495  int GlobalPhiMax = (_subsector == 1) ? 0x7ff : 0xfbd; // (30.985 : 60.986 in degrees)
496  double GlobalPhiShift = (1.0 * GlobalPhiMin + (GlobalPhiMax - GlobalPhiMin) / 2.0);
497 
498  double dt_out = static_cast<double>(csclut.global_phi) - GlobalPhiShift;
499 
500  // these numbers are 62 deg / 1 rad (CSC phi scale vs. DT phi scale)
501  dt_out = (dt_out / 1982) * 2145; //CSC phi 62 degrees; DT phi 57.3 degrees
502 
503  if (dt_out >= 0) // msb != 1
504  {
505  dtlut.global_phi = 0x7ff & static_cast<unsigned>(dt_out);
506  } else {
507  dtlut.global_phi = static_cast<unsigned>(-dt_out);
508  dtlut.global_phi = ~dtlut.global_phi;
509  dtlut.global_phi |= 0x800;
510  }
511 
512  return dtlut;
513 }
514 
515 gblphidat CSCSectorReceiverLUT::globalPhiMB(int phi_local, int wire_group, int cscid, const bool gangedME1a) const {
516  gblphiadd address;
518 
519  address.cscid = cscid;
520  address.wire_group = ((1 << 5) - 1) & (wire_group >> 2);
521  address.phi_local = phi_local;
522 
523  // comment for now
524  // if(useMiniLUTs && isTMB07) result = CSCSectorReceiverMiniLUT::calcGlobalPhiMBMini(_endcap, _sector, _subsector, address.toint());
525  //else
526  if (LUTsFromFile)
527  result = mb_global_phi[address.toint()];
528  else
530 
531  return result;
532 }
533 
534 gblphidat CSCSectorReceiverLUT::globalPhiMB(unsigned address, const bool gangedME1a) const {
536  gblphiadd theadd(address);
537 
538  //if(useMiniLUTs && isTMB07) result = CSCSectorReceiverMiniLUT::calcGlobalPhiMBMini(_endcap, _sector, _subsector, address);
539  //else
540  if (LUTsFromFile)
541  result = mb_global_phi[theadd.toint()];
542  else
544 
545  return result;
546 }
547 
550 
551  //if(useMiniLUTs && isTMB07) result = CSCSectorReceiverMiniLUT::calcGlobalPhiMBMini(_endcap, _sector, _subsector, address.toint());
552  //else
553  if (LUTsFromFile)
554  result = mb_global_phi[address.toint()];
555  else
557 
558  return result;
559 }
560 
561 double CSCSectorReceiverLUT::getGlobalEtaValue(const unsigned& thecscid,
562  const unsigned& thewire_group,
563  const unsigned& thephi_local) const {
564  double result = 0.0;
565  unsigned wire_group = thewire_group;
566  int cscid = thecscid;
567  unsigned phi_local = thephi_local;
568 
569  // Flag to be set if one wants to apply phi corrections ONLY in ME1/1.
570  // Turn it into a parameter?
571  bool me1ir_only = false;
572 
574  edm::LogWarning("CSCSectorReceiverLUT|getEtaValue")
575  << " warning: cscId " << cscid << " is out of bounds [1-" << CSCTriggerNumbering::maxTriggerCscId() << "]\n";
577  }
578 
579  CSCLayerGeometry* layerGeom = nullptr;
580  const unsigned numBins = 1 << 2; // 4 local phi bins
581 
582  if (phi_local > numBins - 1) {
583  edm::LogWarning("CSCSectorReceiverLUT|getEtaValue")
584  << "warning: phiL " << phi_local << " is out of bounds [0-" << numBins - 1 << "]\n";
585  phi_local = numBins - 1;
586  }
587  try {
590  CSCDetId detid(_endcap, _station, ring, chid, 0);
591  const CSCChamber* thechamber = const_cast<const CSCChamber*>(csc_g->chamber(detid));
592  if (thechamber) {
593  layerGeom = const_cast<CSCLayerGeometry*>(thechamber->layer(CSCConstants::KEY_ALCT_LAYER)->geometry());
594  const unsigned nWireGroups = layerGeom->numberOfWireGroups();
595 
596  // Check wire group numbers; expect them to be counted from 0, as in
597  // CorrelatedLCTDigi class.
598  if (wire_group >= nWireGroups) {
599  edm::LogWarning("CSCSectorReceiverLUT|getEtaValue")
600  << "warning: wireGroup " << wire_group << " is out of bounds [0-" << nWireGroups << ")\n";
601  wire_group = nWireGroups - 1;
602  }
603  // Convert to [1; nWireGroups] range used in geometry methods.
604  wire_group += 1;
605 
606  // If me1ir_only is set, apply phi corrections only in ME1/1.
607  if (me1ir_only && (_station != 1 || CSCTriggerNumbering::ringFromTriggerLabels(_station, cscid) != 1)) {
608  result = thechamber->layer(CSCConstants::KEY_ALCT_LAYER)->centerOfWireGroup(wire_group).eta();
609  } else {
610  const unsigned nStrips = layerGeom->numberOfStrips();
611  const unsigned nStripsPerBin = CSCConstants::MAX_NUM_STRIPS_RUN1 / numBins;
616  // Check that no strips will be left out.
617  if (nStrips % numBins != 0 || CSCConstants::MAX_NUM_STRIPS_RUN1 % numBins != 0)
618  edm::LogWarning("CSCSectorReceiverLUT")
619  << "getGlobalEtaValue warning: number of strips " << nStrips << " (" << CSCConstants::MAX_NUM_STRIPS_RUN1
620  << ") is not divisible by numBins " << numBins << " Station " << _station << " sector " << _sector
621  << " subsector " << _subsector << " cscid " << cscid << "\n";
622 
623  unsigned maxStripPrevBin = 0, maxStripThisBin = 0;
624  unsigned correctionStrip;
625  LocalPoint lPoint;
626  GlobalPoint gPoint;
627  // Bins phi_local and find the the middle strip for each bin.
628  maxStripThisBin = nStripsPerBin * (phi_local + 1);
629  if (maxStripThisBin <= nStrips) {
630  correctionStrip = nStripsPerBin / 2 * (2 * phi_local + 1);
631  } else {
632  // If the actual number of strips in the chamber is smaller than
633  // the number of strips corresponding to the right edge of this phi
634  // local bin, we take the middle strip between number of strips
635  // at the left edge of the bin and the actual number of strips.
636  maxStripPrevBin = nStripsPerBin * phi_local;
637  correctionStrip = (nStrips + maxStripPrevBin) / 2;
638  }
639 
640  lPoint = layerGeom->stripWireGroupIntersection(correctionStrip, wire_group);
641  gPoint = thechamber->layer(CSCConstants::KEY_ALCT_LAYER)->surface().toGlobal(lPoint);
642 
643  // end calc of eta correction.
644  result = gPoint.eta();
645  }
646  }
647  } catch (cms::Exception& e) {
648  LogDebug("CSCSectorReceiver|OutofBoundInput") << e.what();
649  }
650 
651  return std::fabs(result);
652 }
653 
656  double float_eta = getGlobalEtaValue(address.cscid, address.wire_group, address.phi_local);
657  unsigned int_eta = 0;
658  unsigned bend_global = 0; // not filled yet... will change when it is.
660  const unsigned me12EtaCut = 56;
661 
662  if ((float_eta < CSCTFConstants::minEta) || (float_eta >= CSCTFConstants::maxEta)) {
663  edm::LogWarning("CSCSectorReceiverLUT:OutOfBounds")
664  << "CSCSectorReceiverLUT warning: float_eta = " << float_eta << " minEta = " << CSCTFConstants::minEta
665  << " maxEta = " << CSCTFConstants::maxEta << " station " << _station << " sector " << _sector << " chamber "
666  << address.cscid << " wire group " << address.wire_group;
667 
668  throw cms::Exception("CSCSectorReceiverLUT")
669  << "+++ Value of CSC ID, " << float_eta << ", is out of bounds [" << CSCTFConstants::minEta << "-"
670  << CSCTFConstants::maxEta << ") +++\n";
671 
672  //if (float_eta < CSCTFConstants::minEta)
673  //result.global_eta = 0;
674  //else if (float_eta >= CSCTFConstants::maxEta)
675  //result.global_eta = CSCTFConstants::etaBins - 1;
676  } else {
677  float_eta -= CSCTFConstants::minEta;
678  float_eta = float_eta / etaPerBin;
679  int_eta = static_cast<unsigned>(float_eta);
680  /* Commented until I find out its use.
681  // Fine-tune eta boundary between DT and CSC.
682  if ((intEta == L1MuCSCSetup::CscEtaStart() && (L1MuCSCSetup::CscEtaStartCorr() > 0.) ) ||
683  (intEta == L1MuCSCSetup::CscEtaStart() - 1 && (L1MuCSCSetup::CscEtaStartCorr() < 0.) ) ) {
684  bitEta = (thisEta-minEta-L1MuCSCSetup::CscEtaStartCorr())/EtaPerBin;
685  intEta = static_cast<int>(bitEta);
686  }
687  */
688  if (_station == 1 && address.cscid >= static_cast<unsigned>(CSCTriggerNumbering::minTriggerCscId()) &&
689  address.cscid <= static_cast<unsigned>(CSCTriggerNumbering::maxTriggerCscId())) {
690  unsigned ring = CSCTriggerNumbering::ringFromTriggerLabels(_station, address.cscid);
691 
692  if (ring == 1 && int_eta < me12EtaCut) {
693  int_eta = me12EtaCut;
694  } else if (ring == 2 && int_eta >= me12EtaCut) {
695  int_eta = me12EtaCut - 1;
696  }
697  }
698  result.global_eta = int_eta;
699  }
700  result.global_bend = bend_global;
701 
702  return result;
703 }
704 
706  int tphi_bend, int tphi_local, int twire_group, int tcscid, const bool gangedME1a) const {
708  gbletaadd theadd;
709 
710  theadd.phi_bend = tphi_bend;
711  theadd.phi_local = (tphi_local >> (CSCBitWidths::kLocalPhiDataBitWidth - 2)) & 0x3; // want 2 msb of local phi
712  theadd.wire_group = twire_group;
713  theadd.cscid = tcscid;
714  if (useMiniLUTs && isTMB07)
716  _endcap, _sector, _station, _subsector, theadd.toint(), gangedME1a);
717  else if (LUTsFromFile)
718  result = me_global_eta[theadd.toint()];
719  else
720  result = calcGlobalEtaME(theadd);
721 
722  return result;
723 }
724 
725 gbletadat CSCSectorReceiverLUT::globalEtaME(unsigned address, const bool gangedME1a) const {
727  gbletaadd theadd(address);
728 
729  if (useMiniLUTs && isTMB07)
731  else if (LUTsFromFile)
732  result = me_global_eta[address];
733  else
734  result = calcGlobalEtaME(theadd);
735  return result;
736 }
737 
740 
741  if (useMiniLUTs && isTMB07)
743  _endcap, _sector, _station, _subsector, address.toint(), gangedME1a);
744  else if (LUTsFromFile)
745  result = me_global_eta[address.toint()];
746  else
747  result = calcGlobalEtaME(address);
748  return result;
749 }
750 
752  std::string fileName = "";
753  if (_station == 1) {
754  if (_subsector == 1)
755  fileName += "1a";
756  if (_subsector == 2)
757  fileName += "1b";
758  } else if (_station == 2)
759  fileName += "2";
760  else if (_station == 3)
761  fileName += "3";
762  else if (_station == 4)
763  fileName += "4";
764  fileName += "End";
765  if (_endcap == 1)
766  fileName += "1";
767  else
768  fileName += "2";
769  fileName += "Sec";
770  if (_sector == 1)
771  fileName += "1";
772  else if (_sector == 2)
773  fileName += "2";
774  else if (_sector == 3)
775  fileName += "3";
776  else if (_sector == 4)
777  fileName += "4";
778  else if (_sector == 5)
779  fileName += "5";
780  else if (_sector == 6)
781  fileName += "6";
782  fileName += "LUT";
783  return fileName;
784 }
785 
787  if (!me_lcl_phi_loaded) {
790  std::ifstream LocalPhiLUT;
791 
792  edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
793 
794  if (isBinary) {
795  LocalPhiLUT.open(fName.c_str(), std::ios::binary);
796  LocalPhiLUT.seekg(0, std::ios::end);
797  int length = LocalPhiLUT.tellg();
798  if (length == (1 << CSCBitWidths::kLocalPhiAddressWidth) * sizeof(short)) {
799  LocalPhiLUT.seekg(0, std::ios::beg);
800  LocalPhiLUT.read(reinterpret_cast<char*>(me_lcl_phi), length);
801  LocalPhiLUT.close();
802  } else
803  edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
804  LocalPhiLUT.close();
805  } else {
806  LocalPhiLUT.open(fName.c_str());
807  unsigned i = 0;
808  unsigned short temp = 0;
809  while (!LocalPhiLUT.eof() && i < 1 << CSCBitWidths::kLocalPhiAddressWidth) {
810  LocalPhiLUT >> temp;
811  me_lcl_phi[i++] = temp;
812  }
813  LocalPhiLUT.close();
814  }
815  }
816  if (!me_global_phi) {
819  std::ifstream GlobalPhiLUT;
820 
821  edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
822 
823  if (isBinary) {
824  GlobalPhiLUT.open(fName.c_str(), std::ios::binary);
825  GlobalPhiLUT.seekg(0, std::ios::end);
826  int length = GlobalPhiLUT.tellg();
827  if (length == (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(short)) {
828  GlobalPhiLUT.seekg(0, std::ios::beg);
829  GlobalPhiLUT.read(reinterpret_cast<char*>(me_global_phi), length);
830  } else
831  edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
832  GlobalPhiLUT.close();
833  } else {
834  GlobalPhiLUT.open(fName.c_str());
835  unsigned short temp = 0;
836  unsigned i = 0;
837  while (!GlobalPhiLUT.eof() && i < 1 << CSCBitWidths::kGlobalPhiAddressWidth) {
838  GlobalPhiLUT >> temp;
839  me_global_phi[i++] = temp;
840  }
841  GlobalPhiLUT.close();
842  }
843  }
844  if (!mb_global_phi && _station == 1) // MB lut only in station one.
845  {
848  std::ifstream GlobalPhiLUT;
849 
850  edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
851 
852  if (isBinary) {
853  GlobalPhiLUT.open(fName.c_str(), std::ios::binary);
854  GlobalPhiLUT.seekg(0, std::ios::end);
855  int length = GlobalPhiLUT.tellg();
856  if (length == (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(short)) {
857  GlobalPhiLUT.seekg(0, std::ios::beg);
858  GlobalPhiLUT.read(reinterpret_cast<char*>(mb_global_phi), length);
859  } else
860  edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
861  GlobalPhiLUT.close();
862  } else {
863  GlobalPhiLUT.open(fName.c_str());
864  unsigned short temp = 0;
865  unsigned i = 0;
866  while (!GlobalPhiLUT.eof() && i < 1 << CSCBitWidths::kGlobalPhiAddressWidth) {
867  GlobalPhiLUT >> temp;
868  mb_global_phi[i++] = temp;
869  }
870  GlobalPhiLUT.close();
871  }
872  }
873  if (!me_global_eta) {
876  std::ifstream GlobalEtaLUT;
877 
878  edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
879 
880  if (isBinary) {
881  GlobalEtaLUT.open(fName.c_str(), std::ios::binary);
882  GlobalEtaLUT.seekg(0, std::ios::end);
883  int length = GlobalEtaLUT.tellg();
884  if (length == (1 << CSCBitWidths::kGlobalEtaAddressWidth) * sizeof(short)) {
885  GlobalEtaLUT.seekg(0, std::ios::beg);
886  GlobalEtaLUT.read(reinterpret_cast<char*>(me_global_eta), length);
887  } else
888  edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
889  GlobalEtaLUT.close();
890  } else {
891  GlobalEtaLUT.open(fName.c_str());
892  unsigned short temp = 0;
893  unsigned i = 0;
894  while (!GlobalEtaLUT.eof() && i < 1 << CSCBitWidths::kGlobalEtaAddressWidth) {
895  GlobalEtaLUT >> temp;
896  me_global_eta[i++] = temp;
897  }
898  GlobalEtaLUT.close();
899  }
900  }
901 }
const CSCLayer * layer(CSCDetId id) const
Return the layer corresponding to the given id.
Definition: CSCChamber.cc:30
static global_phi_data calcGlobalPhiMEMini(unsigned short endcap, unsigned short sector, unsigned short station, unsigned short subsector, unsigned theadd, const bool gangedME1a)
const CSCChamber * chamber(CSCDetId id) const
Return the chamber corresponding to given DetId.
Definition: CSCGeometry.cc:100
std::string fullPath() const
Definition: FileInPath.cc:161
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
T eta() const
Definition: PV3DBase.h:73
static const double minEta
gblphidat globalPhiMB(int phi_local, int wire_group, int cscid, const bool gangedME1a=false) const
Log< level::Error, false > LogError
class global_phi_address gblphiadd
edm::FileInPath mb_gbl_phi_file
gbletadat calcGlobalEtaME(const gbletaadd &address) const
Global Eta LUT.
CSCSectorReceiverLUT & operator=(const CSCSectorReceiverLUT &)
static int ringFromTriggerLabels(int station, int triggerCSCID)
nStrips
1.2 is to make the matching window safely the two nearest strips 0.35 is the size of an ME0 chamber i...
const CSCLayerGeometry * geometry() const
Definition: CSCLayer.h:44
std::string encodeFileIndex() const
Helpers.
lclphidat calcLocalPhi(const lclphiadd &address) const
Local Phi LUT.
double getGlobalPhiValue(const CSCLayer *thelayer, const unsigned &strip, const unsigned &wire_group) const
static const double SECTOR1_CENT_RAD
int numberOfStrips() const
int numberOfWireGroups() const
edm::FileInPath me_gbl_phi_file
edm::FileInPath me_lcl_phi_file
CSCSectorReceiverLUT(int endcap, int sector, int subsector, int station, const edm::ParameterSet &pset, bool TMB07)
static const double maxEta
static lclphidat calcLocalPhiMini(unsigned theadd, const bool gangedME1a)
#define M_PI
GlobalPoint toGlobal(const Point2DBase< Scalar, LocalTag > lp) const
Definition: Surface.h:79
Log< level::Info, false > LogInfo
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
gblphidat calcGlobalPhiME(const gblphiadd &address) const
Global Phi LUT.
edm::FileInPath me_gbl_eta_file
static const double SECTOR_DEG
static lclphidat * me_lcl_phi
double getGlobalEtaValue(const unsigned &cscid, const unsigned &wire_group, const unsigned &phi_local) const
class global_phi_data gblphidat
class local_phi_address lclphiadd
class local_phi_data lclphidat
Data Types.
gblphidat globalPhiME(int phi_local, int wire_group, int cscid, const bool gangedME1a=false) const
static double getLegacyPosition(int pattern)
gblphidat calcGlobalPhiMB(const gblphidat &me_gphi_data) const
lclphidat localPhi(int strip, int pattern, int quality, int lr, const bool gangedME1a=false) const
Geometry Lookup Tables.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
LocalPoint stripWireGroupIntersection(int strip, int wireGroup) const
class global_eta_address gbletaadd
static const double SECTOR_RAD
gbletadat globalEtaME(int phi_bend, int phi_local, int wire_group, int cscid, const bool gangedME1a=false) const
GlobalPoint centerOfStrip(int strip) const
Definition: CSCLayer.cc:4
Log< level::Warning, false > LogWarning
string quality
class global_eta_data gbletadat
const CSCGeometry * csc_g
static global_eta_data calcGlobalEtaMEMini(unsigned short endcap, unsigned short sector, unsigned short station, unsigned short subsector, unsigned theadd, const bool gangedME1a)
static int chamberFromTriggerLabels(int TriggerSector, int TriggerSubSector, int station, int TriggerCSCID)
GlobalPoint centerOfWireGroup(int wireGroup) const
Definition: CSCLayer.cc:10
#define LogDebug(id)