File indexing completed on 2023-03-17 10:50:32
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016 #include "DataFormats/L1Trigger/interface/L1ParticleMap.h"
0017 #include "DataFormats/L1Trigger/interface/L1EmParticle.h"
0018 #include "DataFormats/L1Trigger/interface/L1JetParticle.h"
0019 #include "DataFormats/L1Trigger/interface/L1MuonParticle.h"
0020 #include "FWCore/Concurrency/interface/hardware_pause.h"
0021
0022 using namespace l1extra;
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 const std::string L1ParticleMap::triggerNames_[kNumOfL1TriggerTypes] = {"L1_SingleMu3",
0035 "L1_SingleMu5",
0036 "L1_SingleMu7",
0037 "L1_SingleMu10",
0038 "L1_SingleMu14",
0039 "L1_SingleMu20",
0040 "L1_SingleMu25",
0041 "L1_SingleIsoEG5",
0042 "L1_SingleIsoEG8",
0043 "L1_SingleIsoEG10",
0044 "L1_SingleIsoEG12",
0045 "L1_SingleIsoEG15",
0046 "L1_SingleIsoEG20",
0047 "L1_SingleIsoEG25",
0048 "L1_SingleEG5",
0049 "L1_SingleEG8",
0050 "L1_SingleEG10",
0051 "L1_SingleEG12",
0052 "L1_SingleEG15",
0053 "L1_SingleEG20",
0054 "L1_SingleEG25",
0055 "L1_SingleJet15",
0056 "L1_SingleJet20",
0057 "L1_SingleJet30",
0058 "L1_SingleJet50",
0059 "L1_SingleJet70",
0060 "L1_SingleJet100",
0061 "L1_SingleJet150",
0062 "L1_SingleJet200",
0063 "L1_SingleTauJet10",
0064 "L1_SingleTauJet20",
0065 "L1_SingleTauJet30",
0066 "L1_SingleTauJet35",
0067 "L1_SingleTauJet40",
0068 "L1_SingleTauJet60",
0069 "L1_SingleTauJet80",
0070 "L1_SingleTauJet100",
0071 "L1_HTT100",
0072 "L1_HTT200",
0073 "L1_HTT250",
0074 "L1_HTT300",
0075 "L1_HTT400",
0076 "L1_HTT500",
0077 "L1_ETM10",
0078 "L1_ETM15",
0079 "L1_ETM20",
0080 "L1_ETM30",
0081 "L1_ETM40",
0082 "L1_ETM50",
0083 "L1_ETM60",
0084 "L1_ETT60",
0085 "L1_DoubleMu3",
0086 "L1_DoubleIsoEG8",
0087 "L1_DoubleIsoEG10",
0088 "L1_DoubleEG5",
0089 "L1_DoubleEG10",
0090 "L1_DoubleEG15",
0091 "L1_DoubleJet70",
0092 "L1_DoubleJet100",
0093 "L1_DoubleTauJet20",
0094 "L1_DoubleTauJet30",
0095 "L1_DoubleTauJet35",
0096 "L1_DoubleTauJet40",
0097 "L1_Mu3_IsoEG5",
0098 "L1_Mu5_IsoEG10",
0099 "L1_Mu3_EG12",
0100 "L1_Mu3_Jet15",
0101 "L1_Mu5_Jet15",
0102 "L1_Mu3_Jet70",
0103 "L1_Mu5_Jet20",
0104 "L1_Mu5_TauJet20",
0105 "L1_Mu5_TauJet30",
0106 "L1_IsoEG10_EG10",
0107 "L1_IsoEG10_Jet15",
0108 "L1_IsoEG10_Jet20",
0109 "L1_IsoEG10_Jet30",
0110 "L1_IsoEG10_Jet70",
0111 "L1_IsoEG10_TauJet20",
0112 "L1_IsoEG10_TauJet30",
0113 "L1_EG10_Jet15",
0114 "L1_EG12_Jet20",
0115 "L1_EG12_Jet70",
0116 "L1_EG12_TauJet40",
0117 "L1_Jet70_TauJet40",
0118 "L1_Mu3_HTT200",
0119 "L1_IsoEG10_HTT200",
0120 "L1_EG12_HTT200",
0121 "L1_Jet70_HTT200",
0122 "L1_TauJet40_HTT200",
0123 "L1_Mu3_ETM30",
0124 "L1_IsoEG10_ETM30",
0125 "L1_EG12_ETM30",
0126 "L1_Jet70_ETM40",
0127 "L1_TauJet20_ETM20",
0128 "L1_TauJet30_ETM30",
0129 "L1_TauJet30_ETM40",
0130 "L1_HTT100_ETM30",
0131 "L1_TripleMu3",
0132 "L1_TripleIsoEG5",
0133 "L1_TripleEG10",
0134 "L1_TripleJet50",
0135 "L1_TripleTauJet40",
0136 "L1_DoubleMu3_IsoEG5",
0137 "L1_DoubleMu3_EG10",
0138 "L1_DoubleIsoEG5_Mu3",
0139 "L1_DoubleEG10_Mu3",
0140 "L1_DoubleMu3_HTT200",
0141 "L1_DoubleIsoEG5_HTT200",
0142 "L1_DoubleEG10_HTT200",
0143 "L1_DoubleJet50_HTT200",
0144 "L1_DoubleTauJet40_HTT200",
0145 "L1_DoubleMu3_ETM20",
0146 "L1_DoubleIsoEG5_ETM20",
0147 "L1_DoubleEG10_ETM20",
0148 "L1_DoubleJet50_ETM20",
0149 "L1_DoubleTauJet40_ETM20",
0150 "L1_QuadJet30",
0151 "L1_ExclusiveDoubleIsoEG4",
0152 "L1_ExclusiveDoubleJet60",
0153 "L1_ExclusiveJet25_Gap_Jet25",
0154 "L1_IsoEG10_Jet20_ForJet10",
0155 "L1_MinBias_HTT10",
0156 "L1_ZeroBias"};
0157
0158 namespace {
0159 enum IndexComboStates { kUnset, kSetting, kSet };
0160 }
0161
0162
0163
0164
0165 L1ParticleMap::L1ParticleMap() {}
0166
0167 L1ParticleMap::L1ParticleMap(L1TriggerType triggerType,
0168 bool triggerDecision,
0169 const L1ObjectTypeVector& objectTypes,
0170 const L1EmParticleVectorRef& emParticles,
0171 const L1JetParticleVectorRef& jetParticles,
0172 const L1MuonParticleVectorRef& muonParticles,
0173 const L1EtMissParticleRefProd& etMissParticle,
0174 const L1IndexComboVector& indexCombos)
0175 : triggerType_(triggerType),
0176 triggerDecision_(triggerDecision),
0177 indexCombosState_{static_cast<char>(!indexCombos.empty() ? kSet : IndexComboStates::kUnset)},
0178 objectTypes_(objectTypes),
0179 emParticles_(emParticles),
0180 jetParticles_(jetParticles),
0181 muonParticles_(muonParticles),
0182 etMissParticle_(etMissParticle),
0183 indexCombos_(indexCombos) {}
0184
0185 L1ParticleMap::L1ParticleMap(const L1ParticleMap& rhs)
0186 : triggerType_(rhs.triggerType_),
0187 triggerDecision_(rhs.triggerDecision_),
0188 indexCombosState_(IndexComboStates::kUnset),
0189 objectTypes_(rhs.objectTypes_),
0190 emParticles_(rhs.emParticles_),
0191 jetParticles_(rhs.jetParticles_),
0192 muonParticles_(rhs.muonParticles_),
0193 etMissParticle_(rhs.etMissParticle_),
0194 indexCombos_() {
0195
0196 if (rhs.indexCombosState_.load(std::memory_order_acquire) == kSet) {
0197 indexCombos_ = rhs.indexCombos_;
0198 indexCombosState_.store(kSet, std::memory_order_release);
0199 }
0200 }
0201
0202 L1ParticleMap::~L1ParticleMap() {}
0203
0204
0205
0206
0207 L1ParticleMap& L1ParticleMap::operator=(const L1ParticleMap& rhs) {
0208
0209 L1ParticleMap temp(rhs);
0210 swap(temp);
0211
0212 return *this;
0213 }
0214
0215
0216
0217
0218 void L1ParticleMap::swap(L1ParticleMap& rhs) {
0219 std::swap(triggerType_, rhs.triggerType_);
0220 std::swap(triggerDecision_, rhs.triggerDecision_);
0221 indexCombosState_.store(
0222 rhs.indexCombosState_.exchange(indexCombosState_.load(std::memory_order_acquire), std::memory_order_acq_rel),
0223 std::memory_order_release);
0224 std::swap(objectTypes_, rhs.objectTypes_);
0225 std::swap(emParticles_, rhs.emParticles_);
0226 std::swap(jetParticles_, rhs.jetParticles_);
0227 std::swap(muonParticles_, rhs.muonParticles_);
0228 std::swap(etMissParticle_, rhs.etMissParticle_);
0229 std::swap(indexCombos_, rhs.indexCombos_);
0230 }
0231
0232
0233
0234
0235
0236 const L1ParticleMap::L1IndexComboVector& L1ParticleMap::indexCombos() const {
0237 if (kSet != indexCombosState_.load(std::memory_order_acquire)) {
0238 setIndexCombos();
0239 }
0240 return indexCombos_;
0241 }
0242
0243 void L1ParticleMap::setIndexCombos() const {
0244
0245 int numNonGlobal = 0;
0246 L1ObjectType nonGlobalType = kNumOfL1ObjectTypes;
0247 int nonGlobalIndex = -1;
0248
0249 L1IndexComboVector tempIndexCombos;
0250 for (int i = 0; i < numOfObjects(); ++i) {
0251 if (!objectTypeIsGlobal(objectTypes_[i])) {
0252 ++numNonGlobal;
0253 nonGlobalType = objectTypes_[i];
0254 nonGlobalIndex = i;
0255 }
0256 }
0257
0258 if (numNonGlobal == 0) {
0259
0260 L1IndexCombo tmpCombo;
0261 tmpCombo.reserve(numOfObjects());
0262 for (int i = 0; i < numOfObjects(); ++i) {
0263 tmpCombo.push_back(0);
0264 }
0265
0266 tempIndexCombos.push_back(tmpCombo);
0267 } else if (numNonGlobal == 1) {
0268 int nParticles = 0;
0269
0270 if (nonGlobalType == kEM) {
0271 nParticles = emParticles_.size();
0272 } else if (nonGlobalType == kJet) {
0273 nParticles = jetParticles_.size();
0274 } else if (nonGlobalType == kMuon) {
0275 nParticles = muonParticles_.size();
0276 }
0277
0278 tempIndexCombos.reserve(nParticles);
0279 for (int i = 0; i < nParticles; ++i) {
0280 L1IndexCombo tmpCombo;
0281 tmpCombo.reserve(numOfObjects());
0282 for (int j = 0; j < numOfObjects(); ++j) {
0283 if (j == nonGlobalIndex) {
0284 tmpCombo.push_back(i);
0285 } else {
0286 tmpCombo.push_back(0);
0287 }
0288 }
0289
0290 tempIndexCombos.push_back(tmpCombo);
0291 }
0292 }
0293 char expected = IndexComboStates::kUnset;
0294 if (indexCombosState_.compare_exchange_strong(expected, kSetting, std::memory_order_acq_rel)) {
0295
0296
0297
0298 if (indexCombos_.empty()) {
0299 indexCombos_.swap(tempIndexCombos);
0300 }
0301 indexCombosState_.store(kSet, std::memory_order_release);
0302 } else {
0303
0304 while (kSet != indexCombosState_.load(std::memory_order_acquire)) {
0305 hardware_pause();
0306 }
0307 }
0308 }
0309
0310 const reco::LeafCandidate* L1ParticleMap::candidateInCombo(int aIndexInCombo, const L1IndexCombo& aCombo) const {
0311 L1ObjectType type = objectTypes_[aIndexInCombo];
0312 int particleInList = aCombo[aIndexInCombo];
0313
0314 if (type == kEM) {
0315 return dynamic_cast<const reco::LeafCandidate*>(emParticles_[particleInList].get());
0316 } else if (type == kJet) {
0317 return dynamic_cast<const reco::LeafCandidate*>(jetParticles_[particleInList].get());
0318 } else if (type == kMuon) {
0319 return dynamic_cast<const reco::LeafCandidate*>(muonParticles_[particleInList].get());
0320 } else if (type == kEtMiss || type == kEtTotal || type == kEtHad) {
0321 return dynamic_cast<const reco::LeafCandidate*>(etMissParticle_.get());
0322 } else {
0323 return nullptr;
0324 }
0325 }
0326
0327 const L1EmParticle* L1ParticleMap::emParticleInCombo(int aIndexInCombo, const L1IndexCombo& aCombo) const {
0328 L1ObjectType type = objectTypes_[aIndexInCombo];
0329 int particleInList = aCombo[aIndexInCombo];
0330
0331 if (type == kEM) {
0332 return emParticles_[particleInList].get();
0333 } else {
0334 return nullptr;
0335 }
0336 }
0337
0338 const L1JetParticle* L1ParticleMap::jetParticleInCombo(int aIndexInCombo, const L1IndexCombo& aCombo) const {
0339 L1ObjectType type = objectTypes_[aIndexInCombo];
0340 int particleInList = aCombo[aIndexInCombo];
0341
0342 if (type == kJet) {
0343 return jetParticles_[particleInList].get();
0344 } else {
0345 return nullptr;
0346 }
0347 }
0348
0349 const L1MuonParticle* L1ParticleMap::muonParticleInCombo(int aIndexInCombo, const L1IndexCombo& aCombo) const {
0350 L1ObjectType type = objectTypes_[aIndexInCombo];
0351 int particleInList = aCombo[aIndexInCombo];
0352
0353 if (type == kMuon) {
0354 return muonParticles_[particleInList].get();
0355 } else {
0356 return nullptr;
0357 }
0358 }
0359
0360 const L1EtMissParticle* L1ParticleMap::etMissParticleInCombo(int aIndexInCombo, const L1IndexCombo& aCombo) const {
0361 L1ObjectType type = objectTypes_[aIndexInCombo];
0362
0363 if (type == kEtMiss || type == kEtTotal || type == kEtHad) {
0364 return etMissParticle_.get();
0365 } else {
0366 return nullptr;
0367 }
0368 }
0369
0370 std::vector<const reco::LeafCandidate*> L1ParticleMap::candidateCombo(const L1IndexCombo& aCombo) const {
0371 std::vector<const reco::LeafCandidate*> tmp;
0372
0373 tmp.reserve(numOfObjects());
0374 for (int i = 0; i < numOfObjects(); ++i) {
0375 tmp.push_back(candidateInCombo(i, aCombo));
0376 }
0377
0378 return tmp;
0379 }
0380
0381
0382
0383
0384 const std::string& L1ParticleMap::triggerName(L1TriggerType type) { return triggerNames_[type]; }
0385
0386 L1ParticleMap::L1TriggerType L1ParticleMap::triggerType(const std::string& name) {
0387 for (int i = 0; i < kNumOfL1TriggerTypes; ++i) {
0388 if (triggerNames_[i] == name) {
0389 return (L1TriggerType)i;
0390 }
0391 }
0392
0393 return kNumOfL1TriggerTypes;
0394 }
0395
0396 bool L1ParticleMap::objectTypeIsGlobal(L1ObjectType type) {
0397 return type == kEtMiss || type == kEtTotal || type == kEtHad;
0398 }