ATLAS Offline Software
Loading...
Searching...
No Matches
CaloClusterMomentsMaker Class Reference

Calculate moments for CaloCluster objects. More...

#include <CaloClusterMomentsMaker.h>

Inheritance diagram for CaloClusterMomentsMaker:
Collaboration diagram for CaloClusterMomentsMaker:

Public Member Functions

 CaloClusterMomentsMaker (const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode execute (const EventContext &ctx, xAOD::CaloClusterContainer *theClusColl) const override final
 Execute on an entire collection of clusters.
virtual StatusCode initialize () override
virtual StatusCode finalize () override
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysInitialize () override
 Perform system initialization for an algorithm.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const
 DeclareInterfaceID (CaloClusterCollectionProcessor, 1, 0)

Protected Member Functions

void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>

Private Attributes

std::vector< std::string > m_momentsNames
 vector holding the input list of names of moments to calculate.
std::vector< xAOD::CaloCluster::MomentTypem_validMoments
 set of moments which will be calculated.
const CaloCell_IDm_calo_id
double m_maxAxisAngle
 the maximal allowed deviation from the IP-to-ClusterCenter-axis.
double m_minRLateral
 the minimal \(r\) in the definition of the Lateral moment
double m_minLLongitudinal
 the minimal \(\lambda\) in the definition of the Longitudinal moment
double m_minBadLArQuality
 the minimal cell quality in the LAr for declaring a cell bad
bool m_calculateSignificance
 Set to true if significance moments are need.
bool m_calculateIsolation
 Set to true if cluster isolation is to be calculated.
bool m_calculateLArHVFraction
 Set to true to calculate E and N of cells affected by LAr HV corrections.
bool m_twoGaussianNoise
 if set to true use 2-gaussian noise description for TileCal
ToolHandle< CaloDepthToolm_caloDepthTool
SG::ReadCondHandleKey< CaloDetDescrManagerm_caloMgrKey
SG::ReadCondHandleKey< CaloNoisem_noiseCDOKey {this,"CaloNoiseKey","totalNoise","SG Key of CaloNoise data object"}
 Key of the CaloNoise Conditions data object.
ToolHandle< ILArHVFractionm_larHVFraction
std::string m_momentsNamesAOD
 Not used anymore (with xAOD), but required when configured from COOL.
bool m_absOpt
 if set to true use abs E value of cells to calculate cluster moments
bool m_secondTime = { false }
 Retrieve second moment of cell times and store as moment.
bool m_nCellsPerSampling = { false }
 store number of cells per sampling layer as moment
double m_etaInnerWheel = { 2.52 }
 Transition from outer to inner wheel in EME2.
Gaudi::Property< bool > m_useGPUCriteria {this, "UseGPUCriteria", false, "Adopt a set of criteria that is consistent with the GPU implementation."}
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default).
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default).
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared

Detailed Description

Calculate moments for CaloCluster objects.

Author
Sven Menke menke.nosp@m.@mpp.nosp@m.mu.mp.nosp@m.g.de
Peter Loch loch@.nosp@m.phys.nosp@m.ics.a.nosp@m.rizo.nosp@m.na.ed.nosp@m.u
Date
23-March-2021

This is a CaloClusterCollectionProcessor which can be plugged into a CaloClusterMaker for calculating moments for each CaloCluster. Typically a cluster moment of a certain degree \(n\) over a variable \(x\) defined for each CaloCell member of a CaloCluster is defined as:

\[ \langle x^n\rangle = \frac{1}{E_{\rm norm}} \times \!\!\!\sum\limits_{\{{\rm cell}|E_{\rm cell}>0\}}{\!\!\!E_{\rm cell}\, x^n},\]

with

\[ E_{\rm norm} = \!\!\!\sum\limits_{\{{\rm cell}|E_{\rm cell}>0\}}{\!\!\!E_{\rm cell}}. \]

Note that only cells with positive energy are used in this definition. Common variables to calculate first and second moments of are \(\phi\), \(\eta\), and radial and longitudinal distances from the shower axis and the shower center, respectively.

Since
23-March-2021: second moment of cell time distribution is calculated
Author
Sven Menke menke.nosp@m.@mpp.nosp@m.mu.mp.nosp@m.g.de
Date
28-February-2005

This is a CaloClusterCollectionProcessor which can be plugged into a CaloClusterMaker for calculating moments for each CaloCluster. Typically a cluster moment of a certain degree \(n\) over a variable \(x\) defined for each CaloCell member of a CaloCluster is defined as:

