Skip to content

confusius.xarray

xarray

Xarray extensions for fUSI data analysis.

Modules:

  • accessors

    Xarray accessor for fUSI-specific operations.

  • affine

    Xarray accessor for affine transform operations.

  • connectivity

    Xarray accessor for connectivity analysis.

  • extract

    Xarray accessor for signal extraction.

  • iq

    Xarray accessor for IQ processing.

  • plotting

    Xarray accessor for plotting.

  • registration

    Xarray accessor for registration.

  • scale

    Xarray accessor for scaling operations.

Classes:

Functions:

  • db_scale

    Convert data to decibel scale relative to maximum value.

  • log_scale

    Apply natural logarithm to data.

  • power_scale

    Apply power scaling to data.

FUSIAccessor

Xarray accessor for fUSI-specific operations.

Provides convenient methods for functional ultrasound imaging data analysis.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap.

Examples:

>>> import xarray as xr
>>> import numpy as np
>>> from confusius import xarray as cxr  # Registers the accessor
>>> data = xr.DataArray([1, 10, 100, 1000])
>>> data.fusi.scale.db(factor=20)
<xarray.DataArray (dim_0: 4)>
array([-60., -40., -20.,   0.])

Methods:

  • save

    Save the DataArray to file, dispatching by extension.

Attributes:

affine property

Access affine transform operations.

Returns:

  • FUSIAffineAccessor

    Accessor for computing relative transforms between scans and for applying axis-aligned affines to spatial coordinates.

Examples:

>>> import numpy as np
>>> import xarray as xr
>>> import confusius  # noqa: F401
>>> eye = np.eye(4)
>>> a = xr.DataArray(np.zeros((2, 2)), attrs={"affines": {"to_world": eye}})
>>> b = xr.DataArray(np.zeros((2, 2)), attrs={"affines": {"to_world": eye}})
>>> np.allclose(a.fusi.affine.to(b, via="to_world"), np.eye(4))
True

connectivity property

Access connectivity analysis operations.

Returns:

Examples:

>>> import xarray as xr
>>> import numpy as np
>>> import confusius  # noqa: F401
>>> data = xr.open_zarr("recording.zarr")["power_doppler"]
>>> seed_masks = xr.open_zarr("seed_masks.zarr")["masks"]
>>> mapper = data.fusi.connectivity.seed_map(seed_masks=seed_masks)

extract property

Access signal extraction operations.

Returns:

  • FUSIExtractAccessor

    Accessor for extracting signals from fUSI data and reconstructing fUSI data from processed signals.

Examples:

>>> import xarray as xr
>>> data = xr.open_zarr("output.zarr")["power_doppler"]
>>> mask = xr.open_zarr("brain_mask.zarr")["mask"]
>>> signals = data.fusi.extract.with_mask(mask)
>>> # ... process signals ...
>>> restored = signals.fusi.extract.unmask(mask)

iq property

Access IQ processing operations.

Returns:

Examples:

>>> import xarray as xr
>>> ds = xr.open_zarr("output.zarr")
>>> iq = ds["iq"]
>>> pwd = iq.fusi.iq.process_to_power_doppler()
>>> velocity = iq.fusi.iq.process_to_axial_velocity()

origin property

origin: dict[str, float]

Physical origin (first coordinate value) for all dimensions.

For each dimension, returns the first coordinate value. If a coordinate is missing, warns and falls back to 0.0.

Returns:

  • dict[str, float]

    Origin per dimension, in DataArray dimension order.

Examples:

>>> import xarray as xr
>>> import numpy as np
>>> import confusius  # noqa: F401
>>> data = xr.DataArray(
...     np.zeros((10, 20)),
...     dims=["y", "x"],
...     coords={"y": np.arange(10) * 0.2, "x": np.arange(20) * 0.1},
... )
>>> data.fusi.origin
{'y': 0.0, 'x': 0.0}

plot property

Access plotting operations.

Returns:

Examples:

>>> import xarray as xr
>>> data = xr.open_zarr("output.zarr")["iq"]
>>> viewer, layer = data.fusi.plot.napari()

register property

Access registration operations.

Returns:

Examples:

>>> import xarray as xr
>>> data = xr.open_zarr("output.zarr")["power_doppler"]
>>> registered = data.fusi.register.volumewise(reference_time=0)

scale property

Access scaling operations.

Returns:

Examples:

>>> data = xr.DataArray([1, 10, 100, 1000])
>>> data.fusi.scale.db(factor=10)
<xarray.DataArray (dim_0: 4)>
array([-30., -20., -10.,   0.])

spacing property

spacing: dict[str, float | None]

Coordinate spacing for all dimensions.

Spacing is computed as the median of consecutive coordinate differences. A coordinate is considered uniform if its relative interval range (max_diff - min_diff) / median_diff is below 1%.

Returns:

  • dict[str, float | None]

    Spacing per dimension, in DataArray dimension order. Returns None for dimensions with non-uniform or undefined spacing, with a warning.

Examples:

>>> import xarray as xr
>>> import numpy as np
>>> import confusius  # noqa: F401
>>> data = xr.DataArray(
...     np.zeros((10, 20)),
...     dims=["y", "x"],
...     coords={"y": np.arange(10) * 0.2, "x": np.arange(20) * 0.1},
... )
>>> data.fusi.spacing
{'y': 0.2, 'x': 0.1}

save

save(path: str | Path, **kwargs: Any) -> None

Save the DataArray to file, dispatching by extension.

Supported formats:

Parameters:

  • path
    (str or Path) –

    Output path. The extension determines the format.

  • **kwargs
    (Any, default: {} ) –

    Additional keyword arguments forwarded to the underlying saver.

Examples:

>>> import xarray as xr
>>> import numpy as np
>>> import confusius  # noqa: F401
>>> data = xr.DataArray(
...     np.zeros((10, 32, 1, 64)), dims=["time", "z", "y", "x"]
... )
>>> data.fusi.save("recording.nii.gz")

FUSIAffineAccessor

Accessor for affine transform operations on fUSI DataArrays.

Provides methods to compute relative transforms between scans and to apply axis-aligned affines to a scan's spatial coordinates.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap.

Methods:

  • apply

    Apply an axis-aligned affine to the scan's spatial coordinates.

  • to

    Return the affine mapping self's physical space into other's.

apply

apply(
    affine: NDArray[float64], inplace: bool = False
) -> DataArray

Apply an axis-aligned affine to the scan's spatial coordinates.

Updates z, y, and x coordinate arrays so that plot_volume places the scan in the transformed frame without resampling data values. All affines stored in attrs["affines"] are updated consistently.

Parameters:

  • affine
    ((ndarray, shape(4, 4))) –

    Homogeneous affine matrix. The rotation block must be diagonal (axis-aligned transforms only).

  • inplace
    (bool, default: False ) –

    Whether to modify the DataArray in-place.

Returns:

  • DataArray

    The DataArray with updated spatial coordinates and attrs["affines"].

