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_towers_per_link = 17;
67 static constexpr int n_clusters_per_link = 2;
68 static constexpr int n_clusters_per_L1card = 8;
69 static constexpr int n_towers_Eta = 34;
70 static constexpr int n_towers_Phi = 72;
71 static constexpr int n_towers_halfPhi = 36;
72 static constexpr int n_links_card = 4;
73 static constexpr int n_links_GCTcard = 48;
74 static constexpr int n_GCTcards = 3;
75 static constexpr float ECAL_eta_range = 1.4841;
76 static constexpr float half_crystal_size = 0.00873;
77 static constexpr float slideIsoPtThreshold = 80;
78 static constexpr float plateau_ss = 130.0;
79 static constexpr float a0_80 = 0.85, a1_80 = 0.0080, a0 = 0.21; // passes_iso
80 static constexpr float b0 = 0.38, b1 = 1.9, b2 = 0.05; //passes_looseTkiso
81 static constexpr float c0_ss = 0.94, c1_ss = 0.052, c2_ss = 0.044; //passes_ss
82 static constexpr float d0 = 0.96, d1 = 0.0003; //passes_photon
83 static constexpr float e0_looseTkss = 0.944, e1_looseTkss = 0.65, e2_looseTkss = 0.4; //passes_looseTkss
84 static constexpr float cut_500_MeV = 0.5;
85 
86 // absolue IDs range from 0-33
87 // 0-16 are iEta -17 to -1
88 // 17 to 33 are iEta 1 to 17
89 static constexpr int toweriEta_fromAbsoluteID_shift = 16;
90 
91 // absolue IDs range from 0-71.
92 // To align with detector tower IDs (1 - n_towers_Phi)
93 // shift all indices by 37 and loop over after 72
94 static constexpr int toweriPhi_fromAbsoluteID_shift_lowerHalf = 37;
95 static constexpr int toweriPhi_fromAbsoluteID_shift_upperHalf = 35;
96 
97 float getEta_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) {
98  int etaID = n_crystals_towerEta * (n_towers_per_link * ((link / n_links_card) % 2) + (tower % n_towers_per_link)) +
99  crystal % n_crystals_towerEta;
100  float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta);
101  return etaID * size_cell - ECAL_eta_range + half_crystal_size;
102 }
103 
104 float getPhi_fromL2LinkCardTowerCrystal(int link, int card, int tower, int crystal) {
105  int phiID = n_crystals_towerPhi * ((card * 24) + (n_links_card * (link / 8)) + (tower / n_towers_per_link)) +
106  crystal / n_crystals_towerPhi;
107  float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi);
108  return phiID * size_cell - M_PI + half_crystal_size;
109 }
110 
111 int getCrystal_etaID(float eta) {
112  float size_cell = 2 * ECAL_eta_range / (n_crystals_towerEta * n_towers_Eta);
113  int etaID = int((eta + ECAL_eta_range) / size_cell);
114  return etaID;
115 }
116 
117 int convert_L2toL1_link(int link) { return link % n_links_card; }
118 
119 int convert_L2toL1_tower(int tower) { return tower; }
120 
121 int convert_L2toL1_card(int card, int link) { return card * n_clusters_4link + link / n_links_card; }
122 
123 int getCrystal_phiID(float phi) {
124  float size_cell = 2 * M_PI / (n_crystals_towerPhi * n_towers_Phi);
125  int phiID = int((phi + M_PI) / size_cell);
126  return phiID;
127 }
128 
130  float size_cell = 2 * ECAL_eta_range / n_towers_Eta;
131  int etaID = int((eta + ECAL_eta_range) / size_cell);
132  return etaID;
133 }
134 
136  float size_cell = 2 * M_PI / n_towers_Phi;
137  int phiID = int((phi + M_PI) / size_cell);
138  return phiID;
139 }
140 
142  if (id < n_towers_per_link)
143  return id - n_towers_per_link;
144  else
145  return id - toweriEta_fromAbsoluteID_shift;
146 }
147 
149  if (id < n_towers_Phi / 2)
151  else
153 }
154 
156  float size_cell = 2 * ECAL_eta_range / n_towers_Eta;
157  float eta = (id * size_cell) - ECAL_eta_range + 0.5 * size_cell;
158  return eta;
159 }
160 
162  float size_cell = 2 * M_PI / n_towers_Phi;
163  float phi = (id * size_cell) - M_PI + 0.5 * size_cell;
164  return phi;
165 }
166 
167 int getCrystalIDInTower(int etaID, int phiID) {
168  return int(n_crystals_towerPhi * (phiID % n_crystals_towerPhi) + (etaID % n_crystals_towerEta));
169 }
170 
171 int get_towerEta_fromCardTowerInCard(int card, int towerincard) {
172  return n_towers_per_link * (card % 2) + towerincard % n_towers_per_link;
173 }
174 
175 int get_towerPhi_fromCardTowerInCard(int card, int towerincard) {
176  return 4 * (card / 2) + towerincard / n_towers_per_link;
177 }
178 
179 int get_towerEta_fromCardLinkTower(int card, int link, int tower) { return n_towers_per_link * (card % 2) + tower; }
180 
181 int get_towerPhi_fromCardLinkTower(int card, int link, int tower) { return 4 * (card / 2) + link; }
182 
183 int getTowerID(int etaID, int phiID) {
184  return int(n_towers_per_link * ((phiID / n_crystals_towerPhi) % 4) +
186 }
187 
188 int getTower_phiID(int cluster_phiID) { // Tower ID in card given crystal ID in total detector
189  return int((cluster_phiID / n_crystals_towerPhi) % 4);
190 }
191 
192 int getTower_etaID(int cluster_etaID) { // Tower ID in card given crystal ID in total detector
193  return int((cluster_etaID / n_crystals_towerEta) % n_towers_per_link);
194 }
195 
196 int getEtaMax_card(int card) {
197  int etamax = 0;
198  if (card % 2 == 0)
199  etamax = n_towers_per_link * n_crystals_towerEta - 1; // First eta half. 5 crystals in eta in 1 tower.
200  else
202  return etamax;
203 }
204 
205 int getEtaMin_card(int card) {
206  int etamin = 0;
207  if (card % 2 == 0)
208  etamin = 0 * n_crystals_towerEta; // First eta half. 5 crystals in eta in 1 tower.
209  else
211  return etamin;
212 }
213 
214 int getPhiMax_card(int card) {
215  int phimax = ((card / 2) + 1) * 4 * n_crystals_towerPhi - 1;
216  return phimax;
217 }
218 
219 int getPhiMin_card(int card) {
220  int phimin = (card / 2) * 4 * n_crystals_towerPhi;
221  return phimin;
222 }
223 
225 public:
228 
229 private:
230  void produce(edm::Event&, const edm::EventSetup&) override;
231  bool passes_ss(float pt, float ss);
232  bool passes_photon(float pt, float pss);
233  bool passes_iso(float pt, float iso);
234  bool passes_looseTkss(float pt, float ss);
235  bool passes_looseTkiso(float pt, float iso);
236  float get_calibrate(float uncorr);
237 
241 
243 
249 
250  struct mycluster {
251  float c2x2_;
252  float c2x5_;
253  float c5x5_;
258  float cpt; // ECAL pt
259  int cbrem_; // if brem corrections were applied
262  float ciso_; // pt of cluster divided by 7x7 ECAL towers
263  float chovere_; // 5x5 HCAL towers divided by the ECAL cluster pt
264  float craweta_; // coordinates between -1.44 and 1.44
265  float crawphi_; // coordinates between -pi and pi
266  float chcal_; // 5x5 HCAL towers
267  float ceta_; // eta ID in the whole detector (between 0 and 5*34-1)
268  float cphi_; // phi ID in the whole detector (between 0 and 5*72-1)
269  int ccrystalid_; // crystal ID inside tower (between 0 and 24)
271  int ctowerid_; // tower ID inside card (between 0 and 4*n_towers_per_link-1)
272  };
273 
275  private:
276  float pt_ = 0;
277  float energy_ = 0.;
278  bool isEndcapHit_ = false; // If using endcap, we won't be using integer crystal indices
279  bool stale_ = false; // Hits become stale once used in clustering algorithm to prevent overlap in clusters
280  bool used_ = false;
281  GlobalVector position_; // As opposed to GlobalPoint, so we can add them (for weighted average)
284 
285  public:
286  // tool functions
287  inline void setPt() { pt_ = (position_.mag2() > 0) ? energy_ * sin(position_.theta()) : 0; };
288  inline void setEnergy(float et) { energy_ = et / sin(position_.theta()); };
289  inline void setIsEndcapHit(bool isEC) { isEndcapHit_ = isEC; };
290  inline void setUsed(bool isUsed) { used_ = isUsed; };
291  inline void setPosition(const GlobalVector& pos) { position_ = pos; };
292  inline void setIdHcal(const HcalDetId& idhcal) { id_hcal_ = idhcal; };
293  inline void setId(const EBDetId& id) { id_ = id; };
294 
295  inline float pt() const { return pt_; };
296  inline float energy() const { return energy_; };
297  inline bool isEndcapHit() const { return isEndcapHit_; };
298  inline bool used() const { return used_; };
299  inline const GlobalVector& position() const { return position_; };
300  inline const EBDetId& id() const { return id_; };
301 
302  inline float deta(SimpleCaloHit& other) const { return position_.eta() - other.position().eta(); };
303  int dieta(SimpleCaloHit& other) const {
304  if (isEndcapHit_ || other.isEndcapHit())
305  return 9999; // We shouldn't compare integer indices in endcap, the map is not linear
306  if (id_.ieta() * other.id().ieta() > 0)
307  return id_.ieta() - other.id().ieta();
308  return id_.ieta() - other.id().ieta() - 1;
309  };
310  inline float dphi(SimpleCaloHit& other) const {
311  return reco::deltaPhi(static_cast<float>(position_.phi()), static_cast<float>(other.position().phi()));
312  };
313  int diphi(SimpleCaloHit& other) const {
314  if (isEndcapHit_ || other.isEndcapHit())
315  return 9999; // We shouldn't compare integer indices in endcap, the map is not linear
316  // Logic from EBDetId::distancePhi() without the abs()
317  static constexpr int PI = 180;
318  int result = id().iphi() - other.id().iphi();
319  while (result > PI)
320  result -= 2 * PI;
321  while (result <= -PI)
322  result += 2 * PI;
323  return result;
324  };
326  // Treat position as a point, measure 3D distance
327  // This is used for endcap hits, where we don't have a rectangular mapping
328  return (position() - other.position()).mag();
329  };
331  return (id_ == other.id() && position() == other.position() && energy_ == other.energy() &&
332  isEndcapHit_ == other.isEndcapHit());
333  };
334  };
335 };
336 
338  : ecalTPEBToken_(consumes<EcalEBTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalTPEB"))),
339  hcalTPToken_(
340  consumes<edm::SortedCollection<HcalTriggerPrimitiveDigi> >(iConfig.getParameter<edm::InputTag>("hcalTP"))),
341  decoderTag_(esConsumes<CaloTPGTranscoder, CaloTPGRecord>(edm::ESInputTag("", ""))),
342  calib_(iConfig.getParameter<edm::ParameterSet>("calib")),
343  caloGeometryTag_(esConsumes<CaloGeometry, CaloGeometryRecord>(edm::ESInputTag("", ""))),
344  hbTopologyTag_(esConsumes<HcalTopology, HcalRecNumberingRecord>(edm::ESInputTag("", ""))) {
345  produces<l1tp2::CaloCrystalClusterCollection>();
346  produces<BXVector<l1t::EGamma> >();
347  produces<l1tp2::CaloTowerCollection>("L1CaloTowerCollection");
348 }
349 
351 
353  using namespace edm;
354 
356  iEvent.getByToken(ecalTPEBToken_, pcalohits);
357 
358  const auto& caloGeometry = iSetup.getData(caloGeometryTag_);
359  ebGeometry = caloGeometry.getSubdetectorGeometry(DetId::Ecal, EcalBarrel);
360  hbGeometry = caloGeometry.getSubdetectorGeometry(DetId::Hcal, HcalBarrel);
361  const auto& hbTopology = iSetup.getData(hbTopologyTag_);
362  hcTopology_ = &hbTopology;
363  HcalTrigTowerGeometry theTrigTowerGeometry(hcTopology_);
364 
365  const auto& decoder = iSetup.getData(decoderTag_);
366 
367  //****************************************************************
368  //******************* Get all the hits ***************************
369  //****************************************************************
370 
371  // Get all the ECAL hits
372  iEvent.getByToken(ecalTPEBToken_, pcalohits);
373  std::vector<SimpleCaloHit> ecalhits;
374 
375  for (const auto& hit : *pcalohits.product()) {
376  if (hit.encodedEt() > 0) // hit.encodedEt() returns an int corresponding to 2x the crystal Et
377  {
378  // Et is 10 bit, by keeping the ADC saturation Et at 120 GeV it means that you have to divide by 8
379  float et = hit.encodedEt() / 8.;
380  if (et < cut_500_MeV)
381  continue; // keep the 500 MeV ET Cut
382 
383  auto cell = ebGeometry->getGeometry(hit.id());
384 
385  SimpleCaloHit ehit;
386  ehit.setId(hit.id());
387  ehit.setPosition(GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z()));
388  ehit.setEnergy(et);
389  ehit.setPt();
390  ecalhits.push_back(ehit);
391  }
392  }
393 
394  // Get all the HCAL hits
395  std::vector<SimpleCaloHit> hcalhits;
397  iEvent.getByToken(hcalTPToken_, hbhecoll);
398  for (const auto& hit : *hbhecoll.product()) {
399  float et = decoder.hcaletValue(hit.id(), hit.t0());
400  if (et <= 0)
401  continue;
402  if (!(hcTopology_->validHT(hit.id()))) {
403  LogError("L1EGCrystalClusterEmulatorProducer")
404  << " -- Hcal hit DetID not present in HCAL Geom: " << hit.id() << std::endl;
405  throw cms::Exception("L1EGCrystalClusterEmulatorProducer");
406  continue;
407  }
408  const std::vector<HcalDetId>& hcId = theTrigTowerGeometry.detIds(hit.id());
409  if (hcId.empty()) {
410  LogError("L1EGCrystalClusterEmulatorProducer")
411  << "Cannot find any HCalDetId corresponding to " << hit.id() << std::endl;
412  throw cms::Exception("L1EGCrystalClusterEmulatorProducer");
413  continue;
414  }
415  if (hcId[0].subdetId() > 1)
416  continue;
417  GlobalVector hcal_tp_position = GlobalVector(0., 0., 0.);
418  for (const auto& hcId_i : hcId) {
419  if (hcId_i.subdetId() > 1)
420  continue;
421  auto cell = hbGeometry->getGeometry(hcId_i);
422  if (cell == nullptr)
423  continue;
424  GlobalVector tmpVector = GlobalVector(cell->getPosition().x(), cell->getPosition().y(), cell->getPosition().z());
425  hcal_tp_position = tmpVector;
426  break;
427  }
428  SimpleCaloHit hhit;
429  hhit.setId(hit.id());
430  hhit.setIdHcal(hit.id());
431  hhit.setPosition(hcal_tp_position);
432  hhit.setEnergy(et);
433  hhit.setPt();
434  hcalhits.push_back(hhit);
435  }
436 
437  //*******************************************************************
438  //********************** Do layer 1 *********************************
439  //*******************************************************************
440 
441  // Definition of L1 outputs
442  // 36 L1 cards send each 4 links with 17 towers
443  float ECAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
444  float HCAL_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
445  int iEta_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
446  int iPhi_tower_L1Card[n_links_card][n_towers_per_link][n_towers_halfPhi];
447  // 36 L1 cards send each 4 links with 3 clusters
448  float energy_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
449  // 36 L1 cards send each 4 links with 3 clusters
450  int brem_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
451  int towerID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
452  int crystalID_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
453  int showerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
454  int showerShapeLooseTk_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
455  int photonShowerShape_cluster_L1Card[n_links_card][n_clusters_link][n_towers_halfPhi];
456 
457  for (int ii = 0; ii < n_links_card; ++ii) {
458  for (int jj = 0; jj < n_towers_per_link; ++jj) {
459  for (int ll = 0; ll < n_towers_halfPhi; ++ll) {
460  ECAL_tower_L1Card[ii][jj][ll] = 0;
461  HCAL_tower_L1Card[ii][jj][ll] = 0;
462  iPhi_tower_L1Card[ii][jj][ll] = -999;
463  iEta_tower_L1Card[ii][jj][ll] = -999;
464  }
465  }
466  }
467  for (int ii = 0; ii < n_links_card; ++ii) {
468  for (int jj = 0; jj < n_clusters_link; ++jj) {
469  for (int ll = 0; ll < n_towers_halfPhi; ++ll) {
470  energy_cluster_L1Card[ii][jj][ll] = 0;
471  brem_cluster_L1Card[ii][jj][ll] = 0;
472  towerID_cluster_L1Card[ii][jj][ll] = 0;
473  crystalID_cluster_L1Card[ii][jj][ll] = 0;
474  }
475  }
476  }
477 
478  // There is one list of clusters per card. We take the 12 highest pt per card
479  vector<mycluster> cluster_list[n_towers_halfPhi];
480  // After merging the clusters in different regions of a single L1 card
481  vector<mycluster> cluster_list_merged[n_towers_halfPhi];
482 
483  for (int cc = 0; cc < n_towers_halfPhi; ++cc) { // Loop over 36 L1 cards
484  // Loop over 3x4 etaxphi regions to search for max 5 clusters
485  for (int nregion = 0; nregion <= n_clusters_max; ++nregion) {
486  int nclusters = 0;
487  bool build_cluster = true;
488 
489  // Continue until 5 clusters have been built or there is no cluster left
490  while (nclusters < n_clusters_max && build_cluster) {
491  build_cluster = false;
492  SimpleCaloHit centerhit;
493 
494  for (const auto& hit : ecalhits) {
495  if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) &&
496  getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) &&
497  getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) &&
498  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) &&
499  // Check that the hit is in the good card
500  getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) &&
501  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion &&
502  !hit.used() && hit.pt() >= 1.0 && hit.pt() > centerhit.pt()) // 3 towers x 5 crystals
503  {
504  // Highest hit in good region with pt>1 and not used in any other cluster
505  centerhit = hit;
506  build_cluster = true;
507  }
508  }
509  if (build_cluster)
510  nclusters++;
511 
512  // Use only the 5 most energetic clusters
513  if (build_cluster && nclusters > 0 && nclusters <= n_clusters_max) {
514  mycluster mc1;
515  mc1.cpt = 0.0;
516  mc1.cWeightedEta_ = 0.0;
517  mc1.cWeightedPhi_ = 0.0;
518  float leftlobe = 0;
519  float rightlobe = 0;
520  float e5x5 = 0;
521  float n5x5 = 0;
522  float e2x5_1 = 0;
523  float n2x5_1 = 0;
524  float e2x5_2 = 0;
525  float n2x5_2 = 0;
526  float e2x2_1 = 0;
527  float n2x2_1 = 0;
528  float e2x2_2 = 0;
529  float n2x2_2 = 0;
530  float e2x2_3 = 0;
531  float n2x2_3 = 0;
532  float e2x2_4 = 0;
533  float n2x2_4 = 0;
534  for (auto& hit : ecalhits) {
535  if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) &&
536  getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) &&
537  getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) &&
538  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0 &&
539  getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) &&
540  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion) {
541  if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) {
542  rightlobe += hit.pt();
543  }
544  if (abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) {
545  leftlobe += hit.pt();
546  }
547  if (abs(hit.dieta(centerhit)) <= 2 && abs(hit.diphi(centerhit)) <= 2) {
548  e5x5 += hit.energy();
549  n5x5++;
550  }
551  if ((hit.dieta(centerhit) == 1 or hit.dieta(centerhit) == 0) &&
552  (hit.diphi(centerhit) == 1 or hit.diphi(centerhit) == 0)) {
553  e2x2_1 += hit.energy();
554  n2x2_1++;
555  }
556  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) &&
557  (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == 1)) {
558  e2x2_2 += hit.energy();
559  n2x2_2++;
560  }
561  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) &&
562  (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) {
563  e2x2_3 += hit.energy();
564  n2x2_3++;
565  }
566  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) &&
567  (hit.diphi(centerhit) == 0 or hit.diphi(centerhit) == -1)) {
568  e2x2_4 += hit.energy();
569  n2x2_4++;
570  }
571  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == 1) && abs(hit.diphi(centerhit)) <= 2) {
572  e2x5_1 += hit.energy();
573  n2x5_1++;
574  }
575  if ((hit.dieta(centerhit) == 0 or hit.dieta(centerhit) == -1) && abs(hit.diphi(centerhit)) <= 2) {
576  e2x5_2 += hit.energy();
577  n2x5_2++;
578  }
579  }
580  if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) &&
581  getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) &&
582  getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) &&
583  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && !hit.used() && hit.pt() > 0 &&
584  abs(hit.dieta(centerhit)) <= 1 && abs(hit.diphi(centerhit)) <= 2 &&
585  getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) &&
586  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion) {
587  // clusters 3x5 in etaxphi using only the hits in the corresponding card and in the corresponding 3x4 region
588  hit.setUsed(true);
589  mc1.cpt += hit.pt();
590  mc1.cWeightedEta_ += float(hit.pt()) * float(hit.position().eta());
591  mc1.cWeightedPhi_ = mc1.cWeightedPhi_ + (float(hit.pt()) * float(hit.position().phi()));
592  }
593  }
594  if (do_brem && (rightlobe > 0.10 * mc1.cpt or leftlobe > 0.10 * mc1.cpt)) {
595  for (auto& hit : ecalhits) {
596  if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) &&
597  getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) &&
598  getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) &&
599  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0 &&
600  getCrystal_etaID(hit.position().eta()) < getEtaMin_card(cc) + n_crystals_3towers * (nregion + 1) &&
601  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) + n_crystals_3towers * nregion &&
602  !hit.used()) {
603  if (rightlobe > 0.10 * mc1.cpt && (leftlobe < 0.10 * mc1.cpt or rightlobe > leftlobe) &&
604  abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) > 2 && hit.diphi(centerhit) <= 7) {
605  mc1.cpt += hit.pt();
606  hit.setUsed(true);
607  mc1.cbrem_ = 1;
608  }
609  if (leftlobe > 0.10 * mc1.cpt && (rightlobe < 0.10 * mc1.cpt or leftlobe >= rightlobe) &&
610  abs(hit.dieta(centerhit)) <= 1 && hit.diphi(centerhit) < -2 && hit.diphi(centerhit) >= -7) {
611  mc1.cpt += hit.pt();
612  hit.setUsed(true);
613  mc1.cbrem_ = 1;
614  }
615  }
616  }
617  }
618  mc1.c5x5_ = e5x5;
619  mc1.c2x5_ = max(e2x5_1, e2x5_2);
620  mc1.c2x2_ = e2x2_1;
621  if (e2x2_2 > mc1.c2x2_)
622  mc1.c2x2_ = e2x2_2;
623  if (e2x2_3 > mc1.c2x2_)
624  mc1.c2x2_ = e2x2_3;
625  if (e2x2_4 > mc1.c2x2_)
626  mc1.c2x2_ = e2x2_4;
627  mc1.cWeightedEta_ = mc1.cWeightedEta_ / mc1.cpt;
628  mc1.cWeightedPhi_ = mc1.cWeightedPhi_ / mc1.cpt;
629  mc1.ceta_ = getCrystal_etaID(centerhit.position().eta());
630  mc1.cphi_ = getCrystal_phiID(centerhit.position().phi());
631  mc1.crawphi_ = centerhit.position().phi();
632  mc1.craweta_ = centerhit.position().eta();
633  cluster_list[cc].push_back(mc1);
634  } // End if 5 clusters per region
635  } // End while to find the 5 clusters
636  } // End loop over regions to search for clusters
637  std::sort(begin(cluster_list[cc]), end(cluster_list[cc]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; });
638 
639  // Merge clusters from different regions
640  for (unsigned int jj = 0; jj < unsigned(cluster_list[cc].size()); ++jj) {
641  for (unsigned int kk = jj + 1; kk < unsigned(cluster_list[cc].size()); ++kk) {
642  if (std::abs(cluster_list[cc][jj].ceta_ - cluster_list[cc][kk].ceta_) < 2 &&
643  std::abs(cluster_list[cc][jj].cphi_ - cluster_list[cc][kk].cphi_) < 2) { //Diagonale + exact neighbors
644  if (cluster_list[cc][kk].cpt > cluster_list[cc][jj].cpt) {
645  cluster_list[cc][kk].cpt += cluster_list[cc][jj].cpt;
646  cluster_list[cc][kk].c5x5_ += cluster_list[cc][jj].c5x5_;
647  cluster_list[cc][kk].c2x5_ += cluster_list[cc][jj].c2x5_;
648  cluster_list[cc][jj].cpt = 0;
649  cluster_list[cc][jj].c5x5_ = 0;
650  cluster_list[cc][jj].c2x5_ = 0;
651  cluster_list[cc][jj].c2x2_ = 0;
652  } else {
653  cluster_list[cc][jj].cpt += cluster_list[cc][kk].cpt;
654  cluster_list[cc][jj].c5x5_ += cluster_list[cc][kk].c5x5_;
655  cluster_list[cc][jj].c2x5_ += cluster_list[cc][kk].c2x5_;
656  cluster_list[cc][kk].cpt = 0;
657  cluster_list[cc][kk].c2x2_ = 0;
658  cluster_list[cc][kk].c2x5_ = 0;
659  cluster_list[cc][kk].c5x5_ = 0;
660  }
661  }
662  }
663  if (cluster_list[cc][jj].cpt > 0) {
664  cluster_list[cc][jj].cpt =
665  cluster_list[cc][jj].cpt *
666  calib_(cluster_list[cc][jj].cpt,
667  std::abs(cluster_list[cc][jj].craweta_)); //Mark's calibration as a function of eta and pt
668  cluster_list_merged[cc].push_back(cluster_list[cc][jj]);
669  }
670  }
671  std::sort(begin(cluster_list_merged[cc]), end(cluster_list_merged[cc]), [](mycluster a, mycluster b) {
672  return a.cpt > b.cpt;
673  });
674 
675  // Fill cluster information in the arrays. We keep max 12 clusters (distributed between 4 links)
676  for (unsigned int jj = 0; jj < unsigned(cluster_list_merged[cc].size()) && jj < n_clusters_4link; ++jj) {
677  crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] =
678  getCrystalIDInTower(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_);
679  towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] =
680  getTowerID(cluster_list_merged[cc][jj].ceta_, cluster_list_merged[cc][jj].cphi_);
681  energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cpt;
682  brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = cluster_list_merged[cc][jj].cbrem_;
683  if (passes_ss(cluster_list_merged[cc][jj].cpt,
684  cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_))
685  showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
686  else
687  showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
688  if (passes_looseTkss(cluster_list_merged[cc][jj].cpt,
689  cluster_list_merged[cc][jj].c2x5_ / cluster_list_merged[cc][jj].c5x5_))
690  showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
691  else
692  showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
693  if (passes_photon(cluster_list_merged[cc][jj].cpt,
694  cluster_list_merged[cc][jj].c2x2_ / cluster_list_merged[cc][jj].c2x5_))
695  photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 1;
696  else
697  photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][cc] = 0;
698  }
699 
700  // Loop over calo ecal hits to get the ECAL towers. Take only hits that have not been used to make clusters
701  for (const auto& hit : ecalhits) {
702  if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) &&
703  getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) &&
704  getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) &&
705  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) &&
706  !hit.used()) { // Take all the hits inside the card that have not been used yet
707  for (int jj = 0; jj < n_links_card; ++jj) { // loop over 4 links per card
708  if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % 4 == jj) { // Go to ID tower modulo 4
709  for (int ii = 0; ii < n_towers_per_link; ++ii) {
710  //Apply Mark's calibration at the same time (row of the lowest pT, as a function of eta)
711  if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) {
712  ECAL_tower_L1Card[jj][ii][cc] += hit.pt() * calib_(0, std::abs(hit.position().eta()));
713  iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); //hit.id().ieta();
714  iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); //hit.id().iphi();
715  }
716  } // end of loop over eta towers
717  }
718  } // end of loop over phi links
719  // Make sure towers with 0 ET are initialized with proper iEta, iPhi coordinates
720  static constexpr float tower_width = 0.0873;
721  for (int jj = 0; jj < n_links_card; ++jj) {
722  for (int ii = 0; ii < n_towers_per_link; ++ii) {
723  float phi = getPhiMin_card(cc) * tower_width / n_crystals_towerPhi - M_PI + (jj + 0.5) * tower_width;
724  float eta = getEtaMin_card(cc) * tower_width / n_crystals_towerEta - n_towers_per_link * tower_width +
725  (ii + 0.5) * tower_width;
726  iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(eta);
727  iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(phi);
728  }
729  }
730 
731  } // end of check if inside card
732  } // end of loop over hits to build towers
733 
734  // Loop over hcal hits to get the HCAL towers.
735  for (const auto& hit : hcalhits) {
736  if (getCrystal_phiID(hit.position().phi()) <= getPhiMax_card(cc) &&
737  getCrystal_phiID(hit.position().phi()) >= getPhiMin_card(cc) &&
738  getCrystal_etaID(hit.position().eta()) <= getEtaMax_card(cc) &&
739  getCrystal_etaID(hit.position().eta()) >= getEtaMin_card(cc) && hit.pt() > 0) {
740  for (int jj = 0; jj < n_links_card; ++jj) {
741  if ((getCrystal_phiID(hit.position().phi()) / n_crystals_towerPhi) % n_links_card == jj) {
742  for (int ii = 0; ii < n_towers_per_link; ++ii) {
743  if ((getCrystal_etaID(hit.position().eta()) / n_crystals_towerEta) % n_towers_per_link == ii) {
744  HCAL_tower_L1Card[jj][ii][cc] += hit.pt();
745  iEta_tower_L1Card[jj][ii][cc] = getTower_absoluteEtaID(hit.position().eta()); //hit.id().ieta();
746  iPhi_tower_L1Card[jj][ii][cc] = getTower_absolutePhiID(hit.position().phi()); //hit.id().iphi();
747  }
748  } // end of loop over eta towers
749  }
750  } // end of loop over phi links
751  } // end of check if inside card
752  } // end of loop over hits to build towers
753 
754  // Give back energy of not used clusters to the towers (if there are more than 12 clusters)
755  for (unsigned int kk = n_clusters_4link; kk < cluster_list_merged[cc].size(); ++kk) {
756  if (cluster_list_merged[cc][kk].cpt > 0) {
757  ECAL_tower_L1Card[getTower_phiID(cluster_list_merged[cc][kk].cphi_)]
758  [getTower_etaID(cluster_list_merged[cc][kk].ceta_)][cc] += cluster_list_merged[cc][kk].cpt;
759  }
760  }
761  } //End of loop over cards
762 
763  //*********************************************************
764  //******************** Do layer 2 *************************
765  //*********************************************************
766 
767  // Definition of L2 outputs
768  float HCAL_tower_L2Card[n_links_GCTcard][n_towers_per_link]
769  [n_GCTcards]; // 3 L2 cards send each 48 links with 17 towers
770  float ECAL_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
771  int iEta_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
772  int iPhi_tower_L2Card[n_links_GCTcard][n_towers_per_link][n_GCTcards];
773  float energy_cluster_L2Card[n_links_GCTcard][n_clusters_per_link]
774  [n_GCTcards]; // 3 L2 cards send each 48 links with 2 clusters
775  float brem_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
776  int towerID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
777  int crystalID_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
778  float isolation_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
779  float HE_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
780  int showerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
781  int showerShapeLooseTk_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
782  int photonShowerShape_cluster_L2Card[n_links_GCTcard][n_clusters_per_link][n_GCTcards];
783 
784  for (int ii = 0; ii < n_links_GCTcard; ++ii) {
785  for (int jj = 0; jj < n_towers_per_link; ++jj) {
786  for (int ll = 0; ll < n_GCTcards; ++ll) {
787  HCAL_tower_L2Card[ii][jj][ll] = 0;
788  ECAL_tower_L2Card[ii][jj][ll] = 0;
789  iEta_tower_L2Card[ii][jj][ll] = 0;
790  iPhi_tower_L2Card[ii][jj][ll] = 0;
791  }
792  }
793  }
794  for (int ii = 0; ii < n_links_GCTcard; ++ii) {
795  for (int jj = 0; jj < n_clusters_per_link; ++jj) {
796  for (int ll = 0; ll < n_GCTcards; ++ll) {
797  energy_cluster_L2Card[ii][jj][ll] = 0;
798  brem_cluster_L2Card[ii][jj][ll] = 0;
799  towerID_cluster_L2Card[ii][jj][ll] = 0;
800  crystalID_cluster_L2Card[ii][jj][ll] = 0;
801  isolation_cluster_L2Card[ii][jj][ll] = 0;
802  HE_cluster_L2Card[ii][jj][ll] = 0;
803  photonShowerShape_cluster_L2Card[ii][jj][ll] = 0;
804  showerShape_cluster_L2Card[ii][jj][ll] = 0;
805  showerShapeLooseTk_cluster_L2Card[ii][jj][ll] = 0;
806  }
807  }
808  }
809 
810  // There is one list of clusters per equivalent of L1 card. We take the 8 highest pt.
811  vector<mycluster> cluster_list_L2[n_towers_halfPhi];
812 
813  // Merge clusters on the phi edges
814  for (int ii = 0; ii < n_borders_phi; ++ii) { // 18 borders in phi
815  for (int jj = 0; jj < n_eta_bins; ++jj) { // 2 eta bins
816  int card_left = 2 * ii + jj;
817  int card_right = 2 * ii + jj + 2;
818  if (card_right > 35)
819  card_right = card_right - n_towers_halfPhi;
820  for (int kk = 0; kk < n_clusters_4link; ++kk) { // 12 clusters in the first card. We check the right side
821  if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 &&
822  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 19 &&
823  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) {
824  for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the 12 clusters in the card on the right
825  if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
826  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < 5 &&
827  std::abs(
828  5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) % n_towers_per_link +
829  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 -
830  5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) % n_towers_per_link -
831  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) < 2) {
832  if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] >
833  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) {
834  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] +=
835  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right];
836  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0;
837  } // The least energetic cluster is merged to the most energetic one
838  else {
839  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] +=
840  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left];
841  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0;
842  }
843  }
844  }
845  }
846  }
847  }
848  }
849 
850  // Bremsstrahlung corrections. Merge clusters on the phi edges depending on pT (pt more than 10 percent, dphi leq 5, deta leq 1)
851  if (do_brem) {
852  for (int ii = 0; ii < n_borders_phi; ++ii) { // 18 borders in phi
853  for (int jj = 0; jj < n_eta_bins; ++jj) { // 2 eta bins
854  int card_left = 2 * ii + jj;
855  int card_right = 2 * ii + jj + 2;
856  if (card_right > 35)
857  card_right = card_right - n_towers_halfPhi;
858  // 12 clusters in the first card. We check the right side crystalID_cluster_L1Card[kk%4][kk/4][card_left]
859  for (int kk = 0; kk < n_clusters_4link; ++kk) {
860  // if the tower is at the edge there might be brem corrections, whatever the crystal ID
861  if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 50 &&
862  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] > 0) {
863  for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the 12 clusters in the card on the right
864  //Distance of 1 max in eta
865  if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
866  std::abs(5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right]) %
868  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] % 5 -
869  5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) %
871  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] % 5) <= 1) {
872  //Distance of 5 max in phi
873  if (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] < n_towers_per_link &&
874  std::abs(5 + crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] / 5 -
875  (crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] / 5)) <= 5) {
876  if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] >
877  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] &&
878  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] >
879  0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left]) {
880  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] +=
881  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right];
882  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 0;
883  brem_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 1;
884  }
885  // The least energetic cluster is merged to the most energetic one, if its pt is at least ten percent
886  else if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right] >=
887  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] &&
888  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_left] >
889  0.10 * energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_right]) {
890  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] +=
891  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left];
892  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_left] = 0;
893  brem_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_right] = 1;
894  }
895  } //max distance eta
896  } //max distance phi
897  } //max distance phi
898  }
899  }
900  }
901  }
902  }
903 
904  // Merge clusters on the eta edges
905  for (int ii = 0; ii < n_borders_eta; ++ii) { // 18 borders in eta
906  int card_bottom = 2 * ii;
907  int card_top = 2 * ii + 1;
908  for (int kk = 0; kk < n_clusters_4link; ++kk) { // 12 clusters in the first card. We check the top side
909  if (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % n_towers_per_link == 16 &&
910  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] % 5 == n_links_card &&
911  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] >
912  0) { // If there is one cluster on the right side of the first card
913  for (int ll = 0; ll < n_clusters_4link; ++ll) { // We check the card on the right
914  if (std::abs(
915  5 * (towerID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / n_towers_per_link) +
916  crystalID_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] / 5 -
917  5 * (towerID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / n_towers_per_link) -
918  crystalID_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] / 5) < 2) {
919  if (energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] >
920  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_bottom]) {
921  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] +=
922  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top];
923  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] = 0;
924  } else {
925  energy_cluster_L1Card[ll % n_links_card][ll / n_links_card][card_top] +=
926  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom];
927  energy_cluster_L1Card[kk % n_links_card][kk / n_links_card][card_bottom] = 0;
928  }
929  }
930  }
931  }
932  }
933  }
934 
935  // Regroup the new clusters per equivalent of L1 card geometry
936  for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
937  for (int jj = 0; jj < n_clusters_4link; ++jj) {
938  if (energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii] > 0) {
939  mycluster mc1;
940  mc1.cpt = energy_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
941  mc1.cbrem_ = brem_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
942  mc1.ctowerid_ = towerID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
943  mc1.ccrystalid_ = crystalID_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
944  mc1.cshowershape_ = showerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
945  mc1.cshowershapeloosetk_ = showerShapeLooseTk_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
946  mc1.cphotonshowershape_ = photonShowerShape_cluster_L1Card[jj % n_links_card][jj / n_links_card][ii];
947  cluster_list_L2[ii].push_back(mc1);
948  }
949  }
950  std::sort(
951  begin(cluster_list_L2[ii]), end(cluster_list_L2[ii]), [](mycluster a, mycluster b) { return a.cpt > b.cpt; });
952  }
953 
954  // If there are more than 8 clusters per equivalent of L1 card we need to put them back in the towers
955  for (int ii = 0; ii < n_towers_halfPhi; ++ii) {
956  for (unsigned int jj = n_clusters_per_L1card; jj < n_clusters_4link && jj < cluster_list_L2[ii].size(); ++jj) {
957  if (cluster_list_L2[ii][jj].cpt > 0) {
958  ECAL_tower_L1Card[cluster_list_L2[ii][jj].ctowerid_ / n_towers_per_link]
959  [cluster_list_L2[ii][jj].ctowerid_ % n_towers_per_link][ii] += cluster_list_L2[ii][jj].cpt;
960  cluster_list_L2[ii][jj].cpt = 0;
961  cluster_list_L2[ii][jj].ctowerid_ = 0;
962  cluster_list_L2[ii][jj].ccrystalid_ = 0;
963  }
964  }
965  }
966 
967  // Compute isolation (7*7 ECAL towers) and HCAL energy (5x5 HCAL towers)
968  for (int ii = 0; ii < n_towers_halfPhi; ++ii) { // Loop over the new cluster list (stored in 36x8 format)
969  for (unsigned int jj = 0; jj < n_clusters_per_L1card && jj < cluster_list_L2[ii].size(); ++jj) {
970  int cluster_etaOfTower_fullDetector = get_towerEta_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_);
971  int cluster_phiOfTower_fullDetector = get_towerPhi_fromCardTowerInCard(ii, cluster_list_L2[ii][jj].ctowerid_);
972  float hcal_nrj = 0.0;
973  float isolation = 0.0;
974  int ntowers = 0;
975  for (int iii = 0; iii < n_towers_halfPhi; ++iii) { // The clusters have to be added to the isolation
976  for (unsigned int jjj = 0; jjj < n_clusters_per_L1card && jjj < cluster_list_L2[iii].size(); ++jjj) {
977  if (!(iii == ii && jjj == jj)) {
978  int cluster2_eta = get_towerEta_fromCardTowerInCard(iii, cluster_list_L2[iii][jjj].ctowerid_);
979  int cluster2_phi = get_towerPhi_fromCardTowerInCard(iii, cluster_list_L2[iii][jjj].ctowerid_);
980  if (abs(cluster2_eta - cluster_etaOfTower_fullDetector) <= 2 &&
981  (abs(cluster2_phi - cluster_phiOfTower_fullDetector) <= 2 or
982  abs(cluster2_phi - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) {
983  isolation += cluster_list_L2[iii][jjj].cpt;
984  }
985  }
986  }
987  }
988  for (int kk = 0; kk < n_towers_halfPhi; ++kk) { // 36 cards
989  for (int ll = 0; ll < n_links_card; ++ll) { // 4 links per card
990  for (int mm = 0; mm < n_towers_per_link; ++mm) { // 17 towers per link
991  int etaOftower_fullDetector = get_towerEta_fromCardLinkTower(kk, ll, mm);
992  int phiOftower_fullDetector = get_towerPhi_fromCardLinkTower(kk, ll, mm);
993  // First do ECAL
994  // The towers are within 3. Needs to stitch the two phi sides together
995  if (abs(etaOftower_fullDetector - cluster_etaOfTower_fullDetector) <= 2 &&
996  (abs(phiOftower_fullDetector - cluster_phiOfTower_fullDetector) <= 2 or
997  abs(phiOftower_fullDetector - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) {
998  // Remove the column outside of the L2 card: values (0,71), (23,26), (24,21), (47,50), (48,50), (71,2)
999  if (!((cluster_phiOfTower_fullDetector == 0 && phiOftower_fullDetector == 71) or
1000  (cluster_phiOfTower_fullDetector == 23 && phiOftower_fullDetector == 26) or
1001  (cluster_phiOfTower_fullDetector == 24 && phiOftower_fullDetector == 21) or
1002  (cluster_phiOfTower_fullDetector == 47 && phiOftower_fullDetector == 50) or
1003  (cluster_phiOfTower_fullDetector == 48 && phiOftower_fullDetector == 45) or
1004  (cluster_phiOfTower_fullDetector == 71 && phiOftower_fullDetector == 2))) {
1005  isolation += ECAL_tower_L1Card[ll][mm][kk];
1006  ntowers++;
1007  }
1008  }
1009  // Now do HCAL
1010  // The towers are within 2. Needs to stitch the two phi sides together
1011  if (abs(etaOftower_fullDetector - cluster_etaOfTower_fullDetector) <= 2 &&
1012  (abs(phiOftower_fullDetector - cluster_phiOfTower_fullDetector) <= 2 or
1013  abs(phiOftower_fullDetector - n_towers_Phi - cluster_phiOfTower_fullDetector) <= 2)) {
1014  hcal_nrj += HCAL_tower_L1Card[ll][mm][kk];
1015  }
1016  }
1017  }
1018  }
1019  cluster_list_L2[ii][jj].ciso_ = ((isolation) * (25.0 / ntowers)) / cluster_list_L2[ii][jj].cpt;
1020  cluster_list_L2[ii][jj].chovere_ = hcal_nrj / cluster_list_L2[ii][jj].cpt;
1021  }
1022  }
1023 
1024  //Reformat the information inside the 3 L2 cards
1025  //First let's fill the towers
1026  for (int ii = 0; ii < n_links_GCTcard; ++ii) {
1027  for (int jj = 0; jj < n_towers_per_link; ++jj) {
1028  for (int ll = 0; ll < 3; ++ll) {
1029  ECAL_tower_L2Card[ii][jj][ll] =
1031  HCAL_tower_L2Card[ii][jj][ll] =
1033  iEta_tower_L2Card[ii][jj][ll] =
1035  iPhi_tower_L2Card[ii][jj][ll] =
1037  }
1038  }
1039  }
1040 
1041  //Second let's fill the clusters
1042  for (int ii = 0; ii < n_towers_halfPhi; ++ii) { // The cluster list is still in the L1 like geometry
1043  for (unsigned int jj = 0; jj < unsigned(cluster_list_L2[ii].size()) && jj < n_clusters_per_L1card; ++jj) {
1044  crystalID_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1045  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ccrystalid_;
1046  towerID_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1047  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ctowerid_;
1048  energy_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1049  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cpt;
1050  brem_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1051  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cbrem_;
1052  isolation_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1053  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].ciso_;
1054  HE_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1055  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].chovere_;
1056  showerShape_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1057  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cshowershape_;
1058  showerShapeLooseTk_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1059  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cshowershapeloosetk_;
1060  photonShowerShape_cluster_L2Card[n_links_card * (ii % n_clusters_4link) + jj % n_links_card][jj / n_links_card]
1061  [ii / n_clusters_4link] = cluster_list_L2[ii][jj].cphotonshowershape_;
1062  }
1063  }
1064 
1065  auto L1EGXtalClusters = std::make_unique<l1tp2::CaloCrystalClusterCollection>();
1066  auto L1EGammas = std::make_unique<l1t::EGammaBxCollection>();
1067  auto L1CaloTowers = std::make_unique<l1tp2::CaloTowerCollection>();
1068 
1069  // Fill the cluster collection and towers as well
1070  for (int ii = 0; ii < n_links_GCTcard; ++ii) { // 48 links
1071  for (int ll = 0; ll < n_GCTcards; ++ll) { // 3 cards
1072  // For looping over the Towers a few lines below
1073  for (int jj = 0; jj < 2; ++jj) { // 2 L1EGs
1074  if (energy_cluster_L2Card[ii][jj][ll] > 0.45) {
1076  energy_cluster_L2Card[ii][jj][ll],
1078  ii, ll, towerID_cluster_L2Card[ii][jj][ll], crystalID_cluster_L2Card[ii][jj][ll]),
1080  ii, ll, towerID_cluster_L2Card[ii][jj][ll], crystalID_cluster_L2Card[ii][jj][ll]),
1081  0.);
1082  SimpleCaloHit centerhit;
1083  bool is_iso = passes_iso(energy_cluster_L2Card[ii][jj][ll], isolation_cluster_L2Card[ii][jj][ll]);
1084  bool is_looseTkiso =
1085  passes_looseTkiso(energy_cluster_L2Card[ii][jj][ll], isolation_cluster_L2Card[ii][jj][ll]);
1086  bool is_ss = (showerShape_cluster_L2Card[ii][jj][ll] == 1);
1087  bool is_photon = (photonShowerShape_cluster_L2Card[ii][jj][ll] == 1) && is_ss && is_iso;
1088  bool is_looseTkss = (showerShapeLooseTk_cluster_L2Card[ii][jj][ll] == 1);
1089  // All the ID set to Standalone WP! Some dummy values for non calculated variables
1090  l1tp2::CaloCrystalCluster cluster(p4calibrated,
1091  energy_cluster_L2Card[ii][jj][ll],
1092  HE_cluster_L2Card[ii][jj][ll],
1093  isolation_cluster_L2Card[ii][jj][ll],
1094  centerhit.id(),
1095  -1000,
1096  float(brem_cluster_L2Card[ii][jj][ll]),
1097  -1000,
1098  -1000,
1099  energy_cluster_L2Card[ii][jj][ll],
1100  -1,
1101  is_iso&& is_ss,
1102  is_iso&& is_ss,
1103  is_photon,
1104  is_iso&& is_ss,
1105  is_looseTkiso&& is_looseTkss,
1106  is_iso&& is_ss);
1107  // Experimental parameters, don't want to bother with hardcoding them in data format
1108  std::map<std::string, float> params;
1109  params["standaloneWP_showerShape"] = is_ss;
1110  params["standaloneWP_isolation"] = is_iso;
1111  params["trkMatchWP_showerShape"] = is_looseTkss;
1112  params["trkMatchWP_isolation"] = is_looseTkiso;
1113  params["TTiEta"] = getToweriEta_fromAbsoluteID(getTower_absoluteEtaID(p4calibrated.eta()));
1114  params["TTiPhi"] = getToweriPhi_fromAbsoluteID(getTower_absolutePhiID(p4calibrated.phi()));
1115  cluster.setExperimentalParams(params);
1116  L1EGXtalClusters->push_back(cluster);
1117 
1118  int standaloneWP = (int)(is_iso && is_ss);
1119  int looseL1TkMatchWP = (int)(is_looseTkiso && is_looseTkss);
1120  int photonWP = (int)(is_photon);
1121  int quality =
1122  (standaloneWP * std::pow(2, 0)) + (looseL1TkMatchWP * std::pow(2, 1)) + (photonWP * std::pow(2, 2));
1123  L1EGammas->push_back(
1124  0, l1t::EGamma(p4calibrated, p4calibrated.pt(), p4calibrated.eta(), p4calibrated.phi(), quality, 1));
1125  }
1126  }
1127  }
1128  }
1129 
1130  for (int ii = 0; ii < n_links_GCTcard; ++ii) { // 48 links
1131  for (int ll = 0; ll < n_GCTcards; ++ll) { // 3 cards
1132  // Fill the tower collection
1133  for (int jj = 0; jj < n_towers_per_link; ++jj) { // 17 TTs
1134  l1tp2::CaloTower l1CaloTower;
1135  l1CaloTower.setEcalTowerEt(ECAL_tower_L2Card[ii][jj][ll]);
1136  l1CaloTower.setHcalTowerEt(HCAL_tower_L2Card[ii][jj][ll]);
1137  l1CaloTower.setTowerIEta(getToweriEta_fromAbsoluteID(iEta_tower_L2Card[ii][jj][ll]));
1138  l1CaloTower.setTowerIPhi(getToweriPhi_fromAbsoluteID(iPhi_tower_L2Card[ii][jj][ll]));
1139  l1CaloTower.setTowerEta(getTowerEta_fromAbsoluteID(iEta_tower_L2Card[ii][jj][ll]));
1140  l1CaloTower.setTowerPhi(getTowerPhi_fromAbsoluteID(iPhi_tower_L2Card[ii][jj][ll]));
1141  // Some towers have incorrect eta/phi because that wasn't initialized in certain cases, fix these
1142  static float constexpr towerEtaUpperUnitialized = -80;
1143  static float constexpr towerPhiUpperUnitialized = -90;
1144  if (l1CaloTower.towerEta() < towerEtaUpperUnitialized && l1CaloTower.towerPhi() < towerPhiUpperUnitialized) {
1145  l1CaloTower.setTowerEta(l1t::CaloTools::towerEta(l1CaloTower.towerIEta()));
1146  l1CaloTower.setTowerPhi(l1t::CaloTools::towerPhi(l1CaloTower.towerIEta(), l1CaloTower.towerIPhi()));
1147  }
1148  l1CaloTower.setIsBarrel(true);
1149 
1150  // Add L1EGs if they match in iEta / iPhi
1151  // L1EGs are already pT ordered, we will take the ID info for the leading one, but pT as the sum
1152  for (const auto& l1eg : *L1EGXtalClusters) {
1153  if (l1eg.experimentalParam("TTiEta") != l1CaloTower.towerIEta())
1154  continue;
1155  if (l1eg.experimentalParam("TTiPhi") != l1CaloTower.towerIPhi())
1156  continue;
1157 
1158  int n_L1eg = l1CaloTower.nL1eg();
1159  l1CaloTower.setNL1eg(n_L1eg++);
1160  l1CaloTower.setL1egTowerEt(l1CaloTower.l1egTowerEt() + l1eg.pt());
1161  // Don't record L1EG quality info for subleading L1EG
1162  if (l1CaloTower.nL1eg() > 1)
1163  continue;
1164  l1CaloTower.setL1egTrkSS(l1eg.experimentalParam("trkMatchWP_showerShape"));
1165  l1CaloTower.setL1egTrkIso(l1eg.experimentalParam("trkMatchWP_isolation"));
1166  l1CaloTower.setL1egStandaloneSS(l1eg.experimentalParam("standaloneWP_showerShape"));
1167  l1CaloTower.setL1egStandaloneIso(l1eg.experimentalParam("standaloneWP_isolation"));
1168  }
1169 
1170  L1CaloTowers->push_back(l1CaloTower);
1171  }
1172  }
1173  }
1174 
1175  iEvent.put(std::move(L1EGXtalClusters));
1176  iEvent.put(std::move(L1EGammas));
1177  iEvent.put(std::move(L1CaloTowers), "L1CaloTowerCollection");
1178 }
1179 
1181  bool is_iso = true;
1182  if (pt < slideIsoPtThreshold) {
1183  if (!((a0_80 - a1_80 * pt) > iso))
1184  is_iso = false;
1185  } else {
1186  if (iso > a0)
1187  is_iso = false;
1188  }
1189  if (pt > plateau_ss)
1190  is_iso = true;
1191  return is_iso;
1192 }
1193 
1195  bool is_iso = (b0 + b1 * std::exp(-b2 * pt) > iso);
1196  if (pt > plateau_ss)
1197  is_iso = true;
1198  return is_iso;
1199 }
1200 
1202  bool is_ss = ((c0_ss + c1_ss * std::exp(-c2_ss * pt)) <= ss);
1203  if (pt > plateau_ss)
1204  is_ss = true;
1205  return is_ss;
1206 }
1207 
1209  bool is_ss = (pss > d0 - d1 * pt);
1210  if (pt > plateau_ss)
1211  is_ss = true;
1212  return is_ss;
1213 }
1214 
1216  bool is_ss = ((e0_looseTkss - e1_looseTkss * std::exp(-e2_looseTkss * pt)) <= ss);
1217  if (pt > plateau_ss)
1218  is_ss = true;
1219  return is_ss;
1220 }
1221 
1222 //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
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
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
int towerIPhi() const
Definition: CaloTower.h:37
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
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)
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_
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
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
bool getData(T &iHolder) const
Definition: EventSetup.h:122
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:118
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:119
static constexpr int n_GCTcards
static constexpr int n_towers_Phi
void setNL1eg(int n)
Definition: CaloTower.h:56
static constexpr float b2
float towerEta() const
Definition: CaloTower.h:40
static constexpr float b0
string quality
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
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
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