ATLAS Offline Software
fbtTestBasics.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 // System include(s):
6 #include <fstream>
7 #include <map>
8 #include <memory>
9 #include <getopt.h>
10 
11 // ROOT include(s):
12 #include <TSystem.h>
13 #include <TError.h>
14 #include <TFile.h>
15 #include <TH1F.h>
16 
17 #ifdef XAOD_STANDALONE
18 #include "xAODRootAccess/Init.h"
19 #include "xAODRootAccess/TEvent.h"
20 #include "xAODRootAccess/TStore.h"
21 #else
22 #include "POOLRootAccess/TEvent.h"
23 #endif
24 
25 #include "AsgTools/AnaToolHandle.h"
28 #include "xAODEgamma/Electron.h"
29 #include "xAODMuon/Muon.h"
34 
35 bool successful(bool arg) { return arg; }
36 bool successful(int arg);
37 bool successful(const StatusCode& arg) { return arg == StatusCode::SUCCESS; }
38 
39 #define FBT_CHECK(x) \
40  while(true) { \
41  if(successful(x)) break; \
42  Error("fbtTestBasics", "%s", ("failure encounted on l." + std::to_string(__LINE__)).c_str()); \
43  return false; \
44  }
45 
46 struct Result
47 {
48  float value = 0, statUp = 0, statDown = 0;
49  std::map<CP::SystematicVariation, float> variations;
50  bool operator==(const Result&) const;
51  void Print() const;
52 };
53 
54 bool allTests();
55 bool minimalTest(const std::string& type, Result& result);
56 bool parallelJob(const std::string& type, const std::string& saveAs);
57 bool readFromROOT();
58 bool readFromXML();
59 
60 template<class Interface = CP::IFakeBkgTool> bool setup(asg::AnaToolHandle<Interface>& tool, const std::string& type);
61 template<class Interface = CP::IFakeBkgTool> bool eventLoop(asg::AnaToolHandle<Interface>& tool, Result& result);
64 template<class Interface = CP::IFakeBkgTool> bool fillResult(asg::AnaToolHandle<Interface>& tool, Result& result);
65 
66 #ifdef XAOD_STANDALONE
67 std::unique_ptr<xAOD::TStore> store;
68 #else
69 StoreGateSvc* store = nullptr;
70 #endif
71 
72 std::vector<std::string> config;
73 std::string selection = ">=1T";
74 std::string process = ">=1F[T]";
75 bool readCPVariations = true;
76 int eventOffset = 0;
77 int nEvents = 48;
78 std::string progressFile = "";
79 
80 bool verbose = false;
81 
82 int main(int argc, char* argv[])
83 {
84  for(int i=1;i<argc;++i)
85  {
86  std::string option = argv[i];
87  if(option=="-v" || option=="--verbose") verbose = true;
88  }
89 
90 #ifdef XAOD_STANDALONE
91  xAOD::Init("fbtTestBasics").ignore();
93  store = std::make_unique<xAOD::TStore>();
94  StatusCode::enableFailure();
95 #else
96  IAppMgrUI* app = POOL::Init();
98  FBT_CHECK( event.evtStore().retrieve() );
99  store = event.evtStore().get();
100 #endif
101 
102  int returnCode = allTests() ? 0 : 1;
103 
104 #ifndef XAOD_STANDALONE
105  FBT_CHECK( app->finalize() );
106 #endif
107  return returnCode;
108 }
109 
110 bool allTests()
111 {
112 
113  Result result0, result1, result2, result3, result4, result5;
114 
115  if(verbose) std::cout <<"\nWill do minimal test with CP::ApplyFakeFactor\n";
116  FBT_CHECK( readFromROOT() );
117  FBT_CHECK( minimalTest("CP::ApplyFakeFactor", result0) );
118 
119  if(verbose) std::cout <<"\nWill do minimal test with CP::AsymptMatrixTool\n";
120  FBT_CHECK( minimalTest("CP::AsymptMatrixTool", result1) );
121 
122  if(verbose) std::cout <<"\nWill do minimal test with CP::LhoodMM_tools\n";
123  FBT_CHECK( minimalTest("CP::LhoodMM_tools", result2) );
124 
125  if(verbose) std::cout <<"\nWill test loading efficiencies from XML\n";
126  FBT_CHECK( readFromXML() );
127  FBT_CHECK( minimalTest("CP::AsymptMatrixTool", result3) );
128  FBT_CHECK( readFromROOT() );
129  FBT_CHECK( result1 == result3 );
130 
131  if(verbose) std::cout <<"\nWill test getEventWeight()\n";
132  {
134  FBT_CHECK( setup(tool, "CP::AsymptMatrixTool") );
135  FBT_CHECK( eventLoop(tool, result4) );
136  if(verbose) result3.Print();
137  }
138  FBT_CHECK( result1 == result4 );
139 
140  if(verbose) std::cout <<"\nWill test parallel jobs and merging\n";
141  eventOffset = 0;
142  nEvents = 16;
143  FBT_CHECK( parallelJob("CP::LhoodMM_tools", "fbt_job1.root") );
144  eventOffset = 16;
145  FBT_CHECK( parallelJob("CP::LhoodMM_tools", "fbt_job2.root") );
146  eventOffset = 32;
147  FBT_CHECK( parallelJob("CP::LhoodMM_tools", "fbt_job3.root") );
148  eventOffset = 0;
149  FBT_CHECK( gSystem->Exec("hadd -f fbt_merged.root fbt_job*.root") == 0 );
150  {
152  progressFile = "fbt_merged.root";
153  FBT_CHECK( setup(tool, "CP::LhoodMM_tools") );
154  progressFile.clear();
155  FBT_CHECK( fillResult(tool, result5) );
156  }
157  FBT_CHECK(result2 == result5 );
158 
159  return true;
160 }
161 
162 bool minimalTest(const std::string& type, Result& result)
163 {
165  FBT_CHECK( setup(tool, type) );
168  return true;
169 }
170 
171 bool parallelJob(const std::string& type, const std::string& saveAs)
172 {
174  FBT_CHECK( setup(tool, type) );
175  Result result;
177  std::unique_ptr<TFile> f(TFile::Open(saveAs.c_str(), "RECREATE"));
178  FBT_CHECK( !!f );
179  FBT_CHECK( tool->saveProgress(f->mkdir("fakes")) );
180  f->Close();
181  if(verbose)
182  {
183  float value, up, down;
184  FBT_CHECK( tool->getTotalYield(value, up, down) );
185  std::cout << "Parallel job stored intermediate yield " << value << " +" << up << " -" << down << std::endl;
186  }
187  return true;
188 }
189 
190 static long instance = 0;
191 
192 template<class Interface>
193 bool setup(asg::AnaToolHandle<Interface>& tool, const std::string& type)
194 {
196  FBT_CHECK( tool.setProperty("InputFiles", config) );
197  FBT_CHECK( tool.setProperty("EnergyUnit", "GeV") );
198  FBT_CHECK( tool.setProperty("ConvertWhenMissing", true) );
199  FBT_CHECK( tool.setProperty("Selection", selection) );
200  FBT_CHECK( tool.setProperty("Process", process) );
201  if(progressFile.size())
202  {
203  FBT_CHECK( tool.setProperty("ProgressFileName", progressFile) );
204  FBT_CHECK( tool.setProperty("ProgressFileDirectory", "fakes") );
205  }
206  FBT_CHECK( tool.initialize() );
207  return true;
208 
209 }
210 
211 template<class Interface>
213 {
214  auto eventInfo = std::make_unique<xAOD::EventInfo>();
215  auto eventAuxInfo = std::make_unique<xAOD::EventAuxInfo>();
216  eventInfo->setStore(eventAuxInfo.get());
217  eventInfo->auxdata<int>("flag") = 1;
218  FBT_CHECK( store->record(std::move(eventInfo), "EventInfo") );
219  FBT_CHECK( store->record(std::move(eventAuxInfo), "EventInfoAux.") );
220 
222  auto e = std::make_unique<xAOD::Electron>();
223  e->makePrivateStore();
224  e->setCharge(1);
225  particles.push_back(static_cast<xAOD::IParticle*>(&*e));
226  for(int i=eventOffset;i<nEvents+eventOffset;++i)
227  {
228  e->setP4((1 + (i%3))*1e4, 0., 0. ,0.511);
229  e->auxdecor<char>("Tight") = (i%4)? 0 : 1;
230  FBT_CHECK( tool->addEvent(particles) );
232  }
233 
234 #ifdef XAOD_STANDALONE
235  store->clear();
236 #else
237  FBT_CHECK( store->clearStore(true) );
238 #endif
239  return true;
240 }
241 
243 {
244  FBT_CHECK( tool->applySystematicVariation({}) );
245  float y;
246  FBT_CHECK( tool->getEventWeight(y, selection, process) );
247  result.value += y;
248  result.statUp = sqrt(pow(result.statUp, 2) + y*y);
249  result.statDown = sqrt(pow(result.statDown, 2) + y*y);
250  for(auto& sysvar : tool->affectingSystematics())
251  {
252  FBT_CHECK( tool->applySystematicVariation({sysvar}) );
253  FBT_CHECK( tool->getEventWeight(y, selection, process) );
254  result.variations[sysvar] += y;
255  }
256  return true;
257 }
258 
260 {
261  return true;
262 }
263 
264 template<class Interface>
266 {
267  result.variations.clear();
268  FBT_CHECK( tool->getTotalYield(result.value, result.statUp, result.statDown) );
269  if(readCPVariations)
270  {
271  for(auto& sysvar : tool->affectingSystematics())
272  {
273  FBT_CHECK( tool->applySystematicVariation({sysvar}) );
274  float unused;
275  FBT_CHECK( tool->getTotalYield(result.variations[sysvar], unused, unused) );
276  }
277  }
278  if(verbose) result.Print();
279  return true;
280 }
281 
282 bool Result::operator==(const Result& rhs) const
283 {
284  auto compare = [&](auto x1, auto x2) -> bool
285  {
286  bool closeEnough = std::fabs(x1 - x2) < std::max(1e-5, 1e-3 * std::min(std::fabs(x1), std::fabs(x2)));;
287  if(!closeEnough)
288  {
289  std::cout << "ERROR: found different values for the equality test: " << x1 << " vs " << x2 << std::endl;
290  }
291  return closeEnough;
292  };
293  FBT_CHECK( compare(value, rhs.value) );
294  FBT_CHECK( compare(statUp, rhs.statUp) );
296  FBT_CHECK( variations.size() == rhs.variations.size() );
297  for(auto& kv : variations)
298  {
299  auto itr = rhs.variations.find(kv.first);
300  FBT_CHECK( itr != rhs.variations.end() );
301  FBT_CHECK( compare(kv.second, itr->second) );
302  }
303  return true;
304 }
305 
306 void Result::Print() const
307 {
308  std::cout << "Result: total yield = " << value << " +" << statUp << " -" << statDown << std::endl;
309  for(auto& kv : variations)
310  {
311  std::cout << " variation " << kv.first.name() << " = " << kv.second << std::endl;
312  }
313 }
314 
316 {
317  config.clear();
318  config.emplace_back("fbt_efficiencies.root");
319  TH1D hElFake("FakeEfficiency_el_pt","FakeEfficiency", 1, 10., 100.);
320  hElFake.SetBinContent(1, 0.05);
321  hElFake.SetBinError(1, 0.01);
322  TH1D hMuFake("FakeEfficiency_mu_pt","FakeEfficiency", 1, 10., 100.);
323  hMuFake.SetBinContent(1, 0.15);
324  hMuFake.SetBinError(1, 0.032);
325  TH1D hElReal("RealEfficiency_el_pt","RealEfficiency", 1, 10., 100.);
326  hElReal.SetBinContent(1, 0.90);
327  hElReal.SetBinError(1, 0.01);
328  TH1D hMuReal("RealEfficiency_mu_pt","RealEfficiency", 1, 10., 100.);
329  hMuReal.SetBinContent(1, 0.95);
330  hMuReal.SetBinError(1, 0.01);
331  std::unique_ptr<TFile> f(TFile::Open(config.back().c_str(), "RECREATE"));
332  FBT_CHECK( !!f );
333  f->cd();
334  hElFake.Write();
335  hElReal.Write();
336  hMuFake.Write();
337  hMuReal.Write();
338  f->Close();
339  return true;
340 }
341 
343 {
344  config.clear();
345  config.emplace_back("fbt_efficiencies.xml");
346  std::ofstream out(config.back().c_str(), std::ios_base::out);
347  FBT_CHECK( out.is_open() );
350  out << "<efficiencies>\n";
351  out << "<param type=\"int\" level=\"event\"> flag </param>\n";
352  out << "<electron type=\"fake-efficiency\" input=\"central-value\" stat=\"per-bin\" >\n\t<bin flag=\"1\">\n 0.05 +- 0.01 (stat) </bin>\n</electron>\n";
353  out << "<electron type=\"real-efficiency\" input=\"central-value\" stat=\"global\" >\n\t<bin flag=\"1\">\n 0.90 +- 0.01 (stat) </bin>\n</electron>\n";
354  out << "<muon type=\"fake-efficiency\" input=\"central-value\" stat=\"per-bin\" >\n\t<bin flag=\"1\">\n 0.15 +- 0.032 (stat) </bin>\n</muon>\n";
355  out << "<muon type=\"real-efficiency\" input=\"central-value\" stat=\"global\" >\n\t<bin flag=\"1\">\n 0.95 +- 0.01 (stat) </bin>\n</muon>\n";
356  out << "</efficiencies>\n";
357  out.close();
358  return true;
359 }
parallelJob
bool parallelJob(const std::string &type, const std::string &saveAs)
Definition: fbtTestBasics.cxx:171
StoreGateSvc::record
StatusCode record(T *p2BRegistered, const TKEY &key)
Record an object with a key.
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
Amg::compare
std::pair< int, int > compare(const AmgSymMatrix(N) &m1, const AmgSymMatrix(N) &m2, double precision=1e-9, bool relative=false)
compare two matrices, returns the indices of the first element that fails the condition,...
Definition: EventPrimitivesHelpers.h:109
asg::AnaToolHandle
a modified tool handle that allows its owner to configure new tools from the C++ side
Definition: AnaToolHandle.h:34
get_generator_info.result
result
Definition: get_generator_info.py:21
max
#define max(a, b)
Definition: cfImp.cxx:41
Result::Print
void Print() const
Definition: fbtTestBasics.cxx:306
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
Muon.h
main
int main(int argc, char *argv[])
Definition: fbtTestBasics.cxx:82
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
Result::variations
std::map< CP::SystematicVariation, float > variations
Definition: fbtTestBasics.cxx:49
TH1D
Definition: rootspy.cxx:342
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
athena.value
value
Definition: athena.py:122
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
xAOD::TEvent::kClassAccess
@ kClassAccess
Access auxiliary data using the aux containers.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:97
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
successful
bool successful(bool arg)
Definition: fbtTestBasics.cxx:35
config
Definition: PhysicsAnalysis/AnalysisCommon/AssociationUtils/python/config.py:1
POOL::Init
IAppMgrUI * Init(const char *options="POOLRootAccess/basic.opts")
Bootstraps (creates and configures) the Gaudi Application with the provided options file.
Definition: PhysicsAnalysis/POOLRootAccess/src/TEvent.cxx:29
minimalTest
bool minimalTest(const std::string &type, Result &result)
Definition: fbtTestBasics.cxx:162
FBT_CHECK
#define FBT_CHECK(x)
Definition: fbtTestBasics.cxx:39
POOL::TEvent::kClassAccess
@ kClassAccess
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:45
instance
std::map< std::string, double > instance
Definition: Run_To_Get_Tags.h:8
Result::value
float value
Definition: fbtTestBasics.cxx:48
StoreGateSvc
The Athena Transient Store API.
Definition: StoreGateSvc.h:128
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
lumiFormat.i
int i
Definition: lumiFormat.py:92
readFromXML
bool readFromXML()
Definition: fbtTestBasics.cxx:342
PixelAthClusterMonAlgCfg.e4
e4
Definition: PixelAthClusterMonAlgCfg.py:317
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ILinearFakeBkgTool.h
readCPVariations
bool readCPVariations
Definition: fbtTestBasics.cxx:75
process
std::string process
Definition: fbtTestBasics.cxx:74
MessageCheck.h
macros for messaging and checking status codes
TEvent.h
CalibCoolCompareRT.up
up
Definition: CalibCoolCompareRT.py:109
Init.h
nEvents
int nEvents
Definition: fbtTestBasics.cxx:77
progressFile
std::string progressFile
Definition: fbtTestBasics.cxx:78
fillResult
bool fillResult(asg::AnaToolHandle< Interface > &tool, Result &result)
Definition: fbtTestBasics.cxx:265
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
StoreGateSvc::clearStore
virtual StatusCode clearStore(bool forceRemove=false) override final
clear DataStore contents: called by the event loop mgrs
Definition: StoreGateSvc.cxx:461
selection
std::string selection
Definition: fbtTestBasics.cxx:73
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
eventLoop
bool eventLoop(asg::AnaToolHandle< Interface > &tool, Result &result)
Definition: fbtTestBasics.cxx:212
AnaToolHandle.h
verbose
bool verbose
Definition: fbtTestBasics.cxx:80
min
#define min(a, b)
Definition: cfImp.cxx:40
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
readFromROOT
bool readFromROOT()
Definition: fbtTestBasics.cxx:315
EventAuxInfo.h
POOL::TEvent
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:39
TEvent.h
Result
Definition: fbtTestBasics.cxx:47
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
eventOffset
int eventOffset
Definition: fbtTestBasics.cxx:76
POOL::TEvent::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:59
AtlCoolConsole.tool
tool
Definition: AtlCoolConsole.py:453
TH1D::SetBinContent
void SetBinContent(int, double)
Definition: rootspy.cxx:348
Result::statDown
float statDown
Definition: fbtTestBasics.cxx:48
EventInfo.h
addEventWeight
bool addEventWeight(asg::AnaToolHandle< CP::ILinearFakeBkgTool > &tool, Result &result)
Definition: fbtTestBasics.cxx:242
allTests
bool allTests()
Definition: fbtTestBasics.cxx:110
unused
void unused(Args &&...)
Definition: VP1ExpertSettings.cxx:39
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
y
#define y
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
config
std::vector< std::string > config
Definition: fbtTestBasics.cxx:72
LArG4FSStartPointFilter.particles
list particles
Definition: LArG4FSStartPointFilter.py:84
setup
bool setup(asg::AnaToolHandle< Interface > &tool, const std::string &type)
mostly useful for athena, which will otherwise re-use the previous tool
Definition: fbtTestBasics.cxx:193
Electron.h
CI_EMPFlowData22test.returnCode
returnCode
Definition: CI_EMPFlowData22test.py:16
TStore.h
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:81
Result::statUp
float statUp
Definition: fbtTestBasics.cxx:48
IFakeBkgTool.h
Result::operator==
bool operator==(const Result &) const
Definition: fbtTestBasics.cxx:282
AuxElement.h
Base class for elements of a container that can have aux data.
xAOD::Init
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition: Init.cxx:31