ATLAS Offline Software
Loading...
Searching...
No Matches
InsituDataCorrection.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
8#include <TFile.h>
9#include <TH1.h>
10#include <TEnv.h>
11#include <TAxis.h>
12
13#include <utility>
14
15
28
29InsituDataCorrection::InsituDataCorrection(const std::string& name, TEnv* config, TString jetAlgo, TString calibAreaTag, bool dev, unsigned int firstRun, unsigned int lastRun)
32 m_jetAlgo(std::move(jetAlgo)),
33 m_calibAreaTag(std::move(calibAreaTag)),
34 m_dev(dev),
35 m_insituCorr(nullptr),
36 m_insituCorr_JMS(nullptr),
38 m_firstRun(firstRun),
39 m_lastRun(lastRun)
40{ }
41
43
45
46 ATH_MSG_INFO("Initializing In Situ correction.");
47
48 if(!m_config){
49 ATH_MSG_ERROR("In Situ data correction tool received a null config pointer.");
50 return StatusCode::FAILURE;
51 }
52
53 m_jetStartScale = m_config->GetValue("InsituStartingScale","JetGSCScaleMomentum");
54
55 //Retrieve the name of root file containing the in-situ calibration histograms from the config
56 TString insitu_filename = m_config->GetValue("InsituCalibrationFile","None");
57 //Should be the Relative and Abosolute Insitu correction applied?
58 m_applyRelativeandAbsoluteInsitu = m_config->GetValue("ApplyRelativeandAbsoluteInsitu", true);
59 //Should be a Eta restriction in the Relative and Absolute Insitu correction?
60 m_applyEtaRestrictionRelativeandAbsolute = m_config->GetValue("ApplyEtaRestrictionRelativeandAbsolute", false);
61 //Should be applied the Residual MC based Insitu correction?
62 m_applyResidualMCbasedInsitu = m_config->GetValue("ApplyResidualMCbasedInsitu", false);
63 //Should be a Eta restriction in the Residual MC based Insitu correction?
64 m_applyEtaRestrictionResidualMCbased = m_config->GetValue("ApplyEtaRestrictionResidualMCbased", false);
65 //Retrieve the name of the histogram for the relative in-situ calibration
66 TString rel_histoname = m_config->GetValue("RelativeInsituCalibrationHistogram","");
67 //Retrieve the name of the histogram for the absolute in-situ calibration
68 TString abs_histoname = m_config->GetValue("AbsoluteInsituCalibrationHistogram","");
69 //Retrieve the name of the histogram for the absolute in-situ calibration
70 TString residualmcbased_histoname = m_config->GetValue("ResidualMCbasedInsituCalibrationHistogram","");
71 //Retrieve the description/name of the in-situ calibration
72 TString insitu_desc = m_config->GetValue("InsituCalibrationDescription","");
73 //Retrieve the Eta restriction on the Residual MC based insitu calibration
74 double insitu_etarestriction_residualmcbased = m_config->GetValue("InsituEtaRestrictionResidualMCbased",0.8);
75 //Retrieve the Eta restriction on the Relative and Absolute insitu calibration
76 double insitu_etarestriction_relativeandabsolute = m_config->GetValue("InsituEtaRestrictionRelativeandAbsolute",0.8);
77 // Apply Insitu only to calo and TA mass calibrated jets (only for large jets)
78 m_applyInsituCaloTAjets = m_config->GetValue("ApplyInsituCaloTAJets", false);
79 // Apply in situ JMS:
80 m_applyInsituJMS = m_config->GetValue("ApplyInsituJMS", false);
81
82 //Find the absolute path to the insitu root file
83 if ( !insitu_filename.EqualTo("None") ){
84 if(m_dev){
85 insitu_filename.Remove(0,32);
86 insitu_filename.Insert(0,"JetCalibTools/");
87 }
88 else{insitu_filename.Insert(14,m_calibAreaTag);}
89 insitu_filename=PathResolverFindCalibFile(insitu_filename.Data());
90 }
91
92 std::unique_ptr<TFile> insitu_file(TFile::Open(insitu_filename));
93 if ( !insitu_file ) { ATH_MSG_FATAL( "Cannot open InsituCalibrationFile: " << insitu_filename ); return StatusCode::FAILURE; }
94
95 ATH_MSG_INFO("Reading In-situ correction factors from: " << insitu_filename);
96
97 rel_histoname.ReplaceAll("JETALGO",m_jetAlgo); abs_histoname.ReplaceAll("JETALGO",m_jetAlgo);
99 std::unique_ptr<const TH2> rel_histo(JetCalibUtils::GetHisto2(*insitu_file,rel_histoname));
100 std::unique_ptr<const TH1> abs_histo(JetCalibUtils::GetHisto(*insitu_file,abs_histoname));
101 if ( !rel_histo || !abs_histo ) {
102 ATH_MSG_FATAL( "\n Tool configured for data, but no residual in-situ histograms could be retrieved. Aborting..." );
103 return StatusCode::FAILURE;
104 }
105 gROOT->cd();
106 // save pTmax of the relative and absolute in situ calibrations
107 m_relhistoPtMax = rel_histo->GetXaxis()->GetBinLowEdge(rel_histo->GetNbinsX()+1);
108 m_abshistoPtMax = abs_histo->GetBinLowEdge(abs_histo->GetNbinsX()+1);
109 // combine in situ calibrations
110 m_insituCorr = combineCalibration(rel_histo.get(),abs_histo.get());
111 m_insituEtaMax = m_insituCorr->GetYaxis()->GetBinLowEdge(m_insituCorr->GetNbinsY()+1);
112 m_insituPtMin = m_insituCorr->GetXaxis()->GetBinLowEdge(1);
113 m_insituPtMax = m_insituCorr->GetXaxis()->GetBinLowEdge(m_insituCorr->GetNbinsX()+1);
114 if(m_applyEtaRestrictionRelativeandAbsolute) m_insituEtaMax = insitu_etarestriction_relativeandabsolute;
115 }
117 m_insituCorr_ResidualMCbased = JetCalibUtils::GetHisto2(*insitu_file,residualmcbased_histoname);
119 ATH_MSG_FATAL( "\n Tool configured for the Residual MC based correction, but no residualmcbased in-situ histograms could be retrieved. Aborting..." );
120 return StatusCode::FAILURE;
121 }
122 else{
123 gROOT->cd();
125 m_insituPtMin_ResidualMCbased = m_insituCorr_ResidualMCbased->GetXaxis()->GetBinLowEdge(1);
127 }
128 if(m_applyEtaRestrictionResidualMCbased) m_insituEtaMax_ResidualMCbased = insitu_etarestriction_residualmcbased;
129 }
131 ATH_MSG_FATAL( "\n Tool configured for Insitu correction, but no in-situ histograms could be retrieved. Aborting..." );
132 return StatusCode::FAILURE;
133 }
134
135 //Large-R in situ JMS calibration
137 //Retrieve the name of root files containing the in-situ calibration histograms from the config
138 TString insituJMS_filename = m_config->GetValue("InsituCalibrationFile_JMS","None");
139 //Retrieve the name of the histogram for the absolute in-situ calibration
140 TString abs_histoname_JMS = m_config->GetValue("AbsoluteInsituCalibrationHistogram_JMS","");
141 TString abs_histoname_JMS_TA = m_config->GetValue("AbsoluteInsituCalibrationHistogram_JMS_TA","");
142 //Retrieve the eta range for the in-situ JMS calibration
143 double insitu_etarestriction_JMS = m_config->GetValue("InsituEtaRestriction_JMS",2.0);
144
145 //Find the absolute path to the insitu root file Low and High Mass
146 if ( !insituJMS_filename.EqualTo("None")){
147 if(m_dev){
148 insituJMS_filename.Remove(0,32);
149 insituJMS_filename.Insert(0,"JetCalibTools/");
150 }
151 else{
152 insituJMS_filename.Insert(14,m_calibAreaTag);
153 }
154 insituJMS_filename=PathResolverFindCalibFile(insituJMS_filename.Data());
155 }
156
157 std::unique_ptr<TFile> insituJMS_file(TFile::Open(insituJMS_filename));
158 if ( !insituJMS_file ) { ATH_MSG_FATAL( "Cannot open InsituJMSCalibrationFile: " << insituJMS_filename ); return StatusCode::FAILURE; }
159
160 ATH_MSG_INFO("Reading In-situ JMS correction factors from: " << insituJMS_filename);
161
162 abs_histoname_JMS.ReplaceAll("JETALGO",m_jetAlgo);
164 abs_histoname_JMS_TA.ReplaceAll("JETALGO",m_jetAlgo);
165 }
166
168 std::unique_ptr<const TH2> abs_histo_JMS(JetCalibUtils::GetHisto2(*insituJMS_file,abs_histoname_JMS));
169 if ( !abs_histo_JMS ) {
170 ATH_MSG_FATAL( "\n Tool configured for data, but no in-situ JMS histogram could be retrieved. Aborting..." );
171 return StatusCode::FAILURE;
172 }
173 else {
174 gROOT->cd();
175 // combine in situ calibrations
176 m_insituCorr_JMS = invertHistogram(abs_histo_JMS.get());
177 m_insituEtaMax_JMS = insitu_etarestriction_JMS;
178 m_insituPtMin_JMS = m_insituCorr_JMS->GetXaxis()->GetBinLowEdge(1);
179 m_insituPtMax_JMS = m_insituCorr_JMS->GetXaxis()->GetBinLowEdge(m_insituCorr_JMS->GetNbinsX()+1);
180 m_insituMassMin_JMS = m_insituCorr_JMS->GetYaxis()->GetBinLowEdge(1);
181 m_insituMassMax_JMS = m_insituCorr_JMS->GetYaxis()->GetBinLowEdge((m_insituCorr_JMS->GetNbinsY()+1));
182
184
185 std::unique_ptr<const TH2> abs_histo_JMS_TA(JetCalibUtils::GetHisto2(*insituJMS_file,abs_histoname_JMS_TA));
186
187 if ( !abs_histo_JMS_TA ){
188 ATH_MSG_FATAL( "\n Tool configured for data, but no in-situ JMS histogram for TA mass could be retrieved. Aborting..." );
189 return StatusCode::FAILURE;
190 }
191
192 gROOT->cd();
193 m_insituCorr_JMS_TA = invertHistogram(abs_histo_JMS_TA.get());
194 }
195 }
196 }
198 ATH_MSG_FATAL( "\n Tool configured for Insitu correction, but no in-situ histograms could be retrieved. Aborting..." );
199 return StatusCode::FAILURE;
200 }
201 }
202
203 ATH_MSG_INFO("Tool configured to calibrate data");
204 ATH_MSG_INFO("In-situ correction to be applied: " << insitu_desc);
205 return StatusCode::SUCCESS;
206
207}
208
210
211 //If this is a time-dependent calibration and we're not on a relevant run, don't calibrate.
212 unsigned int runNumber = static_cast<unsigned int>(jetEventInfo.runNumber()+0.5);
213 if(m_lastRun > 0 && (runNumber < m_firstRun || runNumber > m_lastRun))
214 return StatusCode::SUCCESS;
215
216 float detectorEta = jet.getAttribute<float>("DetectorEta");
217
218 // For small R jets or large-R jets without calo-TA combination
220 xAOD::JetFourMom_t jetStartP4;
222 jetStartP4 = jet.jetP4();
223
224 xAOD::JetFourMom_t calibP4=jetStartP4;
225
226 if(m_applyResidualMCbasedInsitu) calibP4=calibP4*getInsituCorr( calibP4.pt(), fabs(detectorEta), "ResidualMCbased" );
227
228 if(m_dev){
229 float insituFactor = getInsituCorr( jetStartP4.pt(), detectorEta, "RelativeAbs" );
230 jet.setAttribute<float>("JetRelativeAbsInsituCalibFactor",insituFactor);
231 }
232
233 if(m_applyRelativeandAbsoluteInsitu) calibP4=calibP4*getInsituCorr( jetStartP4.pt(), detectorEta, "RelativeAbs" );
234
235 // Only for large R jets with insitu JMS but no combination
237 xAOD::JetFourMom_t calibP4_JMS;
238 calibP4_JMS = calibP4;
239
240 calibP4_JMS=calibP4*getInsituCorr_JMS( calibP4.pt(), calibP4.M(), detectorEta, "RelativeAbs", false );
241
242 // pT doesn't change while applying in situ JMS
243 TLorentzVector TLVjet;
244 TLVjet.SetPtEtaPhiM( calibP4.pt(), calibP4.eta(), calibP4.phi(), calibP4_JMS.M() );
245 calibP4.SetPxPyPzE( TLVjet.Px(), TLVjet.Py(), TLVjet.Pz(), TLVjet.E() );
246 }
247
248 //Transfer calibrated jet properties to the Jet object
249 jet.setAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentum",calibP4);
250 jet.setJetP4( calibP4 );
251 }
252
253 // For large-R jets: insitu needs to be applied to calo mass and TA mass (by default it's only applied to combined mass)
255
256 // calo mass calibrated jets
257 xAOD::JetFourMom_t jetStartP4_calo;
258 xAOD::JetFourMom_t calibP4_calo;
259 if(jet.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumCalo",jetStartP4_calo)){
260 calibP4_calo=jetStartP4_calo;
261 }else{
262 ATH_MSG_FATAL( "Cannot retrieve JetJMSScaleMomentumCalo jets" );
263 return StatusCode::FAILURE;
264 }
265
266 if(m_applyResidualMCbasedInsitu) calibP4_calo=calibP4_calo*getInsituCorr( calibP4_calo.pt(), fabs(detectorEta), "ResidualMCbased" );
267
268 if(m_dev){
269 float insituFactor_calo = getInsituCorr( jetStartP4_calo.pt(), detectorEta, "RelativeAbs" );
270 jet.setAttribute<float>("JetRelativeAbsInsituCalibFactor_calo",insituFactor_calo);
271 }
272
273 if(m_applyRelativeandAbsoluteInsitu) calibP4_calo=calibP4_calo*getInsituCorr( jetStartP4_calo.pt(), detectorEta, "RelativeAbs" );
274
276 xAOD::JetFourMom_t calibP4_calo_JMS;
277 calibP4_calo_JMS = calibP4_calo;
278
279 calibP4_calo_JMS=calibP4_calo*getInsituCorr_JMS( calibP4_calo.pt(), calibP4_calo.M(), detectorEta, "RelativeAbs", false );
280
281 // pT doesn't change while applying in situ JMS
282 TLorentzVector TLVjet_calo;
283 TLVjet_calo.SetPtEtaPhiM( calibP4_calo.pt(), calibP4_calo.eta(), calibP4_calo.phi(), calibP4_calo_JMS.M() );
284 calibP4_calo.SetPxPyPzE( TLVjet_calo.Px(), TLVjet_calo.Py(), TLVjet_calo.Pz(), TLVjet_calo.E() );
285 }
286
287 //Transfer calibrated jet properties to the Jet object
288 jet.setAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumCalo",calibP4_calo);
289 jet.setJetP4( calibP4_calo );
290
291 // TA mass calibrated jets
292 xAOD::JetFourMom_t jetStartP4_ta;
293 xAOD::JetFourMom_t calibP4_ta;
294 if(jet.getAttribute<xAOD::JetFourMom_t>("JetJMSScaleMomentumTA", jetStartP4_ta)){
295 calibP4_ta=jetStartP4_ta;
296 }else{
297 ATH_MSG_FATAL( "Cannot retrieve JetJMSScaleMomentumTA jets" );
298 return StatusCode::FAILURE;
299 }
300
301 if(m_applyResidualMCbasedInsitu) calibP4_ta=calibP4_ta*getInsituCorr( calibP4_ta.pt(), fabs(detectorEta), "ResidualMCbased" );
302
303 if(m_dev){
304 float insituFactor_ta = getInsituCorr( jetStartP4_ta.pt(), detectorEta, "RelativeAbs" );
305 jet.setAttribute<float>("JetRelativeAbsInsituCalibFactor_ta",insituFactor_ta);
306 }
307
308 if(m_applyRelativeandAbsoluteInsitu) calibP4_ta=calibP4_ta*getInsituCorr( jetStartP4_ta.pt(), detectorEta, "RelativeAbs" );
309
311 xAOD::JetFourMom_t calibP4_ta_JMS;
312 calibP4_ta_JMS = calibP4_ta;
313
314 calibP4_ta_JMS=calibP4_ta*getInsituCorr_JMS( calibP4_ta.pt(), calibP4_ta.M(), detectorEta, "RelativeAbs", true );
315
316 // pT doesn't change while applying in situ JMS
317 TLorentzVector TLVjet_ta;
318 TLVjet_ta.SetPtEtaPhiM( calibP4_ta.pt(), calibP4_ta.eta(), calibP4_ta.phi(), calibP4_ta_JMS.M() );
319 calibP4_ta.SetPxPyPzE( TLVjet_ta.Px(), TLVjet_ta.Py(), TLVjet_ta.Pz(), TLVjet_ta.E() );
320 }
321
322 //Transfer calibrated jet properties to the Jet object
323 jet.setAttribute<xAOD::JetFourMom_t>("JetInsituScaleMomentumTA",calibP4_ta);
324 jet.setJetP4( calibP4_ta );
325
326 }
327
328 return StatusCode::SUCCESS;
329}
330
331double InsituDataCorrection::getInsituCorr(double pt, double eta, const std::string& calibstep) const {
332 if (m_insituCorr==nullptr && m_insituCorr_ResidualMCbased==nullptr) return 1.0;
333 double myEta = eta, myPt = pt/m_GeV;
334
335 //eta and pt ranges depends on the insitu calibration
336 double etaMax = m_insituEtaMax;
337 double ptMin = m_insituPtMin;
338 double ptMax = m_insituPtMax;
339 if (calibstep == "ResidualMCbased"){
343 }
344
345 //protection against values outside the histogram range, snap back to the lowest/highest bin edge
346 if ( myPt <= ptMin ) myPt = ptMin + 1e-6;
347 else if ( myPt >= ptMax ) myPt = ptMax - 1e-6;
348 if (calibstep == "ResidualMCbased" && m_applyEtaRestrictionResidualMCbased) {
349 if(myEta>=etaMax) return 1.0;
350 return m_insituCorr_ResidualMCbased? (m_insituCorr_ResidualMCbased->Interpolate(myPt,myEta)) : 1.0;
351 }
352 if (calibstep == "RelativeAbs" && m_applyEtaRestrictionRelativeandAbsolute) {
353 if(myEta>=etaMax) return 1.0;
354 else if(myEta<=-etaMax) return 1.0;
355 }
356 if (myEta <= -etaMax) myEta = 1e-6 - etaMax;
357 else if (myEta >= etaMax) myEta = etaMax - 1e-6;
358 if (calibstep == "ResidualMCbased" && !m_applyEtaRestrictionResidualMCbased){
359 return m_insituCorr_ResidualMCbased? (m_insituCorr_ResidualMCbased->Interpolate(myPt,myEta)) : 1.0;
360 }
361 return m_insituCorr? (m_insituCorr->Interpolate(myPt,myEta)):1.0;
362}
363
364double InsituDataCorrection::getInsituCorr_JMS(double pt, double mass, double eta, const std::string& calibstep, bool isTAmass) const {
365
366 if(!isTAmass){
367 if (!m_insituCorr_JMS) return 1.0;
368 }
369 else{
370 if (!m_insituCorr_JMS_TA) return 1.0;
371 }
372
373 double myEta = eta, myPt = pt/m_GeV, myMass = mass/m_GeV;
374
375 //eta and pt ranges depends on the insitu calibration
376 double etaMax = m_insituEtaMax_JMS;
377 double ptMin = m_insituPtMin_JMS;
378 double ptMax = m_insituPtMax_JMS;
379 double massMin = m_insituMassMin_JMS;
380 double massMax = m_insituMassMax_JMS;
381
382 //protection against values outside the histogram range, snap back to the lowest/highest bin edge
383 if ( myPt <= ptMin ) myPt = ptMin + 1e-6;
384 else if ( myPt >= ptMax ) myPt = ptMax - 1e-6;
385 if (calibstep == "RelativeAbs" && m_applyEtaRestrictionRelativeandAbsolute) {
386 if(myEta>=etaMax) return 1.0;
387 else if(myEta<=-etaMax) return 1.0;
388 }
389 if (myEta <= -etaMax) myEta = 1e-6 - etaMax;
390 else if (myEta >= etaMax) myEta = etaMax - 1e-6;
391 if (myMass <= massMin ) myMass = massMin + 1e-6;
392 else if (myMass >= massMax ) myMass = massMax - 1e-6;
393
394 double calibFactor = 1.0;
395 if(!isTAmass){
396 calibFactor = m_insituCorr_JMS->Interpolate(myPt,myMass);
397 }
398 else{
399 calibFactor = m_insituCorr_JMS_TA->Interpolate(myPt,myMass);
400 }
401
402 return calibFactor;
403}
404
405
406
407std::unique_ptr<const TH2> InsituDataCorrection::combineCalibration(const TH2* h2d, const TH1* h) {
408 std::unique_ptr<TH2> prod(static_cast<TH2*>(h2d->Clone()));
409 for (int xi=1;xi<=prod->GetNbinsX();xi++) {
410 double pt=prod->GetXaxis()->GetBinCenter(xi);
411 const double R_abs=h->Interpolate(pt); // Rdata/RMC for the absolute scale
412 const double inv_R_abs = 1. / R_abs;
413 //printf("pT = %7.1f GeV, abs calib: %.4f\n",pt,abs);
414 for (int yi=1;yi<=prod->GetNbinsY();yi++) {
415 double c_rel = h2d->GetBinContent(xi,yi); // 1/Rrel = RMC/Rdata
416 prod->SetBinContent(xi,yi,c_rel*inv_R_abs);
417 }
418 }
419 return prod;
420}
421
422std::unique_ptr<const TH2> InsituDataCorrection::invertHistogram(const TH2* h2d){
423 std::unique_ptr<TH2> inv(static_cast<TH2*>(h2d->Clone()));
424 for (int xi=1;xi<=inv->GetNbinsX();xi++) {
425 for (int yi=1;yi<=inv->GetNbinsY();yi++) {
426 inv->SetBinContent(xi,yi,1./h2d->GetBinContent(xi,yi));
427
428 }
429 }
430 return inv;
431}
Scalar eta() const
pseudorapidity method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Header file for AthHistogramAlgorithm.
double getInsituCorr_JMS(double pt, double mass, double eta, const std::string &calibstep, bool isTAmass) const
std::unique_ptr< const TH2 > m_insituCorr_JMS_TA
std::unique_ptr< const TH2 > invertHistogram(const TH2 *h2d)
std::unique_ptr< const TH2 > m_insituCorr_ResidualMCbased
std::unique_ptr< const TH2 > combineCalibration(const TH2 *h2d, const TH1 *h)
virtual StatusCode initialize() override
virtual ~InsituDataCorrection()
std::unique_ptr< const TH2 > m_insituCorr_JMS
virtual StatusCode calibrate(xAOD::Jet &jet, JetEventInfo &jetEventInfo) const override
std::unique_ptr< const TH2 > m_insituCorr
double getInsituCorr(double pt, double eta, const std::string &calibstep) const
virtual StatusCode setStartP4(xAOD::Jet &jet) const
JetCalibrationStep(const char *name="JetCalibrationStep")
UInt_t runNumber()
std::unique_ptr< const TH2 > GetHisto2(TFile &file, const TString &hname)
std::unique_ptr< const TH1 > GetHisto(TFile &file, const TString &hname)
STL namespace.
Jet_v1 Jet
Definition of the current "jet version".
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition JetTypes.h:17