ATLAS Offline Software
Loading...
Searching...
No Matches
JetBadChanCorrTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifndef XAOD_ANALYSIS
6
7#include "GaudiKernel/ITHistSvc.h"
10
13
16
17#include "TFile.h"
18#include "TH1.h"
19
22#include "AthenaKernel/Units.h"
23
25
26using Athena::Units::GeV;
27
28
30 asg::AsgTool(name),
31 m_thistSvc( "THistSvc", name )
32{
33 declareInterface<IJetDecorator>(this);
34}
35
37= default;
38
40{
41 ATH_MSG_DEBUG("initializing version with data handles");
42
43 if(!m_useClusters){
44 std::string fname = PathResolver::find_file(m_profileName, "DATAPATH");
45
46 if(fname.empty()){
47 ATH_MSG(ERROR) << "Could not get file " << m_profileName << endmsg;
48 return StatusCode::FAILURE;
49 }
50 TFile tf(fname.c_str());
51 if(!tf.IsOpen()){
52 ATH_MSG( ERROR ) << "Could not open file " << fname << endmsg;
53 return StatusCode::FAILURE;
54 }
55 // already registered hists
56 std::vector<std::string> histsInSvc = m_thistSvc->getHists();
57
58 TListIter next(tf.GetListOfKeys());
59 TObject *obj;
60 while((obj = next())) {
61 std::string hname=obj->GetName();
62 if(hname.find('_')==std::string::npos) continue;
63 std::string tag = hname.substr(0,hname.find('_'));
64 std::string para = hname.substr(hname.find('_')+1);
65 std::string location = m_streamName+hname;
66
67 if(m_profileTag=="" || m_profileTag==tag){
68 // read in histo not registered yet
69 if(find(histsInSvc.begin(),histsInSvc.end(),location)==histsInSvc.end()){
70 StatusCode sc = m_thistSvc->regHist(location);
71 if(sc.isFailure()){
72 ATH_MSG( ERROR ) << "failed to read histo " << location << endmsg;
73 return StatusCode::FAILURE;
74 }
75 }
76 int sample=0;
77 double ptMin=0;
78 double ptMax=9999;
79 double etaMin=0;
80 double etaMax=5.0;
81 double phiMin=-M_PI;
82 double phiMax=M_PI;
83 int ret = sscanf(para.c_str(),"sample%d_pt%lf_%lf_eta%lf_%lf_phi%lf_%lf",
84 &sample,&ptMin,&ptMax,&etaMin,&etaMax,&phiMin,&phiMax);
85
86 if(ret<1 || sample<0 || sample>=CaloCell_ID::Unknown) {
87 ATH_MSG( DEBUG ) << "Could not understand the name of hist " << obj->GetName() << endmsg;
88 continue;
89 }
90
91 TH1* th=nullptr;
92 StatusCode sc = m_thistSvc->getHist(location,th);
93 if(sc.isFailure()){
94 ATH_MSG( ERROR ) << "failed to get histo " << location << endmsg;
95 return StatusCode::FAILURE;
96 }
97 m_profileDatas[sample].emplace_back(th,sample,ptMin,ptMax,etaMin,etaMax,phiMin,phiMax);
98 ATH_MSG( DEBUG ) << "read hist=" << th->GetName()
99 << " tag=" << tag << " sample=" << sample
100 << " ptMin=" << ptMin << " ptMax=" << ptMax
101 << " etaMin=" << etaMin << " etaMax=" << etaMax
102 << " phiMin=" << phiMin << " phiMax=" << phiMax << endmsg;
103 }
104 }
105 }
106
107 if(m_jetContainerName.empty()){
108 ATH_MSG_ERROR("JetBadChanCorrTool needs to have its input jet container name configured!");
109 return StatusCode::FAILURE;
110 }
111
112 ATH_CHECK(m_badCellMap_key.initialize());
113
118
119 ATH_CHECK(m_corrCellKey.initialize());
120 // These 3 aren't used if we're configured to use clusters
124
125 return StatusCode::SUCCESS;
126}
127
129{
130 return StatusCode::SUCCESS;
131}
132
133
135{
136
138
139 auto handle = SG::makeHandle (m_badCellMap_key);
140 if (!handle.isValid()){
141 ATH_MSG_ERROR("Could not retieve bad cell map " << m_badCellMap_key.key());
142 return StatusCode::FAILURE;
143 }
144
145 const auto *badCellMap = handle.cptr();
146
147 // number of bad cells exceed the limit, set moments -1 and skip
148 if((int) badCellMap->cells().size() >m_nBadCellLimit){
153 for(const xAOD::Jet* jet : jets){
154 corrCellHandle(*jet) = -1.;
155 corrDotxHandle(*jet) = -1.;
156 corrJetHandle(*jet) = -1.;
157 corrJetForCellHandle(*jet) = -1.;
158 }
159 return StatusCode::SUCCESS;
160 }
161
162 return correctionFromCellsInJet(jets, badCellMap);
163}
164
166
171
172 for(const xAOD::Jet* jet : jets){
173
175 double rawPt = p4.Pt();
176 double rawE = p4.E();
177
178 // jet moments, fraction
179 double corr_jet_associate=0;
180 double corr_jet_forcell=0;
181 double corr_cell=0;
182 double corr_dotx=0;
183
186
187 for( ;cellIt!=cellItE; ++cellIt) {
188
189 const CaloDetDescrElement * dde = (*cellIt)->caloDDE();
190 const CaloCell *cell = *cellIt;
191 double cellWeight = cellIt.weight();
192
193 double cell_energy = cell->e() * cellWeight;
194
195 CaloCell_ID::CaloSample sampling = dde->getSampling();
196
197 bool considerBad = cell->badcell();
198 // for bad channels in jet
199 if(considerBad){
200
201 // determine if this comes from a deadOTX
202 bool isOTX = false;
203 if(!(dde->is_tile()))
204 if(cell->provenance() & 0x0200)
205 isOTX = true;
206
207 double dr = xAOD::P4Helpers::deltaR(jet->eta(),jet->phi(),dde->eta(), dde->phi());
208 double frac_cell = getProfile(rawPt, dr, sampling, dde->eta(), dde->phi());
209
210 double frac = frac_cell * cellWeight;
211
212 corr_jet_associate += frac;
213
214 // corrected in cell-level
215 if(cell_energy!=0){
216 // for cryo.
217 if(isOTX)
218 corr_dotx += cell_energy;
219 else
220 corr_cell += cell_energy;
221
222 corr_jet_forcell += frac;
223 }
224 }
225 } // loop over cells
226
227 const double inv_rawE = 1. / rawE;
228 corr_cell *= inv_rawE;
229 corr_dotx *= inv_rawE;
230 ATH_MSG( DEBUG ) << "pt=" << jet->pt()/GeV << " eta=" << jet->eta() << " phi=" << jet->phi()
231 << " BCH_CORR_CELL=" << corr_cell
232 << " BCH_CORR_DOTX=" << corr_dotx
233 << " BCH_CORR_JET=" << corr_jet_associate
234 << " BCH_CORR_JET_FORCELL=" << corr_jet_forcell << endmsg;
235
236 corrCellHandle(*jet) = corr_cell;
237 corrDotxHandle(*jet) = corr_dotx;
238 corrJetForCellHandle(*jet) = corr_jet_forcell;
239 if(m_useCone)
240 corrJetHandle(*jet) = correctionFromCellsInCone(jet, badCellMap);
241 else
242 corrJetHandle(*jet) = corr_jet_associate;
243 }
244 return StatusCode::SUCCESS;
245}
246
248
249 ATH_MSG_DEBUG( " Missing cells for cone search "<< badCellMap->size() << " jet="<< jet->index() << " R="
250 << jet->getSizeParameter() << " input="<< jet->getInputType() << " jet_eta="<<jet->eta() ) ;
251
252 double corr_jet_cone=0;
253
254 double rawPt = jet->jetP4(xAOD::JetEMScaleMomentum).Pt();
255
256 double jeteta = jet->eta();
257 double jetphi = jet->phi();
258 std::vector<jet::CellPosition> closeCells = badCellMap->cellsInDeltaR(jeteta,jetphi, jet->getSizeParameter() );
259 std::vector<jet::CellPosition>::iterator itr = closeCells.begin();
260 std::vector<jet::CellPosition>::iterator itrE = closeCells.end();
261
262 for(; itr!=itrE; ++itr){
263
264 double cell_eta = itr->x();
265 double cell_phi = itr->phi();
266
267 CaloCell_ID::CaloSample sampling = itr->sampling();
268
269 double dr = xAOD::P4Helpers::deltaR(jeteta, jetphi, cell_eta, cell_phi);
270 double frac_cell = getProfile(rawPt, dr, sampling, cell_eta, cell_phi);
271
272 corr_jet_cone += frac_cell;
273 }
274
275 return corr_jet_cone;
276}
277
279
281
282 for(const xAOD::Jet* jet : jets){
283
284 double corrCell=0;
285
286 size_t nconstit=jet->numConstituents();
287 for(size_t i=0; i<nconstit; i++) {
288 // use the raw constituents since we're interested only in one moment :
289 const xAOD::IParticle* constit = jet->rawConstituent(i);
290 if( constit->type() != xAOD::Type::CaloCluster ) continue;
291 double badE;
292 bool v = static_cast<const xAOD::CaloCluster*>(constit)->retrieveMoment( xAOD::CaloCluster::ENG_BAD_CELLS, badE);
293 if(v) corrCell += badE;
294 }
295
296 double rawE = jet->jetP4(xAOD::JetEMScaleMomentum).E();
297 if(rawE==0) corrCellHandle(*jet) = 0;
298 else corrCellHandle(*jet) = corrCell / rawE;
299 }
300 return StatusCode::SUCCESS;
301}
302
303double JetBadChanCorrTool::getProfile(double pt, double dr, int sample, double eta, double phi) const {
304 std::vector<ProfileData>::const_iterator itr =m_profileDatas[sample].begin();
305 std::vector<ProfileData>::const_iterator itrE =m_profileDatas[sample].end();
306 for(; itr!=itrE; ++itr){
307 if((*itr).match(pt/GeV,sample,eta,phi)){
308 return (*itr).frac(dr);
309 }
310 }
311 return 0;
312}
313
314#endif
#define M_PI
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG(lvl)
#define ATH_MSG_DEBUG(x)
Helpers for checking error return status codes and reporting errors.
static Double_t sc
Handle class for adding a decoration to an object.
Wrapper to avoid constant divisions when using units.
CaloSampling::CaloSample CaloSample
Definition CaloCell_ID.h:53
Data object for each calorimeter readout cell.
Definition CaloCell.h:57
This class groups all DetDescr information related to a CaloCell.
CaloCell_ID::CaloSample getSampling() const
cell sampling
SG::WriteDecorHandleKey< xAOD::JetContainer > m_corrJetKey
virtual StatusCode setupEvent()
Gaudi::Property< int > m_nBadCellLimit
Gaudi::Property< std::string > m_jetContainerName
virtual ~JetBadChanCorrTool()
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
Gaudi::Property< bool > m_useCone
std::vector< ProfileData > m_profileDatas[CaloCell_ID::Unknown]
float correctionFromCellsInCone(const xAOD::Jet *jet, const jet::CaloCellFastMap *badCellMap) const
SG::WriteDecorHandleKey< xAOD::JetContainer > m_corrCellKey
double getProfile(double pt, double dr, int sample, double eta, double phi) const
SG::WriteDecorHandleKey< xAOD::JetContainer > m_corrDotxKey
StatusCode correctionFromClustersBadCells(const xAOD::JetContainer &jets) const
SG::WriteDecorHandleKey< xAOD::JetContainer > m_corrJetForCellKey
SG::ReadHandleKey< jet::CaloCellFastMap > m_badCellMap_key
Gaudi::Property< std::string > m_streamName
Gaudi::Property< std::string > m_profileTag
JetBadChanCorrTool(const std::string &name)
StatusCode correctionFromCellsInJet(const xAOD::JetContainer &jets, const jet::CaloCellFastMap *badCellMap) const
Gaudi::Property< std::string > m_profileName
Gaudi::Property< bool > m_useClusters
ServiceHandle< ITHistSvc > m_thistSvc
virtual StatusCode decorate(const xAOD::JetContainer &jets) const override
Decorate a jet collection without otherwise modifying it.
unsigned int size() const
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)
Handle class for adding a decoration to an object.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
std::vector< CellPosition > cellsInDeltaR(double eta, double phi, double r) const
weight_t weight() const
Accessor for weight associated to this cell.
static const_iterator begin(const xAOD::Jet *jet)
static const_iterator end(const xAOD::Jet *jet)
@ ENG_BAD_CELLS
Total em-scale energy of bad cells in this cluster.
Class providing the definition of the 4-vector interface.
virtual Type::ObjectType type() const =0
The type of the object as a simple enumeration.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
@ CaloCluster
The object is a calorimeter cluster.
Definition ObjectType.h:39
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
Jet_v1 Jet
Definition of the current "jet version".
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
@ JetEMScaleMomentum
Definition JetTypes.h:28
JetContainer_v1 JetContainer
Definition of the current "jet container version".
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition JetTypes.h:17
#define DEBUG
Definition page_access.h:11