Making a TH2F plot taking data from a TTree and from a TH1F of a Root file

Hello, I made this TProfile plot

using these 2 root file

and this macro

caloprof.cpp (2.7 KB)

In the plot previously showed the x coordinate is the local x of the tracker (called tracker 37). I need the same plot in laboratory frame. To trasnform the local coordinate to laboratory one, I used this macro

fit_line.C (1.2 KB)
TBAlign.C (20.7 KB)
TBAlign.h (4.3 KB)

to run this macro, you can do:

 root> .L TBAlign.C
      root> TBAlign t
      root> t.Loop();

so I got the root files with laboratory system

then now I have to plot Calo_EnDep[0] (getting it from the TTree) in function of hx37 that is a TH1F saved in the new root files.

I wrote the new macro

caloprof.cpp (3.0 KB)

but I get the error

Error in TCanvas::Range: illegal world coordinates range: x1=0.000000, y1=-2.748352, x2=0.000000, y2=1.724871
Error in TCanvas::RangeAxis: illegal axis coordinates range: xmin=0.000000, ymin=-2.301030, xmax=0.000000, ymax=1.277549

and no plot

Thank you


Please read tips for efficient and successful posting and posting code

ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


I didn’t look at your code yet, but I think the error is explicit enough, the axis coordinates ranges are invalid (xmin = xmax = 0.0). You should check how this is calculated in your code…

Hello @bellenot I didn’t set the axis- range, Indeed, I wrote

TH2F *henepos = new TH2F("henepos", "", 100, 0., 0.,100, 0.,0.);

I think that there is an error getting the plot from the hystogram

Anyway, these are the two hx37 from the two files

I don’t understand what you’re trying to draw with:

TString varexp = TString::Format("Calo_EnDep[%d] : hx37 >> henepos", a);

This gives:

Error in <TTreeFormula::Compile>:  Bad numerical expression : "hx37"

And then the errors you mentioned in your original post

Hello @bellenote in my first macro
I drawn

TString varexp = TString::Format("Calo_EnDep[%d] : xh >> henepos", a);

because both Calo_EnDep[0] and xh were stored in the TTree of the original root file.

I.e. I made the energy in function of the x coordinate using the first 2 files that I uploaded and I got this plot

The x-values of this plot are in the local tracker system…Now I need the same plot, but in laboratory system.
Then I used the macro TAlign that I uploaded to transform the local coordinates to laboratory one. The x values, after the trasformation are saved in the new root files in the hysogram called hx37

So I’ve to make a Tprofile getting Calo_EnDep[0] (from the TTree ) vs data stored in the TH1F called hx37

So I’ve to make a new TProfile in wich on the y-axis I’ve the Calo_EnDep[0] (just like in the first plot) and on the x-axis I’ve data of the hystogram TH1F stored in the ROOT file

I don’t think you can do that. TTree::Draw() uses TTree internal variables (branches), I don’t think you can use an external histogram as second variable (unless I miss something…) @pcanal might confirm my thoughts

Hello @bellenot , then is there a way to fill an hystogram from the TTree and to make the plot getting data from the 2 hystograms?

Probably, but I suppose one should do it by iterating over the bins of each histogram… Maybe @couet or @moneta know how to do it right

I see, thank you @bellenot

Have you solved your problem ?

Hello @couet…no…I still didn’t

I see two mistakes.

  1. The histogram limits of your TH2F are wrong:
      TH2F *henepos = new TH2F("henepos", "", 100, 0., 0.,100, 0.,0.);

they are all equal to 0.

  1. in the line:
      t->Draw(varexp, selection,"goff");

varexp = Calo_EnDep[0] : hx37 >> henepos
selection = subdet==45

but there no variable named hx37 in your tree t

Hello @couet

I use setting 0 the hystogram limits when I want that ROOT sets automatically them …it always worked…isn’t correct doing that?

Yes, as I wrote, hx237 isn’t a TTree branche…it’s an hystogram saved in the same ROOT file…



antway you are right because I uploaded an old version of the file ROOT in wich there wasn’t that hystogram!

Here the right version

The problem is that should get a TH2F in which on the x-axis I’ve data from the hx37 hystogram and on the y-axis I’ve data from the henepos branche.

@bellenot said me that it’s impossible…so maybe, the way should be to fill a temporany hystogram from the TTree and then make the TH2F from using the two hystograms? but…how to fille the hystogram?

Yes but you do:

t->Draw("Calo_EnDep[0] : hx37", selection,"goff");

When you do something like:

t->Draw("y:x");

x and y must be tree variables, or expressions of tree variables, or cuts … but certainly not a separated histogram.

You can do:

root [0] TFile *fin = TFile::Open("si-500628-trasl.root");
root [1] TTree *t=0;
root [2] fin->GetObject("lemma",t);
root [3] t->Draw("hx37.cxx")

Where hx37.cxx is a .cxx code where you can do some computation on the tree variable. For instance

% cat hx37.cxx 
double hx37()
{
   return nhits; // for example
}

Hello @couet I did it, but getting errors

