Hi!
Some functions like TF1.GetRange need call-by-reference to return more than one value at a time.
Is there a way that this can be done via PyROOT, considering that Python does only support call-by-value AFAIK?
Cheers,
Michael
Hi!
Some functions like TF1.GetRange need call-by-reference to return more than one value at a time.
Is there a way that this can be done via PyROOT, considering that Python does only support call-by-value AFAIK?
Cheers,
Michael
Michael,
[congrats to first post in the new âPyROOTâ section ]
limited support for pass by reference of builtin types made it into 5.02. It is better for the upcoming release (some fixes for overloads float& vs double&), but TF1::GetRange() should be ok.
There is, however, a very important caveat: since in python there is no such thing as âpass by referenceâ there are some aliasing pbs: python will recycle numeric objects if they represent the same value. I.e., if you pass a number by reference, and an equivalent number already exists (locally, that is), both objects will change. Example:
[code]>>> x, y = 0.1, 0.1
gRandom.Rannor( x, y )
print x, y
-1.79938935851 -1.79938935851
x, y = 0.1, 0.2
gRandom.Rannor( x, y )
1.20281322884 0.915717379223
[/code]
Also, always make sure that the type matches (e.g. x = 123 canât be passed through a double&).
HTH,
Wim
Hi all
Is there a way to use the method TGraph::GetPoint((Int_t i, Double_t& x, Double_t& y) and similar methods with the & with PyRoot?
Cheers Angi
Hi,
yes, but only up to an extent, b/c the python objects need to carry the exact same underlying C-type as is passed by reference. There are two such objects, python int and float (i.e. C long and double) that conform. However, to prevent confusion on the python side where interactively number objects tend to get recycled (i.e. an object representing a number can be used in multiple places, so if the C++ reference changes it, it would change in those other python calculations as well, which canât have been the intention), two types were added that derive from the python numeric types. That way, they canât get recycled.
So, the types are ROOT.Long and ROOT.Double which pass through long& and double&. Something like:d1, d2 = ROOT.Long(0), ROOT.Long(0)
myGraph.GetPoint( 41, d1, d2 )
should do the trick.
Since these types derive from python int and float, they can drop in any place where those are used, or you can simply use int() or float() to convert to the âbuiltinâ types.
Cheers,
Wim
Hi thanks for your suggestion, but this does not work unfortunately for me. I get the following error:
d2 = ROOT.Long(0)
Traceback (most recent call last):
File ââ, line 1, in
AttributeError: type object âROOTâ has no attribute âLongâ
Do you have any idea what I am missing?
Cheers Angi
Hi,
which version of ROOT are you using, or is it that you did âfrom ROOT import *â rather than âimport ROOTâ?
Cheers,
Wim
Hi I am using 5.18/00
And yes I use from ROOT import *, what is wrong with that?
Cheers Angi
Angi,
there are two âROOTâ namespaces. One is the PyROOT python module, where Long lives (so ROOT.Long works), the other is the ROOT C++ namespace, which does not contain Long.
Thus, if you use âimport ROOTâ, the type to use is âROOT.Longâ but if you use âfrom ROOT import *â then the type to use is just âLongâ.
HTH,
Wim