File indexing completed on 2024-04-06 12:21:10
0001 #include "L1Trigger/L1TMuonOverlapPhase1/interface/AngleConverterBase.h"
0002 #include "L1Trigger/L1TMuonOverlapPhase1/interface/Omtf/OMTFConfiguration.h"
0003
0004 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0005 #include "L1Trigger/DTUtilities/interface/DTTrigGeom.h"
0006
0007 #include "FWCore/Framework/interface/EventSetup.h"
0008 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0009 #include "Geometry/CSCGeometry/interface/CSCGeometry.h"
0010 #include "Geometry/DTGeometry/interface/DTGeometry.h"
0011 #include "Geometry/RPCGeometry/interface/RPCGeometry.h"
0012 #include "DataFormats/CSCDigi/interface/CSCCorrelatedLCTDigi.h"
0013 #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambPhDigi.h"
0014 #include "DataFormats/L1DTTrackFinder/interface/L1MuDTChambThContainer.h"
0015 #include "DataFormats/RPCDigi/interface/RPCDigi.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017
0018 #include <cmath>
0019
0020 namespace {
0021 template <typename T>
0022 int sgn(T val) {
0023 return (T(0) < val) - (val < T(0));
0024 }
0025
0026 int fixCscOffsetGeom(int offsetLoc) {
0027
0028
0029
0030 const std::vector<int> offCSC = {-154, -133, -17, -4, 4, 17, 133, 146, 154, 167, 283, 296, 304, 317,
0031 433, 446, 454, 467, 583, 596, 604, 617, 733, 746, 754, 767, 883, 904};
0032 auto gep = std::lower_bound(offCSC.begin(), offCSC.end(), offsetLoc);
0033 int fixOff = (gep != offCSC.end()) ? *gep : *(gep - 1);
0034 if (gep != offCSC.begin() && std::abs(*(gep - 1) - offsetLoc) < std::abs(fixOff - offsetLoc))
0035 fixOff = *(gep - 1);
0036 return fixOff;
0037 }
0038
0039 }
0040
0041 AngleConverterBase::AngleConverterBase() : _geom_cache_id(0ULL) {}
0042
0043
0044 AngleConverterBase::~AngleConverterBase() {}
0045
0046
0047 void AngleConverterBase::checkAndUpdateGeometry(const edm::EventSetup& es,
0048 const ProcConfigurationBase* config,
0049 const MuonGeometryTokens& muonGeometryTokens) {
0050 if (muonGeometryRecordWatcher.check(es)) {
0051 _georpc = es.getHandle(muonGeometryTokens.rpcGeometryEsToken);
0052 _geocsc = es.getHandle(muonGeometryTokens.cscGeometryEsToken);
0053 _geodt = es.getHandle(muonGeometryTokens.dtGeometryEsToken);
0054 }
0055 this->config = config;
0056 nPhiBins = config->nPhiBins();
0057 }
0058
0059
0060 int AngleConverterBase::getProcessorPhi(int phiZero, l1t::tftype part, int dtScNum, int dtPhi) const {
0061 int dtPhiBins = 4096;
0062
0063 double hsPhiPitch = 2 * M_PI / nPhiBins;
0064
0065 int sector = dtScNum + 1;
0066
0067 double scale = 1. / dtPhiBins / hsPhiPitch;
0068 int scale_coeff = lround(scale * pow(2, 11));
0069
0070 int ichamber = sector - 1;
0071 if (ichamber > 6)
0072 ichamber = ichamber - 12;
0073
0074 int offsetGlobal = (int)nPhiBins * ichamber / 12;
0075
0076 int phiConverted = floor(dtPhi * scale_coeff / pow(2, 11)) + offsetGlobal - phiZero;
0077
0078
0079 return config->foldPhi(phiConverted);
0080 }
0081
0082
0083 int AngleConverterBase::getProcessorPhi(
0084 int phiZero, l1t::tftype part, const CSCDetId& csc, const CSCCorrelatedLCTDigi& digi, unsigned int iInput) const {
0085 const double hsPhiPitch = 2 * M_PI / nPhiBins;
0086
0087
0088
0089
0090
0091 int halfStrip = digi.getStrip();
0092
0093 const CSCChamber* chamber = _geocsc->chamber(csc);
0094
0095
0096
0097 if (csc.station() == 1 && csc.ring() == 1 && halfStrip > 128) {
0098 CSCDetId cscME11 = CSCDetId(csc.endcap(), csc.station(), 4, csc.chamber());
0099 chamber = _geocsc->chamber(cscME11);
0100 }
0101
0102 const CSCChamberSpecs* cspec = chamber->specs();
0103 const CSCLayer* layer = chamber->layer(3);
0104 int order = (layer->centerOfStrip(2).phi() - layer->centerOfStrip(1).phi() > 0) ? 1 : -1;
0105 double stripPhiPitch = cspec->stripPhiPitch();
0106 double scale = std::abs(stripPhiPitch / hsPhiPitch / 2.);
0107 if (std::abs(scale - 1.) < 0.0002)
0108 scale = 1.;
0109
0110 double phiHalfStrip0 = layer->centerOfStrip(1).phi() - order * stripPhiPitch / 4.;
0111
0112 int offsetLoc = lround((phiHalfStrip0) / hsPhiPitch - phiZero);
0113 offsetLoc = config->foldPhi(offsetLoc);
0114
0115 if (csc.station() == 1 && csc.ring() == 1 && halfStrip > 128) {
0116
0117
0118
0119
0120 halfStrip -= 128;
0121 }
0122
0123
0124
0125 int fixOff = offsetLoc;
0126
0127
0128
0129 if (config->getFixCscGeometryOffset()) {
0130 if (config->nProcessors() == 6)
0131 fixOff = fixCscOffsetGeom(offsetLoc);
0132 else if (config->nProcessors() == 3) {
0133
0134 if (iInput >= 14)
0135 fixOff = fixCscOffsetGeom(offsetLoc - 900) + 900;
0136 else
0137 fixOff = fixCscOffsetGeom(offsetLoc);
0138 }
0139 }
0140 int phi = fixOff + order * scale * halfStrip;
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161 return config->foldPhi(phi);
0162 }
0163
0164
0165
0166 int AngleConverterBase::getProcessorPhi(
0167 int phiZero, l1t::tftype part, const RPCDetId& rollId, const unsigned int& digi1, const unsigned int& digi2) const {
0168 const double hsPhiPitch = 2 * M_PI / nPhiBins;
0169 const int dummy = nPhiBins;
0170 const RPCRoll* roll = _georpc->roll(rollId);
0171 if (!roll)
0172 return dummy;
0173
0174 double stripPhi1 = (roll->toGlobal(roll->centreOfStrip((int)digi1))).phi();
0175 double stripPhi2 = (roll->toGlobal(roll->centreOfStrip((int)digi2))).phi();
0176
0177
0178 if (std::signbit(stripPhi1) != std::signbit(stripPhi2) && std::abs(stripPhi1) > M_PI / 2.) {
0179 if (std::signbit(stripPhi1)) {
0180 stripPhi1 += 2 * M_PI;
0181 } else
0182 stripPhi2 += 2 * M_PI;
0183 }
0184 int halfStrip = lround(((stripPhi1 + stripPhi2) / 2.) / hsPhiPitch);
0185 halfStrip = config->foldPhi(halfStrip);
0186
0187 LogTrace("l1tOmtfEventPrint") << __FUNCTION__ << ":" << 185 << " roll " << rollId.rawId() << " " << rollId
0188 << " cluster: firstStrip " << digi1 << " stripPhi1Global " << stripPhi1
0189 << " stripPhi1LocalPhi " << roll->centreOfStrip((int)digi1).x() << " y "
0190 << roll->centreOfStrip((int)digi1).y() << " lastStrip " << digi2 << " stripPhi2Global "
0191 << stripPhi2 << " stripPhi2LocalPhi x " << roll->centreOfStrip((int)digi2).x() << " y "
0192 << roll->centreOfStrip((int)digi2).y() << " halfStrip " << halfStrip << std::endl;
0193
0194 return config->foldPhi(halfStrip - phiZero);
0195 }
0196
0197 int AngleConverterBase::getProcessorPhi(unsigned int iProcessor,
0198 l1t::tftype part,
0199 const RPCDetId& rollId,
0200 const unsigned int& digi) const {
0201 const double hsPhiPitch = 2 * M_PI / nPhiBins;
0202 const int dummy = nPhiBins;
0203 int processor = iProcessor + 1;
0204 const RPCRoll* roll = _georpc->roll(rollId);
0205 if (!roll)
0206 return dummy;
0207
0208 double phi15deg = M_PI / 3. * (processor - 1) + M_PI / 12.;
0209
0210
0211 double stripPhi = (roll->toGlobal(roll->centreOfStrip((int)digi))).phi();
0212
0213
0214 switch (processor) {
0215 case 1:
0216 break;
0217 case 6: {
0218 phi15deg -= 2 * M_PI;
0219 break;
0220 }
0221 default: {
0222 if (stripPhi < 0)
0223 stripPhi += 2 * M_PI;
0224 break;
0225 }
0226 }
0227
0228
0229 int halfStrip = lround((stripPhi - phi15deg) / hsPhiPitch);
0230
0231 return halfStrip;
0232 }
0233
0234
0235 EtaValue AngleConverterBase::getGlobalEtaDt(const DTChamberId& detId) const {
0236 Local2DPoint chamberMiddleLP(0, 0);
0237 GlobalPoint chamberMiddleGP = _geodt->chamber(detId)->toGlobal(chamberMiddleLP);
0238
0239 const DTChamberId baseidNeigh(detId.wheel() + (detId.wheel() >= 0 ? -1 : +1), detId.station(), detId.sector());
0240 GlobalPoint chambNeighMiddleGP = _geodt->chamber(baseidNeigh)->toGlobal(chamberMiddleLP);
0241
0242 EtaValue etaValue = {
0243 config->etaToHwEta(chamberMiddleGP.eta()),
0244 config->etaToHwEta(std::abs(chamberMiddleGP.eta() - chambNeighMiddleGP.eta())) / 2,
0245 0,
0246 0,
0247 0
0248 };
0249
0250
0251 return etaValue;
0252 }
0253
0254
0255
0256 void AngleConverterBase::getGlobalEta(const L1MuDTChambThDigi& thetaDigi, std::vector<EtaValue>& etaSegments) const {
0257 const DTChamberId baseid(thetaDigi.whNum(), thetaDigi.stNum(), thetaDigi.scNum() + 1);
0258 DTTrigGeom trig_geom(_geodt->chamber(baseid), false);
0259
0260
0261
0262
0263
0264
0265
0266 const int NBTI_theta = trig_geom.nCell(2);
0267 for (unsigned int btiGroup = 0; btiGroup < 7; ++btiGroup) {
0268 if (thetaDigi.position(btiGroup)) {
0269 unsigned btiActual = btiGroup * NBTI_theta / 7 + NBTI_theta / 14 + 1;
0270 DTBtiId thetaBTI = DTBtiId(baseid, 2, btiActual);
0271 GlobalPoint theta_gp = trig_geom.CMSPosition(thetaBTI);
0272
0273 EtaValue etaValue = {
0274 config->etaToHwEta(theta_gp.eta()),
0275 0,
0276 thetaDigi.quality(btiGroup),
0277 thetaDigi.bxNum(),
0278 0
0279 };
0280 etaSegments.emplace_back(etaValue);
0281
0282
0283 }
0284 }
0285 }
0286
0287 std::vector<EtaValue> AngleConverterBase::getGlobalEta(const L1MuDTChambThContainer* dtThDigis,
0288 int bxFrom,
0289 int bxTo) const {
0290
0291
0292 std::vector<EtaValue> etaSegments;
0293
0294 for (auto& thetaDigi : (*(dtThDigis->getContainer()))) {
0295 if (thetaDigi.bxNum() >= bxFrom && thetaDigi.bxNum() <= bxTo) {
0296 getGlobalEta(thetaDigi, etaSegments);
0297 }
0298 }
0299 return etaSegments;
0300 }
0301
0302
0303 float AngleConverterBase::cscChamberEtaSize(const CSCDetId& detId) const {
0304 if (detId.station() == 1) {
0305 if (detId.ring() == 1)
0306 return (2.5 - 1.6) / 2.;
0307
0308 if (detId.ring() == 2)
0309 return (1.7 - 1.2) / 2.;
0310 if (detId.ring() == 3)
0311 return (1.12 - 0.9) / 2.;
0312 if (detId.ring() == 4)
0313 return (2.5 - 1.6) / 2.;
0314 } else if (detId.station() == 2) {
0315 if (detId.ring() == 1)
0316 return (2.5 - 1.6) / 2.;
0317 if (detId.ring() == 2)
0318 return (1.6 - 1.0) / 2.;
0319 } else if (detId.station() == 3) {
0320 if (detId.ring() == 1)
0321 return (2.5 - 1.7) / 2.;
0322 if (detId.ring() == 2)
0323 return (1.7 - 1.1) / 2.;
0324 } else if (detId.station() == 4) {
0325 if (detId.ring() == 1)
0326 return (2.45 - 1.8) / 2.;
0327 if (detId.ring() == 2)
0328 return (1.8 - 1.2) / 2.;
0329 }
0330 return 0;
0331 }
0332
0333 EtaValue AngleConverterBase::getGlobalEta(const CSCDetId& detId, const CSCCorrelatedLCTDigi& aDigi) const {
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 auto chamb = _geocsc->chamber(detId);
0344 auto layer_geom = chamb->layer(CSCConstants::KEY_ALCT_LAYER)->geometry();
0345 auto layer = chamb->layer(CSCConstants::KEY_ALCT_LAYER);
0346
0347 const uint16_t keyWG = aDigi.getKeyWG();
0348
0349 const LocalPoint lpWg = layer_geom->localCenterOfWireGroup(keyWG);
0350 const GlobalPoint gpWg = layer->surface().toGlobal(lpWg);
0351
0352 EtaValue etaSegment = {
0353 config->etaToHwEta(gpWg.eta()),
0354 0,
0355 0,
0356 aDigi.getBX(),
0357 0
0358 };
0359
0360
0361 return etaSegment;
0362 }
0363
0364
0365
0366 EtaValue AngleConverterBase::getGlobalEtaCsc(const CSCDetId& detId) const {
0367 auto chamb = _geocsc->chamber(detId);
0368
0369 Local2DPoint chamberMiddleLP(0, 0);
0370 GlobalPoint chamberMiddleGP = chamb->toGlobal(chamberMiddleLP);
0371
0372 EtaValue etaValue = {
0373 config->etaToHwEta(chamberMiddleGP.eta()),
0374 config->etaToHwEta(cscChamberEtaSize(detId)),
0375 0,
0376 0,
0377 0
0378 };
0379
0380
0381 return etaValue;
0382 }
0383
0384
0385
0386 EtaValue AngleConverterBase::getGlobalEta(unsigned int rawid, const unsigned int& strip) const {
0387 const RPCDetId id(rawid);
0388
0389 auto roll = _georpc->roll(id);
0390 const LocalPoint lp = roll->centreOfStrip((int)strip);
0391 const GlobalPoint gp = roll->toGlobal(lp);
0392
0393 int neighbRoll = 1;
0394
0395 if (id.region() == 0) {
0396 if (id.station() == 2 && ((std::abs(id.ring()) == 2 && id.layer() == 2) ||
0397 (std::abs(id.ring()) != 2 && id.layer() == 1))) {
0398 if (id.roll() == 2)
0399 neighbRoll = 1;
0400 else {
0401 neighbRoll = 2;
0402 }
0403 } else
0404 neighbRoll = (id.roll() == 1 ? 3 : 1);
0405 } else {
0406 neighbRoll = id.roll() + (id.roll() == 1 ? +1 : -1);
0407 }
0408
0409 const RPCDetId idNeigh =
0410 RPCDetId(id.region(), id.ring(), id.station(), id.sector(), id.layer(), id.subsector(), neighbRoll);
0411
0412
0413
0414 auto rollNeigh = _georpc->roll(idNeigh);
0415 const LocalPoint lpNeigh = rollNeigh->centreOfStrip((int)strip);
0416 const GlobalPoint gpNeigh = rollNeigh->toGlobal(lpNeigh);
0417
0418 EtaValue etaValue = {config->etaToHwEta(gp.eta()),
0419 config->etaToHwEta(std::abs(gp.eta() - gpNeigh.eta())) /
0420 2,
0421 0};
0422
0423
0424 return etaValue;
0425 }
0426
0427
0428 bool AngleConverterBase::isCSCCounterClockwise(const CSCLayer* layer) const {
0429 const int nStrips = layer->geometry()->numberOfStrips();
0430 const double phi1 = layer->centerOfStrip(1).phi();
0431 const double phiN = layer->centerOfStrip(nStrips).phi();
0432 return ((std::abs(phi1 - phiN) < M_PI && phi1 >= phiN) || (std::abs(phi1 - phiN) >= M_PI && phi1 < phiN));
0433 }
0434
0435
0436 const int AngleConverterBase::findBTIgroup(const L1MuDTChambPhDigi& aDigi, const L1MuDTChambThContainer* dtThDigis) {
0437 int bti_group = -1;
0438
0439 const L1MuDTChambThDigi* theta_segm =
0440 dtThDigis->chThetaSegm(aDigi.whNum(), aDigi.stNum(), aDigi.scNum(), aDigi.bxNum());
0441 if (!theta_segm)
0442 return bti_group;
0443
0444 for (unsigned int i = 0; i < 7; ++i) {
0445 if (theta_segm->position(i) && bti_group < 0)
0446 bti_group = i;
0447
0448
0449
0450 else if (theta_segm->position(i) && bti_group > -1)
0451 return -1;
0452 }
0453
0454 return bti_group;
0455 }
0456
0457