How to include my function in RooFit?

Hi there,

I need to define a line shape function for the non-resonant background in Roofit in order to get the Breit-Wigner signal. The function is defined as a class in C++ as follows:

// NonResonantFunction.h
class NonResonantFunction : public RooAbsPdf {
public:
    NonResonantFunction() {}
    NonResonantFunction(const char *name, const char *title,
			RooAbsReal& _x, RooAbsReal& _x0, RooAbsReal& _a, RooAbsReal& _c, RooAbsReal& _d);
    NonResonantFunction(const NonResonantFunction& other, const char* name=0);
    virtual TObject* clone(const char* newname) const { return new NonResonantFunction(*this,newname); }
    inline virtual ~NonResonantFunction() {}

protected:
  RooRealProxy x;
  RooRealProxy x0;
  RooRealProxy a;
  RooRealProxy c;
  RooRealProxy d;

  Double_t evaluate() const;

private:
  ClassDef(NonResonantFunction,1) // Your custom function
};

l

Finally the function is explicitly defined in the the main code as follows:

// BreitNonModel3.C
  ClassImp(NonResonantFunction)
  NonResonantFunction::NonResonantFunction(const char *name, const char *title,
		       RooAbsReal& _x, RooAbsReal& _x0, RooAbsReal& _a, RooAbsReal& _c, RooAbsReal& _d) :
    RooAbsPdf(name,title),
    x("x","x",this,_x),
    x0("x0","x0",this,_x0),
    a("a","a",this,_a),
    c("c","c",this,_c),
    d("s","d",this,_d)
  {
  }
  Double_t NonResonantFunction::evaluate() const
  {
    Double_t arg = (x-x0) ;
    return a*pow(arg,c)*TMath::Exp(d*x) ;
  }

using namespace RooFit; 

void BreitNonModel3(int nsig = 400,    // number of signal events 
                    int nbkg = 300 )  // number of background events
{
   RooWorkspace w("w"); 
   w.factory("NonResonantFunction:bkg_pdf(x[0.,5.], x0[0.9,1.077], a[10.,150000.], c[1.200,1.350], d[-6.0,-1.0])");
   w.factory("BreitWigner:sig_pdf(x, mass[1.115,1.125], sigma[0.002,0.130])");
   w.factory("SUM:model(nsig[0,10000]*sig_pdf, nbkg[0,10000]*bkg_pdf)");  // for extended model

   RooAbsPdf * pdf = w.pdf("model");
   RooRealVar * x = w.var("x");  // the observable

However, I am getting a lot of error messages from ROOT Cling:

root BreitNonModel3.C+ 
...
/usr/bin/ld: /home/lgemedia/analyz/analyzer2018/roofit/BreitNonModel3_C_ACLiC_dict.o:(.rodata._ZTV19NonResonantFunction[_ZTV19NonResonantFunction]+0x670): undefined reference to `non-virtual thunk to NonResonantFunction::Streamer(TBuffer&)'
/usr/bin/ld: /home/lgemedia/analyz/analyzer2018/roofit/BreitNonModel3_C_ACLiC_dict.o: in function `.LC57':
BreitNonModel3_C_ACLiC_dict.cxx:(.rodata.cst8+0x30): undefined reference to `vtable for RooStats::ModelConfig'
collect2: error: ld returned 1 exit status
root [1] .q

What am I missing here?
Would anyone advise how to implement my function correctly in Roofit?

Thanks,
Luiz
NonResonantFunction.h (688 Bytes)
BreitNonModel3.C (4.9 KB)

Hi @OtaviusDecius,

thank you for your question, I will tag @jonas to give you some hints.

Cheers,
Marta

I am including the data file.
myhistolambda.root (11.2 KB)

The error is pretty clear, no? :slightly_smiling_face: You are missing the definition of the copy constructor. So you have to add it to your macro:

NonResonantFunction::NonResonantFunction(const NonResonantFunction& other, const char* name) :
  RooAbsPdf(other,name),
  x("x",this,other.x),
  x0("x0",this,other.x0),
  a("a",this,other.a),
  c("c",this,other.c),
  d("s",this,other.d)
{
}

I hope this helps!

Cheers,
Jonas

Hi Jonas,

It worked.

Thanks a lot.
Luiz