Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
750b405
WIP: UI elements
Teranis Mar 29, 2026
83102f4
WIP: UI elements
Teranis Mar 29, 2026
9dbab9d
feat: UI scaffold
Teranis Mar 30, 2026
bfd5a17
feat: saving and loading workflow, changing images
Teranis Mar 31, 2026
fb612d5
feat: workflow validation
Teranis Mar 31, 2026
e79eb55
feat: loadData accepts user_ch_name=None, imgPath can be path to Imag…
Teranis Mar 31, 2026
5972210
feat: backup on saving, block saving when dialogs are open, block dou…
Teranis Mar 31, 2026
4fd9682
WIP: adding SetMeasurementsDialog
Teranis Mar 31, 2026
466f3b1
feat: typing
Teranis Apr 1, 2026
f769c2f
feat: setMeasurements dialog
Teranis Apr 1, 2026
1ed95d9
feat: measurements input for Segm postprocessing, minor qol
Teranis Apr 1, 2026
b66631c
WIP: segmentation card
Teranis Apr 2, 2026
481c5e9
Merge branch 'workflow-gui' of https://github.com/SchmollerLab/Cell_A…
Teranis Apr 2, 2026
5946aa1
WIP: segment card
Teranis Apr 3, 2026
dca85bd
fix: dark light mode selector
Teranis Apr 10, 2026
adbeff0
feat: tracking
Teranis Apr 10, 2026
e27cfc8
fix: typo
Teranis Apr 10, 2026
36e358e
fix: correctly load img and segm shape
Teranis Apr 10, 2026
becfe47
feat: Francesco's suggestions #1067
Teranis Apr 11, 2026
c2b0d6f
feat: Francesco's suggestions #1067
Teranis Apr 11, 2026
79ff542
Merge branch 'workflow-gui' of https://github.com/SchmollerLab/Cell_A…
Teranis Apr 11, 2026
2b58593
feat: input and output tooltips
Teranis Apr 11, 2026
320a2df
feat: Browse inputs, edit metadata, other minor stuff
Teranis Apr 12, 2026
4260359
feat: z proj and crop cards
Teranis Apr 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions cellacdc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ def printl(*objects, pretty=False, is_decorator=False, idx=1, **kwargs):
text = f'{open_printl_str}\n{fileinfo_str}\n{text}\n{close_printl_str}'
print(text)

printl.info = print

parent_path = os.path.dirname(cellacdc_path)
html_path = os.path.join(cellacdc_path, '_html')
models_path = os.path.join(cellacdc_path, 'models')
Expand All @@ -401,6 +403,7 @@ def printl(*objects, pretty=False, is_decorator=False, idx=1, **kwargs):
settings_folderpath, 'favourite_func_metrics.csv'
)
recentPaths_path = os.path.join(settings_folderpath, 'recentPaths.csv')
recentWorkflowPaths_path = os.path.join(settings_folderpath, 'recentWorkflowsPaths.csv')
preproc_recipes_path = os.path.join(settings_folderpath, 'preprocessing_recipes')
combine_channels_recipes_path = os.path.join(settings_folderpath, 'combine_channels')
segm_recipes_path = os.path.join(settings_folderpath, 'segmentation_recipes')
Expand All @@ -413,6 +416,7 @@ def printl(*objects, pretty=False, is_decorator=False, idx=1, **kwargs):
saved_measurements_selections_folderpath = os.path.join(
settings_folderpath, 'saved_measurements_selections'
)
workflow_default_save_folderpath = os.path.join(settings_folderpath, 'acdc_workflows')

# Use to get the acdc_output file name from `segm_filename` as
# `m = re.sub(segm_re_pattern, '_acdc_output', segm_filename)`
Expand Down
65 changes: 51 additions & 14 deletions cellacdc/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@
from . import user_profile_path
from . import cellacdc_path
from . config import parser_args
from . import workflow_gui


try:
import spotmax
Expand Down Expand Up @@ -179,8 +181,17 @@ def __init__(self, app, parent=None):
segmButton.clicked.connect(self.launchSegm)
self.segmButton = segmButton
modulesButtonsGroupBoxLayout.addWidget(segmButton)

workflowButton = QPushButton(' 3. Launch workflow module...')
workflowButton.setIcon(QIcon(':workflow.svg'))
workflowButton.setIconSize(QSize(iconSize, iconSize))
workflowButton.setFont(font)
workflowButton.clicked.connect(self.launchWorkflowGui)
self.workflowButton = workflowButton
modulesButtonsGroupBoxLayout.addWidget(workflowButton)
workflowButton.setFixedHeight(47)

guiButton = QPushButton(' 3. Launch GUI...')
guiButton = QPushButton(' 4. Launch GUI...')
guiButton.setIcon(QIcon(':logo.svg'))
guiButton.setIconSize(QSize(iconSize, iconSize))
guiButton.setFont(font)
Expand All @@ -189,7 +200,7 @@ def __init__(self, app, parent=None):
modulesButtonsGroupBoxLayout.addWidget(guiButton)

