ATLAS Offline Software
Loading...
Searching...
No Matches
JetCalibTools_SmearingPlots.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include "xAODJet/Jet.h"
10
13
15
16#include <vector>
17#include <ctime>
18#include "TString.h"
19#include "TH1D.h"
20#include "TF1.h"
21#include "TCanvas.h"
22#include "TLatex.h"
23#include "TRandom3.h"
24
25
26namespace jet
27{
36 class JetFourMomAccessor: public xAOD::JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> {
37 public:
38 using xAOD::JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t>::AccessorWrapper;
39 xAOD::JetFourMom_t operator()(const xAOD::Jet & jet) const {return const_cast<JetFourMomAccessor*>(this)->getAttribute(jet);}
40 };
41}
42
43int main (int argc, char* argv[])
44{
45 // Check argument usage
46 if (argc < 5 || argc > 7)
47 {
48 std::cout << "USAGE: " << argv[0] << " <JetCollection> <ConfigFile> <OutputFile> <isData> (dev mode switch) (timing test switch)" << std::endl;
49 return 1;
50 }
51
52 // Store the arguments
53 const TString jetAlgo = argv[1];
54 const TString config = argv[2];
55 const TString outFile = argv[3];
56 const bool isData = (TString(argv[4]) == "true");
57 const bool isDevMode = argc > 5 && (TString(argv[5]) == "true" || TString(argv[5]) == "dev");
58 const bool isTimeTest = argc > 6 && TString(argv[6]) == "true";
59
60 // Derived information
61 const bool outFileIsExtensible = outFile.EndsWith(".pdf") || outFile.EndsWith(".ps");
62 const bool outFileIsRoot = outFile.EndsWith(".root");
63
64 // Assumed constants
65 const TString calibSeq = "Smear"; // only want to apply the smearing correction here
66 const std::vector<float> ptVals = {20, 40, 60, 100, 400, 1000};
67 const float eta = 0.202;
68 const float phi = 0;
69 const float mass = 10;
70 const int maxNumIter = 1e5;
71 const int numTimeIter = 100;
72
73 // Accessor strings
74 const TString startingScaleString = "JetGSCScaleMomentum";
75 const TString endingScaleString = "JetSmearedMomentum";
76
77 // Accessors
78 jet::JetFourMomAccessor startingScale(startingScaleString.Data());
79 jet::JetFourMomAccessor endingScale(endingScaleString.Data());
80
81 // Create the calib tool
83 calibTool.setTypeAndName("JetCalibrationTool/MyJetCalibTool");
84 {
85 if (calibTool.initialize().isFailure())
86 {
87 std::cout << "Failed to make ana tool" << std::endl;
88 return 2;
89 }
90 if (calibTool.setProperty("JetCollection",jetAlgo.Data()).isFailure())
91 {
92 std::cout << "Failed to set JetCollection: " << jetAlgo.Data() << std::endl;
93 return 3;
94 }
95 if (calibTool.setProperty("ConfigFile",config.Data()).isFailure())
96 {
97 std::cout << "Failed to set ConfigFile: " << config.Data() << std::endl;
98 return 3;
99 }
100 if (calibTool.setProperty("CalibSequence",calibSeq.Data()).isFailure())
101 {
102 std::cout << "Failed to set CalibSequence: " << calibSeq.Data() << std::endl;
103 return 3;
104 }
105 if (calibTool.setProperty("IsData",isData).isFailure())
106 {
107 std::cout << "Failed to set IsData: " << (isData ? std::string("true") : std::string("false")) << std::endl;
108 return 3;
109 }
110 if (isDevMode && calibTool.setProperty("DEVmode",isDevMode).isFailure())
111 {
112 std::cout << "Failed to set DEVmode" << std::endl;
113 return 4;
114 }
115 if (calibTool.retrieve().isFailure())
116 {
117 std::cout << "Failed to initialize the JetCalibTool" << std::endl;
118 return 5;
119 }
120 }
121
122 // Build a jet container and a jet for us to manipulate later
123 xAOD::TEvent event;
124 xAOD::TStore store;
126 jets->setStore(new xAOD::JetAuxContainer());
127 jets->push_back(new xAOD::Jet());
128 xAOD::Jet* jet = jets->at(0);
129
130
131
132 // Make the histograms to fill
133 std::vector<TH1D*> hists_pt;
134 std::vector<TH1D*> hists_m;
135 for (float pt : ptVals)
136 {
137 const TString baseName = Form("Smear_%.0f",pt);
138 hists_pt.push_back(new TH1D(baseName+"_pT",baseName+"_pT",100,0.25*pt,1.75*pt));
139 hists_m.push_back(new TH1D(baseName+"_mass",baseName+"_mass",100,0.25*mass,1.75*mass));
140 }
141
142 // Run the timing test if specified
143 if (isTimeTest)
144 {
145 TRandom3 rand;
146 rand.SetSeed(0); // Deterministic random test
147
148 for (int numTest = 0; numTest < numTimeIter; ++numTest)
149 {
150 // Make a new calibration tool each time
151 JetCalibrationTool* jetCalibTool = new JetCalibrationTool(Form("mytool_%d",numTest));
152 if (jetCalibTool->setProperty("JetCollection",jetAlgo.Data()).isFailure())
153 return 1;
154 if (jetCalibTool->setProperty("ConfigFile",config.Data()).isFailure())
155 return 1;
156 if (jetCalibTool->setProperty("CalibSequence",calibSeq.Data()).isFailure())
157 return 1;
158 if (jetCalibTool->setProperty("IsData",isData).isFailure())
159 return 1;
160 if (isDevMode && jetCalibTool->setProperty("DEVmode",isDevMode).isFailure())
161 return 1;
162 if (jetCalibTool->initialize().isFailure())
163 return 1;
164
165 clock_t startTime = clock();
166 for (int numIter = 0; numIter < maxNumIter; ++numIter)
167 {
168 xAOD::JetFourMom_t fourvec(rand.Uniform(20.e3,1000.e3),rand.Uniform(-2,2),rand.Uniform(-3.14,3.14),10.e3);
169 jet->setJetP4(fourvec);
170 startingScale.setAttribute(*jet,fourvec);
171 // Apply calibration
172 if(jetCalibTool->modify(*jets).isFailure())
173 return 1;
174 }
175 delete jetCalibTool;
176 printf("Iteration %d: %f seconds\n",numTest+1,(clock()-startTime)/((double)CLOCKS_PER_SEC));
177 }
178 }
179
180 // Fill the histograms
181 for (size_t index = 0; index < ptVals.size(); ++index)
182 {
183 // Get the relevant vector entries
184 const float pt = ptVals.at(index);
185 TH1D* hist_pt = hists_pt.at(index);
186 TH1D* hist_m = hists_m.at(index);
187 hist_pt->Sumw2();
188 hist_m->Sumw2();
189
190
191 printf("Running for pT of %.0f\n",pt);
192
193 for (int numIter = 0; numIter < maxNumIter; ++numIter)
194 {
195 // Set the jet four-vector
196 xAOD::JetFourMom_t fourvec(pt*1.e3,eta,phi,mass*1.e3);
197 jet->setJetP4(fourvec);
198 startingScale.setAttribute(*jet,fourvec);
199
200 // Jet kinematics set, now apply the smearing correction
201 if(calibTool->modify(*jets).isFailure())
202 return 1;
203
204 // Ensure the expected scale was written (within 1 MeV, for floating point differences)
205 if (fabs(endingScale(*jet).pt() - jet->pt()) > 1.e-3)
206 {
207 printf("ERROR: mismatch between ending scale (%.3f) and jet pT (%.3f)\n",endingScale(*jet).pt(),jet->pt());
208 return 1;
209 }
210 if (endingScale(*jet).pt() == startingScale(*jet).pt())
211 {
212 // This can happen (smearing factor can be exactly 1), but it should be rare
213 printf("WARNING: starting and ending scales are identical: %.3f\n",endingScale(*jet).pt());
214 }
215
216 // Fill the histograms
217 hist_pt->Fill(jet->pt()/1.e3);
218 hist_m->Fill(jet->m()/1.e3);
219 }
220 }
221
222
223 // Get the nominal resolution
224 printf("Getting nominal resolutions\n");
225 TH1D nominalResData("NominalResData","NominalResData",1000,20,2020);
226 TH1D nominalResMC( "NominalResMC", "NominalResMC", 1000,20,2020);
227 for (Long64_t binX = 1; binX < nominalResData.GetNbinsX()+1; ++binX)
228 {
229 // Set the jet four-vector
230 const float pt = nominalResData.GetXaxis()->GetBinCenter(binX);
231 xAOD::JetFourMom_t fourvec(pt*1.e3,eta,phi,mass*1.e3);
232 jet->setJetP4(fourvec);
233
234 // Jet kinematics set, now get the nominal resolutions
235 double resolution = 0;
236 if (calibTool->getNominalResolutionData(*jet,resolution).isFailure())
237 {
238 printf("ERROR: Failed to get nominal data resolution\n");
239 return 1;
240 }
241 nominalResData.SetBinContent(binX,resolution);
242 if (calibTool->getNominalResolutionMC(*jet,resolution).isFailure())
243 {
244 printf("ERROR: Failed to get nominal MC resolution\n");
245 return 1;
246 }
247 nominalResMC.SetBinContent(binX,resolution);
248 }
249
250
251 // Make the plots
252 // First the canvas
253 TCanvas* canvas = new TCanvas("canvas");
254 canvas->SetMargin(0.07,0.13,0.1,0.10);
255 canvas->SetFillStyle(4000);
256 canvas->SetFillColor(0);
257 canvas->SetFrameBorderMode(0);
258 canvas->cd();
259
260 // Make the fits
261 std::vector<TF1*> fits_pt;
262 std::vector<TF1*> fits_m;
263 for (size_t index = 0; index < hists_pt.size(); ++index)
264 {
265 TH1D* hist_pt = hists_pt.at(index);
266 TH1D* hist_m = hists_m.at(index);
267
268 TF1* fit_pt = new TF1(Form("fitPt_%zu",index),"gaus");
269 TF1* fit_m = new TF1(Form("fitMass_%zu",index),"gaus");
270
271 hist_pt->Fit(fit_pt,"E");
272 hist_m->Fit(fit_m,"E");
273
274 fits_pt.push_back(fit_pt);
275 fits_m.push_back(fit_m);
276 }
277
278 // Set plot labels
279 for (TH1D* hist : hists_pt)
280 {
281 hist->SetStats(false);
282 hist->GetXaxis()->SetTitle("Jet #it{p}_{T} [GeV]");
283 hist->GetXaxis()->SetTitleOffset(1.35);
284 hist->GetYaxis()->SetTitle("Number of events");
285 hist->GetYaxis()->SetTitleOffset(0.9);
286 }
287 for (TH1D* hist : hists_m)
288 {
289 hist->SetStats(false);
290 hist->GetXaxis()->SetTitle("Jet mass [GeV]");
291 hist->GetXaxis()->SetTitleOffset(1.35);
292 hist->GetYaxis()->SetTitle("Number of events");
293 hist->GetYaxis()->SetTitleOffset(0.9);
294 }
295
296 // Prepare to add labels
297 TLatex tex;
298 tex.SetNDC();
299 tex.SetTextFont(42);
300 tex.SetTextSize(0.04);
301
302 // Prepare to write out
303 if (outFileIsExtensible)
304 {
305 canvas->Print(outFile+"[");
306
307 // Nominal resolutions
308 canvas->SetLogx(true);
309 nominalResData.Draw();
310 canvas->Print(outFile);
311 nominalResMC.Draw();
312 canvas->Print(outFile);
313 canvas->SetLogx(false);
314
315 // Smearing plots
316 for (size_t index = 0; index < hists_pt.size(); ++index)
317 {
318 hists_pt.at(index)->Draw("pe");
319 tex.DrawLatex(0.70,0.9,"Gaussian fit results");
320 tex.DrawLatex(0.70,0.85,Form("#mu = %.0f GeV",fits_pt.at(index)->GetParameter(1)));
321 tex.DrawLatex(0.70,0.80,Form("#sigma = %.1f GeV",fits_pt.at(index)->GetParameter(2)));
322 tex.DrawLatex(0.70,0.75,Form("#mu/#sigma = %.1f%%",fits_pt.at(index)->GetParameter(2)/fits_pt.at(index)->GetParameter(1)*100));
323 canvas->Print(outFile);
324
325 hists_m.at(index)->Draw("pe");
326 tex.DrawLatex(0.70,0.9,"Gaussian fit results");
327 tex.DrawLatex(0.70,0.85,Form("#mu = %.0f GeV",fits_m.at(index)->GetParameter(1)));
328 tex.DrawLatex(0.70,0.80,Form("#sigma = %.1f GeV",fits_m.at(index)->GetParameter(2)));
329 tex.DrawLatex(0.70,0.75,Form("#mu/#sigma = %.1f%%",fits_m.at(index)->GetParameter(2)/fits_m.at(index)->GetParameter(1)*100));
330 canvas->Print(outFile);
331 }
332 canvas->Print(outFile+"]");
333 }
334 else if (outFileIsRoot)
335 {
336 TFile* outRootFile = new TFile(outFile,"RECREATE");
337 std::cout << "Writing to output ROOT file: " << outFile << std::endl;
338 outRootFile->cd();
339
340 // Nominal resolutions
341 nominalResData.Write();
342 nominalResMC.Write();
343
344 // Smearing plots
345 for (size_t index = 0; index < hists_pt.size(); ++index)
346 {
347 hists_pt.at(index)->Write();
348 hists_m.at(index)->Write();
349 }
350 outRootFile->Close();
351 }
352 else
353 {
354 unsigned int counter = 1;
355
356 // Nominal resolutions
357 canvas->SetLogx(true);
358 nominalResData.Draw();
359 canvas->Print(Form("%u-%s",counter++,outFile.Data()));
360 nominalResMC.Draw();
361 canvas->Print(Form("%u-%s",counter++,outFile.Data()));
362 canvas->SetLogx(false);
363
364 // Smearing plots
365 for (size_t index = 0; index < hists_pt.size(); ++index)
366 {
367 hists_pt.at(index)->Draw("pe");
368 canvas->Print(Form("%u-%s",counter,outFile.Data()));
369
370 hists_m.at(index)->Draw("pe");
371 canvas->Print(Form("%u-%s",counter++,outFile.Data()));
372 }
373 }
374
375
376 return 0;
377}
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
virtual StatusCode modify(xAOD::JetContainer &jets) const override final
Apply calibration to a jet container (for IJetModifier interface).
StatusCode initialize() override
Dummy implementation of the initialisation function.
an "initializing" ToolHandle for stand-alone applications
StatusCode setProperty(const std::string &name, T2 &&value)
StatusCode retrieve()
initialize the tool, will succeed if the tool was already initialized
void setTypeAndName(const std::string &typeAndName)
StatusCode initialize()
initialize the tool, will fail if the tool was already initialized
JetFourMomAccessor is an extension of JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> Acces...
xAOD::JetFourMom_t operator()(const xAOD::Jet &jet) const
void getAttribute(const SG::AuxElement &p, xAOD::JetFourMom_t &v) const
void setAttribute(SG::AuxElement &p, const TYPE &v) const
Tool for accessing xAOD files outside of Athena.
A relatively simple transient store for objects created in analysis.
Definition TStore.h:45
int main()
Definition hello.cxx:18
Definition index.py:1
Jet_v1 Jet
Definition of the current "jet version".
JetAuxContainer_v1 JetAuxContainer
Definition of the current jet auxiliary container.
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