Looks like I would need a cast here

Dear PyROOT-experts,

I am currently working with an algorithm based up on the ROOT framework. It’s implemented in C++ and involves different classes. I want to use this algorithm through PyROOT, but running into following problem:

There is the class TGNGUnit, which holds a member fPrototype beeing a pointer to TGNGDataElement.
TGNGDataElement is an abstract class. TGNGVectorData inherits from (and implements) TGNGVectorData and has the member fVector of type TVectorD. I need to acces to fVector, but what happen is the following…

[code]In [11]: unit
Out[11]: <ROOT.TGNGUnit object (“TGNGUnit”) at 0x7fa0c6e0a690>

In [12]: prototype = unit.fPrototype

In [13]: prototype
Out[13]: <ROOT.TGNGDataElement* object (“TGNGVectorData”) at 0x7fa0c6e0a890>

In [14]: prototype.fVector

AttributeError Traceback (most recent call last)
in ()
----> 1 prototype.fVector

AttributeError: ‘TGNGDataElement’ object has no attribute ‘fVector’

In [15]: # but this gives me…

In [16]: prototype.Print()
OBJ: TGNGVectorData TGNGVectorData

In [17]: # and also…

In [18]: prototype.Dump()
==> Dumping object at: 0x00007fa0c6e0a890, name=TGNGVectorData, class=TGNGVectorData

fVector ->7fa0c6e0a8b0 || vector data
fVector.fNrows 128 number of rows
fVector.fRowLwb 0 lower bound of the row index
fVector.*fElements 53.7456 [fNrows] elements themselves
fVector.fDataStack[5] 0 ! data container
fVector.fIsOwner true !default kTRUE, when Use array kFALSE
fVector.fUniqueID 0 object unique identifier
fVector.fBits 0x03000000 bit field status word
*fPayload ->0 || some space to put a user defined payload (owned)
fUniqueID 0 object unique identifier
fBits 0x03000000 bit field status word
fFillColor 19 fill area color
fFillStyle 1001 fill area style[/code]

How could I acces fVector?
My machine is a MacBook Pro OS X 10.10.2; ROOT: 6.03/2; Python 2.7 .
I am thankful for any suggestions!

Kind Regards,

Marc

Marc,

in order to use a class, a dictionary needs to be available. Once available, down-casting will be automatic. Since this is ROOT6, gIntepreter.Declare(’#include “the_header_with_the_class_definition.h”’) should do the trick.

Cheers,
Wim

Hi Wim,

thank you for you reply!
Unfortunately this does not work…

Any further suggestions?
Are there other further readings concerning the use of own C++/ROOT material with PyROOT than the
user guide?

KR,

Marc

Hi,

sorry, but that is how it is designed to work. Iow., you either have found a bug, or something is missing from your description. I mean, you can of course cast by combining BindObject() and GetAddress(), assuming you either know the offset or the offset is zero, but that will still not be used if you don’t have a dictionary for the derived object.

Can you setup a reproducer?

Cheers,
Wim

Hi,

I am pretty shure, that I make a mistake in using own classes via PyROOT…

I am doing the following:

On ROOT-side I have a macro (“tgng-load.C”) loading all TGNG-Files with:
gROOT->ProcessLine(".L …tgng-files.cpp")

I call this macro in a Pythonscript via gROOT.ProcessLine(".x tgng-load.C")
further I load the Libraries with gSystem.Load(TGNG…_cpp)
and do the gInterpreter.Declare(…) for all TGNG header files.
After that I do “from ROOT import tgng_files”.

There is no error message occuring.
Is this the right way to use my own classes?

… I am pretty new to this stuff so…
what is a reproducer? (SORRY!!)
I will try to seet one up.

Sorry!

Marc

Marc,

I’d generate the dictionaries on the fly, using genreflex: https://root.cern.ch/drupal/content/generating-reflex-dictionaries. After processing that once, it will be faster to start up and you can also make use of the class auto-loader.

Still, the process that you describe should work. Do all relevant classes have at least 1 virtual method?

The minimal code that allows me to reproduce the problem.

Cheers,
Wim