I think, because of the way the Python bindings for ROOT are created, that __mul__
can only be linked to one of the overloaded operator*
functions in TVector2
, namely, the first one that is called in the script.
Therefore, both of these scripts fail on Line 3 with could not convert argument 2
:
import ROOT
v1 = ROOT.TVector2(1, 1) * ROOT.TVector2(2, 2) # this works
v2 = ROOT.TVector2(1, 1) * 5 # this doesn't
import ROOT
v1 = ROOT.TVector2(1, 1) * 5 # this works
v2 = ROOT.TVector2(1, 1) * ROOT.TVector2(2, 2) # this doesn't
Is there an obvious way to force the TVector2
to use one version of operator*
vs. another, or do I have to use TVector3
with a zero for the z component, or implement either the scalar multiplication or dot product manually myself, whichever comes second?
Note: This isn’t a problem for TVector3
because the set of methods are completely different, for some reason: TVector3::Mag()
is TVector2::Mod()
and TVector3
defines a TVector3::Dot(TVector3)
, while TVector2
overloads the *
for both scalar multiplication and the dot product. The Pythonic way of overloading __mul__
is to “duck type”: assume the passed argument is the right type, try something, then handle the exception:
class TVector2(object)
...
def __mul__(self, second):
try:
return self.X()*second.X() + self.Y()*second.Y()
except:
return TVector2(self.X()*second, self.Y()*second)
(and similar code for __rmul__
)
… but I guess this was difficult to do with compiled code or with automated Python bindings.