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:
ROOT.gSystem.Load("libMyLib")
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.
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
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?
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
MCParticle::get_px
^
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)
Ok,
all good or are there remaining issues when going back to Python?
I’m not sure I understand the question 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.
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