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