Skip to content

Commit

Permalink
Merge pull request #12 from lambda-science/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
lambda-science authored May 10, 2023
2 parents 31190a9 + 695659e commit ea24108
Show file tree
Hide file tree
Showing 11 changed files with 531 additions and 362 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,8 @@ debug_data/
!nuclei.tif
!cytoplasm.tif
!binary_mask_sdh.tif
data/*
data/*
*intensity_plot.png
*.idea
cellpose.sh
nohup.out
2 changes: 1 addition & 1 deletion .python-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.10.9
3.10.11
2 changes: 1 addition & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"request": "launch",
"module": "myoquant",
"justMyCode": true,
"args": ["atp-analysis", "sample_img/sample_atp.jpg", "--cellpose-path", "sample_img/sample_atp_cellpose_mask.tiff"],
"args": ["atp-analysis", "sample_img/sample_atp.jpg", "--cellpose-path", "sample_img/sample_atp_cellpose_mask.tiff", "--intensity-method", "mean", "--n-classes", "2", "--erosion"],
}
]
}
7 changes: 7 additions & 0 deletions CLI_Documentation.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ $ myoquant [OPTIONS] COMMAND [ARGS]...

**Options**:

- `--version`
- `--help`: Show this message and exit.

**Commands**:
Expand Down Expand Up @@ -43,6 +44,12 @@ $ myoquant atp-analysis [OPTIONS] IMAGE_PATH
- `--output-path PATH`: The path to the folder to save the results. Will save in the same folder as input image if not specified.
- `--intensity-threshold INTEGER RANGE`: Fiber intensity threshold to differenciate between the two fiber types. If not specified, the analysis will try to deduce it. [1<=x<=254]
- `--cellpose-diameter INTEGER`: Approximative single cell diameter in pixel for CellPose detection. If not specified, Cellpose will try to deduce it.
- `--channel INTEGER`: Image channel to use for the analysis. If not specified, the analysis will be performed on all three channels.
- `--channel-first / --no-channel-first`: If the channel is the first dimension of the image, set this to True. False by default. [default: no-channel-first]
- `--rescale-exposure / --no-rescale-exposure`: Rescale the image exposure if your image is not in the 0 255 forma, False by default. [default: no-rescale-exposure]
- `--n-classes INTEGER RANGE`: The number of classes of cell to detect. If not specified this is defaulted to two classes. [default: 2; x<=10]
- `--intensity-method TEXT`: The method to use to compute the intensity of the cell. Can be either 'median' or 'mean'. [default: median]
- `--erosion INTEGER RANGE`: Perform an erosion on the cells images to remove signal in the cell membrane (usefull for fluo). Expressed in percentage of the cell radius [default: False; x<=45]
- `--export-map / --no-export-map`: Export the original image with cells painted by classification label. [default: export-map]
- `--export-stats / --no-export-stats`: Export per fiber and per nuclei stat table. [default: export-stats]
- `--help`: Show this message and exit.
Expand Down
27 changes: 27 additions & 0 deletions myoquant/__main__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
import typer
from rich.console import Console
import pkg_resources

__version__ = pkg_resources.get_distribution("myoquant").version
__version_cellpose__ = pkg_resources.get_distribution("cellpose").version
__version_stardist__ = pkg_resources.get_distribution("stardist").version
__version_torch__ = pkg_resources.get_distribution("torch").version
__version_tensorflow__ = pkg_resources.get_distribution("tensorflow").version

from .commands.docs import app as docs_app
from .commands import run_sdh, run_he, run_atp

console = Console()


def version_callback(value: bool):
if value:
print(
f"MyoQuant Version: {__version__} \nCellpose Version: {__version_cellpose__} \nStardist Version: {__version_stardist__} \nTorch Version: {__version_torch__} \nTensorflow Version: {__version_tensorflow__}"
)
raise typer.Exit()


app = typer.Typer(
name="MyoQuant",
add_completion=False,
Expand All @@ -15,6 +31,17 @@
app.add_typer(docs_app, name="docs", help="Generate documentation")


@app.callback()
def main(
version: bool = typer.Option(
None, "--version", callback=version_callback, is_eager=True
)
):
"""
MyoQuant Analysis Command Line Interface
"""


app.registered_commands += (
run_sdh.app.registered_commands
+ run_he.app.registered_commands
Expand Down
60 changes: 56 additions & 4 deletions myoquant/commands/run_atp.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,32 @@ def atp_analysis(
None,
help="Approximative single cell diameter in pixel for CellPose detection. If not specified, Cellpose will try to deduce it.",
),
channel: int = typer.Option(
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,
help="The number of classes of cell to detect. If not specified this is defaulted to two classes.",
),
intensity_method: str = typer.Option(
"median",
help="The method to use to compute the intensity of the cell. Can be either 'median' or 'mean'.",
),
erosion: int = typer.Option(
False,
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,
help="Export the original image with cells painted by classification label.",
Expand Down Expand Up @@ -110,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
Expand All @@ -135,7 +162,17 @@ def atp_analysis(
) as progress:
progress.add_task(description="Reading all inputs...", total=None)
image_ndarray = imread(image_path)

if channel is not None:
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:
Expand Down Expand Up @@ -200,8 +237,13 @@ def atp_analysis(
transient=False,
) as progress:
progress.add_task(description="Detecting fiber types...", total=None)
result_df, full_label_map, df_cellpose_details = run_atp_analysis(
image_ndarray, mask_cellpose, intensity_threshold
result_df, full_label_map, df_cellpose_details, fig = run_atp_analysis(
image_ndarray,
mask_cellpose,
intensity_threshold,
n_classes,
intensity_method,
erosion,
)
if export_map:
with Progress(
Expand All @@ -214,7 +256,12 @@ def atp_analysis(
description="Blending label and original image together...", total=None
)
labelRGB_map = label2rgb(image_ndarray, full_label_map)
overlay_img = blend_image_with_label(image_ndarray, labelRGB_map)
if channel is not None:
overlay_img = blend_image_with_label(
image_ndarray, labelRGB_map, fluo=True
)
else:
overlay_img = blend_image_with_label(image_ndarray, labelRGB_map)
overlay_filename = image_path.stem + "_label_blend.tiff"
overlay_img.save(output_path / overlay_filename)

Expand All @@ -239,6 +286,11 @@ def atp_analysis(
f"💾 OUTPUT: Summary Table saved as {output_path/csv_name}",
style="green",
)
plot_name = image_path.stem + "_intensity_plot.png"
fig.savefig(output_path / plot_name)
console.print(
f"💾 OUTPUT: Intensity Plot saved as {output_path/plot_name}", style="green"
)
if export_map:
console.print(
f"💾 OUTPUT: Overlay image saved as {output_path/overlay_filename}",
Expand Down
Loading

0 comments on commit ea24108

Please sign in to comment.