CMS 3D CMS Logo

L1EGammaCrystalsEmulatorProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1CaloTrigger
4 // Class: L1EGammaCrystalsEmulatorProducer
5 //
11 //
12 // Original Author: Cecile Caillol
13 // Created: Tue Aug 10 2018
14 //
15 // $Id$
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 #include <array>
22 #include <iostream>
23 #include <cmath>
24 
25 // user include files
30 
39 
40 // ECAL TPs
42 
43 // HCAL TPs
45 
46 // Output tower collection
50 
54 
55 static constexpr bool do_brem = true;
56 
57 static constexpr int n_eta_bins = 2;
58 static constexpr int n_borders_phi = 18;
59 static constexpr int n_borders_eta = 18;
60 static constexpr int n_clusters_max = 5;
61 static constexpr int n_clusters_link = 3;
62 static constexpr int n_clusters_4link = 4 * 3;
63 static constexpr int n_crystals_towerEta = 5;
64 static constexpr int n_crystals_towerPhi = 5;
65 static constexpr int n_crystals_3towers = 3 * 5;
66 static constexpr int n_crystals_2towers = 2 * 5;
67 static constexpr int n_towers_per_link = 17;
68 static constexpr int n_clusters_per_link = 2;
69 static constexpr int n_clusters_per_L1card = 8;
70 static constexpr int n_towers_Eta = 34;
71 static constexpr int n_towers_Phi = 72;
72 static constexpr int n_towers_halfPhi = 36;
73 static constexpr int n_links_card = 4;
74 static constexpr int n_links_GCTcard = 48;
75 static constexpr int n_GCTcards = 3;
76 static constexpr float ECAL_eta_range = 1.4841;
77 static constexpr float half_crystal_size = 0.00873;
78 static constexpr float slideIsoPtThreshold = 80;
79 static constexpr float plateau_ss = 130.0;
80 static constexpr float a0_80 = 0.85, a1_80 = 0.0080, a0 = 0.21; // passes_iso
81 static constexpr float b0 = 0.38, b1 = 1.9, b2 = 0.05; //passes_looseTkiso
82 static constexpr float c0_ss = 0.94, c1_ss = 0.052, c2_ss = 0.044; //passes_ss
83 static constexpr float d0 = 0.96, d1 = 0.0003; //passes_photon
84 static constexpr float e0_looseTkss = 0.944, e1_looseTkss = 0.65, e2_looseTkss = 0.4; //passes_looseTkss
85 static constexpr float cut_500_MeV = 0.5;
86 
87 // absolue IDs range from 0-33
88 // 0-16 are iEta -17 to -1
89 // 17 to 33 are iEta 1 to 17
90 static constexpr int toweriEta_fromAbsoluteID_shift = 16;
91 
92 // absolue IDs range from 0-71.
93 // To align with detector tower IDs (1 - n_towers_Phi)
94 // shift all indices by 37 and loop over after 72
95 static constexpr int toweriPhi_fromAbsoluteID_shift_lowerHalf = 37;
96 static constexpr int toweriPhi_fromAbsoluteID_shift_upperHalf = 35;
97 
98 float getEta_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) {
99  int etaID = n_crystals_towerEta * (n_towers_per_link * ((link / n_links_card) % 2) + (tower % n_towers_per_link)) +
100  crystal % n_crystals_towerEta;
101  float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta);
102  return etaID * size_cell - ECAL_eta_range + half_crystal_size;
103 }
104 
105 float getPhi_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) {
106  int phiID = n_crystals_towerPhi * ((card * 24) + (n_links_card * (link / 8)) + (tower / n_towers_per_link)) +
107  crystal / n_crystals_towerPhi;
108  float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi);
109  return phiID * size_cell - M_PI + half_crystal_size;
110 }
111 
112 int getCrystal_etaID(float eta) {
113  float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta);
114  int etaID = int((eta + ECAL_eta_range) / size_cell);
115  return etaID;
116 }
117 
118 int convert_L2toL1_link(int link) { return link % n_links_card; }
119 
120 int convert_L2toL1_tower(int tower) { return tower; }
121 
122 int convert_L2toL1_card(int card, int link) { return card * n_clusters_4link + link / n_links_card; }
123 
124 int getCrystal_phiID(float phi) {
125  float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi);
126  int phiID = int((phi + M_PI) / size_cell);
127  return phiID;
128 }
129 
131  float size_cell = 2 * ECAL_eta_range / n_towers_Eta;
132  int etaID = int((eta + ECAL_eta_range) / size_cell);
133  return etaID;
134 }
135 
137  float size_cell = 2 * M_PI / n_towers_Phi;
138  int phiID = int((phi + M_PI) / size_cell);
139  return phiID;
140 }
141 
143  if (id < n_towers_per_link)
144  return id - n_towers_per_link;
145  else
146  return id - toweriEta_fromAbsoluteID_shift;
147 }
148 
150  if (id < n_towers_Phi / 2)
152  else
154 }
155 
157  float size_cell = 2 * ECAL_eta_range / n_towers_Eta;
158  float eta = (id * size_cell) - ECAL_eta_range + 0.5 * size_cell;
159  return eta;
160 }
161 
163  float size_cell = 2 * M_PI / n_towers_Phi;
164  float phi = (id * size_cell) - M_PI + 0.5 * size_cell;
165  return phi;
166 }
167 
168 int getCrystalIDInTower(int etaID, int phiID) {
169  return int(n_crystals_towerPhi * (phiID % n_crystals_towerPhi) + (etaID % n_crystals_towerEta));
170 }
171 
172 int get_towerEta_fromCardTowerInCard(int card, int towerincard) {
173  return n_towers_per_link * (card % 2) + towerincard % n_towers_per_link;
174 }
175 
176 int get_towerPhi_fromCardTowerInCard(int card, int towerincard) {
177  return 4 * (card / 2) + towerincard / n_towers_per_link;
178 }
179 
180 int get_towerEta_fromCardLinkTower(int card, int link, int tower) { return n_towers_per_link * (card % 2) + tower; }
181 
182 int get_towerPhi_fromCardLinkTower(int card, int link, int tower) { return 4 * (card / 2) + link; }
183 
184 int getTowerID(int etaID, int phiID) {
185  return int(n_towers_per_link * ((phiID / n_crystals_towerPhi) % 4) +
187 }
188 
189 int getTower_phiID(int cluster_phiID) { // Tower ID in card given crystal ID in total detector
190  return int((cluster_phiID / n_crystals_towerPhi) % 4);
191 }
192 
193 int getTower_etaID(int cluster_etaID) { // Tower ID in card given crystal ID in total detector
194  return int((cluster_etaID / n_crystals_towerEta) % n_towers_per_link);
195 }
196 
197 int getEtaMax_card(int card) {
198  int etamax = 0;
199  if (card % 2 == 0)
200  etamax = n_towers_per_link * n_crystals_towerEta - 1; // First eta half. 5 crystals in eta in 1 tower.
201  else
203  return etamax;
204 }
205 
206 int getEtaMin_card(int card) {
207  int etamin = 0;
208  if (card % 2 == 0)
209  etamin = 0 * n_crystals_towerEta; // First eta half. 5 crystals in eta in 1 tower.
210  else
212  return etamin;
213 }
214 
215 int getPhiMax_card(int card) {
216  int phimax = ((card / 2) + 1) * 4 * n_crystals_towerPhi - 1;
217  return phimax;
218 }
219 
220 int getPhiMin_card(int card) {
221  int phimin = (card / 2) * 4 * n_crystals_towerPhi;
222  return phimin;
223 }
224 
225 /*
226  * Replace in-line region boundary arithmetic with function that accounts for region 0 in negative eta cards
227  * In the indexing convention of the old emulator, region 0 is the region overlapping with the endcap, and is
228  * only two towers wide in eta.
229  */
230 int getEtaMin_region(int card, int nregion) {
231  // Special handling for negative-eta cards
232  if (card % 2 == 0) {
233  if (nregion == 0) {
234  return getEtaMin_card(card);
235  } else {
236  return getEtaMin_card(card) + n_crystals_2towers + n_crystals_3towers * (nregion - 1);
237  }
238  }
239  // Positive-eta cards: same as original in-line arithmetic
240  else {
241  return getEtaMin_card(card) + n_crystals_3towers * nregion;
242  }
243 }
244 
245 /*
246  * Replace in-line region boundary arithmetic that accounts for region 0 in negative eta cards.
247  * Same as above but for max eta of the region.
248  */
249 int getEtaMax_region(int card, int nregion) {
250  // Special handling for negative-eta cards
251  if (card % 2 == 0) {
252  if (nregion == 0) {
253  return getEtaMin_card(card) + n_crystals_2towers;
254  } else {
255  return getEtaMin_card(card) + n_crystals_2towers + (n_crystals_3towers * nregion);
256  }
257  }
258  // Positive-eta cards: same as original in-line arithmetic
259  else {
260  return getEtaMin_card(card) + n_crystals_3towers * (nregion + 1);
261  }
262 }
263 
265 public:
268 
269 private:
270  void produce(edm::Event&, const edm::EventSetup&) override;
271  bool passes_ss(float pt, float ss);
272  bool passes_photon(float pt, float pss);
273  bool passes_iso(float pt, float iso);
274  bool passes_looseTkss(float pt, float ss);
275  bool passes_looseTkiso(float pt, float iso);
276  float get_calibrate(float uncorr);
277 
281 
283 
289 
290  struct mycluster {
291  float c2x2_;
292  float c2x5_;
293  float c5x5_;
298  float cpt; // ECAL pt
299  int cbrem_; // if brem corrections were applied
302  float ciso_; // pt of cluster divided by 7x7 ECAL towers
303  float crawIso_; // raw isolation sum
304  float chovere_; // 5x5 HCAL towers divided by the ECAL cluster pt
305  float craweta_; // coordinates between -1.44 and 1.44
306  float crawphi_; // coordinates between -pi and pi
307  float chcal_; // 5x5 HCAL towers
308  float ceta_; // eta ID in the whole detector (between 0 and 5*34-1)
309  float cphi_; // phi ID in the whole detector (between 0 and 5*72-1)
310  int ccrystalid_; // crystal ID inside tower (between 0 and 24)
312  int ctowerid_; // tower ID inside card (between 0 and 4*n_towers_per_link-1)
313  };
314 
316  private:
317  float pt_ = 0;
318  float energy_ = 0.;
319  bool isEndcapHit_ = false; // If using endcap, we won't be using integer crystal indices
320  bool stale_ = false; // Hits become stale once used in clustering algorithm to prevent overlap in clusters
321  bool used_ = false;
322  GlobalVector position_; // As opposed to GlobalPoint, so we can add them (for weighted average)
325 
326  public:
327  // tool functions
328  inline void setPt() { pt_ = (position_.mag2() > 0) ? energy_ * sin(position_.theta()) : 0; };
329  inline void setEnergy(float et) { energy_ = et / sin(position_.theta()); };
330  inline void setIsEndcapHit(bool isEC) { isEndcapHit_ = isEC; };
331  inline void setUsed(bool isUsed) { used_ = isUsed; };
332  inline void setPosition(const GlobalVector& pos) { position_ = pos; };
333  inline void setIdHcal(const HcalDetId& idhcal) { id_hcal_ = idhcal; };
334  inline void setId(const EBDetId& id) { id_ = id; };
335 
336  inline float pt() const { return pt_; };
337  inline float energy() const { return energy_; };
338  inline bool isEndcapHit() const { return isEndcapHit_; };
339  inline bool used() const { return used_; };
340  inline const GlobalVector& position() const { return position_; };
341  inline const EBDetId& id() const { return id_; };
342 
343  /*
344  * Check if it falls within the boundary of a card.
345  */
346  bool isInCard(int cc) const {
347  return (getCrystal_phiID(position().phi()) <= getPhiMax_card(cc) &&
351  };
352 
353  /*
354  * Check if it falls within the boundary card AND a region in the card.
355  */
356  bool isInCardAndRegion(int cc, int nregion) const {
357  bool isInRegionEta = (getCrystal_etaID(position().eta()) < getEtaMax_region(cc, nregion) &&
358  getCrystal_etaID(position().eta()) >= getEtaMin_region(cc, nregion));
359  return (isInCard(cc) && isInRegionEta);
360  }
361 
362  // Comparison functions with other SimpleCaloHit instances
363  inline float deta(SimpleCaloHit& other) const { return position_.eta() - other.position().eta(); };
364  int dieta(SimpleCaloHit& other) const {
365  if (isEndcapHit_ || other.isEndcapHit())
366  return 9999; // We shouldn't compare integer indices in endcap, the map is not linear
367  if (id_.ieta() * other.id().ieta() > 0)
368  return id_.ieta() - other.id().ieta();
369  return id_.ieta() - other.id().ieta() - 1;
370  };
371  inline float dphi(SimpleCaloHit& other) const {
372  return reco::deltaPhi(static_cast<float>(position_.phi()), static_cast<float>(other.position().phi()));
373  };
374  int diphi(SimpleCaloHit& other) const {
375  if (isEndcapHit_ || other.isEndcapHit())
376  return 9999; // We shouldn't compare integer indices in endcap, the map is not linear
377  // Logic from EBDetId::distancePhi() without the abs()
378  static constexpr int PI = 180;
379  int result = id().iphi() - other.id().iphi();
380  while (result > PI)
381  result -= 2 * PI;
382  while (result <= -PI)
383  result += 2 * PI;
384  return result;
385  };
387  return (getCrystal_etaID(position_.eta()) - getCrystal_etaID(other.position().eta()));
388  };
390  return (getCrystal_phiID(position_.phi()) - getCrystal_phiID(other.position().phi()));
391  };
392  int id_iEta() { return id_.ieta(); }
393  int id_iPhi() { return id_.iphi(); }
395  // Treat position as a point, measure 3D distance
396  // This is used for endcap hits, where we don't have a rectangular mapping
397  return (position() - other.position()).mag();
398  };
400  return (id_ == other.id() && position() == other.position() && energy_ == other.energy() &&
401  isEndcapHit_ == other.isEndcapHit());
402  };
403  };
404 };
405 
407  : ecalTPEBToken_(consumes<EcalEBTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalTPEB"))),
408  hcalTPToken_(
409  consumes<edm::SortedCollection<HcalTriggerPrimitiveDigi> >(iConfig.getParameter<edm::InputTag>("hcalTP"))),
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 }
418 
420 
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 }
1206 
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 
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 
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 
1236  bool is_ss = (pss > d0 - d1 * pt);
1237  if (pt > plateau_ss)
1238  is_ss = true;
1239  return is_ss;
1240 }
1241 
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 //define this as a plug-in
size
Write out results.
static float towerEta(int ieta)
Definition: CaloTools.cc:201
static constexpr int n_links_GCTcard
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
bool validHT(const HcalTrigTowerDetId &id) const
int getCrystal_etaID(float eta)
static constexpr float e2_looseTkss
edm::EDGetTokenT< edm::SortedCollection< HcalTriggerPrimitiveDigi > > hcalTPToken_
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
int getCrystal_phiID(float phi)
int getTower_phiID(int cluster_phiID)
std::pair< ALIstring, ALIstring > pss
Definition: Fit.h:25
static constexpr int toweriEta_fromAbsoluteID_shift
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 toweriPhi_fromAbsoluteID_shift_upperHalf
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
int iphi() const
get the crystal iphi
Definition: EBDetId.h:51
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
T eta() const
Definition: PV3DBase.h:73
static constexpr float ECAL_eta_range
static constexpr float c2_ss
void setTowerIPhi(int iPhi)
Definition: CaloTower.h:51
T const * product() const
Definition: Handle.h:70
static constexpr int n_crystals_2towers
void setL1egStandaloneIso(int staIso)
Definition: CaloTower.h:60
int get_towerEta_fromCardTowerInCard(int card, int towerincard)
int getPhiMax_card(int card)
int getTowerID(int etaID, int phiID)
constexpr int pow(int x)
Definition: conifer.h:24
int get_towerPhi_fromCardLinkTower(int card, int link, int tower)
float get_calibrate(float uncorr)
static constexpr int n_eta_bins
Log< level::Error, false > LogError
int convert_L2toL1_card(int card, int link)
T mag2() const
Definition: PV3DBase.h:63
static constexpr int n_borders_eta
static constexpr float a1_80
int getEtaMin_card(int card)
void setL1egTrkIso(int trkIso)
Definition: CaloTower.h:58
void produce(edm::Event &, const edm::EventSetup &) override
static constexpr int toweriPhi_fromAbsoluteID_shift_lowerHalf
static constexpr int n_clusters_max
float getTowerEta_fromAbsoluteID(int id)
static constexpr int n_crystals_towerPhi
int ieta() const
get the crystal ieta
Definition: EBDetId.h:49
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
L1EGCrystalClusterEmulatorProducer(const edm::ParameterSet &)
std::vector< HcalDetId > detIds(const HcalTrigTowerDetId &) const
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 float a0_80
static constexpr bool do_brem
int getEtaMax_region(int card, int nregion)
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
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static constexpr int n_towers_per_link
void setL1egTrkSS(int trkSS)
Definition: CaloTower.h:57
edm::EDGetTokenT< EcalEBTrigPrimDigiCollection > ecalTPEBToken_
static constexpr float plateau_ss
static constexpr int n_clusters_link
#define PI
Definition: QcdUeDQM.h:37
void setIsBarrel(bool isBarrel)
Definition: CaloTower.h:61
static constexpr float half_crystal_size
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
static constexpr float c1_ss
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_crystals_3towers
int getEtaMax_card(int card)
static constexpr int n_links_card
static constexpr float d0
int getTower_etaID(int cluster_etaID)
T mag() const
The vector magnitude. Equivalent to sqrt(vec.mag2())
int convert_L2toL1_link(int link)
float towerPhi() const
Definition: CaloTower.h:39
static constexpr float slideIsoPtThreshold
static constexpr float a0
static constexpr float e0_looseTkss
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
int getEtaMin_region(int card, int nregion)
static constexpr float b2
float towerEta() const
Definition: CaloTower.h:40
static constexpr float b0
float getPhi_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal)
static constexpr float d1
int getCrystalIDInTower(int etaID, int phiID)
static constexpr int n_towers_Eta
static constexpr float c0_ss
void setL1egStandaloneSS(int staSS)
Definition: CaloTower.h:59
def move(src, dest)
Definition: eostools.py:511
static constexpr float b1
Global3DVector GlobalVector
Definition: GlobalVector.h:10
static constexpr float e1_looseTkss
Geom::Theta< T > theta() const
Definition: PV3DBase.h:72
edm::ESGetToken< CaloTPGTranscoder, CaloTPGRecord > decoderTag_
math::PtEtaPhiMLorentzVector PolarLorentzVector
Lorentz vector.
Definition: Candidate.h:38