ATLAS Offline Software
CaloClusterMomentsMaker.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 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  cellinfo(const bool useGPUCriteria = false)
336  {
337  if (useGPUCriteria) {
338  x = 0;
339  y = 0;
340  z = 0;
341  energy = 0;
342  eta = 0;
343  phi = 0;
344  r = 0;
345  lambda = 0;
346  volume = 0;
348  identifier = 0;
349  }
350  }
351 };
352 
353 } // namespace CaloClusterMomentsMaker_detail
354 
356 CaloClusterMomentsMaker::execute(const EventContext& ctx,
357  xAOD::CaloClusterContainer *theClusColl)
358  const
359 {
360  ATH_MSG_DEBUG("Executing " << name());
361 
362  // Maps cell IdentifierHash to cluster index in cluster collection.
363  // Only used when cluster isolation moment is calculated.
364  using clusterIdx_t = std::uint16_t;
365  typedef std::pair<clusterIdx_t, clusterIdx_t> clusterPair_t;
366  std::vector<clusterPair_t> clusterIdx;
367  const clusterIdx_t noCluster = std::numeric_limits<clusterIdx_t>::max();
368 
369  const CaloNoise* noise=nullptr;
372  noise=*noiseHdl;
373  }
374 
376  const CaloDetDescrManager* caloDDMgr = *caloMgrHandle;
377  // Counters for number of empty and non-empty neighbor cells per sampling
378  // layer Only used when cluster isolation moment is calculated.
379  int nbEmpty[CaloCell_ID::Unknown];
380  int nbNonEmpty[CaloCell_ID::Unknown];
381 
382  // prepare stuff from entire collection in case isolation moment
383  // should be calculated
384 
385  if ( m_calculateIsolation ) {
386 
387  if (theClusColl->size() >= noCluster) {
388  msg(MSG::ERROR) << "Too many clusters" << endmsg;
389  return StatusCode::FAILURE;
390  }
391 
392  // initialize with "empty" values
393  clusterIdx.resize(m_calo_id->calo_cell_hash_max(),
394  clusterPair_t(noCluster, noCluster));
395 
396  int iClus = 0;
397  for (xAOD::CaloCluster* theCluster : *theClusColl) {
398  // loop over all cell members and fill cell vector for used cells
399  xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
400  xAOD::CaloCluster::cell_iterator cellIterEnd = theCluster->cell_end();
401  for(; cellIter != cellIterEnd; cellIter++ ){
402  CxxUtils::prefetchNext(cellIter, cellIterEnd);
403  const CaloCell* pCell = *cellIter;
404 
405  Identifier myId = pCell->ID();
406  IdentifierHash myHashId = m_calo_id->calo_cell_hash(myId);
407  if ( clusterIdx[(unsigned int)myHashId].first != noCluster) {
408  // check weight and assign to current cluster if weight is > 0.5
409  double weight = cellIter.weight();
410  if ( weight > 0.5 )
411  clusterIdx[(unsigned int)myHashId].first = iClus;
412  }
413  else {
414  clusterIdx[(unsigned int)myHashId].first = iClus;
415  }
416  }
417  ++iClus;
418  }
419  }
420 
421  // Move allocation of temporary arrays outside the cluster loop.
422  // That way, we don't need to delete and reallocate them
423  // each time through the loop.
424 
425  std::vector<CaloClusterMomentsMaker_detail::cellinfo> cellinfo;
426  std::vector<double> maxSampE (CaloCell_ID::Unknown);
427  std::vector<double> myMoments(m_validMoments.size(),0);
428  std::vector<double> myNorms(m_validMoments.size(),0);
429  std::vector<std::tuple<int,int> > nCellsSamp; nCellsSamp.reserve(CaloCell_ID::Unknown);
430  std::vector<IdentifierHash> theNeighbors;
431  // loop over individual clusters
432  xAOD::CaloClusterContainer::iterator clusIter = theClusColl->begin();
433  xAOD::CaloClusterContainer::iterator clusIterEnd = theClusColl->end();
434  int iClus = 0;
435  for( ;clusIter!=clusIterEnd;++clusIter,++iClus) {
436  xAOD::CaloCluster * theCluster = *clusIter;
437 
438  double w(0),xc(0),yc(0),zc(0),mx(0),my(0),mz(0),mass(0);
439  double eBad(0),ebad_dac(0),ePos(0),eBadLArQ(0),sumSig2(0),maxAbsSig(0);
440  double eLAr2(0),eLAr2Q(0);
441  double eTile2(0),eTile2Q(0);
442  double eBadLArHV(0);
443  int nbad(0),nbad_dac(0),nBadLArHV(0);
444  unsigned int ncell(0),i,nSigSampl(0);
445  unsigned int theNumOfCells = theCluster->size();
446 
447  // these two are needed for the LATERAL moment
448  int iCellMax(-1);
449  int iCellScndMax(-1);
450 
451  if (cellinfo.capacity() == 0)
452  cellinfo.reserve (theNumOfCells*2);
453  cellinfo.resize (theNumOfCells, CaloClusterMomentsMaker_detail::cellinfo(m_useGPUCriteria));
454 
455  for(i=0;i<(unsigned int)CaloCell_ID::Unknown;i++)
456  maxSampE[i] = 0;
457 
458  if ( !m_momentsNames.empty() ) {
459  std::fill (myMoments.begin(), myMoments.end(), 0);
460  std::fill (myNorms.begin(), myNorms.end(), 0);
461  if ( m_calculateIsolation ) {
462  std::fill_n(nbNonEmpty, CaloCell_ID::Unknown, 0);
463  std::fill_n(nbEmpty, CaloCell_ID::Unknown, 0);
464  }
465 
466  // loop over all cell members and calculate the center of mass
467  xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
468  xAOD::CaloCluster::cell_iterator cellIterEnd = theCluster->cell_end();
469  for(; cellIter != cellIterEnd; cellIter++ ){
470  CaloPrefetch::nextDDE(cellIter, cellIterEnd);
471 
472  const CaloCell* pCell = (*cellIter);
473  Identifier myId = pCell->ID();
474  const CaloDetDescrElement* myCDDE = pCell->caloDDE();
475  double ene = pCell->e();
476  if(m_absOpt) ene = std::abs(ene);
477  double weight = cellIter.weight();//theCluster->getCellWeight(cellIter);
478  if ( pCell->badcell() ) {
479  eBad += ene*weight;
480  nbad++;
481  if(ene!=0){
482  ebad_dac+=ene*weight;
483  nbad_dac++;
484  }
485  }
486  else {
487  if ( myCDDE && ! (myCDDE->is_tile())
488  && ((pCell->provenance() & 0x2000) == 0x2000)
489  && !((pCell->provenance() & 0x0800) == 0x0800)) {
490  if ( pCell->quality() > m_minBadLArQuality ) {
491  eBadLArQ += ene*weight;
492  }
493  eLAr2 += ene*weight*ene*weight;
494  eLAr2Q += ene*weight*ene*weight*pCell->quality();
495  }
496  if ( myCDDE && myCDDE->is_tile() ) {
497  uint16_t tq = pCell->quality();
498  uint8_t tq1 = (0xFF00&tq)>>8; // quality in channel 1
499  uint8_t tq2 = (0xFF&tq); // quality in channel 2
500  // reject cells with either 0xFF00 or 0xFF
501  if ( ((tq1&0xFF) != 0xFF) && ((tq2&0xFF) != 0xFF) ) {
502  eTile2 += ene*weight*ene*weight;
503  // take the worse of both qualities (one might be 0 in
504  // 1-channel cases)
505  eTile2Q += ene*weight*ene*weight*(tq1>tq2?tq1:tq2);
506  }
507  }
508  }
509  if ( ene > 0 ) {
510  ePos += ene*weight;
511  }
512 
513  if ( m_calculateSignificance ) {
514  const float sigma = m_twoGaussianNoise ?\
515  noise->getEffectiveSigma(pCell->ID(),pCell->gain(),pCell->energy()) : \
516  noise->getNoise(pCell->ID(),pCell->gain());
517 
518  sumSig2 += sigma*sigma;
519  // use geomtery weighted energy of cell for leading cell significance
520  double Sig = (sigma>0?ene*weight/sigma:0);
521  if (m_useGPUCriteria) {
522  unsigned int thisSampl = myCDDE->getSampling();
523  if ( ( std::abs(Sig) > std::abs(maxAbsSig) ) ||
524  ( std::abs(Sig) == std::abs(maxAbsSig) && thisSampl > nSigSampl ) ||
525  ( std::abs(Sig) == std::abs(maxAbsSig) && thisSampl == nSigSampl && Sig > maxAbsSig ) ) {
526  maxAbsSig = Sig;
527  nSigSampl = thisSampl;
528  }
529 
530  }
531  else {
532  if ( std::abs(Sig) > std::abs(maxAbsSig) ) {
533  maxAbsSig = Sig;
534  nSigSampl = myCDDE->getSampling();
535  }
536  }
537  }
538  if ( m_calculateIsolation ) {
539  // get all 2D Neighbours if the cell is not inside another cluster with
540  // larger weight
541 
542  IdentifierHash myHashId = m_calo_id->calo_cell_hash(myId);
543  if ( clusterIdx[myHashId].first == iClus ) {
544  theNeighbors.clear();
545  m_calo_id->get_neighbours(myHashId, LArNeighbours::all2D, theNeighbors);
546  for (const auto& nhash: theNeighbors) {
547  clusterPair_t& idx = clusterIdx[nhash];
548 
549  // only need to look at each cell once per cluster
550  if ( idx.second == iClus ) continue;
551  idx.second = iClus;
552 
553  if ( idx.first == noCluster ) {
554  ++ nbEmpty[m_calo_id->calo_sample(nhash)];
555  } else if ( idx.first != iClus ) {
556  ++ nbNonEmpty[m_calo_id->calo_sample(nhash)];
557  }
558 
559  }
560  }
561  }
562 
563  if ( myCDDE != nullptr ) {
564  if ( m_nCellsPerSampling ) {
565  CaloCell_ID::CaloSample sam = myCDDE->getSampling();
566  size_t idx((size_t)sam);
567  if ( idx >= nCellsSamp.size() ) { nCellsSamp.resize(idx+1, { 0, 0 } ); }
568  std::get<0>(nCellsSamp[idx])++;
569  // special count for inner wheel cells in EME2
570  if ( sam == CaloCell_ID::EME2 && std::abs(myCDDE->eta()) > m_etaInnerWheel ) { std::get<1>(nCellsSamp[idx])++; }
571  }
572  if ( ene > 0. && weight > 0) {
573  // get all geometric information needed ...
575  ci.x = myCDDE->x();
576  ci.y = myCDDE->y();
577  ci.z = myCDDE->z();
578  ci.eta = myCDDE->eta();
579  ci.phi = myCDDE->phi();
580  ci.energy = ene*weight;
581  ci.volume = myCDDE->volume();
582  ci.sample = myCDDE->getSampling();
583  ci.identifier = m_calo_id->calo_cell_hash(myId);
584 
585  if ( ci.energy > maxSampE[(unsigned int)ci.sample] )
586  maxSampE[(unsigned int)ci.sample] = ci.energy;
587 
588  if (m_useGPUCriteria) {
589  if (iCellMax < 0 ||
590  ci.energy > cellinfo[iCellMax].energy ||
591  (ci.energy == cellinfo[iCellMax].energy && ci.identifier > cellinfo[iCellMax].identifier) ) {
592  iCellScndMax = iCellMax;
593  iCellMax = ncell;
594  }
595  else if (iCellScndMax < 0 ||
596  ci.energy > cellinfo[iCellScndMax].energy ||
597  (ci.energy == cellinfo[iCellScndMax].energy && ci.identifier > cellinfo[iCellScndMax].identifier) )
598  {
599  iCellScndMax = ncell;
600  }
601  }
602  else {
603  if (iCellMax < 0 || ci.energy > cellinfo[iCellMax].energy ) {
604  iCellScndMax = iCellMax;
605  iCellMax = ncell;
606  }
607  else if (iCellScndMax < 0 ||
608  ci.energy > cellinfo[iCellScndMax].energy )
609  {
610  iCellScndMax = ncell;
611  }
612  }
613 
614  xc += ci.energy*ci.x;
615  yc += ci.energy*ci.y;
616  zc += ci.energy*ci.z;
617 
618  double dir = ci.x*ci.x+ci.y*ci.y+ci.z*ci.z;
619 
620  if ( dir > 0) {
621  dir = sqrt(dir);
622  dir = 1./dir;
623  }
624  mx += ci.energy*ci.x*dir;
625  my += ci.energy*ci.y*dir;
626  mz += ci.energy*ci.z*dir;
627 
628  w += ci.energy;
629 
630  ncell++;
631  } // cell has E>0 and weight != 0
632  } // cell has valid DDE
633  } //end of loop over all cells
635  const auto hvFrac=m_larHVFraction->getLArHVFrac(theCluster->getCellLinks(),ctx);
636  eBadLArHV= hvFrac.first;
637  nBadLArHV=hvFrac.second;
638  }
639 
640  if ( w > 0 ) {
641  mass = w*w - mx*mx - my*my - mz*mz;
642  if ( mass > 0) {
643  mass = sqrt(mass);
644  }
645  else {
646  // make mass negative if m^2 was negative
647  mass = -sqrt(-mass);
648  }
649 
650  xc/=w;
651  yc/=w;
652  zc/=w;
653  Amg::Vector3D showerCenter(xc,yc,zc);
654  w=0;
655 
656 
657  //log << MSG::WARNING << "Found bad cells " << xbad_dac << " " << ybad_dac << " " << zbad_dac << " " << ebad_dac << endmsg;
658  //log << MSG::WARNING << "Found Cluster " << xbad_dac << " " << ybad_dac << " " << zbad_dac << " " << endmsg;
659  // shower axis is just the vector pointing from the IP to the shower center
660  // in case there are less than 3 cells in the cluster
661 
662  Amg::Vector3D showerAxis(xc,yc,zc);
663  Amg::setMag(showerAxis,1.0);
664 
665  // otherwise the principal direction with the largest absolute
666  // eigenvalue will be used unless it's angle w.r.t. the vector pointing
667  // from the IP to the shower center is larger than allowed by the
668  // property m_maxAxisAngle
669 
670  double angle(0),deltaPhi(0),deltaTheta(0);
671  if ( ncell > 2 ) {
672  Eigen::Matrix3d C=Eigen::Matrix3d::Zero();
673  for(i=0;i<ncell;i++) {
674  const CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i];
675  const double e2 = ci.energy * ci.energy;
676 
677  C(0,0) += e2*(ci.x-xc)*(ci.x-xc);
678  C(1,0) += e2*(ci.x-xc)*(ci.y-yc);
679  C(2,0) += e2*(ci.x-xc)*(ci.z-zc);
680 
681  C(1,1) += e2*(ci.y-yc)*(ci.y-yc);
682  C(2,1) += e2*(ci.y-yc)*(ci.z-zc);
683 
684  C(2,2) += e2*(ci.z-zc)*(ci.z-zc);
685  w += e2;
686  }
687  C/=w;
688 
689  Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(C);
690  if (eigensolver.info() != Eigen::Success) {
691  msg(MSG::WARNING) << "Failed to compute Eigenvalues -> Can't determine shower axis" << endmsg;
692  }
693  else {
694  // don't use the principal axes if at least one of the 3
695  // diagonal elements is 0
696 
697  const Eigen::Vector3d& S=eigensolver.eigenvalues();
698  const Eigen::Matrix3d& U=eigensolver.eigenvectors();
699 
700  const double epsilon = 1.E-6;
701 
702  if ( std::abs(S[0]) >= epsilon && std::abs(S[1]) >= epsilon && std::abs(S[2]) >= epsilon ) {
703 
704  Amg::Vector3D prAxis(showerAxis);
705  int iEigen = -1;
706 
707  for (i=0;i<3;i++) {
708  Amg::Vector3D tmpAxis=U.col(i);
709 
710  // calculate the angle
711  double tmpAngle=Amg::angle(tmpAxis,showerAxis);
712 
713  if ( tmpAngle > 90*deg ) {
714  tmpAngle = 180*deg - tmpAngle;
715  tmpAxis = -tmpAxis;
716  }
717 
718  if ( iEigen == -1 || tmpAngle < angle ) {
719  iEigen = i;
720  angle = tmpAngle;
721  prAxis = tmpAxis;
722  }
723  }//end for loop
724 
725  // calculate theta and phi angle differences
726 
727  deltaPhi = CaloPhiRange::diff(showerAxis.phi(),prAxis.phi());
728 
729  deltaTheta = showerAxis.theta() - prAxis.theta();
730 
731  // check the angle
732 
733  if ( angle < m_maxAxisAngle ) {
734  showerAxis = prAxis;
735  }
736  else
737  ATH_MSG_DEBUG("principal Direction (" << prAxis[Amg::x] << ", "
738  << prAxis[Amg::y] << ", " << prAxis[Amg::z] << ") deviates more than "
739  << m_maxAxisAngle*(1./deg)
740  << " deg from IP-to-ClusterCenter-axis (" << showerAxis[Amg::x] << ", "
741  << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")");
742  }//end if std::abs(S)<epsilon
743  else {
744  ATH_MSG_DEBUG("Eigenvalues close to 0, do not use principal axis");
745  }
746  }//end got eigenvalues
747  } //end if ncell>2
748 
749  ATH_MSG_DEBUG("Shower Axis = (" << showerAxis[Amg::x] << ", "
750  << showerAxis[Amg::y] << ", " << showerAxis[Amg::z] << ")");
751 
752 
753  // calculate radial distance from and the longitudinal distance
754  // along the shower axis for each cell. The cluster center is
755  // at r=0 and lambda=0
756 
757  for (auto& ci : cellinfo) {
758  const Amg::Vector3D currentCell(ci.x,ci.y,ci.z);
759  // calculate distance from shower axis r
760  ci.r = ((currentCell-showerCenter).cross(showerAxis)).mag();
761  // calculate distance from shower center along shower axis
762  ci.lambda = (currentCell-showerCenter).dot(showerAxis);
763  }
764 
765  // loop over all positive energy cells and calculate all desired moments
766 
767  // define common norm for all simple moments
768  double commonNorm = 0;
769  double phi0 = ncell > 0 ? cellinfo[0].phi : 0;
770 
771  for(unsigned i=0;i<ncell;i++) {
772  const CaloClusterMomentsMaker_detail::cellinfo& ci = cellinfo[i];
773  // loop over all valid moments
774  commonNorm += ci.energy;
775  for(size_t iMoment = 0, size = m_validMoments.size();
776  iMoment != size;
777  ++ iMoment)
778  {
779  // now calculate the actual moments
780  switch (m_validMoments[iMoment]) {
781  case FIRST_ETA:
782  myMoments[iMoment] += ci.energy*ci.eta;
783  break;
784  case FIRST_PHI:
785  // first cell decides the sign in order to avoid
786  // overlap problem at phi = -pi == +pi
787  // need to be normalized to the range [-pi,+pi] in the end
788  myMoments[iMoment] += ci.energy * proxim (ci.phi, phi0);
789  break;
790  case SECOND_R:
791  myMoments[iMoment] += ci.energy*ci.r*ci.r;
792  break;
793  case SECOND_LAMBDA:
794  myMoments[iMoment] += ci.energy*ci.lambda*ci.lambda;
795  break;
796  case LATERAL:
797  if ( (int)i != iCellMax && (int)i != iCellScndMax ) {
798  myMoments[iMoment] += ci.energy*ci.r*ci.r;
799  myNorms[iMoment] += ci.energy*ci.r*ci.r;
800  }
801  else {
802  double rm = ci.r;
803  if ( rm < m_minRLateral )
804  rm = m_minRLateral;
805  myNorms[iMoment] += rm*rm*ci.energy;
806  }
807  break;
808  case LONGITUDINAL:
809  if ( (int)i != iCellMax && (int)i != iCellScndMax ) {
810  myMoments[iMoment] += ci.energy*ci.lambda*ci.lambda;
811  myNorms[iMoment] += ci.energy*ci.lambda*ci.lambda;
812  }
813  else {
814  double lm = ci.lambda;
815  if ( lm < m_minLLongitudinal )
816  lm = m_minLLongitudinal;
817  myNorms[iMoment] += lm*lm*ci.energy;
818  }
819  break;
820  case FIRST_ENG_DENS:
821  if ( ci.volume > 0 ) {
822  myMoments[iMoment] += ci.energy*ci.energy/ci.volume;
823  myNorms[iMoment] += ci.energy;
824  }
825  break;
826  case SECOND_ENG_DENS:
827  if ( ci.volume > 0 ) {
828  myMoments[iMoment] += ci.energy*std::pow(ci.energy/ci.volume,2);
829  myNorms[iMoment] += ci.energy;
830  }
831  break;
832  case ENG_FRAC_EM:
833  if ( ci.sample == CaloCell_ID::EMB1
834  || ci.sample == CaloCell_ID::EMB2
835  || ci.sample == CaloCell_ID::EMB3
836  || ci.sample == CaloCell_ID::EME1
837  || ci.sample == CaloCell_ID::EME2
838  || ci.sample == CaloCell_ID::EME3
839  || ci.sample == CaloCell_ID::FCAL0 )
840  myMoments[iMoment] += ci.energy;
841  break;
842  case ENG_FRAC_MAX:
843  if ( (int)i == iCellMax )
844  myMoments[iMoment] = ci.energy;
845  break;
846  case PTD:
847  // do not convert to pT since clusters are small and
848  // there is virtually no difference and cosh just costs
849  // time ...
850  myMoments[iMoment] += ci.energy*ci.energy;
851  myNorms[iMoment] += ci.energy;
852  break;
853  default:
854  // nothing to be done for other moments
855  break;
856  }
857  }
858  } //end of loop over cell
859 
860 
861  // assign moments which don't need the loop over the cells
862  for (size_t iMoment = 0, size = m_validMoments.size();
863  iMoment != size;
864  ++ iMoment)
865  {
866  // now calculate the actual moments
867  switch (m_validMoments[iMoment]) {
868  case FIRST_ETA:
869  case FIRST_PHI:
870  case SECOND_R:
871  case SECOND_LAMBDA:
872  case ENG_FRAC_EM:
873  case ENG_FRAC_MAX:
874  myNorms[iMoment] = commonNorm;
875  break;
876  case DELTA_PHI:
877  myMoments[iMoment] = deltaPhi;
878  break;
879  case DELTA_THETA:
880  myMoments[iMoment] = deltaTheta;
881  break;
882  case DELTA_ALPHA:
883  myMoments[iMoment] = angle;
884  break;
885  case CENTER_X:
886  myMoments[iMoment] = showerCenter.x();
887  break;
888  case CENTER_Y:
889  myMoments[iMoment] = showerCenter.y();
890  break;
891  case CENTER_Z:
892  myMoments[iMoment] = showerCenter.z();
893  break;
894  case CENTER_MAG:
895  myMoments[iMoment] = showerCenter.mag();
896  break;
897  case CENTER_LAMBDA:
898  // calculate the longitudinal distance along the shower axis
899  // of the shower center from the calorimeter start
900 
901  // first need calo boundary at given eta phi try LAREM barrel
902  // first, then LAREM endcap OW, then LAREM endcap IW, then
903  // FCal
904  {
905  double r_calo(0),z_calo(0),lambda_c(0);
906  r_calo = m_caloDepthTool->get_entrance_radius(CaloCell_ID::EMB1,
907  showerCenter.eta(),
908  showerCenter.phi(),
909  caloDDMgr);
910  if ( r_calo == 0 ) {
911  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::EME1,
912  showerCenter.eta(),
913  showerCenter.phi(),
914  caloDDMgr);
915  if ( z_calo == 0 )
916  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::EME2,
917  showerCenter.eta(),
918  showerCenter.phi(),
919  caloDDMgr);
920  if ( z_calo == 0 )
921  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::FCAL0,
922  showerCenter.eta(),
923  showerCenter.phi(),
924  caloDDMgr);
925  if ( z_calo == 0 ) // for H6 TB without EMEC outer wheel
926  z_calo = m_caloDepthTool->get_entrance_z(CaloCell_ID::HEC0,
927  showerCenter.eta(),
928  showerCenter.phi(),
929  caloDDMgr);
930  if ( z_calo != 0 && showerAxis.z() != 0 ) {
931  lambda_c = std::abs((z_calo-showerCenter.z())/showerAxis.z());
932  }
933  }
934  else {
935  double r_s2 = showerAxis.x()*showerAxis.x()
936  +showerAxis.y()*showerAxis.y();
937  double r_cs = showerAxis.x()*showerCenter.x()
938  +showerAxis.y()*showerCenter.y();
939  double r_cr = showerCenter.x()*showerCenter.x()
940  +showerCenter.y()*showerCenter.y()-r_calo*r_calo;
941  if ( r_s2 > 0 ) {
942  double det = r_cs*r_cs/(r_s2*r_s2) - r_cr/r_s2;
943  if ( det > 0 ) {
944  det = sqrt(det);
945  double l1(-r_cs/r_s2);
946  double l2(l1);
947  l1 += det;
948  l2 -= det;
949  if ( std::abs(l1) < std::abs(l2) )
950  lambda_c = std::abs(l1);
951  else
952  lambda_c = std::abs(l2);
953  }
954  }
955  }
956  myMoments[iMoment] = lambda_c;
957  }
958  break;
959  case ENG_FRAC_CORE:
960  for(i=0;i<(int)CaloCell_ID::Unknown;i++)
961  myMoments[iMoment] += maxSampE[i];
962  myNorms[iMoment] = commonNorm;
963  break;
964  case ISOLATION:
965  {
966  // loop over empty and filled perimeter cells and
967  // get a weighted ratio by means of energy fraction per layer
968  for(unsigned int i=0; i != CaloSampling::Unknown; ++ i) {
970  if (theCluster->hasSampling(s)) {
971  const double eSample = theCluster->eSample(s);
972  if (eSample > 0) {
973  int nAll = nbEmpty[i]+nbNonEmpty[i];
974  if (nAll > 0) {
975  myMoments[iMoment] += (eSample*nbEmpty[i])/nAll;
976  myNorms[iMoment] += eSample;
977  }
978  }//end of eSample>0
979  }//end has sampling
980  }//end loop over samplings
981  }
982  break;
983  case ENG_BAD_CELLS:
984  myMoments[iMoment] = eBad;
985  break;
986  case N_BAD_CELLS:
987  myMoments[iMoment] = nbad;
988  break;
989  case N_BAD_CELLS_CORR:
990  myMoments[iMoment] = nbad_dac;
991  break;
992  case BAD_CELLS_CORR_E:
993  myMoments[iMoment] = ebad_dac;
994  break;
995  case BADLARQ_FRAC:
996  myMoments[iMoment] = eBadLArQ/(theCluster->e()!=0.?theCluster->e():1.);
997  break;
998  case ENG_POS:
999  myMoments[iMoment] = ePos;
1000  break;
1001  case SIGNIFICANCE:
1002  myMoments[iMoment] = (sumSig2>0?theCluster->e()/sqrt(sumSig2):0.);
1003  break;
1004  case CELL_SIGNIFICANCE:
1005  myMoments[iMoment] = maxAbsSig;
1006  break;
1007  case CELL_SIG_SAMPLING:
1008  myMoments[iMoment] = nSigSampl;
1009  break;
1010  case AVG_LAR_Q:
1011  myMoments[iMoment] = eLAr2Q/(eLAr2>0?eLAr2:1);
1012  break;
1013  case AVG_TILE_Q:
1014  myMoments[iMoment] = eTile2Q/(eTile2>0?eTile2:1);
1015  break;
1016  case ENG_BAD_HV_CELLS:
1017  myMoments[iMoment] = eBadLArHV;
1018  break;
1019  case N_BAD_HV_CELLS:
1020  myMoments[iMoment] = nBadLArHV;
1021  break;
1022  case PTD:
1023  myMoments[iMoment] = sqrt(myMoments[iMoment]);
1024  break;
1025  case MASS:
1026  myMoments[iMoment] = mass;
1027  break;
1028  default:
1029  // nothing to be done for other moments
1030  break;
1031  }
1032  }
1033  }
1034 
1035  // normalize moments and copy to Cluster Moment Store
1036  size_t size= m_validMoments.size();
1037  for (size_t iMoment = 0; iMoment != size; ++iMoment) {
1039  if ( myNorms[iMoment] != 0 )
1040  myMoments[iMoment] /= myNorms[iMoment];
1041  if ( moment == FIRST_PHI )
1042  myMoments[iMoment] = CaloPhiRange::fix(myMoments[iMoment]);
1043  theCluster->insertMoment(moment,myMoments[iMoment]);
1044  } // loop on moments for cluster
1045  } // check on requested moments
1046  // check on second moment of time if requested
1047  if ( m_secondTime ) { theCluster->insertMoment(SECOND_TIME,theCluster->secondTime()); }
1048  // check on number of cells per sampling moment if requested
1049  if ( m_nCellsPerSampling ) {
1050  for ( size_t isam(0); isam < nCellsSamp.size(); ++isam ) {
1051  theCluster->setNumberCellsInSampling((CaloCell_ID::CaloSample)isam,std::get<0>(nCellsSamp.at(isam)),false);
1052  if ( isam == (size_t)CaloCell_ID::EME2 && std::get<1>(nCellsSamp.at(isam)) > 0 ) {
1053  theCluster->setNumberCellsInSampling((CaloCell_ID::CaloSample)isam,std::get<1>(nCellsSamp.at(isam)),true);
1054  }
1055  } // loop on samplings
1056  nCellsSamp.clear();
1057  }
1058  } // loop on clusters
1059 
1060  return StatusCode::SUCCESS;
1061 }
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
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
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::cellinfo
cellinfo(const bool useGPUCriteria=false)
Definition: CaloClusterMomentsMaker.cxx:335
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:356
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
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:399
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
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
ReadCellNoiseFromCool.ncell
ncell
Definition: ReadCellNoiseFromCool.py:197
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
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
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
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:398
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