How to plot TCanvas before program reaches end?

I have tried following :

#include <iostream>

#include "TH1F.h"
#include "TCanvas.h"
#include "TROOT.h"

int test(){
    gROOT->SetBatch(false);
    TCanvas* canvas = new TCanvas("canvas");
    canvas->cd();
    TH1F* h = new TH1F("name","title", 100, 0, 100);
    h->Fill(10.);
    h->Fill(20.);
    h->Fill(30.);
    h->Draw();
    std::cout<<"I will freeze now"<<std::endl;
    std::cin.get();

    return 0;
}

root test.cpp

and canvas with the histogram is drawn only after the input to cin.get() provided and after test() has returned 0.

I want to pause my program and print canvas while in it…
As you can see I attempted with cin.get() but it doesn’t work…

How one should do it?

cheers,
Bohdan

ROOT Version: 6.24

Hi @FoxWise ,
I guess you want something like this:

#include <iostream>
#include <thread>
#include <chrono>

#include "TSystem.h"
#include "TH1F.h"
#include "TCanvas.h"
#include "TROOT.h"

int test(){
    TCanvas* canvas = new TCanvas("canvas");
    canvas->cd();
    TH1F* h = new TH1F("name","title", 100, 0, 100);
    h->Fill(10.);
    h->Fill(20.);
    h->Fill(30.);
    h->Draw();
    canvas->Draw();

    while (true) {
      gSystem->ProcessEvents();
      std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

    return 0;
}

I guess the missing part is to listen for a keypress and exit the ProcessEvents loop if a key (or just Enter) is pressed. You probably need a separate thread for that that communicates with the main thread via a condition variable, or maybe you can use curses or similar for that purpose.

Cheers,
Enrico

1 Like

Oh wow… Didn’t expect “pause” to be so advance in 2021…

My other code parts are most likely not thread-safe. So I would like to stick to one thread if this is possible, of course…

But this is great answer already, thanks!

The problem is that you can’t really pause the program: you still want the program to process clicks and interactions with the plot, but you don’t want to proceed further with the program flow.

1 Like

I found here that something possible like:

#include <iostream>
#include <ncurses.h>


#include "TSystem.h"
#include "TH1F.h"
#include "TCanvas.h"
#include "TROOT.h"

int test(){
    TCanvas* canvas = new TCanvas("canvas");
    canvas->cd();
    TH1F* h = new TH1F("name","title", 100, 0, 100);
    h->Fill(10.);
    h->Fill(20.);
    h->Fill(30.);
    h->Draw();
    canvas->Draw();

    while ( true ) {
        if (getch() == 'q') break;
      gSystem->ProcessEvents();
      std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }

but ROOT output:

Processing test.cpp...
IncrementalExecutor::executeFunction: symbol 'stdscr' unresolved while linking [cling interface function]!
IncrementalExecutor::executeFunction: symbol 'wgetch' unresolved while linking [cling interface function]!

or is it possible to create another root session inside script, and plot temporary saved histo in the root file?

The ROOT interpreter doesn’t know that it has to link libcurses against the program. You can probably tell it to, but at this point it might be simpler to use a compiled program.

I’m not sure I understand the question, but if you save the histogram in a ROOT file then you can inspect it from another ROOT session.

Cheers,
Enrico

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.