Skip to content

Commit 019c2a5

Browse files
committed
improve plugin sync with settings
1 parent a9a5e53 commit 019c2a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+544
-580
lines changed

src/ptychodus/api/plugins.py

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from __future__ import annotations
2-
from collections.abc import Sequence
2+
from collections.abc import Iterable, Iterator
33
from dataclasses import dataclass
44
from types import ModuleType
5-
from typing import Generic, TypeVar, overload
5+
from typing import Generic, TypeVar
66
import importlib
77
import logging
88
import pkgutil
@@ -15,7 +15,8 @@
1515
UpscalingStrategy,
1616
)
1717
from .object import ObjectFileReader, ObjectFileWriter
18-
from .observer import Observable
18+
from .observer import Observable, Observer
19+
from .parametric import StringParameter
1920
from .patterns import DiffractionFileReader, DiffractionFileWriter
2021
from .probe import FresnelZonePlate, ProbeFileReader, ProbeFileWriter
2122
from .product import ProductFileReader, ProductFileWriter
@@ -33,69 +34,62 @@
3334

3435

3536
@dataclass(frozen=True)
36-
class PluginEntry(Generic[T]):
37+
class Plugin(Generic[T]):
3738
strategy: T
38-
simpleName: str
39-
displayName: str
39+
simple_name: str
40+
display_name: str
4041

4142

42-
class PluginChooser(Sequence[PluginEntry[T]], Observable):
43+
class PluginChooser(Iterable[Plugin[T]], Observable, Observer):
4344
def __init__(self) -> None:
4445
super().__init__()
45-
self._entryList: list[PluginEntry[T]] = list()
46-
self._currentIndex = 0
46+
self._registered_plugins: list[Plugin[T]] = list()
47+
self._current_index = 0
48+
self._parameter: StringParameter | None = None
4749

48-
def getSimpleNameList(self) -> Sequence[str]:
49-
return [entry.simpleName for entry in self._entryList]
50+
def register_plugin(self, strategy: T, *, display_name: str, simple_name: str = '') -> None:
51+
if not simple_name:
52+
simple_name = re.sub(r'\W+', '', display_name)
5053

51-
def getDisplayNameList(self) -> Sequence[str]:
52-
return [entry.displayName for entry in self._entryList]
53-
54-
def registerPlugin(self, strategy: T, *, displayName: str, simpleName: str = '') -> None:
55-
if not simpleName:
56-
simpleName = re.sub(r'\W+', '', displayName)
57-
58-
entry = PluginEntry[T](strategy, simpleName, displayName)
59-
self._entryList.append(entry)
54+
plugin = Plugin[T](strategy, simple_name, display_name)
55+
self._registered_plugins.append(plugin)
6056
self.notifyObservers()
6157

62-
@property
63-
def currentPlugin(self) -> PluginEntry[T]:
64-
return self._entryList[self._currentIndex]
58+
def get_current_plugin(self) -> Plugin[T]:
59+
return self._registered_plugins[self._current_index]
6560

66-
def setCurrentPluginByName(self, name: str) -> None:
61+
def set_current_plugin(self, name: str) -> None:
6762
namecf = name.casefold()
6863

69-
for index, entry in enumerate(self._entryList):
70-
if namecf == entry.simpleName.casefold() or namecf == entry.displayName.casefold():
71-
if self._currentIndex != index:
72-
self._currentIndex = index
64+
for index, plugin in enumerate(self._registered_plugins):
65+
if namecf == plugin.simple_name.casefold() or namecf == plugin.display_name.casefold():
66+
if self._current_index != index:
67+
self._current_index = index
68+
69+
if self._parameter is not None:
70+
self._parameter.setValue(self.get_current_plugin().simple_name)
71+
7372
self.notifyObservers()
7473

7574
return
7675

7776
logger.debug(f'Invalid plugin name "{name}"')
7877

79-
@overload
80-
def __getitem__(self, index: int) -> PluginEntry[T]: ...
81-
82-
@overload
83-
def __getitem__(self, index: slice) -> Sequence[PluginEntry[T]]: ...
84-
85-
def __getitem__(self, index: int | slice) -> PluginEntry[T] | Sequence[PluginEntry[T]]:
86-
return self._entryList[index]
78+
def synchronize_with_parameter(self, parameter: StringParameter) -> None:
79+
self._parameter = parameter
80+
self.set_current_plugin(parameter.getValue())
81+
self._parameter.addObserver(self)
8782

88-
def __len__(self) -> int:
89-
return len(self._entryList)
83+
def __iter__(self) -> Iterator[Plugin[T]]:
84+
for plugin in self._registered_plugins:
85+
yield plugin
9086

9187
def __bool__(self) -> bool:
92-
return bool(self._entryList)
88+
return bool(self._registered_plugins)
9389

94-
def copy(self) -> PluginChooser[T]:
95-
clone = PluginChooser[T]()
96-
clone._entryList = self._entryList.copy()
97-
clone._currentIndex = self._currentIndex
98-
return clone
90+
def update(self, observable: Observable) -> None:
91+
if self._parameter is not None and observable is self._parameter:
92+
self.set_current_plugin(self._parameter.getValue())
9993

10094

10195
class PluginRegistry:
@@ -118,7 +112,7 @@ def __init__(self) -> None:
118112
self.deconvolutionStrategies = PluginChooser[DeconvolutionStrategy]()
119113

120114
@classmethod
121-
def loadPlugins(cls) -> PluginRegistry:
115+
def load_plugins(cls) -> PluginRegistry:
122116
registry = cls()
123117

124118
import ptychodus.plugins
@@ -137,6 +131,6 @@ def loadPlugins(cls) -> PluginRegistry:
137131
logger.warning(exc)
138132
else:
139133
logger.info(f'Registering {moduleInfo.name}')
140-
module.registerPlugins(registry)
134+
module.register_plugins(registry)
141135

142136
return registry

src/ptychodus/controller/object/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ def _loadCurrentObjectFromFile(self) -> None:
137137
filePath, nameFilter = self._fileDialogFactory.getOpenFilePath(
138138
self._view,
139139
'Open Object',
140-
nameFilters=self._api.getOpenFileFilterList(),
140+
nameFilters=[nameFilter for nameFilter in self._api.getOpenFileFilterList()],
141141
selectedNameFilter=self._api.getOpenFileFilter(),
142142
)
143143

@@ -181,7 +181,7 @@ def _saveCurrentObjectToFile(self) -> None:
181181
filePath, nameFilter = self._fileDialogFactory.getSaveFilePath(
182182
self._view,
183183
'Save Object',
184-
nameFilters=self._api.getSaveFileFilterList(),
184+
nameFilters=[nameFilter for nameFilter in self._api.getSaveFileFilterList()],
185185
selectedNameFilter=self._api.getSaveFileFilter(),
186186
)
187187

src/ptychodus/controller/patterns/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ def _saveDataset(self) -> None:
103103
filePath, nameFilter = self._file_dialog_factory.getSaveFilePath(
104104
self._view,
105105
'Save Diffraction File',
106-
nameFilters=fileWriterChooser.getDisplayNameList(),
107-
selectedNameFilter=fileWriterChooser.currentPlugin.displayName,
106+
nameFilters=[plugin.display_name for plugin in fileWriterChooser],
107+
selectedNameFilter=fileWriterChooser.get_current_plugin().display_name,
108108
)
109109

110110
if filePath:

src/ptychodus/controller/patterns/wizard/files.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,8 +222,8 @@ def __init__(self, api: PatternsAPI) -> None:
222222
self._file_reader_chooser.addObserver(self)
223223
self._combo_box = QComboBox()
224224

225-
for file_type in self._file_reader_chooser.getDisplayNameList():
226-
self._combo_box.addItem(file_type)
225+
for plugin in self._file_reader_chooser:
226+
self._combo_box.addItem(plugin.display_name)
227227

228228
self._sync_model_to_view()
229229
self._combo_box.textActivated.connect(self._handle_text_activated)
@@ -238,7 +238,7 @@ def _handle_text_activated(self, text: str) -> None:
238238
self.notifyObservers()
239239

240240
def _sync_model_to_view(self) -> None:
241-
self._combo_box.setCurrentText(self._file_reader_chooser.currentPlugin.displayName)
241+
self._combo_box.setCurrentText(self._file_reader_chooser.get_current_plugin().display_name)
242242

