Help with setting up a ROOT read rule for an "external type"

Hi,

This will be a slightly more advanced question… :thinking:

I need to be able to read a file in which CLHEP::Hep3Vector was saved as-is, from CLHEP 2.4.1.3, using a binary that itself uses CLHEP 2.4.7.1.

I know the basics of this full well. See: Draft: Hep3Vector Compatibility, main branch (2025.04.16.) (!79354) · Merge requests · atlas / athena · GitLab Basically, I use the following kind of declaration:

   <read sourceClass="CLHEP::Hep3Vector"
         source="double dx; double dy; double dz;"
         version="[1-]"
         targetClass="CLHEP::Hep3Vector"
         target="data">
  <![CDATA[
    data[0] = onfile.dx;
    data[1] = onfile.dy;
    data[2] = onfile.dz;
  ]]>
  </read>

What I’m not sure of is whether I can provide a more meaningful input to the version parameter. Since ideally I’d like this rule to only be applied when reading “an old file”. But I’m not sure how/if I can find a “version” for a type that doesn’t inherit from TObject. (I vaguely remember that this may not be possible at all…)

Can I do this? Is there some incantation with which I can tell ROOT to only use this read rule “for files with old versions of CLHEP::Hep3Vector”?

Cheers,
Attila


ROOT Version: 6.34.04
Platform: linuxx8664gcc
Compiler: g++ (GCC) 13.1.0


Can I do this? Is there some incantation with which I can tell ROOT to only use this read rule “for files with old versions of CLHEP::Hep3Vector”?

Yes :slight_smile:

whether I can provide a more meaningful input to the version parameter.

The version number is meaningless for ‘un-versioned’ class (classes without a ClassDef and without a ‘version’ annonation in the dictionary generation.

Replace

version="[1-]"

with

checksum="[2464154506]"

[update: added missing brackets]
where the checksum is the CheckSum of the “old” TStreamerInfo and can be obtained (in your case) with (for example):

root.exe -b -l -q oldfile.root -e '_file0->GetStreamerInfoList()->FindObject("CLHEP::Hep3Vector")->ls();'

or once you have the TStreamerInfo call GetCheckSum()

Thanks Philippe! :smiley:

1 Like

For reference, I found the hash to be:

[bash][atspot01]:~ > root -b /cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/aod/AOD-18.0.0/AOD-18.0.0-full.pool.root
   ------------------------------------------------------------------
  | Welcome to ROOT 6.34.04                        https://root.cern |
  | (c) 1995-2024, The ROOT Team; conception: R. Brun, F. Rademakers |
  | Built for linuxx8664gcc on Feb 11 2025, 14:05:34                 |
  | From tags/6-34-04@6-34-04                                        |
  | With g++ (GCC) 13.1.0                                            |
  | Try '.help'/'.?', '.demo', '.license', '.credits', '.quit'/'.q'  |
   ------------------------------------------------------------------

root [0]
Attaching file /cvmfs/atlas-nightlies.cern.ch/repo/data/data-art/aod/AOD-18.0.0/AOD-18.0.0-full.pool.root as _file0...
Warning in <TClass::Init>: no dictionary for class RawInfoSummaryForTag_p1 is available
Warning in <TClass::Init>: no dictionary for class CosmicMuonCollection_tlp1 is available
Warning in <TClass::Init>: no dictionary for class MdtTrackSegmentCollection_p2 is available
Warning in <TClass::Init>: no dictionary for class CosmicMuonCollection_p1 is available
(TFile *) 0x2b58bb0
root [1] _file0->GetStreamerInfoList()->FindObject("CLHEP::Hep3Vector")->ls()

StreamerInfo for class: CLHEP::Hep3Vector, version=1, checksum=0xb53f04d7
  double         dx              offset=  0 type= 8
  double         dy              offset=  0 type= 8
  double         dz              offset=  0 type= 8
...
root [3] TStreamerInfo* si = (TStreamerInfo*)_file0->GetStreamerInfoList()->FindObject("CLHEP::Hep3Vector");
root [4] si->GetCheckSum()
(unsigned int) 3040806103
root [5]

And I checked, 0xb53f04d7 and 3040806103 are the same. :smiley:

And as a (hopefully) very last comment, I ended up with the following code in the end:


   <class name="CLHEP::Hep3Vector"/>
   <read sourceClass="CLHEP::Hep3Vector"
         source="double dx; double dy; double dz;"
         checksum="[3040806103]"
         targetClass="CLHEP::Hep3Vector"
         target="">
  <![CDATA[
    newObj->set(onfile.dx, onfile.dy, onfile.dz);
  ]]>
  </read>

Note that one needs to use angled brackets around the hash. (The dictionary generator gave me a very clear error message when I left those out.)

Should not be left empty but should list the current data members that are updated. (In practice in your case this is unlikely to change any behavior but in the general case this is necessary in case the old schema already had one of those members, the system needs to know which value to use in the end)