ATLAS Offline Software
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"
8 #include "xAODJet/JetContainer.h"
10 
11 #include "xAODRootAccess/TEvent.h"
12 #include "xAODRootAccess/TStore.h"
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 
26 namespace jet
27 {
36  class JetFourMomAccessor: public xAOD::JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> {
37  public:
39  xAOD::JetFourMom_t operator()(const xAOD::Jet & jet) const {return const_cast<JetFourMomAccessor*>(this)->getAttribute(jet);}
40  };
41 }
42 
43 int 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
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 }
SGTest::store
TestStore store
Definition: TestStore.cxx:23
Jet.h
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:67
Base_Fragment.mass
mass
Definition: Sherpa_i/share/common/Base_Fragment.py:59
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
index
Definition: index.py:1
xAOD::JetAttributeAccessor::AccessorWrapper::setAttribute
void setAttribute(SG::AuxElement &p, const TYPE &v) const
Definition: JetAccessors.h:54
muonBucketDump.outRootFile
outRootFile
Definition: muonBucketDump.py:7
plotmaker.hist
hist
Definition: plotmaker.py:148
lumiFormat.startTime
startTime
Definition: lumiFormat.py:95
test_pyathena.pt
pt
Definition: test_pyathena.py:11
xAOD::JetAttributeAccessor::AccessorWrapper< xAOD::JetFourMom_t >::getAttribute
void getAttribute(const SG::AuxElement &p, xAOD::JetFourMom_t &v) const
Definition: JetAccessors.h:58
JetCalibrationTool::initialize
StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: JetCalibrationTool.cxx:54
Dedxcorrection::resolution
double resolution[nGasTypes][nParametersResolution]
Definition: TRT_ToT_Corrections.h:46
IJetCalibrationTool::getNominalResolutionMC
virtual StatusCode getNominalResolutionMC(const xAOD::Jet &, double &) const
Definition: IJetCalibrationTool.h:40
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
xAOD::JetAuxContainer_v1
Temporary container used until we have I/O for AuxStoreInternal.
Definition: JetAuxContainer_v1.h:37
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
JetCalibrationTool.h
asg::StandaloneToolHandle::initialize
StatusCode initialize()
initialize the tool, will fail if the tool was already initialized
Definition: StandaloneToolHandle.h:158
CheckAppliedSFs.e3
e3
Definition: CheckAppliedSFs.py:264
jet::JetFourMomAccessor::operator()
xAOD::JetFourMom_t operator()(const xAOD::Jet &jet) const
Definition: JetCalibTools_SmearingPlots.cxx:39
LArG4FSStartPointFilter.rand
rand
Definition: LArG4FSStartPointFilter.py:80
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
asg::StandaloneToolHandle::setProperty
StatusCode setProperty(const std::string &name, T2 &&value)
Definition: StandaloneToolHandle.h:105
asg::StandaloneToolHandle
an "initializing" ToolHandle for stand-alone applications
Definition: StandaloneToolHandle.h:44
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
DeMoAtlasDataLoss.canvas
dictionary canvas
Definition: DeMoAtlasDataLoss.py:187
JetCalibrationTool
Definition: JetCalibrationTool.h:34
TEvent.h
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
jet::JetFourMomAccessor
JetFourMomAccessor is an extension of JetAttributeAccessor::AccessorWrapper<xAOD::JetFourMom_t> Acces...
Definition: JetCalibTools_PlotJESFactors.cxx:32
Trk::binX
@ binX
Definition: BinningType.h:47
IJetCalibrationTool::modify
virtual StatusCode modify(xAOD::JetContainer &jets) const override final
Apply calibration to a jet container (for IJetModifier interface).
Definition: IJetCalibrationTool.h:33
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
asg::StandaloneToolHandle::retrieve
StatusCode retrieve()
initialize the tool, will succeed if the tool was already initialized
Definition: StandaloneToolHandle.h:147
DQPostProcessTest.outFile
outFile
Comment Out Those You do not wish to run.
Definition: DQPostProcessTest.py:37
xAOD::JetFourMom_t
ROOT::Math::LorentzVector< ROOT::Math::PtEtaPhiM4D< double > > JetFourMom_t
Base 4 Momentum type for Jet.
Definition: JetTypes.h:17
asg::StandaloneToolHandle::setTypeAndName
void setTypeAndName(const std::string &typeAndName)
Definition: StandaloneToolHandle.h:101
xAOD::Jet_v1
Class describing a jet.
Definition: Jet_v1.h:57
DeMoScan.index
string index
Definition: DeMoScan.py:364
xAOD::TStore
A relatively simple transient store for objects created in analysis.
Definition: TStore.h:44
JetContainer.h
xAOD::JetAttributeAccessor::AccessorWrapper
Definition: JetAccessors.h:49
JetAuxContainer.h
main
int main(int argc, char *argv[])
Definition: JetCalibTools_SmearingPlots.cxx:43
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
xAOD::JetContainer
JetContainer_v1 JetContainer
Definition of the current "jet container version".
Definition: JetContainer.h:17
StandaloneToolHandle.h
IJetCalibrationTool::getNominalResolutionData
virtual StatusCode getNominalResolutionData(const xAOD::Jet &, double &) const
Definition: IJetCalibrationTool.h:39
test_pyathena.counter
counter
Definition: test_pyathena.py:15
TStore.h
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:84