Skip to content

Commit

Permalink
[auximg 12/13] Switch aux images to use ImageStack
Browse files Browse the repository at this point in the history
  • Loading branch information
Tony Tung authored and ttung committed Jun 1, 2018
1 parent 105559c commit a415ef3
Show file tree
Hide file tree
Showing 10 changed files with 54 additions and 30 deletions.
57 changes: 39 additions & 18 deletions starfish/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@

import numpy as np
import pandas as pd
from slicedimage import ImageFormat
from slicedimage.io import resolve_url, resolve_path_or_url
from slicedimage import ImageFormat, TileSet, Tile
from slicedimage.io import resolve_path_or_url, Writer

from starfish.constants import Indices
from starfish.constants import Coordinates, Indices
from .image import ImageStack
from .munge import list_to_stack

Expand Down Expand Up @@ -41,11 +41,7 @@ def read(self, in_json_path_or_url):

def _read_aux(self):
for aux_key, aux_data in self.org['auxiliary_images'].items():
name_or_url = aux_data['file']
img_format = ImageFormat[aux_data['tile_format']]
backend, name, _ = resolve_url(name_or_url, self.baseurl)
with backend.read_file_handle(name) as fh:
self.aux_dict[aux_key] = img_format.reader_func(fh)
self.aux_dict[aux_key] = ImageStack.from_url(aux_data, self.baseurl)

@classmethod
def from_experiment_json(cls, json_url: str):
Expand Down Expand Up @@ -83,10 +79,7 @@ def _write_stack(self, dir_name):

def _write_aux(self, dir_name):
for aux_key, aux_data in self.org['auxiliary_images'].items():
fname = os.path.splitext(aux_data['file'])[0]
aux_data['file'] = "{}.{}".format(fname, ImageFormat.NUMPY.file_ext)
aux_data['tile_format'] = ImageFormat.NUMPY.name
self.write_fn(os.path.join(dir_name, fname), self.aux_dict[aux_key])
self.aux_dict[aux_key].write(os.path.join(dir_name, aux_data))

def set_stack(self, new_stack):
if self.image.raw_shape != new_stack.shape:
Expand All @@ -102,13 +95,41 @@ def set_aux(self, key, img):
msg = "Shape mismatch. Current data shape: {}, new data shape: {}".format(
old_img.shape, img.shape)
raise AttributeError(msg)
self.aux_dict[key].numpy_array = img
else:
self.org['auxiliary_images'][key] = {
'file': key,
'tile_format': ImageFormat.NUMPY.name,
'tile_shape': img.shape,
}
self.aux_dict[key] = img
# TODO: (ttung) major hack alert. we don't have a convenient mechanism to build an ImageStack from a single
# numpy array, which we probably should.
tileset = TileSet(
{
Indices.HYB,
Indices.CH,
Indices.Z,
Coordinates.X,
Coordinates.Y,
},
{
Indices.HYB: 1,
Indices.CH: 1,
Indices.Z: 1,
}
)
tile = Tile(
{
Coordinates.X: (0.000, 0.001),
Coordinates.Y: (0.000, 0.001),
},
{
Indices.HYB: 0,
Indices.CH: 0,
Indices.Z: 0,
},
img.shape,
)
tile.numpy_array = img
tileset.add_tile(tile)

self.aux_dict[key] = ImageStack(tileset)
self.org['auxiliary_images'][key] = f"{key}.json"

def max_proj(self, *dims):
return self.image.max_proj(*dims)
Expand Down
4 changes: 3 additions & 1 deletion starfish/pipeline/features/spots/detector/gaussian.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import pandas as pd
from skimage.feature import blob_log

from starfish.constants import Indices
from starfish.munge import gather
from starfish.pipeline.features.encoded_spots import EncodedSpots
from starfish.pipeline.features.spot_attributes import SpotAttributes
Expand Down Expand Up @@ -96,7 +97,8 @@ def fit(self, blobs_image):
return SpotAttributes(fitted_blobs)

def find(self, image_stack) -> Tuple[SpotAttributes, EncodedSpots]:
spot_attributes = self.fit(image_stack.aux_dict[self.blobs])
blobs = image_stack.aux_dict[self.blobs].max_proj(Indices.HYB, Indices.CH, Indices.Z)
spot_attributes = self.fit(blobs)
encoded_spots = self.encode(image_stack, spot_attributes.data)
return spot_attributes, encoded_spots

Expand Down
2 changes: 1 addition & 1 deletion starfish/pipeline/filter/bandpass.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,4 @@ def filter(self, stack) -> None:

# apply to aux dict too:
for k, val in stack.aux_dict.items():
stack.aux_dict[k] = self.bandpass(val, self.lshort, self.llong, self.threshold, self.truncate)
stack.aux_dict[k].apply(bandpass_)
2 changes: 1 addition & 1 deletion starfish/pipeline/filter/clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ def filter(self, stack) -> None:

# apply to aux dict too:
for k, val in stack.aux_dict.items():
stack.aux_dict[k] = self.clip(val, self.p_min, self.p_max)
stack.aux_dict[k].apply(clip)
2 changes: 1 addition & 1 deletion starfish/pipeline/filter/gaussian_high_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,4 @@ def filter(self, stack: Stack) -> None:

# apply to aux dict too:
for k, val in stack.aux_dict.items():
stack.aux_dict[k] = high_pass(val)
stack.aux_dict[k].apply(high_pass)
2 changes: 1 addition & 1 deletion starfish/pipeline/filter/gaussian_low_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,4 @@ def filter(self, stack) -> None:

# apply to aux dict too:
for k, val in stack.aux_dict.items():
stack.aux_dict[k] = self.low_pass(val, self.sigma)
stack.aux_dict[k].apply(low_pass)
2 changes: 1 addition & 1 deletion starfish/pipeline/filter/richardson_lucy_deconvolution.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ def filter(self, stack: Stack) -> None:
stack.image.apply(func)

for k, val in stack.aux_dict.items():
stack.aux_dict[k] = func(val)
stack.aux_dict[k].apply(func)
7 changes: 3 additions & 4 deletions starfish/pipeline/filter/white_tophat.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ def white_tophat(image):

stack.image.apply(white_tophat)

# TODO ambrosejcarr: port aux functionality into apply, I think we always want this
# apply to aux dict too:
for k, val in stack.aux_dict.items():
stack.aux_dict[k] = white_tophat(val)
# apply to aux dict too.
for aux_img in stack.aux_dict.values():
aux_img.apply(white_tophat)
3 changes: 2 additions & 1 deletion starfish/pipeline/registration/fourier_shift.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ def add_arguments(cls, group_parser):
def register(self, stack):
# TODO: (ambrosejcarr) is this the appropriate way of dealing with Z in registration?
mp = stack.max_proj(Indices.CH, Indices.Z)
dots = stack.aux_dict['dots'].max_proj(Indices.HYB, Indices.CH, Indices.Z)

for h in range(stack.image.num_hybs):
# compute shift between maximum projection (across channels) and dots, for each hyb round
# TODO: make the max projection array ignorant of axes ordering.
shift, error = compute_shift(mp[h, :, :], stack.aux_dict['dots'], self.upsampling)
shift, error = compute_shift(mp[h, :, :], dots, self.upsampling)
print("For hyb: {}, Shift: {}, Error: {}".format(h, shift, error))

for c in range(stack.image.num_chs):
Expand Down
3 changes: 2 additions & 1 deletion starfish/pipeline/segmentation/watershed.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ def segment(self, stack):
disk_size_markers = None
disk_size_mask = None

seg = WatershedSegmenter(stack.aux_dict['nuclei'], stain)
nuclei = stack.aux_dict['nuclei'].max_proj(Indices.HYB, Indices.CH, Indices.Z)
seg = WatershedSegmenter(nuclei, stain)
cells_labels = seg.segment(
self.dapi_threshold, self.input_threshold, size_lim, disk_size_markers, disk_size_mask, self.min_distance)

Expand Down

0 comments on commit a415ef3

Please sign in to comment.