SetDirectory(0) for RNTuple

Hello ROOT community,

I’m working on a test where I need to create an RNTuple that can be accessed from another file. Ideally, I’d prefer not to save the ntuple to disk and then delete it afterward.

For TTrees, SetDirectory(0) enables the tree to exist independently of any specific directory. Is there a similar option for RNTuples to achieve this?

Thanks in advance!

Cheers,
Nikolaj

Thanks for your question @Krogh,

I’m adding @jblomer in the loop.

Hi Nikolaj,

Reading and writing concurrently is a functionality that is not matched in RNTuple. Only once an RNTuple is committed, you can start reading.

If you don’t want to persistify the data, you can however write the data into a TMemFile, and once the RNTupleWriter is done, open an RNTupleReader on the memory file.

Cheers,
Jakob

Hi Jakob,

Using TMemFile sounds like a great idea! However, I’m a bit unsure about the implementation.

When I try this approach, as you can see in the example, it still creates a file. I expected something like this to work:
auto ntuple = RNTupleWriter::Recreate(std::move(model), "Input ntuple", memFile.get());
However, it seems that RNTuple doesn’t accept a TMemFile as a parameter.

Do you have any ideas on how I can keep this entirely in memory without creating a file on disk?

Cheers,
Nikolaj

#include <memory>
#include <filesystem>

#include <ROOT/RNTupleModel.hxx>
#include <ROOT/RNTupleWriter.hxx>
#include <TMemFile.h>

using ROOT::Experimental::RNTupleModel;
using ROOT::Experimental::RNTupleWriter;

int main () {
   // Create a TMemFile
    std::unique_ptr<TMemFile> memFile = std::make_unique<TMemFile>("InputNtuple.root", "RECREATE");

   // Create an RNTuple model
   auto model = RNTupleModel::Create();

   // Create fields for the RNTuple
   auto var1Field = model->MakeField<float>("Field1");
   
   // Create an RNTuple
   auto ntuple = RNTupleWriter::Recreate(std::move(model), "Input ntuple", "InputNtuple.root");
   
   // Check if the file exists
   if(std::filesystem::exists("InputNtuple.root")) {
      std::cout << "Input file exists" << std::endl;
   }

   // Fill the RNTuple with some information
   
   *var1Field = 3;
   ntuple->Fill();   

   // Write the TMemFile to memory
   memFile->Write();
}

In order to use an existing TFile (descendant), use the RNTupleWriter::Append() API, like

auto ntuple = RNTupleWriter::Append(std::move(model), "Input ntuple", *memFile);

Note that the writer in this case assumes exclusive access to the underlying file during construction, destruction and Fill().

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