How to get number of histograms in file

Hi

I have two programs. The first program fills histograms and saves them to Histos.root. The second program opens Histos.root and uses the histograms for analysis.

In the second program, it is convenient for me to know exactly how many histograms Histos.root contains.
Is there a way to get this number?

Thanks,
Kristian

Hi Kristian,

Here is an example:

void list_histos(const char *fname)
{
   TKey *key;
   TFile *f = TFile::Open(fname, "READ");
   if (!f || f->IsZombie()) {
      cout << "Unable to open " << fname << " for reading..." <<endl;
      return;
   }
   Int_t total = 0;
   TIter next((TList *)f->GetListOfKeys());
   while (key = (TKey *)next()) {
      TClass *cl = gROOT->GetClass(key->GetClassName());
      if (cl->InheritsFrom("TH1")) {
         // the following line is not needed if you only want 
         // to count the histograms
         TH1 *h = (TH1 *)key->ReadObj();
         cout << "Histo found: " << h->GetName() << " - " << h->GetTitle() << endl;
         total++;
      }
   }
   cout << "Found " << total << " Histograms" << endl;
}

Cheers, Bertrand

2 Likes

Hi Bertrand

Thanks a lot! - it works like a charm :slight_smile:

Kristian

Hi there,

Is there any way to know how many histograms are in the file without doing this? I want to implement a function that creates a matrix (vector>) and contains in each row the binning of each of the histograms in the file. In order to fill the vector, I need the numbers of rows which would be equal to the number of histograms in the file.

Thanks in advance!
Arturo

Hi Arturo,

thanks for reviving the thread after 6 years.
Can’t you start from the solution of bertrand to identify the histograms in the file starting from the associated TKey and fill your vector/matrix with their numbers of bins?

Cheers,
D

Hi D,

Thanks to you for paying me attention!! What you are saying has a lot of sense, however, I will still need to figure out until what number should the first buckle goes. I don’t have any idea about how to do it. I tried to find out if any of the TFile or TKey member functions can give actually how many objects of a specific kind they contain, but I didn’t find anyone. I am rather new in the business, so all the help you can give me is more than welcome.

Thanks in advance,
Arturo

Hi,

I am not sure what you are trying to achieve. You have in hands a recipe to extract the number of bins of all histograms in a file. Is there anything else you would like to do?

D

Hi,

You’re right, I know I can do the extraction of all the bins but this is not what I want, What I want is something like the piece of code below.

vector<vector<double>> bin_matrix;  //this should contain as many rows as histogram I have in the root file

for ( int i = 0; i < Total_number_histo; i++) {//here I am setting the row of my matrix
     vector<double>temp;
     for(int j = 1; j < Number_of_bins_Histo; j++){
     //... some code for taking the name of the histogram and the lowedge of its bins ...    
     temp.push_back(lowedge);
     }
bin_matrix.pus_back(temp);
}

I don’t know if it’s clear now, as you can see, I will need to know the number of histograms in the file, in principle, I can run the recipe and get this total number and then put it in my code, but I will be running twice, because of I use later this piece of code to move over all the histograms in the root file.

Thanks,
Arturo

Hi,

I still do not understand. What do you want, in words, to extract from the histos?

D

Hi,

Well, from every histogram in the file, I want to get a vector that contains the name of the histogram as its first element and the rest of the elements should be the edge of every bin. Later I need to loop over these vectors, to fill other histograms with different data, but the same name and bins.

Thanks a lot for your patient!
Arturo

Hi,

so why not having a vector of strings for the names and a second deque of vectors of doubles with the bin edges? (vectors of vectors are bad data strucures…)
The procedure to find the histograms is in place, you just need to fill the data structures…

Cheers,
D

ok, I think it sounds better, also I realize that a vector of vector wouldn’t work, because of the number of bins could be different, so I would never have a matrix. BTW, do you have any specific reasons for

I thought they were simple structures.

Thanks a lot!
AR

Hi,

when you extend a vector, it could reallocate. If it reallocates, elements must be copied. The copies can have a price, e.g. linked to further allocations. This kind of patterns brings to degradation of performance.

D

Hi, I had read about this issue, but thanks a lot anyway!

Cheers,
Arturo

Hello, sorry for reviving this old thread. I was wondering if someone could explain what some of lines of @bellenot codesnippet do. Especially in the block which starts with:

 TIter next((TList *)f->GetListOfKeys());
   while (key = (TKey *)next()).......

I have a hard time understanding what this keys stuff does.

See ROOT: TFile Class Reference