ATLAS Offline Software
PrunDriver.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 
8 
9 
11 #include <EventLoop/Algorithm.h>
12 #include <EventLoop/ManagerData.h>
13 #include <EventLoop/ManagerStep.h>
14 #include <EventLoop/Job.h>
15 #include <EventLoop/MessageCheck.h>
16 #include <EventLoop/OutputStream.h>
18 #include <RootCoreUtils/Assert.h>
19 #include <RootCoreUtils/hadd.h>
23 #include <SampleHandler/Sample.h>
27 
28 
29 #include <TList.h>
30 #include <TPython.h>
31 #include <TROOT.h>
32 #include <TFile.h>
33 #include <TSystem.h>
34 
35 #include <algorithm>
36 #include <cstdlib>
37 #include <iostream>
38 #include <sstream>
39 #include <string>
40 #include <vector>
41 #include <stdexcept>
42 
43 #include <boost/algorithm/string.hpp>
44 
45 #include "pool.h"
46 #include <mutex>
47 
49 
50 namespace {
51  namespace JobState {
52  static const unsigned int NSTATES = 6;
53  enum Enum { INIT=0, RUN=1, DOWNLOAD=2, MERGE=3, FINISHED=4, FAILED=5 };
54  static const char* name[NSTATES] =
55  { "INIT", "RUNNING", "DOWNLOAD", "MERGE", "FINISHED", "FAILED" };
56  Enum parse(const std::string& what)
57  {
58  for (unsigned int i = 0; i != NSTATES; ++i) {
59  if (what == name[i]) { return static_cast<Enum>(i); }
60  }
61  RCU_ASSERT0("Failed to parse job state string");
62  throw std::runtime_error("PrunDriver.cxx: Failed to parse job state string"); //compiler dummy
63  }
64  }
65 
66  // When changing the values in the enum make sure
67  // corresponding values in `data/ELG_jediState.py` script
68  // are changed accordingly
69  namespace Status {
70  //static const int NSTATES = 3;
71  enum Enum { DONE=0, PENDING=1, FAIL=2 };
72  }
73 
74  struct TransitionRule {
75  JobState::Enum fromState;
76  Status::Enum status;
77  JobState::Enum toState;
78  TransitionRule(JobState::Enum fromState,
79  Status::Enum status,
80  JobState::Enum toState)
81  : fromState(fromState)
82  , status(status)
83  , toState(toState)
84  {
85  }
86  };
87 
88  struct TmpCd {
89  const std::string origDir;
90  TmpCd(const std::string & dir)
91  : origDir(gSystem->pwd())
92  {
93  gSystem->cd(dir.c_str());
94  }
95  ~TmpCd()
96  {
97  gSystem->cd(origDir.c_str());
98  }
99  };
100 }
101 
102 static JobState::Enum sampleState(SH::Sample* sample)
103 {
105  static const std::string defaultState = JobState::name[JobState::INIT];
106  std::string label = sample->meta()->castString ("nc_ELG_state", defaultState, SH::MetaObject::CAST_NOCAST_DEFAULT);
107  return JobState::parse(label);
108 }
109 
110 static JobState::Enum nextState(JobState::Enum state, Status::Enum status)
111 {
113  RCU_REQUIRE(state != JobState::FAILED);
114  static const TransitionRule TABLE[] =
115  {
116  TransitionRule(JobState::INIT, Status::DONE, JobState::RUN),
117  TransitionRule(JobState::INIT, Status::PENDING, JobState::INIT),
118  TransitionRule(JobState::INIT, Status::FAIL, JobState::FAILED),
119  TransitionRule(JobState::RUN, Status::DONE, JobState::DOWNLOAD),
120  TransitionRule(JobState::RUN, Status::PENDING, JobState::RUN),
121  TransitionRule(JobState::RUN, Status::FAIL, JobState::FAILED),
122  TransitionRule(JobState::DOWNLOAD, Status::DONE, JobState::MERGE),
123  TransitionRule(JobState::DOWNLOAD, Status::PENDING, JobState::DOWNLOAD),
124  TransitionRule(JobState::DOWNLOAD, Status::FAIL, JobState::FAILED),
125  TransitionRule(JobState::MERGE, Status::DONE, JobState::FINISHED),
126  TransitionRule(JobState::MERGE, Status::PENDING, JobState::MERGE),
127  TransitionRule(JobState::MERGE, Status::FAIL, JobState::DOWNLOAD)
128  };
129  static const unsigned int TABLE_SIZE = sizeof(TABLE) / sizeof(TABLE[0]);
130  for (unsigned int i = 0; i != TABLE_SIZE; ++i) {
131  if (TABLE[i].fromState == state && TABLE[i].status == status) {
132  return TABLE[i].toState;
133  }
134  }
135  RCU_ASSERT0("Missing state transition rule");
136  throw std::logic_error("PrunDriver.cxx: Missing state transition rule");
137 }
138 
139 static SH::MetaObject defaultOpts()
140 {
141  SH::MetaObject o;
142  o.setString("nc_nGBPerJob", "MAX");
143  o.setString("nc_mergeOutput", "true");
144  o.setString("nc_cmtConfig", gSystem->ExpandPathName("$AnalysisBase_PLATFORM"));
145  o.setString("nc_useAthenaPackages", "true");
146  const std::string mergestr = "elg_merge jobdef.root %OUT %IN";
147  o.setString("nc_mergeScript", mergestr);
148  return o;
149 }
150 
151 static bool downloadContainer(const std::string& name,
152  const std::string& location)
153 {
154  RCU_ASSERT(not name.empty());
155  RCU_ASSERT(name[name.size()-1] == '/');
156  RCU_ASSERT(not location.empty());
157 
158  try {
159  gSystem->Exec(Form("mkdir -p %s", location.c_str()));
160 
161  std::vector<std::string> datasets;
162  for (auto& entry : SH::rucioListDids (name))
163  {
164  if (entry.type == "CONTAINER" || entry.type == "DIDType.CONTAINER")
165  datasets.push_back (entry.name);
166  }
167 
168  auto downloadResult = SH::rucioDownloadList (location, datasets);
169  for (const auto& result : downloadResult)
170  {
171  if (result.notDownloaded != 0)
172  return false;
173  }
174  } catch (...) {
175  return false;
176  }
177  return true;
178 }
179 
180 static Status::Enum submit(SH::Sample* const sample)
181 {
183  using namespace EL::msgEventLoop;
184 
185  ANA_MSG_INFO( "Submitting " << sample->name() << "..." );
186 
187  static bool loaded = false;
188  if (not loaded) {
189  // TString path = "$ROOTCOREBIN/python/EventLoopGrid/ELG_prun.py";
190  // gSystem->ExpandPathName(path);
191  // TPython::LoadMacro(path.Data());
192  std::string path = PathResolverFindCalibFile("EventLoopGrid/ELG_prun.py");
193  TPython::LoadMacro(path.c_str());
194  loaded = true;
195  }
196 
197  TPython::Bind(dynamic_cast<TObject*>(sample), "ELG_SAMPLE");
198 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,33,01)
199  std::any result;
200  TPython::Exec("_anyresult = ELG_prun(ELG_SAMPLE)", &result);
201  int ret = std::any_cast<int>(result);
202 #else
203  int ret = TPython::Eval("ELG_prun(ELG_SAMPLE)");
204 #endif
205  TPython::Bind(0, "ELG_SAMPLE");
206 
207  if (ret < 100) {
208  sample->meta()->setString("nc_ELG_state_details",
209  "problem submitting");
210  return Status::FAIL;
211  }
212 
213  sample->meta()->setDouble("nc_jediTaskID", ret);
214 
215  // Let's also tell people about their task ID
216  ANA_MSG_INFO( "Task submitted; jediTaskID=" << ret );
217 
218  return Status::DONE;
219 }
220 
221 static Status::Enum checkPandaTask(SH::Sample* const sample)
222 {
224  RCU_REQUIRE(static_cast<int>(sample->meta()->castDouble("nc_jediTaskID",0, SH::MetaObject::CAST_NOCAST_DEFAULT)) > 100);
225 
226  static bool loaded = false;
227  if (not loaded) {
228  std::string path = PathResolverFindCalibFile("EventLoopGrid/ELG_jediState.py");
229  TPython::LoadMacro(path.c_str());
230  loaded = true;
231  }
232 
233  TPython::Bind(dynamic_cast<TObject*>(sample), "ELG_SAMPLE");
234 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,33,01)
235  std::any result;
236  TPython::Exec("_anyresult = ELG_jediState(ELG_SAMPLE)", &result);
237  int ret = std::any_cast<int>(result);
238 #else
239  int ret = TPython::Eval("ELG_jediState(ELG_SAMPLE)");
240 #endif
241  TPython::Bind(0, "ELG_SAMPLE");
242 
243  if (ret == Status::DONE) return Status::DONE;
244  if (ret == Status::FAIL) return Status::FAIL;
245 
246  // Value 90 corresponds to `running` state of the job
247  if (ret != 90) { sample->meta()->setString("nc_ELG_state_details", "task status other than done/finished/failed/running"); }
248  // Value 99 is returned if there is error in the script (import, missing ID)
249  if (ret == 99) {
250  sample->meta()->setString("nc_ELG_state_details",
251  "problem checking jedi task status");
252  }
253 
254  return Status::PENDING;
255 }
256 
257 static Status::Enum download(SH::Sample* const sample)
258 {
260 
261  {
262  static std::mutex mutex;
263  std::lock_guard<std::mutex> lock(mutex);
264  std::cout << "Downloading output from: "
265  << sample->name() << "..." << std::endl;
266  }
267 
268  std::string container = sample->meta()->castString("nc_outDS", "", SH::MetaObject::CAST_NOCAST_DEFAULT);
269  RCU_ASSERT(not container.empty());
270  if (container[container.size()-1] == '/') {
271  container.resize(container.size() - 1);
272  }
273  container += "_hist/";
274 
275  bool downloadOk = downloadContainer(container, "elg/download/" + container);
276 
277  if (not downloadOk) {
278  std::cerr << "Failed to download one or more files" << std::endl;
279  sample->meta()->setString("nc_ELG_state_details",
280  "error, check log for details");
281  return Status::PENDING;
282  }
283 
284  return Status::DONE;
285 }
286 
287 static Status::Enum merge(SH::Sample* const sample)
288 {
290 
291  std::string container = sample->meta()->castString("nc_outDS", "", SH::MetaObject::CAST_NOCAST_DEFAULT);
292  RCU_ASSERT(not container.empty());
293  if (container[container.size()-1] == '/') {
294  container.resize(container.size() - 1);
295  }
296  container += "_hist/";
297  const std::string dir = "elg/download/" + container;
298 
299  const std::string fileName = "hist-output.root";
300 
301  const std::string target = Form("hist-%s.root", sample->name().c_str());
302 
303  const std::string findCmd(Form("find %s -name \"*.%s*\" | tr '\n' ' '",
304  dir.c_str(), fileName.c_str()));
305  std::istringstream input(gSystem->GetFromPipe(findCmd.c_str()).Data());
306  std::vector<std::string> files((std::istream_iterator<std::string>(input)),
307  std::istream_iterator<std::string>());
308 
309  std::sort(files.begin(), files.end());
310  RCU_ASSERT(std::unique(files.begin(), files.end()) == files.end());
311 
312  if (not files.size()) {
313  std::cerr << "Found no input files for merging! "
314  << "Requeueing sample for download..." << std::endl;
315  sample->meta()->setString("nc_ELG_state_details", "retry, files were lost");
316  return Status::FAIL;
317  }
318 
319  try {
320  RCU::hadd(target.c_str(), files);
321  } catch (...) {
322  sample->meta()->setString("nc_ELG_state_details",
323  "error, check log for details");
324  gSystem->Exec(Form("rm -f %s", target.c_str()));
325  return Status::PENDING;
326  }
327 
328  for (size_t i = 0; i != files.size(); ++i) {
329  gSystem->Exec(Form("rm %s", files[i].c_str()));
330  }
331  gSystem->Exec(Form("rmdir %s/*", dir.c_str()));
332  gSystem->Exec(Form("rmdir %s", dir.c_str()));
333 
334  return Status::DONE;
335 }
336 
337 static void processTask(SH::Sample* const sample)
338 {
340 
341  JobState::Enum state = sampleState(sample);
342 
343  sample->meta()->setString("nc_ELG_state_details", "");
344 
345  Status::Enum status = Status::PENDING;
346  switch (state) {
347  case JobState::INIT:
348  status = submit(sample);
349  break;
350  case JobState::RUN:
351  status = checkPandaTask(sample);
352  break;
353  case JobState::DOWNLOAD:
354  status = download(sample);
355  break;
356  case JobState::MERGE:
357  status = merge(sample);
358  break;
359  case JobState::FINISHED:
360  case JobState::FAILED:
361  break;
362  }
363 
364  state = nextState(state, status);
365  sample->meta()->setString("nc_ELG_state", JobState::name[state]);
366 }
367 
368 static void processAllInState(const SH::SampleHandler& sh, JobState::Enum state,
369  const size_t nThreads)
370 {
371  RCU_REQUIRE(sh.size());
372 
373  WorkList workList;
374  for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
375  if (sampleState(*s) == state) {
376  workList.push_back([s]()->void{ processTask(*s); });
377  }
378  }
379  process(workList, nThreads);
380 
381 }
382 
383 static std::string formatOutputName(const SH::MetaObject& sampleMeta,
384  const std::string & pattern)
385 {
386  const std::string sampleName = sampleMeta.castString("sample_name");
387  RCU_REQUIRE(not pattern.empty());
388  using namespace EL::msgEventLoop;
389 
390  static const std::string nickname =
391  gSystem->GetFromPipe(Form("python -c \"%s\" 2>/dev/null",
392  "from pandatools import PsubUtils;"
393  "print(PsubUtils.getNickname());")).Data();
394 
395  TString out = pattern.c_str();
396 
397  // Handle case of no proxy; will create a proxy later in the submission
398  if (nickname.length()>20){
399  ANA_MSG_WARNING( "No proxy available - cannot use nickname yet. Will try a late replacement.");
400  } else {
401  out.ReplaceAll("%nickname%", nickname);
402  }
403 
404  out.ReplaceAll("%in:name%", sampleName);
405 
406  std::stringstream ss(sampleName);
407  std::string item;
408  int field = 0;
409  while(std::getline(ss, item, '.')) {
410  std::stringstream sskey;
411  sskey << "%in:name[" << ++field << "]%";
412  out.ReplaceAll(sskey.str(), item);
413  }
414  while (out.Index("%in:") != -1) {
415  int i1 = out.Index("%in:");
416  int i2 = out.Index("%", i1+1);
417  TString metaName = out(i1+4, i2-i1-4);
418  out.ReplaceAll("%in:"+metaName+"%",
419  sampleMeta.castString(std::string(metaName.Data())));
420  }
421  out.ReplaceAll("/", "");
422  return out.Data();
423 }
424 
425 std::string outputFileNames(const EL::Job& job)
426 {
427  TList outputs;
428  for (EL::Job::outputIter out = job.outputBegin(),
429  end = job.outputEnd(); out != end; ++out) {
430  outputs.Add(out->Clone());
431  }
432  std::string out = "hist:hist-output.root";
433  TIter itr(&outputs);
434  TObject *obj = 0;
435  while ((obj = itr())) {
436  EL::OutputStream *os = dynamic_cast<EL::OutputStream*>(obj);
437  const std::string name = os->label() + ".root";
438  const std::string ds =
439  os->options()->castString(EL::OutputStream::optContainerSuffix);
440  out += "," + (ds.empty() ? name : ds + ":" + name);
441  }
442  return out;
443 }
444 
445 // Save algortihms and lists of inputs and outputs to a root file
446 static void saveJobDef(const std::string& fileName,
447  const EL::Job& job,
448  const SH::SampleHandler sh)
449 {
450  TFile file(fileName.c_str(), "RECREATE");
451  TList outputs;
452  for (EL::Job::outputIter o = job.outputBegin(); o !=job.outputEnd(); ++o)
453  outputs.Add(o->Clone());
454  file.WriteTObject(&job.jobConfig(), "jobConfig", "SingleKey");
455  file.WriteTObject(&outputs, "outputs", "SingleKey");
456  bool haveDefault = false;
457  for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
458  const SH::MetaObject& meta = *((*s)->meta());
459  file.WriteObject(&meta, meta.castString("sample_name").c_str());
460  if (!haveDefault)
461  {
462  file.WriteObject (&meta, "defaultMetaObject");
463  haveDefault = true;
464  }
465  }
466 }
467 
468 // Create a sample handler with grid locations of outputs with given label
469 static SH::SampleHandler outputSH(const SH::SampleHandler& in,
470  const std::string& outputLabel)
471 {
473  const std::string outputFile = "*" + outputLabel + ".root*";
474  const std::string outDSSuffix = '_' + outputLabel + ".root/";
475  for (SH::SampleHandler::iterator s = in.begin(); s != in.end(); ++s) {
476  SH::SampleGrid* outSample = new SH::SampleGrid((*s)->name());
477  const std::string outputDS = (*s)->meta()->castString("nc_outDS", "", SH::MetaObject::CAST_NOCAST_DEFAULT) + outDSSuffix;
478  outSample->meta()->setString("nc_grid", outputDS);
479  outSample->meta()->setString("nc_grid_filter", outputFile);
480  out.add(outSample);
481  }
482  out.fetch(in);
483  return out;
484 }
485 
487 {
488  RCU_INVARIANT(this != 0);
489 }
490 
492 {
493  RCU_NEW_INVARIANT(this);
494 }
495 
498 {
499  using namespace msgEventLoop;
501  switch (data.step)
502  {
504  {
505  const std::string jobELGDir = data.submitDir + "/elg";
506  const std::string runShFile = jobELGDir + "/runjob.sh";
507  //const std::string runShOrig = "$ROOTCOREBIN/data/EventLoopGrid/runjob.sh";
508  const std::string mergeShFile = jobELGDir + "/elg_merge";
509  //const std::string mergeShOrig =
510  // "$ROOTCOREBIN/user_scripts/EventLoopGrid/elg_merge";
511  const std::string runShOrig = PathResolverFindCalibFile("EventLoopGrid/runjob.sh");
512  const std::string mergeShOrig = PathResolverFindCalibFile("EventLoopGrid/elg_merge");
513 
514  const std::string jobDefFile = jobELGDir + "/jobdef.root";
515  gSystem->Exec(Form("mkdir -p %s", jobELGDir.c_str()));
516  gSystem->Exec(Form("cp %s %s", runShOrig.c_str(), runShFile.c_str()));
517  gSystem->Exec(Form("chmod +x %s", runShFile.c_str()));
518  gSystem->Exec(Form("cp %s %s", mergeShOrig.c_str(), mergeShFile.c_str()));
519  gSystem->Exec(Form("chmod +x %s", mergeShFile.c_str()));
520 
521  // create symbolic links for additionnal files/directories if any to ship to the grid
522  std::string listToShipToGrid = data.options.castString(EL::Job::optGridPrunShipAdditionalFilesOrDirs, "");
523  // parse the list of comma separated files and/or directories to ship to the grid
524  if (listToShipToGrid.size()){
525  ANA_MSG_INFO (
526  "Creating symbolic links for additional files or directories to be sent to grid.\n"
527  "For root or heavy files you should also add their name (not the full path) to EL::Job::optUserFiles.\n"
528  "Otherwise prun ignores those files."
529  );
530 
531  std::vector<std::string> vect_filesOrDirToShip;
532  // split string based on comma separators
533  boost::split(vect_filesOrDirToShip,listToShipToGrid,boost::is_any_of(","));
534 
535  // Create symbolic links of files or directories to the submission directory
536  for (const std::string & fileOrDirToShip: vect_filesOrDirToShip){
537  ANA_MSG_INFO (("Creating symbolic link for: " +fileOrDirToShip).c_str());
538  RCU::Shell::exec("ln -sf " + fileOrDirToShip + " " + jobELGDir);
539  }
540  ANA_MSG_INFO ("Finished creation of symbolic links");
541  }
542 
543  const SH::SampleHandler& sh = data.job->sampleHandler();
544 
545  for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
546  SH::MetaObject& meta = *(*s)->meta();
547  meta.fetchDefaults(data.options);
548  meta.fetchDefaults(defaultOpts());
549  meta.setString("nc_outputs", outputFileNames(*data.job));
550  std::string outputSampleName = meta.castString("nc_outputSampleName");
551  if (outputSampleName.empty()) {
552  outputSampleName = "user.%nickname%.%in:name%";
553  }
554  meta.setString("nc_outDS", formatOutputName(meta, outputSampleName));
555  meta.setString("nc_inDS", meta.castString("nc_grid", (*s)->name()));
556  meta.setString("nc_writeInputToTxt", "IN:input.txt");
557  meta.setString("nc_match", meta.castString("nc_grid_filter"));
558  const std::string execstr = "runjob.sh " + (*s)->name();
559  meta.setString("nc_exec", execstr);
560  meta.setString("nc_framework", "EventLoopGrid");
561  }
562 
563  saveJobDef(jobDefFile, *data.job, sh);
564 
565  for (EL::Job::outputIter out = data.job->outputBegin();
566  out != data.job->outputEnd(); ++out) {
567  SH::SampleHandler shOut = outputSH(sh, out->label());
568  shOut.save(data.submitDir + "/output-" + out->label());
569  }
570  SH::SampleHandler shHist = outputSH(sh, "hist-output");
571  shHist.save(data.submitDir + "/output-hist");
572 
573  TmpCd keepDir(jobELGDir);
574 
575  processAllInState(sh, JobState::INIT, 0);
576 
577  sh.save(data.submitDir + "/input");
578  data.submitted = true;
579  }
580  break;
581 
583  {
584  ANA_CHECK (doRetrieve (data));
585  }
586  break;
587 
588  default:
589  (void) true; // safe to do nothing
590  }
591  return ::StatusCode::SUCCESS;
592 }
593 
595 {
596  RCU_READ_INVARIANT(this);
597  RCU_REQUIRE(not data.submitDir.empty());
598 
599  TmpCd tmpDir(data.submitDir);
600 
602  sh.load("input");
603  RCU_ASSERT(sh.size());
604 
605  const size_t nRunThreads = options()->castDouble("nc_run_threads", 0);
606  const size_t nDlThreads = options()->castDouble("nc_download_threads", 0);
607  processAllInState(sh, JobState::INIT, 0);
608  processAllInState(sh, JobState::RUN, nRunThreads);
609  processAllInState(sh, JobState::DOWNLOAD, nDlThreads);
610  processAllInState(sh, JobState::MERGE, 0);
611 
612  sh.save("input");
613 
614  std::cout << std::endl;
615 
616  bool allDone = true;
617  for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
618  JobState::Enum state = sampleState(*s);
619  std::string details = (*s)->meta()->castString("nc_ELG_state_details", "", SH::MetaObject::CAST_NOCAST_DEFAULT);
620  if (not details.empty()) { details = '(' + details + ')'; }
621 
622  std::cout << (*s)->name() << "\t";
623  switch (state) {
624  case JobState::INIT:
625  case JobState::RUN:
626  case JobState::DOWNLOAD:
627  case JobState::MERGE:
628  std::cout << JobState::name[state] << "\t";
629  break;
630  case JobState::FINISHED:
631  std::cout << "\033[1;32m" << JobState::name[state] << "\033[0m\t";
632  break;
633  case JobState::FAILED:
634  std::cout << "\033[1;31m" << JobState::name[state] << "\033[0m\t";
635  break;
636  }
637  std::cout << details << std::endl;
638 
639  allDone &= (state == JobState::FINISHED || state == JobState::FAILED);
640  }
641 
642  std::cout << std::endl;
643 
644  data.retrieved = true;
645  data.completed = allDone;
646  return ::StatusCode::SUCCESS;
647 }
648 
649 void EL::PrunDriver::status(const std::string& location)
650 {
651  RCU_REQUIRE(not location.empty());
652  TmpCd tmpDir(location);
654  sh.load("input");
655  RCU_ASSERT(sh.size());
656  processAllInState(sh, JobState::RUN, 0);
657  sh.save("input");
658  for (SH::SampleHandler::iterator s = sh.begin(); s != sh.end(); ++s) {
659  JobState::Enum state = sampleState(*s);
660  std::string details = (*s)->meta()->castString("nc_ELG_state_details", "", SH::MetaObject::CAST_NOCAST_DEFAULT);
661  if (not details.empty()) { details = '(' + details + ')'; }
662  std::cout << (*s)->name() << "\t" << JobState::name[state]
663  << "\t" << details << std::endl;
664  }
665 }
666 
667 void EL::PrunDriver::setState(const std::string& location,
668  const std::string& task,
669  const std::string& state)
670 {
671  RCU_REQUIRE(not location.empty());
672  RCU_REQUIRE(not task.empty());
673  RCU_REQUIRE(not state.empty());
674  TmpCd tmpDir(location);
676  sh.load("input");
677  RCU_ASSERT(sh.size());
678  if (not sh.get(task)) {
679  std::cout << "Unknown task: " << task << std::endl;
680  std::cout << "Choose one of: " << std::endl;
681  sh.print();
682  return;
683  }
684  JobState::parse(state);
685  sh.get(task)->meta()->setString("nc_ELG_state", state);
686  sh.save("input");
687 }
mergePhysValFiles.pattern
pattern
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:26
data
char data[hepevt_bytes_allocation_ATLAS]
Definition: HepEvt.cxx:11
EL::Driver::doManagerStep
virtual ::StatusCode doManagerStep(Detail::ManagerData &data) const
checkxAOD.ds
ds
Definition: Tools/PyUtils/bin/checkxAOD.py:260
SH::MetaObject::CAST_NOCAST_DEFAULT
@ CAST_NOCAST_DEFAULT
cast and return the default value if the input has the wrong type
Definition: MetaObject.h:78
SH::SampleHandler::iterator
std::vector< Sample * >::const_iterator iterator
the iterator to use
Definition: SampleHandler.h:475
INIT
#define INIT(__TYPE)
ExceptionMsg.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
get_generator_info.result
result
Definition: get_generator_info.py:21
offline_EventStorage_v5::FINISHED
@ FINISHED
Definition: v5_DataWriter.h:42
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
SH::MetaObject
A class that manages meta-data to be associated with an object.
Definition: MetaObject.h:56
EL::OutputStream
Definition: OutputStream.h:34
SH::rucioListDids
std::vector< RucioListDidsEntry > rucioListDids(const std::string &dataset)
run rucio-list-dids for the given dataset
Definition: GridTools.cxx:348
BeamSpot::mutex
std::mutex mutex
Definition: InDetBeamSpotVertex.cxx:18
Job.h
DoubleEventSelectorOverlayTest.nThreads
nThreads
Definition: DoubleEventSelectorOverlayTest.py:83
outputLabel
const std::string outputLabel
Definition: OverlapRemovalTester.cxx:69
parse
std::map< std::string, std::string > parse(const std::string &list)
Definition: egammaLayerRecalibTool.cxx:1082
RCU_REQUIRE
#define RCU_REQUIRE(x)
Definition: Assert.h:208
EL::PrunDriver::status
static void status(const std::string &location)
Definition: PrunDriver.cxx:649
OutputStream.h
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
SH::SampleHandler::end
iterator end() const
the end iterator to use
SampleHandler.h
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
hadd.h
ShellExec.h
ReadOfcFromCool.field
field
Definition: ReadOfcFromCool.py:48
EL::PrunDriver::setState
static void setState(const std::string &location, const std::string &task, const std::string &state)
Definition: PrunDriver.cxx:667
Assert.h
MessageCheck.h
SUSY_SimplifiedModel_PostInclude.process
string process
Definition: SUSY_SimplifiedModel_PostInclude.py:42
submit
Definition: submit.py:1
mergePhysValFiles.end
end
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:93
SH::SampleHandler::save
void save(const std::string &directory) const
save the list of samples to the given directory
EL::PrunDriver::PrunDriver
PrunDriver()
Definition: PrunDriver.cxx:491
compareGeometries.outputFile
string outputFile
Definition: compareGeometries.py:25
PyPoolBrowser.item
item
Definition: PyPoolBrowser.py:129
WorkList
std::vector< WorkUnit > WorkList
Definition: PhysicsAnalysis/D3PDTools/EventLoopGrid/Root/pool.h:13
RCU::hadd
void hadd(const std::string &output_file, const std::vector< std::string > &input_files, unsigned max_files)
effects: perform the hadd functionality guarantee: basic failures: out of memory III failures: i/o er...
Definition: hadd.cxx:28
EL::PrunDriver
a Driver to submit jobs via prun
Definition: PrunDriver.h:23
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
MetaObject.h
FullCPAlgorithmsTest_eljob.sh
sh
Definition: FullCPAlgorithmsTest_eljob.py:111
details
Definition: IParticleWriter.h:21
FullCPAlgorithmsTest_eljob.sample
sample
Definition: FullCPAlgorithmsTest_eljob.py:113
lumiFormat.i
int i
Definition: lumiFormat.py:85
internal_poltrig::MERGE
@ MERGE
Definition: PolygonTriangulator.cxx:112
RCU::Shell
Definition: ShellExec.cxx:28
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ManagerData.h
Algorithm.h
EL::Job::optGridPrunShipAdditionalFilesOrDirs
static const std::string optGridPrunShipAdditionalFilesOrDirs
Enables to ship additional files to the tarbal sent to the grid Should be a list of comma separated p...
Definition: Job.h:485
mergePhysValFiles.origDir
origDir
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:24
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
GridTools.h
ANA_MSG_WARNING
#define ANA_MSG_WARNING(xmsg)
Macro printing warning messages.
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:292
generateReferenceFile.files
files
Definition: generateReferenceFile.py:12
add-xsec-uncert-quadrature-N.label
label
Definition: add-xsec-uncert-quadrature-N.py:104
file
TFile * file
Definition: tile_monitor.h:29
SH::SampleGrid
This class implements a Sample located on the grid.
Definition: SampleGrid.h:44
SH::MetaObject::castString
std::string castString(const std::string &name, const std::string &def_val="", CastMode mode=CAST_ERROR_THROW) const
the meta-data string with the given name
python.AtlRunQueryLib.options
options
Definition: AtlRunQueryLib.py:379
EL::PrunDriver::doManagerStep
virtual ::StatusCode doManagerStep(Detail::ManagerData &data) const override
Definition: PrunDriver.cxx:497
EL::Detail::ManagerStep::doRetrieve
@ doRetrieve
call the actual doRetrieve method
SH::Sample::meta
MetaObject * meta()
the meta-information for this sample
RCU_INVARIANT
#define RCU_INVARIANT(x)
Definition: Assert.h:201
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
python.CreateTierZeroArgdict.outputs
outputs
Definition: CreateTierZeroArgdict.py:189
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
beamspotman.dir
string dir
Definition: beamspotman.py:623
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
PathResolver.h
python.ExitCodes.what
def what(code)
Definition: ExitCodes.py:73
LoadMacro
gROOT LoadMacro("../ISF_FastCaloSimParametrization/MeanAndRMS.h+")
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
PrunDriver.h
SH::SampleHandler::begin
iterator begin() const
the begin iterator to use
item
Definition: ItemListSvc.h:43
SH::MetaObject::fetchDefaults
void fetchDefaults(const MetaObject &source)
fetch the meta-data from the given sample not present in this sample.
SampleGrid.h
EL::OutputStream::optContainerSuffix
static const std::string optContainerSuffix
Definition: OutputStream.h:122
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
EL::PrunDriver::testInvariant
void testInvariant() const
Definition: PrunDriver.cxx:486
pool.h
Athena::Status
Status
Athena specific StatusCode values.
Definition: AthStatusCode.h:22
std::sort
void sort(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, const Compare &comp)
Specialization of sort for DataVector/List.
Definition: DVL_algorithms.h:623
copySelective.target
string target
Definition: copySelective.py:37
RCU::Shell::exec
void exec(const std::string &cmd)
effects: execute the given command guarantee: strong failures: out of memory II failures: system fail...
Definition: ShellExec.cxx:29
EL::Detail::ManagerData
an internal data structure for passing data between different manager objects anbd step
Definition: ManagerData.h:46
SH::SampleHandler
A class that manages a list of Sample objects.
Definition: SampleHandler.h:60
RCU_ASSERT0
#define RCU_ASSERT0(y)
Definition: Assert.h:226
merge.status
status
Definition: merge.py:17
ManagerStep.h
EL::Job
Definition: Job.h:51
EL::PrunDriver::doRetrieve
::StatusCode doRetrieve(Detail::ManagerData &data) const
Definition: PrunDriver.cxx:594
test_interactive_athena.job
job
Definition: test_interactive_athena.py:6
python.PyAthena.obj
obj
Definition: PyAthena.py:132
outputFileNames
std::string outputFileNames(const EL::Job &job)
Definition: PrunDriver.cxx:425
RCU_ASSERT
#define RCU_ASSERT(x)
Definition: Assert.h:222
SH::rucioDownloadList
std::vector< RucioDownloadResult > rucioDownloadList(const std::string &location, const std::vector< std::string > &datasets)
run rucio-download with multiple datasets
Definition: GridTools.cxx:523
create_dcsc_inputs_sqlite.RUN
int RUN
Definition: create_dcsc_inputs_sqlite.py:45
RCU_READ_INVARIANT
#define RCU_READ_INVARIANT(x)
Definition: Assert.h:229
EL::Detail::ManagerStep::submitJob
@ submitJob
do the actual job submission
skel.keepDir
keepDir
Definition: skel.ABtoEVGEN.py:487
Sample.h
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
ClassImp
ClassImp(EL::PrunDriver) namespace
Definition: PrunDriver.cxx:48
merge
Definition: merge.py:1
RCU_NEW_INVARIANT
#define RCU_NEW_INVARIANT(x)
Definition: Assert.h:233