mosamatic2 2.0.1__py3-none-any.whl → 2.0.3__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.
Potentially problematic release.
This version of mosamatic2 might be problematic. Click here for more details.
- mosamatic2/app.py +31 -1
- mosamatic2/cli.py +32 -0
- mosamatic2/commands/__init__.py +0 -0
- mosamatic2/commands/calculatescores.py +73 -0
- mosamatic2/commands/createpngsfromsegmentations.py +65 -0
- mosamatic2/commands/rescaledicomimages.py +54 -0
- mosamatic2/commands/segmentmusclefatl3tensorflow.py +55 -0
- mosamatic2/constants.py +27 -0
- mosamatic2/core/__init__.py +0 -0
- mosamatic2/core/data/__init__.py +5 -0
- mosamatic2/core/data/dicomimage.py +18 -0
- mosamatic2/core/data/dicomimageseries.py +26 -0
- mosamatic2/core/data/dixonseries.py +22 -0
- mosamatic2/core/data/filedata.py +26 -0
- mosamatic2/core/data/multidicomimage.py +30 -0
- mosamatic2/core/managers/__init__.py +0 -0
- mosamatic2/core/managers/logmanager.py +45 -0
- mosamatic2/core/managers/logmanagerlistener.py +3 -0
- mosamatic2/core/pipelines/__init__.py +1 -0
- mosamatic2/core/pipelines/defaultpipeline.py +79 -0
- mosamatic2/core/pipelines/pipeline.py +14 -0
- mosamatic2/core/singleton.py +9 -0
- mosamatic2/core/tasks/__init__.py +4 -0
- mosamatic2/core/tasks/calculatescorestask/__init__.py +0 -0
- mosamatic2/core/tasks/calculatescorestask/calculatescorestask.py +149 -0
- mosamatic2/core/tasks/createpngsfromsegmentationstask/__init__.py +0 -0
- mosamatic2/core/tasks/createpngsfromsegmentationstask/createpngsfromsegmentationstask.py +52 -0
- mosamatic2/core/tasks/rescaledicomimagestask/__init__.py +0 -0
- mosamatic2/core/tasks/rescaledicomimagestask/rescaledicomimagestask.py +64 -0
- mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/__init__.py +0 -0
- mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/paramloader.py +39 -0
- mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/segmentmusclefatl3tensorflowtask.py +121 -0
- mosamatic2/core/tasks/task.py +49 -0
- mosamatic2/core/utils.py +316 -0
- mosamatic2/server.py +98 -0
- mosamatic2/ui/__init__.py +0 -0
- mosamatic2/ui/mainwindow.py +196 -0
- mosamatic2/ui/resources/VERSION +1 -0
- mosamatic2/ui/resources/icons/mosamatic2.icns +0 -0
- mosamatic2/ui/resources/icons/mosamatic2.ico +0 -0
- mosamatic2/ui/resources/icons/spinner.gif +0 -0
- mosamatic2/ui/resources/images/body-composition.jpg +0 -0
- mosamatic2/ui/settings.py +62 -0
- mosamatic2/ui/utils.py +36 -0
- mosamatic2/ui/widgets/__init__.py +0 -0
- mosamatic2/ui/widgets/dialogs/__init__.py +0 -0
- mosamatic2/ui/widgets/dialogs/dialog.py +16 -0
- mosamatic2/ui/widgets/dialogs/helpdialog.py +9 -0
- mosamatic2/ui/widgets/panels/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/defaultpanel.py +31 -0
- mosamatic2/ui/widgets/panels/logpanel.py +65 -0
- mosamatic2/ui/widgets/panels/mainpanel.py +82 -0
- mosamatic2/ui/widgets/panels/pipelines/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/pipelines/defaultpipelinepanel.py +299 -0
- mosamatic2/ui/widgets/panels/stackedpanel.py +22 -0
- mosamatic2/ui/widgets/panels/taskpanel.py +6 -0
- mosamatic2/ui/widgets/panels/tasks/__init__.py +0 -0
- mosamatic2/ui/widgets/panels/tasks/calculatescorestaskpanel.py +215 -0
- mosamatic2/ui/widgets/panels/tasks/createpngsfromsegmentationstaskpanel.py +186 -0
- mosamatic2/ui/widgets/panels/tasks/rescaledicomimagestaskpanel.py +184 -0
- mosamatic2/ui/widgets/panels/tasks/segmentmusclefatl3tensorflowtaskpanel.py +216 -0
- mosamatic2/ui/widgets/panels/tasks/selectslicefromscantaskpanel.py +184 -0
- mosamatic2/ui/widgets/splashscreen.py +101 -0
- mosamatic2/ui/worker.py +29 -0
- mosamatic2-2.0.3.dist-info/METADATA +34 -0
- mosamatic2-2.0.3.dist-info/RECORD +70 -0
- mosamatic2-2.0.3.dist-info/entry_points.txt +5 -0
- mosamatic2/api.py +0 -2
- mosamatic2-2.0.1.dist-info/METADATA +0 -12
- mosamatic2-2.0.1.dist-info/RECORD +0 -8
- mosamatic2-2.0.1.dist-info/entry_points.txt +0 -4
- {mosamatic2-2.0.1.dist-info → mosamatic2-2.0.3.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from PySide6.QtWidgets import (
|
|
4
|
+
QLineEdit,
|
|
5
|
+
QCheckBox,
|
|
6
|
+
QHBoxLayout,
|
|
7
|
+
QVBoxLayout,
|
|
8
|
+
QFormLayout,
|
|
9
|
+
QPushButton,
|
|
10
|
+
QFileDialog,
|
|
11
|
+
QMessageBox,
|
|
12
|
+
)
|
|
13
|
+
from PySide6.QtCore import (
|
|
14
|
+
QThread,
|
|
15
|
+
Slot,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
from mosamatic2.core.managers.logmanager import LogManager
|
|
19
|
+
from mosamatic2.ui.widgets.panels.taskpanel import TaskPanel
|
|
20
|
+
from mosamatic2.ui.settings import Settings
|
|
21
|
+
from mosamatic2.ui.utils import is_macos
|
|
22
|
+
from mosamatic2.ui.worker import Worker
|
|
23
|
+
from mosamatic2.core.tasks import SegmentMuscleFatL3TensorFlowTask
|
|
24
|
+
|
|
25
|
+
LOG = LogManager()
|
|
26
|
+
|
|
27
|
+
PANEL_TITLE = 'SegmentMuscleFatL3TensorFlowTask (TensorFlow)'
|
|
28
|
+
PANEL_NAME = 'segmentmusclefatl3tensorflowtaskpanel'
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class SegmentMuscleFatL3TensorFlowTaskPanel(TaskPanel):
|
|
32
|
+
def __init__(self):
|
|
33
|
+
super(SegmentMuscleFatL3TensorFlowTaskPanel, self).__init__()
|
|
34
|
+
self.set_title(PANEL_TITLE)
|
|
35
|
+
self._images_dir_line_edit = None
|
|
36
|
+
self._images_dir_select_button = None
|
|
37
|
+
self._model_files_dir_line_edit = None
|
|
38
|
+
self._model_files_dir_select_button = None
|
|
39
|
+
self._output_dir_line_edit = None
|
|
40
|
+
self._output_dir_select_button = None
|
|
41
|
+
self._overwrite_checkbox = None
|
|
42
|
+
self._form_layout = None
|
|
43
|
+
self._run_task_button = None
|
|
44
|
+
self._settings = None
|
|
45
|
+
self._task = None
|
|
46
|
+
self._worker = None
|
|
47
|
+
self._thread = None
|
|
48
|
+
self.init_layout()
|
|
49
|
+
|
|
50
|
+
def images_dir_line_edit(self):
|
|
51
|
+
if not self._images_dir_line_edit:
|
|
52
|
+
self._images_dir_line_edit = QLineEdit(self.settings().get(f'{PANEL_NAME}/images_dir'))
|
|
53
|
+
return self._images_dir_line_edit
|
|
54
|
+
|
|
55
|
+
def images_dir_select_button(self):
|
|
56
|
+
if not self._images_dir_select_button:
|
|
57
|
+
self._images_dir_select_button = QPushButton('Select')
|
|
58
|
+
self._images_dir_select_button.clicked.connect(self.handle_images_dir_select_button)
|
|
59
|
+
return self._images_dir_select_button
|
|
60
|
+
|
|
61
|
+
def model_files_dir_line_edit(self):
|
|
62
|
+
if not self._model_files_dir_line_edit:
|
|
63
|
+
self._model_files_dir_line_edit = QLineEdit(self.settings().get(f'{PANEL_NAME}/model_files_dir'))
|
|
64
|
+
return self._model_files_dir_line_edit
|
|
65
|
+
|
|
66
|
+
def model_files_dir_select_button(self):
|
|
67
|
+
if not self._model_files_dir_select_button:
|
|
68
|
+
self._model_files_dir_select_button = QPushButton('Select')
|
|
69
|
+
self._model_files_dir_select_button.clicked.connect(self.handle_model_files_dir_select_button)
|
|
70
|
+
return self._model_files_dir_select_button
|
|
71
|
+
|
|
72
|
+
def output_dir_line_edit(self):
|
|
73
|
+
if not self._output_dir_line_edit:
|
|
74
|
+
self._output_dir_line_edit = QLineEdit(self.settings().get(f'{PANEL_NAME}/output_dir'))
|
|
75
|
+
return self._output_dir_line_edit
|
|
76
|
+
|
|
77
|
+
def output_dir_select_button(self):
|
|
78
|
+
if not self._output_dir_select_button:
|
|
79
|
+
self._output_dir_select_button = QPushButton('Select')
|
|
80
|
+
self._output_dir_select_button.clicked.connect(self.handle_output_dir_select_button)
|
|
81
|
+
return self._output_dir_select_button
|
|
82
|
+
|
|
83
|
+
def overwrite_checkbox(self):
|
|
84
|
+
if not self._overwrite_checkbox:
|
|
85
|
+
self._overwrite_checkbox = QCheckBox('')
|
|
86
|
+
self._overwrite_checkbox.setChecked(self.settings().get_bool(f'{PANEL_NAME}/overwrite', True))
|
|
87
|
+
return self._overwrite_checkbox
|
|
88
|
+
|
|
89
|
+
def form_layout(self):
|
|
90
|
+
if not self._form_layout:
|
|
91
|
+
self._form_layout = QFormLayout()
|
|
92
|
+
if is_macos():
|
|
93
|
+
self._form_layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
|
|
94
|
+
return self._form_layout
|
|
95
|
+
|
|
96
|
+
def run_task_button(self):
|
|
97
|
+
if not self._run_task_button:
|
|
98
|
+
self._run_task_button = QPushButton('Run task')
|
|
99
|
+
self._run_task_button.clicked.connect(self.handle_run_task_button)
|
|
100
|
+
return self._run_task_button
|
|
101
|
+
|
|
102
|
+
def settings(self):
|
|
103
|
+
if not self._settings:
|
|
104
|
+
self._settings = Settings()
|
|
105
|
+
return self._settings
|
|
106
|
+
|
|
107
|
+
def init_layout(self):
|
|
108
|
+
images_dir_layout = QHBoxLayout()
|
|
109
|
+
images_dir_layout.addWidget(self.images_dir_line_edit())
|
|
110
|
+
images_dir_layout.addWidget(self.images_dir_select_button())
|
|
111
|
+
model_files_dir_layout = QHBoxLayout()
|
|
112
|
+
model_files_dir_layout.addWidget(self.model_files_dir_line_edit())
|
|
113
|
+
model_files_dir_layout.addWidget(self.model_files_dir_select_button())
|
|
114
|
+
output_dir_layout = QHBoxLayout()
|
|
115
|
+
output_dir_layout.addWidget(self.output_dir_line_edit())
|
|
116
|
+
output_dir_layout.addWidget(self.output_dir_select_button())
|
|
117
|
+
self.form_layout().addRow('Images directory', images_dir_layout)
|
|
118
|
+
self.form_layout().addRow('Model files directory', model_files_dir_layout)
|
|
119
|
+
self.form_layout().addRow('Output directory', output_dir_layout)
|
|
120
|
+
self.form_layout().addRow('Overwrite', self.overwrite_checkbox())
|
|
121
|
+
layout = QVBoxLayout()
|
|
122
|
+
layout.addLayout(self.form_layout())
|
|
123
|
+
layout.addWidget(self.run_task_button())
|
|
124
|
+
self.setLayout(layout)
|
|
125
|
+
self.setObjectName(PANEL_NAME)
|
|
126
|
+
|
|
127
|
+
def handle_images_dir_select_button(self):
|
|
128
|
+
last_directory = self.settings().get('last_directory')
|
|
129
|
+
directory = QFileDialog.getExistingDirectory(dir=last_directory)
|
|
130
|
+
if directory:
|
|
131
|
+
self.images_dir_line_edit().setText(directory)
|
|
132
|
+
self.settings().set('last_directory', directory)
|
|
133
|
+
|
|
134
|
+
def handle_model_files_dir_select_button(self):
|
|
135
|
+
last_directory = self.settings().get('last_directory')
|
|
136
|
+
directory = QFileDialog.getExistingDirectory(dir=last_directory)
|
|
137
|
+
if directory:
|
|
138
|
+
self.model_files_dir_line_edit().setText(directory)
|
|
139
|
+
self.settings().set('last_directory', directory)
|
|
140
|
+
|
|
141
|
+
def handle_output_dir_select_button(self):
|
|
142
|
+
last_directory = self.settings().get('last_directory')
|
|
143
|
+
directory = QFileDialog.getExistingDirectory(dir=last_directory)
|
|
144
|
+
if directory:
|
|
145
|
+
self.output_dir_line_edit().setText(directory)
|
|
146
|
+
self.settings().set('last_directory', directory)
|
|
147
|
+
|
|
148
|
+
def handle_run_task_button(self):
|
|
149
|
+
errors = self.check_inputs_and_parameters()
|
|
150
|
+
if len(errors) > 0:
|
|
151
|
+
error_message = 'Following errors were encountered:\n'
|
|
152
|
+
for error in errors:
|
|
153
|
+
error_message += f' - {error}\n'
|
|
154
|
+
QMessageBox.information(self, 'Error', error_message)
|
|
155
|
+
else:
|
|
156
|
+
LOG.info('Running task...')
|
|
157
|
+
self.run_task_button().setEnabled(False)
|
|
158
|
+
self.save_inputs_and_parameters()
|
|
159
|
+
self._task = SegmentMuscleFatL3TensorFlowTask(
|
|
160
|
+
inputs={
|
|
161
|
+
'images': self.images_dir_line_edit().text(),
|
|
162
|
+
'model_files': self.model_files_dir_line_edit().text(),
|
|
163
|
+
},
|
|
164
|
+
params={'model_version': 1.0},
|
|
165
|
+
output=self.output_dir_line_edit().text(),
|
|
166
|
+
overwrite=self.overwrite_checkbox().isChecked(),
|
|
167
|
+
)
|
|
168
|
+
self._worker = Worker(self._task)
|
|
169
|
+
self._thread = QThread()
|
|
170
|
+
self._worker.moveToThread(self._thread)
|
|
171
|
+
self._thread.started.connect(self._worker.run)
|
|
172
|
+
self._worker.progress.connect(self.handle_progress)
|
|
173
|
+
self._worker.status.connect(self.handle_status)
|
|
174
|
+
self._worker.finished.connect(self.handle_finished)
|
|
175
|
+
self._worker.finished.connect(self._thread.quit)
|
|
176
|
+
self._worker.finished.connect(self._worker.deleteLater)
|
|
177
|
+
self._thread.finished.connect(self._thread.deleteLater)
|
|
178
|
+
self._thread.start()
|
|
179
|
+
|
|
180
|
+
@Slot(int)
|
|
181
|
+
def handle_progress(self, progress):
|
|
182
|
+
LOG.info(f'Progress: {progress} / 100%')
|
|
183
|
+
|
|
184
|
+
@Slot(str)
|
|
185
|
+
def handle_status(self, status):
|
|
186
|
+
LOG.info(f'Status: {status}')
|
|
187
|
+
|
|
188
|
+
@Slot()
|
|
189
|
+
def handle_finished(self):
|
|
190
|
+
self.run_task_button().setEnabled(True)
|
|
191
|
+
|
|
192
|
+
# HELPERS
|
|
193
|
+
|
|
194
|
+
def check_inputs_and_parameters(self):
|
|
195
|
+
errors = []
|
|
196
|
+
if self.images_dir_line_edit().text() == '':
|
|
197
|
+
errors.append('Empty images directory path')
|
|
198
|
+
if not os.path.isdir(self.images_dir_line_edit().text()):
|
|
199
|
+
errors.append('Images directory does not exist')
|
|
200
|
+
if self.model_files_dir_line_edit().text() == '':
|
|
201
|
+
errors.append('Empty model files directory path')
|
|
202
|
+
if not os.path.isdir(self.model_files_dir_line_edit().text()):
|
|
203
|
+
errors.append('Model files directory does not exist')
|
|
204
|
+
if len(os.listdir(self.model_files_dir_line_edit().text())) != 3:
|
|
205
|
+
errors.append('Model files directory should ONLY contain "model-1.1.zip", "contour_model-1.1.zip" and "params-1.1.json", nothing else!')
|
|
206
|
+
if self.output_dir_line_edit().text() == '':
|
|
207
|
+
errors.append('Empty output directory path')
|
|
208
|
+
if os.path.isdir(self.output_dir_line_edit().text()) and not self.overwrite_checkbox().isChecked():
|
|
209
|
+
errors.append('Output directory exists but overwrite=False. Please remove output directory first')
|
|
210
|
+
return errors
|
|
211
|
+
|
|
212
|
+
def save_inputs_and_parameters(self):
|
|
213
|
+
self.settings().set(f'{PANEL_NAME}/images_dir', self.images_dir_line_edit().text())
|
|
214
|
+
self.settings().set(f'{PANEL_NAME}/model_files_dir', self.model_files_dir_line_edit().text())
|
|
215
|
+
self.settings().set(f'{PANEL_NAME}/output_dir', self.output_dir_line_edit().text())
|
|
216
|
+
self.settings().set(f'{PANEL_NAME}/overwrite', self.overwrite_checkbox().isChecked())
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from PySide6.QtWidgets import (
|
|
4
|
+
QLineEdit,
|
|
5
|
+
QCheckBox,
|
|
6
|
+
QSpinBox,
|
|
7
|
+
QHBoxLayout,
|
|
8
|
+
QVBoxLayout,
|
|
9
|
+
QFormLayout,
|
|
10
|
+
QPushButton,
|
|
11
|
+
QFileDialog,
|
|
12
|
+
QMessageBox,
|
|
13
|
+
)
|
|
14
|
+
from PySide6.QtCore import (
|
|
15
|
+
QThread,
|
|
16
|
+
Slot,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
from mosamaticdesktop.core.utils.logmanager import LogManager
|
|
20
|
+
from mosamaticdesktop.ui.panels.taskpanel import TaskPanel
|
|
21
|
+
from mosamaticdesktop.ui.settings import Settings
|
|
22
|
+
from mosamaticdesktop.ui.utils import is_macos
|
|
23
|
+
from mosamaticdesktop.ui.worker import Worker
|
|
24
|
+
|
|
25
|
+
from mosamatic.tasks import SelectSliceFromScanTask
|
|
26
|
+
|
|
27
|
+
LOG = LogManager()
|
|
28
|
+
|
|
29
|
+
PANEL_TITLE = 'Automatically select L3 or T4 slice from full CT scan'
|
|
30
|
+
PANEL_NAME = 'selectslicefromscantaskpanel'
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class SelectSliceFromScanTaskPanel(TaskPanel):
|
|
34
|
+
def __init__(self):
|
|
35
|
+
super(SelectSliceFromScanTaskPanel, self).__init__()
|
|
36
|
+
self.set_title(PANEL_TITLE)
|
|
37
|
+
self._scans_dir_line_edit = None
|
|
38
|
+
self._scans_dir_select_button = None
|
|
39
|
+
self._output_dir_line_edit = None
|
|
40
|
+
self._output_dir_select_button = None
|
|
41
|
+
self._overwrite_checkbox = None
|
|
42
|
+
self._form_layout = None
|
|
43
|
+
self._run_task_button = None
|
|
44
|
+
self._settings = None
|
|
45
|
+
self._task = None
|
|
46
|
+
self._worker = None
|
|
47
|
+
self._thread = None
|
|
48
|
+
self.init_layout()
|
|
49
|
+
|
|
50
|
+
def scans_dir_line_edit(self):
|
|
51
|
+
if not self._scans_dir_line_edit:
|
|
52
|
+
self._scans_dir_line_edit = QLineEdit(self.settings().get(f'{PANEL_NAME}/scans_dir'))
|
|
53
|
+
return self._scans_dir_line_edit
|
|
54
|
+
|
|
55
|
+
def scans_dir_select_button(self):
|
|
56
|
+
if not self._scans_dir_select_button:
|
|
57
|
+
self._scans_dir_select_button = QPushButton('Select')
|
|
58
|
+
self._scans_dir_select_button.clicked.connect(self.handle_scans_dir_select_button)
|
|
59
|
+
return self._scans_dir_select_button
|
|
60
|
+
|
|
61
|
+
def output_dir_line_edit(self):
|
|
62
|
+
if not self._output_dir_line_edit:
|
|
63
|
+
self._output_dir_line_edit = QLineEdit(self.settings().get(f'{PANEL_NAME}/output_dir'))
|
|
64
|
+
return self._output_dir_line_edit
|
|
65
|
+
|
|
66
|
+
def output_dir_select_button(self):
|
|
67
|
+
if not self._output_dir_select_button:
|
|
68
|
+
self._output_dir_select_button = QPushButton('Select')
|
|
69
|
+
self._output_dir_select_button.clicked.connect(self.handle_output_dir_select_button)
|
|
70
|
+
return self._output_dir_select_button
|
|
71
|
+
|
|
72
|
+
def overwrite_checkbox(self):
|
|
73
|
+
if not self._overwrite_checkbox:
|
|
74
|
+
self._overwrite_checkbox = QCheckBox('')
|
|
75
|
+
self._overwrite_checkbox.setChecked(self.settings().get_bool(f'{PANEL_NAME}/overwrite', True))
|
|
76
|
+
return self._overwrite_checkbox
|
|
77
|
+
|
|
78
|
+
def form_layout(self):
|
|
79
|
+
if not self._form_layout:
|
|
80
|
+
self._form_layout = QFormLayout()
|
|
81
|
+
if is_macos():
|
|
82
|
+
self._form_layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
|
|
83
|
+
return self._form_layout
|
|
84
|
+
|
|
85
|
+
def run_task_button(self):
|
|
86
|
+
if not self._run_task_button:
|
|
87
|
+
self._run_task_button = QPushButton('Run task')
|
|
88
|
+
self._run_task_button.clicked.connect(self.handle_run_task_button)
|
|
89
|
+
return self._run_task_button
|
|
90
|
+
|
|
91
|
+
def settings(self):
|
|
92
|
+
if not self._settings:
|
|
93
|
+
self._settings = Settings()
|
|
94
|
+
return self._settings
|
|
95
|
+
|
|
96
|
+
def init_layout(self):
|
|
97
|
+
scans_dir_layout = QHBoxLayout()
|
|
98
|
+
scans_dir_layout.addWidget(self.scans_dir_line_edit())
|
|
99
|
+
scans_dir_layout.addWidget(self.scans_dir_select_button())
|
|
100
|
+
output_dir_layout = QHBoxLayout()
|
|
101
|
+
output_dir_layout.addWidget(self.output_dir_line_edit())
|
|
102
|
+
output_dir_layout.addWidget(self.output_dir_select_button())
|
|
103
|
+
self.form_layout().addRow('Scans directory', scans_dir_layout)
|
|
104
|
+
self.form_layout().addRow('Output directory', output_dir_layout)
|
|
105
|
+
self.form_layout().addRow('Overwrite', self.overwrite_checkbox())
|
|
106
|
+
layout = QVBoxLayout()
|
|
107
|
+
layout.addLayout(self.form_layout())
|
|
108
|
+
layout.addWidget(self.run_task_button())
|
|
109
|
+
self.setLayout(layout)
|
|
110
|
+
self.setObjectName(PANEL_NAME)
|
|
111
|
+
|
|
112
|
+
def handle_scans_dir_select_button(self):
|
|
113
|
+
last_directory = self.settings().get('last_directory')
|
|
114
|
+
directory = QFileDialog.getExistingDirectory(dir=last_directory)
|
|
115
|
+
if directory:
|
|
116
|
+
self.scans_dir_line_edit().setText(directory)
|
|
117
|
+
self.settings().set('last_directory', directory)
|
|
118
|
+
|
|
119
|
+
def handle_output_dir_select_button(self):
|
|
120
|
+
last_directory = self.settings().get('last_directory')
|
|
121
|
+
directory = QFileDialog.getExistingDirectory(dir=last_directory)
|
|
122
|
+
if directory:
|
|
123
|
+
self.output_dir_line_edit().setText(directory)
|
|
124
|
+
self.settings().set('last_directory', directory)
|
|
125
|
+
|
|
126
|
+
def handle_run_task_button(self):
|
|
127
|
+
errors = self.check_inputs_and_parameters()
|
|
128
|
+
if len(errors) > 0:
|
|
129
|
+
error_message = 'Following errors were encountered:\n'
|
|
130
|
+
for error in errors:
|
|
131
|
+
error_message += f' - {error}\n'
|
|
132
|
+
QMessageBox.information(self, 'Error', error_message)
|
|
133
|
+
else:
|
|
134
|
+
LOG.info('Running task...')
|
|
135
|
+
self.run_task_button().setEnabled(False)
|
|
136
|
+
self.save_inputs_and_parameters()
|
|
137
|
+
self._task = SelectSliceFromScanTask(
|
|
138
|
+
self.scans_dir_line_edit().text(),
|
|
139
|
+
self.output_dir_line_edit().text(),
|
|
140
|
+
'vertebrae_L3',
|
|
141
|
+
self.overwrite_checkbox().isChecked()
|
|
142
|
+
)
|
|
143
|
+
self._worker = Worker(self._task)
|
|
144
|
+
self._thread = QThread()
|
|
145
|
+
self._worker.moveToThread(self._thread)
|
|
146
|
+
self._thread.started.connect(self._worker.run)
|
|
147
|
+
self._worker.progress.connect(self.handle_progress)
|
|
148
|
+
self._worker.status.connect(self.handle_status)
|
|
149
|
+
self._worker.finished.connect(self.handle_finished)
|
|
150
|
+
self._worker.finished.connect(self._thread.quit)
|
|
151
|
+
self._worker.finished.connect(self._worker.deleteLater)
|
|
152
|
+
self._thread.finished.connect(self._thread.deleteLater)
|
|
153
|
+
self._thread.start()
|
|
154
|
+
|
|
155
|
+
@Slot(int)
|
|
156
|
+
def handle_progress(self, progress):
|
|
157
|
+
LOG.info(f'Progress: {progress} / 100%')
|
|
158
|
+
|
|
159
|
+
@Slot(str)
|
|
160
|
+
def handle_status(self, status):
|
|
161
|
+
LOG.info(f'Status: {status}')
|
|
162
|
+
|
|
163
|
+
@Slot()
|
|
164
|
+
def handle_finished(self):
|
|
165
|
+
self.run_task_button().setEnabled(True)
|
|
166
|
+
|
|
167
|
+
# HELPERS
|
|
168
|
+
|
|
169
|
+
def check_inputs_and_parameters(self):
|
|
170
|
+
errors = []
|
|
171
|
+
if self.scans_dir_line_edit().text() == '':
|
|
172
|
+
errors.append('Empty scans directory path')
|
|
173
|
+
if not os.path.isdir(self.scans_dir_line_edit().text()):
|
|
174
|
+
errors.append('Scans directory does not exist')
|
|
175
|
+
if self.output_dir_line_edit().text() == '':
|
|
176
|
+
errors.append('Empty output directory path')
|
|
177
|
+
if os.path.isdir(self.output_dir_line_edit().text()) and not self.overwrite_checkbox().isChecked():
|
|
178
|
+
errors.append('Output directory exists but overwrite=False. Please remove output directory first')
|
|
179
|
+
return errors
|
|
180
|
+
|
|
181
|
+
def save_inputs_and_parameters(self):
|
|
182
|
+
self.settings().set(f'{PANEL_NAME}/scans_dir', self.scans_dir_line_edit().text())
|
|
183
|
+
self.settings().set(f'{PANEL_NAME}/output_dir', self.output_dir_line_edit().text())
|
|
184
|
+
self.settings().set(f'{PANEL_NAME}/overwrite', self.overwrite_checkbox().isChecked())
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import mosamatic2.constants as constants
|
|
3
|
+
from PySide6.QtWidgets import (
|
|
4
|
+
QWidget,
|
|
5
|
+
QVBoxLayout,
|
|
6
|
+
QPushButton,
|
|
7
|
+
QLabel,
|
|
8
|
+
)
|
|
9
|
+
from PySide6.QtCore import Qt
|
|
10
|
+
from PySide6.QtGui import QPixmap
|
|
11
|
+
from mosamatic2.ui.mainwindow import MainWindow
|
|
12
|
+
from mosamatic2.ui.utils import resource_path, set_opacity, version
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SplashScreen(QWidget):
|
|
16
|
+
def __init__(self):
|
|
17
|
+
super(SplashScreen, self).__init__()
|
|
18
|
+
self._main = None
|
|
19
|
+
self._background_label = None
|
|
20
|
+
self._background_pixmap = None
|
|
21
|
+
self._title_label = None
|
|
22
|
+
self._sub_text_label = None
|
|
23
|
+
self._start_app_button = None
|
|
24
|
+
self._donate_button = None
|
|
25
|
+
self._close_button = None
|
|
26
|
+
self.init_layout()
|
|
27
|
+
|
|
28
|
+
def main(self):
|
|
29
|
+
if not self._main:
|
|
30
|
+
self._main = MainWindow()
|
|
31
|
+
return self._main
|
|
32
|
+
|
|
33
|
+
def background_label(self):
|
|
34
|
+
if not self._background_label:
|
|
35
|
+
self._background_label = QLabel(self)
|
|
36
|
+
self._background_label.setPixmap(self.background_pixmap())
|
|
37
|
+
self._background_label.setGeometry(0, 0, self.width(), self.height())
|
|
38
|
+
self._background_label.lower()
|
|
39
|
+
return self._background_label
|
|
40
|
+
|
|
41
|
+
def background_pixmap(self):
|
|
42
|
+
if not self._background_pixmap:
|
|
43
|
+
self._background_pixmap = QPixmap(resource_path(os.path.join(
|
|
44
|
+
constants.MOSAMATIC2_IMAGES_DIR_PATH, constants.MOSAMATIC2_BACKGROUND_IMAGE_FILE_NAME,
|
|
45
|
+
))).scaled(self.size(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
|
|
46
|
+
self._background_pixmap = set_opacity(self._background_pixmap, constants.MOSAMATIC2_BACKGROUND_IMAGE_OPACITY)
|
|
47
|
+
return self._background_pixmap
|
|
48
|
+
|
|
49
|
+
def title_label(self):
|
|
50
|
+
if not self._title_label:
|
|
51
|
+
self._title_label = QLabel(f'{constants.MOSAMATIC2_SPLASH_SCREEN_TITLE} {version()}')
|
|
52
|
+
self._title_label.setStyleSheet(constants.MOSAMATIC2_SPLASH_SCREEN_TITLE_STYLESHEET)
|
|
53
|
+
self._title_label.setAlignment(Qt.AlignCenter)
|
|
54
|
+
return self._title_label
|
|
55
|
+
|
|
56
|
+
def sub_text_label(self):
|
|
57
|
+
if not self._sub_text_label:
|
|
58
|
+
message = constants.MOSAMATIC2_SPLASH_SCREEN_SUB_TEXT
|
|
59
|
+
self._sub_text_label = QLabel(message)
|
|
60
|
+
self._sub_text_label.setStyleSheet(constants.MOSAMATIC2_SPLASH_SCREEN_SUB_TEXT_STYLE_SHEET)
|
|
61
|
+
self._sub_text_label.setAlignment(Qt.AlignCenter)
|
|
62
|
+
return self._sub_text_label
|
|
63
|
+
|
|
64
|
+
def start_app_button(self):
|
|
65
|
+
if not self._start_app_button:
|
|
66
|
+
self._start_app_button = QPushButton(constants.MOSAMATIC2_SPLASH_SCREEN_START_BUTTON_TEXT)
|
|
67
|
+
self._start_app_button.clicked.connect(self.handle_start_app_button)
|
|
68
|
+
return self._start_app_button
|
|
69
|
+
|
|
70
|
+
def close_button(self):
|
|
71
|
+
if not self._close_button:
|
|
72
|
+
self._close_button = QPushButton(constants.MOSAMATIC2_SPLASH_SCREEN_QUIT_BUTTON_TEXT)
|
|
73
|
+
self._close_button.clicked.connect(self.handle_close_button)
|
|
74
|
+
return self._close_button
|
|
75
|
+
|
|
76
|
+
# LAYOUT
|
|
77
|
+
|
|
78
|
+
def init_layout(self):
|
|
79
|
+
layout = QVBoxLayout()
|
|
80
|
+
layout.addWidget(self.title_label())
|
|
81
|
+
layout.addWidget(self.sub_text_label())
|
|
82
|
+
layout.addWidget(self.start_app_button())
|
|
83
|
+
layout.addWidget(self.close_button())
|
|
84
|
+
self.setLayout(layout)
|
|
85
|
+
self.setFixedSize(constants.MOSAMATIC2_SPLASH_SCREEN_W, constants.MOSAMATIC2_SPLASH_SCREEN_H)
|
|
86
|
+
self.setWindowFlags(Qt.FramelessWindowHint)
|
|
87
|
+
|
|
88
|
+
# EVENT HANDLERS
|
|
89
|
+
|
|
90
|
+
def handle_start_app_button(self):
|
|
91
|
+
self.close()
|
|
92
|
+
self.main().show()
|
|
93
|
+
|
|
94
|
+
def handle_close_button(self):
|
|
95
|
+
self.close()
|
|
96
|
+
|
|
97
|
+
def resizeEvent(self, event):
|
|
98
|
+
super().resizeEvent(event)
|
|
99
|
+
scaled = self.background_pixmap().scaled(self.size(), Qt.KeepAspectRatioByExpanding, Qt.SmoothTransformation)
|
|
100
|
+
self.background_label().setPixmap(scaled)
|
|
101
|
+
self.background_label().setGeometry(0, 0, self.width(), self.height())
|
mosamatic2/ui/worker.py
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import traceback
|
|
2
|
+
from PySide6.QtCore import (
|
|
3
|
+
QObject,
|
|
4
|
+
Signal,
|
|
5
|
+
)
|
|
6
|
+
from mosamatic2.core.managers.logmanager import LogManager
|
|
7
|
+
|
|
8
|
+
LOG = LogManager()
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Worker(QObject):
|
|
12
|
+
progress = Signal(int)
|
|
13
|
+
status = Signal(str)
|
|
14
|
+
finished = Signal()
|
|
15
|
+
|
|
16
|
+
def __init__(self, task):
|
|
17
|
+
super(Worker, self).__init__()
|
|
18
|
+
self._task = task
|
|
19
|
+
|
|
20
|
+
def run(self):
|
|
21
|
+
try:
|
|
22
|
+
self.status.emit('started')
|
|
23
|
+
self._task.run()
|
|
24
|
+
self.status.emit('done')
|
|
25
|
+
self.finished.emit()
|
|
26
|
+
except Exception as e:
|
|
27
|
+
self.status.emit('failed')
|
|
28
|
+
LOG.error(traceback.format_exc())
|
|
29
|
+
self.finished.emit()
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: mosamatic2
|
|
3
|
+
Version: 2.0.3
|
|
4
|
+
Summary:
|
|
5
|
+
Author: Ralph Brecheisen
|
|
6
|
+
Author-email: r.brecheisen@maastrichtuniversity.nl
|
|
7
|
+
Requires-Python: >=3.11,<3.12
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
+
Requires-Dist: antspyx (>=0.5.4)
|
|
11
|
+
Requires-Dist: flask (>=3.1.2)
|
|
12
|
+
Requires-Dist: nibabel (>=5.3.2)
|
|
13
|
+
Requires-Dist: numpy (>=1.26.4)
|
|
14
|
+
Requires-Dist: openpyxl (>=3.1.5)
|
|
15
|
+
Requires-Dist: pandas (>=2.3.2)
|
|
16
|
+
Requires-Dist: pendulum (>=3.1.0)
|
|
17
|
+
Requires-Dist: pillow (>=11.3.0)
|
|
18
|
+
Requires-Dist: pydicom (>=3.0.1)
|
|
19
|
+
Requires-Dist: pyside6-essentials (>=6.9)
|
|
20
|
+
Requires-Dist: python-gdcm (>=3.0.26)
|
|
21
|
+
Requires-Dist: scipy (>=1.15.3)
|
|
22
|
+
Requires-Dist: tensorboard (==2.15.2)
|
|
23
|
+
Requires-Dist: tensorboard-data-server (==0.7.2)
|
|
24
|
+
Requires-Dist: tensorflow (==2.15.*) ; platform_system == "Linux"
|
|
25
|
+
Requires-Dist: tensorflow-intel (==2.15.0) ; platform_system == "Windows"
|
|
26
|
+
Requires-Dist: tensorflow-io-gcs-filesystem (==0.31.0) ; platform_system == "Windows"
|
|
27
|
+
Requires-Dist: tensorflow-io-gcs-filesystem (>=0.31.0) ; platform_system == "Darwin" and platform_machine == "arm64"
|
|
28
|
+
Requires-Dist: tensorflow-macos (==2.15.0) ; platform_system == "Darwin" and platform_machine == "arm64"
|
|
29
|
+
Requires-Dist: torch (>=2.8.0)
|
|
30
|
+
Requires-Dist: torchvision (>=0.23.0)
|
|
31
|
+
Requires-Dist: totalsegmentator (>=2.11.0)
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
models.py,sha256=Kx6oWKt7IpTTxrhBDrX61X-ZX12J7yPkJFuhVDsDHoQ,8807
|
|
2
|
+
mosamatic2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
mosamatic2/app.py,sha256=RIUa5tvMYFcmEII4xZPLZZdx9dXWqBvwkxkl_R97Jkw,860
|
|
4
|
+
mosamatic2/cli.py,sha256=nrWwbU90RUOcYgmTJ1u5PspO_qy-MPdHX65Nx6kYSkk,1140
|
|
5
|
+
mosamatic2/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
mosamatic2/commands/calculatescores.py,sha256=WtNWB9OKFpiv0z0yqIFJbKuP7ZE5IaeDb70Qlt_WlDY,1989
|
|
7
|
+
mosamatic2/commands/createpngsfromsegmentations.py,sha256=uUAQJVTqOkBCfENzi21RBNYvf6_nuesx1MeR3j_-7dM,1682
|
|
8
|
+
mosamatic2/commands/rescaledicomimages.py,sha256=9yQxk31apPXSJcICbsWgk-2Z6VJkC1bZIMWTJYkbAmo,1285
|
|
9
|
+
mosamatic2/commands/segmentmusclefatl3tensorflow.py,sha256=cTjJZ4uA6IbnuxyGvnjfQmcR4_T5umAzEx4uXsdU8Yg,1429
|
|
10
|
+
mosamatic2/constants.py,sha256=MVYMwO-x2jQSN37o3zNkRseVQ1nYRA3mLv3v_Q0Mlds,1284
|
|
11
|
+
mosamatic2/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
mosamatic2/core/data/__init__.py,sha256=j9iGqUTJlGF0N0gPrzzpe_Dhv0Bj9c6FdQ1g7U-_j2g,298
|
|
13
|
+
mosamatic2/core/data/dicomimage.py,sha256=jv1KIZBgN3SFjqgjXcPG_cx23RPauJ2TF1CzA9vj3Z8,484
|
|
14
|
+
mosamatic2/core/data/dicomimageseries.py,sha256=OZkNi15crL8nEA-PGYsM0k9NMi2mMHRvDRePr_-czvA,849
|
|
15
|
+
mosamatic2/core/data/dixonseries.py,sha256=kq9fy65MSM2XwiScqp7b3rQ09JmpyGwbG6ldZsuPRrM,516
|
|
16
|
+
mosamatic2/core/data/filedata.py,sha256=hCnpizGqOpxzIADJkDS2_NSmKVLL1u49TYjSJE5UXQo,515
|
|
17
|
+
mosamatic2/core/data/multidicomimage.py,sha256=cdd0H4Dq49h7NLKBx51_h_HZVnH7-reu48PY8m6tXwU,1034
|
|
18
|
+
mosamatic2/core/managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
19
|
+
mosamatic2/core/managers/logmanager.py,sha256=NEaXvhl0aILjBbK710GaWanVuuNvB51HpHhE5rgYvng,1391
|
|
20
|
+
mosamatic2/core/managers/logmanagerlistener.py,sha256=Gaig07yjBnyQq9I8sN85olTEeDCDyCFQnEJdwzvmgvc,99
|
|
21
|
+
mosamatic2/core/pipelines/__init__.py,sha256=MXoylu34AlcyudJpjuLa4B7K9gZmxLnZGDaEkK9Ygio,69
|
|
22
|
+
mosamatic2/core/pipelines/defaultpipeline.py,sha256=EUblRhLZXhslz9bdBmx8v9yjpgOdsHviqQZ5elK8gNQ,2901
|
|
23
|
+
mosamatic2/core/pipelines/pipeline.py,sha256=mRxKXLKwgKDpc8R9mCI6gDKGJ2lKVxRQ__Sf0Mfn_Qc,384
|
|
24
|
+
mosamatic2/core/singleton.py,sha256=FV0k_LlOCmFhlWN6gf1c2x7YXWyd8-7DsIMvOKrI6NY,224
|
|
25
|
+
mosamatic2/core/tasks/__init__.py,sha256=ZLdp-N1AdVYDsrXvtBLnoQO5BqFh4xDXRDsM9y73_fc,462
|
|
26
|
+
mosamatic2/core/tasks/calculatescorestask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
27
|
+
mosamatic2/core/tasks/calculatescorestask/calculatescorestask.py,sha256=1CUJK9IsePBbEuF3-0LnZp1sWMxPDiJaNy0a-8DaTUE,6576
|
|
28
|
+
mosamatic2/core/tasks/createpngsfromsegmentationstask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
29
|
+
mosamatic2/core/tasks/createpngsfromsegmentationstask/createpngsfromsegmentationstask.py,sha256=1UpOsp1CH668BQ0g4tALou_tFgisC306VcvqOKSDuTo,1884
|
|
30
|
+
mosamatic2/core/tasks/rescaledicomimagestask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
31
|
+
mosamatic2/core/tasks/rescaledicomimagestask/rescaledicomimagestask.py,sha256=vGSpMJoXFtE-IHGxTEO9DMkerMJcfG5r9tXgtvkxm6Y,3053
|
|
32
|
+
mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
|
+
mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/paramloader.py,sha256=VxTCOYK_1VRAG83P-ulm0LPvqXI-0iT5BCr0Rdr7MWg,900
|
|
34
|
+
mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/segmentmusclefatl3tensorflowtask.py,sha256=bDRG9phYSF4o4mFsdJhyJ613CqOixFPTd5yL2gBFSPY,5351
|
|
35
|
+
mosamatic2/core/tasks/task.py,sha256=yu6XbxFYQCFH3yxL9MVfuNv1rgiyJWtZH8p43gfPfFA,1639
|
|
36
|
+
mosamatic2/core/utils.py,sha256=RHBcvrUshese6NG_OigO4ZGGR3iCOmmeDJjgPnLpaBo,10753
|
|
37
|
+
mosamatic2/server.py,sha256=j-uvJB9YdAKBDSd1eKxFN-t6nQdVjcJFlAGQOWNZTSQ,3173
|
|
38
|
+
mosamatic2/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
39
|
+
mosamatic2/ui/mainwindow.py,sha256=SZRv5GRyliufGHrbxDQ4hZMJ-cooZk1T9pwlBGNSFQI,9275
|
|
40
|
+
mosamatic2/ui/resources/icons/mosamatic2.icns,sha256=OfhC-diJTIgaNMOezxKKilGsY7mRkaGdU5dGr0MOjIA,2994125
|
|
41
|
+
mosamatic2/ui/resources/icons/mosamatic2.ico,sha256=ySD3RYluHK3pgS0Eas7eKrVk_AskdLQ4qs_IT-wNhq4,12229
|
|
42
|
+
mosamatic2/ui/resources/icons/spinner.gif,sha256=rvaac6GUZauHSPFSOLWr0RmLfjmtZih2Q8knQ2WP3Po,16240
|
|
43
|
+
mosamatic2/ui/resources/images/body-composition.jpg,sha256=KD-BudbXwThB4lJOZZN-ad5-TZRaaZ5cKTH0Ar1TOZs,21227
|
|
44
|
+
mosamatic2/ui/resources/VERSION,sha256=Hapa2Ade-cQ7nT9Ty0T8o97c5XqhA-txBDtd1-VscFo,8
|
|
45
|
+
mosamatic2/ui/settings.py,sha256=YEVHYJIfNsqMO3v1pjzgh7Pih9GGoUX7S9s8S-sBNUk,2121
|
|
46
|
+
mosamatic2/ui/utils.py,sha256=6bbPIrh4RJ_yhQKNZrgPbL4XeUEogjIjbk_e5c3QS5g,853
|
|
47
|
+
mosamatic2/ui/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
48
|
+
mosamatic2/ui/widgets/dialogs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
49
|
+
mosamatic2/ui/widgets/dialogs/dialog.py,sha256=whp1xSDVW2t85eh0xvyx1WofEmEQLRbflDPlynwBhJo,354
|
|
50
|
+
mosamatic2/ui/widgets/dialogs/helpdialog.py,sha256=WTm8w2IE1iGfOKILSs6567co6YGAf9r9mTC9SqmFlto,169
|
|
51
|
+
mosamatic2/ui/widgets/panels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
52
|
+
mosamatic2/ui/widgets/panels/defaultpanel.py,sha256=Ry32Xv6ibxm6NdZ7eBOCcisWNcmn7PQUT2JLT5n5zhE,923
|
|
53
|
+
mosamatic2/ui/widgets/panels/logpanel.py,sha256=ogswJ6_ryb6u7JeVnOsh2Ez8KWg6jtCFZwij8s87xO4,1861
|
|
54
|
+
mosamatic2/ui/widgets/panels/mainpanel.py,sha256=KqI8dA7GpLFd2unqVRTBkNxdnh6AWGpVPwQuaEg8PmI,2431
|
|
55
|
+
mosamatic2/ui/widgets/panels/pipelines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
mosamatic2/ui/widgets/panels/pipelines/defaultpipelinepanel.py,sha256=cmjbjllDgwA5zP5EpfRwiYyJI7iXEtPAvh4zSXOhCSw,13714
|
|
57
|
+
mosamatic2/ui/widgets/panels/stackedpanel.py,sha256=dK1YWuHUzxRhVb5gP0Lu9rAiW4XagjcHmGF__5Lpufk,657
|
|
58
|
+
mosamatic2/ui/widgets/panels/taskpanel.py,sha256=t8lIx1P8sS1Fa-aNm6eEha6297pJQNbBRizkobBexz8,170
|
|
59
|
+
mosamatic2/ui/widgets/panels/tasks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
60
|
+
mosamatic2/ui/widgets/panels/tasks/calculatescorestaskpanel.py,sha256=kWtRI0SnjSzvE4MGTxs2-W8f3X3uP3LRtXnfyAl8HL0,9381
|
|
61
|
+
mosamatic2/ui/widgets/panels/tasks/createpngsfromsegmentationstaskpanel.py,sha256=Be7SJfYHDAvPCC52iVqbrgr3CbwnAck37Ph_BbyhKBE,7873
|
|
62
|
+
mosamatic2/ui/widgets/panels/tasks/rescaledicomimagestaskpanel.py,sha256=_K-XM4zvzq_AMugLqN4p87iEsfX594qYSVnfjNlmAfU,7591
|
|
63
|
+
mosamatic2/ui/widgets/panels/tasks/segmentmusclefatl3tensorflowtaskpanel.py,sha256=pLEpUXx_vi6PfOykAwp95m5yLRrIvdF_XaupHBOW31U,9624
|
|
64
|
+
mosamatic2/ui/widgets/panels/tasks/selectslicefromscantaskpanel.py,sha256=Q5txmTPssKEQpy_yc-iKCN22K5h3B_7WzPP885uP79Q,7506
|
|
65
|
+
mosamatic2/ui/widgets/splashscreen.py,sha256=MS-OczOWfwwEQNQd-JWe9_Mh57css0cSQgbu973rwQo,4056
|
|
66
|
+
mosamatic2/ui/worker.py,sha256=v7e3gq7MUudgpB1BJW-P7j5wurzu6-HG5m7I6WHgJp0,699
|
|
67
|
+
mosamatic2-2.0.3.dist-info/entry_points.txt,sha256=MCUpKkgbej1clgp8EqlLQGs0BIKwGPcBPiVWLfGz9Gw,126
|
|
68
|
+
mosamatic2-2.0.3.dist-info/METADATA,sha256=KaFTFjQNx_s-DKle87crkY3K8A5OTUsva4RjwSXmaOQ,1365
|
|
69
|
+
mosamatic2-2.0.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
70
|
+
mosamatic2-2.0.3.dist-info/RECORD,,
|
mosamatic2/api.py
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: mosamatic2
|
|
3
|
-
Version: 2.0.1
|
|
4
|
-
Summary:
|
|
5
|
-
Author: Ralph Brecheisen
|
|
6
|
-
Author-email: r.brecheisen@maastrichtuniversity.nl
|
|
7
|
-
Requires-Python: >=3.11,<3.12
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
10
|
-
Description-Content-Type: text/markdown
|
|
11
|
-
|
|
12
|
-
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
models.py,sha256=Kx6oWKt7IpTTxrhBDrX61X-ZX12J7yPkJFuhVDsDHoQ,8807
|
|
2
|
-
mosamatic2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
-
mosamatic2/api.py,sha256=t1lqcq2BcmbVX3egQtkMO7wdXi-BprvJRd61G69mlbs,51
|
|
4
|
-
mosamatic2/app.py,sha256=pwfdnyemo0VlmsF_K99gV7LBQWFWYSWqTAbm-eAWkfM,47
|
|
5
|
-
mosamatic2-2.0.1.dist-info/entry_points.txt,sha256=FDljcEQ4K4Tt-8Xof4KZf3AsBHDp9RZIx4uZPCspxo4,85
|
|
6
|
-
mosamatic2-2.0.1.dist-info/METADATA,sha256=vuxh6bICEMVtbExN1L9tAaGZ6wrDCbKzgQoV_RRE7P8,311
|
|
7
|
-
mosamatic2-2.0.1.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
8
|
-
mosamatic2-2.0.1.dist-info/RECORD,,
|