Source code for linumpy.gpu.interface

"""GPU implementation of tissue interface detection.

Mirrors the CPU path in :func:`linumpy.geometry.interface.find_tissue_interface`
but routes the heavy filters through ``cupyx.scipy.ndimage`` to avoid
host-device round trips when the caller already holds GPU data or when
the volume is large enough that the transfer cost is amortised.
"""

from typing import Any

import numpy as np

from . import to_cpu


[docs] def find_tissue_interface_gpu( vol: Any, s_xy: int = 15, s_z: int = 2, use_log: bool = True, order: int = 1, detect_cutting_errors: bool = False, ) -> np.ndarray: """GPU equivalent of ``find_tissue_interface`` (no mask path). Always returns a NumPy array of integer depths so callers do not need to be aware of the device. """ import cupy as cp from cupyx.scipy.ndimage import gaussian_filter1d, uniform_filter vol_gpu = cp.asarray(vol) if use_log: vol_p = vol_gpu.astype(cp.float32, copy=True) positive = vol_gpu > 0 vol_p[positive] = cp.log(vol_gpu[positive]) else: vol_p = vol_gpu vol_p = uniform_filter(vol_p, (s_xy, s_xy, 0)) vol_g = gaussian_filter1d(vol_p, s_z, axis=2, order=order) z0 = cp.ceil(vol_g.argmax(axis=2) + s_z * 0.5).astype(cp.int64) if detect_cutting_errors: vol_p = gaussian_filter1d(vol_p, s_z, axis=2, order=0) z0_p = cp.abs(vol_p).argmax(axis=2) mask_max = z0_p < z0 z0 = cp.where(mask_max, z0_p, z0) return to_cpu(z0)