Cannot write histograms in the file because of opening another root file

Hello,

While I’m doing my analysis with a macro, I’m opening another rootfile to copy a tree. Then I’m returning to the previous, main file and filling some histograms and in the end I’m writing them all. The problem is that when I’m opening the resulting root file, all the histograms don’t have any entries. The debugging process showed that the histograms are filled correctly, there’s a problem with writing them. The part with accessing another file was copied from thread somewhere here:

TFile *myfile=new TFile(line.c_str(),"open");
gDirectory->pwd();
myfile->ls();
t = (TTree*)myfile->Get("t");
f.cd();
gDirectory->pwd();
t->CloneTree()->Write();

and it’s working perfectly, but there’s a problem exactly in this part, without it all the histograms are written correctly. The funny thing is also that the whole code began to work for some reason for some time without any major changes and now it’s not working again.

What can be a reason for such problem?

Thank you for help in advance,
Yuliia

Hi Yuliia,
welcome to the ROOT forum! Sorry for the late reply, with summer vacations things move a bit slower than usual.

In your snippet, I don’t see the code that writes the histograms. I think that depending how you do things they might be written either to their corresponding directory (which you can check for example with histo->GetDirectory()->GetName()) or in the current gDirectory (which you can check with gDirectory->GetName()).

In the snippet you report, f.cd(); changes the current gDirectory, so it could be that histograms are written in a different file than you expect.

Hope this helps,
Enrico

1 Like

Hi Enrico,

Thank you for your reply!

All the stuff with histograms looks like this:

  1. I create the histogram with
TH2D hBPD1Position("BPD1Position", "Beam profile at BPD1", 200, -3, 3, 200, -3, 3);
  1. I fill the histogram at some point after opening that another file and it fills correctly:
hBPD1Position.Fill(bpd1X, bpd1Y);
  1. And then in the end of the whole code I write the output file as previously worked nicely
f.Write();

I’m very confused that at some point everything worked just fine for some time but then stopped working again.

Cheers,
Yuliia

Well you must have changed something in the meanwhile! :smiley:

I realize this stuff can be confusing in the beginning. f.Write() writes all objects that belong to that file. You can check what objects belong to a file with e.g. f.ls().
When you construct the histogram hBPD1Position, it is assigned to the current active file, i.e. gDirectory (assuming you don’t change it manually with histo->SetDirectory(...)). What is gDirectory->GetName() at the point where you construct hBPD1Position?

I changed host country :smile:

f.ls() showed all my histograms which I created. I’m creating them in the very beginning, before opening another file, so gDirectory->GetName() gives me name of my output file.

Also I checked where they belong to while filling and it’s also my output file.

Uhm…I can’t tell what’s wrong. Maybe @Axel has an idea.

Otherwise, we’ll need a minimal reproducer of your issue that we can run and debug.

It could be an issue with

  • the file your write isn’t where you think it is: church the change time of the file you are looking at
  • the file isn’t opened for update/ recreate, or is write protected; you should have seen an error message
  • some histogram on stack / file ownership trickery, try to create your histogram on the heap (new TH2D(...)).

If it’s none of those, please provide a reproduce!

Cheers, Axel

1 Like

Hi Axel,

Thank you so much for your reply! I’ll try to check the stuff and write a reproduce also this weekend. Although on a first sight, it’s not the first and the second issue because I’ve already checked these.

Have a nice weekend :slight_smile:

Hi Yuliia,
to be clear:
You find the histograms on the file but they are empty, correct?
This means you write them before filling or you clear them again
before writing.

What gives hist->Print() for the histos on the file?

What root version are you using, did you change from 5 -> 6
I ask because with Root5 ( CINT) all was on heap
You say you changed host country?
Otto

2 Likes

Hi everyone,

Recently I tried Print() method right after writing my file in the code and it gives me non-zero number of entries as it should be, but when I opened my file in ROOT both on server (version 5.34/38) or on my own computer (version 6.16/00) the same method gives 0. But if I comment the line with opening another file everything is ok.

Also I tried to create a histogram on the heap, result was the same.

I’m on holidays in Ukraine now, but previously I was in Poland when everything began.

Cheers,
Yuliia

I tried to write a reproduce (I’ve never done this before), but I can’t even compile it although the structure of code is like in my original code. I will really appreciate any help with it. It can be accessed via

/afs/cern.ch/user/y/yubalkov/Analysis/test.cc

I guess the second file, which is opened during the operating, can be whatever you like, but I specified the one I’ve tried to work with.

Hi,

/afs/cern.ch/user/y/yubalkov/Analysis/test.cc

is not accessible to others, can you move the relevant files
e.g. somewhere below

 /afs/cern.ch/user/y/yubalkov/public/

and let us know
Cheers
Otto

Hi Otto,

I moved everything to

/afs/cern.ch/user/y/yubalkov/public/

test.cc is a reproduce, DataAnalysis.cc is an original code and .root file is file I’m trying to open during analysis.

Cheers,
Yuliia