Raises:

  • ValueError

    If affine shape is not (4, 4) or if the rotation block mixes axes.

Examples:

>>> import numpy as np
>>> import xarray as xr
>>> import confusius  # noqa: F401
>>> data = xr.DataArray(
...     np.zeros((3, 4)),
...     dims=["z", "y"],
...     coords={"z": [0.0, 1.0, 2.0], "y": [0.0, 1.0, 2.0, 3.0]},
... )
>>> shift = np.eye(4)
>>> shift[:3, 3] = [10.0, 5.0, 0.0]
>>> result = data.fusi.affine.apply(shift)
>>> float(result.coords["z"].values[0])
10.0

to

Return the affine mapping self's physical space into other's.

Computes inv(other.attrs["affines"][via]) @ self.attrs["affines"][via], giving the transform from self's physical frame to other's.

Parameters:

  • other
    (DataArray) –

    The scan whose physical space is the target.

  • via
    (str) –

    Key into attrs["affines"] naming the shared intermediate coordinate space (e.g. "physical_to_lab").

Returns:

  • (ndarray, shape(4, 4))

    Homogeneous affine matrix mapping self's physical coordinates to other's physical coordinates.

Raises:

  • KeyError

    If via is not present in either scan's attrs["affines"].

  • ValueError

    If either scan has no "affines" entry in attrs.

Examples:

>>> import numpy as np
>>> import xarray as xr
>>> import confusius  # noqa: F401
>>> eye = np.eye(4)
>>> a = xr.DataArray(np.zeros((2, 2)), attrs={"affines": {"to_world": eye}})
>>> b = xr.DataArray(np.zeros((2, 2)), attrs={"affines": {"to_world": eye}})
>>> np.allclose(a.fusi.affine.to(b, via="to_world"), np.eye(4))
True

FUSIConnectivityAccessor

Xarray accessor for seed-based functional connectivity analysis.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap.

Examples:

>>> import numpy as np
>>> import xarray as xr
>>> import confusius  # noqa: F401
>>>
>>> data = xr.open_zarr("recording.zarr")["power_doppler"]
>>> seed_masks = xr.open_zarr("seed_masks.zarr")["masks"]
>>> mapper = data.fusi.connectivity.seed_map(seed_masks=seed_masks)

Methods:

  • seed_map

    Fit a seed-based correlation map.

seed_map

seed_map(
    *,
    seed_masks: DataArray | None = None,
    seed_signals: DataArray | None = None,
    labels_reduction: Literal[
        "mean", "sum", "median", "min", "max", "var", "std"
    ] = "mean",
    clean_kwargs: dict | None = None,
) -> SeedBasedMaps

Fit a seed-based correlation map.

Convenience wrapper around SeedBasedMaps that constructs the estimator, calls SeedBasedMaps.fit on the wrapped DataArray, and returns the fitted estimator.

Parameters:

  • seed_masks
    (DataArray, default: None ) –

    Integer label map defining the seed region(s). See SeedBasedMaps for accepted formats. Mutually exclusive with seed_signals.

  • seed_signals
    (DataArray, default: None ) –

    Pre-computed (time, ...) seed signals used directly for correlation. When provided, seed extraction from the data is skipped. Mutually exclusive with seed_masks.

  • labels_reduction
    ((mean, sum, median, min, max, var, std), default: "mean" ) –

    Aggregation function applied across voxels within each seed region. Ignored when seed_signals is provided.

  • clean_kwargs
    (dict or None, default: None ) –

    Keyword arguments forwarded to clean. If not provided, no cleaning is applied.

Returns:

  • SeedBasedMaps

    Fitted estimator. Access maps_ and seed_signals_ on the returned object.

Examples:

>>> import numpy as np
>>> import xarray as xr
>>> import confusius  # noqa: F401
>>>
>>> data = xr.open_zarr("recording.zarr")["power_doppler"]
>>> seed_masks = xr.open_zarr("seed_masks.zarr")["masks"]
>>> mapper = data.fusi.connectivity.seed_map(seed_masks=seed_masks)

FUSIExtractAccessor

Xarray accessor for signal extraction operations.

Provides convenient methods for extracting signals from N-D fUSI data by flattening spatial dimensions, and reconstructing N-D volumes from processed signals.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap.

Examples:

>>> import xarray as xr
>>> import numpy as np
>>>
>>> # 3D+t data: (time, z, y, x)
>>> data = xr.DataArray(
...     np.random.randn(100, 10, 20, 30),
...     dims=["time", "z", "y", "x"],
... )
>>> mask = xr.DataArray(
...     np.random.rand(10, 20, 30) > 0.5,
...     dims=["z", "y", "x"],
... )
>>>
>>> # Extract signals
>>> signals = data.fusi.extract.with_mask(mask)
>>> signals.dims
("time", "space")
>>>
>>> # Reconstruct full spatial volume from signals
>>> reconstructed = signals.fusi.extract.unmask(mask)
>>> reconstructed.dims
("time", "z", "y", "x")

Methods:

  • unmask

    Reconstruct N-D volume from masked signals.

  • with_labels

    Extract region-aggregated signals using an integer label map.

  • with_mask

    Extract signals using a boolean or single-label integer mask.

unmask

unmask(
    mask: DataArray, fill_value: float = 0.0
) -> DataArray

Reconstruct N-D volume from masked signals.

Reconstructs the full spatial volume from a DataArray of signals, which must have a voxels dimension. This is a convenience wrapper around confusius.extract.unmask().

Parameters:

  • mask
    (DataArray) –

    Boolean mask used for the original extraction. Provides spatial dimensions and coordinates for reconstruction.

  • fill_value
    (float, default: 0.0 ) –

    Value to fill in non-masked voxels.

Returns:

  • DataArray

    Reconstructed DataArray with shape (..., z, y, x) where spatial coordinates come from the mask.

Examples:

>>> signals = data.fusi.extract.with_mask(mask)
>>> signals.dims
("time", "space")
>>> reconstructed = signals.fusi.extract.unmask(mask)
>>> reconstructed.dims
("time", "z", "y", "x")

with_labels

with_labels(
    labels: DataArray,
    reduction: Literal[
        "mean", "sum", "median", "min", "max", "var", "std"
    ] = "mean",
) -> DataArray

Extract region-aggregated signals using an integer label map.

Parameters:

  • labels
    (DataArray) –

    Integer label map in one of two formats:

    • Flat label map: Spatial dims only, e.g. (z, y, x). Background voxels labeled 0; each unique non-zero integer identifies a distinct, non-overlapping region. The regions coordinate of the output holds the integer label values.
    • Stacked mask format: Has a leading mask dimension followed by spatial dims, e.g. (mask, z, y, x). Each layer has values in {0, region_id} and regions may overlap. The region coordinate of the output holds the mask coordinate values (e.g., region label).
  • reduction
    ((mean, sum, median, min, max, var, std), default: "mean" ) –

    Aggregation function applied across voxels in each region:

    • "mean": arithmetic mean.
    • "sum": sum of values.
    • "median": median value.
    • "min": minimum value.
    • "max": maximum value.
    • "var": variance.
    • "std": standard deviation.