\[ \langle x^n\rangle = \frac{1}{E_{\rm norm}} \times \!\!\!\sum\limits_{\{{\rm cell}|E_{\rm cell}>0\}}{\!\!\!E_{\rm cell}\, x^n},\]

with

\[ E_{\rm norm} = \!\!\!\sum\limits_{\{{\rm cell}|E_{\rm cell}>0\}}{\!\!\!E_{\rm cell}}. \]

Note that only cells with positive energy are used in this definition. Common variables to calculate first and second moments of are \(\phi\), \(\eta\), and radial and longitudinal distances from the shower axis and the shower center, respectively.

Definition at line 49 of file CaloClusterMomentsMaker.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< AlgTool > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ CaloClusterMomentsMaker()

CaloClusterMomentsMaker::CaloClusterMomentsMaker ( const std::string & type,
const std::string & name,
const IInterface * parent )

Definition at line 142 of file CaloClusterMomentsMaker.cxx.

145 : AthAlgTool(type, name, parent),
146 m_calo_id(nullptr),
147 m_maxAxisAngle(20*deg),
148 m_minRLateral(4*cm),
150 m_minBadLArQuality(4000),
154 m_twoGaussianNoise(false),
155 m_caloDepthTool("CaloDepthTool",this),
156 m_larHVFraction("LArHVFraction",this),
157 m_absOpt(false)
158{
159 declareInterface<CaloClusterCollectionProcessor> (this);
160 // Name(s) of Moments to calculate
161 declareProperty("MomentsNames",m_momentsNames);
162
163 // Maximum allowed angle between shower axis and the vector pointing
164 // to the shower center from the IP in degrees. This property is needed
165 // to protect against cases where all significant cells are in one sampling
166 // and the shower axis can thus not be defined.
167 declareProperty("MaxAxisAngle",m_maxAxisAngle);
168 declareProperty("MinRLateral",m_minRLateral);
169 declareProperty("MinLLongitudinal",m_minLLongitudinal);
170 declareProperty("MinBadLArQuality",m_minBadLArQuality);
171 // Use 2-gaussian noise for Tile
172 declareProperty("TwoGaussianNoise",m_twoGaussianNoise);
173 declareProperty("LArHVFraction",m_larHVFraction,"Tool Handle for LArHVFraction");
174 // Not used anymore (with xAOD), but required when configured from COOL.
175 declareProperty("AODMomentsNames",m_momentsNamesAOD);
176 // Use weighting of neg. clusters option?
177 declareProperty("WeightingOfNegClusters", m_absOpt);
178 // Set eta boundary for transition from outer to inner wheel in EME2
179 declareProperty("EMECAbsEtaWheelTransition",m_etaInnerWheel);
180}
#define deg
AthAlgTool()
Default constructor:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
double m_maxAxisAngle
the maximal allowed deviation from the IP-to-ClusterCenter-axis.
bool m_calculateIsolation
Set to true if cluster isolation is to be calculated.
double m_minRLateral
the minimal in the definition of the Lateral moment
bool m_calculateSignificance
Set to true if significance moments are need.
bool m_calculateLArHVFraction
Set to true to calculate E and N of cells affected by LAr HV corrections.
ToolHandle< CaloDepthTool > m_caloDepthTool
std::string m_momentsNamesAOD
Not used anymore (with xAOD), but required when configured from COOL.
bool m_absOpt
if set to true use abs E value of cells to calculate cluster moments
double m_minLLongitudinal
the minimal in the definition of the Longitudinal moment
std::vector< std::string > m_momentsNames
vector holding the input list of names of moments to calculate.
double m_etaInnerWheel
Transition from outer to inner wheel in EME2.
double m_minBadLArQuality
the minimal cell quality in the LAr for declaring a cell bad
bool m_twoGaussianNoise
if set to true use 2-gaussian noise description for TileCal
ToolHandle< ILArHVFraction > m_larHVFraction

Member Function Documentation

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }

◆ DeclareInterfaceID()

CaloClusterCollectionProcessor::DeclareInterfaceID ( CaloClusterCollectionProcessor ,
1 ,
0  )
inherited

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ execute()

StatusCode CaloClusterMomentsMaker::execute ( const EventContext & ctx,
xAOD::CaloClusterContainer * collection ) const
finaloverridevirtual

