ATLAS Offline Software
Loading...
Searching...
No Matches
CaloClusterLocalCalib.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6#include "GaudiKernel/MsgStream.h"
7#include "GaudiKernel/TypeNameString.h"
8
9//Needed for abs option
13
15
19 const std::string& name,
20 const IInterface* parent)
21 :CaloClusterProcessor(type, name, parent),
23 m_calibTools(this),
24 m_absOpt(false)
25{
26 m_recoStatus.resize(0);
27 declareProperty ("ClusterClassificationTool",m_classificationTool);
28 declareProperty ("LocalCalibTools",m_calibTools) ;
29 declareProperty ("ClusterRecoStatus",m_recoStatus) ;
30 //Use weighting of negative clusters?
31 declareProperty ("WeightingOfNegClusters",m_absOpt) ;
32}
33
34
36
37 if (m_classificationTool.size()>1) {
38 msg(MSG::ERROR) << "More than one classification tool specified!" << endmsg;
39 return StatusCode::FAILURE;
40 }
41 //Retrieve classification tool (if necessary)
42 if (!m_classificationTool.empty()) {
44 msg(MSG::INFO) << "Found classification tool " << m_classificationTool[0] << endmsg;
45 }
46
47 //Retrieve calibration tools
48 ATH_CHECK(m_calibTools.retrieve());
49 msg(MSG::INFO) <<"Loaded "<< m_calibTools.size() <<" hadronic calibration tools"<<endmsg;
50
51 // check that at least one reco status is defined
52 if ( m_recoStatus.empty() ) {
53 msg(MSG::ERROR) << "Please specify at least one valid reco status with ClusterRecoStatus = [...] for this calib tool " << endmsg;
54 return StatusCode::FAILURE;
55 }
56 return StatusCode::SUCCESS;
57}
58
59StatusCode CaloClusterLocalCalib::execute(const EventContext& ctx,
60 CaloCluster* theCluster) const
61{
62 CaloRecoStatus& recoStatus=theCluster->recoStatus();
63 // call classification tool
64 if (!m_classificationTool.empty()) {
65 recoStatus=m_classificationTool[0]->classify(theCluster);
66 }
67 // check desired reco status
68 bool isSelected (false);
69 for (unsigned int i=0;!isSelected && i<m_recoStatus.size();i++ )
70 isSelected = recoStatus.checkStatus(CaloRecoStatus::StatusIndicator(m_recoStatus[i]));
71 if ( isSelected ) {
72 if( m_absOpt ){
73
74
75 //double dm_weight(0.);
76 //double had_weight(0.);
77 double centLambd(0.);
78 double engdens(0.);
79 double emprobability(0.);
80 double isolation(0.);
81 // Store moments and energy of the old cluster
82 //theCluster->retrieveMoment(xAOD::CaloCluster::DM_WEIGHT, dm_weight);
83 //theCluster->retrieveMoment(xAOD::CaloCluster::HAD_WEIGHT,had_weight);
84 if (!theCluster->retrieveMoment(xAOD::CaloCluster::CENTER_LAMBDA,centLambd))
85 centLambd = 0;
86 if (!theCluster->retrieveMoment(xAOD::CaloCluster::FIRST_ENG_DENS,engdens))
87 engdens = 0;
88 if (!theCluster->retrieveMoment(xAOD::CaloCluster::EM_PROBABILITY,emprobability))
89 emprobability = 0;
90 if (!theCluster->retrieveMoment(xAOD::CaloCluster::ISOLATION,isolation))
91 isolation = 0;
92
93 double oldEnergy = theCluster->e();
94
95 const CaloCell_ID* calo_id = nullptr;
96 ATH_CHECK(detStore()->retrieve(calo_id,"CaloCell_ID"));
97
98// Make new Cluster and CellColl
99 //std::unique_ptr<CaloCellContainer> myCellColl=std::make_unique<CaloCellContainer>(SG::OWN_ELEMENTS);
101 std::unique_ptr<xAOD::CaloCluster> myCluster = CaloClusterStoreHelper::makeCluster(&myCellColl);
102 int cellIndex = 0;
103// Iterate over cells of old cluster and replicate them with energy weighted by -1 if negative and add it to the new cluster
104 xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
105 for(;cellIter!=theCluster->cell_end();cellIter++) {
106 const CaloCell* pCell = *cellIter;
107 double CellEnergy = pCell->e();
108 //Identifier myId = pCell->ID();
109 //IdentifierHash myHashId = calo_id->calo_cell_hash(myId);
110 if( CellEnergy < 0. ) CellEnergy = -1 * pCell->e();
111 myCellColl.push_back(new CaloCell(pCell->caloDDE(), pCell->ID(), CellEnergy, pCell->time(), pCell->quality(), pCell->provenance(), pCell->gain() ));
112 double cellWeight = cellIter.weight();
113 myCluster->addCell(cellIndex,cellWeight);
114 cellIndex++;
115 }
116
117 CaloClusterKineHelper::calculateKine(myCluster.get(),false,false);
118 myCluster->setRawE(myCluster->e());
119
120// Set sample energy of the new cluster to the one of the old cluster, other wise it is zero, important for dm correction
121 for(unsigned int i=0; i != CaloSampling::Unknown; ++ i) {
123 if (myCluster->hasSampling(s)) myCluster->setEnergy((CaloSampling::CaloSample)i, theCluster->eSample((CaloSampling::CaloSample)i));
124 }//end loop over samplings
125
126 CaloClusterKineHelper::calculateKine(myCluster.get(),true,false);
127// Give the new cluster the same moments as the old one
128 myCluster->insertMoment(xAOD::CaloCluster::CENTER_LAMBDA,centLambd);
129 myCluster->insertMoment(xAOD::CaloCluster::FIRST_ENG_DENS,engdens);
130 myCluster->insertMoment(xAOD::CaloCluster::EM_PROBABILITY,emprobability);
131 myCluster->insertMoment(xAOD::CaloCluster::ISOLATION,isolation);
132
133// Weight the new cluster
134 for (const ToolHandle<IClusterCellWeightTool>& tool : m_calibTools) {
135 if (tool->weight(myCluster.get(),ctx).isFailure())
136 msg(MSG::ERROR) << " failed to weight cluster " << endmsg;
137 }
138
139// Iterate over new, calibrated cluster and write out the weights of every cell into a map
140 std::map<IdentifierHash,double> weightMap;
141 xAOD::CaloCluster::cell_iterator mycellIter = myCluster->cell_begin();
142 xAOD::CaloCluster::cell_iterator mycellIterEnd = myCluster->cell_end();
143 for(;mycellIter!=mycellIterEnd;mycellIter++) {
144 const CaloCell* pCell = *mycellIter;
145 double cellWeight = mycellIter.weight();
146 Identifier myId = pCell->ID();
147 IdentifierHash myHashId = calo_id->calo_cell_hash(myId);
148 weightMap[myHashId] = cellWeight;
149 }
150
151
152// Apply cellweight on the corresponding cell of the original cluster
153
154 cellIter = theCluster->cell_begin();
155 for(;cellIter!=theCluster->cell_end();cellIter++) {
156 const CaloCell* pCell = *cellIter;
157 IdentifierHash myHashId = calo_id->calo_cell_hash(pCell->ID());
158 double weight = weightMap[myHashId];
159 theCluster->reweightCell(cellIter,weight);
160 }
161
162// Update kinematics of new cluster
163 CaloClusterKineHelper::calculateKine(theCluster,true,false);
164
165
166 //Manually insert weight moments to the original cluster, in the OOC case this is a multiplicative weight from LCOut and LCOutPi0
167 double newWeightMoment = theCluster->e()/oldEnergy;
168 if(m_calibTools[0].typeAndName() == "CaloLCWeightTool/LCWeight") theCluster->insertMoment(xAOD::CaloCluster::HAD_WEIGHT,newWeightMoment);
169 if(m_calibTools[0].typeAndName() == "CaloLCDeadMaterialTool/LCDeadMaterial") theCluster->insertMoment(xAOD::CaloCluster::DM_WEIGHT, newWeightMoment);
170 if(m_calibTools[0].typeAndName() == "CaloLCOutOfClusterTool/LCOut") theCluster->insertMoment(xAOD::CaloCluster::OOC_WEIGHT,newWeightMoment);
171 if(m_calibTools[0].typeAndName() == "CaloLCOutOfClusterTool/LCOutPi0")
172 {
173 double ooc_weight;
174 if (theCluster->retrieveMoment(xAOD::CaloCluster::OOC_WEIGHT,ooc_weight)) {
175 newWeightMoment *= ooc_weight;
176 theCluster->insertMoment(xAOD::CaloCluster::OOC_WEIGHT,newWeightMoment);
177 }
178 }
179 }
180// else, what as was always done
181 else{
182
183 for (const ToolHandle<IClusterCellWeightTool>& tool : m_calibTools) {
184 if (tool->weight(theCluster,ctx).isFailure())
185 msg(MSG::ERROR) << " failed to weight cluster " << endmsg;
186 }
187
188 }
189 //report <<MSG::DEBUG<<"new cluster energy="<<theCluster->e()<<endmsg;
190 }//end of "has correct reco status" if statement
191
192 // PL add calibration method bits to reco status
194
195 return StatusCode::SUCCESS;
196}
197
198
199
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
Definition of CaloDetDescrManager.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
const ServiceHandle< StoreGateSvc > & detStore() const
Container class for CaloCell.
void push_back(CaloCell *)
reimplementation of const push_back
IdentifierHash calo_cell_hash(const Identifier cellId) const
create hash id from 'global' cell id
Helper class for offline cell identifiers.
Definition CaloCell_ID.h:34
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
float time() const
get time (data member)
Definition CaloCell.h:368
virtual double e() const override final
get energy (data member) (synonym to method energy()
Definition CaloCell.h:333
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
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
static void calculateKine(xAOD::CaloCluster *clu, const bool useweight=true, const bool updateLayers=true, const bool useGPUCriteria=false)
Helper class to calculate cluster kinematics based on cells.
bool m_absOpt
if set to true, negative clusters are weighted as well
ToolHandleArray< IClusterCellWeightTool > m_calibTools
property: Array of IClusterCellWeightTool
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloCluster *theCluster) const override
Execute on a single cluster.
std::vector< int > m_recoStatus
property: vector of valid Reco Statuses for the clusters in order to be calibrated
CaloClusterLocalCalib(const std::string &type, const std::string &name, const IInterface *parent)
Standard AlgTool constructor.
ToolHandleArray< IClusterClassificationTool > m_classificationTool
property: Classification tools
virtual StatusCode initialize() override
Tool initialization: load calibration tools specified by jobOptions.
CaloClusterProcessor(const std::string &type, const std::string &name, const IInterface *parent)
Constructor.
static std::unique_ptr< xAOD::CaloCluster > makeCluster(const CaloCellContainer *cellCont)
Creates a valid CaloCluster with a private Aux-Store and CellLink container.
Principal data class for CaloCell clusters.
double eSample(sampling_type sampling) const
Retrieve energy in a given sampling.
bool retrieveMoment(const moment_type &momType, moment_value &momValue, bool useLink=true) const
Retrieve individual moment.
virtual double e() const
Retrieve energy independent of signal state.
void insertMoment(const moment_type &momType, const moment_value &momValue, bool useLink=true)
Set individual moment.
cell_iterator cell_end() const
Retrieve a STL-type end() iterator for the cell store.
void reweightCell(const CaloCell *pCell, double weight)
Reweight a cell with kinematic update.
cell_iterator cell_begin() const
Retrieve a STL-type begin() iterator for the cell store.
reconstruction status indicator
StatusIndicator
reconstruction status word
virtual bool checkStatus(const StatusIndicator &statusIndicator) const
Check status.
virtual void setStatus(const StatusIndicator &statusIndicator)
Set status.
This is a "hash" representation of an Identifier.
CaloClusterCellLink::iterator cell_iterator
Iterator of the underlying CaloClusterCellLink (non-const version)
@ OOC_WEIGHT
Out-of-cluster weight (E_ooc/E_w)
@ EM_PROBABILITY
Classification probability to be em-like.
@ DM_WEIGHT
Dead-material weight (E_dm/E_ooc)
@ FIRST_ENG_DENS
First Moment in E/V.
@ HAD_WEIGHT
Hadronic weight (E_w/E_em)
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
@ ISOLATION
Energy weighted fraction of non-clustered perimeter cells.
CaloSampling::CaloSample CaloSample
@ OWN_ELEMENTS
this data object owns its elements
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
MsgStream & msg
Definition testRead.cxx:32