REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestTask.cxx
1 
28 #include "TRestTask.h"
29 
30 #include "TFunction.h"
31 #include "TMethodArg.h"
32 #include "TRestManager.h"
33 #include "TRestReflector.h"
34 #include "TRestStringHelper.h"
35 
36 using namespace std;
37 
38 ClassImp(TRestTask);
39 
40 #ifdef WIN32
41 // in windows the pointer address from string conversion is without "0x", we must add
42 // the prefix so that ROOT can correctly initialize run/metadata objects
43 #define PTR_ADDR_PREFIX "0x"
44 #else
45 #define PTR_ADDR_PREFIX ""
46 #endif // WIN32
47 
52  Initialize();
53  fNRequiredArgument = 0;
54  if (this->ClassName() != (string) "TRestTask") {
55  fMode = TASK_CLASS;
56  }
57 }
58 
65 TRestTask::TRestTask(TString TaskString, REST_TASKMODE mode) {
66  Initialize();
67  fNRequiredArgument = 0;
68  fMode = mode;
69 
70  if (mode == TASK_MACRO) {
71  // we parse the macro file, get the method's name and argument list
72  string filename = TRestTools::SeparatePathAndName((string)TaskString).second;
73  int n = filename.find_last_of('.');
74  string funcName = "";
75  if (n > 0) {
76  funcName = filename.substr(0, n);
77  } else {
78  funcName = TaskString;
79  }
80  TFunction* f = gROOT->GetGlobalFunction(funcName.c_str());
81  if (f == nullptr) {
82  fMode = TASK_ERROR;
83  } else {
84  fNRequiredArgument = f->GetNargs() - f->GetNargsOpt();
85  fInvokeMethod = funcName;
86  // indicates whether the argument is string/TString/const char *. If so, the value would be 1. We
87  // need to add "" mark when constructing command. Otherwise the value is 0.
88 
89  TList* list = f->GetListOfMethodArgs();
90  for (int i = 0; i < list->GetSize(); i++) {
91  TMethodArg* arg = (TMethodArg*)list->At(i);
92  string type = arg->GetTypeName();
93  fArgumentTypes.push_back(type == "string" || type == "char" || type == "TString");
94  fArgumentNames.push_back(arg->GetName());
95  }
96  string fConstructedCommand = "";
97  }
98 
99  } else if (mode == TASK_CPPCMD) {
100  // we parse the command, get the target object, method to be invoked, and
101  // the argument list
102  string cmd = (string)TaskString;
103 
104  string name;
105  string call;
106  if (Split(cmd, "->").size() != 2) {
107  RESTWarning << "command"
108  << " \"" << cmd << "\" "
109  << "is illegal!" << RESTendl;
110  fMode = TASK_ERROR;
111  return;
112  } else {
113  name = Split(cmd, "->")[0];
114  call = Split(cmd, "->")[1];
115  }
116 
117  int p1 = call.find_first_of("(");
118  int p2 = call.find_last_of(")");
119  if (p1 == -1 || p2 == -1 || p1 >= p2) {
120  RESTWarning << "command"
121  << " \"" << cmd << "\" "
122  << "is illegal!" << RESTendl;
123  fMode = TASK_ERROR;
124  return;
125  }
126  fInvokeObject = name;
127  fInvokeMethod = call.substr(0, p1);
128 
129  string args = call.substr(p1 + 1, p2 - p1 - 1);
130  fArgumentValues = Split(args, ",");
131  fConstructedCommand = cmd;
132  } else if (mode == TASK_CLASS) {
133  // I don't think we can get here
134  } else if (mode == TASK_SHELLCMD) {
135  fConstructedCommand = TaskString;
136  fInvokeMethod = Split(fConstructedCommand, " ")[0];
137  }
138 }
139 
144 void TRestTask::InitFromConfigFile() { ReadAllParameters(); }
145 
151 void TRestTask::SetArgumentValue(vector<string> arg) {
152  if (arg.size() < fNRequiredArgument) {
153  PrintArgumentHelp();
154  exit(0);
155  }
156  fArgumentValues = arg;
157 }
158 
163  if (fInvokeMethod == "") {
164  RESTError << "no task specified for TRestTask!!!" << RESTendl;
165  exit(-1);
166  } else {
167  if (fMode == TASK_MACRO) {
168  // call gInterpreter to run a command
169  for (unsigned int i = 0; i < fArgumentValues.size(); i++) {
170  if (fArgumentValues[i] == "NOT SET") {
171  RESTError << "TRestTask : argument " << i << " not set! Task will not run!" << RESTendl;
172  }
173  }
174 
175  fConstructedCommand = fInvokeMethod + "(";
176  for (unsigned int i = 0; i < fArgumentValues.size(); i++) {
177  if (fArgumentTypes[i] == 1) {
178  fConstructedCommand += "\"" + Replace(fArgumentValues[i], "\\", "\\\\", 0) + "\"";
179  } else {
180  fConstructedCommand += fArgumentValues[i];
181  }
182 
183  if (i < fArgumentValues.size() - 1) fConstructedCommand += ",";
184  }
185  fConstructedCommand += ")";
186 
187  cout << "Command : " << fConstructedCommand << endl;
188 
189  gInterpreter->ProcessLine(fConstructedCommand.c_str());
190  return;
191  } else if (fMode == TASK_CPPCMD) {
192  //
193  if (mgr == nullptr) {
194  RESTError << "no target specified for the command:" << RESTendl;
195  RESTError << fConstructedCommand << RESTendl;
196  exit(-1);
197  } else {
198  TRestMetadata* meta = mgr->GetMetadata(fInvokeObject);
199  if (meta == nullptr) {
200  RESTError << "cannot file metadata: " << fInvokeObject << " in TRestManager" << RESTendl;
201  RESTError << "command: " << fConstructedCommand << RESTendl;
202  exit(-1);
203  } else {
204  string type = meta->ClassName();
205  string cmd = Form("%s* %s = (%s*)%s;", type.c_str(), fInvokeObject.c_str(), type.c_str(),
206  (PTR_ADDR_PREFIX + ToString(meta)).c_str());
207 
208  TInterpreter::EErrorCode err;
209  gInterpreter->ProcessLine(cmd.c_str(), &err);
210  if (err != TInterpreter::kNoError) {
211  RESTError << "TRestTask::RunTask(): unknown error" << RESTendl;
212  RESTError << "code: " << err << RESTendl;
213  exit(-1);
214  }
215  gInterpreter->ProcessLine(fConstructedCommand.c_str(), &err);
216  if (err != TInterpreter::kNoError) {
217  RESTError << "TRestTask: failed to execute cpp command, error code: " << err
218  << RESTendl;
219  RESTError << fConstructedCommand << RESTendl;
220  RESTError << "Check your <AddTask section!" << RESTendl;
221  exit(-1);
222  }
223  }
224  }
225  } else if (fMode == TASK_SHELLCMD) {
226  int z = system(fConstructedCommand.c_str());
227  if (z != 0) RESTError << "Problem launching : " << fConstructedCommand << RESTendl;
228  }
229  }
230 }
231 
237  if (fMode == 0) {
238  RESTError << fInvokeMethod << "() Gets invalided input!" << RESTendl;
239  cout << "You should give the following arguments (* is mandatory input):" << endl;
240  unsigned int n = fArgumentNames.size();
241  for (unsigned int i = 0; i < n; i++) {
242  cout << (i < fNRequiredArgument ? "*" : "") << fArgumentNames[i] << endl;
243  }
244  } else if (fMode == 1) {
245  } else if (fMode == 2) {
246  RESTError << "Macro class \"" << this->ClassName() << "\" gets invalided input!" << RESTendl;
247  RESTError << "You should give the following arguments ( * : necessary input):" << RESTendl;
248  unsigned int n = RESTValue(this).GetNumberOfDataMembers();
249  for (unsigned int i = 1; i < n; i++) {
250  if (i < fNRequiredArgument + 1) RESTError << "*";
251  RESTError << RESTValue(this).GetDataMember(i).name << RESTendl;
252  }
253  }
254 }
255 
270 // string macfile = TRestTools::SearchFileInPath({REST_PATH + "/macros"}, "REST_" + (string)taskName + ".C")
271 #ifdef WIN32
272  auto macfiles = TRestTools::GetFilesMatchingPattern(REST_PATH + "/macros/*" + (string)taskName + ".*");
273 #else
274  string macfilelists =
275  TRestTools::Execute("find $REST_PATH/macros -name *" + (string)taskName + (string) ".*");
276  auto macfiles = Split(macfilelists, "\n");
277 #endif
278 
279  if (macfiles.size() != 0 && macfiles[0] != "") {
280  RESTInfo << "Found MacroFile " << macfiles[0] << TRestStringOutput::RESTendl;
281  // system("echo \"#define REST_MANAGER\" > /tmp/tmpMacro.c");
282  // system(("cat " + macfiles[0] + " >> /tmp/tmpMacro.c").c_str());
283  if (gInterpreter->LoadFile(macfiles[0].c_str()) == 0) {
284  TRestTask* tsk = new TRestTask(macfiles[0].c_str(), TASK_MACRO);
285  if (tsk->GetMode() == TASK_ERROR) {
286  RESTError
287  << "Task file: " << macfiles[0]
288  << " loaded but method not found. Make sure it contains the method with same name as "
289  "file name"
290  << TRestStringOutput::RESTendl;
291  return nullptr;
292  }
293  return tsk;
294  } else {
295  RESTError << "Task file: " << macfiles[0] << " contains error" << TRestStringOutput::RESTendl;
296  return nullptr;
297  }
298 
299  } else {
300  // initialize from a class which is inherited from TRestTask
301  TRestTask* tsk = REST_Reflection::Assembly((string)taskName);
302  if (tsk != nullptr && tsk->InheritsFrom("TRestTask")) {
303  tsk->SetMode(TASK_CLASS);
304  return tsk;
305  }
306  }
307  RESTError << "REST ERROR. Task : " << taskName << " not found!!" << TRestStringOutput::RESTendl;
308  return nullptr;
309 }
310 
311 TRestTask* TRestTask::GetTaskFromCommand(TString cmd) {
312  REST_TASKMODE mode = TASK_CPPCMD;
313  if (((string)cmd).find("->") == string::npos) mode = TASK_SHELLCMD;
314 
315  auto tsk = new TRestTask(cmd, mode);
316  if (tsk->GetMode() == TASK_ERROR) {
317  delete tsk;
318  return nullptr;
319  } else {
320  return tsk;
321  }
322 }
int GetNumberOfDataMembers() const
Get the number of data members of a class.
std::string name
Name field.
TRestReflector GetDataMember(const std::string &name)
Find the class's datamember as TRestReflector object, including those from base class.
Managing applications and executing tasks.
Definition: TRestManager.h:16
TRestMetadata * GetMetadata(std::string name)
Get the application metadata class, according to the name.
A base class for any REST metadata class.
Definition: TRestMetadata.h:74
Wrapping REST macros into tasks.
Definition: TRestTask.h:27
void SetArgumentValue(std::vector< std::string > arg)
Set argument directly with a list of string.
Definition: TRestTask.cxx:151
virtual void RunTask(TRestManager *)
Run the task with command line.
Definition: TRestTask.cxx:162
virtual void PrintArgumentHelp()
Default helper method both for TRestTask and any TRestTask-inherited class.
Definition: TRestTask.cxx:236
TRestTask()
TRestTask default constructor.
Definition: TRestTask.cxx:51
static TRestTask * GetTaskFromMacro(TString Name)
Static method to instantiate a TRestTask object with "MacroName".
Definition: TRestTask.cxx:269
void InitFromConfigFile() override
Starter method. Looks through the rml sections and set argument/datamenber value.
Definition: TRestTask.cxx:144
static std::string Execute(std::string cmd)
Executes a shell command and returns its output in a string.
static std::pair< std::string, std::string > SeparatePathAndName(const std::string &fullname)
Separate path and filename in a full path+filename string, returns a pair of string.
Definition: TRestTools.cxx:813
static std::vector< std::string > GetFilesMatchingPattern(std::string pattern, bool unlimited=false)
Returns a list of files whose name match the pattern string. Key word is "*". e.g....
Definition: TRestTools.cxx:976
TRestReflector Assembly(const std::string &typeName)
Assembly an object of type: typeName, returning the allocated memory address and size.
std::vector< std::string > Split(std::string in, std::string separator, bool allowBlankString=false, bool removeWhiteSpaces=false, int startPos=-1)
Split the input string according to the given separator. Returning a vector of fragments.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace any occurences of thisSring by byThisString inside string in.