-
Notifications
You must be signed in to change notification settings - Fork 68
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
adding method to use installed ilastik instance
- Loading branch information
Shannon Axelrod
committed
Jan 22, 2020
1 parent
99a7f43
commit be32e23
Showing
3 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,6 +5,7 @@ | |
python-dateutil < 2.8.1 | ||
click | ||
dataclasses==0.6 | ||
h5py | ||
jsonschema | ||
matplotlib | ||
numpy != 1.13.0 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
121 changes: 121 additions & 0 deletions
121
starfish/core/image/Filter/ilastik_pre_trained_probability.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import subprocess | ||
import tempfile | ||
from pathlib import Path | ||
from typing import Optional, Union | ||
|
||
import h5py | ||
import numpy as np | ||
import scipy.ndimage as ndi | ||
from skimage.filters import threshold_otsu | ||
|
||
from starfish.core.imagestack.imagestack import ImageStack | ||
from ._base import FilterAlgorithm | ||
|
||
|
||
class IlastikPretrainedProbability(FilterAlgorithm): | ||
""" | ||
Use an existing ilastik pixel classifier to generate a probability image for a dapi image. | ||
NOTE: This api may not be used without a downloaded and installed version of Ilastik. Visit | ||
https://www.ilastik.org/download.html to download. | ||
Parameters | ||
---------- | ||
ilastik_executable: Union[Path, str] | ||
Path to run_ilastik.sh needed for running ilastik in headless mode. Typically the script is | ||
located: "/Applications/{ILASTIK_VERSION}/Contents/ilastik-release/run_ilastik.sh" | ||
ilastik_project: Union[Path, str] | ||
path to ilastik project .ilp file | ||
""" | ||
|
||
def __init__(self, ilastik_executable: Union[Path, str], ilastik_project: Union[Path, str]): | ||
ilastik_executable = Path(ilastik_executable) | ||
if not ilastik_executable.exists(): | ||
raise EnvironmentError("Can not find run_ilastik.sh. Make sure you've provided the " | ||
"correct location. If you need to download ilastik please" | ||
" visit: https://www.ilastik.org/download.html") | ||
self.ilastik_executable = ilastik_executable | ||
self.ilastik_project = ilastik_project | ||
|
||
def run( | ||
self, | ||
stack: ImageStack, | ||
in_place: bool = False, | ||
verbose: bool = False, | ||
n_processes: Optional[int] = None, | ||
*args, | ||
) -> Optional[ImageStack]: | ||
""" | ||
Use a pre trained probability pixel classification model to generate probabilites | ||
for a dapi image | ||
Parameters | ||
---------- | ||
stack : ImageStack | ||
Dapi image to be run through ilastik. | ||
in_place : bool | ||
This parameter is ignored for this filter. | ||
verbose : bool | ||
This parameter is ignored for this filter. | ||
n_processes : Optional[int] | ||
This parameter is ignored for this filter. | ||
Returns | ||
------- | ||
ImageStack : | ||
A new ImageStack created from the cell probabilities provided by ilastik. | ||
""" | ||
if stack.num_rounds != 1: | ||
raise ValueError( | ||
f"{IlastikPretrainedProbability.__name__} given an image with more than one round " | ||
f"{stack.num_rounds}") | ||
if stack.num_chs != 1: | ||
raise ValueError( | ||
f"{IlastikPretrainedProbability.__name__} given an image with more than one channel" | ||
f"{stack.num_chs}") | ||
|
||
# temp files | ||
temp_dir = tempfile.TemporaryDirectory() | ||
dapi_file = f"{temp_dir.name}_dapi.npy" | ||
output_file = f"{temp_dir.name}_dapi_Probabilities.h5" | ||
np.save(dapi_file, stack.xarray.values.squeeze()) | ||
|
||
# env {} is needed to fix the weird virtualenv stuff | ||
subprocess.check_call( | ||
[self.ilastik_executable, | ||
'--headless', | ||
'--project', | ||
self.ilastik_project, | ||
"--output_filename_format", | ||
output_file, | ||
dapi_file], env={}) # type: ignore | ||
|
||
return self.import_ilastik_probabilities(output_file) | ||
|
||
@classmethod | ||
def import_ilastik_probabilities(cls, path_to_h5_file: Union[str, Path] | ||
) -> ImageStack: | ||
""" | ||
Import cell probabilities provided by ilastik as an ImageStack. | ||
Parameters | ||
---------- | ||
path_to_h5_file : Union[str, Path] | ||
Path to the .h5 file outputted by ilastik | ||
Returns | ||
------- | ||
ImageStack : | ||
A new ImageStack created from the cell probabilities provided by ilastik. | ||
""" | ||
|
||
h5 = h5py.File(path_to_h5_file) | ||
probability_images = h5["exported_data"][:] | ||
h5.close() | ||
cell_probabilities, _ = probability_images[:, :, 0], probability_images[:, :, 1] | ||
cell_threshold = threshold_otsu(cell_probabilities) | ||
label_array = ndi.label(cell_probabilities > cell_threshold)[0] | ||
# Add flat dims to make 5d tensor | ||
label_array = label_array[np.newaxis, np.newaxis, np.newaxis, ...] | ||
return ImageStack.from_numpy(label_array) |