File indexing completed on 2024-09-07 04:36:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <memory>
0021 #include <array>
0022 #include <iostream>
0023 #include <cmath>
0024
0025
0026 #include "FWCore/Framework/interface/stream/EDProducer.h"
0027 #include "FWCore/Framework/interface/Event.h"
0028 #include "FWCore/Framework/interface/EventSetup.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0030
0031 #include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h"
0032 #include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h"
0033 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
0034 #include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h"
0035 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
0036 #include "FWCore/Framework/interface/MakerMacros.h"
0037 #include "DataFormats/HcalDetId/interface/HcalSubdetector.h"
0038 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
0039
0040
0041 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
0042
0043
0044 #include "DataFormats/HcalDigi/interface/HcalTriggerPrimitiveDigi.h"
0045
0046
0047 #include "DataFormats/L1TCalorimeterPhase2/interface/CaloCrystalCluster.h"
0048 #include "DataFormats/L1TCalorimeterPhase2/interface/CaloTower.h"
0049 #include "DataFormats/L1Trigger/interface/EGamma.h"
0050
0051 #include "L1Trigger/L1CaloTrigger/interface/ParametricCalibration.h"
0052 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0053 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0054
0055 static constexpr bool do_brem = true;
0056
0057 static constexpr int n_eta_bins = 2;
0058 static constexpr int n_borders_phi = 18;
0059 static constexpr int n_borders_eta = 18;
0060 static constexpr int n_clusters_max = 5;
0061 static constexpr int n_clusters_link = 3;
0062 static constexpr int n_clusters_4link = 4 * 3;
0063 static constexpr int n_crystals_towerEta = 5;
0064 static constexpr int n_crystals_towerPhi = 5;
0065 static constexpr int n_crystals_3towers = 3 * 5;
0066 static constexpr int n_crystals_2towers = 2 * 5;
0067 static constexpr int n_towers_per_link = 17;
0068 static constexpr int n_clusters_per_link = 2;
0069 static constexpr int n_clusters_per_L1card = 8;
0070 static constexpr int n_towers_Eta = 34;
0071 static constexpr int n_towers_Phi = 72;
0072 static constexpr int n_towers_halfPhi = 36;
0073 static constexpr int n_links_card = 4;
0074 static constexpr int n_links_GCTcard = 48;
0075 static constexpr int n_GCTcards = 3;
0076 static constexpr float ECAL_eta_range = 1.4841;
0077 static constexpr float half_crystal_size = 0.00873;
0078 static constexpr float slideIsoPtThreshold = 80;
0079 static constexpr float plateau_ss = 130.0;
0080 static constexpr float a0_80 = 0.85, a1_80 = 0.0080, a0 = 0.21;
0081 static constexpr float b0 = 0.38, b1 = 1.9, b2 = 0.05;
0082 static constexpr float c0_ss = 0.94, c1_ss = 0.052, c2_ss = 0.044;
0083 static constexpr float d0 = 0.96, d1 = 0.0003;
0084 static constexpr float e0_looseTkss = 0.944, e1_looseTkss = 0.65, e2_looseTkss = 0.4;
0085 static constexpr float cut_500_MeV = 0.5;
0086
0087
0088
0089
0090 static constexpr int toweriEta_fromAbsoluteID_shift = 16;
0091
0092
0093
0094
0095 static constexpr int toweriPhi_fromAbsoluteID_shift_lowerHalf = 37;
0096 static constexpr int toweriPhi_fromAbsoluteID_shift_upperHalf = 35;
0097
0098 float getEta_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) {
0099 int etaID = n_crystals_towerEta * (n_towers_per_link * ((link / n_links_card) % 2) + (tower % n_towers_per_link)) +
0100 crystal % n_crystals_towerEta;
0101 float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta);
0102 return etaID * size_cell - ECAL_eta_range + half_crystal_size;
0103 }
0104
0105 float getPhi_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) {
0106 int phiID = n_crystals_towerPhi * ((card * 24) + (n_links_card * (link / 8)) + (tower / n_towers_per_link)) +
0107 crystal / n_crystals_towerPhi;
0108 float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi);
0109 return phiID * size_cell - M_PI + half_crystal_size;
0110 }
0111
0112 int getCrystal_etaID(float eta) {
0113 float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta);
0114 int etaID = int((eta + ECAL_eta_range) / size_cell);
0115 return etaID;
0116 }
0117
0118 int convert_L2toL1_link(int link) { return link % n_links_card; }
0119
0120 int convert_L2toL1_tower(int tower) { return tower; }
0121
0122 int convert_L2toL1_card(int card, int link) { return card * n_clusters_4link + link / n_links_card; }
0123
0124 int getCrystal_phiID(float phi) {
0125 float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi);
0126 int phiID = int((phi + M_PI) / size_cell);
0127 return phiID;
0128 }
0129
0130 int getTower_absoluteEtaID(float eta) {
0131 float size_cell = 2 * ECAL_eta_range / n_towers_Eta;
0132 int etaID = int((eta + ECAL_eta_range) / size_cell);
0133 return etaID;
0134 }
0135
0136 int getTower_absolutePhiID(float phi) {
0137 float size_cell = 2 * M_PI / n_towers_Phi;
0138 int phiID = int((phi + M_PI) / size_cell);
0139 return phiID;
0140 }
0141
0142 int getToweriEta_fromAbsoluteID(int id) {
0143 if (id < n_towers_per_link)
0144 return id - n_towers_per_link;
0145 else
0146 return id - toweriEta_fromAbsoluteID_shift;
0147 }
0148
0149 int getToweriPhi_fromAbsoluteID(int id) {
0150 if (id < n_towers_Phi / 2)
0151 return id + toweriPhi_fromAbsoluteID_shift_lowerHalf;
0152 else
0153 return id - toweriPhi_fromAbsoluteID_shift_upperHalf;
0154 }
0155
0156 float getTowerEta_fromAbsoluteID(int id) {
0157 float size_cell = 2 * ECAL_eta_range / n_towers_Eta;
0158 float eta = (id * size_cell) - ECAL_eta_range + 0.5 * size_cell;
0159 return eta;
0160 }
0161
0162 float getTowerPhi_fromAbsoluteID(int id) {
0163 float size_cell = 2 * M_PI / n_towers_Phi;
0164 float phi = (id * size_cell) - M_PI + 0.5 * size_cell;
0165 return phi;
0166 }
0167
0168 int getCrystalIDInTower(int etaID, int phiID) {
0169 return int(n_crystals_towerPhi * (phiID % n_crystals_towerPhi) + (etaID % n_crystals_towerEta));
0170 }
0171
0172 int get_towerEta_fromCardTowerInCard(int card, int towerincard) {
0173 return n_towers_per_link * (card % 2) + towerincard % n_towers_per_link;
0174 }
0175
0176 int get_towerPhi_fromCardTowerInCard(int card, int towerincard) {
0177 return 4 * (card / 2) + towerincard / n_towers_per_link;
0178 }
0179
0180 int get_towerEta_fromCardLinkTower(int card, int link, int tower) { return n_towers_per_link * (card % 2) + tower; }
0181
0182 int get_towerPhi_fromCardLinkTower(int card, int link, int tower) { return 4 * (card / 2) + link; }
0183
0184 int getTowerID(int etaID, int phiID) {
0185 return int(n_towers_per_link * ((phiID / n_crystals_towerPhi) % 4) +
0186 (etaID / n_crystals_towerEta) % n_towers_per_link);
0187 }
0188
0189 int getTower_phiID(int cluster_phiID) {
0190 return int((cluster_phiID / n_crystals_towerPhi) % 4);
0191 }
0192
0193 int getTower_etaID(int cluster_etaID) {
0194 return int((cluster_etaID / n_crystals_towerEta) % n_towers_per_link);
0195 }
0196
0197 int getEtaMax_card(int card) {
0198 int etamax = 0;
0199 if (card % 2 == 0)
0200 etamax = n_towers_per_link * n_crystals_towerEta - 1;
0201 else
0202 etamax = n_towers_Eta * n_crystals_towerEta - 1;
0203 return etamax;
0204 }
0205
0206 int getEtaMin_card(int card) {
0207 int etamin = 0;
0208 if (card % 2 == 0)
0209 etamin = 0 * n_crystals_towerEta;
0210 else
0211 etamin = n_towers_per_link * n_crystals_towerEta;
0212 return etamin;
0213 }
0214
0215 int getPhiMax_card(int card) {
0216 int phimax = ((card / 2) + 1) * 4 * n_crystals_towerPhi - 1;
0217 return phimax;
0218 }
0219
0220 int getPhiMin_card(int card) {
0221 int phimin = (card / 2) * 4 * n_crystals_towerPhi;
0222 return phimin;
0223 }
0224
0225
0226
0227
0228
0229
0230 int getEtaMin_region(int card, int nregion) {
0231
0232 if (card % 2 == 0) {
0233 if (nregion == 0) {
0234 return getEtaMin_card(card);
0235 } else {
0236 return getEtaMin_card(card) + n_crystals_2towers + n_crystals_3towers * (nregion - 1);
0237 }
0238 }
0239
0240 else {
0241 return getEtaMin_card(card) + n_crystals_3towers * nregion;
0242 }
0243 }
0244
0245
0246
0247
0248
0249 int getEtaMax_region(int card, int nregion) {
0250
0251 if (card % 2 == 0) {
0252 if (nregion == 0) {
0253 return getEtaMin_card(card) + n_crystals_2towers;
0254 } else {
0255 return getEtaMin_card(card) + n_crystals_2towers + (n_crystals_3towers * nregion);
0256 }
0257 }
0258
0259 else {
0260 return getEtaMin_card(card) + n_crystals_3towers * (nregion + 1);
0261 }
0262 }
0263
0264 class L1EGCrystalClusterEmulatorProducer : public edm::stream::EDProducer<> {
0265 public:
0266 explicit L1EGCrystalClusterEmulatorProducer(const edm::ParameterSet&);
0267 ~L1EGCrystalClusterEmulatorProducer() override;
0268
0269 private:
0270 void produce(edm::Event&, const edm::EventSetup&) override;
0271 bool passes_ss(float pt, float ss);
0272 bool passes_photon(float pt, float pss);
0273 bool passes_iso(float pt, float iso);
0274 bool passes_looseTkss(float pt, float ss);
0275 bool passes_looseTkiso(float pt, float iso);
0276 float get_calibrate(float uncorr);
0277
0278 edm::EDGetTokenT<EcalEBTrigPrimDigiCollection> ecalTPEBToken_;
0279 edm::EDGetTokenT<edm::SortedCollection<HcalTriggerPrimitiveDigi> > hcalTPToken_;
0280 edm::ESGetToken<CaloTPGTranscoder, CaloTPGRecord> decoderTag_;
0281
0282 l1tp2::ParametricCalibration calib_;
0283
0284 edm::ESGetToken<CaloGeometry, CaloGeometryRecord> caloGeometryTag_;
0285 const CaloSubdetectorGeometry* ebGeometry;
0286 const CaloSubdetectorGeometry* hbGeometry;
0287 edm::ESGetToken<HcalTopology, HcalRecNumberingRecord> hbTopologyTag_;
0288 const HcalTopology* hcTopology_;
0289
0290 struct mycluster {
0291 float c2x2_;
0292 float c2x5_;
0293 float c5x5_;
0294 int cshowershape_;
0295 int cshowershapeloosetk_;
0296 float cvalueshowershape_;
0297 int cphotonshowershape_;
0298 float cpt;
0299 int cbrem_;
0300 float cWeightedEta_;
0301 float cWeightedPhi_;
0302 float ciso_;
0303 float crawIso_;
0304 float chovere_;
0305 float craweta_;
0306 float crawphi_;
0307 float chcal_;
0308 float ceta_;
0309 float cphi_;
0310 int ccrystalid_;
0311 int cinsidecrystalid_;
0312 int ctowerid_;
0313 };
0314
0315 class SimpleCaloHit {
0316 private:
0317 float pt_ = 0;
0318 float energy_ = 0.;
0319 bool isEndcapHit_ = false;
0320 bool stale_ = false;
0321 bool used_ = false;
0322 GlobalVector position_;
0323 HcalDetId id_hcal_;
0324 EBDetId id_;
0325
0326 public:
0327
0328 inline void setPt() { pt_ = (position_.mag2() > 0) ? energy_ * sin(position_.theta()) : 0; };
0329 inline void setEnergy(float et) { energy_ = et / sin(position_.theta()); };
0330 inline void setIsEndcapHit(bool isEC) { isEndcapHit_ = isEC; };
0331 inline void setUsed(bool isUsed) { used_ = isUsed; };
0332 inline void setPosition(const GlobalVector& pos) { position_ = pos; };
0333 inline void setIdHcal(const HcalDetId& idhcal) { id_hcal_ = idhcal; };
0334 inline void setId(const EBDetId& id) { id_ = id; };
0335
0336 inline float pt() const { return pt_; };
0337 inline float energy() const { return energy_; };
0338 inline bool isEndcapHit() const { return isEndcapHit_; };
0339 inline bool used() const { return used_; };
0340 inline const GlobalVector& position() const { return position_; };
0341 inline const EBDetId& id() const { return id_; };
0342
0343
0344
0345
0346 bool isInCard(int cc) const {
0347 return (getCrystal_phiID(position().phi()) <= getPhiMax_card(cc) &&
0348 getCrystal_phiID(position().phi()) >= getPhiMin_card(cc) &&
0349 getCrystal_etaID(position().eta()) <= getEtaMax_card(cc) &&
0350 getCrystal_etaID(position().eta()) >= getEtaMin_card(cc));
0351 };
0352
0353
0354
0355
0356 bool isInCardAndRegion(int cc, int nregion) const {
0357 bool isInRegionEta = (getCrystal_etaID(position().eta()) < getEtaMax_region(cc, nregion) &&
0358 getCrystal_etaID(position().eta()) >= getEtaMin_region(cc, nregion));
0359 return (isInCard(cc) && isInRegionEta);
0360 }
0361
0362
0363 inline float deta(SimpleCaloHit& other) const { return position_.eta() - other.position().eta(); };
0364 int dieta(SimpleCaloHit& other) const {
0365 if (isEndcapHit_ || other.isEndcapHit())
0366 return 9999;
0367 if (id_.ieta() * other.id().ieta() > 0)
0368 return id_.ieta() - other.id().ieta();
0369 return id_.ieta() - other.id().ieta() - 1;
0370 };
0371 inline float dphi(SimpleCaloHit& other) const {
0372 return reco::deltaPhi(static_cast<float>(position_.phi()), static_cast<float>(other.position().phi()));
0373 };
0374 int diphi(SimpleCaloHit& other) const {
0375 if (isEndcapHit_ || other.isEndcapHit())
0376 return 9999;
0377
0378 static constexpr int PI = 180;
0379 int result = id().iphi() - other.id().iphi();
0380 while (result > PI)
0381 result -= 2 * PI;
0382 while (result <= -PI)
0383 result += 2 * PI;
0384 return result;
0385 };
0386 int dieta_byCrystalID(SimpleCaloHit& other) const {
0387 return (getCrystal_etaID(position_.eta()) - getCrystal_etaID(other.position().eta()));
0388 };
0389 int diphi_byCrystalID(SimpleCaloHit& other) const {
0390 return (getCrystal_phiID(position_.phi()) - getCrystal_phiID(other.position().phi()));
0391 };
0392 int id_iEta() { return id_.ieta(); }
0393 int id_iPhi() { return id_.iphi(); }
0394 float distanceTo(SimpleCaloHit& other) const {
0395
0396
0397 return (position() - other.position()).mag();
0398 };
0399 bool operator==(SimpleCaloHit& other) const {
0400 return (id_ == other.id() && position() == other.position() && energy_ == other.energy() &&
0401 isEndcapHit_ == other.isEndcapHit());
0402 };
0403 };
0404 };
0405
0406 L1EGCrystalClusterEmulatorProducer::L1EGCrystalClusterEmulatorProducer(const edm::ParameterSet& iConfig)
0407 : ecalTPEBToken_(consumes<EcalEBTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalTPEB"))),
0408 hcalTPToken_(
0409 consumes<edm::SortedCollection<HcalTriggerPrimitiveDigi> >(iConfig.getParameter<edm::InputTag>("hcalTP"))),
0410 decoderTag_(esConsumes<CaloTPGTranscoder, CaloTPGRecord>(edm::ESInputTag("", ""))),
0411 calib_(iConfig.getParameter<edm::ParameterSet>("calib")),
0412 caloGeometryTag_(esConsumes<CaloGeometry, CaloGeometryRecord>(edm::ESInputTag("", ""))),
0413 hbTopologyTag_(esConsumes<HcalTopology, HcalRecNumberingRecord>(edm::ESInputTag("", ""))) {
0414 produces<l1tp2::CaloCrystalClusterCollection>();
0415 produces<BXVector<l1t::EGamma> >();
0416 produces<l1tp2::CaloTowerCollection>("L1CaloTowerCollection");
0417 }
0418
0419 L1EGCrystalClusterEmulatorProducer::~L1EGCrystalClusterEmulatorProducer() {}
0420
0421 void L1EGCrystalClusterEmulatorProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0422 using namespace edm;
0423
0424 edm::Handle<EcalEBTrigPrimDigiCollection> pcalohits;
0425 iEvent.getByToken(ecalTPEBToken_, pcalohits);
0426
0427 const auto& caloGeometry = iSetup.getData(caloGeometryTag_);
0428 ebGeometry = caloGeometry.getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
0429 hbGeometry = caloGeometry.getSubdetectorGeometry(DetId::Hcal, HcalBarrel);
0430 const auto& hbTopology = iSetup.getData(hbTopologyTag_);
0431 hcTopology_ = &hbTopology;
0432 HcalTrigTowerGeometry theTrigTowerGeometry(hcTopology_);
0433
0434 const auto& decoder = iSetup.getData(decoderTag_);
0435
0436
0437
0438
0439
0440
0441 iEvent.getByToken(ecalTPEBToken_, pcalohits);
0442 std::vector<SimpleCaloHit> ecalhits;
0443
0444 for (const auto& hit : *pcalohits.product()) {
0445 if (hit.encodedEt() > 0)
0446 {
0447
0448 float et = hit.encodedEt() / 8.;
0449 if (et < cut_500_MeV)
0450 continue;
0451
0452 auto cell = ebGeometry->getGeometry(hit.id());
0453
0454 SimpleCaloHit ehit;
0455 ehit.setId(hit.id());
0456 ehit.setPosition(GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z()));
0457 ehit.setEnergy(et);
0458 ehit.setPt();
0459 ecalhits.push_back(ehit);
0460 }
0461 }
0462
0463
0464 std::vector<SimpleCaloHit> hcalhits;
0465 edm::Handle<edm::SortedCollection<HcalTriggerPrimitiveDigi> > hbhecoll;
0466 iEvent.getByToken(hcalTPToken_, hbhecoll);
0467 for (const auto& hit : *hbhecoll.product()) {
0468 float et = decoder.hcaletValue(hit.id(), hit.t0());
0469 if (et <= 0)
0470 continue;
0471 if (!(hcTopology_->validHT(hit.id()))) {
0472 LogError("L1EGCrystalClusterEmulatorProducer")
0473 << " -- Hcal hit DetID not present in HCAL Geom: " << hit.id() << std::endl;
0474 throw cms::Exception("L1EGCrystalClusterEmulatorProducer");
0475 continue;
0476 }
0477 const std::vector<HcalDetId>& hcId = theTrigTowerGeometry.detIds(hit.id());
0478 if (hcId.empty()) {
0479 LogError("L1EGCrystalClusterEmulatorProducer")
0480 << "Cannot find any HCalDetId corresponding to " << hit.id() << std::endl;
0481 throw cms::Exception("L1EGCrystalClusterEmulatorProducer");
0482 continue;
0483 }
0484 if (hcId[0].subdetId() > 1)
0485 continue;
0486 GlobalVector hcal_tp_position = GlobalVector(0., 0., 0.);
0487 for (const auto& hcId_i : hcId) {
0488 if (hcId_i.subdetId() > 1)
0489 continue;
0490 auto cell = hbGeometry->getGeometry(hcId_i);
0491 if (cell == nullptr)
0492 continue;
0493 GlobalVector tmpVector = GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z());
0494 hcal_tp_position = tmpVector;
0495 break;
0496 }
0497 SimpleCaloHit hhit;
0498 hhit.setId(hit.id());
0499 hhit.setIdHcal(hit.id());
0500 hhit.setPosition(hcal_tp_position);
0501 hhit.setEnergy(et);
0502 hhit.setPt();
0503 hcalhits.push_back(hhit);
0504 }
0505
0506
0507
0508
0509
0510
0511
0512 float ECAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
0513 float HCAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
0514 int iEta_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
0515 int iPhi_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
0516
0517 float energy_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
0518
0519 int brem_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
0520 int towerID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
0521 int crystalID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
0522 int showerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
0523 int showerShapeLooseTk_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
0524 int photonShowerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
0525
0526 for (int ii = 0; ii < n_links_card; ++ii) {
0527 for (int jj = 0; jj < n_towers_per_link; ++jj) {
0528 for (int ll = 0; ll < n_towers_halfPhi; ++ll) {
0529 ECAL_tower_L1Card[ii][jj][ll] = 0;
0530 HCAL_tower_L1Card[ii][jj][ll] = 0;
0531 iPhi_tower_L1Card[ii][jj][ll] = -999;
0532 iEta_tower_L1Card[ii][jj][ll] = -999;
0533 }
0534 }
0535 }
0536 for (int ii = 0; ii < n_links_card; ++ii) {
0537 for (int jj = 0; jj < n_clusters_link; ++jj) {
0538 for (int ll = 0; ll < n_towers_halfPhi; ++ll) {
0539 energy_cluster_L1Card[ii][jj][ll] = 0;
0540 brem_cluster_L1Card[ii][jj][ll] = 0;
0541 towerID_cluster_L1Card[ii][jj][ll] = 0;
0542 crystalID_cluster_L1Card[ii][jj][ll] = 0;
0543 }
0544 }
0545 }
0546
0547
0548 vector<mycluster> cluster_list[n_towers_halfPhi];
0549
0550 vector<mycluster> cluster_list_merged[n_towers_halfPhi];
0551
0552 for (int cc = 0; cc < n_towers_halfPhi; ++cc) {
0553
0554 for (int nregion = 0; nregion <= n_clusters_max; ++nregion) {
0555 int nclusters = 0;
0556 bool build_cluster = true;
0557
0558
0559 while (nclusters < n_clusters_max && build_cluster) {
0560 build_cluster = false;
0561 SimpleCaloHit centerhit;
0562
0563 for (const auto& hit : ecalhits) {
0564
0565 if (hit.isInCardAndRegion(cc, nregion) && !hit.used() && hit.pt() >= 1.0 && hit.pt() > centerhit.pt()) {
0566 centerhit = hit;
0567 build_cluster = true;
0568 }
0569 }
0570 if (build_cluster)
0571 nclusters++;
0572
0573
0574 if (build_cluster && nclusters > 0 && nclusters <= n_clusters_max) {
0575 mycluster mc1;
0576 mc1.cpt = 0.0;
0577 mc1.cWeightedEta_ = 0.0;
0578 mc1.cWeightedPhi_ = 0.0;
0579 float leftlobe = 0;
0580 float rightlobe = 0;
0581 float e5x5 = 0;
0582 float e2x5_1 = 0;
0583 float e2x5_2 = 0;
0584 float e2x2_1 = 0;
0585 float e2x2_2 = 0;
0586 float e2x2_3 = 0;
0587 float e2x2_4 = 0;
0588 for (auto& hit : ecalhits) {
0589 if (hit.isInCardAndRegion(cc, nregion) && (hit.pt() > 0)) {
0590 if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) {
0591 rightlobe += hit.pt();
0592 }
0593 if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) {
0594 leftlobe += hit.pt();
0595 }
0596 if (abs(hit.dieta(centerhit)) <= 2 && abs(hit.diphi(centerhit)) <= 2) {
0597 e5x5 += hit.energy();
0598 }
0599 if ((hit.dieta(centerhit) == 1 or hit.dieta(centerhit) == 0) &&
0600 (hit.diphi(centerhit) == 1 or hit.diphi(centerhit) == 0)) {
0601 e2x2_1 += hit.energy();
0602 }
0603 if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) &&
0604 (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == 1)) {
0605 e2x2_2 += hit.energy();
0606 }
0607 if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) &&
0608 (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) {
0609 e2x2_3 += hit.energy();
0610 }
0611 if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) &&
0612 (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) {
0613 e2x2_4 += hit.energy();
0614 }
0615 if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) && abs(hit.diphi(centerhit)) <= 2) {
0616 e2x5_1 += hit.energy();
0617 }
0618 if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) && abs(hit.diphi(centerhit)) <= 2) {
0619 e2x5_2 += hit.energy();
0620 }
0621 }
0622 if (hit.isInCardAndRegion(cc, nregion) && !hit.used() && hit.pt() > 0 && abs(hit.dieta(centerhit)) <= 1 &&
0623 abs(hit.diphi(centerhit)) <= 2) {
0624
0625 hit.setUsed(true);
0626 mc1.cpt += hit.pt();
0627 mc1.cWeightedEta_ += float(hit.pt()) * float(hit.position().eta());
0628 mc1.cWeightedPhi_ = mc1.cWeightedPhi_ + (float(hit.pt()) * float(hit.position().phi()));
0629 }
0630 }
0631 if (do_brem && (rightlobe > 0.10 * mc1.cpt or leftlobe > 0.10 * mc1.cpt)) {
0632 for (auto& hit : ecalhits) {
0633 if (hit.isInCardAndRegion(cc, nregion) && hit.pt() > 0 && !hit.used()) {
0634 if (rightlobe > 0.10 * mc1.cpt && (leftlobe < 0.10 * mc1.cpt or rightlobe > leftlobe) &&
0635 abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) {
0636 mc1.cpt += hit.pt();
0637 hit.setUsed(true);
0638 mc1.cbrem_ = 1;
0639 }
0640 if (leftlobe > 0.10 * mc1.cpt && (rightlobe < 0.10 * mc1.cpt or leftlobe >= rightlobe) &&
0641 abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) {
0642 mc1.cpt += hit.pt();
0643 hit.setUsed(true);
0644 mc1.cbrem_ = 1;
0645 }
0646 }
0647 }
0648 }
0649 mc1.c5x5_ = e5x5;
0650 mc1.c2x5_ = max(e2x5_1, e2x5_2);
0651 mc1.c2x2_ = e2x2_1;
0652 if (e2x2_2 > mc1.c2x2_)
0653 mc1.c2x2_ = e2x2_2;
0654 if (e2x2_3 > mc1.c2x2_)
0655 mc1.c2x2_ = e2x2_3;
0656 if (e2x2_4 > mc1.c2x2_)
0657 mc1.c2x2_ = e2x2_4;
0658 mc1.cWeightedEta_ = mc1.cWeightedEta_ / mc1.cpt;
0659 mc1.cWeightedPhi_ = mc1.cWeightedPhi_ / mc1.cpt;
0660 mc1.ceta_ = getCrystal_etaID(centerhit.position().eta());
0661 mc1.cphi_ = getCrystal_phiID(centerhit.position().phi());
0662 mc1.crawphi_ = centerhit.position().phi();
0663 mc1.craweta_ = centerhit.position().eta();
0664 cluster_list[cc].push_back(mc1);
0665 }
0666 }
0667 }
0668 std::sort(begin(cluster_list[cc]), end(cluster_list[cc]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; });
0669
0670
0671 for (unsigned int jj = 0; jj < unsigned(cluster_list[cc].size()); ++jj) {
0672 for (unsigned int kk = jj + 1; kk < unsigned(cluster_list[cc].size()); ++kk) {
0673 if (std::abs(cluster_list[cc][jj].ceta_ - cluster_list[cc][kk].ceta_) < 2 &&
0674 std::abs(cluster_list[cc][jj].cphi_ - cluster_list[cc][kk].cphi_) < 2) {
0675 if (cluster_list[cc][kk].cpt > cluster_list[cc][jj].cpt) {
0676 cluster_list[cc][kk].cpt += cluster_list[cc][jj].cpt;
0677 cluster_list[cc][kk].c5x5_ += cluster_list[cc][jj].c5x5_;
0678 cluster_list[cc][kk].c2x5_ += cluster_list[cc][jj].c2x5_;
0679 cluster_list[cc][jj].cpt = 0;
0680 cluster_list[cc][jj].c5x5_ = 0;
0681 cluster_list[cc][jj].c2x5_ = 0;
0682 cluster_list[cc][jj].c2x2_ = 0;
0683 } else {
0684 cluster_list[cc][jj].cpt += cluster_list[cc][kk].cpt;
0685 cluster_list[cc][jj].c5x5_ += cluster_list[cc][kk].c5x5_;
0686 cluster_list[cc][jj].c2x5_ += cluster_list[cc][kk].c2x5_;
0687 cluster_list[cc][kk].cpt = 0;
0688 cluster_list[cc][kk].c2x2_ = 0;
0689 cluster_list[cc][kk].c2x5_ = 0;
0690 cluster_list[cc][kk].c5x5_ = 0;
0691 }
0692 }
0693 }
0694 if (cluster_list[cc][jj].cpt > 0) {
0695 cluster_list[cc][jj].cpt =
0696 cluster_list[cc][jj].cpt *
0697 calib_(cluster_list[cc][jj].cpt,
0698 std::abs(cluster_list[cc][jj].craweta_));
0699 cluster_list_merged[cc].push_back(cluster_list[cc][jj]);
0700 }
0701 }
0702 std::sort(begin(cluster_list_merged[cc]), end(cluster_list_merged[cc]), [](mycluster a, mycluster b) {
0703 return a.cpt > b.cpt;
0704 });
0705
0706
0707 for (unsigned int jj = 0; jj < unsigned(cluster_list_merged[cc].size()) && jj < n_clusters_4link; ++jj) {
0708 crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] =
0709 getCrystalIDInTower(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_);
0710 towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] =
0711 getTowerID(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_);
0712 energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cpt;
0713 brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cbrem_;
0714 if (passes_ss(cluster_list_merged[cc][jj].cpt,
0715 cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_))
0716 showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
0717 else
0718 showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
0719 if (passes_looseTkss(cluster_list_merged[cc][jj].cpt,
0720 cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_))
0721 showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
0722 else
0723 showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
0724 if (passes_photon(cluster_list_merged[cc][jj].cpt,
0725 cluster_list_merged[cc][jj].c2x2_ / cluster_list_merged[cc][jj].c2x5_))
0726 photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
0727 else
0728 photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
0729 }
0730
0731
0732 for (const auto& hit : ecalhits) {
0733 if (hit.isInCard(cc) && !hit.used()) {
0734 for (int jj = 0; jj < n_links_card; ++jj) {
0735 if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % 4 == jj) {
0736 for (int ii = 0; ii < n_towers_per_link; ++ii) {
0737
0738 if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) {
0739 ECAL_tower_L1Card[jj][ii][cc] += hit.pt() * calib_(0, std::abs(hit.position().eta()));
0740 iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta());
0741 iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi());
0742 }
0743 }
0744 }
0745 }
0746
0747 static constexpr float tower_width = 0.0873;
0748 for (int jj = 0; jj < n_links_card; ++jj) {
0749 for (int ii = 0; ii < n_towers_per_link; ++ii) {
0750 float phi = getPhiMin_card(cc) * tower_width / n_crystals_towerPhi - M_PI + (jj + 0.5) * tower_width;
0751 float eta = getEtaMin_card(cc) * tower_width / n_crystals_towerEta - n_towers_per_link * tower_width +
0752 (ii + 0.5) * tower_width;
0753 iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(eta);
0754 iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(phi);
0755 }
0756 }
0757 }
0758 }
0759
0760
0761 for (const auto& hit : hcalhits) {
0762 if (hit.isInCard(cc) && hit.pt() > 0) {
0763 for (int jj = 0; jj < n_links_card; ++jj) {
0764 if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % n_links_card == jj) {
0765 for (int ii = 0; ii < n_towers_per_link; ++ii) {
0766 if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) {
0767 HCAL_tower_L1Card[jj][ii][cc] += hit.pt();
0768 iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta());
0769 iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi());
0770 }
0771 }
0772 }
0773 }
0774 }
0775 }
0776
0777
0778 for (unsigned int kk = n_clusters_4link; kk < cluster_list_merged[cc].size(); ++kk) {
0779 if (cluster_list_merged[cc][kk].cpt > 0) {
0780 ECAL_tower_L1Card[getTower_phiID(cluster_list_merged[cc][kk].cphi_)]
0781 [getTower_etaID(cluster_list_merged[cc][kk].ceta_)][cc] += cluster_list_merged[cc][kk].cpt;
0782 }
0783 }
0784 }
0785
0786
0787
0788
0789
0790
0791 float HCAL_tower_L2Card[n_links_GCTcard][n_towers_per_link]
0792 [n_GCTcards];
0793 float ECAL_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
0794 int iEta_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
0795 int iPhi_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
0796 float energy_cluster_L2Card[n_links_GCTcard][n_clusters_per_link]
0797 [n_GCTcards];
0798 float brem_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0799 int towerID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0800 int crystalID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0801 float isolation_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0802 float HE_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0803 int showerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0804 int showerShapeLooseTk_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0805 int photonShowerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
0806
0807 for (int ii = 0; ii < n_links_GCTcard; ++ii) {
0808 for (int jj = 0; jj < n_towers_per_link; ++jj) {
0809 for (int ll = 0; ll < n_GCTcards; ++ll) {
0810 HCAL_tower_L2Card[ii][jj][ll] = 0;
0811 ECAL_tower_L2Card[ii][jj][ll] = 0;
0812 iEta_tower_L2Card[ii][jj][ll] = 0;
0813 iPhi_tower_L2Card[ii][jj][ll] = 0;
0814 }
0815 }
0816 }
0817 for (int ii = 0; ii < n_links_GCTcard; ++ii) {
0818 for (int jj = 0; jj < n_clusters_per_link; ++jj) {
0819 for (int ll = 0; ll < n_GCTcards; ++ll) {
0820 energy_cluster_L2Card[ii][jj][ll] = 0;
0821 brem_cluster_L2Card[ii][jj][ll] = 0;
0822 towerID_cluster_L2Card[ii][jj][ll] = 0;
0823 crystalID_cluster_L2Card[ii][jj][ll] = 0;
0824 isolation_cluster_L2Card[ii][jj][ll] = 0;
0825 HE_cluster_L2Card[ii][jj][ll] = 0;
0826 photonShowerShape_cluster_L2Card[ii][jj][ll] = 0;
0827 showerShape_cluster_L2Card[ii][jj][ll] = 0;
0828 showerShapeLooseTk_cluster_L2Card[ii][jj][ll] = 0;
0829 }
0830 }
0831 }
0832
0833
0834 vector<mycluster> cluster_list_L2[n_towers_halfPhi];
0835
0836
0837 for (int ii = 0; ii < n_borders_phi; ++ii) {
0838 for (int jj = 0; jj < n_eta_bins; ++jj) {
0839 int card_left = 2 * ii + jj;
0840 int card_right = 2 * ii + jj + 2;
0841 if (card_right > 35)
0842 card_right = card_right - n_towers_halfPhi;
0843 for (int kk = 0; kk < n_clusters_4link; ++kk) {
0844 if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 &&
0845 crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 19 &&
0846 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) {
0847 for (int ll = 0; ll < n_clusters_4link; ++ll) {
0848 if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
0849 crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < 5 &&
0850 std::abs(
0851 5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) % n_towers_per_link +
0852 crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 -
0853 5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) % n_towers_per_link -
0854 crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) < 2) {
0855 if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] >
0856 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) {
0857 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] +=
0858 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right];
0859 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0;
0860 }
0861 else {
0862 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] +=
0863 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left];
0864 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0;
0865 }
0866 }
0867 }
0868 }
0869 }
0870 }
0871 }
0872
0873
0874 if (do_brem) {
0875 for (int ii = 0; ii < n_borders_phi; ++ii) {
0876 for (int jj = 0; jj < n_eta_bins; ++jj) {
0877 int card_left = 2 * ii + jj;
0878 int card_right = 2 * ii + jj + 2;
0879 if (card_right > 35)
0880 card_right = card_right - n_towers_halfPhi;
0881
0882 for (int kk = 0; kk < n_clusters_4link; ++kk) {
0883
0884 if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 &&
0885 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) {
0886 for (int ll = 0; ll < n_clusters_4link; ++ll) {
0887
0888 if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
0889 std::abs(5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) %
0890 n_towers_per_link +
0891 crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 -
0892 5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) %
0893 n_towers_per_link -
0894 crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) <= 1) {
0895
0896 if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
0897 std::abs(5 + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] / 5 -
0898 (crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] / 5)) <= 5) {
0899 if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] >
0900 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] &&
0901 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] >
0902 0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) {
0903 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] +=
0904 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right];
0905 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0;
0906 brem_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 1;
0907 }
0908
0909 else if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right] >=
0910 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] &&
0911 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] >
0912 0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right]) {
0913 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] +=
0914 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left];
0915 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0;
0916 brem_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 1;
0917 }
0918 }
0919 }
0920 }
0921 }
0922 }
0923 }
0924 }
0925 }
0926
0927
0928 for (int ii = 0; ii < n_borders_eta; ++ii) {
0929 int card_bottom = 2 * ii;
0930 int card_top = 2 * ii + 1;
0931 for (int kk = 0; kk < n_clusters_4link; ++kk) {
0932 if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % n_towers_per_link == 16 &&
0933 crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % 5 == n_links_card &&
0934 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] >
0935 0) {
0936 for (int ll = 0; ll < n_clusters_4link; ++ll) {
0937 if (std::abs(
0938 5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / n_towers_per_link) +
0939 crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / 5 -
0940 5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / n_towers_per_link) -
0941 crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / 5) < 2) {
0942 if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] >
0943 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_bottom]) {
0944 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] +=
0945 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top];
0946 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] = 0;
0947 } else {
0948 energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] +=
0949 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom];
0950 energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] = 0;
0951 }
0952 }
0953 }
0954 }
0955 }
0956 }
0957
0958
0959 for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
0960 for (int jj = 0; jj < n_clusters_4link; ++jj) {
0961 if (energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii] > 0) {
0962 mycluster mc1;
0963 mc1.cpt = energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
0964 mc1.cbrem_ = brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
0965 mc1.ctowerid_ = towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
0966 mc1.ccrystalid_ = crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
0967 mc1.cshowershape_ = showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
0968 mc1.cshowershapeloosetk_ = showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
0969 mc1.cphotonshowershape_ = photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
0970 cluster_list_L2[ii].push_back(mc1);
0971 }
0972 }
0973 std::sort(
0974 begin(cluster_list_L2[ii]), end(cluster_list_L2[ii]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; });
0975 }
0976
0977
0978 for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
0979 for (unsigned int jj = n_clusters_per_L1card; jj < n_clusters_4link && jj < cluster_list_L2[ii].size(); ++jj) {
0980 if (cluster_list_L2[ii][jj].cpt > 0) {
0981 ECAL_tower_L1Card[cluster_list_L2[ii][jj].ctowerid_ / n_towers_per_link]
0982 [cluster_list_L2[ii][jj].ctowerid_ % n_towers_per_link][ii] += cluster_list_L2[ii][jj].cpt;
0983 cluster_list_L2[ii][jj].cpt = 0;
0984 cluster_list_L2[ii][jj].ctowerid_ = 0;
0985 cluster_list_L2[ii][jj].ccrystalid_ = 0;
0986 }
0987 }
0988 }
0989
0990
0991 for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
0992 for (unsigned int jj = 0; jj < n_clusters_per_L1card && jj < cluster_list_L2[ii].size(); ++jj) {
0993 int cluster_etaOfTower_fullDetector = get_towerEta_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_);
0994 int cluster_phiOfTower_fullDetector = get_towerPhi_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_);
0995 float hcal_nrj = 0.0;
0996 float isolation = 0.0;
0997 int ntowers = 0;
0998
0999 for (int iii = 0; iii < n_towers_halfPhi; ++iii) {
1000 for (unsigned int jjj = 0; jjj < n_clusters_per_L1card && jjj < cluster_list_L2[iii].size(); ++jjj) {
1001 if (!(iii == ii && jjj == jj)) {
1002 int cluster2_eta = get_towerEta_fromCardTowerInCard(iii, cluster_list_L2[iii][jjj].ctowerid_);
1003 int cluster2_phi = get_towerPhi_fromCardTowerInCard(iii, cluster_list_L2[iii][jjj].ctowerid_);
1004 if (abs(cluster2_eta - cluster_etaOfTower_fullDetector) <= 2 &&
1005 (abs(cluster2_phi - cluster_phiOfTower_fullDetector) <= 2 or
1006 abs(cluster2_phi - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) {
1007 isolation += cluster_list_L2[iii][jjj].cpt;
1008 }
1009 }
1010 }
1011 }
1012 for (int kk = 0; kk < n_towers_halfPhi; ++kk) {
1013 for (int ll = 0; ll < n_links_card; ++ll) {
1014 for (int mm = 0; mm < n_towers_per_link; ++mm) {
1015 int etaOftower_fullDetector = get_towerEta_fromCardLinkTower(kk, ll, mm);
1016 int phiOftower_fullDetector = get_towerPhi_fromCardLinkTower(kk, ll, mm);
1017
1018
1019 if (abs(etaOftower_fullDetector - cluster_etaOfTower_fullDetector) <= 2 &&
1020 (abs(phiOftower_fullDetector - cluster_phiOfTower_fullDetector) <= 2 or
1021 abs(phiOftower_fullDetector - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) {
1022
1023 if (!((cluster_phiOfTower_fullDetector == 0 && phiOftower_fullDetector == 71) or
1024 (cluster_phiOfTower_fullDetector == 23 && phiOftower_fullDetector == 26) or
1025 (cluster_phiOfTower_fullDetector == 24 && phiOftower_fullDetector == 21) or
1026 (cluster_phiOfTower_fullDetector == 47 && phiOftower_fullDetector == 50) or
1027 (cluster_phiOfTower_fullDetector == 48 && phiOftower_fullDetector == 45) or
1028 (cluster_phiOfTower_fullDetector == 71 && phiOftower_fullDetector == 2))) {
1029 isolation += ECAL_tower_L1Card[ll][mm][kk];
1030 ntowers++;
1031 }
1032 }
1033
1034
1035 if (abs(etaOftower_fullDetector - cluster_etaOfTower_fullDetector) <= 2 &&
1036 (abs(phiOftower_fullDetector - cluster_phiOfTower_fullDetector) <= 2 or
1037 abs(phiOftower_fullDetector - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) {
1038 hcal_nrj += HCAL_tower_L1Card[ll][mm][kk];
1039 }
1040 }
1041 }
1042 }
1043
1044 int nTowersIn5x5Window = 5 * 5;
1045 cluster_list_L2[ii][jj].ciso_ = ((isolation) * (nTowersIn5x5Window / ntowers)) / cluster_list_L2[ii][jj].cpt;
1046 cluster_list_L2[ii][jj].crawIso_ = ((isolation) * (nTowersIn5x5Window / ntowers));
1047 cluster_list_L2[ii][jj].chovere_ = hcal_nrj / cluster_list_L2[ii][jj].cpt;
1048 }
1049 }
1050
1051
1052
1053 for (int ii = 0; ii < n_links_GCTcard; ++ii) {
1054 for (int jj = 0; jj < n_towers_per_link; ++jj) {
1055 for (int ll = 0; ll < 3; ++ll) {
1056 ECAL_tower_L2Card[ii][jj][ll] =
1057 ECAL_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)];
1058 HCAL_tower_L2Card[ii][jj][ll] =
1059 HCAL_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)];
1060 iEta_tower_L2Card[ii][jj][ll] =
1061 iEta_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)];
1062 iPhi_tower_L2Card[ii][jj][ll] =
1063 iPhi_tower_L1Card[convert_L2toL1_link(ii)][convert_L2toL1_tower(jj)][convert_L2toL1_card(ll, ii)];
1064 }
1065 }
1066 }
1067
1068
1069 for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
1070 for (unsigned int jj = 0; jj < unsigned(cluster_list_L2[ii].size()) && jj < n_clusters_per_L1card; ++jj) {
1071 crystalID_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1072 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ccrystalid_;
1073 towerID_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1074 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ctowerid_;
1075 energy_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1076 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cpt;
1077 brem_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1078 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cbrem_;
1079 isolation_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1080 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ciso_;
1081 HE_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1082 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].chovere_;
1083 showerShape_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1084 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cshowershape_;
1085 showerShapeLooseTk_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1086 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cshowershapeloosetk_;
1087 photonShowerShape_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1088 [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cphotonshowershape_;
1089 }
1090 }
1091
1092 auto L1EGXtalClusters = std::make_unique<l1tp2::CaloCrystalClusterCollection>();
1093 auto L1EGammas = std::make_unique<l1t::EGammaBxCollection>();
1094 auto L1CaloTowers = std::make_unique<l1tp2::CaloTowerCollection>();
1095
1096
1097 for (int ii = 0; ii < n_links_GCTcard; ++ii) {
1098 for (int ll = 0; ll < n_GCTcards; ++ll) {
1099
1100 for (int jj = 0; jj < 2; ++jj) {
1101 if (energy_cluster_L2Card[ii][jj][ll] > 0.45) {
1102 reco::Candidate::PolarLorentzVector p4calibrated(
1103 energy_cluster_L2Card[ii][jj][ll],
1104 getEta_fromL2LinkCardTowerCrystal(
1105 ii, ll, towerID_cluster_L2Card[ii][jj][ll], crystalID_cluster_L2Card[ii][jj][ll]),
1106 getPhi_fromL2LinkCardTowerCrystal(
1107 ii, ll, towerID_cluster_L2Card[ii][jj][ll], crystalID_cluster_L2Card[ii][jj][ll]),
1108 0.);
1109 SimpleCaloHit centerhit;
1110 bool is_iso = passes_iso(energy_cluster_L2Card[ii][jj][ll], isolation_cluster_L2Card[ii][jj][ll]);
1111 bool is_looseTkiso =
1112 passes_looseTkiso(energy_cluster_L2Card[ii][jj][ll], isolation_cluster_L2Card[ii][jj][ll]);
1113 bool is_ss = (showerShape_cluster_L2Card[ii][jj][ll] == 1);
1114 bool is_photon = (photonShowerShape_cluster_L2Card[ii][jj][ll] == 1) && is_ss && is_iso;
1115 bool is_looseTkss = (showerShapeLooseTk_cluster_L2Card[ii][jj][ll] == 1);
1116
1117 l1tp2::CaloCrystalCluster cluster(p4calibrated,
1118 energy_cluster_L2Card[ii][jj][ll],
1119 HE_cluster_L2Card[ii][jj][ll],
1120 isolation_cluster_L2Card[ii][jj][ll],
1121 centerhit.id(),
1122 -1000,
1123 float(brem_cluster_L2Card[ii][jj][ll]),
1124 -1000,
1125 -1000,
1126 energy_cluster_L2Card[ii][jj][ll],
1127 -1,
1128 is_iso && is_ss,
1129 is_iso && is_ss,
1130 is_photon,
1131 is_iso && is_ss,
1132 is_looseTkiso && is_looseTkss,
1133 is_iso && is_ss);
1134
1135 std::map<std::string, float> params;
1136 params["standaloneWP_showerShape"] = is_ss;
1137 params["standaloneWP_isolation"] = is_iso;
1138 params["trkMatchWP_showerShape"] = is_looseTkss;
1139 params["trkMatchWP_isolation"] = is_looseTkiso;
1140 params["TTiEta"] = getToweriEta_fromAbsoluteID(getTower_absoluteEtaID(p4calibrated.eta()));
1141 params["TTiPhi"] = getToweriPhi_fromAbsoluteID(getTower_absolutePhiID(p4calibrated.phi()));
1142 cluster.setExperimentalParams(params);
1143 L1EGXtalClusters->push_back(cluster);
1144
1145 int standaloneWP = (int)(is_iso && is_ss);
1146 int looseL1TkMatchWP = (int)(is_looseTkiso && is_looseTkss);
1147 int photonWP = (int)(is_photon);
1148 int quality =
1149 (standaloneWP * std::pow(2, 0)) + (looseL1TkMatchWP * std::pow(2, 1)) + (photonWP * std::pow(2, 2));
1150 L1EGammas->push_back(
1151 0, l1t::EGamma(p4calibrated, p4calibrated.pt(), p4calibrated.eta(), p4calibrated.phi(), quality, 1));
1152 }
1153 }
1154 }
1155 }
1156
1157 for (int ii = 0; ii < n_links_GCTcard; ++ii) {
1158 for (int ll = 0; ll < n_GCTcards; ++ll) {
1159
1160 for (int jj = 0; jj < n_towers_per_link; ++jj) {
1161 l1tp2::CaloTower l1CaloTower;
1162 l1CaloTower.setEcalTowerEt(ECAL_tower_L2Card[ii][jj][ll]);
1163 l1CaloTower.setHcalTowerEt(HCAL_tower_L2Card[ii][jj][ll]);
1164 l1CaloTower.setTowerIEta(getToweriEta_fromAbsoluteID(iEta_tower_L2Card[ii][jj][ll]));
1165 l1CaloTower.setTowerIPhi(getToweriPhi_fromAbsoluteID(iPhi_tower_L2Card[ii][jj][ll]));
1166 l1CaloTower.setTowerEta(getTowerEta_fromAbsoluteID(iEta_tower_L2Card[ii][jj][ll]));
1167 l1CaloTower.setTowerPhi(getTowerPhi_fromAbsoluteID(iPhi_tower_L2Card[ii][jj][ll]));
1168
1169 static float constexpr towerEtaUpperUnitialized = -80;
1170 static float constexpr towerPhiUpperUnitialized = -90;
1171 if (l1CaloTower.towerEta() < towerEtaUpperUnitialized && l1CaloTower.towerPhi() < towerPhiUpperUnitialized) {
1172 l1CaloTower.setTowerEta(l1t::CaloTools::towerEta(l1CaloTower.towerIEta()));
1173 l1CaloTower.setTowerPhi(l1t::CaloTools::towerPhi(l1CaloTower.towerIEta(), l1CaloTower.towerIPhi()));
1174 }
1175 l1CaloTower.setIsBarrel(true);
1176
1177
1178
1179 for (const auto& l1eg : *L1EGXtalClusters) {
1180 if (l1eg.experimentalParam("TTiEta") != l1CaloTower.towerIEta())
1181 continue;
1182 if (l1eg.experimentalParam("TTiPhi") != l1CaloTower.towerIPhi())
1183 continue;
1184
1185 int n_L1eg = l1CaloTower.nL1eg();
1186 l1CaloTower.setNL1eg(n_L1eg++);
1187 l1CaloTower.setL1egTowerEt(l1CaloTower.l1egTowerEt() + l1eg.pt());
1188
1189 if (l1CaloTower.nL1eg() > 1)
1190 continue;
1191 l1CaloTower.setL1egTrkSS(l1eg.experimentalParam("trkMatchWP_showerShape"));
1192 l1CaloTower.setL1egTrkIso(l1eg.experimentalParam("trkMatchWP_isolation"));
1193 l1CaloTower.setL1egStandaloneSS(l1eg.experimentalParam("standaloneWP_showerShape"));
1194 l1CaloTower.setL1egStandaloneIso(l1eg.experimentalParam("standaloneWP_isolation"));
1195 }
1196
1197 L1CaloTowers->push_back(l1CaloTower);
1198 }
1199 }
1200 }
1201
1202 iEvent.put(std::move(L1EGXtalClusters));
1203 iEvent.put(std::move(L1EGammas));
1204 iEvent.put(std::move(L1CaloTowers), "L1CaloTowerCollection");
1205 }
1206
1207 bool L1EGCrystalClusterEmulatorProducer::passes_iso(float pt, float iso) {
1208 bool is_iso = true;
1209 if (pt < slideIsoPtThreshold) {
1210 if (!((a0_80 - a1_80 * pt) > iso))
1211 is_iso = false;
1212 } else {
1213 if (iso > a0)
1214 is_iso = false;
1215 }
1216 if (pt > plateau_ss)
1217 is_iso = true;
1218 return is_iso;
1219 }
1220
1221 bool L1EGCrystalClusterEmulatorProducer::passes_looseTkiso(float pt, float iso) {
1222 bool is_iso = (b0 + b1 * std::exp(-b2 * pt) > iso);
1223 if (pt > plateau_ss)
1224 is_iso = true;
1225 return is_iso;
1226 }
1227
1228 bool L1EGCrystalClusterEmulatorProducer::passes_ss(float pt, float ss) {
1229 bool is_ss = ((c0_ss + c1_ss * std::exp(-c2_ss * pt)) <= ss);
1230 if (pt > plateau_ss)
1231 is_ss = true;
1232 return is_ss;
1233 }
1234
1235 bool L1EGCrystalClusterEmulatorProducer::passes_photon(float pt, float pss) {
1236 bool is_ss = (pss > d0 - d1 * pt);
1237 if (pt > plateau_ss)
1238 is_ss = true;
1239 return is_ss;
1240 }
1241
1242 bool L1EGCrystalClusterEmulatorProducer::passes_looseTkss(float pt, float ss) {
1243 bool is_ss = ((e0_looseTkss - e1_looseTkss * std::exp(-e2_looseTkss * pt)) <= ss);
1244 if (pt > plateau_ss)
1245 is_ss = true;
1246 return is_ss;
1247 }
1248
1249
1250 DEFINE_FWK_MODULE(L1EGCrystalClusterEmulatorProducer);