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
71 for (std::size_t iter = 0, end =
m_algs.size(); iter != end; ++ iter)
88 addOutput (TObject *output_swallow)
90 std::unique_ptr<TObject> output (output_swallow);
96 ModuleData::addOutput (std::move (output));
102 addOutputList (
const std::string& name, TObject *output_swallow)
104 std::unique_ptr<TObject> output (output_swallow);
110 std::unique_ptr<TList> list (
new TList);
111 list->SetName (name.c_str());
112 list->Add (output.release());
119 getOutputHist (
const std::string& name)
const
124 if (result ==
nullptr)
throw std::runtime_error (
"unknown output histogram: " + name);
131 getOutputFile (
const std::string&
label)
const
136 throw std::runtime_error (
"no output dataset defined with label: " +
label);
143 getOutputFileNull (
const std::string&
label)
const
149 return iter->second->file();
155 addTree(
const TTree&
tree,
const std::string& stream )
157 using namespace msgEventLoop;
160 auto outputIter =
m_outputs.find (stream);
163 ANA_MSG_ERROR (
"No output file with stream name \"" + stream +
165 return ::StatusCode::FAILURE;
168 outputIter->second->addClone (
tree);
171 return ::StatusCode::SUCCESS;
177 getOutputTree(
const std::string& name,
const std::string& stream )
const
179 using namespace msgEventLoop;
182 auto outputIter =
m_outputs.find (stream);
185 throw std::runtime_error (
"No output file with stream name \"" + stream +
"\" found");
188 TTree *result = outputIter->second->getOutputTree( name );
189 if( result ==
nullptr ) {
190 throw std::runtime_error (
"No tree with name \"" + name +
"\" in stream \"" + stream +
"\"");
233 hasInputEvents ()
const
240 std::string Worker ::
241 inputFileName ()
const
245 throw std::runtime_error (
"no input file is currently open");
246 std::string path =
inputFile()->GetName();
247 auto split = path.rfind (
'/');
248 if (
split != std::string::npos)
249 return path.substr (
split + 1);
257 triggerConfig ()
const
261 throw std::runtime_error (
"no input file is currently open");
262 return dynamic_cast<TTree*
>(
inputFile()->Get(
"physicsMeta/TrigConfTree"));
273 throw std::runtime_error (
"Worker::xaodEvent: Job not configured for xAOD support");
285 throw std::runtime_error (
"Worker::xaodStore: Job not configured for xAOD support");
292 getAlg (
const std::string& name)
const
297 if (alg->hasName (name))
298 return alg.m_algorithm->getLegacyAlg();
315 filterPassed ()
const noexcept
324 setFilterPassed (
bool val_filterPassed)
noexcept
354 setOutputHist (
const std::string& val_outputTarget)
364 setSegmentName (
const std::string& val_segmentName)
377 for (
auto& alg : jobConfig.extractAlgorithms())
379 m_algs.push_back (std::move (alg));
388 using namespace msgEventLoop;
396 m_moduleConfig.emplace_back (
"EL::Detail::MemoryMonitorModule/EarlyMemoryMonitorModule");
399 m_moduleConfig.emplace_back (
"EL::Detail::TreeCacheModule/TreeCacheModule");
406 m_moduleConfig.emplace_back (
"EL::Detail::EventModule/EventModule");
412 if (!factoryPreload.empty())
414 m_moduleConfig.emplace_back (
"EL::Detail::FactoryPreloadModule/FactoryPreloadModule");
417 m_moduleConfig.emplace_back (
"EL::Detail::LeakCheckModule/LeakCheckModule");
423 m_moduleConfig.emplace_back (
"EL::Detail::StopwatchModule/StopwatchModule");
425 m_moduleConfig.emplace_back (
"EL::Detail::GridReportingModule/GridReportingModule");
427 m_moduleConfig.emplace_back (
"EL::Detail::AlgorithmTimerModule/AlgorithmTimerModule");
429 m_moduleConfig.emplace_back (
"EL::Detail::AlgorithmMemoryModule/AlgorithmMemoryModule");
430 m_moduleConfig.emplace_back (
"EL::Detail::FileExecutedModule/FileExecutedModule");
431 m_moduleConfig.emplace_back (
"EL::Detail::EventCountModule/EventCountModule");
432 m_moduleConfig.emplace_back (
"EL::Detail::WorkerConfigModule/WorkerConfigModule");
433 m_moduleConfig.emplace_back (
"EL::Detail::AlgorithmStateModule/AlgorithmStateModule");
434 m_moduleConfig.emplace_back (
"EL::Detail::PostClosedOutputsModule/PostClosedOutputsModule");
436 m_moduleConfig.emplace_back (
"EL::Detail::MemoryMonitorModule/LateMemoryMonitorModule");
440 std::unique_ptr<Detail::Module> module;
441 ANA_CHECK (make_module (module, config));
442 m_modules.push_back (std::move (module));
456 std::istringstream iss (aliases);
458 while (std::getline (iss, alias,
','))
460 auto pos = alias.find (
'=');
461 if (pos == std::string::npos)
464 return ::StatusCode::FAILURE;
466 auto aliasName = alias.substr (0, pos);
467 auto realName = alias.substr (pos + 1);
468 auto realOutput =
m_outputs.find (realName);
471 ANA_MSG_ERROR (
"output stream " << realName <<
" not found for alias " << aliasName);
472 return ::StatusCode::FAILURE;
474 auto [aliasOutput, success] =
m_outputs.emplace (aliasName, realOutput->second);
477 ANA_MSG_ERROR (
"output stream " << aliasName <<
" already exists, can't make alias");
478 return ::StatusCode::FAILURE;
484 (
"EventLoop_JobStats",
"EventLoop job statistics");
487 ANA_MSG_INFO (
"calling firstInitialize on all modules");
489 ANA_CHECK (module->firstInitialize (*
this));
490 ANA_MSG_INFO (
"calling preFileInitialize on all modules");
492 ANA_CHECK (module->preFileInitialize (*
this));
494 return ::StatusCode::SUCCESS;
502 using namespace msgEventLoop;
507 ANA_CHECK (module->processInputs (*
this, *
this));
509 return ::StatusCode::SUCCESS;
517 using namespace msgEventLoop;
524 return StatusCode::FAILURE;
534 output.second->saveOutput ();
535 output.second->close ();
536 std::string path = output.second->finalFileName ();
538 addOutputList (
"EventLoop_OutputStream_" + output.first,
new TObjString (path.c_str()));
542 ANA_CHECK (module->postFinalize (*
this));
543 if (
m_jobStats->GetListOfBranches()->GetEntries() > 0)
548 return ::StatusCode::FAILURE;
550 ModuleData::addOutput (std::move (
m_jobStats));
559 ANA_CHECK (module->postFileClose(*
this));
562 return ::StatusCode::SUCCESS;
570 using namespace msgEventLoop;
582 return ::StatusCode::FAILURE;
590 return ::StatusCode::FAILURE;
598 ANA_CHECK (module->onInitialize (*
this));
606 ANA_CHECK (module->onNewInputFile (*
this));
612 ANA_CHECK (module->onFileExecute (*
this));
624 if (module->onExecute (*this).isFailure())
627 return ::StatusCode::FAILURE;
634 ANA_CHECK (module->postFirstEvent (*
this));
640 return ::StatusCode::SUCCESS;
646 fileOpenErrorFilter(
int level,
bool ,
const char* s1,
const char * s2)
649 if (strstr (s2,
"no streamer or dictionary") !=
nullptr) {
654 if( level > kWarning ) {
656 std::string
msg =
"ROOT error detected in Worker.cxx: ";
660 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");
859 return ::StatusCode::SUCCESS;
865 batchExecute (
unsigned job_id,
const char *confFile)
867 using namespace msgEventLoop;
872 std::unique_ptr<TFile>
file (TFile::Open (confFile,
"READ"));
873 if (
file.get() ==
nullptr ||
file->IsZombie())
876 return ::StatusCode::FAILURE;
879 std::unique_ptr<BatchJob> job (
dynamic_cast<BatchJob*
>(
file->Get (
"job")));
881 if (job.get() ==
nullptr)
884 return ::StatusCode::FAILURE;
887 if (job_id >= job->segments.size())
889 ANA_MSG_ERROR (
"invalid job-id " << job_id <<
", max is " << job->segments.size());
890 return ::StatusCode::FAILURE;
897 gSystem->Exec (
"pwd");
898 gSystem->MakeDirectory (
"output");
907 end = job->job.outputEnd(); out != end; ++ out)
915 m_moduleConfig.emplace_back (
"EL::Detail::BatchInputModule/BatchInputModule");
932 std::ostringstream job_name;
934 const std::string completedName (job->location +
"/status/completed-" + job_name.str());
935 std::ofstream completed (completedName.c_str());
938 ANA_MSG_ERROR (
"failed to write completion marker " << completedName);
939 return ::StatusCode::FAILURE;
941 return ::StatusCode::SUCCESS;
947 return ::StatusCode::FAILURE;
954 gridExecute (
const std::string& sampleName, Long64_t SkipEvents, Long64_t nEventsPerJob)
956 using namespace msgEventLoop;
959 ANA_MSG_INFO (
"Running with ROOT version " << gROOT->GetVersion()
960 <<
" (" << gROOT->GetVersionDate() <<
")");
966 std::unique_ptr<JobConfig> jobConfig;
969 std::unique_ptr<TFile> f (TFile::Open(
"jobdef.root"));
970 if (f ==
nullptr || f->IsZombie()) {
972 return ::StatusCode::FAILURE;
980 return ::StatusCode::FAILURE;
983 jobConfig.reset (
dynamic_cast<JobConfig*
>(f->Get(
"jobConfig")));
984 if (jobConfig ==
nullptr)
987 return ::StatusCode::FAILURE;
991 std::unique_ptr<TList> outs ((TList*)f->Get(
"outputs"));
995 return ::StatusCode::FAILURE;
998 TIter itr(outs.get());
1000 while ((obj = itr())) {
1003 bigOutputs.Add(out);
1006 ANA_MSG_ERROR (
"Encountered unexpected entry in list of outputs");
1007 return ::StatusCode::FAILURE;
1015 const std::string location =
".";
1025 TIter itr(&bigOutputs);
1027 while ((obj = itr())) {
1032 return ::StatusCode::FAILURE;
1036 location +
"/" + os->label() +
".root",
"RECREATE"};
1045 std::vector<std::string> fileList;
1046 std::ifstream infile(
"input.txt");
1049 if (!getline(infile, sLine))
break;
1050 std::istringstream ssLine(sLine);
1053 if (!getline(ssLine, sFile,
','))
break;
1054 fileList.push_back(sFile);
1057 if (fileList.size() == 0) {
1062 m_moduleConfig.emplace_back (
"EL::Detail::DirectInputModule/DirectInputModule");
1065 if (nEventsPerJob != -1)
1067 if (SkipEvents != 0)
1081 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