Combining RooDatasets using std::map in PyROOT

Now it works! Thanks!

Karol

Also works here, great. Thanks to both of you for the code. :slight_smile:

Hi,

I also tried:

>>> import ROOT
>>> 
>>> mp1=ROOT.std.map("int, int")()
>>> mp1.insert( ROOT.std.pair("int, int")(4,8) )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: none of the 3 overloaded methods succeeded. Full details:
  pair<_Rb_tree_iterator<pair<const int,int> >,bool> map<int,int>::insert(const pair<const int,int>& __x) =>
    could not convert argument 1
  void map<int,int>::insert(initializer_list<pair<const int,int> > __list) =>
    could not convert argument 1
  _Rb_tree_iterator<pair<const int,int> > map<int,int>::insert(_Rb_tree_const_iterator<pair<const int,int> > __position, const pair<const int,int>& __x) =>
    takes at least 2 arguments (1 given)
>>> 
>>> 

Which did not work, but:

>>> import ROOT
>>> 
>>> 
>>> mp1=ROOT.std.map("const int, const int")()
>>> mp1.insert( ROOT.std.pair("const int, const int")(4,8) )
<ROOT.pair<_Rb_tree_iterator<pair<const int,const int> >,bool> object at 0x7809640>
>>> 
>>> 

works. As was already said, we should not have to use const. Therefore this is likely a bug, which just costed me an hour. Hopefully It will someday be fixed. I am using the latest available ROOT version from CVMFS:

root 6.06.06-x86_64-slc6-gcc49-opt

Cheers.

Chiming in to say that we still need const in ROOT6.16/00. Thanks all for the detailed instructions!

Hello,

With the new PyROOT (likely ROOT 6.22), these problems will hopefully be gone. In the mean time, if somebody wants to test, adding the datasets explicitly could work:
https://root.cern.ch/doc/master/classRooAbsData.html#a900e7778e6b09912764747a94723ebb7

It requires to give the correct category label, and from python it’s dangerous because both C++ and python might think that they own the object, but I can imagine that this works:

dataobjects = []
cat1Data = ROOT.RooDataSet(...)
[...]
dataobjects.append(cat1Data) # this is necessary so that python doesn't delete the dataset
dataset.addOwnedComponent("cat1", cat1Data)
dataset.addOwnedComponent("cat2", cat2Data)
[...]

I confirm this issue does not happen anymore in experimental PyROOT.

Hi,
I tried your example in LCG_101/ROOT/6.24.06/x86_64-centos7-gcc11-opt and can’t make it work. The test script is attached.
test_dd.py (940 Bytes)
Any thing wrong in the script? Thanks.

I think this one is for @jonas or @moneta ?

Hi @Dongliang, sorry for the late reply!

With ROOT 6.26 that will be released in the next days, there will be many new Pythonizations for RooFit! On of them is that you can just pass a Python dictionary to these functions that take a std::map like RooFit::Import:

    comData = RooDataSet('comData','comb data', obs, RooFit.Index(c),
       RooFit.Import({"s1" : data1, "s2" : data2, "s3" : data3})
    )

Before ROOT 6.26, e.g. with 6.24, you can either follow the recommendation by @StephanH, or you just take the pythonization code for RooFit::Import() from 6.26 like I demonstrate in this updated script:
test_dd_jonasedit.py (4.4 KB)

I hope that this helps!

Cheers,
Jonas

Hi Jonas, thanks a lot for taking care of this. I’m currently using the std.map workaround discussed above, which works fine in 6.24.

Ok, thanks for letting me know! I will mark the std::map workaround as the solution for this thread then and close it, so this zombie doesn’t get resurrected over and over :slight_smile: Feel free to open a new thread if needed!