CMS 3D CMS Logo

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