Multiple TApplication in different functions (and different files)

Dear ROOT experts,
I am working on a project that has mainly two functionalities, i.e.

  • fitting an histogram with customizable parameters;
  • calculating a differential cross section and plot it in a T(Multi)Graph.

The second functionality works by calling the first one multiple times.
In my idea of the program, the user can select one of these functionalities by passing a flag as command line argument. More about it is written in the README of the GitHub Repository and in the documentation page.

Now, the whole project is built with CMake and in order to display the canvas of the results I had to create a TApplication. In order to implement it, I took inspiration from here.

My problem relies on the fact that these two functionalities are implemented in two different functions in two different files, therefore I wrote two different TApplications for each graph to display (the fit and the differential cross section).

I managed to make the program display only the one I am interested in, i.e. the one regarding the functionality selected, with a simple if condition in the fitRoo() function inside the fitRoo.C file:

   if (mr == 0) // if mode is set to crossSection, do not open canvas (with the application)
   {
      TRootCanvas *rc2 = (TRootCanvas *)c2->GetCanvasImp();
      rc2->Connect("CloseWindow()", "TApplication", gApplication, "Terminate()");
      theApp2->Run(true);
   }

The idea behind these lines of code is that if the mode (i.e. the functionality) is set to 0 (i.e. Differential Cross Section), the application should not run, because a second one is created in the PlotDiffCrossSection() function inside the diffCrossSection.C file.

In this way, the program does effectively what expected, but the following error is printed on terminal

Error in <TApplication::TApplication>: only one instance of TApplication allowed

and a new empty window is launched every time the fit function is called, resulting pretty annoying.

I think this is due to the fact that in the fitRoo() function an instance of TApplication is created with the following line:

TApplication *theApp2 = new TApplication("theApp2", 0, 0);

I tried deleting the object at the end of the function with a simple delete theApp2, but I get a segmentation violation. I also tried defining the App as an object instead that a pointer, but I get a similar result.
Lastly, I tried implementing a unique pointer, but again, I get a segmentation fault.

Ideally, I would have only one TApplication inside the main that display one or the graph depending on the selected functionality, but I would not know how to implement that. It would also be ok if the TApplication would not launch every time the fitRoo() function is called, but honestly, I am out of ideas (and I don’t really understand the segmentation violation…).

I would really glad if I could get any help about it. I know this is due by the incorrect usage of the TApplication, but I could not find anything on the forum or in the documentation of ROOT.

Sorry if I am not able to provide a stand-alone code, but the program is pretty complex.

Thanks very much in advance for your help.

Cheers,
Giulio


ROOT Version: 6.26/06


The “gApplication” is a singleton.

Yes, I am aware of that. And I figured that this is causing the error in TApplication.

I was wondering if there was a way to display the canvas created in these functions by creating only one application in main. Is this possible?

It should be no problem.

Ok, wonderful. Could I ask you help on that?

I tried to define the TApplication in main and run it after the call to the functions that create the canvas, but the canvas are not displayed. After the call to the function fitRoo() (where a canvas is created), it just launches an empty window.

After the call to the differential cross section function (where a second canvas is created), it crashes at the end with a segmentation violation

*** Break *** segmentation violation

[/usr/lib/system/libsystem_platform.dylib] _sigtramp (no debug info)

[/usr/lib/dyld] dyld::fastBindLazySymbol(ImageLoader**, unsigned long) (no debug info)

[/Users/zenith378/Documents/Uni/Computing/Y-DiMuonResonances/./build/main/YLaunch] main (no debug info)

[/usr/lib/system/libdyld.dylib] start (no debug info)

[<unknown binary>] (no debug info)

Create a minimal “reproducer” (so that some experts here can inspect it),

BTW. You’d better create a TApplication right at the beginning of your “main” (before you call any other ROOT function).