CMS 3D CMS Logo

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