<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def det_axes(self, angles):
 """Return the detector axes tuple at ``angles``. Parameters angles : `array-like` or sequence Euler angles in radians describing the rotation of the detector. The length of the provided argument (along the first axis in case of an array) must be equal to the number of Euler angles in this geometry. Returns ------- axes : `numpy.ndarray` Unit vector(s) along which the detector is aligned. If ``angles`` is a single pair (or triplet) of Euler angles, the returned array has shape ``(2, 3)``, otherwise ``broadcast(*angles).shape + (2, 3)``. Notes ----- To get an array that enumerates the detector axes in the first dimension, move the second-to-last axis to the first position: axes = det_axes(angle) axes_enumeration = np.moveaxis(deriv, -2, 0) Examples -------- Calling the method with a single set of angles produces a ``(2, 3)`` array of vertically stacked vectors: array([[ 1., 0., 0.], [ 0., 0., 1.]]) True The method is vectorized, i.e., it can be called with multiple angle parameters at once. Each of the angle arrays can have different shapes and will be broadcast against each other to determine the final shape: True (4, 5, 2, 3) (4, 5, 2, 3) """

        # Transpose to take dot along axis 1
        axes = self.rotation_matrix(angles).dot(self.det_axes_init.T)
        # `axes` has shape (a, 3, 2), need to roll the last dimensions
        # to the second to last place
        return np.rollaxis(axes, -1, -2)