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