from numbers import Number
from typing import Union

import numpy as np
import nibabel as nib
import torch

from ....data.subject import Subject
from .bounds_transform import BoundsTransform, TypeBounds

Args:
:math:(w_{ini}, w_{fin}, h_{ini}, h_{fin}, d_{ini}, d_{fin})
defining the number of values padded to the edges of each axis.
If the initial shape of the image is
:math:W \times H \times D, the final shape will be
:math:(w_{ini} + W + w_{fin}) \times (h_{ini} + H + h_{fin})
\times (d_{ini} + D + d_{fin}).
If only three values :math:(w, h, d) are provided, then
:math:w_{ini} = w_{fin} = w,
:math:h_{ini} = h_{fin} = h and
:math:d_{ini} = d_{fin} = d.
If only one value :math:n is provided, then
:math:w_{ini} = w_{fin} = h_{ini} = h_{fin} =
d_{ini} = d_{fin} = n.
padding_mode: See possible modes in NumPy docs_. If it is a number,
the mode will be set to 'constant'.
**kwargs: See :class:~torchio.transforms.Transform for additional
keyword arguments.

"""  # noqa: E501

'empty',
'edge',
'wrap',
'constant',
'linear_ramp',
'maximum',
'mean',
'median',
'minimum',
'reflect',
'symmetric',
)

def __init__(
self,
**kwargs
):

@classmethod
message = (
)
raise KeyError(message)

def apply_transform(self, subject: Subject) -> Subject:
low = self.bounds_parameters[::2]
for image in self.get_images(subject):
new_origin = nib.affines.apply_affine(image.affine, -np.array(low))
new_affine = image.affine.copy()
new_affine[:3, 3] = new_origin
kwargs = {'mode': 'constant',