root [0] TFile *fin = TFile::Open("C:/si-500628-trasl.root");
root [1] TTree *t=0;
root [2] fin->GetObject("lemma",t);
root [3] t->Draw("C:/hx37.cxx");
Warning in <TTreePlayer::DrawScript>: TTreeProxy does not work in interpreted mode yet. The script will be compiled.
Info in <TTreePlayer::DrawScript>: Will process tree/chain using generatedSel.h+
Info in <TWinNTSystem::ACLiC>: creating shared library C:/root_v6.24.00/generatedSel_h.dll
In file included from input_line_3:2:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\string:11:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xstring:14:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xmemory:16:
In file included from C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\xutility:15:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\utility:138:9: error: expected member name or ';' after declaration specifiers
        !conjunction_v<_Is_implicitly_default_constructible<_Uty1>, _Is_implicitly_default_constructible<_Uty2>>)
        ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\utility:138:9: error: expected ')'
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\utility:137:23: note: to match this '('
    constexpr explicit(
                      ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\utility:219:24: error: expected member name or ';' after declaration specifiers
    constexpr explicit(!conjunction_v<is_convertible<const _Other1&, _Ty1>, is_convertible<const _Other2&, _Ty2>>)
    ~~~~~~~~~~~~~~~~~~ ^
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\utility:219:24: error: expected ')'
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.28.29910\include\utility:219:23: note: to match this '('
    constexpr explicit(!conjunction_v<is_convertible<const _Other1&, _Ty1>, is_convertible<const _Other2&, _Ty2>>)
                      ^
In file included from input_line_4:2:
In file included from C:/root_v6.24.00/include\Rtypes.h:23:
C:/root_v6.24.00/include/RtypesCore.h:91:17: error: redefinition of 'kTRUE'
const Bool_t    kTRUE        = true;
                ^
note: 'C:/root_v6.24.00/include/RtypesCore.h' included multiple times, additional include site here
fatal error: cannot open file 'input_line_3': no such file or directory
C:/root_v6.24.00/include\Rtypes.h:23:10: note: 'C:/root_v6.24.00/include/RtypesCore.h' included multiple times, additional include site here
#include "RtypesCore.h"
         ^
C:/root_v6.24.00/include/RtypesCore.h:91:17: note: unguarded header; consider using #ifdef guards or #pragma once
const Bool_t    kTRUE        = true;
                ^
Error in <ACLiC>: Executing 'C:\root_v6.24.00\bin\rootcling -v0 "--lib-list-prefix=C:\root_v6.24.00\generatedSel_h_ACLiC_map" -f "C:\root_v6.24.00\generatedSel_h_ACLiC_dict.cxx"  -rml generatedSel_h -rmf "C:\root_v6.24.00\generatedSel_h.rootmap" -DR__ACLIC_ROOTMAP -I%ROOTSYS%\include -D__ACLIC__  "C:/root_v6.24.00/generatedSel.h" "C:\root_v6.24.00\generatedSel_h_ACLiC_linkdef.h"' failed!

==========================================
=============== STACKTRACE ===============
==========================================


================ Thread 0 ================
  libCore!TWinNTSystem::GetProcInfo()
  libCore!TWinNTSystem::GetProcInfo()
  ucrtbase!seh_filter_exe()
  root!Init_thread_abort()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

================ Thread 1 ================
  ntdll!ZwWaitForWorkViaWorkerFactory()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

================ Thread 2 ================
  ntdll!ZwWaitForWorkViaWorkerFactory()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

================ Thread 3 ================
  ntdll!ZwWaitForWorkViaWorkerFactory()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

================ Thread 4 ================
  ntdll!NtDelayExecution()
  KERNELBASE!Sleep()
  libCore!TWinNTSystem::TimerThread()
  libCore!TWinNTSystem::ThreadStub()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

================ Thread 5 ================
  win32u!NtUserGetMessage()
  libCore!TWinNTSystem::GetProcInfo()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

================ Thread 6 ================
  ntdll!ZwWaitForWorkViaWorkerFactory()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

================ Thread 7 ================
  ntdll!ZwWaitForWorkViaWorkerFactory()
  KERNEL32!BaseThreadInitThunk()
  ntdll!RtlGetAppContainerNamedObjectPath()
  ntdll!RtlGetAppContainerNamedObjectPath()

==========================================
============= END STACKTRACE =============
==========================================

This syntax might be confusing with the “:” separating the variables to be ploted . I would remove “C:/”

Hello @couet…in this way it says

root [0] TFile *fin = TFile::Open("C:/si-500628-trasl.root");
root [1] TTree *t=0;
root [2] fin->GetObject("lemma",t);
root [3] t->Draw("hx37.cxx");
Error in <TTreeFormula::Compile>:  Bad numerical expression : "hx37.cxx"
Info in <TSelectorDraw::AbortProcess>: Variable compilation failed: {hx37.cxx,}
root [4]

Try to remove the previously generated files: del generatedSel* generatedSel*.*
Note that your current working directory must be the same as where the macro resides: cd C:\

Hello @Wile_E_Coyote maybe I didn’t understand what to do


root [0]  del generatedSel* generatedSel*.*
ROOT_prompt_0:1:4: error: expected ';' after expression
del generatedSel* generatedSel*.*
   ^
   ;
ROOT_prompt_0:1:5: error: use of undeclared identifier 'generatedSel'
del generatedSel* generatedSel*.*
    ^
ROOT_prompt_0:1:19: error: use of undeclared identifier 'generatedSel'
del generatedSel* generatedSel*.*
                  ^
ROOT_prompt_0:1:32: error: expected expression
del generatedSel* generatedSel*.*
                               ^
ROOT_prompt_0:2:1: error: expected expression