REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestTask.cxx
1
27
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
36using namespace std;
37
38ClassImp(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
65TRestTask::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
145
151void TRestTask::SetArgumentValue(vector<string> arg) {
152 if (arg.size() < fNRequiredArgument) {
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
311TRestTask* 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
endl_t RESTendl
Termination flag object for TRestStringOutput.
virtual void Initialize()
Making default settings.
void ReadAllParameters()
Reflection methods, Set value of a datamember in class according to TRestMetadata::fElement.
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.