File indexing completed on 2024-04-06 12:19:28
0001 #include "L1Trigger/CSCTrackFinder/interface/CSCSectorReceiverLUT.h"
0002 #include "L1Trigger/CSCTrackFinder/interface/CSCSectorReceiverMiniLUT.h"
0003 #include "L1Trigger/CSCTriggerPrimitives/interface/CSCPatternBank.h"
0004 #include "DataFormats/L1CSCTrackFinder/interface/CSCBitWidths.h"
0005 #include "DataFormats/L1CSCTrackFinder/interface/CSCTFConstants.h"
0006 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0007
0008 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
0009 #include "Geometry/CSCGeometry/interface/CSCLayerGeometry.h"
0010 #include "DataFormats/GeometryVector/interface/LocalPoint.h"
0011 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0012
0013 #include "DataFormats/MuonDetId/interface/CSCTriggerNumbering.h"
0014
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016
0017 #include <fstream>
0018 #include <cstring>
0019
0020 lclphidat* CSCSectorReceiverLUT::me_lcl_phi = nullptr;
0021 bool CSCSectorReceiverLUT::me_lcl_phi_loaded = false;
0022
0023 CSCSectorReceiverLUT::CSCSectorReceiverLUT(
0024 int endcap, int sector, int subsector, int station, const edm::ParameterSet& pset, bool TMB07)
0025 : _endcap(endcap), _sector(sector), _subsector(subsector), _station(station), isTMB07(TMB07) {
0026 LUTsFromFile = pset.getUntrackedParameter<bool>("ReadLUTs", false);
0027 useMiniLUTs = pset.getUntrackedParameter<bool>("UseMiniLUTs", true);
0028 isBinary = pset.getUntrackedParameter<bool>("Binary", false);
0029
0030 me_global_eta = nullptr;
0031 me_global_phi = nullptr;
0032 mb_global_phi = nullptr;
0033 if (LUTsFromFile && !useMiniLUTs) {
0034 me_lcl_phi_file = pset.getUntrackedParameter<edm::FileInPath>(
0035 "LocalPhiLUT",
0036 edm::FileInPath(std::string("L1Trigger/CSCTrackFinder/LUTs/LocalPhiLUT" +
0037 (isBinary ? std::string(".bin") : std::string(".dat")))));
0038 me_gbl_phi_file = pset.getUntrackedParameter<edm::FileInPath>(
0039 "GlobalPhiLUTME",
0040 edm::FileInPath((std::string("L1Trigger/CSCTrackFinder/LUTs/GlobalPhiME") + encodeFileIndex() +
0041 (isBinary ? std::string(".bin") : std::string(".dat")))));
0042 if (station == 1)
0043 mb_gbl_phi_file = pset.getUntrackedParameter<edm::FileInPath>(
0044 "GlobalPhiLUTMB",
0045 edm::FileInPath((std::string("L1Trigger/CSCTrackFinder/LUTs/GlobalPhiMB") + encodeFileIndex() +
0046 (isBinary ? std::string(".bin") : std::string(".dat")))));
0047 me_gbl_eta_file = pset.getUntrackedParameter<edm::FileInPath>(
0048 "GlobalEtaLUTME",
0049 edm::FileInPath((std::string("L1Trigger/CSCTrackFinder/LUTs/GlobalEtaME") + encodeFileIndex() +
0050 (isBinary ? std::string(".bin") : std::string(".dat")))));
0051 readLUTsFromFile();
0052 }
0053 }
0054
0055 CSCSectorReceiverLUT::CSCSectorReceiverLUT(const CSCSectorReceiverLUT& lut)
0056 : _endcap(lut._endcap),
0057 _sector(lut._sector),
0058 _subsector(lut._subsector),
0059 _station(lut._station),
0060 me_lcl_phi_file(lut.me_lcl_phi_file),
0061 me_gbl_phi_file(lut.me_gbl_phi_file),
0062 mb_gbl_phi_file(lut.mb_gbl_phi_file),
0063 me_gbl_eta_file(lut.me_gbl_eta_file),
0064 LUTsFromFile(lut.LUTsFromFile),
0065 isBinary(lut.isBinary) {
0066 if (lut.mb_global_phi) {
0067 mb_global_phi = new gblphidat[1 << CSCBitWidths::kGlobalPhiAddressWidth];
0068 memcpy(mb_global_phi, lut.mb_global_phi, (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(gblphidat));
0069 } else
0070 mb_global_phi = nullptr;
0071 if (lut.me_global_phi) {
0072 me_global_phi = new gblphidat[1 << CSCBitWidths::kGlobalPhiAddressWidth];
0073 memcpy(me_global_phi, lut.me_global_phi, (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(gblphidat));
0074 } else
0075 me_global_phi = nullptr;
0076 if (lut.me_global_eta) {
0077 me_global_eta = new gbletadat[1 << CSCBitWidths::kGlobalEtaAddressWidth];
0078 memcpy(me_global_eta, lut.me_global_eta, (1 << CSCBitWidths::kGlobalEtaAddressWidth) * sizeof(gbletadat));
0079 } else
0080 me_global_eta = nullptr;
0081 }
0082
0083 CSCSectorReceiverLUT& CSCSectorReceiverLUT::operator=(const CSCSectorReceiverLUT& lut) {
0084 if (this != &lut) {
0085 _endcap = lut._endcap;
0086 _sector = lut._sector;
0087 _subsector = lut._subsector;
0088 _station = lut._station;
0089 me_lcl_phi_file = lut.me_lcl_phi_file;
0090 me_gbl_phi_file = lut.me_gbl_phi_file;
0091 mb_gbl_phi_file = lut.mb_gbl_phi_file;
0092 me_gbl_eta_file = lut.me_gbl_eta_file;
0093 LUTsFromFile = lut.LUTsFromFile;
0094 isBinary = lut.isBinary;
0095
0096 if (lut.mb_global_phi) {
0097 mb_global_phi = new gblphidat[1 << CSCBitWidths::kGlobalPhiAddressWidth];
0098 memcpy(mb_global_phi, lut.mb_global_phi, (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(gblphidat));
0099 } else
0100 mb_global_phi = nullptr;
0101
0102 if (lut.me_global_phi) {
0103 me_global_phi = new gblphidat[1 << CSCBitWidths::kGlobalPhiAddressWidth];
0104 memcpy(me_global_phi, lut.me_global_phi, (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(gblphidat));
0105 } else
0106 me_global_phi = nullptr;
0107
0108 if (lut.me_global_eta) {
0109 me_global_eta = new gbletadat[1 << CSCBitWidths::kGlobalEtaAddressWidth];
0110 memcpy(me_global_eta, lut.me_global_eta, (1 << CSCBitWidths::kGlobalEtaAddressWidth) * sizeof(gbletadat));
0111 } else
0112 me_global_eta = nullptr;
0113 }
0114 return *this;
0115 }
0116
0117 CSCSectorReceiverLUT::~CSCSectorReceiverLUT() {
0118 if (me_lcl_phi_loaded) {
0119 delete me_lcl_phi;
0120 me_lcl_phi = nullptr;
0121 me_lcl_phi_loaded = false;
0122 }
0123 if (me_global_eta) {
0124 delete me_global_eta;
0125 me_global_eta = nullptr;
0126 }
0127 if (me_global_phi) {
0128 delete me_global_phi;
0129 me_global_phi = nullptr;
0130 }
0131 if (mb_global_phi) {
0132 delete mb_global_phi;
0133 mb_global_phi = nullptr;
0134 }
0135 }
0136
0137 lclphidat CSCSectorReceiverLUT::calcLocalPhi(const lclphiadd& theadd) const {
0138 lclphidat data;
0139
0140 constexpr int maxPhiL = 1 << CSCBitWidths::kLocalPhiDataBitWidth;
0141 double binPhiL = static_cast<double>(maxPhiL) / (2. * CSCConstants::MAX_NUM_STRIPS_RUN1);
0142
0143 double patternOffset;
0144
0145 patternOffset = CSCPatternBank::getLegacyPosition((theadd.pattern_type << 3) + theadd.clct_pattern);
0146
0147
0148 if (theadd.strip < 2 * CSCConstants::MAX_NUM_STRIPS_RUN1)
0149 if (theadd.pattern_type == 1 || isTMB07)
0150 data.phi_local = static_cast<unsigned>((0.5 + theadd.strip + patternOffset) * binPhiL);
0151 else
0152 data.phi_local = static_cast<unsigned>((2 + theadd.strip + 4. * patternOffset) * binPhiL);
0153 else {
0154 throw cms::Exception("CSCSectorReceiverLUT") << "+++ Value of strip, " << theadd.strip << ", exceeds max allowed, "
0155 << 2 * CSCConstants::MAX_NUM_STRIPS_RUN1 - 1 << " +++\n";
0156 }
0157
0158 if (data.phi_local >= maxPhiL) {
0159 throw cms::Exception("CSCSectorReceiverLUT")
0160 << "+++ Value of phi_local, " << data.phi_local << ", exceeds max allowed, " << maxPhiL - 1 << " +++\n";
0161 }
0162
0163 LogDebug("CSCSectorReceiver") << "endcap = " << _endcap << " station = " << _station << " maxPhiL = " << maxPhiL
0164 << " binPhiL = " << binPhiL;
0165 LogDebug("CSCSectorReceiver") << "strip # " << theadd.strip << " hs/ds = " << theadd.pattern_type
0166 << " pattern = " << theadd.clct_pattern << " offset = " << patternOffset
0167 << " phi_local = " << data.phi_local;
0168
0169
0170 data.phi_bend_local = 0;
0171
0172 return data;
0173 }
0174
0175 void CSCSectorReceiverLUT::fillLocalPhiLUT() {
0176
0177 }
0178
0179 lclphidat CSCSectorReceiverLUT::localPhi(
0180 const int strip, const int pattern, const int quality, const int lr, const bool gangedME1a) const {
0181 lclphiadd theadd;
0182
0183 theadd.strip = strip;
0184 theadd.clct_pattern = pattern & 0x7;
0185 theadd.pattern_type = (pattern & 0x8) >> 3;
0186 theadd.quality = quality;
0187 theadd.lr = lr;
0188 theadd.spare = 0;
0189
0190 return localPhi(theadd, gangedME1a);
0191 }
0192
0193 lclphidat CSCSectorReceiverLUT::localPhi(unsigned address, const bool gangedME1a) const {
0194 lclphidat result;
0195 lclphiadd theadd(address);
0196
0197 if (useMiniLUTs && isTMB07) {
0198 result = CSCSectorReceiverMiniLUT::calcLocalPhiMini(address, gangedME1a);
0199 } else if (LUTsFromFile)
0200 result = me_lcl_phi[address];
0201 else
0202 result = calcLocalPhi(theadd);
0203
0204 return result;
0205 }
0206
0207 lclphidat CSCSectorReceiverLUT::localPhi(lclphiadd address, const bool gangedME1a) const {
0208 lclphidat result;
0209
0210 if (useMiniLUTs && isTMB07) {
0211 result = CSCSectorReceiverMiniLUT::calcLocalPhiMini(address.toint(), gangedME1a);
0212 } else if (LUTsFromFile)
0213 result = me_lcl_phi[address.toint()];
0214 else
0215 result = calcLocalPhi(address);
0216
0217 return result;
0218 }
0219
0220 double CSCSectorReceiverLUT::getGlobalPhiValue(const CSCLayer* thelayer,
0221 const unsigned& strip,
0222 const unsigned& wire_group) const {
0223 double result = 0.0;
0224
0225
0226
0227
0228 try {
0229
0230
0231
0232 result = thelayer->centerOfStrip(strip).phi();
0233
0234 if (result < 0.)
0235 result += 2. * M_PI;
0236 } catch (edm::Exception& e) {
0237 LogDebug("CSCSectorReceiverLUT|getGlobalPhiValue") << e.what();
0238 }
0239
0240 return result;
0241 }
0242
0243 gblphidat CSCSectorReceiverLUT::calcGlobalPhiME(const gblphiadd& address) const {
0244 gblphidat result(0);
0245 const CSCChamber* thechamber = nullptr;
0246 const CSCLayer* thelayer = nullptr;
0247 const CSCLayerGeometry* layergeom = nullptr;
0248 int cscid = address.cscid;
0249 unsigned wire_group = address.wire_group;
0250 unsigned local_phi = address.phi_local;
0251 const double sectorOffset =
0252 (CSCTFConstants::SECTOR1_CENT_RAD - CSCTFConstants::SECTOR_RAD / 2.) + (_sector - 1) * M_PI / 3.;
0253
0254
0255 constexpr int maxPhiG = 1 << CSCBitWidths::kGlobalPhiDataBitWidth;
0256 double binPhiG = static_cast<double>(maxPhiG) / CSCTFConstants::SECTOR_RAD;
0257
0258
0259 constexpr unsigned int maxPhiL = 1 << CSCBitWidths::kLocalPhiDataBitWidth;
0260 const double binPhiL = static_cast<double>(maxPhiL) / (2. * CSCConstants::MAX_NUM_STRIPS_RUN1);
0261
0262 if (cscid < CSCTriggerNumbering::minTriggerCscId()) {
0263 edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
0264 << " warning: cscId " << cscid << " is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
0265 << CSCTriggerNumbering::maxTriggerCscId() << "]\n";
0266 throw cms::Exception("CSCSectorReceiverLUT")
0267 << "+++ Value of CSC ID, " << cscid << ", is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
0268 << CSCTriggerNumbering::maxTriggerCscId() << "] +++\n";
0269 }
0270
0271 if (cscid > CSCTriggerNumbering::maxTriggerCscId()) {
0272 edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
0273 << " warning: cscId " << cscid << " is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
0274 << CSCTriggerNumbering::maxTriggerCscId() << "]\n";
0275 throw cms::Exception("CSCSectorReceiverLUT")
0276 << "+++ Value of CSC ID, " << cscid << ", is out of bounds [" << CSCTriggerNumbering::minTriggerCscId() << "-"
0277 << CSCTriggerNumbering::maxTriggerCscId() << "] +++\n";
0278 }
0279
0280 if (wire_group >= 1 << 5) {
0281 edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
0282 << "warning: wire_group" << wire_group << " is out of bounds (1-" << ((1 << 5) - 1) << "]\n";
0283 throw cms::Exception("CSCSectorReceiverLUT")
0284 << "+++ Value of wire_group, " << wire_group << ", is out of bounds (1-" << ((1 << 5) - 1) << "] +++\n";
0285 }
0286
0287 if (local_phi >= maxPhiL) {
0288 edm::LogWarning("CSCSectorReceiverLUT|getGlobalPhiValue")
0289 << "warning: local_phi" << local_phi << " is out of bounds [0-" << maxPhiL << ")\n";
0290 throw cms::Exception("CSCSectorReceiverLUT")
0291 << "+++ Value of local_phi, " << local_phi << ", is out of bounds [0-, " << maxPhiL << ") +++\n";
0292 }
0293
0294 try {
0295 int ring = CSCTriggerNumbering::ringFromTriggerLabels(_station, cscid);
0296 int chid = CSCTriggerNumbering::chamberFromTriggerLabels(_sector, _subsector, _station, cscid);
0297 CSCDetId detid(_endcap, _station, ring, chid, 0);
0298 thechamber = const_cast<const CSCChamber*>(csc_g->chamber(detid));
0299 if (thechamber) {
0300 layergeom = thechamber->layer(CSCConstants::KEY_CLCT_LAYER)->geometry();
0301 thelayer = thechamber->layer(CSCConstants::KEY_CLCT_LAYER);
0302 const int nStrips = layergeom->numberOfStrips();
0303
0304
0305
0306
0307
0308
0309
0310
0311 int strip = 0, halfstrip = 0;
0312
0313 halfstrip = static_cast<int>(local_phi / binPhiL);
0314 strip = halfstrip / 2;
0315
0316
0317
0318
0319
0320 const double phi_f = getGlobalPhiValue(thelayer, 1, wire_group);
0321 const double phi_l = getGlobalPhiValue(thelayer, nStrips, wire_group);
0322
0323
0324 const double hsWidth_f = fabs(getGlobalPhiValue(thelayer, 2, wire_group) - phi_f) / 2.;
0325 const double hsWidth_l = fabs(phi_l - getGlobalPhiValue(thelayer, nStrips - 1, wire_group)) / 2.;
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 bool clockwiseOrder;
0340 double leftEdge, rightEdge;
0341 if (fabs(phi_f - phi_l) < M_PI) {
0342 if (phi_f < phi_l)
0343 clockwiseOrder = true;
0344 else
0345 clockwiseOrder = false;
0346 } else {
0347 if (phi_f < phi_l)
0348 clockwiseOrder = false;
0349 else
0350 clockwiseOrder = true;
0351 }
0352 if (clockwiseOrder) {
0353 leftEdge = phi_f - hsWidth_f;
0354 rightEdge = phi_l + hsWidth_l;
0355 } else {
0356 leftEdge = phi_l - hsWidth_l;
0357 rightEdge = phi_f + hsWidth_f;
0358 }
0359 if (fabs(phi_f - phi_l) >= M_PI) {
0360 rightEdge += 2. * M_PI;
0361 }
0362
0363
0364
0365
0366
0367
0368 double temp_phi = 0.0, strip_phi = 0.0, delta_phi = 0.0;
0369 double distFromHalfStripCenter = 0.0, halfstripWidth = 0.0;
0370
0371 if (strip < nStrips) {
0372
0373
0374 distFromHalfStripCenter = (local_phi + 0.5) / binPhiL - halfstrip - 0.5;
0375
0376
0377
0378
0379 if ((halfstrip % 2 == 0 && halfstrip != 0) || halfstrip == 2 * nStrips - 1) {
0380 halfstripWidth = fabs(getGlobalPhiValue(thelayer, strip + 1, wire_group) -
0381 getGlobalPhiValue(thelayer, strip, wire_group)) /
0382 2.;
0383 } else {
0384 halfstripWidth = fabs(getGlobalPhiValue(thelayer, strip + 1, wire_group) -
0385 getGlobalPhiValue(thelayer, strip + 2, wire_group)) /
0386 2.;
0387 }
0388
0389 if (halfstripWidth > M_PI / 2.)
0390 halfstripWidth = M_PI - halfstripWidth;
0391
0392 strip_phi = getGlobalPhiValue(thelayer, strip + 1, wire_group);
0393
0394 delta_phi = halfstripWidth * (((halfstrip % 2) - 0.5) + distFromHalfStripCenter);
0395 if (clockwiseOrder)
0396 temp_phi = strip_phi + delta_phi;
0397 else
0398 temp_phi = strip_phi - delta_phi;
0399 } else {
0400
0401
0402
0403
0404 if (clockwiseOrder)
0405 temp_phi = rightEdge;
0406 else
0407 temp_phi = leftEdge;
0408 }
0409
0410
0411
0412
0413 temp_phi -= sectorOffset;
0414
0415 if (temp_phi < 0.)
0416 temp_phi += 2. * M_PI;
0417
0418 temp_phi *= binPhiG;
0419
0420 if (temp_phi < 0.) {
0421 result.global_phi = 0;
0422 } else if (temp_phi >= maxPhiG) {
0423 result.global_phi = maxPhiG - 1;
0424 } else {
0425 result.global_phi = static_cast<unsigned short>(temp_phi);
0426 }
0427
0428 LogDebug("CSCSectorReceiverLUT") << "local_phi = " << local_phi << " halfstrip = " << halfstrip
0429 << " strip = " << strip
0430 << " distFromHalfStripCenter = " << distFromHalfStripCenter
0431 << " halfstripWidth = " << halfstripWidth
0432 << " strip phi = " << strip_phi / (M_PI / 180.)
0433 << " temp_phi = " << temp_phi * CSCTFConstants::SECTOR_DEG / maxPhiG
0434 << " global_phi = " << result.global_phi << " "
0435 << result.global_phi * CSCTFConstants::SECTOR_DEG / maxPhiG;
0436 }
0437 } catch (edm::Exception& e) {
0438 edm::LogError("CSCSectorReceiverLUT|getGlobalPhiValue") << e.what();
0439 }
0440
0441 return result;
0442 }
0443
0444 gblphidat CSCSectorReceiverLUT::globalPhiME(int phi_local, int wire_group, int cscid, const bool gangedME1a) const {
0445 gblphidat result;
0446 gblphiadd theadd;
0447 theadd.phi_local = phi_local;
0448 theadd.wire_group = ((1 << 5) - 1) & (wire_group >> 2);
0449 theadd.cscid = cscid;
0450
0451 if (useMiniLUTs && isTMB07)
0452 result = CSCSectorReceiverMiniLUT::calcGlobalPhiMEMini(
0453 _endcap, _sector, _station, _subsector, theadd.toint(), gangedME1a);
0454 else if (LUTsFromFile)
0455 result = me_global_phi[theadd.toint()];
0456 else
0457 result = calcGlobalPhiME(theadd);
0458
0459 return result;
0460 }
0461
0462 gblphidat CSCSectorReceiverLUT::globalPhiME(unsigned address, const bool gangedME1a) const {
0463 gblphidat result;
0464
0465 if (useMiniLUTs && isTMB07)
0466 result = CSCSectorReceiverMiniLUT::calcGlobalPhiMEMini(_endcap, _sector, _station, _subsector, address, gangedME1a);
0467 else if (LUTsFromFile)
0468 result = me_global_phi[address];
0469 else
0470 result = calcGlobalPhiME(gblphiadd(address));
0471
0472 return result;
0473 }
0474
0475 gblphidat CSCSectorReceiverLUT::globalPhiME(gblphiadd address, const bool gangedME1a) const {
0476 gblphidat result;
0477
0478 if (useMiniLUTs && isTMB07)
0479 result = CSCSectorReceiverMiniLUT::calcGlobalPhiMEMini(
0480 _endcap, _sector, _station, _subsector, address.toint(), gangedME1a);
0481 else if (LUTsFromFile)
0482 result = me_global_phi[address.toint()];
0483 else
0484 result = calcGlobalPhiME(address);
0485
0486 return result;
0487 }
0488
0489 gblphidat CSCSectorReceiverLUT::calcGlobalPhiMB(const gblphidat& csclut) const {
0490 gblphidat dtlut;
0491
0492
0493
0494 int GlobalPhiMin = (_subsector == 1) ? 0x42 : 0x800;
0495 int GlobalPhiMax = (_subsector == 1) ? 0x7ff : 0xfbd;
0496 double GlobalPhiShift = (1.0 * GlobalPhiMin + (GlobalPhiMax - GlobalPhiMin) / 2.0);
0497
0498 double dt_out = static_cast<double>(csclut.global_phi) - GlobalPhiShift;
0499
0500
0501 dt_out = (dt_out / 1982) * 2145;
0502
0503 if (dt_out >= 0)
0504 {
0505 dtlut.global_phi = 0x7ff & static_cast<unsigned>(dt_out);
0506 } else {
0507 dtlut.global_phi = static_cast<unsigned>(-dt_out);
0508 dtlut.global_phi = ~dtlut.global_phi;
0509 dtlut.global_phi |= 0x800;
0510 }
0511
0512 return dtlut;
0513 }
0514
0515 gblphidat CSCSectorReceiverLUT::globalPhiMB(int phi_local, int wire_group, int cscid, const bool gangedME1a) const {
0516 gblphiadd address;
0517 gblphidat result;
0518
0519 address.cscid = cscid;
0520 address.wire_group = ((1 << 5) - 1) & (wire_group >> 2);
0521 address.phi_local = phi_local;
0522
0523
0524
0525
0526 if (LUTsFromFile)
0527 result = mb_global_phi[address.toint()];
0528 else
0529 result = calcGlobalPhiMB(globalPhiME(address, gangedME1a));
0530
0531 return result;
0532 }
0533
0534 gblphidat CSCSectorReceiverLUT::globalPhiMB(unsigned address, const bool gangedME1a) const {
0535 gblphidat result;
0536 gblphiadd theadd(address);
0537
0538
0539
0540 if (LUTsFromFile)
0541 result = mb_global_phi[theadd.toint()];
0542 else
0543 result = calcGlobalPhiMB(globalPhiME(address, gangedME1a));
0544
0545 return result;
0546 }
0547
0548 gblphidat CSCSectorReceiverLUT::globalPhiMB(gblphiadd address, const bool gangedME1a) const {
0549 gblphidat result;
0550
0551
0552
0553 if (LUTsFromFile)
0554 result = mb_global_phi[address.toint()];
0555 else
0556 result = calcGlobalPhiMB(globalPhiME(address, gangedME1a));
0557
0558 return result;
0559 }
0560
0561 double CSCSectorReceiverLUT::getGlobalEtaValue(const unsigned& thecscid,
0562 const unsigned& thewire_group,
0563 const unsigned& thephi_local) const {
0564 double result = 0.0;
0565 unsigned wire_group = thewire_group;
0566 int cscid = thecscid;
0567 unsigned phi_local = thephi_local;
0568
0569
0570
0571 bool me1ir_only = false;
0572
0573 if (cscid < CSCTriggerNumbering::minTriggerCscId() || cscid > CSCTriggerNumbering::maxTriggerCscId()) {
0574 edm::LogWarning("CSCSectorReceiverLUT|getEtaValue")
0575 << " warning: cscId " << cscid << " is out of bounds [1-" << CSCTriggerNumbering::maxTriggerCscId() << "]\n";
0576 cscid = CSCTriggerNumbering::maxTriggerCscId();
0577 }
0578
0579 CSCLayerGeometry* layerGeom = nullptr;
0580 const unsigned numBins = 1 << 2;
0581
0582 if (phi_local > numBins - 1) {
0583 edm::LogWarning("CSCSectorReceiverLUT|getEtaValue")
0584 << "warning: phiL " << phi_local << " is out of bounds [0-" << numBins - 1 << "]\n";
0585 phi_local = numBins - 1;
0586 }
0587 try {
0588 int ring = CSCTriggerNumbering::ringFromTriggerLabels(_station, cscid);
0589 int chid = CSCTriggerNumbering::chamberFromTriggerLabels(_sector, _subsector, _station, cscid);
0590 CSCDetId detid(_endcap, _station, ring, chid, 0);
0591 const CSCChamber* thechamber = const_cast<const CSCChamber*>(csc_g->chamber(detid));
0592 if (thechamber) {
0593 layerGeom = const_cast<CSCLayerGeometry*>(thechamber->layer(CSCConstants::KEY_ALCT_LAYER)->geometry());
0594 const unsigned nWireGroups = layerGeom->numberOfWireGroups();
0595
0596
0597
0598 if (wire_group >= nWireGroups) {
0599 edm::LogWarning("CSCSectorReceiverLUT|getEtaValue")
0600 << "warning: wireGroup " << wire_group << " is out of bounds [0-" << nWireGroups << ")\n";
0601 wire_group = nWireGroups - 1;
0602 }
0603
0604 wire_group += 1;
0605
0606
0607 if (me1ir_only && (_station != 1 || CSCTriggerNumbering::ringFromTriggerLabels(_station, cscid) != 1)) {
0608 result = thechamber->layer(CSCConstants::KEY_ALCT_LAYER)->centerOfWireGroup(wire_group).eta();
0609 } else {
0610 const unsigned nStrips = layerGeom->numberOfStrips();
0611 const unsigned nStripsPerBin = CSCConstants::MAX_NUM_STRIPS_RUN1 / numBins;
0612
0613
0614
0615
0616
0617 if (nStrips % numBins != 0 || CSCConstants::MAX_NUM_STRIPS_RUN1 % numBins != 0)
0618 edm::LogWarning("CSCSectorReceiverLUT")
0619 << "getGlobalEtaValue warning: number of strips " << nStrips << " (" << CSCConstants::MAX_NUM_STRIPS_RUN1
0620 << ") is not divisible by numBins " << numBins << " Station " << _station << " sector " << _sector
0621 << " subsector " << _subsector << " cscid " << cscid << "\n";
0622
0623 unsigned maxStripPrevBin = 0, maxStripThisBin = 0;
0624 unsigned correctionStrip;
0625 LocalPoint lPoint;
0626 GlobalPoint gPoint;
0627
0628 maxStripThisBin = nStripsPerBin * (phi_local + 1);
0629 if (maxStripThisBin <= nStrips) {
0630 correctionStrip = nStripsPerBin / 2 * (2 * phi_local + 1);
0631 } else {
0632
0633
0634
0635
0636 maxStripPrevBin = nStripsPerBin * phi_local;
0637 correctionStrip = (nStrips + maxStripPrevBin) / 2;
0638 }
0639
0640 lPoint = layerGeom->stripWireGroupIntersection(correctionStrip, wire_group);
0641 gPoint = thechamber->layer(CSCConstants::KEY_ALCT_LAYER)->surface().toGlobal(lPoint);
0642
0643
0644 result = gPoint.eta();
0645 }
0646 }
0647 } catch (cms::Exception& e) {
0648 LogDebug("CSCSectorReceiver|OutofBoundInput") << e.what();
0649 }
0650
0651 return std::fabs(result);
0652 }
0653
0654 gbletadat CSCSectorReceiverLUT::calcGlobalEtaME(const gbletaadd& address) const {
0655 gbletadat result;
0656 double float_eta = getGlobalEtaValue(address.cscid, address.wire_group, address.phi_local);
0657 unsigned int_eta = 0;
0658 unsigned bend_global = 0;
0659 const double etaPerBin = (CSCTFConstants::maxEta - CSCTFConstants::minEta) / CSCTFConstants::etaBins;
0660 const unsigned me12EtaCut = 56;
0661
0662 if ((float_eta < CSCTFConstants::minEta) || (float_eta >= CSCTFConstants::maxEta)) {
0663 edm::LogWarning("CSCSectorReceiverLUT:OutOfBounds")
0664 << "CSCSectorReceiverLUT warning: float_eta = " << float_eta << " minEta = " << CSCTFConstants::minEta
0665 << " maxEta = " << CSCTFConstants::maxEta << " station " << _station << " sector " << _sector << " chamber "
0666 << address.cscid << " wire group " << address.wire_group;
0667
0668 throw cms::Exception("CSCSectorReceiverLUT")
0669 << "+++ Value of CSC ID, " << float_eta << ", is out of bounds [" << CSCTFConstants::minEta << "-"
0670 << CSCTFConstants::maxEta << ") +++\n";
0671
0672
0673
0674
0675
0676 } else {
0677 float_eta -= CSCTFConstants::minEta;
0678 float_eta = float_eta / etaPerBin;
0679 int_eta = static_cast<unsigned>(float_eta);
0680
0681
0682
0683
0684
0685
0686
0687
0688 if (_station == 1 && address.cscid >= static_cast<unsigned>(CSCTriggerNumbering::minTriggerCscId()) &&
0689 address.cscid <= static_cast<unsigned>(CSCTriggerNumbering::maxTriggerCscId())) {
0690 unsigned ring = CSCTriggerNumbering::ringFromTriggerLabels(_station, address.cscid);
0691
0692 if (ring == 1 && int_eta < me12EtaCut) {
0693 int_eta = me12EtaCut;
0694 } else if (ring == 2 && int_eta >= me12EtaCut) {
0695 int_eta = me12EtaCut - 1;
0696 }
0697 }
0698 result.global_eta = int_eta;
0699 }
0700 result.global_bend = bend_global;
0701
0702 return result;
0703 }
0704
0705 gbletadat CSCSectorReceiverLUT::globalEtaME(
0706 int tphi_bend, int tphi_local, int twire_group, int tcscid, const bool gangedME1a) const {
0707 gbletadat result;
0708 gbletaadd theadd;
0709
0710 theadd.phi_bend = tphi_bend;
0711 theadd.phi_local = (tphi_local >> (CSCBitWidths::kLocalPhiDataBitWidth - 2)) & 0x3;
0712 theadd.wire_group = twire_group;
0713 theadd.cscid = tcscid;
0714 if (useMiniLUTs && isTMB07)
0715 result = CSCSectorReceiverMiniLUT::calcGlobalEtaMEMini(
0716 _endcap, _sector, _station, _subsector, theadd.toint(), gangedME1a);
0717 else if (LUTsFromFile)
0718 result = me_global_eta[theadd.toint()];
0719 else
0720 result = calcGlobalEtaME(theadd);
0721
0722 return result;
0723 }
0724
0725 gbletadat CSCSectorReceiverLUT::globalEtaME(unsigned address, const bool gangedME1a) const {
0726 gbletadat result;
0727 gbletaadd theadd(address);
0728
0729 if (useMiniLUTs && isTMB07)
0730 result = CSCSectorReceiverMiniLUT::calcGlobalEtaMEMini(_endcap, _sector, _station, _subsector, address, gangedME1a);
0731 else if (LUTsFromFile)
0732 result = me_global_eta[address];
0733 else
0734 result = calcGlobalEtaME(theadd);
0735 return result;
0736 }
0737
0738 gbletadat CSCSectorReceiverLUT::globalEtaME(gbletaadd address, const bool gangedME1a) const {
0739 gbletadat result;
0740
0741 if (useMiniLUTs && isTMB07)
0742 result = CSCSectorReceiverMiniLUT::calcGlobalEtaMEMini(
0743 _endcap, _sector, _station, _subsector, address.toint(), gangedME1a);
0744 else if (LUTsFromFile)
0745 result = me_global_eta[address.toint()];
0746 else
0747 result = calcGlobalEtaME(address);
0748 return result;
0749 }
0750
0751 std::string CSCSectorReceiverLUT::encodeFileIndex() const {
0752 std::string fileName = "";
0753 if (_station == 1) {
0754 if (_subsector == 1)
0755 fileName += "1a";
0756 if (_subsector == 2)
0757 fileName += "1b";
0758 } else if (_station == 2)
0759 fileName += "2";
0760 else if (_station == 3)
0761 fileName += "3";
0762 else if (_station == 4)
0763 fileName += "4";
0764 fileName += "End";
0765 if (_endcap == 1)
0766 fileName += "1";
0767 else
0768 fileName += "2";
0769 fileName += "Sec";
0770 if (_sector == 1)
0771 fileName += "1";
0772 else if (_sector == 2)
0773 fileName += "2";
0774 else if (_sector == 3)
0775 fileName += "3";
0776 else if (_sector == 4)
0777 fileName += "4";
0778 else if (_sector == 5)
0779 fileName += "5";
0780 else if (_sector == 6)
0781 fileName += "6";
0782 fileName += "LUT";
0783 return fileName;
0784 }
0785
0786 void CSCSectorReceiverLUT::readLUTsFromFile() {
0787 if (!me_lcl_phi_loaded) {
0788 me_lcl_phi = new lclphidat[1 << CSCBitWidths::kLocalPhiAddressWidth];
0789 std::string fName(me_lcl_phi_file.fullPath());
0790 std::ifstream LocalPhiLUT;
0791
0792 edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
0793
0794 if (isBinary) {
0795 LocalPhiLUT.open(fName.c_str(), std::ios::binary);
0796 LocalPhiLUT.seekg(0, std::ios::end);
0797 int length = LocalPhiLUT.tellg();
0798 if (length == (1 << CSCBitWidths::kLocalPhiAddressWidth) * sizeof(short)) {
0799 LocalPhiLUT.seekg(0, std::ios::beg);
0800 LocalPhiLUT.read(reinterpret_cast<char*>(me_lcl_phi), length);
0801 LocalPhiLUT.close();
0802 } else
0803 edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
0804 LocalPhiLUT.close();
0805 } else {
0806 LocalPhiLUT.open(fName.c_str());
0807 unsigned i = 0;
0808 unsigned short temp = 0;
0809 while (!LocalPhiLUT.eof() && i < 1 << CSCBitWidths::kLocalPhiAddressWidth) {
0810 LocalPhiLUT >> temp;
0811 me_lcl_phi[i++] = temp;
0812 }
0813 LocalPhiLUT.close();
0814 }
0815 }
0816 if (!me_global_phi) {
0817 me_global_phi = new gblphidat[1 << CSCBitWidths::kGlobalPhiAddressWidth];
0818 std::string fName = me_gbl_phi_file.fullPath();
0819 std::ifstream GlobalPhiLUT;
0820
0821 edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
0822
0823 if (isBinary) {
0824 GlobalPhiLUT.open(fName.c_str(), std::ios::binary);
0825 GlobalPhiLUT.seekg(0, std::ios::end);
0826 int length = GlobalPhiLUT.tellg();
0827 if (length == (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(short)) {
0828 GlobalPhiLUT.seekg(0, std::ios::beg);
0829 GlobalPhiLUT.read(reinterpret_cast<char*>(me_global_phi), length);
0830 } else
0831 edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
0832 GlobalPhiLUT.close();
0833 } else {
0834 GlobalPhiLUT.open(fName.c_str());
0835 unsigned short temp = 0;
0836 unsigned i = 0;
0837 while (!GlobalPhiLUT.eof() && i < 1 << CSCBitWidths::kGlobalPhiAddressWidth) {
0838 GlobalPhiLUT >> temp;
0839 me_global_phi[i++] = temp;
0840 }
0841 GlobalPhiLUT.close();
0842 }
0843 }
0844 if (!mb_global_phi && _station == 1)
0845 {
0846 mb_global_phi = new gblphidat[1 << CSCBitWidths::kGlobalPhiAddressWidth];
0847 std::string fName = mb_gbl_phi_file.fullPath();
0848 std::ifstream GlobalPhiLUT;
0849
0850 edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
0851
0852 if (isBinary) {
0853 GlobalPhiLUT.open(fName.c_str(), std::ios::binary);
0854 GlobalPhiLUT.seekg(0, std::ios::end);
0855 int length = GlobalPhiLUT.tellg();
0856 if (length == (1 << CSCBitWidths::kGlobalPhiAddressWidth) * sizeof(short)) {
0857 GlobalPhiLUT.seekg(0, std::ios::beg);
0858 GlobalPhiLUT.read(reinterpret_cast<char*>(mb_global_phi), length);
0859 } else
0860 edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
0861 GlobalPhiLUT.close();
0862 } else {
0863 GlobalPhiLUT.open(fName.c_str());
0864 unsigned short temp = 0;
0865 unsigned i = 0;
0866 while (!GlobalPhiLUT.eof() && i < 1 << CSCBitWidths::kGlobalPhiAddressWidth) {
0867 GlobalPhiLUT >> temp;
0868 mb_global_phi[i++] = temp;
0869 }
0870 GlobalPhiLUT.close();
0871 }
0872 }
0873 if (!me_global_eta) {
0874 me_global_eta = new gbletadat[1 << CSCBitWidths::kGlobalEtaAddressWidth];
0875 std::string fName = me_gbl_eta_file.fullPath();
0876 std::ifstream GlobalEtaLUT;
0877
0878 edm::LogInfo("CSCSectorReceiverLUT") << "Loading SR LUT: " << fName;
0879
0880 if (isBinary) {
0881 GlobalEtaLUT.open(fName.c_str(), std::ios::binary);
0882 GlobalEtaLUT.seekg(0, std::ios::end);
0883 int length = GlobalEtaLUT.tellg();
0884 if (length == (1 << CSCBitWidths::kGlobalEtaAddressWidth) * sizeof(short)) {
0885 GlobalEtaLUT.seekg(0, std::ios::beg);
0886 GlobalEtaLUT.read(reinterpret_cast<char*>(me_global_eta), length);
0887 } else
0888 edm::LogError("CSCSectorReceiverLUT") << "File " << fName << " is incorrect size!";
0889 GlobalEtaLUT.close();
0890 } else {
0891 GlobalEtaLUT.open(fName.c_str());
0892 unsigned short temp = 0;
0893 unsigned i = 0;
0894 while (!GlobalEtaLUT.eof() && i < 1 << CSCBitWidths::kGlobalEtaAddressWidth) {
0895 GlobalEtaLUT >> temp;
0896 me_global_eta[i++] = temp;
0897 }
0898 GlobalEtaLUT.close();
0899 }
0900 }
0901 }