GSI Object Oriented Online Offline (Go4) GO4-6.4.5
Loading...
Searching...
No Matches
TGo4Sniffer.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 "TGo4Sniffer.h"
15
16#include <cstring>
17
18#include "TClass.h"
19#include "TFolder.h"
20#include "THttpServer.h"
21#include "TBufferJSON.h"
22#include "TGraph.h"
23#include "TDatime.h"
24#include "TTimeStamp.h"
25#include "TROOT.h"
26#include "TH1F.h"
27#include "TFile.h"
28#include "TMethodCall.h"
29#include "TGo4HistogramStatus.h"
30
31#include "TGo4AnalysisImp.h"
32#include "TGo4AnalysisObjectManager.h"
33#include "TGo4AnalysisClientImp.h"
34#include "TGo4Log.h"
35#include "TGo4Parameter.h"
36#include "TGo4Condition.h"
37#include "TGo4AnalysisWebStatus.h"
38#include "TGo4EventElement.h"
39#include "TGo4Ratemeter.h"
40#include "TGo4DynamicEntry.h"
41#include "TGo4MsgList.h"
42
43THttpServer *TGo4Sniffer::gHttpServer = nullptr;
44
46{
47 return gHttpServer;
48}
49
50
51
52Bool_t TGo4Sniffer::CreateEngine(const char *args)
53{
54 if (!gHttpServer) {
55 gHttpServer = new THttpServer("");
56
57 gHttpServer->SetSniffer(new TGo4Sniffer("go4_sniffer"));
58
59 gHttpServer->SetTimer(0); // we disable timer - go4 will call ProcessRequests method itself
60
61 gHttpServer->AddLocation("go4sys/", TGo4Log::GO4SYS());
62
63 TBufferJSON::SetFloatFormat("%15.9e");
64 }
65
66 if (strstr(args, "jsroot:") == args) {
67 gHttpServer->SetJSROOT(args+7);
68 return kTRUE;
69 }
70
71 return gHttpServer->CreateEngine(args);
72}
73
74
75TGo4Sniffer::TGo4Sniffer(const char *name) :
76 TRootSnifferFull(name),
78 fDebugOutput("Log","Analysis log messages", 1000),
79 fStatusMessages("Msg","Analysis status messages", 100),
80 fbPythonBound(kFALSE)
81{
82 SetReadOnly(kFALSE);
83 SetScanGlobalDir(kFALSE);
84
85#ifdef __ROOT_HAVE_POST_ALLOWED__
86 SetAllowPostObject(kTRUE);
87#endif
88
89 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,33,0)
90 fAutoLoadArg = "go4sys/html5/go4.mjs";
91 #else
92 fAutoLoadArg = "jq;go4sys/html/go4.js";
93 #endif
94
96
98
99 fAnalysisStatus->SetName("Analysis");
100
101 RegisterObject("/Status", &fDebugOutput);
102 RegisterObject("/Status", &fStatusMessages);
103
104 if (!HasProduceMultiMethod()) {
105 // new multi.json method was implemented together with requests pre and post processing
106 SetItemField("/Status/Log", "_hidden", "true");
107 SetItemField("/Status/Msg", "_hidden", "true");
108
109 CreateItem("/Status/Message", "Last message from analysis");
110 SetItemField("/Status/Message", "_kind","Text");
111 SetItemField("/Status/Message", "value","---");
112
113 CreateItem("/Status/DebugOutput", "Go4 debug output");
114 SetItemField("/Status/DebugOutput", "_kind","Text");
115 SetItemField("/Status/DebugOutput", "value","---");
116 }
117
119 fRatemeter->SetName("Ratemeter");
120 fRatemeter->SetTitle("Analysis rates");
121
122 fEventRate = new TGraph();
123 fEventRate->SetName("EventsRate");
124 fEventRate->SetTitle("Events processing rate");
125 fEventRate->GetXaxis()->SetTimeDisplay(1);
126 fEventRate->GetXaxis()->SetTimeFormat("%H:%M:%S");
127 fEventRate->GetYaxis()->SetTitle("Events/s");
128 fEventRate->GetHistogram()->SetDirectory(nullptr);
129
130 RegisterObject("/Status", fEventRate);
131
132 RegisterObject("/Status", fRatemeter);
133 SetItemField("/Status/Ratemeter", "_hidden", "true");
134 SetItemField("/Status/Ratemeter", "_status", "GO4.DrawAnalysisRatemeter");
135
136 RegisterCommand("/Control/CmdClear", "this->CmdClear();", "button;go4sys/icons/clear.png");
137 SetItemField("/Control/CmdClear", "_title", "Clear histograms and conditions in analysis");
138 SetItemField("/Control/CmdClear", "_hidden", "true");
139
140 RegisterCommand("/Control/CmdStart", "this->CmdStart();", "button;go4sys/icons/start.png");
141 SetItemField("/Control/CmdStart", "_title", "Start analysis");
142 SetItemField("/Control/CmdStart", "_hidden", "true");
143
144 RegisterCommand("/Control/CmdStop", "this->CmdStop();", "button;go4sys/icons/Stop.png");
145 SetItemField("/Control/CmdStop", "_title", "Stop analysis");
146 SetItemField("/Control/CmdStop", "_hidden", "true");
147
148 RegisterCommand("/Control/CmdClose", "this->CmdClose();", "");
149 SetItemField("/Control/CmdClose", "_title", "Close analysis");
150 SetItemField("/Control/CmdClose", "_hidden", "true");
151
152 RegisterCommand("/Control/CmdRestart", "this->CmdRestart();", "button;go4sys/icons/restart.png");
153 SetItemField("/Control/CmdRestart", "_title", "Resubmit analysis configuration and start again");
154 SetItemField("/Control/CmdRestart", "_hidden", "true");
155
156 RegisterCommand("/Control/CmdExit", "this->CmdExit();", "");
157 SetItemField("/Control/CmdExit", "_title", "Exit analysis process");
158 SetItemField("/Control/CmdExit", "_hidden", "true");
159
160 if (HasRestrictMethod()) {
161 // together with Restrict method support of
162 // commands with arguments was introduced
163
164 RegisterCommand("/Control/CmdOpenFile", "this->CmdOpenFile(\"%arg1%\");", "button;go4sys/icons/fileopen.png");
165 SetItemField("/Control/CmdOpenFile", "_title", "Open ROOT file in analysis");
166 SetItemField("/Control/CmdOpenFile", "_hreload", "true"); // after execution hierarchy will be reloaded
167 //SetItemField("/Control/CmdOpenFile", "_hidden", "true");
168
169 RegisterCommand("/Control/CmdCloseFiles", "this->CmdCloseFiles();", "go4sys/icons/fileclose.png");
170 SetItemField("/Control/CmdCloseFiles", "_title", "Close all opened files");
171 SetItemField("/Control/CmdCloseFiles", "_hreload", "true"); // after execution hierarchy will be reloaded
172 //SetItemField("/Control/CmdCloseFiles", "_hidden", "true");
173
174 RegisterCommand("/Control/CmdClearObject", "this->CmdClearObject(\"%arg1%\");", "");
175 SetItemField("/Control/CmdClearObject", "_title", "Clear object content");
176 SetItemField("/Control/CmdClearObject", "_hidden", "true");
177
178 RegisterCommand("/Control/CmdDeleteObject", "this->CmdDeleteObject(\"%arg1%\");", "");
179 SetItemField("/Control/CmdDeleteObject", "_title", "Delete object from analysis");
180 SetItemField("/Control/CmdDeleteObject", "_hidden", "true");
181
182 RegisterCommand("/Control/CmdExecute", "this->CmdExecute(\"%arg1%\");", "go4sys/icons/macro_t.png");
183 SetItemField("/Control/CmdExecute", "_title", "Execute interpreter line in the analysis context. '@' means 'TGo4Analysis::Instance()->' ; A leading '$' invokes python skript.");
184 //SetItemField("/Control/CmdExecute", "_hidden", "true");
185 }
186
187 RegisterObject("/Control", fAnalysisStatus);
188 if (!HasAutoLoadMethod())
189 SetItemField("/Control/Analysis", "_autoload", fAutoLoadArg);
190 SetItemField("/Control/Analysis", "_icon", "go4sys/icons/control.png");
191 SetItemField("/Control/Analysis", "_not_monitor", "true");
192
193 RegisterObject("/Control", this);
194 SetItemField("/Control/go4_sniffer", "_hidden", "true");
195
196 CreateItem("/Control/Terminal", "Analysis terminal");
197 SetItemField("/Control/Terminal", "_icon", "go4sys/icons/analysiswin.png");
198 SetItemField("/Control/Terminal", "_player", "GO4.drawAnalysisTerminal");
199
200 RestrictGo4("/Control","visible=controller,admin");
201
202 RestrictGo4("/Control/CmdExit","visible=admin");
203
204 RestrictGo4("/Conditions", "allow=controller,admin");
205
206 RestrictGo4("/Parameters", "allow=controller,admin&allow_method=CreateStatus");
207
208 // set at the end when other items exists
209 if (!HasAutoLoadMethod())
210 SetItemField("/", "_autoload", fAutoLoadArg);
211 SetItemField("/", "_icon", "go4sys/icons/go4logo2_small.png");
212 SetItemField("/", "_title", "GO4 analysis");
213 SetItemField("/", "_analysis_name", TGo4Analysis::Instance()->GetName());
214 if (HasRestrictMethod())
215 SetItemField("/", "_has_restrict", "true");
216
218 SetItemField("/", "_has_produce_multi", "true");
219
222
224
225 if (!HasRestrictMethod()) {
226 // this was problem with original ROOT sniffer, it does not construct classes
227 // and class required in exe.bin
228 gROOT->GetClass("TGo4ParameterStatus", kTRUE, kTRUE);
229 gROOT->GetClass("TGo4EventElement", kTRUE, kTRUE);
230 gROOT->GetClass("TGo4CompositeEvent", kTRUE, kTRUE);
231 gROOT->GetClass("TGo4AnalysisStatus", kTRUE, kTRUE);
232 gROOT->GetClass("TGo4AnalysisWebStatus", kTRUE, kTRUE);
233 }
234}
235
243
244void TGo4Sniffer::ScanRoot(TRootSnifferScanRec& rec)
245{
246 rec.SetField("_toptitle", "Go4 http server");
247
248 TRootSnifferFull::ScanRoot(rec);
249
251
252 if (!om) return;
253
254 //TGo4LockGuard mainlock; // JAM now done in top level invocation ProcessEvents
255
256 TFolder *main = om->GetObjectFolder();
257
258 TFolder *hist_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetHISTFOLDER()));
259 TFolder *par_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetPARAFOLDER()));
260 TFolder *cond_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetCONDFOLDER()));
261 TFolder *pic_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetPICTFOLDER()));
262 TFolder *tree_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetTREEFOLDER()));
263 TFolder *canv_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetCANVFOLDER()));
264 TFolder *anal_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetANALYSISFOLDER()));
265 TFolder *even_fold = dynamic_cast<TFolder *>(anal_fold->FindObject(TGo4AnalysisObjectManager::GetEVENTFOLDER()));
266 TFolder *user_fold = dynamic_cast<TFolder *>(main->FindObject(TGo4AnalysisObjectManager::GetUSRFOLDER()));
267 TFolder *files_fold = dynamic_cast<TFolder *>(main->FindObject("Files"));
268
269 ScanCollection(rec, hist_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetHISTFOLDER());
270 ScanCollection(rec, par_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetPARAFOLDER());
271 ScanCollection(rec, cond_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetCONDFOLDER());
272 ScanCollection(rec, pic_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetPICTFOLDER());
273 ScanCollection(rec, tree_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetTREEFOLDER());
274 ScanCollection(rec, canv_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetCANVFOLDER());
275 ScanCollection(rec, even_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetEVENTFOLDER());
276 ScanCollection(rec, user_fold->GetListOfFolders(), TGo4AnalysisObjectManager::GetUSRFOLDER());
277 if (files_fold)
278 ScanCollection(rec, files_fold->GetListOfFolders(), "Files");
279}
280
281void TGo4Sniffer::ScanObjectProperties(TRootSnifferScanRec &rec, TObject *obj)
282{
283 TRootSnifferFull::ScanObjectProperties(rec, obj);
284 if (!obj)
285 return;
286
287 if (obj->TestBit(TGo4Status::kGo4CanDelete)) {
288 rec.SetField("_can_delete", "true");
289 }
290
291 if (obj->TestBit(TGo4Status::kGo4NoReset)) {
292 rec.SetField("_no_reset", "true");
293 }
294
295 if (obj->InheritsFrom(TGo4Parameter::Class())) {
296 if (!HasAutoLoadMethod())
297 rec.SetField("_autoload", fAutoLoadArg);
298 rec.SetField("_drawfunc", "GO4.drawParameter");
299 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,33,0)
300 rec.SetField("_drawscript", "modules:go4sys/html5/pareditor.mjs");
301 #else
302 rec.SetField("_drawscript", "go4sys/html/pareditor.js");
303 #endif
304 rec.SetField("_drawopt", "editor");
305 rec.SetField("_icon", "go4sys/icons/parameter.png");
306 return;
307 }
308
309 if (obj->InheritsFrom(TGo4Condition::Class())) {
310 if (!HasAutoLoadMethod())
311 rec.SetField("_autoload", fAutoLoadArg);
312 rec.SetField("_icon", "go4sys/icons/condedit.png");
313 return;
314 }
315
316 if (obj->InheritsFrom(TGo4EventElement::Class())) {
317 rec.SetField("_more", "true");
318 rec.SetField("_go4event", "true");
319 rec.SetField("_icon", "go4sys/icons/eventobj.png");
320 return;
321 }
322
323 if (obj->InheritsFrom(TGo4MsgList::Class())) {
324 if (!HasAutoLoadMethod())
325 rec.SetField("_autoload", fAutoLoadArg);
326 rec.SetField("_make_request", "GO4.MakeMsgListRequest");
327 rec.SetField("_after_request", "GO4.AfterMsgListRequest");
328 rec.SetField("_icon", "img_text");
329 return;
330 }
331
332}
333
334void *TGo4Sniffer::FindInHierarchy(const char *path, TClass **cl, TDataMember **member, Int_t *chld)
335{
336 if (path && (strcmp(path,"Status/Analysis") == 0)) {
338 if (cl) *cl = fAnalysisStatus->IsA();
339 return fAnalysisStatus;
340 }
341
342 return TRootSnifferFull::FindInHierarchy(path, cl, member, chld);
343}
344
345
347{
348 auto an = TGo4Analysis::Instance();
349 if (an) {
350 an->StartAnalysis();
351 StatusMessage(0, kTRUE, "Resume analysis loop");
352 }
353
354 return kTRUE;
355}
356
358{
359 auto an = TGo4Analysis::Instance();
360 if (an) {
361 an->StopAnalysis();
362 StatusMessage(0, kTRUE, "Suspend analysis loop");
363 }
364
365 return kTRUE;
366}
367
368Bool_t TGo4Sniffer::CmdOpenFile(const char *fname)
369{
370 Info("CmdOpenFile", "Open ROOT file %s", fname);
371
373
374 if (om) {
375 TFolder *main = om->GetObjectFolder();
376
377 TFolder *files_fold = dynamic_cast<TFolder *>(main->FindObject("Files"));
378 if (!files_fold) {
379 files_fold = main->AddFolder("Files","ROOT files");
380 files_fold->SetOwner(kTRUE);
381 }
382
383 auto f = dynamic_cast<TFile *> (files_fold->FindObject(fname));
384 if (f) { files_fold->Remove(f); delete f; }
385
386 f = TFile::Open(fname);
387 if (!f) return kFALSE;
388
389 files_fold->Add(f);
390 }
391
392 return kTRUE;
393}
394
396{
397 Info("CmdCloseFiles", "Close all opened files");
399 if (om) {
400 TFolder *main = om->GetObjectFolder();
401 TFolder *files_fold = dynamic_cast<TFolder *>(main->FindObject("Files"));
402 if (files_fold) {
403 files_fold->Clear();
404 main->Remove(files_fold);
405 delete files_fold;
406 }
407 }
408 return kTRUE;
409}
410
411
413{
414 auto an = TGo4Analysis::Instance();
415 if (an) {
416 an->ClearObjects("Histograms");
417 an->ClearObjects("Conditions");
418 an->SendMessageToGUI(1, kTRUE, "Clear Histograms and Conditions folder");
419 }
420 return kTRUE;
421}
422
424{
425 auto an = TGo4Analysis::Instance();
426 TGo4AnalysisClient *cli = an ? an->GetAnalysisClient() : nullptr;
427
428 if (cli) {
429 cli->Stop();
430 an->CloseAnalysis();
431 if (an->InitEventClasses())
432 cli->Start();
433 } else if (an) {
434 an->StopAnalysis();
435 an->PostLoop();
436 an->CloseAnalysis();
437 if (an->InitEventClasses()) {
438 an->PreLoop();
439 an->StartAnalysis();
440 }
441 }
442
443 StatusMessage(0, kTRUE, "Restart analysis loop");
444
445 return kTRUE;
446}
447
449{
450 auto an = TGo4Analysis::Instance();
451 TGo4AnalysisClient *cli = an ? an->GetAnalysisClient() : nullptr;
452
453 if (cli) {
454 cli->Stop();
455 an->CloseAnalysis();
456 } else if (an) {
457 an->StopAnalysis();
458 an->PostLoop();
459 an->CloseAnalysis();
460 }
461
462 StatusMessage(0, kTRUE, "Close analysis");
463
464 return kTRUE;
465}
466
467
469{
470 auto an = TGo4Analysis::Instance();
471 TGo4AnalysisClient *cli = an ? an->GetAnalysisClient() : nullptr;
472
473 if (cli) {
474 cli->Stop();
475 an->CloseAnalysis();
476 cli->Quit();
477 } else if (an) {
478 an->StopWorking();
479 }
480
481 StatusMessage(0, kTRUE, "Exit analysis process");
482
483 return kTRUE;
484}
485
486
487Bool_t TGo4Sniffer::CmdClearObject(const char *objname)
488{
489 auto ana = TGo4Analysis::Instance();
490
491 if(!ana) {
492 SendStatusMessage(3, kTRUE,"CmdClearObject - analysis missing");
493 return kFALSE;
494 }
495
496 if (!objname || (*objname == 0)) {
497 ana->ClearObjects("Histograms");
498 ana->ClearObjects("Conditions");
499 SendStatusMessage(1, kTRUE, "Histograms and conditions were cleared");
500 return kTRUE;
501 }
502
503 Bool_t ok = ana->ClearObjects(objname);
504
505 if(ok) {
506 SendStatusMessage(1, kTRUE, TString::Format("Object %s was cleared.", objname));
507 } else {
508 SendStatusMessage(2, kTRUE, TString::Format("Could not clear object %s", objname));
509 } // if(ob)
510
511 return ok;
512}
513
514Bool_t TGo4Sniffer::CmdDeleteObject(const char *objname)
515{
516 auto ana = TGo4Analysis::Instance();
517
518 if(!ana) {
519 SendStatusMessage(3, kTRUE,"CmdDeleteObject - missing analysis ");
520 return kFALSE;
521 }
522
523 if (!objname || (*objname == 0)) {
524 SendStatusMessage(1, kTRUE, "Object name in CmdDeleteObject not specified");
525 return kFALSE;
526 }
527
528 Bool_t ok = ana->DeleteObjects(objname);
529
530 if(ok) {
531 SendStatusMessage(1, kTRUE, TString::Format("Object %s was deleted", objname));
532 } else {
533 SendStatusMessage(2, kTRUE, TString::Format("Could not delete object %s", objname));
534 } // if(ob)
535
536 return ok;
537}
538
539
540Bool_t TGo4Sniffer::CmdExecute(const char *exeline)
541{
542 if (!exeline || (*exeline == 0)) return kFALSE;
543 auto ana = TGo4Analysis::Instance();
544 if (!ana) {
545 SendStatusMessage(3, kTRUE, "CmdExecute - missing analysis ");
546 return kFALSE;
547 }
548 Int_t errcode = 0;
549 ana->ExecuteLine(exeline, &errcode);
550 fflush(stdout);
551 return errcode != 0 ? kFALSE : kTRUE;
552}
553
554
555
556void TGo4Sniffer::SetTitle(const char *title)
557{
558 // Method called by logger with every string, going to output
559
560 if (!title || (strlen(title) == 0)) return;
561
562 const char *prev = GetItemField("/Status/DebugOutput", "value");
563 TString res;
564 if (prev && (strcmp(prev,"---") != 0)) res = prev;
565 if (res.Length() > 50000) res.Remove(0, res.Length() - 25000);
566 res.Append("\n"); res.Append(title);
567
568 SetItemField("/Status/DebugOutput","value", res);
569
570 const char *cur = title;
571 while (*cur != 0) {
572 const char *next = strchr(cur, '\n');
573 if (!next) {
574 fDebugOutput.AddMsg(cur);
575 break;
576 }
577 fDebugOutput.AddMsg(TString(cur, next-cur));
578 cur = next+1;
579 }
580}
581
583{
584 fRatemeter->UpdateFrom(r);
585
586 Int_t n = fEventRate->GetN();
587 if (n == 100) {
588 fEventRate->RemovePoint(0);
589 n--;
590 }
591
592 TTimeStamp tm, tm0;
593 tm0.Set(1995,1,1,0,0,0,0,kTRUE,0);
594 fEventRate->SetPoint(n, tm.AsDouble() - tm0.AsDouble(), r->GetRate());
595 fEventRate->GetXaxis()->SetTimeDisplay(1);
596 fEventRate->GetXaxis()->SetTimeFormat("%H:%M:%S");
597 fEventRate->GetYaxis()->SetTitle("Events/s");
598 fEventRate->GetHistogram()->SetDirectory(nullptr);
599}
600
601void TGo4Sniffer::StatusMessage(int level, Bool_t, const TString &msg)
602{
603 const char *prev = GetItemField("/Status/Message", "value");
604 TString res;
605 if (prev && (strcmp(prev,"---") != 0)) res = prev;
606 res.Append("\n"); res.Append(msg);
607
608 SetItemField("/Status/Message","value",res);
609
610 TDatime now;
611
612 fStatusMessages.AddMsg(TString::UItoa(now.Convert(kFALSE), 10) + ":" + TString::Itoa(level,10) + ":" + msg);
613
614 // add status message to the log
615 // if (printout) SetTitle(msg.Data());
616}
617
619{
620 // Method called from the thread, where go4 analysis executed
621
622 if (gHttpServer) gHttpServer->ProcessRequests();
623}
624
625void TGo4Sniffer::SendStatusMessage(Int_t level, Bool_t printout, const TString &text)
626{
627 if (printout)
628 TGo4Log::Message(level, "%s", text.Data());
629
630 // to be done
631}
632
634{
635 auto ana = TGo4Analysis::Instance();
636 if (!ana) {
637 SendStatusMessage(3, kFALSE, "Analysis not exists to set object");
638 delete obj;
639 return kFALSE;
640 }
641
642 Bool_t res = ana->AddHistogram(dynamic_cast<TH1 *>(obj));
643 if (!res) res = ana->AddAnalysisCondition(dynamic_cast<TGo4Condition *>(obj));
644 if (!res) res = ana->AddDynamicEntry(dynamic_cast<TGo4DynamicEntry *>(obj));
645
646 if(res) {
647 SendStatusMessage(1, kFALSE, TString::Format("Added new object %s to Go4 folders.", obj->GetName()));
648 } else {
649 SendStatusMessage(3, kFALSE, TString::Format("ERROR on adding new object %s ", obj->GetName()));
650 delete obj;
651 }
652
653 return kTRUE;
654}
655
656Bool_t TGo4Sniffer::RemoteTreeDraw(const char *histoname,
657 const char *treename,
658 const char *varexpr,
659 const char *cutexpr)
660{
661 auto ana = TGo4Analysis::Instance();
662 if (!ana) {
663 SendStatusMessage(3, kTRUE, "No analysis in RemoteTreeDraw");
664 return kFALSE;
665 }
666
667 if (!histoname || (*histoname == 0)) histoname = "hTreeDraw";
668 Bool_t res = ana->AddTreeHistogram(histoname, treename, varexpr, cutexpr);
669 if(res)
670 SendStatusMessage(1,kTRUE, TString::Format("Added Dynamic histogram %s for tree %s.", histoname, treename));
671 else
672 SendStatusMessage(2,kTRUE, TString::Format("Could not add Dynamic histogram %s for tree %s.", histoname, treename));
673
674 return res;
675}
676
677TObject *TGo4Sniffer::CreateItemStatus(const char *itemname)
678{
679 TObject *obj = FindTObjectInHierarchy(itemname);
680
681 TH1 *h1 = dynamic_cast<TH1 *> (obj);
682
683 // printf("CreateItemStatus %s h1 = %p\n", itemname, h1);
684
685 if (h1) return new TGo4HistogramStatus(h1);
686
687 return nullptr;
688}
689
691{
692 return IsA()->GetMethodAllAny("Restrict") != nullptr;
693}
694
696{
697 return IsA()->GetMethodAllAny("ProduceMulti") != nullptr;
698}
699
700void TGo4Sniffer::RestrictGo4(const char *path, const char *options)
701{
702 // wrapper for TRootSnifferFull::Restrict, called only when method exists
703
704 if (!HasRestrictMethod()) return;
705
706 TString call_args = TString::Format("\"%s\",\"%s\"", path, options);
707
708 TMethodCall call(IsA(), "Restrict", call_args.Data());
709
710 call.Execute(this);
711}
712
714{
715 return IsA()->GetMethodAllAny("SetAutoLoad") != nullptr;
716}
717
718Bool_t TGo4Sniffer::SetAutoLoadGo4(const char *script)
719{
720 if (!HasAutoLoadMethod()) return kFALSE;
721
722 TString call_args = TString::Format("\"%s\"", script);
723
724 TMethodCall call(IsA(), "SetAutoLoad", call_args.Data());
725
726 call.Execute(this);
727
728 return kTRUE;
729}
int main(int argc, char *argv[])
void Stop() override
General stop method of slave application to be called from remote command; should be re-implemented b...
void Start() override
General start method of slave application to be called from remote command; should be re-implemented ...
void Quit() override
Quit this instance and the owned task; method to be called from command object, may be overridden in ...
This object is responsible for the organization of analysis objects.
TFolder * GetObjectFolder()
Access to top folder of all objects.
void UpdateStatus(TGo4AnalysisStatus *state)
Create a copy of the analysis internal state.
static TGo4Analysis * Instance()
return analysis instance
TGo4AnalysisObjectManager * ObjectManager() const
Returns pointer on analysis object manager.
TGo4AnalysisWebStatus * CreateWebStatus()
Create a copy of the analysis internal state.
void SetSniffer(TGo4AnalysisSniffer *sniff)
Set pointer on sniffer object.
Go4 condition class.
ABC for all entries that can be kept in a dynamic list.
Runtime status of a histogram object.
static const char * Message(Int_t prio, const char *text,...) GO4_PRINTF2_ARGS
Display a message.
Definition TGo4Log.cxx:214
static const char * GO4SYS()
Return GO4SYS environment variable or Go4 top directory during compile (if GO4SYS) not set.
Definition TGo4Log.cxx:164
static void SetSniffer(TNamed *sniff)
Definition TGo4Log.cxx:159
Class containing event counter and ratemeter services.
Double_t GetRate() const
void ScanRoot(TRootSnifferScanRec &rec) override
static THttpServer * GetHttpServer()
Bool_t CmdStop()
Bool_t AddAnalysisObject(TObject *obj)
Bool_t CmdExit()
TObject * CreateItemStatus(const char *itemname)
TGraph * fEventRate
Definition TGo4Sniffer.h:33
void SetTitle(const char *title="") override
Method called by logger with every string, going to output.
static Bool_t CreateEngine(const char *name)
void StatusMessage(int level, Bool_t printout, const TString &) override
Method from analysis sniffer.
Bool_t HasRestrictMethod()
Indicate that Restrict method implemented, also commands with arguments are exists.
void RatemeterUpdate(TGo4Ratemeter *) override
Method from analysis sniffer.
Bool_t CmdClearObject(const char *objname)
Bool_t CmdDeleteObject(const char *objname)
TGo4MsgList fDebugOutput
Definition TGo4Sniffer.h:37
Bool_t SetAutoLoadGo4(const char *script)
Wrapper for new method in TRootSniffer.
void ScanObjectProperties(TRootSnifferScanRec &rec, TObject *obj) override
Bool_t CmdCloseFiles()
TString fAutoLoadArg
Definition TGo4Sniffer.h:44
static THttpServer * gHttpServer
Definition TGo4Sniffer.h:66
Bool_t CmdOpenFile(const char *fname)
Bool_t RemoteTreeDraw(const char *histoname, const char *treename, const char *varexpr, const char *cutexpr)
TGo4Ratemeter * fRatemeter
Definition TGo4Sniffer.h:35
void * FindInHierarchy(const char *path, TClass **cl=nullptr, TDataMember **member=nullptr, Int_t *chld=nullptr) override
Bool_t CmdRestart()
void ProcessSnifferEvents() override
Method called in go4 analysis thread, used to executed server commands.
Bool_t CmdStart()
TGo4Sniffer(const char *name)
TGo4AnalysisWebStatus * fAnalysisStatus
Definition TGo4Sniffer.h:31
Bool_t HasProduceMultiMethod()
Indicate that sniffer has MultiProcess method implemented, can be used from GUI.
TGo4MsgList fStatusMessages
Definition TGo4Sniffer.h:39
Bool_t HasAutoLoadMethod()
Indicate if SetAutoLoad method exists.
virtual ~TGo4Sniffer()
Bool_t CmdClear()
Bool_t fbPythonBound
if true, python binding of go4 has already been done.
Definition TGo4Sniffer.h:42
Bool_t CmdClose()
Bool_t CmdExecute(const char *exeline)
void RestrictGo4(const char *path, const char *options)
Wrapper for new method in TRootSniffer.
virtual void SendStatusMessage(Int_t level, Bool_t printout, const TString &text)
Send message to gui - need to be implemented.