Problem with Writing Class Objects to TTrees that contain std::tuple<double, double, double> varialbes

Greetings,

I am currently facing a problem with regards to writing class objects that contain the STL class object std::tuple<double, double, double> to TTrees. I have recreated the essence of my problem in the following short snippets:

Event.hpp

#pragma once
#include <tuple>
#include <iostream>
#include <utility>

class Event
{
        public:
                Event();
                ~Event();
                void Set(std::tuple<double, double, double>, std::pair<double, double>);
                void Print();
        private:
                std::tuple<double, double, double> lPosition;
                std::pair<double, double> lTrigger;
};

and Event.cpp

#include <iostream>
#include <tuple>
#include <utility>
#include "Event.hpp"

Event::Event(){}
Event::~Event(){}
void Event::Set(std::tuple<double, double, double> _lPos, std::pair<double, double> _lTrig)
{
        lPosition = _lPos;
        lTrigger = _lTrig;
}
void Event::Print()
{
        std::cout << "Triple: (" << std::get<0>(lPosition) << ", " << std::get<1>(lPosition) << ", " << std::get<2>(lPosition) << ")" << std::endl;
        std::cout << "Pair: (" << lTrigger.first << ", " << lTrigger.second << ")" << std::endl;
}

I am compiling the .cpp file above via:

root -L Event.cpp+

and I load the Event_cpp.so library inside a rootlogon.C file. Now, if I run the following macro, inside the same folder as all the files mentioned above:

fill.cpp

#include <iostream>
#include "Event.hpp"
#include <TFile.h>
#include <TTree.h>
#include <TSystem.h>

int fill()
{

        if (gSystem->AccessPathName("output.root"))
        {
                std::cout << "\033[1;32m[SUCCESS]: \033[0;37mThe default output file \"output.root\" does not exist. Proceeding." << std::endl;
        }
        else
        {
                std::cout << "\033[1;31m[FATAL]\033[0;37m: The default output file \"output.root\" already exists. Aborting (exit code := 1)." << std::endl; std::exit(1);
        }

        TFile* _output = new TFile("output.root", "NEW");
        TTree* _main = new TTree("T", "DataTree");
        Event* _event = nullptr;
        _main->Branch("Event", &_event);
        std::tuple<double, double, double> A_Tuple(1,1,1);
        std::pair<double, double> A_Pair(1,1);
        _event->Set(A_Tuple, A_Pair);
        _event->Print();
        _main->Fill();
        _output->cd();
        _main->Write();
        _output->Close();
        return 0;

}

I get:

[SUCCESS]: The default output file "output.root" does not exist. Proceeding.
Warning in <TStreamerInfo::Build>: Event: tuple<double,double,double> has no streamer or dictionary, data member "lPosition" will not be saved
Triple: (1, 1, 1)
Pair: (1, 1)
(int) 0

which is where the problem appears to be: The object std::tuple cannot be written inside the TTree, while the object std::pair can without any problem. As far as I understand, ROOT does not have a way to “write” the object in the TTree via a TStreamer (which is explained in the warning message). Any help on this issue would be greatly appreciated.

Many Thanks,

Andy


_ROOT Version: 6.24/06
Platform: Centos8
Compiler: g++ 11


In Event.hpp add

#ifdef __ROOTCLING__
#pragma link C++ class std::tuple<double,double,double>+;
#endif

to request the dictionary for that class.

Hi @pcanal,

Thank you very much!! It works flawlessly!

Andy