ATLAS Offline Software
PhysicsAnalysis/D3PDTools/EventLoopTest/Root/UnitTest.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 
7 
8 //
9 // includes
10 //
11 
12 #include <EventLoopTest/UnitTest.h>
13 
14 #include <EventLoop/Driver.h>
15 #include <EventLoop/Job.h>
16 #include <EventLoop/MessageCheck.h>
17 #include <EventLoop/OutputStream.h>
19 #include <RootCoreUtils/Assert.h>
20 #include <RootCoreUtils/ThrowMsg.h>
27 #include <TFile.h>
28 #include <TH1.h>
29 #include <TSystem.h>
30 #include <cstdlib>
31 #include <iostream>
32 #include <memory>
33 #include <sstream>
34 
35 using namespace EL::msgEventLoop;
36 
37 //
38 // method implementations
39 //
40 
41 namespace EL
42 {
44  UnitTest (const std::string& val_name, std::string val_base_path)
45  : name (val_name), base_path (val_base_path), cleanup (true), testOutput (true), outputDisk (0),
46  testFileExecute (true)
47  {
48  if (base_path.empty())
49  base_path = "$ROOTCOREBIN/data/EventLoop/";
50  }
51 
52 
53 
55  run (const Driver& driver) const
56  {
57  std::vector<std::string> files;
58  std::vector<TH1*> histos;
59 
60  for (unsigned iter = 0, end = 3; iter != end; ++ iter)
61  {
62  std::ostringstream path;
63  path << base_path << "test_ntuple" << iter << ".root";
64  TString input = path.str();
65  gSystem->ExpandPathName (input);
66  files.push_back (input.Data());
67  std::unique_ptr<TFile> file (TFile::Open (input.Data(), "READ"));
68  RCU_ASSERT_SOFT (file.get() != 0);
69  TH1 *hist = dynamic_cast<TH1*>(file->Get ("hist_n"));
70  RCU_ASSERT_SOFT (hist != 0);
71  histos.push_back(hist);
72  hist->SetDirectory (0);
73  };
74  std::string tree ("physics");
75 
76 
77  SH::SampleHandler samples;
78 
79  std::vector<std::unique_ptr<SH::Sample> > mysamples;
80  if (gridInput)
81  {
82  std::unique_ptr<SH::SampleGrid> mysample;
83  mysample.reset (new SH::SampleGrid ("user.krumnack:user.krumnack.EventLoopTest.2019-03-25.dataset0"));
84  mysample->meta()->setString (SH::MetaFields::gridName, "user.krumnack:user.krumnack.EventLoopTest.2019-03-25.dataset0");
86  mysamples.push_back (std::move (mysample));
87  mysample.reset (new SH::SampleGrid ("user.krumnack:user.krumnack.EventLoopTest.2019-03-25.dataset1"));
88  mysample->meta()->setString (SH::MetaFields::gridName, "user.krumnack:user.krumnack.EventLoopTest.2019-03-25.dataset1");
90  mysamples.push_back (std::move (mysample));
91  } else
92  {
93  std::unique_ptr<SH::SampleLocal> mysample;
94  mysample.reset (new SH::SampleLocal ("dataset0"));
95  mysample->add (files[0]);
96  mysamples.push_back (std::move (mysample));
97  mysample.reset (new SH::SampleLocal ("dataset1"));
98  mysample->add (files[1]);
99  mysample->add (files[2]);
100  mysamples.push_back (std::move (mysample));
101  }
102  {
103  TH1 *hist = 0;
104  hist = dynamic_cast<TH1*>(histos[0]->Clone ("hist"));
105  mysamples[0]->meta()->addReplace (hist);
106 
107  hist = dynamic_cast<TH1*>(histos[1]->Clone ("hist"));
108  hist->Add (histos[2]);
109  mysamples[1]->meta()->addReplace (hist);
110  }
111  for (auto& mysample : mysamples)
112  samples.add (mysample.release());
113 
115 
116  samples.print ();
117 
118  for (unsigned iter = 0, end = histos.size(); iter != end; ++ iter)
119  delete histos[iter];
120 
121  RCU_ASSERT (samples.size() > 0);
122 
123  if (scanNEvents)
124  SH::scanNEvents (samples);
125 
126  TString submitDir;
127  if (location.empty())
128  {
129  submitDir = "EventLoopTest-" + name;
130  } else submitDir = location;
131  gSystem->ExpandPathName (submitDir);
132 
133  try
134  {
136  alg.makeOutput = testOutput;
137 
138  EL::Job job;
139  // job.options()->setDouble (Job::optD3PDPerfStats, 1);
140  job.options()->setDouble ("jobOpt", 42);
141  // job.options()->setDouble (Job::optPerfTree, 1);
142  // job.options()->setDouble (EL::Job::optCacheSize, 10*1024*1024);
143  // job.options()->setDouble (Job::optPrintPerFileStats, 1);
144  {
145  SH::SampleHandler sh = samples;
146  sh.setMetaString ("mymeta", "test");
147  job.sampleHandler (sh);
148  }
149  job.algsAdd (new UnitTestAlg (alg));
150  bool outputDone = outputDisk == 0;
151  for (Job::outputMIter outputStream = job.outputBegin(),
152  end = job.outputEnd(); outputStream != end; ++ outputStream)
153  {
154  if (!outputDone)
155  {
156  outputStream->output (outputDisk);
157  outputDone = true;
158  }
159  }
160 
161  if (!cleanup)
162  ANA_MSG_INFO ("placing temporary files in: " << submitDir);
163  job.options()->setString (Job::optSubmitDirMode, "unique");
164  std::string output = driver.submit (job, submitDir.Data());
165 
166  for (std::size_t iter = 0, end = samples.size(); iter != end; ++ iter)
167  {
168  ANA_MSG_INFO ("looking at sample " << samples[iter]->name());
169  TH1 *ref_hist = dynamic_cast<TH1*>(samples[iter]->meta()->get ("hist"));
170  if (ref_hist != 0)
171  {
173  sh.load ((output + "/hist").c_str());
174  SH::SamplePtr sample = sh.get (samples[iter]->name());
175  if (sample.empty())
176  RCU_THROW_MSG ("could not find histogram sample " + samples[iter]->name());
177 
178  if (testFileExecute)
179  {
180  TH1 *file_executes = dynamic_cast<TH1*>(sample->readHist ("file_executes"));
181  RCU_ASSERT_SOFT (file_executes != 0);
182  ANA_MSG_INFO ("file executes: " << file_executes->GetEntries() << " " << samples[iter]->makeFileList().size());
183  RCU_ASSERT_SOFT (file_executes->GetEntries() == samples[iter]->makeFileList().size());
184  }
185 
186  TH1 *hist = dynamic_cast<TH1*>(sample->readHist ("el_n"));
187  if (samples[iter]->getNumEntries() == 0)
188  {
189  RCU_ASSERT_SOFT (hist == 0);
190  } else
191  {
192  RCU_ASSERT_SOFT (dynamic_cast<TH1*>(sample->readHist ("el_n2")));
193  RCU_ASSERT_SOFT (dynamic_cast<TList*>(sample->readHist ("alpha")));
194  RCU_ASSERT_SOFT (sample->readHist ("beta/dir/hist"));
195  if (hist == 0)
196  RCU_THROW_MSG ("didn't find histogram el_n in sample " + sample->name());
197  if (hist->GetNbinsX() != ref_hist->GetNbinsX())
198  RCU_THROW_MSG ("bin missmatch between histograms");
199  for (int bin = 0, end = hist->GetNbinsX()+2; bin != end; ++ bin)
200  {
201  if (hist->GetBinContent (bin) != ref_hist->GetBinContent (bin))
202  {
203  std::ostringstream str;
204  str << "bin content missmatch in bin " << bin
205  << " found " << hist->GetBinContent (bin)
206  << " expected " << ref_hist->GetBinContent (bin);
207  RCU_THROW_MSG (str.str());
208  }
209  }
210  }
211  TH1 *count = dynamic_cast<TH1*>(sample->readHist ("EventLoop_EventCount"));
212  if (samples[iter]->getNumEntries() > 0 && count == 0)
213  RCU_THROW_MSG ("didn't find histogram EventLoop_EventCount");
214  }
215  if (testOutput && samples[iter]->getNumEntries() > 0)
216  {
218  sh.load ((output + "/output-out").c_str());
219  SH::Sample *const sample = sh.get (samples[iter]->name());
220  if (!sample)
221  RCU_THROW_MSG ("output dataset not found for " + samples[iter]->name());
222  sample->meta()->setString (SH::MetaFields::treeName, "tree");
223  if (ref_hist && samples[iter]->getNumEntries() != ref_hist->GetEntries())
224  {
225  std::ostringstream str;
226  str << "tree entries missmatch found " << samples[iter]->getNumEntries()
227  << " expected " << ref_hist->GetEntries();
228  RCU_THROW_MSG (str.str());
229  }
230  }
231  }
232  if (cleanup)
233  gSystem->Exec (("rm -rf " + output).c_str());
234  return EXIT_SUCCESS;
235  } catch (std::exception& e)
236  {
237  std::cout << "exception caught in unit test: " << e.what() << std::endl;
238  return EXIT_FAILURE;
239  } catch (std::string& e)
240  {
241  std::cout << "exception caught in unit test: " << e << std::endl;
242  return EXIT_FAILURE;
243  } catch (...)
244  {
245  std::cout << "unknown exception caught in unit test" << std::endl;
246  return EXIT_FAILURE;
247  }
248  }
249 }
UnitTest.h
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
SGout2dot.alg
alg
Definition: SGout2dot.py:243
Driver.h
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
SH::SampleHandler::add
void add(Sample *sample)
add a sample to the handler
EL::OutputStream
Definition: OutputStream.h:34
SH::MetaFields::gridFilter_default
static const std::string gridFilter_default
the default value for gridFilter
Definition: MetaFields.h:41
EL::UnitTest::testFileExecute
bool testFileExecute
whether to test the fileExecute method
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:44
Job.h
plotmaker.hist
hist
Definition: plotmaker.py:148
EL::UnitTest::name
std::string name
description: the name of the unit test
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:19
tree
TChain * tree
Definition: tile_monitor.h:30
OutputStream.h
bin
Definition: BinsDiffFromStripMedian.h:43
RunGeantinoStepRecordingITk.outputStream
outputStream
Definition: RunGeantinoStepRecordingITk.py:126
EL::Driver
the base class for the various EventLoop drivers that allow to run jobs on different backends
Definition: Driver.h:28
SH::SampleHandler::size
std::size_t size() const
the number of samples contained
UnitTestAlg.h
EL::UnitTest::base_path
std::string base_path
description: the base path for the data files
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:22
Assert.h
EL::UnitTest::gridInput
bool gridInput
whether to use the inputs from the grid dataset
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:28
SH::SampleHandler::print
void print() const
print the debugging output to the screen
MessageCheck.h
FullCPAlgorithmsTest_eljob.driver
driver
Definition: FullCPAlgorithmsTest_eljob.py:171
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
EL::UnitTest::location
std::string location
description: the location for the unit test
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:38
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
SamplePtr.h
SampleLocal.h
EL::UnitTest::UnitTest
UnitTest(const std::string &val_name, std::string base_path="")
effects: standard constructor guarantee: storng failures: out of memory II
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/Root/UnitTest.cxx:44
MetaObject.h
FullCPAlgorithmsTest_eljob.sh
sh
Definition: FullCPAlgorithmsTest_eljob.py:111
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:113
RCU_ASSERT_SOFT
#define RCU_ASSERT_SOFT(x)
Definition: Assert.h:167
FullCPAlgorithmsTest_eljob.submitDir
submitDir
Definition: FullCPAlgorithmsTest_eljob.py:160
RCU::Shell
Definition: ShellExec.cxx:28
ANA_MSG_INFO
#define ANA_MSG_INFO(xmsg)
Macro printing info messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:290
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
generateReferenceFile.files
files
Definition: generateReferenceFile.py:12
calibdata.exception
exception
Definition: calibdata.py:496
file
TFile * file
Definition: tile_monitor.h:29
SH::scanNEvents
void scanNEvents(SampleHandler &sh)
effects: scan each sample in the sample handler and store the number of entries per file in the meta-...
Definition: ToolsSplit.cxx:38
SH::SampleGrid
This class implements a Sample located on the grid.
Definition: SampleGrid.h:44
EL
This module defines the arguments passed from the BATCH driver to the BATCH worker.
Definition: AlgorithmWorkerData.h:24
SH::MetaFields::gridFilter
static const std::string gridFilter
the field containing the file filter for the dataset on the grid
Definition: MetaFields.h:38
SH::Sample::meta
MetaObject * meta()
the meta-information for this sample
SH::MetaFields::treeName
static const std::string treeName
the name of the tree in the sample
Definition: MetaFields.h:52
EL::UnitTest::outputDisk
SH::DiskOutput * outputDisk
description: the output disk
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:41
SH::Sample
a base class that manages a set of files belonging to a particular data set and the associated meta-d...
Definition: Sample.h:54
SH::MetaObject::setString
void setString(const std::string &name, const std::string &value)
set the meta-data string with the given name
merge.output
output
Definition: merge.py:17
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
MetaFields.h
ThrowMsg.h
SH::SamplePtr
A smart pointer class that holds a single Sample object.
Definition: SamplePtr.h:35
SH::SampleHandler::setMetaString
void setMetaString(const std::string &name, const std::string &value)
set the meta-data string with the given name for all samples.
SampleGrid.h
EL::UnitTest::cleanup
bool cleanup
description: whether we clean up the submit directory afterwards
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:32
EL::UnitTest::run
int run(const Driver &driver) const
effects: perform a unit test with the given driver returns: EXIT_SUCCESS on success,...
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/Root/UnitTest.cxx:55
SH::MetaFields::gridName
static const std::string gridName
the field containing the name of the dataset on the grid
Definition: MetaFields.h:34
python.CaloScaleNoiseConfig.str
str
Definition: CaloScaleNoiseConfig.py:78
SH::SampleLocal
A Sample based on a simple file list.
Definition: SampleLocal.h:38
SH::SampleHandler
A class that manages a list of Sample objects.
Definition: SampleHandler.h:60
checkCorrelInHIST.histos
dictionary histos
Definition: checkCorrelInHIST.py:413
str
Definition: BTagTrackIpAccessor.cxx:11
EL::UnitTest::scanNEvents
bool scanNEvents
whether to scan for number of events
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:25
EL::Job::optSubmitDirMode
static const std::string optSubmitDirMode
the submit-dir mode (allowed values: "no-clobber", "overwrite", "unique", "unique-link")
Definition: Job.h:195
RCU_THROW_MSG
#define RCU_THROW_MSG(message)
Definition: PrintMsg.h:58
SH::SampleHandler::get
Sample * get(const std::string &name)
get the sample with the given name
EL::UnitTest::testOutput
bool testOutput
description: whether to test creating output n-tuples
Definition: PhysicsAnalysis/D3PDTools/EventLoopTest/EventLoopTest/UnitTest.h:35
SH::SampleLocal::add
void add(const std::string &file)
add a file to the list
EL::Job
Definition: Job.h:51
test_interactive_athena.job
job
Definition: test_interactive_athena.py:6
RCU_ASSERT
#define RCU_ASSERT(x)
Definition: Assert.h:222
EL::UnitTestAlg
Definition: UnitTestAlg.h:34
ToolsSplit.h