RooSimultaneous RooDataHist in pyroot

Hello,
I am trying to reformulate my earlier question RooSimultaneous template fit with no reference to github, or rootpy attempts:

Taks: I want to do a simultaneous (signals+bg) fit of two(+) histograms, while keeping some parameters connected (same sigma’s, constant shift between mean’s… ).
Search result: I can find rf501_simultaneouspdf.py that works nice, but not with histograms.

Attempt: I was able to do the above histogram’s task in C++ replacing some lines of rf501_simultaneouspdf.C

//Import histograms into RooDataHist
   RooArgSet obs( x);

  map<string, RooDataHist*> datasets;
  datasets["physics"] = new RooDataHist("dataA", "dataA", RooArgList(*obs.find("x")), hh1 );
  datasets["control"] = new RooDataHist("dataB", "dataB", RooArgList(*obs.find("x")), hh2 );
  
  RooDataHist combData("combData", "combData", obs, sample, datasets);
  combData.Print("v");

Question: My curiosity is - is there possible to do the Task in pyroot? I went through number of examples, but everytime my attempts crashed …

NotImplementedError: pair<_Rb_tree_iterator<pair<const string,TH1*> >,bool> map<string,TH1*>::insert<std::pair<std::__cxx11::basic_string<char>, TH1 *> >(pair<string,TH1*>&& __x) =>
    could not convert argument 1 (this method can not (yet) be called)

… when the code has called an .insert()

m1 = ROOT.std.map('string, TH1*')()
m1.insert(ROOT.std.pair('string, TH1*')('cat1', histo1))
...

I tried with root 6.16 and 6.18, default python3.6.8 from ubuntu 1804. ( I have not a deep understanding of the idea behind std.map either. I have a feeling of a dict in C++.)
Thank you.
Jaromir

Maybe @StephanH can help here.

I invite @etejedor, the pyroot expert. It looks like we are seeing a python-to-c++ problem rather than a pure RooFit problem.
The problem is that the C++ side expects a
std::map< std::string, RooDataHist*> or
std::map< std::string, TH1*>,
but it’s tricky to create this from the pyroot side.

I just tried this:

>>> import ROOT
>>> map1 = ROOT.std.map("std::string, TH1*")()
>>> hist = ROOT.TH1D("test", "test", 10, 0, 10)
>>> map1.insert(("test", hist))
<ROOT.pair<_Rb_tree_iterator<pair<const string,TH1*> >,bool> object at 0x556a9a4e2540>
>>> map1.at("test")
<ROOT.TH1D object ("test") at 0x556a991a3830>
>>> map1["test"]
<ROOT.TH1D object ("test") at 0x556a991a3830>
# Alternative:
>>> map1.test2 = hist
>>> map1.test2
<ROOT.TH1D object ("test") at 0x556a991a3830>

We will let @etejedor comment if that’s the “best” way to do it, but this seems to work.

1 Like

Yes that looks good to me!

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.