Returns:

  • DataArray

    Array with spatial dimensions replaced by a region dimension. The region dimension has integer coordinates corresponding to each unique non-zero label in labels. All non-spatial dimensions are preserved.

    For example:

    • (time, z, y, x)(time, region)
    • (time, pose, z, y, x)(time, pose, region)
    • (z, y, x)(region,)

Raises:

  • ValueError

    If labels dimensions don't match data's spatial dimensions, if coordinates don't match, or if reduction is not a valid option.

  • TypeError

    If labels is not integer dtype.

Examples:

>>> signals = data.fusi.extract.with_labels(labels)
>>> signals.dims
("time", "region")
>>> signals.coords["region"].values
array([1, 2, 3])
>>>
>>> # Sum per region instead of mean.
>>> sums = data.fusi.extract.with_labels(labels, reduction="sum")

with_mask

with_mask(mask: DataArray) -> DataArray

Extract signals using a boolean or single-label integer mask.

Parameters:

  • mask
    (DataArray) –

    Mask defining which voxels to extract. Its dimensions define the spatial dimensions that will be flattened. Must have boolean dtype, or integer dtype with exactly one non-zero value (0 = background, one region id = foreground). The latter format is produced by Atlas.get_masks. Coordinates must match data.

Returns:

  • DataArray

    Array with spatial dimensions flattened into a space dimension. All non-spatial dimensions are preserved. The space dimension has a MultiIndex storing spatial coordinates.

    For simple round-trip reconstruction, use .unstack("space") which re-creates the original DataArray using the smallest bounding box. For full mask shape reconstruction, use .fusi.extract.unmask().

Raises:

  • ValueError

    If mask dimensions don't match data's spatial dimensions.

  • TypeError

    If mask is not boolean dtype.

Examples:

>>> signals = data.fusi.extract.with_mask(mask)
>>> signals.dims
("time", "space")
>>>
>>> # Quick bounding box reconstruction
>>> bbox = signals.unstack("space")
>>>
>>> # Full mask shape reconstruction
>>> full = signals.fusi.extract.unmask(mask)

FUSIIQAccessor

Accessor for IQ processing operations on fUSI data.

This accessor provides methods to process beamformed IQ data into derived quantities such as power Doppler and axial velocity.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap. Must contain complex beamformed IQ data with dimensions (time, z, y, x).

Examples:

>>> import xarray as xr
>>> ds = xr.open_zarr("iq_data.zarr")
>>> iq = ds["iq"]
>>> pwd = iq.fusi.iq.process_to_power_doppler(low_cutoff=40)

Methods:

process_to_axial_velocity

process_to_axial_velocity(
    clutter_window_width: int | None = None,
    clutter_window_stride: int | None = None,
    filter_method: Literal[
        "svd_indices",
        "svd_energy",
        "svd_cumulative_energy",
        "butterworth",
    ] = "svd_indices",
    clutter_mask: DataArray | None = None,
    low_cutoff: int | float | None = None,
    high_cutoff: int | float | None = None,
    butterworth_order: int = 4,
    velocity_window_width: int | None = None,
    velocity_window_stride: int | None = None,
    lag: int = 1,
    absolute_velocity: bool = False,
    spatial_kernel: int = 1,
    estimation_method: Literal[
        "average_angle", "angle_average"
    ] = "average_angle",
) -> DataArray

Process beamformed IQ into axial velocity volumes.

This method computes axial velocity volumes from beamformed IQ data using nested sliding windows. A first sliding window is used for clutter filtering. Inside each clutter-filtered window, axial velocity volumes are computed using a second sliding window.

Parameters:

  • clutter_window_width
    (int, default: None ) –

    Width of the sliding temporal window for clutter filtering, in volumes. If not provided, uses the chunk size of the IQ data along the temporal dimension.

  • clutter_window_stride
    (int, default: None ) –

    Stride of the sliding temporal window for clutter filtering, in volumes. If not provided, equals clutter_window_width.

  • filter_method
    ((svd_indices, svd_energy, svd_cumulative_energy, butterworth), default: "svd_indices" ) –

    Clutter filtering method to apply before velocity computation.

    • "svd_indices": Static SVD filter using singular vector indices.
    • "svd_energy": Adaptive SVD filter using singular vector energies.
    • "svd_cumulative_energy": Adaptive SVD filter using cumulative energies.
    • "butterworth": Butterworth frequency-domain filter.
  • clutter_mask
    ((z, y, x) xarray.DataArray, default: None ) –

    Boolean mask to define clutter regions. Only used by SVD-based clutter filters to compute clutter vectors from masked voxels. If not provided, all voxels are used. The mask spatial coordinates (z, y, x) must match the IQ data coordinates.

  • low_cutoff
    (int or float, default: None ) –

    Low cutoff for clutter filtering. Interpretation depends on filter_method. If not provided, uses method-specific defaults.

  • high_cutoff
    (int or float, default: None ) –

    High cutoff for clutter filtering. Interpretation depends on filter_method. If not provided, uses method-specific defaults.

  • butterworth_order
    (int, default: 4 ) –

    Order of Butterworth filter. Effective order is doubled due to forward-backward filtering.

  • velocity_window_width
    (int, default: None ) –

    Width of the sliding temporal window for velocity estimation, in volumes. If not provided, equals clutter_window_width.

  • velocity_window_stride
    (int, default: None ) –

    Stride of the sliding temporal window for velocity estimation, in volumes. If not provided, equals velocity_window_width.

  • lag
    (int, default: 1 ) –

    Temporal lag in volumes for autocorrelation computation. Must be positive.

  • absolute_velocity
    (bool, default: False ) –

    If True, compute absolute velocity values. If False, preserve sign information.

  • spatial_kernel
    (int, default: 1 ) –

    Size of the median filter kernel applied spatially to denoise. Must be positive and odd. If 1, no spatial filtering is applied.

  • estimation_method
    ((average_angle, angle_average), default: "average_angle" ) –

    Method for computing the velocity estimate.

    • "average_angle": Compute the angle of the autocorrelation, then average (i.e., average of angles).
    • "angle_average": Average the autocorrelation, then compute the angle (i.e., angle of average).

Returns:

  • (clutter_windows * velocity_windows, z, y, x) xarray.DataArray

    Axial velocity volumes with updated time coordinates, where clutter_windows is the number of clutter filter sliding windows and velocity_windows is the number of velocity sliding windows per clutter window. Velocity values are in meters per second.

Examples:

>>> import xarray as xr
>>> ds = xr.open_zarr("iq_data.zarr")
>>> iq = ds["iq"]
>>> velocity = iq.fusi.iq.process_to_axial_velocity(
...     clutter_window_width=50,
...     velocity_window_width=25,
... )

process_to_bmode

