Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for multiple labels #111

Merged
merged 3 commits into from
Aug 11, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 8 additions & 3 deletions caliban_toolbox/reshape_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,12 @@ def crop_multichannel_data(X_data, y_data, crop_size=None, crop_num=None, overla
if list(X_data.dims) != ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'channels']:
raise ValueError('X_data does not have expected dims, found {}'.format(X_data.dims))

if list(y_data.dims) != ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'channels']:
if list(y_data.dims) != ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'compartments']:
raise ValueError('y_data does not have expected dims, found {}'.format(y_data.dims))

if y_data.shape[-1] != 1:
raise ValueError('Only one type of segmentation label can be processed at a time')

# check if testing or running all samples
if test_parameters:
X_data, y_data = X_data[:1, ...], y_data[:1, ...]
Expand Down Expand Up @@ -141,6 +144,7 @@ def crop_multichannel_data(X_data, y_data, crop_size=None, crop_num=None, overla
log_data['row_padding'] = int(row_padding)
log_data['col_padding'] = int(col_padding)
log_data['num_crops'] = X_data_cropped.shape[2]
log_data['label_name'] = y_data.dims[-1]

return X_data_cropped, y_data_cropped, log_data

Expand Down Expand Up @@ -216,11 +220,12 @@ def reconstruct_image_stack(crop_dir, verbose=True):

# labels for each index within a dimension
_, stack_len, _, _, row_len, col_len, _ = log_data['original_shape']
label_name = log_data['label_name']
coordinate_labels = [log_data['fov_names'], range(stack_len), range(1),
range(1), range(row_len), range(col_len), ['segmentation_label']]
range(1), range(row_len), range(col_len), [label_name]]

# labels for each dimension
dimension_labels = ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'channels']
dimension_labels = ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'compartments']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This list of strings is used twice, maybe we can move it to the top as a global/constant:
DIMENSION_LABELS = ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'compartments']


stitched_xr = xr.DataArray(data=image_stack, coords=coordinate_labels,
dims=dimension_labels)
Expand Down
13 changes: 8 additions & 5 deletions caliban_toolbox/reshape_data_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def test_crop_multichannel_data():

test_y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num, row_len=row_len, col_len=col_len,
chan_len=channel_len)
chan_len=channel_len, last_dim_name='compartments')

X_data_cropped, y_data_cropped, log_data = \
reshape_data.crop_multichannel_data(X_data=test_X_data,
Expand Down Expand Up @@ -133,7 +133,7 @@ def test_create_slice_data():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=num_crops,
slice_num=num_slices, row_len=row_len, col_len=col_len,
chan_len=chan_len)
chan_len=chan_len, last_dim_name='compartments')

X_slice, y_slice, slice_indices = reshape_data.create_slice_data(X_data, y_data,
slice_stack_len)
Expand All @@ -155,7 +155,8 @@ def test_reconstruct_image_stack():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num,
row_len=row_len, col_len=col_len, chan_len=1)
row_len=row_len, col_len=col_len, chan_len=1,
last_dim_name='compartments')

# create image with artificial objects to be segmented

Expand Down Expand Up @@ -203,7 +204,8 @@ def test_reconstruct_image_stack():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num,
row_len=row_len, col_len=col_len, chan_len=1)
row_len=row_len, col_len=col_len, chan_len=1,
last_dim_name='compartments')

# tag upper left hand corner of the label in each image
tags = np.arange(stack_len)
Expand Down Expand Up @@ -237,7 +239,8 @@ def test_reconstruct_image_stack():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num,
row_len=row_len, col_len=col_len, chan_len=1)
row_len=row_len, col_len=col_len, chan_len=1,
last_dim_name='compartments')

# create image with artificial objects to be segmented

Expand Down
7 changes: 5 additions & 2 deletions caliban_toolbox/utils/crop_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,9 @@ def crop_helper(input_data, row_starts, row_ends, col_starts, col_ends, padding)
if input_crop_num > 1:
raise ValueError("Array has already been cropped")

# get name of last dimension from input data to determine if X or y
last_dim_name = input_data.dims[-1]

crop_num = len(row_starts) * len(col_starts)
crop_size_row = row_ends[0] - row_starts[0]
crop_size_col = col_ends[0] - col_starts[0]
Expand All @@ -114,10 +117,10 @@ def crop_helper(input_data, row_starts, row_ends, col_starts, col_ends, padding)

# labels for each index within a dimension
coordinate_labels = [input_data.fovs, input_data.stacks, range(crop_num), input_data.slices,
range(crop_size_row), range(crop_size_col), input_data.channels]
range(crop_size_row), range(crop_size_col), input_data[last_dim_name]]

# labels for each dimension
dimension_labels = ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'channels']
dimension_labels = ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', last_dim_name]

cropped_xr = xr.DataArray(data=cropped_stack, coords=coordinate_labels, dims=dimension_labels)

Expand Down
14 changes: 9 additions & 5 deletions caliban_toolbox/utils/crop_utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
import xarray as xr


def _blank_data_xr(fov_len, stack_len, crop_num, slice_num, row_len, col_len, chan_len):
def _blank_data_xr(fov_len, stack_len, crop_num, slice_num, row_len, col_len, chan_len,
last_dim_name='channels'):
"""Test function to generate a blank xarray with the supplied dimensions

Inputs
Expand All @@ -43,6 +44,7 @@ def _blank_data_xr(fov_len, stack_len, crop_num, slice_num, row_len, col_len, ch
row_num: number of rows
col_num: number of cols
chan_num: number of channels
last_dim_name: name of last dimension. Either channels or compartments for X or y data

Outputs
test_xr: xarray of [fov_num, row_num, col_num, chan_num]"""
Expand All @@ -56,7 +58,7 @@ def _blank_data_xr(fov_len, stack_len, crop_num, slice_num, row_len, col_len, ch
coords=[fovs, range(stack_len), range(crop_num), range(slice_num),
range(row_len), range(col_len), channels],
dims=["fovs", "stacks", "crops", "slices",
"rows", "cols", "channels"])
"rows", "cols", last_dim_name])

return test_stack_xr

Expand Down Expand Up @@ -195,7 +197,8 @@ def test_stitch_crops():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num,
row_len=row_len, col_len=col_len, chan_len=1)
row_len=row_len, col_len=col_len, chan_len=1,
last_dim_name='compartments')

# create image with artificial objects to be segmented

Expand Down Expand Up @@ -258,7 +261,8 @@ def test_stitch_crops():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num,
row_len=row_len, col_len=col_len, chan_len=chan_len)
row_len=row_len, col_len=col_len, chan_len=chan_len,
last_dim_name='compartments')
side_len = 40
cell_num = y_data.shape[4] // side_len

Expand Down Expand Up @@ -309,7 +313,7 @@ def test_stitch_crops():
log_data["num_crops"] = y_cropped.shape[2]
log_data["original_shape"] = y_data.shape
log_data["fov_names"] = y_data.fovs.values.tolist()
log_data["channel_names"] = y_data.channels.values.tolist()
log_data["label_name"] = str(y_data.coords['compartments'][0].values)

stitched_img = crop_utils.stitch_crops(crop_stack=y_cropped, log_data=log_data)

Expand Down
2 changes: 1 addition & 1 deletion caliban_toolbox/utils/io_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def save_npzs_for_caliban(X_data, y_data, original_data, log_data, save_dir,
raise NotImplementedError()

log_data['fov_names'] = fov_names.tolist()
log_data['channel_names'] = original_data.channels.values.tolist()
log_data['label_name'] = str(y_data.coords['compartments'][0].values)
MekWarrior marked this conversation as resolved.
Show resolved Hide resolved
log_data['original_shape'] = original_data.shape
log_data['slice_stack_len'] = X_data.shape[1]
log_data['save_format'] = save_format
Expand Down
9 changes: 6 additions & 3 deletions caliban_toolbox/utils/io_utils_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ def test_save_npzs_for_caliban():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=num_crops,
slice_num=num_slices,
row_len=row_len, col_len=col_len, chan_len=1)
row_len=row_len, col_len=col_len, chan_len=1,
last_dim_name='compartments')

sliced_X, sliced_y, log_data = reshape_data.create_slice_data(X_data=X_data, y_data=y_data,
slice_stack_len=slice_stack_len)
Expand Down Expand Up @@ -194,7 +195,8 @@ def test_load_npzs():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num,
row_len=row_len, col_len=col_len, chan_len=1)
row_len=row_len, col_len=col_len, chan_len=1,
last_dim_name='compartments')

# slice the data
X_slice, y_slice, log_data = reshape_data.create_slice_data(X_data, y_data,
Expand Down Expand Up @@ -249,7 +251,8 @@ def test_load_npzs():

y_data = _blank_data_xr(fov_len=fov_len, stack_len=stack_len, crop_num=crop_num,
slice_num=slice_num,
row_len=row_len, col_len=col_len, chan_len=1)
row_len=row_len, col_len=col_len, chan_len=1,
last_dim_name='compartments')

# slice the data
X_slice, y_slice, log_data = reshape_data.create_slice_data(X_data,
Expand Down
7 changes: 5 additions & 2 deletions caliban_toolbox/utils/slice_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ def slice_helper(data_xr, slice_start_indices, slice_end_indices):
if input_slice_num > 1:
raise ValueError('Input array already contains slice data')

# get name of last dimension from input data to determine if X or y
last_dim_name = data_xr.dims[-1]

slice_num = len(slice_start_indices)
sliced_stack_len = slice_end_indices[0] - slice_start_indices[0]

Expand All @@ -95,10 +98,10 @@ def slice_helper(data_xr, slice_start_indices, slice_end_indices):

# labels for each index within a dimension
coordinate_labels = [data_xr.fovs, range(sliced_stack_len), range(crop_num), range(slice_num),
range(row_len), range(col_len), data_xr.channels]
range(row_len), range(col_len), data_xr[last_dim_name]]

# labels for each dimension
dimension_labels = ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', 'channels']
dimension_labels = ['fovs', 'stacks', 'crops', 'slices', 'rows', 'cols', last_dim_name]

slice_xr = xr.DataArray(data=slice_data, coords=coordinate_labels, dims=dimension_labels)

Expand Down