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  if (towerPhi1 == topTowerPhi) {
72  if (towerPhi2 == botTowerPhi) {
73  if ((dPhi <= 5) && (dEta < 2)) {
74  if (one > two) {
75  outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = one + two;
76  outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0;
77  } else {
78  outputCards[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0;
79  outputCards[i + 1].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two;
80  }
81  }
82  }
83  }
84  }
85  }
86  }
87  }
88  }
89 }
90 
91 inline p2eg::GCTcard_t p2eg::getClustersCombined(const p2eg::GCTcard_t& GCTcard, unsigned int nGCTCard) {
92  p2eg::GCTcard_t GCTcombinedClusters;
93 
94  // Initialize the output
95  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
96  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
97  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
98  GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k] =
100  GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k] =
102  }
103  }
104  }
105  bool isPositiveEta;
106  int iStartingCard;
107 
108  // we will store new et in the GCTcombinedClusters, 0'ing lower clusters after stitching, dont need to care about other variables they stay the
109  // same as input for now at least
110  // we combine even phi boundaries positive eta. Start at card 0 (third argument), and tell the function this is positive eta (fourth argument)
111  isPositiveEta = true;
112  iStartingCard = 0;
114  GCTcard.RCTcardEtaPos, GCTcombinedClusters.RCTcardEtaPos, iStartingCard, isPositiveEta);
115 
116  // now we combine odd phi boundaries positive eta
117  isPositiveEta = true;
118  iStartingCard = 1;
120  GCTcard.RCTcardEtaPos, GCTcombinedClusters.RCTcardEtaPos, iStartingCard, isPositiveEta);
121 
122  // repeat above steps for NEGATIVE eta, even phi boundaries
123  isPositiveEta = false;
124  iStartingCard = 0;
126  GCTcard.RCTcardEtaNeg, GCTcombinedClusters.RCTcardEtaNeg, iStartingCard, isPositiveEta);
127 
128  // lastly, NEGATIVE eta, odd phi boundaries
129  isPositiveEta = false;
130  iStartingCard = 1;
132  GCTcard.RCTcardEtaNeg, GCTcombinedClusters.RCTcardEtaNeg, iStartingCard, isPositiveEta);
133 
134  // we need to store what we did before we start phi stitching
135  p2eg::GCTcard_t GCTout;
136  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
137  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
138  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
140  GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k];
142  GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k];
143  }
144  }
145  }
146 
147  // now we combine eta boundaries, just positive and negative eta
148  // Uses RCTcardEtaPos and RCTcardEtaNeg
149  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
150  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
151  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
152  ap_uint<15> phi1 = (i * 4 + GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].towPhi) * 5 +
154  ap_uint<15> eta1 = GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].crEta;
155  if (GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].towEta == 0 && eta1 == 0) {
156  for (int j1 = 0; j1 < p2eg::N_RCTGCT_FIBERS; j1++) {
157  for (int k1 = 0; k1 < p2eg::N_RCTCLUSTERS_FIBER; k1++) {
158  ap_uint<15> phi2 = (i * 4 + (3 - GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].towPhi)) * 5 +
159  (4 - GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].crPhi);
160  ap_uint<15> eta2 = GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].crEta;
161  if (GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].towEta == 0 && eta2 == 0) {
162  ap_uint<15> dPhi;
163  dPhi = (phi1 > phi2) ? (phi1 - phi2) : (phi2 - phi1);
164  if (dPhi < 2) {
165  ap_uint<12> one = GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].et;
166  ap_uint<12> two = GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et;
167  if (one > two) {
169  GCTout.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et = 0;
170  } else {
171  GCTout.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k].et = 0;
172  GCTout.RCTcardEtaNeg[i].RCTtoGCTfiber[j1].RCTclusters[k1].et = one + two;
173  }
174  }
175  }
176  }
177  }
178  }
179  }
180  }
181  }
182  return GCTout;
183 }
184 
185 /*
186  * Populate a GCTinternal_t struct (consisting of 64 fibers, each fiber has clusters and towers) by converting RCT clusters and towers to GCT notation.
187  */
188 
189 inline p2eg::GCTinternal_t p2eg::getClustersTowers(const p2eg::GCTcard_t& GCTcard, unsigned int nGCTCard) {
190  p2eg::GCTcard_t GCTcombinedClusters;
191  p2eg::GCTinternal_t GCTout;
192 
193  // here we will stitch the clusters in phi and eta
194  GCTcombinedClusters = p2eg::getClustersCombined(GCTcard, nGCTCard);
195 
196  // create internal structure of GCT card
197  // 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
198  // we only need to care about clusters et in combinrdClusters, since the rest remains unchanged wrt input, the cluster that we set to 0
199  // remain in the data at the same place , it will just get 0 et now
200  // we need to code Positive and Negative Eta differently ! For negative Eta link 0 for each RCT
201  // region becomes 3 in GCT output, the RCT card is rotated around 0:0 point of the card
202  // First 16 fibers - positive Eta , second 16 - negative. Eta coded 0...16 and towEtaNeg = 0 or 1 for clusters ;
203  // Phi is coded 0...15 , in case if whole card 0...33 and subdevision 1/5 in crPhi and crEta 0...4 for
204  // position in tower
205  //
206  // towers are put in link starting from eta=0, the link number defines Eta negative or positive and Phi position of tower.
207  for (int i = 0; i < p2eg::N_RCTCARDS_PHI; i++) {
208  for (int j = 0; j < p2eg::N_RCTGCT_FIBERS; j++) {
209  for (int k = 0; k < p2eg::N_RCTCLUSTERS_FIBER; k++) {
210  bool isPositiveEta;
211  // positive eta: initialize from RCT clusters in pos object
212  isPositiveEta = true;
214  i, isPositiveEta, GCTcombinedClusters.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTclusters[k]);
215  // negative eta: initialize from RCT clusters in neg object
216  isPositiveEta = false;
217  GCTout.GCTCorrfiber[i * 4 + (3 - j) + p2eg::N_GCTPOSITIVE_FIBERS].GCTclusters[k].initFromRCTCluster(
218  i, isPositiveEta, GCTcombinedClusters.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTclusters[k]);
219  }
220  for (int k = 0; k < N_RCTTOWERS_FIBER; k++) {
221  GCTout.GCTCorrfiber[i * 4 + j].GCTtowers[k].initFromRCTTower(
222  GCTcard.RCTcardEtaPos[i].RCTtoGCTfiber[j].RCTtowers[k]); // pos eta
223  GCTout.GCTCorrfiber[i * 4 + (3 - j) + p2eg::N_GCTPOSITIVE_FIBERS].GCTtowers[k].initFromRCTTower(
224  GCTcard.RCTcardEtaNeg[i].RCTtoGCTfiber[j].RCTtowers[k]); // neg eta
225  }
226  }
227  }
228  return GCTout;
229 }
230 
231 /*
232  * Return full towers with the tower energy (i.e. unclustered energy) and cluster energy added together.
233  */
235  p2eg::GCTintTowers_t GCTintTowers;
236  // Positive eta
237  for (int i = 0; i < p2eg::N_GCTPOSITIVE_FIBERS; i = i + 4) {
238  for (int i1 = 0; i1 < 4; i1++) {
239  for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) {
240  ap_uint<15> phi = i + i1;
241  ap_uint<15> eta = p2eg::N_GCTETA / 2 + k;
242  GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].et;
243  GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].hoe;
244  GCTintTowers.GCTtower[eta][phi].ecalEt = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].ecalEt;
245  GCTintTowers.GCTtower[eta][phi].hcalEt = GCTinternal.GCTCorrfiber[phi].GCTtowers[k].hcalEt;
246  for (int ic1 = 0; ic1 < 4; ic1++) {
247  for (int jc = 0; jc < p2eg::N_GCTCLUSTERS_FIBER; jc++) {
248  ap_uint<15> eta1 = p2eg::N_GCTETA / 2 + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towEta;
249  ap_uint<15> phi1 = GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towPhi;
250  if (eta == eta1 && phi == phi1) {
251  GCTintTowers.GCTtower[eta][phi].et =
252  (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et);
253  }
254  }
255  }
256  }
257  }
258  }
259 
260  // Negative eta
262  for (int i1 = 0; i1 < 4; i1++) {
263  for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) {
264  ap_uint<15> eta = p2eg::N_GCTETA / 2 - k - 1;
265  ap_uint<15> phi = i + i1 - p2eg::N_GCTPOSITIVE_FIBERS;
266  GCTintTowers.GCTtower[eta][phi].et = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].et;
267  GCTintTowers.GCTtower[eta][phi].hoe = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].hoe;
268  GCTintTowers.GCTtower[eta][phi].ecalEt = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].ecalEt;
269  GCTintTowers.GCTtower[eta][phi].hcalEt = GCTinternal.GCTCorrfiber[i + i1].GCTtowers[k].hcalEt;
270  for (int ic1 = 0; ic1 < 4; ic1++) {
271  for (int jc = 0; jc < p2eg::N_GCTCLUSTERS_FIBER; jc++) {
272  ap_uint<15> eta1 = p2eg::N_GCTETA / 2 - 1 - GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towEta;
273  ap_uint<15> phi1 = GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].towPhi;
274  if (eta == eta1 && phi == phi1) {
275  GCTintTowers.GCTtower[eta][phi].et =
276  (GCTintTowers.GCTtower[eta][phi].et + GCTinternal.GCTCorrfiber[i + ic1].GCTclusters[jc].et);
277  }
278  }
279  }
280  }
281  }
282  }
283 
284  return GCTintTowers;
285 }
286 
287 /*
288  * Fill CMSSW collections and correlator outputs, using GCTinternal.
289  */
291  const p2eg::GCTinternal_t& GCTinternal,
292  p2eg::GCTtoCorr_t& GCTtoCorrOutput,
293  std::unique_ptr<l1tp2::CaloCrystalClusterCollection> const& gctClustersOutput,
294  std::unique_ptr<l1tp2::CaloTowerCollection> const& gctTowersOutput,
295  std::unique_ptr<l1t::EGammaBxCollection> const& gctEGammas,
296  std::unique_ptr<l1tp2::DigitizedClusterCorrelatorCollection> const& gctDigitizedClustersCorrelator,
297  std::unique_ptr<l1tp2::DigitizedTowerCorrelatorCollection> const& gctDigitizedTowersCorrelator,
298  std::unique_ptr<l1tp2::DigitizedClusterGTCollection> const& gctDigitizedClustersGT,
299  int nGCTCard,
300  int fiberStart,
301  int fiberEnd,
302  int corrFiberIndexOffset,
303  int corrTowPhiOffset = 4) {
304  for (int i = fiberStart; i < fiberEnd; i++) {
305  // In each fiber, first do clusters
306  for (int k = 0; k < p2eg::N_GCTCLUSTERS_FIBER; k++) {
307  // First do CMSSW cluster outputs
308  p2eg::GCTcluster_t thisCluster = GCTinternal.GCTCorrfiber[i].GCTclusters[k];
309  if (thisCluster.etFloat() > 0.0) {
310  // Make l1tp2::CaloCrystalCluster
311  gctClustersOutput->push_back(thisCluster.createCaloCrystalCluster());
312 
313  // Make l1t::EGamma
314  int bx = 0;
315  l1t::EGamma thisEGamma = thisCluster.createL1TEGamma();
316  gctEGammas->push_back(bx, thisEGamma);
317  }
318 
319  // Then the clusters to the correlator: all fields are the same with the exception of towPhi, which
320  // needs to be subtracted by 4 because the output to correlator does NOT include the overlap region.
321  GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTclusters[k] = thisCluster;
322  GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTclusters[k].towPhi =
323  (thisCluster.towPhi - corrTowPhiOffset);
324 
325  // Make l1tp2::DigitizedClusterCorrelator. The function needs corrTowPhiOffset to know the towPhi in the card excluding the overlap region.
326  // The correlator clusters don't need to know the fiber offset.
327  if (thisCluster.etFloat() > 0.0) {
328  gctDigitizedClustersCorrelator->push_back(thisCluster.createDigitizedClusterCorrelator(corrTowPhiOffset));
329  }
330 
331  // Make l1tp2::DigitizedClusterGT.
332  if (thisCluster.etFloat() > 0.0) {
333  bool isValid = true;
334  gctDigitizedClustersGT->push_back(thisCluster.createDigitizedClusterGT(isValid));
335  }
336  }
337 
338  // Next do tower outputs
339  for (int k = 0; k < p2eg::N_GCTTOWERS_FIBER; k++) {
340  // First do CMSSW tower outputs
341  p2eg::GCTtower_t thisTower = GCTinternal.GCTCorrfiber[i].GCTtowers[k];
342  l1tp2::CaloTower thisL1CaloTower = thisTower.createCaloTowerFromFiberIdx(nGCTCard, i, k);
343  gctTowersOutput->push_back(thisL1CaloTower);
344 
345  // Then the towers to the correlator. Note the same corrFiberIndexOffset as was done for the clusters
346  GCTtoCorrOutput.GCTCorrfiber[i - corrFiberIndexOffset].GCTtowers[k] = thisTower;
347 
348  // 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
349  l1tp2::DigitizedTowerCorrelator thisDigitizedTowerCorrelator =
350  thisTower.createDigitizedTowerCorrelator(nGCTCard, i - corrFiberIndexOffset, k);
351  gctDigitizedTowersCorrelator->push_back(thisDigitizedTowerCorrelator);
352  }
353  }
354 }
355 
356 /*
357  * algo_top: First two arguments are the same as in the original firmware.
358  * nGCTCard is 0, 1, or 2 (needed for getting the cluster real eta/phis for CMSSW collections).
359  * gctClusters is the CMSSW-style output collection of clusters.
360  * gctTowers is the CMSSW-style output collection of towers.
361  */
362 
363 inline void p2eg::algo_top(
364  const p2eg::GCTcard_t& GCTcard,
365  p2eg::GCTtoCorr_t& GCTtoCorr,
366  unsigned int nGCTCard,
367  std::unique_ptr<l1tp2::CaloCrystalClusterCollection> const& gctClusters,
368  std::unique_ptr<l1tp2::CaloTowerCollection> const& gctTowers,
369  std::unique_ptr<l1tp2::CaloTowerCollection> const& gctFullTowers,
370  std::unique_ptr<l1t::EGammaBxCollection> const& gctEGammas,
371  std::unique_ptr<l1tp2::DigitizedClusterCorrelatorCollection> const& gctDigitizedClustersCorrelator,
372  std::unique_ptr<l1tp2::DigitizedTowerCorrelatorCollection> const& gctDigitizedTowersCorrelator,
373  std::unique_ptr<l1tp2::DigitizedClusterGTCollection> const& gctDigitizedClustersGT,
375  //-------------------------//
376  // Initialize the GCT area
377  //-------------------------//
378  p2eg::GCTinternal_t GCTinternal = p2eg::getClustersTowers(GCTcard, nGCTCard);
379 
380  //------------------------------------------------//
381  // Combine towers and clusters to get full towers
382  //------------------------------------------------//
383  p2eg::GCTintTowers_t GCTintTowers = p2eg::getFullTowers(GCTinternal);
384 
385  //---------------------------//
386  // Compute cluster isolation
387  //--------------------------//
388  GCTinternal.computeClusterIsolationInPlace(nGCTCard);
389  GCTinternal.setIsolationInfo();
390 
391  //-----------------------------------------------------------------------------------------------------------------------//
392  // Output to correlator and CMSSW collections.
393  // For positive eta, skip overlap region, i.e. fibers i = 0, 1, 2, 3, and i = 28, 29, 30, 31.
394  // For negative eta, skip overlap region, i.e. fibers 32, 33, 34, 35, and 61, 62, 63, 64.
395  //-----------------------------------------------------------------------------------------------------------------------//
396  int posEtaFiberStart = p2eg::N_RCTGCT_FIBERS; // 4, since there are 4 fibers in one RCT card
397  int posEtaFiberEnd = (p2eg::N_GCTPOSITIVE_FIBERS - p2eg::N_RCTGCT_FIBERS);
398  int negEtaFiberStart = (p2eg::N_GCTPOSITIVE_FIBERS + p2eg::N_RCTGCT_FIBERS);
399  int negEtaFiberEnd =
400  (p2eg::N_GCTINTERNAL_FIBERS - p2eg::N_RCTGCT_FIBERS); // first term is number of gct internal fibers
401 
402  // When indexing into the correlator output, note that the output to correlator does NOT include the overlap region,
403  // 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.
404  // (4 because we are skipping one RCT card in positive eta, and 12 because we are skipping three RCT cards in negative eta)
405  int posEtaCorrelatorFiberIndexOffset = 4;
406  int negEtaCorrelatorFiberIndexOffset = 12;
407 
408  // 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
409  int correlatorTowPhiOffset = 4;
410 
411  // Positive eta
413  GCTtoCorr,
414  gctClusters,
415  gctTowers,
416  gctEGammas,
417  gctDigitizedClustersCorrelator,
418  gctDigitizedTowersCorrelator,
419  gctDigitizedClustersGT,
420  nGCTCard,
421  posEtaFiberStart,
422  posEtaFiberEnd,
423  posEtaCorrelatorFiberIndexOffset,
424  correlatorTowPhiOffset);
425  // Negative eta
427  GCTtoCorr,
428  gctClusters,
429  gctTowers,
430  gctEGammas,
431  gctDigitizedClustersCorrelator,
432  gctDigitizedTowersCorrelator,
433  gctDigitizedClustersGT,
434  nGCTCard,
435  negEtaFiberStart,
436  negEtaFiberEnd,
437  negEtaCorrelatorFiberIndexOffset,
438  correlatorTowPhiOffset);
439 
440  //-----------------------------------------------------------------------------------------------------------------------//
441  // CMSSW outputs for GCT Full Towers (clusters + towers) output for PFClusters.
442  //-----------------------------------------------------------------------------------------------------------------------//
443  GCTintTowers.writeToPFOutput(nGCTCard, gctFullTowers);
444 }
445 
446 #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:91
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:234
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:290
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:189
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:363
void initFromRCTTower(const RCTtower_t &rctTower)