How to modify roofit headers


I was trying to suggest to change const TTree* RooAbsData::tree() const to do two things a) return a non const TTree (e.g. to use Draw) b) also return a non-nullptr in case of a RooVectorDataStore

/// give access to internal data TTree (if it exists)
/// RooDataSet keeps ownership, RooFit is responsible for deleting.

const TTree* RooAbsData::tree() const
  if (dynamic_cast<const RooTreeDataStore*>(_dstore)) {
    return _dstore->tree();
  } else {
    coutW(InputArguments) << "RooAbsData::tree(" << GetName() << ") WARNING: is not of StorageType::Tree. "
             << "Use export_tree() instead or convert to tree storage." << endl ;
    return (TTree*)nullptr;

/// clone internal data TTree or create it from vector-based storage
/// transfers ownership, user is responsible for deleting.

TTree* RooAbsData::export_tree() const
  if (dynamic_cast<const RooTreeDataStore*>(_dstore)) {
    return const_cast<TTree*>(_dstore->tree())->CloneTree();
  } else {
    RooTreeDataStore buffer(GetName(), GetTitle(), *get(), *_dstore);
    TTree* t = &(buffer.tree());
    return (TTree*)(t->CloneTree());

Adding this to the root source code (v6-07/07) and building, builds root successfully. (I also increased the ClassDef(RooAbsData,5))

As a test case for compiled code I took one of the roofit tutorials

#include <RooDataSet.h>
#include <RooRealVar.h>
#include <RooCategory.h>
#include <RooGaussModel.h>
#include <RooBMixDecay.h>
#include <TTree.h>

int main() {
  RooRealVar dt("dt","dt",-20,20) ;
  RooRealVar dm("dm","dm",0.472) ;
  RooRealVar tau("tau","tau",1.547) ;
  RooRealVar w("w","mistag rate",0.1) ;
  RooRealVar dw("dw","delta mistag rate",0.) ;
  RooCategory mixState("mixState","B0/B0bar mixing state") ;
  mixState.defineType("mixed",-1) ;
  mixState.defineType("unmixed",1) ;
  RooCategory tagFlav("tagFlav","Flavour of the tagged B0") ;
  tagFlav.defineType("B0",1) ;
  tagFlav.defineType("B0bar",-1) ;
  RooRealVar bias1("bias1","bias1",0) ;
  RooRealVar sigma1("sigma1","sigma1",0.1) ;
  RooGaussModel gm1("gm1","gauss model 1",dt,bias1,sigma1) ;
  RooBMixDecay bmix("bmix","decay",dt,mixState,tagFlav,tau,dm,w,dw,gm1,RooBMixDecay::DoubleSided) ;
  RooDataSet *data = bmix.generate(RooArgSet(dt,mixState,tagFlav),2000) ;
  TTree* t = data->export_tree();
  printf("got %d entries\n",t->GetEntries());
  return 0;

This works (compiles, links, runs) as expected, the new method is available. But interactively I don’t succeed

[ins] pseyfert@robusta ~/coding/recentroot/6-07-07 > root -l -n
root [0] RooAbsData* a
(RooAbsData *) nullptr
root [1] a->export_tree()
ROOT_prompt_1:1:4: error: no member named 'export_tree' in 'RooAbsData'
~  ^
root [2] RooDataSet* d
(RooDataSet *) nullptr
root [3] d->export_tree()
ROOT_prompt_3:1:4: error: no member named 'export_tree' in 'RooDataSet'
~  ^
root [4] .q

Is there something wrong how I updated the header files? Or possibly a nasty feature of the build process? I had built root 60707 before and only called “cmake --build . --target install” again, and use ccache and ninja. after a successless run, i also called “cmake --build . --target clean” again before rebuilding, but didn’t do a fresh build w/o ccache in an empty build directory (to save disk and time)


I would try to do a fresh build or at least clean all roofitcore and roofit, to be sure all roofit files get re-compiled


okay, so nothing i missed in code manipulation. Thanks for the advice!

I tried with a clean build and target directory, still without success. Eventually I cloned the source directory and built again from the new source, and things work. I guess it must be some untracked and git-ignored files in the source directory which shouldn’t be there.