Making maps in pyroot

My question is how to make a map of vectors of strings in pyroot. I am accessing C++ code that produces a std::map<std::string,std::vectorstd::string> .
I’ve tried just using a dictionary of lists but that does not work.

I know there is syntax like ROOT.std.map(“string,whatever”) but I can’t see how to tell it how to make the more complicated object of nested stl thingies.

So the simple question is - how do I make x = std::map<std::string,std::vectorstd::string> in pyroot.

Thanks, Heidi - ok, I’ve been using root for over 20 years but I only get to code on vacations so I’m always rusty.

ROOT Version: 6.16
Platform: mac running Mojave
_Compiler:
gcc -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 11.0.0 (clang-1100.0.20.17)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin


Hi Heidi,

you are looking in the right direction with ROOT.std.map, but for complicated types I would do it on the C++ - side with ROOT.gInterpreter.Declare or ProcessLine.

@etejedor probably knows the pythonic way, but I guess we have to wait for next week when people are coming back from vacation.

Ok, so I made a C++ function that creates a map of vectors of the objects I want. I can ginterpret it to load, make it, I can put stuff in it but then when I try to call a C++ constructor for HistWrapper with it as an argument I get the following

type of error_bands is <class ‘ROOT.map<string,vectorPlotUtils::DefaultCVUniverse** >’>

Traceback:

hw_enu = PlotUtils.HistWrapper(CVUniverse.CVUniverse)(“hw_enu”, “E_{#nu} NEW Method”,nbins, xmin, xmax, error_bands);

TypeError: none of the 7 overloaded methods succeeded. Full details:

PlotUtils::HistWrapperPlotUtils::DefaultCVUniverse::PlotUtils::HistWrapperPlotUtils::DefaultCVUniverse(const char* hist_name, const char* title, int nBins, double xmin, double xmax, map<string,vectorPlotUtils::DefaultCVUniverse** >& bands) =>
problem in C++; program state has been reset

Is it trying to compare a ROOT.map with a map?

       map<string,vector<PlotUtils::DefaultCVUniverse**> > vs

ROOT.map<string,vectorPlotUtils::DefaultCVUniverse** >

(the ** seem to be an artifact of this markup they should be a *)

Sorry I can’t provide a code example right away. But is there a difference between a ROOT.map and a map?

Hi,

I suppose that the ROOT.map is a python object with C++ map attached such that the thing can be handled from the python side. Without a code example, I don’t see what’s going on, but tomorrow, @etejedor should be able to have a look.

here is the syntax to instantiate new std::map templates:

>>> import ROOT
>>> m = ROOT.std.map("int", "string")()
>>> m[1] = "one"
>>> m[2] = "two"
>>> m
<ROOT.map<int,string> object at 0x5578151351a0>
>>> m[1]
'one'

>>> m2 = ROOT.std.map("std::string", "std::vector<int>")()
>>> m2["foo"] = ROOT.std.vector("int")()
>>> m2["foo"].push_back(1)
>>> m2["foo"].push_back(2)
>>> m2["foo"]
<ROOT.vector<int> object at 0x5578152b4a20>
>>> list(m2["foo"])
[1, 2]

>>> m3 = ROOT.std.map("std::string", "std::vector<std::string>")()
>>> m3["foo"] = ROOT.std.vector("std::string")()
>>> m3["foo"].push_back("hello")
>>> m3["foo"].push_back("world")
>>> list(m3["foo"])
['hello', 'world']

hth,
-s