zoccoler / napari-flim-phasor-plotter Goto Github PK
View Code? Open in Web Editor NEWLicense: BSD 3-Clause "New" or "Revised" License
License: BSD 3-Clause "New" or "Revised" License
One or multiple tau lines would be important to have displayed for phasor plot calibration
Some menu names have changed and the gif in the readme is outdated.
Median filter is being applied to the original image, but according to the literature, it should be applied to the g
and s
images.
the plugin nicely matures and the option for phasor cluster selection is great. ๐
We would increase the level of information if we made the summed intensity image the top layer and overlayed it (e.g. with opacity 50%, blending additive as a default setting) with the cluster_ids_in_space (opacity 100%) as default upon cluster selection. This combines the phasor cluster classification with pixel intensities and provides overall more detailed info on the image. Fine tuning can be done manually then.
How about also renaming the cluster_ids_in_space layer to '(image name +) phasor cluster' in the layer list? May be more intuitive for users.
cheers,
Conni
Here we use the convention that the first axis contains the photon counting information, aka, microtime (ut), while the napari-clusters-plotter consider the first axis the time.
Thus, changing the time slider for FLIM data (second axis here) does not update the plot while changing the microtime does.
The name of this plugin is not ideal and does not depict what it actually can do.
There are a few python libraries now capable of reading ptu files.
The ptu reader code here should be replaced by https://pypi.org/project/ptufile/ for example
Phasor Plots are usually displayed as a heatmap or 2D Histogram.
This would be a good enhancement to the Plotter. This may be implemented in the napari-cluster-plotter plugin, there is an issue there for this.
When running a median filter on a sample FLIM image I receive the following error:
EmitLoopError: calling <psygnal._weak_callback._StrongFunction object at 0x7f87856bba40> with args=(False,) caused
RuntimeError: filter footprint array has incorrect shape..
The current implementation of the median filter makes a full copy of the array.
So, if the image is very large or if it is a dask array, it will load all data into memory!
An independent implementation of the median filter with dask is necessary.
This may require rechunking the array and using dask_image.ndfilters.median_filter
. Data may need to be rechunked again after median filter for proper fft calculation.
The current implementation makes a label for each pixel. This may generate unnecessarily huge tables, which may hamper performance for large data.
Implementing a binning option could reduce these tables.
Right now, the layer names don't allow knowing which one is the raw data and which one is the intensity image.
This may lead the user to have the wrong one selected in the dropdown fields.
great to have sample data included and the synthetic cat data is amazing.
the only sample that cannot be loaded is the 3D hazelnut dataset, with following error:
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
File ~\AppData\Local\miniconda3\envs\flim-phasor-plotter-230817\lib\site-packages\napari\_qt\menus\file_menu.py:219, in FileMenu._rebuild_samples_menu.<locals>._add_sample(plg='napari-flim-phasor-plotter', smp='hazelnut_z_stack', *args=(False,))
217 def _add_sample(*args, plg=plugin_name, smp=samp_name):
218 try:
--> 219 self._win._qt_viewer.viewer.open_sample(plg, smp)
plg = 'napari-flim-phasor-plotter'
smp = 'hazelnut_z_stack'
self._win = <napari._qt.qt_main_window.Window object at 0x000001764A6A42E0>
self = <napari._qt.menus.file_menu.FileMenu object at 0x0000017658F5CD30>
220 except MultipleReaderError as e:
221 handle_gui_reading(
222 e.paths,
223 self._win._qt_viewer,
224 plugin_name=plugin_name,
225 stack=False,
226 )
File ~\AppData\Local\miniconda3\envs\flim-phasor-plotter-230817\lib\site-packages\napari\components\viewer_model.py:912, in ViewerModel.open_sample(self=Viewer(axes=Axes(visible=False, labels=True, col...._transform_active_layer at 0x0000017656FF7820>}), plugin='napari-flim-phasor-plotter', sample='hazelnut_z_stack', reader_plugin=None, **kwargs={})
910 if callable(data):
911 added = []
--> 912 for datum in data(**kwargs):
data = <bound method SampleDataGenerator.open of SampleDataGenerator(command='napari-flim-phasor-plotter.load_hazelnut_z_stack', key='hazelnut_z_stack', display_name='Hazelnut (3D Raw FLIM)')>
kwargs = {}
913 added.extend(self._add_layer_from_data(*datum))
914 return added
File ~\AppData\Local\miniconda3\envs\flim-phasor-plotter-230817\lib\site-packages\npe2\manifest\contributions\_sample_data.py:44, in SampleDataGenerator.open(self=SampleDataGenerator(command='napari-flim-phasor-..._z_stack', display_name='Hazelnut (3D Raw FLIM)'), _registry=None, *args=(), **kwargs={})
41 def open(
42 self, *args, _registry: Optional["CommandRegistry"] = None, **kwargs
43 ) -> List[LayerData]:
---> 44 return self.exec(args, kwargs, _registry=_registry)
args = ()
kwargs = {}
self = SampleDataGenerator(command='napari-flim-phasor-plotter.load_hazelnut_z_stack', key='hazelnut_z_stack', display_name='Hazelnut (3D Raw FLIM)')
_registry = None
File ~\AppData\Local\miniconda3\envs\flim-phasor-plotter-230817\lib\site-packages\npe2\manifest\utils.py:63, in Executable.exec(self=SampleDataGenerator(command='napari-flim-phasor-..._z_stack', display_name='Hazelnut (3D Raw FLIM)'), args=(), kwargs={}, _registry=None)
61 kwargs = {}
62 reg = _registry or kwargs.pop("_registry", None)
---> 63 return self.get_callable(reg)(*args, **kwargs)
reg = None
kwargs = {}
args = ()
self = SampleDataGenerator(command='napari-flim-phasor-plotter.load_hazelnut_z_stack', key='hazelnut_z_stack', display_name='Hazelnut (3D Raw FLIM)')
File ~\AppData\Local\miniconda3\envs\flim-phasor-plotter-230817\lib\site-packages\napari_flim_phasor_plotter\_sample_data.py:90, in load_hazelnut_z_stack()
87 from napari_flim_phasor_plotter._reader import read_stack
89 folder_path = DATA_ROOT / "hazelnut_FLIM_z_stack"
---> 90 image, metadata = read_stack(folder_path)
folder_path = WindowsPath('C:/Users/cblei/AppData/Local/miniconda3/envs/flim-phasor-plotter-230817/lib/site-packages/napari_flim_phasor_plotter/data/hazelnut_FLIM_z_stack')
91 image, metadata = image[0], metadata[0] # Use first channel, second detector is empty
92 return [(image, {'name': 'hazelnut raw FLIM z-stack',
93 'metadata': metadata,
94 'contrast_limits': (np.amin(image[image.shape[0] // 2, ...]),
(...)
101 }),
102 ]
File ~\AppData\Local\miniconda3\envs\flim-phasor-plotter-230817\lib\site-packages\napari_flim_phasor_plotter\_reader.py:293, in read_stack(folder_path=WindowsPath('C:/Users/cblei/AppData/Local/minico..._flim_phasor_plotter/data/hazelnut_FLIM_z_stack'))
291 from natsort import natsorted
292 from napari.utils import notifications
--> 293 file_extension = get_most_frequent_file_extension(folder_path)
folder_path = WindowsPath('C:/Users/cblei/AppData/Local/miniconda3/envs/flim-phasor-plotter-230817/lib/site-packages/napari_flim_phasor_plotter/data/hazelnut_FLIM_z_stack')
294 if file_extension == '.zarr':
295 file_paths = folder_path
File ~\AppData\Local\miniconda3\envs\flim-phasor-plotter-230817\lib\site-packages\napari_flim_phasor_plotter\_reader.py:193, in get_most_frequent_file_extension(path=WindowsPath('C:/Users/cblei/AppData/Local/minico..._flim_phasor_plotter/data/hazelnut_FLIM_z_stack'))
191 suffixes = [path.suffix]
192 # Get most frequent file entension in path
--> 193 most_frequent_file_type = max(set(suffixes), key=suffixes.count)
194 return most_frequent_file_type
UnboundLocalError: local variable 'suffixes' referenced before assignment
could you have a look at it @zoccoler ?
Thanks!
In some widgets (binning, split N largest and manual_label_extract), the output labels layer loses the scale
information (along with other layer properties).
During phasor calculation, pixels where DC is zero are replaced by DC average to avoid division by zero without interfering with the phasors. But if DC average is close to 0, it gets converted to integer and, thus, gets set to 0 again.
I am trying to open an sdt file retreived from a Becker Hickl FLIM instrument, but I am getting the following error message:
ValueError: could not broadcast input array from shape (1024,1024,1024) into shape (1024,1024)
Is there any way for me to convert the 3D array into 2D? Or is there some other troubleshooting needed?
Besides median filter, wavelets are also used to filter data.
We should have such an implementation for a denser visualization of clusters in the plot.
With napari 0.4.19, this warnings pops up after manually selecting a cluster
FutureWarning: Labels.color is deprecated since 0.4.19 and will be removed in 0.5.0, please set Labels.colormap directly with an instance of napari.utils.colormaps.DirectLabelColormap instead.!
Consider removing it from input fields if it is really unnecessary
Overlaying 2 or more datasets in the plotter (visualized with different transparency/colors) would advance the options to comparatively analyse FLIM datasets. This would have to be implemented in the napari-clusters-plotter, issue opened there.
applying filters creates 'denser' clusters in the phasor plot that are easier to distinguish (at least visually), let's find out how.
If available in metadata
I am encountering a major error in my phasor plot when I use the flim-phasor-plotter plugin. I used the napari-sdtfile plugin to upload my sdt file into napari, then used the phasor plotter plugin. Here is the plot I got:
I have tried uploading the file in .tif format as well, and I get a very similar looking phasor plot. Any ideas about how to troubleshoot this error?
The plugin should have some small sample data:
Currently, images are opened as 'timelapse' (photon counting time), which is appropriate for phasor calculation.
However, user usually expect that the summed intensity image comes along.
It would be nice to have them added as additional layers.
I installed napari-flim-phasor as the steps, and type napari in the command line in this env, and try to open a tif image or stack in napari, there's error:
TypeError: 'NoneType' object is not subscriptable
No matter the tif is 2d or 3d, it both don't work. It's because of 'tif.shaped_metadata = None'. It seems like it can't read my tif's shape properly. What should I do?
Also, when I try to drag in ptu file, the napari break down, the window closed itself.
Calling the plug-in reader function on url results in error message instead of a file download:
File ~/Documents/GitHub/napari-flim-phasor-plotter/src/napari_flim_phasor_plotter/_reader.py:25, in napari_get_reader(path='https://zenodo.org/record/7656540/files/2a_FLIM_single_image.ptu')
12 """A basic implementation of a Reader contribution.
13
14 Parameters
(...)
23 same path or list of paths, and returns a list of layer data tuples.
24 """
---> 25 file_extension = get_most_frequent_file_extension(path)
path = 'https://zenodo.org/record/7656540/files/2a_FLIM_single_image.ptu'
26 # If we recognize the format, we return the actual reader function
File ~/Documents/GitHub/napari-flim-phasor-plotter/src/napari_flim_phasor_plotter/_reader.py:126, in get_most_frequent_file_extension(path=PosixPath('https:/zenodo.org/record/7656540/files/2a_FLIM_single_image.ptu'))
125 # Get most frequent file entension in path
--> 126 most_frequent_file_type = max(set(suffixes), key=suffixes.count)
127 return most_frequent_file_type
UnboundLocalError: local variable 'suffixes' referenced before assignment
This may require multithreading.
This current implementation masks data in time starting from the whole image histogram peak.
We should find a way to use the IRF to obtain this information instead.
import & process ptu files of e.g z stacks and/or time series for which I could provide examples
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.