process_to_bmode(
    bmode_window_width: int | None = None,
    bmode_window_stride: int | None = None,
) -> DataArray

Process beamformed IQ into B-mode volumes.

This method computes B-mode volumes from beamformed IQ data using a single sliding temporal window. Unlike power Doppler, no clutter filtering is applied; the mean magnitude (not squared magnitude) of the IQ data within each window is computed.

Parameters:

  • bmode_window_width
    (int, default: None ) –

    Width of the sliding temporal window for B-mode integration, in volumes. If not provided, uses the chunk size of the IQ data along the temporal dimension.

  • bmode_window_stride
    (int, default: None ) –

    Stride of the sliding temporal window, in volumes. If not provided, equals bmode_window_width.

Returns:

  • (windows, z, y, x) xarray.DataArray

    B-mode volumes with updated time coordinates, where windows is the number of sliding windows.

Examples:

>>> import xarray as xr
>>> ds = xr.open_zarr("iq_data.zarr")
>>> iq = ds["iq"]
>>> bmode = iq.fusi.iq.process_to_bmode(bmode_window_width=50)

process_to_power_doppler

process_to_power_doppler(
    clutter_window_width: int | None = None,
    clutter_window_stride: int | None = None,
    filter_method: Literal[
        "svd_indices",
        "svd_energy",
        "svd_cumulative_energy",
        "butterworth",
    ] = "svd_indices",
    clutter_mask: DataArray | None = None,
    low_cutoff: int | float | None = None,
    high_cutoff: int | float | None = None,
    butterworth_order: int = 4,
    doppler_window_width: int | None = None,
    doppler_window_stride: int | None = None,
) -> DataArray

Process beamformed IQ into power Doppler volumes.

This method computes power Doppler volumes from beamformed IQ data using nested sliding windows. A first sliding window is used for clutter filtering. Inside each clutter-filtered window, power Doppler volumes are computed using a second sliding window.

Parameters:

  • clutter_window_width
    (int, default: None ) –

    Width of the sliding temporal window for clutter filtering, in volumes. If not provided, uses the chunk size of the IQ data along the temporal dimension.

  • clutter_window_stride
    (int, default: None ) –

    Stride of the sliding temporal window for clutter filtering, in volumes. If not provided, equals clutter_window_width.

  • filter_method
    ((svd_indices, svd_energy, svd_cumulative_energy, butterworth), default: "svd_indices" ) –

    Clutter filtering method to apply before power Doppler computation.

    • "svd_indices": Static SVD filter using singular vector indices.
    • "svd_energy": Adaptive SVD filter using singular vector energies.
    • "svd_cumulative_energy": Adaptive SVD filter using cumulative energies.
    • "butterworth": Butterworth frequency-domain filter.
  • clutter_mask
    ((z, y, x) xarray.DataArray, default: None ) –

    Boolean mask to define clutter regions. Only used by SVD-based clutter filters to compute clutter vectors from masked voxels. If not provided, all voxels are used. The mask spatial coordinates (z, y, x) must match the IQ data coordinates.

  • low_cutoff
    (int or float, default: None ) –

    Low cutoff for clutter filtering. Interpretation depends on filter_method. If not provided, uses method-specific defaults.

  • high_cutoff
    (int or float, default: None ) –

    High cutoff for clutter filtering. Interpretation depends on filter_method. If not provided, uses method-specific defaults.

  • butterworth_order
    (int, default: 4 ) –

    Order of Butterworth filter. Effective order is doubled due to forward-backward filtering.

  • doppler_window_width
    (int, default: None ) –

    Width of the sliding temporal window for power Doppler integration, in volumes. If not provided, equals clutter_window_width.

  • doppler_window_stride
    (int, default: None ) –

    Stride of the sliding temporal window for power Doppler integration, in volumes. If not provided, equals doppler_window_width.

Returns:

  • (clutter_windows * doppler_windows, z, y, x) xarray.DataArray

    Power Doppler volumes with updated time coordinates, where clutter_windows is the number of clutter filter sliding windows and doppler_windows is the number of power Doppler sliding windows per clutter window.

Examples:

>>> import xarray as xr
>>> ds = xr.open_zarr("iq_data.zarr")
>>> iq = ds["iq"]
>>> pwd = iq.fusi.iq.process_to_power_doppler(
...     clutter_window_width=50,
...     doppler_window_width=25,
...     low_cutoff=40,
... )

FUSIPlotAccessor

Accessor for plotting fUSI data.

This accessor provides convenient plotting methods for functional ultrasound imaging data, with specialized support for napari visualization.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap.

Examples:

>>> import xarray as xr
>>> data = xr.open_zarr("output.zarr")["iq"]
>>> viewer, layer = data.fusi.plot.napari()

Methods:

  • carpet

    Plot voxel intensities across time as a raster image.

  • contours

    Plot mask contours as a grid of 2D slice panels.

  • draw_napari_labels

    Open napari to interactively paint integer labels over fUSI data.

  • labels_from_layer

    Convert a napari Labels layer to an integer label map DataArray.

  • napari

    Display data in napari viewer.

  • volume

    Plot 2D slices of a volume as a matplotlib subplot grid.

carpet

carpet(
    mask: DataArray | None = None,
    detrend_order: int | None = None,
    standardize: bool = True,
    cmap: str | Colormap = "gray",
    vmin: float | None = None,
    vmax: float | None = None,
    decimation_threshold: int | None = 800,
    figsize: tuple[float, float] = (10, 5),
    title: str | None = None,
    black_bg: bool = False,
    ax: Axes | None = None,
) -> tuple[Figure | SubFigure, Axes]

Plot voxel intensities across time as a raster image.

A carpet plot (also known as "grayplot" or "Power plot") displays voxel intensities as a 2D raster image with time on the x-axis and voxels on the y-axis. Each row represents one voxel's time series, typically standardized to z-scores.

Parameters:

  • mask
    (DataArray, default: None ) –

    Boolean mask with same spatial dimensions and coordinates as data. True values indicate voxels to include. If not provided, all non-zero voxels from the data are included.

  • detrend_order
    (int, default: None ) –

    Polynomial order for detrending:

    • 0: Remove mean (constant detrending).
    • 1: Remove linear trend using least squares regression (default).
    • 2+: Remove polynomial trend of specified order.

    If not provided, no detrending is applied.

  • standardize
    (bool, default: True ) –

    Whether to standardize each voxel's time series to z-scores.

  • cmap
    (str, default: "gray" ) –

    Matplotlib colormap name.

  • vmin
    (float, default: None ) –

    Minimum value for colormap. If not provided, uses mean - 2*std.

  • vmax
    (float, default: None ) –

    Maximum value for colormap. If not provided, uses mean + 2*std.

  • decimation_threshold
    (int or None, default: 800 ) –

    If the number of timepoints exceeds this value, data is downsampled along the time axis to improve plotting performance. Set to None to disable downsampling.

  • figsize
    (tuple[float, float], default: (10, 5) ) –

    Figure size in inches (width, height).

  • title
    (str, default: None ) –

    Plot title.

  • black_bg
    (bool, default: False ) –

    Whether to use a black figure background with white foreground elements (spines, ticks, labels). Use True for dark-themed figures.

  • ax
    (Axes, default: None ) –

    Axes to plot on. If not provided, creates new figure and axes.

Returns:

  • figure ( Figure or SubFigure ) –

    Figure object containing the carpet plot.

  • axes ( Axes ) –

    Axes object with the carpet plot.

Notes

Complex-valued data is converted to magnitude before processing.

This function was inspired by Nilearn's nilearn.plotting.plot_carpet.

References

  1. Power, Jonathan D. “A Simple but Useful Way to Assess fMRI Scan Qualities.” NeuroImage, vol. 154, July 2017, pp. 150–58. DOI.org (Crossref), https://doi.org/10.1016/j.neuroimage.2016.08.009

Examples:

>>> import xarray as xr
>>> data = xr.open_zarr("output.zarr")["iq"]
>>> fig, ax = data.fusi.plot.carpet()
>>> # With linear detrending.
>>> fig, ax = data.fusi.plot.carpet(detrend_order=1)
>>> # With mask.
>>> mask = np.abs(data.isel(time=0)) > threshold
>>> fig, ax = data.fusi.plot.carpet(mask=mask)

contours

contours(
    colors: dict[int | str, str] | str | None = None,
    linewidths: float = 1.5,
    linestyles: str = "solid",
    slice_mode: str = "z",
    slice_coords: list[float] | None = None,
    yincrease: bool = False,
    xincrease: bool = True,
    black_bg: bool = True,
    figure: Figure | None = None,
    axes: NDArray[Any] | None = None,
    **kwargs,
) -> VolumePlotter

Plot mask contours as a grid of 2D slice panels.

Displays contour lines for each labeled region across a grid of subplots. See confusius.plotting.plot_contours for full details.

Parameters:

  • colors
    (dict[int | str, str] or str, default: None ) –

    Color specification for contour lines. A dict maps each label (integer index or region acronym string) to a color; a str applies one color to all regions. If not provided, colors are derived from attrs["cmap"] and attrs["norm"] when present, otherwise from the tab10/tab20 colormap.

  • linewidths
    (float, default: 1.5 ) –

    Width of contour lines in points.

  • linestyles
    (str, default: "solid" ) –

    Line style for contour lines (e.g. "solid", "dashed").

  • slice_mode
    (str, default: "z" ) –

    Dimension along which to slice (e.g. "x", "y", "z"). After slicing, each panel must be 2D.

  • slice_coords
    (list[float], default: None ) –

    Coordinate values along slice_mode at which to extract slices. Slices are selected by nearest-neighbour lookup. If not provided, all coordinate values along slice_mode are used.

  • yincrease
    (bool, default: False ) –

    Whether the y-axis increases upward (True) or downward (False).

  • xincrease
    (bool, default: True ) –

    Whether the x-axis increases to the right (True) or left (False).

  • black_bg
    (bool, default: True ) –

    Whether to set the figure background to black.

  • figure
    (Figure, default: None ) –

    Existing figure to draw into. If not provided, a new figure is created.

  • axes
    (ndarray, default: None ) –

    Existing 2D array of matplotlib.axes.Axes to draw into. If not provided, new axes are created inside figure.

  • **kwargs

    Additional keyword arguments passed to matplotlib.axes.Axes.plot.

Returns:

  • VolumePlotter

    Object managing the figure, axes, and coordinate mapping for overlays.

Examples:

>>> import xarray as xr
>>> import confusius  # Register accessor.
>>> mask = xr.open_zarr("output.zarr")["roi_mask"]
>>> plotter = mask.fusi.plot.contours(colors={1: "red", 2: "blue"})
>>> # Overlay contours on an existing volume plot.
>>> volume = xr.open_zarr("output.zarr")["power_doppler"]
>>> plotter = volume.fusi.plot.volume(slice_mode="z")
>>> plotter.add_contours(mask, colors="yellow")

draw_napari_labels

draw_napari_labels(
    labels_layer_name: str = "labels",
    viewer: Viewer | None = None,
    **plot_kwargs,
) -> tuple[Viewer, Labels]

Open napari to interactively paint integer labels over fUSI data.

Displays the data as an image layer and adds an empty Labels layer on top. The user paints integer labels directly on the image using napari's brush tool. After painting, pass the returned Labels layer to [labels_from_layer][confusius.plotting.FUSIPlotAccessor.labels_from_layer] to obtain an integer label map in the same spatial coordinates as the data.

Parameters:

  • labels_layer_name
    (str, default: "labels" ) –

    Name assigned to the Labels layer added to the viewer.

  • viewer
    (Viewer, default: None ) –

    Existing napari viewer to add layers to. If not provided, a new viewer is created.

  • **plot_kwargs

    Additional keyword arguments forwarded to plot_napari for the image layer (e.g. colormap, contrast_limits).

Returns:

  • viewer ( Viewer ) –

    The napari viewer instance with the image and Labels layers.

  • labels_layer ( Labels ) –

    The empty Labels layer initialised to zeros. After painting labels in the viewer, pass it to [labels_from_layer][confusius.plotting.FUSIPlotAccessor.labels_from_layer] to convert the paintings to an integer label map.

Examples:

>>> import xarray as xr
>>> import confusius  # Register accessor.
>>> pwd = xr.open_zarr("output.zarr")["power_doppler"].compute()
>>> # Display time-averaged image with an interactive Labels layer.
>>> viewer, labels_layer = pwd.mean("time").fusi.plot.draw_napari_labels()
>>> # … paint labels in the viewer …
>>> # Convert painted labels to an integer label map.
>>> label_map = pwd.mean("time").fusi.plot.labels_from_layer(labels_layer)

labels_from_layer

labels_from_layer(labels_layer: Labels) -> DataArray

Convert a napari Labels layer to an integer label map DataArray.

Reads the integer array painted in labels_layer and wraps it in an xarray.DataArray whose spatial dimensions and coordinates match those of the data.

Parameters:

  • labels_layer
    (Labels) –

    A Labels layer populated by the user (e.g. via [draw_napari_labels][confusius.plotting.FUSIPlotAccessor.draw_napari_labels]). Integer values identify distinct regions; zero is the background.

Returns:

  • DataArray

    Integer DataArray with the same spatial dimensions and coordinates as the data. Zero values indicate background (unlabelled) voxels.

Examples:

>>> import xarray as xr
>>> import confusius  # Register accessor.
>>> pwd = xr.open_zarr("output.zarr")["power_doppler"].compute()
>>> viewer, labels_layer = pwd.mean("time").fusi.plot.draw_napari_labels()
>>> # … paint labels in the viewer …
>>> label_map = pwd.mean("time").fusi.plot.labels_from_layer(labels_layer)
>>> # Use the label map for region-based analysis.
>>> from confusius.extract import extract_with_labels
>>> signals = extract_with_labels(pwd, label_map)

napari

napari(
    show_colorbar: bool = True,
    show_scale_bar: bool = True,
    dim_order: tuple[str, ...] | None = None,
    viewer: Viewer | None = None,
    layer_type: Literal["image", "labels"] = "image",
    **layer_kwargs,
) -> tuple[Viewer, Image | Labels]

Display data in napari viewer.

Parameters:

  • show_colorbar
    (bool, default: True ) –

    Whether to show the colorbar. Only applies to image layers.

  • show_scale_bar
    (bool, default: True ) –

    Whether to show the scale bar.

  • dim_order
    (tuple[str, ...], default: None ) –

    Dimension ordering for the spatial axes (last three dimensions). If not provided, the ordering of the last three dimensions in data is used.

  • viewer
    (Viewer, default: None ) –

    Existing napari viewer to add the layer to. If not provided, a new viewer is created.

  • layer_type
    ((image, labels), default: "image" ) –

    Type of layer to create. Use "image" for fUSI data and "labels" for ROI masks, segmentations, or other label data.

  • **layer_kwargs

    Additional keyword arguments passed to the layer creation method. For image layers, if data.attrs contains "cmap" and "colormap" is not in layer_kwargs, the attribute is used as the colormap.

Returns:

  • viewer ( Viewer ) –

    The napari viewer instance with the layer added.

  • layer ( Image or Labels ) –

    The layer added to the viewer.

Notes

If all spatial dimensions have coordinates, their spacing is used as the scale parameter for napari to ensure correct physical scaling. If any spatial dimension is missing coordinates, no scaling is applied. The spacing is computed as the median difference between consecutive coordinate values.

For unitary dimensions (e.g., a single-slice elevation axis in 2D+t data), the spacing cannot be inferred from coordinates. In that case, the function looks for a voxdim attribute on the coordinate variable (data.coords[dim].attrs["voxdim"]) and uses it as the spacing. If no such attribute is found, unit spacing is assumed and a warning is emitted.

Examples:

>>> import xarray as xr
>>> import confusius  # Register accessor.
>>> data = xr.open_zarr("output.zarr")["iq"]
>>> viewer, layer = data.fusi.plot.napari()
>>> # Custom contrast limits
>>> viewer, layer = data.fusi.plot.napari(contrast_limits=(0, 100))
>>> # Different dimension ordering (e.g., depth, elevation, lateral)
>>> viewer, layer = data.fusi.plot.napari(dim_order=("y", "z", "x"))
>>> # Add a second dataset as a new layer in an existing viewer
>>> viewer, layer = data1.fusi.plot.napari()
>>> viewer, layer = data2.fusi.plot.napari(viewer=viewer)
>>> # Display ROI labels (e.g., segmentation mask)
>>> roi_mask = xr.open_zarr("output.zarr")["roi_mask"]
>>> viewer, layer = roi_mask.fusi.plot.napari(layer_type="labels")
>>> # Overlay labels on existing image
>>> viewer, layer = data.fusi.plot.napari()
>>> viewer, layer = roi_mask.fusi.plot.napari(viewer=viewer, layer_type="labels")

volume

volume(
    slice_coords: list[float] | None = None,
    slice_mode: str = "z",
    nrows: int | None = None,
    ncols: int | None = None,
    threshold: float | None = None,
    threshold_mode: Literal["lower", "upper"] = "lower",
    cmap: str | Colormap | None = None,
    norm: Normalize | None = None,
    vmin: float | None = None,
    vmax: float | None = None,
    alpha: float = 1.0,
    show_colorbar: bool = True,
    cbar_label: str | None = None,
    show_titles: bool = True,
    show_axis_labels: bool = True,
    show_axis_ticks: bool = True,
    show_axes: bool = True,
    yincrease: bool = False,
    xincrease: bool = True,
    black_bg: bool = True,
    figure: Figure | None = None,
    axes: NDArray[Any] | None = None,
    dpi: int | None = None,
) -> VolumePlotter

Plot 2D slices of a volume as a matplotlib subplot grid.

See confusius.plotting.plot_volume for full details.

Parameters:

  • slice_coords
    (list[float], default: None ) –

    Coordinate values along slice_mode at which to extract slices. Slices are selected by nearest-neighbour lookup. If not provided, all coordinate values along slice_mode are used.

  • slice_mode
    (str, default: "z" ) –

    Dimension along which to slice (e.g. "x", "y", "z", "time"). After slicing, each panel must be 2D.

  • nrows
    (int, default: None ) –

    Number of rows in the subplot grid. If not provided, computed automatically together with ncols to produce a near-square layout.

  • ncols
    (int, default: None ) –

    Number of columns in the subplot grid. If not provided, computed automatically together with nrows.

  • threshold
    (float, default: None ) –

    Threshold applied to |data|. See threshold_mode for the masking direction. If not provided, no thresholding is applied.

  • threshold_mode
    ((lower, upper), default: "lower" ) –

    Controls how threshold is applied:

    • "lower": set pixels where |data| < threshold to NaN.
    • "upper": set pixels where |data| > threshold to NaN.
  • cmap
    (str or Colormap, default: None ) –

    Colormap. When not provided, falls back to data.attrs["cmap"] if present, otherwise "gray".

  • norm
    (Normalize, default: None ) –

    Normalization instance (e.g. BoundaryNorm for integer label maps). When not provided, falls back to data.attrs["norm"] if present. When a norm is active, vmin and vmax are ignored.

  • vmin
    (float, default: None ) –

    Lower bound of the colormap. Defaults to the 2nd percentile. Ignored when norm is provided explicitly (that is, not just inherited from data attributes).

  • vmax
    (float, default: None ) –

    Upper bound of the colormap. Defaults to the 98th percentile. Ignored when norm is provided explicitly (that is, not just inherited from data attributes).

  • alpha
    (float, default: 1.0 ) –

    Opacity of the image.

  • show_colorbar
    (bool, default: True ) –

    Whether to add a shared colorbar to the figure.

  • cbar_label
    (str, default: None ) –

    Label for the colorbar.

  • show_titles
    (bool, default: True ) –

    Whether to display subplot titles showing the slice coordinate.

  • show_axis_labels
    (bool, default: True ) –

    Whether to display axis labels (with units when available).

  • show_axis_ticks
    (bool, default: True ) –

    Whether to display axis tick labels.

  • show_axes
    (bool, default: True ) –

    Whether to show all axis decorations (spines, ticks, labels). When False, overrides show_axis_labels and show_axis_ticks.

  • yincrease
    (bool, default: False ) –

    Whether the y-axis increases upward (True) or downward (False).

  • xincrease
    (bool, default: True ) –

    Whether the x-axis increases to the right (True) or left (False).

  • black_bg
    (bool, default: True ) –

    Whether to set the figure background to black.

  • figure
    (Figure, default: None ) –

    Existing figure to draw into. If not provided, a new figure is created.

  • axes
    (ndarray, default: None ) –

    Existing 2D array of matplotlib.axes.Axes to draw into. If not provided, new axes are created inside figure.

  • dpi
    (int, default: None ) –

    Figure resolution in dots per inch. Ignored when figure is provided.

