CMS 3D CMS Logo

List of all members | Classes | Public Member Functions | Private Member Functions | Private Attributes
L1EGCrystalClusterEmulatorProducer Class Reference
Inheritance diagram for L1EGCrystalClusterEmulatorProducer:
edm::stream::EDProducer<>

Classes

struct  mycluster
 
class  SimpleCaloHit
 

Public Member Functions

 L1EGCrystalClusterEmulatorProducer (const edm::ParameterSet &)
 
 ~L1EGCrystalClusterEmulatorProducer () override
 
- Public Member Functions inherited from edm::stream::EDProducer<>
 EDProducer ()=default
 
 EDProducer (const EDProducer &)=delete
 
bool hasAbilityToProduceInBeginLumis () const final
 
bool hasAbilityToProduceInBeginProcessBlocks () const final
 
bool hasAbilityToProduceInBeginRuns () const final
 
bool hasAbilityToProduceInEndLumis () const final
 
bool hasAbilityToProduceInEndProcessBlocks () const final
 
bool hasAbilityToProduceInEndRuns () const final
 
const EDProduceroperator= (const EDProducer &)=delete
 

Private Member Functions

float get_calibrate (float uncorr)
 
bool passes_iso (float pt, float iso)
 
bool passes_looseTkiso (float pt, float iso)
 
bool passes_looseTkss (float pt, float ss)
 
bool passes_photon (float pt, float pss)
 
bool passes_ss (float pt, float ss)
 
void produce (edm::Event &, const edm::EventSetup &) override
 

Private Attributes

l1tp2::ParametricCalibration calib_
 
edm::ESGetToken< CaloGeometry, CaloGeometryRecordcaloGeometryTag_
 
edm::ESGetToken< CaloTPGTranscoder, CaloTPGRecorddecoderTag_
 
const CaloSubdetectorGeometryebGeometry
 
edm::EDGetTokenT< EcalEBTrigPrimDigiCollectionecalTPEBToken_
 
const CaloSubdetectorGeometryhbGeometry
 
edm::ESGetToken< HcalTopology, HcalRecNumberingRecordhbTopologyTag_
 
edm::EDGetTokenT< edm::SortedCollection< HcalTriggerPrimitiveDigi > > hcalTPToken_
 
const HcalTopologyhcTopology_
 

Additional Inherited Members

- Public Types inherited from edm::stream::EDProducer<>
using CacheTypes = CacheContexts< T... >
 
using GlobalCache = typename CacheTypes::GlobalCache
 
using HasAbility = AbilityChecker< T... >
 
using InputProcessBlockCache = typename CacheTypes::InputProcessBlockCache
 
using LuminosityBlockCache = typename CacheTypes::LuminosityBlockCache
 
using LuminosityBlockContext = LuminosityBlockContextT< LuminosityBlockCache, RunCache, GlobalCache >
 
using LuminosityBlockSummaryCache = typename CacheTypes::LuminosityBlockSummaryCache
 
using RunCache = typename CacheTypes::RunCache
 
using RunContext = RunContextT< RunCache, GlobalCache >
 
using RunSummaryCache = typename CacheTypes::RunSummaryCache
 

Detailed Description

Definition at line 264 of file L1EGammaCrystalsEmulatorProducer.cc.

Constructor & Destructor Documentation

◆ L1EGCrystalClusterEmulatorProducer()

L1EGCrystalClusterEmulatorProducer::L1EGCrystalClusterEmulatorProducer ( const edm::ParameterSet iConfig)
explicit

Definition at line 406 of file L1EGammaCrystalsEmulatorProducer.cc.

