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