Updating and popping the TCanvas for each loop

Hi all,

Currently, I am trying to making monitoring system.
We are taking data with a few hour length, and we want to check some histograms during data taking.

So, what I tried is fill the histogram ~O(1000) events and show it via the canvas like below.

TApplication* theApp = new TApplication("app", &argc, argv);
TCanvas* c = new TCanvas("", "");

while(1) {
  for (int i = 0; i < 1000; i++)
    aHist->Fill(value);
  
  c->cd();
  aHist->Draw("Hist");
  theApp->Run();
}

We want to use the compiled script, so we tried it with TApplication.

The plot for the first for-loop is well pop. But after that, it is stuck at theApp->Run();.

Is there any way to make it possible?

And also I tried this one with searching live updates for plot

TApplication* theApp = new TApplication("app", &argc, argv);
TCanvas* c = new TCanvas("", "");
TH1D* aHist = new TH1D(...);
aHist->Draw();

while(1) {
  for (int i = 0; i < 1000; i++)
    aHist->Fill(value);
  
  c->Update();
  c->Pad()->Draw();
}

It also does not help.

Okay… I make it works with

TApplication* theApp = new TApplication("app", &argc, argv);
theApp->SetReturnFromRun(true);
TCanvas* c = new TCanvas("", "");
TH1D* aHist = new TH1D(...);
aHist->Draw();

while(1) {
  for (int i = 0; i < 1000; i++)
    aHist->Fill(value);
  
  c->Update();
  c->Pad()->Draw();
  gSystem->ProcessEvents();
}

But after plot is pop, I cannot make any changes on the plot while the system is under loop. Like adjusting the axis range, rebin the plot and etc.
Is there any possible solution for it? I’d very appreciate any suggestion!

Hi Kyuyeong,

Welcome to the ROOT Community!

Yes: please have a look to the following snippet:

using namespace std::this_thread; // sleep_for, sleep_until
using namespace std::chrono; // nanoseconds, system_clock, seconds

TApplication *app = new TApplication("app", argc, argv);

TCanvas* c = new TCanvas("", "");

auto aHist = new TH1D("h","h",128, 0, 64);
aHist->Draw("Hist");

while(1) {
  for (int i = 0; i < 64; i++)
    aHist->Fill(i);

  c->Modified(); 
  c->Update(); 
  gSystem->ProcessEvents();
  
  sleep_for(milliseconds(300));
}

I hope this gets you started!

Cheers,
D

Hi Danilo,

Thank you for suggestion!
Unfortunately, I already make a system sleep ~5 seconds with gSystem->Sleep(5000); right after updating the canvas.
Also std::this_thread::sleep_for(std::chrono::milliseconds(300)) does not works.
Anyway, thank you very much!

Sure, that was one of the many possible examples. Glad to read you solved the issue!

D

Why it is not possible?
gSystem->ProcessEvents() returns fast and you can modify canvas or histograms as much as you want. Just not forget to invoke c->Modified(); c-Update(); after your modifications.

Like:

TH1D* aHist = new TH1D(...);
aHist->Draw();

for (int i = 0; i < 1000; i++)
  aHist->Fill(value);
  
c->Modified(); 
c->Update();
gSystem->ProcessEvents();
  

aHist->Rebin(2);
c->Modified(); 
c->Update();

while(true) {
  gSystem->Sleep(10);
  gSystem->ProcessEvents();
}