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