ATLAS Offline Software
Loading...
Searching...
No Matches
CaloLCOutOfClusterTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5//-----------------------------------------------------------------------
6// File and Version Information:
7// $Id: CaloLCOutOfClusterTool.cxx,v 1.3 2009-01-27 09:09:16 gunal Exp $
8//
9// Description: see CaloLCOutOfClusterTool.h
10//
11// Environment:
12// Software developed for the ATLAS Detector at CERN LHC
13//
14// Author List:
15// Sven Menke
16//
17//-----------------------------------------------------------------------
18
19//-----------------------
20// This Class's Header --
21//-----------------------
30
32
34 const std::string& name,
35 const IInterface* parent)
36 : AthAlgTool(type,name,parent),
37 m_key("OOCCorrection"),
38 m_useEmProbability(false),
40 m_interpolate(false)
41
42{
43
44 declareInterface<IClusterCellWeightTool>(this);
45 m_invalidSamplingNames.resize(3);
46
47 m_invalidSamplingNames[0] = "PreSamplerB";
48 m_invalidSamplingNames[1] = "PreSamplerE";
49 m_invalidSamplingNames[2] = "TileGap3";
50
51 declareProperty("CorrectionKey",m_key);
52 declareProperty("UseEmProbability",m_useEmProbability);
53 declareProperty("UseHadProbability",m_useHadProbability);
54 declareProperty("InvalidSamplings",m_invalidSamplingNames);
55
56 // Use Interpolation or not
57 declareProperty("Interpolate",m_interpolate);
59 m_interpolateDimensionNames[0] = "DIMO_ENER";
60 m_interpolateDimensionNames[1] = "DIMO_ETA";
61 m_interpolateDimensionNames[2] = "DIMO_LAMBDA";
62 declareProperty("InterpolateDimensionNames", m_interpolateDimensionNames);
63 declareProperty("UpdateSamplingVars",m_updateSamplingVars=false);
64}
65
67{
68 ATH_MSG_INFO( "Initializing " << name() );
69
70 //--- check sampling names to use exclude in correction
71 std::vector<std::string>::iterator samplingIter = m_invalidSamplingNames.begin();
72 std::vector<std::string>::iterator samplingIterEnd = m_invalidSamplingNames.end();
73 for(; samplingIter!=samplingIterEnd; ++samplingIter) {
74 int theSampling(CaloSampling::Unknown);
75 for (unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
77 theSampling = jsamp;
78 break;
79 }
80 }
81 if ( theSampling == CaloSampling::Unknown ) {
82 msg(MSG::ERROR) << "Calorimeter sampling "
83 << *samplingIter
84 << " is not a valid Calorimeter sampling name and will be ignored! "
85 << "Valid names are: ";
86 for (unsigned int jsamp = 0;jsamp< CaloSampling::Unknown; jsamp++) {
88 if ( jsamp < CaloSampling::Unknown-1)
89 msg() << ", ";
90 else
91 msg() << ".";
92 }
93 msg() << endmsg;
94 }
95 else {
96 m_invalidSamplings.insert(theSampling);
97 }
98 }
99
100 msg(MSG::INFO) << "Samplings to exclude from the out-of-cluster weighting:";
101 samplingIter = m_invalidSamplingNames.begin();
102 for(; samplingIter!=samplingIterEnd; ++samplingIter)
103 msg() << " " << *samplingIter;
104 msg() << endmsg;
105
106 if(m_interpolate) {
107 msg(MSG::INFO) << "Interpolation is ON, dimensions: ";
108 for(std::vector<std::string>::iterator it=m_interpolateDimensionNames.begin(); it!=m_interpolateDimensionNames.end(); ++it){
109 msg() << " " << (*it);
110 }
111 msg() << endmsg;
112 for(std::vector<std::string>::iterator it=m_interpolateDimensionNames.begin(); it!=m_interpolateDimensionNames.end(); ++it){
115 m_interpolateDimensions.push_back(int(id));
116 }else{
117 ATH_MSG_WARNING( "Dimension '" << (*it) << "' is invalid and will be excluded." );
118 }
119 }
120 }
121
122 // callback for conditions data
123 ATH_CHECK( m_key.initialize() );
124
125 return StatusCode::SUCCESS;
126}
127
128StatusCode CaloLCOutOfClusterTool::weight(CaloCluster *theCluster, const EventContext& ctx) const
129{
130 double eWeightedOrig = theCluster->e();
131 double eWeighted = theCluster->e();
132 // get ratio of weighted and em cluster
133 double ratio=1.;
134 std::vector<float> vars(5);
135
137
138 double pi0Prob = 0;
140 if (!theCluster->retrieveMoment(CaloCluster::EM_PROBABILITY,pi0Prob)) {
141 ATH_MSG_WARNING ("Cannot find cluster moment EM_PROBABILITY");
142 }
143 }
144 else if (theCluster->recoStatus().checkStatus(CaloRecoStatus::TAGGEDEM)) {
145 pi0Prob = 1.;
146 }
147 if ( pi0Prob < 0 )
148 pi0Prob = 0;
149 if ( pi0Prob > 1 )
150 pi0Prob = 1;
151
152 double classifyWeight = 1;
153 if ( m_useEmProbability ) {
154 classifyWeight = pi0Prob;
155 }
156 else if ( m_useHadProbability ) {
157 classifyWeight = 1-pi0Prob;
158 }
159 double eEM = theCluster->rawE();
160 // basic energy can be 0 if the locking tool option FixBasicEnergy is False
161 // in that case simply use the weighted energy ...
162 if ( eEM == 0. ) {
163 ATH_MSG_DEBUG("Basic Energy is 0. Use weighted energy instead");
164 eEM = eWeighted;
165 }
166
167
168
169 // subtract the samplings to ignore from eEM and eWeighted, assuming that
170 // they would not have received any cell weights in prior calibration
171 // steps
172 std::set<int>::const_iterator ivSamplingIter = m_invalidSamplings.begin();
173 std::set<int>::const_iterator ivSamplingIterEnd = m_invalidSamplings.end();
174 for(; ivSamplingIter!=ivSamplingIterEnd; ++ivSamplingIter) {
175 eEM -= theCluster->eSample((CaloCluster::CaloSample)(*ivSamplingIter));
176 eWeighted -= theCluster->eSample((CaloCluster::CaloSample)(*ivSamplingIter));
177 }
178
179 if ( eEM > 0 && eWeighted > 0 ) {
180 // ratio is em energy over weighted energy without the samplings
181 // to ignore. This means also the OOC weight tables have to be made
182 // relative to the em energy wihtout the samplings to ignore ...
183 ratio = eEM / eWeighted;
184
185 if ( ratio < 0.3 || ratio > 3 ) {
186 ATH_MSG_DEBUG("The ratio eEM/eWeighted = "
187 << ratio << " is out of normal range [0.3,3]"
188 << " - this mean we have mainly noise ... using 1 instead");
189 ratio = 1.0;
190 }
191
192 double log10cluse = log10(eEM);
193
195 const CaloLocalHadCoeff* data = *h;
196 if (!data) {
197 ATH_MSG_ERROR("Unable to access conditions object");
198 return StatusCode(CaloRecoStatus::TAGGEDUNKNOWN);
199 }
200
201 const CaloLocalHadCoeff::LocalHadDimension *logeDim = data->getArea(0)->getDimension(2);
202 double lemax = logeDim->getXmax()-0.5*logeDim->getDx();
203 double lemin = logeDim->getXmin()+0.5*logeDim->getDx();
204 if ( log10cluse > lemax )
205 log10cluse = lemax;
206 if ( log10cluse < lemin )
207 log10cluse = lemin;
208
209 double center_lambda,isolation;
210 if ( theCluster->retrieveMoment(CaloCluster::ISOLATION,isolation)
211 && theCluster->retrieveMoment(CaloCluster::CENTER_LAMBDA, center_lambda)) {
212 if ( isolation > 0 ) {
213 if ( center_lambda > 0 ) {
214 const double abseta = fabs(theCluster->eta());
215 const double log10lambda = log10(center_lambda);
216
217 vars[CaloLocalHadDefs::DIMO_SIDE] = static_cast<float> ((theCluster->eta()<0?-1.0:1.0));
218 vars[CaloLocalHadDefs::DIMO_PHI] = static_cast<float> (theCluster->phi());
219 vars[CaloLocalHadDefs::DIMO_ENER] = static_cast<float> (log10cluse);
220 vars[CaloLocalHadDefs::DIMO_ETA] = static_cast<float> (abseta);
221 vars[CaloLocalHadDefs::DIMO_LAMBDA] = static_cast<float> (log10lambda);
222
223 bool isDataOK = false;
224 double oocData(0);
225
226 // accessing coefficients (non-interpolated)
227 int iBin = data->getBin(0,vars);
228 if ( iBin >= 0 ) {
229 const CaloLocalHadCoeff::LocalHadCoeff * pData = data->getCoeff(iBin);
230 if ( pData && (*pData)[CaloLocalHadDefs::BIN_ENTRIES] > 0 ) {
231 isDataOK = true;
232 oocData = (*pData)[CaloLocalHadDefs::BIN_WEIGHT];
233 }
234 if(m_interpolate) {
235 // accesing interpolated coefficients
238 if(isa && parint[CaloLocalHadDefs::BIN_ENTRIES] > 0) {
239 isDataOK = true;
240 oocData = parint[CaloLocalHadDefs::BIN_WEIGHT];
241 }
242 }
243 }
244
245 ATH_MSG_DEBUG("interpolation_ON=" << m_interpolate
246 << "isDataOK="<<isDataOK
247 << "side = " << vars[0]
248 << ", phi = " << vars[1]
249 << ", log10cluse = " << log10cluse
250 << ", eta = " << abseta
251 << ", log10lambda = " << log10lambda
252 << ", ratio = " << ratio
253 << ", isol = " << isolation
254 << ", oocData = " << oocData);
255
256 if(isDataOK){
257 const double oocWeight = 1.+classifyWeight*isolation*ratio*oocData;
258 // loop over all cells
259 CaloCluster::cell_iterator itrCell = theCluster->cell_begin();
260 CaloCluster::cell_iterator itrCellEnd = theCluster->cell_end();
261 for (;itrCell!=itrCellEnd; ++itrCell) {
262 CaloPrefetch::nextDDE(itrCell, itrCellEnd);
263 const CaloDetDescrElement* cDDE = itrCell->caloDDE();
264 if ( cDDE && !m_invalidSamplings.contains(cDDE->getSampling())) { //Fixme ... could use a bit-pattern
265 double weight = itrCell.weight();//theCluster->getCellWeight(itrCell); // fastest!
266 weight *= oocWeight;
267 // reweight cell in cluster
268 theCluster->reweightCell(itrCell,weight);
269 } else if (cDDE) {
270 ATH_MSG_DEBUG("Exclude cell with sampling = " << cDDE->getSampling());
271 }
272 }//cell-loop
274 }
275 } // log10lambda
276 } // isolation
277 } // moments
278 }
279
280 // assume that the weighting could be called more than once. In that
281 // case eWeighted is the result of the previous step and the current
282 // e/eWeighted ratio should be multiplied with the existing
283 // OOC_WEIGHT moment
284 if ( eWeightedOrig > 0 || eWeightedOrig < 0 ) {
285 double old_weight(1);
286 if (!theCluster->retrieveMoment(CaloCluster::OOC_WEIGHT,old_weight)) {
287 ATH_MSG_ERROR("Cannot retrieve OOC_WEIGHT cluster moment." );
288 return StatusCode::FAILURE;
289 }
290 const double new_weight = old_weight*theCluster->e()/eWeightedOrig;
291 theCluster->insertMoment(CaloCluster::OOC_WEIGHT,new_weight);
292 }
293 return StatusCode::SUCCESS;
294}
295
297= default;
298
299
#define endmsg
#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 ATH_MSG_DEBUG(x)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
MsgStream & msg() const
Header file for AthHistogramAlgorithm.
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
Definition CaloCell.h:321
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.
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.
virtual double eta() const
Retrieve eta independent of signal state.
virtual double phi() const
Retrieve phi independent of signal state.
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.
This class groups all DetDescr information related to a CaloCell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
static bool Interpolate(const CaloLocalHadCoeff *m_data, const unsigned int n_area, std::vector< float > &x, CaloLocalHadCoeff::LocalHadCoeff &pars, const std::vector< int > &dim, double xfit=0.)
static CaloLocalHadDefs::LocalHadDimensionId getDimensionId(const std::string &dimensionName)
bool m_useHadProbability
look for em-probability moment and apply relative weight only
bool m_useEmProbability
look for em-probability moment and apply relative weight only
bool m_updateSamplingVars
update also sampling variables
std::vector< int > m_interpolateDimensions
actual set of dimension id's to interpolate
std::vector< std::string > m_invalidSamplingNames
vector of names of the calorimeter samplings not to use when applying the out-of-cluster weights.
bool m_interpolate
interpolate correction coefficients
std::vector< std::string > m_interpolateDimensionNames
vector of names of dimensions in look-up tables to interpolate
virtual StatusCode weight(xAOD::CaloCluster *theCluster, const EventContext &ctx) const override
method to weight the cells in a cluster
CaloLCOutOfClusterTool(const std::string &type, const std::string &name, const IInterface *parent)
virtual StatusCode initialize() override
SG::ReadCondHandleKey< CaloLocalHadCoeff > m_key
name of the key for out-of-cluster weights
virtual ~CaloLCOutOfClusterTool()
std::set< int > m_invalidSamplings
actual set of samplings to be ignored for out-of-cluster weights
Class defines binning for user dimension.
float getDx() const
return size of bin
float getXmax() const
return maximum value for the last bin
float getXmin() const
return minimum value for the first bin
Hold binned correction data for local hadronic calibration procedure.
std::vector< float > LocalHadCoeff
Correction parameters for one general bin.
static const std::string & getSamplingName(const CaloSampling::CaloSample theSample)
Returns a string (name) for each CaloSampling.
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.
@ CENTER_LAMBDA
Shower depth at Cluster Centroid.
@ ISOLATION
Energy weighted fraction of non-clustered perimeter cells.
CaloSampling::CaloSample CaloSample
void nextDDE(Iter iter, Iter endIter)
Prefetch next CaloDDE.
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
LocalHadDimensionId
enums to identify user dimensions id number DIMC_* - classification, DIMW_*-weighting,...