Home | News | Documentation | Download

Namespace with pyRoot and RDF

Dear experts,

I did not prepared a reproducer yet, but maybe this problem could be solved without.
I build a library of functions in C++ that I then load in pyROOT.
For example:


In order to acces the functions for example

.Define("MC_px",         "getMC_px(Particle)")

I need first somehow to pre-load one of the function like this

_func  = ROOT.getMC_px

First question, why do I need to do so in order to access all other functions in the library?

Second question, I am now defining namespaces to be a bit more organised with the quickly developing library, but I have found a way to to the same as abose to pre-load a function within a namespace. I tried a bunch of things, also including in the LinkDef

#pragma link C++ function MCParticle::getMC_px;

but no matter what, I can’t call

_func  = ROOT.getMC_px

as I could do when there is no namespace.

Second question: is it possible to pre-load with namespace?

If some more detailed reproducer are needed, I could work on that later next week, but I thought that might be a known problem already.


_ROOT Version:root-6.22.06

Does ROOT.yournamespace.getMC_px also not work?

I think we need @etejedor .

That is one of the first thing I tried, and no, the error is:

Traceback (most recent call last):
  File "testarea/analysis_test.py", line 12, in <module>
    _fcc  = ROOT.MCParticle.getMC_px
  File "/cvmfs/sw.hsf.org/spackages/linux-centos7-broadwell/gcc-8.3.0/root-6.22.06-p6lo5zfnto46nnfzp2hj2clsuyffmjkx/lib/ROOT/_facade.py", line 163, in _fallback_getattr
    raise AttributeError("Failed to get attribute {} from ROOT".format(name))
AttributeError: Failed to get attribute MCParticle from ROOT


Besides loading the library, I believe the issue is that you also need to JIT the header/s first:

or generate the library with dictionaries (which perhaps you already do since you mention LinkDef.h?)

Thanks @etejedor.
Indeed I generate the library with dictionaries, see CMakeLists:

Then I don’t see a reason why it shouldn’t work. What happens if you try to load the library from the ROOT prompt in C++? Can you call into it in that case?

It does not work either.

root [0] gSystem->Load("libFCCAnalyses")
(int) 0
root [1] MCParticle::get_px
ROOT_prompt_1:1:1: error: 'MCParticle' is not a class, namespace, or enumeration
ROOT_prompt_1:1:1: note: 'MCParticle' declared here

But if first I try with one function in an other class that is not in a namepace (getRP_px) I can get the one in the namespace properly:

root [2] getRP_px
(ROOT::VecOps::RVec<float> (*)(ROOT::VecOps::RVec<edm4hep::ReconstructedParticleData>)) Function @0x7f1c322bb078
  at /afs/cern.ch/user/h/helsens/FCCsoft/FCCAnalyses/install/include/FCCAnalyses/ReconstructedParticle.h:60:
ROOT::VecOps::RVec<float> getRP_px(ROOT::VecOps::RVec<edm4hep::ReconstructedParticleData> in)

root [3] MCParticle::get_px
(ROOT::VecOps::RVec<float> (*)(ROOT::VecOps::RVec<edm4hep::MCParticleData>)) Function @0x7f1c322b4660
  at /afs/cern.ch/user/h/helsens/FCCsoft/FCCAnalyses/install/include/FCCAnalyses/MCParticle.h:114:
ROOT::VecOps::RVec<float> get_px(ROOT::VecOps::RVec<edm4hep::MCParticleData> in)

@Axel any thoughts on why this could be happening?

Typically don’t you also need to #include the header via the interpreter? E.g. with gInterpreter->ProcessLine("#include \"...\"").

with explicitly including the header to the interpreter I can now see the function in the namespace directly. Not sure why it is different though

root [0] gSystem->Load("libFCCAnalyses")
(int) 0
root [1] gInterpreter->ProcessLine("#include \"MCParticle.h\"")
(long) 0
root [2] MCParticle::get_px
(ROOT::VecOps::RVec<float> (*)(ROOT::VecOps::RVec<edm4hep::MCParticleData>)) Function @0x7f560afae650
  at /afs/cern.ch/user/h/helsens/FCCsoft/FCCAnalyses/install/include/FCCAnalyses/MCParticle.h:116:
ROOT::VecOps::RVec<float> get_px(ROOT::VecOps::RVec<edm4hep::MCParticleData> in)

all good or are there remaining issues when going back to Python?

I’m not sure I understand the question :sweat_smile: At a high level: the interpreter does its best to locate symbols when you first mention them – including the header helps because it tells the interprete explicitly that those symbols exist. I might be missing the mark and/or we might need a cling expert to answer properly.


Yes, @eguiraud , in python it runs as well like this, sorry for not mentioning it earlier:

ROOT.gInterpreter.ProcessLine("#include \"MCParticle.h\"")

well, it’s not a question just a remark that I would have naively expected the above to work without the include as I am building a dictionary. But I have so little experience with cling that I can’t comment :slight_smile:

I see. @Axel or @pcanal might be able to clarify when and why the #include is necessary even if you have dictionaries, I’m out of my depth :slight_smile:

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