if SPOTMAX_INSTALLED:
spotmaxButton = QPushButton(' 4. Launch SpotMAX...')
spotmaxButton = QPushButton(' 5. Launch SpotMAX...')
spotmaxButton.setIcon(QIcon(spotmax_logo_path))
spotmaxButton.setIconSize(QSize(iconSize,iconSize))
spotmaxButton.setFont(font)
Expand Down Expand Up @@ -247,6 +258,7 @@ def __init__(self, app, parent=None):
self.guiWins = []
self.spotmaxWins = []
self.dataPrepWins = []
self.workflowWins = []
self._version = None
self.progressWin = None
self.forceClose = False
Expand All @@ -260,10 +272,8 @@ def addStatusBar(self, scheme):
widget.setLayout(layout)
layout.addWidget(label)
self.darkModeToggle = widgets.Toggle(label_text='Dark mode')
self.darkModeToggle.ignoreEvent = False
self.darkModeToggle.warnMessageBox = True
if scheme == 'dark':
self.darkModeToggle.ignoreEvent = True
self.darkModeToggle.setChecked(True)
self.darkModeToggle.toggled.connect(self.onDarkModeToggled)
layout.addWidget(self.darkModeToggle)
Expand All @@ -275,9 +285,7 @@ def getColorScheme(self):
return get_color_scheme()

def onDarkModeToggled(self, checked):
if self.darkModeToggle.ignoreEvent:
self.darkModeToggle.ignoreEvent = False
return
self.darkModeToggle.setDisabled(True)
from ._palettes import getPaletteColorScheme
scheme = 'dark' if checked else 'light'
load.rename_qrc_resources_file(scheme)
Expand All @@ -294,7 +302,7 @@ def onDarkModeToggled(self, checked):
)
self.darkModeToggle.warnMessageBox = True
self.setStatusBarRestartCellACDC()
self.darkModeToggle.setDisabled(True)


def setStatusBarRestartCellACDC(self):
self.statusBarLayout.addWidget(QLabel(html_utils.paragraph(
Expand Down Expand Up @@ -1090,7 +1098,8 @@ def getSelectedPosPath(self, utilityName):
def getSelectedExpPaths(
self, utilityName,
exp_folderpath=None,
custom_txt=None
custom_txt=None,
allowProceedWithout=False,
):
# self._debug()

Expand All @@ -1106,10 +1115,18 @@ def getSelectedExpPaths(
Next, you will be able to <b>choose specific Positions</b>
from each selected experiment.
""")
msg.information(
self, f'{utilityName}', txt,
buttonsTexts=('Cancel', 'Ok')
)
if allowProceedWithout:
_, proceedWithoutButton, _ = msg.information(
self, f'{utilityName}', txt,
buttonsTexts=('Cancel', 'Proceed without', 'Select folders')
)
if msg.clickedButton == proceedWithoutButton:
return {}
else:
msg.information(
self, f'{utilityName}', txt,
buttonsTexts=('Cancel', 'Ok')
)
if msg.cancel:
self.logger.info(f'{utilityName} aborted by the user.')
return
Expand Down Expand Up @@ -1247,7 +1264,7 @@ def warnExpPathAlreadySelected(self, selected_path, exp_path):
def _debug(self):
try:
from . import _q_debug
_q_debug.q_debug(self)
_q_debug.q_debug(self, None)
except Exception as err:
raise err

Expand Down Expand Up @@ -2004,6 +2021,16 @@ def launchGui(self, checked=False):
self.guiWins.append(guiWin)
guiWin.sigClosed.connect(self.guiClosed)
guiWin.run()

def launchWorkflowGui(self, checked=False):
self.logger.info('Opening Workflow GUI...')
workflowWin = workflow_gui.WorkflowGui(
self.app, mainWin=self, version=self._version,
launcherSlot=self.launchWorkflowGui,
)
self.workflowWins.append(workflowWin)
workflowWin.sigClosed.connect(self.workflowGuiClosed)
workflowWin.run()

def launchSpotmaxGui(self, checked=False):
from spotmax import icon_path, logo_path
Expand Down Expand Up @@ -2036,6 +2063,14 @@ def guiClosed(self, guiWin):
pass
self._gc_collect()

def workflowGuiClosed(self, workflowWin):
try:
self.workflowWins.remove(workflowWin)
except ValueError:
pass
self._gc_collect()


def _gc_collect(self):
QTimer.singleShot(100, gc.collect)

Expand Down Expand Up @@ -2207,6 +2242,8 @@ def getOpenModules(self):
openModules.extend(self.guiWins)
if self.spotmaxWins:
openModules.extend(self.spotmaxWins)
if self.workflowWins:
openModules.extend(self.workflowWins)
return openModules


Expand Down
Loading
Loading