42#include <TObjString.h>
56 StatusCode make_module (std::unique_ptr<Detail::Module>& module, asg::AsgComponentConfig config)
58 using namespace msgEventLoop;
60 ANA_CHECK (
config.makeComponentExpert (module,
"new %1% (\"%2%\")",
false,
"ELModule."));
62 return StatusCode::SUCCESS;
69 testInvariant ()
const
72 for (std::size_t iter = 0, end =
m_algs.size(); iter != end; ++ iter)
89 addOutput (TObject *output_swallow)
91 std::unique_ptr<TObject> output (output_swallow);
97 ModuleData::addOutput (std::move (output));
103 addOutputList (
const std::string& name, TObject *output_swallow)
105 std::unique_ptr<TObject> output (output_swallow);
111 std::unique_ptr<TList> list (
new TList);
112 list->SetName (name.c_str());
113 list->Add (output.release());
120 getOutputHist (
const std::string& name)
const
125 if (result ==
nullptr)
throw std::runtime_error (
"unknown output histogram: " + name);
132 getOutputFile (
const std::string&
label)
const
137 throw std::runtime_error (
"no output dataset defined with label: " +
label);
144 getOutputFileNull (
const std::string&
label)
const
150 return iter->second->file();
156 addTree(
const TTree&
tree,
const std::string& stream )
158 using namespace msgEventLoop;
161 auto outputIter =
m_outputs.find (stream);
164 ANA_MSG_ERROR (
"No output file with stream name \"" + stream +
166 return ::StatusCode::FAILURE;
169 outputIter->second->addClone (
tree);
172 return ::StatusCode::SUCCESS;
178 getOutputTree(
const std::string& name,
const std::string& stream )
const
180 using namespace msgEventLoop;
183 auto outputIter =
m_outputs.find (stream);
186 throw std::runtime_error (
"No output file with stream name \"" + stream +
"\" found");
189 TTree *result = outputIter->second->getOutputTree( name );
190 if( result ==
nullptr ) {
191 throw std::runtime_error (
"No tree with name \"" + name +
"\" in stream \"" + stream +
"\"");
234 hasInputEvents ()
const
241 std::string Worker ::
242 inputFileName ()
const
245 std::string path =
inputFile()->GetName();
246 auto split = path.rfind (
'/');
247 if (
split != std::string::npos)
248 return path.substr (
split + 1);
256 triggerConfig ()
const
259 return dynamic_cast<TTree*
>(
inputFile()->Get(
"physicsMeta/TrigConfTree"));
270 throw std::runtime_error (
"Worker::xaodEvent: Job not configured for xAOD support");
282 throw std::runtime_error (
"Worker::xaodStore: Job not configured for xAOD support");
289 getAlg (
const std::string& name)
const
294 if (alg->hasName (name))
295 return alg.m_algorithm->getLegacyAlg();
312 filterPassed ()
const noexcept
321 setFilterPassed (
bool val_filterPassed)
noexcept
351 setOutputHist (
const std::string& val_outputTarget)
361 setSegmentName (
const std::string& val_segmentName)
374 for (
auto& alg : jobConfig.extractAlgorithms())
376 m_algs.push_back (std::move (alg));
385 using namespace msgEventLoop;
393 m_moduleConfig.emplace_back (
"EL::Detail::MemoryMonitorModule/EarlyMemoryMonitorModule");
396 m_moduleConfig.emplace_back (
"EL::Detail::TreeCacheModule/TreeCacheModule");
403 m_moduleConfig.emplace_back (
"EL::Detail::EventModule/EventModule");
409 if (!factoryPreload.empty())
411 m_moduleConfig.emplace_back (
"EL::Detail::FactoryPreloadModule/FactoryPreloadModule");
414 m_moduleConfig.emplace_back (
"EL::Detail::LeakCheckModule/LeakCheckModule");
420 m_moduleConfig.emplace_back (
"EL::Detail::StopwatchModule/StopwatchModule");
422 m_moduleConfig.emplace_back (
"EL::Detail::GridReportingModule/GridReportingModule");
424 m_moduleConfig.emplace_back (
"EL::Detail::AlgorithmTimerModule/AlgorithmTimerModule");
426 m_moduleConfig.emplace_back (
"EL::Detail::AlgorithmMemoryModule/AlgorithmMemoryModule");
427 m_moduleConfig.emplace_back (
"EL::Detail::FileExecutedModule/FileExecutedModule");
428 m_moduleConfig.emplace_back (
"EL::Detail::EventCountModule/EventCountModule");
429 m_moduleConfig.emplace_back (
"EL::Detail::WorkerConfigModule/WorkerConfigModule");
430 m_moduleConfig.emplace_back (
"EL::Detail::AlgorithmStateModule/AlgorithmStateModule");
431 m_moduleConfig.emplace_back (
"EL::Detail::PostClosedOutputsModule/PostClosedOutputsModule");
433 m_moduleConfig.emplace_back (
"EL::Detail::MemoryMonitorModule/LateMemoryMonitorModule");
437 std::unique_ptr<Detail::Module> module;
438 ANA_CHECK (make_module (module, config));
439 m_modules.push_back (std::move (module));
453 std::istringstream iss (aliases);
455 while (std::getline (iss, alias,
','))
457 auto pos = alias.find (
'=');
458 if (pos == std::string::npos)
461 return ::StatusCode::FAILURE;
463 auto aliasName = alias.substr (0, pos);
464 auto realName = alias.substr (pos + 1);
465 auto realOutput =
m_outputs.find (realName);
468 ANA_MSG_ERROR (
"output stream " << realName <<
" not found for alias " << aliasName);
469 return ::StatusCode::FAILURE;
471 auto [aliasOutput, success] =
m_outputs.emplace (aliasName, realOutput->second);
474 ANA_MSG_ERROR (
"output stream " << aliasName <<
" already exists, can't make alias");
475 return ::StatusCode::FAILURE;
481 (
"EventLoop_JobStats",
"EventLoop job statistics");
484 ANA_MSG_INFO (
"calling firstInitialize on all modules");
486 ANA_CHECK (module->firstInitialize (*
this));
487 ANA_MSG_INFO (
"calling preFileInitialize on all modules");
489 ANA_CHECK (module->preFileInitialize (*
this));
491 return ::StatusCode::SUCCESS;
499 using namespace msgEventLoop;
504 ANA_CHECK (module->processInputs (*
this, *
this));
506 return ::StatusCode::SUCCESS;
514 using namespace msgEventLoop;
521 return StatusCode::FAILURE;
531 output.second->saveOutput ();
532 output.second->close ();
533 std::string path = output.second->finalFileName ();
535 addOutputList (
"EventLoop_OutputStream_" + output.first,
new TObjString (path.c_str()));
539 ANA_CHECK (module->postFinalize (*
this));
540 if (
m_jobStats->GetListOfBranches()->GetEntries() > 0)
545 return ::StatusCode::FAILURE;
547 ModuleData::addOutput (std::move (
m_jobStats));
556 ANA_CHECK (module->postFileClose(*
this));
559 return ::StatusCode::SUCCESS;
567 using namespace msgEventLoop;
579 return ::StatusCode::FAILURE;
587 return ::StatusCode::FAILURE;
595 ANA_CHECK (module->onInitialize (*
this));
603 ANA_CHECK (module->onNewInputFile (*
this));
609 ANA_CHECK (module->onFileExecute (*
this));
621 if (module->onExecute (*this).isFailure())
624 return ::StatusCode::FAILURE;
631 ANA_CHECK (module->postFirstEvent (*
this));
637 return ::StatusCode::SUCCESS;
643 fileOpenErrorFilter(
int level,
bool ,
const char* s1,
const char * s2)
646 if (strstr (s2,
"no streamer or dictionary") !=
nullptr) {
651 if( level > kWarning ) {
653 std::string
msg =
"ROOT error detected in Worker.cxx: ";
657 throw std::runtime_error(
msg);
668 openInputFile (
const std::string& inputFileUrl)
670 using namespace msgEventLoop;
678 return ::StatusCode::SUCCESS;
685 ANA_CHECK (module->onCloseInputFile (*
this));
687 ANA_CHECK (module->postCloseInputFile (*
this));
696 if (inputFileUrl.empty())
697 return ::StatusCode::SUCCESS;
712 module->reportInputFailure (*this);
713 return ::StatusCode::FAILURE;
719 module->reportInputFailure (*this);
720 return ::StatusCode::FAILURE;
725 const std::string treeName
727 tree =
dynamic_cast<TTree*
>(
inputFile->Get (treeName.c_str()));
730 ANA_MSG_INFO (
"tree " << treeName <<
" not found in input file: " << inputFileUrl);
731 ANA_MSG_INFO (
"treating this like a tree with no events");
747 ANA_CHECK (module->onFirstInputFile (*
this));
752 ANA_CHECK (module->onNextInputFile (*
this));
760 return ::StatusCode::SUCCESS;
766 addOutputStream (
const std::string&
label,
769 using namespace msgEventLoop;
775 return ::StatusCode::FAILURE;
777 if (data.file() ==
nullptr)
779 ANA_MSG_ERROR (
"output stream does not have a file attached");
780 return ::StatusCode::FAILURE;
782 if (data.mainStreamName().empty())
783 data.setMainStreamName (
label);
784 m_outputs.insert (std::make_pair (
label, std::make_shared<Detail::OutputStreamData>(std::move (data))));
785 return ::StatusCode::SUCCESS;
791 inputFileNumEntries ()
const
808 eventsProcessed ()
const noexcept
820 using namespace msgEventLoop;
824 meta.fetchDefaults (options);
835 end = job.outputEnd(); out != end; ++ out)
838 out->output()->makeWriter (sample.name(),
"",
".root")};
843 m_moduleConfig.emplace_back (
"EL::Detail::DirectInputModule/DirectInputModule");
856 return ::StatusCode::SUCCESS;
862 batchExecute (
unsigned job_id,
const char *confFile)
864 using namespace msgEventLoop;
869 std::unique_ptr<TFile>
file (TFile::Open (confFile,
"READ"));
870 if (
file.get() ==
nullptr ||
file->IsZombie())
873 return ::StatusCode::FAILURE;
876 std::unique_ptr<BatchJob> job (
dynamic_cast<BatchJob*
>(
file->Get (
"job")));
878 if (job.get() ==
nullptr)
881 return ::StatusCode::FAILURE;
884 if (job_id >= job->segments.size())
886 ANA_MSG_ERROR (
"invalid job-id " << job_id <<
", max is " << job->segments.size());
887 return ::StatusCode::FAILURE;
894 gSystem->Exec (
"pwd");
895 gSystem->MakeDirectory (
"output");
904 end = job->job.outputEnd(); out != end; ++ out)
912 m_moduleConfig.emplace_back (
"EL::Detail::BatchInputModule/BatchInputModule");
923 std::ostringstream job_name;
925 std::ofstream completed ((job->location +
"/status/completed-" + job_name.str()).c_str());
926 return ::StatusCode::SUCCESS;
930 return ::StatusCode::FAILURE;
937 gridExecute (
const std::string& sampleName, Long64_t SkipEvents, Long64_t nEventsPerJob)
939 using namespace msgEventLoop;
942 ANA_MSG_INFO (
"Running with ROOT version " << gROOT->GetVersion()
943 <<
" (" << gROOT->GetVersionDate() <<
")");
949 std::unique_ptr<JobConfig> jobConfig;
952 std::unique_ptr<TFile> f (TFile::Open(
"jobdef.root"));
953 if (f ==
nullptr || f->IsZombie()) {
955 return ::StatusCode::FAILURE;
963 return ::StatusCode::FAILURE;
966 jobConfig.reset (
dynamic_cast<JobConfig*
>(f->Get(
"jobConfig")));
967 if (jobConfig ==
nullptr)
970 return ::StatusCode::FAILURE;
974 std::unique_ptr<TList> outs ((TList*)f->Get(
"outputs"));
978 return ::StatusCode::FAILURE;
981 TIter itr(outs.get());
983 while ((obj = itr())) {
989 ANA_MSG_ERROR (
"Encountered unexpected entry in list of outputs");
990 return ::StatusCode::FAILURE;
998 const std::string location =
".";
1008 TIter itr(&bigOutputs);
1010 while ((obj = itr())) {
1015 return ::StatusCode::FAILURE;
1019 location +
"/" + os->label() +
".root",
"RECREATE"};
1028 std::vector<std::string> fileList;
1029 std::ifstream infile(
"input.txt");
1032 if (!getline(infile, sLine))
break;
1033 std::istringstream ssLine(sLine);
1036 if (!getline(ssLine, sFile,
','))
break;
1037 fileList.push_back(sFile);
1040 if (fileList.size() == 0) {
1045 m_moduleConfig.emplace_back (
"EL::Detail::DirectInputModule/DirectInputModule");
1048 if (nEventsPerJob != -1)
1050 if (SkipEvents != 0)
1064 return ::StatusCode::SUCCESS;
#define RCU_DESTROY_INVARIANT(x)
#define RCU_CHANGE_INVARIANT(x)
#define RCU_NEW_INVARIANT(x)
#define RCU_REQUIRE_SOFT(x)
#define RCU_READ_INVARIANT(x)
Run a MT piece of code with an alternate root error handler.
all data needed to manage a given output stream
the job configuration that is independent of driver and dataset
static const std::string optPrintPerFileStats
description: the option to turn on printing of i/o statistics at the end of each file rationale: whil...
static const std::string optMemFailOnLeak
Failure behaviour of the code when a "significant memory leak" is found.
static const std::string optMaxEvents
description: the name of the option used for setting the maximum number of events to process per samp...
static const std::string optGridReporting
whether to use grid reporting even when not running on the grid
static const std::string optAlgorithmTimer
a boolean flag for whether to add a timer for the algorithms
static const std::string optMemResidentIncreaseLimit
The minimal resident memory increase necessary to trigger an error.
static const std::string optXAODPerfStats
description: the name of the option for turning on XAODPerfStats.
const OutputStream * outputIter
static const std::string optXAODSummaryReport
the option to turn on/off the xAOD summary reporting at the end of the job
static const std::string optCacheLearnEntries
description: this option allows to configure the number of tree entries used for learning cache behav...
static const std::string optCacheSize
description: this option allows to configure the TTreeCache size for this job.
static const std::string optAlgorithmMemoryMonitor
a boolean flag for whether to add a memory monitor for the algorithms
static const std::string optXAODInput
the option to select whether our input is xAODs
static const std::string optMemResidentPerEventIncreaseLimit
The minimal per-event resident memory increase for triggering an error.
static const std::string optMemVirtualIncreaseLimit
The minimal virtual memory increase necessary to trigger an error.
static const std::string optMemVirtualPerEventIncreaseLimit
The minimal per-event virtual memory increase for triggering an error.
static const std::string optSkipEvents
description: the name of the option used for skipping a certain number of events in the beginning rat...
static const std::string optStreamAliases
an option for stream aliases
static const std::string optFactoryPreload
a boolean flag for whether to perform a component factory preload
static const std::string histogramStreamName
the name of the histogram output stream
Long64_t treeEntry() const override
description: the entry in the tree we are reading guarantee: no-fail
std::string inputFileName() const override
the name of the file we are reading the current tree from, without the path component
void addOutputList(const std::string &name, TObject *output_swallow) override
effects: add a given object to the output.
::StatusCode addTree(const TTree &tree, const std::string &stream) final override
effects: adds a tree to an output file specified by the stream/label failures: Incorrect stream/label...
TFile * inputFile() const override
description: the file we are reading the current tree from guarantee: no-fail
TTree * getOutputTree(const std::string &name, const std::string &stream) const final override
effects: get the tree that was added to an output file earlier failures: Tree doesn't exist
static bool fileOpenErrorFilter(int level, bool, const char *, const char *)
Error handler for file opening.
void setOutputHist(const std::string &val_outputTarget)
set the histogram output list
std::vector< asg::AsgComponentConfig > m_moduleConfig
the module configurations we use
::StatusCode addOutputStream(const std::string &label, Detail::OutputStreamData output)
effects: add another output file guarantee: strong failures: low level errors II failures: label alre...
const SH::MetaObject * metaData() const override
description: the sample meta-data we are working on guarantee: no-fail invariant: metaData !...
std::string m_segmentName
the name of the segment we are processing
::StatusCode finalize()
finalize the worker
bool m_firstInputFile
whether this is the first input file
void setJobConfig(JobConfig &&jobConfig)
set the JobConfig
::StatusCode openInputFile(const std::string &inputFileUrl) override
open the given input file without processing it
uint64_t eventsProcessed() const noexcept
the number of events that have been processed
bool m_newInputFile
whether this is a new input file (i.e.
TTree * tree() const override
description: the tree we are running on guarantee: no-fail
void setMetaData(const SH::MetaObject *val_metaData)
set the metaData
bool m_algorithmsInitialized
whether the algorithms are initialized
std::vector< std::unique_ptr< Detail::Module > > m_modules
the list of modules we hold
void addOutput(TObject *output_swallow) final override
effects: add an object to the output.
::StatusCode initialize()
initialize the worker
TFile * getOutputFileNull(const std::string &label) const override
effects: get the output file that goes into the dataset with the given label.
void setSegmentName(const std::string &val_segmentName)
set the segment name
Long64_t inputFileNumEntries() const override
the number of events in the input file
::StatusCode processInputs()
process all the inputs
bool m_firstEvent
whether we are still to process the first event
std::string m_outputTarget
the target file to which we will write the histogram output
Run a MT piece of code with an alternate root error handler.
a base class that manages a set of files belonging to a particular data set and the associated meta-d...
Base class for the event (xAOD::TEvent and xAOD::REvent) classes.
A relatively simple transient store for objects created in analysis.
std::vector< std::string > split(const std::string &s, const std::string &t=":")
std::string label(const std::string &format, int i)
void report_exception(std::exception_ptr eptr)
print out the currently evaluated exception
This module defines the arguments passed from the BATCH driver to the BATCH worker.
::StatusCode StatusCode
StatusCode definition for legacy code.
bool SetDirectory(TObject *object, TDirectory *directory)
effects: set the directory this object is associated with returns: whether the object type actively k...
std::unique_ptr< TFile > openFile(const std::string &name, const MetaObject &options)
open a file with the given options
UInt_t job_id
description: the job id of this segment
std::string segmentName
the name/id to use for this segment (not including the sample name)
std::string fullName
the name/id to use for this segment (including the sample name)
UInt_t sample
description: the index of the sample we are using
std::string sampleName
the name of the sample for this segment
std::string m_inputFileUrl
the input file url of the currently opened file
const SH::MetaObject * m_metaData
the meta-data we use
Worker * m_worker
the worker (to pass on to the algorithms)
TTree * m_inputTree
the (main) tree in the input file
uint64_t m_inputEntry
the entry in the input tree we are currently looking at
BatchJob * m_batchJob
the BatchJob configuration (if used)
xAOD::TStore * m_tstore
the TStore structure, if we use one
bool m_skipEvent
whether we are skipping the current event
OutputStreamData * m_histOutput
the histogram output stream
std::unique_ptr< TTree > m_jobStats
Tree saving per-job statistics information.
bool m_hasInputEvents
flag whether the most recently opened input file has events or not
std::unique_ptr< TFile > m_inputFile
the input file pointer of the currently opened filed
std::map< std::string, std::shared_ptr< Detail::OutputStreamData > > m_outputs
the list of output files
std::vector< Detail::AlgorithmData > m_algs
the list of algorithms
uint64_t m_eventsProcessed
the number of events that have been processed
xAOD::Event * m_event
the Event object, if we use one
a range of events in a given file
std::string m_url
the location of the file
static constexpr Long64_t eof
the special value to indicate that the range includes all events until the end of the file
Long64_t m_beginEvent
the first event to process
Long64_t m_endEvent
the event past the last event, or eof