243243
def get_widget(self) -> QWidget:
244244
return self._combo_box
@@ -284,7 +284,7 @@ def __init__(
284284

285285
def open_dataset(self) -> None:
286286
file_reader_chooser = self._api.getFileReaderChooser()
287-
file_type = file_reader_chooser.currentPlugin.simpleName
287+
file_type = file_reader_chooser.get_current_plugin().simple_name
288288
file_path = self._settings.filePath.getValue()
289289

290290
try:

src/ptychodus/controller/probe/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def _loadCurrentProbeFromFile(self) -> None:
179179
filePath, nameFilter = self._fileDialogFactory.getOpenFilePath(
180180
self._view,
181181
'Open Probe',
182-
nameFilters=self._api.getOpenFileFilterList(),
182+
nameFilters=[nameFilter for nameFilter in self._api.getOpenFileFilterList()],
183183
selectedNameFilter=self._api.getOpenFileFilter(),
184184
)
185185

@@ -223,7 +223,7 @@ def _saveCurrentProbeToFile(self) -> None:
223223
filePath, nameFilter = self._fileDialogFactory.getSaveFilePath(
224224
self._view,
225225
'Save Probe',
226-
nameFilters=self._api.getSaveFileFilterList(),
226+
nameFilters=[nameFilter for nameFilter in self._api.getSaveFileFilterList()],
227227
selectedNameFilter=self._api.getSaveFileFilter(),
228228
)
229229

src/ptychodus/controller/probe/editorFactory.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ def __init__(self, title: str, probeBuilder: FresnelZonePlateProbeBuilder) -> No
4343
super().__init__()
4444
self._widget = GroupBoxWithPresets(title)
4545

46-
for index, presetsLabel in enumerate(probeBuilder.labelsForPresets()):
47-
action = self._widget.presetsMenu.addAction(presetsLabel)
48-
action.triggered.connect(lambda _, index=index: probeBuilder.applyPresets(index))
46+
for label in probeBuilder.labelsForPresets():
47+
action = self._widget.presetsMenu.addAction(label)
48+
action.triggered.connect(lambda _, label=label: probeBuilder.applyPresets(label))
4949

5050
self._zonePlateDiameterViewController = LengthWidgetParameterViewController(
5151
probeBuilder.zonePlateDiameterInMeters

src/ptychodus/controller/probe/fluorescence.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ def _openMeasuredDataset(self) -> None:
194194
filePath, nameFilter = self._fileDialogFactory.getOpenFilePath(
195195
self._dialog,
196196
title,
197-
nameFilters=self._enhancer.getOpenFileFilterList(),
197+
nameFilters=[nameFilter for nameFilter in self._enhancer.getOpenFileFilterList()],
198198
selectedNameFilter=self._enhancer.getOpenFileFilter(),
199199
)
200200

@@ -229,7 +229,7 @@ def _saveEnhancedDataset(self) -> None:
229229
filePath, nameFilter = self._fileDialogFactory.getSaveFilePath(
230230
self._dialog,
231231
title,
232-
nameFilters=self._enhancer.getSaveFileFilterList(),
232+
nameFilters=[nameFilter for nameFilter in self._enhancer.getSaveFileFilterList()],
233233
selectedNameFilter=self._enhancer.getSaveFileFilter(),
234234
)
235235

src/ptychodus/controller/product/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def _openProductFromFile(self) -> None:
239239
filePath, nameFilter = self._fileDialogFactory.getOpenFilePath(
240240
self._view,
241241
'Open Product',
242-
nameFilters=self._api.getOpenFileFilterList(),
242+
nameFilters=[nameFilter for nameFilter in self._api.getOpenFileFilterList()],
243243
selectedNameFilter=self._api.getOpenFileFilter(),
244244
)
245245

@@ -260,7 +260,7 @@ def _saveCurrentProductToFile(self) -> None:
260260
filePath, nameFilter = self._fileDialogFactory.getSaveFilePath(
261261
self._view,
262262
'Save Product',
263-
nameFilters=self._api.getSaveFileFilterList(),
263+
nameFilters=[nameFilter for nameFilter in self._api.getSaveFileFilterList()],
264264
selectedNameFilter=self._api.getSaveFileFilter(),
265265
)
266266

src/ptychodus/controller/scan/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def _loadCurrentScanFromFile(self) -> None:
117117
filePath, nameFilter = self._fileDialogFactory.getOpenFilePath(
118118
self._view,
119119
'Open Scan',
120-
nameFilters=self._api.getOpenFileFilterList(),
120+
nameFilters=[nameFilter for nameFilter in self._api.getOpenFileFilterList()],
121121
selectedNameFilter=self._api.getOpenFileFilter(),
122122
)
123123

@@ -161,7 +161,7 @@ def _saveCurrentScanToFile(self) -> None:
161161
filePath, nameFilter = self._fileDialogFactory.getSaveFilePath(
162162
self._view,
163163
'Save Scan',
164-
nameFilters=self._api.getSaveFileFilterList(),
164+
nameFilters=[nameFilter for nameFilter in self._api.getSaveFileFilterList()],
165165
selectedNameFilter=self._api.getSaveFileFilter(),
166166
)
167167

src/ptychodus/model/automation/core.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from __future__ import annotations
2-
from collections.abc import Sequence
2+
from collections.abc import Iterator
33
from pathlib import Path
44
import queue
55

@@ -36,7 +36,7 @@ def __init__(
3636
settings.addObserver(self)
3737
watcher.addObserver(self)
3838

39-
def getStrategyList(self) -> Sequence[str]:
39+
def getStrategyList(self) -> Iterator[str]:
4040
return self._workflow.getAvailableWorkflows()
4141

4242
def getStrategy(self) -> str:

0 commit comments

Comments
 (0)