Skip to content

Commit

Permalink
Merge pull request #16 from rhoitink/develop
Browse files Browse the repository at this point in the history
Pull request for v1.6.2
  • Loading branch information
rhoitink authored Mar 20, 2024
2 parents 78a3e83 + 233f704 commit 10163cd
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 23 deletions.
14 changes: 9 additions & 5 deletions CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# Visit https://bit.ly/cffinit to generate yours today!

cff-version: 1.2.0
title: Simulated Microscopy
message: >-
If you use this software, please cite it using the
metadata from this file.
title: >-
Simulated Microscopy: A Python Package for Simulation of
Confocal Microscopy Data based on Particle Coordinates
message: 'If you use this software, please cite using the Zenodo DOI.'
type: software
authors:
- given-names: Leroy Daniël
Expand All @@ -15,6 +15,10 @@ authors:
Soft Condensed Matter & Biophysics, Debye Institute
for Nanomaterials Science, Utrecht University
orcid: 'https://orcid.org/0000-0002-3470-0078'
identifiers:
- type: doi
value: 10.5281/zenodo.10678180
description: Zenodo
repository-code: 'https://github.com/rhoitink/simulatedmicroscopy'
url: 'https://rhoitink.github.io/simulatedmicroscopy/'
abstract: >-
Expand All @@ -28,5 +32,5 @@ keywords:
- point spread function
- image generation
license: MIT
version: "v1.6.1"
version: v1.6.1
date-released: '2024-02-19'
80 changes: 63 additions & 17 deletions src/simulatedmicroscopy/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

import h5py
import numpy as np
import scipy.signal
import skimage.measure

from .input import Coordinates
Expand Down Expand Up @@ -162,7 +161,7 @@ def save_h5file(

@classmethod
def load_h5file(cls, filename: str) -> type[Image]:
"""Load data from h5 file (custom format)
"""Load data from h5 file (custom format or HuygensImage)
Parameters
----------
Expand All @@ -176,19 +175,40 @@ def load_h5file(cls, filename: str) -> type[Image]:
"""

with h5py.File(filename, "r") as f:
image = f["Image"][()]
pixel_sizes = [
float(f[f"Metadata/DimensionScale{dim.upper()}"][()])
for dim in list("zyx")
]
if "PixelCoordinates" in f["Metadata"]:
pixel_coordinates = f["Metadata/PixelCoordinates"][()]
root_elements = list(f.keys())
if "Image" in root_elements and "Metadata" in root_elements:
return cls._load_h5file_custom(f)
else:
pixel_coordinates = None
return HuygensImage(filename)

@staticmethod
def _load_h5file_custom(f: h5py.File) -> type[Image]:
"""Load data from h5 file (custom format)
Parameters
----------
f : h5py.File
File to load from
Returns
-------
Image
Resulting image with correct pixel sizes
"""

metadata = dict(f["Metadata"].attrs)
image = f["Image"][()]
pixel_sizes = [
float(f[f"Metadata/DimensionScale{dim.upper()}"][()])
for dim in list("zyx")
]
if "PixelCoordinates" in f["Metadata"]:
pixel_coordinates = f["Metadata/PixelCoordinates"][()]
else:
pixel_coordinates = None

metadata = dict(f["Metadata"].attrs)

im = cls(image=image, pixel_sizes=pixel_sizes, metadata=metadata)
im = Image(image=image, pixel_sizes=pixel_sizes, metadata=metadata)
if pixel_coordinates is not None:
im.pixel_coordinates = pixel_coordinates
return im
Expand Down Expand Up @@ -398,9 +418,21 @@ def convolve(self, other: type[Image]) -> type[Image]:
"Cannot convolve images with different pixel sizes"
)

self.image = scipy.signal.convolve(
self.image, other.image, mode="same"
)
try:
import cupy as cp
from cupyx.scipy import signal as cusignal

self.image = cusignal.fftconvolve(
cp.asarray(self.image), cp.asarray(other.image), mode="same"
).get()
except ImportError:
# resort to scipy if cupy is not available

import scipy.signal

self.image = scipy.signal.convolve(
self.image, other.image, mode="same"
)

self.is_convolved = True
self.metadata["is_convolved"] = True
Expand Down Expand Up @@ -566,9 +598,23 @@ def __init__(self, filename: str | Path) -> None:
raise FileNotFoundError("Requested file does not exist")

with h5py.File(filepath, "r") as f:
image = np.squeeze(f[filepath.stem + "/ImageData/Image"][()])
root_elements = list(f.keys())
if len(root_elements) == 1:
root_element = root_elements[0]
else:
# find root element with ImageData
root_element = None
for re in root_elements:
if "ImageData" in f[re].keys():
root_element = re
break
if root_element is None:
raise ValueError(
"No ImageData found in the file, cannot load image"
)
image = np.squeeze(f[root_element + "/ImageData/Image"][()])
pixel_sizes = [
float(f[filepath.stem + f"/ImageData/DimensionScale{dim}"][()])
float(f[root_element + f"/ImageData/DimensionScale{dim}"][()])
for dim in list("ZYX")
]

Expand Down
21 changes: 20 additions & 1 deletion tests/test_image.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import pytest
from simulatedmicroscopy import HuygensImage, Image
from simulatedmicroscopy import HuygensImage, Image, HuygensPSF


def create_demo_image():
Expand Down Expand Up @@ -40,6 +40,25 @@ def test_huygens_notexisting(tmp_path):
with pytest.raises(FileNotFoundError):
HuygensImage(tmp_path / "thisfiledoesnotexist.h5")

def test_huygens_loading(tmp_path):
import h5py
im = create_demo_image()
pixel_sizes = im.get_pixel_sizes()
filename = tmp_path / "testfile.hdf5"
with h5py.File(filename, "w") as f:
root = f.create_group("testfile")
root.create_dataset("ImageData/Image", data=im.image)
[root.create_dataset(f"ImageData/DimensionScale{dim}", data=pixel_sizes[i]) for i,dim in enumerate(list("ZYX"))]


im_loaded = im.load_h5file(filename)
im_loaded_huygens_im = HuygensImage(filename)
im_loaded_huygens_psf = HuygensPSF(filename)


assert im_loaded == im
assert im_loaded_huygens_im == im
assert im_loaded_huygens_psf == im

@pytest.mark.parametrize(
"unit,conversionfactor",
Expand Down

0 comments on commit 10163cd

Please sign in to comment.