ATLAS Offline Software
EFexEMClusterTool.cxx
Go to the documentation of this file.
1 // Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2 
10 #include "EFexEMClusterTool.h"
12 
13 
14 LVL1::EFexEMClusterTool::EFexEMClusterTool(const std::string& type, const std::string& name, const IInterface* parent)
16 {
17  declareProperty("CleanCellContainer", m_useProvenance=true);
18  declareProperty("QualBitMask", m_qualBitMask=0x40);
19 
20  // baseline selection properties
21  declareProperty("ClusterEnergyThreshold", m_clustET_thresh = 28., "Cluster energy threshold for baseline selection");
22  declareProperty("EnergyThresholdToApplyIsolation", m_clustET_NoIso_thresh = 60., "Cluster energy above which no isolation cut is applied for baseline selection");
23  declareProperty("REtaThreshold", m_REta_thresh = 0.12, "Reta cut for baseline selection");
24  declareProperty("RHadThreshold", m_RHad_thresh = 0.16, "Rhad cut for baseline selection");
25  declareProperty("L1WidthThreshold", m_L1Width_thresh = 0.02, "L1Width cut for baseline selection");
26  declareProperty("EtaThresholdToApplyL1Width", m_eta_dropL1Width = 2.3, "Eta outside of which no L1Width cut is applied for baseline selection");
27 
28  // loose selection properties
29  declareProperty("UseTileCells", m_use_tileCells = false);
30  declareProperty("NominalDigitizationValue", m_nominalDigitization = 25.);
31  declareProperty("NominalNoiseThreshold", m_nominalNoise_thresh = 100.);
32  declareProperty("TileNoiseThreshold", m_tileNoise_tresh = 100.);
33  declareProperty("EtaWidthTDRCluster", m_etaWidth_TDRCluster = 3);
34  declareProperty("PhiWidthTDRCluster", m_phiWidth_TDRCluster = 2);
35  declareProperty("EtaWidthWStotIsolation", m_etaWidth_wstotIsolation = 5);
36  declareProperty("PhiWidthWStotIsolation", m_phiWidth_wstotIsolation = 3);
37  declareProperty("EtaEMWidthRHadIsolation", m_etaEMWidth_RHadIsolation = 3); // 1 for a 1-eta-tower had cluster, 5 for 2-tower, 9 for 3-tower
38  declareProperty("PhiEMWidthRHadIsolation", m_phiEMWidth_RHadIsolation = 3);
39  declareProperty("EtaWidthREtaIsolationDenominator", m_etaWidth_REtaIsolation_den = 7);
40  declareProperty("PhiWidthREtaIsolationDenominator", m_phiWidth_REtaIsolation_den = 3);
41  declareProperty("EtaWidthREtaIsolationNumerator", m_etaWidth_REtaIsolation_num = 3);
42  declareProperty("PhiWidthREtaIsolationNumerator", m_phiWidth_REtaIsolation_num = 2);
43  declareProperty("ClusterEnergyThresholdLooseEFEX", m_clustET_looseAlg_thresh = 10.);
44  declareProperty("EtaHadWidthRHadIsolation", m_etaHadWidth_RHadIsolation = 9); // 1 for a 1-eta-tower had cluster, 5 for 2-tower, 9 for 3-tower
45  declareProperty("PhiHadWidthRHadIsolation", m_phiHadWidth_RHadIsolation = 3);
46 }
47 
48 std::vector<LVL1::EFexEMClusterTool::AlgResult>
49 LVL1::EFexEMClusterTool::clusterAlg(bool applyBaselineCuts,
50  const CaloConstCellContainer* scells, const xAOD::TriggerTowerContainer* TTs,
51  const CaloCell_SuperCell_ID* idHelper, const TileID* tileIDHelper,
52  const CaloConstCellContainer* tileCellCon) const
53 {
54  std::vector<AlgResult> baselineClusters;
55  for (auto & cluster : looseAlg(scells, TTs, idHelper, tileIDHelper, tileCellCon) ) {
56 
57  // cluster E_T
58  cluster.passClusterEnergy = cluster.clusterET >= m_clustET_thresh; // if ET cut passes
59 
60  // R_eta
61  cluster.passREta = cluster.rEta <= m_REta_thresh || // if reta cut passes
62  cluster.clusterET > m_clustET_NoIso_thresh; // or ET above threshold where any isolation is applied
63 
64  // R_had
65  cluster.passRHad = cluster.rHad <= m_RHad_thresh || // if rhad cut passes
66  cluster.clusterET > m_clustET_NoIso_thresh; // or ET above threshold where any isolation is applied
67 
68  // Wstot
69  cluster.passWstot = cluster.l1Width < m_L1Width_thresh || // if cut passes
70  std::abs(cluster.eta) > m_eta_dropL1Width || // or eta outside range where cut is applied
71  cluster.clusterET > m_clustET_NoIso_thresh; // or ET above threshold where any isolation is applied
72 
73  bool passBaseLineSelection = cluster.passClusterEnergy &&
74  cluster.passRHad &&
75  cluster.passREta &&
76  cluster.passWstot;
77 
78  if (applyBaselineCuts and not passBaseLineSelection ) {
79  continue;
80  }
81 
82  baselineClusters.push_back(cluster);
83  }
84  return baselineClusters;
85 }
86 
87 std::vector<LVL1::EFexEMClusterTool::AlgResult>
89  const CaloCell_SuperCell_ID* idHelper, const TileID* tileIDHelper,
90  const CaloConstCellContainer* tileCellCon ) const
91 {
92  std::vector<AlgResult> result;
93  // Loops through and find L2 SCs that are local maxes and adds to list of local maxes if cluster ET is at least 10GeV
94  std::vector<const CaloCell*> potentialCentres;
95  for (auto ithCell : *SCs) {
96  if ( !( std::abs(CaloCellET(ithCell, m_nominalDigitization, m_nominalNoise_thresh)) > 0) ) {
97  continue;
98  }
99  Identifier ithID = ithCell->ID();
100  if (idHelper->sampling(ithID) != 2) {
101  continue;
102  }
103 
104  if (idHelper->sub_calo(ithID) != 0) {
105  continue;
106  }
107 
108  bool inEfexCoverage = false;
109  if ( std::abs(idHelper->pos_neg(ithID)) < 3) {
110  inEfexCoverage = true;
111  }
112 
113  if (!inEfexCoverage) {
114  continue;
115  }
116 
117  if (localMax(SCs, ithCell, idHelper, m_nominalDigitization, m_nominalNoise_thresh)) {
118  potentialCentres.push_back(ithCell);
119  }
120  }
121 
122  // Looops through the local maxes and skips the less energetic ones that belong to the same TT
123  for (auto ithCell : potentialCentres){
124  bool useSC = true;
125  for (auto jthCell : potentialCentres){
126  if (jthCell == ithCell) continue;
127  if (!SameTT(ithCell, jthCell, idHelper)) continue;
128  float ithEt = CaloCellET(ithCell, m_nominalDigitization, m_nominalNoise_thresh);
129  float jthEt = CaloCellET(jthCell, m_nominalDigitization, m_nominalNoise_thresh);
130  if (ithEt > jthEt) continue;
131  if (ithEt == jthEt && ithCell->eta() > jthCell->eta()) continue;
132  useSC = false;
133  }
135  float clustET = EMClusET(ithCell, m_etaWidth_TDRCluster, m_phiWidth_TDRCluster, SCs, idHelper, m_nominalDigitization, m_nominalNoise_thresh)/1000.;
136  if (clustET < m_clustET_looseAlg_thresh) useSC = false;
137 
138  if (useSC) {
139  float HadET = -999;
140  float ithRHad = -1;
141  float ithEta = ithCell->eta();
142  float ithPhi = ithCell->phi();
143  float ithREta = REta( ithCell, m_etaWidth_REtaIsolation_num, m_phiWidth_REtaIsolation_num, m_etaWidth_REtaIsolation_den,
144  m_phiWidth_REtaIsolation_den, SCs, idHelper, m_nominalDigitization, m_nominalNoise_thresh);
145  if (!m_use_tileCells) {
146  ithRHad = RHad(ithCell, m_etaEMWidth_RHadIsolation, m_phiEMWidth_RHadIsolation, SCs, TTs, idHelper, m_nominalDigitization, m_nominalNoise_thresh, HadET);
147  } else {
148  ithRHad = RHadTile(ithCell, m_etaEMWidth_RHadIsolation, m_phiEMWidth_RHadIsolation, SCs, idHelper, m_nominalDigitization, m_nominalNoise_thresh, tileIDHelper, tileCellCon, m_tileNoise_tresh, HadET);
149  }
150 
151  float ithL1Width = L1Width( ithCell, m_etaWidth_wstotIsolation, m_phiWidth_wstotIsolation, SCs,
152  idHelper, m_nominalDigitization, m_nominalNoise_thresh);
153  float L2ClusterET33 = L2clusET( ithCell, 3, 3, SCs, idHelper, m_nominalDigitization, m_nominalNoise_thresh)/1e3;
154  float L2ClusterET37 = L2clusET( ithCell, 7, 3, SCs, idHelper, m_nominalDigitization, m_nominalNoise_thresh)/1e3;
155 
156  float ithREtaL12{-1};
157  if (m_use_REtaL12) {
158  ithREtaL12 = REtaL12(ithCell, m_etaWidth_REtaIsolation_num, m_phiWidth_REtaIsolation_num,
159  m_etaWidth_REtaIsolation_den, m_phiWidth_REtaIsolation_den, SCs, idHelper,
160  m_nominalDigitization, m_nominalNoise_thresh);
161  }
162  result.push_back(AlgResult{ithEta, ithPhi, clustET, ithREta, ithRHad, ithL1Width, HadET, L2ClusterET33, L2ClusterET37, ithREtaL12});
163  }
164  }
165  return result;
166 }
167 
172 float
173 LVL1::EFexEMClusterTool::CaloCellET(const CaloCell* const &inputCell, float digitScale, float digitThreshold) const
174 {
175  if (inputCell==nullptr) return 0.;
176  // Check that timing is correct
177  if ( m_useProvenance ) {
178  bool correctProv = (inputCell->provenance() & m_qualBitMask);
179  if (!correctProv) return 0.;
180  }
181  // Calculates the ET (before digitization)
182  float inputCell_energy = inputCell->energy();
183  float inputCell_eta = inputCell->eta();
184  float inputCell_ET = inputCell_energy / cosh(inputCell_eta);
185  // Check to see if negative ET values are allowed
186  bool allowNegs = false;
187  if (digitScale < 0.){
188  digitScale = std::abs(digitScale);
189  allowNegs = true;
190  }
191  if (inputCell_ET==0) return 0.;
192  else if (digitScale==0) return inputCell_ET;
193  if (allowNegs || inputCell_ET>0.){
194  // Split up ET into magnitude & whether it's positive or negative
195  float posOrNeg = inputCell_ET / std::abs(inputCell_ET);
196  inputCell_ET = std::abs(inputCell_ET);
197  // If no digitisation, return ET following noise cut
198  if (digitScale == 0){
199  if (inputCell_ET>digitThreshold) return inputCell_ET*posOrNeg;
200  else return 0.;
201  }
202  // Apply digitization & then noise cut
203  else {
204  float divET = inputCell_ET / digitScale;
205  int roundET = divET;
206  float result = digitScale * roundET;
207  if (digitThreshold == 0) return result*posOrNeg;
208  else if (result >= digitThreshold) return result*posOrNeg;
209  else return 0;
210  }
211  }
212  else return 0.;
213 }
214 
215 bool
216 LVL1::EFexEMClusterTool::SameTT(const CaloCell* inputCell1, const CaloCell* inputCell2, const CaloCell_SuperCell_ID* &idHelper) const
217 {
218  const Identifier ID1 = inputCell1->ID();
219  int phi1 = idHelper->phi(ID1);
220  const Identifier ID2 = inputCell2->ID();
221  int phi2 = idHelper->phi(ID2);
222  if (phi1 != phi2) {
223  return false;
224  }
225  int pn1 = idHelper->pos_neg(ID1);
226  int pn2 = idHelper->pos_neg(ID2);
227  if (pn1 != pn2) {
228  return false;
229  }
230  // Is barrel
231  if (abs(pn1)==1) {
232  int reg1 = idHelper->region(ID1);
233  int reg2 = idHelper->region(ID2);
234  if (reg1 != reg2) {
235  return false;
236  }
237  int etaDiv1 = idHelper->eta(ID1)/4;
238  int etaDiv2 = idHelper->eta(ID2)/4;
239  if (etaDiv1 == etaDiv2) {
240  return true;
241  }
242  else {
243  return false;
244  }
245  }
246  // OW
247  else if (abs(pn1)==2){
248  int reg1 = idHelper->region(ID1);
249  int reg2 = idHelper->region(ID2);
250  int eta1 = idHelper->eta(ID1);
251  int eta2 = idHelper->eta(ID2);
252  if ((reg1 == 0 && reg2 == 1 && eta2 < 3 ) || (reg2 == 0 && reg1 == 1 && eta1 < 3 )) return true;
253  else {
254  if (reg1 != reg2) return false;
255  int etaDiv1 = (idHelper->eta(ID1) - 3)/4;
256  int etaDiv2 = (idHelper->eta(ID2) - 3)/4;
257  if (etaDiv1 == etaDiv2) return true;
258  else return false;
259  }
260  }
261  else return false;
262 }
263 
264 bool
265 LVL1::EFexEMClusterTool::localMax(const CaloConstCellContainer* &inputContainer, const CaloCell* inputCell,
266  const CaloCell_SuperCell_ID* &idHelper, float digitScale, float digitThreshold) const
267 {
268  return localMax(inputContainer, inputCell, 0, idHelper, digitScale, digitThreshold);
269 }
270 
271 bool
272 LVL1::EFexEMClusterTool::localMax(const CaloConstCellContainer* &inputContainer, const CaloCell* inputCell, int numOthers,
273  const CaloCell_SuperCell_ID* &idHelper, float digitScale, float digitThreshold) const
274 {
275  if (inputCell == nullptr) return false;
276  // Get ID info
277  const Identifier inputID = inputCell->ID();
278  const int sub_calo = idHelper->sub_calo(inputID);
279  const int pos_neg = idHelper->pos_neg(inputID);
280  if (!(sub_calo == 0 || sub_calo == 1) || !(abs(pos_neg) < 4)){
281  ATH_MSG_DEBUG ( "Issue with local max logic");
282  return false;
283  }
284  double seedCandidateEnergy = CaloCellET(inputCell, digitScale, digitThreshold);
285  int nCellsMoreEnergetic = 0;
286  const CaloCell* leftCell = NextEtaCell(inputCell, true, inputContainer, idHelper);
287  if (leftCell != nullptr){
288  double leftEnergy = CaloCellET(leftCell, digitScale, 0.);
289  if (leftEnergy>seedCandidateEnergy) nCellsMoreEnergetic++;
290  }
291  const CaloCell* rightCell = NextEtaCell(inputCell, false, inputContainer, idHelper);
292  if (rightCell != nullptr){
293  double rightEnergy = CaloCellET(rightCell, digitScale, 0.);
294  if (rightEnergy>=seedCandidateEnergy) nCellsMoreEnergetic++;
295  }
296  const CaloCell* upCell = NextPhiCell(inputCell, true, inputContainer, idHelper);
297  if (upCell != nullptr){
298  double upEnergy = CaloCellET(upCell, digitScale, 0.);
299  if (upEnergy>=seedCandidateEnergy) nCellsMoreEnergetic++;
300  }
301  const CaloCell* downCell = NextPhiCell(inputCell, false, inputContainer, idHelper);
302  if (downCell != nullptr){
303  double downEnergy = CaloCellET(downCell, digitScale, 0.);
304  if (downEnergy>seedCandidateEnergy) nCellsMoreEnergetic++;
305  }
306  if (upCell != nullptr){
307  const CaloCell* upRightCell = NextEtaCell(upCell, false, inputContainer, idHelper);
308  if (upRightCell != nullptr){
309  double upRightEnergy = CaloCellET(upRightCell, digitScale, 0.);
310  if (upRightEnergy>=seedCandidateEnergy) nCellsMoreEnergetic++;
311  }
312  const CaloCell* upLeftCell = NextEtaCell(upCell, true, inputContainer, idHelper);
313  if (upLeftCell != nullptr){
314  double upLeftEnergy = CaloCellET(upLeftCell, digitScale, 0.);
315  if (upLeftEnergy>=seedCandidateEnergy) nCellsMoreEnergetic++;
316  }
317  }
318  if (downCell != nullptr){
319  const CaloCell* downRightCell = NextEtaCell(downCell, false, inputContainer, idHelper);
320  if (downRightCell != nullptr){
321  double downRightEnergy = CaloCellET(downRightCell, digitScale, 0.);
322  if (downRightEnergy>seedCandidateEnergy) nCellsMoreEnergetic++;
323  }
324  const CaloCell* downLeftCell = NextEtaCell(downCell, true, inputContainer, idHelper);
325  if (downLeftCell != nullptr){
326  double downLeftEnergy = CaloCellET(downLeftCell, digitScale, 0.);
327  if (downLeftEnergy>seedCandidateEnergy) nCellsMoreEnergetic++;
328  }
329  }
330  // If candidate is more energetic than all of neighbours, it is a local max
331  if (nCellsMoreEnergetic <= numOthers) return true;
332  else return false;
333 }
334 
335 void
336 LVL1::EFexEMClusterTool::addOnce(const CaloCell* inputCell, std::vector<const CaloCell*> &outputVector) const
337 {
338  if (inputCell==nullptr) return;
339  bool alreadyThere = false;
340  for (auto oCell : outputVector){
341  if (oCell==nullptr) ATH_MSG_WARNING ( "nullptr cell in vector");
342  else if (inputCell->ID() == oCell->ID()) alreadyThere=true;
343  }
344  if (!alreadyThere) outputVector.push_back(inputCell);
345 }
346 
347 double
348 LVL1::EFexEMClusterTool::EMClusET(const CaloCell* centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer* scells,
349  const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh) const
350 {
351  // Sums the ET of the vector
352  std::vector<const CaloCell*> fullClus = TDR_Clus(centreCell, etaWidth, phiWidth, scells, idHelper, digitScale,digitThresh);
353  double EMcomp = sumVectorET(fullClus, digitScale, digitThresh);
354  bool EMcheck = checkDig(EMcomp, digitScale, digitThresh);
355  if (!EMcheck) ATH_MSG_WARNING ( "EMcomp not digitised " << EMcomp << " " << digitScale << " " << digitThresh);
356  double total = EMcomp;
357  return total;
358 }
359 
360 double
361 LVL1::EFexEMClusterTool::REta(const CaloCell* centreCell, int etaWidth1, int phiWidth1, int etaWidth2, int phiWidth2,
362  const CaloConstCellContainer* scells, const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh) const
363 {
364  // Check windows sizes are right way round
365  if (etaWidth1 > etaWidth2) ATH_MSG_WARNING ( "REta: eta1 = " << etaWidth1 << ", eta2 = " << etaWidth2);
366  if (phiWidth1 > phiWidth2) ATH_MSG_WARNING ( "Rphi: phi1 = " << phiWidth1 << ", phi2 = " << phiWidth2);
367  // Finds ET of windows
368  double inner_ET = L2clusET(centreCell, etaWidth1, phiWidth1, scells, idHelper, digitScale, digitThresh);
369  double outer_ET = L2clusET(centreCell, etaWidth2, phiWidth2, scells, idHelper, digitScale, digitThresh);
370  // Find normal value of REta & changes it to my version
371  double normal_REta;
372  if (inner_ET != 0. && outer_ET==0.) normal_REta = 0.;
373  else if (inner_ET==0.) normal_REta = 0.;
374  else normal_REta = inner_ET / outer_ET;
375  if (normal_REta < 0) normal_REta = 0.;
376  double my_REta = 1-normal_REta;
377  return my_REta;
378 }
379 
380 double
381 LVL1::EFexEMClusterTool::RHad(const CaloCell* centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer* scells,
382  const xAOD::TriggerTowerContainer* &TTContainer, const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh, float &HadET) const
383 {
384  std::vector<const CaloCell*> fullClus = TDR_Clus(centreCell, etaWidth, phiWidth, scells, idHelper, digitScale, digitThresh);
385  double EMcomp = sumVectorET(fullClus, digitScale, digitThresh);
386  double HCALcomp = HadronicET(L2cluster(centreCell, m_etaHadWidth_RHadIsolation, m_phiHadWidth_RHadIsolation, scells, idHelper, digitScale, digitThresh), scells, TTContainer, idHelper, digitScale, digitThresh);
387  HadET = HCALcomp/1e3;
388  double result = HCALcomp/(EMcomp+HCALcomp);
389  if (result < 0. || result > 1.){
390  ATH_MSG_WARNING ( "RHAD -> " << etaWidth << " * " << phiWidth);
391  ATH_MSG_WARNING ( "fullClus count = " << fullClus.size() << ", EMcomp = " << EMcomp << ", HCALcomp = " << HCALcomp);
392  }
393  return result;
394 }
395 
396 void
397 LVL1::EFexEMClusterTool::checkTileCell(const TileCell* &inputCell, std::vector<const TileCell*> &tileCellVector, bool &isAlreadyThere) const
398 {
399  for (auto ithCell : tileCellVector){
400  if (ithCell->ID() == inputCell->ID()) isAlreadyThere = true;
401  }
402  if (!isAlreadyThere) tileCellVector.push_back(inputCell);
403 }
404 
405 double
406 LVL1::EFexEMClusterTool::tileCellEnergyCalib(float eIn, float etaIn, float tileNoiseThresh) const
407 {
408  if (eIn <= 0) return 0.;
409  float eOut = eIn/cosh(etaIn);
410  if (tileNoiseThresh == 0.) return eOut;
411  else {
412  if (eOut > tileNoiseThresh) return eOut;
413  else return 0.;
414  }
415 }
416 
417 int
418 LVL1::EFexEMClusterTool::detRelPos(const float inEta) const
419 {
420  float pos_neg = inEta/std::abs(inEta);
421  // Right PMT : inPos = 0, Left PMT : inPos = 1, Both PMTs : inPos = 2
422  int inPos = -1;
423  // True if even, false if odd
424  bool isEven = false;
425  if (((int)(std::abs(inEta)*10)) % 2 == 0) isEven = true;
426  if (pos_neg > 0){
427  // A side of TileCal
428  if (inEta < 0.1) inPos = 0;
429  else if (inEta > 0.8 && inEta < 0.9) inPos = 2;
430  else {
431  if (isEven) inPos = 0;
432  else inPos = 1;
433  }
434  }
435  else {
436  // C side of TileCal
437  if (inEta > -0.1) inPos = 1;
438  else if (inEta > -0.9 && inEta < -0.8) inPos = 2;
439  else {
440  if (isEven) inPos = 1;
441  else inPos = 0;
442  }
443  }
444  return inPos;
445 }
446 
447 double
448 LVL1::EFexEMClusterTool::L1Width(const CaloCell* centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer* scells,
449  const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh) const
450 {
451  // Finds a L2 cluster and the corresponding L1 cells
452  std::vector<const CaloCell*> L2cells = L2cluster(centreCell, etaWidth, phiWidth, scells, idHelper,digitScale, digitThresh);
457 
458  float oldPhi = centreCell->phi();
459  int counter = 0;
460  std::vector<int> offsets;
461  std::vector<const CaloCell*> frontLayerCells;
462  for (auto ithL2Cell : L2cells){
463  // How many cells added already?
464  unsigned int oldsize = frontLayerCells.size();
465  // Add cells matching this L2 cell
466  fromLayer2toLayer1(scells, ithL2Cell, frontLayerCells, idHelper);
467  // HoW many were added?
468  unsigned int additions = frontLayerCells.size() - oldsize;
469  // Reset counter if phi has changed significantly
470  float dPhi = std::abs(ithL2Cell->phi() - oldPhi);
471  if (dPhi > M_PI) dPhi = 2*M_PI - dPhi;
472  if (dPhi > 0.09) {
473  counter = 0;
474  oldPhi = ithL2Cell->phi();
475  }
476  // Try storing signed offsets
477  int sign = (ithL2Cell->eta()-centreCell->eta() > 0 ? 1 : -1);
478  // Store current eta offset value for all added cells
479  for (unsigned int adds = 0; adds < additions; ++adds) offsets.push_back(sign*((counter+1)/2));
480  counter++;
481  }
482 
483  // Finds the 'width' for the cluster, based on eta offsets found above
484  float sumET = 0, sumET_Eta2=0;
485  unsigned int cellCount = 0;
486  //for (auto ithCell : frontLayerCells){
487  for (std::vector<const CaloCell*>::iterator ithCell = frontLayerCells.begin(); ithCell != frontLayerCells.end(); ++ithCell){
488 
489  // Find offset. As a precaution ignore cells where this can't be found, but warn user
490  int offset = (cellCount < offsets.size() ? offsets[cellCount] : -999);
491  if (offset < -2 || offset > 2) {
492  ATH_MSG_WARNING("Offset out of range, cell skipped");
493  offset = 0; // This will result in a weight of zero for the cell
494  }
495 
496  // Is this one of the cells between 1.8-2.0 that will be divided?
497  Identifier cellID = (*ithCell)->ID();
498  int pos_neg = idHelper->pos_neg(cellID);
499  int region = idHelper->region(cellID);
500  int eta_index = idHelper->eta(cellID);
501  bool halfCell = false;
502  if (abs(pos_neg) == 2 && region == 3 && (eta_index == 1 || eta_index == 4 || eta_index == 7 || eta_index == 10)) halfCell = true;
503 
504  // Total and weighted ET sums (integer weights to match firmware)
505  float ithET = CaloCellET((*ithCell), digitScale, digitThresh);
506  sumET += ithET;
507 
508  // 4 cells will be shared with neighbours. Jiggery-pokery required here:
509  if (halfCell) {
510  sumET_Eta2 += 0.5*ithET*pow(offset,2);
511  // Now what should be the offset for the other half?
512  // Is this one shared with the previous cell?
513  // If so, which cell is shares with depends on which side of that cell it is
514  if ((int)cellCount-1 >= 0 && offsets[cellCount-1] == offset) {
515  auto ithPrev = std::prev(ithCell,1);
516  int sign = ((*ithCell)->eta() > (*ithPrev)->eta() ? 1 : -1);
517  int nextOffset = offset+sign;
518  if (abs(nextOffset) <= 2) sumET_Eta2 += 0.5*ithET*pow(nextOffset,2);
519  }
520  }
521  // Alternatively may be shared with next cell
522  else if (cellCount+1 < offsets.size() && offsets[cellCount+1] == offset) {
523  auto ithNext = std::next(ithCell,1);
524  int sign = ((*ithCell)->eta() > (*ithNext)->eta() ? 1 : -1);
525  int nextOffset = offset+sign;
526  if (abs(nextOffset) <= 2) sumET_Eta2 += 0.5*ithET*pow(nextOffset,2);
527  }
528  // For everything else just add cell with weight to the second sum
529  else {
530  sumET_Eta2 += ithET*pow(offset,2);
531  }
532  cellCount++;
533  }
534 
537  float result = 4.;
538  if (sumET > 0.) result = sumET_Eta2/sumET;
539  return result;
540 }
541 
542 double
543 LVL1::EFexEMClusterTool::L2clusET(const CaloCell* centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer* scells,
544  const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh) const
545 {
546  return sumVectorET(L2cluster(centreCell, etaWidth, phiWidth, scells, idHelper, digitScale, digitThresh), digitScale, digitThresh);
547 }
548 
549 double
550 LVL1::EFexEMClusterTool::RHadTile(const CaloCell* centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer* scells,
551  const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh, const TileID* tileIDHelper,
552  const CaloConstCellContainer* tileCellCon, float tileNoiseThresh, float &HadronicET) const
553 {
554  std::vector<float> outVec;
555  double HadET = 0.;
556  std::vector<const CaloCell*> L2Cells = L2cluster(centreCell, etaWidth, phiWidth, scells, idHelper, digitScale, digitThresh);
557  std::vector<const CaloCell*> fullClus = TDR_Clus(centreCell, m_etaHadWidth_RHadIsolation, m_phiHadWidth_RHadIsolation, scells, idHelper, digitScale, digitThresh);
558  // Last Tile cell boundary: eta = 1.6
559  // Last outer wheel SC seed that still falls into Tile boundary: eta = 1.5625
560  if (std::abs(centreCell->eta()) < 1.57){
561  const int barrel_ec = idHelper->pos_neg(centreCell->ID());
562  bool isOW = false;
563  if (std::abs(barrel_ec) == 2) isOW = true;
564  std::vector<double> energyPerLayer = EnergyPerTileLayer(L2Cells, tileCellCon, tileIDHelper, isOW, tileNoiseThresh);
565  if (energyPerLayer.size() > 0){
566  for (auto ithLayerEnergy : energyPerLayer){
567  HadET += ithLayerEnergy;
568  }
569  }
570  }
571  else {
572  std::vector<const CaloCell*> HCAL_LAr_vector;
573  for (auto ithCell : L2Cells){
574  if (std::abs(ithCell->eta()) > 2.5) continue;
575  const CaloCell* tempLArHad = matchingHCAL_LAr(ithCell, scells, idHelper);
576  if (tempLArHad != nullptr) HCAL_LAr_vector.push_back(tempLArHad);
577  }
578  for (auto ithSC : HCAL_LAr_vector){
579  HadET += CaloCellET(ithSC, digitScale, digitThresh);
580  }
581  }
582  HadronicET = HadET/1e3;
583  double EMcomp = sumVectorET(fullClus, digitScale, digitThresh);
584  double result = HadET/(EMcomp+HadET);
585  if (result < 0. || result > 1.){
586  ATH_MSG_WARNING ( "RHADTILE -> " << etaWidth << " * " << phiWidth);
587  ATH_MSG_WARNING ( "fullClus count = " << fullClus.size() << ", EMcomp = " << EMcomp << ", HCALcomp = " << HadET);
588  return 1.;
589  }
590  return result;
591 }
592 
593 double
594 LVL1::EFexEMClusterTool::REtaL12(const CaloCell* centreCell, int etaWidth1, int phiWidth1, int etaWidth2, int phiWidth2,
595  const CaloConstCellContainer* scells, const CaloCell_SuperCell_ID* idHelper,
596  float digitScale, float digitThresh) const
597 {
598  // Check windows sizes are right way round
599  if (etaWidth1 > etaWidth2) ATH_MSG_WARNING ( "REta: eta1 = " << etaWidth1 << ", eta2 = " << etaWidth2);
600  if (phiWidth1 > phiWidth2) ATH_MSG_WARNING ( "Rphi: phi1 = " << phiWidth1 << ", phi2 = " << phiWidth2);
601  // Finds ET of windows
602  double inner_ET = L2clusET(centreCell, etaWidth1, phiWidth1, scells, idHelper, digitScale, digitThresh);
603  double outer_ET = L2clusET(centreCell, etaWidth2, phiWidth2, scells, idHelper, digitScale, digitThresh);
604  // Find corresponding L1 cells, calculate the L1 ET and add them to L2 ET
605  std::vector<const CaloCell*> L2cells_inner = L2cluster(centreCell, etaWidth1, phiWidth1, scells, idHelper,digitScale, digitThresh);
606  std::vector<const CaloCell*> L1cells_inner;
607  for (auto ithL2Cell : L2cells_inner){
608  fromLayer2toLayer1(scells, ithL2Cell, L1cells_inner, idHelper);
609  }
610  inner_ET += sumVectorET(L1cells_inner, digitScale, digitThresh);
611  std::vector<const CaloCell*> L2cells_outer = L2cluster(centreCell, etaWidth2, phiWidth2, scells, idHelper,digitScale, digitThresh);
612  std::vector<const CaloCell*> L1cells_outer;
613  for (auto ithL2Cell : L2cells_outer){
614  fromLayer2toLayer1(scells, ithL2Cell, L1cells_outer, idHelper);
615  }
616  outer_ET += sumVectorET(L1cells_outer, digitScale, digitThresh);
617  // Find normal value of REta & changes it to my version
618  double normal_REta;
619  if (inner_ET != 0. && outer_ET==0.) normal_REta = 0.;
620  else if (inner_ET==0.) normal_REta = 0.;
621  else normal_REta = inner_ET / outer_ET;
622  if (normal_REta < 0) normal_REta = 0.;
623  double my_REta = 1-normal_REta;
624  return my_REta;
625 }
626 
627 void
629  std::vector<const CaloCell*> &outputVector, const CaloCell_SuperCell_ID* &idHelper) const
630 {
631  if (inputCell==nullptr) return;
632  // Gets ID info
633  Identifier inputID = inputCell->ID();
634  int sampling = idHelper->sampling(inputID);
635  const int sub_calo = idHelper->sub_calo(inputID);
636  int pos_neg = idHelper->pos_neg(inputID);
637  int region = idHelper->region(inputID);
638  int eta_index = idHelper->eta(inputID);
639  const int phi_index = idHelper->phi(inputID);
640  int tracker = 0;
641  if (sampling != 2) return;
642  // Default values are same as input
643  int outputRegion = region;
644  int outputEta = eta_index;
645  bool oneCell = false; // True if layer 2 SC only matches to a single layer 1 SC
646  // Barrel reg 0 (which is a simple one)
647  if ((abs(pos_neg) == 1)&&(region == 0)){
648  oneCell = true;
649  }
650  // Barrel reg 1: 3 layer 1 SCs for 1 layer 2 SC
651  // But we should map one of these onto the barrel SC, the other 2 onto EC SCs
652  else if ((abs(pos_neg) == 1)&&(region == 1)){
653  tracker = 2;
654  outputRegion = 1;
655  outputEta = 0;
656  oneCell = true;
657  /* This code produces a one-to-many matching, which is not how things work
658  for (unsigned int i = 0; i < 3; i++){
659  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 1, region, i, phi_index);
660  const CaloCell* resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
661  addOnce(resultCell,outputVector);
662  }
663  */
664  }
667  else if (abs(pos_neg)==2 && region == 0) {
668  tracker = -1;
669  }
672  else if (abs(pos_neg)==2&&((region==1 && eta_index < 2))){
673  tracker = 3;
674  outputRegion = 1;
675  outputEta = eta_index + 1;
676  pos_neg /= abs(pos_neg);
677  oneCell = true;
678  }
680  else if (abs(pos_neg)==2&&((region==1 && eta_index == 2))){
681  tracker = 4;
682  outputRegion = 0;
683  outputEta = 0;
684  oneCell = true;
685  }
687  else if (abs(pos_neg)==2&&region==1 && eta_index <= 14){
688  // OW region 1 (on doc): 1:1 match
689  tracker = 5;
690  outputRegion = 2;
691  outputEta = eta_index - 3;
692  oneCell = true;
693  }
695  else if (abs(pos_neg) == 2 && region == 1 && eta_index <= 22){
696  // In this region there are 6 L1 supercells for every 4 L2 ones
697  // The code below groups them 2:1:1:2 2:1:1:2, which is an old proposal
698  // This is not what is actually done, but the structure of this code
699  // makes it impossible to do this correctly.
700  outputRegion = 3;
701  // Middle 2 layer cells match central 2 layer 1 cells
702  if (eta_index%4 == 0 || eta_index%4 ==1){
703  tracker = 6;
704  oneCell = true;
705  if (eta_index < 20) outputEta = eta_index -14;
706  else outputEta = eta_index - 12;
707  }
708  // Edges have a 2:1 ratio. 2 L1s for each L2
709  else {
710  tracker = 7;
711  int offset = 0;
712  if (eta_index == 15) offset = 15;
713  else if (eta_index == 18) offset = 14;
714  else if (eta_index == 19) offset = 13;
715  else if (eta_index == 22) offset = 12;
716  else {
717  ATH_MSG_DEBUG ( "ISSUE with: " << __LINE__);
718  }
719  for (unsigned int i = 0; i < 2; i++){
720  outputEta = i+eta_index - offset;
721  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 1, outputRegion, outputEta, phi_index);
722  const CaloCell* resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
723  addOnce(resultCell,outputVector);
724  }
725  }
726  }
728  else if (abs(pos_neg)==2 && region == 1 && eta_index <= 38){
729  // OW Reg 3 (on doc): 1:1 match
730  tracker = 8;
731  oneCell = true;
732  outputRegion = 4;
733  outputEta = eta_index - 23;
734  }
736  else if (abs(pos_neg)==2 && region == 1 && eta_index == 40){
737  // OW Reg 4 (on doc): 1 L1 for all 4 L2s
738  // But this must be mapped onto a specific cell: second one seems best
739  // Note: to try alternative mapping of this cell (to Layer 0) should return without adding cell here
740  tracker = 9;
741  oneCell = true;
742  outputEta = 0;
743  outputRegion = 5;
744  }
745 
746  if (oneCell){
747  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 1, outputRegion, outputEta, phi_index);
748  const CaloCell* resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
749  addOnce(resultCell,outputVector);
750  }
751  ATH_MSG_DEBUG("L2->L1: sampling = " << sampling << ", region = " << region << ", eta = " << pos_neg*eta_index<< " tracker = " << tracker);
752 }
753 
754 const CaloCell*
755 LVL1::EFexEMClusterTool::fromLayer2toLayer3(const CaloConstCellContainer* &inputContainer, const CaloCell* inputCell, const CaloCell_SuperCell_ID* &idHelper) const
756 {
757  // Gets ID info
758  int tracker = 0;
759  if ( inputCell == nullptr ) return nullptr;
760  const CaloCell* resultCell = nullptr;
761  Identifier inputID = inputCell->ID();
762  int sampling = idHelper->sampling(inputID);
763  const int sub_calo = idHelper->sub_calo(inputID);
764  const int pos_neg = idHelper->pos_neg(inputID);
765  int region = idHelper->region(inputID);
766  int eta_index = idHelper->eta(inputID);
767  const int phi_index = idHelper->phi(inputID);
768  if (sampling != 2) return nullptr;
769  else if (abs(pos_neg)==1 && ((region==0 && eta_index>53)||region==1)) return nullptr;
770  else if ((abs(pos_neg)==2) && (region == 0 || (region == 1 && eta_index < 3))) return nullptr;
771  else if (abs(pos_neg)==3) return nullptr;
772  // Default values are same as input
773  int outputRegion = region;
774  int outputEta = eta_index;
775  // Is barrel Reg 0
776  if (abs(pos_neg)==1 && region ==0){
777  int outputEta = eta_index/4;
778  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 3, outputRegion, outputEta, phi_index);
779  resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
780  tracker = 1;
781  }
783  else if (abs(pos_neg)==1 && region ==1) {
784  int output_pos_neg = pos_neg*2;
785  outputRegion = 0;
786  int outputEta = 0;
787  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, output_pos_neg, 2, outputRegion, outputEta, phi_index);
788  resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
789  tracker = 2;
790  }
792  else if (abs(pos_neg)==2 && region ==1){
793  outputEta = (eta_index - 3)/4;
794  outputRegion = 0;
795  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 3, outputRegion, outputEta, phi_index);
796  resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
797  tracker = 3;
798  }
799  ATH_MSG_DEBUG("L2->L3: sampling = " << sampling << ", region = " << region << ", eta = " << pos_neg*eta_index<< " tracker = " << tracker);
800  return resultCell;
801 }
802 
803 const CaloCell*
804 LVL1::EFexEMClusterTool::fromLayer2toPS(const CaloConstCellContainer* & inputContainer, const CaloCell* inputCell, const CaloCell_SuperCell_ID* &idHelper) const
805 {
806  // Gets ID info
807  if (inputCell==nullptr) return nullptr;
808  const CaloCell* resultCell = nullptr;
809  Identifier inputID = inputCell->ID();
810  int sampling = idHelper->sampling(inputID);
811  const int sub_calo = idHelper->sub_calo(inputID);
812  const int pos_neg = idHelper->pos_neg(inputID);
813  int region = idHelper->region(inputID);
814  int eta_index = idHelper->eta(inputID);
815  const int phi_index = idHelper->phi(inputID);
816  if (sampling != 2) return nullptr;
817  if (abs(pos_neg)==2 && (eta_index<3 || eta_index>14)) return nullptr;
818  if (abs(pos_neg)==3) return nullptr;
819  // Default values are same as input
820  int outputRegion = region;
821  int outputEta = eta_index;
822  // Is barrel Reg 0
823  if (abs(pos_neg)==1 && region ==0){
824  int outputEta = eta_index/4;
825  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 0, outputRegion, outputEta, phi_index);
826  resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
827  }
828  else if (abs(pos_neg)==1 && region ==1){
829  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 0, 0, 14, phi_index);
830  resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
831  }
832  else if (abs(pos_neg)==2 && region ==1){
833  outputEta = (eta_index - 3)/4;
834  outputRegion = 0;
835  Identifier resultID = idHelper->CaloCell_SuperCell_ID::cell_id(sub_calo, pos_neg, 0, outputRegion, outputEta, phi_index);
836  resultCell = returnCellFromCont(resultID, inputContainer, idHelper);
837  }
838  return resultCell;
839 }
840 
841 std::vector<const CaloCell*>
842 LVL1::EFexEMClusterTool::L2cluster( const CaloCell* centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer* scells,
843  const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh ) const
844 {
845  // Forms the central band of cells, spread in phi
846  std::vector<const CaloCell*> centCells;
847  centCells.push_back(centreCell);
848  const CaloCell* upPhiCell = NextPhiCell(centreCell,true,scells,idHelper);
849  const CaloCell* downPhiCell = NextPhiCell(centreCell,false,scells,idHelper);
850  const CaloCell* energeticPhiCell;
851  // Finds the most energetic phi neighbour, defaulting to the 'down' side if they are equal
852  if ( CaloCellET(upPhiCell, digitScale, digitThresh) > CaloCellET(downPhiCell, digitScale, digitThresh)) energeticPhiCell = upPhiCell;
853  else energeticPhiCell = downPhiCell;
854  if (phiWidth == 2) addOnce(energeticPhiCell, centCells); //centCells.push_back(energeticPhiCell);
855  else if (phiWidth == 3){
856  addOnce(upPhiCell, centCells); //centCells.push_back(upPhiCell);
857  addOnce(downPhiCell, centCells); //centCells.push_back(downPhiCell);
858  }
859  else if (phiWidth > 3) {
860  ATH_MSG_DEBUG ( "phiWidth not 2 or 3!!!");
861  }
862  // Forms the main cluster. Starts with each SC in the central band and spreads outward in eta
863  std::vector<const CaloCell*> clusCells;
864  int halfEtaWidth = (etaWidth-1)/2;
865  int backToEta = (2*halfEtaWidth)+1;
866  if (backToEta != etaWidth) {
867  ATH_MSG_DEBUG ( "Eta width doesn't match! " << backToEta << " -> " << halfEtaWidth << " -> " << etaWidth << " " << __LINE__);
868  }
869  for (auto ithCentCell : centCells){
870  addOnce(ithCentCell, clusCells); //clusCells.push_back(ithCentCell);
871  if (etaWidth > 1){
872  const CaloCell* tempRightCell = NextEtaCell(ithCentCell,true,scells,idHelper);
873  const CaloCell* tempLeftCell = NextEtaCell(ithCentCell,false,scells,idHelper);
874  addOnce(tempRightCell, clusCells); //clusCells.push_back(tempRightCell);
875  addOnce(tempLeftCell, clusCells); //clusCells.push_back(tempLeftCell);
876  for (int i = 1; i < halfEtaWidth; i++){
877  tempRightCell = NextEtaCell(tempRightCell,true,scells,idHelper);
878  tempLeftCell = NextEtaCell(tempLeftCell,false,scells,idHelper);
879  addOnce(tempRightCell, clusCells); //clusCells.push_back(tempRightCell);
880  addOnce(tempLeftCell, clusCells); //clusCells.push_back(tempLeftCell);
881  }
882  }
883  }
884  return clusCells;
885 }
886 
887 std::vector<double>
888 LVL1::EFexEMClusterTool::EnergyPerTileLayer( const std::vector<const CaloCell*> & inputSCVector, const CaloConstCellContainer* CellCon,
889  const TileID* tileIDHelper, bool isOW, float tileNoiseThresh) const
890 {
891  std::vector<double> layerEnergy;
892  if (CellCon==nullptr) return layerEnergy;
893  if (CellCon->size()==0) return layerEnergy;
894  if (inputSCVector.size()==0) return layerEnergy;
895  double ELayer0 = 0, ELayer1 = 0, ELayer2 = 0;
896  std::vector<const TileCell*> tileCellVector;
897  for (auto ithSC : inputSCVector){
898  float ithSCEta = ithSC->eta();
899  float ithSCPhi = ithSC->phi();
900  int matchingCells = 0;
903  for ( ; fCell != lCell; ++fCell){
904  const TileCell* tileCell = static_cast<const TileCell*>(*fCell);
905  if (!tileCell){
906  ATH_MSG_WARNING ( "Failed to cast from CaloCell to TileCell");
907  return layerEnergy;
908  }
909  int layer = tileIDHelper->sample(tileCell->ID());
910  float ithdR = dR(tileCell->eta(), tileCell->phi(), ithSCEta, ithSCPhi);
911  if (layer < 2){
912  float matchingDistance = 0.;
913  if (isOW && (std::abs(ithSCEta) > 1.38 && std::abs(ithSCEta) < 1.42)) matchingDistance = 0.065;
914  else matchingDistance = 0.05;
915  if (ithdR <= matchingDistance){
916  bool isAlreadyThere = false;
917  checkTileCell(tileCell, tileCellVector, isAlreadyThere);
918  if (isAlreadyThere) continue;
919  matchingCells++;
920  if (layer == 0) ELayer0 += tileCellEnergyCalib(tileCell->e(), tileCell->eta(), tileNoiseThresh);
921  if (layer == 1) ELayer1 += tileCellEnergyCalib(tileCell->e(), tileCell->eta(), tileNoiseThresh);
922  }
923  }
924  else if (layer == 2){
925  float matchingDistance = 0.;
926  if (std::abs(ithSCEta) > 0.7 && std::abs(ithSCEta) < 0.8) matchingDistance = 0.05;
927  else if (std::abs(ithSCEta) > 0.9 && std::abs(ithSCEta) < 1.0) matchingDistance = 0.05;
928  else matchingDistance = 0.09;
929  if (ithdR < matchingDistance){
930  bool isAlreadyThere = false;
931  checkTileCell(tileCell, tileCellVector, isAlreadyThere);
932  if (isAlreadyThere) continue;
933  matchingCells++;
934  int tempPos = detRelPos(ithSCEta);
935  // Unknown : tempPos = -1, Right PMT : tempPos = 0, Left PMT : tempPos = 1, Both PMTs : tempPos = 2
936  if (tempPos < 0){
937  ATH_MSG_WARNING ( "Unknown behaviour matching Tile cells to the SC");
938  layerEnergy.clear();
939  return layerEnergy;
940  }
941  else if (tempPos == 0) ELayer2 += tileCellEnergyCalib(tileCell->ene2(), tileCell->eta(), tileNoiseThresh);
942  else if (tempPos == 1) ELayer2 += tileCellEnergyCalib(tileCell->ene1(), tileCell->eta(), tileNoiseThresh);
943  else ELayer2 += tileCellEnergyCalib(tileCell->e(), tileCell->eta(), tileNoiseThresh);
944  }
945  }
946  }
947  if ((matchingCells > 3 && !isOW) || (matchingCells > 3 && isOW && std::abs(ithSCEta) > 1.42) || (matchingCells > 4 && isOW && std::abs(ithSCEta) < 1.42)){
948  ATH_MSG_WARNING ( matchingCells << " matching Tile cells:");
949  ATH_MSG_WARNING ( "Input SC: (eta,phi) = (" << ithSCEta << "," << ithSCPhi << ")");
950  for (auto cell : tileCellVector){
951  ATH_MSG_WARNING ( "Tile cell: (eta,phi) = (" << cell->eta() << "," << cell->phi() << ")" << " dR = " << dR(cell->eta(), cell->phi(), ithSCEta, ithSCPhi) << " layer = " << tileIDHelper->sample(cell->ID()));
952  }
953  layerEnergy.clear();
954  return layerEnergy;
955  }
956  }
957  layerEnergy = {ELayer0, ELayer1, ELayer2};
958  return layerEnergy;
959 }
960 
961 double
963 {
964  if (inputTower == nullptr){
965  ATH_MSG_WARNING ( "Tower is nullptr in phi transformation!");
966  return 0.;
967  }
968  else {
969  double phi = inputTower->phi();
970  if (phi > M_PI) phi = phi - 2*M_PI;
971  return phi;
972  }
973 }
974 
975 double
976 LVL1::EFexEMClusterTool::dR(double eta1, double phi1, double eta2, double phi2) const
977 {
978  double etaDif = eta1 - eta2;
979  double phiDif = std::abs(phi1 - phi2);
980  if (phiDif > M_PI) phiDif = phiDif - (2*M_PI);
981  double result = std::sqrt(pow(etaDif,2)+pow(phiDif,2));
982  return result;
983 }
984 
985 const xAOD::TriggerTower*
987 {
988  std::vector<const xAOD::TriggerTower*> matchingTTs;
989  if (TTContainer==nullptr) return nullptr;
990  if (TTContainer->size()==0) return nullptr;
991  if (inputCell==nullptr) return nullptr;
992  for (auto ithTT : *TTContainer){
993  if (ithTT->sampling()==1){
994  float ithTT_eta = ithTT->eta();
995  float ithTT_phi = TT_phi(ithTT);
996  float ithdR = dR(ithTT_eta, ithTT_phi, inputCell->eta(), inputCell->phi());
997  if (ithdR < 0.05) matchingTTs.push_back(ithTT);
998  }
999  }
1000  if (matchingTTs.size()==1) return matchingTTs[0];
1001  else if (matchingTTs.size()!=0){
1002  ATH_MSG_WARNING ( "More than one matching HCAL TT!!! (Returned Null)");
1003  }
1004  return nullptr;
1005 }
1006 
1007 const CaloCell*
1008 LVL1::EFexEMClusterTool::matchingHCAL_LAr(const CaloCell* &inputCell, const CaloConstCellContainer* &SCContainer, const CaloCell_SuperCell_ID* &idHelper) const
1009 {
1010  std::vector<const CaloCell*> matchingCells;
1011  if (inputCell==nullptr) return nullptr;
1012  for (auto ithSC : *SCContainer){
1013  Identifier ithID = ithSC->ID();
1014  int ithSub_calo = idHelper->sub_calo(ithID);
1015  if (ithSub_calo == 1){
1016  double ithdR = dR(inputCell->eta(), inputCell->phi(), ithSC->eta(), ithSC->phi());
1017  if (ithdR < 0.05) matchingCells.push_back(ithSC);
1018  }
1019  }
1020 
1021  if (matchingCells.size()==1)
1022  return matchingCells[0];
1023 
1024 
1025  if (matchingCells.size()==0){
1026 
1027  ATH_MSG_WARNING ( "No match betweem LAr ECAL SC and LAr HCAL SC!!! Input coords: " << inputCell->eta() << ", " << inputCell->phi());
1028 
1029  } else if (matchingCells.size()!=0) {
1030 
1031  ATH_MSG_WARNING ( "More than one matching LAr HCAL SC!!! (Returned Null)");
1032  ATH_MSG_WARNING ( "Input cell coords: " << inputCell->eta() << " x " << inputCell->phi());
1033  for (auto ithMatch : matchingCells){
1034  ATH_MSG_WARNING ( " " << ithMatch->eta() << " x " << ithMatch->phi() << ", dR = "
1035  << dR(inputCell->eta(), inputCell->phi(), ithMatch->eta(), ithMatch->phi()));
1036  }
1037  }
1038  return nullptr;
1039 }
1040 
1041 double
1043 {
1044  if (inputTower == nullptr){
1045  ATH_MSG_WARNING ( "Tower is nullptr!");
1046  return 0.;
1047  }
1048  else if (inputTower->cpET() < 0.) {
1049  return 0;
1050  } else {
1051  return 500*inputTower->cpET();
1052  }
1053 }
1054 
1055 std::vector<const CaloCell*>
1056 LVL1::EFexEMClusterTool::TDR_Clus( const CaloCell* centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer* scells,
1057  const CaloCell_SuperCell_ID* idHelper, float digitScale, float digitThresh ) const
1058 {
1059  // Find the L2 cells
1060  std::vector<const CaloCell*> L2cells = L2cluster(centreCell, etaWidth, phiWidth, scells, idHelper, digitScale, digitThresh);
1061  // Forms a vector of the centre L2 cells (to be used to find L0/3 SCs)
1062  std::vector<const CaloCell*> centCells;
1063  centCells.push_back(centreCell);
1064  const CaloCell* upPhiCell = NextPhiCell(centreCell,true,scells,idHelper);
1065  const CaloCell* downPhiCell = NextPhiCell(centreCell,false,scells,idHelper);
1066  const CaloCell* energeticPhiCell;
1067  // If the phi width is 2, the most energetic neighbour is chosen (defaulting to the 'down' side)
1068  // If the phi width is 3, both neighbours are added
1069  if (phiWidth > 1){
1070  if (CaloCellET(upPhiCell, digitScale, digitThresh) > CaloCellET(downPhiCell, digitScale, digitThresh)) energeticPhiCell = upPhiCell;
1071  else energeticPhiCell = downPhiCell;
1072  if (phiWidth == 2) addOnce(energeticPhiCell, centCells); //centCells.push_back(energeticPhiCell);
1073  else if (phiWidth == 3){
1074  addOnce(upPhiCell, centCells); //centCells.push_back(upPhiCell);
1075  addOnce(downPhiCell, centCells); //centCells.push_back(downPhiCell);
1076  }
1077  else if (phiWidth > 3) ATH_MSG_WARNING ( "phiWidth not 2 or 3!!!. Value = " << phiWidth);
1078  }
1079  // The actual cluster is initialised
1080  std::vector<const CaloCell*> fullClus;
1081  // The L1&2 SCs are added that match the full width
1082  for (auto ithL2Cell : L2cells){
1083  fullClus.push_back(ithL2Cell);
1084  fromLayer2toLayer1(scells, ithL2Cell, fullClus, idHelper);
1085  }
1086  // The L0&3 SCs are added that match the central L2 cells
1087  for (auto ithL2CentCell : centCells){
1088  addOnce( fromLayer2toPS( scells, ithL2CentCell, idHelper),fullClus);
1089  addOnce( fromLayer2toLayer3( scells, ithL2CentCell, idHelper),fullClus);
1090  }
1091  return fullClus;
1092 }
1093 
1094 double
1095 LVL1::EFexEMClusterTool::sumVectorET(const std::vector<const CaloCell*> &inputVector, float digitScale, float digitThreshold) const
1096 {
1097  double TotalET=0.0;
1098  for (auto ithCell : inputVector){
1099  if (ithCell!=nullptr) TotalET += CaloCellET(ithCell, digitScale, digitThreshold);
1100  }
1101  return TotalET;
1102 }
1103 
1104 bool
1105 LVL1::EFexEMClusterTool::checkDig(float EM_ET, float digitScale, float digitThresh) const
1106 {
1107  if (EM_ET == 0 || digitScale == 0) return true;
1108  else {
1109  int div = EM_ET / digitScale;
1110  if (div * digitScale == EM_ET) return true;
1111  else {
1112  ATH_MSG_WARNING ( "ET = " << EM_ET << ", digitThresh = " << digitThresh << " digitScale = " << digitScale << " div = " << div << " " << " -> div * digitScale");
1113  return false;
1114  }
1115  }
1116 }
1117 
1118 double
1119 LVL1::EFexEMClusterTool::HadronicET( const std::vector<const CaloCell*> & inputVector, const CaloConstCellContainer* scells,
1120  const xAOD::TriggerTowerContainer* &TTContainer, const CaloCell_SuperCell_ID* idHelper,
1121  float digitScale, float digitThresh) const
1122 {
1123  // Finds the HCAL SCs & TTs matching the input cluster
1124  std::vector<const CaloCell*> HCAL_LAr_vector;
1125  std::vector<const xAOD::TriggerTower*> HCAL_TT_vector;
1126  for (auto ithCell : inputVector){
1127  if (std::abs(ithCell->eta())<1.5){
1128  const xAOD::TriggerTower* tempTT = matchingHCAL_TT(ithCell, TTContainer);
1129  if (tempTT != nullptr) HCAL_TT_vector.push_back(tempTT);
1130  }
1131  else if (std::abs(ithCell->eta())<2.5){
1132  const CaloCell* tempLArHad = matchingHCAL_LAr(ithCell, scells, idHelper);
1133  if (tempLArHad != nullptr) HCAL_LAr_vector.push_back(tempLArHad);
1134  }
1135  }
1136  // Sums the ET in the HCAL
1137  double HadET = 0.;
1138  for (auto ithTT : HCAL_TT_vector) {HadET += TT_ET(ithTT);}
1139  for (auto ithSC : HCAL_LAr_vector) {HadET += CaloCellET(ithSC, digitScale, digitThresh);}
1140  return HadET;
1141 }
1142 
1143 
1147 const CaloCell*
1149 {
1150  const CaloCell* isCell = cellContainer->findCell(idHelper->CaloCell_SuperCell_ID::calo_cell_hash(inputID));
1151  if (isCell) return isCell;
1152  else return nullptr;
1153 }
1154 
1155 const CaloCell*
1156 LVL1::EFexEMClusterTool::NextEtaCell( const CaloCell* inputCell, bool upwards, const CaloConstCellContainer* &cellContainer,
1157  const CaloCell_SuperCell_ID* &idHelper) const
1158 {
1159  if (inputCell==nullptr) return nullptr;
1160  Identifier ithID = inputCell->ID();
1161  int ithSub_calo = idHelper->sub_calo(ithID);
1162  int ithPos_neg = idHelper->pos_neg(ithID);
1163  const CaloCell* tempCell = nullptr;
1164  // Only works for LArEM
1165  if (ithSub_calo==0){
1166  // Barrel regions
1167  if (abs(ithPos_neg)==1) tempCell = NextEtaCell_Barrel(inputCell, upwards, cellContainer, idHelper);
1168  // EC OW
1169  else if (abs(ithPos_neg)==2) tempCell = NextEtaCell_OW(inputCell, upwards, cellContainer, idHelper);
1170  // EC IW
1171  else if (abs(ithPos_neg)==3) tempCell = NextEtaCell_IW(inputCell, upwards, cellContainer, idHelper);
1172  // Not barrel or end cap
1173  else {
1174  ATH_MSG_WARNING ( "Layer 2 cell not passed to specific method at" << inputCell->eta() << " , " << inputCell->phi());
1175  return nullptr;
1176  }
1177  return tempCell;
1178  }
1179  // Is FCAL
1180  else {
1181  ATH_MSG_WARNING ( "Next eta cell called for non-EM SC!");
1182  return nullptr;
1183  }
1184 }
1185 
1186 const CaloCell*
1187 LVL1::EFexEMClusterTool::NextEtaCell_Barrel(const CaloCell* inputCell, bool upwards, const CaloConstCellContainer* &cellContainer,
1188  const CaloCell_SuperCell_ID* &idHelper) const
1189 {
1190  const Identifier ithID = inputCell->ID();
1191  const int ithEta_index = idHelper->eta(ithID);
1192  const int ithPhi_index = idHelper->phi(ithID);
1193  const int ithSampling = idHelper->sampling(ithID);
1194  const int ithSub_calo = idHelper->sub_calo(ithID);
1195  const int ithPos_neg = idHelper->pos_neg(ithID);
1196  const int ithRegion = idHelper->region(ithID);
1197 
1198  // Extreme indices of each region
1199  int maxEta_index = 0;
1200  int minEta_index = 0;
1201  if (ithRegion==0){
1202  if (ithSampling == 0) maxEta_index = 14;
1203  else if (ithSampling == 1 || ithSampling == 2) maxEta_index = 55;
1204  else if (ithSampling == 3) maxEta_index = 13;
1205  else ATH_MSG_DEBUG ( "ISSUE: " << __LINE__);
1206  }
1207  else if (ithRegion==1){
1208  if (ithSampling == 1) maxEta_index =2;
1209  else if (ithSampling == 2) maxEta_index=0;
1210  else ATH_MSG_DEBUG ( "ISSUE: " << __LINE__);
1211  }
1212  else ATH_MSG_DEBUG ( "ISSUE: " << __LINE__);
1213  // Declare next values, default initialisation is the same as cell
1214  int nextEta_index = ithEta_index;
1215  // Phi shouldn't change!
1216  // One special case where sampling does change, otherwise stays same
1217  int nextSampling = ithSampling;
1218  int nextSub_calo = ithSub_calo;
1219  int nextPos_neg = ithPos_neg;
1220  int nextRegion = ithRegion;
1221 
1222  // Calculate the increment for eta: it depends on whether we are moving 'up' & which side we are on
1223  int incrementEta;
1224  if (upwards) incrementEta = ithPos_neg;
1225  else incrementEta = -1*ithPos_neg;
1226 
1227  int tracker = 0;
1228 
1229  // If first cell in region & moving more inwards
1230  if (ithEta_index==minEta_index && incrementEta==-1){
1231  if (ithRegion == 0){
1232  nextEta_index = 0;
1233  nextPos_neg = ithPos_neg * -1;
1234  tracker = 1;
1235  }
1236  else if (ithRegion == 1){
1237  nextEta_index = 55;
1238  nextRegion = 0;
1239  tracker = 2;
1240  }
1241  else ATH_MSG_DEBUG ( "ISSUE: " << __LINE__);
1242  }
1243 
1244  // If last cell in region & moving outwards
1245  else if ((ithEta_index == maxEta_index) && (incrementEta == 1)) {
1246  // Reg 0, Layers 1 & 2 go to barrel region 1
1247  if ((ithRegion == 0)&&(ithSampling == 1 || ithSampling == 2)){
1248  nextRegion = 1;
1249  nextEta_index = 0;
1250  tracker = 3;
1251  }
1252  // Reg 0, Layer 0 goes to OW region 0
1253  else if ((ithRegion == 0)&&(ithSampling == 0)){
1254  nextEta_index = 0;
1255  nextRegion = 0;
1256  nextPos_neg = 2*ithPos_neg;
1257  tracker = 4;
1258  }
1259  // Reg 0, Layer 3 goes to OW Layer 2 region 0 (change by ATW)
1260  else if ((ithRegion == 0)&&(ithSampling == 3)){
1261  nextSampling = 2;
1262  nextEta_index = 0;
1263  nextRegion = 0;
1264  nextPos_neg = 2*ithPos_neg;
1265  tracker = 5;
1266  }
1267  // Reg 1, Layer 1 go to OW region 0 (change by ATW)
1268  else if ((ithRegion == 1)&&(ithSampling == 1)){
1269  nextEta_index=0;
1270  nextRegion = 0;
1271  nextPos_neg = 2 * ithPos_neg;
1272  tracker = 6;
1273  }
1274  // Reg 1, Layer 2 goes to OW region 1
1275  else if ((ithRegion == 1)&&(ithSampling == 2)){
1276  nextEta_index=0;
1277  nextRegion = 1;
1278  nextPos_neg = 2 * ithPos_neg;
1279  tracker = 7;
1280  }
1281  else ATH_MSG_DEBUG ( "ISSUE: " << __LINE__);
1282  }
1283  // Otherwise 'simply' next cell along
1284  else {
1285  nextEta_index = ithEta_index + incrementEta;
1286  tracker = 8;
1287  }
1288  //ATH_MSG_DEBUG ( "B Tracker = " << tracker);
1289  // Form identifier, find cell & return it
1290  // sub_calo, left_pos_neg, 2, region, eta_index, down_phi_index
1291  Identifier nextCellID = idHelper->CaloCell_SuperCell_ID::cell_id(nextSub_calo, nextPos_neg, nextSampling, nextRegion, nextEta_index, ithPhi_index);
1292  const CaloCell* nextCell = returnCellFromCont(nextCellID, cellContainer, idHelper);
1293  if (nextCell == nullptr) {
1294  ATH_MSG_DEBUG ( "ISSUE: " << __LINE__);
1295  ATH_MSG_DEBUG ( "Barrel Tracker = " << tracker);
1296  ATH_MSG_DEBUG ( "from nextCellID: "<<idHelper->sub_calo(nextCellID)<<", "<<idHelper->pos_neg(nextCellID)<<", "<<idHelper->sampling(nextCellID)<<", "<<idHelper->region(nextCellID)<<", "<<idHelper->eta(nextCellID)<<", "<<idHelper->phi(nextCellID)<<", "<<idHelper->calo_cell_hash(nextCellID)<<", "<<nextCellID);
1297  }
1298  else {
1299  Identifier newID = nextCell->ID();
1300  int IDsample = idHelper->sampling(nextCell->ID());
1302  if (IDsample!=ithSampling){
1303  ATH_MSG_DEBUG ( "Layer has changed " << " tracker = " << tracker);
1304  ATH_MSG_DEBUG ( "from nextCellID: "<<idHelper->sub_calo(nextCellID)<<", "<<idHelper->pos_neg(nextCellID)<<", "<<idHelper->sampling(nextCellID)<<", "<<idHelper->region(nextCellID)<<", "<<idHelper->eta(nextCellID)<<", "<<idHelper->phi(nextCellID)<<", "<<idHelper->calo_cell_hash(nextCellID)<<", "<<nextCellID);
1305  ATH_MSG_DEBUG ( "from ID from new cell: "<<idHelper->sub_calo(newID)<<", "<<idHelper->pos_neg(newID)<<", "<<idHelper->sampling(newID)<<", "<<idHelper->region(newID)<<", "<<idHelper->eta(newID)<<", "<<idHelper->phi(newID)<<", "<<idHelper->calo_cell_hash(newID)<<", "<<newID);
1306  ATH_MSG_DEBUG ( "comp indices: "<< (nextCellID == newID));
1307  }
1308  }
1309  if (nextCell && (nextCell->ID() != nextCellID)) ATH_MSG_DEBUG ( __LINE__ << " does not match");
1310  return nextCell;
1311 }
1312 
1313 const CaloCell*
1314 LVL1::EFexEMClusterTool::NextEtaCell_OW( const CaloCell*inputCell, bool upwards, const CaloConstCellContainer* &cellContainer,
1315  const CaloCell_SuperCell_ID* &idHelper) const
1316 {
1317  Identifier ithID = inputCell->ID();
1318  int ithEta_index = idHelper->eta(ithID);
1319  const int ithPhi_index = idHelper->phi(ithID);
1320  const int ithSampling = idHelper->sampling(ithID);
1321  int ithSub_calo = idHelper->sub_calo(ithID);
1322  int ithPos_neg = idHelper->pos_neg(ithID);
1323  int ithRegion = idHelper->region(ithID);
1324  // Declare next values, default initialisation is the same as cell
1325  int nextEta_index = ithEta_index;
1326  int nextPhi_index = ithPhi_index;
1327  // Sampling may change in a couple of special cases (transition tower)
1328  int nextSampling = ithSampling;
1329  int nextSub_calo = ithSub_calo;
1330  int nextPos_neg = ithPos_neg;
1331  int nextRegion = ithRegion;
1332  // Maximum indices for barrel region 0:
1333  int maxEta_index = 0;
1334  int minEta_index = 0;
1335  // Set max / min values based on ithRegion
1336  if (ithSampling==0) maxEta_index = 2;
1337  else if (ithSampling==2 && ithRegion==0) maxEta_index = 0;
1338  else if (ithSampling==2 && ithRegion==1) maxEta_index = 42;
1339  else if (ithSampling==3) maxEta_index=9;
1340  else if (ithSampling==1) {
1341  switch(ithRegion){
1342  case 0:
1343  maxEta_index=0;
1344  break;
1345  case 1:
1346  ATH_MSG_DEBUG ( "ISSUE " << __LINE__);
1347  break;
1348  case 2:
1349  maxEta_index=11;
1350  break;
1351  case 3:
1352  maxEta_index=11;// Should this be 11? - it was 7
1353  break;
1354  case 4:
1355  maxEta_index=15;
1356  break;
1357  case 5:
1358  maxEta_index=0;
1359  break;
1360  default:
1361  ATH_MSG_WARNING ( "OW region is not covered: " << ithRegion);
1362  }
1363  }
1364  else ATH_MSG_DEBUG ( "ISSUE: " << __LINE__ );
1365 
1366  // Calculate the increment for eta: it depends on whether we are moving 'up' & which side we are on
1367  int incrementEta;
1368  int ithSide = ithPos_neg / abs(ithPos_neg);
1369  if (upwards) incrementEta = ithSide;
1370  else incrementEta = ithSide * -1;
1371  int tracker = 0;
1372  // Lower end of OW, going inwards
1373  if (ithEta_index==minEta_index && ithRegion==0 && incrementEta==-1){
1374  nextPos_neg = ithSide;
1375  if (ithSampling==0){
1376  nextRegion = 0;
1377  nextEta_index = 14;
1378  tracker = 1;
1379  }
1380  else if (ithSampling==1){
1381  nextRegion = 1;
1382  nextEta_index = 2;
1383  tracker = 2;
1384  }
1386  else if (ithSampling==2){
1387  nextRegion = 0;
1388  nextSampling = 2;
1389  nextEta_index = 13;
1390  tracker = 3;
1391  }
1393  else if (ithSampling==3){
1394  nextRegion = 0;
1395  nextSampling = 2;
1396  nextEta_index = 0;
1397  nextPos_neg = ithPos_neg;
1398  tracker = 4;
1399  }
1400  }
1401  // Higher end of OW, going outwards
1402  else if (ithEta_index==maxEta_index && incrementEta==1){
1403  // Layers 0 & 3 aren't in IW
1404  if (ithSampling==0 || ithSampling==3) return nullptr;
1405  else if (ithSampling==2 && ithRegion==0){
1406  nextRegion = 1;
1407  nextEta_index = 0;
1408  tracker = 5;
1409  }
1410  else if ((ithSampling==2 && ithRegion==1)||(ithSampling==1 && ithRegion==5)){
1411  // Reaches IW
1412  nextEta_index=0;
1413  nextRegion=0;
1414  nextPhi_index=ithPhi_index/2;
1415  nextPos_neg=3*ithSide;
1416  tracker=6;
1417  }
1418  else if (ithSampling==1 && ithRegion==0){
1419  // Unsure what to do??
1420  nextRegion = 2;
1421  nextEta_index = 0;
1422  tracker = 7;
1423  }
1424  else if (ithSampling==1){
1425  nextRegion=ithRegion + 1;
1426  nextEta_index=0;
1427  tracker = 8;
1428  }
1429  }
1430  // Lower end of region in OW, going inwards
1431  else if (ithEta_index==minEta_index && incrementEta==-1){
1432  // Shouldn't apply to layers 0 & 3
1433  // Only case for layer 2 should be in region 1
1434  // But this one is special because we want to step into barrel (ATW)
1435  if (ithSampling==2){
1436  nextRegion = 1;
1437  nextEta_index = 0;
1438  nextPos_neg = ithPos_neg;
1439  tracker = 9;
1440  }
1441  else if (ithSampling==1){
1442  if (ithRegion==0){ // haven't we covered this? (ATW)
1443  nextPos_neg = ithSide;
1444  nextRegion = 1;
1445  nextEta_index = 2;
1446  tracker = 10;
1447  }
1448  else {
1449  tracker = 11;
1450  // Layer one has muliple regions
1451  nextRegion = ithRegion-1;
1452  if (nextRegion==0) {
1453  nextEta_index=0;
1454  ATH_MSG_DEBUG ( "ISSUE: "<< __LINE__);
1455  }
1456  else if (nextRegion==1) {
1457  nextRegion = 0;
1458  nextEta_index= 0;
1459  }
1460  else if (nextRegion==2) nextEta_index=11;
1461  else if (nextRegion==3) nextEta_index=7;
1462  else if (nextRegion==4) nextEta_index=15;
1463  }
1464  }
1465  }
1466  // Middle of region in middle of endcap
1467  else {
1468  nextEta_index = ithEta_index+incrementEta;
1469  tracker = 12;
1470  }
1471  Identifier nextCellID = idHelper->CaloCell_SuperCell_ID::cell_id(nextSub_calo, nextPos_neg, nextSampling, nextRegion, nextEta_index, nextPhi_index);
1472  const CaloCell* nextCell = returnCellFromCont(nextCellID, cellContainer, idHelper);
1473  if (nextCell == nullptr) {
1474  ATH_MSG_DEBUG ( "ISSUE: "<<__LINE__);
1475  ATH_MSG_DEBUG ( "OW Tracker = "<<tracker);
1476  ATH_MSG_DEBUG ( "from nextCellID: "<<idHelper->sub_calo(nextCellID)<<", "<<idHelper->pos_neg(nextCellID)<<", "<<idHelper->sampling(nextCellID)<<", "<<idHelper->region(nextCellID)<<", "<<idHelper->eta(nextCellID)<<", "<<idHelper->phi(nextCellID)<<", "<<idHelper->calo_cell_hash(nextCellID)<<", "<<nextCellID);
1477  ATH_MSG_DEBUG ( "Increment eta = "<<incrementEta<<", max_eta = "<<maxEta_index<<", min_eta = "<<minEta_index);
1478  }
1479  else {
1480  Identifier newID = nextCell->ID();
1481  int IDsample = idHelper->sampling(nextCell->ID());
1482  if (IDsample!=ithSampling){
1483  ATH_MSG_DEBUG ( "Layer has changed "<<" tracker = "<<tracker);
1484  ATH_MSG_DEBUG ( "from nextCellID: "<<idHelper->sub_calo(nextCellID)<<", "<<idHelper->pos_neg(nextCellID)<<", "<<idHelper->sampling(nextCellID)<<", "<<idHelper->region(nextCellID)<<", "<<idHelper->eta(nextCellID)<<", "<<idHelper->phi(nextCellID)<<", "<<idHelper->calo_cell_hash(nextCellID)<<", "<<nextCellID);
1485  ATH_MSG_DEBUG ( "from ID from new cell: "<<idHelper->sub_calo(newID)<<", "<<idHelper->pos_neg(newID)<<", "<<idHelper->sampling(newID)<<", "<<idHelper->region(newID)<<", "<<idHelper->eta(newID)<<", "<<idHelper->phi(newID)<<", "<<idHelper->calo_cell_hash(newID)<<", "<<newID);
1486  ATH_MSG_DEBUG ( "comp indices: "<<(nextCellID == newID));
1487  }
1488  }
1489  if (nextCell && (nextCell->ID() != nextCellID)) ATH_MSG_DEBUG ( __LINE__<< " does not match");
1490  return nextCell;
1491 }
1492 
1493 const CaloCell*
1494 LVL1::EFexEMClusterTool::NextEtaCell_IW( const CaloCell* inputCell, bool upwards, const CaloConstCellContainer* &cellContainer,
1495  const CaloCell_SuperCell_ID* &idHelper) const
1496 {
1497  const Identifier ithID = inputCell->ID();
1498  const int ithEta_index = idHelper->eta(ithID);
1499  const int ithPhi_index = idHelper->phi(ithID);
1500  const int ithSampling = idHelper->sampling(ithID);
1501  const int ithSub_calo = idHelper->sub_calo(ithID);
1502  const int ithPos_neg = idHelper->pos_neg(ithID);
1503  const int ithRegion = idHelper->region(ithID);
1504  //int tracker =0;
1505  // Declare next values, default initialisation is the same as cell
1506  int nextEta_index = ithEta_index;
1507  int nextPhi_index = ithPhi_index;
1508  // Sampling shouldn't change!
1509  int nextSub_calo = ithSub_calo;
1510  int nextPos_neg = ithPos_neg;
1511  int nextRegion = ithRegion;
1512 
1513  // Maximum indices for barrel region 0:
1514  int maxEta_index = 0;
1515  int minEta_index = 0;
1516 
1517  if (ithRegion==0){
1518  maxEta_index=2;
1519  minEta_index=0;
1520  }
1521  else if (ithRegion!=1) ATH_MSG_DEBUG ( "ISSUE: " <<__LINE__);
1522 
1523  // Calculate the increment for eta: it depends on whether we are moving 'up' & which side we are on
1524  int incrementEta;
1525  int ithSide = ithPos_neg / abs(ithPos_neg);
1526  if (upwards) incrementEta = ithSide;
1527  else incrementEta = ithSide * -1;
1528  // Lower end of region IW, going inwards
1529  if (ithEta_index==minEta_index&& incrementEta==-1){
1530  // Goes to OW
1531  if (ithRegion == 0){
1532  nextPos_neg = 2*ithSide;
1533  nextPhi_index=2*ithPhi_index;
1534  if (ithSampling==1){
1535  // tracker=1;
1536  nextRegion=5;
1537  nextEta_index=0;
1538  }
1539  else if (ithSampling==2){
1540  // tracker=2;
1541  nextRegion=1;
1542  nextEta_index=42;
1543  }
1544  else ATH_MSG_DEBUG ( "ISSUE: " <<__LINE__);
1545  }
1546  // Goes to IW region 0
1547  else if (ithRegion == 1){
1548  // tracker=3;
1549  nextRegion=0;
1550  nextEta_index=2;
1551  }
1552  }
1553  // Upper end of region in IW
1554  else if (ithEta_index==maxEta_index && incrementEta==1){
1555  // Goes to region 1
1556  if (ithRegion==0){
1557  // tracker=4;
1558  nextRegion=1;
1559  nextEta_index=0;
1560  }
1561  // Reaches FCAL
1562  else if (ithRegion==1) return nullptr;
1563  }
1564  // Increment eta like normal
1565  else {
1566  // tracker=5;
1567  nextEta_index=ithEta_index+incrementEta;
1568  }
1569  Identifier nextCellID = idHelper->CaloCell_SuperCell_ID::cell_id(nextSub_calo, nextPos_neg, ithSampling, nextRegion, nextEta_index, nextPhi_index);
1570  const CaloCell* nextCell = returnCellFromCont(nextCellID, cellContainer, idHelper);
1571  if (nextCell && (nextCell->ID() != nextCellID)) ATH_MSG_DEBUG ( __LINE__<<" does not match");
1572  return nextCell;
1573 }
1574 
1575 int
1576 LVL1::EFexEMClusterTool::restrictPhiIndex(int input_index, bool is64) const
1577 {
1578  if (is64&&input_index<0) return input_index+64;
1579  else if (is64&&input_index>63) return input_index-64;
1580  else if (!(is64)&&input_index<0) return input_index+32;
1581  else if (!(is64)&&input_index>31) return input_index-32;
1582  else return input_index;
1583 }
1584 
1585 const CaloCell*
1586 LVL1::EFexEMClusterTool::NextPhiCell( const CaloCell * inputCell, bool upwards, const CaloConstCellContainer* &cellContainer,
1587  const CaloCell_SuperCell_ID* &idHelper) const
1588 {
1589  if (inputCell==nullptr)
1590  return nullptr;
1591 
1592  const Identifier ithID = inputCell->ID();
1593  const int ithEta_index = idHelper->eta(ithID);
1594  const int ithPhi_index = idHelper->phi(ithID);
1595  const int ithSampling = idHelper->sampling(ithID);
1596  const int ithSub_calo = idHelper->sub_calo(ithID);
1597  const int ithPos_neg = idHelper->pos_neg(ithID);
1598  const int ithRegion = idHelper->region(ithID);
1599 
1600  bool is64;
1601  if (abs(ithPos_neg)==3) is64 = false;
1602  else is64 = true;
1603 
1604  int incrementPhi;
1605  if (upwards==true) incrementPhi=1;
1606  else incrementPhi=-1;
1607 
1608  const int nextPhi_index = restrictPhiIndex(ithPhi_index+incrementPhi, is64);
1609  Identifier nextCellID = idHelper->CaloCell_SuperCell_ID::cell_id(ithSub_calo, ithPos_neg, ithSampling, ithRegion, ithEta_index, nextPhi_index);
1610  const CaloCell* nextCell = returnCellFromCont(nextCellID, cellContainer, idHelper);
1611  if (nextCell && (nextCell->ID() != nextCellID)) ATH_MSG_DEBUG ( __LINE__ << " does not match");
1612  if (nextCell == nullptr) ATH_MSG_DEBUG ( "Next phi cell is nullptr at " << __LINE__);
1613  return nextCell;
1614 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
LVL1::EFexEMClusterTool::TDR_Clus
std::vector< const CaloCell * > TDR_Clus(const CaloCell *centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
form the cluster around the central SC
Definition: EFexEMClusterTool.cxx:1056
TileCell
Definition: TileCell.h:57
LVL1::EFexEMClusterTool::localMax
bool localMax(const CaloConstCellContainer *&inputContainer, const CaloCell *inputCell, const CaloCell_SuperCell_ID *&idHelper, float digitScale, float digitThreshold) const
helper function calling localMax()
Definition: EFexEMClusterTool.cxx:265
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
xAOD::TriggerTower_v2::cpET
uint8_t cpET() const
get cpET from peak of lut_cp
Definition: TriggerTower_v2.cxx:180
CaloCell::phi
virtual double phi() const override final
get phi (through CaloDetDescrElement)
Definition: CaloCell.h:359
CaloCell_Base_ID::calo_cell_hash
IdentifierHash calo_cell_hash(const Identifier cellId) const
create hash id from 'global' cell id
get_generator_info.result
result
Definition: get_generator_info.py:21
CaloCell_Base_ID::region
int region(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
ReadCellNoiseFromCool.cell
cell
Definition: ReadCellNoiseFromCool.py:53
LVL1::EFexEMClusterTool::SameTT
bool SameTT(const CaloCell *inputCell1, const CaloCell *inputCell2, const CaloCell_SuperCell_ID *&idHelper) const
check if both input cells belong to the same TT
Definition: EFexEMClusterTool.cxx:216
ParticleGun_SamplingFraction.eta2
eta2
Definition: ParticleGun_SamplingFraction.py:96
LVL1::EFexEMClusterTool::matchingHCAL_LAr
const CaloCell * matchingHCAL_LAr(const CaloCell *&inputCell, const CaloConstCellContainer *&SCContainer, const CaloCell_SuperCell_ID *&idHelper) const
Match each SC from L2 to one corresponding HCAL SC.
Definition: EFexEMClusterTool.cxx:1008
LVL1::EFexEMClusterTool::m_use_tileCells
bool m_use_tileCells
boolean for using Tile cells instead of Tile TT
Definition: EFexEMClusterTool.h:217
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
xAOD::TriggerTower_v2::phi
virtual double phi() const final
The azimuthal angle ( ) of the particle.
Definition: TriggerTower_v2.cxx:222
LVL1::EFexEMClusterTool::m_phiWidth_REtaIsolation_num
int m_phiWidth_REtaIsolation_num
phi width for REta isolation given in number of SCs (numerator of fraction)
Definition: EFexEMClusterTool.h:230
LVL1::EFexEMClusterTool::REta
double REta(const CaloCell *centreCell, int etaWidth1, int phiWidth1, int etaWidth2, int phiWidth2, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
calculate the energy isolation of the central cell along eta
Definition: EFexEMClusterTool.cxx:361
LVL1::EFexEMClusterTool::NextEtaCell
const CaloCell * NextEtaCell(const CaloCell *inputCell, bool upwards, const CaloConstCellContainer *&cellContainer, const CaloCell_SuperCell_ID *&idHelper) const
helper function calling NextEtaCell_Barrel(), NextEtaCell_OW(), NextEtaCell_IW() according to positio...
Definition: EFexEMClusterTool.cxx:1156
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
TileCell::ene1
float ene1(void) const
get energy of first PMT
Definition: TileCell.h:193
CaloCell_Base_ID::pos_neg
int pos_neg(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
LVL1::EFexEMClusterTool::m_clustET_thresh
float m_clustET_thresh
threshold for minimum cluster energy (baseline selection)
Definition: EFexEMClusterTool.h:208
LVL1::EFexEMClusterTool::EMClusET
double EMClusET(const CaloCell *centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
calculate cluster energy
Definition: EFexEMClusterTool.cxx:348
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
LVL1::EFexEMClusterTool::RHad
double RHad(const CaloCell *centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer *scells, const xAOD::TriggerTowerContainer *&TTContainer, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh, float &HadronicET) const
calculate the hadronic isolation of the central cell
Definition: EFexEMClusterTool.cxx:381
LVL1::EFexEMClusterTool::m_nominalNoise_thresh
float m_nominalNoise_thresh
noise threshold
Definition: EFexEMClusterTool.h:219
Tile_Base_ID::sample
int sample(const Identifier &id) const
Definition: Tile_Base_ID.cxx:171
M_PI
#define M_PI
Definition: ActiveFraction.h:11
LVL1::EFexEMClusterTool::HadronicET
double HadronicET(const std::vector< const CaloCell * > &inputVector, const CaloConstCellContainer *scells, const xAOD::TriggerTowerContainer *&TTContainer, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
calculate the energy in the HCAL (LAr + Tile) for SC/TT that match the EM cluster cells of L2
Definition: EFexEMClusterTool.cxx:1119
LVL1::EFexEMClusterTool::m_useProvenance
bool m_useProvenance
properties
Definition: EFexEMClusterTool.h:204
CaloCell::e
virtual double e() const override final
get energy (data member) (synonym to method energy()
Definition: CaloCell.h:317
xAOD::eta1
setEt setPhi setE277 setWeta2 eta1
Definition: TrigEMCluster_v1.cxx:41
LVL1::EFexEMClusterTool::m_tileNoise_tresh
float m_tileNoise_tresh
TileCal cell noise threshold.
Definition: EFexEMClusterTool.h:220
LVL1::EFexEMClusterTool::m_phiWidth_TDRCluster
int m_phiWidth_TDRCluster
phi width of the TDR cluster formation given in number of SCs (including the central cell),...
Definition: EFexEMClusterTool.h:221
LVL1::EFexEMClusterTool::detRelPos
int detRelPos(const float inEta) const
determine the PMT position of the Tile cell to be matched
Definition: EFexEMClusterTool.cxx:418
CaloCell::provenance
uint16_t provenance() const
get provenance (data member)
Definition: CaloCell.h:338
LVL1::EFexEMClusterTool::NextPhiCell
const CaloCell * NextPhiCell(const CaloCell *inputCell, bool upwards, const CaloConstCellContainer *&cellContainer, const CaloCell_SuperCell_ID *&idHelper) const
returns the SC above/below the input cell
Definition: EFexEMClusterTool.cxx:1586
LVL1::EFexEMClusterTool::m_phiWidth_wstotIsolation
int m_phiWidth_wstotIsolation
phi width for wstot isolation given in number of SCs
Definition: EFexEMClusterTool.h:224
LVL1::EFexEMClusterTool::AlgResult
Definition: EFexEMClusterTool.h:30
CaloCell::energy
double energy() const
get energy (data member)
Definition: CaloCell.h:311
LVL1::EFexEMClusterTool::m_L1Width_thresh
float m_L1Width_thresh
threshold for isolation L1Width (wstot) (baseline selection)
Definition: EFexEMClusterTool.h:212
LVL1::EFexEMClusterTool::restrictPhiIndex
int restrictPhiIndex(int input_index, bool is64) const
manager function for the phi index
Definition: EFexEMClusterTool.cxx:1576
LVL1::EFexEMClusterTool::fromLayer2toPS
const CaloCell * fromLayer2toPS(const CaloConstCellContainer *&inputContainer, const CaloCell *inputCell, const CaloCell_SuperCell_ID *&idHelper) const
match SCs from the cluster in L2 to one cell of PS
Definition: EFexEMClusterTool.cxx:804
LVL1::EFexEMClusterTool::m_qualBitMask
int m_qualBitMask
Configurable quality bitmask.
Definition: EFexEMClusterTool.h:205
LVL1::EFexEMClusterTool::addOnce
void addOnce(const CaloCell *inputCell, std::vector< const CaloCell * > &outputVector) const
adds SC to vector if the SC is not part of this vector yet
Definition: EFexEMClusterTool.cxx:336
LVL1::EFexEMClusterTool::REtaL12
double REtaL12(const CaloCell *centreCell, int etaWidth1, int phiWidth1, int etaWidth2, int phiWidth2, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
calculate the energy isolation of the central cell along eta using Layer 1 and Layer 2
Definition: EFexEMClusterTool.cxx:594
LVL1::EFexEMClusterTool::L1Width
double L1Width(const CaloCell *centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
calculate the lateral isolation aorund the central cell
Definition: EFexEMClusterTool.cxx:448
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
LVL1::EFexEMClusterTool::EFexEMClusterTool
EFexEMClusterTool(const std::string &type, const std::string &name, const IInterface *parent)
Name : EFexEMClusterTool.cxx PACKAGE : Trigger/TrigT1/TrigT1CaloFexPerf AUTHOR : Denis Oliveira Damaz...
Definition: EFexEMClusterTool.cxx:14
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
CaloCell_SuperCell_ID
Helper class for offline supercell identifiers.
Definition: CaloCell_SuperCell_ID.h:48
LVL1::EFexEMClusterTool::m_etaWidth_TDRCluster
int m_etaWidth_TDRCluster
eta width of the TDR cluster formation given in number of SCs (including the central cell),...
Definition: EFexEMClusterTool.h:222
LVL1::EFexEMClusterTool::NextEtaCell_OW
const CaloCell * NextEtaCell_OW(const CaloCell *inputCell, bool upwards, const CaloConstCellContainer *&cellContainer, const CaloCell_SuperCell_ID *&idHelper) const
returns the SC left/right to the input cell for the OW
Definition: EFexEMClusterTool.cxx:1314
LVL1::EFexEMClusterTool::RHadTile
double RHadTile(const CaloCell *centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh, const TileID *m_tileIDHelper, const CaloConstCellContainer *tileCellCon, float tileNoiseThresh, float &HadronicET) const
calculate the hadronic isolation for a seed cell using TileCal cells
Definition: EFexEMClusterTool.cxx:550
lumiFormat.i
int i
Definition: lumiFormat.py:92
LVL1::EFexEMClusterTool::L2clusET
double L2clusET(const CaloCell *centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
calculate cluster energy of cells in L2 around the central cell in a given eta/phi width
Definition: EFexEMClusterTool.cxx:543
LVL1::EFexEMClusterTool::sumVectorET
double sumVectorET(const std::vector< const CaloCell * > &inputVector, float digitScale=0., float digitThreshold=0.) const
calculate cluster energy from all SCs in PS, L1, L2, L3
Definition: EFexEMClusterTool.cxx:1095
TileID
Helper class for TileCal offline identifiers.
Definition: TileID.h:68
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
LVL1::EFexEMClusterTool::dR
double dR(double eta1, double phi1, double eta2, double phi2) const
calculate deltaR between two points in eta/phi space
Definition: EFexEMClusterTool.cxx:976
CaloCell_Base_ID::sampling
int sampling(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
LVL1::EFexEMClusterTool::checkTileCell
void checkTileCell(const TileCell *&inputCell, std::vector< const TileCell * > &tileCellVector, bool &isAlreadyThere) const
determine if Tile cell has already been taken into account
Definition: EFexEMClusterTool.cxx:397
CaloConstCellContainer::findCell
const CaloCell * findCell(IdentifierHash theHash) const
fast find method given identifier hash.
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
LVL1::EFexEMClusterTool::m_nominalDigitization
float m_nominalDigitization
value of nominal digitisation
Definition: EFexEMClusterTool.h:218
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
TauGNNUtils::Variables::Track::dPhi
bool dPhi(const xAOD::TauJet &tau, const xAOD::TauTrack &track, double &out)
Definition: TauGNNUtils.cxx:530
LVL1::EFexEMClusterTool::m_REta_thresh
float m_REta_thresh
threshold for isolation REta (baseline selection)
Definition: EFexEMClusterTool.h:210
xAOD::TriggerTower_v2
Description of TriggerTower_v2.
Definition: TriggerTower_v2.h:49
xAOD::TriggerTower_v2::eta
virtual double eta() const final
The pseudorapidity ( ) of the particle.
Definition: TriggerTower_v2.cxx:210
test_pyathena.parent
parent
Definition: test_pyathena.py:15
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:127
CaloCell_Base_ID::eta
int eta(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
CaloCell_Base_ID::sub_calo
int sub_calo(const Identifier id) const
returns an int taken from SUBCALO enum and describing the subCalo to which the Id belongs.
EFexEMClusterTool.h
CaloCell_Base_ID::TILE
@ TILE
Definition: CaloCell_Base_ID.h:46
LVL1::EFexEMClusterTool::m_etaHadWidth_RHadIsolation
int m_etaHadWidth_RHadIsolation
hadronic eta width for RHad isolation given in number of SCs
Definition: EFexEMClusterTool.h:231
createCablingJSON.eta_index
int eta_index
Definition: createCablingJSON.py:9
LVL1::EFexEMClusterTool::NextEtaCell_Barrel
const CaloCell * NextEtaCell_Barrel(const CaloCell *inputCell, bool upwards, const CaloConstCellContainer *&cellContainer, const CaloCell_SuperCell_ID *&idHelper) const
returns the SC left/right to the input cell for the barrel
Definition: EFexEMClusterTool.cxx:1187
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
TrigConf::name
Definition: HLTChainList.h:35
LVL1::EFexEMClusterTool::m_RHad_thresh
float m_RHad_thresh
threshold for isolation RHad (baseline selection)
Definition: EFexEMClusterTool.h:211
LVL1::EFexEMClusterTool::m_phiHadWidth_RHadIsolation
int m_phiHadWidth_RHadIsolation
hadronic phi width for RHad isolation given in number of SCs
Definition: EFexEMClusterTool.h:232
LVL1::EFexEMClusterTool::NextEtaCell_IW
const CaloCell * NextEtaCell_IW(const CaloCell *inputCell, bool upwards, const CaloConstCellContainer *&cellContainer, const CaloCell_SuperCell_ID *&idHelper) const
returns the SC left/right to the input cell for the IW
Definition: EFexEMClusterTool.cxx:1494
LVL1::EFexEMClusterTool::m_clustET_NoIso_thresh
float m_clustET_NoIso_thresh
threshold for applying cluster isolation cuts (baseline selection)
Definition: EFexEMClusterTool.h:209
TrigConf::counter
Definition: HLTChainList.h:37
LVL1::EFexEMClusterTool::m_etaWidth_REtaIsolation_den
int m_etaWidth_REtaIsolation_den
eta width for REta isolation given in number of SCs (denominator of fraction)
Definition: EFexEMClusterTool.h:227
LVL1::EFexEMClusterTool::tileCellEnergyCalib
double tileCellEnergyCalib(float eIn, float etaIn, float tileNoiseThresh) const
determine transverse energy and apply noise threshold to Tile cells
Definition: EFexEMClusterTool.cxx:406
LVL1::EFexEMClusterTool::EnergyPerTileLayer
std::vector< double > EnergyPerTileLayer(const std::vector< const CaloCell * > &inputSCVector, const CaloConstCellContainer *CellCon, const TileID *tileIDHelper, bool isOW, float tileNoiseThresh) const
match all Tile cells to a given L2Cluster and determine the summed energy per Tile layer
Definition: EFexEMClusterTool.cxx:888
CaloCell::ID
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition: CaloCell.h:279
CaloCell_Base_ID::phi
int phi(const Identifier id) const
LAr field values (NOT_VALID == invalid request)
LVL1::EFexEMClusterTool::m_eta_dropL1Width
float m_eta_dropL1Width
max eta for applying cut on L1Width (baseline selection)
Definition: EFexEMClusterTool.h:213
LVL1::EFexEMClusterTool::m_phiWidth_REtaIsolation_den
int m_phiWidth_REtaIsolation_den
phi width for REta isolation given in number of SCs (denominator of fraction)
Definition: EFexEMClusterTool.h:228
LVL1::EFexEMClusterTool::returnCellFromCont
const CaloCell * returnCellFromCont(Identifier inputID, const CaloConstCellContainer *&cellContainer, const CaloCell_SuperCell_ID *&idHelper) const
helper functions to find neighbouring cells
Definition: EFexEMClusterTool.cxx:1148
LVL1::EFexEMClusterTool::CaloCellET
float CaloCellET(const CaloCell *const &inputCell, float digitScale, float digitThreshold) const
private algorithms
Definition: EFexEMClusterTool.cxx:173
LVL1::EFexEMClusterTool::m_etaWidth_wstotIsolation
int m_etaWidth_wstotIsolation
eta width for wstot isolation given in number of SCs
Definition: EFexEMClusterTool.h:223
TileCell::ene2
float ene2(void) const
get energy of second PMT
Definition: TileCell.h:195
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
CaloConstCellContainer
CaloCellContainer that can accept const cell pointers.
Definition: CaloConstCellContainer.h:45
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
LVL1::EFexEMClusterTool::looseAlg
std::vector< AlgResult > looseAlg(const CaloConstCellContainer *SCs, const xAOD::TriggerTowerContainer *TTs, const CaloCell_SuperCell_ID *idHelper, const TileID *m_tileIDHelper, const CaloConstCellContainer *tileCellCon) const
algorithm fors cluster building
Definition: EFexEMClusterTool.cxx:88
xAOD::phiWidth
phiWidth
Definition: RingSetConf_v1.cxx:612
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
LVL1::EFexEMClusterTool::TT_phi
double TT_phi(const xAOD::TriggerTower *&inputTower) const
convert the TT phi to match the definition of SC phi
Definition: EFexEMClusterTool.cxx:962
LVL1::EFexEMClusterTool::m_etaWidth_REtaIsolation_num
int m_etaWidth_REtaIsolation_num
eta width for REta isolation given in number of SCs (numerator of fraction)
Definition: EFexEMClusterTool.h:229
LVL1::EFexEMClusterTool::m_phiEMWidth_RHadIsolation
int m_phiEMWidth_RHadIsolation
EM phi width for RHad isolation given in number of SCs.
Definition: EFexEMClusterTool.h:226
LVL1::EFexEMClusterTool::fromLayer2toLayer3
const CaloCell * fromLayer2toLayer3(const CaloConstCellContainer *&inputContainer, const CaloCell *inputCell, const CaloCell_SuperCell_ID *&idHelper) const
match SCs from the cluster in L2 to one cell of L3
Definition: EFexEMClusterTool.cxx:755
LVL1::EFexEMClusterTool::TT_ET
double TT_ET(const xAOD::TriggerTower *&inputTower) const
calculate the energy of an input TT
Definition: EFexEMClusterTool.cxx:1042
LVL1::EFexEMClusterTool::L2cluster
std::vector< const CaloCell * > L2cluster(const CaloCell *centreCell, int etaWidth, int phiWidth, const CaloConstCellContainer *scells, const CaloCell_SuperCell_ID *idHelper, float digitScale, float digitThresh) const
form the cluster from cells of the second layer L2
Definition: EFexEMClusterTool.cxx:842
CaloConstCellContainer::beginConstCalo
::CaloCellContainer::const_iterator beginConstCalo(CaloCell_ID::SUBCALO caloNum) const
get const begin iterator on cell of just one calo
AthAlgTool
Definition: AthAlgTool.h:26
CaloConstCellContainer::endConstCalo
::CaloCellContainer::const_iterator endConstCalo(CaloCell_ID::SUBCALO caloNum) const
get const begin iterator on cell of just one calo
LVL1::EFexEMClusterTool::fromLayer2toLayer1
void fromLayer2toLayer1(const CaloConstCellContainer *&inputContainer, const CaloCell *inputCell, std::vector< const CaloCell * > &outputVector, const CaloCell_SuperCell_ID *&idHelper) const
match SCs from the cluster in L2 to L1
Definition: EFexEMClusterTool.cxx:628
LVL1::EFexEMClusterTool::m_etaEMWidth_RHadIsolation
int m_etaEMWidth_RHadIsolation
EM eta width for RHad isolation given in number of SCs.
Definition: EFexEMClusterTool.h:225
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
LVL1::EFexEMClusterTool::checkDig
bool checkDig(float EM_ET, float digitScale, float digitThresh) const
check if conversion from ET to energy after digitization was performed successfully
Definition: EFexEMClusterTool.cxx:1105
LVL1::EFexEMClusterTool::clusterAlg
std::vector< AlgResult > clusterAlg(bool applyBaselineCuts, const CaloConstCellContainer *scells, const xAOD::TriggerTowerContainer *TTs, const CaloCell_SuperCell_ID *idHelper, const TileID *m_tileIDHelper, const CaloConstCellContainer *tileCellCon) const
find cluster and associated variables using a user defined selection
Definition: EFexEMClusterTool.cxx:49
LVL1::EFexEMClusterTool::m_clustET_looseAlg_thresh
float m_clustET_looseAlg_thresh
threshold for minimum cluster energy for the loose eFEX algorithm
Definition: EFexEMClusterTool.h:233
CaloCell::eta
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Definition: CaloCell.h:366
TileCellContainer.h
LVL1::EFexEMClusterTool::matchingHCAL_TT
const xAOD::TriggerTower * matchingHCAL_TT(const CaloCell *&inputCell, const xAOD::TriggerTowerContainer *&TTContainer) const
Match each SC from L2 to one corresponding TT.
Definition: EFexEMClusterTool.cxx:986