Using SWIG-wrapped class withing PyROOT

Dear All,

I just learned to use SWIG to wrap my C++ classes and use them within ROOT. My next step is to try to wrap with SWIG classes whose methods receive objects of ROOT classes. This results in runtime errors of the following type when I use those methods in python (I’m passing a TRandom3 object to the constructor of my TimeGenerator class):

TypeError: in method ‘new_TimeGenerator’, argument 1 of type ‘TRandom3 &’

The reason is that SWIG ignores the class TRandom3. If I add TRandom3 to my SWIG module I would duplicate the definition used in the ROOT module (and anyway this gives an error at the moment…).

Is there any working solution or example to this problem?

Thanks,

Luca

Hi Luca,

Out of curiosity … why use SWIG at all? (i.e. what is the advantage in your case) … Simply loading the header file for those classes through cling (and/or generating a dictionary to handle it automatically) would suffice to give access to your classes from python without having to generate any code from SWIG.

Cheers,
Philippe.

Hi Philippe,

SWING seemed to me to be the most recommended tool to wrap C++, I never used cling. Do you have any example of user-defined classes that use ROOT objects wrapped with cling and used in PyRoot?

Cheers,

 Luca

Hi Luca,

In my humble (biased) opinion, Cling is a much superior and much more flexible solution than SWIG.

To use in python (without generating code) [via PyROOT]

import ROOT
ROOT.gSystem.Load(libraryname); # or any other means to load the library into the process
# Might have to manipulate the include path
ROOT.gInterpreter.Declare('#include "name_of_library_header.h" ');
# All symbols declared in name_of_library_header.h (and nested include) are now available via PyROOT.

Cheers,
Philippe.

Hi,

the main strikes against SWIG are that it can’t parse the ROOT header files (for us, full stop right there …), it is clunky when working with namespaces and global variables (common in ROOT), and it is slow when using multiple overloads (also common in ROOT) and things like std::vector.

More practically, centrally provided code from experiments already provide dictionaries for their classes for I/O and cling interactive purposes. Redoing things in SWIG would be an increased maintenance cost (and run-time memory, etc.).

All that said, if you persist, both PyROOT and SWIG speak CObject, and you can use that to convert types of the one to types of the other. (You’ll still need to duplicate all types, including ROOT types, that you want to cross between the two interfaces.)

Cheers,
Wim

Hi Philippe,

[quote=“pcanal”]Hi Luca,

In my humble (biased) opinion, Cling is a much superior and much more flexible solution than SWIG.

To use in python (without generating code) [via PyROOT]

import ROOT
ROOT.gSystem.Load(libraryname); # or any other means to load the library into the process
# Might have to manipulate the include path
ROOT.gInterpreter.Declare('#include "name_of_library_header.h" ');
# All symbols declared in name_of_library_header.h (and nested include) are now available via PyROOT.

Cheers,
Philippe.[/quote]

I’d like to use the compiled classes in both C++ applications and in python, possibly also without dependencies on ROOT, for applications that don’t explicitly need it.

What is the way you recommend to declare then in a separate module and then use it as:

from mymodule import *
from ROOT import TH1, TCanvas, etc.

then use in python both ROOT and mymodule classes?

Cheers,

Luca

Is that a current need, or a future wish? One way or another, ROOT comes with a ROOT dependency.

Use the cppyy module in your ‘mymodule’, and declare an all for the classes loaded from cppyy (ROOT). There’s a GSoC project started to remove most of the ROOT dependencies (the cling dependency remains). The duplicate this in SWIG or whatever you like.

Ciao,
Wim