Updating/Overwriting Histograms

Hi all,

A part of my code involves writing the same named histograms on each other.

TH2D *myhist[56];
for(const int n=0; n<size; n++){
for (const int i=0; i<size2;i++ ) {
TFile *f = new TFile(fname);
read stuff iterated over ‘i’ and save to some buffer array;
TFile *fn = new TFile(“test.root”, “RECREATE”);
TString hiname = i; //because TH2D doesn’t take integer as title
myhist[i] = new TH2D(hiname,title,other parameters);

It keeps on writing histos on themselvess and ends up with the last value of myhist[i] being written to file. When I change parameter “RECREATE” to “UPDATE”, it writes all the data but then the output takes the following format ;


having ‘1’ entry at each histogram (i*n histograms in total) instead of having ‘i’ histograms with n entries. After that I can combine those individual Trees but that is completely unnecessary. I can also achieve what I want by merging data by ‘htop’ but I don’t want to add extra phase to the analysis. Defining as a list and pushing ‘Addlist’ provided the same result as ‘UPDATE’ parameter option as well.

Also each iteration file I/O consumes time but myhist[i]->Write(); operates on the last file pointer by default thus reading/writing different files in the same loop is achieved like that. There should be a better way to do this.

Problems are ROOT specific, not ANSI C thus I think experienced users can save me some time on this.


Can you, please, explain what you want to do?
It’s quite difficult to find the question in your post, and the code sample looks wrong.
So, you want to update a histogram in a file? What do you mean by update - overwrite or add more data?
If you are adding more data - you do not have to re-create a hist, you have to read it from your file and add more data. But if it’s just one hist over bunch of input files … why writing/overwriting - just fill it in a loop and write it once. So, you have to clarify your problem.

I thought it was clear enough :slight_smile:

Let me reduce the problem;

There is a two dimensional array let’s say flatliner[i][n], I am trying to write it to a root file with ‘i’ number of histograms with each histogram containing ‘n’ number of entries.

If it was, I would not ask.

Well, now it’s even more confusing. This reduced description is not what you have in your original code - in your code you do not use any flatliner and do not need any input at all, since you’re just filling a bunch of 2D histograms with ‘n’ and ‘i’ indices, is it what you really want?

Anyway, I think your problem has nothing to do with ROOT (and has nothing to do “with ANSI C” or even with “ISO/IEC C++” or whatever, since it’s a problem of organising a couple of loops).

I assume that you have an input of size == size * size2 (both names are from your first code sample) and that you want to have size2 2D histograms (whatever this 2D histogram means).

Step 1: create size2 hists:

[code]TFile output(“test.root”, “recreate”);

for (int i = 0; i < size2; ++i) {
TString name = … somehow create a name derived from the index ‘i’.
myhist[i] = new TH2D(name, title, other parameters)

So now you do not need any updates/overwrites, since you already have … all histograms you’ll be using.

step 2: iterate over your … data set (this was your outer loop with index n over a range [0, size)); it’s not clear though, if you have only one input file or size number of files.
If it’s only one, open it only once before any loop:

TFile input(fileName);
for (int i = 0; i < size; ++i) {//Here's your external loop
   //"read i-th row" (??) I suppose, 'row' must have a size == size2 == 56??
    for (int j = 0; j < size2; ++i) {
         ///do something
         myhist[j]->Fill(params);//fill it the way you want

Now, step 3: write the histograms.

for (int i = 0; i < size2; ++i)

Well, if it’s still not what you want, you’ll probably have to explain why it’s not, so we can further adjust/modify this code :slight_smile: