synthbold.transforms

Single transformation blocks for the data synthesis pipeline.

class synthbold.transforms.BiasField(lowres_shape: tuple[int, int, int], amplitude_range: tuple[float, float] = (0.0, 1.0), device: str = 'cpu', seed: int | None = None)

Bases: Transform

Generates a smooth multiplicative bias field and applies it to a 3D (X, Y, Z) or 4D (B, X, Y, Z) tensor.

This transform creates a random low-resolution field, upsamples it to the target shape, applies an exponential to ensure positivity, and multiplies it with the input tensor. For 4D tensors, a randomly generated bias field is created for each 3D volume within the batch.

Parameters:
  • lowres_shape – The matrix size of the low-resolution noise map to generate a smooth bias field.

  • amplitude_range – Minimum and maximum scaling factor for bias field variation.

  • device – Target compute device, e.g. ‘cuda’ or ‘cpu’.

  • seed – Random seed for reproducibility.

Raises:

ValueError – If any lowres_shape dimension is less than 1.

static apply(data: Tensor, bias: Tensor) Tensor

Applies the smooth bias field to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • bias – Bias field tensor of same shape.

Returns:

Biased tensor of same shape.

classmethod from_config(config: Config) Self

Constructs BiasField instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Compute the bias field of shape (B, X, Y, Z).

