![Logo](../../ATLAS-Logo-Square-Blue-RGB.png) |
ATLAS Offline Software
|
Go to the documentation of this file.
18 #include "CaloEvent/CaloClusterContainer.h"
19 #include "CaloEvent/CaloCluster.h"
29 #include "CLHEP/Units/SystemOfUnits.h"
31 #include <Eigen/Dense>
54 const MomentName moment_names[] = {
93 const MomentName*
const moment_names_end =
94 moment_names +
sizeof(moment_names)/
sizeof(moment_names[0]);
97 bool operator< (
const std::string&
v,
const MomentName&
m)
99 return strcmp (
v.c_str(),
m.name) < 0;
102 bool operator< (
const MomentName&
m,
const std::string&
v)
104 return strcmp (
m.name,
v.c_str()) < 0;
114 const std::string&
name,
118 m_maxAxisAngle(20*
deg),
120 m_minLLongitudinal(10*
cm),
121 m_minBadLArQuality(4000),
122 m_calculateSignificance(false),
123 m_calculateIsolation(false),
124 m_calculateLArHVFraction(false),
125 m_twoGaussianNoise(false),
126 m_caloDepthTool(
"CaloDepthTool",this),
127 m_larHVFraction(
"LArHVFraction",this),
174 const MomentName*
it =
175 std::lower_bound (moment_names, moment_names_end,
name);
179 for(
const auto& testName: moment_names){
180 if(
name == testName.name)
it = &testName;
182 if (
it != moment_names_end) {
199 msg(MSG::ERROR) <<
"Moment " <<
name
200 <<
" is not a valid Moment name and will be ignored! "
201 <<
"Valid names are:";
203 for (
const MomentName&
m : moment_names)
204 msg() << ((
count++)==0?
" ":
", ") <<
m.name;
252 return StatusCode::SUCCESS;
288 typedef std::pair<clusterIdx_t, clusterIdx_t> clusterPair_t;
289 std::vector<clusterPair_t> clusterIdx;
311 if (theClusColl->
size() >= noCluster) {
312 msg(MSG::ERROR) <<
"Too many clusters" <<
endmsg;
313 return StatusCode::FAILURE;
318 clusterPair_t(noCluster, noCluster));
325 for(; cellIter != cellIterEnd; cellIter++ ){
332 if(hashid >= (signalCells)->
size())
continue;
333 myCell = (*signalCells).findCell(hashid);
334 if(!myCell)
continue;
339 if ( clusterIdx[(
unsigned int)myHashId].
first != noCluster) {
343 clusterIdx[(
unsigned int)myHashId].
first = iCluster;
346 clusterIdx[(
unsigned int)myHashId].
first = iCluster;
357 std::vector<CaloClusterMomentsMaker_DigiHSTruth_detail::cellinfo> cellinfo;
361 std::vector<IdentifierHash> theNeighbors;
366 for( ;clusIter!=clusIterEnd;++clusIter,++iClus) {
369 double w(0),xc(0),yc(0),zc(0);
370 double eBad(0),ebad_dac(0),ePos(0),eBadLArQ(0),sumSig2(0),maxAbsSig(0);
371 double eLAr2(0),eLAr2Q(0);
372 double eTile2(0),eTile2Q(0);
374 int nbad(0),nbad_dac(0),nBadLArHV(0);
375 unsigned int ncell(0),
i,nSigSampl(0);
376 unsigned int theNumOfCells = theCluster->
size();
377 double theClusterEnergy = 0;
378 double theClusterAbsEnergy = 0;
379 double theClusterEta = 0;
380 double theClusterPhi = 0;
384 int iCellScndMax(-1);
386 if (cellinfo.capacity() == 0)
387 cellinfo.reserve (theNumOfCells*2);
388 cellinfo.resize (theNumOfCells);
390 double phi0 = theCluster->
phi();;
395 std::fill (myMoments.begin(), myMoments.end(), 0);
396 std::fill (myNorms.begin(), myNorms.end(), 0);
405 for(; cellIter != cellIterEnd; cellIter++ ){
407 const CaloCell* pCell = (*cellIter);
412 if(hashid >= (signalCells)->
size())
continue;
413 pCell = (*signalCells).findCell(hashid);
418 double ene = pCell->
e();
423 double cellPhi = myCDDE->
phi();
426 theClusterEnergy +=
weight * ene;
427 theClusterAbsEnergy +=
weight*std::abs(ene);
428 theClusterEta +=
weight*std::abs(ene)*pCell->
eta();
429 theClusterPhi +=
weight*std::abs(ene)* thePhi;
441 && !((pCell->
provenance() & 0x0800) == 0x0800)) {
453 if ( ((tq1&0xFF) != 0xFF) && ((tq2&0xFF) != 0xFF) ) {
466 noise->getEffectiveSigma(pCell->
ID(),pCell->
gain(),pCell->
energy()) : \
471 if ( std::abs(Sig) > std::abs(maxAbsSig) ) {
481 if ( clusterIdx[myHashId].
first == iClus ) {
482 theNeighbors.clear();
484 for (
const auto& nhash: theNeighbors) {
485 clusterPair_t&
idx = clusterIdx[nhash];
488 if (
idx.second == iClus )
continue;
491 if (
idx.first == noCluster ) {
493 }
else if (
idx.first != iClus ) {
501 if ( myCDDE && ene > 0. &&
weight > 0) {
515 if (iCellMax < 0 || ci.energy > cellinfo[iCellMax].
energy ) {
516 iCellScndMax = iCellMax;
519 else if (iCellScndMax < 0 ||
520 ci.
energy > cellinfo[iCellScndMax].energy )
522 iCellScndMax =
ncell;
562 C(0,0) +=
e2*(ci.
x-xc)*(ci.
x-xc);
563 C(1,0) +=
e2*(ci.
x-xc)*(ci.
y-yc);
564 C(2,0) +=
e2*(ci.
x-xc)*(ci.
z-zc);
566 C(1,1) +=
e2*(ci.
y-yc)*(ci.
y-yc);
567 C(2,1) +=
e2*(ci.
y-yc)*(ci.
z-zc);
569 C(2,2) +=
e2*(ci.
z-zc)*(ci.
z-zc);
576 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> eigensolver(
C);
577 if (eigensolver.info() != Eigen::Success) {
578 msg(MSG::WARNING) <<
"Failed to compute Eigenvalues -> Can't determine shower axis" <<
endmsg;
585 const Eigen::Vector3d&
S=eigensolver.eigenvalues();
586 const Eigen::Matrix3d& U=eigensolver.eigenvectors();
588 const double epsilon = 1.E-6;
590 if ( std::abs(
S[0]) >= epsilon && std::abs(
S[1]) >= epsilon && std::abs(
S[2]) >= epsilon ) {
600 double tmpAngle=
Amg::angle(tmpAxis,showerAxis);
602 if ( tmpAngle > 90*
deg ) {
603 tmpAngle = 180*
deg - tmpAngle;
607 if ( iEigen == -1 || tmpAngle <
angle ) {
619 deltaTheta = showerAxis.theta() - prAxis.theta();
628 << prAxis[
Amg::y] <<
", " << prAxis[
Amg::z] <<
") deviates more than "
630 <<
" deg from IP-to-ClusterCenter-axis (" << showerAxis[
Amg::x] <<
", "
631 << showerAxis[
Amg::y] <<
", " << showerAxis[
Amg::z] <<
")");
637 << showerAxis.y() <<
", " << showerAxis.z() <<
")");
643 for (
auto& ci : cellinfo) {
646 ci.r = ((currentCell-showerCenter).cross(showerAxis)).
mag();
648 ci.lambda = (currentCell-showerCenter).
dot(showerAxis);
654 double commonNorm = 0;
655 double phi0 =
ncell > 0 ? cellinfo[0].phi : 0;
676 myMoments[iMoment] += ci.
energy*ci.
r*ci.
r;
682 if ( (
int)
i != iCellMax && (
int)
i != iCellScndMax ) {
683 myMoments[iMoment] += ci.
energy*ci.
r*ci.
r;
684 myNorms[iMoment] += ci.
energy*ci.
r*ci.
r;
690 myNorms[iMoment] += rm*rm*ci.
energy;
694 if ( (
int)
i != iCellMax && (
int)
i != iCellScndMax ) {
702 myNorms[iMoment] += lm*lm*ci.
energy;
708 myNorms[iMoment] += ci.
energy;
714 myNorms[iMoment] += ci.
energy;
725 myMoments[iMoment] += ci.
energy;
728 if ( (
int)
i == iCellMax )
729 myMoments[iMoment] = ci.
energy;
739 eBadLArHV= hvFrac.first;
740 nBadLArHV=hvFrac.second;
756 myNorms[iMoment] = commonNorm;
762 myMoments[iMoment] = deltaTheta;
765 myMoments[iMoment] =
angle;
768 myMoments[iMoment] = showerCenter.x();
771 myMoments[iMoment] = showerCenter.y();
774 myMoments[iMoment] = showerCenter.z();
777 myMoments[iMoment] = showerCenter.mag();
787 double r_calo(0),z_calo(0),lambda_c(0);
812 if ( z_calo != 0 && showerAxis.z() != 0 ) {
813 lambda_c = std::abs((z_calo-showerCenter.z())/showerAxis.z());
817 double r_s2 = showerAxis.x()*showerAxis.x()
818 +showerAxis.y()*showerAxis.y();
819 double r_cs = showerAxis.x()*showerCenter.x()
820 +showerAxis.y()*showerCenter.y();
821 double r_cr = showerCenter.x()*showerCenter.x()
822 +showerCenter.y()*showerCenter.y()-r_calo*r_calo;
824 double det = r_cs*r_cs/(r_s2*r_s2) - r_cr/r_s2;
827 double l1(-r_cs/r_s2);
831 if ( std::abs(
l1) < std::abs(
l2) )
832 lambda_c = std::abs(
l1);
834 lambda_c = std::abs(
l2);
838 myMoments[iMoment] = lambda_c;
843 myMoments[iMoment] += maxSampE[
i];
844 myNorms[iMoment] = commonNorm;
853 const double eSample = theCluster->
eSample(
s);
855 int nAll = nbEmpty[
i]+nbNonEmpty[
i];
857 myMoments[iMoment] += (eSample*nbEmpty[
i])/nAll;
858 myNorms[iMoment] += eSample;
866 myMoments[iMoment] = eBad;
869 myMoments[iMoment] = nbad;
872 myMoments[iMoment] = nbad_dac;
875 myMoments[iMoment] = ebad_dac;
878 myMoments[iMoment] = eBadLArQ/(theCluster->
e()!=0.?theCluster->
e():1.);
881 myMoments[iMoment] = ePos;
884 myMoments[iMoment] = (sumSig2>0?theCluster->
e()/sqrt(sumSig2):0.);
887 myMoments[iMoment] = maxAbsSig;
890 myMoments[iMoment] = nSigSampl;
893 myMoments[iMoment] = eLAr2Q/(eLAr2>0?eLAr2:1);
896 myMoments[iMoment] = eTile2Q/(eTile2>0?eTile2:1);
899 myMoments[iMoment] = eBadLArHV;
902 myMoments[iMoment] = nBadLArHV;
905 myMoments[iMoment] = theClusterEnergy;
908 if(theClusterAbsEnergy > 0)
909 myMoments[iMoment] = theClusterEta / theClusterAbsEnergy;
911 myMoments[iMoment] = 0;
915 if(theClusterAbsEnergy > 0)
918 myMoments[iMoment] = 0;
930 for (
size_t iMoment = 0; iMoment !=
size; ++iMoment) {
932 if ( myNorms[iMoment] != 0 )
933 myMoments[iMoment] /= myNorms[iMoment];
942 return StatusCode::SUCCESS;
947 return StatusCode::SUCCESS;
def retrieve(aClass, aKey=None)
SG::ReadCondHandleKey< CaloNoise > m_noiseCDOKey
Key of the CaloNoise Conditions data object.
virtual double phi() const
The azimuthal angle ( ) of the particle.
bool operator<(const DataVector< T > &a, const DataVector< T > &b)
Vector ordering relation.
@ FIRST_ETA_DigiHSTruth
First Moment in .
const_cell_iterator cell_begin() const
Iterator of the underlying CaloClusterCellLink (const version)
@ LONGITUDINAL_DigiHSTruth
Normalized longitudinal moment.
IdentifierHash calo_cell_hash(const Identifier cellId) const
create hash id from 'global' cell id
@ SECOND_LAMBDA_DigiHSTruth
Second Moment in .
void setMag(Amg::Vector3D &v, double mag)
scales the vector length without changing the angles
CaloSampling::CaloSample CaloSample
double angle(const Amg::Vector3D &v1, const Amg::Vector3D &v2)
calculates the opening angle between two vectors
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
setSAddress setEtaMS setDirPhiMS setDirZMS setBarrelRadius setEndcapAlpha setEndcapRadius setInterceptInner setEtaMap setEtaBin setIsTgcFailure setDeltaPt deltaPhi
std::vector< std::string > m_momentsNames
vector holding the input list of names of moments to calculate.
This class groups all DetDescr information related to a CaloCell. Provides a generic interface for al...
double proxim(double b, double a)
@ BADLARQ_FRAC_DigiHSTruth
weight_t weight() const
Accessor for weight associated to this cell.
bool m_twoGaussianNoise
if set to true use 2-gaussian noise description for TileCal
void insertMoment(MomentType type, double value)
virtual double e() const override final
get energy (data member) (synonym to method energy()
bool m_calculateIsolation
Set to true if cluster isolation is to be calculated.
@ CENTER_Y_DigiHSTruth
Cluster Centroid ( )
int calo_sample(const Identifier id) const
returns an int taken from Sampling enum and describing the subCalo to which the Id belongs.
uint16_t provenance() const
get provenance (data member)
@ LATERAL_DigiHSTruth
Normalized lateral moment.
double m_maxAxisAngle
the maximal allowed deviation from the IP-to-ClusterCenter-axis.
@ CENTER_Z_DigiHSTruth
Cluster Centroid ( )
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
double energy() const
get energy (data member)
MomentType
Enums to identify different moments.
STL-style allocator wrapper for ArenaPoolAllocator.
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloClusterContainer *theClusColl) const override final
Execute on an entire collection of clusters.
Description of a calorimeter cluster.
@ ENG_POS_DigiHSTruth
Total positive Energy of this cluster.
IdentifierHash calo_hash() const
cell calo hash
@ SIGNIFICANCE_DigiHSTruth
Cluster significance.
@ SECOND_ENG_DENS_DigiHSTruth
Second Moment in E/V.
(Non-const) Iterator class for DataVector/DataList.
std::vector< xAOD::CaloCluster::MomentType > m_validMoments
set of moments which will be calculated.
@ ETA_DigiHSTruth
Eta moment that I am trying to include.
virtual StatusCode initialize() override
@ CENTER_LAMBDA_DigiHSTruth
Shower depth at Cluster Centroid.
@ CELL_SIG_SAMPLING_DigiHSTruth
::StatusCode StatusCode
StatusCode definition for legacy code.
@ FIRST_ENG_DENS_DigiHSTruth
First Moment in E/V.
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
bool m_calculateLArHVFraction
Set to true to calculate E and N of cells affected by LAr HV corrections.
virtual bool badcell() const
check is cell is dead
size_t size() const
size method (forwarded from CaloClusterCellLink obj)
CaloPhiRange class declaration.
const CaloCell_ID * m_calo_id
static double fix(double phi)
def dot(G, fn, nodesToHighlight=[])
const CaloClusterCellLink * getCellLinks() const
Get a pointer to the CaloClusterCellLink object (const version)
uint16_t quality() const
get quality (data member)
bool is_valid() const
Check if id is in a valid state.
@ ENG_BAD_HV_CELLS_DigiHSTruth
void prefetchNext(Iter iter, Iter endIter)
Prefetch next object in sequence.
bool is_tile() const
cell belongs to Tile
SG::ReadHandleKey< CaloCellContainer > m_signalCellKey
@ N_BAD_CELLS_CORR_DigiHSTruth
float volume() const
cell volume
@ N_BAD_CELLS_DigiHSTruth
number of bad cells
@ N_BAD_HV_CELLS_DigiHSTruth
number of cells with bad HV
CaloGain::CaloGain gain() const
get gain (data member )
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
StatusCode initialize(bool used=true)
@ FIRST_PHI_DigiHSTruth
First Moment in .
@ PHI_DigiHSTruth
phi moment I would like to have
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
@ ENERGY_DigiHSTruth
First Moment in .
double m_minRLateral
the minimal in the definition of the Lateral moment
@ ENG_BAD_CELLS_DigiHSTruth
SG::ReadCondHandleKey< CaloDetDescrManager > m_caloMgrKey
Eigen::Matrix< double, 3, 1 > Vector3D
bool m_absOpt
if set to true use abs E value of cells to calculate
@ SECOND_R_DigiHSTruth
Second Moment in .
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
@ ENG_FRAC_EM_DigiHSTruth
Energy fraction in EM calorimeters.
std::string m_momentsNamesAOD
Not used anymore (with xAOD), but required when configured from COOL.
float eSample(const CaloSample sampling) const
ToolHandle< CaloDepthTool > m_caloDepthTool
This class provides the client interface for accessing the detector description information common to...
Data object for each calorimeter readout cell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
@ DELTA_ALPHA_DigiHSTruth
CaloClusterMomentsMaker_DigiHSTruth(const std::string &type, const std::string &name, const IInterface *parent)
const_cell_iterator cell_end() const
@ DELTA_THETA_DigiHSTruth
bool m_calculateSignificance
Set to true if significance moments are need.
@ BAD_CELLS_CORR_E_DigiHSTruth
float eta() const
cell eta
@ ENG_FRAC_MAX_DigiHSTruth
Energy fraction of hottest cell.
float phi() const
cell phi
bool hasSampling(const CaloSample s) const
Checks if certain smapling contributes to cluster.
double m_minBadLArQuality
the minimal cell quality in the LAr for declaring a cell bad
size_type size() const noexcept
Returns the number of elements in the collection.
virtual StatusCode finalize() override
void nextDDE(Iter iter, Iter endIter)
Prefetch next CaloDDE.
@ ENG_FRAC_CORE_DigiHSTruth
CaloCell_ID::CaloSample sample
Scalar mag() const
mag method
virtual double e() const
The total energy of the particle.
ToolHandle< ILArHVFraction > m_larHVFraction
@ CENTER_X_DigiHSTruth
Cluster Centroid ( )
virtual double eta() const override final
get eta (through CaloDetDescrElement)
Functions to prefetch blocks of memory.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
static double diff(double phi1, double phi2)
simple phi1 - phi2 calculation, but result is fixed to respect range.
double m_minLLongitudinal
the minimal in the definition of the Longitudinal moment
@ CELL_SIGNIFICANCE_DigiHSTruth
size_type calo_cell_hash_max(void) const
cell 'global' hash table max size