GSI Object Oriented Online Offline (Go4)  GO4-6.1.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
MainUserAnalysis.cxx
Go to the documentation of this file.
1 // $Id: MainUserAnalysis.cxx 3028 2021-03-05 14:36:27Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include <cstring>
15 #include <cstdlib>
16 #include <cstdio>
17 #include <iostream>
18 
19 #include "RVersion.h"
20 #include "TROOT.h"
21 #include "TClass.h"
22 #include "TClassTable.h"
23 #include "TDataType.h"
24 #include "TMethod.h"
25 #include "TMethodArg.h"
26 #include "TRint.h"
27 #include "TSystem.h"
28 #include "TObjString.h"
29 #include "TInterpreter.h"
30 #include "TStyle.h"
31 
32 #include "TGo4Version.h"
33 #include "TGo4Log.h"
34 #include "TGo4StepFactory.h"
35 #include "TGo4AnalysisStep.h"
36 #include "TGo4AnalysisImp.h"
37 #include "TGo4AnalysisClient.h"
38 #include "Go4EventServer.h"
39 #include "Go4EventServerTypes.h"
40 
41 #ifdef __GO4HDF5__
43 #include "TGo4HDF5StoreParameter.h"
44 #endif
45 
46 #include "TGo4FileStore.h"
47 
48 #define PROCESSLOOPDELAY 20
49 // milliseconds
50 #define TERMCOUNTS 10000
51 // x PROCESSLOOPDELAY termination wait time
52 
53 void showerror(const char* msg)
54 {
55  std::cerr << "Error: " << msg << std::endl;
56  std::cerr << "Call 'go4analysis -help' to see list of available arguments" << std::endl;
57  exit(1);
58 }
59 
61 {
62  std::cout << " -file filename : use file filename (lmd or lml) as MBS event source (short: -f)" << std::endl;
63  std::cout << " -transport server : connect to MBS transport server (short: -tr)" << std::endl;
64  std::cout << " -stream server : connect to MBS stream server (short: -st)" << std::endl;
65  std::cout << " -evserv server : connect to MBS event server (short: -ev)" << std::endl;
66  std::cout << " -revserv server [port] : connect to remote event server (short: -rev)" << std::endl;
67  std::cout << " -random : use random generator as source (short: -rnd)" << std::endl;
68 #ifdef __GO4HDF5__
69  std::cout << " -hdf5 name : use HDF5 formatted file (h5) as event source" << std::endl;
70 #endif
71  std::cout << " -user name : create user-defined event source" << std::endl;
72  std::cout << " -timeout tm : specify timeout parameter for event source" << std::endl;
73  std::cout << " -skip num : skip num first events in mbs event source" << std::endl;
74  std::cout << " -mbs-select first last step : select events interval from mbs source " << std::endl;
75  std::cout << " first: sequence number of the first event (starts from 0)" << std::endl;
76  std::cout << " last: sequence number of the last event" << std::endl;
77  std::cout << " step: step over several events, 1 means all events are used" << std::endl;
78 
79 }
80 
81 void usage(const char* subtopic = 0)
82 {
83  std::cout << std::endl;
84  std::cout << "GO4 analysis runnable " << __GO4RELEASE__ << std::endl;
85  std::cout << "S. Linev, GSI, Darmstadt" << std::endl;
86 
87  if ((subtopic!=0) && (strlen(subtopic)>0)) {
88  const char* sub = subtopic;
89  if (*sub=='-') sub++;
90 
91  if ((strcmp(subtopic, "sources")==0) || (strcmp(subtopic, "src")==0) || (strcmp(subtopic, "src")==0)) {
92  std::cout << "These are arguments of go4analysis which allows to specify event source" << std::endl;
93  printsources();
94  return;
95  } else
96  if ((strcmp(sub, "print")==0) || (strcmp(sub, "pr")==0) ||
97  (strcmp(sub, "type")==0) || (strcmp(sub, "ty")==0)) {
98  std::cout << "Usage of go4analysis -print command." << std::endl;
99  std::cout << std::endl;
100  std::cout << " go4analysis -print|-pr|-type|-ty [PROPT] [SOURCE] [MISC]" << std::endl;
101  std::cout << std::endl;
102  std::cout << "PROPT: print options, right after -print command" << std::endl;
103  std::cout << " hex : print data in hexadecimal format" << std::endl;
104  std::cout << " dec : print data in decimal format" << std::endl;
105  std::cout << " long : print data in long (4 bytes) form (default)" << std::endl;
106  std::cout << " short : print data in short (2 bytes) form" << std::endl;
107  std::cout << " sub=N : select subevent id N (default all subevents are shown)" << std::endl;
108  std::cout << " fhead : print current lmd file header" << std::endl;
109  std::cout << " bhead : print current buffer header" << std::endl;
110  std::cout << "SOURCE: event source print options" << std::endl;
111  printsources();
112  std::cout << "MISC: other options, which may be relevant for \"print\" command" << std::endl;
113  std::cout << " -number M : print M events, default is 1 (short: -num)" << std::endl;
114  std::cout << " -lib name : load library, may be required for user-defined sources" << std::endl;
115  std::cout << " -v : enable verbose mode to see some debug output (default: -v2)" << std::endl;
116  std::cout << std::endl;
117  std::cout << " Print event header from MBS stream server" << std::endl;
118  std::cout << " go4analysis -stream r4-4 -print " << std::endl;
119  std::cout << std::endl;
120  std::cout << " Print event data in hexadecimal form from MBS event server" << std::endl;
121  std::cout << " go4analysis -ev r2-1 -pr hex" << std::endl;
122  std::cout << std::endl;
123  std::cout << " Print 5 events with subevent id=1 in decimal form from MBS transport server" << std::endl;
124  std::cout << " go4analysis -tr r2-2 -num 5 -ty dec sub=1 " << std::endl;
125  std::cout << std::endl;
126  return;
127  } else {
128  std::cout << "No help for topic: \""<< subtopic << "\"" << std::endl;
129  std::cout << "Available: print, sources" << std::endl;
130  return;
131  }
132  }
133 
134  std::cout << "calling: " << std::endl;
135  std::cout << "" << std::endl;
136  std::cout << " go4analysis [RUN] [ANALYSIS] [STEP1] [STEP2] ... [USER]" << std::endl;
137  std::cout << "" << std::endl;
138  std::cout << "RUN: configuration, relevant for application run mode" << std::endl;
139  std::cout << " -lib name : user library to load (default: libGo4UserLibrary)" << std::endl;
140  std::cout << " -server [name] : run analysis in server mode, name - optional analysis name" << std::endl;
141  std::cout << " -gui name guihost guiport : run analysis in gui mode, used by GUI launch analysis" << std::endl;
142 #ifdef WITH_HTTP
143  std::cout << " -http [port] : run analysis with web-server running, " << std::endl;
144  std::cout << " optionally port can be specified, default 8080" << std::endl;
145  std::cout << " -auth [filename] : use authentication file to restrict access to http server " << std::endl;
146  std::cout << " file should contain 'controller' and 'admin' accounts for 'go4' domain" << std::endl;
147  std::cout << " Could be generated with htdigets utility, by default '$GO4SYS/etc/.htdigest' filename is used" << std::endl;
148  std::cout << " -fastcgi port : run analysis with fastcgi server running, "<< std::endl;
149  std::cout << " which can deliver data to normal webserver (see mod_proxy_fcgi for Apache)" << std::endl;
150  std::cout << " -jsroot location : use JSROOT from other location like https://root.cern.ch/js/latest/" << std::endl;
151 #ifdef WITH_DABC
152  std::cout << " -dabc master_host:port : run analysis with optional connection to dabc application, "<< std::endl;
153  std::cout << " which could receive objects from running analysis" << std::endl;
154 #endif
155 #endif
156  std::cout << " -run : run analysis in server mode (default only run if source specified)" << std::endl;
157  std::cout << " -norun : exclude automatical run" << std::endl;
158  std::cout << " -number NUMBER : process NUMBER events in batch mode" << std::endl;
159  std::cout << " -hserver [name [passwd]] : start histogram server with optional name and password" << std::endl;
160  std::cout << " -log [filename] : enable log output into filename (default:go4logfile.txt)" << std::endl;
161  std::cout << " -v -v0 -v1 -v2 -v3 : change log output verbosity (0 - maximum, 1 - info, 2 - warn, 3 - errors)" << std::endl;
162  std::cout << " -gdebug [lvl] : set ROOT gDebug value, default 1" << std::endl;
163  std::cout << " -rate : display rate information during run" << std::endl;
164  std::cout << " -print [sub=N] [hex|dec] : print events, see -help print for more info" << std::endl;
165  std::cout << " -help [topic] : show this help or for selected topic" << std::endl;
166  std::cout << " -graphics : enable graphics in the analysis" << std::endl;
167  std::cout << "" << std::endl;
168  std::cout << "ANALYSIS: common analysis configurations" << std::endl;
169  std::cout << " -name name : specify analysis instance name" << std::endl;
170  std::cout << " -asf [filename] : enable store autosave file and set autosave filename (default <Name>ASF.root)" << std::endl;
171  std::cout << " -enable-asf [interval] : enable store of autosave file, optionally interval in seconds" << std::endl;
172  std::cout << " -disable-asf : disable usage of asf" << std::endl;
173  std::cout << " -prefs [filename] : load preferences (analysis configuration) from specified file (default Go4AnalysisPrefs.root)" << std::endl;
174  std::cout << " -no-prefs : disable preferences loading" << std::endl;
175  std::cout << " -maxtreesize value : define maximum tree size, value can be: 2g, 1900m, 1900000000" << std::endl;
176  std::cout << "" << std::endl;
177  std::cout << "STEP: individual step configurations" << std::endl;
178  std::cout << " -step name : select step by it's name, if not found, first step will be used" << std::endl;
179  std::cout << " -step number : select step by it's number (first step has number 0)" << std::endl;
180  std::cout << " -enable-step : enable step processing" << std::endl;
181  std::cout << " -disable-step : disable step processing" << std::endl;
182  std::cout << " -file filename : use file filename (lmd or lml) as MBS event source" << std::endl;
183  std::cout << " -transport server : connect to MBS transport server" << std::endl;
184  std::cout << " -stream server : connect to MBS stream server" << std::endl;
185  std::cout << " -evserv server : connect to MBS event server" << std::endl;
186  std::cout << " -revserv server [port] : connect to remote event server" << std::endl;
187  std::cout << " -port number : select custom port number for event source" << std::endl;
188  std::cout << " -retry number : select number of retries when connection to source was lost" << std::endl;
189  std::cout << " -random : use random generator as source" << std::endl;
190  std::cout << " -user name : create user-defined event source" << std::endl;
191  std::cout << " -source filename : read step input from the root file" << std::endl;
192 #ifdef __GO4HDF5__
193  std::cout << " -hdf5 filename : read step input from hdf5 file (.h5)" << std::endl;
194 #endif
195  std::cout << " -skip num : skip num first events in mbs event source" << std::endl;
196  std::cout << " -mbs-select first last step : select events interval from mbs source" << std::endl;
197  std::cout << " -timeout tm : specify timeout parameter for event source" << std::endl;
198  std::cout << " -enable-source : enable step source" << std::endl;
199  std::cout << " -disable-source : disable step source" << std::endl;
200  std::cout << " -store filename [split buffersize compression] : write step output into the root file" << std::endl;
201  std::cout << " -overwrite-store : overwrite file, when store output" << std::endl;
202  std::cout << " -append-store : append to file, when store output" << std::endl;
203  std::cout << " -backstore name : create backstore for online tree draw" << std::endl;
204 #ifdef __GO4HDF5__
205  std::cout << " -hdf5store filename : write step output into hdf5 file (.h5)" << std::endl;
206 #endif
207  std::cout << " -userstore name : create user-defined store for output data" << std::endl;
208  std::cout << " -enable-store : enable step store" << std::endl;
209  std::cout << " -disable-store : disable step store" << std::endl;
210  std::cout << " -enable-errstop : enable stop-on-error mode" << std::endl;
211  std::cout << " -disable-errstop : disable stop-on-error mode" << std::endl;
212  std::cout << " -inpevt-class name : (re)define class name of input event" << std::endl;
213  std::cout << " -outevt-class name : (re)define class name of output event" << std::endl;
214  std::cout << std::endl;
215  std::cout << "USER: user-defined arguments" << std::endl;
216  std::cout << " -args [userargs] : create user analysis with constructor (int argc, char** argv) signature" << std::endl;
217  std::cout << " all following arguments will be provided as array of strings, first argument - analysis name" << std::endl;
218  std::cout << std::endl;
219 }
220 
222  public:
223  TGo4PrintProcessor(const char* name) : TGo4EventProcessor(name) {}
224 
225  static Int_t fSubId;
226  static Bool_t fHex;
227  static Bool_t fLong;
228  static Bool_t fData;
229  static Bool_t fFileHead;
230  static Bool_t fBufHead;
231 
232  virtual Bool_t BuildEvent(TGo4EventElement* dest)
233  {
235 
236  TGo4MbsEvent* mbs = dynamic_cast<TGo4MbsEvent*> (evnt);
237  if (mbs) mbs->PrintMbsEvent(fSubId, fLong, fHex, fData, fBufHead, fFileHead);
238  else evnt->PrintEvent();
239 
240  return kTRUE;
241  }
242 };
243 
244 Int_t TGo4PrintProcessor::fSubId = -1;
245 Bool_t TGo4PrintProcessor::fHex = kTRUE;
246 Bool_t TGo4PrintProcessor::fLong = kTRUE;
247 Bool_t TGo4PrintProcessor::fData = kFALSE;
248 Bool_t TGo4PrintProcessor::fFileHead = kFALSE;
249 Bool_t TGo4PrintProcessor::fBufHead = kFALSE;
250 
252  public:
253  TGo4PrintFactory(const char* name) : TGo4StepFactory(name) {}
255  {
256  return new TGo4PrintProcessor("PrintProc");
257  }
258 };
259 
260 
261 typedef TGo4Analysis* (UserCreateFunc)(const char* name);
262 
263 int FindArg(int argc, char **argv, const char* argname)
264 {
265  if ((argname==0) || (strlen(argname)==0)) return -1;
266  for (int n=0;n<argc;n++)
267  if (strcmp(argv[n], argname)==0) return n;
268  return -1;
269 }
270 
271 const char* GetArgValue(int argc, char **argv, const char* argname, int* pos = 0, bool incomplete = false)
272 {
273  int n = pos ? *pos : 0;
274 
275  while (++n<argc)
276  if (strcmp(argv[n], argname)==0) {
277  if ((n+1<argc) && (argv[n+1][0]!='-')) {
278  if (pos) *pos = n+1;
279  return argv[n+1];
280  } else
281  if (incomplete) {
282  if (pos) *pos = n+1;
283  return "";
284  }
285  }
286 
287  if (pos) *pos = 0;
288  return 0;
289 }
290 
291 TList* GetClassesList(TList* prev = 0)
292 {
293  TClassTable::Init();
294  char* name = 0;
295 
296  TList* lst = new TList;
297  lst->SetOwner(kTRUE);
298 
299  if (prev!=0) TGo4Log::Debug("Search user classes in loaded library");
300 
301  while ((name = TClassTable::Next()) != 0) {
302  if (prev && prev->FindObject(name)) continue;
303 
304  TNamed* obj = new TNamed(name, name);
305  lst->Add(obj);
306 
307  if (prev!=0) TGo4Log::Debug("New class %s", name);
308  }
309  return lst;
310 }
311 
312 TGo4Analysis* CreateDefaultAnalysis(TList* lst, const char* name, int user_argc, char** user_argv, bool doprint)
313 {
314  TIter iter(lst);
315  TObject* obj(0);
316 
317  TObjArray evnt_classes; // list of found event classes
318 
319  TClass *proc_cl(0), *an_cl(0), *evsrc_cl(0), *evstore_cl(0);
320 
321  while ((obj = iter()) != 0) {
322  TClass* cl = TClass::GetClass(obj->GetName());
323 
324  // all relevant go4 classes inherited from TObject
325  if ((cl==0) || !cl->IsStartingWithTObject()) continue;
326 
327  if (cl->InheritsFrom(TGo4EventProcessor::Class())) {
328  // if several processor classes are existing, take higher in hierarchy
329  if ((cl!=TGo4EventProcessor::Class()) && ((proc_cl==0) || cl->InheritsFrom(proc_cl))) proc_cl = cl;
330  } else
331  if (cl->InheritsFrom(TGo4EventSource::Class())) {
332  if ((cl != TGo4EventSource::Class()) && !evsrc_cl) evsrc_cl = cl;
333  } else
334  if (cl->InheritsFrom(TGo4EventStore::Class())) {
335  if ((cl != TGo4EventStore::Class()) && !evstore_cl) evstore_cl = cl;
336  } else
337  if (cl->InheritsFrom(TGo4EventElement::Class())) {
338  if (cl != TGo4EventElement::Class()) evnt_classes.Add(cl);
339  } else
340  if (cl->InheritsFrom(TGo4Analysis::Class())) {
341  if ((cl != TGo4Analysis::Class()) && !an_cl) an_cl = cl;
342  }
343  }
344 
345  if (doprint) {
346  an_cl = 0;
347  }
348 
349  if (an_cl!=0) {
350 
351  TGo4Log::Info("Find user analysis class %s", an_cl->GetName());
352 
353  TMethod* meth = an_cl->GetMethodWithPrototype(an_cl->GetName(), "int,char**");
354  if (meth!=0) {
355  TGo4Log::Info("!!! Find constructor with prototype %s::%s(int, char**)", an_cl->GetName(), an_cl->GetName());
356 
357  if ((user_argc>0) && (user_argv!=0))
358  user_argv[0] = (char*) name;
359  else {
360  user_argc = 1;
361  user_argv = (char**) &name;
362  }
363 
364  #ifdef WIN32
365  TString cmd = TString::Format("new %s(%d, (char**)0x%x)", an_cl->GetName(), user_argc, user_argv);
366  #else
367  TString cmd = TString::Format("new %s(%d, (char**)%p)", an_cl->GetName(), user_argc, user_argv);
368  #endif
369  Int_t err = 0;
370 
371  TGo4Log::Info("Process: %s", cmd.Data());
372 
373  TGo4Analysis* analysis = (TGo4Analysis*) gROOT->ProcessLineFast(cmd.Data(), &err);
374 
375  if ((analysis!=0) && (err==0)) return analysis;
376 
377  TGo4Log::Error("Cannot create analysis class %s instance with (int, char**) prototype", an_cl->GetName());
378  TGo4Log::Error("Implement correct analysis constructor with such signature in user library");
379  exit(1);
380  }
381 
382 
383  meth = an_cl->GetMethodWithPrototype(an_cl->GetName(), "const char*");
384  if (meth!=0) {
385  TGo4Log::Info("!!! Find constructor with prototype %s::%s(const char*)", an_cl->GetName(), an_cl->GetName());
386 
387  TString cmd = TString::Format("new %s(\"%s\")", an_cl->GetName(), name);
388  Int_t err = 0;
389 
390  TGo4Log::Info("Process: %s", cmd.Data());
391 
392  TGo4Analysis* analysis = (TGo4Analysis*) gROOT->ProcessLineFast(cmd.Data(), &err);
393 
394  if ((analysis!=0) && (err==0)) return analysis;
395 
396  TGo4Log::Error("Cannot create analysis class %s instance with (const char*) prototype", an_cl->GetName());
397  TGo4Log::Error("Implement correct analysis constructor with such signature in user library");
398  exit(1);
399  }
400 
401  // search for non-default analysis constructor
402  TIter iter(an_cl->GetListOfMethods());
403  while ((meth = (TMethod*) iter()) != 0) {
404  if (strcmp(meth->GetName(), an_cl->GetName()) != 0) continue;
405  if (meth->GetListOfMethodArgs()->GetSize()==0) continue;
406  break;
407  }
408 
409  if (meth==0) {
410  TGo4Log::Error("Cannot find non-default constructor for class %s", an_cl->GetName());
411  TGo4Log::Error("Implement analysis constructor with (const char*) or (int,char**) signature");
412  TGo4Log::Error("Or define TGo4Analysis* CreateUserAnalysis(const char*) function in user library");
413  exit(1);
414  }
415 
416  TGo4Log::Info("Find constructor with %d arguments", meth->GetListOfMethodArgs()->GetSize());
417 
418  TMethodArg *argument = 0;
419  TIter next(meth->GetListOfMethodArgs());
420 
421  TString cmd = TString::Format("new %s(", an_cl->GetName());
422 
423  int counter = 0;
424 
425  while ((argument = (TMethodArg *) next())) {
426 
427  if (counter>0) cmd+=", ";
428  counter++;
429 
430  TDataType *datatype = gROOT->GetType(argument->GetTypeName());
431 
432  TString basictype = (datatype==0) ? "int" : datatype->GetTypeName();
433 
434  TGo4Log::Debug("Argument %s type %s basictype %s", argument->GetName(), argument->GetTitle(), basictype.Data());
435 
436  TString argDflt = argument->GetDefault() ? argument->GetDefault() : "";
437  if (argDflt.Length()>0) {
438  cmd += argDflt;
439  continue;
440  }
441 
442  bool isptr = strchr(argument->GetTitle(), '*') != 0;
443 
444  if ((datatype==0) && !isptr) {
445  TGo4Log::Error("Cannot specify any value for argument %s of class %s constructor", argument->GetName(), an_cl->GetName());
446  TGo4Log::Error("Add CreateUserAnalysis(const char*) function in user library");
447  exit(1);
448  }
449 
450  if (isptr) {
451  if ((basictype == "char") || (basictype="Text_t")) cmd+="\"\"";
452  else cmd+="0";
453  } else {
454  if ((counter==2) && (basictype=="int")) {
455  TGo4Log::Info("Special treatment for second integer argument, suppose MBS input type");
456  cmd += TString::Format("%d", GO4EV_MBS_FILE);
457  } else
458  if (basictype=="bool") {
459  cmd += "false";
460  } else
461  cmd += "0";
462  }
463  }
464 
465  cmd += ")";
466 
467  Int_t err = 0;
468  TGo4Log::Info("Process: %s", cmd.Data());
469  TGo4Analysis* analysis = (TGo4Analysis*) gROOT->ProcessLineFast(cmd.Data(), &err);
470  if ((analysis!=0) && (err==0)) return analysis;
471 
472  TGo4Log::Error("Cannot create analysis class %s instance", an_cl->GetName());
473  TGo4Log::Error("Add CreateUserAnalysis(const char*) function in user library");
474 
475  exit(1);
476  }
477 
478  TClass *outev_cl(0), *inpev_cl(0);
479 
480  const char* inp_evnt_classname = GetArgValue(user_argc, user_argv, "-inpevt-class");
481  const char* out_evnt_classname = GetArgValue(user_argc, user_argv, "-outevt-class");
482 
483  if (inp_evnt_classname!=0) {
484  inpev_cl = gROOT->GetClass(inp_evnt_classname);
485  if (inpev_cl==0) {
486  TGo4Log::Error("Class %s not exists", inp_evnt_classname);
487  exit(1);
488  }
489 
490  if (!inpev_cl->InheritsFrom(TGo4EventElement::Class())) {
491  TGo4Log::Error("Class %s cannot be used as input event", inp_evnt_classname);
492  exit(1);
493  }
494 
495  evnt_classes.Remove(inpev_cl);
496  evnt_classes.Compress();
497  }
498 
499  if (out_evnt_classname!=0) {
500  outev_cl = gROOT->GetClass(out_evnt_classname);
501  if (outev_cl==0) {
502  TGo4Log::Error("Class %s not exists", out_evnt_classname);
503  exit(1);
504  }
505 
506  if (!outev_cl->InheritsFrom(TGo4EventElement::Class())) {
507  TGo4Log::Error("Class %s cannot be used as output event", out_evnt_classname);
508  exit(1);
509  }
510 
511  evnt_classes.Remove(outev_cl);
512  evnt_classes.Compress();
513  }
514 
515  // check if user event source requires special event class
516  // create instance only if we have something to check
517  if ((evsrc_cl!=0) && (inpev_cl==0) && (evnt_classes.GetLast() >= 0)) {
518  TGo4EventSource* src = (TGo4EventSource*) evsrc_cl->New();
519 
520  // if special input event is required, try to detect it
521  if ((src!=0) && !src->CheckEventClass(TGo4MbsEvent::Class())) {
522  for (int n=0; n<=evnt_classes.GetLast(); n++) {
523  TClass* cl = (TClass*) evnt_classes.At(n);
524  if (!src->CheckEventClass(cl)) continue;
525 
526  // if more than two classes are suited - ignore any of them
527  if (inpev_cl!=0) { inpev_cl = 0; break; }
528 
529  inpev_cl = cl;
530  }
531  }
532 
533  delete src;
534 
535  if (inpev_cl!=0) {
536  evnt_classes.Remove(inpev_cl);
537  evnt_classes.Compress();
538  }
539  }
540 
541  // as very last, try to define best-suitable output event
542  if (outev_cl==0)
543  for (int n=0; n<=evnt_classes.GetLast(); n++) {
544  TClass* cl = (TClass*) evnt_classes.At(n);
545  if ((outev_cl==0) || cl->InheritsFrom(outev_cl)) outev_cl = cl;
546  }
547 
548  if (doprint) {
549  TGo4Log::Info("Create default analysis with print-processor class");
550  outev_cl = 0;
551  } else {
552  if (proc_cl==0) return 0;
553  TGo4Log::Info("Create default analysis with processor class %s", proc_cl->GetName());
554  if (outev_cl!=0)
555  TGo4Log::Info("Use class %s as output event", outev_cl->GetName());
556  }
557 
558 
559  if (inpev_cl!=0)
560  TGo4Log::Info("Use class %s as input event", inpev_cl->GetName());
561 
562  TGo4Analysis* analysis = TGo4Analysis::Instance();
563  analysis->SetAnalysisName(name);
564 
566 
567  if (doprint) {
568  factory = new TGo4PrintFactory("Factory");
569  } else {
570  factory = new TGo4StepFactory("Factory");
571  factory->DefEventProcessor("Processor", proc_cl->GetName());// object name, class name
572  }
573 
574  if (inpev_cl)
575  factory->DefInputEvent("InputEvent", inpev_cl->GetName()); // object name, class name
576 
577  if (outev_cl)
578  factory->DefOutputEvent("OutputEvent", outev_cl->GetName()); // object name, class name
579  else
580  factory->DefOutputEvent("OutputEvent", "TGo4EventElement"); // object name, class name
581 
582  if (evsrc_cl)
583  factory->DefUserEventSource(evsrc_cl->GetName());
584 
585  if (evstore_cl)
586  factory->DefUserEventStore(evstore_cl->GetName());
587 
588  TGo4MbsFileParameter* sourcepar = new TGo4MbsFileParameter(analysis->GetDefaultTestFileName());
589 
590  TGo4AnalysisStep* step = new TGo4AnalysisStep("Analysis", factory, sourcepar);
591 
592  step->SetSourceEnabled(kTRUE);
593  step->SetStoreEnabled(evstore_cl != 0);
594  step->SetProcessEnabled(kTRUE);
595  step->SetErrorStopEnabled(kTRUE);
596 
597  // Now the first analysis step is set up.
598  // Other steps could be created here
599  analysis->AddAnalysisStep(step);
600 
601  return analysis;
602 }
603 
604 //================== analysis main program ============================
605 int main(int argc, char **argv)
606 {
608  std::cerr << "Please check your system configuration and restart analysis again" << std::endl;
609  return -1;
610  }
611 
612  if (argc==1) {
613  usage();
614  return 0;
615  }
616 
617  int phelp = FindArg(argc, argv, "-help");
618  if (phelp < 0) phelp = FindArg(argc, argv, "-h") > 0;
619  if (phelp > 0) {
620  usage(phelp < argc-1 ? argv[phelp+1] : 0);
621  return 0;
622  }
623 
624  int user_argc = 0;
625  char** user_argv = 0;
626 
627  int userargspos = FindArg(argc, argv, "-args");
628  if (userargspos<0) userargspos = FindArg(argc, argv, "-x");
629  if (userargspos>0) {
630  user_argc = argc - userargspos;
631  user_argv = argv + userargspos;
632  // hide user-defined arguments
633  argc = userargspos;
634  }
635 
636  bool doprint = (FindArg(argc, argv, "-print") > 0) || (FindArg(argc, argv, "-type") > 0) ||
637  (FindArg(argc, argv, "-pr") > 0) || (FindArg(argc, argv, "-ty") > 0);
638  if (doprint) TGo4Log::SetIgnoreLevel(2);
639 
640  const char* logfile = GetArgValue(argc, argv, "-log", 0, true);
641  if (logfile!=0) {
642 
644 
645  TGo4Log::LogfileEnable(kTRUE);
646  if (strlen(logfile)==0) logfile = TGo4Log::GetDefaultLogname();
647  TGo4Log::OpenLogfile(logfile, 0, kTRUE);
648 
649  TString info = "go4analysis";
650  for (int n=1;n<argc;n++) { info += " "; info += argv[n]; }
651 
652  TGo4Log::WriteLogfile(info.Data(), true);
653  }
654 
655  if ((FindArg(argc, argv, "-v")>0) || (FindArg(argc, argv, "-verbose")>0)) TGo4Log::SetIgnoreLevel(-1);
656  else if (FindArg(argc, argv, "-v0")>0) TGo4Log::SetIgnoreLevel(0);
657  else if (FindArg(argc, argv, "-v1")>0) TGo4Log::SetIgnoreLevel(1);
658  else if (FindArg(argc, argv, "-v2")>0) TGo4Log::SetIgnoreLevel(2);
659  else if (FindArg(argc, argv, "-v3")>0) TGo4Log::SetIgnoreLevel(3);
660 
662  if (FindArg(argc, argv, "-gui")>0) TGo4Analysis::SetRunningMode(1); else
663  if (FindArg(argc, argv, "-server")>0) TGo4Analysis::SetRunningMode(2);
664 
665  // disable cint locking when called via process line
666  // makes problem in multi-threaded environment, where CINT lock
667  // also used for object streaming
668  gInterpreter->SetProcessLineLock(kFALSE);
669 
670  // add main go4 include path for the case if scripts are called from inside analysis, required for ROOT6
671  TString go4inc = TGo4Log::GO4INCPATH();
672  if (go4inc.Length()==0) go4inc = TGo4Log::subGO4SYS("include");
673  if (go4inc.Length()>0)
674  gInterpreter->AddIncludePath(go4inc.Data());
675 
676  const char *extra_incl = gSystem->Getenv("GO4EXTRAINCLUDE");
677  if (extra_incl && *extra_incl)
678  gInterpreter->AddIncludePath(extra_incl);
679 
680  const char* analysis_name = GetArgValue(argc, argv, "-server");
681  if (analysis_name==0) analysis_name = GetArgValue(argc, argv, "-gui");
682  if (analysis_name==0) analysis_name = GetArgValue(argc, argv, "-name");
683  if (analysis_name==0) analysis_name = "Go4Analysis";
684 
685  TList* lst0 = GetClassesList();
686 
687  int argpos = 0;
688  bool isanylib = false;
689  const char* libname = 0;
690  while ((libname = GetArgValue(argc, argv, "-lib", &argpos))!=0) {
691  TGo4Log::Info("Reading library: %s", libname);
692  if (gSystem->Load(libname)<0) return -1;
693  isanylib = true;
694  }
695 
696  // we should try to load library if for printing -user argument specified - means user input
697  if (!isanylib && (!doprint || GetArgValue(argc, argv, "-user"))) {
698  libname = "libGo4UserAnalysis";
699  TGo4Log::Info("Reading library: %s", libname);
700  if (gSystem->Load(libname)<0) return -1;
701  }
702 
703  TList* lst1 = GetClassesList(lst0);
704 
705  TGo4Analysis* analysis = 0;
706 
707  UserCreateFunc* crfunc = (UserCreateFunc*) gSystem->DynFindSymbol("*", "CreateUserAnalysis");
708  if (crfunc) analysis = crfunc(analysis_name);
709  else analysis = CreateDefaultAnalysis(lst1, analysis_name, user_argc, user_argv, doprint);
710 
711  if (analysis==0) {
712  std::cerr << "!!! Analysis instance cannot be created" << std::endl;
713  std::cerr << "!!! PLEASE check your analysis library " << libname << std::endl;
714  std::cerr << "!!! One requires user subclass for TGo4Analysis class in user library" << std::endl;
715  std::cerr << "!!! Alternatively, CreateUserAnalysis(const char*) function can be implemented" << std::endl;
716  std::cerr << "!!! See Go4ExampleSimple, Go4Example1Step or Go4Example2Step for details" << std::endl;
717  return -1;
718  }
719 
720  delete lst0; lst0 = 0;
721  delete lst1; lst1 = 0;
722 
723  TGo4AnalysisStep* step = analysis->GetAnalysisStep(0);
724  if (step==0) {
725  std::cerr << "No active step in analysis found" << std::endl;
726  return -1;
727  }
728 
729  int app_argc = 1;
730  // char* app_argv[] = { argv[0], (char*) "-l" };
731  // TApplication theApp("Go4App", &app_argc, argv);
732 
733  gROOT->SetBatch(kTRUE);
734 
735  TObjArray http_args; // all arguments for http server
736  http_args.SetOwner(kTRUE);
737  TString auth_file; // authentication file for http server
738  const char* auth_domain = "go4"; // default authentication domain http server
739  (void) auth_domain; // prevent compiler warning
740 
741  Bool_t batchMode(kTRUE); // GUI or Batch
742  Bool_t servermode(kFALSE); // run analysis as server task
743  Bool_t httpmode(kFALSE); // run analysis with web server
744  Bool_t hserver(kFALSE); // enable histogram server
745  Bool_t loadprefs(kTRUE); // loading preferences by client
746  Bool_t showrate(kFALSE); // display event rate
747  Double_t process_interv(-1.); // interval how often system events will be processed by analysis
748  const char* hname = ""; // namebase for histogram server
749  const char* hpasswd = ""; // password for histogram server
750  const char* hostname = "localhost"; // gui host name
751  Int_t iport(5000); // port number used by GUI
752 
753  bool autorun(false); // immediately run analysis on start
754  long maxevents(-1); // number of events (batch mode)
755  Int_t canrun(0); // -1 cannot run, 0 - only if source specify, 1 - always
756 
757  if (doprint) {
758  maxevents = 1;
759  analysis->SetAutoSave(kFALSE);
760  }
761 
762  //------ process arguments -------------------------
763 
764  int narg = 1;
765 
766  while (narg < argc) {
767  if (strcmp(argv[narg], "-server")==0) {
768  narg++;
769  batchMode = kFALSE;
770  servermode = kTRUE;
771  // skip name, if specified
772  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-')) narg++;
773  } else
774  if(strcmp(argv[narg], "-gui") == 0) {
775  batchMode = kFALSE;
776  if (argc <= narg + 3) showerror("Not all -gui arguments specified");
777  narg++; // -gui
778  narg++; // name
779  hostname = argv[narg++];
780  iport = atoi(argv[narg++]); // port of GUI server
781  } else
782 #ifdef WITH_HTTP
783  if (strcmp(argv[narg], "-http")==0) {
784  narg++;
785  httpmode = kTRUE;
786  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
787  http_args.Add(new TObjString(Form("http:%s?top=Go4", argv[narg++])));
788  else
789  http_args.Add(new TObjString("http:8080?top=Go4"));
790  } else
791  if (strcmp(argv[narg], "-fastcgi")==0) {
792  narg++;
793  httpmode = kTRUE;
794  if (narg >= argc) showerror("fastcgi options not specified");
795  http_args.Add(new TObjString(Form("fastcgi:%s?top=Go4", argv[narg++])));
796  } else
797  if (strcmp(argv[narg], "-jsroot")==0) {
798  narg++;
799  if (narg >= argc) showerror("jsroot location not specified");
800  http_args.Add(new TObjString(Form("jsroot:%s", argv[narg++])));
801  } else
802  if (strcmp(argv[narg], "-auth")==0) {
803  narg++;
804  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
805  auth_file = argv[narg++];
806  else
807  auth_file = TGo4Log::subGO4SYS("etc/htdigest.txt");
808  } else
809  if (strcmp(argv[narg], "-domain")==0) {
810  narg++;
811  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
812  auth_domain = argv[narg++];
813  else
814  auth_domain = "go4";
815  } else
816 #ifdef WITH_DABC
817  if (strcmp(argv[narg], "-dabc")==0) {
818  narg++;
819  if (narg >= argc) showerror("Master dabc node not specified");
820  const char* hostname = gSystem->HostName();
821  if ((hostname==0) || (*hostname==0)) hostname = "localhost";
822  http_args.Add(new TObjString(Form("dabc:%s?top=Go4/%s_pid%d", argv[narg++],hostname,gSystem->GetPid())));
823  } else
824 #endif
825 #endif
826  if(strcmp(argv[narg], "-lib") == 0) {
827  // skip library name
828  if (++narg >= argc) showerror("library name not specified");
829  narg++;
830  } else
831  if(strcmp(argv[narg], "-name") == 0) {
832  // skip analysis name
833  if (++narg >= argc) showerror("analysis name not specified");
834  narg++;
835  } else
836  if (strcmp(argv[narg],"-step")==0) {
837  if (++narg < argc) {
838  const char* step_name = argv[narg++];
839  int step_number(-1);
840  step = 0;
841  if (sscanf(step_name, "%d", &step_number)==1)
842  if (step_number>=0) step = analysis->GetAnalysisStepNum(step_number);
843  if (step==0) step = analysis->GetAnalysisStep(step_name);
844  if (step==0) showerror("step not found");
845  } else
846  showerror("step name not specified");
847  } else
848  if(strcmp(argv[narg],"-enable-step")==0) {
849  narg++;
850  step->SetProcessEnabled(kTRUE);
851  } else
852  if(strcmp(argv[narg],"-disable-step")==0) {
853  narg++;
854  step->SetProcessEnabled(kFALSE);
855  } else
856  if ((strcmp(argv[narg],"-file")==0) || (strcmp(argv[narg],"-f")==0)) {
857  if (++narg < argc) {
858  TGo4MbsFileParameter sourcepar(argv[narg++]);
859  // this is case when many files are specified at once
860  while ((narg<argc) && (argv[narg][0]!='-'))
861  sourcepar.AddMoreFile(argv[narg++]);
862  step->SetEventSource(&sourcepar);
863  step->SetSourceEnabled(kTRUE);
864  autorun = true;
865  } else
866  showerror("LMD/LML file name not specified");
867  } else
868  if (strcmp(argv[narg],"-source")==0) {
869  if (++narg < argc) {
870  TGo4FileSourceParameter sourcepar(argv[narg++]);
871  step->SetEventSource(&sourcepar);
872  step->SetSourceEnabled(kTRUE);
873  autorun = true;
874  } else
875  showerror("Input file name not specified");
876  } else
877  if ((strcmp(argv[narg],"-transport")==0) || (strcmp(argv[narg],"-tr")==0)) {
878  if (++narg < argc) {
879  TGo4MbsTransportParameter sourcepar(argv[narg++]);
880  step->SetEventSource(&sourcepar);
881  step->SetSourceEnabled(kTRUE);
882  autorun = true;
883  } else
884  showerror("MBS Transport server name not specified");
885  } else
886  if ((strcmp(argv[narg],"-stream")==0) || (strcmp(argv[narg],"-st")==0)) {
887  if (++narg < argc) {
888  TGo4MbsStreamParameter sourcepar(argv[narg++]);
889  step->SetEventSource(&sourcepar);
890  step->SetSourceEnabled(kTRUE);
891  autorun = true;
892  } else
893  showerror("MBS Stream server name not specified");
894  } else
895  if ((strcmp(argv[narg],"-evserv")==0) || (strcmp(argv[narg],"-ev")==0)) {
896  if (++narg < argc) {
897  TGo4MbsEventServerParameter sourcepar(argv[narg++]);
898  step->SetEventSource(&sourcepar);
899  step->SetSourceEnabled(kTRUE);
900  autorun = true;
901  } else
902  showerror("MBS Event server name not specified");
903  } else
904  if ((strcmp(argv[narg],"-random")==0) || (strcmp(argv[narg],"-rnd")==0)) {
905  narg++;
906  TGo4MbsRandomParameter sourcepar("Random");
907  step->SetEventSource(&sourcepar);
908  step->SetSourceEnabled(kTRUE);
909  autorun = true;
910  } else
911  if (strcmp(argv[narg],"-user")==0) {
912  if (++narg < argc) {
913  TGo4UserSourceParameter sourcepar(argv[narg++]);
914  step->SetEventSource(&sourcepar);
915  step->SetSourceEnabled(kTRUE);
916  autorun = true;
917  } else
918  showerror("User source name not specified");
919  }
920 #ifdef __GO4HDF5__
921  else
922  if (strcmp(argv[narg],"-hdf5")==0) {
923  if (++narg < argc) {
924  TGo4HDF5SourceParameter sourcepar(argv[narg++]);
925  step->SetEventSource(&sourcepar);
926  step->SetSourceEnabled(kTRUE);
927  autorun = true;
928  } else
929  showerror("HDF5 file name not specified");
930  }
931 #endif
932 
933  else
934  if ((strcmp(argv[narg],"-revserv")==0) || (strcmp(argv[narg],"-rev")==0)) {
935  if (++narg < argc) {
936  const char* serv_name = argv[narg++];
937  int serv_port = 0;
938  if ((narg < argc) && (argv[narg][0] != '-'))
939  serv_port = atoi(argv[narg++]);
940  TGo4RevServParameter sourcepar(serv_name, serv_port);
941  step->SetEventSource(&sourcepar);
942  step->SetSourceEnabled(kTRUE);
943  autorun = true;
944  } else
945  showerror("Remote event server name or port are not specified");
946  } else
947  if (strcmp(argv[narg],"-skip")==0) {
948  narg++;
949  TGo4MbsSourceParameter* param = dynamic_cast<TGo4MbsSourceParameter*> (step->GetEventSource());
950  if (param==0) showerror("only in MBS source events can be skipped");
951  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-')) {
952  unsigned value=0;
953  if (sscanf(argv[narg],"%u",&value)!=1)
954  showerror(Form("Value error %s", argv[narg]));
955  param->SetStartEvent(value);
956  narg++;
957  }
958  } else
959  if (strcmp(argv[narg],"-port")==0) {
960  narg++;
961  int port(0);
962  if ((narg < argc) && (argv[narg][0]!='-')) {
963  if (sscanf(argv[narg],"%d",&port)!=1)
964  showerror(Form("Value error %s", argv[narg]));
965  narg++;
966  }
967  TGo4MbsSourceParameter* param = dynamic_cast<TGo4MbsSourceParameter*> (step->GetEventSource());
968  if (param) param->SetPort(port);
969 
970  TGo4UserSourceParameter* user = dynamic_cast<TGo4UserSourceParameter*> (step->GetEventSource());
971  if (user) user->SetPort(port);
972  } else
973  if (strcmp(argv[narg],"-retry")==0) {
974  narg++;
975  int nretry(0);
976  if ((narg < argc) && (argv[narg][0]!='-')) {
977  if (sscanf(argv[narg],"%d",&nretry)!=1)
978  showerror(Form("Value error %s", argv[narg]));
979  narg++;
980  }
981  TGo4MbsSourceParameter* param = dynamic_cast<TGo4MbsSourceParameter*> (step->GetEventSource());
982  if (param) param->SetRetryCnt(nretry);
983  } else
984  if (strcmp(argv[narg],"-mbs-select")==0) {
985  narg++;
986  TGo4MbsSourceParameter* param = dynamic_cast<TGo4MbsSourceParameter*> (step->GetEventSource());
987  if (param==0) showerror("only in MBS source events can be selected");
988  unsigned cnt=0;
989  while ((cnt<3) && (narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-')) {
990  unsigned value(0);
991  if ((cnt==1) && (strcmp(argv[narg],"all")==0)) value = 0; else
992  if (sscanf(argv[narg],"%u",&value)!=1)
993  showerror(Form("Value error %s", argv[narg]));
994  if (cnt==0) param->SetStartEvent(value); else
995  if (cnt==1) param->SetStopEvent(value); else
996  if (cnt==2) param->SetEventInterval(value);
997  narg++; cnt++;
998  }
999  } else
1000  if(strcmp(argv[narg],"-store")==0) {
1001  if (++narg >= argc) showerror("Store name not specified");
1002 
1003  const char* sourcename = argv[narg++];
1004  int splitlevel = 1;
1005  int buffersize = 64000;
1006  int compression = 5;
1007 
1008  unsigned cnt=0;
1009  while ((cnt<3) && (narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-')) {
1010  int value(0);
1011  if (sscanf(argv[narg],"%d",&value)!=1)
1012  showerror(Form("Value error %s", argv[narg]));
1013  if (cnt==0) splitlevel = value; else
1014  if (cnt==1) buffersize = value; else
1015  if (cnt==2) compression = value;
1016  narg++; cnt++;
1017  }
1018 
1019  TGo4FileStoreParameter storepar(sourcename, splitlevel, buffersize, compression);
1020  step->SetEventStore(&storepar);
1021  step->SetStoreEnabled(kTRUE);
1022  } else
1023  if (strcmp(argv[narg], "-timeout")==0) {
1024  if (++narg >= argc) showerror("Timeout value not specified");
1025  if (step->GetEventSource()==0) showerror("No source parameter configured");
1026  int value(0);
1027  if (sscanf(argv[narg],"%d",&value)!=1)
1028  showerror(Form("Timeout value error %s", argv[narg]));
1029  narg++;
1030  step->GetEventSource()->SetTimeout(value);
1031  } else
1032  if (strcmp(argv[narg],"-overwrite-store")==0) {
1033  narg++;
1034  TGo4FileStoreParameter* par = dynamic_cast<TGo4FileStoreParameter*> (step->GetEventStore());
1035  if (par) par->SetOverwriteMode(kTRUE);
1036  else showerror("No file-store parameter available");
1037  } else
1038  if (strcmp(argv[narg],"-append-store")==0) {
1039  narg++;
1040  TGo4FileStoreParameter* par = dynamic_cast<TGo4FileStoreParameter*> (step->GetEventStore());
1041  if (par) par->SetOverwriteMode(kFALSE);
1042  else showerror("No file-store parameter available");
1043  } else
1044  if(strcmp(argv[narg],"-backstore")==0) {
1045  if (++narg < argc) {
1046  TGo4BackStoreParameter storepar(argv[narg++]);
1047  step->SetEventStore(&storepar);
1048  step->SetStoreEnabled(kTRUE);
1049  } else
1050  showerror("Backstore name not specified");
1051  } else
1052  if(strcmp(argv[narg],"-userstore")==0) {
1053  if (++narg < argc) {
1054  TGo4UserStoreParameter storepar(argv[narg++]);
1055  step->SetEventStore(&storepar);
1056  step->SetStoreEnabled(kTRUE);
1057  } else
1058  showerror("User store name not specified");
1059  } else
1060 #ifdef __GO4HDF5__
1061  if(strcmp(argv[narg],"-hdf5store")==0) {
1062  if (++narg < argc) {
1063  TGo4HDF5StoreParameter storepar(argv[narg++]);
1064  step->SetEventStore(&storepar);
1065  step->SetStoreEnabled(kTRUE);
1066  } else
1067  showerror("HDF5 store name not specified");
1068  } else
1069 #endif
1070  if ((strcmp(argv[narg],"-events")==0) || (strcmp(argv[narg],"-number")==0) || (strcmp(argv[narg],"-num")==0)) {
1071  if (++narg < argc) {
1072  if (sscanf(argv[narg++],"%ld",&maxevents)!=1) maxevents = -1;
1073  } else
1074  showerror("number of events to process not specified");
1075  } else
1076  if (strcmp(argv[narg],"-asf")==0) {
1077  narg++;
1078  analysis->SetAutoSave(kTRUE);
1079  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
1080  analysis->SetAutoSaveFile(argv[narg++]);
1081  } else
1082  if (strcmp(argv[narg],"-enable-asf")==0) {
1083  narg++;
1084  analysis->SetAutoSave(kTRUE);
1085  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
1086  analysis->SetAutoSaveInterval(atoi(argv[narg++]));
1087  } else
1088  if (strcmp(argv[narg],"-disable-asf")==0) {
1089  narg++;
1090  analysis->SetAutoSave(kFALSE);
1091  } else
1092  if (strcmp(argv[narg],"-prefs")==0) {
1093  narg++;
1094  const char* fname = 0;
1095  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
1096  fname = argv[narg++];
1097  analysis->LoadStatus(fname);
1098  loadprefs = kFALSE;
1099  } else
1100  if (strcmp(argv[narg],"-no-prefs")==0) {
1101  narg++;
1102  loadprefs = kFALSE;
1103  } else
1104  if(strcmp(argv[narg],"-log")==0) {
1105  narg++;
1106  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-')) narg++;
1107  } else
1108  if(strcmp(argv[narg],"-gdebug")==0) {
1109  narg++;
1110  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
1111  gDebug = TString(argv[narg++]).Atoi();
1112  else
1113  gDebug = 1;
1114  } else
1115  if((strcmp(argv[narg],"-v")==0) || (strcmp(argv[narg],"-v0")==0) || (strcmp(argv[narg],"-v1")==0) || (strcmp(argv[narg],"-v2")==0) || (strcmp(argv[narg],"-v3")==0)) {
1116  narg++;
1117  } else
1118  if((strcmp(argv[narg],"-graphics")==0) || (strcmp(argv[narg],"-gr")==0)) {
1119  narg++;
1120  gROOT->SetBatch(kFALSE);
1121  process_interv = 0.1; // allow system events processing
1122  new TApplication("Go4App", &app_argc, argv);
1123  TStyle::BuildStyles();
1124  gROOT->SetStyle();
1125  } else
1126  if(strcmp(argv[narg],"-run")==0) {
1127  narg++;
1128  autorun = true;
1129  } else
1130  if(strcmp(argv[narg],"-norun")==0) {
1131  narg++;
1132  canrun = -1;
1133  } else
1134  if(strcmp(argv[narg],"-maxtreesize")==0) {
1135  narg++;
1136  long long maxtreesize = 1900000000;
1137  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-')) {
1138  char sbuf[1000];
1139  strncpy(sbuf, argv[narg], sizeof(sbuf)-1);
1140  long long mult(1), val(1);
1141  int len = strlen(sbuf);
1142  if ((sbuf[len-1]=='g') || (sbuf[len-1]=='G')) { mult = 1000000000; sbuf[len-1] = 0; } else
1143  if ((sbuf[len-1]=='m') || (sbuf[len-1]=='M')) { mult = 1000000; sbuf[len-1] = 0; } else
1144  if ((sbuf[len-1]=='k') || (sbuf[len-1]=='K')) { mult = 1000; sbuf[len-1] = 0; }
1145  if (sscanf(sbuf, "%lld", &val)==1) maxtreesize = val*mult;
1146  narg++;
1147  }
1148  TGo4Log::Info("Set tree file size limit to %lld bytes", maxtreesize);
1149  TGo4FileStore::SetMaxTreeSize(maxtreesize);
1150  } else
1151  if ((strcmp(argv[narg],"-print")==0) || (strcmp(argv[narg],"-type")==0) || (strcmp(argv[narg],"-ty")==0) || (strcmp(argv[narg],"-pr")==0)) {
1152  narg++;
1153  while ((narg<argc) && (argv[narg][0]!='-')) {
1154  if (strncmp(argv[narg],"sub=",4)==0) {
1155  TGo4PrintProcessor::fSubId = atoi(argv[narg] + 4);
1156  } else
1157  if (strcmp(argv[narg],"hex")==0) {
1158  TGo4PrintProcessor::fHex = kTRUE;
1159  TGo4PrintProcessor::fData = kTRUE;
1160  } else
1161  if (strcmp(argv[narg],"dec")==0) {
1162  TGo4PrintProcessor::fHex = kFALSE;
1163  TGo4PrintProcessor::fData = kTRUE;
1164  } else
1165  if (strcmp(argv[narg],"long")==0) {
1166  TGo4PrintProcessor::fLong = kTRUE;
1167  TGo4PrintProcessor::fData = kTRUE;
1168  } else
1169  if (strcmp(argv[narg],"short")==0) {
1170  TGo4PrintProcessor::fLong = kFALSE;
1171  TGo4PrintProcessor::fData = kTRUE;
1172  } else
1173  if (strcmp(argv[narg],"data")==0) {
1174  TGo4PrintProcessor::fData = kTRUE;
1175  } else
1176  if (strcmp(argv[narg],"nodata")==0) {
1177  TGo4PrintProcessor::fData = kFALSE;
1178  } else
1179  if (strcmp(argv[narg],"fhead")==0) {
1181  } else
1182  if (strcmp(argv[narg],"bhead")==0) {
1184  }
1185  narg++;
1186  }
1187  } else
1188  if(strcmp(argv[narg],"-enable-store")==0) {
1189  narg++;
1190  step->SetStoreEnabled(kTRUE);
1191  } else
1192  if(strcmp(argv[narg],"-disable-store")==0) {
1193  narg++;
1194  step->SetStoreEnabled(kFALSE);
1195  } else
1196  if(strcmp(argv[narg],"-enable-source")==0) {
1197  narg++;
1198  step->SetSourceEnabled(kTRUE);
1199  } else
1200  if(strcmp(argv[narg],"-disable-source")==0) {
1201  narg++;
1202  step->SetSourceEnabled(kFALSE);
1203  } else
1204  if(strcmp(argv[narg],"-disable-errstop")==0) {
1205  narg++;
1206  step->SetErrorStopEnabled(kFALSE);
1207  } else
1208  if(strcmp(argv[narg],"-enable-errstop")==0) {
1209  narg++;
1210  step->SetErrorStopEnabled(kTRUE);
1211  } else
1212  if(strcmp(argv[narg],"-rate")==0) {
1213  narg++;
1214  showrate = kTRUE;
1215  } else
1216  if(strcmp(argv[narg],"-norate")==0) {
1217  narg++;
1218  showrate = kFALSE;
1219  } else
1220  if(strcmp(argv[narg],"-inpevt-class")==0) {
1221  // these arguments used only in simple analysis with single step and
1222  // processed when analysis created
1223  narg++;
1224  if (narg < argc) narg++;
1225  } else
1226  if(strcmp(argv[narg],"-outevt-class")==0) {
1227  // these arguments used only in simple analysis with single step and
1228  // processed when analysis created
1229  narg++;
1230  if (narg < argc) narg++;
1231  } else
1232  if(strcmp(argv[narg],"-hserver")==0) {
1233  narg++;
1234  hserver = true;
1235  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
1236  hname = argv[narg++];
1237  if ((narg < argc) && (strlen(argv[narg]) > 0) && (argv[narg][0]!='-'))
1238  hpasswd = argv[narg++];
1239  } else
1240  showerror(Form("Unknown argument %d %s", narg, argv[narg]));
1241  }
1242 
1243  #ifdef WITH_HTTP
1244  if (http_args.GetLast() >= 0) {
1245  if (gSystem->Load("libGo4Http")!=0)
1246  showerror("Fail to load libGo4Http.so library");
1247 
1248  TGo4Log::EnableRedirection(); // one sniff complete std out
1249 
1250  TGo4MbsSource::SetPollingMode(kTRUE); // allow to process http requests when no events are coming
1251 
1252  TString cmd;
1253  Long_t res(0);
1254  Int_t err(0);
1255  for (Int_t n=0;n<=http_args.GetLast();n++) {
1256  TString engine = http_args[n]->GetName();
1257  if ((engine.Index("http:")==0) && (auth_file.Length()>0))
1258  engine.Append(TString::Format("&auth_file=%s&auth_domain=%s", auth_file.Data(), auth_domain));
1259 
1260  cmd.Form("TGo4Sniffer::CreateEngine(\"%s\");", engine.Data());
1261  res = gROOT->ProcessLineFast(cmd.Data(), &err);
1262  if ((res<=0) || (err!=0)) {
1263  printf("Fail to start %s", engine.Data());
1264  return 1;
1265  }
1266  }
1267 
1268  process_interv = 0.1;
1269  }
1270  #endif
1271 
1272  //------ start the analysis -------------------------
1273  if(batchMode) {
1274  TGo4Log::Info("Main: starting analysis in batch mode ... ");
1275 
1276  Bool_t enter_loop = kTRUE;
1277  if ((canrun>=0) || autorun) {
1278  // initialize event classes also with -norun option if any source was specified
1279  if (!analysis->InitEventClasses()) {
1280  TGo4Log::Error("Main: Init event classes failed, aborting!");
1281  enter_loop = kFALSE;
1282  } else {
1283  if (canrun>=0) analysis->StartAnalysis();
1284  }
1285  }
1286 
1287  if (enter_loop) {
1288  analysis->RunImplicitLoop(maxevents, showrate, process_interv, httpmode);
1289  delete analysis;
1290  TGo4Log::Info("Main: analysis batch done");
1291  }
1292  } else {
1293  if (hostname==0) hostname = "localhost";
1294 
1295  if(servermode) TGo4Log::Info("Main: starting analysis in server mode ...");
1296  else TGo4Log::Info("Main: starting analysis in slave mode ...");
1297 
1298  if (canrun<0) autorun = false;
1299 
1300  TGo4AnalysisClient* client = new TGo4AnalysisClient("UserClient", analysis, hostname, iport, hserver, hname, hpasswd, servermode, autorun, kFALSE, loadprefs, showrate);
1301 
1302  TGo4Log::Info("Main: created AnalysisClient instance: %s", client->GetName());
1303  TGo4Log::Info("Main: Run application loop");
1304 
1305 #ifndef WIN32
1306 #if ROOT_VERSION_CODE <= ROOT_VERSION(5,25,2)
1307  // workaround TUnixSystem::DispatchOneEvent problem
1308  gSystem->AddFileHandler(new TFileHandler(0, TFileHandler::kRead));
1309 #endif
1310 #endif
1311 
1312  int termcounter=0;
1313 
1314  while (TGo4Analysis::Exists()) {
1315  // add this check while at some moments ROOT could reset this pointer
1316  if (gSystem==0) {
1317  // printf("ROOT feature - gSystem==0, break execution\n");
1318 
1319  // exit call exit handler and produces even more problems
1320  // we trying to close application as soon as possible - anyway many
1321  // items already cleaned up
1322  abort();
1323  //exit(5);
1324  }
1325 
1326  gSystem->ProcessEvents();
1327  gSystem->Sleep(PROCESSLOOPDELAY);
1328  if(client->IsBeingQuit()) {
1329  if(termcounter == 0) {
1330  termcounter = TERMCOUNTS;
1331  TGo4Log::Info("Found Quit state: starting termination counter with %d s", PROCESSLOOPDELAY * TERMCOUNTS / 1000);
1332  } else
1333  if (termcounter>0) {
1334  termcounter--;
1335  if (termcounter == 0) {
1336  TGo4Log::Info("Reached end of termination counter after %d s, terminating.", PROCESSLOOPDELAY * TERMCOUNTS / 1000);
1337  break;
1338  }
1339  if ((termcounter % (10000 / PROCESSLOOPDELAY)) == 0)
1340  TGo4Log::Info("Counting termination counter down, remains %d s", PROCESSLOOPDELAY * termcounter / 1000);
1341  }
1342  }
1343  }
1344 
1345  }
1346 
1347  TGo4Log::Info("Main: THE END");
1349 
1350  return 0;
1351 }
void SetStartEvent(UInt_t firstindex)
static TGo4Log * Instance()
Definition: TGo4Log.cxx:87
virtual Bool_t BuildEvent(TGo4EventElement *dest)
Bool_t LoadStatus(const char *filename=0)
void SetStopEvent(UInt_t lastindex)
TGo4Analysis *( UserCreateFunc)(const char *name)
void printsources()
static Bool_t CheckVersion(Int_t version)
Definition: TGo4Version.cxx:42
static void SetMaxTreeSize(Long64_t sz)
virtual Bool_t CheckEventClass(TClass *cl)
void DefUserEventSource(const char *Sclass)
void SetEventStore(TGo4EventStoreParameter *kind)
static void WriteLogfile(const char *text, Bool_t withtime=kTRUE)
Definition: TGo4Log.cxx:432
#define TERMCOUNTS
void DefEventProcessor(const char *Pname, const char *Pclass)
TList * GetClassesList(TList *prev=0)
static void CloseLogfile()
Definition: TGo4Log.cxx:456
static const char * GetDefaultLogname()
Definition: TGo4Log.cxx:342
static void SetIgnoreLevel(Int_t level)
Definition: TGo4Log.cxx:326
function factory
Definition: go4canvas.js:1
TGo4PrintFactory(const char *name)
TGo4EventProcessor * CreateEventProcessor(TGo4EventProcessorParameter *par)
static void OpenLogfile(const char *name=0, const char *headercomment=0, Bool_t appendmode=kFALSE)
Definition: TGo4Log.cxx:395
virtual void PrintEvent()
int main(int argc, char **argv)
TGo4AnalysisStep * GetAnalysisStep(const char *name)
void SetSourceEnabled(Bool_t on=kTRUE)
void SetOverwriteMode(Bool_t over=kTRUE)
#define __GO4RELEASE__
Definition: TGo4Version.h:25
Int_t RunImplicitLoop(Int_t times, Bool_t showrate=kFALSE, Double_t process_event_interval=-1., Bool_t iswebserver=kFALSE)
static const char * GO4INCPATH()
Definition: TGo4Log.cxx:181
TGo4EventStoreParameter * GetEventStore() const
void SetAutoSave(Bool_t on=kTRUE)
static void EnableRedirection()
Definition: TGo4Log.cxx:95
static void SetPollingMode(Bool_t on=kTRUE)
#define PROCESSLOOPDELAY
int FindArg(int argc, char **argv, const char *argname)
void DefOutputEvent(const char *Oname, const char *Oclass)
void SetEventInterval(UInt_t skipinterval)
const char * GetName() const
#define __GO4BUILDVERSION__
Definition: TGo4Version.h:24
void PrintMbsEvent(Int_t subid=-1, Bool_t longw=kTRUE, Bool_t hexw=kTRUE, Bool_t dataw=kTRUE, Bool_t bufhead=kFALSE, Bool_t filhead=kFALSE)
void showerror(const char *msg)
void SetStoreEnabled(Bool_t on=kTRUE)
TGo4EventSourceParameter * GetEventSource() const
void AddMoreFile(const char *more)
const char * GetArgValue(int argc, char **argv, const char *argname, int *pos=0, bool incomplete=false)
TGo4EventElement * GetInputEvent()
virtual Bool_t InitEventClasses()
void usage(const char *subtopic=0)
void SetProcessEnabled(Bool_t on=kTRUE)
void SetEventSource(TGo4EventSourceParameter *kind)
void SetAutoSaveFile(const char *filename=0, Bool_t overwrite=kFALSE, Int_t compression=5)
TGo4AnalysisStep * GetAnalysisStepNum(Int_t number)
static TString subGO4SYS(const char *subdir)
Definition: TGo4Log.cxx:192
void DefUserEventStore(const char *Sclass)
void SetErrorStopEnabled(Bool_t on)
TGo4PrintProcessor(const char *name)
static Bool_t Exists()
void DefInputEvent(const char *Iname, const char *Iclass)
static void SetRunningMode(int mode)
static TGo4Analysis * Instance()
static void Error(const char *text,...)
Definition: TGo4Log.cxx:313
Bool_t IsBeingQuit()
static void Info(const char *text,...)
Definition: TGo4Log.cxx:287
TGo4Analysis * CreateDefaultAnalysis(TList *lst, const char *name, int user_argc, char **user_argv, bool doprint)
void SetAutoSaveInterval(Int_t interval=0)
static void Debug(const char *text,...)
Definition: TGo4Log.cxx:274
string msg
Definition: go4init.py:11
static void LogfileEnable(Bool_t on=kTRUE)
Definition: TGo4Log.cxx:373