How to copy one histogram from the subdirectory to my canvas

Hey all,

I have one question I could not find the answer to.
I have a root file with 8 subdirectories. Each subdirectory contains a histogram named “h_iEta_hitADC”.

I want to copy this histogram from each subdirectory and put it on one canvas.

Could anyone please help me?

Here code:


using namespace std;

int canvases_working()

{
  TFile *f = new TFile("analyzed.root");
  //TFile *f2 = new TFile("spuriousSignalCapture2_dataTree.root");
  
  
  
  // Creating canvases
  
  
  hitADC=new TCanvas("canvas1","Run1 hitADC results 13/04/2016", 1024, 960);
  hitPos=new TCanvas("canvas2","Run2 hitPos results 13/04/2016", 1024, 960);
 
  hitADC->Divide(2,4);
  hitPos->Divide(2,4);

  
  //Creating histograms

  char histoname [20];
  char histotitle [20];
  char dirname [20];


  TH1D* hadc[8];
  TH1D* hpos[8];
  
  //loop over the subdirs

  for (Int_t i=1; i<9; i++)
  {
    sprintf(histoname,"histo no:%d",i);
    sprintf(histotitle,"eta no:%d",i);
    sprintf(dirname,"SectorEta%d",i);
   
     
    f->cd(dirname);
    cout<<"dir changed to: "<<dirname<<endl;
   

    hitADC->cd(i);
    hitPos->cd(i);

    //hit ADCs
    hadc[i] = f->Get("h_iEta_hitADC");
   
    cout<<"taken"<<endl;
    hadc[i]->Draw("");
    
    //hit Pos
   /* hpos[i]= new TH1D(histoname,histotitle,1000,0,1000);
    hpos[i]->Draw("");*/


  }
  
}

Thanks in advance!

a few fixes:

using namespace std;

int canvases_working()

{
  TFile *f = new TFile("analyzed.root");
  //TFile *f2 = new TFile("spuriousSignalCapture2_dataTree.root");
  
  
  
  // Creating canvases
  
  
  hitADC=new TCanvas("canvas1","Run1 hitADC results 13/04/2016", 1024, 960);
  hitPos=new TCanvas("canvas2","Run2 hitPos results 13/04/2016", 1024, 960);
 
  hitADC->Divide(2,4);
  hitPos->Divide(2,4);

  
  //Creating histograms

  char histoname [20];
  char histotitle [20];
  char dirname [20];


  TH1D* hadc[8];
  TH1D* hpos[8];
  
  //loop over the subdirs

  for (Int_t i=1; i<9; i++)
  {
    sprintf(histoname,"histo no:%d",i);
    sprintf(histotitle,"eta no:%d",i);
    sprintf(dirname,"SectorEta%d",i);
   
    f->cd(dirname);
    cout<<"dir changed to: "<<dirname<<endl;
   
    //hit ADCs
   hitADC->cd(i);
   hadc[i] = f->Get("h_iEta_hitADC");
   hadc[i]->Draw("");
    
    //hit Pos
   hitPos->cd(i);
   hpos[i]= f-Get(...); ???
   hpos[i]->Draw("");

  }
  
}


Hey,

thanks but for your reply but it still does not work.


using namespace std;

int canvases_working_fix()

{
  TFile *f = new TFile("analyzed.root");

  
  
  
  // Creating canvases
  
  
  hitADC=new TCanvas("canvas1","Run1 hitADC results 13/04/2016", 1024, 960);
  
 
  hitADC->Divide(2,4);
  
  //Creating histograms

  char histoname [20];
  char histotitle [20];
  char dirname [20];


  TH1D* hadc[8];
  
  
  //loop over the subdirs

  for (Int_t i=1; i<9; i++)
  {
    sprintf(histoname,"histo no:%d",i);
    sprintf(histotitle,"eta no:%d",i);
    sprintf(dirname,"SectorEta%d",i);
   
    f->cd(dirname);
    cout<<"dir changed to: "<<dirname<<endl;
   
    //hit ADCs
   hitADC->cd(i);
   hadc[i] = f->Get("h_iEta_hitADC");
   hadc[i]->Draw("");
    
   }
  }

I attach my .root file

The output is:

Error: illegal pointer to class object hadc[i] 0x0 1714 canvases_working_fix.cpp:45:

it seems retrieving the TH1F from the file gives problem. It could be that you file is corrupted ?

oot [0]    TFile *f = new TFile("analyzed.root");
root [1]    TH1F* hadc;
root [2]    f->cd("SectorEta1");
root [3]    hadc = (TH1F*)f->Get("h_iEta_hitADC");
root [4] hadc
(TH1F *) nullptr
root [5] 

Try: [code]#include “TFile.h”
#include “TDirectory.h”
#include “TCanvas.h”
#include “TH1.h”
#include “TString.h”

#include
#include

int canvases_working() {
TFile *f = new TFile(“analyzed.root”);
//TFile *f2 = new TFile(“spuriousSignalCapture2_dataTree.root”);

// Creating canvases

TCanvas *hitADC =
new TCanvas(“canvas1”, “Run1 hitADC results 13/04/2016”, 1024, 960);
hitADC->Divide(2, 4);

TCanvas *hitPos =
new TCanvas(“canvas2”, “Run2 hitPos results 13/04/2016”, 1024, 960);
hitPos->Divide(2, 4);

//Creating histograms

char histoname[20];
char histotitle[20];
char dirname[20];

TH1F* hadc[8];
TH1F* hpos[8];

//loop over the subdirs

for (Int_t i = 1; i < 9; i++)
{
sprintf(histoname, “histo no:%d”, i);
sprintf(histotitle, “eta no:%d”, i);
sprintf(dirname, “SectorEta%d”, i);

  std::cout << "dir changed to: " << dirname << std::endl;
  f->cd(dirname);
  
  //hit ADCs
  hitADC->cd(i);
  gDirectory->GetObject(TString::Format("h_iEta%d_hitADC", i),
                        hadc[(i - 1)]);
  if (hadc[(i - 1)]) hadc[(i - 1)]->Draw("");
  
  //hit Pos
  hitPos->cd(i);
  gDirectory->GetObject(TString::Format("h_iEta%d_hitPos", i),
                        hpos[(i - 1)]);
  if (hpos[(i - 1)]) hpos[(i - 1)]->Draw("");
}

hitADC->cd(0);
hitADC->Modified(); hitADC->Update();

hitPos->cd(0);
hitPos->Modified(); hitPos->Update();

return 0;
}[/code]

Thank both of you for your help!

It works fine now.

Btw. Is there any good tutorial I could get through to learn as much as possible?

Best regards.

I “simplified” the code: [code]#include “TFile.h”
#include “TDirectory.h”
#include “TCanvas.h”
#include “TH1.h”
#include “TString.h”

#include

int canvases_working() {
TFile *f = new TFile(“analyzed.root”);
//TFile *f2 = new TFile(“spuriousSignalCapture2_dataTree.root”);

// Creating canvases

TCanvas *hitADC =
new TCanvas(“canvas1”, “Run1 hitADC results 13/04/2016”, 1024, 960);
hitADC->Divide(2, 4);

TCanvas *hitPos =
new TCanvas(“canvas2”, “Run2 hitPos results 13/04/2016”, 1024, 960);
hitPos->Divide(2, 4);

//Creating histograms

TH1F* hadc[8];
TH1F* hpos[8];

//loop over the subdirs

for (Int_t i = 1; i < 9; i++)
{
std::cout << "subdir " << i << std::endl;
f->cd(TString::Format(“SectorEta%d”, i));

  //hit ADCs
  hitADC->cd(i);
  gDirectory->GetObject(TString::Format("h_iEta%d_hitADC", i),
                        hadc[(i - 1)]);
  if (hadc[(i - 1)]) hadc[(i - 1)]->Draw("");
  
  //hit Pos
  hitPos->cd(i);
  gDirectory->GetObject(TString::Format("h_iEta%d_hitPos", i),
                        hpos[(i - 1)]);
  if (hpos[(i - 1)]) hpos[(i - 1)]->Draw("");
}

hitADC->cd(0);
hitADC->Modified(); hitADC->Update();

hitPos->cd(0);
hitPos->Modified(); hitPos->Update();

return 0;
}[/code]

Hey,

In my case everything works fine. If you have any solution of your problems, it would be nice if you could share it.

Thanks for your help!

Hi Pepe,