class synthbold.transforms.CaliberDeformation(sigma: float = 20.0, alpha: float = 4.0, device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies a random caliber transform to 3D or 4D tensors.

This transformation is designed to modify roughly cylindrical structures (e.g. vessels) to have smooth, spatially varying diameters. It works by generating a smoothed random radius field and applying a local distance-based masking (“pinch”) to the input volume.

Parameters:
  • sigma – Standard deviation of Gaussian field to generate smooth random Gaussian field.

  • alpha – Radius variation of random radius field.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If sigma is not strictly positive.

static apply(data: Tensor, radius_field: Tensor) Tensor

Randomly applies caliber transform to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • radius_field – Displacement field for caliber deformation of same shape.

Returns:

Tensor of the same shape with inserted caliber deformations.

classmethod from_config(config: Config) Self

Constructs CaliberTransform instance from a config object.

Raises:

ValueError – If config.transform.caliber_sigma is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Creates a random displacement field for smooth caliber deformations. Note that shape is expected to be a tuple of length 4, corresponding to dimension (B, X, Y, Z).

class synthbold.transforms.DeformedSphericalMask(radius_range: tuple[float, float], deform_amplitude: float = 0.3, deform_shape: tuple[int, int, int] = (4, 4, 4), sphere_prob: float = 1.0, device: str = 'cpu', seed: int | None = None)

Bases: SphericalMask

Generates a deformed spherical background mask and applies it to 3D or 4D tensors.

This transform builds on SphericalMask by perturbing the sphere radius with smooth, low-frequency noise, so that the resulting mask boundary is an irregular blob rather than a perfect sphere. The noise field is drawn at low resolution and trilinearly upsampled to the full volume size, then normalized per volume to [-1, 1] and scaled by deform_amplitude before perturbing the radius. For 4D tensors, an independently deformed mask is created for each 3D volume within the batch.

Parameters:
  • radius_range – Minimum and maximum radii for the underlying sphere, before deformation.

  • deform_amplitude – Maximum relative perturbation of the radius, e.g. 0.3 allows the local radius to vary by up to 30% in either direction.

  • deform_shape – Matrix size of the low-resolution noise field controlling the deformation. Smaller values yield smoother, lower-frequency deformations.

  • sphere_prob – Probability of applying the mask to each volume. Volumes not selected are returned unmasked (mask is all True).

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If the minimum of radius_range exceeds the maximum, if deform_amplitude is negative, or if any deform_shape dimension is less than 1.

classmethod from_config(config: Config) Self

Constructs DeformedSphericalMask instance from a config object.

Raises:

ValueError – If config.transform.sphere_radius is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Compute the deformed background mask data of shape (B, X, Y, Z).

class synthbold.transforms.ElasticDeformation(sigma: float = 20.0, max_disp: float = 10.0, device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies a smooth random elastic deformation to 3D or 4D tensors)``.

The transform generates a random noise field, smooths it with a Gaussian kernel to obtain a spatially smooth displacement field, and applies this displacement equally in the x, y, and z directions to warp the volume. This results in smooth deformation of structures (e.g., for curving vessels), without explicitly modeling diameter changes.

Parameters:
  • sigma – Standard deviation of Gaussian field to generate smooth random Gaussian field.

  • max_disp – Maximum displacement magnitude (in voxels) applied after normalization of the displacement field.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If sigma is not strictly positive.

static apply(data: Tensor, displacement: Tensor) Tensor

Randomly applies elastic transform to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • displacement – Displacement field of same shape.

Returns:

Tensor of the same shape with inserted elastic deformations.

classmethod from_config(config: Config) Self

Constructs ElasticDeformation instance from a config object.

Raises:

ValueError – If config.transform.elastic_sigma is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Creates a random displacement field for smooth elastic deformations. Note that shape is expected to be a tuple of length 4, corresponding to dimension (B, X, Y, Z).

class synthbold.transforms.GammaTransform(gamma_range: tuple[float, float] = (0.5, 2.0), device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies a random gamma intensity transform to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

For each volume in the batch, a random gamma exponent is sampled from a uniform distribution with set boundaries. The volume is rescaled to [0, 1], raised to the power of gamma, and rescaled back to its original intensity range. Values of gamma below 1 brighten darker regions, while values above 1 darken them.

Parameters:
  • gamma_range – Minimum and maximum gamma exponent. Must be strictly positive.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If gamma_range is not strictly positive.

static apply(data: Tensor, gamma: Tensor) Tensor

Applies the gamma transform to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • gamma – Per-volume gamma exponent tensor broadcastable to the shape of data.

Returns:

Tensor of the same shape with gamma-adjusted intensities.

classmethod from_config(config: Config) Self

Constructs GammaTransform instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes per-volume gamma exponents for the given output shape (B, X, Y, Z).

class synthbold.transforms.GaussianNoise(mu_range: tuple[float, float], std_range: tuple[float, float], device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies random Gaussian noise to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors. The distribution is defined based on randomly chosen mu and std that are sampled from a uniform distribution with set boundaries.

Parameters:
  • mu_range – Minimum and maximum mean of the noise distribution.

  • std_range – Minimum and maximum standard deviation of the noise distribution.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

static apply(data: Tensor, noise: Tensor) Tensor

Applies the noise to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • noise – Noise tensor of same shape.

Returns:

Tensor of the same shape with added Gaussian noise.

classmethod from_config(config: Config) Self

Constructs GaussianNoise instance from a config object.

Raises:

ValueError – If config.transform.gnoise_mu or config.transform.gnoise_std is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Computes gaussian noise for the given output shape (B, X, Y, Z).

class synthbold.transforms.GaussianSharpening(sigma_range: tuple[float, float], amount_range: tuple[float, float], kernel_size: int = 3, device: str = 'cpu', seed: int | None = None)

Bases: Transform

Generates an unsharp-masking kernel and applies it to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

This transform builds a Gaussian blur kernel and combines it with an identity kernel into a single unsharp-masking kernel, computing output = (1 + amount) * data - amount * gaussian_blur(data). Standard deviation of the underlying blur and the sharpening amount are randomly chosen from uniform distributions with set boundaries. For 4D tensors, an independently sampled kernel is created for each 3D volume within the batch.

Parameters:
  • sigma_range – Minimum and maximum standard deviation for the underlying Gaussian blur kernel.

  • amount_range – Minimum and maximum sharpening strength. A value of 0 leaves the input unchanged, while larger values increase the sharpening effect.

  • kernel_size – Isotropic kernel size (must be odd).

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If sigma_range is not strictly positive, if its minimum exceeds its maximum, if amount_range is negative, or if kernel_size is even.

static apply(data: Tensor, kernel: Tensor) Tensor

Applies unsharp masking to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • kernel – Batch of 3D unsharp-masking kernels of same shape.

Returns:

Sharpened tensor of same shape.

classmethod from_config(config: Config) Self

Constructs GaussianSharpening instance from a config object.

Raises:

ValueError – If config.transform.sharpen_sigma or config.transform.sharpen_amount is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Creates a batch of 3D unsharp-masking kernels.

class synthbold.transforms.GaussianSmoothing(sigma_range: tuple[float, float], kernel_size: int = 3, isotropic: bool = True, device: str = 'cpu', seed: int | None = None)

Bases: Transform

Generates an Gaussian smoothing kernel and applies it to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

This transform creates a Gaussian kernel and applies it to the 3D volume. Standard deviation is randomly chosen from a uniform distribution with set boundaries. Parameters can be set isotropic or anisotropic, i.e., with independent smoothing parameters per axis. For 4D tensors, a randomly generated Gaussian kernel is created for each 3D volume within the batch.

Parameters:
  • sigma_range – Minimum and maximum standard deviation for Gaussian kernel.

  • kernel_size – Isotropic or anisotropic kernel size (must be odd).

  • isotropic – If True, spatially isotropic smoothing will be applied.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If sigma_range is not strictly positive, if its minimum exceeds its maximum, or if kernel_size is even.

static apply(data: Tensor, kernel: Tensor) Tensor

Applies the spatial smoothing to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • kernel – Batch of 3D Gaussian kernels of same shape.

Returns:

Smoothed tensor of same shape.

classmethod from_config(config: Config) Self

Constructs SpatialSmoothing instance from a config object.

Raises:

ValueError – If config.transform.gsmooth_sigma is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Creates a batch of 3D Gaussian kernels.

class synthbold.transforms.GibbsRinging(cutoff_range: tuple[float, float], device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies Gibbs ringing artifacts to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

Gibbs ringing arises from the truncation of k-space data during MRI acquisition and produces oscillatory artifacts near sharp intensity transitions. This transform simulates the effect in the frequency domain: the volume is Fourier transformed, a spherical low-pass mask zeroes out k-space beyond a randomly chosen normalized cutoff radius, and the inverse Fourier transform is taken. A cutoff of 1.0 retains all frequencies (no ringing), while smaller values truncate more aggressively and produce stronger ringing. For each volume in the batch, a random cutoff is sampled from a uniform distribution with set boundaries.

Parameters:
  • cutoff_range – Minimum and maximum normalized k-space cutoff radius, within (0, 1].

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If cutoff_range is not within (0, 1], or if its minimum exceeds its maximum.

static apply(data: Tensor, cutoff: Tensor) Tensor

Applies Gibbs ringing to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • cutoff – Per-volume normalized k-space cutoff radius, broadcastable to the shape of data.

Returns:

Tensor of the same shape with Gibbs ringing artifacts applied.

classmethod from_config(config: Config) Self

Constructs GibbsRinging instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes the per-volume k-space cutoff radius for the given output shape (B, X, Y, Z).

class synthbold.transforms.KSpaceSpikeNoise(num_spikes_range: tuple[int, int] = (1, 3), intensity_range: tuple[float, float] = (1.0, 3.0), device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies random localized spikes in k-space to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

K-space spike artifacts (also known as RF interference or “corduroy” artifacts) arise from isolated erroneous samples in the acquired frequency-domain data and manifest as periodic stripe patterns across the reconstructed image. This transform Fourier transforms the volume, overwrites the k-space coefficients at one or more randomly chosen locations with a value proportional to the maximum spectral magnitude, and takes the inverse Fourier transform. The number of spikes is randomly chosen once per call from num_spikes_range. For each spike, an independent intensity multiplier is sampled from intensity_range.

Parameters:
  • num_spikes_range – Minimum and maximum number of k-space spikes (inclusive).

  • intensity_range – Minimum and maximum spike intensity, expressed as a multiple of the maximum k-space magnitude.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If num_spikes_range does not satisfy 0 <= min <= max.

static apply(data: Tensor, spikes: Tensor) Tensor

Applies localized k-space spikes to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • spikes – Spike tensor of shape (B, num_spikes, 4) as returned by sample.

Returns:

Tensor of the same shape with k-space spike artifacts applied.

classmethod from_config(config: Config) Self

Constructs KSpaceSpikeNoise instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Samples per-volume spike locations and intensities for the given output shape (B, X, Y, Z).

Returns:

Tensor of shape (B, num_spikes, 4), where the last dimension holds the voxel coordinates (x, y, z) of each spike in k-space, followed by its intensity multiplier.

class synthbold.transforms.MultiplicativeGammaNoise(shape_range: tuple[float, float], device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies multiplicative gamma noise to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

Multiplicative gamma noise models output = data * noise, where noise is drawn from a Gamma distribution with mean 1, i.e. Gamma(shape, rate) with rate == shape. The shape (concentration) parameter controls the noise variance, var(noise) == 1 / shape: smaller values yield stronger, more skewed noise, while larger values yield a multiplicative factor close to 1. For each volume in the batch, a random shape is sampled from a uniform distribution with set boundaries.

Parameters:
  • shape_range – Minimum and maximum shape (concentration) parameter of the multiplicative gamma noise distribution. Must be strictly positive.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If shape_range is not strictly positive.

Notes

The gamma samples drawn in apply rely on the global PyTorch RNG state and are not controlled by seed. Only the sampled shape values are reproducible.

static apply(data: Tensor, concentration: Tensor) Tensor

Applies multiplicative gamma noise to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • concentration – Per-volume gamma shape parameter tensor broadcastable to the shape of data.

Returns:

Tensor of the same shape with multiplicative gamma noise applied.

classmethod from_config(config: Config) Self

Constructs MultiplicativeGammaNoise instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes the per-volume gamma shape (concentration) parameter for the given output shape (B, X, Y, Z).

class synthbold.transforms.NoncentralChiNoise(std_range: tuple[float, float], dof: int = 4, device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies noncentral chi noise to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

Noncentral chi noise generalizes Rician noise to magnitude images reconstructed from multiple channels via sum-of-squares, such as multi-coil MRI data. The magnitude is modeled as the norm of a dof-dimensional vector whose first component carries the input signal and all components are corrupted by independent zero-mean Gaussian noise with shared standard deviation. For dof == 2 this is equivalent to Rician noise. For each volume in the batch, a random std is sampled from a uniform distribution with set boundaries and used as the standard deviation of all noise channels.

Parameters:
  • std_range – Minimum and maximum standard deviation of the underlying Gaussian noise channels.

  • dof – Degrees of freedom, i.e. the number of underlying Gaussian noise channels. Must be at least 2.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If dof is less than 2.

static apply(data: Tensor, noise: Tensor) Tensor

Applies the noise to the input (magnitude) tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • noise – Noise tensor of shape (dof, *data.shape) holding the independent Gaussian noise channels.

Returns:

Tensor of the same shape with noncentral chi noise applied.

classmethod from_config(config: Config) Self

Constructs NoncentralChiNoise instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes the dof independent Gaussian noise channels for the given output shape (B, X, Y, Z), stacked along a new leading dimension.

class synthbold.transforms.PerlinNoise(base_shape: tuple[int, int, int], octaves: int = 4, persistence: float = 0.5, amplitude_range: tuple[float, float] = (0.0, 1.0), device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies additive Perlin-like fractal noise to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

Multiple octaves of smooth, low-frequency noise are summed with geometrically decaying amplitudes (persistence), yielding a self-similar fractal noise pattern with detail across multiple spatial scales, similar to Perlin noise. For each volume in the batch, a random amplitude is sampled from a uniform distribution with set boundaries and used to scale the resulting field.

Parameters:
  • base_shape – Matrix size of the coarsest (first) noise octave.

  • octaves – Number of noise octaves to combine. Each successive octave doubles the resolution of the previous one, capped at the target shape. Must be at least 1.

  • persistence – Amplitude decay factor between successive octaves. Must be in (0, 1].

  • amplitude_range – Minimum and maximum scaling factor for the noise field.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If any base_shape dimension is less than 1, if octaves is less than 1, or if persistence is not within (0, 1].

static apply(data: Tensor, noise: Tensor) Tensor

Applies the noise to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • noise – Noise tensor of same shape.

Returns:

Tensor of the same shape with additive Perlin-like noise.

classmethod from_config(config: Config) Self

Constructs PerlinNoise instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes Perlin-like fractal noise for the given output shape (B, X, Y, Z).

class synthbold.transforms.PoissonNoise(peak_range: tuple[float, float], device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies signal-dependent Poisson noise to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

For each volume in the batch, a random peak count is drawn from a uniform distribution with set boundaries. The input is scaled by peak, Poisson-distributed counts are drawn, and the result is rescaled back, so that the relative noise level increases as peak decreases.

Parameters:
  • peak_range – Minimum and maximum peak count used to scale the input before drawing Poisson counts.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If peak_range is not strictly positive.

Notes

The Poisson counts drawn in apply rely on the global PyTorch RNG state and are not controlled by seed. Only the sampled peak values are reproducible.

static apply(data: Tensor, peak: Tensor) Tensor

Applies signal-dependent Poisson noise to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • peak – Per-volume peak count tensor broadcastable to the shape of data.

Returns:

Tensor of the same shape with Poisson-distributed noise applied.

classmethod from_config(config: Config) Self

Constructs PoissonNoise instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes the per-volume peak count for the given output shape (B, X, Y, Z).

class synthbold.transforms.RandomFlip(flip_prob: float = 0.5, device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies spatial random flips to 3D or 4D tensors along one or multiple axes.

Parameters:
  • flip_prob – Probability of flipping each axis independently.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

static apply(data: Tensor, flip: Tensor) Tensor

Randomly flips the tensor along spatial axes.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • flip – 1D boolean indicating if single spatial dimensions will be flipped.

Returns:

Tensor of the same shape with flipped axes.

classmethod from_config(config: Config) Self

Constructs RandomFlip instance from a config object.

Raises:

ValueError – If config.transform.flip_prob is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Compute 1D random boolean tensor, denoting if single spatial dimension will be flipped or not.

class synthbold.transforms.RicianNoise(std_range: tuple[float, float], device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies Rician noise to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

Rician noise models the magnitude of a complex signal whose real and imaginary parts are each corrupted by independent Gaussian noise, as is the case for MRI magnitude images. For each volume in the batch, a random std is sampled from a uniform distribution with set boundaries and used as the standard deviation of both Gaussian noise channels.

Parameters:
  • std_range – Minimum and maximum standard deviation of the underlying Gaussian noise channels.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

static apply(data: Tensor, noise: Tensor) Tensor

Applies the noise to the input (magnitude) tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • noise – Noise tensor of shape (2, *data.shape) holding the real and imaginary Gaussian noise channels.

Returns:

Tensor of the same shape with Rician noise applied.

classmethod from_config(config: Config) Self

Constructs RicianNoise instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes the real and imaginary Gaussian noise channels for the given output shape (B, X, Y, Z), stacked along a new leading dimension.

class synthbold.transforms.SpeckleNoise(std_range: tuple[float, float], device: str = 'cpu', seed: int | None = None)

Bases: Transform

Applies multiplicative speckle noise to 3D (X, Y, Z) or 4D (B, X, Y, Z) tensors.

Speckle noise models multiplicative degradation as output = data + data * noise, where noise is drawn from a zero-mean Gaussian distribution. For each volume in the batch, a random std is sampled from a uniform distribution with set boundaries and used as the standard deviation of the noise.

Parameters:
  • std_range – Minimum and maximum standard deviation of the multiplicative noise distribution.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

static apply(data: Tensor, noise: Tensor) Tensor

Applies the noise to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • noise – Noise tensor of same shape.

Returns:

Tensor of the same shape with multiplicative speckle noise applied.

classmethod from_config(config: Config) Self

Constructs SpeckleNoise instance from a config object.

sample(shape: tuple[int, ...]) Tensor

Computes multiplicative speckle noise for the given output shape (B, X, Y, Z).

class synthbold.transforms.SphericalMask(radius_range: tuple[float, float], sphere_prob: float = 1.0, device: str = 'cpu', seed: int | None = None)

Bases: Transform

Generates a spherical background mask and applies it to 3D or 4D tensors.

This transform creates a spherical mask with randomized center and radius, and multiples it with the input tensor. The central voxel can be any voxel within the input tensor array. For 4D tensors, a randomly generated mask is created for each 3D volume within the batch.

Parameters:
  • radius_range – Minimum and maximum radii for spherical mask.

  • sphere_prob – Probability of applying the spherical mask to each volume. Volumes not selected are returned unmasked (mask is all True).

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

Raises:

ValueError – If the minimum of radius_range exceeds the maximum.

static apply(data: Tensor, mask: Tensor) Tensor

Applies background masks to the input tensor.

Parameters:
  • data – Input tensor of shape (X, Y, Z) or (B, X, Y, Z).

  • mask – Mask tensor of same shape.

Returns:

Masked tensor of same shape.

classmethod from_config(config: Config) Self

Constructs SphericalMask instance from a config object.

Raises:

ValueError – If config.transform.sphere_radius is not set in the config.

sample(shape: tuple[int, ...]) Tensor

Compute the background mask data of shape (B, X, Y, Z).

synthbold.transforms.functional

Helper functions for transforms.

class synthbold.transforms.functional.Pipeline(transforms: list[Transform], prob: float = 0.5, device: str = 'cpu', seed: int | None = None)

Bases: RandomGeneratorMixin

Compose multiple tensor-to-tensor transforms in sequence.

This class chains multiple Transform instances together. When called, it passes the input tensor through each transform in the order they were provided. Each transform is independently and randomly skipped according to prob, evaluated per batch element.

Parameters:
  • transforms – A list of Transform instances.

  • prob – Probability of applying each transform. Evaluated independently per transform and per batch element.

  • device – Target compute device (“cuda” or “cpu”).

  • seed – Random seed for reproducibility.

synthbold.transforms.functional.apply_deformation(data: Tensor, displacement: Tensor, interp: str = 'bilinear') Tensor

Applies a 3D displacement field to a volumetric tensor. This function warps a batch of 3D volumes using a smooth displacement field. Each voxel in data is moved according to the corresponding vector in displacement. The output has the same shape as the input.

Parameters:
  • data – Input tensor of shape (B, X, Y, Z).

  • displacement – Displacement field of shape (B, X, Y, Z, 3), specifying voxel offsets in voxel coordinates along X, Y, and Z.

  • interp – Interpolation method (bilinear, nearest, …)

Returns:

Deformed tensor of shape (B, X, Y, Z).

synthbold.transforms.functional.percentile_scale(data: Tensor, lower: float = 0.01, upper: float = 0.99, eps: float = 1e-08) Tensor

Rescales each batch element to [0, 1] using percentile clipping.

Per batch element, values are linearly rescaled so that the lower and upper quantiles map to 0 and 1 respectively, then clamped to [0, 1]. This is more robust to outliers than min-max scaling since it doesn’t rely on the tensor’s extreme values.

Parameters:
  • data – Input tensor of shape (B, ...).

  • lower – Lower quantile, in [0, 1], mapped to 0.

  • upper – Upper quantile, in [0, 1], mapped to 1.

  • eps – Relative floor, as a fraction of each batch element’s peak absolute value, added to the denominator to avoid division by zero. Expressed relative to data rather than as an absolute constant so the floor stays negligible regardless of the physical scale/units of data.

Returns:

Tensor of the same shape as data, rescaled and clamped to [0, 1].

synthbold.transforms.functional.psc(data: Tensor, eps: float = 1e-08) Tensor

Converts each batch element to percent signal change relative to its mean.

Mean is computed per batch element over all non-batch dimensions, so the conversion is independent across the batch.

Parameters:
  • data – Input tensor of shape (B, ...).

  • eps – Relative floor, as a fraction of each batch element’s peak absolute value, added to the mean to avoid division by zero. Expressed relative to data rather than as an absolute constant so the floor stays negligible regardless of the physical scale/units of data.

Returns:

Tensor of the same shape as data, expressed as percent deviation from each batch element’s mean.

synthbold.transforms.functional.sample_fractal_noise(batch_size: int, base_shape: tuple[int, int, int], target_shape: tuple[int, int, int], octaves: int, persistence: float, device: device, generator: Generator) Tensor

Samples a batch of Perlin-like fractal noise fields.

Multiple octaves of smooth, low-frequency noise (see sample_lowres_noise) are generated at progressively doubling resolutions, starting from base_shape, and summed with geometrically decaying amplitudes. This yields a self-similar noise pattern with detail across multiple scales, similar to Perlin noise.

Parameters:
  • batch_size – Number of independent noise fields to generate.

  • base_shape – Matrix size (x, y, z) of the coarsest (first) octave.

  • target_shape – Matrix size (X, Y, Z) of the output noise field.

  • octaves – Number of octaves to combine. Each successive octave doubles the resolution of the previous one, capped at target_shape.

  • persistence – Amplitude decay factor between successive octaves, in (0, 1].

  • device – Target compute device.

  • generator – Random number generator for reproducibility.

Returns:

Noise tensor of shape (B, X, Y, Z), normalized to unit total amplitude.

synthbold.transforms.functional.sample_lowres_noise(batch_size: int, lowres_shape: tuple[int, int, int], target_shape: tuple[int, int, int], device: device, generator: Generator, align_corners: bool = False) Tensor

Samples a batch of smooth, low-frequency noise fields.

Standard Gaussian noise is drawn on a coarse grid and trilinearly upsampled to the target resolution, yielding spatially smooth random fields.

Parameters:
  • batch_size – Number of independent noise fields to generate.

  • lowres_shape – Matrix size (x, y, z) of the coarse noise grid.

  • target_shape – Matrix size (X, Y, Z) to upsample to.

  • device – Target compute device.

  • generator – Random number generator for reproducibility.

  • align_corners – Passed to torch.nn.functional.interpolate.

Returns:

Noise tensor of shape (B, X, Y, Z).

synthbold.transforms.functional.zscore(data: Tensor, center: bool = True, eps: float = 1e-08) Tensor

Normalizes each batch element to zero mean and unit variance.

Mean and standard deviation are computed per batch element over all non-batch dimensions, so normalization is independent across the batch.

Parameters:
  • data – Input tensor of shape (B, ...).

  • center – Whether to subtract the mean. Set to False for quantities derived from squared units (e.g. a variance), which should be rescaled but not mean-centered.

  • eps – Relative floor, as a fraction of each batch element’s peak absolute value, added to std to avoid division by zero. Expressed relative to data rather than as an absolute constant so the floor stays negligible regardless of the physical scale/units of data.

Returns:

Tensor of the same shape as data, normalized.