Problem reading custom Root file

Hello everyone,

I have received a very old Root file with some data that I need. However, the data is stored as a custom class and I am having trouble reading the file. I also have the source file of the custom class.

Here is what it tried:

rootcint -v -f dict.cpp -c BCR_PDF.h
g++ -o $(root-config --cflags --libs --ldflags) -I. dict.cpp BCR_PDF.C -shared -fPIC
g++ -o main $(root-config --cflags --libs --ldflags) -I. main.cpp

main.cpp contains the following:

#include <TFile.h>
#include "BCR_PDF.h"

int main(int argc, char** argv)
    TFile f("ZeusJets.root");;

Running the script results in the following error message:
Error in <TBufferFile::CheckByteCount>: object of class BCR_PDF read too few bytes: 51 instead of 1823399

I know that the Root file was previously used on a 32bit machine running Root 5.26. Now, I am trying to read it on a 64bit machine with Root 5.34. Maybe that is part of the problem. But looking at the class header, it contains no machine dependent member variables, such as size_t.

I have attached the Root file as well as the source code. To make the above steps work, I had to move the definitions of the variables chNum and debug from the header to the source file. But presumably, at some point the files where working without any modification. Therefore I am not sure if I am on the right track. How can I read this file?

data.tar.gz (713.5 KB)

I can reproduce the issue, it doesn’t seem to be related to the dictionaries (happens with or without). @pcanal can you help?

What was the linkdef line in the ‘old’ code for this class?

I have no more information than what I posted above. The directory did not contain any Makefile or compile script.
I have the old .so-file that was used. But since that was created on a very old machine, I cannot link against it.
Maybe this file contains any useful information? (58.2 KB)

In the “BCR_PDF.h” file, change:

TString chNum[10]={"0","1","2","3","4","5","6","7","8","9"};
bool debug=kFALSE;


#include "TString.h"

extern TString chNum[10];
extern bool debug;

and change:

#if !defined (__CINT__)


#if defined(__MAKECINT__) || defined(__ROOTCLING__)
#pragma link C++ global chNum;
#pragma link C++ global debug;
#pragma link C++ class BCR_PDF+;

In the “BCR_PDF.C” file, change:

#include <BCR_PDF.h>


#include "BCR_PDF.h"
#include <iostream>
#include <istream>
#include <iomanip>
using std::cout, std::endl, std::ifstream, std::setw;

TString chNum[10]={"0","1","2","3","4","5","6","7","8","9"};
bool debug=kFALSE;


Then, in an interactive ROOT session, try:

root [0] .L BCR_PDF.C++
root [1] TFile *f = TFile::Open("ZeusJets.root");
root [2] f->ls();
root [3] BCR_PDF *p; f->GetObject("CTEQ5D_f2", p);
root [4] p->FullDump();
1 Like

Thank you very much. This solves the issue.

Could you give a short explanation of what your solution does (especially the #pragma link statements)? I never could have found this solution on my own.

I guess custom Root files are just an unsuitable format for the long term storage of data. From now on, I will store these values in a text file.

Search for “pragma” in the “ROOT 5 User’s Guide” (when “rootcint” is used) and in the “ROOT 6 User’s Guide” (when “rootcling” is used).

If you do not have the source code for the classes which were used, you can often help yourself using something like this (you will get “access” to the stored data members but not to the original class methods):

root [0] TFile::Open("ZeusJets.root");
root [1] gFile->MakeProject("MyWeirdFile", "*", "recreate++");
root [2] .class BCR_PDF

Then you can use the “generated” dictionaries:

root [0] .L MyWeirdFile/
root [1] TFile *f = TFile::Open("ZeusJets.root");
1 Like

Thanks a lot. Reading the data members should be enough to reconstruct any class. If I get into a similar situation again, this will save me a lot of trouble.

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