Do you have a copy of ‘analyzed.root’ that you use to reproduce the problem?

Thanks,
Philippe.

.

Hi Pepe,

I think the problem is that the code is faulty in regard to index range: TH1F* hadc[8]; .... for (Int_t i = 1; i < 9; i++) ... set hadc[i]

thus hadc[8] is set by the ‘last’ iteration but this is out of bound for hadc which has only 8 elements (0 throught 7) and actually set the value of i. This is not seen in the std::cout output ‘thanks’ to optimization to use a register for the printing but use a memory address for the comparison.

Cheers,
Philippe.

Many thanks for finding this bug (I wonder why neither the interpreter nor the compiler complained about it and there was no “out of range” / “index out of bounds” error when running it -> I guess I’m getting too old that I did not spot it myself).

I corrected the source code in both my previous posts.

Philippe,
for future reference, could you, please, say how you “detected” this bug.

I tried:
valgrind --tool=memcheck --leak-check=full --suppressions=root-config --etcdir/valgrind-root.supp root-config --bindir/root.exe -l -q canvases_working.cxx++

For ROOT 5 (v5-34-00-patches “debug”), it unfortunately exited without problems and I got one lost block related to std::string / G__setup_func_struct and another six lost blocks related to libfontconfig / libXft / TGX11TTF.

For ROOT 6 (6.06/02 “RelWithDebInfo”), the “for” loop did not stop at 8, so I had to kill it with CTRL+C, and then I got hundreds of lost blocks, so it’s not really possible to analyse it (well, I checked several in beginning and in the end).

Hi Pepe,

[quote]For ROOT 6 I got hundreds of lost blocks, so it’s not really possible to analyse it (well, I checked several in beginning and in the end).[/quote]Turning on leak check would not help whatsoever here, as it just detect memory leak and not memory override. As a side note, I am in the tail end of a major set of updates to the suppression files that should illuminate most (hopefully) all the (per-se) false-positive report of possibly-lost.

Unfortunately, valgrind is not properly detecting memory overwrite when the memory is on the stack and indeed I ran valgrind and it did not report any issues.

I discovered the problem by code inspection of the code I ended-up when trying to reducing the problem to be minimal set. I end up with:[code]#include

class Histo { public: void Print() { } };

int canvases_working() {
Histo* hadc[9];

//loop over the subdirs
int counter = 0;
for (Int_t iii = 1; iii < 9; iii++)
{
std::cout << "subdir " << iii << std::endl;

  hadc[iii] = nullptr;
  if (hadc[iii]) hadc[iii]->Print();
 
  if (counter > 10) return 2;
  ++counter;
}

return 0;
}[/code].

I also had a look at the assembly code produced (via gdb) to see what’s was going on (hence my affirmation on register vs memory).

Cheers,
Philippe.

O.K. Thanks (so, you did the same as I usually do -> just in this case I forgot about it completely).

I also tried (“exp-sgcheck” is supposed to deal with “stack and global array overrun” problems):
valgrind --tool=exp-sgcheck --suppressions=root-config --etcdir/valgrind-root.supp root-config --bindir/root.exe -l -q canvases_working.cxx++

It seems to me that “exp-sgcheck” completely refuses to work with ROOT (I tried v5-34-00-patches “debug” and 6.06/02 “RelWithDebInfo”) -> it “immediately” exits without running the macro: [code][…]$ valgrind --tool=exp-sgcheck --suppressions=root-config --etcdir/valgrind-root.supp root-config --bindir/root.exe -l -q canvases_working.cxx++
==966== exp-sgcheck, a stack and global array overrun detector
==966== NOTE: This is an Experimental-Class Valgrind Tool
==966== Copyright © 2003-2015, and GNU GPL’d, by OpenWorks Ltd et al.
==966== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
==966== Command: /opt/ROOT/debug/v5-34-00-patches/bin/root.exe -l -q canvases_working.cxx++
==966==
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93
–966-- warning: evaluate_Dwarf3_Expr: unhandled DW_OP_ 0x93

exp-sgcheck: sg_main.c:559 (add_blocks_to_StackTree): Assertion ‘!already_present’ failed.

