Hello, I’m learning to use TDataFrame at the moment. It’s pretty nifty. I have an analysis class that I’d like to use on several different root files so I want to be able to access the histograms which are output from TDataFrame as members of my analysis class.
don’t worry. TResultProxy is just a wrapper class, owning its “result” and able to trigger the event loop of the TDF upon usage of the “result” by the user (myRes->Draw(), for example)
I am not sure I get the full picture of the analysis you are trying to put up but what is stopping you from having data members of type TResultProxy ? You can access all the methods of the underlying histo via the -> operator (e.g. myProxy->GetName(), myProxy->Write()) and even can get the reference to the histo with the GetValue method.
././Analyzer.C:120:8: error: assigning to 'ROOT::Experimental::TDF::TResultProxy<TH1D> *' from incompatible type 'TResultProxy< ::TH1D>'
h1_ = selected_reco.Histo1D<double>(TH1D("h1", "h1", 80, 0, 2), "recon_theta", "weight");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
././Analyzer.C:139:8: error: no member named 'DrawClone' in 'ROOT::Experimental::TDF::TResultProxy<TH1D>'
h1_->DrawClone();
I didn’t realize that you had to use “.” to access the TResultProxy, I kept using “->” and I was instead accessing the underlying histogram.
If there’s a more beautiful way to do it, it would still be appreciated. Thanks for the help!
you need to use a data member of type ROOT::Experimental::TDF::TResultProxy and not ROOT::Experimental::TDF::TResultProxy*. The second attempt for sure works, but implies a copy, which is less than optimal. Why did you clone?
To further clarify: TResultProxy<TH1D> is a type that acts as a smart pointer to a TH1D. All results of TDataFrame actions are of type TResultProxy<T>; in terms of usage, you can think of it as a std::shared_ptr<T>, or even just a T*.
Its only particular feature is that this is a pointer that is smart enough to trigger the TDataFrame event loop when you try to access its contents for the first time, although for most applications (yours included) one can safely ignore this under-the-hood details.
Anyway, since TResultProxy<T> already acts like a pointer, you don’t need to store a pointer to a TResultProxy<T> in your class, just use TResultProxy<TH1D> as you would use a TH1D*.