Manual schema evolution: handling change of namespace

Hello all,

I recently moved a custom class from a sublibrary to another and changed its namespace. This class is a member of a larger class that is written to disk, and in order to read an old file, I wanted to add a manual rule to the LinkDef.h. However, I haven’t found a way to get it to work. Here is a scheme of the situation:

  • Larger class: ActRoot::Cluster
  • Member class: ActPhysics::Line, now ActRoot::Line and has been moved from a sublibrary to the same library as ActRoot::Cluster
  • I added this rule to the LinkDef.h that now contains both Cluster and Line:
// Schema evolution for ActPhysics::Line to ActRoot::Line
#pragma read \
        sourceClass="ActPhysics::Line" \
        source="ROOT::Math::PositionVector3D<ROOT::Math::Cartesian3D<float>,ROOT::Math::DefaultCoordinateSystemTag> fSigmas; ROOT::Math::PositionVector3D<ROOT::Math::Cartesian3D<float>,ROOT::Math::DefaultCoordinateSystemTag> fPoint; ROOT::Math::DisplacementVector3D<ROOT::Math::Cartesian3D<float>,ROOT::Math::DefaultCoordinateSystemTag> fDirection; float fChi2" \
        targetClass="ActRoot::Line"\
        target="fSigmas, fPoint, fDirection, fChi2" \
        include="Math/Point3D.h,Math/Vector3D.h" \
        code="{fSigmas = onfile.fSigmas; fPoint = onfile.fPoint; fDirection = onfile.fDirection; fChi2 = onfile.fChi2;}";

I’ve played with the different options: changing the types in the source (three of them are XYZPoint/Vectors), explicitly providing a code snippet, etc… But I get always:

Warning in <TClass::Init>: no dictionary for class ActPhysics::Line is available

Dictonaries are generated and correctly accessible to ROOT (indeed, I can see the rules are added to the dictionary .cxx file). I’m not using TObject inheritance or a ClassDef macro, could this be the reason?

I would appreciate any input you could have on this!

Cheers


ROOT Version: 6.32.02
Platform: Ubuntu 22.04
Compiler: Prebuild binary


If the data member lists is the same in the old and new class (it seems that way in your example) you can simplify the rule as:

#pragma read sourceClass="ActPhysics::Line" targetClass="ActRoot::Line";

explicitly providing a code snippet, etc… But I get always:

Indeed, this is independent of the existence of the rule … at least for now. There is 2 ways to suppress the error message:

  • Re-introduce an (empty) class ActPhysics::Line in your source and request the dictionary for it
  • Use code to supress the print of all warning during the file opening (so including that one).
   Int_t oldlevel = gErrorIgnoreLevel;
   // Hide the warning about the missing dictionary.
   gErrorIgnoreLevel = kError;
 
   ... TFile::Open(...) ...
   
   gErrorIgnoreLevel = oldlevel;

In addition, you may want to consider opening an issue to request that the automatic suppression of this message if a rule is registered (I am not sure whether or not it can practically be implemented though).