ROOT7 RNTuple and custom classes

Hello!

I’m looking at the future of TTree with ROOT7, RNTuple and running some test to understand its capabilities and limitations.

I noticed that custom class are currently not supported in RField. The following code stopping with an error:

terminate called after throwing an instance of 'ROOT::Experimental::RException'
  what():  std::atomic<TClass*> is not supported
At:
  ROOT::Experimental::RClassField::RClassField(std::string_view, std::string_view, TClass*) [/home/pronost/Software/root/root_src/tree/ntuple/v7/src/RField.cxx:782]
R__LOAD_LIBRARY(ROOTNTuple)
 
#include <ROOT/RNTuple.hxx>
#include <ROOT/RNTupleModel.hxx>
 
#include <TCanvas.h>
#include <TH1F.h>
#include <TRandom.h>
#include <TRandom3.h>
#include <TSystem.h>
 
#include <cstdio>
#include <iostream>
#include <memory>
#include <vector>
#include <utility>

using RNTupleModel = ROOT::Experimental::RNTupleModel;
using RNTupleReader = ROOT::Experimental::RNTupleReader;
using RNTupleWriter = ROOT::Experimental::RNTupleWriter;

class PMTHit : public TObject {
	public:
		int  PMT;
		float  T;
		float  Q;
	 
		void Reset() {
			PMT=0; 
			T=0; 
			Q=0;
		}
		
		PMTHit() { Reset(); }
	 
		ClassDef(PMTHit,1)
};

class PMTHitCollection : public TObject {
	public:
		int  nHits;
		std::vector<PMTHit>  hits;
	 
		void Reset() {
			nHits=0; 
			hits.clear();
		}
		PMTHitCollection() { Reset(); }
	 
		ClassDef(PMTHitCollection,1)
};

class RecoInfo : public TObject {
	public:
		double vtx[4];
		double goodness;
	 
		void Reset() {
			vtx[0]=0;
			vtx[1]=0;
			vtx[2]=0;
			vtx[3]=0;
			goodness=0;
		}
		
		RecoInfo() { Reset(); }
	 
		ClassDef(RecoInfo,1)
};
 
void ntuple_write()
{
	auto model = RNTupleModel::Create();
	auto gRecoInfo = model->MakeField<RecoInfo>("RecoInfo");
	auto gHitCollection = model->MakeField<PMTHitCollection>("HitInfo");
	auto ntuple = RNTupleWriter::Recreate(std::move(model), "my_data", "ntuple_custom.root");
	
	std::cout << "Filling NTuple" << std::endl;
	TRandom* tRandom = new TRandom3();
	for (int i = 0; i < 10000; i++) {
		gRecoInfo->Reset();
		gHitCollection->Reset();

		gHitCollection->nHits = tRandom->Integer(100);
		for ( int iHit = 0; iHit < gHitCollection->nHits; iHit++ ) {
			PMTHit h;
			h.PMT = tRandom->Integer(10);
			h.Q = tRandom->Poisson(1000);
			h.T = tRandom->Poisson(1000);
			gHitCollection->hits.push_back(h);
		}
		gRecoInfo->goodness = tRandom->Gaus(0.5, 0.5);
		gRecoInfo->vtx[0] = tRandom->Gaus(0, 10);
		gRecoInfo->vtx[1] = tRandom->Gaus(0, 10);
		gRecoInfo->vtx[2] = tRandom->Gaus(0, 10);
		gRecoInfo->vtx[3] = tRandom->Gaus(1000, 10);
		
		ntuple->Fill();
	}
	
	std::cout << "Closing NTuple" << std::endl;
}

Is there already a way to have custom class supported in RNTuple? Is it something which is planned for an upcoming release? Or is there another “more correct” way to deal with such data structure (specially the vector of another class) with RNTuple?

Hi @gpronost, welcome back to the forum!

Maybe @jblomer can answer your question?

1 Like

Hello,

In general, custom classes with dictionaries are supported in RNTuple. Also combinations as shown here, custom classes containing vectors of other custom classes.

Are you using the latest master branch of ROOT? I could not reproduce the error.

That said, RNTuple has only support for a well-defined subset of the C++ types, which does not include std::atomic or raw pointers. Support for std::atomic is straight-forward to add and probably useful. Raw pointers we intend to not support (unique_ptr, however, is supported).

@pcanal I’m a bit puzzled by the error message. The std::atomic<TClass*> may be coming from the fgIsA member of the ClassDef macro. But this is a static member, so it’s not written to disk. If you have an idea, let me know.

Cheers,
Jakob

Just wondering, could you make any progress? Please let us know if you need more information from us.

Hi,

Sorry for the delay answer, I actually missed your answer on the 29th.
I’m taking my annual leave currently (and my internet connection is very poor).

It seems my root version is a bit old (last commit was Wed Nov 16 12:03:13 2022 +010). I will update and test as soon as possible.

Hi,

Sorry for the delayed answer. I just updated my ROOT version and re-test the code. It’s working fine with custom class now.

Best,
Guillaume

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