File indexing completed on 2022-07-22 22:47:09
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 void CSCGEMMatcher::setESLookupTables(const CSCL1TPLookupTableME11ILT* conf) { lookupTableME11ILT_ = conf; }
0030
0031 void CSCGEMMatcher::setESLookupTables(const CSCL1TPLookupTableME21ILT* conf) { lookupTableME21ILT_ = conf; }
0032
0033
0034
0035
0036
0037 void CSCGEMMatcher::bestClusterLoc(const CSCALCTDigi& alct,
0038 const GEMInternalClusters& clusters,
0039 GEMInternalCluster& best) const {
0040 if (!alct.isValid() or clusters.empty())
0041 return;
0042
0043
0044 GEMInternalClusters clustersLoc;
0045 matchingClustersLoc(alct, clusters, clustersLoc);
0046
0047
0048 if (!clustersLoc.empty())
0049 best = clustersLoc[0];
0050 }
0051
0052 void CSCGEMMatcher::bestClusterLoc(const CSCCLCTDigi& clct,
0053 const GEMInternalClusters& clusters,
0054 GEMInternalCluster& best) const {
0055 if (!clct.isValid() or clusters.empty())
0056 return;
0057
0058
0059 bool ignoreALCTGEMmatch = true;
0060 GEMInternalClusters clustersLoc;
0061 matchingClustersLoc(clct, clusters, clustersLoc, ignoreALCTGEMmatch);
0062
0063
0064 if (!clustersLoc.empty())
0065 best = clustersLoc[0];
0066 }
0067
0068 void CSCGEMMatcher::bestClusterLoc(const CSCALCTDigi& alct,
0069 const CSCCLCTDigi& clct,
0070 const GEMInternalClusters& clusters,
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, 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) const {
0142 if (!clct.isValid() or clusters.empty())
0143 return;
0144
0145 if (station_ == 1 and !enable_match_gem_me1a_ and !enable_match_gem_me1b_)
0146 return;
0147
0148 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0149
0150
0151 unsigned eighthStripCut = isEven_ ? 4 * maxDeltaHsEven_ : 4 * maxDeltaHsOdd_;
0152
0153 for (const auto& cl : clusters) {
0154
0155
0156
0157 bool isMatchedLayer1 = false;
0158 bool isMatchedLayer2 = false;
0159
0160 if (cl.id1().layer() == 1) {
0161 if ((station_ == 1 and enable_match_gem_me1a_ and
0162 ((isME1a and cl.roll1() == 8) or (!isME1a and cl.roll1() < 8))) or
0163 (station_ == 1 and !enable_match_gem_me1a_ and !isME1a) or (station_ == 2)) {
0164 constexpr bool isLayer2 = false;
0165 unsigned distanceES = abs(matchedClusterDistES(clct, cl, isLayer2, false));
0166 if (distanceES <= eighthStripCut)
0167 isMatchedLayer1 = true;
0168 }
0169 }
0170 if (cl.id2().layer() == 2) {
0171 if ((station_ == 1 and enable_match_gem_me1a_ and
0172 ((isME1a and cl.roll2() == 8) or (!isME1a and cl.roll2() < 8))) or
0173 (station_ == 1 and !enable_match_gem_me1a_ and !isME1a) or (station_ == 2)) {
0174 constexpr bool isLayer2 = true;
0175 unsigned distanceES = abs(matchedClusterDistES(clct, cl, isLayer2, false));
0176 if (distanceES <= eighthStripCut)
0177 isMatchedLayer2 = true;
0178 }
0179 }
0180
0181
0182
0183 if (((ignoreALCTGEMmatch or cl.isMatchingLayer1()) and isMatchedLayer1) or
0184 ((ignoreALCTGEMmatch or cl.isMatchingLayer2()) and isMatchedLayer2)) {
0185 output.push_back(cl);
0186 output.back().set_matchingLayer1(false);
0187 output.back().set_matchingLayer2(false);
0188 if ((ignoreALCTGEMmatch or cl.isMatchingLayer1()) and isMatchedLayer1)
0189 output.back().set_matchingLayer1(true);
0190 if ((ignoreALCTGEMmatch or cl.isMatchingLayer2()) and isMatchedLayer2)
0191 output.back().set_matchingLayer2(true);
0192 }
0193 }
0194
0195
0196 std::sort(
0197 output.begin(), output.end(), [clct, this](const GEMInternalCluster cl1, const GEMInternalCluster cl2) -> bool {
0198 if (cl1.isCoincidence() and !cl2.isCoincidence())
0199 return cl1.isCoincidence();
0200 else if ((cl1.isCoincidence() and cl2.isCoincidence()) or (!cl1.isCoincidence() and !cl2.isCoincidence())) {
0201 bool cl1_isLayer2 = !cl1.isMatchingLayer1() and cl1.isMatchingLayer2();
0202 bool cl2_isLayer2 = !cl2.isMatchingLayer1() and cl2.isMatchingLayer2();
0203 unsigned cl1_distanceES = abs(matchedClusterDistES(clct, cl1, cl1_isLayer2, false));
0204 unsigned cl2_distanceES = abs(matchedClusterDistES(clct, cl2, cl2_isLayer2, false));
0205 return cl1_distanceES < cl2_distanceES;
0206 } else
0207 return false;
0208 });
0209 }
0210
0211 void CSCGEMMatcher::matchingClustersLoc(const CSCALCTDigi& alct,
0212 const CSCCLCTDigi& clct,
0213 const GEMInternalClusters& clusters,
0214 GEMInternalClusters& output) const {
0215
0216 if (!alct.isValid() or !clct.isValid() or clusters.empty())
0217 return;
0218
0219
0220 bool ignoreALCTGEMmatch = false;
0221 GEMInternalClusters alctClusters;
0222 matchingClustersLoc(alct, clusters, alctClusters);
0223 matchingClustersLoc(clct, alctClusters, output, ignoreALCTGEMmatch);
0224 }
0225
0226
0227
0228
0229
0230
0231 int CSCGEMMatcher::matchedClusterDistES(const CSCCLCTDigi& clct,
0232 const GEMInternalCluster& cl,
0233 const bool isLayer2,
0234 const bool ForceTotal) const {
0235 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0236
0237 int cl_es = isME1a ? cl.getKeyStripME1a(8, isLayer2) : cl.getKeyStrip(8, isLayer2);
0238
0239 int eighthStripDiff = cl_es - clct.getKeyStrip(8);
0240
0241 if (matchCLCTpropagation_ and !ForceTotal) {
0242 int SlopeShift = 0;
0243 uint16_t baseSlope = -1;
0244 baseSlope = mitigateSlopeByCosi_ ? mitigatedSlopeByConsistency(clct) : clct.getSlope();
0245
0246 int clctSlope = pow(-1, clct.getBend()) * baseSlope;
0247
0248 SlopeShift = CSCGEMSlopeCorrector(isME1a, clctSlope, isLayer2);
0249 eighthStripDiff -= SlopeShift;
0250 }
0251
0252 return eighthStripDiff;
0253 }
0254
0255
0256
0257
0258
0259
0260 uint16_t CSCGEMMatcher::mitigatedSlopeByConsistency(const CSCCLCTDigi& clct) const {
0261 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0262
0263
0264 std::vector<std::vector<uint16_t>> CLCTHitMatrix = clct.getHits();
0265 int CLCTHits[6] = {-1, -1, -1, -1, -1, -1};
0266
0267 for (unsigned layer = 0; layer < CLCTHitMatrix.size(); ++layer) {
0268 for (unsigned position = 0; position < CLCTHitMatrix.at(layer).size(); ++position) {
0269 const uint16_t value = CLCTHitMatrix.at(layer).at(position);
0270 if (value != 0 && value != 65535) {
0271 CLCTHits[layer] = (int)value;
0272 break;
0273 }
0274 }
0275 }
0276
0277
0278
0279
0280
0281 float MinMaxPairDifferences[2] = {999., -999.};
0282 for (unsigned First = 0; First < 5; ++First) {
0283
0284 if (CLCTHits[First] == -1)
0285 continue;
0286 for (unsigned Second = First + 1; Second < 6; ++Second) {
0287
0288 if (CLCTHits[Second] == -1)
0289 continue;
0290 float PairDifference = (CLCTHits[First] - CLCTHits[Second]) / (float)(Second - First);
0291 if (PairDifference < MinMaxPairDifferences[0])
0292 MinMaxPairDifferences[0] = PairDifference;
0293 if (PairDifference > MinMaxPairDifferences[1])
0294 MinMaxPairDifferences[1] = PairDifference;
0295 }
0296 }
0297
0298
0299 uint16_t cosi = std::ceil(std::abs(MinMaxPairDifferences[1] - MinMaxPairDifferences[0]));
0300
0301
0302
0303
0304
0305
0306 if (cosi > 3)
0307 return 0;
0308
0309 else if (cosi < 2)
0310 return clct.getSlope();
0311
0312 else if (cosi == 2) {
0313 if (station_ == 1) {
0314 if (isME1a) {
0315 if (chamber_ % 2 == 0)
0316 return lookupTableME11ILT_->CSC_slope_cosi_2to1_L1_ME11a_even(clct.getSlope());
0317 else
0318 return lookupTableME11ILT_->CSC_slope_cosi_2to1_L1_ME11a_odd(clct.getSlope());
0319 } else {
0320 if (chamber_ % 2 == 0)
0321 return lookupTableME11ILT_->CSC_slope_cosi_2to1_L1_ME11b_even(clct.getSlope());
0322 else
0323 return lookupTableME11ILT_->CSC_slope_cosi_2to1_L1_ME11b_odd(clct.getSlope());
0324 }
0325 } else {
0326 if (chamber_ % 2 == 0)
0327 return lookupTableME21ILT_->CSC_slope_cosi_2to1_L1_ME21_even(clct.getSlope());
0328 else
0329 return lookupTableME21ILT_->CSC_slope_cosi_2to1_L1_ME21_odd(clct.getSlope());
0330 }
0331 }
0332
0333 else if (cosi == 3) {
0334 if (station_ == 1) {
0335 if (isME1a) {
0336 if (chamber_ % 2 == 0)
0337 return lookupTableME11ILT_->CSC_slope_cosi_3to1_L1_ME11a_even(clct.getSlope());
0338 else
0339 return lookupTableME11ILT_->CSC_slope_cosi_3to1_L1_ME11a_odd(clct.getSlope());
0340 } else {
0341 if (chamber_ % 2 == 0)
0342 return lookupTableME11ILT_->CSC_slope_cosi_3to1_L1_ME11b_even(clct.getSlope());
0343 else
0344 return lookupTableME11ILT_->CSC_slope_cosi_3to1_L1_ME11b_odd(clct.getSlope());
0345 }
0346 } else {
0347 if (chamber_ % 2 == 0)
0348 return lookupTableME21ILT_->CSC_slope_cosi_3to1_L1_ME21_even(clct.getSlope());
0349 else
0350 return lookupTableME21ILT_->CSC_slope_cosi_3to1_L1_ME21_odd(clct.getSlope());
0351 }
0352 }
0353
0354 else {
0355 return 999;
0356 }
0357 }
0358
0359
0360
0361
0362
0363
0364 int CSCGEMMatcher::CSCGEMSlopeCorrector(bool isME1a, int cscSlope, bool isLayer2) const {
0365 int SlopeShift = 0;
0366 int SlopeSign = pow(-1, std::signbit(cscSlope));
0367
0368
0369 if (mitigateSlopeByCosi_) {
0370 if (station_ == 1) {
0371 if (chamber_ % 2 == 0)
0372 SlopeShift = isME1a ? lookupTableME11ILT_->CSC_slope_cosi_corr_L1_ME11a_even(std::abs(cscSlope))
0373 : lookupTableME11ILT_->CSC_slope_cosi_corr_L1_ME11b_even(std::abs(cscSlope));
0374 else
0375 SlopeShift = isME1a ? lookupTableME11ILT_->CSC_slope_cosi_corr_L1_ME11a_odd(std::abs(cscSlope))
0376 : lookupTableME11ILT_->CSC_slope_cosi_corr_L1_ME11b_odd(std::abs(cscSlope));
0377 } else if (station_ == 2) {
0378 if (chamber_ % 2 == 0)
0379 SlopeShift = lookupTableME21ILT_->CSC_slope_cosi_corr_L1_ME21_even(std::abs(cscSlope));
0380 else
0381 SlopeShift = lookupTableME21ILT_->CSC_slope_cosi_corr_L1_ME21_odd(std::abs(cscSlope));
0382 }
0383 } else {
0384 if (station_ == 1) {
0385 if (!isLayer2) {
0386 if (chamber_ % 2 == 0)
0387 SlopeShift = isME1a ? lookupTableME11ILT_->CSC_slope_corr_L1_ME11a_even(std::abs(cscSlope))
0388 : lookupTableME11ILT_->CSC_slope_corr_L1_ME11b_even(std::abs(cscSlope));
0389 else
0390 SlopeShift = isME1a ? lookupTableME11ILT_->CSC_slope_corr_L1_ME11a_odd(std::abs(cscSlope))
0391 : lookupTableME11ILT_->CSC_slope_corr_L1_ME11b_odd(std::abs(cscSlope));
0392 } else {
0393 if (chamber_ % 2 == 0)
0394 SlopeShift = isME1a ? lookupTableME11ILT_->CSC_slope_corr_L2_ME11a_even(std::abs(cscSlope))
0395 : lookupTableME11ILT_->CSC_slope_corr_L2_ME11b_even(std::abs(cscSlope));
0396 else
0397 SlopeShift = isME1a ? lookupTableME11ILT_->CSC_slope_corr_L2_ME11a_odd(std::abs(cscSlope))
0398 : lookupTableME11ILT_->CSC_slope_corr_L2_ME11b_odd(std::abs(cscSlope));
0399 }
0400 } else if (station_ == 2) {
0401 if (!isLayer2) {
0402 if (chamber_ % 2 == 0)
0403 SlopeShift = lookupTableME21ILT_->CSC_slope_corr_L1_ME21_even(std::abs(cscSlope));
0404 else
0405 SlopeShift = lookupTableME21ILT_->CSC_slope_corr_L1_ME21_odd(std::abs(cscSlope));
0406 } else {
0407 if (chamber_ % 2 == 0)
0408 SlopeShift = lookupTableME21ILT_->CSC_slope_corr_L2_ME21_even(std::abs(cscSlope));
0409 else
0410 SlopeShift = lookupTableME21ILT_->CSC_slope_corr_L2_ME21_odd(std::abs(cscSlope));
0411 }
0412 }
0413 }
0414 return std::round(SlopeShift * SlopeSign);
0415 }
0416
0417
0418
0419
0420
0421
0422 int CSCGEMMatcher::calculateGEMCSCBending(const CSCCLCTDigi& clct, const GEMInternalCluster& cluster) const {
0423 const bool isME1a(station_ == 1 and clct.getKeyStrip() > CSCConstants::MAX_HALF_STRIP_ME1B);
0424
0425 bool isLayer2 = false;
0426 if (!cluster.isMatchingLayer1() and cluster.isMatchingLayer2())
0427 isLayer2 = true;
0428
0429
0430 const int SignedEighthStripDiff = matchedClusterDistES(clct, cluster, isLayer2, true);
0431 const unsigned eighthStripDiff = abs(SignedEighthStripDiff);
0432
0433
0434 int slopeShift = 0;
0435 if (station_ == 2) {
0436 if (!isLayer2) {
0437 if (isEven_)
0438 slopeShift = lookupTableME21ILT_->es_diff_slope_L1_ME21_even(eighthStripDiff);
0439 else
0440 slopeShift = lookupTableME21ILT_->es_diff_slope_L1_ME21_odd(eighthStripDiff);
0441 } else {
0442 if (isEven_)
0443 slopeShift = lookupTableME21ILT_->es_diff_slope_L2_ME21_even(eighthStripDiff);
0444 else
0445 slopeShift = lookupTableME21ILT_->es_diff_slope_L2_ME21_odd(eighthStripDiff);
0446 }
0447 } else if (station_ == 1) {
0448 if (isME1a) {
0449 if (!isLayer2) {
0450 if (isEven_)
0451 slopeShift = lookupTableME11ILT_->es_diff_slope_L1_ME11a_even(eighthStripDiff);
0452 else
0453 slopeShift = lookupTableME11ILT_->es_diff_slope_L1_ME11a_odd(eighthStripDiff);
0454 } else {
0455 if (isEven_)
0456 slopeShift = lookupTableME11ILT_->es_diff_slope_L2_ME11a_even(eighthStripDiff);
0457 else
0458 slopeShift = lookupTableME11ILT_->es_diff_slope_L2_ME11a_odd(eighthStripDiff);
0459 }
0460 } else {
0461 if (!isLayer2) {
0462 if (isEven_)
0463 slopeShift = lookupTableME11ILT_->es_diff_slope_L1_ME11b_even(eighthStripDiff);
0464 else
0465 slopeShift = lookupTableME11ILT_->es_diff_slope_L1_ME11b_odd(eighthStripDiff);
0466 } else {
0467 if (isEven_)
0468 slopeShift = lookupTableME11ILT_->es_diff_slope_L2_ME11b_even(eighthStripDiff);
0469 else
0470 slopeShift = lookupTableME11ILT_->es_diff_slope_L2_ME11b_odd(eighthStripDiff);
0471 }
0472 }
0473 }
0474
0475
0476 slopeShift *= pow(-1, std::signbit(SignedEighthStripDiff));
0477
0478 return slopeShift;
0479 }