deepinterpolation-app / core /deepinterp_engine.py
katospiegel's picture
Deploy deepinterpolation-app as an imaging-plaza Gradio Space (SDSC)
8f6f117 verified
Raw
History Blame Contribute Delete
3.38 kB
"""The 'deepinterpolation' engine: real Allen Institute DeepInterpolation.
This is the wired slot for the actual TensorFlow/Keras `deepinterpolation`
package (https://github.com/AllenInstitute/deepinterpolation). It is NOT part of
the light default image — install it via Dockerfile.deepinterp and point
DEEPINTERP_MODEL at a pretrained inference model (HDF5).
The learned network predicts frame t from a stack of its temporal neighbors
(center excluded) just like the fast engine, but with a deep U-Net that has been
trained on real two-photon / Ophys data, so it removes far more noise.
"""
from __future__ import annotations
import os
import numpy as np
def available() -> bool:
try:
import deepinterpolation # noqa: F401
return True
except Exception: # noqa: BLE001
return False
def interpolate(movie: np.ndarray, pre: int = 30, post: int = 30,
omit: int = 0) -> np.ndarray:
"""Run real DeepInterpolation inference over a (T, H, W) movie.
Requires the `deepinterpolation` package (TensorFlow) and a pretrained model
given by env DEEPINTERP_MODEL. Raises a clear error if either is missing so
the UI/API can fall back or report it.
"""
model_path = os.environ.get("DEEPINTERP_MODEL", "")
if not available():
raise RuntimeError(
"The 'deepinterpolation' package is not installed. Build the image "
"with Dockerfile.deepinterp to use this engine."
)
if not model_path or not os.path.exists(model_path):
raise RuntimeError(
"Set DEEPINTERP_MODEL to a pretrained DeepInterpolation inference "
"model (HDF5). See https://github.com/AllenInstitute/deepinterpolation."
)
# Real inference path. Kept import-local so the light image never imports TF.
import tempfile
import tifffile
from deepinterpolation.generic import ClassLoader
movie = np.asarray(movie, dtype=np.float32)
with tempfile.TemporaryDirectory() as td:
in_tif = os.path.join(td, "input.tif")
out_base = os.path.join(td, "di_out")
tifffile.imwrite(in_tif, movie)
generator_param = {
"type": "generator",
"name": "SingleTifGenerator",
"pre_frame": int(pre),
"post_frame": int(post),
"pre_post_omission": int(omit),
"train_path": in_tif,
"batch_size": 1,
"start_frame": int(pre),
"end_frame": int(movie.shape[0] - post - 1),
}
inference_param = {
"type": "inferrence",
"name": "core_inferrence",
"model_path": model_path,
"output_file": out_base + ".h5",
}
data_generator = ClassLoader(generator_param).find_and_build()(generator_param)
inferrence_class = ClassLoader(inference_param).find_and_build()(
inference_param, data_generator
)
inferrence_class.run()
import h5py
with h5py.File(out_base + ".h5", "r") as f:
pred = np.asarray(f["data"][:]).astype(np.float32)
pred = np.squeeze(pred)
# The network only produces frames [pre, T-post); pad edges with the input so
# the output has the same shape (T, H, W) the contract expects.
out = movie.copy()
out[int(pre):int(pre) + pred.shape[0]] = pred
return out