CMS 3D CMS Logo

Stage2Layer2EGammaAlgorithmFirmwareImp1.cc
Go to the documentation of this file.
1 
10 
15 
16 
17 namespace l1t {
18  bool operator > ( const l1t::EGamma& a, const l1t::EGamma& b )
19  {
20  return a.pt() > b.pt();
21  }
22 }
23 
24 
25 /*****************************************************************/
27  params_(params)
28 /*****************************************************************/
29 {
30 
31 }
32 
33 /*****************************************************************/
34 void l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::processEvent(const std::vector<l1t::CaloCluster>& clusters, const std::vector<l1t::CaloTower>& towers, std::vector<l1t::EGamma>& egammas)
35 /*****************************************************************/
36 {
37  l1t::CaloStage2Nav caloNav;
38  egammas.clear();
39 
40  //EGammas without check of FG and shape ID
41  std::vector<l1t::EGamma> egammas_raw;
42 
43  for(const auto& cluster : clusters)
44  {
45  // Keep only valid clusters
46  if(cluster.isValid())
47  {
48  // need tower energies to recompute egamma trimmed energy
49  int iEta = cluster.hwEta();
50  int iPhi = cluster.hwPhi();
51  int iEtaP = caloNav.offsetIEta(iEta, 1);
52  int iEtaM = caloNav.offsetIEta(iEta, -1);
53  int iPhiP = caloNav.offsetIPhi(iPhi, 1);
54  int iPhiP2 = caloNav.offsetIPhi(iPhi, 2);
55  int iPhiM = caloNav.offsetIPhi(iPhi, -1);
56  int iPhiM2 = caloNav.offsetIPhi(iPhi, -2);
57  const l1t::CaloTower& seed = l1t::CaloTools::getTower(towers, iEta , iPhi );
58  const l1t::CaloTower& towerNW = l1t::CaloTools::getTower(towers, iEtaM, iPhiM);
59  const l1t::CaloTower& towerN = l1t::CaloTools::getTower(towers, iEta , iPhiM);
60  const l1t::CaloTower& towerNE = l1t::CaloTools::getTower(towers, iEtaP, iPhiM);
61  const l1t::CaloTower& towerE = l1t::CaloTools::getTower(towers, iEtaP, iPhi );
62  const l1t::CaloTower& towerSE = l1t::CaloTools::getTower(towers, iEtaP, iPhiP);
63  const l1t::CaloTower& towerS = l1t::CaloTools::getTower(towers, iEta , iPhiP);
64  const l1t::CaloTower& towerSW = l1t::CaloTools::getTower(towers, iEtaM, iPhiP);
65  const l1t::CaloTower& towerW = l1t::CaloTools::getTower(towers, iEtaM, iPhi );
66  const l1t::CaloTower& towerNN = l1t::CaloTools::getTower(towers, iEta , iPhiM2);
67  const l1t::CaloTower& towerSS = l1t::CaloTools::getTower(towers, iEta , iPhiP2);
68  //
69 
70  int seedEt = seed .hwPt();
71  int towerEtNW = towerNW.hwPt();
72  int towerEtN = towerN .hwPt();
73  int towerEtNE = towerNE.hwPt();
74  int towerEtE = towerE .hwPt();
75  int towerEtSE = towerSE.hwPt();
76  int towerEtS = towerS .hwPt();
77  int towerEtSW = towerSW.hwPt();
78  int towerEtW = towerW .hwPt();
79  int towerEtNN = towerNN.hwPt();
80  int towerEtSS = towerSS.hwPt();
81 
82  if(abs(iEta)> params_->egEtaCut() )
83  continue;
84 
85  // initialize egamma from cluster
86  egammas_raw.push_back(cluster);
87  l1t::EGamma& egamma = egammas_raw.back();
88 
89  // Trim cluster (only for egamma energy computation, the original cluster is unchanged)
90  l1t::CaloCluster clusterTrim = trimCluster(cluster);
91 
92  // Recompute hw energy (of the trimmed cluster) from towers
93  egamma.setHwPt(seedEt);
94  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NW)) egamma.setHwPt(egamma.hwPt() + towerEtNW);
95  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_N)) egamma.setHwPt(egamma.hwPt() + towerEtN);
96  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NE)) egamma.setHwPt(egamma.hwPt() + towerEtNE);
97  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_E)) egamma.setHwPt(egamma.hwPt() + towerEtE);
98  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SE)) egamma.setHwPt(egamma.hwPt() + towerEtSE);
99  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_S)) egamma.setHwPt(egamma.hwPt() + towerEtS);
100  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SW)) egamma.setHwPt(egamma.hwPt() + towerEtSW);
101  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_W)) egamma.setHwPt(egamma.hwPt() + towerEtW);
102  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NN)) egamma.setHwPt(egamma.hwPt() + towerEtNN);
103  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SS)) egamma.setHwPt(egamma.hwPt() + towerEtSS);
104 
105 
106  //Extended H/E flag computed using all neighbouring towers
107  bool HoE_ext = idHoverE_ext(seed);
108  HoE_ext &= idHoverE_ext(towerNW);
109  HoE_ext &= idHoverE_ext(towerN);
110  HoE_ext &= idHoverE_ext(towerNE);
111  HoE_ext &= idHoverE_ext(towerE);
112  HoE_ext &= idHoverE_ext(towerSE);
113  HoE_ext &= idHoverE_ext(towerS);
114  HoE_ext &= idHoverE_ext(towerSW);
115  HoE_ext &= idHoverE_ext(towerW);
116  //NN and SS only checked if included
117  if(cluster.checkClusterFlag(CaloCluster::INCLUDE_NN)) HoE_ext &= idHoverE_ext(towerNN);
118  if(cluster.checkClusterFlag(CaloCluster::INCLUDE_SS)) HoE_ext &= idHoverE_ext(towerSS);
119 
120 
121  // Identification of the egamma
122  // Based on the seed tower FG bit, the H/E ratio of the seed tower, and the shape of the cluster
123  bool hOverEBit = cluster.hOverE()>0 || params_->egBypassHoE();
124  bool hOverEExtBit = HoE_ext || params_->egBypassExtHOverE();
125  if(!params_->egBypassExtHOverE())
126  hOverEExtBit = HoE_ext;
127  bool shapeBit = idShape(cluster, egamma.hwPt()) || params_->egBypassShape();
128  bool fgBit = !(cluster.fgECAL()) || params_->egBypassECALFG();
129  int qual = 0;
130  if(fgBit) qual |= (0x1); // first bit = FG
131  if(hOverEBit) qual |= (0x1<<1); // second bit = H/E
132  if(shapeBit) qual |= (0x1<<2); // third bit = shape
133  if(hOverEExtBit) qual |= (0x1<<3); // fourth bit = shape
134  egamma.setHwQual( qual );
135 
136  // Isolation
137  int isoLeftExtension = params_->egIsoAreaNrTowersEta();
138  int isoRightExtension = params_->egIsoAreaNrTowersEta();
139 
140  if(cluster.checkClusterFlag(CaloCluster::TRIM_LEFT))
141  isoRightExtension++;
142  else
143  isoLeftExtension++;
144 
145  int hwEtSum = CaloTools::calHwEtSum(cluster.hwEta(), cluster.hwPhi(), towers,
146  -isoLeftExtension,isoRightExtension,
148  params_->egPUSParam(2));
149 
150  int hwFootPrint = isoCalEgHwFootPrint(cluster,towers);
151  int nrTowers = CaloTools::calNrTowers(-1*params_->egPUSParam(1),
152  params_->egPUSParam(1),
153  1,72,towers,1+params_->pileUpTowerThreshold(),999,CaloTools::CALO);
154  unsigned int lutAddress = isoLutIndex(egamma.hwEta(), nrTowers, egamma.hwPt());
155 
156  int isolBit = (((hwEtSum-hwFootPrint) < params_->egIsolationLUT()->data(lutAddress)) || (params_->egIsolationLUT()->data(lutAddress)>255));
157  int isolBit2 = (((hwEtSum-hwFootPrint) < params_->egIsolationLUT2()->data(lutAddress)) || (params_->egIsolationLUT2()->data(lutAddress)>255));
158  isolBit += (isolBit2 << 1);
159  egamma.setHwIso(isolBit);
160  int hwIsoEnergy = hwEtSum-hwFootPrint;
161 
162  // development vars
163  egamma.setTowerIPhi((short int)cluster.hwPhi());
164  egamma.setTowerIEta((short int)cluster.hwEta());
165  egamma.setRawEt((short int)egamma.hwPt());
166  egamma.setIsoEt((short int)hwIsoEnergy);
167  egamma.setFootprintEt((short int)hwFootPrint);
168  egamma.setNTT((short int)nrTowers);
169  egamma.setShape((short int)returnShape(cluster));
170  egamma.setTowerHoE((short int)returnHoE(seed));
171 
172  // Energy calibration
173  // Corrections function of ieta, ET, and cluster shape
174  int calibPt = calibratedPt(cluster, egamma.hwPt());
175  egamma.setHwPt(calibPt);
176 
177  // Physical eta/phi. Computed from ieta/iphi of the seed tower and the fine-grain position within the seed
178  double eta = 0.;
179  double phi = 0.;
180  double seedEta = CaloTools::towerEta(cluster.hwEta());
181  double seedEtaSize = CaloTools::towerEtaSize(cluster.hwEta());
182  double seedPhi = CaloTools::towerPhi(cluster.hwEta(), cluster.hwPhi());
183  double seedPhiSize = CaloTools::towerPhiSize(cluster.hwEta());
184  if(cluster.fgEta()==0) eta = seedEta; // center
185  //Test
186  else if(cluster.fgEta()==2) eta = seedEta + seedEtaSize*0.251; // center + 1/4
187  else if(cluster.fgEta()==1) eta = seedEta - seedEtaSize*0.251; // center - 1/4
188 
189 
190  //fgPhi is recomputed after trimming
191  int fgPhi = 0;
192 
193  int EtUp = 0;
194  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NE)) EtUp += towerEtNE;
195  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_N)) EtUp += towerEtN;
196  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NW)) EtUp += towerEtNW;
197  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_NN)) EtUp += towerEtNN;
198  int EtDown = 0;
199  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SE)) EtDown += towerEtSE;
200  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_S)) EtDown += towerEtS;
201  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SW)) EtDown += towerEtSW;
202  if(clusterTrim.checkClusterFlag(CaloCluster::INCLUDE_SS)) EtDown += towerEtSS;
203  //
204  if(EtDown>EtUp) fgPhi = 2;
205  else if(EtUp>EtDown) fgPhi = 1;
206 
207 
208  if(fgPhi==0) phi = seedPhi; // center
209  else if(fgPhi==2) phi = seedPhi + seedPhiSize*0.251; // center + 1/4
210  else if(fgPhi==1) phi = seedPhi - seedPhiSize*0.251; // center - 1/4
211 
212 
213  // Set 4-vector
214  math::PtEtaPhiMLorentzVector calibP4((double)calibPt*params_->egLsb(), eta, phi, 0.);
215  egamma.setP4(calibP4);
216 
217  }//end of cuts on cluster to make EGamma
218  }//end of cluster loop
219 
220  // prepare content to be sorted -- each phi ring contains 18 elements, with Et = 0 if no candidate exists
222  l1t::EGamma tempEG (emptyP4, 0, 0, 0, 0);
223  std::vector< std::vector<l1t::EGamma> > egEtaPos( params_->egEtaCut() , std::vector<l1t::EGamma>(18, tempEG));
224  std::vector< std::vector<l1t::EGamma> > egEtaNeg( params_->egEtaCut() , std::vector<l1t::EGamma>(18, tempEG));
225  for (unsigned int iEG = 0; iEG < egammas_raw.size(); iEG++)
226  {
227  int fgBit = egammas_raw.at(iEG).hwQual() & (0x1);
228  int hOverEBit = egammas_raw.at(iEG).hwQual()>>1 & (0x1);
229  int shapeBit = egammas_raw.at(iEG).hwQual()>>2 & (0x1);
230  int hOverEExtBit = egammas_raw.at(iEG).hwQual()>>3 & (0x1);
231 
232  bool IDcuts = (fgBit && hOverEBit && shapeBit && hOverEExtBit) || (egammas_raw.at(iEG).pt()>=params_->egMaxPtHOverE()) || (params_->egBypassEGVetos());
233 
234  if(!IDcuts) continue;
235  egammas_raw.at(iEG).setHwQual( 7 ); //Default value in firmware, not used
236 
237  if (egammas_raw.at(iEG).hwEta() > 0) egEtaPos.at( egammas_raw.at(iEG).hwEta()-1).at((72-egammas_raw.at(iEG).hwPhi())/4) = egammas_raw.at(iEG);
238  else egEtaNeg.at( -(egammas_raw.at(iEG).hwEta()+1)).at((72-egammas_raw.at(iEG).hwPhi())/4) = egammas_raw.at(iEG);
239  }
240 
241  AccumulatingSort <l1t::EGamma> etaPosSorter(6);
242  AccumulatingSort <l1t::EGamma> etaNegSorter(6);
243  std::vector<l1t::EGamma> accumEtaPos;
244  std::vector<l1t::EGamma> accumEtaNeg;
245 
246  for( int ieta = 0 ; ieta < params_->egEtaCut() ; ++ieta)
247  {
248  // eta +
249  std::vector<l1t::EGamma>::iterator start_, end_;
250  start_ = egEtaPos.at(ieta).begin();
251  end_ = egEtaPos.at(ieta).end();
252  BitonicSort<l1t::EGamma>(down, start_, end_);
253  etaPosSorter.Merge( egEtaPos.at(ieta) , accumEtaPos );
254 
255  // eta -
256  start_ = egEtaNeg.at(ieta).begin();
257  end_ = egEtaNeg.at(ieta).end();
258  BitonicSort<l1t::EGamma>(down, start_, end_);
259  etaNegSorter.Merge( egEtaNeg.at(ieta) , accumEtaNeg );
260 
261  }
262 
263  // put all 12 candidates in the original tau vector, removing zero energy ones
264  egammas.clear();
265  for (l1t::EGamma acceg : accumEtaPos)
266  {
267  if (acceg.hwPt() > 0) egammas.push_back(acceg);
268  }
269  for (l1t::EGamma acceg : accumEtaNeg)
270  {
271  if (acceg.hwPt() > 0) egammas.push_back(acceg);
272  }
273 
274 }
275 
276 
277 /*****************************************************************/
279 /*****************************************************************/
280 {
281  unsigned int shape = 0;
282  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_N)) ) shape |= (0x1);
283  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_S)) ) shape |= (0x1<<1);
284  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)) ) shape |= (0x1<<2);
285  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)) ) shape |= (0x1<<2);
286  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)) ) shape |= (0x1<<3);
287  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)) ) shape |= (0x1<<3);
288  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)) ) shape |= (0x1<<4);
289  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)) ) shape |= (0x1<<4);
290  if( clus.checkClusterFlag(CaloCluster::INCLUDE_NN) ) shape |= (0x1<<5);
291  if( clus.checkClusterFlag(CaloCluster::INCLUDE_SS) ) shape |= (0x1<<6);
292 
293  unsigned int lutAddress = idShapeLutIndex(clus.hwEta(), hwPt, shape);
294  bool shapeBit = ((params_->egCalibrationLUT()->data(lutAddress))>>9) & 0x1;
295 
296  return shapeBit;
297 }
298 
299 /*****************************************************************/
301 /*****************************************************************/
302 {
303  if(params_->egShapeIdType()=="compressed")
304  {
305  unsigned int iEtaNormed = abs(iEta);
306  if(iEtaNormed>28) iEtaNormed = 28;
307  if(E>255) E = 255;
308  unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
309  unsigned int compressedE = params_->egCompressShapesLUT()->data((0x1<<7)+E);
310  unsigned int compressedEta = params_->egCompressShapesLUT()->data((0x1<<7)+(0x1<<8)+iEtaNormed);
311  return (compressedShape | compressedE | compressedEta);
312  }
313  else // Uncompressed (kept for backward compatibility)
314  {
315  unsigned int iEtaNormed = abs(iEta);
316  if(iEtaNormed>28) iEtaNormed = 28;
317  if(E>255) E = 255;
318  unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
319  return E+compressedShape*256+(iEtaNormed-1)*256*64;
320  }
321 }
322 
323 //calculates the footprint of the electron in hardware values
324 /*****************************************************************/
325 int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::isoCalEgHwFootPrint(const l1t::CaloCluster& clus,const std::vector<l1t::CaloTower>& towers)
326 /*****************************************************************/
327 {
328  int iEta=clus.hwEta();
329  int iPhi=clus.hwPhi();
330 
331  // hwEmEtSumLeft = CaloTools::calHwEtSum(iEta,iPhi,towers,-1,-1,-1,1,CaloTools::ECAL);
332  // int hwEmEtSumRight = CaloTools::calHwEtSum(iEta,iPhi,towers,1,1,-1,1,CaloTools::ECAL);
333 
334  int etaSide = clus.checkClusterFlag(CaloCluster::TRIM_LEFT) ? 1 : -1; //if we trimed left, its the right (ie +ve) side we want
335  int phiSide = iEta>0 ? 1 : -1;
336 
337  int ecalHwFootPrint = CaloTools::calHwEtSum(iEta,iPhi,towers,0,0,
340  CaloTools::calHwEtSum(iEta,iPhi,towers,etaSide,etaSide,
343 
344  //Because of compression E+H can be different from E + H
345  int ecalHwFootPrint_2x1 = CaloTools::calHwEtSum(iEta,iPhi,towers,0,0,0,0,params_->egPUSParam(2),CaloTools::ECAL) +
346  CaloTools::calHwEtSum(iEta,iPhi,towers,0,0,phiSide,phiSide,params_->egPUSParam(2),CaloTools::ECAL);
347 
348  int ecalhcal_HwFootPrint_2x1 = CaloTools::calHwEtSum(iEta,iPhi,towers,0,0,0,0,params_->egPUSParam(2)) +
349  CaloTools::calHwEtSum(iEta,iPhi,towers,0,0,phiSide,phiSide,params_->egPUSParam(2));
350 
351  return ecalHwFootPrint-ecalHwFootPrint_2x1+ecalhcal_HwFootPrint_2x1;
352 
353 }
354 
355 //ieta =-28, nrTowers 0 is 0, increases to ieta28, nrTowers=kNrTowersInSum
356 /*****************************************************************/
357 unsigned l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::isoLutIndex(int iEta,unsigned int nrTowers,int E)
358 /*****************************************************************/
359 {
360 
361  if(params_->egIsolationType()=="compressed")
362  {
363  if(nrTowers>255) nrTowers = 255;
364  unsigned int iEtaNormed = abs(iEta);
365  if(iEtaNormed>28) iEtaNormed = 28;
366  if(E>255) E = 255;
367  unsigned int compressednTT = params_->egCompressShapesLUT()->data((0x1<<7)+(0x1<<8)+(0x1<<5)+nrTowers);
368  unsigned int compressedE = params_->egCompressShapesLUT()->data((0x1<<7)+E)<<1;
369  unsigned int compressedEta = params_->egCompressShapesLUT()->data((0x1<<7)+(0x1<<8)+iEtaNormed)<<1;
370 
371  return (compressednTT | compressedE | compressedEta);
372  }
373 
374  else // Uncompressed (kept for backward compatibility)
375  {
376  const unsigned int kNrTowersInSum=72*params_->egPUSParam(1)*2;
377  const unsigned int kTowerGranularity=params_->egPUSParam(0);
378  const unsigned int kMaxAddress = kNrTowersInSum%kTowerGranularity==0 ? (kNrTowersInSum/kTowerGranularity+1)*28*2 :
379  (kNrTowersInSum/kTowerGranularity)*28*2;
380 
381  unsigned int nrTowersNormed = nrTowers/kTowerGranularity;
382 
383  unsigned int iEtaNormed = iEta+28;
384  if(iEta>0) iEtaNormed--; //we skip zero
385 
386  if(std::abs(iEta)>28 || iEta==0 || nrTowers>kNrTowersInSum) return kMaxAddress;
387  else return iEtaNormed*(kNrTowersInSum/kTowerGranularity+1)+nrTowersNormed;
388  }
389 
390 }
391 
392 /*****************************************************************/
394 /*****************************************************************/
395 {
396  unsigned int shape = 0;
397  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_N)) ) shape |= (0x1);
398  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_S)) ) shape |= (0x1<<1);
399  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)) ) shape |= (0x1<<2);
400  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)) ) shape |= (0x1<<2);
401  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)) ) shape |= (0x1<<3);
402  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)) ) shape |= (0x1<<3);
403  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)) ) shape |= (0x1<<4);
404  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)) ) shape |= (0x1<<4);
405  if( clus.checkClusterFlag(CaloCluster::INCLUDE_NN) ) shape |= (0x1<<5);
406  if( clus.checkClusterFlag(CaloCluster::INCLUDE_SS) ) shape |= (0x1<<6);
407 
408  unsigned int lutAddress = calibrationLutIndex(clus.hwEta(), hwPt, shape);
409  int corr = params_->egCalibrationLUT()->data(lutAddress) & (0x1ff);// 9 bits. [0,2]. corrPt = (corr)*rawPt
410  // the correction can increase or decrease the energy
411  int rawPt = hwPt;
412  int corrXrawPt = corr*rawPt;// 17 bits
413  // round corr*rawPt
414  int corrPt = corrXrawPt>>8;// 8 MS bits (truncation)
415 
416  //12 bits saturation
417  if(corrPt>4095)
418  corrPt = 4095;
419 
420  return corrPt;
421 }
422 
423 /*****************************************************************/
425 /*****************************************************************/
426 {
427  if(params_->egCalibrationType()=="compressed")
428  {
429  unsigned int iEtaNormed = abs(iEta);
430  if(iEtaNormed>28) iEtaNormed = 28;
431  if(E>255) E = 255;
432  unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
433  unsigned int compressedE = params_->egCompressShapesLUT()->data((0x1<<7)+E);
434  unsigned int compressedEta = params_->egCompressShapesLUT()->data((0x1<<7)+(0x1<<8)+iEtaNormed);
435  return (compressedShape | compressedE | compressedEta);
436  }
437  else // Uncompressed (kept for backward compatibility)
438  {
439  unsigned int iEtaNormed = abs(iEta);
440  if(iEtaNormed>28) iEtaNormed = 28;
441  if(E>255) E = 255;
442  if(E<22) E = 22;
443  unsigned int compressedShape = params_->egCompressShapesLUT()->data(shape);
444  if(compressedShape>31) compressedShape = 31;
445  return (E-20)+compressedShape*236+(iEtaNormed-1)*236*32;
446  }
447 }
448 
449 /*****************************************************************/
451 /*****************************************************************/
452 {
453  l1t::CaloCluster clusCopy = clus;
454 
455  unsigned int shape = 0;
456  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_N)) ) shape |= (0x1);
457  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_S)) ) shape |= (0x1<<1);
458  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)) ) shape |= (0x1<<2);
459  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)) ) shape |= (0x1<<2);
460  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)) ) shape |= (0x1<<3);
461  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)) ) shape |= (0x1<<3);
462  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)) ) shape |= (0x1<<4);
463  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)) ) shape |= (0x1<<4);
464  if( clus.checkClusterFlag(CaloCluster::INCLUDE_NN) ) shape |= (0x1<<5);
465  if( clus.checkClusterFlag(CaloCluster::INCLUDE_SS) ) shape |= (0x1<<6);
466 
467  unsigned int lutAddress = trimmingLutIndex(shape, clus.hwEta());
468  unsigned int shapeTrim = params_->egTrimmingLUT()->data(lutAddress);
469  // apply trimming flags
470  clusCopy.setClusterFlag(CaloCluster::INCLUDE_N, ( shapeTrim&(0x1) ) ? true : false);
471  clusCopy.setClusterFlag(CaloCluster::INCLUDE_S, ( shapeTrim&(0x1<<1) ) ? true : false);
472  clusCopy.setClusterFlag(CaloCluster::INCLUDE_NN, ( shapeTrim&(0x1<<5) ) ? true : false);
473  clusCopy.setClusterFlag(CaloCluster::INCLUDE_SS, ( shapeTrim&(0x1<<6) ) ? true : false);
475  {
476  clusCopy.setClusterFlag(CaloCluster::INCLUDE_E, ( shapeTrim&(0x1<<2) ) ? true : false);
477  clusCopy.setClusterFlag(CaloCluster::INCLUDE_NE, ( shapeTrim&(0x1<<3) ) ? true : false);
478  clusCopy.setClusterFlag(CaloCluster::INCLUDE_SE, ( shapeTrim&(0x1<<4) ) ? true : false);
479  }
480  else
481  {
482  clusCopy.setClusterFlag(CaloCluster::INCLUDE_W, ( shapeTrim&(0x1<<2) ) ? true : false);
483  clusCopy.setClusterFlag(CaloCluster::INCLUDE_NW, ( shapeTrim&(0x1<<3) ) ? true : false);
484  clusCopy.setClusterFlag(CaloCluster::INCLUDE_SW, ( shapeTrim&(0x1<<4) ) ? true : false);
485  }
486  return clusCopy;
487 }
488 
489 /*****************************************************************/
490 unsigned int l1t::Stage2Layer2EGammaAlgorithmFirmwareImp1::trimmingLutIndex(unsigned int shape, int iEta)
491 /*****************************************************************/
492 {
493  unsigned int iEtaNormed = abs(iEta)-1;
494  if(iEtaNormed>31) iEtaNormed = 31;
495  if(shape>127) shape = 127;
496  unsigned int index = iEtaNormed*128+shape;
497  return index;
498 }
499 
500 /*****************************************************************/
502 /*****************************************************************/
503 {
504 
505  unsigned int shape = 0;
506  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_N)) ) shape |= (0x1);
507  if( (clus.checkClusterFlag(CaloCluster::INCLUDE_S)) ) shape |= (0x1<<1);
508  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_E)) ) shape |= (0x1<<2);
509  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_W)) ) shape |= (0x1<<2);
510  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NE)) ) shape |= (0x1<<3);
511  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_NW)) ) shape |= (0x1<<3);
512  if( clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SE)) ) shape |= (0x1<<4);
513  if( !clus.checkClusterFlag(CaloCluster::TRIM_LEFT) && (clus.checkClusterFlag(CaloCluster::INCLUDE_SW)) ) shape |= (0x1<<4);
514  if( clus.checkClusterFlag(CaloCluster::INCLUDE_NN) ) shape |= (0x1<<5);
515  if( clus.checkClusterFlag(CaloCluster::INCLUDE_SS) ) shape |= (0x1<<6);
516 
517  return shape;
518 }
519 
520 
521 
522 
523 /*****************************************************************/
525 /*****************************************************************/
526 {
527 
528  int ratio = tow.hwEtRatio();
529  int qual = tow.hwQual();
530  bool denomZeroFlag = ((qual&0x1) > 0);
531  bool eOverHFlag = ((qual&0x2) > 0);
532 
533  if (denomZeroFlag && !eOverHFlag) //E=0
534  ratio = -1;
535  if (denomZeroFlag && eOverHFlag) //H=0
536  ratio = 8; // ratio is on 3 bits, so 8 should be ok for overflow
537  if (!denomZeroFlag && !eOverHFlag) // H > E
538  ratio = -1;
539  //else E >= H , so ratio=log(E/H)
540 
541  return ratio;
542 
543 }
544 
545 
546 
547 
549 
550  int qual = tow.hwQual();
551  bool eOverHFlag = ((qual&0x2) > 0);
552 
553  if(tow.hwPt()<=10) return true; //Only applied for towers with ET>5 GeV
554  else return eOverHFlag;
555 
556 }
static float towerEta(int ieta)
Definition: CaloTools.cc:171
void setRawEt(short int pt)
Definition: EGamma.cc:51
unsigned isoLutIndex(int iEta, unsigned int nrTowers, int E)
static float towerPhi(int ieta, int iphi)
Definition: CaloTools.cc:179
void Merge(const std::vector< T > &aInput, std::vector< T > &aOutput)
static int offsetIEta(int iEta, int offset)
Definition: CaloStage2Nav.h:44
static float towerEtaSize(int ieta)
Definition: CaloTools.cc:186
int hwEtRatio() const
Definition: CaloTower.cc:74
static int calHwEtSum(int iEta, int iPhi, const std::vector< l1t::CaloTower > &towers, int localEtaMin, int localEtaMax, int localPhiMin, int localPhiMax, SubDet etMode=CALO)
Definition: CaloTools.cc:109
unsigned egIsoAreaNrTowersPhi() const
l1t::LUT const * egIsolationLUT2() const
double pt() const final
transverse momentum
void setHwQual(int qual)
Definition: L1Candidate.h:44
int hwPhi() const
Definition: L1Candidate.h:50
int isoCalEgHwFootPrint(const l1t::CaloCluster &, const std::vector< l1t::CaloTower > &)
delete x;
Definition: CaloConfig.h:22
unsigned egBypassShape() const
unsigned egBypassEGVetos() const
l1t::LUT const * egIsolationLUT() const
l1t::LUT * egCompressShapesLUT()
PtEtaPhiMLorentzVectorD PtEtaPhiMLorentzVector
Lorentz vector with cartesian internal representation.
Definition: LorentzVector.h:25
l1t::LUT const * egCalibrationLUT() const
std::string const & egIsolationType() const
bool checkClusterFlag(ClusterFlag flag) const
Definition: CaloCluster.cc:66
void setTowerHoE(short int HoE)
Definition: EGamma.cc:71
unsigned egIsoVetoNrTowersPhi() const
void setNTT(short int ntt)
Definition: EGamma.cc:63
static int offsetIPhi(int iPhi, int offset)
Definition: CaloStage2Nav.h:33
static size_t calNrTowers(int iEtaMin, int iEtaMax, int iPhiMin, int iPhiMax, const std::vector< l1t::CaloTower > &towers, int minHwEt, int maxHwEt, SubDet etMode=CALO)
Definition: CaloTools.cc:139
int pileUpTowerThreshold() const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void setFootprintEt(short int fp)
Definition: EGamma.cc:59
l1t::CaloCluster trimCluster(const l1t::CaloCluster &clus)
int hwEta() const
Definition: L1Candidate.h:49
void processEvent(const std::vector< CaloCluster > &clusters, const std::vector< CaloTower > &towers, std::vector< EGamma > &egammas) override
int hwQual() const
Definition: L1Candidate.h:51
JetCorrectorParameters corr
Definition: classes.h:5
double egPUSParam(int ipar) const
static float towerPhiSize(int ieta)
Definition: CaloTools.cc:193
std::string const & egShapeIdType() const
void setHwIso(int iso)
Definition: L1Candidate.h:45
void setTowerIEta(short int ieta)
Definition: EGamma.cc:43
int hwPt() const
Definition: L1Candidate.h:48
double egMaxPtHOverE() const
unsigned egBypassHoE() const
void setShape(short int s)
Definition: EGamma.cc:67
void setIsoEt(short int iso)
Definition: EGamma.cc:55
std::string const & egCalibrationType() const
double b
Definition: hdecay.h:120
unsigned egBypassExtHOverE() const
static const l1t::CaloTower & getTower(const std::vector< l1t::CaloTower > &towers, int iEta, int iPhi)
Definition: CaloTools.cc:37
unsigned egBypassECALFG() const
void setHwPt(int pt)
Definition: L1Candidate.h:41
double a
Definition: hdecay.h:121
void setTowerIPhi(short int iphi)
Definition: EGamma.cc:47
int data(unsigned int address) const
Definition: LUT.h:46
bool operator>(const l1t::Jet &a, l1t::Jet &b)
unsigned egIsoAreaNrTowersEta() const
void setP4(const LorentzVector &p4) final
set 4-momentum
void setClusterFlag(ClusterFlag flag, bool val=true)
Definition: CaloCluster.cc:19