Hi Yullia,
I tried your test.cc and after some mods it works as
expected with root_6.18.00 (I dont expect a diff to 6.16.00),
histos are filled on the output file.
mods: make it a complete macro:

void test()
{
...
}

Changed filling, TH2 has not FillRandom(“gaus”).

I cannot run your DataAnalysis.cc , includes missing,
it is a main(), so Makefile needed and too lengthy
One thing I see:
in line 255

 TTree *t=new TTree("t","tree");

in line 308 you overwrite the pointer:

t = (TTree*)myfile->Get("t");

Dont know if this relevant

Cheers
Otto
test.cc (848 Bytes)

1 Like

Hi Otto,

Thank you for your help!

To run DataAnalysis.cc you need to set environment of SHINE experiment, and I don’t know if external users can do it. I just wanted to show that structure of code is exactly the same. The feature with tree was token from ROOT forum, so I assumed that it’ll work.

I tried to run corrected file and here what I’m talking about:

root [0] .L test.cc
root [1] test()
Warning in <TClass::TClass>: no dictionary for class ROOT::TIOFeatures is available
Error in <TClass::New>: cannot create object of class TH2
Error in <TClass::New>: cannot create object of class TH1
run-039390x000_.root:/
TFile**         run-039390x000_.root
 TFile*         run-039390x000_.root
  KEY: TTree    t;1     tree
  KEY: TH1F     hADCS1sum;1     S1 ADC amplitude
  KEY: TH1F     hADCAdet;1      A_det ADC amplitude
  KEY: TH1F     hTDCS113;1      S11+S13 TDC amplitude
  KEY: TH1F     hTDCS124;1      S12+S14 TDC amplitude
  KEY: TH1F     hTDCS1sum;1     S1 TDC amplitude (sum)
  KEY: TH1F     hTDCS1diff;1    S1 TDC amplitude (diff)
  KEY: TH1F     hTDCAdet;1      A_det TDC amplitude
  KEY: TH2F     hADCcorr;1      S1 ADC amplitude vs A_det ADC amplitude
  KEY: TH2F     hTDCcorr;1      S1 TDC amplitude vs A_det TDC amplitude
  KEY: TH2F     hADCS1TDCall;1  S1 ADC amplitude vs overall TDC amplitude
test.root:/
TH1.Print Name  = histo1, Entries= 5000, Total sum= 4978
TH1.Print Name  = histo2, Entries= 5000, Total sum= 3782
TFile**         test.root
 TFile*         test.root
  OBJ: TH2D     histo1   : 0 at: 0x141b8a0
  OBJ: TH2D     histo2   : 0 at: 0x141bf20
TH1.Print Name  = histo1, Entries= 5000, Total sum= 4978
TH1.Print Name  = histo2, Entries= 5000, Total sum= 3782
root [2] TFile *_file0 = TFile::Open("test.root")
root [3] histo1->Print()
TH1.Print Name  = histo1, Entries= 0, Total sum= 0 <-----!!!

Do I understand correct that you don’t get such a result?

Cheers,
Yuliia

Hi Yullia,
you are obviously running root version 5 but your run-039390x000_.root
was made with: fVersion 61600 File format version.
Therefore you get:

Warning in <TClass::TClass>: no dictionary for class ROOT::TIOFeatures is available

and

  OBJ: TH2D     histo1   : 0 at: 0x141b8a0
  OBJ: TH2D     histo2   : 0 at: 0x141bf20

i.e. both histos are on heap (CINT) whereas with 6.16.00 one is on stack
the other on heap as it ought to be with CLING:

  OBJ: TH2D     histo1   : 0 at: 0x7fff1df0b508
  OBJ: TH2D     histo2   : 0 at: 0x1cdf170

If I run test.cc with 5.34.36 I get the same b a d result as you.
With 6.16.00 I dont get the Warnings, Errors and the histos
are as expected on the output file.

For the danger of TIOFeatures also consult this
https://root.cern.ch/doc/master/classROOT_1_1TIOFeatures.html

Could you try “test.cc” with 6.16.00

Otto

Hi Otto,

It seems that it’s a problem: in internal SHINE environment only 5.34 version is available for compilation, and as you wrote before all .root files were created with 6.16 version. It’s a pity, but the only solution I see here is to create all these files with 5.34, because it’ll be a problem now to switch all the environment to 6.16. I guess it’s impossible to make these versions compatible by ROOT itself.

Thank you so much for your time and help! If you see another solution, please, write it here.

Cheers,
Yuliia

@axel @pcanal It seems that opening a file produced by ROOT 6.14/06 or 6.16/00 (files from ROOT 6.12/06 and earlier releases and also ROOT 6.18/00 seem fine) in ROOT 5 is sufficient to screw the old ROOT 5 so that it is unable to properly save its newly created histograms in its newly created file (e.g. in ROOT 5.34/36 or the current “v5-34-00-patches” branch).

Here’s a simple standalone trial.cxx (987 Bytes) macro which reproduces this problem (it needs the standard “hsimple.root” file from ROOT 6.14/06 or 6.16/00).

2 Likes

This needs @pcanal who is currently traveling.

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