ATLAS Offline Software
Loading...
Searching...
No Matches
CaloClusterLocalCalib.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 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)
22{
23}
24
25
27
28 if (m_classificationTool.size()>1) {
29 msg(MSG::ERROR) << "More than one classification tool specified!" << endmsg;
30 return StatusCode::FAILURE;
31 }
32 //Retrieve classification tool (if necessary)
33 if (!m_classificationTool.empty()) {
35 msg(MSG::INFO) << "Found classification tool " << m_classificationTool[0] << endmsg;
36 }
37
38 //Retrieve calibration tools
39 ATH_CHECK(m_calibTools.retrieve());
40 msg(MSG::INFO) <<"Loaded "<< m_calibTools.size() <<" hadronic calibration tools"<<endmsg;
41
42 // check that at least one reco status is defined
43 if ( m_recoStatus.empty() ) {
44 msg(MSG::ERROR) << "Please specify at least one valid reco status with ClusterRecoStatus = [...] for this calib tool " << endmsg;
45 return StatusCode::FAILURE;
46 }
47 return StatusCode::SUCCESS;
48}
49
50StatusCode CaloClusterLocalCalib::execute(const EventContext& ctx,
51 CaloCluster* theCluster) const
52{
53 CaloRecoStatus& recoStatus=theCluster->recoStatus();
54 // call classification tool
55 if (!m_classificationTool.empty()) {
56 recoStatus=m_classificationTool[0]->classify(theCluster);
57 }
58 // check desired reco status
59 bool isSelected (false);
60 for (unsigned int i=0;!isSelected && i<m_recoStatus.size();i++ )
61 isSelected = recoStatus.checkStatus(CaloRecoStatus::StatusIndicator(m_recoStatus[i]));
62 if ( isSelected ) {
63 if( m_absOpt ){
64
65
66 //double dm_weight(0.);
67 //double had_weight(0.);
68 double centLambd(0.);
69 double engdens(0.);
70 double emprobability(0.);
71 double isolation(0.);
72 // Store moments and energy of the old cluster
73 //theCluster->retrieveMoment(xAOD::CaloCluster::DM_WEIGHT, dm_weight);
74 //theCluster->retrieveMoment(xAOD::CaloCluster::HAD_WEIGHT,had_weight);
75 if (!theCluster->retrieveMoment(xAOD::CaloCluster::CENTER_LAMBDA,centLambd))
76 centLambd = 0;
77 if (!theCluster->retrieveMoment(xAOD::CaloCluster::FIRST_ENG_DENS,engdens))
78 engdens = 0;
79 if (!theCluster->retrieveMoment(xAOD::CaloCluster::EM_PROBABILITY,emprobability))
80 emprobability = 0;
81 if (!theCluster->retrieveMoment(xAOD::CaloCluster::ISOLATION,isolation))
82 isolation = 0;
83
84 double oldEnergy = theCluster->e();
85
86 const CaloCell_ID* calo_id = nullptr;
87 ATH_CHECK(detStore()->retrieve(calo_id,"CaloCell_ID"));
88
89// Make new Cluster and CellColl
90 //std::unique_ptr<CaloCellContainer> myCellColl=std::make_unique<CaloCellContainer>(SG::OWN_ELEMENTS);
92 std::unique_ptr<xAOD::CaloCluster> myCluster = CaloClusterStoreHelper::makeCluster(&myCellColl);
93 int cellIndex = 0;
94// Iterate over cells of old cluster and replicate them with energy weighted by -1 if negative and add it to the new cluster
95 xAOD::CaloCluster::cell_iterator cellIter = theCluster->cell_begin();
96 for(;cellIter!=theCluster->cell_end();cellIter++) {
97 const CaloCell* pCell = *cellIter;
98 double CellEnergy = pCell->e();
99 //Identifier myId = pCell->ID();
100 //IdentifierHash myHashId = calo_id->calo_cell_hash(myId);
101 if( CellEnergy < 0. ) CellEnergy = -1 * pCell->e();
102 myCellColl.push_back(new CaloCell(pCell->caloDDE(), pCell->ID(), CellEnergy, pCell->time(), pCell->quality(), pCell->provenance(), pCell->gain() ));
103 double cellWeight = cellIter.weight();
104 myCluster->addCell(cellIndex,cellWeight);
105 cellIndex++;
106 }
107
108 CaloClusterKineHelper::calculateKine(myCluster.get(),false,false);
109 myCluster->setRawE(myCluster->e());
110
111// Set sample energy of the new cluster to the one of the old cluster, other wise it is zero, important for dm correction
112 for(unsigned int i=0; i != CaloSampling::Unknown; ++ i) {
114 if (myCluster->hasSampling(s)) myCluster->setEnergy((CaloSampling::CaloSample)i, theCluster->eSample((CaloSampling::CaloSample)i));
115 }//end loop over samplings
116
117 CaloClusterKineHelper::calculateKine(myCluster.get(),true,false);
118// Give the new cluster the same moments as the old one
119 myCluster->insertMoment(xAOD::CaloCluster::CENTER_LAMBDA,centLambd);
120 myCluster->insertMoment(xAOD::CaloCluster::FIRST_ENG_DENS,engdens);
121 myCluster->insertMoment(xAOD::CaloCluster::EM_PROBABILITY,emprobability);
122 myCluster->insertMoment(xAOD::CaloCluster::ISOLATION,isolation);
123
124// Weight the new cluster
125 for (const ToolHandle<IClusterCellWeightTool>& tool : m_calibTools) {
126 if (tool->weight(myCluster.get(),ctx).isFailure())
127 msg(MSG::ERROR) << " failed to weight cluster " << endmsg;
128 }
129
130// Iterate over new, calibrated cluster and write out the weights of every cell into a map
131 std::map<IdentifierHash,double> weightMap;
132 xAOD::CaloCluster::cell_iterator mycellIter = myCluster->cell_begin();
133 xAOD::CaloCluster::cell_iterator mycellIterEnd = myCluster->cell_end();
134 for(;mycellIter!=mycellIterEnd;mycellIter++) {
135 const CaloCell* pCell = *mycellIter;
136 double cellWeight = mycellIter.weight();
137 Identifier myId = pCell->ID();
138 IdentifierHash myHashId = calo_id->calo_cell_hash(myId);
139 weightMap[myHashId] = cellWeight;
140 }
141
142
143// Apply cellweight on the corresponding cell of the original cluster
144
145 cellIter = theCluster->cell_begin();
146 for(;cellIter!=theCluster->cell_end();cellIter++) {
147 const CaloCell* pCell = *cellIter;
148 IdentifierHash myHashId = calo_id->calo_cell_hash(pCell->ID());
149 double weight = weightMap[myHashId];
150 theCluster->reweightCell(cellIter,weight);
151 }
152
153// Update kinematics of new cluster
154 CaloClusterKineHelper::calculateKine(theCluster,true,false);
155
156
157 //Manually insert weight moments to the original cluster, in the OOC case this is a multiplicative weight from LCOut and LCOutPi0
158 double newWeightMoment = theCluster->e()/oldEnergy;
159 if(m_calibTools[0].typeAndName() == "CaloLCWeightTool/LCWeight") theCluster->insertMoment(xAOD::CaloCluster::HAD_WEIGHT,newWeightMoment);
160 if(m_calibTools[0].typeAndName() == "CaloLCDeadMaterialTool/LCDeadMaterial") theCluster->insertMoment(xAOD::CaloCluster::DM_WEIGHT, newWeightMoment);
161 if(m_calibTools[0].typeAndName() == "CaloLCOutOfClusterTool/LCOut") theCluster->insertMoment(xAOD::CaloCluster::OOC_WEIGHT,newWeightMoment);
162 if(m_calibTools[0].typeAndName() == "CaloLCOutOfClusterTool/LCOutPi0")
163 {
164 double ooc_weight;
165 if (theCluster->retrieveMoment(xAOD::CaloCluster::OOC_WEIGHT,ooc_weight)) {
166 newWeightMoment *= ooc_weight;
167 theCluster->insertMoment(xAOD::CaloCluster::OOC_WEIGHT,newWeightMoment);
168 }
169 }
170 }
171// else, what as was always done
172 else{
173
174 for (const ToolHandle<IClusterCellWeightTool>& tool : m_calibTools) {
175 if (tool->weight(theCluster,ctx).isFailure())
176 msg(MSG::ERROR) << " failed to weight cluster " << endmsg;
177 }
178
179 }
180 //report <<MSG::DEBUG<<"new cluster energy="<<theCluster->e()<<endmsg;
181 }//end of "has correct reco status" if statement
182
183 // PL add calibration method bits to reco status
185
186 return StatusCode::SUCCESS;
187}
188
189
190
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
Definition of CaloDetDescrManager.
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.
ToolHandleArray< IClusterCellWeightTool > m_calibTools
property: Array of IClusterCellWeightTool
virtual StatusCode execute(const EventContext &ctx, xAOD::CaloCluster *theCluster) const override
Execute on a single cluster.
CaloClusterLocalCalib(const std::string &type, const std::string &name, const IInterface *parent)
Standard AlgTool constructor.
Gaudi::Property< std::vector< int > > m_recoStatus
property: vector of valid Reco Statuses for the clusters in order to be calibrated
ToolHandleArray< IClusterClassificationTool > m_classificationTool
property: Classification tools
virtual StatusCode initialize() override
Tool initialization: load calibration tools specified by jobOptions.
Gaudi::Property< bool > m_absOpt
if set to true, negative clusters are weighted as well
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