CMS 3D CMS Logo

Phase2L1GCT.h
Go to the documentation of this file.
1 #ifndef PHASE_2_L1_GCT_H_INCL
2 #define PHASE_2_L1_GCT_H_INCL
3 
4 #include <iostream>
5 #include <ap_int.h>
6 
7 // Output collections
10 
12 
13 /*
14  * Do proximity stitching and brems combination for POSITIVE eta, using GCTcard as input. Write to GCTcombinedClusters.
15  * iStartingCard is 0 for even phi boundaries, and 1 for odd phi boundaries.
16  * The first argument is for RCTcardEtaPos/Neg, which are arrays of RCTcard_t of size N_RCTCARDS_PHI. We pass by reference for the second argument to modify it.
17  */
19  p2eg::RCTcard_t (&outputCards)[p2eg::N_RCTCARDS_PHI],
20  int iStartingCard,
21  bool isPositiveEta) {
22  for (int i = iStartingCard; i < p2eg::N_RCTCARDS_PHI - 1; i = i + 2) {
23  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
24  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
25  ap_uint<5> towerPhi1 = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].towPhi;
26 
27  ap_uint<15> crystalEta1 = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].towEta * 5 +
28  inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].crEta;
29  ap_uint<15> crystalPhi1 = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].crPhi;
30 
31  for (int j1 = 0; j1 < p2eg::N_RCTGCT_FIBERS; j1++) {
32  for (int k1 = 0; k1 < p2eg::N_RCTCLUSTERS_FIBER; k1++) {
33  // For each pair, we check if cluster #1 is in the top card and if cluster #2 is in the bottom card.
34  ap_uint<5> towerPhi2 = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].towPhi;
35  ap_uint<15> crystalEta2 = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].towEta * 5 +
36  inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].crEta;
37  ap_uint<15> crystalPhi2 = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].crPhi;
38 
39  // For positive eta, phi1 = 4, phi2 = 0 if cluster 1 is in the top card and cluster 2 is in the bottom card. For negative eta, the reverse is true.
40  ap_uint<15> dPhi;
41  dPhi = (isPositiveEta) ? ((5 - crystalPhi1) + crystalPhi2) : ((5 - crystalPhi2) + crystalPhi1);
42  ap_uint<15> dEta;
43  dEta = (crystalEta1 > crystalEta2) ? (crystalEta1 - crystalEta2) : (crystalEta2 - crystalEta1);
44 
45  ap_uint<12> one = inputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et;
46  ap_uint<12> two = inputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et;
47 
48  int topTowerPhi = (isPositiveEta) ? 3 : 0;
49  int botTowerPhi = (isPositiveEta) ? 0 : 3;
50 
51  int topCrystalPhi = (isPositiveEta) ? 4 : 0;
52  int botCrystalPhi = (isPositiveEta) ? 0 : 4;
53 
54  // First check for proximity stitching: clusters need to be exactly next to each other in crystals (across an RCT card boundary).
55  // No requirement on their relative energy.
56  if (towerPhi1 == topTowerPhi && crystalPhi1 == topCrystalPhi) {
57  if (towerPhi2 == botTowerPhi && crystalPhi2 == botCrystalPhi) {
58  if (dEta < 2) {
59  if (one > two) {
60  outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = one + two;
61  outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0;
62  } else {
63  outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0;
64  outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two;
65  }
66  }
67  }
68  }
69 
70  // Next, check for brems correction: clusters need to be next to each other in TOWERS only (not crystals) across an RCT card boundary.
71  // And the sub-leading cluster must have a significant (>10%) energy of the larger cluster, in order for them to be combined.
72  if (towerPhi1 == topTowerPhi) {
73  if (towerPhi2 == botTowerPhi) {
74  if ((dPhi <= 5) && (dEta < 2)) {
75  if (one > two) {
76  if (two >
77  (0.10 * one)) { // Only stitch if the sub-leading cluster has a significant amount of energy
78  outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = one + two;
79  outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0;
80  }
81  } else {
82  if (one >
83  (0.10 * two)) { // Only stitch if the sub-leading cluster has a significant amount of energy
84  outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0;
85  outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two;
86  }
87  }
88  }
89  }
90  }
91  }
92  }
93  }
94  }
95  }
96 }
97 
98 inline p2eg::GCTcard_t p2eg::getClustersCombined(const p2eg::GCTcard_t& GCTcard, unsigned int nGCTCard) {
99  p2eg::GCTcard_t GCTcombinedClusters;
100 
101  // Initialize the output
102  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
103  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
104  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
105  GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k] =
107  GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k] =
109  }
110  }
111  }
112  bool isPositiveEta;
113  int iStartingCard;
114 
115  // we will store new et in the GCTcombinedClusters, 0'ing lower clusters after stitching, dont need to care about other variables they stay the
116  // same as input for now at least
117  // we combine even phi boundaries positive eta. Start at card 0 (third argument), and tell the function this is positive eta (fourth argument)
118  isPositiveEta = true;
119  iStartingCard = 0;
121  GCTcard.RCTcardEtaPos, GCTcombinedClusters.RCTcardEtaPos, iStartingCard, isPositiveEta);
122 
123  // now we combine odd phi boundaries positive eta
124  isPositiveEta = true;
125  iStartingCard = 1;
127  GCTcard.RCTcardEtaPos, GCTcombinedClusters.RCTcardEtaPos, iStartingCard, isPositiveEta);
128 
129  // repeat above steps for NEGATIVE eta, even phi boundaries
130  isPositiveEta = false;
131  iStartingCard = 0;
133  GCTcard.RCTcardEtaNeg, GCTcombinedClusters.RCTcardEtaNeg, iStartingCard, isPositiveEta);
134 
135  // lastly, NEGATIVE eta, odd phi boundaries
136  isPositiveEta = false;
137  iStartingCard = 1;
139  GCTcard.RCTcardEtaNeg, GCTcombinedClusters.RCTcardEtaNeg, iStartingCard, isPositiveEta);
140 
141  // we need to store what we did before we start phi stitching
142  p2eg::GCTcard_t GCTout;
143  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
144  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
145  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
147  GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k];
149  GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k];
150  }
151  }
152  }
153 
154  // now we combine eta boundaries, just positive and negative eta
155  // Uses RCTcardEtaPos and RCTcardEtaNeg
156  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
157  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
158  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
159  ap_uint<15> phi1 = (i * 4 + GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].towPhi) * 5 +
161  ap_uint<15> eta1 = GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].crEta;
162  if (GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].towEta == 0 && eta1 == 0) {
163  for (int j1 = 0; j1 < p2eg::N_RCTGCT_FIBERS; j1++) {
164  for (int k1 = 0; k1 < p2eg::N_RCTCLUSTERS_FIBER; k1++) {
165  ap_uint<15> phi2 = (i * 4 + (3 - GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].towPhi)) * 5 +
166  (4 - GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].crPhi);
167  ap_uint<15> eta2 = GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].crEta;
168  if (GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].towEta == 0 && eta2 == 0) {
169  ap_uint<15> dPhi;
170  dPhi = (phi1 > phi2) ? (phi1 - phi2) : (phi2 - phi1);
171  if (dPhi < 2) {
172  ap_uint<12> one = GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].et;
173  ap_uint<12> two = GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et;
174  if (one > two) {
176  GCTout.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0;
177  } else {
178  GCTout.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0;
179  GCTout.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two;
180  }
181  }
182  }
183  }
184  }
185  }
186  }
187  }
188  }
189  return GCTout;
190 }
191 
192 /*
193  * Populate a GCTinternal_t struct (consisting of 64 fibers, each fiber has clusters and towers) by converting RCT clusters and towers to GCT notation.
194  */
195 
196 inline p2eg::GCTinternal_t p2eg::getClustersTowers(const p2eg::GCTcard_t& GCTcard, unsigned int nGCTCard) {
197  p2eg::GCTcard_t GCTcombinedClusters;
198  p2eg::GCTinternal_t GCTout;
199 
200  // here we will stitch the clusters in phi and eta
201  GCTcombinedClusters = p2eg::getClustersCombined(GCTcard, nGCTCard);
202 
203  // create internal structure of GCT card
204  // we start from RCT card 0 - it is overlap with other GCT card and fill structure that we will use to send data to Correlator
205  // we only need to care about clusters et in combinrdClusters, since the rest remains unchanged wrt input, the cluster that we set to 0
206  // remain in the data at the same place , it will just get 0 et now
207  // we need to code Positive and Negative Eta differently ! For negative Eta link 0 for each RCT
208  // region becomes 3 in GCT output, the RCT card is rotated around 0:0 point of the card
209  // First 16 fibers - positive Eta , second 16 - negative. Eta coded 0...16 and towEtaNeg = 0 or 1 for clusters ;
210  // Phi is coded 0...15 , in case if whole card 0...33 and subdevision 1/5 in crPhi and crEta 0...4 for
211  // position in tower
212  //
213  // towers are put in link starting from eta=0, the link number defines Eta negative or positive and Phi position of tower.
214  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
215  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
216  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
217  bool isPositiveEta;
218  // positive eta: initialize from RCT clusters in pos object
219  isPositiveEta = true;
221  i, isPositiveEta, GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k]);
222  // negative eta: initialize from RCT clusters in neg object
223  isPositiveEta = false;
224  GCTout.GCTCorrfiber[i * 4 + (3 - j) + p2eg::N_GCTPOSITIVE_FIBERS].GCTclusters[k].initFromRCTCluster(
225  i, isPositiveEta, GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k]);
226  }
227  for (int k = 0; k < N_RCTTOWERS_FIBER; k++) {
228  GCTout.GCTCorrfiber[i * 4 + j].GCTtowers[k].initFromRCTTower(
229  GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTtowers[k]); // pos eta
230  GCTout.GCTCorrfiber[i * 4 + (3 - j) + p2eg::N_GCTPOSITIVE_FIBERS].GCTtowers[k].initFromRCTTower(
231  GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTtowers[k]); // neg eta
232  }
233  }
234  }
235  return GCTout;
236 }
237 
238 /*
239  * Return full towers with the tower energy (i.e. unclustered energy) and cluster energy added together.
240  */
242  p2eg::GCTintTowers_t GCTintTowers;
243  // Positive eta
244  for (int i = 0; i < p2eg::N_GCTPOSITIVE_FIBERS; i = i + 4) {
245  for (int i1 = 0; i1 < 4; i1++) {
246  for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) {
247  ap_uint<15> phi = i + i1;
248  ap_uint<15> eta = p2eg::N_GCTETA / 2 + k;
249  GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].et;
250  GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].hoe;
251  GCTintTowers.GCTtower[eta][phi].ecalEt = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].ecalEt;
252  GCTintTowers.GCTtower[eta][phi].hcalEt = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].hcalEt;
253  for (int ic1 = 0; ic1 < 4; ic1++) {
254  for (int jc = 0; jc < p2eg::N_GCTCLUSTERS_FIBER; jc++) {
255  ap_uint<15> eta1 = p2eg::N_GCTETA / 2 + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towEta;
256  ap_uint<15> phi1 = GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towPhi;
257  if (eta == eta1 && phi == phi1) {
258  GCTintTowers.GCTtower[eta][phi].et =
259  (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et);
260  }
261  }
262  }
263  }
264  }
265  }
266 
267  // Negative eta
269  for (int i1 = 0; i1 < 4; i1++) {
270  for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) {
271  ap_uint<15> eta = p2eg::N_GCTETA / 2 - k - 1;
272  ap_uint<15> phi = i + i1 - p2eg::N_GCTPOSITIVE_FIBERS;
273  GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].et;
274  GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].hoe;
275  GCTintTowers.GCTtower[eta][phi].ecalEt = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].ecalEt;
276  GCTintTowers.GCTtower[eta][phi].hcalEt = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].hcalEt;
277  for (int ic1 = 0; ic1 < 4; ic1++) {
278  for (int jc = 0; jc < p2eg::N_GCTCLUSTERS_FIBER; jc++) {
279  ap_uint<15> eta1 = p2eg::N_GCTETA / 2 - 1 - GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towEta;
280  ap_uint<15> phi1 = GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towPhi;
281  if (eta == eta1 && phi == phi1) {
282  GCTintTowers.GCTtower[eta][phi].et =
283  (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et);
284  }
285  }
286  }
287  }
288  }
289  }
290 
291  return GCTintTowers;
292 }
293 
294 /*
295  * Fill CMSSW collections and correlator outputs, using GCTinternal.
296  */
298  const p2eg::GCTinternal_t& GCTinternal,
299  p2eg::GCTtoCorr_t& GCTtoCorrOutput,
300  std::unique_ptr<l1tp2::CaloCrystalClusterCollection> const& gctClustersOutput,
301  std::unique_ptr<l1tp2::CaloTowerCollection> const& gctTowersOutput,
302  std::unique_ptr<l1t::EGammaBxCollection> const& gctEGammas,
303  std::unique_ptr<l1tp2::DigitizedClusterCorrelatorCollection> const& gctDigitizedClustersCorrelator,
304  std::unique_ptr<l1tp2::DigitizedTowerCorrelatorCollection> const& gctDigitizedTowersCorrelator,
305  std::unique_ptr<l1tp2::DigitizedClusterGTCollection> const& gctDigitizedClustersGT,
306  int nGCTCard,
307  int fiberStart,
308  int fiberEnd,
309  int corrFiberIndexOffset,
310  int corrTowPhiOffset = 4) {
311  for (int i = fiberStart; i < fiberEnd; i++) {
312  // In each fiber, first do clusters
313  for (int k = 0; k < p2eg::N_GCTCLUSTERS_FIBER; k++) {
314  // First do CMSSW cluster outputs
315  p2eg::GCTcluster_t thisCluster = GCTinternal.GCTCorrfiber[i].GCTclusters[k];
316  if (thisCluster.etFloat() > 0.0) {
317  // Make l1tp2::CaloCrystalCluster
318  gctClustersOutput->push_back(thisCluster.createCaloCrystalCluster());
319 
320  // Make l1t::EGamma
321  int bx = 0;
322  l1t::EGamma thisEGamma = thisCluster.createL1TEGamma();
323  gctEGammas->push_back(bx, thisEGamma);
324  }
325 
326  // Then the clusters to the correlator: all fields are the same with the exception of towPhi, which
327  // needs to be subtracted by 4 because the output to correlator does NOT include the overlap region.
328  GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTclusters[k] = thisCluster;
329  GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTclusters[k].towPhi =
330  (thisCluster.towPhi - corrTowPhiOffset);
331 
332  // Make l1tp2::DigitizedClusterCorrelator. The function needs corrTowPhiOffset to know the towPhi in the card excluding the overlap region.
333  // The correlator clusters don't need to know the fiber offset.
334  if (thisCluster.etFloat() > 0.0) {
335  gctDigitizedClustersCorrelator->push_back(thisCluster.createDigitizedClusterCorrelator(corrTowPhiOffset));
336  }
337 
338  // Make l1tp2::DigitizedClusterGT.
339  if (thisCluster.etFloat() > 0.0) {
340  bool isValid = true;
341  gctDigitizedClustersGT->push_back(thisCluster.createDigitizedClusterGT(isValid));
342  }
343  }
344 
345  // Next do tower outputs
346  for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) {
347  // First do CMSSW tower outputs
348  p2eg::GCTtower_t thisTower = GCTinternal.GCTCorrfiber[i].GCTtowers[k];
349  l1tp2::CaloTower thisL1CaloTower = thisTower.createCaloTowerFromFiberIdx(nGCTCard, i, k);
350  gctTowersOutput->push_back(thisL1CaloTower);
351 
352  // Then the towers to the correlator. Note the same corrFiberIndexOffset as was done for the clusters
353  GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTtowers[k] = thisTower;
354 
355  // For the collection, the three arguments are (1) the GCT card, (2) the fiber index in the GCT card (excluding the overlap region), and (3) the tower index in the fiber
356  l1tp2::DigitizedTowerCorrelator thisDigitizedTowerCorrelator =
357  thisTower.createDigitizedTowerCorrelator(nGCTCard, i - corrFiberIndexOffset, k);
358  gctDigitizedTowersCorrelator->push_back(thisDigitizedTowerCorrelator);
359  }
360  }
361 }
362 
363 /*
364  * algo_top: First two arguments are the same as in the original firmware.
365  * nGCTCard is 0, 1, or 2 (needed for getting the cluster real eta/phis for CMSSW collections).
366  * gctClusters is the CMSSW-style output collection of clusters.
367  * gctTowers is the CMSSW-style output collection of towers.
368  */
369 
370 inline void p2eg::algo_top(
371  const p2eg::GCTcard_t& GCTcard,
372  p2eg::GCTtoCorr_t& GCTtoCorr,
373  unsigned int nGCTCard,
374  std::unique_ptr<l1tp2::CaloCrystalClusterCollection> const& gctClusters,
375  std::unique_ptr<l1tp2::CaloTowerCollection> const& gctTowers,
376  std::unique_ptr<l1tp2::CaloTowerCollection> const& gctFullTowers,
377  std::unique_ptr<l1t::EGammaBxCollection> const& gctEGammas,
378  std::unique_ptr<l1tp2::DigitizedClusterCorrelatorCollection> const& gctDigitizedClustersCorrelator,
379  std::unique_ptr<l1tp2::DigitizedTowerCorrelatorCollection> const& gctDigitizedTowersCorrelator,
380  std::unique_ptr<l1tp2::DigitizedClusterGTCollection> const& gctDigitizedClustersGT,
382  //-------------------------//
383  // Initialize the GCT area
384  //-------------------------//
385  p2eg::GCTinternal_t GCTinternal = p2eg::getClustersTowers(GCTcard, nGCTCard);
386 
387  //------------------------------------------------//
388  // Combine towers and clusters to get full towers
389  //------------------------------------------------//
390  p2eg::GCTintTowers_t GCTintTowers = p2eg::getFullTowers(GCTinternal);
391 
392  //---------------------------//
393  // Compute cluster isolation
394  //--------------------------//
395  GCTinternal.computeClusterIsolationInPlace(nGCTCard);
396  GCTinternal.setIsolationInfo();
397 
398  //-----------------------------------------------------------------------------------------------------------------------//
399  // Output to correlator and CMSSW collections.
400  // For positive eta, skip overlap region, i.e. fibers i = 0, 1, 2, 3, and i = 28, 29, 30, 31.
401  // For negative eta, skip overlap region, i.e. fibers 32, 33, 34, 35, and 61, 62, 63, 64.
402  //-----------------------------------------------------------------------------------------------------------------------//
403  int posEtaFiberStart = p2eg::N_RCTGCT_FIBERS; // 4, since there are 4 fibers in one RCT card
404  int posEtaFiberEnd = (p2eg::N_GCTPOSITIVE_FIBERS - p2eg::N_RCTGCT_FIBERS);
405  int negEtaFiberStart = (p2eg::N_GCTPOSITIVE_FIBERS + p2eg::N_RCTGCT_FIBERS);
406  int negEtaFiberEnd =
407  (p2eg::N_GCTINTERNAL_FIBERS - p2eg::N_RCTGCT_FIBERS); // first term is number of gct internal fibers
408 
409  // When indexing into the correlator output, note that the output to correlator does NOT include the overlap region,
410  // so fiber number "i" in GCT is not fiber "i" in the correlator output, it's reduced by 4 in positive eta, and 12 in negative eta.
411  // (4 because we are skipping one RCT card in positive eta, and 12 because we are skipping three RCT cards in negative eta)
412  int posEtaCorrelatorFiberIndexOffset = 4;
413  int negEtaCorrelatorFiberIndexOffset = 12;
414 
415  // The offset in the actual towPhi value is going to be the same in pos/neg eta; shifted down by 4 due to no overlap region
416  int correlatorTowPhiOffset = 4;
417 
418  // Positive eta
420  GCTtoCorr,
421  gctClusters,
422  gctTowers,
423  gctEGammas,
424  gctDigitizedClustersCorrelator,
425  gctDigitizedTowersCorrelator,
426  gctDigitizedClustersGT,
427  nGCTCard,
428  posEtaFiberStart,
429  posEtaFiberEnd,
430  posEtaCorrelatorFiberIndexOffset,
431  correlatorTowPhiOffset);
432  // Negative eta
434  GCTtoCorr,
435  gctClusters,
436  gctTowers,
437  gctEGammas,
438  gctDigitizedClustersCorrelator,
439  gctDigitizedTowersCorrelator,
440  gctDigitizedClustersGT,
441  nGCTCard,
442  negEtaFiberStart,
443  negEtaFiberEnd,
444  negEtaCorrelatorFiberIndexOffset,
445  correlatorTowPhiOffset);
446 
447  //-----------------------------------------------------------------------------------------------------------------------//
448  // CMSSW outputs for GCT Full Towers (clusters + towers) output for PFClusters.
449  //-----------------------------------------------------------------------------------------------------------------------//
450  GCTintTowers.writeToPFOutput(nGCTCard, gctFullTowers);
451 }
452 
453 #endif
GCTCorrfiber_t GCTCorrfiber[N_GCTCORR_FIBERS]
static constexpr int N_GCTCLUSTERS_FIBER
GCTtower_t GCTtower[N_GCTETA][N_GCTPHI]
const bool isValid(const Frame &aFrame, const FrameQuality &aQuality, const uint16_t aExpectedPos)
RCTcluster_t RCTclusters[N_RCTCLUSTERS_FIBER]
l1tp2::CaloCrystalCluster createCaloCrystalCluster(void) const
GCTCorrfiber_t GCTCorrfiber[N_GCTINTERNAL_FIBERS]
static constexpr int N_GCTPOSITIVE_FIBERS
static constexpr int N_GCTTOWERS_FIBER
RCTtower_t RCTtowers[N_RCTTOWERS_FIBER]
GCTcluster_t GCTclusters[N_GCTCLUSTERS_FIBER]
l1t::EGamma createL1TEGamma(void) const
void computeClusterIsolationInPlace(int nGCTCard)
RCTcard_t RCTcardEtaNeg[N_RCTCARDS_PHI]
static constexpr int N_RCTCARDS_PHI
l1tp2::DigitizedClusterGT createDigitizedClusterGT(bool isValid) const
static constexpr int N_RCTTOWERS_FIBER
GCTcard_t getClustersCombined(const GCTcard_t &GCTcard, unsigned int nGCTCard)
Definition: Phase2L1GCT.h:98
static constexpr int N_RCTGCT_FIBERS
static constexpr int N_RCTCLUSTERS_FIBER
l1tp2::DigitizedClusterCorrelator createDigitizedClusterCorrelator(const int corrTowPhiOffset) const
l1tp2::CaloTower createCaloTowerFromFiberIdx(int nGCTCard, int iFiber, int iTowerInFiber)
static constexpr int N_GCTINTERNAL_FIBERS
GCTintTowers_t getFullTowers(const GCTinternal_t &GCTinternal)
Definition: Phase2L1GCT.h:241
void writeToCorrelatorAndGTOutputs(const GCTinternal_t &GCTinternal, GCTtoCorr_t &GCTtoCorrOutput, std::unique_ptr< l1tp2::CaloCrystalClusterCollection > const &gctClustersOutput, std::unique_ptr< l1tp2::CaloTowerCollection > const &gctTowersOutput, std::unique_ptr< l1t::EGammaBxCollection > const &gctEGammas, std::unique_ptr< l1tp2::DigitizedClusterCorrelatorCollection > const &gctDigitizedClustersCorrelator, std::unique_ptr< l1tp2::DigitizedTowerCorrelatorCollection > const &gctDigitizedTowersCorrelator, std::unique_ptr< l1tp2::DigitizedClusterGTCollection > const &gctDigitizedClustersGT, int nGCTCard, int fiberStart, int fiberEnd, int corrFiberIndexOffset, int corrTowPhiOffset)
Definition: Phase2L1GCT.h:297
void doProximityAndBremsStitching(const RCTcard_t(&inputCards)[N_RCTCARDS_PHI], RCTcard_t(&outputCards)[N_RCTCARDS_PHI], int iStartingCard, bool isPositiveEta)
static constexpr int N_GCTETA
void initFromRCTCluster(int iRCTcardIndex, bool isPosEta, const RCTcluster_t &rctCluster)
RCTtoGCTfiber_t RCTtoGCTfiber[N_RCTGCT_FIBERS]
RCTcard_t RCTcardEtaPos[N_RCTCARDS_PHI]
l1tp2::DigitizedTowerCorrelator createDigitizedTowerCorrelator(unsigned int indexCard, unsigned int indexFiber, unsigned int indexTower)
GCTtower_t GCTtowers[N_GCTTOWERS_FIBER]
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
GCTinternal_t getClustersTowers(const GCTcard_t &GCTcard, unsigned int nGCTCard)
Definition: Phase2L1GCT.h:196
void writeToPFOutput(int nGCTCard, std::unique_ptr< l1tp2::CaloTowerCollection > const &gctFullTowers)
void algo_top(const GCTcard_t &GCTcard, GCTtoCorr_t &GCTtoCorr, unsigned int nGCTCard, std::unique_ptr< l1tp2::CaloCrystalClusterCollection > const &gctClusters, std::unique_ptr< l1tp2::CaloTowerCollection > const &gctTowers, std::unique_ptr< l1tp2::CaloTowerCollection > const &gctFullTowers, std::unique_ptr< l1t::EGammaBxCollection > const &gctEGammas, std::unique_ptr< l1tp2::DigitizedClusterCorrelatorCollection > const &gctDigitizedClustersCorrelator, std::unique_ptr< l1tp2::DigitizedTowerCorrelatorCollection > const &gctDigitizedTowersCorrelator, std::unique_ptr< l1tp2::DigitizedClusterGTCollection > const &gctDigitizedClustersGT, l1tp2::ParametricCalibration calib_)
Definition: Phase2L1GCT.h:370
void initFromRCTTower(const RCTtower_t &rctTower)