Fickle call to importTH1

Hi,

I’m attempting to write a class where a RooHistPdf is a data member, but the histogram on which it is based isn’t defined until after initialization. I’ve been attempting to use a RooDataHist and the importTH1 function to achieve this. The behavior of this is rather fickle, and I don’t know why: sometimes importTH1 works, sometimes it segfaults, sometimes it flips the distribution negative (!), sometimes the functionality depends on the number of bins in the histogram.

I imagine the problem is not with the importTH1 method, but with something that I’m doing wrong. Unfortunately, I have no idea what it is…

Can someone tell me what I need to change? I have attached the code.
Test.h (421 Bytes)
Test.cxx (989 Bytes)

Hi,

Your code doesn’t work for a couple of reasons. You cannot create a functional RooDataHist object using the default constructor. (The default constructor only exists to support ROOT persistence of RooDataHist object).
Secondly I am suprised that it is possible to call importTH1! The method is protected in class RooDataHist (but I confirm that I can do it). I protected it because it is only meant for internal use because it requires some specific initial conditions.
Finally there is a conceptual problem: It is in general not possible, to import histograms after a RooDataHist has been created: the binning definition of a RooDataHist is frozen in the constructor. If a TH1 that is imported later that does not have the same binning, cannot be imported properly.
There is however a simple solution to your problem: make your Test class own a pointer to a RooDataHist and construct the RooDataHist instance after your TH1 becomes available:

datahist = new RooDataHist(“datahist”,“datahist”,x,Import(myTH1)) ;

Wouter

Ah yes. How silly of me. I was blindly following an example given in a previous thread, and did not consider just using pointers as the data members to avoid having to initialize a large number of RooFit objects at the beginning. Live and learn…

If I may ask another stupid question: when used with a RooAbsReal, is the bindFunction method limited to functions with no more than three arguments? The documentation seems to hint at this, but the syntax involving a ROOT::Math function and a RooArgList argument leaves me hopeful it can handle more. I am trying to fit a Chi2 with pull terms, with an additional parameter in the minimization function for each term.

Thanks for you time.

Hi,

There should be a bindFunction with four arguments as well:

typedef Double_t (*CFUNCD4DDDD)(Double_t,Double_t,Double_t,Double_t) ;
typedef Double_t (*CFUNCD4DDDI)(Double_t,Double_t,Double_t,Int_t) ;
typedef Double_t (*CFUNCD4DDDB)(Double_t,Double_t,Double_t,Bool_t) ;

RooAbsReal* bindFunction(const char* name,CFUNCD4DDDD func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
RooAbsReal* bindFunction(const char* name,CFUNCD4DDDI func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;
RooAbsReal* bindFunction(const char* name,CFUNCD4DDDB func,RooAbsReal& x, RooAbsReal& y, RooAbsReal& z, RooAbsReal& w) ;

Additionally you should be able to use

RooAbsReal* bindFunction(const char* name, const ROOT::Math::IBaseFunctionOneDim& ftor, RooAbsReal& vars) ;
RooAbsPdf* bindPdf(const char* name, const ROOT::Math::IBaseFunctionOneDim& ftor, RooAbsReal& vars) ;
RooAbsReal* bindFunction(const char* name, const ROOT::Math::IBaseFunctionMultiDim& ftor,const RooArgList& vars) ;
RooAbsPdf* bindPdf(const char* name, const ROOT::Math::IBaseFunctionMultiDim& ftor, const RooArgList& vars) ;

where the object you pass is MathCore functor object, e.g. created as

 ROOT::Math::Functor af1(&a, &A::Eval1D,1);

This route has no limit on the number of arguments, but assumes the’re all
of type Double_t.

Wouter