ATLAS Offline Software
CaloClusterMomentsMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //-----------------------------------------------------------------------
6 // File and Version Information:
7 //
8 // Description: see CaloClusterMomentsMaker.h
9 //
10 // Environment:
11 // Software developed for the ATLAS Detector at CERN LHC
12 //
13 // Author List:
14 // Sven Menke
15 // Peter Loch
16 //
17 //-----------------------------------------------------------------------
18 
20 #include "CaloEvent/CaloCell.h"
21 #include "CaloEvent/CaloClusterContainer.h"
22 #include "CaloEvent/CaloCluster.h"
23 #include "CaloGeoHelpers/proxim.h"
24 #include "CaloEvent/CaloPrefetch.h"
29 
32 
33 #include "CLHEP/Units/SystemOfUnits.h"
34 #include "CxxUtils/prefetch.h"
35 #include <Eigen/Dense>
36 #include <cmath>
37 #include <cstdint>
38 #include <iterator>
39 #include <limits>
40 #include <sstream>
41 
42 #include <map>
43 #include <vector>
44 #include <tuple>
45 #include <string>
46 #include <cstdio>
47 #include <cmath>
48 
49 using CLHEP::deg;
50 using CLHEP::cm;
51 
52 
53 // Known moments
54 namespace {
55  // name -> enum translator
56  const std::map<std::string,xAOD::CaloCluster::MomentType> momentNameToEnumMap = {
57  { "AVG_LAR_Q", xAOD::CaloCluster::AVG_LAR_Q },
58  { "AVG_TILE_Q", xAOD::CaloCluster::AVG_TILE_Q },
59  { "BADLARQ_FRAC", xAOD::CaloCluster::BADLARQ_FRAC },
60  { "BAD_CELLS_CORR_E", xAOD::CaloCluster::BAD_CELLS_CORR_E },
61  { "CELL_SIGNIFICANCE", xAOD::CaloCluster::CELL_SIGNIFICANCE },
62  { "CELL_SIG_SAMPLING", xAOD::CaloCluster::CELL_SIG_SAMPLING },
63  { "CENTER_LAMBDA", xAOD::CaloCluster::CENTER_LAMBDA },
64  { "CENTER_MAG", xAOD::CaloCluster::CENTER_MAG },
65  { "CENTER_X", xAOD::CaloCluster::CENTER_X },
66  { "CENTER_Y", xAOD::CaloCluster::CENTER_Y },
67  { "CENTER_Z", xAOD::CaloCluster::CENTER_Z },
68  { "DELTA_ALPHA", xAOD::CaloCluster::DELTA_ALPHA },
69  { "DELTA_PHI", xAOD::CaloCluster::DELTA_PHI },
70  { "DELTA_THETA", xAOD::CaloCluster::DELTA_THETA },
71  { "ENG_BAD_CELLS", xAOD::CaloCluster::ENG_BAD_CELLS },
72  { "ENG_BAD_HV_CELLS", xAOD::CaloCluster::ENG_BAD_HV_CELLS },
73  { "ENG_FRAC_CORE", xAOD::CaloCluster::ENG_FRAC_CORE },
74  { "ENG_FRAC_EM", xAOD::CaloCluster::ENG_FRAC_EM },
75  { "ENG_FRAC_MAX", xAOD::CaloCluster::ENG_FRAC_MAX },
76  { "ENG_POS", xAOD::CaloCluster::ENG_POS },
77  { "FIRST_ENG_DENS", xAOD::CaloCluster::FIRST_ENG_DENS },
78  { "FIRST_ETA", xAOD::CaloCluster::FIRST_ETA },
79  { "FIRST_PHI", xAOD::CaloCluster::FIRST_PHI },
80  { "ISOLATION", xAOD::CaloCluster::ISOLATION },
81  { "LATERAL", xAOD::CaloCluster::LATERAL },
82  { "LONGITUDINAL", xAOD::CaloCluster::LONGITUDINAL },
83  { "MASS", xAOD::CaloCluster::MASS },
84  { "N_BAD_CELLS", xAOD::CaloCluster::N_BAD_CELLS },
85  { "N_BAD_HV_CELLS", xAOD::CaloCluster::N_BAD_HV_CELLS },
86  { "N_BAD_CELLS_CORR", xAOD::CaloCluster::N_BAD_CELLS_CORR },
87  { "PTD", xAOD::CaloCluster::PTD },
88  { "SECOND_ENG_DENS", xAOD::CaloCluster::SECOND_ENG_DENS },
89  { "SECOND_LAMBDA", xAOD::CaloCluster::SECOND_LAMBDA },
90  { "SECOND_R", xAOD::CaloCluster::SECOND_R },
91  { "SECOND_TIME", xAOD::CaloCluster::SECOND_TIME },
92  { "SIGNIFICANCE", xAOD::CaloCluster::SIGNIFICANCE },
93  { "EM_PROBABILITY", xAOD::CaloCluster::EM_PROBABILITY },
94  { "NCELL_SAMPLING", xAOD::CaloCluster::NCELL_SAMPLING }
95  };
96  // enum -> name translator
97  const std::map<xAOD::CaloCluster::MomentType,std::string> momentEnumToNameMap = {
98  { xAOD::CaloCluster::AVG_LAR_Q, "AVG_LAR_Q" },
99  { xAOD::CaloCluster::AVG_TILE_Q, "AVG_TILE_Q" },
100  { xAOD::CaloCluster::BADLARQ_FRAC, "BADLARQ_FRAC" },
101  { xAOD::CaloCluster::BAD_CELLS_CORR_E, "BAD_CELLS_CORR_E" },
102  { xAOD::CaloCluster::CELL_SIGNIFICANCE, "CELL_SIGNIFICANCE"},
103  { xAOD::CaloCluster::CELL_SIG_SAMPLING, "CELL_SIG_SAMPLING"},
104  { xAOD::CaloCluster::CENTER_LAMBDA, "CENTER_LAMBDA" },
105  { xAOD::CaloCluster::CENTER_MAG, "CENTER_MAG" },
106  { xAOD::CaloCluster::CENTER_X, "CENTER_X" },
107  { xAOD::CaloCluster::CENTER_Y, "CENTER_Y" },
108  { xAOD::CaloCluster::CENTER_Z, "CENTER_Z" },
109  { xAOD::CaloCluster::DELTA_ALPHA, "DELTA_ALPHA" },
110  { xAOD::CaloCluster::DELTA_PHI, "DELTA_PHI" },
111  { xAOD::CaloCluster::DELTA_THETA, "DELTA_THETA" },
112  { xAOD::CaloCluster::ENG_BAD_CELLS, "ENG_BAD_CELLS" },
113  { xAOD::CaloCluster::ENG_BAD_HV_CELLS, "ENG_BAD_HV_CELLS" },
114  { xAOD::CaloCluster::ENG_FRAC_CORE, "ENG_FRAC_CORE" },
115  { xAOD::CaloCluster::ENG_FRAC_EM, "ENG_FRAC_EM" },
116  { xAOD::CaloCluster::ENG_FRAC_MAX, "ENG_FRAC_MAX" },
117  { xAOD::CaloCluster::ENG_POS, "ENG_POS" },
118  { xAOD::CaloCluster::FIRST_ENG_DENS, "FIRST_ENG_DENS" },
119  { xAOD::CaloCluster::FIRST_ETA, "FIRST_ETA" },
120  { xAOD::CaloCluster::FIRST_PHI, "FIRST_PHI" },
121  { xAOD::CaloCluster::ISOLATION, "ISOLATION" },
122  { xAOD::CaloCluster::LATERAL, "LATERAL" },
123  { xAOD::CaloCluster::LONGITUDINAL, "LONGITUDINAL" },
124  { xAOD::CaloCluster::MASS, "MASS" },
125  { xAOD::CaloCluster::N_BAD_CELLS, "N_BAD_CELLS" },
126  { xAOD::CaloCluster::N_BAD_HV_CELLS, "N_BAD_HV_CELLS" },
127  { xAOD::CaloCluster::N_BAD_CELLS_CORR, "N_BAD_CELLS_CORR" },
128  { xAOD::CaloCluster::PTD, "PTD" },
129  { xAOD::CaloCluster::SECOND_ENG_DENS, "SECOND_ENG_DENS" },
130  { xAOD::CaloCluster::SECOND_LAMBDA, "SECOND_LAMBDA" },
131  { xAOD::CaloCluster::SECOND_R, "SECOND_R" },
132  { xAOD::CaloCluster::SECOND_TIME, "SECOND_TIME" },
133  { xAOD::CaloCluster::SIGNIFICANCE, "SIGNIFICANCE" },
134  { xAOD::CaloCluster::EM_PROBABILITY, "EM_PROBABILITY" },
135  { xAOD::CaloCluster::NCELL_SAMPLING, "NCELL_SAMPLING" }
136  };
137 }
138 
139 //###############################################################################
140 
142  const std::string& name,
143  const IInterface* parent)
144  : AthAlgTool(type, name, parent),
145  m_calo_id(nullptr),
146  m_maxAxisAngle(20*deg),
147  m_minRLateral(4*cm),
148  m_minLLongitudinal(10*cm),
149  m_minBadLArQuality(4000),
150  m_calculateSignificance(false),
151  m_calculateIsolation(false),
152  m_calculateLArHVFraction(false),
153  m_twoGaussianNoise(false),
154  m_caloDepthTool("CaloDepthTool",this),
155  m_larHVFraction("LArHVFraction",this),
156  m_absOpt(false)
157 {
158  declareInterface<CaloClusterCollectionProcessor> (this);
159  // Name(s) of Moments to calculate
160  declareProperty("MomentsNames",m_momentsNames);
161 
162  // Maximum allowed angle between shower axis and the vector pointing
163  // to the shower center from the IP in degrees. This property is needed
164  // to protect against cases where all significant cells are in one sampling
165  // and the shower axis can thus not be defined.
166  declareProperty("MaxAxisAngle",m_maxAxisAngle);
167  declareProperty("MinRLateral",m_minRLateral);
168  declareProperty("MinLLongitudinal",m_minLLongitudinal);
169  declareProperty("MinBadLArQuality",m_minBadLArQuality);
170  // Use 2-gaussian noise for Tile
171  declareProperty("TwoGaussianNoise",m_twoGaussianNoise);
172  declareProperty("LArHVFraction",m_larHVFraction,"Tool Handle for LArHVFraction");
173  // Not used anymore (with xAOD), but required when configured from COOL.
174  declareProperty("AODMomentsNames",m_momentsNamesAOD);
175  // Use weighting of neg. clusters option?
176  declareProperty("WeightingOfNegClusters", m_absOpt);
177  // Set eta boundary for transition from outer to inner wheel in EME2
178  declareProperty("EMECAbsEtaWheelTransition",m_etaInnerWheel);
179 }
180 
181 //###############################################################################
182 
184 {
185  // loop list of requested moments
186  std::string::size_type nstr(0); int nmom(0);
187  for (const auto& mom : m_momentsNames) {
188  ATH_MSG_DEBUG("Moment " << mom << " requested");
189  // check if moment is known (enumerator available)
190  auto fmap(momentNameToEnumMap.find(mom));
191  if (fmap != momentNameToEnumMap.end()) {
192  // valid moment found
193  nstr = std::max(nstr, mom.length());
194  ++nmom;
195  if (fmap->second == xAOD::CaloCluster::SECOND_TIME) {
196  // special flag for second moment of cell times - this moment is not
197  // calculated in this tool! Do not add to internal (!) valid moments
198  // list. Its value is available from xAOD::CaloCluster::secondTime()!
199  m_secondTime = true;
200  } else if (fmap->second == xAOD::CaloCluster::NCELL_SAMPLING) {
201  // flag indicates if number of cells in a sampling should be counted.
202  // This is a vector of integers counts that is filled in this tool but
203  // does not need any post-processing (e.g. normalization). It is not
204  // added to the valid moments list for this reason.
205  ATH_MSG_DEBUG("moment " << fmap->first << " found");
206  m_nCellsPerSampling = true;
207  } else if (fmap->second == xAOD::CaloCluster::EM_PROBABILITY) {
209  << " not calculated in this tool - misconfiguration?");
210  } else {
211  // all other valid moments
212  m_validMoments.push_back(fmap->second);
213  // flag some special requests
214  switch (fmap->second) {
218  break;
220  m_calculateIsolation = true;
221  break;
224  break;
225  default:
226  break;
227  } // set special processing flags
228  } // moment calculated with this tool
229  } else {
230  ATH_MSG_ERROR("Moment name " << mom << " not known; known moments are:");
231  char buffer[128];
232  std::string::size_type lstr(nstr);
233  // determine field size
234  for (const auto& fmom : momentNameToEnumMap) {
235  lstr = std::max(lstr, fmom.first.length());
236  }
237  // print available moments
238  for (const auto& fmom : momentNameToEnumMap) {
239  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)lstr,
240  (int)lstr, fmom.first.c_str(), (int)fmom.second);
242  }
243  auto fmom(momentNameToEnumMap.find("SECOND_TIME"));
244  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
245  (int)nstr, fmom->first.c_str(), (int)fmom->second);
247  fmom = momentNameToEnumMap.find("NCELL_SAMPLING");
248  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
249  (int)nstr, fmom->first.c_str(), (int)fmom->second);
251  return StatusCode::FAILURE;
252  } // found unknown moment name
253  } // loop configured moment names
254 
255  // sort and remove duplicates
256  std::sort(m_validMoments.begin(), m_validMoments.end());
257  m_validMoments.erase(
258  std::unique(m_validMoments.begin(), m_validMoments.end()),
259  m_validMoments.end());
260 
261  // print configured moments
262  ATH_MSG_INFO("Construct and save " << nmom << " cluster moments: ");
263  char buffer[128];
264  for (auto menum : m_validMoments) {
265  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
266  (int)nstr, momentEnumToNameMap.at(menum).c_str(), (int)menum);
268  }
269  if (m_secondTime) {
270  auto fmom(momentNameToEnumMap.find("SECOND_TIME"));
271  sprintf(buffer, "moment name: %-*.*s - enumerator: %i (save only)",
272  (int)nstr, (int)nstr, fmom->first.c_str(), (int)fmom->second);
274  }
275  if (m_nCellsPerSampling) {
276  auto fmom(momentNameToEnumMap.find("NCELL_SAMPLING"));
277  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
278  (int)nstr, fmom->first.c_str(), (int)fmom->second);
280  }
281 
282  // retrieve CaloCell ID server
283  CHECK(detStore()->retrieve(m_calo_id,"CaloCell_ID"));
284 
285  // retrieve the calo depth tool
286  CHECK(m_caloDepthTool.retrieve());
288 
289  // retrieve specific servers and tools for selected processes
291  if (m_calculateLArHVFraction) { ATH_CHECK(m_larHVFraction.retrieve()); } else { m_larHVFraction.disable(); }
292 
293  return StatusCode::SUCCESS;
294 }
295 
297 {
298  return StatusCode::SUCCESS;
299 }
300 
301 //#############################################################################
302 
304 
305 
306 struct cellinfo {
307  double x;
308  double y;
309  double z;
310  double energy;
311  double eta;
312  double phi;
313  double r;
314  double lambda;
315  double volume;
317  unsigned int identifier;
318  cellinfo(const bool useGPUCriteria = false)
319  {
320  if (useGPUCriteria) {
321  x = 0;
322  y = 0;
323  z = 0;
324  energy = 0;
325  eta = 0;
326  phi = 0;
327  r = 0;
328  lambda = 0;
329  volume = 0;
331  identifier = 0;
332  }
333  }
334 };
335 
336 } // namespace CaloClusterMomentsMaker_detail
337 
339 CaloClusterMomentsMaker::execute(const EventContext& ctx,
340  xAOD::CaloClusterContainer *theClusColl)
341  const
342 {
343  ATH_MSG_DEBUG("Executing " << name());
344 
345  // Maps cell IdentifierHash to cluster index in cluster collection.
346  // Only used when cluster isolation moment is calculated.
347  using clusterIdx_t = std::uint16_t;
348  typedef std::pair<clusterIdx_t, clusterIdx_t> clusterPair_t;
349  std::vector<clusterPair_t> clusterIdx;
350  const clusterIdx_t noCluster = std::numeric_limits<clusterIdx_t>::max();
351 
352  const CaloNoise* noise=nullptr;
355  noise=*noiseHdl;
356  }
357 
359  const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
360  // Counters for number of empty and non-empty neighbor cells per sampling
361  // layer Only used when cluster isolation moment is calculated.
362  int nbEmpty[CaloCell_ID::Unknown];
363  int nbNonEmpty[CaloCell_ID::Unknown];
364 
365  // prepare stuff from entire collection in case isolation moment
366  // should be calculated
367 
368  if ( m_calculateIsolation ) {
369 
370  if (theClusColl->size() >= noCluster) {
371  msg(MSG::ERROR) << "Too many clusters" << endmsg;
372  return StatusCode::FAILURE;
373  }
374 
375  // initialize with "empty" values
376  clusterIdx.resize(m_calo_id->calo_cell_hash_max(),
377  clusterPair_t(noCluster, noCluster));
378 
379  int iClus = 0;
380  for (xAOD::CaloCluster* theCluster : *theClusColl) {
381  // loop over all cell members and fill cell vector for used cells
382  xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
383  xAOD::CaloCluster::cell_iterator cellIterEnd = theCluster->cell_end();
384  for(; cellIter != cellIterEnd; cellIter++ ){
385  CxxUtils::prefetchNext(cellIter, cellIterEnd);
386  const CaloCell* pCell = *cellIter;
387 
388  Identifier myId = pCell->ID();
389  IdentifierHash myHashId = m_calo_id->calo_cell_hash(myId);
390  if ( clusterIdx[(unsigned int)myHashId].first != noCluster) {
391  // check weight and assign to current cluster if weight is > 0.5
392  double weight = cellIter.weight();
393  if ( weight > 0.5 )
394  clusterIdx[(unsigned int)myHashId].first = iClus;
395  }
396  else {
397  clusterIdx[(unsigned int)myHashId].first = iClus;
398  }
399  }
400  ++iClus;
401  }
402  }
403 
404  // Move allocation of temporary arrays outside the cluster loop.
405  // That way, we don't need to delete and reallocate them
406  // each time through the loop.
407 
408  std::vector<CaloClusterMomentsMaker_detail::cellinfo> cellinfo;
409  std::vector<double> maxSampE (CaloCell_ID::Unknown);
410  std::vector<double> myMoments(m_validMoments.size(),0);
411  std::vector<double> myNorms(m_validMoments.size(),0);
412  std::vector<std::tuple<int,int> > nCellsSamp; nCellsSamp.reserve(CaloCell_ID::Unknown);
413  std::vector<IdentifierHash> theNeighbors;
414  // loop over individual clusters
415  xAOD::CaloClusterContainer::iterator clusIter = theClusColl->begin();
416  xAOD::CaloClusterContainer::iterator clusIterEnd = theClusColl->end();
417  int iClus = 0;
418  for( ;clusIter!=clusIterEnd;++clusIter,++iClus) {
419  xAOD::CaloCluster * theCluster = *clusIter;
420 
421  double w(0),xc(0),yc(0),zc(0),mx(0),my(0),mz(0),mass(0);
422  double eBad(0),ebad_dac(0),ePos(0),eBadLArQ(0),sumSig2(0),maxAbsSig(0);
423  double eLAr2(0),eLAr2Q(0);
424  double eTile2(0),eTile2Q(0);
425  double eBadLArHV(0);
426  int nbad(0),nbad_dac(0),nBadLArHV(0);
427  unsigned int ncell(0),i,nSigSampl(0);
428  unsigned int theNumOfCells = theCluster->size();
429 
430  // these two are needed for the LATERAL moment
431  int iCellMax(-1);
432  int iCellScndMax(-1);
433 
434  if (cellinfo.capacity() == 0)
435  cellinfo.reserve (theNumOfCells*2);
436  cellinfo.resize (theNumOfCells, CaloClusterMomentsMaker_detail::cellinfo(m_useGPUCriteria));
437 
438  for(i=0;i<(unsigned int)CaloCell_ID::Unknown;i++)
439  maxSampE[i] = 0;
440 
441  if ( !m_momentsNames.empty() ) {
442  std::fill (myMoments.begin(), myMoments.end(), 0);
443  std::fill (myNorms.begin(), myNorms.end(), 0);
444  if ( m_calculateIsolation ) {
445  std::fill_n(nbNonEmpty, CaloCell_ID::Unknown, 0);
446  std::fill_n(nbEmpty, CaloCell_ID::Unknown, 0);
447  }
448 
449  // loop over all cell members and calculate the center of mass
450  xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
451  xAOD::CaloCluster::cell_iterator cellIterEnd = theCluster->cell_end();
452  for(; cellIter != cellIterEnd; cellIter++ ){
453  CaloPrefetch::nextDDE(cellIter, cellIterEnd);
454 
455  const CaloCell* pCell = (*cellIter);
456  Identifier myId = pCell->ID();
457  const CaloDetDescrElement* myCDDE = pCell->caloDDE();
458  double ene = pCell->e();
459  if(m_absOpt) ene = std::abs(ene);
460  double weight = cellIter.weight();//theCluster->getCellWeight(cellIter);
461  if ( pCell->badcell() ) {
462  eBad += ene*weight;
463  nbad++;
464  if(ene!=0){
465  ebad_dac+=ene*weight;
466  nbad_dac++;
467  }
468  }
469  else {
470  if ( myCDDE && ! (myCDDE->is_tile())
471  && ((pCell->provenance() & 0x2000) == 0x2000)
472  && !((pCell->provenance() & 0x0800) == 0x0800)) {
473  if ( pCell->quality() > m_minBadLArQuality ) {
474  eBadLArQ += ene*weight;
475  }
476  eLAr2 += ene*weight*ene*weight;
477  eLAr2Q += ene*weight*ene*weight*pCell->quality();
478  }
479  if ( myCDDE && myCDDE->is_tile() ) {
480  uint16_t tq = pCell->quality();
481  uint8_t tq1 = (0xFF00&tq)>>8; // quality in channel 1
482  uint8_t tq2 = (0xFF&tq); // quality in channel 2
483  // reject cells with either 0xFF00 or 0xFF
484  if ( ((tq1&0xFF) != 0xFF) && ((tq2&0xFF) != 0xFF) ) {
485  eTile2 += ene*weight*ene*weight;
486  // take the worse of both qualities (one might be 0 in
487  // 1-channel cases)
488  eTile2Q += ene*weight*ene*weight*(tq1>tq2?tq1:tq2);
489  }
490  }
491  }
492  if ( ene > 0 ) {
493  ePos += ene*weight;
494  }
495 
496  if ( m_calculateSignificance ) {
497  const float sigma = m_twoGaussianNoise ?\
498  noise->getEffectiveSigma(pCell->ID(),pCell->gain(),pCell->energy()) : \
499  noise->getNoise(pCell->ID(),pCell->gain());
500 
501  sumSig2 += sigma*sigma;
502  // use geomtery weighted energy of cell for leading cell significance
503  double Sig = (sigma>0?ene*weight/sigma:0);
504  if (m_useGPUCriteria) {
505  unsigned int thisSampl = myCDDE->getSampling();
506  if ( ( std::abs(Sig) > std::abs(maxAbsSig) ) ||
507  ( std::abs(Sig) == std::abs(maxAbsSig) && thisSampl > nSigSampl ) ||
508  ( std::abs(Sig) == std::abs(maxAbsSig) && thisSampl == nSigSampl && Sig > maxAbsSig ) ) {
509  maxAbsSig = Sig;
510  nSigSampl = thisSampl;
511  }
512 
513  }
514  else {
515  if ( std::abs(Sig) > std::abs(maxAbsSig) ) {
516  maxAbsSig = Sig;
517  nSigSampl = myCDDE->getSampling();
518  }
519  }
520  }
521  if ( m_calculateIsolation ) {
522  // get all 2D Neighbours if the cell is not inside another cluster with
523  // larger weight
524 
525  IdentifierHash myHashId = m_calo_id->calo_cell_hash(myId);
526  if ( clusterIdx[myHashId].first == iClus ) {
527  theNeighbors.clear();
528  m_calo_id->get_neighbours(myHashId, LArNeighbours::all2D, theNeighbors);
529  for (const auto& nhash: theNeighbors) {
530  clusterPair_t& idx = clusterIdx[nhash];
531 
532  // only need to look at each cell once per cluster
533  if ( idx.second == iClus ) continue;
534  idx.second = iClus;
535 
536  if ( idx.first == noCluster ) {
537  ++ nbEmpty[m_calo_id->calo_sample(nhash)];
538  } else if ( idx.first != iClus ) {
539  ++ nbNonEmpty[m_calo_id->calo_sample(nhash)];
540  }
541 
542  }
543  }
544  }
545 
546  if ( myCDDE != nullptr ) {
547  if ( m_nCellsPerSampling ) {
548  CaloCell_ID::CaloSample sam = myCDDE->getSampling();
549  size_t idx((size_t)sam);
550  if ( idx >= nCellsSamp.size() ) { nCellsSamp.resize(idx+1, { 0, 0 } ); }
551  std::get<0>(nCellsSamp[idx])++;
552  // special count for inner wheel cells in EME2
553  if ( sam == CaloCell_ID::EME2 && std::abs(myCDDE->eta()) > m_etaInnerWheel ) { std::get<1>(nCellsSamp[idx])++; }
554  }
555  if ( ene > 0. && weight > 0) {
556  // get all geometric information needed ...
558  ci.x = myCDDE->x();
559  ci.y = myCDDE->y();
560  ci.z = myCDDE->z();
561  ci.eta = myCDDE->eta();
562  ci.phi = myCDDE->phi();
563  ci.energy = ene*weight;
564  ci.volume = myCDDE->volume();
565  ci.sample = myCDDE->getSampling();
566  ci.identifier = m_calo_id->calo_cell_hash(myId);
567 
568  if ( ci.energy > maxSampE[(unsigned int)ci.sample] )
569  maxSampE[(unsigned int)ci.sample] = ci.energy;
570 
571  if (m_useGPUCriteria) {
572  if (iCellMax < 0 ||
573  ci.energy > cellinfo[iCellMax].energy ||
574  (ci.energy == cellinfo[iCellMax].energy && ci.identifier > cellinfo[iCellMax].identifier) ) {
575  iCellScndMax = iCellMax;
576  iCellMax = ncell;
577  }
578  else if (iCellScndMax < 0 ||
579  ci.energy > cellinfo[iCellScndMax].energy ||
580  (ci.energy == cellinfo[iCellScndMax].energy && ci.identifier > cellinfo[iCellScndMax].identifier) )
581  {
582  iCellScndMax = ncell;
583  }
584  }
585  else {
586  if (iCellMax < 0 || ci.energy > cellinfo[iCellMax].energy ) {
587  iCellScndMax = iCellMax;
588  iCellMax = ncell;
589  }
590  else if (iCellScndMax < 0 ||
591  ci.energy > cellinfo[iCellScndMax].energy )
592  {
593  iCellScndMax = ncell;
594  }
595  }
596 
597  xc += ci.energy*ci.x;
598  yc += ci.energy*ci.y;
599  zc += ci.energy*ci.z;
600 
601  double dir = ci.x*ci.x+ci.y*ci.y+ci.z*ci.z;
602 
603  if ( dir > 0) {
604  dir = sqrt(dir);
605  dir = 1./dir;
606  }
607  mx += ci.energy*ci.x*dir;
608  my += ci.energy*ci.y*dir;
609  mz += ci.energy*ci.z*dir;
610 
611  w += ci.energy;
612 
613  ncell++;
614  } // cell has E>0 and weight != 0
615  } // cell has valid DDE
616  } //end of loop over all cells
618  const auto hvFrac=m_larHVFraction->getLArHVFrac(theCluster->getCellLinks(),ctx);
619  eBadLArHV= hvFrac.first;
620  nBadLArHV=hvFrac.second;
621  }
622 
623  if ( w > 0 ) {
624  mass = w*w - mx*mx - my*my - mz*mz;
625  if ( mass > 0) {
626  mass = sqrt(mass);
627  }
628  else {
629  // make mass negative if m^2 was negative
630  mass = -sqrt(-mass);
631  }
632 
633  xc/=w;
634  yc/=w;
635  zc/=w;
636  Amg::Vector3D showerCenter(xc,yc,zc);
637  w=0;
638 
639 
640  //log << MSG::WARNING << "Found bad cells " << xbad_dac << " " << ybad_dac << " " << zbad_dac << " " << ebad_dac << endmsg;
641  //log << MSG::WARNING << "Found Cluster " << xbad_dac << " " << ybad_dac << " " << zbad_dac << " " << endmsg;
642  // shower axis is just the vector pointing from the IP to the shower center
643  // in case there are less than 3 cells in the cluster
644 
645  Amg::Vector3D showerAxis(xc,yc,zc);
646  Amg::setMag(showerAxis,1.0);
647 
648  // otherwise the principal direction with the largest absolute
649  // eigenvalue will be used unless it's angle w.r.t. the vector pointing
650  // from the IP to the shower center is larger than allowed by the
651  // property m_maxAxisAngle
652 
653  double angle(0),deltaPhi(0),deltaTheta(0);
654  if ( ncell > 2 ) {
655  Eigen::Matrix3d C=Eigen::Matrix3d::Zero();
656  for(i=0;i<ncell;i++) {
657  const CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i];
658  const double e2 = ci.energy * ci.energy;
659 
660  C(0,0) += e2*(ci.x-xc)*(ci.x-xc);
661  C(1,0) += e2*(ci.x-xc)*(ci.y-yc);
662  C(2,0) += e2*(ci.x-xc)*(ci.z-zc);
663 
664  C(1,1) += e2*(ci.y-yc)*(ci.y-yc);
665  C(2,1) += e2*(ci.y-yc)*(ci.z-zc);
666 
667  C(2,2) += e2*(ci.z-zc)*(ci.z-zc);
668  w += e2;
669  }
670  C/=w;
671 
672  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(C);
673  if (eigensolver.info() != Eigen::Success) {
674  msg(MSG::WARNING) << "Failed to compute Eigenvalues -> Can't determine shower axis" << endmsg;
675  }
676  else {
677  // don't use the principal axes if at least one of the 3
678  // diagonal elements is 0
679 
680  const Eigen::Vector3d& S=eigensolver.eigenvalues();
681  const Eigen::Matrix3d& U=eigensolver.eigenvectors();
682 
683  const double epsilon = 1.E-6;
684 
685  if ( std::abs(S[0]) >= epsilon && std::abs(S[1]) >= epsilon && std::abs(S[2]) >= epsilon ) {
686 
687  Amg::Vector3D prAxis(showerAxis);
688  int iEigen = -1;
689 
690  for (i=0;i<3;i++) {
691  Amg::Vector3D tmpAxis=U.col(i);
692 
693  // calculate the angle
694  double tmpAngle=Amg::angle(tmpAxis,showerAxis);
695 
696  if ( tmpAngle > 90*deg ) {
697  tmpAngle = 180*deg - tmpAngle;
698  tmpAxis = -tmpAxis;
699  }
700 
701  if ( iEigen == -1 || tmpAngle < angle ) {
702  iEigen = i;
703  angle = tmpAngle;
704  prAxis = tmpAxis;
705  }
706  }//end for loop
707 
708  // calculate theta and phi angle differences
709 
710  deltaPhi = CaloPhiRange::diff(showerAxis.phi(),prAxis.phi());
711 
712  deltaTheta = showerAxis.theta() - prAxis.theta();
713 
714  // check the angle
715 
716  if ( angle < m_maxAxisAngle ) {
717  showerAxis = prAxis;
718  }
719  else
720  ATH_MSG_DEBUG("principal Direction (" << prAxis[Amg::x] << ", "
721  << prAxis[Amg::y] << ", " << prAxis[Amg::z] << ") deviates more than "
722  << m_maxAxisAngle*(1./deg)
723  << " deg from IP-to-ClusterCenter-axis (" << showerAxis[Amg::x] << ", "
724  << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")");
725  }//end if std::abs(S)<epsilon
726  else {
727  ATH_MSG_DEBUG("Eigenvalues close to 0, do not use principal axis");
728  }
729  }//end got eigenvalues
730  } //end if ncell>2
731 
732  ATH_MSG_DEBUG("Shower Axis = (" << showerAxis[Amg::x] << ", "
733  << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")");
734 
735 
736  // calculate radial distance from and the longitudinal distance
737  // along the shower axis for each cell. The cluster center is
738  // at r=0 and lambda=0
739 
740  for (auto& ci : cellinfo) {
741  const Amg::Vector3D currentCell(ci.x,ci.y,ci.z);
742  // calculate distance from shower axis r
743  ci.r = ((currentCell-showerCenter).cross(showerAxis)).mag();
744  // calculate distance from shower center along shower axis
745  ci.lambda = (currentCell-showerCenter).dot(showerAxis);
746  }
747 
748  // loop over all positive energy cells and calculate all desired moments
749 
750  // define common norm for all simple moments
751  double commonNorm = 0;
752  double phi0 = ncell > 0 ? cellinfo[0].phi : 0;
753 
754  for(unsigned i=0;i<ncell;i++) {
755  const CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i];
756  // loop over all valid moments
757  commonNorm += ci.energy;
758  for(size_t iMoment = 0, size = m_validMoments.size();
759  iMoment != size;
760  ++ iMoment)
761  {
762  // now calculate the actual moments
763  switch (m_validMoments[iMoment]) {
765  myMoments[iMoment] += ci.energy*ci.eta;
766  break;
768  // first cell decides the sign in order to avoid
769  // overlap problem at phi = -pi == +pi
770  // need to be normalized to the range [-pi,+pi] in the end
771  myMoments[iMoment] += ci.energy * proxim (ci.phi, phi0);
772  break;
774  myMoments[iMoment] += ci.energy*ci.r*ci.r;
775  break;
777  myMoments[iMoment] += ci.energy*ci.lambda*ci.lambda;
778  break;
780  if ( (int)i != iCellMax && (int)i != iCellScndMax ) {
781  myMoments[iMoment] += ci.energy*ci.r*ci.r;
782  myNorms[iMoment] += ci.energy*ci.r*ci.r;
783  }
784  else {
785  double rm = ci.r;
786  if ( rm < m_minRLateral )
787  rm = m_minRLateral;
788  myNorms[iMoment] += rm*rm*ci.energy;
789  }
790  break;
792  if ( (int)i != iCellMax && (int)i != iCellScndMax ) {
793  myMoments[iMoment] += ci.energy*ci.lambda*ci.lambda;
794  myNorms[iMoment] += ci.energy*ci.lambda*ci.lambda;
795  }
796  else {
797  double lm = ci.lambda;
798  if ( lm < m_minLLongitudinal )
799  lm = m_minLLongitudinal;
800  myNorms[iMoment] += lm*lm*ci.energy;
801  }
802  break;
804  if ( ci.volume > 0 ) {
805  myMoments[iMoment] += ci.energy*ci.energy/ci.volume;
806  myNorms[iMoment] += ci.energy;
807  }
808  break;
810  if ( ci.volume > 0 ) {
811  myMoments[iMoment] += ci.energy*std::pow(ci.energy/ci.volume,2);
812  myNorms[iMoment] += ci.energy;
813  }
814  break;
816  if ( ci.sample == CaloCell_ID::EMB1
817  || ci.sample == CaloCell_ID::EMB2
818  || ci.sample == CaloCell_ID::EMB3
819  || ci.sample == CaloCell_ID::EME1
820  || ci.sample == CaloCell_ID::EME2
821  || ci.sample == CaloCell_ID::EME3
822  || ci.sample == CaloCell_ID::FCAL0 )
823  myMoments[iMoment] += ci.energy;
824  break;
826  if ( (int)i == iCellMax )
827  myMoments[iMoment] = ci.energy;
828  break;
830  // do not convert to pT since clusters are small and
831  // there is virtually no difference and cosh just costs
832  // time ...
833  myMoments[iMoment] += ci.energy*ci.energy;
834  myNorms[iMoment] += ci.energy;
835  break;
836  default:
837  // nothing to be done for other moments
838  break;
839  }
840  }
841  } //end of loop over cell
842 
843 
844  // assign moments which don't need the loop over the cells
845  for (size_t iMoment = 0, size = m_validMoments.size();
846  iMoment != size;
847  ++ iMoment)
848  {
849  // now calculate the actual moments
850  switch (m_validMoments[iMoment]) {
857  myNorms[iMoment] = commonNorm;
858  break;
860  myMoments[iMoment] = deltaPhi;
861  break;
863  myMoments[iMoment] = deltaTheta;
864  break;
866  myMoments[iMoment] = angle;
867  break;
869  myMoments[iMoment] = showerCenter.x();
870  break;
872  myMoments[iMoment] = showerCenter.y();
873  break;
875  myMoments[iMoment] = showerCenter.z();
876  break;
878  myMoments[iMoment] = showerCenter.mag();
879  break;
881  // calculate the longitudinal distance along the shower axis
882  // of the shower center from the calorimeter start
883 
884  // first need calo boundary at given eta phi try LAREM barrel
885  // first, then LAREM endcap OW, then LAREM endcap IW, then
886  // FCal
887  {
888  double r_calo(0),z_calo(0),lambda_c(0);
889  r_calo = m_caloDepthTool->get_entrance_radius(CaloCell_ID::EMB1,
890  showerCenter.eta(),
891  showerCenter.phi(),
892  caloDDMgr);
893  if ( r_calo == 0 ) {
894  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::EME1,
895  showerCenter.eta(),
896  showerCenter.phi(),
897  caloDDMgr);
898  if ( z_calo == 0 )
899  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::EME2,
900  showerCenter.eta(),
901  showerCenter.phi(),
902  caloDDMgr);
903  if ( z_calo == 0 )
904  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::FCAL0,
905  showerCenter.eta(),
906  showerCenter.phi(),
907  caloDDMgr);
908  if ( z_calo == 0 ) // for H6 TB without EMEC outer wheel
909  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::HEC0,
910  showerCenter.eta(),
911  showerCenter.phi(),
912  caloDDMgr);
913  if ( z_calo != 0 && showerAxis.z() != 0 ) {
914  lambda_c = std::abs((z_calo-showerCenter.z())/showerAxis.z());
915  }
916  }
917  else {
918  double r_s2 = showerAxis.x()*showerAxis.x()
919  +showerAxis.y()*showerAxis.y();
920  double r_cs = showerAxis.x()*showerCenter.x()
921  +showerAxis.y()*showerCenter.y();
922  double r_cr = showerCenter.x()*showerCenter.x()
923  +showerCenter.y()*showerCenter.y()-r_calo*r_calo;
924  if ( r_s2 > 0 ) {
925  double det = r_cs*r_cs/(r_s2*r_s2) - r_cr/r_s2;
926  if ( det > 0 ) {
927  det = sqrt(det);
928  double l1(-r_cs/r_s2);
929  double l2(l1);
930  l1 += det;
931  l2 -= det;
932  if ( std::abs(l1) < std::abs(l2) )
933  lambda_c = std::abs(l1);
934  else
935  lambda_c = std::abs(l2);
936  }
937  }
938  }
939  myMoments[iMoment] = lambda_c;
940  }
941  break;
943  for(i=0;i<(int)CaloCell_ID::Unknown;i++)
944  myMoments[iMoment] += maxSampE[i];
945  myNorms[iMoment] = commonNorm;
946  break;
948  {
949  // loop over empty and filled perimeter cells and
950  // get a weighted ratio by means of energy fraction per layer
951  for(unsigned int i=0; i != CaloSampling::Unknown; ++ i) {
953  if (theCluster->hasSampling(s)) {
954  const double eSample = theCluster->eSample(s);
955  if (eSample > 0) {
956  int nAll = nbEmpty[i]+nbNonEmpty[i];
957  if (nAll > 0) {
958  myMoments[iMoment] += (eSample*nbEmpty[i])/nAll;
959  myNorms[iMoment] += eSample;
960  }
961  }//end of eSample>0
962  }//end has sampling
963  }//end loop over samplings
964  }
965  break;
967  myMoments[iMoment] = eBad;
968  break;
970  myMoments[iMoment] = nbad;
971  break;
973  myMoments[iMoment] = nbad_dac;
974  break;
976  myMoments[iMoment] = ebad_dac;
977  break;
979  myMoments[iMoment] = eBadLArQ/(theCluster->e()!=0.?theCluster->e():1.);
980  break;
982  myMoments[iMoment] = ePos;
983  break;
985  myMoments[iMoment] = (sumSig2>0?theCluster->e()/sqrt(sumSig2):0.);
986  break;
988  myMoments[iMoment] = maxAbsSig;
989  break;
991  myMoments[iMoment] = nSigSampl;
992  break;
994  myMoments[iMoment] = eLAr2Q/(eLAr2>0?eLAr2:1);
995  break;
997  myMoments[iMoment] = eTile2Q/(eTile2>0?eTile2:1);
998  break;
1000  myMoments[iMoment] = eBadLArHV;
1001  break;
1003  myMoments[iMoment] = nBadLArHV;
1004  break;
1006  myMoments[iMoment] = sqrt(myMoments[iMoment]);
1007  break;
1009  myMoments[iMoment] = mass;
1010  break;
1011  default:
1012  // nothing to be done for other moments
1013  break;
1014  }
1015  }
1016  }
1017 
1018  // normalize moments and copy to Cluster Moment Store
1019  size_t size= m_validMoments.size();
1020  for (size_t iMoment = 0; iMoment != size; ++iMoment) {
1022  if ( myNorms[iMoment] != 0 )
1023  myMoments[iMoment] /= myNorms[iMoment];
1024  if ( moment == xAOD::CaloCluster::FIRST_PHI )
1025  myMoments[iMoment] = CaloPhiRange::fix(myMoments[iMoment]);
1026  theCluster->insertMoment(moment,myMoments[iMoment]);
1027  } // loop on moments for cluster
1028  } // check on requested moments
1029  // check on second moment of time if requested
1030  if ( m_secondTime ) { theCluster->insertMoment(xAOD::CaloCluster::SECOND_TIME,theCluster->secondTime()); }
1031  // check on number of cells per sampling moment if requested
1032  if ( m_nCellsPerSampling ) {
1033  for ( size_t isam(0); isam < nCellsSamp.size(); ++isam ) {
1034  theCluster->setNumberCellsInSampling((CaloCell_ID::CaloSample)isam,std::get<0>(nCellsSamp.at(isam)),false);
1035  if ( isam == (size_t)CaloCell_ID::EME2 && std::get<1>(nCellsSamp.at(isam)) > 0 ) {
1036  theCluster->setNumberCellsInSampling((CaloCell_ID::CaloSample)isam,std::get<1>(nCellsSamp.at(isam)),true);
1037  }
1038  } // loop on samplings
1039  nCellsSamp.clear();
1040  }
1041  } // loop on clusters
1042 
1043  return StatusCode::SUCCESS;
1044 }
xAOD::CaloCluster_v1::SECOND_R
@ SECOND_R
Second Moment in .
Definition: CaloCluster_v1.h:123
xAOD::CaloCluster_v1::CENTER_MAG
@ CENTER_MAG
Cluster Centroid ( )
Definition: CaloCluster_v1.h:135
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
GetLCDefs::Unknown
@ Unknown
Definition: GetLCDefs.h:21
xAOD::CaloCluster_v1::FIRST_PHI
@ FIRST_PHI
First Moment in .
Definition: CaloCluster_v1.h:121
CaloPrefetch.h
xAOD::CaloCluster_v1::ENG_FRAC_CORE
@ ENG_FRAC_CORE
Energy fraction of the sum of the hottest cells in each sampling.
Definition: CaloCluster_v1.h:142
xAOD::CaloCluster_v1::cell_begin
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
Definition: CaloCluster_v1.h:812
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
CaloClusterMomentsMaker_detail::cellinfo::identifier
unsigned int identifier
Definition: CaloClusterMomentsMaker.cxx:317
CaloCell_Base_ID::calo_cell_hash
IdentifierHash calo_cell_hash(const Identifier cellId) const
create hash id from 'global' cell id
constants.EMB1
int EMB1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:53
max
#define max(a, b)
Definition: cfImp.cxx:41
Amg::setMag
void setMag(Amg::Vector3D &v, double mag)
scales the vector length without changing the angles
Definition: GeoPrimitivesHelpers.h:104
fitman.my
my
Definition: fitman.py:523
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::CaloCluster_v1::CaloSample
CaloSampling::CaloSample CaloSample
Definition: CaloCluster_v1.h:66
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:575
xAOD::CaloCluster_v1::MASS
@ MASS
cell based mass i.e. the mass of the 4-vector sum of all massless positive energetic cells
Definition: CaloCluster_v1.h:172
CaloDetDescrElement::y
float y() const
cell y
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:365
Amg::angle
double angle(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
calculates the opening angle between two vectors
Definition: GeoPrimitivesHelpers.h:41
xAOD::CaloCluster_v1::EM_PROBABILITY
@ EM_PROBABILITY
Classification probability to be em-like.
Definition: CaloCluster_v1.h:173
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
xAOD::CaloCluster_v1::CENTER_X
@ CENTER_X
Cluster Centroid ( )
Definition: CaloCluster_v1.h:131
xAOD::CaloCluster_v1::ENG_BAD_HV_CELLS
@ ENG_BAD_HV_CELLS
Total em-scale energy of cells with bad HV in this cluster.
Definition: CaloCluster_v1.h:167
CaloClusterMomentsMaker::m_caloDepthTool
ToolHandle< CaloDepthTool > m_caloDepthTool
Definition: CaloClusterMomentsMaker.h:125
CaloClusterMomentsMaker_detail::cellinfo::cellinfo
cellinfo(const bool useGPUCriteria=false)
Definition: CaloClusterMomentsMaker.cxx:318
CaloClusterMomentsMaker_detail::cellinfo::energy
double energy
Definition: CaloClusterMomentsMaker.cxx:310
CaloClusterMomentsMaker::execute
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusColl) const override final
Execute on an entire collection of clusters.
Definition: CaloClusterMomentsMaker.cxx:339
CaloClusterMomentsMaker_detail::cellinfo::lambda
double lambda
Definition: CaloClusterMomentsMaker.cxx:314
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
xAOD::deltaPhi
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
Definition: L2StandAloneMuon_v1.cxx:160
xAOD::CaloCluster_v1::secondTime
flt_t secondTime() const
Access second moment of cell timing distribution.
Definition: CaloCluster_v1.cxx:987
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
xAOD::CaloCluster_v1::AVG_LAR_Q
@ AVG_LAR_Q
Sum(E_cell_LAr^2 Q_cell_LAr)/Sum(E_cell_LAr^2)
Definition: CaloCluster_v1.h:163
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
DMTest::C
C_v1 C
Definition: C.h:26
proxim
double proxim(double b, double a)
Definition: proxim.h:17
Amg::y
@ y
Definition: GeoPrimitives.h:35
deg
#define deg
Definition: SbPolyhedron.cxx:17
xAOD::CaloCluster_v1::insertMoment
void insertMoment(MomentType type, double value)
Definition: CaloCluster_v1.cxx:754
CaloCell.h
xAOD::CaloCluster_v1::CENTER_LAMBDA
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
Definition: CaloCluster_v1.h:136
CaloCell::e
virtual double e() const override final
get energy (data member) (synonym to method energy()
Definition: CaloCell.h:317
CaloClusterMomentsMaker::m_caloMgrKey
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Definition: CaloClusterMomentsMaker.h:127
fitman.mx
mx
Definition: fitman.py:520
CaloClusterMomentsMaker::m_calculateIsolation
bool m_calculateIsolation
Set to true if cluster isolation is to be calculated.
Definition: CaloClusterMomentsMaker.h:115
CaloCell_Base_ID::calo_sample
int calo_sample(const Identifier id) const
returns an int taken from Sampling enum and describing the subCalo to which the Id belongs.
Definition: CaloCell_Base_ID.cxx:141
CaloCell::provenance
uint16_t provenance() const
get provenance (data member)
Definition: CaloCell.h:338
CaloClusterMomentsMaker::m_minLLongitudinal
double m_minLLongitudinal
the minimal in the definition of the Longitudinal moment
Definition: CaloClusterMomentsMaker.h:101
CaloClusterMomentsMaker::m_minBadLArQuality
double m_minBadLArQuality
the minimal cell quality in the LAr for declaring a cell bad
Definition: CaloClusterMomentsMaker.h:109
CaloClusterMomentsMaker::m_noiseCDOKey
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
Definition: CaloClusterMomentsMaker.h:136
xAOD::CaloCluster_v1::ENG_FRAC_MAX
@ ENG_FRAC_MAX
Energy fraction of hottest cell.
Definition: CaloCluster_v1.h:140
CaloClusterMomentsMaker::m_etaInnerWheel
double m_etaInnerWheel
Transition from outer to inner wheel in EME2.
Definition: CaloClusterMomentsMaker.h:158
JetTiledMap::S
@ S
Definition: TiledEtaPhiMap.h:44
CaloClusterMomentsMaker::m_useGPUCriteria
Gaudi::Property< bool > m_useGPUCriteria
Definition: CaloClusterMomentsMaker.h:161
dqt_zlumi_pandas.mass
mass
Definition: dqt_zlumi_pandas.py:170
CaloClusterMomentsMaker::m_calo_id
const CaloCell_ID * m_calo_id
Definition: CaloClusterMomentsMaker.h:79
CaloCell_ID.h
AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:95
CaloCell::energy
double energy() const
get energy (data member)
Definition: CaloCell.h:311
CaloClusterMomentsMaker::m_momentsNames
std::vector< std::string > m_momentsNames
vector holding the input list of names of moments to calculate.
Definition: CaloClusterMomentsMaker.h:69
xAOD::CaloCluster_v1::SECOND_LAMBDA
@ SECOND_LAMBDA
Second Moment in .
Definition: CaloCluster_v1.h:124
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
xAOD::CaloCluster_v1::MomentType
MomentType
Enums to identify different moments.
Definition: CaloCluster_v1.h:120
xAOD::CaloCluster_v1::PTD
@ PTD
relative spread of pT of constiuent cells = sqrt(n)*RMS/Mean
Definition: CaloCluster_v1.h:170
xAOD::CaloCluster_v1::NCELL_SAMPLING
@ NCELL_SAMPLING
Number of cells in sampling layer.
Definition: CaloCluster_v1.h:182
xAOD::CaloCluster_v1::CENTER_Z
@ CENTER_Z
Cluster Centroid ( )
Definition: CaloCluster_v1.h:133
cm
const double cm
Definition: Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimParametrization/tools/FCAL_ChannelMap.cxx:25
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
GeoPrimitives.h
CaloClusterMomentsMaker::m_calculateSignificance
bool m_calculateSignificance
Set to true if significance moments are need.
Definition: CaloClusterMomentsMaker.h:112
ArenaPoolSTLAllocator.h
STL-style allocator wrapper for ArenaPoolAllocator.
proxim.h
xAOD::CaloCluster_v1::SECOND_ENG_DENS
@ SECOND_ENG_DENS
Second Moment in E/V.
Definition: CaloCluster_v1.h:144
CaloClusterMomentsMaker::m_absOpt
bool m_absOpt
if set to true use abs E value of cells to calculate cluster moments
Definition: CaloClusterMomentsMaker.h:146
Amg::z
@ z
Definition: GeoPrimitives.h:36
xAOD::CaloCluster_v1
Description of a calorimeter cluster.
Definition: CaloCluster_v1.h:59
skel.l2
l2
Definition: skel.GENtoEVGEN.py:426
createCoolChannelIdFile.buffer
buffer
Definition: createCoolChannelIdFile.py:12
ParticleGun_EoverP_Config.mom
mom
Definition: ParticleGun_EoverP_Config.py:63
CaloClusterMomentsMaker::m_calculateLArHVFraction
bool m_calculateLArHVFraction
Set to true to calculate E and N of cells affected by LAr HV corrections.
Definition: CaloClusterMomentsMaker.h:118
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
ParticleGun_FastCalo_ChargeFlip_Config.energy
energy
Definition: ParticleGun_FastCalo_ChargeFlip_Config.py:78
constants.EMB2
int EMB2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:54
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
DataModel_detail::iterator
(Non-const) Iterator class for DataVector/DataList.
Definition: DVLIterator.h:184
lumiFormat.i
int i
Definition: lumiFormat.py:92
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:73
xAOD::CaloCluster_v1::CELL_SIG_SAMPLING
@ CELL_SIG_SAMPLING
CaloSample of the cell with the largest |E|/sig.
Definition: CaloCluster_v1.h:161
Amg::x
@ x
Definition: GeoPrimitives.h:34
CaloCell::caloDDE
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition: CaloCell.h:305
CaloClusterMomentsMaker::m_validMoments
std::vector< xAOD::CaloCluster::MomentType > m_validMoments
set of moments which will be calculated.
Definition: CaloClusterMomentsMaker.h:77
fitman.mz
mz
Definition: fitman.py:526
WritePulseShapeToCool.det
det
Definition: WritePulseShapeToCool.py:204
xAOD::CaloCluster_v1::ISOLATION
@ ISOLATION
Energy weighted fraction of non-clustered perimeter cells.
Definition: CaloCluster_v1.h:146
test_pyathena.parent
parent
Definition: test_pyathena.py:15
CaloCell::badcell
virtual bool badcell() const
check is cell is dead
Definition: CaloCell.cxx:210
xAOD::CaloCluster_v1::size
size_t size() const
size method (forwarded from CaloClusterCellLink obj)
Definition: CaloCluster_v1.cxx:996
constants.EME1
int EME1
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:55
CaloPhiRange.h
CaloPhiRange class declaration.
xAOD::CaloCluster_v1::DELTA_PHI
@ DELTA_PHI
Angular shower axis deviation ( ) from IP-to-Center.
Definition: CaloCluster_v1.h:126
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloClusterMomentsMaker_detail::cellinfo::y
double y
Definition: CaloClusterMomentsMaker.cxx:308
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
CaloClusterMomentsMaker::m_minRLateral
double m_minRLateral
the minimal in the definition of the Lateral moment
Definition: CaloClusterMomentsMaker.h:91
CaloClusterMomentsMaker::finalize
virtual StatusCode finalize() override
Definition: CaloClusterMomentsMaker.cxx:296
xAOD::CaloCluster_v1::FIRST_ENG_DENS
@ FIRST_ENG_DENS
First Moment in E/V.
Definition: CaloCluster_v1.h:143
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
CaloPhiRange::fix
static double fix(double phi)
Definition: CaloPhiRange.cxx:14
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
xAOD::CaloCluster_v1::getCellLinks
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
Definition: CaloCluster_v1.cxx:905
xAOD::CaloCluster_v1::ENG_BAD_CELLS
@ ENG_BAD_CELLS
Total em-scale energy of bad cells in this cluster.
Definition: CaloCluster_v1.h:148
CaloCell::quality
uint16_t quality() const
get quality (data member)
Definition: CaloCell.h:332
beamspotman.dir
string dir
Definition: beamspotman.py:623
CxxUtils::prefetchNext
void prefetchNext(Iter iter, Iter endIter)
Prefetch next object in sequence.
Definition: prefetch.h:130
CaloDetDescrElement::is_tile
bool is_tile() const
cell belongs to Tile
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:442
CaloNoise
Definition: CaloNoise.h:16
ReadCellNoiseFromCool.ncell
ncell
Definition: ReadCellNoiseFromCool.py:197
xAOD::CaloCluster_v1::ENG_FRAC_EM
@ ENG_FRAC_EM
Energy fraction in EM calorimeters.
Definition: CaloCluster_v1.h:139
CaloClusterMomentsMaker::m_nCellsPerSampling
bool m_nCellsPerSampling
store number of cells per sampling layer as moment
Definition: CaloClusterMomentsMaker.h:154
CaloClusterMomentsMaker::CaloClusterMomentsMaker
CaloClusterMomentsMaker(const std::string &type, const std::string &name, const IInterface *parent)
Definition: CaloClusterMomentsMaker.cxx:141
CaloDetDescrElement::volume
float volume() const
cell volume
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:381
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
CaloClusterMomentsMaker::m_larHVFraction
ToolHandle< ILArHVFraction > m_larHVFraction
Definition: CaloClusterMomentsMaker.h:138
CaloCell_ID_FCS::EME3
@ EME3
Definition: FastCaloSim_CaloCell_ID.h:26
CaloClusterMomentsMaker_detail::cellinfo::z
double z
Definition: CaloClusterMomentsMaker.cxx:309
CaloClusterMomentsMaker_detail::cellinfo::phi
double phi
Definition: CaloClusterMomentsMaker.cxx:312
xAOD::CaloCluster_v1::setNumberCellsInSampling
void setNumberCellsInSampling(CaloSampling::CaloSample samp, int ncells, bool isInnerWheel=false)
Set the number of cells in a sampling layer.
Definition: CaloCluster_v1.cxx:790
CaloClusterMomentsMaker_detail::cellinfo
Definition: CaloClusterMomentsMaker.cxx:306
CaloCell::gain
CaloGain::CaloGain gain() const
get gain (data member )
Definition: CaloCell.h:345
CaloCell_Base_ID::get_neighbours
int get_neighbours(const IdentifierHash caloHash, const LArNeighbours::neighbourOption &option, std::vector< IdentifierHash > &neighbourList) const
access to hashes for neighbours return == 0 for neighbours found
Definition: CaloCell_Base_ID.cxx:190
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
CaloCell::ID
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
Definition: CaloCell.h:279
xAOD::CaloCluster_v1::AVG_TILE_Q
@ AVG_TILE_Q
Sum(E_cell_Tile^2 Q_cell_Tile)/Sum(E_cell_Tile^2)
Definition: CaloCluster_v1.h:165
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
CaloDetDescrElement::x
float x() const
cell x
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:363
CaloClusterMomentsMaker::m_secondTime
bool m_secondTime
Retrieve second moment of cell times and store as moment.
Definition: CaloClusterMomentsMaker.h:150
CaloCell_ID_FCS::HEC0
@ HEC0
Definition: FastCaloSim_CaloCell_ID.h:27
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
xAOD::CaloCluster_v1::FIRST_ETA
@ FIRST_ETA
First Moment in .
Definition: CaloCluster_v1.h:122
CaloClusterMomentsMaker::initialize
virtual StatusCode initialize() override
Definition: CaloClusterMomentsMaker.cxx:183
xAOD::CaloCluster_v1::DELTA_THETA
@ DELTA_THETA
Angular shower axis deviation ( ) from IP-to-Center.
Definition: CaloCluster_v1.h:128
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:521
CaloClusterMomentsMaker::m_momentsNamesAOD
std::string m_momentsNamesAOD
Not used anymore (with xAOD), but required when configured from COOL.
Definition: CaloClusterMomentsMaker.h:141
CaloDetDescrManager
This class provides the client interface for accessing the detector description information common to...
Definition: CaloDetDescrManager.h:473
CaloCell
Data object for each calorimeter readout cell.
Definition: CaloCell.h:57
CaloDetDescrElement::getSampling
CaloCell_ID::CaloSample getSampling() const
cell sampling
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:395
egammaEnergyPositionAllSamples::e2
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
lumiFormat.fill
fill
Definition: lumiFormat.py:111
xAOD::CaloCluster_v1::SIGNIFICANCE
@ SIGNIFICANCE
Cluster significance.
Definition: CaloCluster_v1.h:157
CaloClusterMomentsMaker_detail
Definition: CaloClusterMomentsMaker.cxx:303
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
CaloDetDescrElement::z
float z() const
cell z
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:367
GeoPrimitivesHelpers.h
xAOD::CaloCluster_v1::N_BAD_HV_CELLS
@ N_BAD_HV_CELLS
number of cells with bad HV
Definition: CaloCluster_v1.h:168
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
DeMoScan.first
bool first
Definition: DeMoScan.py:534
xAOD::CaloCluster_v1::cell_end
const_cell_iterator cell_end() const
Definition: CaloCluster_v1.h:813
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:569
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
CaloClusterMomentsMaker_detail::cellinfo::r
double r
Definition: CaloClusterMomentsMaker.cxx:313
xAOD::CaloCluster_v1::LATERAL
@ LATERAL
Normalized lateral moment.
Definition: CaloCluster_v1.h:137
CaloDetDescrElement::eta
float eta() const
cell eta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:344
xAOD::CaloCluster_v1::SECOND_TIME
@ SECOND_TIME
Second moment of cell time distribution in cluster.
Definition: CaloCluster_v1.h:180
CaloClusterMomentsMaker_detail::cellinfo::x
double x
Definition: CaloClusterMomentsMaker.cxx:307
CaloDetDescrElement::phi
float phi() const
cell phi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:346
xAOD::CaloCluster_v1::DELTA_ALPHA
@ DELTA_ALPHA
Angular shower axis deviation ( ) from IP-to-Center.
Definition: CaloCluster_v1.h:130
xAOD::CaloCluster_v1::CELL_SIGNIFICANCE
@ CELL_SIGNIFICANCE
Cell significance = E/sig of the cell with the largest |E|/sig.
Definition: CaloCluster_v1.h:159
skel.l1
l1
Definition: skel.GENtoEVGEN.py:425
xAOD::CaloCluster_v1::BAD_CELLS_CORR_E
@ BAD_CELLS_CORR_E
Energy of bad cells with energy density average correction applied.
Definition: CaloCluster_v1.h:153
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
Definition: IdentifierHash.h:38
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
xAOD::CaloCluster_v1::hasSampling
bool hasSampling(const CaloSample s) const
Checks if certain smapling contributes to cluster.
Definition: CaloCluster_v1.h:890
CaloClusterMomentsMaker_detail::cellinfo::eta
double eta
Definition: CaloClusterMomentsMaker.cxx:311
xAOD::CaloCluster_v1::N_BAD_CELLS_CORR
@ N_BAD_CELLS_CORR
Number of bad cells with energy density average correction applied.
Definition: CaloCluster_v1.h:151
xAOD::CaloCluster_v1::LONGITUDINAL
@ LONGITUDINAL
Normalized longitudinal moment.
Definition: CaloCluster_v1.h:138
CaloClusterMomentsMaker::m_maxAxisAngle
double m_maxAxisAngle
the maximal allowed deviation from the IP-to-ClusterCenter-axis.
Definition: CaloClusterMomentsMaker.h:83
CaloCell_ID_FCS::FCAL0
@ FCAL0
Definition: FastCaloSim_CaloCell_ID.h:40
CaloClusterMomentsMaker_detail::cellinfo::volume
double volume
Definition: CaloClusterMomentsMaker.cxx:315
CaloCell_ID_FCS::EMB3
@ EMB3
Definition: FastCaloSim_CaloCell_ID.h:22
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
CaloClusterMomentsMaker_detail::cellinfo::sample
CaloCell_ID::CaloSample sample
Definition: CaloClusterMomentsMaker.cxx:316
xAOD::CaloCluster_v1::N_BAD_CELLS
@ N_BAD_CELLS
number of bad cells
Definition: CaloCluster_v1.h:149
CaloPrefetch::nextDDE
void nextDDE(Iter iter, Iter endIter)
Prefetch next CaloDDE.
Definition: CaloPrefetch.h:47
CaloClusterMomentsMaker::m_twoGaussianNoise
bool m_twoGaussianNoise
if set to true use 2-gaussian noise description for TileCal
Definition: CaloClusterMomentsMaker.h:123
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:25
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
xAOD::CaloCluster_v1::CENTER_Y
@ CENTER_Y
Cluster Centroid ( )
Definition: CaloCluster_v1.h:132
LArNeighbours::all2D
@ all2D
Definition: LArNeighbours.h:18
constants.EME2
int EME2
Definition: Calorimeter/CaloClusterCorrection/python/constants.py:56
CaloClusterMomentsMaker.h
WriteCellNoiseToCool.noise
noise
Definition: WriteCellNoiseToCool.py:380
ILArHVFraction.h
prefetch.h
Functions to prefetch blocks of memory.
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
xAOD::CaloCluster_v1::ENG_POS
@ ENG_POS
Total positive Energy of this cluster.
Definition: CaloCluster_v1.h:156
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
CaloPhiRange::diff
static double diff(double phi1, double phi2)
simple phi1 - phi2 calculation, but result is fixed to respect range.
Definition: CaloPhiRange.cxx:22
CaloCell_Base_ID::calo_cell_hash_max
size_type calo_cell_hash_max(void) const
cell 'global' hash table max size
xAOD::CaloCluster_v1::BADLARQ_FRAC
@ BADLARQ_FRAC
Energy fraction of LAr cells with quality larger than a given cut.
Definition: CaloCluster_v1.h:155