Execute on an entire collection of clusters.

Parameters
collectionThe container of clusters. param ctx The event context.

Implements CaloClusterCollectionProcessor.

Definition at line 341 of file CaloClusterMomentsMaker.cxx.

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

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ finalize()

StatusCode CaloClusterMomentsMaker::finalize ( )
overridevirtual

Definition at line 314 of file CaloClusterMomentsMaker.cxx.

315{
316 return StatusCode::SUCCESS;
317}

◆ initialize()

StatusCode CaloClusterMomentsMaker::initialize ( )
overridevirtual

Definition at line 184 of file CaloClusterMomentsMaker.cxx.

185{
186 xAOD::CaloCluster dummyCluster;
187
188 // loop list of requested moments
189 std::string::size_type nstr(0); int nmom(0);
190 for (const auto& mom : m_momentsNames) {
191 ATH_MSG_DEBUG("Moment " << mom << " requested");
192 // check if moment is known (enumerator available)
193 auto fmap(momentNameToEnumMap.find(mom));
194 if (fmap != momentNameToEnumMap.end()) {
195 // valid moment found
196 nstr = std::max(nstr, mom.length());
197 ++nmom;
198 if (fmap->second == SECOND_TIME) {
199 // special flag for second moment of cell times - this moment is not
200 // calculated in this tool! Do not add to internal (!) valid moments
201 // list. Its value is available from xAOD::CaloCluster::secondTime()!
202 m_secondTime = true;
203
204 // Make sure the variable used for the moment is declared
205 // to the auxiliary variable registry. Otherwise, if we don't
206 // set the moment for the first event (perhaps because there
207 // are no clusters), then we can get warnings from AuxSelection.
208 (void)dummyCluster.getMomentValue (fmap->second);
209 } else if (fmap->second == NCELL_SAMPLING) {
210 // flag indicates if number of cells in a sampling should be counted.
211 // This is a vector of integers counts that is filled in this tool but
212 // does not need any post-processing (e.g. normalization). It is not
213 // added to the valid moments list for this reason.
214 ATH_MSG_DEBUG("moment " << fmap->first << " found");
215 m_nCellsPerSampling = true;
217
218 // Make sure the variable used for the moment is declared
219 // to the auxiliary variable registry.
220 (void)dummyCluster.retrieveMoment (fmap->second, cellsdum);
221 } else if (fmap->second == EM_PROBABILITY) {
223 << " not calculated in this tool - misconfiguration?");
224 } else {
225 // Make sure the variable used for the moment is declared
226 // to the auxiliary variable registry.
227 (void)dummyCluster.getMomentValue (fmap->second);
228
229 // all other valid moments
230 m_validMoments.push_back(fmap->second);
231 // flag some special requests
232 switch (fmap->second) {
233 case SIGNIFICANCE:
234 case CELL_SIGNIFICANCE:
236 break;
237 case ISOLATION:
239 break;
240 case ENG_BAD_HV_CELLS:
242 break;
243 default:
244 break;
245 } // set special processing flags
246 } // moment calculated with this tool
247 } else {
248 ATH_MSG_ERROR("Moment name " << mom << " not known; known moments are:");
249 char buffer[128];
250 std::string::size_type lstr(nstr);
251 // determine field size
252 for (const auto& fmom : momentNameToEnumMap) {
253 lstr = std::max(lstr, fmom.first.length());
254 }
255 // print available moments
256 for (const auto& fmom : momentNameToEnumMap) {
257 sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)lstr,
258 (int)lstr, fmom.first.c_str(), (int)fmom.second);
259 ATH_MSG_ERROR(buffer);
260 }
261 auto fmom(momentNameToEnumMap.find("SECOND_TIME"));
262 sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
263 (int)nstr, fmom->first.c_str(), (int)fmom->second);
264 ATH_MSG_ERROR(buffer);
265 fmom = momentNameToEnumMap.find("NCELL_SAMPLING");
266 sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
267 (int)nstr, fmom->first.c_str(), (int)fmom->second);
268 ATH_MSG_ERROR(buffer);
269 return StatusCode::FAILURE;
270 } // found unknown moment name
271 } // loop configured moment names
272
273 // sort and remove duplicates
275 m_validMoments.erase(
277 m_validMoments.end());
278
279 // print configured moments
280 ATH_MSG_INFO("Construct and save " << nmom << " cluster moments: ");
281 char buffer[128];
282 for (auto menum : m_validMoments) {
283 sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
284 (int)nstr, momentEnumToNameMap.at(menum).c_str(), (int)menum);
285 ATH_MSG_INFO(buffer);
286 }
287 if (m_secondTime) {
288 auto fmom(momentNameToEnumMap.find("SECOND_TIME"));
289 sprintf(buffer, "moment name: %-*.*s - enumerator: %i (save only)",
290 (int)nstr, (int)nstr, fmom->first.c_str(), (int)fmom->second);
291 ATH_MSG_INFO(buffer);
292 }
294 auto fmom(momentNameToEnumMap.find("NCELL_SAMPLING"));
295 sprintf(buffer, "moment name: %-*.*s - enumerator: %i", (int)nstr,
296 (int)nstr, fmom->first.c_str(), (int)fmom->second);
297 ATH_MSG_INFO(buffer);
298 }
299
300 // retrieve CaloCell ID server
301 CHECK(detStore()->retrieve(m_calo_id,"CaloCell_ID"));
302
303 // retrieve the calo depth tool
304 CHECK(m_caloDepthTool.retrieve());
305 ATH_CHECK(m_caloMgrKey.initialize());
306
307 // retrieve specific servers and tools for selected processes
309 if (m_calculateLArHVFraction) { ATH_CHECK(m_larHVFraction.retrieve()); } else { m_larHVFraction.disable(); }
310
311 return StatusCode::SUCCESS;
312}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define CHECK(...)
Evaluate an expression and check for errors.
const ServiceHandle< StoreGateSvc > & detStore() const
bool retrieveMoment(MomentType type, double &value) const
Retrieve individual moment.
double getMomentValue(MomentType type) const
Retrieve individual moment - no check for existance! Returns -999 on error.
std::vector< uint16_t > ncells_store_t
Store type for number-of-cells-in-sampling counter.
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ msg()

