How to handle multiple geometries simultaneously

Hi all,

on a previous post ([url]TGeoManager handling multiple geometries at the same time Andrea told us how to handle multiple geometries at the same time, say :

TGeoManager *oldgeom = gGeoManager; // backup in some way
gGeoManager = 0; // Important for not deleting the old geometry
TGeoManager *newgeom = new TGeoManager(...); 

it runs well in C++, but it seems to fail if I try to do the same in python :

fredj @ /home/fredj>python
Python 2.7.2 (default, Apr  6 2012, 09:30:25) 
[GCC 4.5.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ROOT import TGeoManager, gGeoManager
>>> oldgeom = TGeoManager("geom1", "1st geom")
Info in <TGeoManager::TGeoManager>: Geometry geom1, 1st geom created
>>> gGeoManager = 0
>>> newgeom = TGeoManager("geom2", "2nd geom")
TGeoManager::Init:0: RuntimeWarning: Deleting previous geometry: geom1/1st geom
        !!!!!!!!!!!!!!!!! ooops !!!!!!!!!!!!!!!!!
Info in <TGeoManager::TGeoManager>: Geometry geom2, 2nd geom created
>>> oldgeom.GetName()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'PyROOT_NoneType' object has no attribute 'GetName'
        !!!!!!!!!!!!!!!!! ooops again !!!!!!!!!!!!!!!!!

I also tried “gGeoManager = None” but it leads to the same result.
Has anybody a workaround ?

regards,

Fred

PS : I use to work with root_v5.30.02 but I got the same after trying v5.34.01

Hi,

the assignment as done that way in Python, is to a new local reference, not to the global gGeoManager in ROOT (and would not work for general Python modules either). Handling of builtin types will work when set on the module ROOT, but even that won’t work for global objects (this is fixed in cppyy, though). As-is, simply do:gROOT.ProcessLine("gGeoManager = 0;")
Cheers,
Wim

thanks Wim for this quick answer,
I would’nt say that its content is clear for me, but anway the solution does the job !
best regards
Fred

Fred,

then, as an elaboration … If I have a python module, like so:$ cat amod.py val = 1
Then with use in a python session, you can only change “val” with visibility in the module, by changing it on the module:[code]>>> import amod

print amod.val
1

from amod import val
print val
1

val = 2
print val
2

print amod.val
1

amod.val = 2
print amod.val
2[/code]
Same with ROOT, except that the above only works as expected for global variables that are of builtin type, such as ints, floats, etc. It does not work for pointers to objects (but it does in cppyy, successor to-be of PyROOT):[code]>>> import ROOT

print ROOT.gDebug
0

from ROOT import gDebug
print gDebug
0

gDebug = 10
ROOT.gROOT.ProcessLine(“cout << gDebug << endl;”)
0

ROOT.gDebug = 10
ROOT.gROOT.ProcessLine(“cout << gDebug << endl;”)
10

[/code]
Hope that clears things up. :slight_smile:

Cheers,
Wim

ok, I already noticed that kind of thing in “pure” python, but I never went further in my comprehension of the inner mechanisms of (Py)ROOT.
I must apologize that as the time goes on I use to rest on the magical side of ROOT, aka everything I try works easilly just as I expected !

thanks a lot for this clear explanation,

regards

Fred