Problem with Writing and Reading Custom Class Objects from TTrees

Greetings,

I would like to write and read custom classes in TTrees, but I am facing an issue. I have created a custom class, illustrated below (Name of the files is class.hpp and class.cpp, respectively)

class.hpp

#pragma once

class myclass : public TObject
{
        private:
                Double_t Charge;
                Double_t X;
                Double_t Y;
                Double_t Z;
        public:
                myclass();
                ~myclass();
                Double_t getX();
                Double_t getY();
                Double_t getZ();
                Double_t getCharge();
                void Set(Double_t, Double_t, Double_t, Double_t);
                ClassDef(myclass, 1)
};

class.cpp

include <TObject.h>
#include "class.hpp"
#include <TClass.h>

myclass::myclass(){}
myclass::~myclass(){}
void myclass::Set(Double_t _X, Double_t _Y, Double_t _Z, Double_t _charge)
{
        X = _X; Y = _Y; Z = _Z; Charge = _charge;
}
Double_t myclass::getX(){return X;}
Double_t myclass::getY(){return Y;}
Double_t myclass::getZ(){return Z;}
Double_t myclass::getCharge(){return Charge;}

I compile my class definitions via the command:

root -l
root [0] .L class.cpp+

which yields a class_cpp.so file, to which I add on the rootlogon.C file in my working directory. Now, if I run the following macro, which is designed to test both the creation and the reading of a TTree with the class entries defined above,

#include <TFile.h>
#include <TTree.h>
#include "class.hpp"

int maker()
{
        // Making the .root file
        TFile* _file = new TFile("output.root", "NEW");
        TTree* _tree = new TTree("Tree", "Main");
        myclass Event;
        _tree->Branch("Event", &Event);
        // Creating a simple 'event', i.e. row in the main TTree
        Event.Set(1,1,1,1000);
        std::cout << Event.getX() << " " << Event.getY() << " " << Event.getZ() << " " << Event.getCharge() << std::endl;
        _tree->Fill();
        _file->cd();
        _tree->Write();
        _file->Close();

        // Reading the .root file created above.
        myclass* rEvent;
        TFile* _reader = TFile::Open("output.root", "READ");
        TTree* _rtree = (TTree*)_reader->FindObjectAny("Tree");
        _rtree->SetBranchAddress("Event", &rEvent);
        _rtree->GetEntry(1);
        std::cout << rEvent->getX() << " " << rEvent->getY() << " " << rEvent->getZ() << " " << rEvent->getCharge() << std::endl;
        return 0;
}

I get:

root [0] 
Processing maker.cpp...
1 1 1 1000
-3.60071e-305 6.80648e+38 -1.37406e+308 -2.55744e-254
(int) 0

which essentially means that even if my class definitions work correctly, the “writing” in the TTree seems to be faulty, and consequently, I do not get what I want when reading it. I would really appreciate any help on this issue.

Many Thanks,

Andy

FURTHER THOUGHTS
Apparently, there is a segment of the ROOT Guide about this, that mentions “Streamers”, that, as far I understand, help with the “parsing” of a custom object, but I do not know how to use them. There is also this question on the FORUM on this, but the answers do not a straight answer to the problem.


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


Use

        // Reading the .root file created above.
        myclass* rEvent = nullptr;

Hi,
also note that you don’t need to inherit from TObject and usage of ClassDef is not mandatory (although it provides a little performance optimization and other goodies).

Updated docs regarding I/O of custom classes with ROOT can be found at I/O of custom classes - ROOT .

Cheers,
Enrico

@pcanal @eguiraud Thank you both for your replies. Indeed, @pcanal’s answer solved the issue. Thanks also for the info @eguiraud.

Cheers,

Andy