File indexing completed on 2024-04-06 12:19:52
0001 #include "L1Trigger/GlobalCaloTrigger/interface/L1GctHardwareJetFinder.h"
0002
0003
0004 const unsigned int L1GctHardwareJetFinder::N_COLS = 2;
0005 const unsigned int L1GctHardwareJetFinder::CENTRAL_COL0 = 0;
0006 const unsigned int L1GctHardwareJetFinder::MAX_REGIONS_IN =
0007 (((L1CaloRegionDetId::N_ETA) / 2) + N_EXTRA_REGIONS_ETA00) * L1GctHardwareJetFinder::N_COLS;
0008
0009 L1GctHardwareJetFinder::L1GctHardwareJetFinder(int id)
0010 : L1GctJetFinderBase(id),
0011 m_localMaxima(MAX_JETS_OUT),
0012 m_clusters(MAX_JETS_OUT),
0013 m_numberOfClusters(0),
0014 m_localMax00(2),
0015 m_cluster00(2) {
0016 this->reset();
0017
0018
0019 static const unsigned NPHI = L1CaloRegionDetId::N_PHI;
0020 m_minColThisJf = (NPHI + m_id * 2 - CENTRAL_COL0) % NPHI;
0021 }
0022
0023 L1GctHardwareJetFinder::~L1GctHardwareJetFinder() {}
0024
0025 std::ostream& operator<<(std::ostream& os, const L1GctHardwareJetFinder& algo) {
0026 os << "===L1GctHardwareJetFinder===" << std::endl;
0027 const L1GctJetFinderBase* temp = &algo;
0028 os << *temp;
0029 return os;
0030 }
0031
0032 void L1GctHardwareJetFinder::reset() { L1GctJetFinderBase::reset(); }
0033
0034 void L1GctHardwareJetFinder::fetchInput() {
0035 if (setupOk()) {
0036 findProtoJets();
0037 }
0038 }
0039
0040 void L1GctHardwareJetFinder::process() {
0041 if (setupOk()) {
0042 fetchProtoJetsFromNeighbour(TOPBOT);
0043 findJets();
0044 sortJets();
0045 doEnergySums();
0046 }
0047 }
0048
0049
0050
0051
0052 void L1GctHardwareJetFinder::findProtoJets() {
0053 findLocalMaxima();
0054 findProtoClusters();
0055 convertClustersToProtoJets();
0056 }
0057
0058
0059 void L1GctHardwareJetFinder::findJets() {
0060 findFinalClusters();
0061 convertClustersToOutputJets();
0062 }
0063
0064
0065
0066 void L1GctHardwareJetFinder::findLocalMaxima() {
0067 m_localMaxima.clear();
0068 m_localMaxima.resize(MAX_JETS_OUT);
0069 m_localMax00.clear();
0070 m_localMax00.resize(2);
0071
0072 UShort jetNum = 0;
0073 UShort centreIndex = COL_OFFSET * this->centralCol0();
0074 for (UShort column = 0; column < 2; ++column)
0075 {
0076
0077
0078
0079
0080
0081 ++centreIndex;
0082 for (UShort row = 1; row < COL_OFFSET; ++row) {
0083
0084
0085
0086 unsigned JET_THRESHOLD = ((row > m_EtaBoundry) ? m_FwdJetSeed : m_CenJetSeed);
0087 bool localMax = !m_inputRegions.at(centreIndex).empty() && (m_inputRegions.at(centreIndex).et() >= JET_THRESHOLD);
0088 if (m_positiveEtaWheel) {
0089 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex - 1).et());
0090 if (row < (COL_OFFSET - 1)) {
0091 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex + 1).et());
0092 }
0093 if (column == 0) {
0094 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex + COL_OFFSET).et());
0095 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex + COL_OFFSET - 1).et());
0096 if (row < (COL_OFFSET - 1)) {
0097 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex + COL_OFFSET + 1).et());
0098 }
0099 } else {
0100 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex - COL_OFFSET).et());
0101 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex - COL_OFFSET - 1).et());
0102 if (row < (COL_OFFSET - 1)) {
0103 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex - COL_OFFSET + 1).et());
0104 }
0105 }
0106 } else {
0107 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex - 1).et());
0108 if (row < (COL_OFFSET - 1)) {
0109 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex + 1).et());
0110 }
0111 if (column == 0) {
0112 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex + COL_OFFSET).et());
0113 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex + COL_OFFSET - 1).et());
0114 if (row < (COL_OFFSET - 1)) {
0115 localMax &= (m_inputRegions.at(centreIndex).et() >= m_inputRegions.at(centreIndex + COL_OFFSET + 1).et());
0116 }
0117 } else {
0118 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex - COL_OFFSET).et());
0119 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex - COL_OFFSET - 1).et());
0120 if (row < (COL_OFFSET - 1)) {
0121 localMax &= (m_inputRegions.at(centreIndex).et() > m_inputRegions.at(centreIndex - COL_OFFSET + 1).et());
0122 }
0123 }
0124 }
0125 if (localMax) {
0126 if (row > 1) {
0127 if (jetNum < MAX_JETS_OUT) {
0128 m_localMaxima.at(jetNum) = m_inputRegions.at(centreIndex);
0129 ++jetNum;
0130 }
0131 }
0132
0133
0134 else {
0135 unsigned phi = m_inputRegions.at(centreIndex).rctPhi();
0136 m_localMax00.at(phi) = m_inputRegions.at(centreIndex);
0137 }
0138 }
0139 ++centreIndex;
0140 }
0141 }
0142
0143 m_numberOfClusters = jetNum;
0144 }
0145
0146
0147
0148
0149 void L1GctHardwareJetFinder::findProtoClusters() {
0150 m_clusters.clear();
0151 m_clusters.resize(MAX_JETS_OUT);
0152 m_cluster00.clear();
0153 m_cluster00.resize(2);
0154
0155 RegionsVector topJets(MAX_JETS_OUT), botJets(MAX_JETS_OUT);
0156 std::vector<unsigned> topJetsPosition(MAX_JETS_OUT), botJetsPosition(MAX_JETS_OUT);
0157 unsigned numberOfTopJets = 0, numberOfBotJets = 0;
0158
0159
0160 for (unsigned j = 0; j < m_numberOfClusters; ++j) {
0161
0162 L1GctRegion temp = makeProtoJet(m_localMaxima.at(j));
0163
0164 if (m_localMaxima.at(j).rctPhi() == 0) {
0165
0166 topJets.at(numberOfTopJets) = temp;
0167 topJetsPosition.at(numberOfTopJets) = 0;
0168 for (unsigned k = 0; k < numberOfTopJets; ++k) {
0169 if (topJets.at(numberOfTopJets).et() >= topJets.at(k).et()) {
0170 ++topJetsPosition.at(k);
0171 }
0172 if (topJets.at(numberOfTopJets).et() <= topJets.at(k).et()) {
0173 ++topJetsPosition.at(numberOfTopJets);
0174 }
0175 }
0176 ++numberOfTopJets;
0177 } else {
0178
0179 botJets.at(numberOfBotJets) = temp;
0180 botJetsPosition.at(numberOfBotJets) = 0;
0181 for (unsigned k = 0; k < numberOfBotJets; ++k) {
0182 if (botJets.at(numberOfBotJets).et() >= botJets.at(k).et()) {
0183 ++botJetsPosition.at(k);
0184 }
0185 if (botJets.at(numberOfBotJets).et() <= botJets.at(k).et()) {
0186 ++botJetsPosition.at(numberOfBotJets);
0187 }
0188 }
0189 ++numberOfBotJets;
0190 }
0191 }
0192
0193
0194
0195
0196
0197
0198 static const unsigned int MAX_TOPBOT_JETS = MAX_JETS_OUT / 2;
0199 unsigned pos = 0;
0200 for (unsigned j = 0; j < numberOfBotJets; ++j) {
0201 if (botJetsPosition.at(j) < MAX_TOPBOT_JETS) {
0202 m_clusters.at(pos++) = botJets.at(j);
0203 }
0204 }
0205 pos = MAX_TOPBOT_JETS;
0206 for (unsigned j = 0; j < numberOfTopJets; ++j) {
0207 if (topJetsPosition.at(j) < MAX_TOPBOT_JETS) {
0208 m_clusters.at(pos++) = topJets.at(j);
0209 }
0210 }
0211
0212 if (!m_localMax00.at(0).empty())
0213 m_cluster00.at(0) = makeProtoJet(m_localMax00.at(0));
0214 if (!m_localMax00.at(1).empty())
0215 m_cluster00.at(1) = makeProtoJet(m_localMax00.at(1));
0216 }
0217
0218
0219 L1GctRegion L1GctHardwareJetFinder::makeProtoJet(L1GctRegion localMax) {
0220 unsigned eta = localMax.gctEta();
0221 unsigned phi = localMax.gctPhi();
0222 int16_t bx = localMax.bx();
0223
0224 unsigned localEta = localMax.rctEta();
0225 unsigned localPhi = localMax.rctPhi();
0226
0227 unsigned etCluster = 0;
0228 bool ovrFlowOr = false;
0229 bool tauVetoOr = false;
0230 unsigned rgnsAboveIsoThreshold = 0;
0231
0232
0233 const unsigned midEta = (L1CaloRegionDetId::N_ETA) / 2;
0234 bool wrongEtaWheel = ((!m_positiveEtaWheel) && (eta >= midEta)) || ((m_positiveEtaWheel) && (eta < midEta));
0235
0236
0237 unsigned rowStart, rowEnd, rowMid;
0238 static const unsigned row0 = N_EXTRA_REGIONS_ETA00 - 1;
0239 if (wrongEtaWheel) {
0240 if (localEta > row0 - 1) {
0241 rowStart = 0;
0242 rowMid = 0;
0243 } else {
0244 rowStart = row0 - 1 - localEta;
0245 rowMid = rowStart + 1;
0246 }
0247 if (localEta > row0 + 2) {
0248 rowEnd = 0;
0249 } else {
0250 rowEnd = row0 + 2 - localEta;
0251 }
0252 } else {
0253 rowStart = row0 + localEta;
0254 rowMid = rowStart + 1;
0255 if (localEta < COL_OFFSET - row0 - 2) {
0256 rowEnd = rowStart + 3;
0257 } else {
0258 rowEnd = COL_OFFSET;
0259 }
0260 }
0261
0262 for (unsigned row = rowStart; row < rowEnd; ++row) {
0263 for (unsigned column = 0; column < 2; ++column) {
0264 unsigned index = column * COL_OFFSET + row;
0265 etCluster += m_inputRegions.at(index).et();
0266 ovrFlowOr |= m_inputRegions.at(index).overFlow();
0267
0268 if (m_useImprovedTauAlgo) {
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288 if (!((row == rowMid) && (column == localPhi))) {
0289
0290 if (m_inputRegions.at(index).et() >= m_tauIsolationThreshold) {
0291 rgnsAboveIsoThreshold++;
0292 }
0293 }
0294
0295 if (!m_ignoreTauVetoBitsForIsolation) {
0296 tauVetoOr |= m_inputRegions.at(index).tauVeto();
0297 }
0298
0299 } else {
0300
0301 tauVetoOr |= m_inputRegions.at(index).tauVeto();
0302 }
0303 }
0304 }
0305
0306 bool tauFeatureBit = false;
0307 if (m_useImprovedTauAlgo) {
0308 tauVetoOr |= (rgnsAboveIsoThreshold > 1);
0309 tauFeatureBit |= (rgnsAboveIsoThreshold == 1);
0310 }
0311
0312 L1GctRegion temp(L1GctRegion::makeProtoJetRegion(etCluster, ovrFlowOr, tauVetoOr, tauFeatureBit, eta, phi, bx));
0313 return temp;
0314 }
0315
0316
0317 void L1GctHardwareJetFinder::findFinalClusters() {
0318 m_clusters.clear();
0319 m_clusters.resize(MAX_JETS_OUT);
0320
0321
0322
0323
0324
0325 for (unsigned j = 0; j < MAX_JETS_OUT; ++j) {
0326 unsigned et0 = m_rcvdProtoJets.at(j).et();
0327 unsigned localEta0 = m_rcvdProtoJets.at(j).rctEta();
0328 unsigned localPhi0 = m_rcvdProtoJets.at(j).rctPhi();
0329 unsigned JET_THRESHOLD = ((localEta0 >= m_EtaBoundry) ? m_FwdJetSeed : m_CenJetSeed);
0330 if (et0 >= JET_THRESHOLD) {
0331 bool storeJet = false;
0332 bool isolated = true;
0333
0334 if (localEta0 == 0) {
0335 unsigned neighbourEt = m_cluster00.at(1 - localPhi0).et();
0336 isolated &= et0 >= neighbourEt;
0337 }
0338
0339
0340
0341 if (isolated) {
0342 for (unsigned k = 0; k < MAX_JETS_OUT; ++k) {
0343 unsigned et1 = m_keptProtoJets.at(k).et();
0344 unsigned localEta1 = m_keptProtoJets.at(k).rctEta();
0345 unsigned localPhi1 = m_keptProtoJets.at(k).rctPhi();
0346 if (et1 > 0) {
0347 bool distantJet = ((localPhi0 == localPhi1) || (localEta1 > localEta0 + 1) || (localEta0 > localEta1 + 1));
0348
0349 isolated &= distantJet;
0350 storeJet |= !distantJet && ((et0 > et1) || ((et0 == et1) && localPhi0 == 1));
0351 }
0352 }
0353 }
0354
0355 storeJet |= isolated;
0356
0357 if (storeJet) {
0358
0359 unsigned etCluster = et0;
0360 bool ovrFlowOr = m_rcvdProtoJets.at(j).overFlow();
0361 bool tauVetoOr = m_rcvdProtoJets.at(j).tauVeto();
0362 unsigned rgnsAboveIsoThreshold = (m_rcvdProtoJets.at(j).featureBit0() ? 1 : 0);
0363
0364
0365
0366 unsigned column = 1 - localPhi0;
0367
0368 unsigned rowStart, rowEnd;
0369 static const unsigned row0 = N_EXTRA_REGIONS_ETA00 - 1;
0370 rowStart = row0 + localEta0;
0371 if (localEta0 < COL_OFFSET - row0 - 2) {
0372 rowEnd = rowStart + 3;
0373 } else {
0374 rowEnd = COL_OFFSET;
0375 }
0376 unsigned index = COL_OFFSET * (this->centralCol0() + column) + rowStart;
0377 for (unsigned row = rowStart; row < rowEnd; ++row) {
0378 etCluster += m_inputRegions.at(index).et();
0379 ovrFlowOr |= m_inputRegions.at(index).overFlow();
0380 if (m_useImprovedTauAlgo) {
0381 if (!m_ignoreTauVetoBitsForIsolation) {
0382 tauVetoOr |= m_inputRegions.at(index).tauVeto();
0383 }
0384
0385 if (m_inputRegions.at(index).et() >= m_tauIsolationThreshold) {
0386 rgnsAboveIsoThreshold++;
0387 }
0388 } else {
0389 tauVetoOr |= m_inputRegions.at(index).tauVeto();
0390 }
0391
0392 ++index;
0393 }
0394
0395
0396 unsigned eta = m_rcvdProtoJets.at(j).gctEta();
0397 unsigned phi = m_rcvdProtoJets.at(j).gctPhi();
0398 int16_t bx = m_rcvdProtoJets.at(j).bx();
0399
0400
0401 if (m_useImprovedTauAlgo) {
0402 tauVetoOr |= (rgnsAboveIsoThreshold > 1);
0403 }
0404
0405 L1GctRegion temp(L1GctRegion::makeFinalJetRegion(etCluster, ovrFlowOr, tauVetoOr, eta, phi, bx));
0406 m_clusters.at(j) = temp;
0407 }
0408 }
0409 }
0410 }
0411
0412
0413 void L1GctHardwareJetFinder::convertClustersToProtoJets() {
0414 for (unsigned j = 0; j < MAX_JETS_OUT; ++j) {
0415 bool isForward = (m_clusters.at(j).rctEta() >= m_EtaBoundry);
0416 unsigned JET_THRESHOLD = (isForward ? m_FwdJetSeed : m_CenJetSeed);
0417 if (m_clusters.at(j).et() >= JET_THRESHOLD) {
0418 m_keptProtoJets.at(j) = m_clusters.at(j);
0419 m_sentProtoJets.at(j) = m_clusters.at(j);
0420 }
0421 }
0422 }
0423
0424
0425 void L1GctHardwareJetFinder::convertClustersToOutputJets() {
0426 for (unsigned j = 0; j < MAX_JETS_OUT; ++j) {
0427 bool isForward = (m_clusters.at(j).rctEta() >= m_EtaBoundry);
0428 unsigned JET_THRESHOLD = (isForward ? m_FwdJetSeed : m_CenJetSeed);
0429 if (m_clusters.at(j).et() >= JET_THRESHOLD) {
0430 L1GctJet temp(m_clusters.at(j).et(),
0431 m_clusters.at(j).gctEta(),
0432 m_clusters.at(j).gctPhi(),
0433 m_clusters.at(j).overFlow(),
0434 isForward,
0435 m_clusters.at(j).tauVeto(),
0436 m_clusters.at(j).bx());
0437 m_outputJets.at(j) = temp;
0438 }
0439 }
0440 }