host stacktrace:
==966== at 0x38013B88: show_sched_status_wrk (m_libcassert.c:343)
==966== by 0x38013C94: report_and_quit (m_libcassert.c:415)
==966== by 0x38013E21: vgPlain_assert_fail (m_libcassert.c:481)
==966== by 0x3800A980: add_blocks_to_StackTree (sg_main.c:559)
==966== by 0x3800B8A9: shadowStack_new_frame.isra.22 (sg_main.c:1883)
==966== by 0x805092FE9: ???
==966== by 0x804072F2F: ???
==966== by 0x80206456F: ???
==966== by 0x61E757A: __nscd_get_mapping (nscd_helper.c:286)
==966== by 0x80206456F: ???
==966== by 0x1BFF: ???

sched status:
running_tid=1

Thread 1: status = VgTs_Runnable (lwpid 966)
==966== at 0x61E75B8: __nscd_get_mapping (nscd_helper.c:293)
==966== by 0x61E7ABB: __nscd_get_map_ref (nscd_helper.c:443)
==966== by 0x61E4207: nscd_getpw_r (nscd_getpw_r.c:95)
==966== by 0x61E4645: __nscd_getpwuid_r (nscd_getpw_r.c:63)
==966== by 0x617538F: getpwuid_r@@GLIBC_2.2.5 (getXXbyYY_r.c:196)
==966== by 0x6174B85: getpwuid (getXXbyYY.c:116)
==966== by 0x517A11C: TUnixSystem::UnixHomedirectory(char const*) (TUnixSystem.cxx:4032)
==966== by 0x5173FCF: TUnixSystem::HomeDirectory(char const*) (TUnixSystem.cxx:1509)
==966== by 0x50BDD8C: TROOT::InitSystem() (TROOT.cxx:1434)
==966== by 0x50B8960: TROOT::TROOT(char const*, char const*, void (**)()) (TROOT.cxx:298)
==966== by 0x50B7EEE: ROOT::GetROOT() (TROOT.cxx:206)
==966== by 0x50C0334: __static_initialization_and_destruction_0(int, int) (TROOT.cxx:215)
==966== by 0x50C037A: _GLOBAL__sub_I_TROOT.cxx (TROOT.cxx:2236)
==966== by 0x4010139: call_init.part.0 (dl-init.c:78)
==966== by 0x4010222: _dl_init (dl-init.c:36)
==966== by 0x4001309: ??? (in /lib/x86_64-linux-gnu/ld-2.19.so)
==966== by 0x3: ???
==966== by 0xFFEFFFE1A: ???
==966== by 0xFFEFFFE48: ???
==966== by 0xFFEFFFE4B: ???
==966== by 0xFFEFFFE4E: ???

Note: see also the FAQ in the source distribution.
It contains workarounds to several common problems.
In particular, if Valgrind aborted or crashed after
identifying problems in your program, there’s a good chance
that fixing those problems will prevent Valgrind aborting or
crashing, especially if it happened in m_mallocfree.c.

If that doesn’t help, please report this bug to: www.valgrind.org

In the bug report, send all the above text, the valgrind
version, and what OS and version you are using. Thanks.[/code] Actually, it looks like it is sufficient to #include “TObject.h” (or anything that inherits from TObject) and the “exp-sgcheck” is dead (you do not need to create any object, just #include the header file).
On the other hand, if I just #include “TString.h” then “exp-sgcheck” works fine (does not need any ROOT libraries). However, as soon as I add “TString s;” in the source code, then it dies (needs libCore and libCint ROOT 5 libraries or just libCore in ROOT 6).
So, the problem is somehow related to ROOT libraries.

I tried Valgrind-3.10.1 (the default version on Ubuntu 14.04.4 LTS), Valgrind 3.11.0 (the current release) and the current svn trunk, and in all cases I get the same problem.

Hi Pepe,

This ‘sounds’ like it is a problem in sgcheck. Can you reduce the problem even more (i.e. which part of TObject.h is triggering this)?

Thanks,
Philippe

In the end … it turns out that, in order to collapse “exp-sgcheck”, one does not even need to #include anything from ROOT … see a new thread dedicated to this problem: viewtopic.php?f=7&t=21520

P.S. See also another thread which may be helpful in finding use-after-free and {heap,stack,global}-buffer overflow bugs: viewtopic.php?f=7&t=21522