File indexing completed on 2024-04-06 12:21:04
0001 #include <cmath>
0002 #include <vector>
0003 #include <iostream>
0004 #include <algorithm>
0005
0006 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0007 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
0008 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
0009 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
0010
0011 #include "L1Trigger/L1TMuonOverlap/interface/OMTFinputMaker.h"
0012 #include "L1Trigger/L1TMuonOverlap/interface/OMTFinput.h"
0013 #include "L1Trigger/L1TMuonOverlap/interface/OMTFConfiguration.h"
0014 #include "L1Trigger/L1TMuonOverlap/interface/AngleConverter.h"
0015 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0017
0018
0019
0020 OMTFinputMaker::OMTFinputMaker(edm::ConsumesCollector &iC, bool getDuringEvent)
0021 : myAngleConverter(std::make_unique<AngleConverter>(iC, getDuringEvent)) {}
0022
0023
0024 void OMTFinputMaker::initialize(const edm::EventSetup &es, const OMTFConfiguration *omtfConfig) {
0025 myAngleConverter->checkAndUpdateGeometry(es, omtfConfig->nPhiBins());
0026
0027 myOmtfConfig = omtfConfig;
0028 }
0029
0030
0031 OMTFinputMaker::~OMTFinputMaker() {}
0032
0033
0034 bool OMTFinputMaker::acceptDigi(uint32_t rawId, unsigned int iProcessor, l1t::tftype type) {
0035 unsigned int aMin = myOmtfConfig->getBarrelMin()[iProcessor];
0036 unsigned int aMax = myOmtfConfig->getBarrelMax()[iProcessor];
0037 unsigned int aSector = 99;
0038
0039
0040 DetId detId(rawId);
0041 if (detId.det() != DetId::Muon)
0042 edm::LogError("Critical OMTFinputMaker") << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
0043 switch (detId.subdetId()) {
0044 case MuonSubdetId::RPC: {
0045 RPCDetId aId(rawId);
0046
0047
0048 if (type == l1t::tftype::omtf_pos &&
0049 (aId.region() < 0 || (aId.region() == 0 && aId.ring() != 2) || (aId.region() == 0 && aId.station() == 4) ||
0050 (aId.region() == 0 && aId.station() == 2 && aId.layer() == 2 && aId.roll() == 1) ||
0051 (aId.region() == 0 && aId.station() == 3 && aId.roll() == 1) || (aId.region() == 1 && aId.station() == 4) ||
0052
0053 (aId.region() == 1 && aId.station() > 0 && aId.ring() < 3)))
0054 return false;
0055
0056 if (type == l1t::tftype::omtf_neg &&
0057 (aId.region() > 0 || (aId.region() == 0 && aId.ring() != -2) || (aId.region() == 0 && aId.station() == 4) ||
0058 (aId.region() == 0 && aId.station() == 2 && aId.layer() == 2 && aId.roll() == 1) ||
0059 (aId.region() == 0 && aId.station() == 3 && aId.roll() == 1) || (aId.region() == -1 && aId.station() == 4) ||
0060
0061 (aId.region() == -1 && aId.station() > 0 && aId.ring() < 3)))
0062 return false;
0063
0064 if (type == l1t::tftype::bmtf && aId.region() != 0)
0065 return false;
0066
0067 if (type == l1t::tftype::emtf_pos && (aId.region() <= 0 || (aId.station() == 1 && aId.ring() == 3)))
0068 return false;
0069 if (type == l1t::tftype::emtf_neg && (aId.region() >= 0 || (aId.station() == 1 && aId.ring() == 3)))
0070 return false;
0071
0072 if (aId.region() == 0)
0073 aSector = aId.sector();
0074 if (aId.region() != 0) {
0075 aSector = (aId.sector() - 1) * 6 + aId.subsector();
0076 aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
0077 aMax = myOmtfConfig->getEndcap10DegMax()[iProcessor];
0078 }
0079
0080 break;
0081 }
0082 case MuonSubdetId::DT: {
0083 DTChamberId dt(rawId);
0084
0085 if (type == l1t::tftype::omtf_pos && dt.wheel() != 2)
0086 return false;
0087 if (type == l1t::tftype::omtf_neg && dt.wheel() != -2)
0088 return false;
0089 if (type == l1t::tftype::emtf_pos || type == l1t::tftype::emtf_neg)
0090 return false;
0091
0092 aSector = dt.sector();
0093 break;
0094 }
0095 case MuonSubdetId::CSC: {
0096 CSCDetId csc(rawId);
0097 if (type == l1t::tftype::omtf_pos && (csc.endcap() == 2 || csc.ring() == 1 || csc.station() == 4))
0098 return false;
0099 if (type == l1t::tftype::omtf_neg && (csc.endcap() == 1 || csc.ring() == 1 || csc.station() == 4))
0100 return false;
0101
0102 if (type == l1t::tftype::emtf_pos && (csc.endcap() == 2 || (csc.station() == 1 && csc.ring() == 3)))
0103 return false;
0104 if (type == l1t::tftype::emtf_neg && (csc.endcap() == 1 || (csc.station() == 1 && csc.ring() == 3)))
0105 return false;
0106
0107 aSector = csc.chamber();
0108 aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
0109 aMax = myOmtfConfig->getEndcap10DegMax()[iProcessor];
0110
0111 if ((type == l1t::tftype::emtf_pos || type == l1t::tftype::emtf_neg) && csc.station() > 1 && csc.ring() == 1) {
0112 aMin = myOmtfConfig->getEndcap20DegMin()[iProcessor];
0113 aMax = myOmtfConfig->getEndcap20DegMax()[iProcessor];
0114 }
0115 break;
0116 }
0117 }
0118
0119 if (aMax > aMin && aSector >= aMin && aSector <= aMax)
0120 return true;
0121 if (aMax < aMin && (aSector >= aMin || aSector <= aMax))
0122 return true;
0123
0124 return false;
0125 }
0126
0127
0128 unsigned int OMTFinputMaker::getInputNumber(unsigned int rawId, unsigned int iProcessor, l1t::tftype type) {
0129 unsigned int iInput = 99;
0130 unsigned int aSector = 99;
0131 int aMin = myOmtfConfig->getBarrelMin()[iProcessor];
0132 int iRoll = 1;
0133 int nInputsPerSector = 2;
0134
0135 DetId detId(rawId);
0136 if (detId.det() != DetId::Muon)
0137 edm::LogError("Critical OMTFinputMaker") << "PROBLEM: hit in unknown Det, detID: " << detId.det() << std::endl;
0138 switch (detId.subdetId()) {
0139 case MuonSubdetId::RPC: {
0140 RPCDetId rpc(rawId);
0141 if (rpc.region() == 0) {
0142 nInputsPerSector = 4;
0143 aSector = rpc.sector();
0144
0145
0146 if (iProcessor == 5 && aSector < 3)
0147 aMin = -1;
0148
0149 iRoll = rpc.roll();
0150
0151
0152 if (rpc.station() == 2 && rpc.layer() == 2 && rpc.roll() == 2)
0153 iRoll = 1;
0154
0155 if (rpc.station() == 3) {
0156 iRoll = 1;
0157 nInputsPerSector = 2;
0158 }
0159
0160 if (type == l1t::tftype::bmtf)
0161 iRoll = 1;
0162 }
0163 if (rpc.region() != 0) {
0164 aSector = (rpc.sector() - 1) * 6 + rpc.subsector();
0165 aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
0166
0167
0168 if (iProcessor == 5 && aSector < 5)
0169 aMin = -4;
0170 }
0171 break;
0172 }
0173 case MuonSubdetId::DT: {
0174 DTChamberId dt(rawId);
0175 aSector = dt.sector();
0176
0177
0178 if (iProcessor == 5 && aSector < 3)
0179 aMin = -1;
0180 break;
0181 }
0182 case MuonSubdetId::CSC: {
0183 CSCDetId csc(rawId);
0184 aSector = csc.chamber();
0185 aMin = myOmtfConfig->getEndcap10DegMin()[iProcessor];
0186
0187
0188 if (iProcessor == 5 && aSector < 5)
0189 aMin = -4;
0190
0191
0192
0193 if ((type == l1t::tftype::emtf_pos || type == l1t::tftype::emtf_neg) && csc.station() > 1 && csc.ring() == 1) {
0194 aMin = myOmtfConfig->getEndcap20DegMin()[iProcessor];
0195 if (iProcessor == 5 && aSector < 3)
0196 aMin = -2;
0197 }
0198 break;
0199 }
0200 }
0201
0202
0203 iInput = (aSector - aMin) * nInputsPerSector;
0204
0205 iInput += iRoll - 1;
0206
0207 return iInput;
0208 }
0209
0210
0211 OMTFinput OMTFinputMaker::processDT(const L1MuDTChambPhContainer *dtPhDigis,
0212 const L1MuDTChambThContainer *dtThDigis,
0213 unsigned int iProcessor,
0214 l1t::tftype type,
0215 int bxTrg) {
0216 OMTFinput result(myOmtfConfig);
0217 if (!dtPhDigis)
0218 return result;
0219
0220 for (const auto &digiIt : *dtPhDigis->getContainer()) {
0221 DTChamberId detid(digiIt.whNum(), digiIt.stNum(), digiIt.scNum() + 1);
0222
0223
0224 if (!acceptDigi(detid.rawId(), iProcessor, type))
0225 continue;
0226
0227
0228
0229
0230
0231
0232
0233
0234 if (digiIt.bxNum() != bxTrg)
0235 continue;
0236
0237 if (myOmtfConfig->fwVersion() <= 4) {
0238 if (digiIt.code() != 4 && digiIt.code() != 5 && digiIt.code() != 6)
0239 continue;
0240 } else {
0241 if (digiIt.code() != 2 && digiIt.code() != 3 && digiIt.code() != 4 && digiIt.code() != 5 && digiIt.code() != 6)
0242 continue;
0243 }
0244
0245 unsigned int hwNumber = myOmtfConfig->getLayerNumber(detid.rawId());
0246 if (myOmtfConfig->getHwToLogicLayer().find(hwNumber) == myOmtfConfig->getHwToLogicLayer().end())
0247 continue;
0248
0249 auto iter = myOmtfConfig->getHwToLogicLayer().find(hwNumber);
0250 unsigned int iLayer = iter->second;
0251 int iPhi = myAngleConverter->getProcessorPhi(iProcessor, type, digiIt);
0252 int iEta = myAngleConverter->getGlobalEta(detid.rawId(), digiIt, dtThDigis);
0253 unsigned int iInput = getInputNumber(detid.rawId(), iProcessor, type);
0254 bool allowOverwrite = false;
0255 result.addLayerHit(iLayer, iInput, iPhi, iEta, allowOverwrite);
0256 result.addLayerHit(iLayer + 1, iInput, digiIt.phiB(), iEta, allowOverwrite);
0257 }
0258
0259 return result;
0260 }
0261
0262
0263 OMTFinput OMTFinputMaker::processCSC(const CSCCorrelatedLCTDigiCollection *cscDigis,
0264 unsigned int iProcessor,
0265 l1t::tftype type,
0266 int bxTrg) {
0267 OMTFinput result(myOmtfConfig);
0268 if (!cscDigis)
0269 return result;
0270
0271 auto chamber = cscDigis->begin();
0272 auto chend = cscDigis->end();
0273 for (; chamber != chend; ++chamber) {
0274 unsigned int rawid = (*chamber).first;
0275
0276 if (!acceptDigi(rawid, iProcessor, type))
0277 continue;
0278 auto digi = (*chamber).second.first;
0279 auto dend = (*chamber).second.second;
0280 for (; digi != dend; ++digi) {
0281
0282 if (digi->getBX() - CSCConstants::LCT_CENTRAL_BX != bxTrg)
0283 continue;
0284
0285 unsigned int hwNumber = myOmtfConfig->getLayerNumber(rawid);
0286 if (myOmtfConfig->getHwToLogicLayer().find(hwNumber) == myOmtfConfig->getHwToLogicLayer().end())
0287 continue;
0288
0289 unsigned int iLayer = myOmtfConfig->getHwToLogicLayer().at(hwNumber);
0290 int iPhi = myAngleConverter->getProcessorPhi(iProcessor, type, CSCDetId(rawid), *digi);
0291 int iEta = myAngleConverter->getGlobalEta(rawid, *digi);
0292
0293
0294
0295
0296
0297 unsigned int iInput = getInputNumber(rawid, iProcessor, type);
0298
0299 bool allowOverwrite = false;
0300 result.addLayerHit(iLayer, iInput, iPhi, iEta, allowOverwrite);
0301 }
0302 }
0303 return result;
0304 }
0305
0306
0307 bool rpcPrimitiveCmp(const RPCDigi &a, const RPCDigi &b) { return a.strip() < b.strip(); };
0308
0309
0310 OMTFinput OMTFinputMaker::processRPC(const RPCDigiCollection *rpcDigis,
0311 unsigned int iProcessor,
0312 l1t::tftype type,
0313 int bxTrg) {
0314 OMTFinput result(myOmtfConfig);
0315 if (!rpcDigis)
0316 return result;
0317 std::stringstream str;
0318
0319
0320
0321 const RPCDigiCollection &rpcDigiCollection = *rpcDigis;
0322 for (auto rollDigis : rpcDigiCollection) {
0323 RPCDetId roll = rollDigis.first;
0324 unsigned int rawid = roll.rawId();
0325 if (!acceptDigi(rawid, iProcessor, type))
0326 continue;
0327
0328
0329
0330
0331 std::vector<RPCDigi> digisCopy;
0332
0333 for (auto pDigi = rollDigis.second.first; pDigi != rollDigis.second.second; pDigi++) {
0334 if (pDigi->bx() == bxTrg)
0335 digisCopy.push_back(*pDigi);
0336 }
0337 std::sort(digisCopy.begin(), digisCopy.end(), rpcPrimitiveCmp);
0338 typedef std::pair<unsigned int, unsigned int> Cluster;
0339 std::vector<Cluster> clusters;
0340 for (auto &digi : digisCopy) {
0341 if (clusters.empty())
0342 clusters.push_back(Cluster(digi.strip(), digi.strip()));
0343 else if (digi.strip() - clusters.back().second == 1)
0344 clusters.back().second = digi.strip();
0345 else if (digi.strip() - clusters.back().second > 1)
0346 clusters.push_back(Cluster(digi.strip(), digi.strip()));
0347 }
0348
0349 for (auto &cluster : clusters) {
0350
0351
0352 int iPhi = myAngleConverter->getProcessorPhi(iProcessor, type, roll, cluster.first, cluster.second);
0353 int cSize = abs(int(cluster.first) - int(cluster.second)) + 1;
0354
0355 if (cSize > 3)
0356 continue;
0357 int iEta = myAngleConverter->getGlobalEta(rawid, cluster.first);
0358 unsigned int hwNumber = myOmtfConfig->getLayerNumber(rawid);
0359 unsigned int iLayer = myOmtfConfig->getHwToLogicLayer().at(hwNumber);
0360 unsigned int iInput = getInputNumber(rawid, iProcessor, type);
0361
0362 if (iLayer == 17 && (iInput == 0 || iInput == 1))
0363 continue;
0364 bool outres = result.addLayerHit(iLayer, iInput, iPhi, iEta);
0365
0366
0367
0368 str << " RPC halfDigi "
0369 << " begin: " << cluster.first << " end: " << cluster.second << " iPhi: " << iPhi << " iEta: " << iEta
0370 << " hwNumber: " << hwNumber << " iInput: " << iInput << " iLayer: " << iLayer << " out: " << outres
0371 << std::endl;
0372 }
0373 }
0374
0375 edm::LogInfo("OMTFInputMaker") << str.str();
0376 return result;
0377 }
0378
0379
0380 OMTFinput OMTFinputMaker::buildInputForProcessor(const L1MuDTChambPhContainer *dtPhDigis,
0381 const L1MuDTChambThContainer *dtThDigis,
0382 const CSCCorrelatedLCTDigiCollection *cscDigis,
0383 const RPCDigiCollection *rpcDigis,
0384 unsigned int iProcessor,
0385 l1t::tftype type,
0386 int bx) {
0387 OMTFinput result(myOmtfConfig);
0388 result += processDT(dtPhDigis, dtThDigis, iProcessor, type, bx);
0389 result += processCSC(cscDigis, iProcessor, type, bx);
0390 result += processRPC(rpcDigis, iProcessor, type, bx);
0391 return result;
0392 }
0393
0394