MsgStream & AthCommonMsg< AlgTool >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< AlgTool >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< AlgTool > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< AlgTool > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ sysInitialize()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysInitialize ( )
overridevirtualinherited

Perform system initialization for an algorithm.

We override this to declare all the elements of handle key arrays at the end of initialization. See comments on updateVHKA.

Reimplemented in asg::AsgMetadataTool, AthCheckedComponent< AthAlgTool >, AthCheckedComponent<::AthAlgTool >, and DerivationFramework::CfAthAlgTool.

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< AlgTool > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< AlgTool > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }
std::vector< SG::VarHandleKeyArray * > m_vhka

Member Data Documentation

◆ m_absOpt

bool CaloClusterMomentsMaker::m_absOpt
private

if set to true use abs E value of cells to calculate cluster moments

Definition at line 146 of file CaloClusterMomentsMaker.h.

◆ m_calculateIsolation

bool CaloClusterMomentsMaker::m_calculateIsolation
private

Set to true if cluster isolation is to be calculated.

Definition at line 115 of file CaloClusterMomentsMaker.h.

◆ m_calculateLArHVFraction

bool CaloClusterMomentsMaker::m_calculateLArHVFraction
private

Set to true to calculate E and N of cells affected by LAr HV corrections.

Definition at line 118 of file CaloClusterMomentsMaker.h.

◆ m_calculateSignificance

bool CaloClusterMomentsMaker::m_calculateSignificance
private

Set to true if significance moments are need.

Definition at line 112 of file CaloClusterMomentsMaker.h.

◆ m_calo_id

const CaloCell_ID* CaloClusterMomentsMaker::m_calo_id
private

Definition at line 79 of file CaloClusterMomentsMaker.h.

◆ m_caloDepthTool

ToolHandle<CaloDepthTool> CaloClusterMomentsMaker::m_caloDepthTool
private

Definition at line 125 of file CaloClusterMomentsMaker.h.

◆ m_caloMgrKey

SG::ReadCondHandleKey<CaloDetDescrManager> CaloClusterMomentsMaker::m_caloMgrKey
private
Initial value:
{
this,
"CaloDetDescrManager",
"CaloDetDescrManager"
}

Definition at line 127 of file CaloClusterMomentsMaker.h.

127 {
128 this,
129 "CaloDetDescrManager",
130 "CaloDetDescrManager"
131 };

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default).

Definition at line 393 of file AthCommonDataStore.h.

◆ m_etaInnerWheel

