<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def frommatrix(cls, apart, dpart, det_radius, init_matrix, **kwargs):
 """Create a `ParallelHoleCollimatorGeometry` using a matrix. This alternative constructor uses a matrix to rotate and translate the default configuration. It is most useful when the transformation to be applied is already given as a matrix. Parameters apart : 1-dim. `RectPartition` Partition of the parameter interval. dpart : 2-dim. `RectPartition` Partition of the detector parameter set. det_radius : positive float Radius of the circular detector orbit. init_matrix : `array_like`, shape ``(3, 3)`` or ``(3, 4)``, optional Transformation matrix whose left ``(3, 3)`` block is multiplied with the default ``det_pos_init`` and ``det_axes_init`` to determine the new vectors. If present, the fourth column acts as a translation after the initial transformation. The resulting ``det_axes_init`` will be normalized. kwargs : Further keyword arguments passed to the class constructor. Returns ------- geometry : `ParallelHoleCollimatorGeometry` The resulting geometry. """

        # Get transformation and translation parts from `init_matrix`
        init_matrix = np.asarray(init_matrix, dtype=float)
        if init_matrix.shape not in ((3, 3), (3, 4)):
            raise ValueError('`matrix` must have shape (3, 3) or (3, 4), '
                             'got array with shape {}'
                             ''.format(init_matrix.shape))
        trafo_matrix = init_matrix[:, :3]
        translation = init_matrix[:, 3:].squeeze()

        # Transform the default vectors
        default_axis = cls._default_config['axis']
        # Normalized version, just in case
        default_orig_to_det_init = (
            np.array(cls._default_config['det_pos_init'], dtype=float) /
            np.linalg.norm(cls._default_config['det_pos_init']))
        default_det_axes_init = cls._default_config['det_axes_init']
        vecs_to_transform = ((default_orig_to_det_init,) +
                             default_det_axes_init)
        transformed_vecs = transform_system(
            default_axis, None, vecs_to_transform, matrix=trafo_matrix)

        # Use the standard constructor with these vectors
        axis, orig_to_det, det_axis_0, det_axis_1 = transformed_vecs
        if translation.size != 0:
            kwargs['translation'] = translation

        return cls(apart, dpart, det_radius, axis,
                   orig_to_det_init=orig_to_det,
                   det_axes_init=[det_axis_0, det_axis_1],
                   **kwargs)