# Buggy code
def generate_bias_field(
    data: TypeData,
    order: int,
    coefficients: TypeData,
) -> np.ndarray:
    # Create the bias field map using a linear combination of polynomial
    # functions and the coefficients previously sampled
    shape = np.array(data.shape[1:])  # first axis is channels
    half_shape = shape / 2

    ranges = [np.arange(-n, n) for n in half_shape]

    bias_field = np.zeros(shape)
    x_mesh, y_mesh, z_mesh = np.asarray(np.meshgrid(*ranges))

    x_mesh /= x_mesh.max()
    y_mesh /= y_mesh.max()
    z_mesh /= z_mesh.max()

    i = 0
    for x_order in range(order + 1):
        for y_order in range(order + 1 - x_order):
            for z_order in range(order + 1 - (x_order + y_order)):
                coefficient = coefficients[i]
                new_map = (
                    coefficient * x_mesh**x_order * y_mesh**y_order * z_mesh**z_order
                )
                bias_field += np.transpose(new_map, (1, 0, 2))  # why?
                i += 1
    bias_field = np.exp(bias_field).astype(np.float32)
    return bias_field


# Traceback (FloatingPointError)
---------------------------------------------------------------------------
FloatingPointError                        Traceback (most recent call last)
<ipython-input-3-fb6790e7e65a> in <module>
----> 1 tio.RandomBiasField()(torch.rand(1, 2, 3, 4))

~/git/torchio/torchio/transforms/augmentation/random_transform.py in __call__(self, sample)
32     def __call__(self, sample: Subject):
33         self.check_seed()
---> 34         return super().__call__(sample)
35
36     def parse_degrees(

~/git/torchio/torchio/transforms/transform.py in __call__(self, data)
93
94         with np.errstate(all='raise'):
---> 95             transformed = self.apply_transform(sample)
96
97         for image in transformed.get_images(intensity_only=False):

~/git/torchio/torchio/transforms/augmentation/intensity/random_bias_field.py in apply_transform(self, sample)
56             random_parameters_images_dict[image_name] = random_parameters_dict
57
---> 58             bias_field = self.generate_bias_field(
59                 image_dict[DATA], self.order, coefficients)
60             image_dict[DATA] = image_dict[DATA] * torch.from_numpy(bias_field)

~/git/torchio/torchio/transforms/augmentation/intensity/random_bias_field.py in generate_bias_field(data, order, coefficients)
93         x_mesh, y_mesh, z_mesh = np.asarray(np.meshgrid(*ranges))
94
---> 95         x_mesh /= x_mesh.max()
96         y_mesh /= y_mesh.max()
97         z_mesh /= z_mesh.max()

FloatingPointError: divide by zero encountered in true_divide

# Fixed code
def generate_bias_field(
    data: TypeData,
    order: int,
    coefficients: TypeData,
) -> np.ndarray:
    # Create the bias field map using a linear combination of polynomial
    # functions and the coefficients previously sampled
    shape = np.array(data.shape[1:])  # first axis is channels
    half_shape = shape.astype(float) / 2

    ranges = [np.arange(-n, n) + 0.5 for n in half_shape]

    bias_field = np.zeros(shape)
    x_mesh, y_mesh, z_mesh = np.asarray(np.meshgrid(*ranges))

    x_mesh /= x_mesh.max()
    y_mesh /= y_mesh.max()
    z_mesh /= z_mesh.max()

    i = 0
    for x_order in range(order + 1):
        for y_order in range(order + 1 - x_order):
            for z_order in range(order + 1 - (x_order + y_order)):
                coefficient = coefficients[i]
                new_map = (
                    coefficient * x_mesh**x_order * y_mesh**y_order * z_mesh**z_order
                )
                bias_field += np.transpose(new_map, (1, 0, 2))  # why?
                i += 1
    bias_field = np.exp(bias_field).astype(np.float32)
    return bias_field