Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
CaloClusterMomentsMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 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;
52 
53 // Known moments
54 namespace {
55  // name -> enum translator
56  const std::map<std::string,xAOD::CaloCluster::MomentType> momentNameToEnumMap = {
57  { "AVG_LAR_Q", AVG_LAR_Q },
58  { "AVG_TILE_Q", AVG_TILE_Q },
59  { "BADLARQ_FRAC", BADLARQ_FRAC },
60  { "BAD_CELLS_CORR_E", BAD_CELLS_CORR_E },
61  { "CELL_SIGNIFICANCE", CELL_SIGNIFICANCE },
62  { "CELL_SIG_SAMPLING", CELL_SIG_SAMPLING },
63  { "CENTER_LAMBDA", CENTER_LAMBDA },
64  { "CENTER_MAG", CENTER_MAG },
65  { "CENTER_X", CENTER_X },
66  { "CENTER_Y", CENTER_Y },
67  { "CENTER_Z", CENTER_Z },
68  { "DELTA_ALPHA", DELTA_ALPHA },
69  { "DELTA_PHI", DELTA_PHI },
70  { "DELTA_THETA", DELTA_THETA },
71  { "ENG_BAD_CELLS", ENG_BAD_CELLS },
72  { "ENG_BAD_HV_CELLS", ENG_BAD_HV_CELLS },
73  { "ENG_FRAC_CORE", ENG_FRAC_CORE },
74  { "ENG_FRAC_EM", ENG_FRAC_EM },
75  { "ENG_FRAC_MAX", ENG_FRAC_MAX },
76  { "ENG_POS", ENG_POS },
77  { "FIRST_ENG_DENS", FIRST_ENG_DENS },
78  { "FIRST_ETA", FIRST_ETA },
79  { "FIRST_PHI", FIRST_PHI },
80  { "ISOLATION", ISOLATION },
81  { "LATERAL", LATERAL },
82  { "LONGITUDINAL", LONGITUDINAL },
83  { "MASS", MASS },
84  { "N_BAD_CELLS", N_BAD_CELLS },
85  { "N_BAD_HV_CELLS", N_BAD_HV_CELLS },
86  { "N_BAD_CELLS_CORR", N_BAD_CELLS_CORR },
87  { "PTD", PTD },
88  { "SECOND_ENG_DENS", SECOND_ENG_DENS },
89  { "SECOND_LAMBDA", SECOND_LAMBDA },
90  { "SECOND_R", SECOND_R },
91  { "SECOND_TIME", SECOND_TIME },
92  { "SIGNIFICANCE", SIGNIFICANCE },
93  { "EM_PROBABILITY", EM_PROBABILITY },
94  { "NCELL_SAMPLING", NCELL_SAMPLING }
95  };
96  // enum -> name translator
97  const std::map<xAOD::CaloCluster::MomentType,std::string> momentEnumToNameMap = {
98  { AVG_LAR_Q, "AVG_LAR_Q" },
99  { AVG_TILE_Q, "AVG_TILE_Q" },
100  { BADLARQ_FRAC, "BADLARQ_FRAC" },
101  { BAD_CELLS_CORR_E, "BAD_CELLS_CORR_E" },
102  { CELL_SIGNIFICANCE, "CELL_SIGNIFICANCE"},
103  { CELL_SIG_SAMPLING, "CELL_SIG_SAMPLING"},
104  { CENTER_LAMBDA, "CENTER_LAMBDA" },
105  { CENTER_MAG, "CENTER_MAG" },
106  { CENTER_X, "CENTER_X" },
107  { CENTER_Y, "CENTER_Y" },
108  { CENTER_Z, "CENTER_Z" },
109  { DELTA_ALPHA, "DELTA_ALPHA" },
110  { DELTA_PHI, "DELTA_PHI" },
111  { DELTA_THETA, "DELTA_THETA" },
112  { ENG_BAD_CELLS, "ENG_BAD_CELLS" },
113  { ENG_BAD_HV_CELLS, "ENG_BAD_HV_CELLS" },
114  { ENG_FRAC_CORE, "ENG_FRAC_CORE" },
115  { ENG_FRAC_EM, "ENG_FRAC_EM" },
116  { ENG_FRAC_MAX, "ENG_FRAC_MAX" },
117  { ENG_POS, "ENG_POS" },
118  { FIRST_ENG_DENS, "FIRST_ENG_DENS" },
119  { FIRST_ETA, "FIRST_ETA" },
120  { FIRST_PHI, "FIRST_PHI" },
121  { ISOLATION, "ISOLATION" },
122  { LATERAL, "LATERAL" },
123  { LONGITUDINAL, "LONGITUDINAL" },
124  { MASS, "MASS" },
125  { N_BAD_CELLS, "N_BAD_CELLS" },
126  { N_BAD_HV_CELLS, "N_BAD_HV_CELLS" },
127  { N_BAD_CELLS_CORR, "N_BAD_CELLS_CORR" },
128  { PTD, "PTD" },
129  { SECOND_ENG_DENS, "SECOND_ENG_DENS" },
130  { SECOND_LAMBDA, "SECOND_LAMBDA" },
131  { SECOND_R, "SECOND_R" },
132  { SECOND_TIME, "SECOND_TIME" },
133  { SIGNIFICANCE, "SIGNIFICANCE" },
134  { EM_PROBABILITY, "EM_PROBABILITY" },
135  { 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  xAOD::CaloCluster dummyCluster;
186 
187  // loop list of requested moments
188  std::string::size_type nstr(0); int nmom(0);
189  for (const auto& mom : m_momentsNames) {
190  ATH_MSG_DEBUG("Moment " << mom << " requested");
191  // check if moment is known (enumerator available)
192  auto fmap(momentNameToEnumMap.find(mom));
193  if (fmap != momentNameToEnumMap.end()) {
194  // valid moment found
195  nstr = std::max(nstr, mom.length());
196  ++nmom;
197  if (fmap->second == SECOND_TIME) {
198  // special flag for second moment of cell times - this moment is not
199  // calculated in this tool! Do not add to internal (!) valid moments
200  // list. Its value is available from xAOD::CaloCluster::secondTime()!
201  m_secondTime = true;
202 
203  // Make sure the variable used for the moment is declared
204  // to the auxiliary variable registry. Otherwise, if we don't
205  // set the moment for the first event (perhaps because there
206  // are no clusters), then we can get warnings from AuxSelection.
207  (void)dummyCluster.getMomentValue (fmap->second);
208  } else if (fmap->second == NCELL_SAMPLING) {
209  // flag indicates if number of cells in a sampling should be counted.
210  // This is a vector of integers counts that is filled in this tool but
211  // does not need any post-processing (e.g. normalization). It is not
212  // added to the valid moments list for this reason.
213  ATH_MSG_DEBUG("moment " << fmap->first << " found");
214  m_nCellsPerSampling = true;
216 
217  // Make sure the variable used for the moment is declared
218  // to the auxiliary variable registry.
219  (void)dummyCluster.retrieveMoment (fmap->second, cellsdum);
220  } else if (fmap->second == EM_PROBABILITY) {
222  << " not calculated in this tool - misconfiguration?");
223  } else {
224  // Make sure the variable used for the moment is declared
225  // to the auxiliary variable registry.
226  (void)dummyCluster.getMomentValue (fmap->second);
227 
228  // all other valid moments
229  m_validMoments.push_back(fmap->second);
230  // flag some special requests
231  switch (fmap->second) {
232  case SIGNIFICANCE:
233  case CELL_SIGNIFICANCE:
235  break;
236  case ISOLATION:
237  m_calculateIsolation = true;
238  break;
239  case ENG_BAD_HV_CELLS:
241  break;
242  default:
243  break;
244  } // set special processing flags
245  } // moment calculated with this tool
246  } else {
247  ATH_MSG_ERROR("Moment name " << mom << " not known; known moments are:");
248  char buffer[128];
249  std::string::size_type lstr(nstr);
250  // determine field size
251  for (const auto& fmom : momentNameToEnumMap) {
252  lstr = std::max(lstr, fmom.first.length());
253  }
254  // print available moments
255  for (const auto& fmom : momentNameToEnumMap) {
256  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)lstr,
257  (int)lstr, fmom.first.c_str(), (int)fmom.second);
259  }
260  auto fmom(momentNameToEnumMap.find("SECOND_TIME"));
261  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
262  (int)nstr, fmom->first.c_str(), (int)fmom->second);
264  fmom = momentNameToEnumMap.find("NCELL_SAMPLING");
265  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
266  (int)nstr, fmom->first.c_str(), (int)fmom->second);
268  return StatusCode::FAILURE;
269  } // found unknown moment name
270  } // loop configured moment names
271 
272  // sort and remove duplicates
273  std::sort(m_validMoments.begin(), m_validMoments.end());
274  m_validMoments.erase(
275  std::unique(m_validMoments.begin(), m_validMoments.end()),
276  m_validMoments.end());
277 
278  // print configured moments
279  ATH_MSG_INFO("Construct and save " << nmom << " cluster moments: ");
280  char buffer[128];
281  for (auto menum : m_validMoments) {
282  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
283  (int)nstr, momentEnumToNameMap.at(menum).c_str(), (int)menum);
285  }
286  if (m_secondTime) {
287  auto fmom(momentNameToEnumMap.find("SECOND_TIME"));
288  sprintf(buffer, "moment name: %-*.*s - enumerator: %i (save only)",
289  (int)nstr, (int)nstr, fmom->first.c_str(), (int)fmom->second);
291  }
292  if (m_nCellsPerSampling) {
293  auto fmom(momentNameToEnumMap.find("NCELL_SAMPLING"));
294  sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
295  (int)nstr, fmom->first.c_str(), (int)fmom->second);
297  }
298 
299  // retrieve CaloCell ID server
300  CHECK(detStore()->retrieve(m_calo_id,"CaloCell_ID"));
301 
302  // retrieve the calo depth tool
303  CHECK(m_caloDepthTool.retrieve());
305 
306  // retrieve specific servers and tools for selected processes
308  if (m_calculateLArHVFraction) { ATH_CHECK(m_larHVFraction.retrieve()); } else { m_larHVFraction.disable(); }
309 
310  return StatusCode::SUCCESS;
311 }
312 
314 {
315  return StatusCode::SUCCESS;
316 }
317 
318 //#############################################################################
319 
321 
322 
323 struct cellinfo {
324  double x;
325  double y;
326  double z;
327  double energy;
328  double eta;
329  double phi;
330  double r;
331  double lambda;
332  double volume;
334  unsigned int identifier;
335 };
336 
337 } // namespace CaloClusterMomentsMaker_detail
338 
340 CaloClusterMomentsMaker::execute(const EventContext& ctx,
341  xAOD::CaloClusterContainer *theClusColl)
342  const
343 {
344  ATH_MSG_DEBUG("Executing " << name());
345 
346  // Maps cell IdentifierHash to cluster index in cluster collection.
347  // Only used when cluster isolation moment is calculated.
348  using clusterIdx_t = std::uint16_t;
349  typedef std::pair<clusterIdx_t, clusterIdx_t> clusterPair_t;
350  std::vector<clusterPair_t> clusterIdx;
351  const clusterIdx_t noCluster = std::numeric_limits<clusterIdx_t>::max();
352 
353  const CaloNoise* noise=nullptr;
356  noise=*noiseHdl;
357  }
358 
360  const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
361  // Counters for number of empty and non-empty neighbor cells per sampling
362  // layer Only used when cluster isolation moment is calculated.
363  int nbEmpty[CaloCell_ID::Unknown];
364  int nbNonEmpty[CaloCell_ID::Unknown];
365 
366  // prepare stuff from entire collection in case isolation moment
367  // should be calculated
368 
369  if ( m_calculateIsolation ) {
370 
371  if (theClusColl->size() >= noCluster) {
372  msg(MSG::ERROR) << "Too many clusters" << endmsg;
373  return StatusCode::FAILURE;
374  }
375 
376  // initialize with "empty" values
377  clusterIdx.resize(m_calo_id->calo_cell_hash_max(),
378  clusterPair_t(noCluster, noCluster));
379 
380  int iClus = 0;
381  for (xAOD::CaloCluster* theCluster : *theClusColl) {
382  // loop over all cell members and fill cell vector for used cells
383  xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
384  xAOD::CaloCluster::cell_iterator cellIterEnd = theCluster->cell_end();
385  for(; cellIter != cellIterEnd; cellIter++ ){
386  CxxUtils::prefetchNext(cellIter, cellIterEnd);
387  const CaloCell* pCell = *cellIter;
388 
389  Identifier myId = pCell->ID();
390  IdentifierHash myHashId = m_calo_id->calo_cell_hash(myId);
391  if ( clusterIdx[(unsigned int)myHashId].first != noCluster) {
392  // check weight and assign to current cluster if weight is > 0.5
393  double weight = cellIter.weight();
394  if ( weight > 0.5 )
395  clusterIdx[(unsigned int)myHashId].first = iClus;
396  }
397  else {
398  clusterIdx[(unsigned int)myHashId].first = iClus;
399  }
400  }
401  ++iClus;
402  }
403  }
404 
405  // Move allocation of temporary arrays outside the cluster loop.
406  // That way, we don't need to delete and reallocate them
407  // each time through the loop.
408 
409  std::vector<CaloClusterMomentsMaker_detail::cellinfo> cellinfo;
410  std::vector<double> maxSampE (CaloCell_ID::Unknown);
411  std::vector<double> myMoments(m_validMoments.size(),0);
412  std::vector<double> myNorms(m_validMoments.size(),0);
413  std::vector<std::tuple<int,int> > nCellsSamp; nCellsSamp.reserve(CaloCell_ID::Unknown);
414  std::vector<IdentifierHash> theNeighbors;
415  // loop over individual clusters
416  xAOD::CaloClusterContainer::iterator clusIter = theClusColl->begin();
417  xAOD::CaloClusterContainer::iterator clusIterEnd = theClusColl->end();
418  int iClus = 0;
419  for( ;clusIter!=clusIterEnd;++clusIter,++iClus) {
420  xAOD::CaloCluster * theCluster = *clusIter;
421 
422  double w(0),xc(0),yc(0),zc(0),mx(0),my(0),mz(0),mass(0);
423  double eBad(0),ebad_dac(0),ePos(0),eBadLArQ(0),sumSig2(0),maxAbsSig(0);
424  double eLAr2(0),eLAr2Q(0);
425  double eTile2(0),eTile2Q(0);
426  double eBadLArHV(0);
427  int nbad(0),nbad_dac(0),nBadLArHV(0);
428  unsigned int i,nSigSampl(0);
429  unsigned int theNumOfCells = theCluster->size();
430 
431  // these two are needed for the LATERAL moment
432  int iCellMax(-1);
433  int iCellScndMax(-1);
434 
435  cellinfo.clear();
436  if (cellinfo.capacity() == 0)
437  cellinfo.reserve (theNumOfCells*2);
438 
439  for(i=0;i<(unsigned int)CaloCell_ID::Unknown;i++)
440  maxSampE[i] = 0;
441 
442  if ( !m_momentsNames.empty() ) {
443  std::fill (myMoments.begin(), myMoments.end(), 0);
444  std::fill (myNorms.begin(), myNorms.end(), 0);
445  if ( m_calculateIsolation ) {
446  std::fill_n(nbNonEmpty, CaloCell_ID::Unknown, 0);
447  std::fill_n(nbEmpty, CaloCell_ID::Unknown, 0);
448  }
449 
450  // loop over all cell members and calculate the center of mass
451  xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
452  xAOD::CaloCluster::cell_iterator cellIterEnd = theCluster->cell_end();
453  for(; cellIter != cellIterEnd; cellIter++ ){
454  CaloPrefetch::nextDDE(cellIter, cellIterEnd);
455 
456  const CaloCell* pCell = (*cellIter);
457  Identifier myId = pCell->ID();
458  const CaloDetDescrElement* myCDDE = pCell->caloDDE();
459  double ene = pCell->e();
460  if(m_absOpt) ene = std::abs(ene);
461  double weight = cellIter.weight();//theCluster->getCellWeight(cellIter);
462  if ( pCell->badcell() ) {
463  eBad += ene*weight;
464  nbad++;
465  if(ene!=0){
466  ebad_dac+=ene*weight;
467  nbad_dac++;
468  }
469  }
470  else {
471  if ( myCDDE && ! (myCDDE->is_tile())
472  && ((pCell->provenance() & 0x2000) == 0x2000)
473  && !((pCell->provenance() & 0x0800) == 0x0800)) {
474  if ( pCell->quality() > m_minBadLArQuality ) {
475  eBadLArQ += ene*weight;
476  }
477  eLAr2 += ene*weight*ene*weight;
478  eLAr2Q += ene*weight*ene*weight*pCell->quality();
479  }
480  if ( myCDDE && myCDDE->is_tile() ) {
481  uint16_t tq = pCell->quality();
482  uint8_t tq1 = (0xFF00&tq)>>8; // quality in channel 1
483  uint8_t tq2 = (0xFF&tq); // quality in channel 2
484  // reject cells with either 0xFF00 or 0xFF
485  if ( ((tq1&0xFF) != 0xFF) && ((tq2&0xFF) != 0xFF) ) {
486  eTile2 += ene*weight*ene*weight;
487  // take the worse of both qualities (one might be 0 in
488  // 1-channel cases)
489  eTile2Q += ene*weight*ene*weight*(tq1>tq2?tq1:tq2);
490  }
491  }
492  }
493  if ( ene > 0 ) {
494  ePos += ene*weight;
495  }
496 
497  if ( m_calculateSignificance ) {
498  const float sigma = m_twoGaussianNoise ?\
499  noise->getEffectiveSigma(pCell->ID(),pCell->gain(),pCell->energy()) : \
500  noise->getNoise(pCell->ID(),pCell->gain());
501 
502  sumSig2 += sigma*sigma;
503  // use geometry weighted energy of cell for leading cell significance
504  double Sig = (sigma>0?ene*weight/sigma:0);
505  if (m_useGPUCriteria) {
506  unsigned int thisSampl = myCDDE->getSampling();
507  if ( ( std::abs(Sig) > std::abs(maxAbsSig) ) ||
508  ( std::abs(Sig) == std::abs(maxAbsSig) && thisSampl > nSigSampl ) ||
509  ( std::abs(Sig) == std::abs(maxAbsSig) && thisSampl == nSigSampl && Sig > maxAbsSig ) ) {
510  maxAbsSig = Sig;
511  nSigSampl = thisSampl;
512  }
513 
514  }
515  else {
516  if ( std::abs(Sig) > std::abs(maxAbsSig) ) {
517  maxAbsSig = Sig;
518  nSigSampl = myCDDE->getSampling();
519  }
520  }
521  }
522  if ( m_calculateIsolation ) {
523  // get all 2D Neighbours if the cell is not inside another cluster with
524  // larger weight
525 
526  IdentifierHash myHashId = m_calo_id->calo_cell_hash(myId);
527  if ( clusterIdx[myHashId].first == iClus ) {
528  theNeighbors.clear();
529  m_calo_id->get_neighbours(myHashId, LArNeighbours::all2D, theNeighbors);
530  for (const auto& nhash: theNeighbors) {
531  clusterPair_t& idx = clusterIdx[nhash];
532 
533  // only need to look at each cell once per cluster
534  if ( idx.second == iClus ) continue;
535  idx.second = iClus;
536 
537  if ( idx.first == noCluster ) {
538  ++ nbEmpty[m_calo_id->calo_sample(nhash)];
539  } else if ( idx.first != iClus ) {
540  ++ nbNonEmpty[m_calo_id->calo_sample(nhash)];
541  }
542 
543  }
544  }
545  }
546 
547  if ( myCDDE != nullptr ) {
548  if ( m_nCellsPerSampling ) {
549  CaloCell_ID::CaloSample sam = myCDDE->getSampling();
550  size_t idx((size_t)sam);
551  if ( idx >= nCellsSamp.size() ) { nCellsSamp.resize(idx+1, { 0, 0 } ); }
552  std::get<0>(nCellsSamp[idx])++;
553  // special count for inner wheel cells in EME2
554  if ( sam == CaloCell_ID::EME2 && std::abs(myCDDE->eta()) > m_etaInnerWheel ) { std::get<1>(nCellsSamp[idx])++; }
555  }
556  if ( ene > 0. && weight > 0) {
557  // get all geometric information needed ...
558  cellinfo.push_back (CaloClusterMomentsMaker_detail::cellinfo {
559  .x = myCDDE->x(),
560  .y = myCDDE->y(),
561  .z = myCDDE->z(),
562  .energy = ene*weight,
563  .eta = myCDDE->eta(),
564  .phi = myCDDE->phi(),
565  .r = 0, // These two are filled in later.
566  .lambda = 0,
567  .volume = myCDDE->volume(),
568  .sample = myCDDE->getSampling(),
569  .identifier = m_calo_id->calo_cell_hash(myId)});
570 
571  CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo.back();
572 
573  if ( ci.energy > maxSampE[(unsigned int)ci.sample] )
574  maxSampE[(unsigned int)ci.sample] = ci.energy;
575 
576  if (m_useGPUCriteria) {
577  if (iCellMax < 0 ||
578  ci.energy > cellinfo[iCellMax].energy ||
579  (ci.energy == cellinfo[iCellMax].energy && ci.identifier > cellinfo[iCellMax].identifier) ) {
580  iCellScndMax = iCellMax;
581  iCellMax = cellinfo.size()-1;
582  }
583  else if (iCellScndMax < 0 ||
584  ci.energy > cellinfo[iCellScndMax].energy ||
585  (ci.energy == cellinfo[iCellScndMax].energy && ci.identifier > cellinfo[iCellScndMax].identifier) )
586  {
587  iCellScndMax = cellinfo.size()-1;
588  }
589  }
590  else {
591  if (iCellMax < 0 || ci.energy > cellinfo[iCellMax].energy ) {
592  iCellScndMax = iCellMax;
593  iCellMax = cellinfo.size()-1;
594  }
595  else if (iCellScndMax < 0 ||
596  ci.energy > cellinfo[iCellScndMax].energy )
597  {
598  iCellScndMax = cellinfo.size()-1;
599  }
600  }
601 
602  xc += ci.energy*ci.x;
603  yc += ci.energy*ci.y;
604  zc += ci.energy*ci.z;
605 
606  double dir = ci.x*ci.x+ci.y*ci.y+ci.z*ci.z;
607 
608  if ( dir > 0) {
609  dir = sqrt(dir);
610  dir = 1./dir;
611  }
612  mx += ci.energy*ci.x*dir;
613  my += ci.energy*ci.y*dir;
614  mz += ci.energy*ci.z*dir;
615 
616  w += ci.energy;
617  } // cell has E>0 and weight != 0
618  } // cell has valid DDE
619  } //end of loop over all cells
621  const auto hvFrac=m_larHVFraction->getLArHVFrac(theCluster->getCellLinks(),ctx);
622  eBadLArHV= hvFrac.first;
623  nBadLArHV=hvFrac.second;
624  }
625 
626  if ( w > 0 ) {
627  mass = w*w - mx*mx - my*my - mz*mz;
628  if ( mass > 0) {
629  mass = sqrt(mass);
630  }
631  else {
632  // make mass negative if m^2 was negative
633  mass = -sqrt(-mass);
634  }
635 
636  xc/=w;
637  yc/=w;
638  zc/=w;
639  Amg::Vector3D showerCenter(xc,yc,zc);
640  w=0;
641 
642 
643  //log << MSG::WARNING << "Found bad cells " << xbad_dac << " " << ybad_dac << " " << zbad_dac << " " << ebad_dac << endmsg;
644  //log << MSG::WARNING << "Found Cluster " << xbad_dac << " " << ybad_dac << " " << zbad_dac << " " << endmsg;
645  // shower axis is just the vector pointing from the IP to the shower center
646  // in case there are less than 3 cells in the cluster
647 
648  Amg::Vector3D showerAxis(xc,yc,zc);
649  Amg::setMag(showerAxis,1.0);
650 
651  // otherwise the principal direction with the largest absolute
652  // eigenvalue will be used unless it's angle w.r.t. the vector pointing
653  // from the IP to the shower center is larger than allowed by the
654  // property m_maxAxisAngle
655 
656  double angle(0),deltaPhi(0),deltaTheta(0);
657  if ( cellinfo.size() > 2 ) {
658  Eigen::Matrix3d C=Eigen::Matrix3d::Zero();
659  for(const CaloClusterMomentsMaker_detail::cellinfo& ci : cellinfo) {
660  const double e2 = ci.energy * ci.energy;
661 
662  C(0,0) += e2*(ci.x-xc)*(ci.x-xc);
663  C(1,0) += e2*(ci.x-xc)*(ci.y-yc);
664  C(2,0) += e2*(ci.x-xc)*(ci.z-zc);
665 
666  C(1,1) += e2*(ci.y-yc)*(ci.y-yc);
667  C(2,1) += e2*(ci.y-yc)*(ci.z-zc);
668 
669  C(2,2) += e2*(ci.z-zc)*(ci.z-zc);
670  w += e2;
671  }
672  C/=w;
673 
674  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(C);
675  if (eigensolver.info() != Eigen::Success) {
676  msg(MSG::WARNING) << "Failed to compute Eigenvalues -> Can't determine shower axis" << endmsg;
677  }
678  else {
679  // don't use the principal axes if at least one of the 3
680  // diagonal elements is 0
681 
682  const Eigen::Vector3d& S=eigensolver.eigenvalues();
683  const Eigen::Matrix3d& U=eigensolver.eigenvectors();
684 
685  const double epsilon = 1.E-6;
686 
687  if ( std::abs(S[0]) >= epsilon && std::abs(S[1]) >= epsilon && std::abs(S[2]) >= epsilon ) {
688 
689  Amg::Vector3D prAxis(showerAxis);
690  int iEigen = -1;
691 
692  for (i=0;i<3;i++) {
693  Amg::Vector3D tmpAxis=U.col(i);
694 
695  // calculate the angle
696  double tmpAngle=Amg::angle(tmpAxis,showerAxis);
697 
698  if ( tmpAngle > 90*deg ) {
699  tmpAngle = 180*deg - tmpAngle;
700  tmpAxis = -tmpAxis;
701  }
702 
703  if ( iEigen == -1 || tmpAngle < angle ) {
704  iEigen = i;
705  angle = tmpAngle;
706  prAxis = tmpAxis;
707  }
708  }//end for loop
709 
710  // calculate theta and phi angle differences
711 
712  deltaPhi = CaloPhiRange::diff(showerAxis.phi(),prAxis.phi());
713 
714  deltaTheta = showerAxis.theta() - prAxis.theta();
715 
716  // check the angle
717 
718  if ( angle < m_maxAxisAngle ) {
719  showerAxis = prAxis;
720  }
721  else
722  ATH_MSG_DEBUG("principal Direction (" << prAxis[Amg::x] << ", "
723  << prAxis[Amg::y] << ", " << prAxis[Amg::z] << ") deviates more than "
724  << m_maxAxisAngle*(1./deg)
725  << " deg from IP-to-ClusterCenter-axis (" << showerAxis[Amg::x] << ", "
726  << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")");
727  }//end if std::abs(S)<epsilon
728  else {
729  ATH_MSG_DEBUG("Eigenvalues close to 0, do not use principal axis");
730  }
731  }//end got eigenvalues
732  } //end if cellinfo.size()>2
733 
734  ATH_MSG_DEBUG("Shower Axis = (" << showerAxis[Amg::x] << ", "
735  << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")");
736 
737 
738  // calculate radial distance from and the longitudinal distance
739  // along the shower axis for each cell. The cluster center is
740  // at r=0 and lambda=0
741 
742  for (auto& ci : cellinfo) {
743  const Amg::Vector3D currentCell(ci.x,ci.y,ci.z);
744  // calculate distance from shower axis r
745  ci.r = ((currentCell-showerCenter).cross(showerAxis)).mag();
746  // calculate distance from shower center along shower axis
747  ci.lambda = (currentCell-showerCenter).dot(showerAxis);
748  }
749 
750  // loop over all positive energy cells and calculate all desired moments
751 
752  // define common norm for all simple moments
753  double commonNorm = 0;
754  double phi0 = cellinfo.size() > 0 ? cellinfo[0].phi : 0;
755 
756  for(unsigned i=0;i<cellinfo.size();i++) {
757  const CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i];
758  // loop over all valid moments
759  commonNorm += ci.energy;
760  for(size_t iMoment = 0, size = m_validMoments.size();
761  iMoment != size;
762  ++ iMoment)
763  {
764  // now calculate the actual moments
765  switch (m_validMoments[iMoment]) {
766  case FIRST_ETA:
767  myMoments[iMoment] += ci.energy*ci.eta;
768  break;
769  case FIRST_PHI:
770  // first cell decides the sign in order to avoid
771  // overlap problem at phi = -pi == +pi
772  // need to be normalized to the range [-pi,+pi] in the end
773  myMoments[iMoment] += ci.energy * proxim (ci.phi, phi0);
774  break;
775  case SECOND_R:
776  myMoments[iMoment] += ci.energy*ci.r*ci.r;
777  break;
778  case SECOND_LAMBDA:
779  myMoments[iMoment] += ci.energy*ci.lambda*ci.lambda;
780  break;
781  case LATERAL:
782  if ( (int)i != iCellMax && (int)i != iCellScndMax ) {
783  myMoments[iMoment] += ci.energy*ci.r*ci.r;
784  myNorms[iMoment] += ci.energy*ci.r*ci.r;
785  }
786  else {
787  double rm = ci.r;
788  if ( rm < m_minRLateral )
789  rm = m_minRLateral;
790  myNorms[iMoment] += rm*rm*ci.energy;
791  }
792  break;
793  case LONGITUDINAL:
794  if ( (int)i != iCellMax && (int)i != iCellScndMax ) {
795  myMoments[iMoment] += ci.energy*ci.lambda*ci.lambda;
796  myNorms[iMoment] += ci.energy*ci.lambda*ci.lambda;
797  }
798  else {
799  double lm = ci.lambda;
800  if ( lm < m_minLLongitudinal )
801  lm = m_minLLongitudinal;
802  myNorms[iMoment] += lm*lm*ci.energy;
803  }
804  break;
805  case FIRST_ENG_DENS:
806  if ( ci.volume > 0 ) {
807  myMoments[iMoment] += ci.energy*ci.energy/ci.volume;
808  myNorms[iMoment] += ci.energy;
809  }
810  break;
811  case SECOND_ENG_DENS:
812  if ( ci.volume > 0 ) {
813  myMoments[iMoment] += ci.energy*std::pow(ci.energy/ci.volume,2);
814  myNorms[iMoment] += ci.energy;
815  }
816  break;
817  case ENG_FRAC_EM:
818  if ( ci.sample == CaloCell_ID::EMB1
819  || ci.sample == CaloCell_ID::EMB2
820  || ci.sample == CaloCell_ID::EMB3
821  || ci.sample == CaloCell_ID::EME1
822  || ci.sample == CaloCell_ID::EME2
823  || ci.sample == CaloCell_ID::EME3
824  || ci.sample == CaloCell_ID::FCAL0 )
825  myMoments[iMoment] += ci.energy;
826  break;
827  case ENG_FRAC_MAX:
828  if ( (int)i == iCellMax )
829  myMoments[iMoment] = ci.energy;
830  break;
831  case PTD:
832  // do not convert to pT since clusters are small and
833  // there is virtually no difference and cosh just costs
834  // time ...
835  myMoments[iMoment] += ci.energy*ci.energy;
836  myNorms[iMoment] += ci.energy;
837  break;
838  default:
839  // nothing to be done for other moments
840  break;
841  }
842  }
843  } //end of loop over cell
844 
845 
846  // assign moments which don't need the loop over the cells
847  for (size_t iMoment = 0, size = m_validMoments.size();
848  iMoment != size;
849  ++ iMoment)
850  {
851  // now calculate the actual moments
852  switch (m_validMoments[iMoment]) {
853  case FIRST_ETA:
854  case FIRST_PHI:
855  case SECOND_R:
856  case SECOND_LAMBDA:
857  case ENG_FRAC_EM:
858  case ENG_FRAC_MAX:
859  myNorms[iMoment] = commonNorm;
860  break;
861  case DELTA_PHI:
862  myMoments[iMoment] = deltaPhi;
863  break;
864  case DELTA_THETA:
865  myMoments[iMoment] = deltaTheta;
866  break;
867  case DELTA_ALPHA:
868  myMoments[iMoment] = angle;
869  break;
870  case CENTER_X:
871  myMoments[iMoment] = showerCenter.x();
872  break;
873  case CENTER_Y:
874  myMoments[iMoment] = showerCenter.y();
875  break;
876  case CENTER_Z:
877  myMoments[iMoment] = showerCenter.z();
878  break;
879  case CENTER_MAG:
880  myMoments[iMoment] = showerCenter.mag();
881  break;
882  case CENTER_LAMBDA:
883  // calculate the longitudinal distance along the shower axis
884  // of the shower center from the calorimeter start
885 
886  // first need calo boundary at given eta phi try LAREM barrel
887  // first, then LAREM endcap OW, then LAREM endcap IW, then
888  // FCal
889  {
890  double r_calo(0),z_calo(0),lambda_c(0);
891  r_calo = m_caloDepthTool->get_entrance_radius(CaloCell_ID::EMB1,
892  showerCenter.eta(),
893  showerCenter.phi(),
894  caloDDMgr);
895  if ( r_calo == 0 ) {
896  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::EME1,
897  showerCenter.eta(),
898  showerCenter.phi(),
899  caloDDMgr);
900  if ( z_calo == 0 )
901  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::EME2,
902  showerCenter.eta(),
903  showerCenter.phi(),
904  caloDDMgr);
905  if ( z_calo == 0 )
906  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::FCAL0,
907  showerCenter.eta(),
908  showerCenter.phi(),
909  caloDDMgr);
910  if ( z_calo == 0 ) // for H6 TB without EMEC outer wheel
911  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::HEC0,
912  showerCenter.eta(),
913  showerCenter.phi(),
914  caloDDMgr);
915  if ( z_calo != 0 && showerAxis.z() != 0 ) {
916  lambda_c = std::abs((z_calo-showerCenter.z())/showerAxis.z());
917  }
918  }
919  else {
920  double r_s2 = showerAxis.x()*showerAxis.x()
921  +showerAxis.y()*showerAxis.y();
922  double r_cs = showerAxis.x()*showerCenter.x()
923  +showerAxis.y()*showerCenter.y();
924  double r_cr = showerCenter.x()*showerCenter.x()
925  +showerCenter.y()*showerCenter.y()-r_calo*r_calo;
926  if ( r_s2 > 0 ) {
927  double det = r_cs*r_cs/(r_s2*r_s2) - r_cr/r_s2;
928  if ( det > 0 ) {
929  det = sqrt(det);
930  double l1(-r_cs/r_s2);
931  double l2(l1);
932  l1 += det;
933  l2 -= det;
934  if ( std::abs(l1) < std::abs(l2) )
935  lambda_c = std::abs(l1);
936  else
937  lambda_c = std::abs(l2);
938  }
939  }
940  }
941  myMoments[iMoment] = lambda_c;
942  }
943  break;
944  case ENG_FRAC_CORE:
945  for(i=0;i<(int)CaloCell_ID::Unknown;i++)
946  myMoments[iMoment] += maxSampE[i];
947  myNorms[iMoment] = commonNorm;
948  break;
949  case ISOLATION:
950  {
951  // loop over empty and filled perimeter cells and
952  // get a weighted ratio by means of energy fraction per layer
953  for(unsigned int i=0; i != CaloSampling::Unknown; ++ i) {
955  if (theCluster->hasSampling(s)) {
956  const double eSample = theCluster->eSample(s);
957  if (eSample > 0) {
958  int nAll = nbEmpty[i]+nbNonEmpty[i];
959  if (nAll > 0) {
960  myMoments[iMoment] += (eSample*nbEmpty[i])/nAll;
961  myNorms[iMoment] += eSample;
962  }
963  }//end of eSample>0
964  }//end has sampling
965  }//end loop over samplings
966  }
967  break;
968  case ENG_BAD_CELLS:
969  myMoments[iMoment] = eBad;
970  break;
971  case N_BAD_CELLS:
972  myMoments[iMoment] = nbad;
973  break;
974  case N_BAD_CELLS_CORR:
975  myMoments[iMoment] = nbad_dac;
976  break;
977  case BAD_CELLS_CORR_E:
978  myMoments[iMoment] = ebad_dac;
979  break;
980  case BADLARQ_FRAC:
981  myMoments[iMoment] = eBadLArQ/(theCluster->e()!=0.?theCluster->e():1.);
982  break;
983  case ENG_POS:
984  myMoments[iMoment] = ePos;
985  break;
986  case SIGNIFICANCE:
987  myMoments[iMoment] = (sumSig2>0?theCluster->e()/sqrt(sumSig2):0.);
988  break;
989  case CELL_SIGNIFICANCE:
990  myMoments[iMoment] = maxAbsSig;
991  break;
992  case CELL_SIG_SAMPLING:
993  myMoments[iMoment] = nSigSampl;
994  break;
995  case AVG_LAR_Q:
996  myMoments[iMoment] = eLAr2Q/(eLAr2>0?eLAr2:1);
997  break;
998  case AVG_TILE_Q:
999  myMoments[iMoment] = eTile2Q/(eTile2>0?eTile2:1);
1000  break;
1001  case ENG_BAD_HV_CELLS:
1002  myMoments[iMoment] = eBadLArHV;
1003  break;
1004  case N_BAD_HV_CELLS:
1005  myMoments[iMoment] = nBadLArHV;
1006  break;
1007  case PTD:
1008  myMoments[iMoment] = sqrt(myMoments[iMoment]);
1009  break;
1010  case MASS:
1011  myMoments[iMoment] = mass;
1012  break;
1013  default:
1014  // nothing to be done for other moments
1015  break;
1016  }
1017  }
1018  }
1019 
1020  // normalize moments and copy to Cluster Moment Store
1021  size_t size= m_validMoments.size();
1022  for (size_t iMoment = 0; iMoment != size; ++iMoment) {
1024  if ( myNorms[iMoment] != 0 )
1025  myMoments[iMoment] /= myNorms[iMoment];
1026  if ( moment == FIRST_PHI )
1027  myMoments[iMoment] = CaloPhiRange::fix(myMoments[iMoment]);
1028  theCluster->insertMoment(moment,myMoments[iMoment]);
1029  } // loop on moments for cluster
1030  } // check on requested moments
1031  // check on second moment of time if requested
1032  if ( m_secondTime ) { theCluster->insertMoment(SECOND_TIME,theCluster->secondTime()); }
1033  // check on number of cells per sampling moment if requested
1034  if ( m_nCellsPerSampling ) {
1035  for ( size_t isam(0); isam < nCellsSamp.size(); ++isam ) {
1036  theCluster->setNumberCellsInSampling((CaloCell_ID::CaloSample)isam,std::get<0>(nCellsSamp.at(isam)),false);
1037  if ( isam == (size_t)CaloCell_ID::EME2 && std::get<1>(nCellsSamp.at(isam)) > 0 ) {
1038  theCluster->setNumberCellsInSampling((CaloCell_ID::CaloSample)isam,std::get<1>(nCellsSamp.at(isam)),true);
1039  }
1040  } // loop on samplings
1041  nCellsSamp.clear();
1042  }
1043  } // loop on clusters
1044 
1045  return StatusCode::SUCCESS;
1046 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
GetLCDefs::Unknown
@ Unknown
Definition: GetLCDefs.h:21
TauGNNUtils::Variables::Cluster::CENTER_LAMBDA
bool CENTER_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:840
CaloPrefetch.h
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:334
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
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::getMomentValue
double getMomentValue(MomentType type) const
Retrieve individual moment - no check for existance! Returns -999 on error.
Definition: CaloCluster_v1.h:906
xAOD::CaloCluster_v1::CaloSample
CaloSampling::CaloSample CaloSample
Definition: CaloCluster_v1.h:66
xAOD::uint8_t
uint8_t
Definition: Muon_v1.cxx:557
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
TauGNNUtils::Variables::Cluster::EM_PROBABILITY
bool EM_PROBABILITY(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:909
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
CaloClusterMomentsMaker::m_caloDepthTool
ToolHandle< CaloDepthTool > m_caloDepthTool
Definition: CaloClusterMomentsMaker.h:125
CaloClusterMomentsMaker_detail::cellinfo::energy
double energy
Definition: CaloClusterMomentsMaker.cxx:327
CaloClusterMomentsMaker::execute
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusColl) const override final
Execute on an entire collection of clusters.
Definition: CaloClusterMomentsMaker.cxx:340
TRTCalib_Extractor.det
det
Definition: TRTCalib_Extractor.py:36
CaloClusterMomentsMaker_detail::cellinfo::lambda
double lambda
Definition: CaloClusterMomentsMaker.cxx:331
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
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
CaloDetDescrElement
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:66
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
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
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
python.CaloAddPedShiftConfig.type
type
Definition: CaloAddPedShiftConfig.py:42
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
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
xAOD::CaloCluster_v1::MomentType
MomentType
Enums to identify different moments.
Definition: CaloCluster_v1.h:120
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
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:404
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:93
DataModel_detail::iterator
(Non-const) Iterator class for DataVector/DataList.
Definition: DVLIterator.h:184
lumiFormat.i
int i
Definition: lumiFormat.py:85
CaloSampling::CaloSample
CaloSample
Definition: Calorimeter/CaloGeoHelpers/CaloGeoHelpers/CaloSampling.h:22
xAOD::CaloCluster_v1::ncells_store_t
std::vector< uint16_t > ncells_store_t
Store type for number-of-cells-in-sampling counter.
Definition: CaloCluster_v1.h:80
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
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
python.LArMinBiasAlgConfig.int
int
Definition: LArMinBiasAlgConfig.py:59
fitman.mz
mz
Definition: fitman.py:526
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.
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
CaloClusterMomentsMaker_detail::cellinfo::y
double y
Definition: CaloClusterMomentsMaker.cxx:325
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
xAOD::CaloCluster_v1::retrieveMoment
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
Definition: CaloCluster_v1.cxx:738
CaloClusterMomentsMaker::m_minRLateral
double m_minRLateral
the minimal in the definition of the Lateral moment
Definition: CaloClusterMomentsMaker.h:91
TauGNNUtils::Variables::Cluster::SECOND_LAMBDA
bool SECOND_LAMBDA(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:835
CaloClusterMomentsMaker::finalize
virtual StatusCode finalize() override
Definition: CaloClusterMomentsMaker.cxx:313
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
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
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
fill
void fill(H5::Group &out_file, size_t iterations)
Definition: test-hdf5-writer.cxx:95
CaloDetDescrElement::is_tile
bool is_tile() const
cell belongs to Tile
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:442
CaloNoise
Definition: CaloNoise.h:16
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:228
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:326
CaloClusterMomentsMaker_detail::cellinfo::phi
double phi
Definition: CaloClusterMomentsMaker.cxx:329
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:323
TauGNNUtils::Variables::Cluster::SECOND_R
bool SECOND_R(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:830
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
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
TauGNNUtils::Variables::Cluster::CENTER_MAG
bool CENTER_MAG(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:916
DataVector::end
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
CaloClusterMomentsMaker::initialize
virtual StatusCode initialize() override
Definition: CaloClusterMomentsMaker.cxx:183
xAOD::CaloCluster_v1::eSample
float eSample(const CaloSample sampling) const
Definition: CaloCluster_v1.cxx:521
y
#define y
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
CaloClusterMomentsMaker_detail
Definition: CaloClusterMomentsMaker.cxx:320
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
DeMoScan.first
bool first
Definition: DeMoScan.py:536
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:567
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
TauGNNUtils::Variables::Cluster::FIRST_ENG_DENS
bool FIRST_ENG_DENS(const xAOD::TauJet &, const xAOD::CaloVertexedTopoCluster &cluster, double &out)
Definition: TauGNNUtils.cxx:902
CaloClusterMomentsMaker_detail::cellinfo::r
double r
Definition: CaloClusterMomentsMaker.cxx:330
CaloDetDescrElement::eta
float eta() const
cell eta
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:344
CaloClusterMomentsMaker_detail::cellinfo::x
double x
Definition: CaloClusterMomentsMaker.cxx:324
CaloDetDescrElement::phi
float phi() const
cell phi
Definition: Calorimeter/CaloDetDescr/CaloDetDescr/CaloDetDescrElement.h:346
skel.l1
l1
Definition: skel.GENtoEVGEN.py:403
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
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:328
CaloClusterMomentsMaker::m_maxAxisAngle
double m_maxAxisAngle
the maximal allowed deviation from the IP-to-ClusterCenter-axis.
Definition: CaloClusterMomentsMaker.h:83
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
CaloCell_ID_FCS::FCAL0
@ FCAL0
Definition: FastCaloSim_CaloCell_ID.h:40
CaloClusterMomentsMaker_detail::cellinfo::volume
double volume
Definition: CaloClusterMomentsMaker.cxx:332
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:333
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:26
xAOD::CaloCluster_v1::e
virtual double e() const
The total energy of the particle.
Definition: CaloCluster_v1.cxx:265
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.
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
Identifier
Definition: IdentifierFieldParser.cxx:14