407  : ecalTPEBToken_(consumes<EcalEBTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalTPEB"))),
408  hcalTPToken_(
410  decoderTag_(esConsumes<CaloTPGTranscoder, CaloTPGRecord>(edm::ESInputTag("", ""))),
411  calib_(iConfig.getParameter<edm::ParameterSet>("calib")),
412  caloGeometryTag_(esConsumes<CaloGeometry, CaloGeometryRecord>(edm::ESInputTag("", ""))),
413  hbTopologyTag_(esConsumes<HcalTopology, HcalRecNumberingRecord>(edm::ESInputTag("", ""))) {
414  produces<l1tp2::CaloCrystalClusterCollection>();
415  produces<BXVector<l1t::EGamma> >();
416  produces<l1tp2::CaloTowerCollection>("L1CaloTowerCollection");
417 }
edm::EDGetTokenT< edm::SortedCollection< HcalTriggerPrimitiveDigi > > hcalTPToken_
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeometryTag_
edm::ESGetToken< HcalTopology, HcalRecNumberingRecord > hbTopologyTag_
edm::EDGetTokenT< EcalEBTrigPrimDigiCollection > ecalTPEBToken_
edm::ESGetToken< CaloTPGTranscoder, CaloTPGRecord > decoderTag_

◆ ~L1EGCrystalClusterEmulatorProducer()

L1EGCrystalClusterEmulatorProducer::~L1EGCrystalClusterEmulatorProducer ( )
override

Definition at line 419 of file L1EGammaCrystalsEmulatorProducer.cc.

419 {}

Member Function Documentation

◆ get_calibrate()

float L1EGCrystalClusterEmulatorProducer::get_calibrate ( float  uncorr)
private

◆ passes_iso()

bool L1EGCrystalClusterEmulatorProducer::passes_iso ( float  pt,
float  iso 
)
private

Definition at line 1207 of file L1EGammaCrystalsEmulatorProducer.cc.

References a0, a0_80, a1_80, plateau_ss, DiDispStaMuonMonitor_cfi::pt, and slideIsoPtThreshold.

Referenced by produce().

1207  {
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 }
static constexpr float a1_80
static constexpr float a0_80
static constexpr float plateau_ss
static constexpr float slideIsoPtThreshold
static constexpr float a0

◆ passes_looseTkiso()

bool L1EGCrystalClusterEmulatorProducer::passes_looseTkiso ( float  pt,
float  iso 
)
private

Definition at line 1221 of file L1EGammaCrystalsEmulatorProducer.cc.

References b0, b1, b2, JetChargeProducer_cfi::exp, plateau_ss, and DiDispStaMuonMonitor_cfi::pt.

Referenced by produce().

1221  {
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 }
static constexpr float plateau_ss
static constexpr float b2
static constexpr float b0
static constexpr float b1

◆ passes_looseTkss()

bool L1EGCrystalClusterEmulatorProducer::passes_looseTkss ( float  pt,
float  ss 
)
private

Definition at line 1242 of file L1EGammaCrystalsEmulatorProducer.cc.

References e0_looseTkss, e1_looseTkss, e2_looseTkss, JetChargeProducer_cfi::exp, plateau_ss, DiDispStaMuonMonitor_cfi::pt, and contentValuesCheck::ss.

Referenced by produce().

1242  {
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 }
static constexpr float e2_looseTkss
static constexpr float plateau_ss
static constexpr float e0_looseTkss
static constexpr float e1_looseTkss

◆ passes_photon()

bool L1EGCrystalClusterEmulatorProducer::passes_photon ( float  pt,
float  pss 
)
private

Definition at line 1235 of file L1EGammaCrystalsEmulatorProducer.cc.

References d0, d1, plateau_ss, and DiDispStaMuonMonitor_cfi::pt.

Referenced by produce().

1235  {
1236  bool is_ss = (pss > d0 - d1 * pt);
1237  if (pt > plateau_ss)
1238  is_ss = true;
1239  return is_ss;
1240 }
std::pair< ALIstring, ALIstring > pss
Definition: Fit.h:25
static constexpr float plateau_ss
static constexpr float d0
static constexpr float d1

◆ passes_ss()

bool L1EGCrystalClusterEmulatorProducer::passes_ss ( float  pt,
float  ss 
)
private

Definition at line 1228 of file L1EGammaCrystalsEmulatorProducer.cc.

References c0_ss, c1_ss, c2_ss, JetChargeProducer_cfi::exp, plateau_ss, DiDispStaMuonMonitor_cfi::pt, and contentValuesCheck::ss.

Referenced by produce().

1228  {
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 }
static constexpr float c2_ss
static constexpr float plateau_ss
static constexpr float c1_ss
static constexpr float c0_ss

◆ produce()

void L1EGCrystalClusterEmulatorProducer::produce ( edm::Event iEvent,
const edm::EventSetup iSetup 
)
overrideprivate

Definition at line 421 of file L1EGammaCrystalsEmulatorProducer.cc.

References a, funct::abs(), b, L1EGCrystalClusterEmulatorProducer::mycluster::c2x2_, L1EGCrystalClusterEmulatorProducer::mycluster::c2x5_, L1EGCrystalClusterEmulatorProducer::mycluster::c5x5_, calib_, caloGeometryTag_, L1EGCrystalClusterEmulatorProducer::mycluster::cbrem_, gpuPixelDoublets::cc, L1EGCrystalClusterEmulatorProducer::mycluster::ccrystalid_, L1EGCrystalClusterEmulatorProducer::mycluster::ceta_, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), convert_L2toL1_card(), convert_L2toL1_link(), convert_L2toL1_tower(), L1EGCrystalClusterEmulatorProducer::mycluster::cphi_, L1EGCrystalClusterEmulatorProducer::mycluster::cphotonshowershape_, L1EGCrystalClusterEmulatorProducer::mycluster::cpt, L1EGCrystalClusterEmulatorProducer::mycluster::craweta_, L1EGCrystalClusterEmulatorProducer::mycluster::crawphi_, L1EGCrystalClusterEmulatorProducer::mycluster::cshowershape_, L1EGCrystalClusterEmulatorProducer::mycluster::cshowershapeloosetk_, L1EGCrystalClusterEmulatorProducer::mycluster::ctowerid_, cut_500_MeV, L1EGCrystalClusterEmulatorProducer::mycluster::cWeightedEta_, L1EGCrystalClusterEmulatorProducer::mycluster::cWeightedPhi_, decoderTag_, HcalTrigTowerGeometry::detIds(), do_brem, ebGeometry, DetId::Ecal, EcalBarrel, ecalTPEBToken_, mps_fire::end, EgHLTOffHistBins_cfi::et, PVValHelper::eta, PV3DBase< T, PVType, FrameType >::eta(), Exception, nano_mu_digi_cff::float, get_towerEta_fromCardLinkTower(), get_towerEta_fromCardTowerInCard(), get_towerPhi_fromCardLinkTower(), get_towerPhi_fromCardTowerInCard(), getCrystal_etaID(), getCrystal_phiID(), getCrystalIDInTower(), edm::EventSetup::getData(), getEta_fromL2LinkCardTowerCrystal(), getEtaMin_card(), CaloSubdetectorGeometry::getGeometry(), getPhi_fromL2LinkCardTowerCrystal(), getPhiMin_card(), getTower_absoluteEtaID(), getTower_absolutePhiID(), getTower_etaID(), getTower_phiID(), getTowerEta_fromAbsoluteID(), getTowerID(), getToweriEta_fromAbsoluteID(), getToweriPhi_fromAbsoluteID(), getTowerPhi_fromAbsoluteID(), hbGeometry, hbTopologyTag_, DetId::Hcal, HcalBarrel, hcalTPToken_, hcTopology_, hit::id, L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::id(), iEvent, cuy::ii, createfilelist::int, findQualityFiles::jj, GetRecoTauVFromDQM_MC_cff::kk, l1tp2::CaloTower::l1egTowerEt(), M_PI, SiStripPI::max, eostools::move(), n_borders_eta, n_borders_phi, n_clusters_4link, n_clusters_link, n_clusters_max, n_clusters_per_L1card, n_clusters_per_link, n_crystals_towerEta, n_crystals_towerPhi, n_eta_bins, n_GCTcards, n_links_card, n_links_GCTcard, n_towers_halfPhi, n_towers_per_link, n_towers_Phi, l1tp2::CaloTower::nL1eg(), or, submitPVValidationJobs::params, passes_iso(), passes_looseTkiso(), passes_looseTkss(), passes_photon(), passes_ss(), phi, PV3DBase< T, PVType, FrameType >::phi(), L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::position(), funct::pow(), edm::Handle< T >::product(), L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::pt(), quality, l1tp2::CaloTower::setEcalTowerEt(), L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::setEnergy(), l1tp2::CaloTower::setHcalTowerEt(), L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::setId(), L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::setIdHcal(), l1tp2::CaloTower::setIsBarrel(), l1tp2::CaloTower::setL1egStandaloneIso(), l1tp2::CaloTower::setL1egStandaloneSS(), l1tp2::CaloTower::setL1egTowerEt(), l1tp2::CaloTower::setL1egTrkIso(), l1tp2::CaloTower::setL1egTrkSS(), l1tp2::CaloTower::setNL1eg(), L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::setPosition(), L1EGCrystalClusterEmulatorProducer::SimpleCaloHit::setPt(), l1tp2::CaloTower::setTowerEta(), l1tp2::CaloTower::setTowerIEta(), l1tp2::CaloTower::setTowerIPhi(), l1tp2::CaloTower::setTowerPhi(), findQualityFiles::size, jetUpdater_cfi::sort, l1tp2::CaloTower::towerEta(), l1t::CaloTools::towerEta(), l1tp2::CaloTower::towerIEta(), l1tp2::CaloTower::towerIPhi(), l1tp2::CaloTower::towerPhi(), l1t::CaloTools::towerPhi(), and HcalTopology::validHT().

421  {
422  using namespace edm;
423 
425  iEvent.getByToken(ecalTPEBToken_, pcalohits);
426 
427  const auto& caloGeometry = iSetup.getData(caloGeometryTag_);
428  ebGeometry = caloGeometry.getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
429  hbGeometry = caloGeometry.getSubdetectorGeometry(DetId::Hcal, HcalBarrel);
430  const auto& hbTopology = iSetup.getData(hbTopologyTag_);
431  hcTopology_ = &hbTopology;
432  HcalTrigTowerGeometry theTrigTowerGeometry(hcTopology_);
433 
434  const auto& decoder = iSetup.getData(decoderTag_);
435 
436  //****************************************************************
437  //******************* Get all the hits ***************************
438  //****************************************************************
439 
440  // Get all the ECAL hits
441  iEvent.getByToken(ecalTPEBToken_, pcalohits);
442  std::vector<SimpleCaloHit> ecalhits;
443 
444  for (const auto& hit : *pcalohits.product()) {
445  if (hit.encodedEt() > 0) // hit.encodedEt() returns an int corresponding to 2x the crystal Et
446  {
447  // Et is 10 bit, by keeping the ADC saturation Et at 120 GeV it means that you have to divide by 8
448  float et = hit.encodedEt() / 8.;
449  if (et < cut_500_MeV)
450  continue; // keep the 500 MeV ET Cut
451 
452  auto cell = ebGeometry->getGeometry(hit.id());
453 
454  SimpleCaloHit ehit;
455  ehit.setId(hit.id());
456  ehit.setPosition(GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z()));
457  ehit.setEnergy(et);
458  ehit.setPt();
459  ecalhits.push_back(ehit);
460  }
461  }
462 
463  // Get all the HCAL hits
464  std::vector<SimpleCaloHit> hcalhits;
466  iEvent.getByToken(hcalTPToken_, hbhecoll);
467  for (const auto& hit : *hbhecoll.product()) {
468  float et = decoder.hcaletValue(hit.id(), hit.t0());
469  if (et <= 0)
470  continue;
471  if (!(hcTopology_->validHT(hit.id()))) {
472  LogError("L1EGCrystalClusterEmulatorProducer")
473  << " -- Hcal hit DetID not present in HCAL Geom: " << hit.id() << std::endl;
474  throw cms::Exception("L1EGCrystalClusterEmulatorProducer");
475  continue;
476  }
477  const std::vector<HcalDetId>& hcId = theTrigTowerGeometry.detIds(hit.id());
478  if (hcId.empty()) {
479  LogError("L1EGCrystalClusterEmulatorProducer")
480  << "Cannot find any HCalDetId corresponding to " << hit.id() << std::endl;
481  throw cms::Exception("L1EGCrystalClusterEmulatorProducer");
482  continue;
483  }
484  if (hcId[0].subdetId() > 1)
485  continue;
486  GlobalVector hcal_tp_position = GlobalVector(0., 0., 0.);
487  for (const auto& hcId_i : hcId) {
488  if (hcId_i.subdetId() > 1)
489  continue;
490  auto cell = hbGeometry->getGeometry(hcId_i);
491  if (cell == nullptr)
492  continue;
493  GlobalVector tmpVector = GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z());
494  hcal_tp_position = tmpVector;
495  break;
496  }
497  SimpleCaloHit hhit;
498  hhit.setId(hit.id());
499  hhit.setIdHcal(hit.id());
500  hhit.setPosition(hcal_tp_position);
501  hhit.setEnergy(et);
502  hhit.setPt();
503  hcalhits.push_back(hhit);
504  }
505 
506  //*******************************************************************
507  //********************** Do layer 1 *********************************
508  //*******************************************************************
509 
510  // Definition of L1 outputs
511  // 36 L1 cards send each 4 links with 17 towers
512  float ECAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
513  float HCAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
514  int iEta_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
515  int iPhi_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
516  // 36 L1 cards send each 4 links with 3 clusters
517  float energy_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
518  // 36 L1 cards send each 4 links with 3 clusters
519  int brem_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
520  int towerID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
521  int crystalID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
522  int showerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
523  int showerShapeLooseTk_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
524  int photonShowerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
525 
526  for (int ii = 0; ii < n_links_card; ++ii) {
527  for (int jj = 0; jj < n_towers_per_link; ++jj) {
528  for (int ll = 0; ll < n_towers_halfPhi; ++ll) {
529  ECAL_tower_L1Card[ii][jj][ll] = 0;
530  HCAL_tower_L1Card[ii][jj][ll] = 0;
531  iPhi_tower_L1Card[ii][jj][ll] = -999;
532  iEta_tower_L1Card[ii][jj][ll] = -999;
533  }
534  }
535  }
536  for (int ii = 0; ii < n_links_card; ++ii) {
537  for (int jj = 0; jj < n_clusters_link; ++jj) {
538  for (int ll = 0; ll < n_towers_halfPhi; ++ll) {
539  energy_cluster_L1Card[ii][jj][ll] = 0;
540  brem_cluster_L1Card[ii][jj][ll] = 0;
541  towerID_cluster_L1Card[ii][jj][ll] = 0;
542  crystalID_cluster_L1Card[ii][jj][ll] = 0;
543  }
544  }
545  }
546 
547  // There is one list of clusters per card. We take the 12 highest pt per card
548  vector<mycluster> cluster_list[n_towers_halfPhi];
549  // After merging the clusters in different regions of a single L1 card
550  vector<mycluster> cluster_list_merged[n_towers_halfPhi];
551 
552  for (int cc = 0; cc < n_towers_halfPhi; ++cc) { // Loop over 36 L1 cards
553  // Loop over 3x4 etaxphi regions to search for max 5 clusters
554  for (int nregion = 0; nregion <= n_clusters_max; ++nregion) {
555  int nclusters = 0;
556  bool build_cluster = true;
557 
558  // Continue until 5 clusters have been built or there is no cluster left
559  while (nclusters < n_clusters_max && build_cluster) {
560  build_cluster = false;
561  SimpleCaloHit centerhit;
562 
563  for (const auto& hit : ecalhits) {
564  // Highest hit in good region with pt>1 and not used in any other cluster
565  if (hit.isInCardAndRegion(cc, nregion) && !hit.used() && hit.pt() >= 1.0 && hit.pt() > centerhit.pt()) {
566  centerhit = hit;
567  build_cluster = true;
568  }
569  }
570  if (build_cluster)
571  nclusters++;
572 
573  // Use only the 5 most energetic clusters
574  if (build_cluster && nclusters > 0 && nclusters <= n_clusters_max) {
575  mycluster mc1;
576  mc1.cpt = 0.0;
577  mc1.cWeightedEta_ = 0.0;
578  mc1.cWeightedPhi_ = 0.0;
579  float leftlobe = 0;
580  float rightlobe = 0;
581  float e5x5 = 0;
582  float e2x5_1 = 0;
583  float e2x5_2 = 0;
584  float e2x2_1 = 0;
585  float e2x2_2 = 0;
586  float e2x2_3 = 0;
587  float e2x2_4 = 0;
588  for (auto& hit : ecalhits) {
589  if (hit.isInCardAndRegion(cc, nregion) && (hit.pt() > 0)) {
590  if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) {
591  rightlobe += hit.pt();
592  }
593  if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) {
594  leftlobe += hit.pt();
595  }
596  if (abs(hit.dieta(centerhit)) <= 2 && abs(hit.diphi(centerhit)) <= 2) {
597  e5x5 += hit.energy();
598  }
599  if ((hit.dieta(centerhit) == 1 or hit.dieta(centerhit) == 0) &&
600  (hit.diphi(centerhit) == 1 or hit.diphi(centerhit) == 0)) {
601  e2x2_1 += hit.energy();
602  }
603  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) &&
604  (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == 1)) {
605  e2x2_2 += hit.energy();
606  }
607  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) &&
608  (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) {
609  e2x2_3 += hit.energy();
610  }
611  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) &&
612  (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) {
613  e2x2_4 += hit.energy();
614  }
615  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) && abs(hit.diphi(centerhit)) <= 2) {
616  e2x5_1 += hit.energy();
617  }
618  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) && abs(hit.diphi(centerhit)) <= 2) {
619  e2x5_2 += hit.energy();
620  }
621  }
622  if (hit.isInCardAndRegion(cc, nregion) && !hit.used() && hit.pt() > 0 && abs(hit.dieta(centerhit)) <= 1 &&
623  abs(hit.diphi(centerhit)) <= 2) {
624  // clusters 3x5 in etaxphi using only the hits in the corresponding card and in the corresponding 3x4 region
625  hit.setUsed(true);
626  mc1.cpt += hit.pt();
627  mc1.cWeightedEta_ += float(hit.pt()) * float(hit.position().eta());
628  mc1.cWeightedPhi_ = mc1.cWeightedPhi_ + (float(hit.pt()) * float(hit.position().phi()));
629  }
630  }
631  if (do_brem && (rightlobe > 0.10 * mc1.cpt or leftlobe > 0.10 * mc1.cpt)) {
632  for (auto& hit : ecalhits) {
633  if (hit.isInCardAndRegion(cc, nregion) && hit.pt() > 0 && !hit.used()) {
634  if (rightlobe > 0.10 * mc1.cpt && (leftlobe < 0.10 * mc1.cpt or rightlobe > leftlobe) &&
635  abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) {
636  mc1.cpt += hit.pt();
637  hit.setUsed(true);
638  mc1.cbrem_ = 1;
639  }
640  if (leftlobe > 0.10 * mc1.cpt && (rightlobe < 0.10 * mc1.cpt or leftlobe >= rightlobe) &&
641  abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) {
642  mc1.cpt += hit.pt();
643  hit.setUsed(true);
644  mc1.cbrem_ = 1;
645  }
646  }
647  }
648  }
649  mc1.c5x5_ = e5x5;
650  mc1.c2x5_ = max(e2x5_1, e2x5_2);
651  mc1.c2x2_ = e2x2_1;
652  if (e2x2_2 > mc1.c2x2_)
653  mc1.c2x2_ = e2x2_2;
654  if (e2x2_3 > mc1.c2x2_)
655  mc1.c2x2_ = e2x2_3;
656  if (e2x2_4 > mc1.c2x2_)
657  mc1.c2x2_ = e2x2_4;
658  mc1.cWeightedEta_ = mc1.cWeightedEta_ / mc1.cpt;
659  mc1.cWeightedPhi_ = mc1.cWeightedPhi_ / mc1.cpt;
660  mc1.ceta_ = getCrystal_etaID(centerhit.position().eta());
661  mc1.cphi_ = getCrystal_phiID(centerhit.position().phi());
662  mc1.crawphi_ = centerhit.position().phi();
663  mc1.craweta_ = centerhit.position().eta();
664  cluster_list[cc].push_back(mc1);
665  } // End if 5 clusters per region
666  } // End while to find the 5 clusters
667  } // End loop over regions to search for clusters
668  std::sort(begin(cluster_list[cc]), end(cluster_list[cc]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; });
669 
670  // Merge clusters from different regions
671  for (unsigned int jj = 0; jj < unsigned(cluster_list[cc].size()); ++jj) {
672  for (unsigned int kk = jj + 1; kk < unsigned(cluster_list[cc].size()); ++kk) {
673  if (std::abs(cluster_list[cc][jj].ceta_ - cluster_list[cc][kk].ceta_) < 2 &&
674  std::abs(cluster_list[cc][jj].cphi_ - cluster_list[cc][kk].cphi_) < 2) { // Diagonal + exact neighbors
675  if (cluster_list[cc][kk].cpt > cluster_list[cc][jj].cpt) {
676  cluster_list[cc][kk].cpt += cluster_list[cc][jj].cpt;
677  cluster_list[cc][kk].c5x5_ += cluster_list[cc][jj].c5x5_;
678  cluster_list[cc][kk].c2x5_ += cluster_list[cc][jj].c2x5_;
679  cluster_list[cc][jj].cpt = 0;
680  cluster_list[cc][jj].c5x5_ = 0;
681  cluster_list[cc][jj].c2x5_ = 0;
682  cluster_list[cc][jj].c2x2_ = 0;
683  } else {
684  cluster_list[cc][jj].cpt += cluster_list[cc][kk].cpt;
685  cluster_list[cc][jj].c5x5_ += cluster_list[cc][kk].c5x5_;
686  cluster_list[cc][jj].c2x5_ += cluster_list[cc][kk].c2x5_;
687  cluster_list[cc][kk].cpt = 0;
688  cluster_list[cc][kk].c2x2_ = 0;
689  cluster_list[cc][kk].c2x5_ = 0;
690  cluster_list[cc][kk].c5x5_ = 0;
691  }
692  }
693  }
694  if (cluster_list[cc][jj].cpt > 0) {
695  cluster_list[cc][jj].cpt =
696  cluster_list[cc][jj].cpt *
697  calib_(cluster_list[cc][jj].cpt,
698  std::abs(cluster_list[cc][jj].craweta_)); //Mark's calibration as a function of eta and pt
699  cluster_list_merged[cc].push_back(cluster_list[cc][jj]);
700  }
701  }
702  std::sort(begin(cluster_list_merged[cc]), end(cluster_list_merged[cc]), [](mycluster a, mycluster b) {
703  return a.cpt > b.cpt;
704  });
705 
706  // Fill cluster information in the arrays. We keep max 12 clusters (distributed between 4 links)
707  for (unsigned int jj = 0; jj < unsigned(cluster_list_merged[cc].size()) && jj < n_clusters_4link; ++jj) {
708  crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] =
709  getCrystalIDInTower(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_);
710  towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] =
711  getTowerID(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_);
712  energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cpt;
713  brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cbrem_;
714  if (passes_ss(cluster_list_merged[cc][jj].cpt,
715  cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_))
716  showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
717  else
718  showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
719  if (passes_looseTkss(cluster_list_merged[cc][jj].cpt,
720  cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_))
721  showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
722  else
723  showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
724  if (passes_photon(cluster_list_merged[cc][jj].cpt,
725  cluster_list_merged[cc][jj].c2x2_ / cluster_list_merged[cc][jj].c2x5_))
726  photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
727  else
728  photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
729  }
730 
731  // Loop over calo ecal hits to get the ECAL towers. Take only hits that have not been used to make clusters
732  for (const auto& hit : ecalhits) {
733  if (hit.isInCard(cc) && !hit.used()) {
734  for (int jj = 0; jj < n_links_card; ++jj) { // loop over 4 links per card
735  if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % 4 == jj) { // Go to ID tower modulo 4
736  for (int ii = 0; ii < n_towers_per_link; ++ii) {
737  // Apply Mark's calibration at the same time (row of the lowest pT, as a function of eta)
738  if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) {
739  ECAL_tower_L1Card[jj][ii][cc] += hit.pt() * calib_(0, std::abs(hit.position().eta()));
740  iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta());
741  iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi());
742  }
743  } // end of loop over eta towers
744  }
745  } // end of loop over phi links
746  // Make sure towers with 0 ET are initialized with proper iEta, iPhi coordinates
747  static constexpr float tower_width = 0.0873;
748  for (int jj = 0; jj < n_links_card; ++jj) {
749  for (int ii = 0; ii < n_towers_per_link; ++ii) {
750  float phi = getPhiMin_card(cc) * tower_width / n_crystals_towerPhi - M_PI + (jj + 0.5) * tower_width;
751  float eta = getEtaMin_card(cc) * tower_width / n_crystals_towerEta - n_towers_per_link * tower_width +
752  (ii + 0.5) * tower_width;
753  iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(eta);
754  iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(phi);
755  }
756  }
757  } // end of check if inside card
758  } // end of loop over hits to build towers
759 
760  // Loop over hcal hits to get the HCAL towers.
761  for (const auto& hit : hcalhits) {
762  if (hit.isInCard(cc) && hit.pt() > 0) {
763  for (int jj = 0; jj < n_links_card; ++jj) {
764  if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % n_links_card == jj) {
765  for (int ii = 0; ii < n_towers_per_link; ++ii) {
766  if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) {
767  HCAL_tower_L1Card[jj][ii][cc] += hit.pt();
768  iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta());
769  iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi());
770  }
771  } // end of loop over eta towers
772  }
773  } // end of loop over phi links
774  } // end of check if inside card
775  } // end of loop over hits to build towers
776 
777  // Give back energy of not used clusters to the towers (if there are more than 12 clusters)
778  for (unsigned int kk = n_clusters_4link; kk < cluster_list_merged[cc].size(); ++kk) {
779  if (cluster_list_merged[cc][kk].cpt > 0) {
780  ECAL_tower_L1Card[getTower_phiID(cluster_list_merged[cc][kk].cphi_)]
781  [getTower_etaID(cluster_list_merged[cc][kk].ceta_)][cc] += cluster_list_merged[cc][kk].cpt;
782  }
783  }
784  } //End of loop over cards
785 
786  //*********************************************************
787  //******************** Do layer 2 *************************
788  //*********************************************************
789 
790  // Definition of L2 outputs
791  float HCAL_tower_L2Card[n_links_GCTcard][n_towers_per_link]
792  [n_GCTcards]; // 3 L2 cards send each 48 links with 17 towers
793  float ECAL_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
794  int iEta_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
795  int iPhi_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
796  float energy_cluster_L2Card[n_links_GCTcard][n_clusters_per_link]
797  [n_GCTcards]; // 3 L2 cards send each 48 links with 2 clusters
798  float brem_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
799  int towerID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
800  int crystalID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
801  float isolation_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
802  float HE_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
803  int showerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
804  int showerShapeLooseTk_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
805  int photonShowerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
806 
807  for (int ii = 0; ii < n_links_GCTcard; ++ii) {
808  for (int jj = 0; jj < n_towers_per_link; ++jj) {
809  for (int ll = 0; ll < n_GCTcards; ++ll) {
810  HCAL_tower_L2Card[ii][jj][ll] = 0;
811  ECAL_tower_L2Card[ii][jj][ll] = 0;
812  iEta_tower_L2Card[ii][jj][ll] = 0;
813  iPhi_tower_L2Card[ii][jj][ll] = 0;
814  }
815  }
816  }
817  for (int ii = 0; ii < n_links_GCTcard; ++ii) {
818  for (int jj = 0; jj < n_clusters_per_link; ++jj) {
819  for (int ll = 0; ll < n_GCTcards; ++ll) {
820  energy_cluster_L2Card[ii][jj][ll] = 0;
821  brem_cluster_L2Card[ii][jj][ll] = 0;
822  towerID_cluster_L2Card[ii][jj][ll] = 0;
823  crystalID_cluster_L2Card[ii][jj][ll] = 0;
824  isolation_cluster_L2Card[ii][jj][ll] = 0;
825  HE_cluster_L2Card[ii][jj][ll] = 0;
826  photonShowerShape_cluster_L2Card[ii][jj][ll] = 0;
827  showerShape_cluster_L2Card[ii][jj][ll] = 0;
828  showerShapeLooseTk_cluster_L2Card[ii][jj][ll] = 0;
829  }
830  }
831  }
832 
833  // There is one list of clusters per equivalent of L1 card. We take the 8 highest pt.
834  vector<mycluster> cluster_list_L2[n_towers_halfPhi];
835 
836  // Merge clusters on the phi edges
837  for (int ii = 0; ii < n_borders_phi; ++ii) { // 18 borders in phi
838  for (int jj = 0; jj < n_eta_bins; ++jj) { // 2 eta bins
839  int card_left = 2 * ii + jj;
840  int card_right = 2 * ii + jj + 2;
841  if (card_right > 35)
842  card_right = card_right - n_towers_halfPhi;
843  for (int kk = 0; kk < n_clusters_4link; ++kk) { // 12 clusters in the first card. We check the right side
844  if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 &&
845  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 19 &&
846  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) {
847  for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the 12 clusters in the card on the right
848  if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
849  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < 5 &&
850  std::abs(
851  5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) % n_towers_per_link +
852  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 -
853  5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) % n_towers_per_link -
854  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) < 2) {
855  if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] >
856  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) {
857  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] +=
858  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right];
859  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0;
860  } // The least energetic cluster is merged to the most energetic one
861  else {
862  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] +=
863  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left];
864  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0;
865  }
866  }
867  }
868  }
869  }
870  }
871  }
872 
873  // Bremsstrahlung corrections. Merge clusters on the phi edges depending on pT (pt more than 10 percent, dphi leq 5, deta leq 1)
874  if (do_brem) {
875  for (int ii = 0; ii < n_borders_phi; ++ii) { // 18 borders in phi
876  for (int jj = 0; jj < n_eta_bins; ++jj) { // 2 eta bins
877  int card_left = 2 * ii + jj;
878  int card_right = 2 * ii + jj + 2;
879  if (card_right > 35)
880  card_right = card_right - n_towers_halfPhi;
881  // 12 clusters in the first card. We check the right side crystalID_cluster_L1Card[kk%4][kk/4][card_left]
882  for (int kk = 0; kk < n_clusters_4link; ++kk) {
883  // if the tower is at the edge there might be brem corrections, whatever the crystal ID
884  if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 &&
885  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) {
886  for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the 12 clusters in the card on the right
887  //Distance of 1 max in eta
888  if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
889  std::abs(5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) %
891  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 -
892  5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) %
894  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) <= 1) {
895  //Distance of 5 max in phi
896  if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
897  std::abs(5 + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] / 5 -
898  (crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] / 5)) <= 5) {
899  if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] >
900  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] &&
901  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] >
902  0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) {
903  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] +=
904  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right];
905  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0;
906  brem_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 1;
907  }
908  // The least energetic cluster is merged to the most energetic one, if its pt is at least ten percent
909  else if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right] >=
910  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] &&
911  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] >
912  0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right]) {
913  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] +=
914  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left];
915  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0;
916  brem_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 1;
917  }
918  } //max distance eta
919  } //max distance phi
920  } //max distance phi
921  }
922  }
923  }
924  }
925  }
926 
927  // Merge clusters on the eta edges
928  for (int ii = 0; ii < n_borders_eta; ++ii) { // 18 borders in eta
929  int card_bottom = 2 * ii;
930  int card_top = 2 * ii + 1;
931  for (int kk = 0; kk < n_clusters_4link; ++kk) { // 12 clusters in the first card. We check the top side
932  if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % n_towers_per_link == 16 &&
933  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % 5 == n_links_card &&
934  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] >
935  0) { // If there is one cluster on the right side of the first card
936  for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the card on the right
937  if (std::abs(
938  5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / n_towers_per_link) +
939  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / 5 -
940  5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / n_towers_per_link) -
941  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / 5) < 2) {
942  if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] >
943  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_bottom]) {
944  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] +=
945  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top];
946  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] = 0;
947  } else {
948  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] +=
949  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom];
950  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] = 0;
951  }
952  }
953  }
954  }
955  }
956  }
957 
958  // Regroup the new clusters per equivalent of L1 card geometry
959  for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
960  for (int jj = 0; jj < n_clusters_4link; ++jj) {
961  if (energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii] > 0) {
962  mycluster mc1;
963  mc1.cpt = energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
964  mc1.cbrem_ = brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
965  mc1.ctowerid_ = towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
966  mc1.ccrystalid_ = crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
967  mc1.cshowershape_ = showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
968  mc1.cshowershapeloosetk_ = showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
969  mc1.cphotonshowershape_ = photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
970  cluster_list_L2[ii].push_back(mc1);
971  }
972  }
973  std::sort(
974  begin(cluster_list_L2[ii]), end(cluster_list_L2[ii]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; });
975  }
976 
977  // If there are more than 8 clusters per equivalent of L1 card we need to put them back in the towers
978  for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
979  for (unsigned int jj = n_clusters_per_L1card; jj < n_clusters_4link && jj < cluster_list_L2[ii].size(); ++jj) {
980  if (cluster_list_L2[ii][jj].cpt > 0) {
981  ECAL_tower_L1Card[cluster_list_L2[ii][jj].ctowerid_ / n_towers_per_link]
982  [cluster_list_L2[ii][jj].ctowerid_ % n_towers_per_link][ii] += cluster_list_L2[ii][jj].cpt;
983  cluster_list_L2[ii][jj].cpt = 0;
984  cluster_list_L2[ii][jj].ctowerid_ = 0;
985  cluster_list_L2[ii][jj].ccrystalid_ = 0;
986  }
987  }
988  }
989 
990  // Compute isolation (7*7 ECAL towers) and HCAL energy (5x5 HCAL towers)
991  for (int ii = 0; ii < n_towers_halfPhi; ++ii) { // Loop over the new cluster list (stored in 36x8 format)
992  for (unsigned int jj = 0; jj < n_clusters_per_L1card && jj < cluster_list_L2[ii].size(); ++jj) {
993  int cluster_etaOfTower_fullDetector = get_towerEta_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_);
994  int cluster_phiOfTower_fullDetector = get_towerPhi_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_);
995  float hcal_nrj = 0.0;
996  float isolation = 0.0;
997  int ntowers = 0;
998 
999  for (int iii = 0; iii < n_towers_halfPhi; ++iii) { // The clusters have to be added to the isolation
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) { // 36 cards
1013  for (int ll = 0; ll < n_links_card; ++ll) { // 4 links per card
1014  for (int mm = 0; mm < n_towers_per_link; ++mm) { // 17 towers per link
1015  int etaOftower_fullDetector = get_towerEta_fromCardLinkTower(kk, ll, mm);
1016  int phiOftower_fullDetector = get_towerPhi_fromCardLinkTower(kk, ll, mm);
1017  // First do ECAL
1018  // The towers are within 3. Needs to stitch the two phi sides together
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  // Remove the column outside of the L2 card: values (0,71), (23,26), (24,21), (47,50), (48,50), (71,2)
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  // Now do HCAL
1034  // The towers are within 2. Needs to stitch the two phi sides together
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  // If we summed over fewer than 5*5 = 25 towers (because the cluster was near the edge), scale up the isolation sum
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  //Reformat the information inside the 3 L2 cards
1052  //First let's fill the towers
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] =
1058  HCAL_tower_L2Card[ii][jj][ll] =
1060  iEta_tower_L2Card[ii][jj][ll] =
1062  iPhi_tower_L2Card[ii][jj][ll] =
1064  }
1065  }
1066  }
1067 
1068  //Second let's fill the clusters
1069  for (int ii = 0; ii < n_towers_halfPhi; ++ii) { // The cluster list is still in the L1 like geometry
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  // Fill the cluster collection and towers as well
1097  for (int ii = 0; ii < n_links_GCTcard; ++ii) { // 48 links
1098  for (int ll = 0; ll < n_GCTcards; ++ll) { // 3 cards
1099  // For looping over the Towers a few lines below
1100  for (int jj = 0; jj < 2; ++jj) { // 2 L1EGs
1101  if (energy_cluster_L2Card[ii][jj][ll] > 0.45) {
1103  energy_cluster_L2Card[ii][jj][ll],
1105  ii, ll, towerID_cluster_L2Card[ii][jj][ll], crystalID_cluster_L2Card[ii][jj][ll]),
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  // All the ID set to Standalone WP! Some dummy values for non calculated variables
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  // Experimental parameters, don't want to bother with hardcoding them in data format
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) { // 48 links
1158  for (int ll = 0; ll < n_GCTcards; ++ll) { // 3 cards
1159  // Fill the tower collection
1160  for (int jj = 0; jj < n_towers_per_link; ++jj) { // 17 TTs
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  // Some towers have incorrect eta/phi because that wasn't initialized in certain cases, fix these
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  // Add L1EGs if they match in iEta / iPhi
1178  // L1EGs are already pT ordered, we will take the ID info for the leading one, but pT as the sum
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  // Don't record L1EG quality info for subleading L1EG
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 }
size
Write out results.
static float towerEta(int ieta)
Definition: CaloTools.cc:201
static constexpr int n_links_GCTcard
bool validHT(const HcalTrigTowerDetId &id) const
int getCrystal_etaID(float eta)
edm::EDGetTokenT< edm::SortedCollection< HcalTriggerPrimitiveDigi > > hcalTPToken_
int getCrystal_phiID(float phi)
int getTower_phiID(int cluster_phiID)
static float towerPhi(int ieta, int iphi)
Definition: CaloTools.cc:208
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
static constexpr int n_towers_halfPhi
static constexpr float cut_500_MeV
int getPhiMin_card(int card)
edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeometryTag_
void setEcalTowerEt(float et)
Definition: CaloTower.h:49
int towerIPhi() const
Definition: CaloTower.h:37
uint32_t cc[maxCellsPerHit]
Definition: gpuFishbone.h:49
void setTowerIPhi(int iPhi)
Definition: CaloTower.h:51
T const * product() const
Definition: Handle.h:70
void setL1egStandaloneIso(int staIso)
Definition: CaloTower.h:60
int get_towerEta_fromCardTowerInCard(int card, int towerincard)
int getTowerID(int etaID, int phiID)
int get_towerPhi_fromCardLinkTower(int card, int link, int tower)
static constexpr int n_eta_bins
Log< level::Error, false > LogError
int convert_L2toL1_card(int card, int link)
static constexpr int n_borders_eta
int getEtaMin_card(int card)
void setL1egTrkIso(int trkIso)
Definition: CaloTower.h:58
static constexpr int n_clusters_max
float getTowerEta_fromAbsoluteID(int id)
static constexpr int n_crystals_towerPhi
void setHcalTowerEt(float et)
Definition: CaloTower.h:50
static constexpr int n_clusters_4link
void setTowerIEta(int iEta)
Definition: CaloTower.h:52
edm::ESGetToken< HcalTopology, HcalRecNumberingRecord > hbTopologyTag_
string quality
int get_towerEta_fromCardLinkTower(int card, int link, int tower)
int iEvent
Definition: GenABIO.cc:224
int getTower_absolutePhiID(float phi)
void setTowerPhi(float phi)
Definition: CaloTower.h:53
int getTower_absoluteEtaID(float eta)
int getToweriPhi_fromAbsoluteID(int id)
static constexpr int n_clusters_per_link
int nL1eg() const
Definition: CaloTower.h:42
static constexpr bool do_brem
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
float getTowerPhi_fromAbsoluteID(int id)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int towerIEta() const
Definition: CaloTower.h:38
static constexpr int n_towers_per_link
void setL1egTrkSS(int trkSS)
Definition: CaloTower.h:57
edm::EDGetTokenT< EcalEBTrigPrimDigiCollection > ecalTPEBToken_
static constexpr int n_clusters_link
void setIsBarrel(bool isBarrel)
Definition: CaloTower.h:61
virtual std::shared_ptr< const CaloCellGeometry > getGeometry(const DetId &id) const
Get the cell geometry of a given detector id. Should return false if not found.
int convert_L2toL1_tower(int tower)
void setTowerEta(float eta)
Definition: CaloTower.h:54
ii
Definition: cuy.py:589
#define M_PI
int get_towerPhi_fromCardTowerInCard(int card, int towerincard)
unsigned int id
float getEta_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal)
int getToweriEta_fromAbsoluteID(int id)
static constexpr int n_links_card
int getTower_etaID(int cluster_etaID)
int convert_L2toL1_link(int link)
float towerPhi() const
Definition: CaloTower.h:39
void setL1egTowerEt(float et)
Definition: CaloTower.h:55
static constexpr int n_clusters_per_L1card
double b
Definition: hdecay.h:120
float l1egTowerEt() const
Definition: CaloTower.h:41
static constexpr int n_borders_phi
static constexpr int n_crystals_towerEta
HLT enums.
double a
Definition: hdecay.h:121
static constexpr int n_GCTcards
static constexpr int n_towers_Phi
void setNL1eg(int n)
Definition: CaloTower.h:56
float towerEta() const
Definition: CaloTower.h:40
float getPhi_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal)
int getCrystalIDInTower(int etaID, int phiID)
void setL1egStandaloneSS(int staSS)
Definition: CaloTower.h:59
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
def move(src, dest)
Definition: eostools.py:511
Global3DVector GlobalVector
Definition: GlobalVector.h:10
edm::ESGetToken< CaloTPGTranscoder, CaloTPGRecord > decoderTag_
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Candidate.h:38

Member Data Documentation

◆ calib_

l1tp2::ParametricCalibration L1EGCrystalClusterEmulatorProducer::calib_
private

Definition at line 282 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ caloGeometryTag_

edm::ESGetToken<CaloGeometry, CaloGeometryRecord> L1EGCrystalClusterEmulatorProducer::caloGeometryTag_
private

Definition at line 284 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ decoderTag_

edm::ESGetToken<CaloTPGTranscoder, CaloTPGRecord> L1EGCrystalClusterEmulatorProducer::decoderTag_
private

Definition at line 280 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ ebGeometry

const CaloSubdetectorGeometry* L1EGCrystalClusterEmulatorProducer::ebGeometry
private

Definition at line 285 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ ecalTPEBToken_

edm::EDGetTokenT<EcalEBTrigPrimDigiCollection> L1EGCrystalClusterEmulatorProducer::ecalTPEBToken_
private

Definition at line 278 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ hbGeometry

const CaloSubdetectorGeometry* L1EGCrystalClusterEmulatorProducer::hbGeometry
private

Definition at line 286 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ hbTopologyTag_

edm::ESGetToken<HcalTopology, HcalRecNumberingRecord> L1EGCrystalClusterEmulatorProducer::hbTopologyTag_
private

Definition at line 287 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ hcalTPToken_

edm::EDGetTokenT<edm::SortedCollection<HcalTriggerPrimitiveDigi> > L1EGCrystalClusterEmulatorProducer::hcalTPToken_
private

Definition at line 279 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().

◆ hcTopology_

const HcalTopology* L1EGCrystalClusterEmulatorProducer::hcTopology_
private

Definition at line 288 of file L1EGammaCrystalsEmulatorProducer.cc.

Referenced by produce().