How to Rename a Class in Output with Backwards Compatibility

Please can someone help me as how to change the class in name in a schema.

I have a shared library with my own classes in it that I store to the output. I want to rename a class for a new version of the output and shared library but retain backwards compatibility. I followed the instructions:

There are no anchors, so at “ The dictionaries”.

I have a class currently called “BDSOutputROOTGeant4Data”. I will not change any members (two std::map<int, structs>) where there are 2 structs called ParticleInfo and IonInfo both defined inside BDSOutputROOTGeant4Data.

In the linkdef, I currently have (for ClassDef(BDSOutputROOTGeant4Data,2):

#pragma link C++ class BDSOutputROOTGeant4Data+;
#pragma link C++ class BDSOutputROOTGeant4Data::ParticleInfo+;
#pragma link C++ class BDSOutputROOTGeant4Data::IonInfo+;

I want to rename this class to BDSOutputROOTEventParticleData. The structs will remain the same inside the class.

I changed the link def to (file now called BDSOutputROOTEventParticleDataLinkDef.hh):

#pragma link C++ class BDSOutputROOTEventParticleData+;
#pragma link C++ class BDSOutputROOTEventParticleData::ParticleInfo+;
#pragma link C++ class BDSOutputROOTEventParticleData::IonInfo+;

#pragma read sourceClass=“BDSOutputROOTGeant4Data”

At the end of the new header (BDSOutputROOTEventParticleData.hh), I have:

When I load the old data using the new shared library I get an error that there’s no dictionary so it’s not working…

TClass::Init:0: RuntimeWarning: no dictionary for class BDSOutputROOTGeant4Data is available
TClass::Init:0: RuntimeWarning: no dictionary for class BDSOutputROOTGeant4Data::ParticleInfo is available

I also found the following paper on this, which has similar instructions.

Is this possible and does anyone know how to do this?

I can’t find any example of only changing the class name either on the ROOT website, the documentation or the included tutorial example files.

Many thanks,

_ROOT Version: 6.16/00
_Platform: Mac OSX Mojave
_Compiler: Apple LLVM version 10.0.0 (clang-1000.11.45.5)

To make this work you will also need the renaming rule for ParticleInfo and IonInfo.

After that it should work while still issuing the warning about missing dictionary. To avoid the warning you would need to add back to the executable classes with the names BDSOutputROOTGeant4Data, etc. for which you generate a dictionary (but those classes can be ‘empty’.



Thanks for the quick response. Ah, I didn’t think about the nested ones. I added rules for the other nested structs -> now in BDSOutputROOTEventParticleDataLinkDef.hh

#pragma link C++ class BDSOutputROOTEventParticleData+;
#pragma link C++ class BDSOutputROOTEventParticleData::ParticleInfo+;
#pragma link C++ class BDSOutputROOTEventParticleData::IonInfo+;

#pragma read sourceClass="BDSOutputROOTGeant4Data" \
  version="[-2]" \

#pragma read sourceClass="BDSOutputROOTGeant4Data::ParticleInfo" \
  version="[-2]" \

#pragma read sourceClass="BDSOutputROOTGeant4Data::IonInfo" \
  version="[-2]" \

However, when loading in ROOT or pyroot, I still have problems that it doesn’t recognise the old data.

root [4] TFile * f = new TFile("/Users/nevay/physics/reps/bdsim-develop-build/examples/beamLoss/t1.root")
Warning in <TClass::Init>: no dictionary for class BDSOutputROOTGeant4Data is available
Warning in <TClass::Init>: no dictionary for class BDSOutputROOTGeant4Data::ParticleInfo is available
(TFile *) 0x7f86007196b0
root [7] TTree * pdt2 = (TTree*)f->Get("Geant4Data")
(TTree *) 0x7f8603172810
root [8] ParticleData* pdl = new ParticleData()
(ParticleData *) 0x7f8600403100
root [9] pdt2->SetBranchAddress("Geant4Data.", &pdl)
Error in <TTree::SetBranchAddress>: The pointer type given (ParticleData) does not correspond to the class needed (BDSOutputROOTGeant4Data) by the branch: Geant4Data.
(int) -1
root [10]

Any help would be greatly appreciated.

Hi Laurie,

i am confused you added rules for BDSOutputROOTEventParticleData but are creating a TParticleData. What is the relationship between the two?


Ah apologies there. ParticleData is a further class in the analysis that represents the tree in the output. Similarly we have a class Event which has members as in the event tree. ParticleData is simple and has one member which is BDSOutputROOTEventParticleData*. This allows us to link a tree from a file to a local instance of something that is the same layout. I’m attaching the source for each of the relevant classes here.

I tried directly onto an object of BDSOutputROOTEventParticleData and got:

(TFile *) 0x7ff371d481f0
root [1] gSystem->Load("librebdsim")
(int) 0
root [2] gSystem->Load("libbdsimRootEvent")
(int) 0
root [3] TTree* pdt2 = (TTree*)f->Get("Geant4Data")
(TTree *) 0x7ff36fd94f80
root [4] BDSOutputROOTEventParticleData* pd = new BDSOutputROOTEventParticleData()
(BDSOutputROOTEventParticleData *) 0x7ff3743a0060
root [5] pdt2->SetBranchAddress("Geant4Data.", &pd);
Warning in <TStreamerInfo::BuildOld>: Cannot convert BDSOutputROOTGeant4Data::particles from type: map<int,BDSOutputROOTGeant4Data::ParticleInfo> to type: map<int,BDSOutputROOTEventParticleData::ParticleInfo>, skip element

Warning in <TStreamerInfo::BuildOld>: Cannot convert BDSOutputROOTGeant4Data::ions from type: map<int,BDSOutputROOTGeant4Data::IonInfo> to type: map<int,BDSOutputROOTEventParticleData::IonInfo>, skip element
root [6]

So getting closer… (1.1 KB)
ParticleData.hh (1.2 KB)
ParticleDataLinkDef.hh (720 Bytes) (6.2 KB)
BDSOutputROOTEventParticleData.hh (4.8 KB)
BDSOutputROOTEventParticleDataLinkDef.hh (1.2 KB)

Thanks again!

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