Returns:

  • VolumePlotter

    Object managing the figure, axes, and coordinate mapping for overlays.

Raises:

  • ValueError

    If slice_mode is not a dimension of the data.

  • ValueError

    If the data is not 3D after squeezing unitary dimensions.

  • ValueError

    If axes is provided but does not contain enough elements for all slices.

Examples:

>>> import xarray as xr
>>> import confusius  # Register accessor.
>>> data = xr.open_zarr("output.zarr")["power_doppler"]
>>> plotter = data.fusi.plot.volume(slice_mode="z")
>>> # dB-scale data with upper threshold to suppress far-field noise.
>>> plotter = data.fusi.scale.db().fusi.plot.volume(
...     slice_mode="z",
...     threshold=-60,
...     threshold_mode="upper",
...     cmap="hot",
...     black_bg=True,
... )

FUSIRegistrationAccessor

Accessor for registration operations on fUSI data.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap.

Examples:

>>> import xarray as xr
>>> data = xr.open_zarr("output.zarr")["power_doppler"]
>>> registered = data.fusi.register.volumewise(reference_time=0)

Methods:

  • to_volume

    Register this volume to a fixed reference volume.

  • volumewise

    Register all volumes to a reference time point.

to_volume

to_volume(
    fixed: DataArray,
    *,
    transform: Literal[
        "translation", "rigid", "affine", "bspline"
    ] = "rigid",
    metric: Literal[
        "correlation", "mattes_mi"
    ] = "correlation",
    number_of_histogram_bins: int = 50,
    learning_rate: float | Literal["auto"] = "auto",
    number_of_iterations: int = 100,
    convergence_minimum_value: float = 1e-06,
    convergence_window_size: int = 10,
    initialization: Literal[
        "geometry", "moments", "none"
    ] = "geometry",
    optimizer_weights: list[float] | None = None,
    mesh_size: tuple[int, int, int] = (10, 10, 10),
    use_multi_resolution: bool = False,
    shrink_factors: Sequence[int] = (6, 2, 1),
    smoothing_sigmas: Sequence[int] = (6, 2, 1),
    resample: bool = False,
    resample_interpolation: Literal[
        "linear", "bspline"
    ] = "linear",
    show_progress: bool = False,
    plot_metric: bool = True,
    plot_composite: bool = True,
) -> tuple[DataArray, NDArray[float64] | DataArray | None]

Register this volume to a fixed reference volume.

Parameters:

  • fixed
    (DataArray) –

    Reference volume to register to.

  • transform
    ((translation, rigid, affine, bspline), default: "translation" ) –

    Type of transform to use for registration.

  • metric
    ((correlation, mattes_mi), default: "correlation" ) –

    Similarity metric for registration.

  • number_of_histogram_bins
    (int, default: 50 ) –

    Number of histogram bins (only used when metric="mattes_mi").

  • learning_rate
    (float or auto, default: "auto" ) –

    Optimizer step size in normalised units (after SetOptimizerScalesFromPhysicalShift). "auto" re-estimates the rate at every iteration.

  • number_of_iterations
    (int, default: 100 ) –

    Maximum number of optimizer iterations.

  • convergence_minimum_value
    (float, default: 1e-6 ) –

    Convergence threshold for early stopping.

  • convergence_window_size
    (int, default: 10 ) –

    Window size for convergence check.

  • initialization
    ((geometry, moments, none), default: "geometry" ) –

    Transform initialization strategy. Ignored for bspline transforms.

  • optimizer_weights
    (list of float or None, default: None ) –

    Per-parameter weights applied on top of auto-estimated scales via SetOptimizerWeights(). None applies no additional weighting. The weight for each parameter is multiplied into the effective step size: 0 freezes a parameter, values in (0, 1) slow it down, 1 leaves it unchanged. For the 3D Euler transform the order is [angleX, angleY, angleZ, tx, ty, tz]; to disable rotations around x and y use [0, 0, 1, 1, 1, 1].

  • mesh_size
    (tuple of int, default: (10, 10, 10) ) –

    BSpline mesh size. Only used when transform="bspline".

  • use_multi_resolution
    (bool, default: False ) –

    Whether to use a multi-resolution pyramid during registration.

  • shrink_factors
    (sequence of int, default: (6, 2, 1) ) –

    Downsampling factor at each pyramid level, from coarsest to finest. Only used when use_multi_resolution=True.

  • smoothing_sigmas
    (sequence of int, default: (6, 2, 1) ) –

    Gaussian smoothing sigma (in voxels) at each pyramid level, from coarsest to finest. Only used when use_multi_resolution=True.

  • resample
    (bool, default: False ) –

    Whether to resample the moving volume into the fixed volume's space. When False (the default), only the transform is estimated and the moving volume is returned unchanged.

  • resample_interpolation
    ((linear, bspline), default: "linear" ) –

    Interpolation method used for the final resample step.

  • show_progress
    (bool, default: False ) –

    Whether to display a live progress plot during registration.

  • plot_metric
    (bool, default: True ) –

    Whether to include the optimizer metric curve in the progress plot. Ignored when show_progress=False.

  • plot_composite
    (bool, default: True ) –

    Whether to include a fixed/moving composite overlay in the progress plot. Ignored when show_progress=False.

Returns:

  • registered ( DataArray ) –

    Registered volume. When resample=True, resampled onto the fixed grid; otherwise the original moving volume with registration metadata added.

  • affine ( (N+1, N+1) numpy.ndarray or xarray.DataArray or None ) –

    Estimated registration transform. For linear transforms, a homogeneous affine matrix. For transform="bspline", a DataArray encoding the B-spline control-point grid.

Examples:

>>> moving.fusi.register.to_volume(fixed)
>>> moving.fusi.register.to_volume(fixed, resample=True)
>>> moving.fusi.register.to_volume(fixed, show_progress=True)

volumewise

volumewise(
    *,
    reference_time: int = 0,
    n_jobs: int = -1,
    transform: Literal[
        "translation", "rigid", "affine"
    ] = "rigid",
    metric: Literal[
        "correlation", "mattes_mi"
    ] = "correlation",
    number_of_histogram_bins: int = 50,
    learning_rate: float | Literal["auto"] = "auto",
    number_of_iterations: int = 100,
    convergence_minimum_value: float = 1e-06,
    convergence_window_size: int = 10,
    initialization: Literal[
        "geometry", "moments", "none"
    ] = "geometry",
    optimizer_weights: list[float] | None = None,
    use_multi_resolution: bool = False,
    shrink_factors: Sequence[int] = (6, 2, 1),
    smoothing_sigmas: Sequence[int] = (6, 2, 1),
    resample_interpolation: Literal[
        "linear", "bspline"
    ] = "linear",
) -> DataArray

