Skip to content

Commit 9939eab

Browse files
authored
Merge pull request #2 from zoccoler/add_packages_info
Add packages info
2 parents bea07b5 + 6775798 commit 9939eab

10 files changed

+553
-272
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
# IPython Notebook
3+
.ipynb_checkpoints
4+
5+
__pycache__/
6+
*.py[cod]

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
# Lifetime Unmixing
22

33
This repository hosts code for distinguishing 2 dyes with overlapping spectra via lifetime.
4-
Images are 6D (3D FLIM timelapse multichannel).
4+
The workflows presented here mainly rely on the [napari-flim-phasor-plotter](https://zenodo.org/records/13319544) plugin, along with some post-processing/analysis steps done using [pyclesperanto-prototype](https://zenodo.org/records/10432619), [scikit-image](https://scikit-image.org/) and [scikit-learn](https://scikit-learn.org/stable/index.html), plus file saving using [tifffile](https://pypi.org/project/tifffile/).
5+
Images of worm embryos are 6D (3D FLIM timelapse multichannel). Images of adult worms are 5D (3D FLIM multichannel).
56

67
## Installation
78

8-
Install [Miniforge](https://github.com/conda-forge/miniforge?tab=readme-ov-file#miniforge) in your computer (which contains [`mamba`](https://mamba.readthedocs.io/en/latest/installation/mamba-installation.html#).
9+
Install [Miniforge](https://github.com/conda-forge/miniforge?tab=readme-ov-file#miniforge) in your computer (which contains [`mamba`](https://mamba.readthedocs.io/en/latest/installation/mamba-installation.html#)).
910

1011
Clone this repository locally (for example using [Github Desktop](https://desktop.github.com/)).
1112

@@ -29,4 +30,5 @@ We recommend running this code on a powerful workstation, preferably with > 48GB
2930

3031
## Acknowledgements
3132

32-
To be added
33+
We thank the Bio-Image Analysis Technology Development team of Physics of Life at TU Dresden (BiA-PoL) for the provision of infrastructure, code development and fruitful discussions.
34+

code/phasor_plot_AZ212.ipynb

Lines changed: 64 additions & 13 deletions
Large diffs are not rendered by default.

code/phasor_plot_JJ1473.ipynb

Lines changed: 86 additions & 36 deletions
Large diffs are not rendered by default.

code/phasor_plot_analysis_batch_processing.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@
1414
from utilities import ellipse_vertices, format_metadata, set_plot_zoom_position, add_segmentation_metadata
1515
import time
1616
import warnings
17+
from watermark import watermark
1718
warnings.filterwarnings("ignore")
18-
start_time = time.time()
19-
print("Napari version: ", napari.__version__)
19+
# Print package versions and machine info
20+
print(watermark(packages="numpy,pandas,napari,napari_flim_phasor_plotter,skimage,dask,pyclesperanto_prototype,tifffile,xmltodict", machine=True, python=True, gpu=True))
2021

22+
start_time = time.time()
2123
# Inputs
2224

23-
# Main folder path
25+
# Main folder path (each folder contains a zarr file and an xml file)
2426
main_folder_path = Path("/home/pol_haase/mazo260d/Data/I227_Lifetime_Unmixing_of_Dyes_with_Overlapping_Sprectra/Batch_Processing")
2527

2628
# Additional metadata in case the xml file is not available
@@ -280,12 +282,16 @@
280282
# Convert the segmentation result to a Dask array
281283
chunk_shape = summed_intensity_stack.chunksize
282284
cluster_labels_image_timelapse_dask = da.from_array(cluster_labels_image_timelapse_post_processed, chunks=chunk_shape)
283-
# Add segmentation result to the summed intensity stack
284-
summed_intensity_stack = da.concatenate([summed_intensity_stack, cluster_mask_timelapse_dask, cluster_labels_image_timelapse_dask], axis=0)
285+
285286
if store_phasor_mask:
286287
cluster_mask_timelapse = np.expand_dims(cluster_mask_timelapse.astype(summed_intensity_stack.dtype), axis=0)
287288
cluster_mask_timelapse_dask = da.from_array(cluster_mask_timelapse, chunks=chunk_shape)
288289
metadata_timelapse = add_segmentation_metadata(metadata_timelapse, channel_name='Phasor Mask')
290+
# Add mask and segmentation result to the summed intensity stack
291+
summed_intensity_stack = da.concatenate([summed_intensity_stack, cluster_mask_timelapse_dask, cluster_labels_image_timelapse_dask], axis=0)
292+
else:
293+
# Add segmentation result to the summed intensity stack
294+
summed_intensity_stack = da.concatenate([summed_intensity_stack, cluster_labels_image_timelapse_dask], axis=0)
289295
# Add metadata to 'segmentation' channel(s): Phasor Mask and Segmentation results after post-processing
290296
metadata_timelapse = add_segmentation_metadata(metadata_timelapse)
291297
output_file_name = sample_name + '_summed_intensity_with_segmentation.ome.tif'

code/phasor_plot_single_timepoint_LP307_3.ipynb

Lines changed: 111 additions & 72 deletions
Large diffs are not rendered by default.

code/phasor_plot_single_timepoint_TMR17_3.ipynb

Lines changed: 110 additions & 71 deletions
Large diffs are not rendered by default.

code/phasor_plot_single_timepoint_TMR31_3.ipynb

Lines changed: 111 additions & 71 deletions
Large diffs are not rendered by default.

code/utilities.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,38 @@ def ellipse_vertices(center, a, b, angle, num_vertices=100):
7474
return vertices
7575

7676
def format_metadata(flim_metadata, xml_path=None, stack_shape=None, z_pixel_size = 0.5, pixel_size_unit = 'µm', time_resolution_per_slice = 0.663, time_unit = 's', channel_names = ['0', '1'], axes='CTZYX', timelapse=True):
77+
"""Format metadata for OME-TIFF based on the provided metadata and XML file.
78+
79+
Parameters
80+
----------
81+
flim_metadata : List[Dict]
82+
Metadata from the raw FLIM data file (usually .ptu or .sdt).
83+
xml_path : Path, optional
84+
Path to the XML file, containing metadata from the whole timelapse.
85+
The xml file is assumed to be in the format of the XML file generated by the Leica SP8 software.
86+
If None (default), then additional arguments must be provided.
87+
stack_shape : Tuple[int], optional
88+
Shape of the stack, by default None. Required if no XML file is provided.
89+
z_pixel_size : float, optional
90+
Pixel size along the z-axis, by default 0.5. Required if no XML file is provided.
91+
pixel_size_unit : str, optional
92+
Unit of the pixel size, by default 'µm'. Required if no XML file is provided.
93+
time_resolution_per_slice : float, optional
94+
Time resolution per slice, by default 0.663. Required if no XML file is provided.
95+
time_unit : str, optional
96+
Unit of the time resolution, by default 's'. Required if no XML file is provided.
97+
channel_names : List[str], optional
98+
Names of the channels, by default ['0', '1']. Required if no XML file is provided.
99+
axes : str, optional
100+
Axes of the data, by default 'CTZYX'.
101+
timelapse : bool, optional
102+
Whether the data is a timelapse, by default True.
103+
104+
Returns
105+
-------
106+
Tuple[Dict, Dict]
107+
Metadata for the whole timelapse without photon counts axis and metadata for single timepoint with photon counts axis.
108+
"""
77109
import xmltodict
78110
if xml_path is None:
79111
xml_exist = False
@@ -163,6 +195,20 @@ def format_metadata(flim_metadata, xml_path=None, stack_shape=None, z_pixel_size
163195
return metadata_timelapse, metadata_single_timepoint
164196

165197
def add_segmentation_metadata(metadata_timelapse, channel_name='Segmentation'):
198+
"""Add metadata for a segmentation channel to the existing metadata.
199+
200+
Parameters
201+
----------
202+
metadata_timelapse : Dict
203+
Metadata for the whole timelapse.
204+
channel_name : str, optional
205+
Name of the segmentation channel, by default 'Segmentation'.
206+
207+
Returns
208+
-------
209+
Dict
210+
Updated metadata for the whole timelapse
211+
"""
166212
for channel_key, channel_values in metadata_timelapse['Channel'].items():
167213
if channel_key == 'Name':
168214
metadata_timelapse['Channel'][channel_key].append(channel_name)

env.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,6 @@ dependencies:
1313
- pip:
1414
- napari-flim-phasor-plotter
1515
- tifffile==2022.8.12
16-
- pyclesperanto_prototype
16+
- pyclesperanto_prototype
17+
- watermark
18+
- watermark[gpu]

0 commit comments

Comments
 (0)