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