Register all volumes to a reference time point.

Parameters:

  • reference_time
    (int, default: 0 ) –

    Index of the time point to use as registration target.

  • n_jobs
    (int, default: -1 ) –

    Number of parallel jobs. -1 uses all available CPUs. Use 1 for serial processing.

  • transform
    ((translation, rigid, affine), default: "translation" ) –

    Type of transform to use for registration.

  • metric
    ((correlation, mattes_mi), default: "correlation" ) –

    Similarity metric for registration.

  • number_of_histogram_bins
    (int, default: 50 ) –

    Number of histogram bins (only used when metric="mattes_mi").

  • learning_rate
    (float or auto, default: "auto" ) –

    Optimizer step size in normalised units (after SetOptimizerScalesFromPhysicalShift). "auto" re-estimates the rate at every iteration.

  • number_of_iterations
    (int, default: 100 ) –

    Maximum number of optimizer iterations.

  • convergence_minimum_value
    (float, default: 1e-6 ) –

    Convergence threshold for early stopping.

  • convergence_window_size
    (int, default: 10 ) –

    Window size for convergence check.

  • initialization
    ((geometry, moments, none), default: "geometry" ) –

    Transform initialization strategy.

  • optimizer_weights
    (list of float or None, default: None ) –

    Per-parameter weights applied on top of auto-estimated scales via SetOptimizerWeights(). None applies no additional weighting. The weight for each parameter is multiplied into the effective step size: 0 freezes a parameter, values in (0, 1) slow it down, 1 leaves it unchanged. For the 3D Euler transform the order is [angleX, angleY, angleZ, tx, ty, tz]; to disable rotations around x and y use [0, 0, 1, 1, 1, 1].

  • use_multi_resolution
    (bool, default: False ) –

    Whether to use a multi-resolution pyramid during registration.

  • shrink_factors
    (sequence of int, default: (6, 2, 1) ) –

    Downsampling factor at each pyramid level, from coarsest to finest. Only used when use_multi_resolution=True.

  • smoothing_sigmas
    (sequence of int, default: (6, 2, 1) ) –

    Gaussian smoothing sigma (in voxels) at each pyramid level, from coarsest to finest. Only used when use_multi_resolution=True.

  • resample_interpolation
    ((linear, bspline), default: "linear" ) –

    Interpolation method used for the final resample step.

Returns:

  • DataArray

    Registered data with same coordinates and attributes.

Examples:

>>> data.fusi.register.volumewise(reference_time=0)
>>> data.fusi.register.volumewise(reference_time=0, transform="translation")

FUSIScaleAccessor

Accessor for scaling operations on fUSI data.

This accessor provides various scaling transformations commonly used in functional ultrasound imaging analysis.

Parameters:

  • xarray_obj

    (DataArray) –

    The DataArray to wrap.

Examples:

>>> import xarray as xr
>>> data = xr.DataArray([1, 10, 100, 1000])
>>> data.fusi.scale.db(factor=20)
<xarray.DataArray (dim_0: 4)>
array([-60., -40., -20.,   0.])

Methods:

  • db

    Convert data to decibel scale relative to maximum value.

  • log

    Apply natural logarithm to data.

  • power

    Apply power scaling to data.

db

db(factor: int = 10) -> DataArray

Convert data to decibel scale relative to maximum value.

Parameters:

  • factor
    (int, default: 10 ) –

    Scaling factor for decibel conversion. Use 10 for power quantities (default), 20 for amplitude quantities.

Returns:

  • DataArray

    Data in decibel scale. Values are in range [factor * log(min/max), 0] dB.

Notes

Warnings are suppressed for zero/negative values, which are set to -inf.

If the input data is backed by Dask (lazily loaded), the global maximum is computed eagerly when this method is called. This avoids re-triggering a full array scan on each frame access (e.g. during napari playback), at the cost of a one-time upfront computation.

Examples:

>>> data = xr.DataArray([1, 10, 100, 1000])
>>> data.fusi.scale.db(factor=20)
<xarray.DataArray (dim_0: 4)>
array([-60., -40., -20.,   0.])

log

log() -> DataArray

Apply natural logarithm to data.

Returns:

  • DataArray

    Natural logarithm of the data.

Examples:

>>> import numpy as np
>>> data = xr.DataArray([1, np.e, np.e**2])
>>> data.fusi.scale.log()
<xarray.DataArray (dim_0: 3)>
array([0., 1., 2.])

power

power(exponent: float = 0.5) -> DataArray

Apply power scaling to data.

Parameters:

  • exponent
    (float, default: 0.5 ) –

    Power exponent to apply. Default is 0.5 (square root). Use 2.0 for squaring, etc.

Returns:

  • DataArray

    Power-scaled data.

Examples:

>>> data = xr.DataArray([1, 4, 9, 16])
>>> data.fusi.scale.power(exponent=0.5)  # Square root
<xarray.DataArray (dim_0: 4)>
array([1., 2., 3., 4.])

db_scale

db_scale(data: DataArray, factor: int = 10) -> DataArray

Convert data to decibel scale relative to maximum value.

Parameters:

  • data

    (DataArray) –

    Input DataArray.

  • factor

    (int, default: 10 ) –

    Scaling factor for decibel conversion. Use 10 for power quantities (default), 20 for amplitude quantities.

Returns:

  • DataArray

    Data in decibel scale. Values are in range [factor * log(min/max), 0] dB.

Notes

Warnings are suppressed for zero/negative values, which are set to -inf.

If the input data is backed by Dask (lazily loaded), the global maximum is computed eagerly when this function is called. This avoids re-triggering a full array scan on each frame access (e.g. during napari playback), at the cost of a one-time upfront computation.

Examples:

>>> import xarray as xr
>>> import numpy as np
>>> data = xr.DataArray([1, 10, 100, 1000])
>>> db_scale(data, factor=20)

log_scale

log_scale(data: DataArray) -> DataArray

Apply natural logarithm to data.

Parameters:

  • data

    (DataArray) –

    Input data array.

Returns:

  • DataArray

    Natural logarithm of the data.

Notes

Warnings are suppressed for zero/negative values, which are set to -inf/nan.

Examples:

>>> import xarray as xr
>>> import numpy as np
>>> data = xr.DataArray([1, np.e, np.e**2])
>>> log_scale(data)

power_scale

power_scale(
    data: DataArray, exponent: float = 0.5
) -> DataArray

Apply power scaling to data.

Parameters:

  • data

    (DataArray) –

    Input data array.

  • exponent

    (float, default: 0.5 ) –

    Power exponent to apply. Default is 0.5 (square root). Use 2.0 for squaring, etc.

Returns:

  • DataArray

    Power-scaled data.

Examples:

>>> import xarray as xr
>>> data = xr.DataArray([1, 4, 9, 16])
>>> power_scale(data, exponent=0.5)  # Square root