microlive 1.0.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- microlive/__init__.py +50 -0
- microlive/data/__init__.py +0 -0
- microlive/data/icons/__init__.py +0 -0
- microlive/data/icons/icon_micro.png +0 -0
- microlive/data/models/__init__.py +0 -0
- microlive/gui/__init__.py +1 -0
- microlive/gui/app.py +16340 -0
- microlive/gui/main.py +86 -0
- microlive/gui/micro_mac.command +18 -0
- microlive/gui/micro_windows.bat +24 -0
- microlive/imports.py +209 -0
- microlive/microscopy.py +13321 -0
- microlive/ml_spot_detection.py +252 -0
- microlive/pipelines/__init__.py +17 -0
- microlive/pipelines/pipeline_FRAP.py +1225 -0
- microlive/pipelines/pipeline_folding_efficiency.py +297 -0
- microlive/pipelines/pipeline_particle_tracking.py +489 -0
- microlive/pipelines/pipeline_spot_detection_no_tracking.py +368 -0
- microlive/utils/__init__.py +13 -0
- microlive/utils/device.py +99 -0
- microlive/utils/resources.py +60 -0
- microlive-1.0.11.dist-info/METADATA +361 -0
- microlive-1.0.11.dist-info/RECORD +26 -0
- microlive-1.0.11.dist-info/WHEEL +4 -0
- microlive-1.0.11.dist-info/entry_points.txt +2 -0
- microlive-1.0.11.dist-info/licenses/LICENSE +674 -0
microlive/gui/main.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"""Entry point for MicroLive GUI application.
|
|
2
|
+
|
|
3
|
+
This module provides the command-line entry point for launching
|
|
4
|
+
the MicroLive graphical user interface.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
$ microlive
|
|
8
|
+
|
|
9
|
+
Or programmatically:
|
|
10
|
+
from microlive.gui.main import main
|
|
11
|
+
main()
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
import os
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main():
|
|
19
|
+
"""Launch the MicroLive GUI application."""
|
|
20
|
+
# Ensure proper Qt platform on macOS
|
|
21
|
+
if sys.platform == "darwin":
|
|
22
|
+
os.environ.setdefault("QT_MAC_WANTS_LAYER", "1")
|
|
23
|
+
|
|
24
|
+
# Import Qt after environment setup
|
|
25
|
+
from PyQt5.QtWidgets import QApplication
|
|
26
|
+
from PyQt5.QtGui import QIcon, QFont, QPalette, QColor
|
|
27
|
+
from PyQt5.QtCore import Qt
|
|
28
|
+
import matplotlib.pyplot as plt
|
|
29
|
+
|
|
30
|
+
# Import the main application window
|
|
31
|
+
from .app import GUI
|
|
32
|
+
|
|
33
|
+
# Get icon path
|
|
34
|
+
from ..utils.resources import get_icon_path
|
|
35
|
+
|
|
36
|
+
# Create application
|
|
37
|
+
app = QApplication(sys.argv)
|
|
38
|
+
app.setStyle('Fusion')
|
|
39
|
+
|
|
40
|
+
# Set modern font based on platform
|
|
41
|
+
if sys.platform == 'win32':
|
|
42
|
+
app.setFont(QFont("Segoe UI", 11))
|
|
43
|
+
elif sys.platform == 'darwin':
|
|
44
|
+
app.setFont(QFont("SF Pro", 11))
|
|
45
|
+
else:
|
|
46
|
+
app.setFont(QFont("Inter", 11))
|
|
47
|
+
|
|
48
|
+
# Set dark matplotlib style
|
|
49
|
+
plt.style.use('dark_background')
|
|
50
|
+
|
|
51
|
+
# Set dark palette for the application
|
|
52
|
+
palette = QPalette()
|
|
53
|
+
palette.setColor(QPalette.Window, QColor(53, 53, 53))
|
|
54
|
+
palette.setColor(QPalette.WindowText, Qt.white)
|
|
55
|
+
palette.setColor(QPalette.Base, QColor(35, 35, 35))
|
|
56
|
+
palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
|
|
57
|
+
palette.setColor(QPalette.ToolTipBase, Qt.white)
|
|
58
|
+
palette.setColor(QPalette.ToolTipText, Qt.white)
|
|
59
|
+
palette.setColor(QPalette.Text, Qt.white)
|
|
60
|
+
palette.setColor(QPalette.Button, QColor(53, 53, 53))
|
|
61
|
+
palette.setColor(QPalette.ButtonText, Qt.white)
|
|
62
|
+
palette.setColor(QPalette.BrightText, Qt.red)
|
|
63
|
+
palette.setColor(QPalette.Highlight, QColor(142, 45, 197).lighter())
|
|
64
|
+
palette.setColor(QPalette.HighlightedText, Qt.black)
|
|
65
|
+
app.setPalette(palette)
|
|
66
|
+
|
|
67
|
+
# Set application metadata
|
|
68
|
+
app.setApplicationName("MicroLive")
|
|
69
|
+
app.setApplicationDisplayName("MicroLive")
|
|
70
|
+
app.setOrganizationName("Zhao Lab")
|
|
71
|
+
|
|
72
|
+
# Set application icon
|
|
73
|
+
icon_path = get_icon_path()
|
|
74
|
+
if icon_path and icon_path.exists():
|
|
75
|
+
app.setWindowIcon(QIcon(str(icon_path)))
|
|
76
|
+
|
|
77
|
+
# Create and show main window
|
|
78
|
+
window = GUI(icon_path=icon_path)
|
|
79
|
+
window.show()
|
|
80
|
+
|
|
81
|
+
# Run event loop
|
|
82
|
+
sys.exit(app.exec_())
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
if __name__ == "__main__":
|
|
86
|
+
main()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# MicroLive GUI Launcher (macOS)
|
|
3
|
+
|
|
4
|
+
# Find the conda base directory
|
|
5
|
+
CONDA_BASE=$(conda info --base 2>/dev/null)
|
|
6
|
+
if [ -z "$CONDA_BASE" ]; then
|
|
7
|
+
echo "Conda does not appear to be installed or not in your PATH."
|
|
8
|
+
exit 1
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
# Source conda's shell functions
|
|
12
|
+
source "$CONDA_BASE/etc/profile.d/conda.sh"
|
|
13
|
+
|
|
14
|
+
# Activate the 'microlive' environment
|
|
15
|
+
conda activate microlive
|
|
16
|
+
|
|
17
|
+
# Launch MicroLive using the pip-installed entry point
|
|
18
|
+
microlive
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
@echo off
|
|
2
|
+
REM =======================================================
|
|
3
|
+
REM MicroLive GUI Launcher (Windows)
|
|
4
|
+
REM This batch file activates the conda environment
|
|
5
|
+
REM and launches MicroLive using the pip-installed entry point.
|
|
6
|
+
REM =======================================================
|
|
7
|
+
|
|
8
|
+
REM Check if conda is available in PATH.
|
|
9
|
+
where conda >nul 2>&1
|
|
10
|
+
if errorlevel 1 (
|
|
11
|
+
echo Conda does not appear to be installed or is not in your PATH.
|
|
12
|
+
pause
|
|
13
|
+
exit /b 1
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
REM Activate the 'microlive' environment.
|
|
17
|
+
REM Using "call" is critical in batch files so that the script continues after activation.
|
|
18
|
+
call conda activate microlive
|
|
19
|
+
|
|
20
|
+
REM Launch MicroLive using the pip-installed entry point
|
|
21
|
+
microlive
|
|
22
|
+
|
|
23
|
+
REM Optional: Pause at the end so the window doesn't immediately close.
|
|
24
|
+
pause
|
microlive/imports.py
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# Import standard libraries
|
|
2
|
+
import sys
|
|
3
|
+
import os
|
|
4
|
+
import pathlib
|
|
5
|
+
import tempfile
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import warnings
|
|
8
|
+
import getpass
|
|
9
|
+
import importlib
|
|
10
|
+
import random
|
|
11
|
+
import time
|
|
12
|
+
import math
|
|
13
|
+
import socket
|
|
14
|
+
import datetime
|
|
15
|
+
from functools import partial, wraps
|
|
16
|
+
from itertools import compress
|
|
17
|
+
import io
|
|
18
|
+
import traceback
|
|
19
|
+
import subprocess
|
|
20
|
+
import re
|
|
21
|
+
import bisect
|
|
22
|
+
from numba import njit, types
|
|
23
|
+
from numba.typed import List as TypedList
|
|
24
|
+
import cv2
|
|
25
|
+
import io
|
|
26
|
+
import fpdf
|
|
27
|
+
import json
|
|
28
|
+
|
|
29
|
+
# Import third-party libraries
|
|
30
|
+
import shutil
|
|
31
|
+
import urllib.request
|
|
32
|
+
import gzip
|
|
33
|
+
import inspect
|
|
34
|
+
import numpy as np
|
|
35
|
+
import pandas as pd
|
|
36
|
+
import tifffile
|
|
37
|
+
import matplotlib.pyplot as plt
|
|
38
|
+
from matplotlib import gridspec
|
|
39
|
+
from matplotlib.animation import FuncAnimation, PillowWriter
|
|
40
|
+
import matplotlib.colors as mcolors
|
|
41
|
+
from matplotlib_scalebar.scalebar import ScaleBar
|
|
42
|
+
from matplotlib.font_manager import FontProperties
|
|
43
|
+
import matplotlib.patches as patches
|
|
44
|
+
from matplotlib.ticker import MaxNLocator
|
|
45
|
+
from matplotlib.patches import Rectangle
|
|
46
|
+
from skimage.io import imread
|
|
47
|
+
from skimage.measure import regionprops
|
|
48
|
+
from skimage import exposure # for adaptive histogram equalization
|
|
49
|
+
from skimage.filters import threshold_local
|
|
50
|
+
from skimage.morphology import disk, binary_opening, binary_closing
|
|
51
|
+
from skimage.measure import label, regionprops
|
|
52
|
+
from skimage.filters import threshold_otsu
|
|
53
|
+
from skimage.transform import hough_circle, hough_circle_peaks
|
|
54
|
+
import openpyxl
|
|
55
|
+
import bigfish.stack as stack
|
|
56
|
+
from PIL import Image
|
|
57
|
+
from joblib import Parallel, delayed
|
|
58
|
+
from scipy.ndimage import binary_opening as binary_opening_ndi
|
|
59
|
+
from scipy.ndimage import binary_closing as binary_closing_ndi
|
|
60
|
+
from scipy.ndimage import gaussian_filter, binary_dilation,gaussian_filter1d , uniform_filter1d#label
|
|
61
|
+
from scipy.ndimage import label as ndi_label
|
|
62
|
+
from scipy.signal import find_peaks
|
|
63
|
+
from scipy.integrate import odeint, solve_ivp
|
|
64
|
+
from scipy.optimize import curve_fit
|
|
65
|
+
from scipy.stats import linregress, pearsonr, gaussian_kde, mannwhitneyu,ttest_ind
|
|
66
|
+
from statsmodels.stats.multitest import multipletests
|
|
67
|
+
from snapgene_reader import snapgene_file_to_dict, snapgene_file_to_seqrecord
|
|
68
|
+
from IPython.display import Image as IPImage, display
|
|
69
|
+
import ipywidgets as widgets
|
|
70
|
+
import imageio
|
|
71
|
+
import contextlib, io
|
|
72
|
+
_f = io.StringIO()
|
|
73
|
+
with contextlib.redirect_stdout(_f), contextlib.redirect_stderr(_f):
|
|
74
|
+
from cellpose import models, denoise
|
|
75
|
+
import seaborn as sns
|
|
76
|
+
from dna_features_viewer import GraphicFeature, GraphicRecord, CircularGraphicRecord
|
|
77
|
+
from Bio.Seq import Seq
|
|
78
|
+
from Bio import SeqIO
|
|
79
|
+
from Bio.SeqUtils import CodonAdaptationIndex
|
|
80
|
+
from Bio.SeqRecord import SeqRecord
|
|
81
|
+
from typing import List
|
|
82
|
+
import trackpy as tp
|
|
83
|
+
tp.quiet(suppress=True)
|
|
84
|
+
from PIL import Image
|
|
85
|
+
from matplotlib.colors import LinearSegmentedColormap
|
|
86
|
+
from matplotlib.colors import to_rgb
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
import torch
|
|
90
|
+
except ImportError:
|
|
91
|
+
print("Warning: napari and/or napari-animation not found. Some functionality will not be available.")
|
|
92
|
+
napari = None
|
|
93
|
+
|
|
94
|
+
import logging
|
|
95
|
+
logging.getLogger("root").setLevel(logging.ERROR)
|
|
96
|
+
|
|
97
|
+
# Suppress Cellpose verbose logging (only show warnings and errors)
|
|
98
|
+
logging.getLogger('cellpose').setLevel(logging.WARNING)
|
|
99
|
+
logging.getLogger('cellpose.core').setLevel(logging.WARNING)
|
|
100
|
+
logging.getLogger('cellpose.models').setLevel(logging.WARNING)
|
|
101
|
+
|
|
102
|
+
from mpl_toolkits.mplot3d import Axes3D # For older versions of Matplotlib
|
|
103
|
+
import matplotlib.colors as mcolors
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
# Get the username
|
|
107
|
+
computer_user_name = getpass.getuser()
|
|
108
|
+
|
|
109
|
+
# =============================================================================
|
|
110
|
+
# Package-aware imports and paths (pip packaging compatible)
|
|
111
|
+
# =============================================================================
|
|
112
|
+
|
|
113
|
+
# Import MicroLive modules using direct module imports (avoid circular import via __init__.py)
|
|
114
|
+
from microlive.microscopy import * # Direct module import, not through package __init__
|
|
115
|
+
import microlive.microscopy as mi
|
|
116
|
+
import microlive.ml_spot_detection as ML
|
|
117
|
+
from microlive.utils.resources import get_icon_path, get_model_path
|
|
118
|
+
|
|
119
|
+
# Get icon path (works both in development and installed modes)
|
|
120
|
+
icon_file = get_icon_path()
|
|
121
|
+
if icon_file is None:
|
|
122
|
+
warnings.warn("Icon file not found. Some GUI features may not display correctly.")
|
|
123
|
+
|
|
124
|
+
# Load machine learning model
|
|
125
|
+
try:
|
|
126
|
+
model_path = get_model_path()
|
|
127
|
+
if model_path is not None and model_path.exists():
|
|
128
|
+
model_ML = ML.ParticleDetectionCNN()
|
|
129
|
+
ML.load_model(model_ML, model_path)
|
|
130
|
+
else:
|
|
131
|
+
model_ML = None
|
|
132
|
+
warnings.warn("ML model not found. ML spot detection will not be available.")
|
|
133
|
+
except Exception as e:
|
|
134
|
+
model_ML = None
|
|
135
|
+
warnings.warn(f"Error loading machine learning model: {e}")
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# --- Set microscope folder path based on operating system ---
|
|
140
|
+
if sys.platform.startswith('win'):
|
|
141
|
+
# Windows example (adjust the path as needed)
|
|
142
|
+
microscope_folder_path = Path(f"C:/Users/{computer_user_name}/OneDrive - TheUniversityofColoradoDenver/Microscope")
|
|
143
|
+
elif sys.platform.startswith('darwin'):
|
|
144
|
+
# macOS path (your original path)
|
|
145
|
+
microscope_folder_path = Path(
|
|
146
|
+
f"/Users/{computer_user_name}/Library/CloudStorage/OneDrive-TheUniversityofColoradoDenver/"
|
|
147
|
+
"General - Zhao (NZ) Lab/Microscope"
|
|
148
|
+
)
|
|
149
|
+
elif sys.platform.startswith('linux'):
|
|
150
|
+
# Linux example (adjust as needed)
|
|
151
|
+
microscope_folder_path = Path(f"/home/{computer_user_name}/Microscope")
|
|
152
|
+
else:
|
|
153
|
+
# Fallback: use the home directory plus a default folder name
|
|
154
|
+
microscope_folder_path = Path.home() / "Microscope"
|
|
155
|
+
|
|
156
|
+
# Suppress warnings
|
|
157
|
+
warnings.filterwarnings("ignore")
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
# Define a custom green colormap from black to green
|
|
162
|
+
cdict_green = {
|
|
163
|
+
'red': ((0.0, 0.0, 0.0), # No red at any point
|
|
164
|
+
(1.0, 0.0, 0.0)),
|
|
165
|
+
'green': ((0.0, 0.0, 0.0), # Start with no green
|
|
166
|
+
(1.0, 1.0, 1.0)), # Full green at the end
|
|
167
|
+
'blue': ((0.0, 0.0, 0.0), # No blue at any point
|
|
168
|
+
(1.0, 0.0, 0.0))
|
|
169
|
+
}
|
|
170
|
+
cdict_magenta = {
|
|
171
|
+
'red': ((0.0, 0.0, 0.0), # Start with no red
|
|
172
|
+
(1.0, 1.0, 1.0)), # Full red at the end
|
|
173
|
+
'green': ((0.0, 0.0, 0.0), # No green at any point
|
|
174
|
+
(1.0, 0.0, 0.0)),
|
|
175
|
+
'blue': ((0.0, 0.0, 0.0), # Start with no blue
|
|
176
|
+
(1.0, 1.0, 1.0)) # Full blue at the end
|
|
177
|
+
}
|
|
178
|
+
cdict_red = {
|
|
179
|
+
'red': ((0.0, 0.0, 0.0), # Start with no red
|
|
180
|
+
(1.0, 1.0, 1.0)), # Full red at the end
|
|
181
|
+
'green': ((0.0, 0.0, 0.0), # No green at any point
|
|
182
|
+
(1.0, 0.0, 0.0)),
|
|
183
|
+
'blue': ((0.0, 0.0, 0.0), # No blue at any point
|
|
184
|
+
(1.0, 0.0, 0.0))
|
|
185
|
+
}
|
|
186
|
+
cdict_yellow = {
|
|
187
|
+
'red': ((0.0, 0.0, 0.0), # Start with no red
|
|
188
|
+
(1.0, 1.0, 1.0)), # Full red at the end
|
|
189
|
+
'green': ((0.0, 0.0, 0.0), # Start with no green
|
|
190
|
+
(1.0, 1.0, 1.0)), # Full green at the end
|
|
191
|
+
'blue': ((0.0, 0.0, 0.0), # No blue at any point
|
|
192
|
+
(1.0, 0.0, 0.0))
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
yellow_colormap = LinearSegmentedColormap('BlackYellow', cdict_yellow)
|
|
196
|
+
red_colormap = LinearSegmentedColormap('BlackRed', cdict_red)
|
|
197
|
+
green_colormap = LinearSegmentedColormap('BlackGreen', cdict_green)
|
|
198
|
+
magenta_colormap = LinearSegmentedColormap('BlackMagenta', cdict_magenta)
|
|
199
|
+
|
|
200
|
+
cmap_list_imagej = [green_colormap, magenta_colormap ,yellow_colormap,red_colormap]
|
|
201
|
+
|
|
202
|
+
# List of colors for plotting in GUI
|
|
203
|
+
color_green = (0.0, 1.0, 0.0) # No Red, Full Green, No Blue
|
|
204
|
+
color_magenta = (1.0, 0.0, 1.0) # Full Red, No Green, Full Blue
|
|
205
|
+
color_red = (1.0, 0.0, 0.0) # Full Red, No Green, No Blue
|
|
206
|
+
color_yellow = (1.0, 1.0, 0.0) # Full Red, Full Green, No Blue
|
|
207
|
+
|
|
208
|
+
list_colors_default = [ color_green, color_magenta, color_yellow, color_red]
|
|
209
|
+
|