File indexing completed on 2024-04-06 12:19:36
0001 #include "L1Trigger/CSCTriggerPrimitives/interface/CSCGEMMatcher.h"
0002 #include "L1Trigger/CSCTriggerPrimitives/interface/GEMInternalCluster.h"
0003 #include "DataFormats/CSCDigi/interface/CSCConstants.h"
0004 #include "DataFormats/CSCDigi/interface/CSCALCTDigi.h"
0005 #include "DataFormats/CSCDigi/interface/CSCCLCTDigi.h"
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007
0008 #include <algorithm>
0009 #include <cmath>
0010
0011 CSCGEMMatcher::CSCGEMMatcher(
0012 int endcap, unsigned station, unsigned chamber, const edm::ParameterSet& tmbParams, const edm::ParameterSet& conf)
0013 : endcap_(endcap), station_(station), chamber_(chamber) {
0014 isEven_ = (chamber_ % 2 == 0);
0015
0016 enable_match_gem_me1a_ = tmbParams.getParameter<bool>("enableMatchGEMandME1a");
0017 enable_match_gem_me1b_ = tmbParams.getParameter<bool>("enableMatchGEMandME1b");
0018
0019 maxDeltaWG_ = tmbParams.getParameter<unsigned>("maxDeltaWG");
0020 maxDeltaHsEven_ = tmbParams.getParameter<unsigned>("maxDeltaHsEven");
0021 maxDeltaHsOdd_ = tmbParams.getParameter<unsigned>("maxDeltaHsOdd");
0022
0023 matchCLCTpropagation_ = tmbParams.getParameter<bool>("matchCLCTpropagation");
0024
0025 mitigateSlopeByCosi_ = tmbParams.getParameter<bool>("mitigateSlopeByCosi");
0026 assign_gem_csc_bending_ = tmbParams.getParameter<bool>("assignGEMCSCBending");
0027 }
0028
0029
0030
0031
0032
0033 void CSCGEMMatcher::bestClusterLoc(const CSCALCTDigi& alct,
0034 const GEMInternalClusters& clusters,
0035 GEMInternalCluster& best) const {
0036 if (!alct.isValid() or clusters.empty())
0037 return;
0038
0039
0040 GEMInternalClusters clustersLoc;
0041 matchingClustersLoc(alct, clusters, clustersLoc);
0042
0043
0044 if (!clustersLoc.empty())
0045 best = clustersLoc[0];
0046 }
0047
0048 void CSCGEMMatcher::bestClusterLoc(const CSCCLCTDigi& clct,
0049 const GEMInternalClusters& clusters,
0050 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0051 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT,
0052 GEMInternalCluster& best) const {
0053 if (!clct.isValid() or clusters.empty())
0054 return;
0055
0056
0057 bool ignoreALCTGEMmatch = true;
0058 GEMInternalClusters clustersLoc;
0059 matchingClustersLoc(clct, clusters, clustersLoc, ignoreALCTGEMmatch, lookupTableME11ILT, lookupTableME21ILT);
0060
0061
0062 if (!clustersLoc.empty())
0063 best = clustersLoc[0];
0064 }
0065
0066 void CSCGEMMatcher::bestClusterLoc(const CSCALCTDigi& alct,
0067 const CSCCLCTDigi& clct,
0068 const GEMInternalClusters& clusters,
0069 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0070 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT,
0071 GEMInternalCluster& best) const {
0072 if (!alct.isValid() or !clct.isValid() or clusters.empty())
0073 return;
0074
0075
0076 GEMInternalClusters clustersLoc;
0077 matchingClustersLoc(alct, clct, clusters, lookupTableME11ILT, lookupTableME21ILT, clustersLoc);
0078
0079
0080 if (!clustersLoc.empty()) {
0081 best = clustersLoc[0];
0082 if (best.isCoincidence() and !best.isMatchingLayer1() and best.isMatchingLayer2())
0083 best.set_coincidence(false);
0084
0085 }
0086 }
0087
0088
0089
0090
0091
0092
0093 void CSCGEMMatcher::matchingClustersLoc(const CSCALCTDigi& alct,
0094 const GEMInternalClusters& clusters,
0095 GEMInternalClusters& output) const {
0096 if (!alct.isValid() or clusters.empty())
0097 return;
0098
0099 int number_of_wg = 0;
0100 if (station_ == 1)
0101 number_of_wg = CSCConstants::NUM_WIREGROUPS_ME11;
0102 else if (station_ == 2)
0103 number_of_wg = CSCConstants::NUM_WIREGROUPS_ME21;
0104
0105
0106
0107 for (const auto& cl : clusters) {
0108
0109 bool isMatchedLayer1 = false;
0110 bool isMatchedLayer2 = false;
0111
0112 if (cl.id1().layer() == 1) {
0113 int min_wg = std::max(0, int(cl.layer1_min_wg() - maxDeltaWG_));
0114 int max_wg = std::min(number_of_wg - 1, int(cl.layer1_max_wg() + maxDeltaWG_));
0115 if (min_wg <= alct.getKeyWG() and alct.getKeyWG() <= max_wg)
0116 isMatchedLayer1 = true;
0117 }
0118 if (cl.id2().layer() == 2) {
0119 int min_wg = std::max(0, int(cl.layer2_min_wg() - maxDeltaWG_));
0120 int max_wg = std::min(number_of_wg - 1, int(cl.layer2_max_wg() + maxDeltaWG_));
0121 if (min_wg <= alct.getKeyWG() and alct.getKeyWG() <= max_wg)
0122 isMatchedLayer2 = true;
0123 }
0124
0125
0126
0127 if (isMatchedLayer1 or isMatchedLayer2) {
0128 output.push_back(cl);
0129 if (isMatchedLayer1)
0130 output.back().set_matchingLayer1(true);
0131 if (isMatchedLayer2)
0132 output.back().set_matchingLayer2(true);
0133 }
0134 }
0135 }
0136
0137
0138 void CSCGEMMatcher::matchingClustersLoc(const CSCCLCTDigi& clct,
0139 const GEMInternalClusters& clusters,
0140 GEMInternalClusters& output,
0141 bool ignoreALCTGEMmatch,
0142 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0143 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT) const {
0144 if (!clct.isValid() or clusters.empty())
0145 return;
0146
0147 if (station_ == 1 and !enable_match_gem_me1a_ and !enable_match_gem_me1b_)
0148 return;
0149
0150 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0151
0152
0153 unsigned eighthStripCut = isEven_ ? 4 * maxDeltaHsEven_ : 4 * maxDeltaHsOdd_;
0154
0155 for (const auto& cl : clusters) {
0156
0157
0158
0159 bool isMatchedLayer1 = false;
0160 bool isMatchedLayer2 = false;
0161
0162 if (cl.id1().layer() == 1) {
0163 if ((station_ == 1 and enable_match_gem_me1a_ and
0164 ((isME1a and cl.roll1() == 8) or (!isME1a and cl.roll1() < 8))) or
0165 (station_ == 1 and !enable_match_gem_me1a_ and !isME1a) or (station_ == 2)) {
0166 constexpr bool isLayer2 = false;
0167 unsigned distanceES =
0168 abs(matchedClusterDistES(clct, cl, isLayer2, false, lookupTableME11ILT, lookupTableME21ILT));
0169 if (distanceES <= eighthStripCut)
0170 isMatchedLayer1 = true;
0171 }
0172 }
0173 if (cl.id2().layer() == 2) {
0174 if ((station_ == 1 and enable_match_gem_me1a_ and
0175 ((isME1a and cl.roll2() == 8) or (!isME1a and cl.roll2() < 8))) or
0176 (station_ == 1 and !enable_match_gem_me1a_ and !isME1a) or (station_ == 2)) {
0177 constexpr bool isLayer2 = true;
0178 unsigned distanceES =
0179 abs(matchedClusterDistES(clct, cl, isLayer2, false, lookupTableME11ILT, lookupTableME21ILT));
0180 if (distanceES <= eighthStripCut)
0181 isMatchedLayer2 = true;
0182 }
0183 }
0184
0185
0186
0187 if (((ignoreALCTGEMmatch or cl.isMatchingLayer1()) and isMatchedLayer1) or
0188 ((ignoreALCTGEMmatch or cl.isMatchingLayer2()) and isMatchedLayer2)) {
0189 output.push_back(cl);
0190 output.back().set_matchingLayer1(false);
0191 output.back().set_matchingLayer2(false);
0192 if ((ignoreALCTGEMmatch or cl.isMatchingLayer1()) and isMatchedLayer1)
0193 output.back().set_matchingLayer1(true);
0194 if ((ignoreALCTGEMmatch or cl.isMatchingLayer2()) and isMatchedLayer2)
0195 output.back().set_matchingLayer2(true);
0196 }
0197 }
0198
0199
0200 std::sort(
0201 output.begin(),
0202 output.end(),
0203 [clct, lookupTableME11ILT, lookupTableME21ILT, this](const GEMInternalCluster cl1,
0204 const GEMInternalCluster cl2) -> bool {
0205 if (cl1.isCoincidence() and !cl2.isCoincidence())
0206 return cl1.isCoincidence();
0207 else if ((cl1.isCoincidence() and cl2.isCoincidence()) or (!cl1.isCoincidence() and !cl2.isCoincidence())) {
0208 bool cl1_isLayer2 = !cl1.isMatchingLayer1() and cl1.isMatchingLayer2();
0209 bool cl2_isLayer2 = !cl2.isMatchingLayer1() and cl2.isMatchingLayer2();
0210 unsigned cl1_distanceES =
0211 abs(matchedClusterDistES(clct, cl1, cl1_isLayer2, false, lookupTableME11ILT, lookupTableME21ILT));
0212 unsigned cl2_distanceES =
0213 abs(matchedClusterDistES(clct, cl2, cl2_isLayer2, false, lookupTableME11ILT, lookupTableME21ILT));
0214 return cl1_distanceES < cl2_distanceES;
0215 } else
0216 return false;
0217 });
0218 }
0219
0220 void CSCGEMMatcher::matchingClustersLoc(const CSCALCTDigi& alct,
0221 const CSCCLCTDigi& clct,
0222 const GEMInternalClusters& clusters,
0223 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0224 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT,
0225 GEMInternalClusters& output) const {
0226
0227 if (!alct.isValid() or !clct.isValid() or clusters.empty())
0228 return;
0229
0230
0231 bool ignoreALCTGEMmatch = false;
0232 GEMInternalClusters alctClusters;
0233 matchingClustersLoc(alct, clusters, alctClusters);
0234 matchingClustersLoc(clct, alctClusters, output, ignoreALCTGEMmatch, lookupTableME11ILT, lookupTableME21ILT);
0235 }
0236
0237
0238
0239
0240
0241
0242 int CSCGEMMatcher::matchedClusterDistES(const CSCCLCTDigi& clct,
0243 const GEMInternalCluster& cl,
0244 const bool isLayer2,
0245 const bool ForceTotal,
0246 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0247 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT) const {
0248 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0249
0250 int cl_es = isME1a ? cl.getKeyStripME1a(8, isLayer2) : cl.getKeyStrip(8, isLayer2);
0251
0252 int eighthStripDiff = cl_es - clct.getKeyStrip(8);
0253
0254 if (matchCLCTpropagation_ and !ForceTotal) {
0255 int SlopeShift = 0;
0256 uint16_t baseSlope = -1;
0257 baseSlope = mitigateSlopeByCosi_ ? mitigatedSlopeByConsistency(clct, lookupTableME11ILT, lookupTableME21ILT)
0258 : clct.getSlope();
0259
0260 int clctSlope = pow(-1, clct.getBend()) * baseSlope;
0261
0262 SlopeShift = CSCGEMSlopeCorrector(isME1a, clctSlope, isLayer2, lookupTableME11ILT, lookupTableME21ILT);
0263 eighthStripDiff -= SlopeShift;
0264 }
0265
0266 return eighthStripDiff;
0267 }
0268
0269
0270
0271
0272
0273
0274 uint16_t CSCGEMMatcher::mitigatedSlopeByConsistency(const CSCCLCTDigi& clct,
0275 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0276 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT) const {
0277 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0278
0279
0280 std::vector<std::vector<uint16_t>> CLCTHitMatrix = clct.getHits();
0281 int CLCTHits[6] = {-1, -1, -1, -1, -1, -1};
0282
0283 for (unsigned layer = 0; layer < CLCTHitMatrix.size(); ++layer) {
0284 for (unsigned position = 0; position < CLCTHitMatrix.at(layer).size(); ++position) {
0285 const uint16_t value = CLCTHitMatrix.at(layer).at(position);
0286 if (value != 0 && value != 65535) {
0287 CLCTHits[layer] = (int)value;
0288 break;
0289 }
0290 }
0291 }
0292
0293
0294
0295
0296
0297 float MinMaxPairDifferences[2] = {999., -999.};
0298 for (unsigned First = 0; First < 5; ++First) {
0299
0300 if (CLCTHits[First] == -1)
0301 continue;
0302 for (unsigned Second = First + 1; Second < 6; ++Second) {
0303
0304 if (CLCTHits[Second] == -1)
0305 continue;
0306 float PairDifference = (CLCTHits[First] - CLCTHits[Second]) / (float)(Second - First);
0307 if (PairDifference < MinMaxPairDifferences[0])
0308 MinMaxPairDifferences[0] = PairDifference;
0309 if (PairDifference > MinMaxPairDifferences[1])
0310 MinMaxPairDifferences[1] = PairDifference;
0311 }
0312 }
0313
0314
0315 uint16_t cosi = std::ceil(std::abs(MinMaxPairDifferences[1] - MinMaxPairDifferences[0]));
0316
0317
0318
0319
0320
0321
0322 if (cosi > 3)
0323 return 0;
0324
0325 else if (cosi < 2)
0326 return clct.getSlope();
0327
0328 else if (cosi == 2) {
0329 if (station_ == 1) {
0330 if (isME1a) {
0331 if (chamber_ % 2 == 0)
0332 return lookupTableME11ILT->CSC_slope_cosi_2to1_L1_ME11a_even(clct.getSlope());
0333 else
0334 return lookupTableME11ILT->CSC_slope_cosi_2to1_L1_ME11a_odd(clct.getSlope());
0335 } else {
0336 if (chamber_ % 2 == 0)
0337 return lookupTableME11ILT->CSC_slope_cosi_2to1_L1_ME11b_even(clct.getSlope());
0338 else
0339 return lookupTableME11ILT->CSC_slope_cosi_2to1_L1_ME11b_odd(clct.getSlope());
0340 }
0341 } else {
0342 if (chamber_ % 2 == 0)
0343 return lookupTableME21ILT->CSC_slope_cosi_2to1_L1_ME21_even(clct.getSlope());
0344 else
0345 return lookupTableME21ILT->CSC_slope_cosi_2to1_L1_ME21_odd(clct.getSlope());
0346 }
0347 }
0348
0349 else if (cosi == 3) {
0350 if (station_ == 1) {
0351 if (isME1a) {
0352 if (chamber_ % 2 == 0)
0353 return lookupTableME11ILT->CSC_slope_cosi_3to1_L1_ME11a_even(clct.getSlope());
0354 else
0355 return lookupTableME11ILT->CSC_slope_cosi_3to1_L1_ME11a_odd(clct.getSlope());
0356 } else {
0357 if (chamber_ % 2 == 0)
0358 return lookupTableME11ILT->CSC_slope_cosi_3to1_L1_ME11b_even(clct.getSlope());
0359 else
0360 return lookupTableME11ILT->CSC_slope_cosi_3to1_L1_ME11b_odd(clct.getSlope());
0361 }
0362 } else {
0363 if (chamber_ % 2 == 0)
0364 return lookupTableME21ILT->CSC_slope_cosi_3to1_L1_ME21_even(clct.getSlope());
0365 else
0366 return lookupTableME21ILT->CSC_slope_cosi_3to1_L1_ME21_odd(clct.getSlope());
0367 }
0368 }
0369
0370 else {
0371 return 999;
0372 }
0373 }
0374
0375
0376
0377
0378
0379
0380 int CSCGEMMatcher::CSCGEMSlopeCorrector(bool isME1a,
0381 int cscSlope,
0382 bool isLayer2,
0383 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0384 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT) const {
0385 int SlopeShift = 0;
0386 int SlopeSign = pow(-1, std::signbit(cscSlope));
0387
0388
0389 if (mitigateSlopeByCosi_) {
0390 if (station_ == 1) {
0391 if (chamber_ % 2 == 0)
0392 SlopeShift = isME1a ? lookupTableME11ILT->CSC_slope_cosi_corr_L1_ME11a_even(std::abs(cscSlope))
0393 : lookupTableME11ILT->CSC_slope_cosi_corr_L1_ME11b_even(std::abs(cscSlope));
0394 else
0395 SlopeShift = isME1a ? lookupTableME11ILT->CSC_slope_cosi_corr_L1_ME11a_odd(std::abs(cscSlope))
0396 : lookupTableME11ILT->CSC_slope_cosi_corr_L1_ME11b_odd(std::abs(cscSlope));
0397 } else if (station_ == 2) {
0398 if (chamber_ % 2 == 0)
0399 SlopeShift = lookupTableME21ILT->CSC_slope_cosi_corr_L1_ME21_even(std::abs(cscSlope));
0400 else
0401 SlopeShift = lookupTableME21ILT->CSC_slope_cosi_corr_L1_ME21_odd(std::abs(cscSlope));
0402 }
0403 } else {
0404 if (station_ == 1) {
0405 if (!isLayer2) {
0406 if (chamber_ % 2 == 0)
0407 SlopeShift = isME1a ? lookupTableME11ILT->CSC_slope_corr_L1_ME11a_even(std::abs(cscSlope))
0408 : lookupTableME11ILT->CSC_slope_corr_L1_ME11b_even(std::abs(cscSlope));
0409 else
0410 SlopeShift = isME1a ? lookupTableME11ILT->CSC_slope_corr_L1_ME11a_odd(std::abs(cscSlope))
0411 : lookupTableME11ILT->CSC_slope_corr_L1_ME11b_odd(std::abs(cscSlope));
0412 } else {
0413 if (chamber_ % 2 == 0)
0414 SlopeShift = isME1a ? lookupTableME11ILT->CSC_slope_corr_L2_ME11a_even(std::abs(cscSlope))
0415 : lookupTableME11ILT->CSC_slope_corr_L2_ME11b_even(std::abs(cscSlope));
0416 else
0417 SlopeShift = isME1a ? lookupTableME11ILT->CSC_slope_corr_L2_ME11a_odd(std::abs(cscSlope))
0418 : lookupTableME11ILT->CSC_slope_corr_L2_ME11b_odd(std::abs(cscSlope));
0419 }
0420 } else if (station_ == 2) {
0421 if (!isLayer2) {
0422 if (chamber_ % 2 == 0)
0423 SlopeShift = lookupTableME21ILT->CSC_slope_corr_L1_ME21_even(std::abs(cscSlope));
0424 else
0425 SlopeShift = lookupTableME21ILT->CSC_slope_corr_L1_ME21_odd(std::abs(cscSlope));
0426 } else {
0427 if (chamber_ % 2 == 0)
0428 SlopeShift = lookupTableME21ILT->CSC_slope_corr_L2_ME21_even(std::abs(cscSlope));
0429 else
0430 SlopeShift = lookupTableME21ILT->CSC_slope_corr_L2_ME21_odd(std::abs(cscSlope));
0431 }
0432 }
0433 }
0434 return std::round(SlopeShift * SlopeSign);
0435 }
0436
0437
0438
0439
0440
0441
0442 int CSCGEMMatcher::calculateGEMCSCBending(const CSCCLCTDigi& clct,
0443 const GEMInternalCluster& cluster,
0444 const CSCL1TPLookupTableME11ILT* lookupTableME11ILT,
0445 const CSCL1TPLookupTableME21ILT* lookupTableME21ILT) const {
0446 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0447
0448 bool isLayer2 = false;
0449 if (!cluster.isMatchingLayer1() and cluster.isMatchingLayer2())
0450 isLayer2 = true;
0451
0452
0453 const int SignedEighthStripDiff =
0454 matchedClusterDistES(clct, cluster, isLayer2, true, lookupTableME11ILT, lookupTableME21ILT);
0455 const unsigned eighthStripDiff = abs(SignedEighthStripDiff);
0456
0457
0458 int slopeShift = 0;
0459 if (station_ == 2) {
0460 if (!isLayer2) {
0461 if (isEven_)
0462 slopeShift = lookupTableME21ILT->es_diff_slope_L1_ME21_even(eighthStripDiff);
0463 else
0464 slopeShift = lookupTableME21ILT->es_diff_slope_L1_ME21_odd(eighthStripDiff);
0465 } else {
0466 if (isEven_)
0467 slopeShift = lookupTableME21ILT->es_diff_slope_L2_ME21_even(eighthStripDiff);
0468 else
0469 slopeShift = lookupTableME21ILT->es_diff_slope_L2_ME21_odd(eighthStripDiff);
0470 }
0471 } else if (station_ == 1) {
0472 if (isME1a) {
0473 if (!isLayer2) {
0474 if (isEven_)
0475 slopeShift = lookupTableME11ILT->es_diff_slope_L1_ME11a_even(eighthStripDiff);
0476 else
0477 slopeShift = lookupTableME11ILT->es_diff_slope_L1_ME11a_odd(eighthStripDiff);
0478 } else {
0479 if (isEven_)
0480 slopeShift = lookupTableME11ILT->es_diff_slope_L2_ME11a_even(eighthStripDiff);
0481 else
0482 slopeShift = lookupTableME11ILT->es_diff_slope_L2_ME11a_odd(eighthStripDiff);
0483 }
0484 } else {
0485 if (!isLayer2) {
0486 if (isEven_)
0487 slopeShift = lookupTableME11ILT->es_diff_slope_L1_ME11b_even(eighthStripDiff);
0488 else
0489 slopeShift = lookupTableME11ILT->es_diff_slope_L1_ME11b_odd(eighthStripDiff);
0490 } else {
0491 if (isEven_)
0492 slopeShift = lookupTableME11ILT->es_diff_slope_L2_ME11b_even(eighthStripDiff);
0493 else
0494 slopeShift = lookupTableME11ILT->es_diff_slope_L2_ME11b_odd(eighthStripDiff);
0495 }
0496 }
0497 }
0498
0499
0500 slopeShift *= pow(-1, std::signbit(SignedEighthStripDiff));
0501
0502 return slopeShift;
0503 }