From 98c0837b81c43379e8c6c34995b3a37d9a8d0495 Mon Sep 17 00:00:00 2001 From: Corentin <> Date: Fri, 17 Feb 2023 11:24:23 +0100 Subject: [PATCH] better atp options and treatment --- .gitignore | 2 +- myoquant/commands/run_atp.py | 26 ++++++++++++++++++++++---- myoquant/src/ATP_analysis.py | 6 +++--- myoquant/src/common_func.py | 12 +++++++----- poetry.lock | 13 +++---------- 5 files changed, 36 insertions(+), 23 deletions(-) diff --git a/.gitignore b/.gitignore index c6906a5..7a5cbed 100644 --- a/.gitignore +++ b/.gitignore @@ -170,4 +170,4 @@ debug_data/ !cytoplasm.tif !binary_mask_sdh.tif data/* -sample_atp_intensity_plot.png \ No newline at end of file +*intensity_plot.png \ No newline at end of file diff --git a/myoquant/commands/run_atp.py b/myoquant/commands/run_atp.py index c94082f..1bf736c 100644 --- a/myoquant/commands/run_atp.py +++ b/myoquant/commands/run_atp.py @@ -63,6 +63,14 @@ def atp_analysis( None, help="Image channel to use for the analysis. If not specified, the analysis will be performed on all three channels.", ), + channel_first: bool = typer.Option( + False, + help="If the channel is the first dimension of the image, set this to True. False by default.", + ), + rescale_exposure: bool = typer.Option( + False, + help="Rescale the image exposure if your image is not in the 0 255 forma, False by default.", + ), n_classes: int = typer.Option( 2, max=10, @@ -72,9 +80,10 @@ def atp_analysis( "median", help="The method to use to compute the intensity of the cell. Can be either 'median' or 'mean'.", ), - erosion: bool = typer.Option( + erosion: int = typer.Option( False, - help="Perform an erosion on the cells images to remove signal in the cell membrane (usefull for fluo)", + max=45, + help="Perform an erosion on the cells images to remove signal in the cell membrane (usefull for fluo). Expressed in percentage of the cell radius", ), export_map: bool = typer.Option( True, @@ -127,6 +136,7 @@ def atp_analysis( from ..src.ATP_analysis import run_atp_analysis import numpy as np from PIL import Image + from skimage.exposure import rescale_intensity try: from imageio.v2 import imread @@ -153,8 +163,16 @@ def atp_analysis( progress.add_task(description="Reading all inputs...", total=None) image_ndarray = imread(image_path) if channel is not None: - image_ndarray = image_ndarray[:, :, channel] - + if channel_first: + # Put the channel as third dimension instead of first + image_ndarray = np.moveaxis(image_ndarray, 0, -1) + image_ndarray = image_ndarray[:, :, channel] + if rescale_exposure: + image_ndarray = rescale_intensity( + image_ndarray, + in_range=(np.amin(image_ndarray), np.amax(image_ndarray)), + out_range=np.uint8, + ) if mask_path is not None: mask_ndarray = imread(mask_path) if np.unique(mask_ndarray).shape[0] != 2: diff --git a/myoquant/src/ATP_analysis.py b/myoquant/src/ATP_analysis.py index 41386fb..cc8cbdd 100644 --- a/myoquant/src/ATP_analysis.py +++ b/myoquant/src/ATP_analysis.py @@ -14,7 +14,7 @@ def get_all_intensity( - image_array, df_cellpose, intensity_method="median", erosion=False + image_array, df_cellpose, intensity_method="median", erosion=None ): all_cell_median_intensity = [] for index in range(len(df_cellpose)): @@ -97,7 +97,7 @@ def predict_all_cells( intensity_threshold, n_classes=2, intensity_method="median", - erosion=False, + erosion=None, ): all_cell_median_intensity = get_all_intensity( histo_img, cellpose_df, intensity_method, erosion @@ -146,7 +146,7 @@ def run_atp_analysis( intensity_threshold=None, n_classes=2, intensity_method="median", - erosion=False, + erosion=None, ): df_cellpose = df_from_cellpose_mask(mask_cellpose) class_predicted_all, intensity_all, intensity_threshold = predict_all_cells( diff --git a/myoquant/src/common_func.py b/myoquant/src/common_func.py index f6ed068..0a6080e 100644 --- a/myoquant/src/common_func.py +++ b/myoquant/src/common_func.py @@ -173,17 +173,19 @@ def df_from_stardist_mask(mask, intensity_image=None): return df_stardist -def extract_single_image(raw_image, df_props, index, erosion=False): +def extract_single_image(raw_image, df_props, index, erosion=None): single_entity_img = raw_image[ df_props.iloc[index, 5] : df_props.iloc[index, 7], df_props.iloc[index, 6] : df_props.iloc[index, 8], ].copy() surface_area = df_props.iloc[index, 1] cell_radius = math.sqrt(surface_area / math.pi) - single_entity_mask = df_props.iloc[index, 9] - erosion_size = int(cell_radius / 5) # 20% of the cell - if erosion: - for i in range(erosion_size): + single_entity_mask = df_props.iloc[index, 9].copy() + erosion_size = cell_radius * ( + erosion / 100 + ) # Erosion in percentage of the cell radius + if erosion is not None: + for i in range(int(erosion_size)): single_entity_mask = binary_erosion( single_entity_mask, out=single_entity_mask ) diff --git a/poetry.lock b/poetry.lock index 79ebbd9..0bf3b92 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1181,14 +1181,14 @@ files = [ [[package]] name = "jupyter-client" -version = "8.0.2" +version = "8.0.3" description = "Jupyter protocol implementation and client libraries" category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "jupyter_client-8.0.2-py3-none-any.whl", hash = "sha256:c53731eb590b68839b0ce04bf46ff8c4f03278f5d9fe5c3b0f268a57cc2bd97e"}, - {file = "jupyter_client-8.0.2.tar.gz", hash = "sha256:47ac9f586dbcff4d79387ec264faf0fdeb5f14845fa7345fd7d1e378f8096011"}, + {file = "jupyter_client-8.0.3-py3-none-any.whl", hash = "sha256:be48ac6bd659cbbddb7a674cf06b3b8afbf53f228253cf58bde604c03bd487b0"}, + {file = "jupyter_client-8.0.3.tar.gz", hash = "sha256:ed65498bea6d876ef9d8da3e0db3dd33c5d129f5b2645f56ae03993782966bd0"}, ] [package.dependencies] @@ -2136,13 +2136,6 @@ files = [ {file = "Pillow-9.4.0-1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:b8c2f6eb0df979ee99433d8b3f6d193d9590f735cf12274c108bd954e30ca858"}, {file = "Pillow-9.4.0-1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:b70756ec9417c34e097f987b4d8c510975216ad26ba6e57ccb53bc758f490dab"}, {file = "Pillow-9.4.0-1-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:43521ce2c4b865d385e78579a082b6ad1166ebed2b1a2293c3be1d68dd7ca3b9"}, - {file = "Pillow-9.4.0-2-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:9d9a62576b68cd90f7075876f4e8444487db5eeea0e4df3ba298ee38a8d067b0"}, - {file = "Pillow-9.4.0-2-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:87708d78a14d56a990fbf4f9cb350b7d89ee8988705e58e39bdf4d82c149210f"}, - {file = "Pillow-9.4.0-2-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8a2b5874d17e72dfb80d917213abd55d7e1ed2479f38f001f264f7ce7bae757c"}, - {file = "Pillow-9.4.0-2-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:83125753a60cfc8c412de5896d10a0a405e0bd88d0470ad82e0869ddf0cb3848"}, - {file = "Pillow-9.4.0-2-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:9e5f94742033898bfe84c93c831a6f552bb629448d4072dd312306bab3bd96f1"}, - {file = "Pillow-9.4.0-2-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:013016af6b3a12a2f40b704677f8b51f72cb007dac785a9933d5c86a72a7fe33"}, - {file = "Pillow-9.4.0-2-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:99d92d148dd03fd19d16175b6d355cc1b01faf80dae93c6c3eb4163709edc0a9"}, {file = "Pillow-9.4.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:2968c58feca624bb6c8502f9564dd187d0e1389964898f5e9e1fbc8533169157"}, {file = "Pillow-9.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c5c1362c14aee73f50143d74389b2c158707b4abce2cb055b7ad37ce60738d47"}, {file = "Pillow-9.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd752c5ff1b4a870b7661234694f24b1d2b9076b8bf337321a814c612665f343"},