Following the example from RNTuple documentation: ROOT: RNTuple-related classes, that:
tree->Branch("px", &Category, "px/F");
becomes
auto px = model->MakeField<float>("px"); // px is std::shared_ptr<float>
This however makes a problem with sharing leafs between trees.
With tree I could
tree1->Branch("px", &Category, "px/F");
tree2->Branch("px", &Category, "px/F");
and both trees would read from the same variable. However, this is not possible anymore with the RNTuple:
{
auto model = ROOT::RNTupleModel::Create();
auto fldAge = model->MakeField<int>("Age");
auto writer1 = ROOT::RNTupleWriter::Recreate(model->Clone(), "Staff1", "out1.root");
auto writer2 = ROOT::RNTupleWriter::Recreate(std::move(model), "Staff2", "out2.root");
*fldAge = 25.;
writer1->Fill();
writer2->Fill();
}
Here, as the model
is unique pointer, I must e.g. clone the model but then fldAge
is not connected to the model
any more. The writer2
will have Age = 25 whereas writer1
will have Age = 0.
I think that the writer takes ownership of the model’s unique_ptr
was perhaps unfortunate design choice. Could the RNTuple Writer/Reader take the model as non-owning (model.get()
) or model is of shared_ptr
type? Then I should be able to do:
// non-owning pointer
auto writer1 = ROOT::RNTupleWriter::Recreate(model.get(), "Staff1", "out1.root");
auto writer2 = ROOT::RNTupleWriter::Recreate(model.get(), "Staff2", "out2.root");
or
// shared_ptr
auto writer1 = ROOT::RNTupleWriter::Recreate(model, "Staff1", "out1.root");
auto writer2 = ROOT::RNTupleWriter::Recreate(model, "Staff2", "out2.root");
I cannot imagine any reason forcing model to be unique - it could be shared between different RNTuples. I also think about an application where we have:
// shared_ptr
auto reader1 = ROOT::RNTupleReader::Open(model, "Staff", "input1.root");
auto writer1 = ROOT::RNTupleWriter::Recreate(model, "Staff", "out2.root");
where we read a field, play with it and store it back to another tuple.
How much the RNTuple interface is fixed atm?