double CaloClusterMomentsMaker::m_etaInnerWheel = { 2.52 }
private

Transition from outer to inner wheel in EME2.

Definition at line 158 of file CaloClusterMomentsMaker.h.

158{ 2.52 };

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< AlgTool > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default).

Definition at line 390 of file AthCommonDataStore.h.

◆ m_larHVFraction

ToolHandle<ILArHVFraction> CaloClusterMomentsMaker::m_larHVFraction
private

Definition at line 138 of file CaloClusterMomentsMaker.h.

◆ m_maxAxisAngle

double CaloClusterMomentsMaker::m_maxAxisAngle
private

the maximal allowed deviation from the IP-to-ClusterCenter-axis.

Definition at line 83 of file CaloClusterMomentsMaker.h.

◆ m_minBadLArQuality

double CaloClusterMomentsMaker::m_minBadLArQuality
private

the minimal cell quality in the LAr for declaring a cell bad

This defines the minimal quality (large values mean worse shape) a cell needs to exceed in order to be considered as not compatible with a normal ionization signal.

Definition at line 109 of file CaloClusterMomentsMaker.h.

◆ m_minLLongitudinal

double CaloClusterMomentsMaker::m_minLLongitudinal
private

the minimal \(\lambda\) in the definition of the Longitudinal moment

This defines the minimal distance along the shower axis from the cluster center the two leading cells might have before this value is used instead of their real distance in the normalization of the LONGITUDINAL moment.

Definition at line 101 of file CaloClusterMomentsMaker.h.

◆ m_minRLateral

double CaloClusterMomentsMaker::m_minRLateral
private

the minimal \(r\) in the definition of the Lateral moment

This defines the minimal distance the two leading cells might have before this value is used instead of their real distance in the normalization of the LATERAL moment.

Definition at line 91 of file CaloClusterMomentsMaker.h.

◆ m_momentsNames

std::vector<std::string> CaloClusterMomentsMaker::m_momentsNames
private

vector holding the input list of names of moments to calculate.

This is the list of desired names of moments given in the jobOptions.

Definition at line 69 of file CaloClusterMomentsMaker.h.

◆ m_momentsNamesAOD

std::string CaloClusterMomentsMaker::m_momentsNamesAOD
private

Not used anymore (with xAOD), but required when configured from COOL.

Definition at line 141 of file CaloClusterMomentsMaker.h.

◆ m_nCellsPerSampling

bool CaloClusterMomentsMaker::m_nCellsPerSampling = { false }
private

store number of cells per sampling layer as moment

Definition at line 154 of file CaloClusterMomentsMaker.h.

154{ false };

◆ m_noiseCDOKey

SG::ReadCondHandleKey<CaloNoise> CaloClusterMomentsMaker::m_noiseCDOKey {this,"CaloNoiseKey","totalNoise","SG Key of CaloNoise data object"}
private

Key of the CaloNoise Conditions data object.

Typical values are '"electronicNoise', 'pileupNoise', or '"totalNoise' (default)

Definition at line 136 of file CaloClusterMomentsMaker.h.

136{this,"CaloNoiseKey","totalNoise","SG Key of CaloNoise data object"};

◆ m_secondTime

bool CaloClusterMomentsMaker::m_secondTime = { false }
private

Retrieve second moment of cell times and store as moment.

Definition at line 150 of file CaloClusterMomentsMaker.h.

150{ false };

◆ m_twoGaussianNoise

bool CaloClusterMomentsMaker::m_twoGaussianNoise
private

if set to true use 2-gaussian noise description for TileCal

Definition at line 123 of file CaloClusterMomentsMaker.h.

◆ m_useGPUCriteria

Gaudi::Property<bool> CaloClusterMomentsMaker::m_useGPUCriteria {this, "UseGPUCriteria", false, "Adopt a set of criteria that is consistent with the GPU implementation."}
private

Definition at line 161 of file CaloClusterMomentsMaker.h.

161{this, "UseGPUCriteria", false, "Adopt a set of criteria that is consistent with the GPU implementation."};

◆ m_validMoments

std::vector<xAOD::CaloCluster::MomentType> CaloClusterMomentsMaker::m_validMoments
private

set of moments which will be calculated.

This set will hold each valid enum indexed if its name was found on the input list (m_momentsNames) and in the list of valid moment names (m_validNames).

Definition at line 77 of file CaloClusterMomentsMaker.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< AlgTool > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< AlgTool > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files: