Skip to content

Commit

Permalink
Merge pull request #61 from fish-quant/develop
Browse files Browse the repository at this point in the history
v0.6.0
  • Loading branch information
Henley13 authored Jan 25, 2022
2 parents 5512b6e + a24a9fa commit 690404b
Show file tree
Hide file tree
Showing 76 changed files with 5,100 additions and 3,921 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Big-FISH requires Python 3.6 or newer. Additionally, it has the following depend

- numpy (== 1.16.0)
- scipy (== 1.4.1)
- scikit-learn (== 0.20.2)
- scikit-learn (== 0.21.0)
- scikit-image (== 0.14.2)
- matplotlib (== 3.0.2)
- pandas (== 0.24.0)
Expand Down
2 changes: 1 addition & 1 deletion bigfish/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
# MINOR: new features
# PATCH: backwards compatible bug fixes
# MAJOR.MINOR.PATCHdev means a version under development
__version__ = "0.5.0"
__version__ = "0.6.0"
72 changes: 45 additions & 27 deletions bigfish/classification/features.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
from .input_preparation import prepare_extracted_data


# TODO allow RNA coordinates in float64 and int64

# ### Main functions ###

def compute_features(cell_mask, nuc_mask, ndim, rna_coord, smfish=None,
Expand Down Expand Up @@ -359,10 +361,14 @@ def features_distance(rna_coord, distance_cell, distance_nuc, cell_mask, ndim,
if ndim not in [2, 3]:
raise ValueError("'ndim' should be 2 or 3, not {0}.".format(ndim))
stack.check_array(rna_coord, ndim=2, dtype=np.int64)
stack.check_array(distance_cell, ndim=2,
dtype=[np.float16, np.float32, np.float64])
stack.check_array(distance_nuc, ndim=2,
dtype=[np.float16, np.float32, np.float64])
stack.check_array(
distance_cell,
ndim=2,
dtype=[np.float16, np.float32, np.float64])
stack.check_array(
distance_nuc,
ndim=2,
dtype=[np.float16, np.float32, np.float64])
stack.check_array(cell_mask, ndim=2, dtype=bool)

# case where no mRNAs are detected
Expand All @@ -371,8 +377,9 @@ def features_distance(rna_coord, distance_cell, distance_nuc, cell_mask, ndim,
return features

# compute mean and median distance to cell membrane
rna_distance_cell = distance_cell[rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
rna_distance_cell = distance_cell[
rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
expected_distance = np.mean(distance_cell[cell_mask])
index_mean_dist_cell = np.mean(rna_distance_cell) / expected_distance
expected_distance = np.median(distance_cell[cell_mask])
Expand All @@ -381,8 +388,9 @@ def features_distance(rna_coord, distance_cell, distance_nuc, cell_mask, ndim,
features = (index_mean_dist_cell, index_median_dist_cell)

# compute mean and median distance to nucleus
rna_distance_nuc = distance_nuc[rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
rna_distance_nuc = distance_nuc[
rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
expected_distance = np.mean(distance_nuc[cell_mask])
index_mean_dist_nuc = np.mean(rna_distance_nuc) / expected_distance
expected_distance = np.median(distance_nuc[cell_mask])
Expand Down Expand Up @@ -481,8 +489,9 @@ def features_protrusion(rna_coord, cell_mask, nuc_mask, ndim, voxel_size_yx,
# check parameters
stack.check_parameter(check_input=bool)
if check_input:
stack.check_parameter(ndim=int,
voxel_size_yx=(int, float))
stack.check_parameter(
ndim=int,
voxel_size_yx=(int, float))
if ndim not in [2, 3]:
raise ValueError("'ndim' should be 2 or 3, not {0}.".format(ndim))
stack.check_array(rna_coord, ndim=2, dtype=np.int64)
Expand All @@ -507,16 +516,18 @@ def features_protrusion(rna_coord, cell_mask, nuc_mask, ndim, voxel_size_yx,

if protrusion_area > 0:
expected_rna_protrusion = nb_rna * protrusion_area / cell_area
mask_rna = mask_cell_opened[rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
mask_rna = mask_cell_opened[
rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
rna_after_opening = rna_coord[mask_rna]
nb_rna_protrusion = nb_rna - len(rna_after_opening)
index_rna_protrusion = nb_rna_protrusion / expected_rna_protrusion
proportion_rna_protrusion = nb_rna_protrusion / nb_rna

features = (index_rna_protrusion,
proportion_rna_protrusion,
protrusion_area)
features = (
index_rna_protrusion,
proportion_rna_protrusion,
protrusion_area)
else:
features = (1., 0., 0.)

Expand Down Expand Up @@ -701,8 +712,9 @@ def features_topography(rna_coord, cell_mask, nuc_mask, cell_mask_out_nuc,
# check parameters
stack.check_parameter(check_input=bool)
if check_input:
stack.check_parameter(ndim=int,
voxel_size_yx=(int, float))
stack.check_parameter(
ndim=int,
voxel_size_yx=(int, float))
if ndim not in [2, 3]:
raise ValueError("'ndim' should be 2 or 3, not {0}.".format(ndim))
stack.check_array(rna_coord, ndim=2, dtype=np.int64)
Expand Down Expand Up @@ -926,14 +938,17 @@ def features_centrosome(smfish, rna_coord, distance_centrosome, cell_mask,
# check parameters
stack.check_parameter(check_input=bool)
if check_input:
stack.check_parameter(ndim=int,
voxel_size_yx=(int, float))
stack.check_parameter(
ndim=int,
voxel_size_yx=(int, float))
if ndim not in [2, 3]:
raise ValueError("'ndim' should be 2 or 3, not {0}.".format(ndim))
stack.check_array(smfish, ndim=2, dtype=[np.uint8, np.uint16])
stack.check_array(rna_coord, ndim=2, dtype=np.int64)
stack.check_array(distance_centrosome, ndim=2,
dtype=[np.float16, np.float32, np.float64])
stack.check_array(
distance_centrosome,
ndim=2,
dtype=[np.float16, np.float32, np.float64])
stack.check_array(cell_mask, ndim=2, dtype=bool)

# case where no mRNAs are detected
Expand All @@ -946,8 +961,9 @@ def features_centrosome(smfish, rna_coord, distance_centrosome, cell_mask,
cell_area = cell_mask.sum()

# compute mean and median distances from the centrosomes
rna_distance_cent = distance_centrosome[rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
rna_distance_cent = distance_centrosome[
rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
expected_distance = np.mean(distance_centrosome[cell_mask])
index_mean_dist_cent = np.mean(rna_distance_cent) / expected_distance
expected_distance = np.median(distance_centrosome[cell_mask])
Expand All @@ -969,8 +985,9 @@ def features_centrosome(smfish, rna_coord, distance_centrosome, cell_mask,
mask_centrosome[~cell_mask] = False
centrosome_area = max(mask_centrosome.sum(), 1)
expected_nb_rna = nb_rna * centrosome_area / cell_area
mask_rna = mask_centrosome[rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
mask_rna = mask_centrosome[
rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]]
nb_rna_centrosome = len(rna_coord[mask_rna])
index_rna_centrosome = nb_rna_centrosome / expected_nb_rna
proportion_rna_centrosome = nb_rna_centrosome / len(rna_coord)
Expand All @@ -988,8 +1005,9 @@ def features_centrosome(smfish, rna_coord, distance_centrosome, cell_mask,
total_intensity_cell = cell_value.sum()

# compute attraction index
r = distance_centrosome[rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]] ** 2
r = distance_centrosome[
rna_coord[:, ndim - 2],
rna_coord[:, ndim - 1]] ** 2
a = np.sum((r * rna_value) / total_intensity_rna)
r = distance_centrosome[cell_coord[:, 0], cell_coord[:, 1]] ** 2
b = np.sum((r * cell_value) / total_intensity_cell)
Expand Down
62 changes: 40 additions & 22 deletions bigfish/classification/input_preparation.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,23 @@ def prepare_extracted_data(cell_mask, nuc_mask=None, ndim=None, rna_coord=None,
Distance map from the centrosome with shape (y, x), in pixels.
"""
# TODO allow RNA coordinates in float64 and int64
# check parameters
stack.check_parameter(ndim=(int, type(None)))
if rna_coord is not None and ndim is None:
raise ValueError("'ndim' should be specified (2 or 3).")

# check arrays and make masks binary
stack.check_array(cell_mask, ndim=2,
dtype=[np.uint8, np.uint16, np.int64, bool])
stack.check_array(
cell_mask,
ndim=2,
dtype=[np.uint8, np.uint16, np.int64, bool])
cell_mask = cell_mask.astype(bool)
if nuc_mask is not None:
stack.check_array(nuc_mask, ndim=2,
dtype=[np.uint8, np.uint16, np.int64, bool])
stack.check_array(
nuc_mask,
ndim=2,
dtype=[np.uint8, np.uint16, np.int64, bool])
nuc_mask = nuc_mask.astype(bool)
if rna_coord is not None:
stack.check_array(rna_coord, ndim=2, dtype=np.int64)
Expand All @@ -106,8 +111,9 @@ def prepare_extracted_data(cell_mask, nuc_mask=None, ndim=None, rna_coord=None,

# get cell centroid and a distance map from its localisation
centroid_cell = _get_centroid_surface(cell_mask)
distance_centroid_cell = _get_centroid_distance_map(centroid_cell,
cell_mask)
distance_centroid_cell = _get_centroid_distance_map(
centroid_cell,
cell_mask)

# prepare arrays relative to the nucleus
if nuc_mask is not None:
Expand All @@ -124,8 +130,9 @@ def prepare_extracted_data(cell_mask, nuc_mask=None, ndim=None, rna_coord=None,

# get nucleus centroid and a distance map from its localisation
centroid_nuc = _get_centroid_surface(nuc_mask)
distance_centroid_nuc = _get_centroid_distance_map(centroid_nuc,
cell_mask)
distance_centroid_nuc = _get_centroid_distance_map(
centroid_nuc,
cell_mask)

else:
cell_mask_out_nuc = None
Expand Down Expand Up @@ -159,12 +166,14 @@ def prepare_extracted_data(cell_mask, nuc_mask=None, ndim=None, rna_coord=None,
if len(rna_coord_out_nuc) == 0:
centroid_rna_out_nuc = np.array([0] * ndim, dtype=np.int64)
else:
centroid_rna_out_nuc = _get_centroid_rna(rna_coord_out_nuc,
ndim)
centroid_rna_out_nuc = _get_centroid_rna(
rna_coord_out_nuc,
ndim)

# build rna distance map (outside nucleus)
distance_centroid_rna_out_nuc = _get_centroid_distance_map(
centroid_rna_out_nuc, cell_mask)
centroid_rna_out_nuc,
cell_mask)

else:
rna_coord_out_nuc = None
Expand All @@ -186,22 +195,31 @@ def prepare_extracted_data(cell_mask, nuc_mask=None, ndim=None, rna_coord=None,
distance_centrosome = distance_cell.copy()
else:
distance_centrosome = _get_centrosome_distance_map(
centrosome_coord, cell_mask)
centrosome_coord,
cell_mask)

else:
distance_centrosome = None

# gather cell, nucleus, rna and centrosome data
prepared_inputs = (cell_mask,
distance_cell, distance_cell_normalized,
centroid_cell, distance_centroid_cell,
nuc_mask, cell_mask_out_nuc,
distance_nuc, distance_nuc_normalized,
centroid_nuc, distance_centroid_nuc,
rna_coord_out_nuc,
centroid_rna, distance_centroid_rna,
centroid_rna_out_nuc, distance_centroid_rna_out_nuc,
distance_centrosome)
prepared_inputs = (
cell_mask,
distance_cell,
distance_cell_normalized,
centroid_cell,
distance_centroid_cell,
nuc_mask,
cell_mask_out_nuc,
distance_nuc,
distance_nuc_normalized,
centroid_nuc,
distance_centroid_nuc,
rna_coord_out_nuc,
centroid_rna,
distance_centroid_rna,
centroid_rna_out_nuc,
distance_centroid_rna_out_nuc,
distance_centrosome)

return prepared_inputs

Expand Down
Empty file.
18 changes: 18 additions & 0 deletions bigfish/classification/tests/test_features.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Author: Arthur Imbert <[email protected]>
# License: BSD 3 clause

"""
Unitary tests for bigfish.classification.features module.
"""

# TODO add test bigfish.classification.compute_features
# TODO add test bigfish.classification.get_features_name
# TODO add test bigfish.classification.features_distance
# TODO add test bigfish.classification.features_in_out_nucleus
# TODO add test bigfish.classification.features_protrusion
# TODO add test bigfish.classification.features_dispersion
# TODO add test bigfish.classification.features_topography
# TODO add test bigfish.classification.features_foci
# TODO add test bigfish.classification.features_area
# TODO add test bigfish.classification.features_centrosome
9 changes: 9 additions & 0 deletions bigfish/classification/tests/test_input_preparation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# -*- coding: utf-8 -*-
# Author: Arthur Imbert <[email protected]>
# License: BSD 3 clause

"""
Unitary tests for bigfish.classification.input_preparation module.
"""

# TODO add test bigfish.classification.prepare_extracted_data
Loading

0 comments on commit 690404b

Please sign in to comment.