Initialization after getting a pointer to a class stored in ROOT file using Get method

ROOT Version: 6.20

Hi,

I have a class that inherits from TObject and that I store in a ROOT file.

When I do the following I can load the data members stored inside the ROOT object into my instance pointer, i.e. ob at the following code.

~ root
[0] TFile *f = new TFile("myFile.root");
[1] MyObject *ob = (MyObject *) f->Get("objName");

When I execute those lines, the default constructor of MyObject is called before data members are assigned a value.

In the next step [2], the data members of the class - as they are stored in the ROOT file - have been already loaded.

So, the following command works as expected

[2] ob->GetMyDataMember();

However, before reaching the execution of [2] I would like to be able to call another Initialisation method, once the data members have been already loaded. Because I need to know the values in the initialisation. It is this possible?

I hope I explained myself.
Thanks!

My first approach would be: Have you tried ?
If that does not work I guess @pcanal can help you.

If you tell me how to try … or point me to the right documentation that explains how to do such thing…

I thought you had in mind some method to call ? That why I suggested you tried;

[0] TFile *f = new TFile("myFile.root");
[1] MyObject *ob = (MyObject *) f->Get("objName");
[2] ob->AnOtherInitialisationMethod();
[3] ob->GetMyDataMember();

May be I misunderstood what you are trying to do.

Sorry for the poor explanation, I want the method

ob->AnOtherInitialisationMethod()

to be called automatically (lets say internally) when I call

MyObject *ob = (MyObject *) f->Get("objName");.

I thought I could do that in the constructor of the class, but data members have not been yet loaded. There is a way to force the load of data members already in the constructor?

Oh I see. I do not think it is possible… I let @pcanal comment.

Adds something like:

#pragma read sourceClass="MyObject" targetClass="MyObject" version="[1-]" source="" target="name_of_datamembers" code="{ newObj->AnOtherInitialisationMethod(); }"

to your LinkDef.h file.

Ok, I have not much experience with LinkDef and pragma instructions. But for each class in our library we create a custom LinkDef inside a cmake macro. So I guess I will be able to add that line to the class I am interested in.

For information, at this header link and source link you will find the class code where I want to do such thing.

The following data members load normally with f->Get.

std::vector<string> fFileNames;  //<
std::vector<TVector3> fPositions;  //<
std::vector<Double_t> fMeshSize;  //<
std::vector<TString> fGasMixtures;  //<
std::vector<TString> fGasDensities;  //<

and the following member

std::vector<MagneticFieldVolume> fMagneticFieldVolumes;  //!

must be initialised with the method LoadMagneticVolumes(), after the //< members have been loaded.

Now my guess for the pragma line you propose I have to build is:

#pragma read sourceClass="TRestAxionMagneticField" targetClass="TRestAxionMagneticField" version="2" source="" target="fMagneticFieldVolumes" code="{ newObj->LoadMagneticVolumes();}" 

And here my questions from non-expert on this.

  • name_of_datamembers : This is a list of data members that need to be preloaded? Or that will be initialised afterwards? If it is a list, a proper separator is :?

  • newObj : is a key parameter definition or I should replace by something more meaningful?

  • version : I have to specify the current version of the class? Or I can specify any?

Thanks!

You should specify the verison on-file that which the rule should applies (so from your description, it is ‘any/all’ so "[1-]" should do.

newObj : is a key parameter definition or I should replace by something more meaningful?

No. It is a variable provided as input to the code. It points to the live object in memory. (there is also
onfile which would point to a in-memory representation of the data as-is on of the file).

name_of_datamembers : This is a list of data members that need to be preloaded? Or that will be initialised afterwards? If it is a list, a proper separator is : ?

Not exactly. There are 2 lists. source which should contain the onfile data member that needs to be used as input (in their onfile/old format); an example of such list is "float fPx; float fPy;".
The second is target which is a list of the in-memory object affected by the rule and an example is "fentries, farrayPointer"

1 Like

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