How can I inherit from scipy.spatial.transform.Rotate and define my own custom __init__ function that uses a class constructor?

Viewed 21

I want to do a wrapper around scipy.spatial.transform.Rotation where the initializer has the same result as Rotation.from_rotvec, but defaults to degrees=true. I dont know how the from_rotvec method works because its written in C/C++. I tried using a __new__ constructor but I couldnt get it to work:

class Rotation(ScipyRotation):
    def __new__(cls, *args, **kwargs):
        kwargs.setdefault("degrees", True)
        print(args, kwargs)
        print(np.asarray(args[0]).shape)
        obj = Rotation.from_rotvec(np.asarray(args[0]), degrees=kwargs["degrees"])
        return obj

    def __init__(self, rotation: npt.ArrayLike, *, degrees: bool = True):
        pass

rotation = Rotation([0, 0, 0], degrees=True)

As for some reason the shape of the input array was changing:

([0, 0, 0],) {'degrees': True}
(3,)
(<MemoryView of 'array' at 0x16c5e137ba0>,) {'normalize': False, 'copy': False, 'degrees': True}
(4,)

Ran 1 test in 0.008s

FAILED (errors=1)

Error
Traceback (most recent call last):
  File "C:\Users\mclea\src\VPP\VPP\rigid_body\components\tests\test_rotation.py", line 9, in test_initializer_uses_rotvec
    rotation = Rotation([0, 0, 0], degrees=True)
  File "C:\Users\mclea\src\VPP\VPP\rigid_body\components\rotation.py", line 21, in __new__
    obj = Rotation.from_rotvec(np.asarray(args[0]), degrees=kwargs["degrees"])
  File "rotation.pyx", line 883, in scipy.spatial.transform.rotation.Rotation.from_rotvec
  File "C:\Users\mclea\src\VPP\VPP\rigid_body\components\rotation.py", line 21, in __new__
    obj = Rotation.from_rotvec(np.asarray(args[0]), degrees=kwargs["degrees"])
  File "rotation.pyx", line 851, in scipy.spatial.transform.rotation.Rotation.from_rotvec
ValueError: Expected `rot_vec` to have shape (3,) or (N, 3), got (4,)

Edit: I just realised why that metaclass doesnt work, but I have no idea how to get it to work otherwise!

0 Answers
Related