diff --git a/Python/AllFunctions.py b/Python/AllFunctions.py index 4c9866a..99889f1 100644 --- a/Python/AllFunctions.py +++ b/Python/AllFunctions.py @@ -1437,9 +1437,10 @@ def makemask(imageR, Lambdachannel, varlist, MaskParams, colocalization): idx_col = [Lambdachannel.index(colocalization)] else: idx_col = [] - + notnoisemask, Thr_abovenoise = abovenoise(imageR, varidxs, MaskParams['S_N'], MaskParams['stddev'], MaskParams['bgmean'], idx_col) + combinedmask, satperc = nosaturated(imageR, notnoisemask, varidxs, MaskParams['PixelDepth']) # > S/N + no sat @@ -1878,14 +1879,14 @@ def exportframes(filename, savingpath, frames, dims): try: if sum(np.array(dims) > 1) == 2 or sum(np.array(dims) > 1) == 3: frames.to_excel(excelname + '.xlsx', sheet_name='Global', index=False, header=False, index_label=False) - frames.to_csv(excelname, index=False, header=False, index_label=False) + frames.to_csv(excelname + '.csv', index=False, header=False, index_label=False) elif sum(np.array(dims) > 1) == 4: with pd.ExcelWriter(excelname + '.xlsx', engine='xlsxwriter') as writer: for z in frames.keys(): frames[z].to_excel(writer, sheet_name='slice_{0}'.format(z), index=False, header=False, index_label=False) - frames[z].to_csv(excelname + '_slice_{0}'.format(z), index=False, header=False, index_label=False) + frames[z].to_csv(excelname + '_slice_{0}'.format(z) + '.csv' , index=False, header=False, index_label=False) elif sum(np.array(dims) > 1) == 5: with pd.ExcelWriter(excelname + '.xlsx', engine='xlsxwriter') as writer: @@ -1893,7 +1894,7 @@ def exportframes(filename, savingpath, frames, dims): for z in frames[t].keys(): frames[t][z].to_excel(writer, sheet_name='slice_t{0}_z{1}'.format(t, z), index=False, header=False, index_label=False) - frames[t][z].to_csv(excelname + '_t{0}_z{1}'.format(t, z), index=False, header=False, + frames[t][z].to_csv(excelname + '_t{0}_z{1}'.format(t, z) + '.csv', index=False, header=False, index_label=False) except: print('Nothing to save') diff --git a/Python/Analyzer_V1_0_3.py b/Python/Analyzer_V1_0_3.py new file mode 100644 index 0000000..7155170 --- /dev/null +++ b/Python/Analyzer_V1_0_3.py @@ -0,0 +1,226 @@ +# -*- coding: utf-8 -*- + +from Packages import np +import AllFunctions as F + + + +def GP_Analyser(mode, filename, Lambdachannel, image, dims, varlist, ObjectDetection, profiler, + profilershape, autoff, PDiamCutoff, proDim1, proDim2, text, histpars, histpars_cyto, + text_cyto, profile_cyto, varlist_cyto, n_debranch, tol0, tol1, savecroppedmembrane, savecroppedcyto, + savelinearized, savepath, objlinear, recentering, dim_line, MaskParams_mem, MaskParams_cyto, + colocalization, savephasors, radius): + + Profpars = [profilershape, (proDim1, proDim2), PDiamCutoff] + if dims[0] <= 1 and dims[1] <= 1: # 3dim (t and z are 1) + if mode == 0: + Dict = {'datamask': []} + imageR = image + + slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Thr_abovenoise = \ + F.makemask(imageR, Lambdachannel, varlist, MaskParams_mem, colocalization) + + if profile_cyto: + _, _, Recmask_cyto, _, Meta_cyto, _, _, varidxs_cyto, *_ = \ + F.makemask(imageR, Lambdachannel, varlist_cyto, MaskParams_cyto, colocalization) + Recmask_cyto[Recmask] = False + + else: + Recmask_cyto, Meta_cyto, Reccoors_cyto, varidxs_cyto = [], [], [], [] + + Dict.update( + {'datamask': [slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Recmask_cyto]}) + return Dict + + else: + Dict = {'datamask': [], 'analysis': []} + imageR = image + + slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Thr_abovenoise = \ + F.makemask(imageR, Lambdachannel, varlist, MaskParams_mem, colocalization) + + if profile_cyto: + _, _, Recmask_cyto, _, Meta_cyto, _, _, varidxs_cyto, *_ = \ + F.makemask(imageR, Lambdachannel, varlist_cyto, MaskParams_cyto, colocalization) + Recmask_cyto[Recmask] = False + Reccoors_cyto = np.transpose(np.nonzero(Recmask_cyto)) + + else: + Recmask_cyto, Meta_cyto, Reccoors_cyto, varidxs_cyto = [], [], [], [] + + Dict.update( + {'datamask': [slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Recmask_cyto]}) + + if np.sum(Recmask_cyto) == 0: + profile_cyto = False + + if notempty: + Results, frames = F.measuremask(imageR, Reccoors, Reccoors_cyto, Meta, varidxs, varidxs_cyto, text, + histpars, ObjectDetection, Recmask, + Recmask_cyto, n_debranch, tol0, tol1, Lambdachannel, profile_cyto, + varlist_cyto, text_cyto, savecroppedmembrane, + savecroppedcyto, savepath, profiler, Profpars, autoff, objlinear, radius, + savelinearized, histpars_cyto, recentering, MaskParams_mem['pxlSize'], + MaskParams_mem['PixelDepth'], Thr_abovenoise, dim_line, colocalization, + savephasors) + + F.exportframes(filename, savepath, frames, dims) + + else: + print('Image is empty') + Results = [] + + Dict.update({'analysis': Results}) + + return Dict + + elif dims[0] > 1 or dims[1] > 1: #4dim (t or z is bigger than 1) + if mode == 0: + preDict_z = {z: [] for z in range(image.shape[0])} + for z in range(0, image.shape[0]): + Dict = {'datamask': []} + imageR = image[z, :, :, :] + + slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Thr_abovenoise = \ + F.makemask(imageR, Lambdachannel, varlist, MaskParams_mem[z], colocalization) + + if profile_cyto: + _, _, Recmask_cyto, _, Meta_cyto, _, _, varidxs_cyto, *_ = \ + F.makemask(imageR, Lambdachannel, varlist_cyto, MaskParams_cyto[z], colocalization) + Recmask_cyto[Recmask] = False + + else: + Recmask_cyto, Meta_cyto, Reccoors_cyto, varidxs_cyto = [], [], [], [] + + Dict.update( + {'datamask': [slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, + Recmask_cyto]}) + preDict_z[z] = Dict + + return preDict_z + + else: + preDict_z = {z: [] for z in range(image.shape[0])} + frames_z = {z: [] for z in range(image.shape[0])} + for z in range(0, image.shape[0]): + print('Analyzing slice n{0}'.format(z + 1)) + Dict = {'datamask': [], 'analysis': []} + imageR = image[z, :, :, :] + + slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Thr_abovenoise = \ + F.makemask(imageR, Lambdachannel, varlist, MaskParams_mem[z], colocalization) + + if profile_cyto: + _, _, Recmask_cyto, _, Meta_cyto, _, _, varidxs_cyto, *_ = \ + F.makemask(imageR, Lambdachannel, varlist_cyto, MaskParams_cyto[z], colocalization) + Recmask_cyto[Recmask] = False + Reccoors_cyto = np.transpose(np.nonzero(Recmask_cyto)) + + else: + Recmask_cyto, Meta_cyto, Reccoors_cyto, varidxs_cyto = [], [], [], [] + + Dict.update( + {'datamask': [slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Recmask_cyto]}) + + if np.sum(Recmask_cyto) == 0: + profile_cyto = False + + if notempty: + Results, frames_z[z] = F.measuremask(imageR, Reccoors, Reccoors_cyto, Meta, varidxs, varidxs_cyto, text, + histpars, ObjectDetection, Recmask, + Recmask_cyto, n_debranch, tol0, tol1, Lambdachannel, profile_cyto, + varlist_cyto, text_cyto, savecroppedmembrane, + savecroppedcyto, savepath, profiler, Profpars, autoff, objlinear, + radius, + savelinearized, histpars_cyto, recentering, MaskParams_mem[z]['pxlSize'], + MaskParams_mem[z]['PixelDepth'], Thr_abovenoise, dim_line, colocalization, + savephasors) + + else: + print('Image is empty') + Results = [] + + Dict.update({'analysis': Results}) + + preDict_z[z] = Dict + + F.exportframes(filename, savepath, frames_z, dims) + + return preDict_z + + elif dims[0] > 1 and dims[1] > 1: #5dim (t and z is bigger than 1) + if mode == 0: + preDict_zt = {t: {z: [] for z in range(image.shape[1])} for t in range(image.shape[0])} + for t in range(0, image.shape[0]): + for z in range(0, image.shape[1]): + Dict = {'datamask': []} + imageR = image[t, z, :, :, :] + + slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Thr_abovenoise = \ + F.makemask(imageR, Lambdachannel, varlist, MaskParams_mem[t][z], colocalization) + + if profile_cyto: + _, _, Recmask_cyto, _, Meta_cyto, _, _, varidxs_cyto, *_ = \ + F.makemask(imageR, Lambdachannel, varlist_cyto, MaskParams_cyto[t][z], colocalization) + Recmask_cyto[Recmask] = False + + else: + Recmask_cyto, Meta_cyto, Reccoors_cyto, varidxs_cyto = [], [], [], [] + + Dict.update( + {'datamask': [slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, + Recmask_cyto]}) + preDict_zt[t][z] = Dict + + return preDict_zt + + else: + preDict_zt = {t: {z: [] for z in range(image.shape[1])} for t in range(image.shape[0])} + frames_zt = {t: {z: [] for z in range(image.shape[1])} for t in range(image.shape[0])} + for t in range(0, image.shape[0]): + for z in range(0, image.shape[1]): + print('Analyzing slice t{0}z{1}'.format(t + 1, z + 1)) + Dict = {'datamask': [], 'analysis': []} + imageR = image[t, z, :, :, :] + + slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, Thr_abovenoise = \ + F.makemask(imageR, Lambdachannel, varlist, MaskParams_mem[t][z], colocalization) + + if profile_cyto: + _, _, Recmask_cyto, _, Meta_cyto, _, _, varidxs_cyto, *_ = \ + F.makemask(imageR, Lambdachannel, varlist_cyto, MaskParams_cyto[t][z], colocalization) + Recmask_cyto[Recmask] = False + Reccoors_cyto = np.transpose(np.nonzero(Recmask_cyto)) + + else: + Recmask_cyto, Meta_cyto, Reccoors_cyto, varidxs_cyto = [], [], [], [] + + Dict.update( + {'datamask': [slice_Thr, Threshold, Recmask, IntSum, Meta, Reccoors, notempty, varidxs, + Recmask_cyto]}) + + if np.sum(Recmask_cyto) == 0: + profile_cyto = False + + if notempty: + Results, frames_zt[t][z] = F.measuremask(imageR, Reccoors, Reccoors_cyto, Meta, varidxs, varidxs_cyto, text, + histpars, ObjectDetection, Recmask, + Recmask_cyto, n_debranch, tol0, tol1, Lambdachannel, profile_cyto, + varlist_cyto, text_cyto, savecroppedmembrane, + savecroppedcyto, savepath, profiler, Profpars, autoff, objlinear, + radius, + savelinearized, histpars_cyto, recentering, + MaskParams_mem[t][z]['pxlSize'], + MaskParams_mem[t][z]['PixelDepth'], Thr_abovenoise, dim_line, + colocalization, savephasors) + else: + print('Image is empty') + Results = [] + + Dict.update({'analysis': Results}) + + preDict_zt[t][z] = Dict + + F.exportframes(filename, savepath, frames_zt, dims) + + return preDict_zt \ No newline at end of file diff --git a/Python/README.md b/Python/README.md index 3f0f59a..a93d677 100644 --- a/Python/README.md +++ b/Python/README.md @@ -1,5 +1,8 @@ # User Guide for VISION -**Version**: V1.0.0 +## [Manuscript (biorxiv)](https://www.biorxiv.org/content/10.1101/2024.03.29.587344v1) + + +**Version**: V1.0.2 ## Contents - [Introduction](#introduction) @@ -14,7 +17,7 @@ - [Installation Instructions](#installation-instructions) - [Standalone Version Installation](#standalone-version-installation) - [Windows](#windows) - - [macOS](#macOS) + - [macOS](#macos) - [Python-Based Version Setup](#python-based-version-setup) - [First Launch](#first-launch) - [Navigating the Interface](#navigating-the-interface) @@ -22,7 +25,7 @@ - [Load and Table Interaction Section](#load-and-table-interaction-section) - [Test, Run, and Analysis Settings](#test-run-and-analysis-settings) - [Specific Analysis Settings](#specific-analysis-settings) - - [Membrane Settings – P Value and Analysis](#membrane-settings--p-value-and-analysis) + - [Membrane Settings – β Value and Analysis](#membrane-settings--β-value-and-analysis) - [Membrane Settings – Global Membrane Masking Options](#membrane-settings--global-membrane-masking-options) - [Cytosol Settings](#cytosol-settings) - [Advanced Settings](#advanced-settings) @@ -31,11 +34,14 @@ - [Basic Project Walk Through](#basic-project-walk-through) - [Youtube Tutorials](#youtube-tutorials) - [Advanced Features](#advanced-features) -- [Using '*.ome.tiff' as image format](#using-ome-tiff-as-image-format) +- [Using '*.ome.tiff' as image format](#using-'*.ome.tiff'-as-image-format) - [Troubleshooting and Support](#troubleshooting-and-support) + - [General Guidelines for Microscopy Image Quality](#general-guidelines-for-microscopy-image-quality) + - [Common Issues and Solutions](#common-issues-and-solutions) + - [Error Messages and Solutions](#error-messages-and-solutions) + - [Reporting Bugs](#reporting-bugs) +- [Getting Help](#getting-help) - [Appendix](#appendix) - - [Glossary](#glossary) -- [Index](#index) - [License](#license) ## Introduction @@ -89,7 +95,7 @@ VISION is designed to be easily accessible, offering both a standalone version f #### Standalone Version Installation **General Steps for All Platforms:** -1. Download the ZIP file for your respective operating system (Windows, macOS, or Linux) from the VISION official website. +1. Download the lates VISION Version for your respective operating system (Windows, macOS, or Linux) from the VISION official website (https://github.com/biosciflo/VISION/releases). 2. Extract the ZIP file to your desired location. This will create a folder containing the VISION executable and all necessary dependencies. ##### **Windows:** @@ -104,15 +110,15 @@ macOS prevents certain applications from running due to security restrictions, p **Step 1: Grant Execution Permission** -- **Command**: `chmod +x /path/to/yourApp` +- **Command**: `chmod +x /path/to/VISION(the folder)/VISION(theapp)` - **Purpose**: Grants execute permission to your application, making it runnable on your system. -- **Usage**: Replace `/path/to/yourApp` with the actual path to the application you wish to run. +- **Usage**: Replace `/path/to/VISION(the folder)/VISION(theapp)` with the actual path to the application you wish to run. **Step 2: Remove Quarantine Attribute** -- **Command**: `xattr -cr /path/to/yourApplication` +- **Command**: `xattr -cr /path/to/VISION(the folder)` - **Purpose**: Removes the quarantine attribute macOS applies to files downloaded from the internet, which causes the security block. -- **Usage**: Replace `/path/to/yourApplication` with the path to the affected application or folder containing multiple blocked files. +- **Usage**: Replace `/path/to/VISION(the folder)` with the path to the affected application and folder (_internal) containing multiple blocked files. **Notes** @@ -121,7 +127,7 @@ macOS prevents certain applications from running due to security restrictions, p - This guide is intended to help users quickly resolve issues with running applications that macOS has blocked due to its security settings. -**Linux:** +**Linux(Not supported yet):** - Open a terminal and change to the directory containing the extracted files. - Make the VISION binary executable with the command: `chmod +x VISION` (replace `VISION` with the actual name of the binary file). - Run the application by typing `./VISION` in the terminal. @@ -197,12 +203,12 @@ The main window of VISION is designed with intuitiveness and efficiency in mind, ## Specific Analysis Settings -### Membrane Settings – P Value and Analysis +### Membrane Settings – β Value and Analysis - **Channel Settings**: Upon loading image files, fields A, B, C, & D automatically populate with existing channel information, such as '488' or numbers '1-9', derived directly from the original file's metadata. When loading spectral LSM or CZI files, the results in the comboboxes will include all available channel wavelengths. - **Membrane Profiler**: Enables/disables Membrane Profiler. - **Colocalization**: Enables/disables an additional, independent colocalization channel. The population of the combobox below follows the same procedure as described in Channel Settings above. -- **Equation**: The "Equation" text field leverages the channel settings A, B, C, and D to calculate the P-Value, for example, the GP-Value using the formula “(A-B)/(A+B)”. Please note, only the variables A, B, C, and D are permitted in this field. +- **Equation**: The "Equation" text field leverages the channel settings A, B, C, and D to calculate the β-Value, for example, the GP-Value using the formula “(A-B)/(A+B)”. Please note, only the variables A, B, C, and D are permitted in this field. ### Membrane Settings – Global Membrane Masking Options @@ -232,7 +238,7 @@ The main window of VISION is designed with intuitiveness and efficiency in mind, - **Membrane Profiling – dim_line** - **Membrane Profiling – Integrations Element**: Integration Element Shape - **Membrane Profiling – Integrations Element X/Y-Dimension**: Integration Element XY Dimension -- **Membrane Profiling – P-Value Threshold Auto Cut off** +- **Membrane Profiling – β-Value Threshold Auto Cut off** ### Data Saving @@ -252,30 +258,31 @@ Each panel has a Membrane and Cytosolic part and is split into Mask, Full Image, 1. **Start VISON** 2. **Load File(s) / Load Folder** -3. **(Membrane Settings)** (Optional) Enter Equation for P-Value calculation. -4. **(Membrane Settings)** Select Channels for each used variable in Equation. -5. **(Membrane Settings)** (Optional) Enable and Choose Specific Thresholding Channel. -6. **Test Mask** (if Mask is not optimal follow with Steps a-c, otherwise go to 7) +3. **Inspect RawImage** Inspect all channels and dimensions of your RawImage by clicking onto the Filename in the image table. +4. **(Membrane Settings)** (Optional) Enter Equation for β-Value calculation. +5. **(Membrane Settings)** Select Channels for each used variable in Equation. +6. **(Membrane Settings)** (Optional) Enable and Choose Specific Thresholding Channel. +7. **Test Mask** (if Mask is not optimal follow with Steps a-c, otherwise go to 7) a. Move displayed Raw Image (Right Panel of Mask Results) to the channel of Choose Specific Thresholding Channel or used Channel of Equation with the lowest intensity. Click on “Probe Raw Image” and select a background area. b. Activate Background Compensation. c. Test Mask (if Mask is not optimal follow with Steps d-, otherwise go to 7) d. Enable options such as the Gauss Filter, Dilation, Compression, and Fill Holes, then fine-tune their respective parameters until the mask is satisfactory. Proceed to Step 7 upon completion. -7. **Run Analysis – (Full Image)** +8. **Run Analysis – (Full Image)** a. Check Full Image Results. -8. **Activate Object Detection** -9. **Run Analysis – (Full Image & Object Detection)** +9. **Activate Object Detection** +10. **Run Analysis – (Full Image & Object Detection)** a. If an error appears in the mini console, try to adapt the Masking options; it could be that the subroutines can't detect single objects. b. Check Full Image Results and Object-Related Results. **Note**: Once you have run the image, all Results are automatically Saved. ## Youtube Tutorials: -- [TUTORIAL1](https://) -- [TUTORIAL2](https://) -- [TUTORIAL3](https://) +- [TUTORIAL1 - VISION BASIC TUTORIAL](https://) +- [TUTORIAL2 - Image analysis via VISION](https://youtu.be/ZDZju8mgNiY?si=7WxcNF6_3l1iwFpn) +- [TUTORIAL3 - Working with .ome.tif images in VISION](https://youtu.be/NmAVgJb-E-g?si=5x0bynHKfuwzkJ2S) # Advanced Features -- **Custom Analyses**: Equations???? Different Equations? +- **Custom Analyses**: (cooming soon) - **Patch Processing**: If multiple images are in the Image – List, either: - Select Multiple Images and press Run – Selected Images will be Processed. Or… @@ -286,7 +293,6 @@ Each panel has a Membrane and Cytosolic part and is split into Mask, Full Image, - Important Note for Batch Processing: To apply specific masking options across multiple images in batch processing, it is essential to first initialize the detailed masking settings for each image file listed in the image table. This involves clicking on each file to activate the detailed options. Failing to perform this step may result in a key value error displayed in the mini console. We are aware of this issue and plan to streamline the process in future updates of VISION. - # Using '*.ome.tiff' as imageformat: Currently image file types of '*.lsm' and '*.czi' can be openend but with '*.ome.tiff' (imagej/fiji) all images can be anlaysed with VISION. - Other image types: If you have special image types such as .lif or .obf. Please get in touch with us. We will be happy to implement the image type if you can provide us with some test images. @@ -306,19 +312,243 @@ Currently image file types of '*.lsm' and '*.czi' can be openend but with '*.ome # Troubleshooting and Support -- **Common Issues and Solutions**: As of now, no common issues have been identified. However, we acknowledge that problems we have not yet tested may arise. We appreciate your understanding and patience in these matters. We also encourage you to assist us by reporting any problems you encounter. Your feedback is invaluable in helping us continuously improve the software. -- **Software Updates**: We will release eventually, updates where we cover all the bugs which we and you encounter. New releases you will find here at the GitHub repository. -- **Getting Help**: At the GitHub repository. +## General Guidelines for Microscopy Image Quality -# Appendix +### Minimum Information Guidelines for Fluorescence Microscopy +- **Metadata**: Ensure that all relevant metadata is recorded, including details about the imaging setup, sample preparation, and acquisition settings. This includes the type of microscope, objective lenses, exposure times, and light sources used. +- **Calibration**: Maintain consistent calibration of imaging systems to ensure reproducibility. Include calibration scales or indicators in the images. +- **Transparency**: Provide information on the software and settings used for image analysis to allow for reproducibility and transparency. -- **Glossary**: Definitions of terms and concepts used within the guide and software. -- **FAQs**: Answers to frequently asked questions about the software. +### Signal-to-Noise Ratio (SNR) Optimization +- **Photon Noise Management**: Maximize photon detection by optimizing exposure times and minimizing background noise through appropriate use of detector apertures and cooling techniques for CCD cameras. +- **Dark and Read Noise**: Reduce thermal noise by cooling the camera sensor and minimize read noise by using high-performance cameras designed for low-light imaging. + +### Image Acquisition and Processing +- **Sampling Rates**: Use appropriate sampling rates to ensure that the pixel size is suitable for the resolution of the microscope. The Nyquist criterion suggests that the pixel size should be at least half the size of the optical resolution limit. +- **Contrast and Brightness**: Adjust contrast and brightness appropriately without over-processing the images. Maintain the original data integrity to allow for proper interpretation and analysis. +- **Image Restoration**: Implement deconvolution and other image restoration techniques to improve image clarity while maintaining the original information content. + +### Quality Control and Troubleshooting +- **Calibration**: Regularly check and maintain the calibration of the microscope and imaging system. Include a troubleshooting section in your manual to address common issues such as focus drift, alignment problems, and illumination inconsistencies. +- **Artifact Recognition**: Provide example images and descriptions of common artifacts and how to avoid or correct them. This can help users recognize and troubleshoot problems in their own imaging setups. + +### Community Standards and Checklists +- **Community Guidelines**: Follow established community guidelines, such as those from the QUAREP-LiMi initiative, which provides detailed checklists and protocols for quality assessment and reproducibility in light microscopy. These guidelines cover a wide range of aspects from data acquisition to image analysis and publication standards. +- **Data Sharing**: Encourage users to share their data and analysis pipelines in public repositories to promote transparency and reproducibility in the scientific community. + +### Useful Resources +- [EMBL Guidelines for Microscopy Images](https://www.embl.org/news/science/global-guidelines-to-improve-the-quality-of-microscopy-images-in-scientific-publications/) +- [QUAREP-LiMi Guidelines](https://quarep.org/) +- [Minimum Information Guidelines for Fluorescence Microscopy](https://arxiv.org/abs/2101.09153) + + +## Common Issues and Solutions + +### 1. Software Installation Problems + +**Issue:** +The VISION software does not install correctly. + +**Potential Causes:** +- Incompatible operating system or hardware. +- Missing dependencies. + +**Solutions:** +- Ensure your system meets the minimum requirements listed in the installation guide. +- Follow the installation steps carefully, and ensure all necessary dependencies are installed. +- Refer to the installation section for detailed instructions. + +### 2. Software Crashes or Freezes + +**Issue:** +The software crashes or becomes unresponsive during use. + +**Potential Causes:** +- Insufficient system resources (RAM, CPU). +- Bug in the software. + +**Solutions:** +- Close other applications to free up system resources. +- Ensure your system meets the recommended hardware specifications. +- Check for software updates that may address stability issues. +- Report the issue on our [ISSUES](https://github.com/biosciflo/VISION/issues) with detailed information about your system and the problem. (How to report: [Reporting Bugs](#reporting-bugs)) + +### 3. Error Messages + +**Issue:** +You encounter error messages while using the software. + +**Potential Causes:** +- Incorrect usage or unsupported operations. +- Missing or corrupt files. + +**Solutions:** +- Refer to the error message documentation in the manual or on our [Error Messages and Solutions](#Error-Messages-and-Solutions) to understand the cause and potential fixes. +- Ensure all required files are present and correctly formatted. + +### 4. Unexpected Results + +**Issue:** +The software produces unexpected or incorrect results. + +**Potential Causes:** +- Incorrect input data or parameters. +- Misconfigured settings. +- Bug in the software. + +**Solutions:** +- Verify that your input data meets the software's requirements. +- Double-check all parameters and settings before running the software. +- Refer to the user manual for guidance on proper usage and configuration. +- Report the issue on our [ISSUES](https://github.com/biosciflo/VISION/issues) with detailed information about your system and the problem. (How to report: [Reporting Bugs](#reporting-bugs)) + +## Error Messages and Solutions + +1. **Error Message:** `Error: Invalid character '{char}' found in the text. ('E', 'I', 'N', 'O', 'Q', 'S' are reserved for mathematical operators). Please use A,B,C or D.` + + - **Cause:** Invalid character found in the input string. + - **Solution:** Ensure that only characters A, B, C, and D are used in the input string. + +2. **Error Message:** `Error: Invalid letter '{char}' found in the text.` + + - **Cause:** Invalid uppercase letter found in the input string. + - **Solution:** Ensure only A, B, C, and D are used as uppercase letters. + +3. **Error Message:** `Error Membrane Settings: Letter(s) {chars} are in use in the Equation, but corresponding ComboBox value(s) are not selected. Please select a Channel for {chars}` + + - **Cause:** ComboBox values for certain letters (A,B,C,D) are not selected. + - **Solution:** Select the appropriate ComboBox (A,B,C,D) values for the letters used in the equation. + +4. **Error Message:** `Error Membrane Settings: Letter(s) {chars} are not 'NaN' but corresponding letter(s) are not used in the equation. Please select 'NaN' for {chars}` + + - **Cause:** ComboBox (A,B,C,D) values are not 'NaN' while the corresponding letters are not used in the equation. + - **Solution:** Set the ComboBox (A,B,C,D) values to 'NaN' for the letters not used in the equation. + +5. **Error Message:** `Error: It was not possible to detect single objects. Please check your masking and thresholding settings.` + + - **Cause:** Function DBSCAN found no samples or no objects to concatenate. + - **Solution:** Review and adjust the masking and thresholding settings. + + +6. **Error Message:** `Invalid value. Expected 'NAN'.` + + - **Cause:** Value conversion failed, and the value was not 'NAN'. + - **Solution:** Ensure the value is either valid or 'NAN' as expected. + +7. **Error Message:** `The value '{newValue}' is not valid for 'Thresholding Mode'. (Otsu or Manual)` + + - **Cause:** Invalid value for Thresholding Mode. + - **Solution:** Use either 'Otsu' or 'Manual' for Thresholding Mode. -# Index +8. **Error Message:** `The value '{newValue}' is not valid for 'Manual Cutoff Level'. (a int)` -- **Keyword Index**: An index to help users quickly find information within the guide. + - **Cause:** Non-integer value for Manual Cutoff Level. + - **Solution:** Enter an integer value for Manual Cutoff Level. +9. **Error Message:** `The value '{newValue}' is not valid for 'Compression True/False'. (True or False)` + + - **Cause:** Invalid value for Compression True/False. + - **Solution:** Use either 'True' or 'False' for Compression. + +10. **Error Message:** `The value '{newValue}' is not valid for 'Compression Value'. (a float)` + + - **Cause:** Non-float value for Compression Value. + - **Solution:** Enter a float value for Compression Value. + +11. **Error Message:** `The value '{newValue}' is not valid for 'Remove Object'. (NaN or a int)` + + - **Cause:** Value for Remove Object is neither 'NaN' nor an integer. + - **Solution:** Use either 'NaN' or an integer for Remove Object. + +12. **Error Message:** `The value '{newValue}' is not valid for 'Fill Holes'. (NaN or a float)` + + - **Cause:** Value for Fill Holes is neither 'NaN' nor a float. + - **Solution:** Use either 'NaN' or a float for Fill Holes. + +13. **Error Message:** `The value '{newValue}' is not valid for 'Dilate True/False'. (True or False)` + + - **Cause:** Invalid value for Dilate True/False. + - **Solution:** Use either 'True' or 'False' for Dilate. + +14. **Error Message:** `The value '{newValue}' is not valid for 'Dilation Shape'. (octagon, disk or square)` + + - **Cause:** Invalid value for Dilation Shape. + - **Solution:** Use either 'octagon', 'disk', or 'square' for Dilation Shape. + +15. **Error Message:** `The value '{newValue}' is not valid for 'Dilation Shape Dimension 1'. (a int)` + + - **Cause:** Non-integer value for Dilation Shape Dimension 1. + - **Solution:** Enter an integer value for Dilation Shape Dimension 1. + +16. **Error Message:** `The value '{newValue}' is not valid for 'Dilation Shape Dimension 2'. (a int)` + + - **Cause:** Non-integer value for Dilation Shape Dimension 2. + - **Solution:** Enter an integer value for Dilation Shape Dimension 2. + +17. **Error Message:** `The value "{newValue}" is not valid for "Filter Type". ( pls choose one of these: "No Filter", "Gaussian", "Mode", "Median", "Mean", "Geometric_mean","Majority","Minimum","Maximum","Sum","Gradient","Entropy")` + + - **Cause:** Invalid value for Filter Type. + - **Solution:** Choose one of the valid filter types listed. + +18. **Error Message:** `The value '{newValue}' is not valid for 'Filter Value'. (a float)` + + - **Cause:** Non-float value for Filter Value. + - **Solution:** Enter a float value for Filter Value. + +19. **Error Message:** `The value '{newValue}' is not valid for 'Signal to Noise Ratio'. (a float)` + + - **Cause:** Non-float value for Signal to Noise Ratio. + - **Solution:** Enter a float value for Signal to Noise Ratio. + +20. **Error Message:** `The value '{newValue}' is not valid for 'Background StdDev'. (a float)` + + - **Cause:** Non-float value for Background StdDev. + - **Solution:** Enter a float value for Background StdDev. + +21. **Error Message:** `The value '{newValue}' is not valid for 'Background Mean'. (NaN or a float)` + + - **Cause:** Value for Background Mean is neither 'NaN' nor a float. + - **Solution:** Use either 'NaN' or a float for Background Mean. + +22. **Error Message:** `The value '{value}' is not valid for 'Specific Channel Wavelength'. (NaN or a list of available channels e.g. [488,647])` + + - **Cause:** Invalid value for Specific Channel Wavelength. + - **Solution:** Use either 'NaN' or a list of available channels (e.g., [488, 647]) for Specific Channel Wavelength. + +## Reporting Bugs +If you encounter any issues while using our software, we highly encourage you to report them on our [ISSUES](https://github.com/biosciflo/VISION/issues) page so we can work on fixing them promptly. Here's how to report a bug on GitHub: + +**Visit the GitHub Repository:** Navigate to our software's GitHub repository. If you're not already signed in, GitHub will prompt you to log in or create a new account. + +**Check Existing Issues:** Before submitting a new bug report, please take a moment to check if the issue has already been reported. You can use the repository's search tool to find issues by keywords. If you find an existing issue that matches yours, you can add any new information you have to that issue rather than creating a new one. + +**Create a New Issue:** If your issue is new, click the 'Issues' tab in the repository, and then click the 'New issue' button. If the repository uses issue templates, select the one that matches your situation or choose 'Open a blank issue' if none of the templates fit. + +**Fill Out the Issue Template:** Provide a clear and concise title for your issue. Fill in the template with as much detail as possible. Be sure to include de following parts: + +- A brief description of the issue. +- Steps to reproduce the issue. +- Expected behavior and what actually happens. +- Any relevant error messages or screenshots. For that please add the "global_error_log.txt" and/or "error_log.txt". They are in the folder were your executable file is located. +- Your operating system and version, as well as the software version you're using. +- Any files that you used. +- Submit the Issue: Once you've filled out the template, submit your issue by clicking the 'Submit new issue' button. + +**Monitor Your Issue:** After submitting, keep an eye on your issue for any comments or questions from the development team. They may need more information or provide a workaround or solution. + +Your reports play a crucial role in improving the quality of the software, and we appreciate your contributions to making our project better for everyone. + +# Getting Help + +If you encounter issues not covered in this guide, please refer to the following resources: + +- **Support:** Contact us for support via the [ISSUES](https://github.com/biosciflo/VISION/issues) . + +We hope this troubleshooting guide helps you resolve any issues and enhances your experience with the VISION software. + +# Appendix + +- **FAQs**: Answers to frequently asked questions about the software. ## License diff --git a/Python/README.txt b/Python/README.txt index 42b37b1..783f329 100644 --- a/Python/README.txt +++ b/Python/README.txt @@ -1,5 +1,8 @@ # User Guide for VISION -**Version**: V1.0.0 +## [Manuscript (biorxiv)](https://www.biorxiv.org/content/10.1101/2024.03.29.587344v1) + + +**Version**: V1.0.2 ## Contents - [Introduction](#introduction) @@ -14,7 +17,7 @@ - [Installation Instructions](#installation-instructions) - [Standalone Version Installation](#standalone-version-installation) - [Windows](#windows) - - [macOS](#macOS) + - [macOS](#macos) - [Python-Based Version Setup](#python-based-version-setup) - [First Launch](#first-launch) - [Navigating the Interface](#navigating-the-interface) @@ -22,7 +25,7 @@ - [Load and Table Interaction Section](#load-and-table-interaction-section) - [Test, Run, and Analysis Settings](#test-run-and-analysis-settings) - [Specific Analysis Settings](#specific-analysis-settings) - - [Membrane Settings – P Value and Analysis](#membrane-settings--p-value-and-analysis) + - [Membrane Settings – β Value and Analysis](#membrane-settings--β-value-and-analysis) - [Membrane Settings – Global Membrane Masking Options](#membrane-settings--global-membrane-masking-options) - [Cytosol Settings](#cytosol-settings) - [Advanced Settings](#advanced-settings) @@ -31,11 +34,14 @@ - [Basic Project Walk Through](#basic-project-walk-through) - [Youtube Tutorials](#youtube-tutorials) - [Advanced Features](#advanced-features) -- [Using '*.ome.tiff' as image format](#using-ome-tiff-as-image-format) +- [Using '*.ome.tiff' as image format](#using-'*.ome.tiff'-as-image-format) - [Troubleshooting and Support](#troubleshooting-and-support) + - [General Guidelines for Microscopy Image Quality](#general-guidelines-for-microscopy-image-quality) + - [Common Issues and Solutions](#common-issues-and-solutions) + - [Error Messages and Solutions](#error-messages-and-solutions) + - [Reporting Bugs](#reporting-bugs) +- [Getting Help](#getting-help) - [Appendix](#appendix) - - [Glossary](#glossary) -- [Index](#index) - [License](#license) ## Introduction @@ -89,7 +95,7 @@ VISION is designed to be easily accessible, offering both a standalone version f #### Standalone Version Installation **General Steps for All Platforms:** -1. Download the ZIP file for your respective operating system (Windows, macOS, or Linux) from the VISION official website. +1. Download the lates VISION Version for your respective operating system (Windows, macOS, or Linux) from the VISION official website (https://github.com/biosciflo/VISION/releases). 2. Extract the ZIP file to your desired location. This will create a folder containing the VISION executable and all necessary dependencies. ##### **Windows:** @@ -104,15 +110,15 @@ macOS prevents certain applications from running due to security restrictions, p **Step 1: Grant Execution Permission** -- **Command**: `chmod +x /path/to/yourApp` +- **Command**: `chmod +x /path/to/VISION(the folder)/VISION(theapp)` - **Purpose**: Grants execute permission to your application, making it runnable on your system. -- **Usage**: Replace `/path/to/yourApp` with the actual path to the application you wish to run. +- **Usage**: Replace `/path/to/VISION(the folder)/VISION(theapp)` with the actual path to the application you wish to run. **Step 2: Remove Quarantine Attribute** -- **Command**: `xattr -cr /path/to/yourApplication` +- **Command**: `xattr -cr /path/to/VISION(the folder)` - **Purpose**: Removes the quarantine attribute macOS applies to files downloaded from the internet, which causes the security block. -- **Usage**: Replace `/path/to/yourApplication` with the path to the affected application or folder containing multiple blocked files. +- **Usage**: Replace `/path/to/VISION(the folder)` with the path to the affected application and folder (_internal) containing multiple blocked files. **Notes** @@ -121,7 +127,7 @@ macOS prevents certain applications from running due to security restrictions, p - This guide is intended to help users quickly resolve issues with running applications that macOS has blocked due to its security settings. -**Linux:** +**Linux(Not supported yet):** - Open a terminal and change to the directory containing the extracted files. - Make the VISION binary executable with the command: `chmod +x VISION` (replace `VISION` with the actual name of the binary file). - Run the application by typing `./VISION` in the terminal. @@ -197,12 +203,12 @@ The main window of VISION is designed with intuitiveness and efficiency in mind, ## Specific Analysis Settings -### Membrane Settings – P Value and Analysis +### Membrane Settings – β Value and Analysis - **Channel Settings**: Upon loading image files, fields A, B, C, & D automatically populate with existing channel information, such as '488' or numbers '1-9', derived directly from the original file's metadata. When loading spectral LSM or CZI files, the results in the comboboxes will include all available channel wavelengths. - **Membrane Profiler**: Enables/disables Membrane Profiler. - **Colocalization**: Enables/disables an additional, independent colocalization channel. The population of the combobox below follows the same procedure as described in Channel Settings above. -- **Equation**: The "Equation" text field leverages the channel settings A, B, C, and D to calculate the P-Value, for example, the GP-Value using the formula “(A-B)/(A+B)”. Please note, only the variables A, B, C, and D are permitted in this field. +- **Equation**: The "Equation" text field leverages the channel settings A, B, C, and D to calculate the β-Value, for example, the GP-Value using the formula “(A-B)/(A+B)”. Please note, only the variables A, B, C, and D are permitted in this field. ### Membrane Settings – Global Membrane Masking Options @@ -232,7 +238,7 @@ The main window of VISION is designed with intuitiveness and efficiency in mind, - **Membrane Profiling – dim_line** - **Membrane Profiling – Integrations Element**: Integration Element Shape - **Membrane Profiling – Integrations Element X/Y-Dimension**: Integration Element XY Dimension -- **Membrane Profiling – P-Value Threshold Auto Cut off** +- **Membrane Profiling – β-Value Threshold Auto Cut off** ### Data Saving @@ -252,30 +258,31 @@ Each panel has a Membrane and Cytosolic part and is split into Mask, Full Image, 1. **Start VISON** 2. **Load File(s) / Load Folder** -3. **(Membrane Settings)** (Optional) Enter Equation for P-Value calculation. -4. **(Membrane Settings)** Select Channels for each used variable in Equation. -5. **(Membrane Settings)** (Optional) Enable and Choose Specific Thresholding Channel. -6. **Test Mask** (if Mask is not optimal follow with Steps a-c, otherwise go to 7) +3. **Inspect RawImage** Inspect all channels and dimensions of your RawImage by clicking onto the Filename in the image table. +4. **(Membrane Settings)** (Optional) Enter Equation for β-Value calculation. +5. **(Membrane Settings)** Select Channels for each used variable in Equation. +6. **(Membrane Settings)** (Optional) Enable and Choose Specific Thresholding Channel. +7. **Test Mask** (if Mask is not optimal follow with Steps a-c, otherwise go to 7) a. Move displayed Raw Image (Right Panel of Mask Results) to the channel of Choose Specific Thresholding Channel or used Channel of Equation with the lowest intensity. Click on “Probe Raw Image” and select a background area. b. Activate Background Compensation. c. Test Mask (if Mask is not optimal follow with Steps d-, otherwise go to 7) d. Enable options such as the Gauss Filter, Dilation, Compression, and Fill Holes, then fine-tune their respective parameters until the mask is satisfactory. Proceed to Step 7 upon completion. -7. **Run Analysis – (Full Image)** +8. **Run Analysis – (Full Image)** a. Check Full Image Results. -8. **Activate Object Detection** -9. **Run Analysis – (Full Image & Object Detection)** +9. **Activate Object Detection** +10. **Run Analysis – (Full Image & Object Detection)** a. If an error appears in the mini console, try to adapt the Masking options; it could be that the subroutines can't detect single objects. b. Check Full Image Results and Object-Related Results. **Note**: Once you have run the image, all Results are automatically Saved. ## Youtube Tutorials: -- [TUTORIAL1](https://) -- [TUTORIAL2](https://) -- [TUTORIAL3](https://) +- [TUTORIAL1 - VISION BASIC TUTORIAL](https://) +- [TUTORIAL2 - Image analysis via VISION](https://youtu.be/ZDZju8mgNiY?si=7WxcNF6_3l1iwFpn) +- [TUTORIAL3 - Working with .ome.tif images in VISION](https://youtu.be/NmAVgJb-E-g?si=5x0bynHKfuwzkJ2S) # Advanced Features -- **Custom Analyses**: Equations???? Different Equations? +- **Custom Analyses**: (cooming soon) - **Patch Processing**: If multiple images are in the Image – List, either: - Select Multiple Images and press Run – Selected Images will be Processed. Or… @@ -286,7 +293,6 @@ Each panel has a Membrane and Cytosolic part and is split into Mask, Full Image, - Important Note for Batch Processing: To apply specific masking options across multiple images in batch processing, it is essential to first initialize the detailed masking settings for each image file listed in the image table. This involves clicking on each file to activate the detailed options. Failing to perform this step may result in a key value error displayed in the mini console. We are aware of this issue and plan to streamline the process in future updates of VISION. - # Using '*.ome.tiff' as imageformat: Currently image file types of '*.lsm' and '*.czi' can be openend but with '*.ome.tiff' (imagej/fiji) all images can be anlaysed with VISION. - Other image types: If you have special image types such as .lif or .obf. Please get in touch with us. We will be happy to implement the image type if you can provide us with some test images. @@ -306,19 +312,243 @@ Currently image file types of '*.lsm' and '*.czi' can be openend but with '*.ome # Troubleshooting and Support -- **Common Issues and Solutions**: As of now, no common issues have been identified. However, we acknowledge that problems we have not yet tested may arise. We appreciate your understanding and patience in these matters. We also encourage you to assist us by reporting any problems you encounter. Your feedback is invaluable in helping us continuously improve the software. -- **Software Updates**: We will release eventually, updates where we cover all the bugs which we and you encounter. New releases you will find here at the GitHub repository. -- **Getting Help**: At the GitHub repository. +## General Guidelines for Microscopy Image Quality -# Appendix +### Minimum Information Guidelines for Fluorescence Microscopy +- **Metadata**: Ensure that all relevant metadata is recorded, including details about the imaging setup, sample preparation, and acquisition settings. This includes the type of microscope, objective lenses, exposure times, and light sources used. +- **Calibration**: Maintain consistent calibration of imaging systems to ensure reproducibility. Include calibration scales or indicators in the images. +- **Transparency**: Provide information on the software and settings used for image analysis to allow for reproducibility and transparency. -- **Glossary**: Definitions of terms and concepts used within the guide and software. -- **FAQs**: Answers to frequently asked questions about the software. +### Signal-to-Noise Ratio (SNR) Optimization +- **Photon Noise Management**: Maximize photon detection by optimizing exposure times and minimizing background noise through appropriate use of detector apertures and cooling techniques for CCD cameras. +- **Dark and Read Noise**: Reduce thermal noise by cooling the camera sensor and minimize read noise by using high-performance cameras designed for low-light imaging. + +### Image Acquisition and Processing +- **Sampling Rates**: Use appropriate sampling rates to ensure that the pixel size is suitable for the resolution of the microscope. The Nyquist criterion suggests that the pixel size should be at least half the size of the optical resolution limit. +- **Contrast and Brightness**: Adjust contrast and brightness appropriately without over-processing the images. Maintain the original data integrity to allow for proper interpretation and analysis. +- **Image Restoration**: Implement deconvolution and other image restoration techniques to improve image clarity while maintaining the original information content. + +### Quality Control and Troubleshooting +- **Calibration**: Regularly check and maintain the calibration of the microscope and imaging system. Include a troubleshooting section in your manual to address common issues such as focus drift, alignment problems, and illumination inconsistencies. +- **Artifact Recognition**: Provide example images and descriptions of common artifacts and how to avoid or correct them. This can help users recognize and troubleshoot problems in their own imaging setups. + +### Community Standards and Checklists +- **Community Guidelines**: Follow established community guidelines, such as those from the QUAREP-LiMi initiative, which provides detailed checklists and protocols for quality assessment and reproducibility in light microscopy. These guidelines cover a wide range of aspects from data acquisition to image analysis and publication standards. +- **Data Sharing**: Encourage users to share their data and analysis pipelines in public repositories to promote transparency and reproducibility in the scientific community. + +### Useful Resources +- [EMBL Guidelines for Microscopy Images](https://www.embl.org/news/science/global-guidelines-to-improve-the-quality-of-microscopy-images-in-scientific-publications/) +- [QUAREP-LiMi Guidelines](https://quarep.org/) +- [Minimum Information Guidelines for Fluorescence Microscopy](https://arxiv.org/abs/2101.09153) + + +## Common Issues and Solutions + +### 1. Software Installation Problems + +**Issue:** +The VISION software does not install correctly. + +**Potential Causes:** +- Incompatible operating system or hardware. +- Missing dependencies. + +**Solutions:** +- Ensure your system meets the minimum requirements listed in the installation guide. +- Follow the installation steps carefully, and ensure all necessary dependencies are installed. +- Refer to the installation section for detailed instructions. + +### 2. Software Crashes or Freezes + +**Issue:** +The software crashes or becomes unresponsive during use. + +**Potential Causes:** +- Insufficient system resources (RAM, CPU). +- Bug in the software. + +**Solutions:** +- Close other applications to free up system resources. +- Ensure your system meets the recommended hardware specifications. +- Check for software updates that may address stability issues. +- Report the issue on our [ISSUES](https://github.com/biosciflo/VISION/issues) with detailed information about your system and the problem. (How to report: [Reporting Bugs](#reporting-bugs)) + +### 3. Error Messages + +**Issue:** +You encounter error messages while using the software. + +**Potential Causes:** +- Incorrect usage or unsupported operations. +- Missing or corrupt files. + +**Solutions:** +- Refer to the error message documentation in the manual or on our [Error Messages and Solutions](#Error-Messages-and-Solutions) to understand the cause and potential fixes. +- Ensure all required files are present and correctly formatted. + +### 4. Unexpected Results + +**Issue:** +The software produces unexpected or incorrect results. + +**Potential Causes:** +- Incorrect input data or parameters. +- Misconfigured settings. +- Bug in the software. + +**Solutions:** +- Verify that your input data meets the software's requirements. +- Double-check all parameters and settings before running the software. +- Refer to the user manual for guidance on proper usage and configuration. +- Report the issue on our [ISSUES](https://github.com/biosciflo/VISION/issues) with detailed information about your system and the problem. (How to report: [Reporting Bugs](#reporting-bugs)) + +## Error Messages and Solutions + +1. **Error Message:** `Error: Invalid character '{char}' found in the text. ('E', 'I', 'N', 'O', 'Q', 'S' are reserved for mathematical operators). Please use A,B,C or D.` + + - **Cause:** Invalid character found in the input string. + - **Solution:** Ensure that only characters A, B, C, and D are used in the input string. + +2. **Error Message:** `Error: Invalid letter '{char}' found in the text.` + + - **Cause:** Invalid uppercase letter found in the input string. + - **Solution:** Ensure only A, B, C, and D are used as uppercase letters. + +3. **Error Message:** `Error Membrane Settings: Letter(s) {chars} are in use in the Equation, but corresponding ComboBox value(s) are not selected. Please select a Channel for {chars}` + + - **Cause:** ComboBox values for certain letters (A,B,C,D) are not selected. + - **Solution:** Select the appropriate ComboBox (A,B,C,D) values for the letters used in the equation. + +4. **Error Message:** `Error Membrane Settings: Letter(s) {chars} are not 'NaN' but corresponding letter(s) are not used in the equation. Please select 'NaN' for {chars}` + + - **Cause:** ComboBox (A,B,C,D) values are not 'NaN' while the corresponding letters are not used in the equation. + - **Solution:** Set the ComboBox (A,B,C,D) values to 'NaN' for the letters not used in the equation. + +5. **Error Message:** `Error: It was not possible to detect single objects. Please check your masking and thresholding settings.` + + - **Cause:** Function DBSCAN found no samples or no objects to concatenate. + - **Solution:** Review and adjust the masking and thresholding settings. + + +6. **Error Message:** `Invalid value. Expected 'NAN'.` + + - **Cause:** Value conversion failed, and the value was not 'NAN'. + - **Solution:** Ensure the value is either valid or 'NAN' as expected. + +7. **Error Message:** `The value '{newValue}' is not valid for 'Thresholding Mode'. (Otsu or Manual)` + + - **Cause:** Invalid value for Thresholding Mode. + - **Solution:** Use either 'Otsu' or 'Manual' for Thresholding Mode. -# Index +8. **Error Message:** `The value '{newValue}' is not valid for 'Manual Cutoff Level'. (a int)` -- **Keyword Index**: An index to help users quickly find information within the guide. + - **Cause:** Non-integer value for Manual Cutoff Level. + - **Solution:** Enter an integer value for Manual Cutoff Level. +9. **Error Message:** `The value '{newValue}' is not valid for 'Compression True/False'. (True or False)` + + - **Cause:** Invalid value for Compression True/False. + - **Solution:** Use either 'True' or 'False' for Compression. + +10. **Error Message:** `The value '{newValue}' is not valid for 'Compression Value'. (a float)` + + - **Cause:** Non-float value for Compression Value. + - **Solution:** Enter a float value for Compression Value. + +11. **Error Message:** `The value '{newValue}' is not valid for 'Remove Object'. (NaN or a int)` + + - **Cause:** Value for Remove Object is neither 'NaN' nor an integer. + - **Solution:** Use either 'NaN' or an integer for Remove Object. + +12. **Error Message:** `The value '{newValue}' is not valid for 'Fill Holes'. (NaN or a float)` + + - **Cause:** Value for Fill Holes is neither 'NaN' nor a float. + - **Solution:** Use either 'NaN' or a float for Fill Holes. + +13. **Error Message:** `The value '{newValue}' is not valid for 'Dilate True/False'. (True or False)` + + - **Cause:** Invalid value for Dilate True/False. + - **Solution:** Use either 'True' or 'False' for Dilate. + +14. **Error Message:** `The value '{newValue}' is not valid for 'Dilation Shape'. (octagon, disk or square)` + + - **Cause:** Invalid value for Dilation Shape. + - **Solution:** Use either 'octagon', 'disk', or 'square' for Dilation Shape. + +15. **Error Message:** `The value '{newValue}' is not valid for 'Dilation Shape Dimension 1'. (a int)` + + - **Cause:** Non-integer value for Dilation Shape Dimension 1. + - **Solution:** Enter an integer value for Dilation Shape Dimension 1. + +16. **Error Message:** `The value '{newValue}' is not valid for 'Dilation Shape Dimension 2'. (a int)` + + - **Cause:** Non-integer value for Dilation Shape Dimension 2. + - **Solution:** Enter an integer value for Dilation Shape Dimension 2. + +17. **Error Message:** `The value "{newValue}" is not valid for "Filter Type". ( pls choose one of these: "No Filter", "Gaussian", "Mode", "Median", "Mean", "Geometric_mean","Majority","Minimum","Maximum","Sum","Gradient","Entropy")` + + - **Cause:** Invalid value for Filter Type. + - **Solution:** Choose one of the valid filter types listed. + +18. **Error Message:** `The value '{newValue}' is not valid for 'Filter Value'. (a float)` + + - **Cause:** Non-float value for Filter Value. + - **Solution:** Enter a float value for Filter Value. + +19. **Error Message:** `The value '{newValue}' is not valid for 'Signal to Noise Ratio'. (a float)` + + - **Cause:** Non-float value for Signal to Noise Ratio. + - **Solution:** Enter a float value for Signal to Noise Ratio. + +20. **Error Message:** `The value '{newValue}' is not valid for 'Background StdDev'. (a float)` + + - **Cause:** Non-float value for Background StdDev. + - **Solution:** Enter a float value for Background StdDev. + +21. **Error Message:** `The value '{newValue}' is not valid for 'Background Mean'. (NaN or a float)` + + - **Cause:** Value for Background Mean is neither 'NaN' nor a float. + - **Solution:** Use either 'NaN' or a float for Background Mean. + +22. **Error Message:** `The value '{value}' is not valid for 'Specific Channel Wavelength'. (NaN or a list of available channels e.g. [488,647])` + + - **Cause:** Invalid value for Specific Channel Wavelength. + - **Solution:** Use either 'NaN' or a list of available channels (e.g., [488, 647]) for Specific Channel Wavelength. + +## Reporting Bugs +If you encounter any issues while using our software, we highly encourage you to report them on our [ISSUES](https://github.com/biosciflo/VISION/issues) page so we can work on fixing them promptly. Here's how to report a bug on GitHub: + +**Visit the GitHub Repository:** Navigate to our software's GitHub repository. If you're not already signed in, GitHub will prompt you to log in or create a new account. + +**Check Existing Issues:** Before submitting a new bug report, please take a moment to check if the issue has already been reported. You can use the repository's search tool to find issues by keywords. If you find an existing issue that matches yours, you can add any new information you have to that issue rather than creating a new one. + +**Create a New Issue:** If your issue is new, click the 'Issues' tab in the repository, and then click the 'New issue' button. If the repository uses issue templates, select the one that matches your situation or choose 'Open a blank issue' if none of the templates fit. + +**Fill Out the Issue Template:** Provide a clear and concise title for your issue. Fill in the template with as much detail as possible. Be sure to include de following parts: + +- A brief description of the issue. +- Steps to reproduce the issue. +- Expected behavior and what actually happens. +- Any relevant error messages or screenshots. For that please add the "global_error_log.txt" and/or "error_log.txt". They are in the folder were your executable file is located. +- Your operating system and version, as well as the software version you're using. +- Any files that you used. +- Submit the Issue: Once you've filled out the template, submit your issue by clicking the 'Submit new issue' button. + +**Monitor Your Issue:** After submitting, keep an eye on your issue for any comments or questions from the development team. They may need more information or provide a workaround or solution. + +Your reports play a crucial role in improving the quality of the software, and we appreciate your contributions to making our project better for everyone. + +# Getting Help + +If you encounter issues not covered in this guide, please refer to the following resources: + +- **Support:** Contact us for support via the [ISSUES](https://github.com/biosciflo/VISION/issues) . + +We hope this troubleshooting guide helps you resolve any issues and enhances your experience with the VISION software. + +# Appendix + +- **FAQs**: Answers to frequently asked questions about the software. ## License @@ -998,3 +1228,4 @@ the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . ``` + diff --git a/Python/VISION_V1.0.3.py b/Python/VISION_V1.0.3.py new file mode 100644 index 0000000..81a946e --- /dev/null +++ b/Python/VISION_V1.0.3.py @@ -0,0 +1,5830 @@ +""" +Created on Wed Oct 19 12:39:12 2022 + +@author: P41650 +""" + +#performance +import copy + +# import pyi_splash + +import warnings +warnings.filterwarnings("ignore", category=DeprecationWarning) +warnings.filterwarnings("ignore", category=FutureWarning) + + +#ForGUI +from PyQt5 import uic, QtCore, QtWidgets,QtGui +from PyQt5.QtCore import QThread, pyqtSignal +from PyQt5.QtGui import QGuiApplication +from PyQt5.QtWidgets import QWidget, QVBoxLayout,QTableWidgetItem, QComboBox +import sys + +#for equation checks +from sympy import sympify +from sympy.core.sympify import SympifyError + + +#ForPLots +from matplotlib.ticker import FixedLocator +from matplotlib.widgets import RectangleSelector + + +#from matplotlib.backends.backend_agg import FigureCanvasAgg +from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg, NavigationToolbar2QT +from matplotlib.figure import Figure + +import numpy as np +import seaborn as sns +import seaborn_image as isns +import pandas as pd +import json + +#For Splashscreen +from PyQt5.QtGui import QPixmap +from PyQt5.QtWidgets import QSplashScreen + +import time + +#ForOpenDirectory +from PyQt5.QtWidgets import QFileDialog,QMessageBox + +from os import listdir,getcwd +from os.path import isfile, join, basename,dirname +from PyQt5.QtCore import Qt + + + +#GP Analyser +import Analyzer_V1_0_3 as analyzer + + +#OpenFormat + +import xmltodict + +from nd2reader import ND2Reader +import tifffile as lsm +import czifile +from readlif.reader import LifFile +import obf_support + + +#for Erroe handling +import traceback + +QtCore.QCoreApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) + +##segment color map: +from matplotlib.colors import ListedColormap +num_unique_colors = 15 # or any number you need +# Choose a palette that supports more unique colors +palette_name = "tab20" # tab20 has 20 unique colors + +# Generate the palette with the required number of unique colors +color_palette = sns.color_palette(palette_name, num_unique_colors) + +# Assuming your segment numbers are integers starting from 1 +segment_numbers = list(range(1, num_unique_colors + 1)) + +# Create a color map: a dictionary mapping segment numbers to colors +color_map = {segment_number: color for segment_number, color in zip(segment_numbers, color_palette)} + + + + +#varlist = [ 'NaN', 'NaN', 'NaN', 'NaN'] +def apply_dark_palette(app): + app.setStyle("Fusion") # Optional: Set Fusion style for a more modern look + dark_palette = QtGui.QPalette() + + # Adjust palette colors for dark mode + dark_palette.setColor(QtGui.QPalette.Window, QtGui.QColor(53, 53, 53)) + dark_palette.setColor(QtGui.QPalette.WindowText, QtGui.QColor(255, 255, 255)) + dark_palette.setColor(QtGui.QPalette.Base, QtGui.QColor(25, 25, 25)) + dark_palette.setColor(QtGui.QPalette.AlternateBase, QtGui.QColor(53, 53, 53)) + dark_palette.setColor(QtGui.QPalette.ToolTipBase, QtGui.QColor(255, 255, 255)) + dark_palette.setColor(QtGui.QPalette.ToolTipText, QtGui.QColor(255, 255, 255)) + dark_palette.setColor(QtGui.QPalette.Text, QtGui.QColor(255, 255, 255)) + dark_palette.setColor(QtGui.QPalette.Button, QtGui.QColor(53, 53, 53)) + dark_palette.setColor(QtGui.QPalette.ButtonText, QtGui.QColor(255, 255, 255)) + dark_palette.setColor(QtGui.QPalette.BrightText, QtGui.QColor(255, 0, 0)) + dark_palette.setColor(QtGui.QPalette.Link, QtGui.QColor(42, 130, 218)) + dark_palette.setColor(QtGui.QPalette.Highlight, QtGui.QColor(42, 130, 218)) + dark_palette.setColor(QtGui.QPalette.HighlightedText, QtGui.QColor(0, 0, 0)) + + app.setPalette(dark_palette) + app.setStyleSheet("QToolTip { color: #ffffff; background-color: #2a82da; border: 1px solid white; }") + + +from custom_combobox import CheckableComboBox + +class NumpyEncoder(json.JSONEncoder): + def default(self, obj): + if isinstance(obj, np.ndarray): + return obj.tolist() + elif isinstance(obj, np.int32): + return int(obj) # Convert int32 to regular int + elif isinstance(obj, np.int64): + return int(obj) # Convert int64 to regular int + return json.JSONEncoder.default(self, obj) + +class WorkerThread(QThread): + finished = pyqtSignal() + terminate_thread = pyqtSignal() + + def __init__(self, window): + super().__init__() + self.window = window + + def run(self): + try: + print("Thread run start") + self.window.Run() + print("Thread run end") + self.finished.emit() + print("Thread finished emitted") + except Exception as e: + error_trace = traceback.format_exc() + specific_error_messages = [ "Found array with 0 sample(s) (shape=(0, 2)) while a minimum of 1 is required by DBSCAN.", + "No objects to concatenate"] + if str(e) in specific_error_messages: + custom_error_message = "Error: It was not possible to detect single objects. Please check your masking and thresholding settings." + print(custom_error_message) + self.window.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.window.plainTextEdit_1.appendPlainText(custom_error_message) + + else: + print(f"Error: An exception occurred in run: In Line {error_trace}: {e}") + self.window.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.window.plainTextEdit_1.appendPlainText(f"Error: An exception occurred in TestThreshold: \nIn Run Traceback:\n{error_trace}") + + + if getattr(sys, 'frozen', False): + current_directory = dirname(sys.executable) + else: + current_directory = getcwd() + + error_log_path = join(current_directory, 'error_log.txt') + with open(error_log_path, 'w') as f: + f.write(f"Error message: {e}\n") + f.write(f"In Run Traceback:\n{error_trace}") + self.terminate_thread.emit() + + def testthresholding(self): + try: + self.window.testThresholding() + self.finished.emit() + except Exception as e: + error_trace = traceback.format_exc() + specific_error_messages = [ "Found array with 0 sample(s) (shape=(0, 2)) while a minimum of 1 is required by DBSCAN.", + "No objects to concatenate"] + if str(e) in specific_error_messages: + custom_error_message = "Error: It was not possible to detect single objects. Please check your masking and thresholding settings." + print(custom_error_message) + self.window.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.window.plainTextEdit_1.appendPlainText(custom_error_message) + + else: + print(f"Error: An exception occurred in run: In Line {error_trace}: {e}") + self.window.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.window.plainTextEdit_1.appendPlainText(f"Error: An exception occurred in TestThreshold: \nIn Run Traceback:\n{error_trace}") + + + if getattr(sys, 'frozen', False): + current_directory = dirname(sys.executable) + else: + current_directory = getcwd() + + error_log_path = join(current_directory, 'error_log.txt') + with open(error_log_path, 'w') as f: + f.write(f"Error message: {e}\n") + f.write(f"In Run Traceback:\n{error_trace}") + self.terminate_thread.emit() + + def SavingThread(self): + try: + self.window.Data_Saving() + self.finished.emit() + except Exception as e: + print(f"Error: An exception occurred in DataSaving: {e}") + self.window.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.window.plainTextEdit_1.appendPlainText(f"Error: An exception occurred in DataSaving: {e}") + self.terminate_thread.emit() + + +def RunAnalyser(mode, filename, Lambdachannel, + image, dims, varlist, + ObjectDetection, profiler,profilershape, + autoff, PDiamCutoff, proDim1, + proDim2, text, histpars, + histpars_cyto,text_cyto, profile_cyto, + varlist_cyto, n_debranch, tol0, + tol1,savecroppedmembrane, savecroppedcyto, + savelinearized, savepath, objlinear, + recentering, dim_line, + MaskParams_mem, MaskParams_cyto, + Colocalization, savephasors, + tocut =0,radius = 'auto'): + if tocut == 0: + radius = 'auto' + else: + radius = tocut + if varlist[0] == 'NaN': + return 0 + else: + return analyzer.GP_Analyser(mode, filename, Lambdachannel, + image, dims, varlist, + ObjectDetection, profiler,profilershape, + autoff, PDiamCutoff, proDim1, + proDim2, text, histpars, + histpars_cyto,text_cyto, profile_cyto, + varlist_cyto, n_debranch, tol0, + tol1,savecroppedmembrane, savecroppedcyto, + savelinearized, savepath, objlinear, + recentering, dim_line, + MaskParams_mem, MaskParams_cyto, # NEW + Colocalization, savephasors, + radius) + + + +def load_and_process_czi(fullpath): +#for spectral ana multi chanell + metadata = { + "Pixelsize": None, + "Nchannels": None, + "ChannelColors": [], + "Dimensions": None, + "BitDepth": None, + "PixelsizeUnit": None + } + DimensionTime = DimensionZ = DimensionX = DimensionY = DimensionChannels = 1 + with czifile.CziFile(fullpath) as czi: + czi_metadata = xmltodict.parse(czi.metadata()) + + metadata['Pixelsize']=float(czi_metadata["ImageDocument"]["Metadata"]["Scaling"]["Items"]["Distance"][0].get("Value", 1)) + DimensionChannels=int(czi_metadata["ImageDocument"]["Metadata"]["Information"]["Image"].get("SizeC", 1)) + metadata['Nchannels']=DimensionChannels + DimensionTime = int(czi_metadata["ImageDocument"]["Metadata"]["Information"]["Image"].get("SizeT", 1)) + DimensionZ = int(czi_metadata["ImageDocument"]["Metadata"]["Information"]["Image"].get("SizeZ", 1)) + DimensionX = int(czi_metadata["ImageDocument"]["Metadata"]["Information"]["Image"].get("SizeX", 1)) + DimensionY = int(czi_metadata["ImageDocument"]["Metadata"]["Information"]["Image"].get("SizeY", 1)) + metadata['BitDepth']=int(czi_metadata["ImageDocument"]["Metadata"]["Information"]["Image"].get("ComponentBitCount", 1)) + metadata['Dimensions'] = [DimensionTime, DimensionZ, DimensionX, DimensionY, DimensionChannels] + i=1 + for subdict in czi_metadata["ImageDocument"]["Metadata"]["Information"]["Image"]["Dimensions"]["Channels"]["Channel"]: + if subdict ["@Name"].isdigit(): + metadata['ChannelColors'].append((subdict["@Name"])) + elif "EmissionWavelength" in subdict: + metadata['ChannelColors'].append(str(int(float(subdict["EmissionWavelength"])))) + else: + metadata['ChannelColors'].append(subdict ["@Name"]) #if needed we can add the names here but than we have to change in lucas codes somewere something or i have to translate the names into integers again so it works seemlessly for him + #metadata['ChannelColors'].append(int(i)) + i+=1 + + metadata['ChannelColors']=np.array(metadata['ChannelColors']).tolist() + + image=czifile.imread(fullpath) + if len(image.shape) < 8: + data = np.squeeze(np.transpose(czifile.imread(fullpath)[0, 0, :, :, :, :, 0], (1, 2, 3, 0))) # wenn hier eins mit T oder Z kommt dann gibts probleme denn ich weis nicht was was ist + else: + data = np.squeeze(np.transpose(czifile.imread(fullpath)[0, 0, :, :, :, :, :, 0], (1, 2, 3, 4, 0))) + + return data, metadata + + +def load_and_process_lsm(fullpath): +#for spectral ana multi chanell + metadata = { + "Pixelsize": None, + "Nchannels": None, + "ChannelColors": None, + "Dimensions": None, + "BitDepth": None, + "PixelsizeUnit": None + } + DimensionTime = DimensionZ = DimensionX = DimensionY = DimensionChannels = 1 + + with lsm.TiffFile(fullpath) as tif: + if hasattr(tif, 'lsm_metadata'): + lsm_metadata = tif.lsm_metadata + + metadata['Pixelsize'] = lsm_metadata.get("VoxelSizeX", None) + DimensionChannels = lsm_metadata.get("DimensionChannels", 1) + metadata['Nchannels'] = DimensionChannels + + if "ChannelColors" in lsm_metadata and all(item.isdigit() for item in lsm_metadata["ChannelColors"]["ColorNames"]): + metadata['ChannelColors'] = [str(int(item)) for item in lsm_metadata["ChannelColors"]["ColorNames"]] + else: + metadata['ChannelColors'] = [str(int((value))) for value in (np.mean(lsm_metadata["ChannelWavelength"], axis=1) * 1e9)] + + DimensionTime = lsm_metadata.get("DimensionTime", 1) + DimensionZ = lsm_metadata.get("DimensionZ", 1) + DimensionX = lsm_metadata.get("DimensionX", 1) + DimensionY = lsm_metadata.get("DimensionY", 1) + + metadata['Dimensions'] = [DimensionTime, DimensionZ, DimensionX, DimensionY, DimensionChannels] + + data = lsm.imread(fullpath) + + if data.dtype == np.uint16: + metadata['BitDepth']=16 + elif data.dtype == np.uint8: + metadata['BitDepth']=8 + + if metadata['Nchannels'] >1: + if data.ndim == 3: + data = np.transpose(data, (1, 2, 0)) + elif data.ndim == 4: + data = np.transpose(data, (0, 2, 3, 1)) + elif data.ndim == 5: + data = np.transpose(data, (0, 1, 3, 4, 2)) + else: + data = np.expand_dims(data, axis=-1) + + return data, metadata + +def load_and_process_lif(fullpath): # not completley implemented and absolutely not tested + metadata={} + data={} + lif = LifFile(fullpath) + xml=xmltodict.parse(lif.xml_header) + images = lif.image_list + i=0 + for image in images: + + metadata[i] = { + "Pixelsize": [], + "Nchannels": [], + "ChannelColors": [], + "Dimensions": [], + "BitDepth": [], + "PixelsizeUnit": None + } + channel_data=[] + + nthimage=lif.get_image(i) + metadata[i]['Pixelsize'] = image["scale"][0] + metadata[i]['Nchannels'] = image["channels"] + DimensionChannels=nthimage.channels + if metadata[i]['Nchannels'] > 1: + for n in range(metadata[i]['Nchannels']): + metadata[i]['ChannelColors'].append(xml["LMSDataContainerHeader"]["Element"]["Children"]["Element"][i]["Data"]["Image"]["ImageDescription"]["Channels"]["ChannelDescription"][n]["@LUTName"]) + frame_data = np.array(nthimage.get_frame(c=n)) + channel_data.append(frame_data) + data[i]=np.stack(channel_data, axis=-1) + + + else: + metadata[i]['Nchannels'] = image["dims_n"][5] + DimensionChannels=image["dims_n"][5] + for n in range(DimensionChannels): + metadata[i]['ChannelColors'].append(n+1) + frame_data = np.array(nthimage.get_plane((1, 2),n)) + channel_data.append(frame_data) + data[i]=np.stack(channel_data, axis=-1) + + metadata[i]['BitDepth'] = image["bit_depth"][0] + + DimensionTime = nthimage.dims.t + DimensionZ = nthimage.dims.z + DimensionX = nthimage.dims.x + DimensionY = nthimage.dims.y + + metadata[i]['ChannelColors']=np.array(metadata[i]['ChannelColors']).tolist() + metadata[i]['Dimensions']=[DimensionTime, DimensionZ, DimensionX, DimensionY, DimensionChannels] + + i+=1 + return data,metadata + +def load_and_process_obf(fullpath): # not completley implemented and absolutely not tested + # Load an image file + obf = obf_support.File(fullpath) + xml=xmltodict.parse(obf.meta["ome_xml"]) + + + metadata={} + data={} + + for i, stack in enumerate(obf.stacks[:]): + metadata[i] = { + "name":[], + "Pixelsize": [], + "Nchannels": [], + "ChannelColors": [], + "Dimensions": [], + "BitDepth": [], + "PixelsizeUnit": None + } + metadata[i]['name'] = xml["OME"]["Image"][i]["@Name"] + metadata[i]['Pixelsize'] = float(xml["OME"]["Image"][i]["Pixels"]["@PhysicalSizeX"]) + metadata[i]['Nchannels'] = int(xml["OME"]["Image"][i]["Pixels"]["@SizeC"]) + + metadata[i]['ChannelColors'] = ((xml["OME"]["Image"][i]["Pixels"]["Channel"]["@EmissionWavelength"])).tolist() + + DimensionChannels=int(xml["OME"]["Image"][i]["Pixels"]["@SizeC"]) + DimensionTime = int(xml["OME"]["Image"][i]["Pixels"]["@SizeT"]) + DimensionZ = int(xml["OME"]["Image"][i]["Pixels"]["@SizeZ"]) + DimensionX = int(xml["OME"]["Image"][i]["Pixels"]["@SizeX"]) + DimensionY = int(xml["OME"]["Image"][i]["Pixels"]["@SizeY"]) + + metadata[i]['Dimensions']=[DimensionTime, DimensionZ, DimensionX, DimensionY, DimensionChannels] + + metadata[i]['BitDepth'] = xml["OME"]["Image"][i]["Pixels"]["@Type"] + digits = [char for char in metadata[i]['BitDepth'] if char.isdigit()] + metadata[i]['BitDepth'] = int(''.join(digits)) + + stack_data=[] + stack_data.append(stack.data) + data[i]=np.squeeze(np.stack(stack_data, axis=-1)) + + return data,metadata + +def load_and_process_ometiff(fullpath): + metadata = { + "Pixelsize": None, + "Nchannels": None, + "ChannelColors": [], + "Dimensions": None, + "BitDepth": None, + "PixelsizeUnit": None + } + DimensionTime = DimensionZ = DimensionX = DimensionY = DimensionChannels = 1 + with lsm.TiffFile(fullpath) as tif: + if hasattr(tif, 'ome_metadata') and tif.ome_metadata: + ometiff_metadata = xmltodict.parse(tif.ome_metadata) + metadata['Pixelsize'] = float(ometiff_metadata["OME"]["Image"]["Pixels"]["@PhysicalSizeX"]) + metadata['Nchannels'] = int(ometiff_metadata["OME"]["Image"]["Pixels"]["@SizeC"]) + i=1 + if metadata['Nchannels']>1: + for channels in ometiff_metadata["OME"]["Image"]["Pixels"]["Channel"]: + if "@Name" in channels: + if channels["@Name"]: + metadata['ChannelColors'].append((channels["@Name"])) + i+=1 + else: + metadata['ChannelColors'].append(str(i)) + i+=1 + else: + metadata['ChannelColors'].append(str(i)) + + metadata['ChannelColors']=np.array(metadata['ChannelColors']).tolist() + + DimensionChannels=int(ometiff_metadata["OME"]["Image"]["Pixels"]["@SizeC"]) + DimensionTime = int(ometiff_metadata["OME"]["Image"]["Pixels"]["@SizeT"]) + DimensionZ = int(ometiff_metadata["OME"]["Image"]["Pixels"]["@SizeZ"]) + DimensionX = int(ometiff_metadata["OME"]["Image"]["Pixels"]["@SizeX"]) + DimensionY = int(ometiff_metadata["OME"]["Image"]["Pixels"]["@SizeY"]) + + metadata['Dimensions']=[DimensionTime, DimensionZ, DimensionX, DimensionY, DimensionChannels] + + metadata['BitDepth'] = ometiff_metadata["OME"]["Image"]["Pixels"]["@Type"] + digits = [char for char in metadata['BitDepth'] if char.isdigit()] + metadata['BitDepth'] = int(''.join(digits)) + metadata['PixelsizeUnit'] = ometiff_metadata["OME"]["Image"]["Pixels"]["@PhysicalSizeXUnit"] + + data = tif.asarray() + + if metadata['PixelsizeUnit'] == 'µm': + metadata['Pixelsize'] = metadata['Pixelsize'] * 1E-6 + elif metadata['PixelsizeUnit'] == 'nm': + metadata['Pixelsize'] = metadata['Pixelsize'] * 1E-9 + elif metadata['PixelsizeUnit'] == 'mm': + metadata['Pixelsize'] = metadata['Pixelsize'] * 1E-3 + + if metadata['Nchannels'] >1: + if data.ndim == 3: + data = np.transpose(data, (1, 2, 0)) + elif data.ndim == 4: + data = np.transpose(data, (0, 2, 3, 1)) + elif data.ndim == 5: + data = np.transpose(data, (0, 1, 3, 4, 2)) + else: + data = np.expand_dims(data, axis=-1) + + return data,metadata + +def load_and_process_nd2(fullpath): + metadata = { + "Pixelsize": None, + "Nchannels": None, + "ChannelColors": None, + "Dimensions": None, + "BitDepth": None, + "PixelsizeUnit": None + } + + + with ND2Reader(fullpath) as nd2: + # Extract metadata + metadata['Pixelsize'] = nd2.metadata.get('pixel_microns', None)*1e-6 + metadata['PixelsizeUnit'] = 'um' # Assuming unit is micrometers + metadata['Nchannels'] = nd2.sizes.get('c', 1) + + DimensionTime = nd2.sizes.get('t', 1) + DimensionZ = nd2.sizes.get('z', 1) + DimensionX = nd2.sizes['x'] + DimensionY = nd2.sizes['y'] + + metadata['Dimensions'] = [DimensionTime, DimensionZ, DimensionX, DimensionY, metadata['Nchannels']] + + # Extract ChannelColors + metadata['ChannelColors'] = nd2.metadata.get('channels', None) + if metadata['ChannelColors'] is not None: + # Ensure ChannelColors contains numerical values + if all(isinstance(item, (int, float)) for item in metadata['ChannelColors']): + metadata['ChannelColors'] = [str(int(item)) for item in metadata['ChannelColors']] + else: + metadata['ChannelColors'] = [str(item) for item in metadata['ChannelColors']] + + # Read the image data + data = np.zeros((DimensionTime, DimensionZ, DimensionY, DimensionX, metadata['Nchannels']), dtype=nd2[0].dtype) + + for t in range(DimensionTime): + for z in range(DimensionZ): + for c in range(metadata['Nchannels']): + data[t, z, :, :, c] = nd2.get_frame_2D(c=c, t=t, z=z) + + data=np.squeeze(data) + + if data.dtype == np.uint16: + metadata['BitDepth'] = 16 + elif data.dtype == np.uint8: + metadata['BitDepth'] = 8 + + + return data,metadata + +def openfile(fullfilepath): + + if fullfilepath.endswith(('.lsm')): + data,metadata=load_and_process_lsm(fullfilepath) + return data, metadata + elif fullfilepath.endswith(('.czi')): + data,metadata=load_and_process_czi(fullfilepath) + return data, metadata + elif fullfilepath.endswith(('.lif')): + data,metadata=load_and_process_lif(fullfilepath) + return data, metadata + # elif fullfilepath.endswith(('.obf')): + # data,metadata=load_and_process_obf(fullfilepath) + # return data, metadata + elif fullfilepath.endswith(('.ome.tif')): + data,metadata=load_and_process_ometiff(fullfilepath) + return data, metadata + elif fullfilepath.endswith(('.nd2')): + data,metadata=load_and_process_nd2(fullfilepath) + return data, metadata + else: + print("Only .lsm, .czi, lif, nd2 & .ome.tif !!! Your Variation of this filefomate is currently not supported. Pls send us a test image and we will gladly incorporte it (.lif and .obf are prepeared but I had no test images so pls send me some and I can implement it)") + +class Splashscreen(QSplashScreen): + def __init__(self): + super(QSplashScreen,self).__init__() +# self.UI_FILE_SPLASH = str(Path(__file__).parent / "splash.ui") +# uic.loadUi(self.UI_FILE_SPLASH, self) +# ui_file = join(dirname(sys.argv[0]), "ui/splash.ui") # for python + ui_file = join(getattr(sys, '_MEIPASS', dirname(sys.argv[0])), "ui/splash.ui") # Standalone + uic.loadUi(ui_file,self) + self.setWindowFlag(Qt.FramelessWindowHint) + pixmap = QPixmap("ui/splashscreen.png") + self.setPixmap(pixmap) + + def progress(self,n): + for i in range(n): + time.sleep(0.1) + +class MatplotlibWidget(QWidget): + def __init__(self, parent=None): + super(MatplotlibWidget,self).__init__(parent) + self.figure = Figure(facecolor='#434343') # Set figure background color + self.canvas = FigureCanvasQTAgg(self.figure) + self.axis = self.figure.add_subplot(111) + self.axis.set_facecolor('#2D2D2D') # Set axes background color + self.figure.tight_layout() + self.toolbar = NavigationToolbar2QT(self.canvas, self) + + self.layoutvertical = QVBoxLayout(self) + self.layoutvertical.addWidget(self.toolbar) + self.layoutvertical.addWidget(self.canvas) + self.layoutvertical.setContentsMargins(0, 0, 0, 0) + self.layoutvertical.setSpacing(0) + +class MatplotlibWidgetPolar(QWidget): + def __init__(self, parent=None): + super(MatplotlibWidgetPolar,self).__init__(parent) + self.figure = Figure(facecolor='#434343') # Set figure background color + self.canvas = FigureCanvasQTAgg(self.figure) + self.axis = self.figure.add_subplot(111,projection='polar') + self.axis.set_facecolor('#2D2D2D') # Set axes background color + self.toolbar = NavigationToolbar2QT(self.canvas, self) + self.layoutvertical = QVBoxLayout(self) + self.layoutvertical.addWidget(self.toolbar) + self.layoutvertical.addWidget(self.canvas) + self.layoutvertical.setContentsMargins(0, 0, 0, 0) + self.layoutvertical.setSpacing(0) + +def px_to_dp(pixels): + return int(pixels * QGuiApplication.primaryScreen().physicalDotsPerInch() / 96) + +class MainWindow(QtWidgets.QMainWindow): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + ui_file = join(getattr(sys, '_MEIPASS', dirname(sys.argv[0])), "ui/gui_V1.0.3.ui") # Standalone + self.ui = uic.loadUi(ui_file, self) + + # Convert sizes to dp - example for a label + if hasattr(self, 'label'): # Check if the label exists + label_width_dp = px_to_dp(self.label.width()) + self.label.setFixedWidth(label_width_dp) + + # Wrap existing central widget with QScrollArea + self.wrapCentralWidgetWithScrollArea() + + + # Set window size in dp + self.resize(px_to_dp(self.width()), px_to_dp(self.height())) + + #for matplotlib widget1 Rawfile + self.matplotlibwidget = MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget) + self.layoutvertical.addWidget(self.matplotlibwidget) + #self.pushButton.clicked.connect(self.plot_widget) + + #for matplotlib widget2 Mask + self.matplotlibwidget_2 = MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_2) + self.layoutvertical.addWidget(self.matplotlibwidget_2) + + #for matplotlib widget3 GP image + self.matplotlibwidget_3 = MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_3) + self.layoutvertical.addWidget(self.matplotlibwidget_3) + + #for matplotlib widget4 GP Histogramm + self.matplotlibwidget_4= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_4) + self.layoutvertical.addWidget(self.matplotlibwidget_4) + + + #for matplotlib widget5 Object overview + self.matplotlibwidget_5= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_5) + self.layoutvertical.addWidget(self.matplotlibwidget_5) + + #for matplotlib widget6 Phasor plot GP + self.matplotlibwidget_6= MatplotlibWidgetPolar() + self.layoutvertical = QVBoxLayout(self.MplWidget_6) + self.layoutvertical.addWidget(self.matplotlibwidget_6) + + #for matplotlib widget7 hist intensities + self.matplotlibwidget_7= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_7) + self.layoutvertical.addWidget(self.matplotlibwidget_7) + + #for matplotlib widget8 zoom in of Object + self.matplotlibwidget_8= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_8) + self.layoutvertical.addWidget(self.matplotlibwidget_8) + + #for matplotlib widget9 hist GP of Object + self.matplotlibwidget_9= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_9) + self.layoutvertical.addWidget(self.matplotlibwidget_9) + + #for matplotlib widget10 hist intensities of object + self.matplotlibwidget_10= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_10) + self.layoutvertical.addWidget(self.matplotlibwidget_10) + + #for matplotlib widget11 Phasor plot GP of object + self.matplotlibwidget_11= MatplotlibWidgetPolar() + self.layoutvertical = QVBoxLayout(self.MplWidget_11) + self.layoutvertical.addWidget(self.matplotlibwidget_11) + + #for matplotlib widget12 Phasor plot GP of object + self.matplotlibwidget_12= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_12) + self.layoutvertical.addWidget(self.matplotlibwidget_12) + + + #for matplotlib widget13 cytoprifer object plot GP of object + self.matplotlibwidget_13= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_13) + self.layoutvertical.addWidget(self.matplotlibwidget_13) + + #for matplotlib widget14 cytoprifer object plot GP of object + self.matplotlibwidget_14= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_14) + self.layoutvertical.addWidget(self.matplotlibwidget_14) + + #for matplotlib widget17 hist GP of Object + self.matplotlibwidget_17= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_17) + self.layoutvertical.addWidget(self.matplotlibwidget_17) + + #for matplotlib widget15 hist intensities of object + self.matplotlibwidget_15= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_15) + self.layoutvertical.addWidget(self.matplotlibwidget_15) + + #for matplotlib widget16 Phasor plot GP of object + self.matplotlibwidget_16= MatplotlibWidgetPolar() + self.layoutvertical = QVBoxLayout(self.MplWidget_16) + self.layoutvertical.addWidget(self.matplotlibwidget_16) + + #for matplotlib widget18 Cytosol Mask + self.matplotlibwidget_18= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_18) + self.layoutvertical.addWidget(self.matplotlibwidget_18) + + #for matplotlib widget19 Cytosol Whole Image + self.matplotlibwidget_19= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_19) + self.layoutvertical.addWidget(self.matplotlibwidget_19) + + #for matplotlib MplWidget_20 Cytosol histogramme Image + self.matplotlibwidget_20= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_20) + self.layoutvertical.addWidget(self.matplotlibwidget_20) + + #for matplotlib MplWidget_21 Cytosol intensities Image + self.matplotlibwidget_21= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_21) + self.layoutvertical.addWidget(self.matplotlibwidget_21) + + #for matplotlib MplWidget_22 Cytosol polar Image + self.matplotlibwidget_22= MatplotlibWidgetPolar() + self.layoutvertical = QVBoxLayout(self.MplWidget_22) + self.layoutvertical.addWidget(self.matplotlibwidget_22) + + #for matplotlib MplWidget_23 Cytosol object overview image + self.matplotlibwidget_23= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_23) + self.layoutvertical.addWidget(self.matplotlibwidget_23) + + #for matplotlib MplWidget_24 Membrane Segment + self.matplotlibwidget_24= MatplotlibWidget() + self.layoutvertical = QVBoxLayout(self.MplWidget_24) + self.layoutvertical.addWidget(self.matplotlibwidget_24) + + #Settings + self.B_LoadFiles.clicked.connect(self.LoadFiles) #(self.tranPath) + self.B_LoadFolder.clicked.connect(self.LoadFolder) #(self.tranPath) + + self.B_ClearTable.clicked.connect(self.ClearTable) #(self.tranPath) + self.B_DeletEntry.clicked.connect(self.DeletEntry) #(self.tranPath) + self.B_ClearSelection.clicked.connect(self.ClearSelection) + + self.pushButton_3.clicked.connect(self.start_worker_thread_2) + + self.comboBox_18 = self.findChild(CheckableComboBox, "comboBox_18") + self.comboBox_23 = self.findChild(CheckableComboBox, "comboBox_23") + + self.checkBox_2.stateChanged.connect(self.objectDetectionEnable) + self.checkBox_4.stateChanged.connect(self.removeObjectsEnable) + self.checkBox_5.stateChanged.connect(self.fillHolesEnable) + self.checkBox_6.stateChanged.connect(self.dilateEnable) + self.checkBox_3.stateChanged.connect(self.compressEnable) + self.checkBox_8.stateChanged.connect(self.profilerEnable) + self.checkBox_9.stateChanged.connect(self.autoCutOffEnable) + self.checkBox_14.stateChanged.connect(self.toggle_Colocalization) + self.checkBox_31.stateChanged.connect(self.toggle_Detailed_cyto) + self.checkBox_24.stateChanged.connect(self.toggle_Detailed_membrane) + + self.comboBox_3.currentIndexChanged.connect(self.threholdEnable) + self.comboBox_21.currentIndexChanged.connect(self.threholdEnable_cyto) + self.checkBox.stateChanged.connect(self.cytoprofilerEnable) + self.checkBox_34.stateChanged.connect(self.removeObjectsEnable_cyto) + self.checkBox_35.stateChanged.connect(self.fillHolesEnable_cyto) + self.checkBox_37.stateChanged.connect(self.dilateEnable_cyto) + self.checkBox_32.stateChanged.connect(self.compressEnable_cyto) + + self.checkBox_27.stateChanged.connect(self.threholdChannelEnable) + self.checkBox_36.stateChanged.connect(self.threholdChannelEnable_cyto) + self.comboBox_9.currentIndexChanged.connect(self.filterEnable) + self.comboBox_10.currentIndexChanged.connect(self.filterEnable_cyto) + self.checkBox_16.stateChanged.connect(self.toggle_background_std_cyto) + self.checkBox_15.stateChanged.connect(self.toggle_background_std_membrane) + self.tableWidget.setColumnWidth(0,250) + self.tableWidget.setColumnWidth(1,1100-250) + + self.checkBox_18.stateChanged.connect(self.toggleSaveJSONResults) + self.checkBox_19.stateChanged.connect(self.JSONResultsWarning) + + self.tableWidget.itemSelectionChanged.connect(self.updatePlots) + self.tableWidget.itemSelectionChanged.connect(self.PlotRaw_initial) + + + self.verticalScrollBar.valueChanged.connect(self.updatePlots) + self.verticalScrollBar_2.valueChanged.connect(self.updatePlots) + self.verticalScrollBar_3.valueChanged.connect(self.updatePlots) + + self.horizontalScrollBar.valueChanged.connect(self.updatePlots) + self.horizontalScrollBar_2.valueChanged.connect(self.updatePlots) + self.horizontalScrollBar_3.valueChanged.connect(self.updatePlots) + self.horizontalScrollBar_4.valueChanged.connect(self.updatePlots) + self.horizontalScrollBar_5.valueChanged.connect(self.updatePlots) + + self.tableWidget_2.itemClicked.connect(self.updatePlots_Objects) + self.tableWidget.itemSelectionChanged.connect(self.updatePlots_Objects) + + self.verticalScrollBar.valueChanged.connect(self.updatePlots_Objects) + self.verticalScrollBar_2.valueChanged.connect(self.updatePlots_Objects) + self.verticalScrollBar_3.valueChanged.connect(self.updatePlots_Objects) + + self.horizontalScrollBar.valueChanged.connect(self.updatePlots_Objects) + self.horizontalScrollBar_2.valueChanged.connect(self.updatePlots_Objects) + self.horizontalScrollBar_3.valueChanged.connect(self.updatePlots_Objects) + self.horizontalScrollBar_4.valueChanged.connect(self.updatePlots_Objects) + self.horizontalScrollBar_5.valueChanged.connect(self.updatePlots_Objects) + + self.horizontalScrollBar_4.valueChanged.connect(self.updateLambda_1) + self.horizontalScrollBar_5.valueChanged.connect(self.updateLambda_2) + + #DetailedMasking_Setting + self.tableWidget.itemSelectionChanged.connect(self.Update_Detailed_Membrane_Masking_Setting) + self.tableWidget.itemSelectionChanged.connect(self.Update_Detailed_Cytosol_Masking_Setting) + self.tableWidget.itemSelectionChanged.connect(self.Update_Membrane_Cytosol_Chnnel_Settings) + self.comboBox_17.activated.connect(self.Update_formZ_Detailed_Membrane_Masking_Setting) + self.comboBox_24.activated.connect(self.Update_formZ_Detailed_Cytosol_Masking_Setting) + self.tableWidget_3.itemChanged.connect(self.Detailed_Membrane_Masking_onItemChanged) + self.tableWidget_6.itemChanged.connect(self.Detailed_Cytosol_Masking_onItemChanged) + self.pushButton_6.clicked.connect(self.helper_for_button_updater) + self.pushButton_7.clicked.connect(self.helper2_for_button_updater) + + self.pushButton_2.clicked.connect(self.activate_rectangle_selector) + + self.comboBox.currentIndexChanged.connect(self.Save_Membranechannel_A) + self.comboBox_2.currentIndexChanged.connect(self.Save_Membranechannel_B) + self.comboBox_6.currentIndexChanged.connect(self.Save_Membranechannel_C) + self.comboBox_7.currentIndexChanged.connect(self.Save_Membranechannel_D) + self.comboBox_8.currentIndexChanged.connect(self.Save_ColocolisationChannel) + + self.comboBox_13.currentIndexChanged.connect(self.Save_Cytosolchannel_A) + self.comboBox_14.currentIndexChanged.connect(self.Save_Cytosolchannel_B) + self.comboBox_15.currentIndexChanged.connect(self.Save_Cytosolchannel_C) + self.comboBox_16.currentIndexChanged.connect(self.Save_Cytosolchannel_D) + + self.pushButton_4.clicked.connect(self.Globalize_Channel_Settings) + self.pushButton_5.clicked.connect(self.Globalize_Channel_Settings) + + self.progressBar_1.setVisible(False) + self.label_10.setVisible(False) + + self.plainTextEdit_1.setReadOnly(True) + + self.tabWidget_2.currentChanged.connect(self.updatePlots) + + #Testbutton + self.pushButton.clicked.connect(self.test) + self.pushButton.setVisible(False) + + self.B_selectsavingpath.clicked.connect(self.Select_Saving_Path) + + self.BLUB=True + + self.B_Run.clicked.connect(self.start_worker_thread) + + self.tabWidget.setCurrentIndex(0) + + self.Results={} + self.Membrane_Channels_selected={} + self.Colocolisation_Channel_selected={} + self.Cytosol_Channels_selected={} + self.Membrane_Maskdata={} + self.Cyto_Maskdata={} + self.previously_selected_file=[None] + self.dims={} + self.RawImages={} + self.Metadata={} + self.GPImage={} + self.FullImage_Parameters={} + self.Cyto_GPImage={} + self.GPImage_per_object={} + self.GPPhasor={} + self.Cyto_GPPhasor={} + self.Masks={} + self.Cyto_Masks={} + self.Intensities={} + self.Cyto_Intensities={} + self.nobjects={} + self.Object_Parameters={} + self.Object_Morphology={} + self.Object_Coordinates={} + self.Mask_Object_Coordinates={} + self.Intensities_per_object={} + self.Channellamda={} + self.phasex_object={} + self.phasey_object={} + self.GPPhasor_polar_all={} + self.Cyto_GPPhasor_polar_all={} + self.GPPhasor_polar_obj={} + self.key={} + self.ConnectSliders={} + self.Profile={} + self.MembraneSegments={} + self.Cytoprof={} + self.Cyto_Image={} + self.FullImage_Parameters_cyto={} + self.Object_Parameters_cyto={} + self.Cyto_Intensities_per_object={} + self.Cyto_GPPhasor_polar_obj={} + self.savingpath=str([]) + self.DifferentSavingPath=str([]) + + +#### for testing purposes + global Results_g + global Membrane_Maskdata_g + global Membrane_Channels_selected_g + global Colocolisation_Channel_selected_g + global Cytosol_Channels_selected_g + global Cyto_Maskdata_g + global previously_selected_file_g + global dims_g + global RawImages_g + global Metadata_g + global GPImage_g + global FullImage_Parameters_g + global Cyto_GPImage_g + global GPImage_per_object_g + global GPPhasor_g + global Masks_g + global Intensities_g + global Cyto_Intensities_g + global nobjects_g + global Object_Parameters_g + global Object_Morphology_g + global Object_Coordinates_g + global Mask_Object_Coordinates_g + global Intensities_per_object_g + global Channellamda_g + global phasex_object_g + global phasey_object_g + global GPPhasor_polar_all_g + global Cyto_GPPhasor_polar_all_g + global GPPhasor_polar_obj_g + global key_g + global ConnectSliders_g + global Profile_g + global MembraneSegments_g + global Cytoprof_g + global Cyto_Image_g + global FullImage_Parameters_cyto_g + global Object_Parameters_cyto_g + global Cyto_Intensities_per_object_g + global Cyto_GPPhasor_polar_obj_g + global savingpath_g + + def test(self): + selected_items1 = self.comboBox_18.checkedItems() + print(selected_items1) + global Results_g + Results_g = self.Results + global Membrane_Channels_selected_g + Membrane_Channels_selected_g = self.Membrane_Channels_selected + global Colocolisation_Channel_selected_g + Colocolisation_Channel_selected_g = self.Colocolisation_Channel_selected + global Cytosol_Channels_selected_g + Cytosol_Channels_selected_g = self.Cytosol_Channels_selected + global Membrane_Maskdata_g + Membrane_Maskdata_g = self.Membrane_Maskdata + global Cyto_Maskdata_g + Cyto_Maskdata_g = self.Cyto_Maskdata + global previously_selected_file_g + previously_selected_file_g = self.previously_selected_file + global dims_g + dims_g = self.dims + global RawImages_g + RawImages_g = self.RawImages + global Metadata_g + Metadata_g = self.Metadata + global GPImage_g + GPImage_g = self.GPImage + global FullImage_Parameters_g + FullImage_Parameters_g = self.FullImage_Parameters + global Cyto_GPImage_g + Cyto_GPImage_g = self.Cyto_GPImage + global GPImage_per_object_g + GPImage_per_object_g = self.GPImage_per_object + global Cyto_GPPhasor_polar_all_g + Cyto_GPPhasor_polar_all_g = self.Cyto_GPPhasor_polar_all + global Cyto_GPPhasor_g + Cyto_GPPhasor_g = self.Cyto_GPPhasor + global Masks_g + Masks_g = self.Masks + global Cyto_Masks_g + Cyto_Masks_g = self.Cyto_Masks + global Intensities_g + Intensities_g = self.Intensities + global Cyto_Intensities_g + Cyto_Intensities_g = self.Cyto_Intensities + global nobjects_g + nobjects_g = self.nobjects + global Object_Parameters_g + Object_Parameters_g = self.Object_Parameters + global Object_Morphology_g + Object_Morphology_g = self.Object_Morphology + global Object_Coordinates_g + Object_Coordinates_g = self.Object_Coordinates + global Mask_Object_Coordinates_g + Mask_Object_Coordinates_g = self.Mask_Object_Coordinates + global Intensities_per_object_g + Intensities_per_object_g = self.Intensities_per_object + global Channellamda_g + Channellamda_g = self.Channellamda + global phasex_object_g + phasex_object_g = self.phasex_object + global phasey_object_g + phasey_object_g = self.phasey_object + global GPPhasor_polar_all_g + GPPhasor_polar_all_g = self.GPPhasor_polar_all + global GPPhasor_polar_obj_g + GPPhasor_polar_obj_g = self.GPPhasor_polar_obj + global key_g + key_g = self.key + global ConnectSliders_g + ConnectSliders_g = self.ConnectSliders + global Profile_g + Profile_g = self.Profile + global MembraneSegments_g + MembraneSegments_g = self.MembraneSegments + global Cytoprof_g + Cytoprof_g = self.Cytoprof + global Cyto_Image_g + Cyto_Image_g = self.Cyto_Image + global Object_Parameters_cyto_g + Object_Parameters_cyto_g = self.Object_Parameters_cyto + global FullImage_Parameters_cyto_g + FullImage_Parameters_cyto_g = self.FullImage_Parameters_cyto + global Cyto_Intensities_per_object_g + Cyto_Intensities_per_object_g = self.Cyto_Intensities_per_object + global Cyto_GPPhasor_polar_obj_g + Cyto_GPPhasor_polar_obj_g = self.Cyto_GPPhasor_polar_obj + global savingpath_g + savingpath_g = self.savingpath + + def initialize_membrane_channels(self, filename): + if filename not in self.Membrane_Channels_selected: + self.Membrane_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + def initialize_coloc_channels(self, filename): + if filename not in self.Colocolisation_Channel_selected: + self.Colocolisation_Channel_selected[filename] = None + + def initialize_cytosol_channels(self, filename): + if filename not in self.Cytosol_Channels_selected: + self.Cytosol_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + def Globalize_Channel_Settings(self): + if self.tableWidget.currentRow() !=-1: + self.block_combobox_signals(True) + + # Collect all items from the first column of the tableWidget + row_count = self.tableWidget.rowCount() + items = [self.tableWidget.item(row, 0).text() for row in range(row_count) if self.tableWidget.item(row, 0) != "NaN"] + + current_filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + # Apply globalization logic for Membrane_Channels_selected + if current_filename in self.Membrane_Channels_selected: + globalize = self.Membrane_Channels_selected[current_filename] + filtered_entries = [entry for entry in globalize if entry != "NaN"] + + for filename in items: + if filename in self.Membrane_Channels_selected: + if all(entry in self.Metadata[filename]['ChannelColors'] for entry in filtered_entries): + self.Membrane_Channels_selected[filename] = globalize.copy() + else: + self.Membrane_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + if all(entry in self.Metadata[filename]['ChannelColors'] for entry in filtered_entries): + self.Membrane_Channels_selected[filename] = globalize.copy() + + # Apply globalization logic for Colocolisation_Channel_selected + if current_filename in self.Colocolisation_Channel_selected: + globalize = self.Colocolisation_Channel_selected[current_filename] + for filename in items: + if filename in self.Colocolisation_Channel_selected: + if str(globalize) in self.Metadata[filename]['ChannelColors']: + self.Colocolisation_Channel_selected[filename] = globalize + else: + self.Colocolisation_Channel_selected[filename] = "NaN" + if str(globalize) in self.Metadata[filename]['ChannelColors']: + self.Colocolisation_Channel_selected[filename] = globalize + + # Apply globalization logic for Cytosol_Channels_selected + if current_filename in self.Cytosol_Channels_selected: + globalize = self.Cytosol_Channels_selected[current_filename] + filtered_entries = [entry for entry in globalize if entry != "NaN"] + + for filename in items: + if filename in self.Cytosol_Channels_selected: + if all(entry in self.Metadata[filename]['ChannelColors'] for entry in filtered_entries): + self.Cytosol_Channels_selected[filename] = globalize.copy() + else: + self.Cytosol_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + if all(entry in self.Metadata[filename]['ChannelColors'] for entry in filtered_entries): + self.Cytosol_Channels_selected[filename] = globalize.copy() + + self.block_combobox_signals(False) + + def Update_Membrane_Cytosol_Chnnel_Settings(self): + if self.tableWidget.currentRow() !=-1: + self.block_combobox_signals(True) + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + + # Ensure the channels are initialized + self.initialize_membrane_channels(filename) + self.initialize_coloc_channels(filename) + self.initialize_cytosol_channels(filename) + + # Update comboBox selections based on the current file's settings + if filename in self.Membrane_Channels_selected: + self.update_combobox_selection(self.Membrane_Channels_selected[filename], [ + self.comboBox, + self.comboBox_2, + self.comboBox_6, + self.comboBox_7, + ]) + + if filename in self.Colocolisation_Channel_selected: + self.update_single_combobox_selection(self.Colocolisation_Channel_selected[filename], self.comboBox_8) + + if filename in self.Cytosol_Channels_selected: + self.update_combobox_selection(self.Cytosol_Channels_selected[filename], [ + self.comboBox_13, + self.comboBox_14, + self.comboBox_15, + self.comboBox_16, + ]) + + self.block_combobox_signals(False) + + def Save_Membranechannel_A(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Membrane_Channels_selected: + self.Membrane_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Membrane_Channels_selected[filename][0] = self.comboBox.currentText() + + + def Save_Membranechannel_B(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Membrane_Channels_selected: + self.Membrane_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Membrane_Channels_selected[filename][1] = self.comboBox_2.currentText() + + + def Save_Membranechannel_C(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Membrane_Channels_selected: + self.Membrane_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Membrane_Channels_selected[filename][2] = self.comboBox_6.currentText() + + def Save_Membranechannel_D(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Membrane_Channels_selected: + self.Membrane_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Membrane_Channels_selected[filename][3] = self.comboBox_7.currentText() + + def Save_ColocolisationChannel(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + self.Colocolisation_Channel_selected[filename] = self.comboBox_8.currentText() + + def Save_Cytosolchannel_A(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Cytosol_Channels_selected: + self.Cytosol_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Cytosol_Channels_selected[filename][0] = self.comboBox_13.currentText() + + def Save_Cytosolchannel_B(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Cytosol_Channels_selected: + self.Cytosol_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Cytosol_Channels_selected[filename][1] = self.comboBox_14.currentText() + + def Save_Cytosolchannel_C(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Cytosol_Channels_selected: + self.Cytosol_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Cytosol_Channels_selected[filename][2] = self.comboBox_15.currentText() + + def Save_Cytosolchannel_D(self, index): + if self.tableWidget.currentRow() !=-1: + filename = self.tableWidget.item(self.tableWidget.currentRow(), 0).text() + if filename not in self.Cytosol_Channels_selected: + self.Cytosol_Channels_selected[filename] = ["NaN", "NaN", "NaN", "NaN"] + + self.Cytosol_Channels_selected[filename][3] = self.comboBox_16.currentText() + + def block_combobox_signals(self, block): + self.comboBox.blockSignals(block) + self.comboBox_2.blockSignals(block) + self.comboBox_6.blockSignals(block) + self.comboBox_7.blockSignals(block) + self.comboBox_8.blockSignals(block) + self.comboBox_13.blockSignals(block) + self.comboBox_14.blockSignals(block) + self.comboBox_15.blockSignals(block) + self.comboBox_16.blockSignals(block) + self.comboBox_18.blockSignals(block) + self.comboBox_23.blockSignals(block) + + def update_combobox_selection(self, selections, comboboxes): + for selection, combobox in zip(selections, comboboxes): + if selection != "NaN": + index = combobox.findText(selection) + if index != -1: + combobox.setCurrentIndex(index) + + def update_single_combobox_selection(self, selection, combobox): + if selection != "NaN": + index = combobox.findText(selection) + if index != -1: + combobox.setCurrentIndex(index) + + def PlotRaw_initial(self): + if self.tableWidget.currentRow() !=-1: + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() + self.update_comboboxes(self.Metadata[filename]['ChannelColors']) + if self.tableWidget.item(self.tableWidget.currentRow(),0) != [] and filename in self.RawImages: + #self.RawImages[filename],metadata=openfile(join(path, filename)) + dims=self.Metadata[filename]['Dimensions'] + if ((dims[0]!=1) != (dims[1]!=1)): #if Z or T 4D + if dims[1]!=1: #Zstack 4D + self.key[filename]="Zstack" + self.verticalScrollBar_3.setEnabled(True) + self.verticalScrollBar_3.setRange(0,len(self.RawImages[filename])-1) + self.horizontalScrollBar_3.setEnabled(False) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0][0])-1) + else: + self.key[filename]="Tstack" + self.horizontalScrollBar_3.setEnabled(True) + self.horizontalScrollBar_3.setRange(0,len(self.RawImages[filename])-1) + self.verticalScrollBar_3.setEnabled(False) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0][0])-1) + elif (dims[0]!=1 and dims[1]!=1): #if Z and T 5D + self.key[filename]="TZstack" + self.horizontalScrollBar_3.setEnabled(True) + self.horizontalScrollBar_3.setRange(0,len(self.RawImages[filename])-1) + self.verticalScrollBar_3.setEnabled(True) + self.verticalScrollBar_3.setRange(0,len(self.RawImages[filename])-1) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0][0][0])-1) + else: + self.key[filename]="3dim" + self.verticalScrollBar_3.setEnabled(False) + self.horizontalScrollBar_3.setEnabled(False) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0])-1) + + if self.tabWidget_2.currentIndex() == 0 and filename in self.RawImages: + self.plot_RawImage(self.RawImages[filename],self.key[filename]) + else: + self.plot_RawImage([],[]) + else: + self.plot_RawImage([],[]) + + + def toggle_Colocalization(self): + self.comboBox_8.setEnabled(self.checkBox_14.checkState()) + + def toggleSaveJSONResults(self): + self.checkBox_19.setEnabled(self.checkBox_18.checkState()) + + def JSONResultsWarning(self): + if self.checkBox_19.checkState(): + QMessageBox.warning(self, 'Warning', 'Enabling this option can significantly slow down performance. Additionally, please be aware that the file size will be considerably larger compared to the original image. It is not recommended to use this for batch processing; instead, it is best suited for single images.') + + def toggle_background_std_membrane(self): + self.doubleSpinBox_9.setEnabled(self.checkBox_15.checkState()) + self.doubleSpinBox_7.setEnabled(self.checkBox_15.checkState()) + + def toggle_background_std_cyto(self): + self.doubleSpinBox_10.setEnabled(self.checkBox_16.checkState()) + self.doubleSpinBox_20.setEnabled(self.checkBox_16.checkState()) + + def toggle_Detailed_cyto(self): + self.comboBox_24.setEnabled(not self.checkBox_31.checkState()) + self.tableWidget_6.setEnabled(not self.checkBox_31.checkState()) + + def toggle_Detailed_membrane(self): + self.comboBox_17.setEnabled(not self.checkBox_24.checkState()) + self.tableWidget_3.setEnabled(not self.checkBox_24.checkState()) + + def updateLambda_1(self, value): + # Update the QLabel with the current value of the QScrollBar + self.label_7.setText(str(self.comboBox.itemText(value+1))) + + def updateLambda_2(self, value): + # Update the QLabel with the current value of the QScrollBar + self.label_42.setText(str(self.comboBox.itemText(value+1))) + + + def wrapCentralWidgetWithScrollArea(self): + central_widget = self.centralWidget() + if central_widget is not None: + # Create a QScrollArea + scroll_area = QtWidgets.QScrollArea() + scroll_area.setWidget(central_widget) # Set the existing central widget as the scroll area's widget + scroll_area.setWidgetResizable(True) # Make the scroll area resize with its contents + + # Set the QScrollArea as the new central widget + self.setCentralWidget(scroll_area) + + # Adjust layout contents margins in dp, if necessary + layout = central_widget.layout() + if layout is not None: + margins = layout.contentsMargins() + margins_dp = QtCore.QMargins(px_to_dp(margins.left()), px_to_dp(margins.top()), + px_to_dp(margins.right()), px_to_dp(margins.bottom())) + layout.setContentsMargins(margins_dp) + + def start_worker_thread(self): # Run analyzer + self.progressBar_1.setVisible(True) + self.label_10.setVisible(True) + result,msg, = self.find_unique_valid_letters(self.plainTextEdit.toPlainText(), + self.comboBox.currentText(), + self.comboBox_2.currentText(), + self.comboBox_6.currentText(), + self.comboBox_7.currentText()) + if result: + if not self.checkBox.isChecked(): + self.thread = QThread() + self.worker = WorkerThread(self) + self.worker.moveToThread(self.thread) + self.thread.started.connect(self.worker.run) + self.worker.finished.connect(self.thread.quit) + self.worker.terminate_thread.connect(self.thread.quit) + self.worker.finished.connect(self.worker.deleteLater) + self.thread.finished.connect(self.thread.deleteLater) + self.thread.finished.connect(self.on_thread_finished) + self.disable_parts() + self.thread.start() + elif self.checkBox.isChecked(): + result1,msg1, = self.find_unique_valid_letters(self.plainTextEdit_2.toPlainText(), + self.comboBox_13.currentText(), + self.comboBox_14.currentText(), + self.comboBox_15.currentText(), + self.comboBox_16.currentText()) + if result1: + self.thread = QThread() + self.worker = WorkerThread(self) + self.worker.moveToThread(self.thread) + self.thread.started.connect(self.worker.run) + self.worker.finished.connect(self.thread.quit) + self.worker.terminate_thread.connect(self.thread.quit) + self.worker.finished.connect(self.worker.deleteLater) + self.thread.finished.connect(self.thread.deleteLater) + self.thread.finished.connect(self.on_thread_finished) + self.disable_parts() + self.thread.start() + else: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(msg1) + self.progressBar_1.setVisible(False) + else: + pass + else: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(msg) + self.progressBar_1.setVisible(False) + + + def start_worker_thread_2(self): # Thresholding allone + self.progressBar_1.setVisible(True) + self.label_10.setVisible(True) + result,msg, = self.find_unique_valid_letters(self.plainTextEdit.toPlainText(), self.comboBox.currentText(), self.comboBox_2.currentText(), self.comboBox_6.currentText(), self.comboBox_7.currentText()) + + if result: + if not self.checkBox.isChecked(): + self.thread = QThread() + self.worker = WorkerThread(self) + self.worker.moveToThread(self.thread) + self.thread.started.connect(self.worker.testthresholding) + self.worker.finished.connect(self.thread.quit) + self.worker.terminate_thread.connect(self.thread.quit) + self.worker.finished.connect(self.worker.deleteLater) + self.thread.finished.connect(self.thread.deleteLater) + self.thread.finished.connect(self.on_thread_finished) + self.disable_parts() + self.thread.start() + elif self.checkBox.isChecked(): + result1,msg1, = self.find_unique_valid_letters_cyto(self.plainTextEdit_2.toPlainText(), + self.comboBox_13.currentText(), + self.comboBox_14.currentText(), + self.comboBox_15.currentText(), + self.comboBox_16.currentText()) + if result1: + self.thread = QThread() + self.worker = WorkerThread(self) + self.worker.moveToThread(self.thread) + self.thread.started.connect(self.worker.testthresholding) + self.worker.finished.connect(self.thread.quit) + self.worker.terminate_thread.connect(self.thread.quit) + self.worker.finished.connect(self.worker.deleteLater) + self.thread.finished.connect(self.thread.deleteLater) + self.thread.finished.connect(self.on_thread_finished) + self.disable_parts() + self.thread.start() + else: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(msg1) + self.progressBar_1.setVisible(False) + else: + pass + else: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(msg) + self.progressBar_1.setVisible(False) + + + def on_thread_finished(self): + # Thread finished execution + #print("Thread finished.1") + if self.tableWidget.currentRow() !=-1: + self.tableWidget.selectRow(self.tableWidget.currentRow()) + self.updatePlots() + #print("Thread finished.2") + self.enablee_parts() + self.progressBar_1.setVisible(False) + self.label_10.setVisible(False) + print("Thread finished") + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText("Thread finished") + + def convert_to_type(self,value, value_type): + try: + # Attempt to convert the value to the primary type + converted_value = value_type[0](value) + return converted_value + except ValueError: + # If conversion fails, check if there's a secondary type defined + if len(value_type) > 1: + # Check if the value is "NAN" (case insensitive) + if value.strip().lower() == "nan": + # If the value is "NAN", return it as a string + return "NaN" + if len(value_type) > 2: + if value_type[2] == list: + # Split the value by commas and strip any whitespace + values = [v.strip() for v in value.split(',')] + # Convert each value in the list to the specified type (assuming the secondary type is int or str) + converted_values = [value_type[1](v) for v in values] + return converted_values + else: + # Otherwise, raise an exception + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText("Invalid value. Expected 'NAN'.") + else: + # If there's no secondary type, raise a general conversion exception + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText("Invalid value conversion.") + + def Detailed_Membrane_Masking_onItemChanged(self, item): + + row = item.row() + newValue = item.text() + T_value= item.column() + Z_Value= self.comboBox_17.currentIndex() + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + + translation_table = { + 'Thresholding Mode': {'key': 'Ttype', 'type': (str,)}, + 'Manual Cutoff Level': {'key': 'ValManual', 'type': (int,)}, + 'Compression True/False': {'key': 'compress', 'type': (bool,)}, + 'Compression Value': {'key': 'Kvalue', 'type': (float,)}, + 'Remove Object': {'key': 'objSize', 'type': (int, str)}, # can be str or int + 'Fill Holes': {'key': 'holesSize', 'type': (float, str)}, # can be str or float + 'Dilate True/False': {'key': 'dilate', 'type': (bool,)}, + 'Dilation Shape': {'key': 'shape', 'type': (str,)}, + 'Dilation Shape Dimension 1': {'key': 'dim1', 'type': (int,)}, + 'Dilation Shape Dimension 2': {'key': 'dim2', 'type': (int,)}, + 'Filter Type': {'key': 'filter_type', 'type': (str,)}, + 'Filter Value': {'key': 'filter_val', 'type': (float,)}, + 'Signal to Noise Ratio': {'key': 'S_N', 'type': (float,)}, + 'Background StdDev': {'key': 'stddev', 'type': (float,)}, # can be 1 or float + 'Background Mean': {'key': 'bgmean', 'type': (float, str)}, # can be str or float + 'Specific Channel Wavelength': {'key': 'lambdaThr', 'type': (int, str,list)}, # can be str or int + # Add more translations as needed + } + translation = translation_table.get(self.tableWidget_3.verticalHeaderItem(row).text()) + Error=True + + if translation: + key = translation['key'] + if key == "Ttype": + if newValue != "Otsu" and newValue != "Manual": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Thresholding Mode'. (Otsu or Manual)") + Error=False + elif key == "ValManual": + if not newValue.isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Manual Cutoff Level'. (a int)") + Error=False + elif key == "compress": + if newValue != "True" and newValue != "False": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Compression True/False'. (True or False)") + Error=False + elif key == "Kvalue": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Compression Value'. (a float)") + Error=False + elif key == "objSize": + if not newValue.isdigit() and newValue != "NaN": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Remove Object'. (NaN or a int)") + Error=False + elif key == "holesSize": + if not newValue.replace(".", "", 1).isdigit() and newValue != "NaN": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Fill Holes'. (NaN or a float)") + Error=False + elif key == "dilate": + if newValue != "True" and newValue != "False": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilate True/False'. (True or False)") + Error=False + elif key == "shape": + if newValue != "octagon" and newValue != "disk" and newValue != "square": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilation Shape'. (octagon ,disk or square)") + Error=False + elif key == "dim1": + if not newValue.isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilation Shape Dimension 1'. (a int)") + Error=False + elif key == "dim2": + if not newValue.isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilation Shape Dimension 2'. (a int)") + Error=False + elif key == "filter_type": + invalid_values = ["No Filter", "Gaussian", "Mode", "Median", "Mean", "Geometric_mean","Majority","Minimum","Maximum", + "Sum","Gradient","Entropy"] + if not newValue.isdigit() and newValue not in invalid_values: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f'The value "{newValue}" is not valid for "Filter Type". ( pls choose one of these: "No Filter", "Gaussian", "Mode", "Median", "Mean", "Geometric_mean","Majority","Minimum","Maximum","Sum","Gradient","Entropy")') + Error=False + elif key == "filter_val": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Filter Value'. (a float)") + Error=False + elif key == "S_N": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Signal to Noise Ratio'. (a float)") + Error=False + elif key == "stddev": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Background StdDev'. (a float)") + Error=False + elif key == "bgmean": + if not newValue.replace(".", "", 1).isdigit() and newValue!="NaN": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Background Mean'. (NaN or a float)") + Error=False + elif key == 'lambdaThr': + combo_items = [self.comboBox_18.itemText(i) for i in range(self.comboBox_18.count())] + if newValue != []: + new_values_list = [value.strip() for value in newValue.split(',')] + for value in new_values_list: + if value not in combo_items: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{value}' is not valid for 'Specific Channel Wavelength'. (NaN or a list of available channels e.g. [488,647])") + Error=False + + if Error: + value_type = translation['type'] + maxT = self.tableWidget_3.columnCount() + maxZ = self.comboBox_17.count() + + if filename in self.Membrane_Maskdata: + if maxT > 1 and maxZ < 1: # T only + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Membrane_Maskdata[filename][T_value][key] = converted_value + elif maxT < 2 and maxZ > 1: # Z only + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Membrane_Maskdata[filename][Z_Value][key] = converted_value + elif maxT > 1 and maxZ > 1: # TZ + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Membrane_Maskdata[filename][T_value][Z_Value][key] = converted_value + elif maxT < 2 and maxZ < 1: # TZ + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Membrane_Maskdata[filename][key] = converted_value + + + def Update_formZ_Detailed_Membrane_Masking_Setting(self): + if not self.tableWidget.rowCount() == 0: + if self.tableWidget.currentItem() is not None: + if self.tableWidget.currentItem().isSelected(): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + self.tableWidget_3.blockSignals(True) + if filename in self.Membrane_Maskdata: + maxT=self.tableWidget_3.columnCount() + maxZ=self.comboBox_17.count() + + # Verwenden Sie die umgekehrte Übersetzungstabelle, um den Anzeigenamen in den internen Variablennamen umzuwandeln + reverse_translation_table = { + 'Ttype': 'Thresholding Mode', + 'ValManual': 'Manual Cutoff Level', + 'compress': 'Compression True/False', + 'Kvalue': 'Compression Value', + 'objSize': 'Remove Object', + 'holesSize': 'Fill Holes', + 'dilate': 'Dilate True/False', + 'shape': 'Dilation Shape', + 'dim1': 'Dilation Shape Dimmension 1', + 'dim2': 'Dilation Shape Dimmension 2', + 'filter_type': 'Filter Type', + 'filter_val': 'Filter Value', + 'S_N': 'Signal to Noise Ratio', + 'stddev': 'Background StdDev', + 'bgmean': 'Background Mean', + 'lambdaThr': 'Specific Channel Wavelength', + } + + if maxT < 2 and maxZ > 1: # Z only + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in self.Membrane_Maskdata[filename][self.comboBox_17.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index, QTableWidgetItem(item_value)) + + elif maxT > 1 and maxZ > 1: # TZ + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in self.Membrane_Maskdata[filename][T_index][self.comboBox_17.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index,QTableWidgetItem(item_value)) + self.tableWidget_3.blockSignals(False) + + def helper_for_button_updater(self): + if self.tableWidget.rowCount() != 0 and self.tableWidget.currentItem() is not None and self.tableWidget.currentItem().isSelected(): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() if self.tableWidget.currentRow() >= 0 else None + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() if self.tableWidget.currentRow() >= 0 else None + self.update_toglobal_values_membrane(filename=filename, path=path) + + + def update_toglobal_values_membrane(self,filename=None, path=None): + self.tableWidget_3.blockSignals(True) + if filename is None: + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() if self.tableWidget.currentRow() >= 0 else None + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() if self.tableWidget.currentRow() >= 0 else None + if path is None: + return + #image,metadata=openfile(join(path,filename)) + Standard_Values={"Ttype":self.comboBox_3.currentText(), + "ValManual":int(self.spinBox.value()), + "compress": bool(self.checkBox_3.isChecked()), + "Kvalue": float(self.doubleSpinBox.value()), + "objSize":"NaN" if not self.checkBox_4.isChecked() else (self.spinBox_2.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_5.isChecked() else (self.doubleSpinBox_13.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_6.isChecked()), + "shape": self.comboBox_4.currentText(), + "dim1":int(self.spinBox_4.value()), #shpae dim1 + "dim2":int(self.spinBox_5.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_9.currentText() == "No Filter" else (self.comboBox_9.currentText()), + "filter_val": self.doubleSpinBox_12.value(), + "S_N":self.doubleSpinBox_8.value(), + "stddev": 1 if not self.checkBox_15.isChecked() else (self.doubleSpinBox_7.value()), + "bgmean": "NaN" if not self.checkBox_15.isChecked() else (self.doubleSpinBox_9.value()), + "lambdaThr":[] if not self.checkBox_27.isChecked() else self.comboBox_18.checkedItems(), + } + reverse_translation_table = { + 'Ttype': 'Thresholding Mode', + 'ValManual': 'Manual Cutoff Level', + 'compress': 'Compression True/False', + 'Kvalue': 'Compression Value', + 'objSize': 'Remove Object', + 'holesSize': 'Fill Holes', + 'dilate': 'Dilate True/False', + 'shape': 'Dilation Shape', + 'dim1': 'Dilation Shape Dimmension 1', + 'dim2': 'Dilation Shape Dimmension 2', + 'filter_type': 'Filter Type', + 'filter_val': 'Filter Value', + 'S_N': 'Signal to Noise Ratio', + 'stddev': 'Background StdDev', + 'bgmean': 'Background Mean', + 'lambdaThr': 'Specific Channel Wavelength', + } + + if self.Metadata[filename]: + if "Dimensions" in self.Metadata[filename]: + if self.Metadata[filename]['Dimensions'][0]>1: #its a T stack + self.tableWidget_3.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + else: # Z or 3dim + self.tableWidget_3.setColumnCount(1) + + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in Standard_Values.items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index, QTableWidgetItem(item_value)) + + #self.comboBox_17.addItems([str(x) for x in metadata['Dimensions'][1]]) + + if self.Metadata[filename]['Dimensions'][1]>1: + self.comboBox_17.clear() + self.comboBox_17.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + else: + self.comboBox_17.clear() + + elif "0" in self.Metadata[filename]: # for lif and obl + for n in range(len(self.Metadata[filename])): + print(self.Metadata[filename][n]['Dimensions']) + self.Save_Detailed_Membrane_Masking_Setting(filename=filename, path=path) + self.tableWidget_3.blockSignals(False) + + def Update_Detailed_Membrane_Masking_Setting(self): + if not self.tableWidget.rowCount() == 0: + if self.tableWidget.currentItem() is not None: + if self.tableWidget.currentItem().isSelected(): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() if self.tableWidget.currentRow() >= 0 else None + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() + self.tableWidget_3.blockSignals(True) + reverse_translation_table = { + 'Ttype': 'Thresholding Mode', + 'ValManual': 'Manual Cutoff Level', + 'compress': 'Compression True/False', + 'Kvalue': 'Compression Value', + 'objSize': 'Remove Object', + 'holesSize': 'Fill Holes', + 'dilate': 'Dilate True/False', + 'shape': 'Dilation Shape', + 'dim1': 'Dilation Shape Dimmension 1', + 'dim2': 'Dilation Shape Dimmension 2', + 'filter_type': 'Filter Type', + 'filter_val': 'Filter Value', + 'S_N': 'Signal to Noise Ratio', + 'stddev': 'Background StdDev', + 'bgmean': 'Background Mean', + 'lambdaThr': 'Specific Channel Wavelength', + } + if filename in self.Membrane_Maskdata: + self.comboBox_17.clear() + self.tableWidget_3.setColumnCount(0) + #image,metadata=openfile(join(path,filename)) + if "Dimensions" in self.Metadata[filename]: + if self.Metadata[filename]['Dimensions'][0]>1 and self.Metadata[filename]['Dimensions'][1]>1 : #its a TZ stack + self.tableWidget_3.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + self.comboBox_17.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in self.Membrane_Maskdata[filename][T_index][self.comboBox_17.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif self.Metadata[filename]['Dimensions'][0]>1 and not self.Metadata[filename]['Dimensions'][1]>1 : #its a T stack + self.tableWidget_3.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in self.Membrane_Maskdata[filename][T_index].items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif not self.Metadata[filename]['Dimensions'][0]>1 and self.Metadata[filename]['Dimensions'][1]>1 : #its a Z stack + self.tableWidget_3.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + self.comboBox_17.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in self.Membrane_Maskdata[filename][self.comboBox_17.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif not self.Metadata[filename]['Dimensions'][0]>1 and not self.Metadata[filename]['Dimensions'][1]>1 : #its a Z stack + self.tableWidget_3.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in self.Membrane_Maskdata[filename].items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif filename not in self.Membrane_Maskdata and filename: + #image,metadata=openfile(join(path,filename)) + Standard_Values={"Ttype":self.comboBox_3.currentText(), + "ValManual":int(self.spinBox.value()), + "compress": bool(self.checkBox_3.isChecked()), + "Kvalue": float(self.doubleSpinBox.value()), + "objSize":"NaN" if not self.checkBox_4.isChecked() else (self.spinBox_2.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_5.isChecked() else (self.doubleSpinBox_13.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_6.isChecked()), + "shape": self.comboBox_4.currentText(), + "dim1":int(self.spinBox_4.value()), #shpae dim1 + "dim2":int(self.spinBox_5.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_9.currentText() == "No Filter" else (self.comboBox_9.currentText()), + "filter_val": self.doubleSpinBox_12.value(), + "S_N":self.doubleSpinBox_8.value(), + "stddev": 1 if not self.checkBox_15.isChecked() else (self.doubleSpinBox_7.value()), + "bgmean": "NaN" if not self.checkBox_15.isChecked() else (self.doubleSpinBox_9.value()), + "lambdaThr":[] if not self.checkBox_27.isChecked() else self.comboBox_18.checkedItems(), + } + if self.Metadata[filename]: + if "Dimensions" in self.Metadata[filename]: + if self.Metadata[filename]['Dimensions'][0]>1: #its a T stack + self.tableWidget_3.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + else: # Z or 3dim + self.tableWidget_3.setColumnCount(1) + + for T_index in range(self.tableWidget_3.columnCount()): + for key, value in Standard_Values.items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_3.rowCount()): + if self.tableWidget_3.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_3.setItem(header_index,T_index, QTableWidgetItem(item_value)) + + #self.comboBox_17.addItems([str(x) for x in metadata['Dimensions'][1]]) + + if self.Metadata[filename]['Dimensions'][1]>1: + self.comboBox_17.clear() + self.comboBox_17.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + else: + self.comboBox_17.clear() + + elif "0" in self.Metadata[filename]: # for lif and obl + for n in range(len(self.Metadata[filename])): + print(self.Metadata[filename][n]['Dimensions']) + self.Save_Detailed_Membrane_Masking_Setting(filename=filename, path=path) + else: + self.tableWidget_3.setColumnCount(0) + self.comboBox_17.clear() + + self.tableWidget_3.blockSignals(False) + + + def Save_Detailed_Membrane_Masking_Setting(self,filename=None, path=None): + if not self.tableWidget.rowCount() == 0: + if filename is None: + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() + #image,metadata=openfile(join(path,filename)) + + self.Membrane_Maskdata[filename]=[] + if self.tableWidget_3.columnCount()>1: # only T + for i in range(self.tableWidget_3.columnCount()): + self.Membrane_Maskdata[filename].append({"Ttype":self.comboBox_3.currentText(), + "ValManual":int(self.spinBox.value()), + "compress": bool(self.checkBox_3.isChecked()), + "Kvalue": float(self.doubleSpinBox.value()), + "objSize":"NaN" if not self.checkBox_4.isChecked() else (self.spinBox_2.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_5.isChecked() else (self.doubleSpinBox_13.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_6.isChecked()), + "shape": self.comboBox_4.currentText(), + "dim1":int(self.spinBox_4.value()), #shpae dim1 + "dim2":int(self.spinBox_5.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_9.currentText() == "No Filter" else (self.comboBox_9.currentText()), + "filter_val": self.doubleSpinBox_12.value(), + "S_N":self.doubleSpinBox_8.value(), + "stddev": 1 if not self.checkBox_15.isChecked() else (self.doubleSpinBox_7.value()), + "bgmean": "NaN" if not self.checkBox_15.isChecked() else (self.doubleSpinBox_9.value()), + "lambdaThr":[] if not self.checkBox_27.isChecked() else self.comboBox_18.checkedItems(), + }) + if self.comboBox_17.count() > 1: # TZ + self.Membrane_Maskdata[filename][i]=[] + for n in range(self.comboBox_17.count()): + self.Membrane_Maskdata[filename][i].append({"Ttype":self.comboBox_3.currentText(), + "ValManual":int(self.spinBox.value()), + "compress": bool(self.checkBox_3.isChecked()), + "Kvalue": float(self.doubleSpinBox.value()), + "objSize":"NaN" if not self.checkBox_4.isChecked() else (self.spinBox_2.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_5.isChecked() else (self.doubleSpinBox_13.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_6.isChecked()), + "shape": self.comboBox_4.currentText(), + "dim1":int(self.spinBox_4.value()), #shpae dim1 + "dim2":int(self.spinBox_5.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_9.currentText() == "No Filter" else (self.comboBox_9.currentText()), + "filter_val": self.doubleSpinBox_12.value(), + "S_N":self.doubleSpinBox_8.value(), + "stddev": 1 if not self.checkBox_15.isChecked() else (self.doubleSpinBox_7.value()), + "bgmean": "NaN" if not self.checkBox_15.isChecked() else (self.doubleSpinBox_9.value()), + "lambdaThr":[] if not self.checkBox_27.isChecked() else self.comboBox_18.checkedItems(), + }) + + else: + if self.comboBox_17.count() > 1: # only Z + self.Membrane_Maskdata[filename]=[] + for n in range(self.comboBox_17.count()): + self.Membrane_Maskdata[filename].append({"Ttype":self.comboBox_3.currentText(), + "ValManual":int(self.spinBox.value()), + "compress": bool(self.checkBox_3.isChecked()), + "Kvalue": float(self.doubleSpinBox.value()), + "objSize":"NaN" if not self.checkBox_4.isChecked() else (self.spinBox_2.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_5.isChecked() else (self.doubleSpinBox_13.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_6.isChecked()), + "shape": self.comboBox_4.currentText(), + "dim1":int(self.spinBox_4.value()), #shpae dim1 + "dim2":int(self.spinBox_5.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_9.currentText() != "No Filter" else (self.comboBox_9.currentText()), + "filter_val": self.doubleSpinBox_12.value(), + "S_N":self.doubleSpinBox_8.value(), + "stddev": 1 if not self.checkBox_15.isChecked() else (self.doubleSpinBox_7.value()), + "bgmean": "NaN" if not self.checkBox_15.isChecked() else (self.doubleSpinBox_9.value()), + "lambdaThr":[] if not self.checkBox_27.isChecked() else self.comboBox_18.checkedItems(), + }) + else: # only 3dim + self.Membrane_Maskdata[filename]={"Ttype":self.comboBox_3.currentText(), + "ValManual":int(self.spinBox.value()), + "compress": bool(self.checkBox_3.isChecked()), + "Kvalue": float(self.doubleSpinBox.value()), + "objSize":"NaN" if not self.checkBox_4.isChecked() else (self.spinBox_2.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_5.isChecked() else (self.doubleSpinBox_13.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_6.isChecked()), + "shape": self.comboBox_4.currentText(), + "dim1":int(self.spinBox_4.value()), #shpae dim1 + "dim2":int(self.spinBox_5.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_9.currentText() == "No Filter" else (self.comboBox_9.currentText()), + "filter_val": self.doubleSpinBox_12.value(), + "S_N":self.doubleSpinBox_8.value(), + "stddev": 1 if not self.checkBox_15.isChecked() else (self.doubleSpinBox_7.value()), + "bgmean": "NaN" if not self.checkBox_15.isChecked() else (self.doubleSpinBox_9.value()), + "lambdaThr":[] if not self.checkBox_27.isChecked() else self.comboBox_18.checkedItems() + } + + + def Detailed_Cytosol_Masking_onItemChanged(self, item): + row = item.row() + newValue = item.text() + T_value= item.column() + Z_Value= self.comboBox_24.currentIndex() + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + + translation_table = { + 'Thresholding Mode': {'key': 'Ttype', 'type': (str,)}, + 'Manual Cutoff Level': {'key': 'ValManual', 'type': (int,)}, + 'Compression True/False': {'key': 'compress', 'type': (bool,)}, + 'Compression Value': {'key': 'Kvalue', 'type': (float,)}, + 'Remove Object': {'key': 'objSize', 'type': (int, str)}, # can be str or int + 'Fill Holes': {'key': 'holesSize', 'type': (float, str)}, # can be str or float + 'Dilate True/False': {'key': 'dilate', 'type': (bool,)}, + 'Dilation Shape': {'key': 'shape', 'type': (str,)}, + 'Dilation Shape Dimension 1': {'key': 'dim1', 'type': (int,)}, + 'Dilation Shape Dimension 2': {'key': 'dim2', 'type': (int,)}, + 'Filter Type': {'key': 'filter_type', 'type': (str,)}, + 'Filter Value': {'key': 'filter_val', 'type': (float,)}, + 'Signal to Noise Ratio': {'key': 'S_N', 'type': (float,)}, + 'Background StdDev': {'key': 'stddev', 'type': (float,)}, # can be 1 or float + 'Background Mean': {'key': 'bgmean', 'type': (float, str)}, # can be str or float + 'Specific Channel Wavelength': {'key': 'lambdaThr', 'type': (int, str, list)}, # can be str or int + # Add more translations as needed + } + translation = translation_table.get(self.tableWidget_3.verticalHeaderItem(row).text()) + Error=True + + if translation: + key = translation['key'] + if key == "Ttype": + if newValue != "Otsu" and newValue != "Manual": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Thresholding Mode'. (Otsu or Manual)") + Error=False + elif key == "ValManual": + if not newValue.isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Manual Cutoff Level'. (a int)") + Error=False + elif key == "compress": + if newValue != "True" and newValue != "False": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Compression True/False'. (True or False)") + Error=False + elif key == "Kvalue": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Compression Value'. (a float)") + Error=False + elif key == "objSize": + if not newValue.isdigit() and newValue != "NaN": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Remove Object'. (NaN or a int)") + Error=False + elif key == "holesSize": + if not newValue.replace(".", "", 1).isdigit() and newValue != "NaN": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Fill Holes'. (NaN or a float)") + Error=False + elif key == "dilate": + if newValue != "True" and newValue != "False": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilate True/False'. (True or False)") + Error=False + elif key == "shape": + if newValue != "octagon" and newValue != "disk" and newValue != "square": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilation Shape'. (octagon ,disk or square)") + Error=False + elif key == "dim1": + if not newValue.isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilation Shape Dimension 1'. (a int)") + Error=False + elif key == "dim2": + if not newValue.isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Dilation Shape Dimension 2'. (a int)") + Error=False + elif key == "filter_type": + invalid_values = ["No Filter", "Gaussian", "Mode", "Median", "Mean", "Geometric_mean","Majority","Minimum","Maximum", + "Sum","Gradient","Entropy"] + if not newValue.isdigit() and newValue not in invalid_values: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f'The value "{newValue}" is not valid for "Filter Type". ( pls choose one of these: "No Filter", "Gaussian", "Mode", "Median", "Mean", "Geometric_mean","Majority","Minimum","Maximum","Sum","Gradient","Entropy")') + Error=False + elif key == "filter_val": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Filter Value'. (a float)") + Error=False + elif key == "S_N": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Signal to Noise Ratio'. (a float)") + Error=False + elif key == "stddev": + if not newValue.replace(".", "", 1).isdigit(): + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Background StdDev'. (a float)") + Error=False + elif key == "bgmean": + if not newValue.replace(".", "", 1).isdigit() and newValue!="NaN": + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{newValue}' is not valid for 'Background Mean'. (NaN or a float)") + Error=False + elif key == 'lambdaThr': + combo_items = [self.comboBox_18.itemText(i) for i in range(self.comboBox_18.count())] + if newValue != []: + new_values_list = [value.strip() for value in newValue.split(',')] + for value in new_values_list: + if value not in combo_items: + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText(f"The value '{value}' is not valid for 'Specific Channel Wavelength'. (NaN or a list of available channels e.g. [488,647])") + Error=False + + if Error: + value_type = translation['type'] + maxT=self.tableWidget_6.columnCount() + maxZ=self.comboBox_24.count() + + if filename in self.Cyto_Maskdata: + if maxT > 1 and maxZ < 1: # T only + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Cyto_Maskdata[filename][T_value][key] = converted_value + elif maxT < 2 and maxZ > 1: # Z only + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Cyto_Maskdata[filename][Z_Value][key] = converted_value + elif maxT > 1 and maxZ > 1: # TZ + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Cyto_Maskdata[filename][T_value][Z_Value][key] = converted_value + elif maxT < 2 and maxZ < 1: # TZ + # Convert the value to the desired type + converted_value = self.convert_to_type(newValue, value_type) + self.Cyto_Maskdata[filename][key] = converted_value + + def Update_formZ_Detailed_Cytosol_Masking_Setting(self): + if not self.tableWidget.rowCount() == 0: + if self.tableWidget.currentItem() is not None: + if self.tableWidget.currentItem().isSelected(): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + self.tableWidget_6.blockSignals(True) + if filename in self.Cyto_Maskdata: + maxT=self.tableWidget_6.columnCount() + maxZ=self.comboBox_24.count() + + # Verwenden Sie die umgekehrte Übersetzungstabelle, um den Anzeigenamen in den internen Variablennamen umzuwandeln + reverse_translation_table = { + 'Ttype': 'Thresholding Mode', + 'ValManual': 'Manual Cutoff Level', + 'compress': 'Compression True/False', + 'Kvalue': 'Compression Value', + 'objSize': 'Remove Object', + 'holesSize': 'Fill Holes', + 'dilate': 'Dilate True/False', + 'shape': 'Dilation Shape', + 'dim1': 'Dilation Shape Dimmension 1', + 'dim2': 'Dilation Shape Dimmension 2', + 'filter_type': 'Filter Type', + 'filter_val': 'Filter Value', + 'S_N': 'Signal to Noise Ratio', + 'stddev': 'Background StdDev', + 'bgmean': 'Background Mean', + 'lambdaThr': 'Specific Channel Wavelength', + } + + if maxT < 2 and maxZ > 1: # Z only + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in self.Cyto_Maskdata[filename][self.comboBox_24.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index, QTableWidgetItem(item_value)) + + elif maxT > 1 and maxZ > 1: # TZ + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in self.Cyto_Maskdata[filename][T_index][self.comboBox_24.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index,QTableWidgetItem(item_value)) + self.tableWidget_6.blockSignals(False) + + + def helper2_for_button_updater(self): + if self.tableWidget.rowCount() != 0 and self.tableWidget.currentItem() is not None and self.tableWidget.currentItem().isSelected(): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() if self.tableWidget.currentRow() >= 0 else None + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() if self.tableWidget.currentRow() >= 0 else None + self.update_toglobal_values_cytosol(filename=filename, path=path) + + def update_toglobal_values_cytosol(self, filename=None,path=None): + self.tableWidget_6.blockSignals(True) + if filename is None: + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() if self.tableWidget.currentRow() >= 0 else None + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() if self.tableWidget.currentRow() >= 0 else None + if path is None: + return + #image,metadata=openfile(join(path,filename)) + Standard_Values={"Ttype":self.comboBox_21.currentText(), + "ValManual":int(self.spinBox_15.value()), + "compress": bool(self.checkBox_32.isChecked()), + "Kvalue": float(self.doubleSpinBox_23.value()), + "objSize":"NaN" if not self.checkBox_34.isChecked() else (self.spinBox_18.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_35.isChecked() else (self.doubleSpinBox_22.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_37.isChecked()), + "shape": self.comboBox_22.currentText(), + "dim1":int(self.spinBox_17.value()), #shpae dim1 + "dim2":int(self.spinBox_16.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_10.currentText() == "No Filter" else (self.comboBox_10.currentText()), + "filter_val": self.doubleSpinBox_11.value(), + "S_N":self.doubleSpinBox_21.value(), + "stddev": 1 if not self.checkBox_16.isChecked() else (self.doubleSpinBox_20.value()), + "bgmean": "NaN" if not self.checkBox_16.isChecked() else (self.doubleSpinBox_10.value()), + "lambdaThr":[] if not self.checkBox_36.isChecked() else self.comboBox_23.checkedItems(), + } + reverse_translation_table = { + 'Ttype': 'Thresholding Mode', + 'ValManual': 'Manual Cutoff Level', + 'compress': 'Compression True/False', + 'Kvalue': 'Compression Value', + 'objSize': 'Remove Object', + 'holesSize': 'Fill Holes', + 'dilate': 'Dilate True/False', + 'shape': 'Dilation Shape', + 'dim1': 'Dilation Shape Dimmension 1', + 'dim2': 'Dilation Shape Dimmension 2', + 'filter_type': 'Filter Type', + 'filter_val': 'Filter Value', + 'S_N': 'Signal to Noise Ratio', + 'stddev': 'Background StdDev', + 'bgmean': 'Background Mean', + 'lambdaThr': 'Specific Channel Wavelength', + } + + if self.Metadata[filename]: + if "Dimensions" in self.Metadata[filename]: + if self.Metadata[filename]['Dimensions'][0]>1: #its a T stack + self.tableWidget_6.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + else: # Z or 3dim + self.tableWidget_6.setColumnCount(1) + + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in Standard_Values.items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index, QTableWidgetItem(item_value)) + + #self.comboBox_17.addItems([str(x) for x in metadata['Dimensions'][1]]) + + if self.Metadata[filename]['Dimensions'][1]>1: + self.comboBox_24.clear() + self.comboBox_24.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + else: + self.comboBox_24.clear() + + elif "0" in self.Metadata[filename]: # for lif and obl + for n in range(len(self.Metadata[filename])): + print(self.Metadata[filename][n]['Dimensions']) + self.Save_Detailed_Cytosol_Masking_Setting(filename=filename, path=path) + self.tableWidget_6.blockSignals(False) + + def Update_Detailed_Cytosol_Masking_Setting(self): + if not self.tableWidget.rowCount() == 0: + if self.tableWidget.currentItem() is not None: + if self.tableWidget.currentItem().isSelected(): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() if self.tableWidget.currentRow() >= 0 else None + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() + self.tableWidget_6.blockSignals(True) + reverse_translation_table = { + 'Ttype': 'Thresholding Mode', + 'ValManual': 'Manual Cutoff Level', + 'compress': 'Compression True/False', + 'Kvalue': 'Compression Value', + 'objSize': 'Remove Object', + 'holesSize': 'Fill Holes', + 'dilate': 'Dilate True/False', + 'shape': 'Dilation Shape', + 'dim1': 'Dilation Shape Dimmension 1', + 'dim2': 'Dilation Shape Dimmension 2', + 'filter_type': 'Filter Type', + 'filter_val': 'Filter Value', + 'S_N': 'Signal to Noise Ratio', + 'stddev': 'Background StdDev', + 'bgmean': 'Background Mean', + 'lambdaThr': 'Specific Channel Wavelength', + } + if filename in self.Cyto_Maskdata: + self.comboBox_24.clear() + self.tableWidget_6.setColumnCount(0) + #image,metadata=openfile(join(path,filename)) + if "Dimensions" in self.Metadata[filename]: + if self.Metadata[filename]['Dimensions'][0]>1 and self.Metadata[filename]['Dimensions'][1]>1 : #its a TZ stack + self.tableWidget_6.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + self.comboBox_24.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in self.Cyto_Maskdata[filename][T_index][self.comboBox_24.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) # Übersetzen Sie den internen Variablennamen in den Anzeigenamen + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif self.Metadata[filename]['Dimensions'][0]>1 and not self.Metadata[filename]['Dimensions'][1]>1 : #its a T stack + self.tableWidget_6.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in self.Cyto_Maskdata[filename][T_index].items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif not self.Metadata[filename]['Dimensions'][0]>1 and self.Metadata[filename]['Dimensions'][1]>1 : #its a Z stack + self.tableWidget_6.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + self.comboBox_24.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in self.Cyto_Maskdata[filename][self.comboBox_24.currentIndex()].items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif not self.Metadata[filename]['Dimensions'][0]>1 and not self.Metadata[filename]['Dimensions'][1]>1 : #its a Z stack + self.tableWidget_6.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in self.Cyto_Maskdata[filename].items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index, QTableWidgetItem(item_value)) + elif filename not in self.Cyto_Maskdata and filename: + # image,self.Metadata[filename]=openfile(join(path,filename)) + Standard_Values={"Ttype":self.comboBox_21.currentText(), + "ValManual":int(self.spinBox_15.value()), + "compress": bool(self.checkBox_32.isChecked()), + "Kvalue": float(self.doubleSpinBox_23.value()), + "objSize":"NaN" if not self.checkBox_34.isChecked() else (self.spinBox_18.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_35.isChecked() else (self.doubleSpinBox_22.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_37.isChecked()), + "shape": self.comboBox_22.currentText(), + "dim1":int(self.spinBox_17.value()), #shpae dim1 + "dim2":int(self.spinBox_16.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_val": self.doubleSpinBox_11.value(), + "S_N":self.doubleSpinBox_21.value(), + "stddev": 1 if not self.checkBox_16.isChecked() else (self.doubleSpinBox_20.value()), + "bgmean": "NaN" if not self.checkBox_16.isChecked() else (self.doubleSpinBox_10.value()), + "lambdaThr":[] if not self.checkBox_36.isChecked() else self.comboBox_23.checkedItems(), + } + if self.Metadata[filename]: + if "Dimensions" in self.Metadata[filename]: + if self.Metadata[filename]['Dimensions'][0]>1: #its a T stack + self.tableWidget_6.setColumnCount(self.Metadata[filename]['Dimensions'][0]) + else: # Z or 3dim + self.tableWidget_6.setColumnCount(1) + + for T_index in range(self.tableWidget_6.columnCount()): + for key, value in Standard_Values.items(): + translated_key = reverse_translation_table.get(key, key) + header_index = None + for i in range(self.tableWidget_6.rowCount()): + if self.tableWidget_6.verticalHeaderItem(i).text() == translated_key: + header_index = i + break # Exit the column search loop once a match is found + + # Set the value if a matching column was found + if header_index is not None: + item_value = str(value) if not isinstance(value, bool) else "True" if value else "False" + item_value=item_value.translate(str.maketrans("", "", "['']")) + self.tableWidget_6.setItem(header_index,T_index, QTableWidgetItem(item_value)) + + #self.comboBox_24.addItems([str(x) for x in metadata['Dimensions'][1]]) + + if self.Metadata[filename]['Dimensions'][1]>1: + self.comboBox_24.clear() + self.comboBox_24.addItems([str(x+1) for x in range(self.Metadata[filename]['Dimensions'][1])]) + else: + self.comboBox_24.clear() + + elif "0" in self.Metadata[filename]: # for lif and obl + for n in range(len(self.Metadata[filename])): + print(self.Metadata[filename][n]['Dimensions']) + self.Save_Detailed_Cytosol_Masking_Setting(filename=filename, path=path) + else: + self.tableWidget_6.setColumnCount(0) + self.comboBox_24.clear() + + self.tableWidget_6.blockSignals(False) + + + def Save_Detailed_Cytosol_Masking_Setting(self,filename=None, path=None): + if not self.tableWidget.rowCount() == 0: + if filename is None: + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + path=self.tableWidget.item(self.tableWidget.currentRow(),1).text() + #image,metadata=openfile(join(path,filename)) + + self.Cyto_Maskdata[filename]=[] + if self.tableWidget_6.columnCount()>1: # only T + for i in range(self.tableWidget_6.columnCount()): + self.Cyto_Maskdata[filename].append({"Ttype":self.comboBox_21.currentText(), + "ValManual":int(self.spinBox_15.value()), + "compress": bool(self.checkBox_32.isChecked()), + "Kvalue": float(self.doubleSpinBox_23.value()), + "objSize":"NaN" if not self.checkBox_34.isChecked() else (self.spinBox_18.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_35.isChecked() else (self.doubleSpinBox_22.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_37.isChecked()), + "shape": self.comboBox_22.currentText(), + "dim1":int(self.spinBox_17.value()), #shpae dim1 + "dim2":int(self.spinBox_16.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_10.currentText() == "No Filter" else (self.comboBox_10.currentText()), + "filter_val": self.doubleSpinBox_11.value(), + "S_N":self.doubleSpinBox_21.value(), + "stddev": 1 if not self.checkBox_16.isChecked() else (self.doubleSpinBox_20.value()), + "bgmean": "NaN" if not self.checkBox_16.isChecked() else (self.doubleSpinBox_10.value()), + "lambdaThr":[] if not self.checkBox_36.isChecked() else self.comboBox_23.checkedItems(), + }) + if self.comboBox_24.count() > 1: # TZ + self.Cyto_Maskdata[filename][i]=[] + for n in range(self.comboBox_24.count()): + self.Cyto_Maskdata[filename][i].append({"Ttype":self.comboBox_21.currentText(), + "ValManual":int(self.spinBox_15.value()), + "compress": bool(self.checkBox_32.isChecked()), + "Kvalue": float(self.doubleSpinBox_23.value()), + "objSize":"NaN" if not self.checkBox_34.isChecked() else (self.spinBox_18.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_35.isChecked() else (self.doubleSpinBox_22.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_37.isChecked()), + "shape": self.comboBox_22.currentText(), + "dim1":int(self.spinBox_17.value()), #shpae dim1 + "dim2":int(self.spinBox_16.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_10.currentText() == "No Filter" else (self.comboBox_10.currentText()), + "filter_val": self.doubleSpinBox_11.value(), + "S_N":self.doubleSpinBox_21.value(), + "stddev": 1 if not self.checkBox_16.isChecked() else (self.doubleSpinBox_20.value()), + "bgmean": "NaN" if not self.checkBox_16.isChecked() else (self.doubleSpinBox_10.value()), + "lambdaThr":[] if not self.checkBox_36.isChecked() else self.comboBox_23.checkedItems(), + }) + + else: + if self.comboBox_24.count() > 1: # only Z + self.Cyto_Maskdata[filename]=[] + for n in range(self.comboBox_24.count()): + self.Cyto_Maskdata[filename].append({"Ttype":self.comboBox_21.currentText(), + "ValManual":int(self.spinBox_15.value()), + "compress": bool(self.checkBox_32.isChecked()), + "Kvalue": float(self.doubleSpinBox_23.value()), + "objSize":"NaN" if not self.checkBox_34.isChecked() else (self.spinBox_18.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_35.isChecked() else (self.doubleSpinBox_22.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_37.isChecked()), + "shape": self.comboBox_22.currentText(), + "dim1":int(self.spinBox_17.value()), #shpae dim1 + "dim2":int(self.spinBox_16.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_10.currentText() == "No Filter" else (self.comboBox_10.currentText()), + "filter_val": self.doubleSpinBox_11.value(), + "S_N":self.doubleSpinBox_21.value(), + "stddev": 1 if not self.checkBox_16.isChecked() else (self.doubleSpinBox_20.value()), + "bgmean": "NaN" if not self.checkBox_16.isChecked() else (self.doubleSpinBox_10.value()), + "lambdaThr":[] if not self.checkBox_36.isChecked() else self.comboBox_23.checkedItems(), + }) + else: # only 3dim + self.Cyto_Maskdata[filename]={"Ttype":self.comboBox_21.currentText(), + "ValManual":int(self.spinBox_15.value()), + "compress": bool(self.checkBox_32.isChecked()), + "Kvalue": float(self.doubleSpinBox_23.value()), + "objSize":"NaN" if not self.checkBox_34.isChecked() else (self.spinBox_18.value()), #removeobjet size + "holesSize":"NaN" if not self.checkBox_35.isChecked() else (self.doubleSpinBox_22.value()), #dilate hole size + "pxlSize":self.Metadata[filename]['Pixelsize'], + "dilate": bool(self.checkBox_37.isChecked()), + "shape": self.comboBox_22.currentText(), + "dim1":int(self.spinBox_17.value()), #shpae dim1 + "dim2":int(self.spinBox_16.value()), #shpae dim2 + "PixelDepth":self.Metadata[filename]['BitDepth'], + "filter_type":"No Filter" if self.comboBox_10.currentText() == "No Filter" else (self.comboBox_10.currentText()), + "filter_val": self.doubleSpinBox_11.value(), + "S_N":self.doubleSpinBox_21.value(), + "stddev": 1 if not self.checkBox_16.isChecked() else (self.doubleSpinBox_20.value()), + "bgmean": "NaN" if not self.checkBox_16.isChecked() else (self.doubleSpinBox_10.value()), + "lambdaThr":[] if not self.checkBox_36.isChecked() else self.comboBox_23.checkedItems(), + } + + + def changeverticalScrollBar(self): + self.verticalScrollBar_2.setValue(self.verticalScrollBar.value()) + self.tableWidget_2.setCurrentCell(0,0) + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + if filename in self.ConnectSliders: + self.verticalScrollBar_3.setValue(self.verticalScrollBar.value()) + + + def changeverticalScrollBar_2(self): + self.verticalScrollBar.setValue(self.verticalScrollBar_2.value()) + self.tableWidget_2.setCurrentCell(0,0) + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + if filename in self.ConnectSliders: + self.verticalScrollBar_3.setValue(self.verticalScrollBar_2.value()) + + def changeverticalScrollBar_3(self): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + if filename in self.ConnectSliders: + self.verticalScrollBar.setValue(self.verticalScrollBar_3.value()) + self.tableWidget_2.setCurrentCell(0,0) + self.verticalScrollBar_2.setValue(self.verticalScrollBar_3.value()) + + def changehorzontalScrollBar(self): + + self.horizontalScrollBar_2.setValue(self.horizontalScrollBar.value()) + self.tableWidget_2.setCurrentCell(0,0) + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + if filename in self.ConnectSliders: + self.horizontalScrollBar_3.setValue(self.horizontalScrollBar.value()) + + def changehorzontalScrollBar_2(self): + self.horizontalScrollBar.setValue(self.horizontalScrollBar_2.value()) + self.tableWidget_2.setCurrentCell(0,0) + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + if filename in self.ConnectSliders: + self.horizontalScrollBar_3.setValue(self.horizontalScrollBar_2.value()) + + def changehorzontalScrollBar_3(self): + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + if filename in self.ConnectSliders: + self.horizontalScrollBar.setValue(self.horizontalScrollBar_3.value()) + self.tableWidget_2.setCurrentCell(0,0) + self.horizontalScrollBar_2.setValue(self.horizontalScrollBar_3.value()) + + def updatePlots(self): + if self.tableWidget.currentRow() !=-1: + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + + if self.tableWidget.item(self.tableWidget.currentRow(),0) != [] and filename in self.key: + if self.key[filename]=="Zstack": + if filename in self.GPImage: + self.verticalScrollBar.setEnabled(True) + self.verticalScrollBar.setRange(0,len(self.GPImage[filename])-1) + self.horizontalScrollBar.setEnabled(False) + if self.nobjects[filename][0] != 0: + self.verticalScrollBar_2.setEnabled(True) + self.verticalScrollBar_2.setRange(0,len(self.GPImage[filename])-1) + self.horizontalScrollBar_2.setEnabled(False) + + self.verticalScrollBar_3.setEnabled(True) + self.verticalScrollBar_3.setRange(0,len(self.RawImages[filename])-1) + self.horizontalScrollBar_3.setEnabled(False) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0][0])-1) + + elif self.key[filename]=="Tstack": + if filename in self.GPImage: + self.horizontalScrollBar.setEnabled(True) + self.horizontalScrollBar.setRange(0,len(self.GPImage[filename])-1) + self.verticalScrollBar.setEnabled(False) + if self.nobjects[filename][0] != 0: + self.horizontalScrollBar_2.setEnabled(True) + self.horizontalScrollBar_2.setRange(0,len(self.GPImage[filename])-1) + self.verticalScrollBar_2.setEnabled(False) + + self.horizontalScrollBar_3.setEnabled(True) + self.horizontalScrollBar_3.setRange(0,len(self.RawImages[filename])-1) + self.verticalScrollBar_3.setEnabled(False) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0][0])-1) + + elif self.key[filename]=="TZstack": + if filename in self.GPImage: + self.horizontalScrollBar.setEnabled(True) + self.horizontalScrollBar.setRange(0,len(self.GPImage[filename])-1) + self.verticalScrollBar.setEnabled(True) + self.verticalScrollBar.setRange(0,len(self.GPImage[filename][0])-1) + if self.nobjects[filename][0][0] != 0: + self.horizontalScrollBar_2.setEnabled(True) + self.horizontalScrollBar_2.setRange(0,len(self.GPImage[filename])-1) + self.verticalScrollBar_2.setEnabled(True) + self.verticalScrollBar_2.setRange(0,len(self.GPImage[filename][0])-1) + + self.horizontalScrollBar_3.setEnabled(True) + self.horizontalScrollBar_3.setRange(0,len(self.RawImages[filename])-1) + self.verticalScrollBar_3.setEnabled(True) + self.verticalScrollBar_3.setRange(0,len(self.RawImages[filename][0])-1) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0][0][0])-1) + + else: + self.verticalScrollBar.setEnabled(False) + self.verticalScrollBar_2.setEnabled(False) + self.verticalScrollBar_3.setEnabled(False) + self.horizontalScrollBar.setEnabled(False) + self.horizontalScrollBar_2.setEnabled(False) + self.horizontalScrollBar_3.setEnabled(False) + self.horizontalScrollBar_4.setEnabled(True) + self.horizontalScrollBar_4.setRange(0,len(self.RawImages[filename][0][0])-1) + + + if self.tabWidget_2.currentIndex() == 0 and filename in self.RawImages: + self.plot_RawImage(self.RawImages[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 0 and filename in self.Masks: + self.plot_Mask(self.Masks[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 0 and filename in self.Cyto_Masks: + self.plot_Cyto_Mask(self.Cyto_Masks[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.GPImage: + self.plot_GPImage(self.GPImage[filename],self.key[filename]) + self.Update_Stats_FullImage(self.FullImage_Parameters[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.Cyto_GPImage: + self.plot_Cyto_GPImage(self.Cyto_GPImage[filename],self.key[filename]) + self.Update_Stats_FullImage_cyto(self.FullImage_Parameters_cyto[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.GPImage: #GP Histogramm + self.plot_GPHistogramm(self.GPImage[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.Cyto_GPImage: #GP Histogramm + self.plot_Cyto_GPHistogramm(self.Cyto_GPImage[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.GPPhasor_polar_all: #Phasor + self.plot_GPPhasor(self.GPPhasor_polar_all[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.Cyto_GPPhasor_polar_all: #Phasor + self.plot_Cyto_GPPhasor(self.Cyto_GPPhasor_polar_all[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.Intensities: #Intensities Histogramm + self.plot_IntesitieDist(self.Intensities[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 1 and filename in self.Cyto_Intensities: #Intensities Histogramm + self.plot_Cyto_IntesitieDist(self.Cyto_Intensities[filename],self.key[filename]) + if self.tabWidget_2.currentIndex() == 2 and filename in self.nobjects: + if self.key[filename] == "3dim": + if self.nobjects[filename] != 0: + self.tableWidget_2.setRowCount(self.nobjects[filename]) + row=0 + for i in range(self.nobjects[filename]): + self.tableWidget_2.setItem(row, 0, QtWidgets.QTableWidgetItem(str(i+1))) + row=row+1 + self.tableWidget_2.setHorizontalHeaderItem(0,QtWidgets.QTableWidgetItem("Object Nr.")) + self.plot_GPImage_Object(self.GPImage[filename],self.key[filename],self.Object_Coordinates[filename]) + if filename in self.Cyto_Image: + self.plot_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.key[filename],self.Object_Coordinates[filename]) + else: + self.tableWidget_2.setRowCount(0) + self.plot_GPImage_Object([],[],[]) + self.plot_Cyto_GPImage_Object([],[],[]) + self.plot_GPHistogramm_Object([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_GPImageZoom_Object([],[]) + self.Update_Stats_oject_membrane([],[],[]) + self.plot_Membrane_Segment_Object([],[]) + self.plot_IntesitieDist_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_GPPhasor_Object([],[],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + self.plot_GProfile_Object([],[]) + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_CytoLineProfile([],[]) + self.tableWidget_2.clear() + + elif self.key[filename] == "Zstack": + if self.nobjects[filename][0] != 0: + self.tableWidget_2.setRowCount(self.nobjects[filename][self.verticalScrollBar_2.value()]) + row=0 + for i in range(self.nobjects[filename][self.verticalScrollBar_2.value()]): + self.tableWidget_2.setItem(row, 0, QtWidgets.QTableWidgetItem(str(i+1))) + row=row+1 + self.tableWidget_2.setHorizontalHeaderItem(0,QtWidgets.QTableWidgetItem("Object Nr.")) + self.plot_GPImage_Object(self.GPImage[filename],self.key[filename],self.Object_Coordinates[filename][self.verticalScrollBar_2.value()]) + if filename in self.Cyto_Image: + self.plot_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.key[filename],self.Object_Coordinates[filename][self.verticalScrollBar_2.value()]) + else: + self.tableWidget_2.setRowCount(0) + self.plot_GPImage_Object([],[],[]) + self.plot_Cyto_GPImage_Object([],[],[]) + self.plot_GPHistogramm_Object([],[]) + self.plot_GPImageZoom_Object([],[]) + self.Update_Stats_oject_membrane([],[],[]) + self.plot_Membrane_Segment_Object([],[]) + self.plot_IntesitieDist_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_GPPhasor_Object([],[],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + self.plot_GProfile_Object([],[]) + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_CytoLineProfile([],[]) + self.tableWidget_2.clear() + + elif self.key[filename] == "Tstack": + if self.nobjects[filename][0] != 0: + self.tableWidget_2.setRowCount(self.nobjects[filename][self.horizontalScrollBar_2.value()]) + row=0 + for i in range(self.nobjects[filename][self.horizontalScrollBar_2.value()]): + self.tableWidget_2.setItem(row, 0, QtWidgets.QTableWidgetItem(str(i+1))) + row=row+1 + self.tableWidget_2.setHorizontalHeaderItem(0,QtWidgets.QTableWidgetItem("Object Nr.")) + self.plot_GPImage_Object(self.GPImage[filename],self.key[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()]) + if filename in self.Cyto_Image: + self.plot_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.key[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()]) + else: + self.tableWidget_2.setRowCount(0) + self.plot_GPImage_Object([],[],[]) + self.plot_Cyto_GPImage_Object([],[],[]) + self.plot_GPHistogramm_Object([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_GPImageZoom_Object([],[]) + self.Update_Stats_oject_membrane([],[],[]) + self.plot_Membrane_Segment_Object([],[]) + self.plot_IntesitieDist_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_GPPhasor_Object([],[],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + self.plot_GProfile_Object([],[]) + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_CytoLineProfile([],[]) + self.tableWidget_2.clear() + + elif self.key[filename] == "TZstack": + if self.nobjects[filename][0][0] != 0: + self.tableWidget_2.setRowCount(self.nobjects[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()]) + row=0 + for i in range(self.nobjects[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()]): + self.tableWidget_2.setItem(row, 0, QtWidgets.QTableWidgetItem(str(i+1))) + row=row+1 + self.tableWidget_2.setHorizontalHeaderItem(0,QtWidgets.QTableWidgetItem("Object Nr.")) + self.plot_GPImage_Object(self.GPImage[filename],self.key[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()]) + if filename in self.Cyto_Image: + self.plot_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.key[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()]) + else: + self.tableWidget_2.setRowCount(0) + self.plot_GPImage_Object([],[],[]) + self.plot_Cyto_GPImage_Object([],[],[]) + self.plot_GPHistogramm_Object([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_GPImageZoom_Object([],[]) + self.Update_Stats_oject_membrane([],[],[]) + self.plot_Membrane_Segment_Object([],[]) + self.plot_IntesitieDist_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_GPPhasor_Object([],[],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + self.plot_GProfile_Object([],[]) + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_CytoLineProfile([],[]) + self.tableWidget_2.clear() + else: + self.tableWidget_2.setRowCount(0) + + else: + self.plot_RawImage([],[]) + self.plot_Mask([],[]) + self.plot_Cyto_Mask([],[]) + self.plot_GPImage([],[]) + self.plot_Cyto_GPImage([],[]) + self.Update_Stats_FullImage_cyto([],[]) + self.plot_GPHistogramm([],[]) + self.plot_Cyto_GPHistogramm([],[]) + self.plot_GPPhasor([],[]) + self.plot_IntesitieDist([],[]) + self.plot_GPImage_Object([],[],[]) + self.plot_Cyto_GPImage_Object([],[],[]) + self.plot_GPHistogramm_Object([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_GPImageZoom_Object([],[]) + self.Update_Stats_oject_membrane([],[],[]) + self.plot_Membrane_Segment_Object([],[]) + self.plot_IntesitieDist_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_GPPhasor_Object([],[],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + self.plot_GProfile_Object([],[]) + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_CytoLineProfile([],[]) + self.tableWidget_2.clear() + app.processEvents() + + def updatePlots_Objects(self): + if self.tableWidget_2.currentRow() != -1: + ObjectNr=self.tableWidget_2.item(self.tableWidget_2.currentRow(),0).text() + if self.tableWidget.currentItem() is not None: + filename=self.tableWidget.item(self.tableWidget.currentRow(),0).text() + if len(self.key) != 0: + if self.key[filename] == "3dim": + if ObjectNr !=0: + self.plot_update_GPImage_Object(self.GPImage[filename],self.Object_Coordinates[filename],ObjectNr,self.key[filename]) + self.plot_GPImageZoom_Object(self.GPImage_per_object[filename][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_membrane(self.Object_Parameters[filename][int(ObjectNr)-1],self.Object_Morphology[filename][int(ObjectNr)-1],self.key[filename]) + self.plot_Membrane_Segment_Object(self.MembraneSegments[filename][int(ObjectNr)-1],self.key[filename]) + self.plot_GPHistogramm_Object(self.GPImage_per_object[filename][int(ObjectNr)-1],self.key[filename]) + self.plot_IntesitieDist_Object(self.Intensities_per_object[filename][int(ObjectNr)-1],self.key[filename]) + self.plot_GPPhasor_Object(self.GPPhasor_polar_obj[filename],ObjectNr,self.key[filename]) + if len(self.Cytoprof[filename]) !=0: + self.horizontalScrollBar_5.setEnabled(True) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile(self.Cytoprof[filename][int(ObjectNr)-1],self.key[filename]) + else: + self.horizontalScrollBar_5.setEnabled(False) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile([],[]) + if len(self.Profile) !=0: + if filename in self.Profile and self.Profile: + self.plot_GProfile_Object(self.Profile[filename][int(ObjectNr)-1],self.key[filename]) + else: + self.plot_GProfile_Object([],[]) + if filename in self.Cyto_Image: + if len(self.Cyto_Image) != 0: + self.plot_update_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.Object_Coordinates[filename],ObjectNr,self.key[filename]) + self.plot_CytoObject(self.Cyto_Image[filename][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_cyto(self.Object_Parameters_cyto[filename][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPHistogramm_Object(self.Cyto_Image[filename][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_IntesitieDist_Object(self.Cyto_Intensities_per_object[filename][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPPhasor_Object(self.Cyto_GPPhasor_polar_obj[filename],ObjectNr,self.key[filename]) + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + + + elif self.key[filename] == "Zstack": + if len(self.nobjects[filename]) != 0: + self.plot_update_GPImage_Object(self.GPImage[filename],self.Object_Coordinates[filename][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + self.plot_GPHistogramm_Object(self.GPImage_per_object[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_GPImageZoom_Object(self.GPImage_per_object[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_membrane(self.Object_Parameters[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.Object_Morphology[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Membrane_Segment_Object(self.MembraneSegments[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_IntesitieDist_Object(self.Intensities_per_object[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_GPPhasor_Object(self.GPPhasor_polar_obj[filename][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + if len(self.Cytoprof[filename]) !=0: + self.horizontalScrollBar_5.setEnabled(True) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile(self.Cytoprof[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + else: + self.horizontalScrollBar_5.setEnabled(False) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile([],[]) + if len(self.Profile[filename]) !=0: + if filename in self.Profile: + self.plot_GProfile_Object(self.Profile[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + else: + self.plot_GProfile_Object([],[],[]) + if filename in self.Cyto_Image: + if len(self.Cyto_Image[filename]) != 0: + self.plot_update_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.Object_Coordinates[filename][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + self.plot_CytoObject(self.Cyto_Image[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_cyto(self.Object_Parameters_cyto[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPHistogramm_Object(self.Cyto_Image[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_IntesitieDist_Object(self.Cyto_Intensities_per_object[filename][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPPhasor_Object(self.Cyto_GPPhasor_polar_obj[filename][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + + elif self.key[filename] == "Tstack": + if len(self.nobjects[filename]) != 0: + self.plot_update_GPImage_Object(self.GPImage[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()],ObjectNr,self.key[filename]) + self.plot_GPHistogramm_Object(self.GPImage_per_object[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_GPImageZoom_Object(self.GPImage_per_object[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_membrane(self.Object_Parameters[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.Object_Morphology[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Membrane_Segment_Object(self.MembraneSegments[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_IntesitieDist_Object(self.Intensities_per_object[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_GPPhasor_Object(self.GPPhasor_polar_obj[filename][self.horizontalScrollBar_2.value()],ObjectNr,self.key[filename]) + if len(self.Cytoprof[filename]) !=0: + self.horizontalScrollBar_5.setEnabled(True) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile(self.Cytoprof[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + else: + self.horizontalScrollBar_5.setEnabled(False) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile([],[]) + if len(self.Profile[filename]) !=0: + if filename in self.Profile: + self.plot_GProfile_Object(self.Profile[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + else: + self.plot_GProfile_Object([],[]) + if filename in self.Cyto_Image: + if len(self.Cyto_Image[filename]) != 0: + self.plot_update_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()],ObjectNr,self.key[filename]) + self.plot_CytoObject(self.Cyto_Image[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_cyto(self.Object_Parameters_cyto[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPHistogramm_Object(self.Cyto_Image[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_IntesitieDist_Object(self.Cyto_Intensities_per_object[filename][self.horizontalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPPhasor_Object(self.Cyto_GPPhasor_polar_obj[filename][self.horizontalScrollBar_2.value()],ObjectNr,self.key[filename]) + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + + elif self.key[filename] == "TZstack": + if len(self.nobjects[filename]) != 0: + self.plot_update_GPImage_Object(self.GPImage[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + self.plot_GPHistogramm_Object(self.GPImage_per_object[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_GPImageZoom_Object(self.GPImage_per_object[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_membrane(self.Object_Parameters[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.Object_Morphology[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Membrane_Segment_Object(self.MembraneSegments[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_IntesitieDist_Object(self.Intensities_per_object[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_GPPhasor_Object(self.GPPhasor_polar_obj[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + if len(self.Cytoprof[filename]) !=0: + self.horizontalScrollBar_5.setEnabled(True) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile(self.Cytoprof[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + else: + self.horizontalScrollBar_5.setEnabled(False) + self.horizontalScrollBar_5.setRange(0,self.dims[filename][len(self.dims[filename])-1]-1) + self.plot_CytoLineProfile([],[]) + + if len(self.Profile[filename]) !=0: + if filename in self.Profile: + self.plot_GProfile_Object(self.Profile[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + else: + self.plot_GProfile_Object([],[]) + if filename in self.Cyto_Image: + if len(self.Cyto_Image[filename][0]) != 0: + self.plot_update_Cyto_GPImage_Object(self.Cyto_GPImage[filename],self.Object_Coordinates[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + self.plot_CytoObject(self.Cyto_Image[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.Update_Stats_oject_cyto(self.Object_Parameters_cyto[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPHistogramm_Object(self.Cyto_Image[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_IntesitieDist_Object(self.Cyto_Intensities_per_object[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()][int(ObjectNr)-1],self.key[filename]) + self.plot_Cyto_GPPhasor_Object(self.Cyto_GPPhasor_polar_obj[filename][self.horizontalScrollBar_2.value()][self.verticalScrollBar_2.value()],ObjectNr,self.key[filename]) + + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + else: + self.plot_CytoObject([],[]) + self.Update_Stats_oject_cyto([],[]) + self.plot_Cyto_GPHistogramm_Object([],[]) + self.plot_Cyto_IntesitieDist_Object([],[]) + self.plot_Cyto_GPPhasor_Object([],[],[]) + + + app.processEvents() + + def activate_rectangle_selector(self): + ax = self.matplotlibwidget.axis # Assuming this is your Matplotlib axis + self.rectangle_selector = RectangleSelector(ax, self.on_rectangle_select, + useblit=True, button=[1], + minspanx=5, minspany=5, + spancoords='pixels', interactive=True) + + self.matplotlibwidget.canvas.draw_idle() + + def on_rectangle_select(self, eclick, erelease): + if self.matplotlibwidget.axis.images: + # Get the first (and presumably only) AxesImage + ax_image = self.matplotlibwidget.axis.images[0] + image_data = ax_image.get_array().data # Get the numpy array of the image data + + # Extract coordinates from the event clicks + x1, y1 = int(eclick.xdata), int(eclick.ydata) + x2, y2 = int(erelease.xdata), int(erelease.ydata) + + # Ensure x1 < x2 and y1 < y2 for slicing + x1, x2 = sorted([x1, x2]) + y1, y2 = sorted([y1, y2]) + + # Extract the selected region from the image data + selected_region = image_data[y1:y2, x1:x2] + + # Calculate mean and standard deviation + mean_val = np.round(np.mean(selected_region),2) + median_val = np.round(np.median(selected_region),2) + std_val = np.round(np.std(selected_region),2) + min_val = np.round(np.min(selected_region),2) + max_val = np.round(np.max(selected_region),2) + + self.label_84.setText(str(mean_val)) + self.doubleSpinBox_9.setValue(mean_val) + self.doubleSpinBox_10.setValue(mean_val) + self.label_86.setText(str(median_val)) + self.label_85.setText(str(std_val)) + self.doubleSpinBox_7.setValue(std_val) + self.doubleSpinBox_20.setValue(std_val) + self.label_87.setText(str(min_val)) + self.label_88.setText(str(max_val)) + else: + print("No image found in the plot.") + self.plainTextEdit_1.appendPlainText(time.asctime(time.localtime())) + self.plainTextEdit_1.appendPlainText("No image found in the plot.") + + def plot_RawImage(self, img, key, vmin=None, vmax=None): + # Raw Image + self.matplotlibwidget.axis.clear() + ax = self.matplotlibwidget.axis + ax.clear() + + if key != []: + if key == "Zstack": + c = self.horizontalScrollBar_4.value() + z = self.verticalScrollBar_3.value() + img_slice = img[z,:,:,c] + elif key == "Tstack": + c = self.horizontalScrollBar_4.value() + t = self.horizontalScrollBar_3.value() + img_slice = img[t,:,:,c] + elif key == "TZstack": + c = self.horizontalScrollBar_4.value() + t = self.horizontalScrollBar_3.value() + z = self.verticalScrollBar_3.value() + img_slice = img[t,z,:,:,c] + elif key == "3dim": + n = self.horizontalScrollBar_4.value() + img_slice = img[:,:,n] + else: + img_slice = None + + if self.checkBox_33.checkState(): + if img_slice is not None: + if vmax is None: + vmax = np.percentile(img_slice, 99) # Automatic calculation of vmax + if vmin is None: + vmin = np.percentile(img_slice, 1) # Automatic calculation of vmin if needed + + isns.imgplot(img_slice, ax=ax, cmap="gray", cbar=False, origin='upper', vmin=vmin, vmax=vmax) + else: + isns.imgplot(img_slice, ax=ax, cmap="gray", cbar=False, origin='upper') + + self.matplotlibwidget.canvas.draw_idle() + else: + ax.clear() + self.matplotlibwidget.canvas.draw_idle() + + + def plot_Mask(self,img,key): #Mask Image + self.matplotlibwidget_2.axis.clear() + + ax=self.matplotlibwidget_2.axis + ax.clear() + if key !=[]: + if key == "Zstack": + z=self.verticalScrollBar_3.value() + isns.imgplot(img[z],ax=ax,cmap="binary",cbar=False,origin='upper') + + if key == "Tstack": + t=self.horizontalScrollBar_3.value() + isns.imgplot(img[t],ax=ax,cmap="binary",cbar=False,origin='upper') + + if key == "TZstack": + t=self.horizontalScrollBar_3.value() + z=self.verticalScrollBar_3.value() + isns.imgplot(img[t][z],ax=ax,cmap="binary",cbar=False,origin='upper') + if key == "3dim": + isns.imgplot(img,ax=ax,cmap="binary",cbar=False,origin='upper') + + self.matplotlibwidget_2.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_2.canvas.draw_idle() + + def plot_Cyto_Mask(self,img,key): #Mask Image + self.matplotlibwidget_18.axis.clear() + + ax=self.matplotlibwidget_18.axis + ax.clear() + if key !=[] and ((isinstance(img, np.ndarray) and img.size > 0) or (isinstance(img, list) and len(img) > 0)): + if key == "Zstack": + z=self.verticalScrollBar_3.value() + isns.imgplot(img[z],ax=ax,cmap="binary",cbar=False,origin='upper') + + if key == "Tstack": + t=self.horizontalScrollBar_3.value() + isns.imgplot(img[t],ax=ax,cmap="binary",cbar=False,origin='upper') + + if key == "TZstack": + t=self.horizontalScrollBar_3.value() + z=self.verticalScrollBar_3.value() + isns.imgplot(img[t][z],ax=ax,cmap="binary",cbar=False,origin='upper') + if key == "3dim": + isns.imgplot(img,ax=ax,cmap="binary",cbar=False,origin='upper') + + self.matplotlibwidget_18.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_18.canvas.draw_idle() + + def Update_Stats_FullImage(self,params,key): + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + if params[n]!=[]: + self.label_76.setText(str(params[n][0])) # rejected pixels + self.label_73.setText(str(params[n][1])) #median + self.label_71.setText(str(params[n][2])) #std + self.label_69.setText(str(params[n][3])) + if key == "Tstack": + n=self.horizontalScrollBar.value() + if params[n]!=[]: + self.label_76.setText(str(params[n][0])) # rejected pixels + self.label_73.setText(str(params[n][1])) #median + self.label_71.setText(str(params[n][2])) #std + self.label_69.setText(str(params[n][3])) + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + if params[n][m] !=[]: + self.label_76.setText(str(params[n][m][0])) # rejected pixels + self.label_73.setText(str(params[n][m][1])) #median + self.label_71.setText(str(params[n][m][2])) #std + self.label_69.setText(str(params[n][m][3])) + + if key == "3dim" and params!=[]: + self.label_76.setText(str(params[0])) # rejected pixels + self.label_73.setText(str(params[1])) #median + self.label_71.setText(str(params[2])) #std + self.label_69.setText(str(params[3])) # normal intens??? + + def Update_Stats_FullImage_cyto(self,params,key): + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + if params[n]!=[]: + self.label_77.setText(str(params[n][0])) # rejected pixels + self.label_75.setText(str(params[n][1])) #median + self.label_78.setText(str(params[n][2])) #std + self.label_79.setText(str(params[n][3])) + if key == "Tstack": + n=self.horizontalScrollBar.value() + if params[n]!=[]: + self.label_77.setText(str(params[n][0])) # rejected pixels + self.label_75.setText(str(params[n][1])) #median + self.label_78.setText(str(params[n][2])) #std + self.label_79.setText(str(params[n][3])) + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + if params[n][m]!=[]: + self.label_77.setText(str(params[n][m][0])) # rejected pixels + self.label_75.setText(str(params[n][m][1])) #median + self.label_78.setText(str(params[n][m][2])) #std + self.label_79.setText(str(params[n][m][3])) + + if key == "3dim" and params!=[]: + self.label_77.setText(str(params[0])) # rejected pixels + self.label_75.setText(str(params[1])) #median + self.label_78.setText(str(params[2])) #std + self.label_79.setText(str(params[3])) # normal intens??? + + def Update_Stats_oject_membrane(self,params,morphology,key): + if key !=[] and params !=[] and morphology!=[]: + self.label_63.setText(str(params[0])) # rejected pixels + self.label_60.setText(str(params[1])) #median + self.label_62.setText(str(params[2])) #std + self.label_64.setText(str(params[3])) + + self.label_66.setText(str(morphology[0])) + self.label_67.setText(str(morphology[1])) + self.label_90.setText(str(morphology[2])) + else: + self.label_63.setText(str("NaN")) # rejected pixels + self.label_60.setText(str("NaN")) #median + self.label_62.setText(str("NaN")) #std + self.label_64.setText(str("NaN")) + + self.label_66.setText(str("NaN")) + self.label_67.setText(str("NaN")) + self.label_90.setText(str("NaN")) + + + def Update_Stats_oject_cyto(self,params,key): + if key !=[] and params !=[]: + self.label_138.setText(str(params[0])) # rejected pixels + self.label_140.setText(str(params[1])) #median + self.label_139.setText(str(params[2])) #std + self.label_137.setText(str(params[3])) + else: + self.label_138.setText(str("NaN")) # rejected pixels + self.label_140.setText(str("NaN")) #median + self.label_139.setText(str("NaN")) #std + self.label_137.setText(str("NaN")) + + + def plot_GPImage(self,img,key): # GP image + self.matplotlibwidget_3.figure.clf() + self.matplotlibwidget_3.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_3.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_3.axis = ax + ax=self.matplotlibwidget_3.axis + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n]) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + + if key == "Tstack": + n=self.horizontalScrollBar.value() + img1=copy.deepcopy(img[n]) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n][m]) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + + if key == "3dim": + img1=copy.deepcopy(img) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + + fig=self.matplotlibwidget_3.figure + fig.tight_layout() + self.matplotlibwidget_3.canvas.draw_idle() + + else: + self.matplotlibwidget_3.figure.clf() + self.matplotlibwidget_3.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_3.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_3.axis = ax + self.matplotlibwidget_3.canvas.draw_idle() + + def plot_Cyto_GPImage(self,img,key): # GP image + + self.matplotlibwidget_19.figure.clf() + self.matplotlibwidget_19.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_19.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_19.axis = ax + ax=self.matplotlibwidget_19.axis + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n]) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + + if key == "Tstack": + n=self.horizontalScrollBar.value() + img1=copy.deepcopy(img[n]) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n][m]) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + + if key == "3dim": + img1=copy.deepcopy(img) + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + + fig=self.matplotlibwidget_19.figure + fig.tight_layout() + self.matplotlibwidget_19.canvas.draw_idle() + + else: + self.matplotlibwidget_19.figure.clf() + self.matplotlibwidget_19.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_19.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_19.axis = ax + self.matplotlibwidget_19.canvas.draw_idle() + + def plot_GPHistogramm(self,img,key): # GP Histogramm + self.matplotlibwidget_4.axis.clear() + + ax=self.matplotlibwidget_4.axis + ax.clear() + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n]) + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + if key == "Tstack": + n=self.horizontalScrollBar.value() + img1=copy.deepcopy(img[n]) + + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n][m]) + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + if key == "3dim": + img1=copy.deepcopy(img) + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + sns.histplot(data=df, x="GP-Value",ax=ax,bins=np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+self.doubleSpinBox_4.value(),self.doubleSpinBox_4.value())) + ax.set_xlabel(r'$\beta$-Value') + ax.set_ylabel('Counts') + fig=self.matplotlibwidget_4.figure + fig.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.1, wspace=0.2, hspace=0.2) + fig.tight_layout() + + self.matplotlibwidget_4.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_4.canvas.draw_idle() + + def plot_Cyto_GPHistogramm(self,img,key): # GP Histogramm + self.matplotlibwidget_20.axis.clear() + + ax=self.matplotlibwidget_20.axis + ax.clear() + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n]) + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + if key == "Tstack": + n=self.horizontalScrollBar.value() + img1=copy.deepcopy(img[n]) + + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + img1=copy.deepcopy(img[n][m]) + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + if key == "3dim": + img1=copy.deepcopy(img) + flattenedImage=img1.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + + + sns.histplot(data=df, x="GP-Value",ax=ax,bins=np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+self.doubleSpinBox_19.value(),self.doubleSpinBox_19.value())) + ax.set_xlabel(r'$\beta$-Value') + ax.set_ylabel('Counts') + + fig=self.matplotlibwidget_20.figure + fig.tight_layout() + + self.matplotlibwidget_20.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_4.canvas.draw_idle() + + def plot_GPPhasor(self,phase,key): # GP Phasor + self.matplotlibwidget_6.axis.clear() + ax=self.matplotlibwidget_6.axis + ax.clear() + + if key !=[] and isinstance(phase[0], np.ndarray): + if key == "Zstack": + n=self.verticalScrollBar.value() + phase1=phase[n] + + if phase1[0].ndim == 2: + amp=phase1[0][:,0] + ph=phase1[1][:,0] + + if phase1[0].ndim == 1: + amp=phase1[0][:] + ph=phase1[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + + if key == "Tstack": + n=self.horizontalScrollBar.value() + phase1=phase[n] + + if phase1[0].ndim == 2: + amp=phase1[0][:,0] + ph=phase1[1][:,0] + + if phase1[0].ndim == 1: + amp=phase1[0][:] + ph=phase1[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + + phase1=phase[n][m] + if phase1[0].ndim == 2: + amp=phase1[0][:,0] + ph=phase1[1][:,0] + + if phase1[0].ndim == 1: + amp=phase1[0][:] + ph=phase1[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + + if key == "3dim": + if phase[0].ndim == 2: + amp=phase[0][:,0] + ph=phase[1][:,0] + + if phase[0].ndim == 1: + amp=phase[0][:] + ph=phase[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + #df = pd.DataFrame({'amplitude': np.sqrt(np.square(x)+np.square(y)), 'phase': np.arctan(np.divide(y,x))}) + + + ax.grid(False) + rbins = np.linspace(0,df["amplitude"].max(), 100) + abins = np.linspace(0,2*np.pi, 360) + hist, _, _ = np.histogram2d(df["phase"], df["amplitude"], bins=(abins, rbins)) + A, R = np.meshgrid(abins, rbins) + ax.pcolormesh(A, R, hist.T, cmap="YlOrRd") + ax.grid(True) + ax.set_rlabel_position(0) + + fig=self.matplotlibwidget_6.figure + fig.tight_layout() + + self.matplotlibwidget_6.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_6.canvas.draw_idle() + + def plot_Cyto_GPPhasor(self,phase,key): # GP Phasor + self.matplotlibwidget_22.axis.clear() + ax=self.matplotlibwidget_22.axis + ax.clear() + + if key !=[] and isinstance(phase[0], np.ndarray): + if key == "Zstack": + n=self.verticalScrollBar.value() + phase1=phase[n] + + if phase1[0].ndim == 2: + amp=phase1[0][:,0] + ph=phase1[1][:,0] + + if phase1[0].ndim == 1: + amp=phase1[0][:] + ph=phase1[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + + if key == "Tstack": + n=self.horizontalScrollBar.value() + phase1=phase[n] + + if phase1[0].ndim == 2: + amp=phase1[0][:,0] + ph=phase1[1][:,0] + + if phase1[0].ndim == 1: + amp=phase1[0][:] + ph=phase1[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + + phase1=phase[n][m] + if phase1[0].ndim == 2: + amp=phase1[0][:,0] + ph=phase1[1][:,0] + + if phase1[0].ndim == 1: + amp=phase1[0][:] + ph=phase1[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + + if key == "3dim": + if phase[0].ndim == 2: + amp=phase[0][:,0] + ph=phase[1][:,0] + + if phase[0].ndim == 1: + amp=phase[0][:] + ph=phase[1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': amp, 'phase': ph}) + #df = pd.DataFrame({'amplitude': np.sqrt(np.square(x)+np.square(y)), 'phase': np.arctan(np.divide(y,x))}) + + + ax.grid(False) + rbins = np.linspace(0,df["amplitude"].max(), 100) + abins = np.linspace(0,2*np.pi, 360) + hist, _, _ = np.histogram2d(df["phase"], df["amplitude"], bins=(abins, rbins)) + A, R = np.meshgrid(abins, rbins) + ax.pcolormesh(A, R, hist.T, cmap="YlOrRd") + ax.grid(True) + ax.set_rlabel_position(0) + + fig=self.matplotlibwidget_22.figure + fig.tight_layout() + + self.matplotlibwidget_22.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_6.canvas.draw_idle() + + def plot_IntesitieDist(self,img,key): # GP Phasor + self.matplotlibwidget_7.axis.clear() + ax=self.matplotlibwidget_7.axis + ax.clear() + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + img1=img[n] + df = pd.DataFrame({"wavelength": img1[0],"intensites":img1[1]}) + + if key == "Tstack": + n=self.horizontalScrollBar.value() + img1=img[n] + df = pd.DataFrame({"wavelength": img1[0],"intensites":img1[1]}) + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + img1=img[n][m] + df = pd.DataFrame({"wavelength": img1[0],"intensites":img1[1]}) + + if key == "3dim": + df = pd.DataFrame({"wavelength": img[0],"intensites":img[1]}) + + sns.barplot(data=df, x="wavelength", y="intensites",hue="wavelength",ax=ax, palette="Reds",legend=False) + ax.xaxis.set_major_locator(FixedLocator(ax.get_xticks())) + ax.set_xticklabels(ax.get_xticklabels(),rotation=90) + ax.set_xlabel('Channels') + ax.set_ylabel('Normalized Intensities') + fig=self.matplotlibwidget_7.figure + fig.tight_layout() + self.matplotlibwidget_7.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_7.canvas.draw_idle() + + def plot_Cyto_IntesitieDist(self,img,key): # GP Phasor + self.matplotlibwidget_21.axis.clear() + ax=self.matplotlibwidget_21.axis + ax.clear() + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar.value() + img1=img[n] + df = pd.DataFrame({"wavelength": img1[0],"intensites":img1[1]}) + + if key == "Tstack": + n=self.horizontalScrollBar.value() + img1=img[n] + df = pd.DataFrame({"wavelength": img1[0],"intensites":img1[1]}) + + if key == "TZstack": + n=self.horizontalScrollBar.value() + m=self.verticalScrollBar.value() + img1=img[n][m] + df = pd.DataFrame({"wavelength": img1[0],"intensites":img1[1]}) + + if key == "3dim": + df = pd.DataFrame({"wavelength": img[0],"intensites":img[1]}) + + sns.barplot(data=df, x="wavelength", y="intensites",hue="wavelength",ax=ax, palette="Reds",legend=False) + ax.xaxis.set_major_locator(FixedLocator(ax.get_xticks())) + ax.set_xticklabels(ax.get_xticklabels(),rotation=90) + ax.set_xlabel('Channels') + ax.set_ylabel('Normalized Intesities') + fig=self.matplotlibwidget_21.figure + fig.tight_layout() + self.matplotlibwidget_21.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_7.canvas.draw_idle() + + def plot_GPImage_Object(self,img,key,Object_Coordinates): # GP image + self.matplotlibwidget_5.figure.clf() + self.matplotlibwidget_5.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_5.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_5.axis = ax + ax=self.matplotlibwidget_5.axis + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + if key == "Tstack": + n=self.horizontalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + if key == "TZstack": + n=self.horizontalScrollBar_2.value() + m=self.verticalScrollBar_2.value() + img1=img[n][m] + img1[img[n][m]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + + if key == "3dim": + img[img==2]=np.nan + isns.imgplot(img,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + + i=1 + for n in Object_Coordinates: + ax.text(n[1],n[0],i,verticalalignment='center',color="red") + i=i+1 + + fig=self.matplotlibwidget_5.figure + fig.tight_layout() + self.matplotlibwidget_5.canvas.draw_idle() + + else: + self.matplotlibwidget_5.figure.clf() + self.matplotlibwidget_5.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_5.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_5.axis = ax + self.matplotlibwidget_5.canvas.draw_idle() + + def plot_Cyto_GPImage_Object(self,img,key,Object_Coordinates): # GP image + self.matplotlibwidget_23.figure.clf() + self.matplotlibwidget_23.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_23.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_23.axis = ax + ax=self.matplotlibwidget_23.axis + + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + if key == "Tstack": + n=self.horizontalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + if key == "TZstack": + n=self.horizontalScrollBar_2.value() + m=self.verticalScrollBar_2.value() + img1=img[n][m] + img1[img[n][m]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + + if key == "3dim": + img[img==2]=np.nan + isns.imgplot(img,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + + i=1 + for n in Object_Coordinates: + ax.text(n[1],n[0],i,verticalalignment='center',color="red") + i=i+1 + + fig=self.matplotlibwidget_23.figure + fig.tight_layout() + + self.matplotlibwidget_23.canvas.draw_idle() + + else: + self.matplotlibwidget_23.figure.clf() + self.matplotlibwidget_23.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_23.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_23.axis = ax + self.matplotlibwidget_23.canvas.draw_idle() + + def plot_update_GPImage_Object(self,img,Object_Coordinates,ObjectNr,key): # GP image + self.matplotlibwidget_5.figure.clf() + self.matplotlibwidget_5.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_5.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_5.axis = ax + ax=self.matplotlibwidget_5.axis + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + if key == "Tstack": + n=self.horizontalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + if key == "TZstack": + n=self.horizontalScrollBar_2.value() + m=self.verticalScrollBar_2.value() + img1=img[n][m] + img1[img[n][m]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + if key == "3dim": + img[img==2]=np.nan + isns.imgplot(img,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + + i=1 + for n in Object_Coordinates: + if i != int(ObjectNr): + ax.text(n[1],n[0],i,verticalalignment='center',color="red") + i=i+1 + else: + ax.text(n[1],n[0],i,verticalalignment='center',color="yellow") + i=i+1 + + fig=self.matplotlibwidget_5.figure + fig.tight_layout() + + self.matplotlibwidget_5.canvas.draw_idle() + + else: + self.matplotlibwidget_5.figure.clf() + self.matplotlibwidget_5.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_5.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_5.axis = ax + self.matplotlibwidget_5.canvas.draw_idle() + + def plot_update_Cyto_GPImage_Object(self,img,Object_Coordinates,ObjectNr,key): # GP image + ax=self.matplotlibwidget_23.axis + self.matplotlibwidget_23.figure.clf() + self.matplotlibwidget_23.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_23.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_23.axis = ax + ax=self.matplotlibwidget_23.axis + if key !=[]: + if key == "Zstack": + n=self.verticalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + if key == "Tstack": + n=self.horizontalScrollBar_2.value() + img1=img[n] + img1[img[n]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + if key == "TZstack": + n=self.horizontalScrollBar_2.value() + m=self.verticalScrollBar_2.value() + img1=img[n][m] + img1[img[n][m]==2]=np.nan + isns.imgplot(img1,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + if key == "3dim": + img[img==2]=np.nan + isns.imgplot(img,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + + i=1 + for n in Object_Coordinates: + if i != int(ObjectNr): + ax.text(n[1],n[0],i,verticalalignment='center',color="red") + i=i+1 + else: + ax.text(n[1],n[0],i,verticalalignment='center',color="yellow") + i=i+1 + + fig=self.matplotlibwidget_23.figure + fig.tight_layout() + + self.matplotlibwidget_23.canvas.draw_idle() + + else: + self.matplotlibwidget_23.figure.clf() + self.matplotlibwidget_23.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_23.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_23.axis = ax + self.matplotlibwidget_23.canvas.draw_idle() + + def plot_GPImageZoom_Object(self,GPImage_per_object,key): # GP Histogramm object + ax=self.matplotlibwidget_8.axis + self.matplotlibwidget_8.figure.clf() + self.matplotlibwidget_8.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_8.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_8.axis = ax + ax=self.matplotlibwidget_8.axis + #GPImage_per_object + if key !=[]: + img=GPImage_per_object + self.matplotlibwidget_8.axis.clear() + ax.set_facecolor("#2D2D2D") + isns.imgplot(img,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_6.value(), vmin=self.doubleSpinBox_5.value(),cbar_ticks =np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8,abs(abs(self.doubleSpinBox_5.value())+abs(self.doubleSpinBox_6.value()))/8),origin='upper') + fig=self.matplotlibwidget_8.figure + fig.tight_layout() + self.matplotlibwidget_8.canvas.draw_idle() + else: + self.matplotlibwidget_8.figure.clf() + self.matplotlibwidget_8.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_8.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_8.axis = ax + self.matplotlibwidget_8.canvas.draw_idle() + + def plot_Membrane_Segment_Object(self,SegmentImage,key): # GP Histogramm object + ax=self.matplotlibwidget_24.axis + self.matplotlibwidget_24.figure.clf() + self.matplotlibwidget_24.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_24.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_24.axis = ax + ax=self.matplotlibwidget_24.axis + + if SegmentImage: + if key !=[] and ((isinstance(SegmentImage[0], np.ndarray) and SegmentImage[0].size > 0) or (isinstance(SegmentImage[0], list) and len(SegmentImage[0]) > 0)): + img=SegmentImage[0] + + unique_segments = np.unique(img) + max_segment = unique_segments.max() + # Create a list of colors for the colormap, one for each segment, adjusted for the offset in color_map + colors = [color_map[(segment + 1) % len(color_map)] for segment in range(max_segment + 1)] + + custom_cmap = ListedColormap(colors) + + ax.set_facecolor("#2D2D2D") + isns.imgplot(img,cmap=custom_cmap,ax=ax,cbar=False,interpolation='nearest') + fig=self.matplotlibwidget_24.figure + fig.tight_layout() + self.matplotlibwidget_24.canvas.draw_idle() + else: + self.matplotlibwidget_24.figure.clf() + self.matplotlibwidget_24.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_12.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_24.axis = ax + self.matplotlibwidget_24.canvas.draw_idle() + else: + self.matplotlibwidget_24.figure.clf() + self.matplotlibwidget_24.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_12.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_24.axis = ax + self.matplotlibwidget_24.canvas.draw_idle() + + def plot_GPHistogramm_Object(self,GPImage_per_object,key): # GP Histogramm object + ax=self.matplotlibwidget_9.axis + if key !=[]: + img=GPImage_per_object + self.matplotlibwidget_9.axis.clear() + flattenedImage=img.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + sns.histplot(data=df, x="GP-Value",ax=ax,bins=np.arange(self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value()+self.doubleSpinBox_4.value(),self.doubleSpinBox_4.value())) + ax.set_xlabel(r'$\beta$-Value') + ax.set_ylabel('Counts') + fig=self.matplotlibwidget_9.figure + fig.tight_layout() + self.matplotlibwidget_9.canvas.draw_idle() + else: + ax.clear() + self.matplotlibwidget_9.canvas.draw_idle() + + def plot_IntesitieDist_Object(self,intensites,key): # GP Phasor + self.matplotlibwidget_10.axis.clear() + ax=self.matplotlibwidget_10.axis + if key !=[]: + df = pd.DataFrame({"wavelength": intensites[0],"intensites":intensites[1]}) + sns.barplot(data=df, x="wavelength", y="intensites",hue="wavelength",ax=ax, palette="Reds",legend=False) + ax.xaxis.set_major_locator(FixedLocator(ax.get_xticks())) + ax.set_xticklabels(ax.get_xticklabels(),rotation=90) + ax.set_xticklabels(ax.get_xticklabels(),rotation=90) + ax.set_xlabel('Channels') + ax.set_ylabel('Normalized Intensites') + fig=self.matplotlibwidget_10.figure + fig.tight_layout() + self.matplotlibwidget_10.canvas.draw_idle() + else: + ax.clear() + self.matplotlibwidget_10.canvas.draw_idle() + + def plot_GPPhasor_Object(self,phase,ObjectNr,key): # GP Phasor + self.matplotlibwidget_11.axis.clear() + ax=self.matplotlibwidget_11.axis + ax.clear() + if key !=[] and isinstance(phase[int(ObjectNr)-1][0], np.ndarray): + ph=phase[int(ObjectNr)-1][1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': phase[int(ObjectNr)-1][0][:], 'phase': ph}) + ax.grid(False) + rbins = np.linspace(0,df["amplitude"].max(), 100) + abins = np.linspace(0,2*np.pi, 360) + hist, _, _ = np.histogram2d(df["phase"], df["amplitude"], bins=(abins, rbins)) + A, R = np.meshgrid(abins, rbins) + ax.pcolormesh(A, R, hist.T, cmap="YlOrRd") + ax.grid(True) + ax.set_rlabel_position(0) + fig=self.matplotlibwidget_11.figure + fig.tight_layout() + self.matplotlibwidget_11.canvas.draw_idle() + else: + ax.clear() + self.matplotlibwidget_11.canvas.draw_idle() + + def plot_GProfile_Object(self,profile,key): + self.matplotlibwidget_12.figure.clf() + self.matplotlibwidget_12.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_12.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_12.axis = ax + ax=self.matplotlibwidget_12.axis + if key !=[] and profile: + if profile[0].shape[1] >= 5: + + df = pd.DataFrame({"x": profile[0][:,0],"P-Value":profile[0][:,3], "Segment": profile[0][:,4].astype(int)}) + sns.lineplot(data=df, x="x", y="P-Value",ax=ax,color=sns.color_palette("deep")[0]) + ax.set_ylabel(r'$\beta$-Value', color=sns.color_palette("deep")[0]) + + for segment in np.unique(df['Segment']): + # Adjust segment by +1 for color mapping, loop back to 1 if it exceeds the length of the color_map + adjusted_segment = segment % len(color_map)+1 + segment_indices = df[df['Segment'] == segment].index + if len(segment_indices) > 0: + ax.axvspan(df['x'].iloc[segment_indices[0]], df['x'].iloc[segment_indices[-1]], color=color_map[adjusted_segment], alpha=0.3) + + if profile[0].shape[1] > 5: + df1 = pd.DataFrame({"x": profile[0][:,0],"Colocalization":profile[0][:,5]}) + ax2 = ax.twinx() + sns.lineplot(data=df1, x="x", y="Colocalization",ax=ax2, color="red") + ax2.set_ylabel('Colocalization', color='red') + else: + df = pd.DataFrame({"x": profile[0][:,0],"Intensity":profile[0][:,2], "Segment": profile[0][:,3].astype(int)}) + sns.lineplot(data=df, x="x", y="Intensity",ax=ax,color=sns.color_palette("deep")[0]) + ax.set_ylabel('Intensity', color=sns.color_palette("deep")[0]) + + for segment in np.unique(df['Segment']): + # Adjust segment by +1 for color mapping, loop back to 1 if it exceeds the length of the color_map + adjusted_segment = segment % len(color_map)+1 + segment_indices = df[df['Segment'] == segment].index + if len(segment_indices) > 0: + ax.axvspan(df['x'].iloc[segment_indices[0]], df['x'].iloc[segment_indices[-1]], color=color_map[adjusted_segment], alpha=0.3) + + if profile[0].shape[1] > 4: + df1 = pd.DataFrame({"x": profile[0][:,0],"Colocalization":profile[0][:,5]}) + ax2 = ax.twinx() + sns.lineplot(data=df1, x="x", y="Colocalization",ax=ax2, color="red") + ax2.set_ylabel('Colocalization', color='red') + + + + ax.grid(which='both') + ax.set_xlim(left=0) + fig=self.matplotlibwidget_12.figure + fig.tight_layout() + self.matplotlibwidget_12.canvas.draw_idle() + else: + self.matplotlibwidget_12.figure.clf() + self.matplotlibwidget_12.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_12.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_12.axis = ax + self.matplotlibwidget_12.canvas.draw_idle() + + def plot_CytoObject(self,img,key): # GP Histogramm object + self.matplotlibwidget_14.figure.clf() + self.matplotlibwidget_14.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_14.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_14.axis = ax + ax=self.matplotlibwidget_14.axis + if key != [] and ((isinstance(img, np.ndarray) and img.size > 0) or (isinstance(img, list) and len(img) > 0)): + img=img + ax.set_facecolor("#2D2D2D") + #img[img==2]=np.nan + isns.imgplot(img,ax=ax,cmap="viridis",cbar=True,vmax =self.doubleSpinBox_18.value(), vmin=self.doubleSpinBox_17.value(),cbar_ticks =np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8,abs(abs(self.doubleSpinBox_17.value())+abs(self.doubleSpinBox_18.value()))/8),origin='upper') + fig=self.matplotlibwidget_14.figure + fig.tight_layout() + self.matplotlibwidget_14.canvas.draw_idle() + else: + self.matplotlibwidget_14.figure.clf() + self.matplotlibwidget_14.figure.patch.set_facecolor('#434343') + ax = self.matplotlibwidget_14.figure.add_subplot(111) + ax.set_facecolor('#2D2D2D') + self.matplotlibwidget_14.axis = ax + self.matplotlibwidget_14.canvas.draw_idle() + + def plot_CytoLineProfile(self,Cytoprof,key): # GP Histogramm object + ax=self.matplotlibwidget_13.axis + if key !=[] and Cytoprof and Cytoprof != [[]]: + img=Cytoprof[0][2][self.horizontalScrollBar_5.value(),:,:].T + self.matplotlibwidget_13.axis.clear() + ax.clear() + ax.set_facecolor("black") + isns.imgplot(img,ax=ax,cmap="YlGnBu_r",cbar=False) #origin='lower' + ax.set_aspect("auto") + fig=self.matplotlibwidget_13.figure + fig.tight_layout() + self.matplotlibwidget_13.canvas.draw_idle() + else: + ax.clear() + ax.set_facecolor("#2D2D2D") + self.matplotlibwidget_13.canvas.draw_idle() + + + def plot_Cyto_GPHistogramm_Object(self,GPImage_per_object,key): # GP Histogramm object + ax=self.matplotlibwidget_17.axis + if key !=[] and ((isinstance(GPImage_per_object, np.ndarray) and GPImage_per_object.size > 0) or (isinstance(GPImage_per_object, list) and len(GPImage_per_object) > 0)): + img=GPImage_per_object + self.matplotlibwidget_17.axis.clear() + flattenedImage=img.flatten() + flattenedImage = flattenedImage[flattenedImage != 2] + df = pd.DataFrame({"GP-Value": flattenedImage}) + sns.histplot(data=df, x="GP-Value",ax=ax,bins=np.arange(self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value()+self.doubleSpinBox_19.value(),self.doubleSpinBox_19.value())) + ax.set_xlabel(r'$\beta$-Value') + ax.set_ylabel('Counts') + fig=self.matplotlibwidget_17.figure + fig.tight_layout() + self.matplotlibwidget_17.canvas.draw_idle() + else: + ax.clear() + self.matplotlibwidget_17.canvas.draw_idle() + + def plot_Cyto_IntesitieDist_Object(self,intensites,key): + self.matplotlibwidget_15.axis.clear() + ax=self.matplotlibwidget_15.axis + + if key !=[] and intensites: + df = pd.DataFrame({"wavelength": intensites[0],"intensites":intensites[1]}) + sns.barplot(data=df, x="wavelength", y="intensites",hue="wavelength",ax=ax, palette="Reds",legend=False) + ax.xaxis.set_major_locator(FixedLocator(ax.get_xticks())) + ax.set_xticklabels(ax.get_xticklabels(),rotation=90) + ax.set_xlabel('Channels') + ax.set_ylabel('Normalized Intensities') + fig=self.matplotlibwidget_15.figure + fig.tight_layout() + self.matplotlibwidget_15.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_15.canvas.draw_idle() + + def plot_Cyto_GPPhasor_Object(self,phase,ObjectNr,key): # GP Phasor + self.matplotlibwidget_16.axis.clear() + ax=self.matplotlibwidget_16.axis + ax.clear() + if key !=[] and phase[int(ObjectNr)-1] != []: + if key !=[] and isinstance(phase[int(ObjectNr)-1][0], np.ndarray): + ph=phase[int(ObjectNr)-1][1][:] + ph=np.where(ph < 0, ph + 2*np.pi, ph) + df = pd.DataFrame({'amplitude': phase[int(ObjectNr)-1][0][:], 'phase': ph}) + + ax.grid(False) + rbins = np.linspace(0,df["amplitude"].max(), 100) + abins = np.linspace(0,2*np.pi, 360) + hist, _, _ = np.histogram2d(df["phase"], df["amplitude"], bins=(abins, rbins)) + A, R = np.meshgrid(abins, rbins) + ax.pcolormesh(A, R, hist.T, cmap="YlOrRd") + ax.grid(True) + ax.set_rlabel_position(0) + + fig=self.matplotlibwidget_16.figure + fig.tight_layout() + self.matplotlibwidget_16.canvas.draw_idle() + + else: + ax.clear() + self.matplotlibwidget_16.canvas.draw_idle() + + + def autoCutOffEnable(self): + pass +# self.doubleSpinBox_3.setEnabled(self.checkBox_9.checkState()) + + def singleImageEnable(self): + self.pushButton_3.setEnabled(self.checkBox.checkState()) + # remove singe image button + # check test if one or more are selecten than active + + def profilerEnable(self): + self.comboBox_5.setEnabled(self.checkBox_8.checkState()) + self.spinBox_7.setEnabled(self.checkBox_8.checkState()) + self.spinBox_8.setEnabled(self.checkBox_8.checkState()) + self.checkBox_9.setEnabled(self.checkBox_8.checkState()) + self.checkBox_14.setEnabled(self.checkBox_8.checkState()) + self.doubleSpinBox_3.setEnabled(self.checkBox_8.checkState()) + if self.checkBox_8.checkState()==False: + self.checkBox_9.setCheckState(self.checkBox_8.checkState()) + self.checkBox_14.setCheckState(self.checkBox_8.checkState()) + + def cytoprofilerEnable(self): + if self.checkBox.checkState()==False: + self.checkBox_9.setCheckState(self.checkBox.checkState()) + + + def removeClusterEnable(self): + self.comboBox_5.setEnabled(self.checkBox_8.checkState()) + self.doubleSpinBox_3.setEnabled(self.checkBox_8.checkState()) + self.spinBox_7.setEnabled(self.checkBox_8.checkState()) + self.spinBox_8.setEnabled(self.checkBox_8.checkState()) + + + + + + + def threholdEnable(self): + if self.comboBox_3.currentText() == 'Manual': + self.spinBox.setEnabled(True) + + elif self.comboBox_3.currentText() == 'Otsu': + self.spinBox.setEnabled(False) + + + def threholdEnable_cyto(self): + if self.comboBox_21.currentText() == 'Manual': + self.spinBox_15.setEnabled(True) + + + elif self.comboBox_21.currentText() == 'Otsu': + self.spinBox_15.setEnabled(False) + + + def compressEnable(self): + self.doubleSpinBox.setEnabled(self.checkBox_3.checkState()) + + def compressEnable_cyto(self): + self.doubleSpinBox_23.setEnabled(self.checkBox_32.checkState()) + + def dilateEnable(self): + self.comboBox_4.setEnabled(self.checkBox_6.checkState()) + self.spinBox_4.setEnabled(self.checkBox_6.checkState()) + self.spinBox_5.setEnabled(self.checkBox_6.checkState()) + + def dilateEnable_cyto(self): + self.comboBox_22.setEnabled(self.checkBox_37.checkState()) + self.spinBox_16.setEnabled(self.checkBox_37.checkState()) + self.spinBox_17.setEnabled(self.checkBox_37.checkState()) + + def fillHolesEnable(self): + self.doubleSpinBox_13.setEnabled(self.checkBox_5.checkState()) + + def fillHolesEnable_cyto(self): + self.doubleSpinBox_22.setEnabled(self.checkBox_35.checkState()) + + def removeObjectsEnable(self): + self.spinBox_2.setEnabled(self.checkBox_4.checkState()) + + def removeObjectsEnable_cyto(self): + self.spinBox_18.setEnabled(self.checkBox_34.checkState()) + + def threholdChannelEnable(self): + self.comboBox_18.setEnabled(self.checkBox_27.checkState()) + + def threholdChannelEnable_cyto(self): + self.comboBox_23.setEnabled(self.checkBox_36.checkState()) + + def filterEnable(self): + if self.comboBox_9.currentText() != "No Filter": + self.doubleSpinBox_12.setEnabled(True) + else: + self.doubleSpinBox_12.setEnabled(False) + + def filterEnable_cyto(self): + if self.comboBox_10.currentText() != "No Filter": + self.doubleSpinBox_11.setEnabled(True) + else: + self.doubleSpinBox_11.setEnabled(False) + + + + + def objectDetectionEnable(self): + self.checkBox_8.setEnabled(self.checkBox_2.checkState()) + self.comboBox_5.setEnabled(self.checkBox_8.checkState()) + self.doubleSpinBox_3.setEnabled(self.checkBox_8.checkState()) + self.spinBox_7.setEnabled(self.checkBox_8.checkState()) + self.spinBox_8.setEnabled(self.checkBox_8.checkState()) + self.checkBox_7.setEnabled(self.checkBox_2.checkState()) + + + if self.checkBox_2.checkState()==False: + self.checkBox_8.setEnabled(self.checkBox_2.checkState()) + self.comboBox_5.setEnabled(self.checkBox_2.checkState()) + self.doubleSpinBox_3.setEnabled(self.checkBox_2.checkState()) + self.spinBox_7.setEnabled(self.checkBox_2.checkState()) + self.spinBox_8.setEnabled(self.checkBox_2.checkState()) + self.checkBox_8.setCheckState(False) + self.checkBox_7.setCheckState(False) + self.checkBox_8.setCheckState(False) + self.checkBox_9.setCheckState(self.checkBox_8.checkState()) + + + def SaveAllInJSON(self,filename,savepath): + ui_settings = { + "filenme":filename, + "savepath":savepath, + "Date":time.asctime(time.localtime()), + "Metadata":self.Metadata[filename], + "General Settings":{ + "Object Detection":self.checkBox_2.isChecked(), + "Object Linearization":self.checkBox_7.isChecked() + }, + "Membrane Settings":{ + "Membrane Profiler":self.checkBox_8.isChecked(), + "Colocalzation":self.checkBox_14.isChecked(), + "Colocalzation Channel":(self.comboBox_8.currentText()), + "Channel A": (self.comboBox.currentText()), + "Channel B": (self.comboBox_2.currentText()), + "Channel C": (self.comboBox_6.currentText()), + "Channel D": (self.comboBox_7.currentText()), + "Equation": self.plainTextEdit.toPlainText(), + "Specific Channel for Masking":self.checkBox_27.isChecked(), + "Specific Channel for Masking Value":[] if not self.checkBox_27.isChecked() else ((self.comboBox_18.currentText())), + "Thresholding Type":self.comboBox_3.currentText(), + "Manual Cutoff Level":(self.spinBox.value()), + "Signal to Noise Ratio":self.doubleSpinBox_8.value(), + "Background Compensation": self.checkBox_15.isChecked(), + "Background Mean": "NaN" if not self.checkBox_15.isChecked() else (self.doubleSpinBox_9.value()), + "Background Standarddeviation": 1 if not self.checkBox_15.isChecked() else (self.doubleSpinBox_7.value()), + "Compression": (self.checkBox_3.isChecked()), + "Compression Value": (self.doubleSpinBox.value()), + "Remove Object":(self.checkBox_4.isChecked()), + "Remove Object Value":"NaN" if not self.checkBox_4.isChecked() else (self.spinBox_2.value()), #removeobjet size + "Fill Holes":(self.checkBox_5.isChecked()), + "Fill Holes Value":"NaN" if not self.checkBox_5.isChecked() else (self.doubleSpinBox_13.value()), #dilate hole size + "Dilate": (self.checkBox_6.isChecked()), + "Dilation Shape": self.comboBox_4.currentText(), + "Dilation Dimmension 1":(self.spinBox_4.value()), #shpae dim1 + "Dilation Dimmension 2":(self.spinBox_5.value()), #shpae dim2 + "filter_type":"No Filte" if self.comboBox_9.currentText() == "No Filter" else self.comboBox_9.currentText(), + "filter_val ":self.doubleSpinBox_12.value(), + "Binning Values [min,max,step]": [self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value(),self.doubleSpinBox_4.value()], + "Global Slice Masking": self.checkBox_24.isChecked(), + "Individual Slice MaskingSettings":self.Membrane_Maskdata[filename], + }, + "Cytosol Settings":{ + "Cytosol Measurement":self.checkBox.isChecked(), + "Channel A": (self.comboBox_13.currentText()), + "Channel B": (self.comboBox_14.currentText()), + "Channel C": (self.comboBox_15.currentText()), + "Channel D": (self.comboBox_16.currentText()), + "Equation": self.plainTextEdit_2.toPlainText(), + "Specific Channel for Masking":self.checkBox_36.isChecked(), + "Specific Channel for Masking Value":[] if not self.checkBox_36.isChecked() else ((self.comboBox_23.currentText())), + "Thresholding Type":self.comboBox_21.currentText(), + "Manual Cutoff Level":(self.spinBox_15.value()), + "Signal to Noise Ratio":self.doubleSpinBox_21.value(), + "Background Compensation": self.checkBox_16.isChecked(), + "Background Mean": "NaN" if not self.checkBox_16.isChecked() else (self.doubleSpinBox_10.value()), + "Background Standarddeviation": 1 if not self.checkBox_16.isChecked() else (self.doubleSpinBox_20.value()), + "Compression": (self.checkBox_32.isChecked()), + "Compression Value": (self.doubleSpinBox_23.value()), + "Remove Object":(self.checkBox_34.isChecked()), + "Remove Object Value":"NaN" if not self.checkBox_34.isChecked() else (self.spinBox_18.value()), #removeobjet size + "Fill Holes":(self.checkBox_35.isChecked()), + "Fill Holes Value":"NaN" if not self.checkBox_35.isChecked() else (self.doubleSpinBox_22.value()), #dilate hole size + "Dilate": (self.checkBox_37.isChecked()), + "Dilation Shape": self.comboBox_22.currentText(), + "Dilation Dimmension 1":(self.spinBox_17.value()), #shpae dim1 + "Dilation Dimmension 2":(self.spinBox_16.value()), #shpae dim2 + "Filter Type":self.comboBox_10.currentText(), + "Filter Value":self.doubleSpinBox_11.value(), + "Binning Values [min,max,step]": [self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value(),self.doubleSpinBox_19.value()], + "Global Slice Masking": self.checkBox_31.isChecked(), + "Individual Slice MaskingSettings": self.Cyto_Maskdata[filename] + }, + "Advanced Settings":{ + "Skeleton Debranching":(self.spinBox_3.value()), + "Tolerance Value 0":self.doubleSpinBox_2.value(), + "Tolerance Value 1":(self.spinBox_6.value()), + "Recentering":self.checkBox_10.isChecked(), + "dim_line":self.spinBox_9.value(), + "Integrating Element":self.comboBox_5.currentText(), + "Integrating Element Dimmension 1":(self.spinBox_7.value()), + "Integrating Element Dimmension 2":(self.spinBox_8.value()), + "P-Value Threshold Auto Cut Off":self.checkBox_9.isChecked(), + "P-Value Threshold CutOff-Value":self.doubleSpinBox_3.value() + }, + "Data Saving Settings":{ + "Save Cropped Membrane":self.checkBox_11.isChecked(), + "Save Cropped Cytosl":self.checkBox_12.isChecked(), + "Save Linearized Cytosol":self.checkBox_13.isChecked(), + "Save Phasors":self.checkBox_17.isChecked(), + "Save Settings":self.checkBox_18.isChecked(), + "Save Results":self.checkBox_19.isChecked() + }, + "Results":self.Results[filename] if self.checkBox_19.isChecked() else [] + } + + # Specify the file path where you want to save the settings + + filename_ext=join(filename+".json") + file_path = join(savepath,filename_ext) + + # Save the settings to a JSON file + + #ui_settings_serializable = self.convert_np_arrays_to_lists(ui_settings) + with open(file_path, "w") as json_file: + json.dump(ui_settings, json_file, cls=NumpyEncoder) + + print("Settings saved successfully.") + + + def LoadFiles(self): + self.ClearALL_andDissable() + self.path, _ = QFileDialog.getOpenFileNames(None, "Open Image File", "", "Images (*.lsm *.czi *.lif *.nd2 *.ome.tif)") + + if not self.path: + self.enablee_parts() + self.B_LoadFiles.setEnabled(True) + self.B_LoadFolder.setEnabled(True) + return + + row = 0 + maxlen = 0 + + # Calculate the total number of rows needed + for file_path in self.path: + image, metadata = openfile(file_path) + if isinstance(image, dict): + maxlen += len(image) + else: + maxlen += 1 + + self.tableWidget.setRowCount(maxlen if maxlen > len(self.path) else len(self.path)) + + for pathn, file_path in enumerate(self.path): + image, metadata = openfile(file_path) + base_name = basename(file_path) + dir_name = dirname(file_path) + + if isinstance(image, dict): + for n in range(len(image)): + subimage_name = f"{base_name}_subimage_{n+1}" + self._set_table_item(row, subimage_name, dir_name) + self.RawImages[subimage_name] = image[n] + self.Metadata[subimage_name] = metadata[n] + self.initialize_membrane_channels(subimage_name) + self.initialize_coloc_channels(subimage_name) + self.initialize_cytosol_channels(subimage_name) + row += 1 + else: + self._set_table_item(row, base_name, dir_name) + self.RawImages[base_name] = image + self.Metadata[base_name] = metadata + self.initialize_membrane_channels(base_name) + self.initialize_coloc_channels(base_name) + self.initialize_cytosol_channels(base_name) + row += 1 + + self._update_comboboxes(metadata) + + self._enable_widgets() + + def _set_table_item(self, row, name, dir_name): + self.tableWidget.setItem(row, 0, QtWidgets.QTableWidgetItem(name)) + self.tableWidget.setItem(row, 1, QtWidgets.QTableWidgetItem(dir_name)) + + def _update_comboboxes(self, metadata): + if isinstance(metadata, dict) and 'ChannelColors' in metadata: + Lambdachannel = metadata['ChannelColors'] + else: + Lambdachannel = metadata[0]['ChannelColors'] + + self.update_comboboxes(Lambdachannel) + + def _enable_widgets(self): + comboboxes = [ + self.comboBox, self.comboBox_2, self.comboBox_6, self.comboBox_7, + self.comboBox_13, self.comboBox_14, self.comboBox_15, self.comboBox_16, + self.comboBox_18, self.comboBox_23, self.comboBox_3, self.comboBox_10, + self.comboBox_9, self.comboBox_21 + ] + checkboxes = [ + self.checkBox, self.checkBox_2, self.checkBox_3, self.checkBox_4, + self.checkBox_5, self.checkBox_6, self.checkBox_24, self.checkBox_27, + self.checkBox_36, self.checkBox_16, self.checkBox_15, self.checkBox_32, + self.checkBox_34, self.checkBox_35, self.checkBox_37, self.checkBox_31 + ] + spinboxes = [ + self.doubleSpinBox_4, self.doubleSpinBox_5, self.doubleSpinBox_6, + self.doubleSpinBox_8, self.doubleSpinBox_17, self.doubleSpinBox_18, + self.doubleSpinBox_19, self.doubleSpinBox_21 + ] + buttons = [ + self.B_Run, self.pushButton_3, self.B_LoadFiles, self.B_LoadFolder, + self.pushButton_6, self.pushButton_7 + ] + + for combobox in comboboxes: + combobox.setEnabled(True) + + for checkbox in checkboxes: + checkbox.setEnabled(True) + + for spinbox in spinboxes: + spinbox.setEnabled(True) + + for button in buttons: + button.setEnabled(True) + + self.enablee_parts() + + def update_comboboxes(self,Lambdachannel): + self.comboBox.blockSignals(True) + self.comboBox_2.blockSignals(True) + self.comboBox_6.blockSignals(True) + self.comboBox_7.blockSignals(True) + self.comboBox_8.blockSignals(True) + self.comboBox_13.blockSignals(True) + self.comboBox_14.blockSignals(True) + self.comboBox_15.blockSignals(True) + self.comboBox_16.blockSignals(True) + self.comboBox_18.blockSignals(True) + self.comboBox_23.blockSignals(True) + + self.comboBox.clear() + self.comboBox_2.clear() + self.comboBox_6.clear() + self.comboBox_7.clear() + self.comboBox_8.clear() + self.comboBox_13.clear() + self.comboBox_14.clear() + self.comboBox_15.clear() + self.comboBox_16.clear() + self.comboBox_18.clear() + self.comboBox_23.clear() + + self.comboBox.addItems(['NaN']) + self.comboBox_2.addItems(['NaN']) + self.comboBox_6.addItems(['NaN']) + self.comboBox_7.addItems(['NaN']) + self.comboBox_13.addItems(['NaN']) + self.comboBox_14.addItems(['NaN']) + self.comboBox_15.addItems(['NaN']) + self.comboBox_16.addItems(['NaN']) + + self.comboBox.addItems([str(x) for x in Lambdachannel]) + self.comboBox_2.addItems([str(x) for x in Lambdachannel]) + self.comboBox_6.addItems([str(x) for x in Lambdachannel]) + self.comboBox_7.addItems([str(x) for x in Lambdachannel]) + self.comboBox_8.addItems([str(x) for x in Lambdachannel]) + self.comboBox_13.addItems([str(x) for x in Lambdachannel]) + self.comboBox_14.addItems([str(x) for x in Lambdachannel]) + self.comboBox_15.addItems([str(x) for x in Lambdachannel]) + self.comboBox_16.addItems([str(x) for x in Lambdachannel]) + self.comboBox_18.addItems([str(x) for x in Lambdachannel]) + self.comboBox_23.addItems([str(x) for x in Lambdachannel]) + + self.comboBox.blockSignals(False) + self.comboBox_2.blockSignals(False) + self.comboBox_6.blockSignals(False) + self.comboBox_7.blockSignals(False) + self.comboBox_8.blockSignals(False) + self.comboBox_13.blockSignals(False) + self.comboBox_14.blockSignals(False) + self.comboBox_15.blockSignals(False) + self.comboBox_16.blockSignals(False) + self.comboBox_18.blockSignals(False) + self.comboBox_23.blockSignals(False) + + + def Select_Saving_Path(self): + #self.savingpath= QFileDialog.getExistingDirectory(None, "Open Image Directory") + self.DifferentSavingPath=QFileDialog.getExistingDirectory(None, "Open Image Directory") + self.textBrowser.setText(self.DifferentSavingPath) + + def LoadFolder(self): + self.ClearALL_andDissable() + self.path = QFileDialog.getExistingDirectory(None, "Open Image Directory") + + if not self.path: + self.enablee_parts() + self.B_LoadFiles.setEnabled(True) + self.B_LoadFolder.setEnabled(True) + return + + allowed_extensions = ['.lsm', '.czi', '.lif', '.nd2', '.ome.tif'] + self.Files = [f for f in listdir(self.path) if isfile(join(self.path, f)) and any(f.endswith(ext) for ext in allowed_extensions)] + + if not self.Files: + self.enablee_parts() + self.B_LoadFiles.setEnabled(True) + self.B_LoadFolder.setEnabled(True) + return + + row = 0 + maxlen = 0 + + # Calculate the total number of rows needed + for file_name in self.Files: + image, metadata = openfile(join(self.path, file_name)) + if isinstance(image, dict): + maxlen += len(image) + else: + maxlen += 1 + + self.tableWidget.setRowCount(maxlen if maxlen > len(self.Files) else len(self.Files)) + + for file_name in self.Files: + file_path = join(self.path, file_name) + image, metadata = openfile(file_path) + base_name = basename(file_name) + + if isinstance(image, dict): + for n in range(len(image)): + subimage_name = f"{base_name}_subimage_{n+1}" + self._set_table_item(row, subimage_name, self.path) + self.RawImages[subimage_name] = image[n] + self.Metadata[subimage_name] = metadata[n] + self.initialize_membrane_channels(subimage_name) + self.initialize_coloc_channels(subimage_name) + self.initialize_cytosol_channels(subimage_name) + row += 1 + else: + self._set_table_item(row, base_name, self.path) + self.RawImages[base_name] = image + self.Metadata[base_name] = metadata + self.initialize_membrane_channels(base_name) + self.initialize_coloc_channels(base_name) + self.initialize_cytosol_channels(base_name) + row += 1 + + self._update_comboboxes(metadata) + self._enable_widgets() + + + + def DeletEntry(self): + self.block_combobox_signals(True) + if not len(self.tableWidget.selectionModel().selectedIndexes())==0: + if not self.tableWidget.rowCount() == 0: + if self.tableWidget.currentItem().isSelected(): + counter=0 + for i in reversed(range(self.tableWidget.rowCount())): + if (self.tableWidget.item(i,0)).isSelected(): + self.ClearEntry(self.tableWidget.item(self.tableWidget.currentRow(),0).text()) + counter=counter+1 + self.tableWidget.removeRow(i) + + if self.tableWidget.rowCount() == 0: + self.ClearALL_andDissable() + self.B_LoadFiles.setEnabled(True) + self.B_LoadFolder.setEnabled(True) + self.block_combobox_signals(False) + def ClearTable(self): + self.block_combobox_signals(True) + self.tableWidget.setRowCount(0) + self.ClearALL_andDissable() + self.B_LoadFiles.setEnabled(True) + self.B_LoadFolder.setEnabled(True) + self.block_combobox_signals(False) + + + def ClearEntry(self,filename): + self.block_combobox_signals(True) + self.Results[filename]={} + self.Membrane_Channels_selected[filename]={} + self.Colocolisation_Channel_selected[filename]={} + self.Cytosol_Channels_selected[filename]={} + self.Membrane_Maskdata[filename]={} #[filename][t][z][key] + self.Cyto_Maskdata[filename]={} + self.dims[filename]={} + self.RawImages[filename]={} + self.GPImage[filename]={} + self.FullImage_Parameters[filename]={} + self.Cyto_GPImage[filename]={} + self.GPImage_per_object[filename]={} + self.GPPhasor[filename]={} + self.Cyto_GPPhasor[filename]={} + self.Masks[filename]={} + self.Cyto_Masks[filename]={} + self.Intensities[filename]={} + self.Cyto_Intensities[filename]={} + self.nobjects[filename]={} + self.Object_Parameters[filename]={} + self.Object_Morphology[filename]={} + self.Object_Coordinates[filename]={} + self.Mask_Object_Coordinates[filename]={} + self.Intensities_per_object[filename]={} + self.Channellamda[filename]={} + self.phasex_object[filename]={} + self.phasey_object[filename]={} + self.GPPhasor_polar_all[filename]={} + self.Cyto_GPPhasor_polar_all[filename]={} + self.GPPhasor_polar_obj[filename]={} + self.key[filename]={} + self.ConnectSliders[filename]={} + self.Profile[filename]={} + self.MembraneSegments[filename]={} + self.Cytoprof[filename]={} + self.Cyto_Image[filename]={} + self.FullImage_Parameters_cyto[filename]={} + self.Object_Parameters_cyto[filename]={} + self.Cyto_Intensities_per_object[filename]={} + self.Cyto_GPPhasor_polar_obj[filename]={} + + del self.Results[filename] + del self.Membrane_Channels_selected[filename] + del self.Colocolisation_Channel_selected[filename] + del self.Cytosol_Channels_selected[filename] + del self.Membrane_Maskdata[filename] + del self.Cyto_Maskdata[filename] + del self.dims[filename] + del self.RawImages[filename] + del self.GPImage[filename] + del self.FullImage_Parameters[filename] + del self.Cyto_GPImage[filename] + del self.GPImage_per_object[filename] + del self.GPPhasor[filename] + del self.Cyto_GPPhasor[filename] + del self.Masks[filename] + del self.Cyto_Masks[filename] + del self.Intensities[filename] + del self.Cyto_Intensities[filename] + del self.nobjects[filename] + del self.Object_Parameters[filename] + del self.Object_Morphology[filename] + del self.Object_Coordinates[filename] + del self.Mask_Object_Coordinates[filename] + del self.Intensities_per_object[filename] + del self.Channellamda[filename] + del self.phasex_object[filename] + del self.phasey_object[filename] + del self.GPPhasor_polar_all[filename] + del self.Cyto_GPPhasor_polar_all[filename] + del self.GPPhasor_polar_obj[filename] + del self.key[filename] + del self.ConnectSliders[filename] + del self.Profile[filename] + del self.MembraneSegments[filename] + del self.Cytoprof[filename] + del self.Cyto_Image[filename] + del self.FullImage_Parameters_cyto[filename] + del self.Object_Parameters_cyto[filename] + del self.Cyto_Intensities_per_object[filename] + del self.Cyto_GPPhasor_polar_obj[filename] + self.block_combobox_signals(False) + + def ClearALL_andDissable(self): + self.block_combobox_signals(True) + self.Results={} + self.Membrane_Channels_selected={} + self.Colocolisation_Channel_selected={} + self.Cytosol_Channels_selected={} + self.Membrane_Maskdata={} #[filename][t][z][key] + self.Cyto_Maskdata={} + self.previously_selected_file=[None] + self.dims={} + self.RawImages={} + self.GPImage={} + self.FullImage_Parameters={} + self.Cyto_GPImage={} + self.GPImage_per_object={} + self.GPPhasor={} + self.Cyto_GPPhasor={} + self.Masks={} + self.Cyto_Masks={} + self.Intensities={} + self.Cyto_Intensities={} + self.nobjects={} + self.Object_Parameters={} + self.Object_Morphology={} + self.Object_Coordinates={} + self.Mask_Object_Coordinates={} + self.Intensities_per_object={} + self.Channellamda={} + self.phasex_object={} + self.phasey_object={} + self.GPPhasor_polar_all={} + self.Cyto_GPPhasor_polar_all={} + self.GPPhasor_polar_obj={} + self.key={} + self.ConnectSliders={} + self.Profile={} + self.MembraneSegments={} + self.Cytoprof={} + self.Cyto_Image={} + self.FullImage_Parameters_cyto={} + self.Object_Parameters_cyto={} + self.Cyto_Intensities_per_object={} + self.Cyto_GPPhasor_polar_obj={} + self.savingpath=str([]) + self.DifferentSavingPath=str([]) + + self.disable_parts() + self.block_combobox_signals(False) + + + def ClearSelection(self): + self.block_combobox_signals(True) + self.tableWidget.selectionModel().clearSelection() + self.tableWidget.setCurrentCell(-1,-1) + self.block_combobox_signals(False) + + + def find_unique_valid_letters(self,equation_string, combo_A, combo_B, combo_C, combo_D): + allowed_chars = {'A', 'B', 'C', 'D'} + invalid_characters = {'E', 'I', 'N', 'O', 'Q', 'S'} + invalid_char = next((char for char in equation_string if char in invalid_characters), None) + if invalid_char: + return False, f"Error: Invalid character '{invalid_char}' found in the text. ('E', 'I', 'N', 'O', 'Q', 'S' are reserved for mathematical operators). Please use A,B,C or D." + try: + expression = sympify(equation_string) + variables = expression.free_symbols + + for var in variables: + if str(var) not in allowed_chars: + return False, f"Invalid variable '{var}' found in the membrane equation. Only {', '.join(allowed_chars)} are allowed." + except SympifyError as e: + return False, f"Error: {e}" + + unique_letters = set() + + for char in equation_string: + if char.isupper(): + if char not in allowed_chars: + return 1,unique_letters,f"Error: Invalid letter '{char}' found in the text." + unique_letters.add(char) + + invalid_combos = [] + if 'A' in unique_letters and combo_A == 'NaN': + invalid_combos.append("'A'") + if 'B' in unique_letters and combo_B == 'NaN': + invalid_combos.append("'B'") + if 'C' in unique_letters and combo_C == 'NaN': + invalid_combos.append("'C'") + if 'D' in unique_letters and combo_D == 'NaN': + invalid_combos.append("'D'") + + value=self.comboBox_18.checkedItems() + if isinstance(value, str): + values = [v.strip() for v in value.split(',')] + elif isinstance(value, list): + values = [str(v).strip() for v in value] + else: + values = [str(value).strip()] + if self.checkBox_27.isChecked(): + if len(values)==0: + invalid_combos.append("'Specific Membrane Thresholding Channel'") + if self.checkBox_14.isChecked() and self.comboBox_8.currentText() == []: + invalid_combos.append("'Colocalization Channel'") + + if invalid_combos: + return False,f"Error Membrane Settings: Letter(s) {', '.join(invalid_combos)} are in use in the Equation, but corresponding ComboBox value(s) are not selected. Please select a Channel for {', '.join(invalid_combos)}" + + invalid_combos = [] + if combo_A != 'NaN' and 'A' not in unique_letters : + invalid_combos.append("'A'") + if combo_B != 'NaN' and 'B' not in unique_letters : + invalid_combos.append("'B'") + if combo_C != 'NaN' and 'C' not in unique_letters : + invalid_combos.append("'C'") + if combo_D != 'NaN' and 'D' not in unique_letters : + invalid_combos.append("'D'") + + if invalid_combos: + return False,f"Error Membrane Settings: Letter(s) {', '.join(invalid_combos)} are not 'NaN' but corresponding letter(s) are not used in the equation. Please select 'NaN' for {', '.join(invalid_combos)}" + + return True,"All good" + + + def find_unique_valid_letters_cyto(self,equation_string, combo_A, combo_B, combo_C, combo_D): + allowed_chars = {'A', 'B', 'C', 'D'} + invalid_characters = {'E', 'I', 'N', 'O', 'Q', 'S'} + invalid_char = next((char for char in equation_string if char in invalid_characters), None) + if invalid_char: + return False, f"Error: Invalid character '{invalid_char}' found in the text. ('E', 'I', 'N', 'O', 'Q', 'S' are reserved for mathematical operators).Please use A,B,C or D." + try: + expression = sympify(equation_string) + variables = expression.free_symbols + + for var in variables: + if str(var) not in allowed_chars: + return False, f"Invalid variable '{var}' found in the membrane equation. Only {', '.join(allowed_chars)} are allowed." + except SympifyError as e: + return False, f"Error: {e}" + + unique_letters = set() + + for char in equation_string: + if char.isupper(): + if char not in allowed_chars: + return 1,unique_letters,f"Error: Invalid letter '{char}' found in the text." + unique_letters.add(char) + + invalid_combos = [] + if 'A' in unique_letters and combo_A == 'NaN': + invalid_combos.append("'A'") + if 'B' in unique_letters and combo_B == 'NaN': + invalid_combos.append("'B'") + if 'C' in unique_letters and combo_C == 'NaN': + invalid_combos.append("'C'") + if 'D' in unique_letters and combo_D == 'NaN': + invalid_combos.append("'D'") + + value=self.comboBox_23.checkedItems() + if isinstance(value, str): + values = [v.strip() for v in value.split(',')] + elif isinstance(value, list): + values = [str(v).strip() for v in value] + else: + values = [str(value).strip()] + if self.checkBox_36.isChecked(): + if len(values)==0: + invalid_combos.append("'Specific Cytosolic Thresholding Channel'") + + if invalid_combos: + return False,f"Error Cytosol Settings: Letter(s) {', '.join(invalid_combos)} are in use in the Equation, but corresponding ComboBox value(s) are not selected. Please select a Channel for {', '.join(invalid_combos)}" + + invalid_combos = [] + if combo_A != 'NaN' and 'A' not in unique_letters : + invalid_combos.append("'A'") + if combo_B != 'NaN' and 'B' not in unique_letters : + invalid_combos.append("'B'") + if combo_C != 'NaN' and 'C' not in unique_letters : + invalid_combos.append("'C'") + if combo_D != 'NaN' and 'D' not in unique_letters : + invalid_combos.append("'D'") + + if invalid_combos: + return False,f"Error Cytosol Settings: Letter(s) {', '.join(invalid_combos)} are not 'NaN' but corresponding letter(s) are not used in the equation. Please select 'NaN' for {', '.join(invalid_combos)}" + + + return True,"All good" + + + def testThresholding(self): + global Resultstest + if True: # Placehodler + if not self.tableWidget.rowCount() == 0: + if self.tableWidget.currentItem() is not None: + if self.tableWidget.currentItem().isSelected(): + for i in range(self.tableWidget.rowCount()): + if (self.tableWidget.item(i,0)).isSelected(): + mode=0 + filename=self.tableWidget.item(i,0).text() + path=self.tableWidget.item(i,1).text() + app.processEvents() + + # if "_subimage_" in filename: + # modified_filename = filename.split("_subimage_")[0] + # image_dict,metadata_dict=openfile(join(path, modified_filename)) + # image=image_dict[0] + # metadata=metadata_dict[0] + # Lambdachannel=metadata['ChannelColors'] + # dims=metadata['Dimensions'] + + # Data_py=image + + # else: + # modified_filename = filename + # image,metadata=openfile(join(path, modified_filename)) + + # Lambdachannel=metadata['ChannelColors'] + # dims=metadata['Dimensions'] + # Data_py=image + + + Lambdachannel=self.Metadata[filename]['ChannelColors'] + dims=self.Metadata[filename]['Dimensions'] + Data_py=self.RawImages[filename] + # print("--------------------------------------") + # print("--------------------------------------") + # print("Pixelsize") + # print(type(Pixelsize)) + # print(Pixelsize) + # print("Nchannels") + # print(type(Nchannels)) + # print(Nchannels) + # print("Lambdachannel") + # print(type(Lambdachannel)) + # print(Lambdachannel) + # print("dims") + # print(type(dims)) + # print(dims) + # print("PixelDepth") + # print(type(PixelDepth)) + # print(PixelDepth) + # print("image") + # print(type(Data_py)) + # print(Data_py.shape) + # print("--------------------------------------") + # print("--------------------------------------") + + + if self.checkBox_24.isChecked(): + self.update_toglobal_values_membrane() + if self.checkBox_31.isChecked(): + self.update_toglobal_values_cytosol() + + + + if self.savingpath: + savepath=self.tableWidget.item(i,1).text() + else: + savepath=self.savingpath + + + + Result=RunAnalyser( mode=mode, + filename=filename, + Lambdachannel=Lambdachannel, + image=Data_py, + dims=dims, + varlist=self.Membrane_Channels_selected[filename], + ObjectDetection=self.checkBox_2.isChecked(), + profiler=self.checkBox_8.isChecked(), + profilershape=self.comboBox_5.currentText(), + autoff=self.checkBox_9.isChecked(), #??? + PDiamCutoff=self.doubleSpinBox_3.value(), #??? + proDim1=self.spinBox_7.value(), + proDim2=self.spinBox_8.value(), + text=self.plainTextEdit.toPlainText(), + histpars=[self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value(),self.doubleSpinBox_4.value()], + histpars_cyto=[self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value(),self.doubleSpinBox_19.value()], + text_cyto=self.plainTextEdit_2.toPlainText(), + profile_cyto=self.checkBox.isChecked(), + varlist_cyto=self.Cytosol_Channels_selected[filename], + n_debranch=self.spinBox_3.value(), #NEW + tol0=self.doubleSpinBox_2.value(), #NEW + tol1=self.spinBox_6.value(), #NEW + savecroppedmembrane=self.checkBox_11.isChecked(), + savecroppedcyto=self.checkBox_12.isChecked(), + savelinearized=self.checkBox_13.isChecked(), + savepath=savepath, + objlinear=self.checkBox_7.isChecked(), #NEW ??? + recentering=False, #NEW ??? + dim_line=self.spinBox_9.value(), #NEW ??? + MaskParams_mem=self.Membrane_Maskdata[filename], + MaskParams_cyto=self.Cyto_Maskdata[filename], # NEW + Colocalization= (self.Colocolisation_Channel_selected[filename]) if self.checkBox_14.isChecked() and self.comboBox_8.currentText().isdigit() else [], + savephasors=self.checkBox_17.isChecked(), + tocut = 0, #???? WAS hab i ma dabei gedacht + radius = 'auto') #???? WAS hab i ma dabei gedacht + + Resultstest=Result + + if ((dims[0]!=1) != (dims[1]!=1)): #if Z or T 4D + if dims[1]!=1: #Zstack 4D + self.key[filename]="Zstack" + else: + self.key[filename]="Tstack" + self.Masks[filename]=[] + if ((isinstance(Result[0]["datamask"][8], np.ndarray) and Result[0]["datamask"][8].size > 0) + or (isinstance(Result[0]["datamask"][8], list) and len(Result[0]["datamask"][8]) > 0)): + self.Cyto_Masks[filename]=[] + for Stack in Result: + self.Masks[filename].append(Result[Stack]["datamask"][2]) + if ((isinstance(Result[Stack]["datamask"][8], np.ndarray) and Result[Stack]["datamask"][8].size > 0) + or (isinstance(Result[Stack]["datamask"][8], list) and len(Result[Stack]["datamask"][8]) > 0)): + self.Cyto_Masks[filename].append(Result[Stack]["datamask"][8]) + self.RawImages[filename]=Data_py + + elif (dims[0]!=1 and dims[1]!=1): #if Z and T 5D + self.Masks[filename]=[] + if ((isinstance(Result[0][0]["datamask"][8], np.ndarray) and Result[0][0]["datamask"][8].size > 0) + or (isinstance(Result[0][0]["datamask"][8], list) and len(Result[0][0]["datamask"][8]) > 0)): + self.Cyto_Masks[filename]=[] + self.key[filename]="TZstack" + for T_Stack in Result: + self.Masks[filename].append([]) + if ((isinstance(Result[T_Stack][0]["datamask"][8], np.ndarray) and Result[T_Stack][0]["datamask"][8].size > 0) + or (isinstance(Result[T_Stack][0]["datamask"][8], list) and len(Result[T_Stack][0]["datamask"][8]) > 0)): + self.Cyto_Masks[filename].append([]) + for Z_Stack in Result[T_Stack]: + self.Masks[filename][T_Stack].append(Result[T_Stack][Z_Stack]["datamask"][2]) + if ((isinstance(Result[T_Stack][Z_Stack]["datamask"][8], np.ndarray) and Result[T_Stack][Z_Stack]["datamask"][8].size > 0) + or (isinstance(Result[T_Stack][Z_Stack]["datamask"][8], list) and len(Result[T_Stack][Z_Stack]["datamask"][8]) > 0)): + self.Cyto_Masks[filename][T_Stack].append(Result[T_Stack][Z_Stack]["datamask"][8]) + self.RawImages[filename]=Data_py + else: + self.key[filename]="3dim" + if isinstance(Result, dict): + self.Masks[filename]=Result["datamask"][2] + self.Cyto_Masks[filename]=Result["datamask"][8] + self.RawImages[filename]=Data_py + + else: + for i in range(self.tableWidget.rowCount()): + mode=0 + filename=self.tableWidget.item(i,0).text() + path=self.tableWidget.item(i,1).text() + + # if "_subimage_" in filename: + # modified_filename = filename.split("_subimage_")[0] + # image_dict,metadata_dict=openfile(join(path, modified_filename)) + # image=image_dict[0] + # metadata=metadata_dict[0] + # Lambdachannel=metadata['ChannelColors'] + # dims=metadata['Dimensions'] + + # Data_py=image + + # else: + # modified_filename = filename + # image,metadata=openfile(join(path, modified_filename)) + + # Lambdachannel=metadata['ChannelColors'] + # dims=metadata['Dimensions'] + # Data_py=image + + + Lambdachannel=self.Metadata[filename]['ChannelColors'] + dims=self.Metadata[filename]['Dimensions'] + Data_py=self.RawImages[filename] + + if self.savingpath: + savepath=self.tableWidget.item(i,1).text() + else: + savepath=self.savingpath + + if self.checkBox_24.isChecked(): + self.update_toglobal_values_membrane(filename=filename, path=path) + if self.checkBox_31.isChecked(): + self.update_toglobal_values_cytosol(filename=filename, path=path) + + Result=RunAnalyser(mode=mode, + filename=filename, + Lambdachannel=Lambdachannel, + image=Data_py, + dims=dims, + varlist=self.Membrane_Channels_selected[filename], + profiler=self.checkBox_8.isChecked(), + profilershape=self.comboBox_5.currentText(), + autoff=self.checkBox_9.isChecked(), #??? + PDiamCutoff=self.doubleSpinBox_3.value(), #??? + proDim1=self.spinBox_7.value(), + proDim2=self.spinBox_8.value(), + text=self.plainTextEdit.toPlainText(), + histpars=[self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value(),self.doubleSpinBox_4.value()], + histpars_cyto=[self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value(),self.doubleSpinBox_19.value()], + text_cyto=self.plainTextEdit_2.toPlainText(), + profile_cyto=self.checkBox.isChecked(), + varlist_cyto=self.Cytosol_Channels_selected[filename], + n_debranch=self.spinBox_3.value(), #NEW + tol0=self.doubleSpinBox_2.value(), #NEW + tol1=self.spinBox_6.value(), #NEW + savecroppedmembrane=self.checkBox_11.isChecked(), + savecroppedcyto=self.checkBox_12.isChecked(), + savelinearized=self.checkBox_13.isChecked(), + savepath=savepath, + objlinear=self.checkBox_7.isChecked(), #NEW ??? + recentering=False, #NEW ??? + dim_line=self.spinBox_9.value(), #NEW ??? + MaskParams_mem=self.Membrane_Maskdata[filename], + MaskParams_cyto=self.Cyto_Maskdata[filename], # NEW + Colocalization= (self.Colocolisation_Channel_selected[filename]) if self.checkBox_14.isChecked() and self.comboBox_8.currentText().isdigit() else [], + savephasors=self.checkBox_17.isChecked(), + tocut = 0, #???? WAS hab i ma dabei gedacht + radius = 'auto') #???? WAS hab i ma dabei gedacht + + Resultstest=Result + + if ((dims[0]!=1) != (dims[1]!=1)): #if Z or T 4D + if dims[1]!=1: #Zstack 4D + self.key[filename]="Zstack" + else: + self.key[filename]="Tstack" + self.Masks[filename]=[] + if ((isinstance(Result[0]["datamask"][8], np.ndarray) and Result[0]["datamask"][8].size > 0) + or (isinstance(Result[0]["datamask"][8], list) and len(Result[0]["datamask"][8]) > 0)): + self.Cyto_Masks[filename]=[] + for Stack in Result: + self.Masks[filename].append(Result[Stack]["datamask"][2]) + if ((isinstance(Result[Stack]["datamask"][8], np.ndarray) and Result[Stack]["datamask"][8].size > 0) + or (isinstance(Result[Stack]["datamask"][8], list) and len(Result[Stack]["datamask"][8]) > 0)): + self.Cyto_Masks[filename].append(Result[Stack]["datamask"][8]) + self.RawImages[filename]=Data_py + + elif (dims[0]!=1 and dims[1]!=1): #if Z and T 5D + self.Masks[filename]=[] + if ((isinstance(Result[0][0]["datamask"][8], np.ndarray) and Result[0][0]["datamask"][8].size > 0) + or (isinstance(Result[0][0]["datamask"][8], list) and len(Result[0][0]["datamask"][8]) > 0)): + self.Cyto_Masks[filename]=[] + self.key[filename]="TZstack" + for T_Stack in Result: + self.Masks[filename].append([]) + if ((isinstance(Result[T_Stack][0]["datamask"][8], np.ndarray) and Result[T_Stack][0]["datamask"][8].size > 0) + or (isinstance(Result[T_Stack][0]["datamask"][8], list) and len(Result[T_Stack][0]["datamask"][8]) > 0)): + self.Cyto_Masks[filename].append([]) + for Z_Stack in Result[T_Stack]: + self.Masks[filename][T_Stack].append(Result[T_Stack][Z_Stack]["datamask"][2]) + if ((isinstance(Result[T_Stack][Z_Stack]["datamask"][8], np.ndarray) and Result[T_Stack][Z_Stack]["datamask"][8].size > 0) + or (isinstance(Result[T_Stack][Z_Stack]["datamask"][8], list) and len(Result[T_Stack][Z_Stack]["datamask"][8]) > 0)): + self.Cyto_Masks[filename][T_Stack].append(Result[T_Stack][Z_Stack]["datamask"][8]) + self.RawImages[filename]=Data_py + else: + self.key[filename]="3dim" + if isinstance(Result, dict): + self.Masks[filename]=Result["datamask"][2] + self.Cyto_Masks[filename]=Result["datamask"][8] + self.RawImages[filename]=Data_py + + # + else: + print("NO Data Loaded") + else: + pass + + + def disable_parts(self): + self.B_Run.setEnabled(False) + self.pushButton_3.setEnabled(False) + self.B_LoadFiles.setEnabled(False) + self.B_LoadFolder.setEnabled(False) + self.B_ClearSelection.setEnabled(False) + self.B_DeletEntry.setEnabled(False) + self.B_ClearTable.setEnabled(False) + + + def enablee_parts(self): + self.B_Run.setEnabled(True) + self.pushButton_3.setEnabled(True) + self.B_LoadFiles.setEnabled(True) + self.B_LoadFolder.setEnabled(True) + self.B_ClearSelection.setEnabled(True) + self.B_DeletEntry.setEnabled(True) + self.B_ClearTable.setEnabled(True) + + + + def Run(self): + global Resultstest + if True: + self.testThresholding() #Umändern + if not self.tableWidget.rowCount() == 0: + if self.tableWidget.currentItem() is not None: + if self.tableWidget.currentItem().isSelected(): + for i in range(self.tableWidget.rowCount()): + if (self.tableWidget.item(i,0)).isSelected(): + filename=self.tableWidget.item(i,0).text() + self.ConnectSliders[filename]=True + path=self.tableWidget.item(i,1).text() + app.processEvents() + image=self.RawImages[filename] + metadata=self.Metadata[filename] + Lambdachannel=metadata['ChannelColors'] + dims=metadata['Dimensions'] + #self.Metadata[filename]=metadata + Data_py=image + ## Run Analysis selected images + mode=1 + if len(self.DifferentSavingPath)>2: + savepath=self.DifferentSavingPath + else: + savepath=self.tableWidget.item(i,1).text() + if self.checkBox_24.isChecked(): + self.update_toglobal_values_membrane(filename=filename, path=path) + else: + pass # here we need the fix for the detailed masking not prior selecte image issue + if self.checkBox_31.isChecked(): + self.update_toglobal_values_cytosol(filename=filename, path=path) + else: + pass # here we need the fix for the detailed masking not prior selecte image issue + + Result=RunAnalyser(mode=mode, + filename=filename, + Lambdachannel=Lambdachannel, + image=Data_py, + dims=dims, + varlist=self.Membrane_Channels_selected[filename], + ObjectDetection=self.checkBox_2.isChecked(), + profiler=self.checkBox_8.isChecked(), + profilershape=self.comboBox_5.currentText(), + autoff=self.checkBox_9.isChecked(), #??? + PDiamCutoff=self.doubleSpinBox_3.value(), #??? + proDim1=self.spinBox_7.value(), + proDim2=self.spinBox_8.value(), + text=self.plainTextEdit.toPlainText(), + histpars=[self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value(),self.doubleSpinBox_4.value()], + histpars_cyto=[self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value(),self.doubleSpinBox_17.value()], + text_cyto=self.plainTextEdit_2.toPlainText(), + profile_cyto=self.checkBox.isChecked(), + varlist_cyto=self.Cytosol_Channels_selected[filename], + n_debranch=self.spinBox_3.value(), #NEW + tol0=self.doubleSpinBox_2.value(), #NEW + tol1=self.spinBox_6.value(), #NEW + savecroppedmembrane=self.checkBox_11.isChecked(), + savecroppedcyto=self.checkBox_12.isChecked(), + savelinearized=self.checkBox_13.isChecked(), + savepath=savepath, + objlinear=self.checkBox_7.isChecked(), #NEW ??? + recentering=False, #NEW ??? + dim_line=self.spinBox_9.value(), #NEW ??? + MaskParams_mem=self.Membrane_Maskdata[filename], + MaskParams_cyto=self.Cyto_Maskdata[filename], # NEW + Colocalization= (self.Colocolisation_Channel_selected[filename]) if self.checkBox_14.isChecked() and self.comboBox_8.currentText().isdigit() else [], + savephasors=self.checkBox_17.isChecked(), + tocut = 0, #???? WAS hab i ma dabei gedacht + radius = 'auto') #???? WAS hab i ma dabei gedacht + + Resultstest=Result + + self.Results[filename]=Result + self.dims[filename]=dims + app.processEvents() + + self.Poppulationg_Results (Result, dims, filename,Lambdachannel) + if self.checkBox_18.isChecked(): + self.SaveAllInJSON(filename,savepath) + if self.checkBox_20.isChecked(): + self.SaveBetaColorcodedImageasTif(Result,filename,savepath) + + + else: # without selection + for i in range(self.tableWidget.rowCount()): + filename=self.tableWidget.item(i,0).text() + self.ConnectSliders[filename]=True + path=self.tableWidget.item(i,1).text() + app.processEvents() + image=self.RawImages[filename] + metadata=self.Metadata[filename] + Lambdachannel=metadata['ChannelColors'] + dims=metadata['Dimensions'] + #self.Metadata[filename]=metadata + Data_py=image + mode=1 + if len(self.DifferentSavingPath)>2: + savepath=self.DifferentSavingPath + else: + savepath=self.tableWidget.item(i,1).text() + if self.checkBox_24.isChecked(): + self.update_toglobal_values_membrane(filename=filename, path=path) + if self.checkBox_31.isChecked(): + self.update_toglobal_values_cytosol(filename=filename, path=path) + + Result=RunAnalyser(mode=mode, + filename=filename, + Lambdachannel=Lambdachannel, + image=Data_py, + dims=dims, + varlist=self.Membrane_Channels_selected[filename], + ObjectDetection=self.checkBox_2.isChecked(), + profiler=self.checkBox_8.isChecked(), + profilershape=self.comboBox_5.currentText(), + autoff=self.checkBox_9.isChecked(), #??? + PDiamCutoff=self.doubleSpinBox_3.value(), #??? + proDim1=self.spinBox_7.value(), + proDim2=self.spinBox_8.value(), + text=self.plainTextEdit.toPlainText(), + histpars=[self.doubleSpinBox_5.value(),self.doubleSpinBox_6.value(),self.doubleSpinBox_4.value()], + histpars_cyto=[self.doubleSpinBox_17.value(),self.doubleSpinBox_18.value(),self.doubleSpinBox_19.value()], + text_cyto=self.plainTextEdit_2.toPlainText(), + profile_cyto=self.checkBox.isChecked(), + varlist_cyto=self.Cytosol_Channels_selected[filename], + n_debranch=self.spinBox_3.value(), #NEW + tol0=self.doubleSpinBox_2.value(), #NEW + tol1=self.spinBox_6.value(), #NEW + savecroppedmembrane=self.checkBox_11.isChecked(), + savecroppedcyto=self.checkBox_12.isChecked(), + savelinearized=self.checkBox_13.isChecked(), + savepath=savepath, + objlinear=self.checkBox_7.isChecked(), #NEW ??? + recentering=False, #NEW ??? + dim_line=self.spinBox_9.value(), #NEW ??? + MaskParams_mem=self.Membrane_Maskdata[filename], + MaskParams_cyto=self.Cyto_Maskdata[filename], # NEW + Colocalization= (self.Colocolisation_Channel_selected[filename]) if self.checkBox_14.isChecked() and self.comboBox_8.currentText().isdigit() else [], + savephasors=self.checkBox_17.isChecked(), + tocut = 0, #???? WAS hab i ma dabei gedacht + radius = 'auto') #???? WAS hab i ma dabei gedacht + + Resultstest=Result + self.Results[filename]=Result + self.dims[filename]=dims + app.processEvents() + + self.Poppulationg_Results (Result, dims, filename,Lambdachannel) + if self.checkBox_18.isChecked(): + self.SaveAllInJSON(filename,savepath) + if self.checkBox_20.isChecked(): + self.SaveBetaColorcodedImageasTif(Result,filename,savepath) + + else: + print("NO Data Loaded") + + + else: + pass + + def SaveBetaColorcodedImageasTif(self,Result,filename,savepath): + self.GPImage[filename] + self.key[filename] + + if self.key[filename] == "3dim": + new_filename = join(savepath, filename.rsplit('.', 1)[0] + '.tiff') + lsm.imwrite(new_filename, self.GPImage[filename].astype(np.float32), imagej=True, metadata={'axes': 'YX'}) + elif self.key[filename] == "Tstack": + new_filename = join(savepath, filename.rsplit('.', 1)[0] + '.tiff') + t_array = np.array(self.GPImage[filename]).astype(np.float32) + lsm.imwrite(new_filename, t_array, imagej=True, metadata={'axes': 'TYX'}) + elif self.key[filename] == "Zstack": + new_filename = join(savepath, filename.rsplit('.', 1)[0] + '.tiff') + z_array = np.array(self.GPImage[filename]).astype(np.float32) + lsm.imwrite(new_filename, z_array, imagej=True, metadata={'axes': 'ZYX'}) + elif self.key[filename] == "TZstack": + new_filename = join(savepath, filename.rsplit('.', 1)[0] + '.tiff') + tz_array = np.array(self.GPImage[filename]).astype(np.float32) + lsm.imwrite(new_filename, tz_array, imagej=True, metadata={'axes': 'TZYX'}) + + def Poppulationg_Results (self, Result, dims, filename,Lambdachannel): + if ((dims[0]!=1) != (dims[1]!=1)): #if Z or T 4D + if dims[1]!=1: #Zstack 4D + self.key[filename]="Zstack" + else: + self.key[filename]="Tstack" + self.GPImage[filename]=[] + self.FullImage_Parameters[filename]=[] + self.GPPhasor[filename]=[] + self.GPPhasor_polar_all[filename]=[] + + self.Intensities[filename]=[] + + self.nobjects[filename]=[] + self.GPPhasor_polar_obj[filename]=[] + self.Intensities_per_object[filename]=[] + self.GPImage_per_object[filename]=[] + self.Object_Parameters[filename]=[] + self.Object_Morphology[filename]=[] + self.Object_Coordinates[filename]=[] + self.Channellamda[filename]=[] + self.Profile[filename]=[] + self.MembraneSegments[filename]=[] + self.Cytoprof[filename]=[] + if Result[0]["analysis"]["results_whole_cyto"]: + self.Cyto_GPPhasor_polar_all[filename]=[] + self.Cyto_Intensities[filename]=[] + self.Cyto_GPImage[filename]=[] + self.FullImage_Parameters_cyto[filename]=[] + self.Cyto_Intensities_per_object[filename]=[] + self.Cyto_GPPhasor_polar_obj[filename]=[] + self.Cyto_Image[filename]=[] + self.Object_Parameters_cyto[filename]=[] + + for Stack in Result: + self.GPImage[filename].append(Result[Stack]["analysis"]["results_whole"][2]) + self.FullImage_Parameters[filename].append(Result[Stack]["analysis"]["results_whole"][0]["Parameters"]) + if Result[Stack]["analysis"]["results_whole_cyto"]: + self.Cyto_GPImage[filename].append(Result[Stack]["analysis"]["results_whole_cyto"][2]) + self.FullImage_Parameters_cyto[filename].append(Result[Stack]["analysis"]["results_whole_cyto"][0]["Parameters"]) + self.Cyto_GPPhasor_polar_all[filename].append(Result[Stack]["analysis"]["results_whole"][3]) + self.Cyto_Intensities[filename].append([]) + self.Cyto_Intensities[filename][Stack].append(Result[Stack]["analysis"]["results_whole_cyto"][0]["Wavelengths (nm)"]) + self.Cyto_Intensities[filename][Stack].append(Result[Stack]["analysis"]["results_whole_cyto"][0]["Norm. Intensity"]) + + self.GPPhasor[filename].append(Result[Stack]["analysis"]["results_whole"][3]) + self.GPPhasor_polar_all[filename].append(Result[Stack]["analysis"]["results_whole"][3]) + self.Intensities[filename].append([]) + self.Intensities[filename][Stack].append(Result[Stack]["analysis"]["results_whole"][0]["Wavelengths (nm)"]) + self.Intensities[filename][Stack].append(Result[Stack]["analysis"]["results_whole"][0]["Norm. Intensity"]) + self.nobjects[filename].append(0) + + if len(Result[Stack]["analysis"]["results_obj"])!=0: + self.nobjects[filename][Stack]=len(Result[Stack]["analysis"]["results_obj"]) + self.Channellamda[filename].append(Lambdachannel) + + self.GPPhasor_polar_obj[filename].append([]) + self.GPImage_per_object[filename].append([]) + self.Object_Parameters[filename].append([]) + self.Object_Morphology[filename].append([]) + self.Intensities_per_object[filename].append([]) + self.Object_Coordinates[filename].append([]) + self.Profile[filename].append([]) + self.MembraneSegments[filename].append([]) + self.Cytoprof[filename].append([]) + if Result[0]["analysis"]["results_whole_cyto"]: + self.Cyto_Image[filename].append([]) + self.Object_Parameters_cyto[filename].append([]) + self.Cyto_Intensities_per_object[filename].append([]) + self.Cyto_GPPhasor_polar_obj[filename].append([]) + + for objn in Resultstest[Stack]["analysis"]["results_obj"]: + self.GPPhasor_polar_obj[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basicmembrane"][3]) + self.GPImage_per_object[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basicmembrane"][2]) + self.Object_Parameters[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basicmembrane"][0]["Parameters"]) + self.Object_Morphology[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["morphology"][2:]) + self.Intensities_per_object[filename][Stack].append([]) + self.Intensities_per_object[filename][Stack][int(objn)-1].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basicmembrane"][0]["Wavelengths (nm)"]) + self.Intensities_per_object[filename][Stack][int(objn)-1].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basicmembrane"][0]["Norm. Intensity"]) + self.Object_Coordinates[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["morphology"][1]) + if len(Resultstest[Stack]["analysis"]["results_obj"][objn]["profile"]) !=0: + self.Profile[filename][Stack].append([]) + self.Profile[filename][Stack][int(objn)-1].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["profile"][0]) + self.MembraneSegments[filename][Stack].append([]) + self.MembraneSegments[filename][Stack][int(objn)-1].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["profile"][6]) + else: + self.Profile[filename][Stack].append([]) + self.MembraneSegments[filename][Stack].append([]) + if len(Resultstest[Stack]["analysis"]["results_obj"][objn]["objlinearization"]) !=0: + self.Cytoprof[filename][Stack].append([]) + self.Cytoprof[filename][Stack][int(objn)-1].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["objlinearization"]) + else: + self.Cytoprof[filename][Stack].append([]) + if len(Resultstest[Stack]["analysis"]["results_obj"][objn]["basiccyto"]) !=0: + self.Cyto_Image[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basiccyto"][2]) + self.Object_Parameters_cyto[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basiccyto"][0]["Parameters"]) + self.Cyto_Intensities_per_object[filename][Stack].append([]) + self.Cyto_Intensities_per_object[filename][Stack][int(objn)-1].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basiccyto"][0]["Wavelengths (nm)"]) + self.Cyto_Intensities_per_object[filename][Stack][int(objn)-1].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basiccyto"][0]["Norm. Intensity"]) + self.Cyto_GPPhasor_polar_obj[filename][Stack].append(Resultstest[Stack]["analysis"]["results_obj"][objn]["basicmembrane"][3]) + elif Result[0]["analysis"]["results_whole_cyto"]: + self.Cyto_Image[filename][Stack].append([]) + self.Object_Parameters_cyto[filename][Stack].append([]) + self.Cyto_Intensities_per_object[filename][Stack].append([]) + self.Cyto_GPPhasor_polar_obj[filename][Stack].append([]) + + elif (dims[0]!=1 and dims[1]!=1): #if Z and T 5D + self.key[filename]="TZstack" + self.GPImage[filename]=[] + self.FullImage_Parameters[filename]=[] + self.GPPhasor[filename]=[] + self.GPPhasor_polar_all[filename]=[] + self.Intensities[filename]=[] + self.nobjects[filename]=[] + self.GPPhasor_polar_obj[filename]=[] + self.Intensities_per_object[filename]=[] + self.GPImage_per_object[filename]=[] + self.Object_Parameters[filename]=[] + self.Object_Morphology[filename]=[] + self.Object_Coordinates[filename]=[] + self.Channellamda[filename]=[] + self.Profile[filename]=[] + self.MembraneSegments[filename]=[] + self.Cytoprof[filename]=[] + if Result[0][0]["analysis"]["results_whole_cyto"]: + self.Cyto_GPImage[filename]=[] + self.FullImage_Parameters_cyto[filename]=[] + self.Cyto_GPPhasor_polar_all[filename]=[] + self.Cyto_Intensities[filename]=[] + self.Cyto_Intensities_per_object[filename]=[] + self.Cyto_GPPhasor_polar_obj[filename]=[] + self.Cyto_Image[filename]=[] + self.Object_Parameters_cyto[filename]=[] + + for T_Stack in Result: + self.GPImage[filename].append([]) + self.FullImage_Parameters[filename].append([]) + self.GPPhasor[filename].append([]) + self.GPPhasor_polar_all[filename].append([]) + self.Intensities[filename].append([]) + self.nobjects[filename].append([]) + self.GPPhasor_polar_obj[filename].append([]) + self.Intensities_per_object[filename].append([]) + self.GPImage_per_object[filename].append([]) + self.Object_Parameters[filename].append([]) + self.Object_Morphology[filename].append([]) + self.Object_Coordinates[filename].append([]) + self.Channellamda[filename].append([]) + self.Profile[filename].append([]) + self.MembraneSegments[filename].append([]) + self.Cytoprof[filename].append([]) + if Result[0][0]["analysis"]["results_whole_cyto"]: + self.Cyto_GPImage[filename].append([]) + self.FullImage_Parameters_cyto[filename][T_Stack].append([]) + self.Cyto_GPPhasor_polar_all[filename].append([]) + self.Cyto_Intensities[filename].append([]) + self.Cyto_Intensities_per_object[filename].append([]) + self.Cyto_GPPhasor_polar_obj[filename].append([]) + self.Cyto_Image[filename].append([]) + self.Object_Parameters_cyto[filename].append([]) + for Z_Stack in Result[T_Stack]: + if Result[T_Stack][Z_Stack]["analysis"]["results_whole_cyto"]: + self.Cyto_Intensities[filename][T_Stack].append([]) + self.Cyto_GPImage[filename][T_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole_cyto"][2]) + self.FullImage_Parameters_cyto[filename][T_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole_cyto"][0]["Parameters"]) + self.Cyto_GPPhasor_polar_all[filename][T_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole_cyto"][3]) + self.Cyto_Intensities[filename][T_Stack][Z_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole_cyto"][0]["Wavelengths (nm)"]) + self.Cyto_Intensities[filename][T_Stack][Z_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole_cyto"][0]["Norm. Intensity"]) + self.GPImage[filename][T_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole"][2]) + self.FullImage_Parameters[filename][T_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole"][0]["Parameters"]) + self.GPPhasor[filename][T_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole"][3]) + self.GPPhasor_polar_all[filename][T_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole"][3]) + self.Intensities[filename][T_Stack].append([]) + self.Intensities[filename][T_Stack][Z_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole"][0]["Wavelengths (nm)"]) + self.Intensities[filename][T_Stack][Z_Stack].append(Result[T_Stack][Z_Stack]["analysis"]["results_whole"][0]["Norm. Intensity"]) + + self.nobjects[filename][T_Stack].append(0) + self.Channellamda[filename][T_Stack].append([]) + self.GPPhasor_polar_obj[filename][T_Stack].append([]) + self.GPImage_per_object[filename][T_Stack].append([]) + self.Object_Parameters[filename][T_Stack].append([]) + self.Object_Morphology[filename][T_Stack].append([]) + self.Intensities_per_object[filename][T_Stack].append([]) + self.Object_Coordinates[filename][T_Stack].append([]) + self.Profile[filename][T_Stack].append([]) + self.MembraneSegments[filename][T_Stack].append([]) + self.Cytoprof[filename][T_Stack].append([]) + if Result[0][0]["analysis"]["results_whole_cyto"]: + self.Cyto_Image[filename][T_Stack].append([]) + self.Object_Parameters_cyto[filename][T_Stack].append([]) + self.Cyto_Intensities_per_object[filename][T_Stack].append([]) + self.Cyto_GPPhasor_polar_obj[filename][T_Stack].append([]) + + if len(Result[T_Stack][Z_Stack]["analysis"]["results_obj"])!=0: + self.nobjects[filename][T_Stack][Z_Stack]=len(Result[T_Stack][Z_Stack]["analysis"]["results_obj"]) + self.Channellamda[filename][T_Stack][Z_Stack].append(Lambdachannel) + self.GPPhasor_polar_obj[filename][T_Stack][Z_Stack]=[] + self.GPImage_per_object[filename][T_Stack][Z_Stack]=[] + self.Object_Parameters[filename][T_Stack][Z_Stack]=[] + self.Object_Morphology[filename][T_Stack][Z_Stack]=[] + self.Intensities_per_object[filename][T_Stack][Z_Stack]=[] + self.Object_Coordinates[filename][T_Stack][Z_Stack]=[] + self.Profile[filename][T_Stack][Z_Stack]=[] + self.MembraneSegments[filename][T_Stack][Z_Stack]=[] + self.Cytoprof[filename][T_Stack][Z_Stack]=[] + if Result[0][0]["analysis"]["results_whole_cyto"]: + self.Cyto_Image[filename][T_Stack][Z_Stack]=[] + self.Object_Parameters_cyto[filename][T_Stack][Z_Stack]=[] + self.Cyto_Intensities_per_object[filename][T_Stack][Z_Stack]=[] + self.Cyto_GPPhasor_polar_obj[filename][T_Stack][Z_Stack]=[] + + for objn in Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"]: + self.GPPhasor_polar_obj[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basicmembrane"][3]) + self.GPImage_per_object[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basicmembrane"][2]) + self.Object_Parameters[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basicmembrane"][0]["Parameters"]) + self.Object_Morphology[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["morphology"][2:]) + self.Intensities_per_object[filename][T_Stack][Z_Stack].append([]) + self.Intensities_per_object[filename][T_Stack][Z_Stack][int(objn)-1].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basicmembrane"][0]["Wavelengths (nm)"]) + self.Intensities_per_object[filename][T_Stack][Z_Stack][int(objn)-1].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basicmembrane"][0]["Norm. Intensity"]) + self.Object_Coordinates[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["morphology"][1]) + if len(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["profile"]) !=0: + self.Profile[filename][T_Stack][Z_Stack].append([]) + self.Profile[filename][T_Stack][Z_Stack][int(objn)-1].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["profile"][0]) + self.MembraneSegments[filename][T_Stack][Z_Stack].append([]) + self.MembraneSegments[filename][T_Stack][Z_Stack][int(objn)-1].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["profile"][6]) + else: + self.Profile[filename][T_Stack][Z_Stack].append([]) + self.MembraneSegments[filename][T_Stack][Z_Stack].append([]) + if len(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["objlinearization"]) !=0: + self.Cytoprof[filename][T_Stack][Z_Stack].append([]) + self.Cytoprof[filename][T_Stack][Z_Stack][int(objn)-1].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["objlinearization"]) + else: + self.Cytoprof[filename][T_Stack][Z_Stack].append([]) + + if len(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basiccyto"]) !=0: + + self.Cyto_Image[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basiccyto"][2]) + self.Object_Parameters_cyto[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basiccyto"][0]["Parameters"]) + self.Cyto_Intensities_per_object[filename][T_Stack][Z_Stack].append([]) + self.Cyto_Intensities_per_object[filename][T_Stack][Z_Stack][int(objn)-1].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basiccyto"][0]["Wavelengths (nm)"]) + self.Cyto_Intensities_per_object[filename][T_Stack][Z_Stack][int(objn)-1].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basiccyto"][0]["Norm. Intensity"]) + self.Cyto_GPPhasor_polar_obj[filename][T_Stack][Z_Stack].append(Resultstest[T_Stack][Z_Stack]["analysis"]["results_obj"][objn]["basicmembrane"][3]) + elif Result[0][0]["analysis"]["results_whole_cyto"]: + + self.Cyto_Image[filename][T_Stack][Z_Stack].append([]) + self.Object_Parameters_cyto[filename][T_Stack][Z_Stack].append([]) + self.Cyto_Intensities_per_object[filename][T_Stack][Z_Stack].append([]) + self.Cyto_GPPhasor_polar_obj[filename][T_Stack][Z_Stack].append([]) + else: + self.key[filename]="3dim" + if isinstance(Result, dict): + if Result["analysis"]["results_whole_cyto"]: + self.Cyto_Intensities[filename]=[] + self.Cyto_GPImage[filename]=Result["analysis"]["results_whole_cyto"][2] # GPImage + self.FullImage_Parameters_cyto[filename]=Result["analysis"]["results_whole_cyto"][0]["Parameters"] + self.Cyto_GPPhasor_polar_all[filename]=Result["analysis"]["results_whole_cyto"][3] #GPPhasor + self.Cyto_Intensities[filename].append(Result["analysis"]["results_whole_cyto"][0]["Wavelengths (nm)"]) + self.Cyto_Intensities[filename].append(Result["analysis"]["results_whole_cyto"][0]["Norm. Intensity"]) #Intensity per channel + self.GPImage[filename]=Result["analysis"]["results_whole"][2] # GPImage + self.FullImage_Parameters[filename]=Result["analysis"]["results_whole"][0]["Parameters"] # GPImage + self.GPPhasor[filename]=Result["analysis"]["results_whole"][3] #??? + self.GPPhasor_polar_all[filename]=Result["analysis"]["results_whole"][3] #GPPhasor + self.Intensities[filename]=[] + self.Intensities[filename].append(Result["analysis"]["results_whole"][0]["Wavelengths (nm)"]) + self.Intensities[filename].append(Result["analysis"]["results_whole"][0]["Norm. Intensity"]) + self.nobjects[filename]=0 + if len(Result["analysis"]["results_obj"])!=0: + self.nobjects[filename]=len(Resultstest["analysis"]["results_obj"]) + self.Object_Parameters[filename]=[] + self.Object_Morphology[filename]=[] + self.GPPhasor_polar_obj[filename]=[] + self.Intensities_per_object[filename]=[] + self.GPImage_per_object[filename]=[] + self.Object_Coordinates[filename]=[] + self.Channellamda[filename]=[] + self.Channellamda[filename]=Lambdachannel + self.Profile[filename]=[] + self.MembraneSegments[filename]=[] + self.Cytoprof[filename]=[] + if Result["analysis"]["results_whole_cyto"]: + self.Cyto_Intensities_per_object[filename]=[] + self.Cyto_GPPhasor_polar_obj[filename]=[] + self.Cyto_Image[filename]=[] + self.Object_Parameters_cyto[filename]=[] + for objn in Resultstest["analysis"]["results_obj"]: + self.GPPhasor_polar_obj[filename].append(Resultstest["analysis"]["results_obj"][objn]["basicmembrane"][3]) + self.GPImage_per_object[filename].append(Resultstest["analysis"]["results_obj"][objn]["basicmembrane"][2]) + self.Object_Parameters[filename].append(Resultstest["analysis"]["results_obj"][objn]["basicmembrane"][0]["Parameters"]) + self.Object_Morphology[filename].append(Resultstest["analysis"]["results_obj"][objn]["morphology"][2:]) + self.Intensities_per_object[filename].append([]) + self.Intensities_per_object[filename][int(objn)-1].append(Resultstest["analysis"]["results_obj"][objn]["basicmembrane"][0]["Wavelengths (nm)"]) + self.Intensities_per_object[filename][int(objn)-1].append(Resultstest["analysis"]["results_obj"][objn]["basicmembrane"][0]["Norm. Intensity"]) + self.Object_Coordinates[filename].append(Resultstest["analysis"]["results_obj"][objn]["morphology"][1]) + if len(Resultstest["analysis"]["results_obj"][objn]["profile"]) !=0: + self.Profile[filename].append([]) + self.Profile[filename][int(objn)-1].append(Resultstest["analysis"]["results_obj"][objn]["profile"][0]) + self.MembraneSegments[filename].append([]) + self.MembraneSegments[filename][int(objn)-1].append(Resultstest["analysis"]["results_obj"][objn]["profile"][6]) + else: + self.Profile[filename].append([]) + self.MembraneSegments[filename].append([]) + if len(Resultstest["analysis"]["results_obj"][objn]["objlinearization"]) !=0: + self.Cytoprof[filename].append([]) + self.Cytoprof[filename][int(objn)-1].append(Resultstest["analysis"]["results_obj"][objn]["objlinearization"]) + else: + self.Cytoprof[filename].append([]) + if len(Resultstest["analysis"]["results_obj"][objn]["basiccyto"]) !=0 : + + self.Cyto_Image[filename].append(Resultstest["analysis"]["results_obj"][objn]["basiccyto"][2]) + self.Object_Parameters_cyto[filename].append(Resultstest["analysis"]["results_obj"][objn]["basiccyto"][0]["Parameters"]) + self.Cyto_Intensities_per_object[filename].append([]) + self.Cyto_Intensities_per_object[filename][int(objn)-1].append(Resultstest["analysis"]["results_obj"][objn]["basiccyto"][0]["Wavelengths (nm)"]) + self.Cyto_Intensities_per_object[filename][int(objn)-1].append(Resultstest["analysis"]["results_obj"][objn]["basiccyto"][0]["Norm. Intensity"]) + self.Cyto_GPPhasor_polar_obj[filename].append(Resultstest["analysis"]["results_obj"][objn]["basicmembrane"][3]) + elif Result["analysis"]["results_whole_cyto"]: + self.Object_Parameters_cyto[filename].append([]) + self.Cyto_Image[filename].append([]) + self.Cyto_Intensities_per_object[filename].append([]) + self.Cyto_GPPhasor_polar_obj[filename].append([]) + + +def exception_hook(exctype, value, traceback_obj): + # Define the format of your log message + log_message = f"{'='*80}\n" # Separator line + log_message += f"Timestamp: {time.asctime(time.localtime())}\n" # Timestamp + log_message += f"Exception type: {exctype.__name__}\n" # Exception type + log_message += f"Exception message: {value}\n" # Exception message + log_message += "".join(traceback.format_tb(traceback_obj)) # Stack trace + + # Define the path to your log file + if getattr(sys, 'frozen', False): + # For standalone executables + current_directory =dirname(sys.executable) + else: + # For running as a script +# current_directory = dirname(abspath(__file__)) + # or + current_directory = getcwd() + log_file_path = join(current_directory, 'global_error_log.txt') + + # Write the log message to the file + with open(log_file_path, "a") as log_file: + log_file.write(log_message) + + """Custom exception hook.""" + QMessageBox.critical(None, "An exception was raised", f"Exception type: {exctype.__name__}\n{value}") + sys.exit(1) + +sys.excepthook = exception_hook + +if __name__ == "__main__": + app = QtWidgets.QApplication(sys.argv) + apply_dark_palette(app) + window = MainWindow() + # pyi_splash.close() + app.processEvents() + window.showMaximized() + sys.exit(app.exec_()) + #app.exec_() + with open(log_file_path, "a") as log_file: + log_file.write(log_message) + + """Custom exception hook.""" + QMessageBox.critical(None, "An exception was raised", f"Exception type: {exctype.__name__}\n{value}") + sys.exit(1) + +sys.excepthook = exception_hook + +if __name__ == "__main__": + app = QtWidgets.QApplication(sys.argv) + apply_dark_palette(app) + window = MainWindow() + # pyi_splash.close() + app.processEvents() + window.showMaximized() + sys.exit(app.exec_()) + #app.exec_() diff --git a/Python/VISION_V1.0.3_Env_Packages.yaml b/Python/VISION_V1.0.3_Env_Packages.yaml new file mode 100644 index 0000000..205cd8e --- /dev/null +++ b/Python/VISION_V1.0.3_Env_Packages.yaml @@ -0,0 +1,393 @@ +name: GP-Analyzer +channels: + - anaconda + - conda-forge + - defaults +dependencies: + - abseil-cpp=20220623.0=h0e60522_0 + - aicsimageio=4.10.0=pyhd8ed1ab_1 + - aiohttp=3.9.3=py311h2bbff1b_0 + - aiosignal=1.2.0=pyhd3eb1b0_0 + - alabaster=0.7.12=pyhd3eb1b0_0 + - altgraph=0.17.3=py311haa95532_0 + - aom=3.6.0=hd77b12b_0 + - arrow=1.2.3=py311haa95532_1 + - arrow-cpp=11.0.0=h57928b3_5_cpu + - asciitree=0.3.3=py_2 + - astroid=2.14.2=py311haa95532_0 + - asttokens=2.0.5=pyhd3eb1b0_0 + - atomicwrites=1.4.0=py_0 + - attrs=23.1.0=py311haa95532_0 + - autopep8=1.6.0=pyhd3eb1b0_1 + - aws-c-auth=0.6.25=he7784bb_4 + - aws-c-cal=0.5.21=h85b6bf8_1 + - aws-c-common=0.8.12=hcfcfb64_0 + - aws-c-compression=0.2.16=hf8831c8_4 + - aws-c-event-stream=0.2.20=h2d3f8d5_2 + - aws-c-http=0.7.5=h4b9a195_3 + - aws-c-io=0.13.18=h7ae7922_3 + - aws-c-mqtt=0.8.6=hbdca61f_9 + - aws-c-s3=0.2.6=hf99a3b4_0 + - aws-c-sdkutils=0.1.7=hf8831c8_4 + - aws-checksums=0.1.14=hf8831c8_4 + - aws-crt-cpp=0.19.8=h65e3961_7 + - aws-sdk-cpp=1.10.57=hd5bd07e_7 + - babel=2.11.0=py311haa95532_0 + - bcrypt=3.2.0=py311h2bbff1b_1 + - beautifulsoup4=4.12.2=py311haa95532_0 + - binaryornot=0.4.4=pyhd3eb1b0_1 + - black=23.11.0=py311haa95532_0 + - blas=1.0=mkl + - bleach=4.1.0=pyhd3eb1b0_0 + - blosc=1.21.5=hdccc3a2_0 + - bokeh=3.3.4=py311h746a85d_0 + - boost-cpp=1.85.0=h6f18f0d_2 + - bottleneck=1.3.5=py311h5bb9823_0 + - brotli=1.0.9=h2bbff1b_7 + - brotli-bin=1.0.9=h2bbff1b_7 + - brotli-python=1.0.9=py311hd77b12b_7 + - bzip2=1.0.8=he774522_0 + - c-ares=1.19.1=h2bbff1b_0 + - c-blosc2=2.12.0=h2f4ed9d_0 + - ca-certificates=2024.7.2=haa95532_0 + - certifi=2024.7.4=py311haa95532_0 + - cffi=1.16.0=py311h2bbff1b_0 + - cfitsio=4.2.0=h9ebe7e4_0 + - chardet=4.0.0=py311haa95532_1003 + - charls=2.4.2=h1537add_0 + - charset-normalizer=2.0.4=pyhd3eb1b0_0 + - click=8.1.7=py311haa95532_0 + - click-default-group=1.2.2=py311haa95532_0 + - cloudpickle=2.2.1=py311haa95532_0 + - colorama=0.4.6=py311haa95532_0 + - comm=0.1.2=py311haa95532_0 + - contourpy=1.2.0=py311h59b6b97_0 + - cookiecutter=2.5.0=py311haa95532_0 + - cryptography=41.0.7=py311h89fc84f_0 + - cycler=0.11.0=pyhd3eb1b0_0 + - cytoolz=0.12.2=py311h2bbff1b_0 + - czifile=2019.7.2=pyh9f0ad1d_0 + - dask=2023.11.0=py311haa95532_0 + - dask-core=2023.11.0=py311haa95532_0 + - dataclasses=0.8=pyh6d0b6a4_7 + - dav1d=1.2.1=h2bbff1b_0 + - debugpy=1.6.7=py311hd77b12b_0 + - decorator=5.1.1=pyhd3eb1b0_0 + - defusedxml=0.7.1=pyhd3eb1b0_0 + - diff-match-patch=20200713=pyhd3eb1b0_0 + - dill=0.3.7=py311haa95532_0 + - distributed=2023.11.0=py311haa95532_0 + - docformatter=1.5.1=pyhd8ed1ab_0 + - docstring-to-markdown=0.11=py311haa95532_0 + - docutils=0.18.1=py311haa95532_3 + - elementpath=4.2.0=pyhd8ed1ab_0 + - entrypoints=0.4=py311haa95532_0 + - executing=0.8.3=pyhd3eb1b0_0 + - fasteners=0.16.3=pyhd3eb1b0_0 + - ffmpeg=4.2.2=he774522_0 + - flake8=6.0.0=py311haa95532_0 + - fonttools=4.25.0=pyhd3eb1b0_0 + - freetype=2.12.1=hdaf720e_2 + - frozenlist=1.4.0=py311h2bbff1b_0 + - fsspec=2023.10.0=py311haa95532_0 + - future=0.18.3=py311haa95532_0 + - gettext=0.22.5=h5728263_2 + - gettext-tools=0.22.5=h7d00a51_2 + - gflags=2.2.2=hd77b12b_1 + - giflib=5.2.1=h8cc25b3_3 + - glib=2.80.3=h7025463_1 + - glib-tools=2.80.3=h4394cf3_1 + - glog=0.6.0=h4797de2_0 + - grpc-cpp=1.51.1=h9c18f36_1 + - gst-plugins-base=1.22.9=h001b923_1 + - gstreamer=1.22.9=hb4038d2_1 + - heapdict=1.0.1=pyhd3eb1b0_0 + - icc_rt=2022.1.0=h6049295_2 + - icu=70.1=h0e60522_0 + - idna=3.4=py311haa95532_0 + - imagecodecs=2023.1.23=py311h8318e5d_0 + - imagecodecs-lite=2019.12.3=py311h59ca53f_7 + - imageio=2.33.1=py311haa95532_0 + - imageio-ffmpeg=0.4.9=pyhd8ed1ab_0 + - imagesize=1.4.1=py311haa95532_0 + - importlib-metadata=7.0.1=py311haa95532_0 + - importlib_metadata=7.0.1=hd3eb1b0_0 + - inflection=0.5.1=py311haa95532_0 + - intel-openmp=2023.1.0=h59b6b97_46320 + - intervaltree=3.1.0=pyhd3eb1b0_0 + - ipykernel=6.28.0=py311haa95532_0 + - ipython=8.20.0=py311haa95532_0 + - ipython_genutils=0.2.0=pyhd3eb1b0_1 + - isort=5.9.3=pyhd3eb1b0_0 + - jaraco.classes=3.2.1=pyhd3eb1b0_0 + - jedi=0.18.1=py311haa95532_1 + - jellyfish=1.0.1=py311h36a85e1_0 + - jinja2=3.1.3=py311haa95532_0 + - joblib=1.2.0=py311haa95532_0 + - jpeg=9e=h2bbff1b_1 + - jsonschema=4.19.2=py311haa95532_0 + - jsonschema-specifications=2023.7.1=py311haa95532_0 + - jupyter_client=8.6.0=py311haa95532_0 + - jupyter_core=5.5.0=py311haa95532_0 + - jupyterlab_pygments=0.2.2=py311haa95532_0 + - jxrlib=1.1=he774522_2 + - keyring=23.13.1=py311haa95532_0 + - kiwisolver=1.4.4=py311hd77b12b_0 + - krb5=1.20.1=h5b6d351_0 + - lazy-object-proxy=1.6.0=py311h2bbff1b_0 + - lazy_loader=0.3=py311haa95532_0 + - lcms2=2.15=ha5c8aab_0 + - lerc=4.0.0=h63175ca_0 + - libabseil=20220623.0=cxx17_h1a56200_6 + - libaec=1.1.3=h63175ca_0 + - libarrow=11.0.0=hbddb5ef_5_cpu + - libasprintf=0.22.5=h5728263_2 + - libasprintf-devel=0.22.5=h5728263_2 + - libavif=0.11.1=h2bbff1b_0 + - libboost=1.85.0=h9a677ad_2 + - libboost-devel=1.85.0=h91493d7_2 + - libboost-headers=1.85.0=h57928b3_2 + - libbrotlicommon=1.0.9=h2bbff1b_7 + - libbrotlidec=1.0.9=h2bbff1b_7 + - libbrotlienc=1.0.9=h2bbff1b_7 + - libclang=15.0.7=default_h3a3e6c3_5 + - libclang13=15.0.7=default_hf64faad_5 + - libcrc32c=1.1.2=hd77b12b_0 + - libcurl=8.1.2=h68f0423_0 + - libdeflate=1.17=h2bbff1b_1 + - libevent=2.1.12=h56d1f94_1 + - libffi=3.4.4=hd77b12b_0 + - libgettextpo=0.22.5=h5728263_2 + - libgettextpo-devel=0.22.5=h5728263_2 + - libglib=2.80.3=h7025463_1 + - libgoogle-cloud=2.7.0=h5fc25aa_1 + - libgrpc=1.51.1=hb074f84_1 + - libiconv=1.17=hcfcfb64_2 + - libintl=0.22.5=h5728263_2 + - libintl-devel=0.22.5=h5728263_2 + - libogg=1.3.5=h2bbff1b_1 + - libpng=1.6.43=h19919ed_0 + - libpq=12.2=hb652d5d_1 + - libprotobuf=3.21.12=h12be248_2 + - libsodium=1.0.18=h62dcd97_0 + - libspatialindex=1.9.3=h6c2663c_0 + - libsqlite=3.46.0=h2466b09_0 + - libssh2=1.10.0=he2ea4bf_2 + - libthrift=0.18.0=h9ce19ad_0 + - libtiff=4.5.0=h8a3f274_0 + - libutf8proc=2.8.0=h82a8f57_0 + - libvorbis=1.3.7=he774522_0 + - libwebp-base=1.3.2=h2bbff1b_0 + - libxcb=1.13=hcd874cb_1004 + - libxml2=2.12.7=h0f24e4e_4 + - libxslt=1.1.39=h3df6e99_0 + - libzlib=1.3.1=h2466b09_1 + - libzopfli=1.0.3=ha925a31_0 + - locket=1.0.0=py311haa95532_0 + - lxml=5.2.2=py311h12967d8_0 + - lz4=4.3.2=py311h2bbff1b_0 + - lz4-c=1.9.4=h2bbff1b_0 + - m2w64-gcc-libgfortran=5.3.0=6 + - m2w64-gcc-libs=5.3.0=7 + - m2w64-gcc-libs-core=5.3.0=7 + - m2w64-gmp=6.1.0=2 + - m2w64-libwinpthread-git=5.0.0.4634.697f757=2 + - markdown-it-py=2.2.0=py311haa95532_1 + - markupsafe=2.1.3=py311h2bbff1b_0 + - matplotlib=3.9.1=py311h1ea47a8_0 + - matplotlib-base=3.9.1=py311h8f1b1e4_0 + - matplotlib-inline=0.1.6=py311haa95532_0 + - matplotlib-scalebar=0.8.1=pyhd8ed1ab_0 + - mccabe=0.7.0=pyhd3eb1b0_0 + - mdurl=0.1.0=py311haa95532_0 + - mistune=2.0.4=py311haa95532_0 + - mkl=2023.1.0=h6b88ed4_46358 + - mkl-service=2.4.0=py311h2bbff1b_1 + - mkl_fft=1.3.8=py311h2bbff1b_0 + - mkl_random=1.2.4=py311h59b6b97_0 + - more-itertools=10.1.0=py311haa95532_0 + - mpmath=1.3.0=py311haa95532_0 + - msgpack-python=1.0.3=py311h59b6b97_0 + - msys2-conda-epoch=20160418=1 + - multidict=6.0.4=py311h2bbff1b_0 + - munkres=1.1.4=py_0 + - mypy_extensions=1.0.0=py311haa95532_0 + - nbclient=0.8.0=py311haa95532_0 + - nbconvert=7.10.0=py311haa95532_0 + - nbformat=5.9.2=py311haa95532_0 + - nest-asyncio=1.5.6=py311haa95532_0 + - networkx=3.1=py311haa95532_0 + - numcodecs=0.11.0=py311hd77b12b_0 + - numexpr=2.8.7=py311h1fcbade_0 + - numpy=1.24.3=py311hdab7c0b_1 + - numpy-base=1.24.3=py311hd01c5d8_1 + - numpydoc=1.5.0=py311haa95532_0 + - ome-types=0.4.5=pyhd8ed1ab_0 + - ome-zarr=0.8.3=pyhd8ed1ab_0 + - openjpeg=2.5.0=ha2aaf27_2 + - openssl=3.0.14=h827c3e9_0 + - orc=1.8.2=hada7b9e_2 + - packaging=23.1=py311haa95532_0 + - palettable=3.3.0=pyhd3eb1b0_0 + - pandas=2.1.4=py311hf62ec03_0 + - pandocfilters=1.5.0=pyhd3eb1b0_0 + - paramiko=2.8.1=pyhd3eb1b0_0 + - parso=0.8.3=pyhd3eb1b0_0 + - partd=1.4.1=py311haa95532_0 + - pathspec=0.10.3=py311haa95532_0 + - patsy=0.5.3=py311haa95532_0 + - pcre2=10.44=h3d7b363_0 + - pefile=2022.5.30=py311haa95532_0 + - pexpect=4.8.0=pyhd3eb1b0_3 + - pickleshare=0.7.5=pyhd3eb1b0_1003 + - pims=0.6.1=py311haa95532_0 + - pint=0.23=pyhd8ed1ab_0 + - pip=23.3.1=py311haa95532_0 + - platformdirs=3.10.0=py311haa95532_0 + - pluggy=1.0.0=py311haa95532_1 + - ply=3.11=py311haa95532_0 + - pooch=1.7.0=py311haa95532_0 + - prompt-toolkit=3.0.43=py311haa95532_0 + - prompt_toolkit=3.0.43=hd3eb1b0_0 + - psutil=5.9.0=py311h2bbff1b_0 + - pthread-stubs=0.3=h3c9f919_1 + - ptyprocess=0.7.0=pyhd3eb1b0_2 + - pure_eval=0.2.2=pyhd3eb1b0_0 + - pyarrow=11.0.0=py311h8a3a540_1 + - pycodestyle=2.10.0=py311haa95532_0 + - pycparser=2.21=pyhd3eb1b0_0 + - pydantic=1.10.12=py311h2bbff1b_1 + - pydantic-compat=0.1.1=pyhd8ed1ab_0 + - pydocstyle=6.3.0=py311haa95532_0 + - pyflakes=3.0.1=py311haa95532_0 + - pygments=2.15.1=py311haa95532_1 + - pyinstaller=6.9.0=py311ha408274_0 + - pyinstaller-hooks-contrib=2024.7=pyhd8ed1ab_0 + - pylint=2.16.2=py311haa95532_0 + - pylint-venv=2.3.0=py311haa95532_0 + - pyls-spyder=0.4.0=pyhd3eb1b0_0 + - pynacl=1.5.0=py311h8cc25b3_0 + - pyopenssl=24.0.0=py311haa95532_0 + - pyparsing=3.0.9=py311haa95532_0 + - pyqt=5.15.10=py311hd77b12b_0 + - pyqt5-sip=12.13.0=py311h2bbff1b_0 + - pyqtwebengine=5.15.10=py311hd77b12b_0 + - pysocks=1.7.1=py311haa95532_0 + - python=3.11.0=hcf16a7b_0_cpython + - python-dateutil=2.8.2=pyhd3eb1b0_0 + - python-fastjsonschema=2.16.2=py311haa95532_0 + - python-lmdb=1.4.1=py311hd77b12b_0 + - python-lsp-black=1.2.1=py311haa95532_0 + - python-lsp-jsonrpc=1.0.0=pyhd3eb1b0_0 + - python-lsp-server=1.7.2=py311haa95532_0 + - python-slugify=5.0.2=pyhd3eb1b0_0 + - python-tzdata=2023.3=pyhd3eb1b0_0 + - python_abi=3.11=2_cp311 + - pytoolconfig=1.2.6=py311haa95532_0 + - pytz=2023.3.post1=py311haa95532_0 + - pywavelets=1.5.0=py311hd7041d2_0 + - pywin32=305=py311h2bbff1b_0 + - pywin32-ctypes=0.2.2=py311h1ea47a8_1 + - pyyaml=6.0.1=py311h2bbff1b_0 + - pyzmq=25.1.2=py311hd77b12b_0 + - qdarkstyle=3.0.2=pyhd3eb1b0_0 + - qhull=2020.2=h59b6b97_2 + - qstylizer=0.2.2=py311haa95532_0 + - qt-main=5.15.8=h720456b_6 + - qt-webengine=5.15.9=h5bd16bc_7 + - qtawesome=1.2.2=py311haa95532_0 + - qtconsole=5.4.2=py311haa95532_0 + - qtpy=2.4.1=py311haa95532_0 + - re2=2023.02.01=h63175ca_0 + - readlif=0.6.5=pyhd8ed1ab_0 + - referencing=0.30.2=py311haa95532_0 + - requests=2.31.0=py311haa95532_0 + - resource_backed_dask_array=0.1.0=pyhd8ed1ab_1 + - rich=13.3.5=py311haa95532_0 + - rope=1.7.0=py311haa95532_0 + - rpds-py=0.10.6=py311h062c2fa_0 + - rtree=1.0.1=py311h2eaa2aa_0 + - scikit-image=0.20.0=py311h3513d60_0 + - scikit-learn=1.3.0=py311hf62ec03_0 + - scipy=1.11.4=py311hc1ccb85_0 + - seaborn=0.13.2=hd8ed1ab_0 + - seaborn-base=0.13.2=pyhd8ed1ab_0 + - seaborn-image=0.9.0=pyhd8ed1ab_0 + - setuptools=68.2.2=py311haa95532_0 + - sip=6.7.12=py311hd77b12b_0 + - six=1.16.0=pyhd3eb1b0_1 + - slicerator=1.1.0=py311haa95532_0 + - snappy=1.1.10=h6c2663c_1 + - snowballstemmer=2.2.0=pyhd3eb1b0_0 + - sortedcontainers=2.4.0=pyhd3eb1b0_0 + - soupsieve=2.5=py311haa95532_0 + - sphinx=5.0.2=py311haa95532_0 + - sphinxcontrib-applehelp=1.0.2=pyhd3eb1b0_0 + - sphinxcontrib-devhelp=1.0.2=pyhd3eb1b0_0 + - sphinxcontrib-htmlhelp=2.0.0=pyhd3eb1b0_0 + - sphinxcontrib-jsmath=1.0.1=pyhd3eb1b0_0 + - sphinxcontrib-qthelp=1.0.3=pyhd3eb1b0_0 + - sphinxcontrib-serializinghtml=1.1.5=pyhd3eb1b0_0 + - spyder=5.4.3=py311haa95532_1 + - spyder-kernels=2.4.4=py311haa95532_0 + - sqlite=3.41.2=h2bbff1b_0 + - stack_data=0.2.0=pyhd3eb1b0_0 + - statsmodels=0.14.0=py311hd7041d2_0 + - sympy=1.11.1=py311haa95532_0 + - tbb=2021.8.0=h59b6b97_0 + - tblib=1.7.0=pyhd3eb1b0_0 + - text-unidecode=1.3=pyhd3eb1b0_0 + - textdistance=4.2.1=pyhd3eb1b0_0 + - threadpoolctl=2.2.0=pyh0d69192_0 + - three-merge=0.1.1=pyhd3eb1b0_0 + - tifffile=2023.2.28=pyhd8ed1ab_0 + - tinycss2=1.2.1=py311haa95532_0 + - tk=8.6.12=h2bbff1b_0 + - toml=0.10.2=pyhd3eb1b0_0 + - tomlkit=0.11.1=py311haa95532_0 + - toolz=0.12.0=py311haa95532_0 + - toposort=1.10=pyhd8ed1ab_0 + - tornado=6.3.3=py311h2bbff1b_0 + - traitlets=5.7.1=py311haa95532_0 + - typing-extensions=4.9.0=py311haa95532_1 + - typing_extensions=4.9.0=py311haa95532_1 + - tzdata=2023d=h04d1e81_0 + - ucrt=10.0.20348.0=haa95532_0 + - ujson=5.4.0=py311hd77b12b_0 + - unidecode=1.2.0=pyhd3eb1b0_0 + - untokenize=0.1.1=py_0 + - urllib3=1.26.18=py311haa95532_0 + - utf8proc=2.6.1=h2bbff1b_1 + - vc=14.2=h21ff451_1 + - vc14_runtime=14.38.33130=h82b7239_18 + - vs2015_runtime=14.38.33130=hcb4865c_18 + - watchdog=2.1.6=py311haa95532_0 + - wcwidth=0.2.5=pyhd3eb1b0_0 + - webencodings=0.5.1=py311haa95532_1 + - whatthepatch=1.0.2=py311haa95532_0 + - wheel=0.41.2=py311haa95532_0 + - win_inet_pton=1.1.0=py311haa95532_0 + - wrapt=1.14.1=py311h2bbff1b_0 + - xarray=2022.11.0=py311haa95532_0 + - xlsxwriter=3.1.9=pyhd8ed1ab_0 + - xmlschema=3.0.1=pyhd8ed1ab_0 + - xmltodict=0.13.0=pyhd8ed1ab_0 + - xorg-libxau=1.0.11=hcd874cb_0 + - xorg-libxdmcp=1.1.3=hcd874cb_0 + - xsdata=23.7=pyhd8ed1ab_0 + - xyzservices=2022.9.0=py311haa95532_1 + - xz=5.2.10=h8cc25b3_1 + - yaml=0.2.5=he774522_0 + - yapf=0.31.0=pyhd3eb1b0_0 + - yarl=1.9.3=py311h2bbff1b_0 + - zarr=2.13.3=py311haa95532_0 + - zeromq=4.3.5=hd77b12b_0 + - zfp=1.0.0=hd77b12b_0 + - zict=3.0.0=py311haa95532_0 + - zipp=3.17.0=py311haa95532_0 + - zlib=1.3.1=h2466b09_1 + - zlib-ng=2.0.7=h2bbff1b_0 + - zstd=1.5.6=h0ea2cb4_0 + - pip: + - nd2reader==3.3.0 + - pillow==10.4.0 diff --git a/Python/ui/gui_V1.0.3.ui b/Python/ui/gui_V1.0.3.ui new file mode 100644 index 0000000..b52e56b --- /dev/null +++ b/Python/ui/gui_V1.0.3.ui @@ -0,0 +1,5539 @@ + + + MainWindow + + + + 0 + 0 + 1948 + 1032 + + + + + 0 + 0 + + + + + PreferDefault + true + + + + VISION + + + Qt::LeftToRight + + + false + + + + + 0 + 0 + + + + Qt::LeftToRight + + + + + + 10 + + + 10 + + + + + + + + + + 75 + 20 + + + + Load Files + + + + + + + + 75 + 20 + + + + Load Folder + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 100 + 20 + + + + + + + + false + + + + 75 + 20 + + + + Unselects all selections in table + + + Clear Selection + + + + + + + false + + + + 75 + 20 + + + + Delete Entry + + + + + + + false + + + + 75 + 20 + + + + Delete Table + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + + + 0 + 0 + + + + + 100 + 100 + + + + + 522 + 150 + + + + QAbstractScrollArea::AdjustIgnored + + + false + + + QAbstractItemView::AnyKeyPressed|QAbstractItemView::EditKeyPressed + + + false + + + QAbstractItemView::ExtendedSelection + + + QAbstractItemView::SelectRows + + + + Name + + + + + Directory + + + + + + + + + + + + false + + + + 0 + 20 + + + + Test Mask + + + + + + + false + + + + 0 + 20 + + + + Run Analysis + + + + + + + false + + + + 0 + 20 + + + + + + + Object Detection + + + false + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activatea Object linearization. &quot;Object Detection has to be activated&quot;</p><p>(Can significantly slow down the calculation for images with high number of pixels and t-,z-, tz-Stack images)</p></body></html> + + + Linearizer + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + true + + + + 560 + 470 + + + + + 522 + 16777215 + + + + 0 + + + + Membrane Settings + + + + + 1 + 132 + 551 + 311 + + + + 0 + + + + Global Membrane Masking Options + + + + false + + + + 17 + 10 + 201 + 20 + + + + + 0 + 20 + + + + <html><head/><body><p>Aktivates Table and Settings in &quot;Detailed Membrane Masking Options&quot; </p></body></html> + + + Use Global Membrane Mask Settings + + + true + + + + + + 247 + 210 + 291 + 62 + + + + + 0 + 0 + + + + Binning + + + + + + false + + + + 0 + 0 + + + + + 70 + 20 + + + + <html><head/><body><p>Lowest binning value for colorbar and histograms. In order for the changes to become active, images must be reanalyzed (run) again.</p></body></html> + + + 2 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + 1.000000000000000 + + + -1.000000000000000 + + + + + + + false + + + + 0 + 0 + + + + + 70 + 20 + + + + <html><head/><body><p>Highest binning value for colorbar and histograms. In order for the changes to become active, images must be analyzed (run) again.</p></body></html> + + + 2 + + + -100.000000000000000 + + + 100000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 0 + 0 + + + + + 70 + 20 + + + + <html><head/><body><p>Binn range for colorbar and histograms. In order for the changes to become active, images must be analyzed (run) again.</p></body></html> + + + 3 + + + 0.001000000000000 + + + 10000.000000000000000 + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 30 + 241 + 211 + + + + Thresholding Options + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Aktivate if, a specific channel should be used for Thresholding.</p></body></html> + + + Specific Channel + + + false + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Channel corresponding to A in the equation below.</p></body></html> + + + + + + + + 0 + 20 + + + + Thesholding Mode + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Automatic detection of thershold level with Otsus algorythm, or manual choice. (further methods will come in future)</p></body></html> + + + + Otsu + + + + + Manual + + + + + + + + + 0 + 20 + + + + Manual Cutoff Level + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Manual threshold - everything below is evaluated as NaN </p></body></html> + + + 1 + + + 65535 + + + 8 + + + + + + + + 0 + 20 + + + + Signal to Noise Ratio + + + + + + + false + + + + 0 + 0 + + + + + 70 + 20 + + + + 4 + + + 100000.000000000000000 + + + 0.500000000000000 + + + 3.000000000000000 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p><br/></p></body></html> + + + Background Compen. + + + false + + + + + + + + 0 + 20 + + + + Background Mean + + + + + + + false + + + + 70 + 20 + + + + 4 + + + 10000.000000000000000 + + + 0.500000000000000 + + + 1.000000000000000 + + + + + + + + 0 + 20 + + + + Background StdDev. + + + + + + + false + + + + 70 + 20 + + + + 4 + + + 10000.000000000000000 + + + 0.500000000000000 + + + 1.000000000000000 + + + + + + + + + 247 + 0 + 291 + 211 + + + + Masking Options + + + + + + false + + + + 70 + 20 + + + + 0.500000000000000 + + + + + + + false + + + + 50 + 20 + + + + <html><head/><body><p>y-dimention for dilation tool</p></body></html> + + + 1 + + + 3 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activate compression of mask. Compression of the mask can help in profiling the membrane and cytosolic profiling.</p></body></html> + + + Compress + + + + + + + + 50 + 20 + + + + Dimension 2 + + + + + + + false + + + + 70 + 20 + + + + 1 + + + 2 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activate Dilation of Mask. Dilation of the mask can help in profiling the membrane and cytosolic profiling.</p></body></html> + + + Dilate + + + false + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activatse removement of objects from mask. Renmoving objects from mask can help in profiling the membrane and cytosolic profiling.</p></body></html> + + + Remove Object + + + + + + + false + + + + 70 + 20 + + + + 4 + + + 999999.000000000000000 + + + 0.000500000000000 + + + 0.010000000000000 + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Dilation tool shape</p></body></html> + + + + octagon + + + + + disk + + + + + square + + + + + + + + false + + + + 50 + 20 + + + + <html><head/><body><p>x-dimention for dilation tool</p></body></html> + + + 1 + + + 3 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Hole filling of the mask can help in profiling the membrane.</p></body></html> + + + Fill Holes + + + + + + + + 50 + 20 + + + + Dimension 1 + + + + + + + false + + + + 70 + 20 + + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Dilation tool shape</p></body></html> + + + + No Filter + + + + + Gaussian + + + + + Mode + + + + + Median + + + + + Mean + + + + + Geometric_mean + + + + + Majority + + + + + Minimum + + + + + Maximum + + + + + Sum + + + + + Gradient + + + + + Entropy + + + + + + + + + + Detailed Membrane Masking Options + + + + false + + + + 5 + 30 + 501 + 211 + + + + + 501 + 211 + + + + QFrame::StyledPanel + + + true + + + false + + + 10 + + + + Specific Channel Wavelength + + + + + Thresholding Mode + + + + + Manual Cutoff Level + + + + + Signal to Noise Ratio + + + + + Background Mean + + + + + Background StdDev + + + + + Compression True/False + + + + + Compression Value + + + + + Remove Object + + + + + Fill Holes + + + + + Dilate True/False + + + + + Dilation Shape + + + + + Dilation Shape Dimmension 1 + + + + + Dilation Shape Dimmension 2 + + + + + Filter Type + + + + + Filter Value + + + + + + + 10 + 3 + 71 + 20 + + + + + 0 + 20 + + + + Z-Stack Pos + + + + + false + + + + 90 + 3 + 51 + 20 + + + + + 0 + 20 + + + + <html><head/><body><p>Selection of Z-Slice</p></body></html> + + + + + false + + + + 266 + 4 + 231 + 23 + + + + + 0 + 20 + + + + <html><head/><body><p>Transferes Global Masking Settings to all Slices</p></body></html> + + + Transfer Global Membrane Settings + + + + + + + false + + + + 120 + 90 + 103 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to D in the equation.</p></body></html> + + + + + + 11 + 5 + 104 + 20 + + + + + 0 + 20 + + + + Channel Setting: + + + + + + 11 + 33 + 104 + 21 + + + + + 0 + 20 + + + + + 50 + false + + + + A + + + Qt::AutoText + + + Qt::AlignCenter + + + + + + 11 + 72 + 104 + 22 + + + + + 0 + 20 + + + + C + + + Qt::AlignCenter + + + + + + 120 + 72 + 103 + 22 + + + + + 0 + 20 + + + + 1 + + + D + + + Qt::AlignCenter + + + + + false + + + + 11 + 90 + 104 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to C in the equation.</p></body></html> + + + + + false + + + + 11 + 50 + 104 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to A in the equation.</p></body></html> + + + + + false + + + + 120 + 50 + 103 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to B in the equation.</p></body></html> + + + + + + 120 + 33 + 103 + 21 + + + + + 0 + 20 + + + + + 50 + false + + + + B + + + Qt::AlignCenter + + + + + + 250 + 50 + 256 + 71 + + + + + 0 + 0 + + + + + 256 + 71 + + + + <html><head/><body><p>Enter analysis Equation here:</p><p><br/>e.g. (A - B) / (A + B) for GP-Analysis (Default)</p></body></html> + + + (A - B) / (A + B) + + + + + false + + + + 251 + 7 + 133 + 20 + + + + + 0 + 0 + + + + + 0 + 20 + + + + <html><head/><body><p>Activate Membrane Profiling. &quot;Object Detection has to be activated&quot;</p><p><br/></p><p> (Can significantly slow down the calculation for images with high number of pixels and t-,z-, tz-Stack images)</p></body></html> + + + Membrane Profiler + + + + + false + + + + 384 + 27 + 121 + 22 + + + + + 0 + 0 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to B in the equation below.</p></body></html> + + + + + false + + + + 384 + 7 + 121 + 20 + + + + + 0 + 0 + + + + + 0 + 20 + + + + <html><head/><body><p>Activates Additional Profiling Channel e.g. ProteinChannel. &quot;Object Detection &amp; Membrane Profiling has to be activated&quot;</p></body></html> + + + Colocalization + + + + + + 251 + 27 + 133 + 22 + + + + + 0 + 20 + + + + Equation + + + + + true + + + + 122 + 7 + 100 + 23 + + + + + 100 + 100 + + + + <html><head/><body><p>Sets Channels of all loaded images to the current used one. (If Possible)</p></body></html> + + + globalize Channels + + + + + + Cytosol Settings + + + + true + + + + 1 + 132 + 551 + 311 + + + + + 0 + 0 + + + + + 560 + 16777215 + + + + 0 + + + + Global Cytosol Masking Options + + + + false + + + + 17 + 10 + 191 + 20 + + + + + 0 + 20 + + + + <html><head/><body><p>Aktivates Table and Settings in &quot;Detailed Cytosol Masking Options&quot; </p></body></html> + + + Use Global Cytosol Mask Settings + + + true + + + + + + 247 + 210 + 291 + 62 + + + + Binning + + + + + + false + + + + 0 + 0 + + + + + 70 + 20 + + + + <html><head/><body><p>Lowest binning value for colorbar and histograms. In order for the changes to become active, images must be reanalyzed (run) again.</p></body></html> + + + 2 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + 1.000000000000000 + + + -1.000000000000000 + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Highest binning value for colorbar and histograms. In order for the changes to become active, images must be reanalyzed (run) again.</p></body></html> + + + 2 + + + -100000000.000000000000000 + + + 100000000.000000000000000 + + + 1.000000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 0 + 0 + + + + + 70 + 20 + + + + <html><head/><body><p>Distance between binning values for colorbar and histograms. In order for the changes to become active, images must be reanalyzed (run) again.</p></body></html> + + + 3 + + + 0.001000000000000 + + + 10000.000000000000000 + + + 0.100000000000000 + + + 0.100000000000000 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 0 + 30 + 241 + 211 + + + + Thresholding Options + + + + + + false + + + + 0 + 20 + + + + Aktivate if, a specific channel should be used for Thresholding. + + + Specific Channel + + + false + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Channel corresponding to A in the equation below.</p></body></html> + + + + + + + + 0 + 20 + + + + Thesholding Mode + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Automatic detection of thershold level with Otsus algorythm, or manual choice</p></body></html> + + + + Otsu + + + + + Manual + + + + + + + + + 0 + 20 + + + + Manual Cutoff Level + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Manual threshold - everything below is evaluated as NaN </p></body></html> + + + 1 + + + 65535 + + + 8 + + + + + + + + 0 + 20 + + + + Signal to Noise Ratio + + + + + + + false + + + + 70 + 20 + + + + 4 + + + 100000.000000000000000 + + + 0.500000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p><br/></p></body></html> + + + Background Compen. + + + false + + + + + + + + 0 + 20 + + + + Background Mean. + + + + + + + false + + + + 70 + 20 + + + + 4 + + + 10000.000000000000000 + + + 0.500000000000000 + + + 1.000000000000000 + + + + + + + + 0 + 20 + + + + Background StdDev. + + + + + + + false + + + + 70 + 20 + + + + 4 + + + 10000000.000000000000000 + + + 0.500000000000000 + + + 1.000000000000000 + + + + + + + + + 247 + 0 + 291 + 211 + + + + Masking Options + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activate compression of mask.</p></body></html> + + + Compress + + + + + + + false + + + + 70 + 20 + + + + 4 + + + 999999.000000000000000 + + + 0.000500000000000 + + + 0.010000000000000 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activatse removement of objects from mask</p></body></html> + + + Remove Object + + + + + + + false + + + + 70 + 20 + + + + 1 + + + 2 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activate hole filling of mask</p></body></html> + + + Fill Holes + + + + + + + false + + + + 70 + 20 + + + + 0.500000000000000 + + + + + + + + 50 + 20 + + + + Dimension 1 + + + + + + + false + + + + 0 + 20 + + + + <html><head/><body><p>Activate Dilation of Mask.</p></body></html> + + + Dilate + + + false + + + + + + + false + + + + 0 + 0 + + + + + 70 + 20 + + + + <html><head/><body><p>Dilation tool shape</p></body></html> + + + + octagon + + + + + disk + + + + + square + + + + + + + + false + + + + 50 + 20 + + + + <html><head/><body><p>x-dimention for dilation tool</p></body></html> + + + 1 + + + 3 + + + + + + + + 50 + 20 + + + + Dimension 2 + + + + + + + false + + + + 50 + 20 + + + + <html><head/><body><p>y-dimention for dilation tool</p></body></html> + + + 1 + + + 3 + + + + + + + false + + + + 70 + 20 + + + + 0.100000000000000 + + + 1.000000000000000 + + + + + + + false + + + + 70 + 20 + + + + <html><head/><body><p>Dilation tool shape</p></body></html> + + + + No Filter + + + + + Gaussian + + + + + Mode + + + + + Median + + + + + Mean + + + + + Geometric_mean + + + + + Majority + + + + + Minimum + + + + + Maximum + + + + + Sum + + + + + Gradient + + + + + Entropy + + + + + + + + + + Detailed Cytosol Masking Options + + + + + 10 + 3 + 71 + 20 + + + + + 0 + 20 + + + + Z-Stack Pos + + + + + false + + + + 71 + 3 + 51 + 20 + + + + + 0 + 20 + + + + <html><head/><body><p>Selection of Z-Slice</p></body></html> + + + + + false + + + + 286 + 4 + 211 + 23 + + + + + 0 + 20 + + + + <html><head/><body><p>Transferes Global Masking Settings to all Slices</p></body></html> + + + Transfer Global Cytosol Settings + + + + + false + + + + 5 + 30 + 501 + 211 + + + + + 501 + 211 + + + + QFrame::StyledPanel + + + true + + + false + + + 10 + + + + Specific Channel Wavelength + + + + + Thresholding Mode + + + + + Manual Cutoff Level + + + + + Signal to Noise Ratio + + + + + Background Mean + + + + + Background StdDev + + + + + Compression True/False + + + + + Compression Value + + + + + Remove Object + + + + + Fill Holes + + + + + Dilate True/False + + + + + Dilation Shape + + + + + Dilation Shape Dimmension 1 + + + + + Dilation Shape Dimmension 2 + + + + + Filter Type + + + + + Filter Value + + + + + + + + + 250 + 50 + 256 + 71 + + + + + 0 + 0 + + + + + 256 + 71 + + + + <html><head/><body><p>Enter analysis Equation here:</p><p>e.g. (A - B) / (A + B) for GP-Analysis (Default)</p></body></html> + + + (A - B) / (A + B) + + + + + false + + + + 251 + 7 + 199 + 21 + + + + + 0 + 0 + + + + + 0 + 20 + + + + <html><head/><body><p>Activates cytosolic mesaurements.</p></body></html> + + + Cytosol Measuremnt + + + + + + 251 + 27 + 51 + 20 + + + + Equation + + + + + + 120 + 33 + 103 + 21 + + + + + 0 + 20 + + + + + 50 + false + + + + B + + + Qt::AlignCenter + + + + + false + + + + 11 + 50 + 104 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to A in the equation.</p></body></html> + + + + + + 11 + 72 + 104 + 22 + + + + + 0 + 20 + + + + C + + + Qt::AlignCenter + + + + + + 11 + 33 + 104 + 21 + + + + + 0 + 20 + + + + + 50 + false + + + + A + + + Qt::AutoText + + + Qt::AlignCenter + + + + + false + + + + 11 + 90 + 104 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to C in the equation.</p></body></html> + + + + + false + + + + 120 + 50 + 103 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to B in the equation.</p></body></html> + + + + + + 11 + 5 + 104 + 22 + + + + + 0 + 20 + + + + Channel Setting: + + + + + false + + + + 120 + 90 + 103 + 22 + + + + + 0 + 20 + + + + <html><head/><body><p>Channel corresponding to D in the equation.</p></body></html> + + + + + + 120 + 72 + 103 + 22 + + + + + 0 + 20 + + + + 1 + + + D + + + Qt::AlignCenter + + + + + true + + + + 122 + 7 + 100 + 23 + + + + + 100 + 100 + + + + globalize Channels + + + + + + Advanced Settings + + + + + 10 + 70 + 321 + 185 + + + + Membrane Profiling + + + + + + dim_line + + + + + + + true + + + + 50 + 20 + + + + <html><head/><body><p>y-Dimmension</p></body></html> + + + 1 + + + 3 + + + + + + + + 0 + 20 + + + + β-Value Threshold + + + + + + + true + + + + 50 + 20 + + + + <html><head/><body><p>x-Dimmension</p></body></html> + + + 1 + + + 3 + + + + + + + false + + + + 0 + 20 + + + + 2 + + + 1.000000000000000 + + + 0.010000000000000 + + + 0.100000000000000 + + + + + + + true + + + + 0 + 20 + + + + <html><head/><body><p>Activates recentering of profiler tools.</p></body></html> + + + recentering + + + + + + + true + + + + 0 + 20 + + + + Auto Cut Off + + + true + + + + + + + Integrating Element + + + + + + + + 50 + 20 + + + + 5 + + + + + + + true + + + + 50 + 20 + + + + <html><head/><body><p>Integration element shape</p></body></html> + + + + line + + + + + disk + + + + + square + + + + + octagon + + + + + + + + + + 10 + 10 + 391 + 60 + + + + + 0 + 0 + + + + Object Segementation + + + + + + + 0 + 20 + + + + Skeleton Debranching + + + + + + + + 50 + 20 + + + + <html><head/><body><p>Debranching Level</p></body></html> + + + 1 + + + + + + + + 0 + 0 + + + + + 0 + 20 + + + + tol0 + + + + + + + + 50 + 20 + + + + <html><head/><body><p>Tolerance Value 0</p></body></html> + + + 1.000000000000000 + + + + + + + + 0 + 0 + + + + tol1 + + + + + + + + 50 + 20 + + + + <html><head/><body><p>Tolerance Value1 </p></body></html> + + + 5 + + + + + + + + + Data Saving + + + + + 10 + 10 + 141 + 28 + + + + + 0 + 20 + + + + Select Saving Path + + + + + + 10 + 40 + 500 + 31 + + + + + 500 + 31 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:7.8pt;">Default is image directory</span></p></body></html> + + + + + true + + + + 20 + 80 + 171 + 20 + + + + + 0 + 20 + + + + Save Cropped Membrane + + + + + true + + + + 20 + 100 + 171 + 20 + + + + + 0 + 20 + + + + Save Cropped Cytosol + + + + + true + + + + 20 + 120 + 211 + 20 + + + + + 0 + 20 + + + + Save Linearized Cytosol + + + + + true + + + + 20 + 140 + 211 + 20 + + + + + 0 + 20 + + + + Save Phasors + + + + + true + + + + 20 + 180 + 211 + 20 + + + + + 0 + 20 + + + + Save Settings in JSON + + + + + false + + + + 50 + 200 + 211 + 20 + + + + + 0 + 20 + + + + Save Results in JSON + + + + + true + + + + 20 + 160 + 221 + 20 + + + + + 0 + 0 + + + + + 0 + 20 + + + + Save β-ColorCodedImage as TIF + + + + + + + + + true + + + + 522 + 21 + + + + + 522 + 16777215 + + + + -1 + + + 1000000000 + + + 999999999 + + + false + + + true + + + %p% + + + + + + + + 0 + 20 + + + + + 10 + 75 + true + + + + Calculating... + + + + + + + false + + + + 100 + 100 + + + + PushButton + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 100 + + + + + + + + true + + + + 0 + 0 + + + + + 560 + 10 + + + + false + + + + + + + + + 0 + + + + + true + + + + 1331 + 975 + + + + 0 + + + + Mask-Results + + + + + 0 + 0 + 641 + 681 + + + + 0 + + + + Membrane + + + + + 0 + 0 + 631 + 650 + + + + + + + Cytosol + + + + + 0 + 0 + 631 + 650 + + + + + + + + false + + + + 740 + 625 + 451 + 20 + + + + <html><head/><body><p>Z-Stack Slider</p></body></html> + + + true + + + Qt::Horizontal + + + false + + + true + + + + + + 700 + 670 + 47 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + - + + + Qt::AlignCenter + + + + + false + + + + 741 + 650 + 451 + 20 + + + + false + + + <html><head/><body><p>T-Stack Slider</p></body></html> + + + + + + 1 + + + Qt::Horizontal + + + + + + 680 + 710 + 161 + 23 + + + + + 0 + 20 + + + + Probe Raw Image + + + + + false + + + + 741 + 670 + 451 + 20 + + + + <html><head/><body><p>Channel-Stack Slider</p></body></html> + + + Qt::Horizontal + + + + + + 640 + 20 + 641 + 650 + + + + + + + 680 + 740 + 181 + 131 + + + + + 181 + 131 + + + + Statistical Overview - Full Image + + + + + + + 0 + 0 + + + + + 0 + 20 + + + + Mean + + + + + + + + 0 + 20 + + + + - + + + + + + + + 0 + 20 + + + + Median + + + + + + + + 0 + 20 + + + + - + + + + + + + + 0 + 20 + + + + Standard Deviation + + + + + + + + 0 + 20 + + + + - + + + + + + + + 0 + 20 + + + + Min + + + + + + + + 0 + 20 + + + + - + + + + + + + + 0 + 20 + + + + Max + + + + + + + + 0 + 20 + + + + - + + + + + + + + + 720 + 650 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + T + + + Qt::AlignCenter + + + + + + 720 + 630 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Z + + + Qt::AlignCenter + + + + + + 690 + 670 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + C + + + Qt::AlignCenter + + + + + true + + + + 900 + 710 + 181 + 20 + + + + + 0 + 20 + + + + <html><head/><body><p>Uses a percentile-based approach (99th percentile) to avoid the influence of outliers.</p><p><br/></p><p>Its usfull in images with super bright spots. </p></body></html> + + + Automatic Brightness Adjustment + + + true + + + MplWidget + tabWidget_8 + verticalScrollBar_3 + label_7 + horizontalScrollBar_3 + pushButton_2 + horizontalScrollBar_4 + groupBox_20 + label_8 + label_13 + label_47 + checkBox_33 + + + + Full Image-Results + + + + false + + + + 77 + 701 + 501 + 20 + + + + <html><head/><body><p>T-Stack Slider</p></body></html> + + + Qt::LeftToRight + + + false + + + Qt::Horizontal + + + false + + + true + + + + + false + + + + 77 + 678 + 501 + 21 + + + + <html><head/><body><p>Z-Stack Slider</p></body></html> + + + false + + + Qt::Horizontal + + + false + + + true + + + + + + 0 + 0 + 1341 + 941 + + + + 0 + + + + Membrane + + + + + 0 + 0 + 661 + 661 + + + + + + + 830 + -10 + 491 + 451 + + + + + 0 + 0 + + + + + + + 830 + 440 + 501 + 471 + + + + 0 + + + + Channel Intensities + + + + + 0 + 0 + 491 + 451 + + + + + + + Phasor Plot + + + + + 0 + 2 + 491 + 441 + + + + + + + + + 10 + 700 + 221 + 121 + + + + + 0 + 121 + + + + Statistical Overview - Full Image + + + + + + + 0 + 20 + + + + Median: + + + + + + + + 0 + 20 + + + + - + + + + + + + + 0 + 20 + + + + Standard Deviaton: + + + + + + + + 0 + 20 + + + + - + + + + + + + + 0 + 20 + + + + Rejected Pixels %: + + + + + + + + 0 + 20 + + + + - + + + + + + + + 0 + 20 + + + + Mean Intensity of Thr Ch: + + + + + + + + 0 + 20 + + + + - + + + + + + + + + 60 + 654 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Z + + + Qt::AlignCenter + + + + + + Cytosol + + + + + 0 + 0 + 661 + 661 + + + + + + + 830 + -10 + 491 + 451 + + + + + 0 + 0 + + + + + + + 830 + 440 + 501 + 471 + + + + 0 + + + + Channel Intensities + + + + + 0 + 0 + 491 + 441 + + + + + + + Phasor Plot + + + + + 0 + 2 + 491 + 451 + + + + + + + + + 10 + 700 + 221 + 121 + + + + + 0 + 121 + + + + Statistical Overview - Full Image + + + + + + Median: + + + + + + + - + + + + + + + Standard Deviaton: + + + + + + + - + + + + + + + Rejected Pixels %: + + + + + + + - + + + + + + + Normalized Intensity: + + + + + + + - + + + + + + + + + 60 + 656 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Z + + + Qt::AlignCenter + + + + + + + + 63 + 700 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + T + + + Qt::AlignCenter + + + tabWidget_9 + verticalScrollBar + horizontalScrollBar + label_32 + + + + Object-Results + + + + + 530 + 30 + 81 + 311 + + + + + 0 + 311 + + + + PointingHandCursor + + + false + + + 80 + + + 45 + + + false + + + + Object Nr. + + + + 8 + + + + AlignHCenter|AlignBottom + + + + + + false + + + + 80 + 520 + 361 + 20 + + + + <html><head/><body><p>T-Stack Slider</p></body></html> + + + false + + + Qt::Horizontal + + + false + + + true + + + + + false + + + + 80 + 500 + 361 + 20 + + + + <html><head/><body><p>Z-Stack Slider</p></body></html> + + + false + + + Qt::Horizontal + + + false + + + true + + + + + + 0 + 550 + 1321 + 391 + + + + 0 + + + + Membrane Overview + + + + + 0 + -10 + 411 + 381 + + + + + + + 900 + -10 + 411 + 381 + + + + + + + 450 + -10 + 411 + 381 + + + + + + + Membrane Profile + + + + + 0 + -10 + 1321 + 381 + + + + + + + Cytosol Overview + + + + + 450 + -10 + 411 + 381 + + + + + + + 900 + -10 + 411 + 381 + + + + + + + 0 + -10 + 411 + 381 + + + + + + + Cytosol Linearized Profile + + + + + 0 + 0 + 1311 + 381 + + + + + + 350 + 15 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + C + + + Qt::AlignCenter + + + + + + false + + + + 391 + 16 + 671 + 20 + + + + <html><head/><body><p>Channel-Stack Slider</p></body></html> + + + false + + + Qt::Horizontal + + + false + + + true + + + + + + 351 + 15 + 47 + 20 + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + 710 + -50 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + C + + + Qt::AlignCenter + + + + + + + + 790 + 0 + 531 + 551 + + + + 0 + + + + Membrane Object Zoom + + + + + 0 + -16 + 541 + 541 + + + + + + + Membrane Sections + + + + + 0 + -16 + 541 + 541 + + + + + + + Cytosol Object Zoom + + + + + 0 + -16 + 541 + 541 + + + + + + + + + 0 + 0 + 521 + 551 + + + + 0 + + + + Membrane + + + + + 0 + -12 + 501 + 501 + + + + + + + Cytosol + + + + + 0 + 0 + 501 + 501 + + + + + + + + + 523 + 357 + 261 + 191 + + + + + 0 + 191 + + + + Statistical Overview - Object + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + Standard Deviaton + + + + + + + + 0 + 20 + + + + Normalized Intensity + + + + + + + + 0 + 20 + + + + Eccentricity: + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + Perimeter: + + + + + + + + 0 + 20 + + + + Area: + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + Median + + + + + + + + 0 + 20 + + + + Rejected Pixels % + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + - + + + Qt::AlignCenter + + + + + + + + 0 + 20 + + + + Membrane + + + + + + + + 0 + 20 + + + + Cytosol + + + Qt::AlignCenter + + + + + + + + + 70 + 500 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Z + + + Qt::AlignCenter + + + + + + 70 + 520 + 21 + 20 + + + + + 0 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + T + + + Qt::AlignCenter + + + tableWidget_2 + tabWidget_3 + tabWidget_5 + tabWidget_11 + verticalScrollBar_2 + horizontalScrollBar_2 + groupBox_18 + label_40 + label_43 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Dark Mode + + + + + Light Mode + + + + + + CheckableComboBox + QComboBox +
custom_combobox.h
+
+
+ + +
diff --git a/Python/ui/splashscreen.cdr b/Python/ui/splashscreen.cdr new file mode 100644 index 0000000..2eb6406 Binary files /dev/null and b/Python/ui/splashscreen.cdr differ diff --git a/Python/ui/splashscreen.png b/Python/ui/splashscreen.png index 5004e97..52770a5 100644 Binary files a/Python/ui/splashscreen.png and b/Python/ui/splashscreen.png differ