mosamatic2 2.0.3__tar.gz → 2.0.4__tar.gz
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-2.0.3 → mosamatic2-2.0.4}/PKG-INFO +2 -1
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/pyproject.toml +2 -1
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/cli.py +2 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/commands/calculatescores.py +1 -1
- mosamatic2-2.0.4/src/mosamatic2/commands/dicom2nifti.py +46 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/commands/rescaledicomimages.py +1 -1
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/commands/segmentmusclefatl3tensorflow.py +1 -1
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/__init__.py +2 -1
- mosamatic2-2.0.4/src/mosamatic2/core/tasks/dicom2niftitask/dicom2niftitask.py +24 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/task.py +5 -4
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/server.py +15 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/mainwindow.py +15 -0
- mosamatic2-2.0.4/src/mosamatic2/ui/resources/VERSION +1 -0
- mosamatic2-2.0.4/src/mosamatic2/ui/widgets/panels/tasks/__init__.py +0 -0
- mosamatic2-2.0.4/src/mosamatic2/ui/widgets/panels/tasks/dicom2niftitaskpanel.py +183 -0
- mosamatic2-2.0.3/src/mosamatic2/ui/resources/VERSION +0 -1
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/README.md +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/models.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/app.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/commands/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/commands/createpngsfromsegmentations.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/constants.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/data/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/data/dicomimage.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/data/dicomimageseries.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/data/dixonseries.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/data/filedata.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/data/multidicomimage.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/managers/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/managers/logmanager.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/managers/logmanagerlistener.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/pipelines/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/pipelines/defaultpipeline.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/pipelines/pipeline.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/singleton.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/calculatescorestask/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/calculatescorestask/calculatescorestask.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/createpngsfromsegmentationstask/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/createpngsfromsegmentationstask/createpngsfromsegmentationstask.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/core/tasks/rescaledicomimagestask → mosamatic2-2.0.4/src/mosamatic2/core/tasks/dicom2niftitask}/__init__.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask → mosamatic2-2.0.4/src/mosamatic2/core/tasks/rescaledicomimagestask}/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/rescaledicomimagestask/rescaledicomimagestask.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/ui → mosamatic2-2.0.4/src/mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask}/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/paramloader.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/segmentmusclefatl3tensorflowtask.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/utils.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/ui/widgets → mosamatic2-2.0.4/src/mosamatic2/ui}/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/resources/icons/mosamatic2.icns +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/resources/icons/mosamatic2.ico +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/resources/icons/spinner.gif +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/resources/images/body-composition.jpg +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/settings.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/utils.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/ui/widgets/dialogs → mosamatic2-2.0.4/src/mosamatic2/ui/widgets}/__init__.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/ui/widgets/panels → mosamatic2-2.0.4/src/mosamatic2/ui/widgets/dialogs}/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/dialogs/dialog.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/dialogs/helpdialog.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/ui/widgets/panels/pipelines → mosamatic2-2.0.4/src/mosamatic2/ui/widgets/panels}/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/defaultpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/logpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/mainpanel.py +0 -0
- {mosamatic2-2.0.3/src/mosamatic2/ui/widgets/panels/tasks → mosamatic2-2.0.4/src/mosamatic2/ui/widgets/panels/pipelines}/__init__.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/pipelines/defaultpipelinepanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/stackedpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/taskpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/tasks/calculatescorestaskpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/tasks/createpngsfromsegmentationstaskpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/tasks/rescaledicomimagestaskpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/tasks/segmentmusclefatl3tensorflowtaskpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/panels/tasks/selectslicefromscantaskpanel.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/widgets/splashscreen.py +0 -0
- {mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/worker.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: mosamatic2
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Ralph Brecheisen
|
|
6
6
|
Author-email: r.brecheisen@maastrichtuniversity.nl
|
|
@@ -8,6 +8,7 @@ Requires-Python: >=3.11,<3.12
|
|
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.11
|
|
10
10
|
Requires-Dist: antspyx (>=0.5.4)
|
|
11
|
+
Requires-Dist: dicom2nifti (>=2.6.2)
|
|
11
12
|
Requires-Dist: flask (>=3.1.2)
|
|
12
13
|
Requires-Dist: nibabel (>=5.3.2)
|
|
13
14
|
Requires-Dist: numpy (>=1.26.4)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "mosamatic2"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.4"
|
|
4
4
|
description = ""
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Ralph Brecheisen", email = "r.brecheisen@maastrichtuniversity.nl"}
|
|
@@ -10,6 +10,7 @@ requires-python = ">=3.11,<3.12"
|
|
|
10
10
|
dependencies = [
|
|
11
11
|
"pyside6-essentials>=6.9",
|
|
12
12
|
"pydicom>=3.0.1",
|
|
13
|
+
"dicom2nifti>=2.6.2",
|
|
13
14
|
"numpy>=1.26.4",
|
|
14
15
|
"pandas>=2.3.2",
|
|
15
16
|
"nibabel>=5.3.2",
|
|
@@ -4,6 +4,7 @@ from mosamatic2.commands import (
|
|
|
4
4
|
rescaledicomimages,
|
|
5
5
|
segmentmusclefatl3tensorflow,
|
|
6
6
|
createpngsfromsegmentations,
|
|
7
|
+
dicom2nifti,
|
|
7
8
|
)
|
|
8
9
|
from mosamatic2.core.utils import show_doc_command
|
|
9
10
|
|
|
@@ -29,4 +30,5 @@ main.add_command(calculatescores.calculatescores)
|
|
|
29
30
|
main.add_command(rescaledicomimages.rescaledicomimages)
|
|
30
31
|
main.add_command(segmentmusclefatl3tensorflow.segmentmusclefatl3tensorflow)
|
|
31
32
|
main.add_command(createpngsfromsegmentations.createpngsfromsegmentations)
|
|
33
|
+
main.add_command(dicom2nifti.dicom2nifti)
|
|
32
34
|
main.add_command(show_doc_command(main)) # Special command to show long description for command
|
|
@@ -48,7 +48,7 @@ def calculatescores(images, segmentations, output, file_type, overwrite):
|
|
|
48
48
|
Parameters
|
|
49
49
|
----------
|
|
50
50
|
--images : str
|
|
51
|
-
Directory with
|
|
51
|
+
Directory with input L3 images
|
|
52
52
|
|
|
53
53
|
--segmentations : str
|
|
54
54
|
Directory with L3 muscle and fat segmenation files. Must be output of
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from mosamatic2.core.tasks import Dicom2NiftiTask
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@click.command(help='Converts DICOM series to NIFTI')
|
|
7
|
+
@click.option(
|
|
8
|
+
'--images',
|
|
9
|
+
required=True,
|
|
10
|
+
type=click.Path(exists=True),
|
|
11
|
+
help='Directory with images',
|
|
12
|
+
)
|
|
13
|
+
@click.option(
|
|
14
|
+
'--output',
|
|
15
|
+
required=True,
|
|
16
|
+
type=click.Path(),
|
|
17
|
+
help='Output directory'
|
|
18
|
+
)
|
|
19
|
+
@click.option(
|
|
20
|
+
'--overwrite',
|
|
21
|
+
type=click.BOOL,
|
|
22
|
+
default=False,
|
|
23
|
+
help='Overwrite [true|false]'
|
|
24
|
+
)
|
|
25
|
+
def dicom2nifti(images, output, overwrite):
|
|
26
|
+
"""
|
|
27
|
+
Converts single DICOM series (scan) to NIFTI
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
--images : str
|
|
32
|
+
Directory with DICOM images of a single series
|
|
33
|
+
|
|
34
|
+
--output : str
|
|
35
|
+
Path to output directory
|
|
36
|
+
|
|
37
|
+
--overwrite : bool
|
|
38
|
+
Overwrite contents output directory [true|false]
|
|
39
|
+
"""
|
|
40
|
+
task = Dicom2NiftiTask(
|
|
41
|
+
inputs={'images': images},
|
|
42
|
+
params=None,
|
|
43
|
+
output=output,
|
|
44
|
+
overwrite=overwrite,
|
|
45
|
+
)
|
|
46
|
+
task.run()
|
{mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/commands/segmentmusclefatl3tensorflow.py
RENAMED
|
@@ -35,7 +35,7 @@ def segmentmusclefatl3tensorflow(images, model_files, output, overwrite):
|
|
|
35
35
|
Parameters
|
|
36
36
|
----------
|
|
37
37
|
--images : str
|
|
38
|
-
Directory with
|
|
38
|
+
Directory with input L3 images
|
|
39
39
|
|
|
40
40
|
--model_files : str
|
|
41
41
|
Directory with AI model files (model-1.0.zip, contour_model-1.0.zip, params-1.0.json)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from mosamatic2.core.tasks.rescaledicomimagestask.rescaledicomimagestask import RescaleDicomImagesTask
|
|
2
2
|
from mosamatic2.core.tasks.segmentmusclefatl3tensorflowtask.segmentmusclefatl3tensorflowtask import SegmentMuscleFatL3TensorFlowTask
|
|
3
3
|
from mosamatic2.core.tasks.calculatescorestask.calculatescorestask import CalculateScoresTask
|
|
4
|
-
from mosamatic2.core.tasks.createpngsfromsegmentationstask.createpngsfromsegmentationstask import CreatePngsFromSegmentationsTask
|
|
4
|
+
from mosamatic2.core.tasks.createpngsfromsegmentationstask.createpngsfromsegmentationstask import CreatePngsFromSegmentationsTask
|
|
5
|
+
from mosamatic2.core.tasks.dicom2niftitask.dicom2niftitask import Dicom2NiftiTask
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import dicom2nifti
|
|
3
|
+
from mosamatic2.core.tasks.task import Task
|
|
4
|
+
from mosamatic2.core.managers.logmanager import LogManager
|
|
5
|
+
|
|
6
|
+
LOG = LogManager()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class Dicom2NiftiTask(Task):
|
|
10
|
+
INPUTS = ['images']
|
|
11
|
+
PARAMS = []
|
|
12
|
+
|
|
13
|
+
def __init__(self, inputs, params, output, overwrite):
|
|
14
|
+
super(Dicom2NiftiTask, self).__init__(inputs, params, output, overwrite)
|
|
15
|
+
|
|
16
|
+
def run(self):
|
|
17
|
+
nifti_file_name = os.path.split(self.input('images'))[1] + '.nii.gz'
|
|
18
|
+
LOG.info(f'Converting DICOM directory to {nifti_file_name}')
|
|
19
|
+
dicom2nifti.dicom_series_to_nifti(
|
|
20
|
+
self.input('images'),
|
|
21
|
+
os.path.join(self.output(), nifti_file_name),
|
|
22
|
+
reorient_nifti=True,
|
|
23
|
+
)
|
|
24
|
+
self.set_progress(0, 1)
|
|
@@ -25,10 +25,11 @@ class Task:
|
|
|
25
25
|
for k, v in self._inputs.items():
|
|
26
26
|
assert k in self.__class__.INPUTS
|
|
27
27
|
assert isinstance(v, str)
|
|
28
|
-
# Check that param names match specification
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
# Check that param names match specification (if not None)
|
|
29
|
+
if self._params:
|
|
30
|
+
assert len(self._params.keys()) == len(self.__class__.PARAMS)
|
|
31
|
+
for k in self._params.keys():
|
|
32
|
+
assert k in self.__class__.PARAMS
|
|
32
33
|
|
|
33
34
|
def input(self, name):
|
|
34
35
|
return self._inputs[name]
|
|
@@ -5,6 +5,7 @@ from mosamatic2.core.tasks import RescaleDicomImagesTask
|
|
|
5
5
|
from mosamatic2.core.tasks import SegmentMuscleFatL3TensorFlowTask
|
|
6
6
|
from mosamatic2.core.tasks import CalculateScoresTask
|
|
7
7
|
from mosamatic2.core.tasks import CreatePngsFromSegmentationsTask
|
|
8
|
+
from mosamatic2.core.tasks import Dicom2NiftiTask
|
|
8
9
|
|
|
9
10
|
app = Flask(__name__)
|
|
10
11
|
|
|
@@ -89,6 +90,20 @@ def run_createpngsfromsegmentations():
|
|
|
89
90
|
return 'PASSED'
|
|
90
91
|
|
|
91
92
|
|
|
93
|
+
@app.route('/dicom2nifti')
|
|
94
|
+
def run_dicom2nifti():
|
|
95
|
+
images = request.args.get('images')
|
|
96
|
+
output = request.args.get('output')
|
|
97
|
+
overwrite = request.args.get('overwrite', default=True, type=bool)
|
|
98
|
+
task = Dicom2NiftiTask(
|
|
99
|
+
inputs={'images': images},
|
|
100
|
+
params=None,
|
|
101
|
+
output=output,
|
|
102
|
+
overwrite=overwrite,
|
|
103
|
+
)
|
|
104
|
+
task.run()
|
|
105
|
+
return 'PASSED'
|
|
106
|
+
|
|
92
107
|
|
|
93
108
|
def main():
|
|
94
109
|
parser = argparse.ArgumentParser()
|
|
@@ -18,6 +18,7 @@ from mosamatic2.ui.widgets.panels.tasks.rescaledicomimagestaskpanel import Resca
|
|
|
18
18
|
from mosamatic2.ui.widgets.panels.tasks.segmentmusclefatl3tensorflowtaskpanel import SegmentMuscleFatL3TensorFlowTaskPanel
|
|
19
19
|
from mosamatic2.ui.widgets.panels.tasks.createpngsfromsegmentationstaskpanel import CreatePngsFromSegmentationsTaskPanel
|
|
20
20
|
from mosamatic2.ui.widgets.panels.tasks.calculatescorestaskpanel import CalculateScoresTaskPanel
|
|
21
|
+
from mosamatic2.ui.widgets.panels.tasks.dicom2niftitaskpanel import Dicom2NiftiTaskPanel
|
|
21
22
|
from mosamatic2.ui.widgets.panels.pipelines.defaultpipelinepanel import DefaultPipelinePanel
|
|
22
23
|
|
|
23
24
|
LOG = LogManager()
|
|
@@ -34,6 +35,7 @@ class MainWindow(QMainWindow):
|
|
|
34
35
|
self._segment_muscle_fat_l3_tensorflow_task_panel = None
|
|
35
36
|
self._create_pngs_from_segmentations_task_panel = None
|
|
36
37
|
self._calculate_scores_task_panel = None
|
|
38
|
+
self._dicom2nifti_task_panel = None
|
|
37
39
|
self._default_pipeline_panel = None
|
|
38
40
|
self.init_window()
|
|
39
41
|
|
|
@@ -71,11 +73,14 @@ class MainWindow(QMainWindow):
|
|
|
71
73
|
calculate_scores_task_action.triggered.connect(self.handle_calculate_scores_task_action)
|
|
72
74
|
create_pngs_from_segmentations_task_action = QAction('CreatePngsFromSegmentationsTask', self)
|
|
73
75
|
create_pngs_from_segmentations_task_action.triggered.connect(self.handle_create_pngs_from_segmentations_task_action)
|
|
76
|
+
dicom2nifti_task_action = QAction('Dicom2NiftiTask', self)
|
|
77
|
+
dicom2nifti_task_action.triggered.connect(self.handle_dicom2nifti_task_action)
|
|
74
78
|
tasks_menu = self.menuBar().addMenu('Tasks')
|
|
75
79
|
tasks_menu.addAction(rescale_dicom_images_task_action)
|
|
76
80
|
tasks_menu.addAction(segment_muscle_fat_l3_tensorflow_task_action)
|
|
77
81
|
tasks_menu.addAction(calculate_scores_task_action)
|
|
78
82
|
tasks_menu.addAction(create_pngs_from_segmentations_task_action)
|
|
83
|
+
tasks_menu.addAction(dicom2nifti_task_action)
|
|
79
84
|
|
|
80
85
|
def init_pipelines_menu(self):
|
|
81
86
|
default_pipeline_action = QAction('DefaultPipeline', self)
|
|
@@ -100,6 +105,7 @@ class MainWindow(QMainWindow):
|
|
|
100
105
|
self._main_panel.add_panel(self.segment_muscle_fat_l3_tensorflow_task_panel(), 'segmentmusclefatl3tensorflowtaskpanel')
|
|
101
106
|
self._main_panel.add_panel(self.create_pngs_from_segmentations_task_panel(), 'createpngsfromsegmentationstaskpanel')
|
|
102
107
|
self._main_panel.add_panel(self.calculate_scores_task_panel(), 'calculatescorestaskpanel')
|
|
108
|
+
self._main_panel.add_panel(self.dicom2nifti_task_panel(), 'dicom2niftitaskpanel')
|
|
103
109
|
self._main_panel.add_panel(self.default_pipeline_panel(), 'defaultpipelinepanel')
|
|
104
110
|
self._main_panel.select_panel('defaultpipelinepanel')
|
|
105
111
|
return self._main_panel
|
|
@@ -132,6 +138,11 @@ class MainWindow(QMainWindow):
|
|
|
132
138
|
self._calculate_scores_task_panel = CalculateScoresTaskPanel()
|
|
133
139
|
return self._calculate_scores_task_panel
|
|
134
140
|
|
|
141
|
+
def dicom2nifti_task_panel(self):
|
|
142
|
+
if not self._dicom2nifti_task_panel:
|
|
143
|
+
self._dicom2nifti_task_panel = Dicom2NiftiTaskPanel()
|
|
144
|
+
return self._dicom2nifti_task_panel
|
|
145
|
+
|
|
135
146
|
def default_pipeline_panel(self):
|
|
136
147
|
if not self._default_pipeline_panel:
|
|
137
148
|
self._default_pipeline_panel = DefaultPipelinePanel()
|
|
@@ -156,6 +167,9 @@ class MainWindow(QMainWindow):
|
|
|
156
167
|
def handle_calculate_scores_task_action(self):
|
|
157
168
|
self.main_panel().select_panel('calculatescorestaskpanel')
|
|
158
169
|
|
|
170
|
+
def handle_dicom2nifti_task_action(self):
|
|
171
|
+
self.main_panel().select_panel('dicom2niftitaskpanel')
|
|
172
|
+
|
|
159
173
|
def handle_default_pipeline_action(self):
|
|
160
174
|
self.main_panel().select_panel('defaultpipelinepanel')
|
|
161
175
|
|
|
@@ -169,6 +183,7 @@ class MainWindow(QMainWindow):
|
|
|
169
183
|
self.segment_muscle_fat_l3_tensorflow_task_panel().save_inputs_and_parameters()
|
|
170
184
|
self.create_pngs_from_segmentations_task_panel().save_inputs_and_parameters()
|
|
171
185
|
self.calculate_scores_task_panel().save_inputs_and_parameters()
|
|
186
|
+
self.dicom2nifti_task_panel().save_inputs_and_parameters()
|
|
172
187
|
self.default_pipeline_panel().save_inputs_and_parameters()
|
|
173
188
|
return super().closeEvent(event)
|
|
174
189
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.0.4
|
|
File without changes
|
|
@@ -0,0 +1,183 @@
|
|
|
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 mosamatic2.core.managers.logmanager import LogManager
|
|
20
|
+
from mosamatic2.ui.widgets.panels.taskpanel import TaskPanel
|
|
21
|
+
from mosamatic2.ui.settings import Settings
|
|
22
|
+
from mosamatic2.ui.utils import is_macos
|
|
23
|
+
from mosamatic2.ui.worker import Worker
|
|
24
|
+
from mosamatic2.core.tasks import Dicom2NiftiTask
|
|
25
|
+
|
|
26
|
+
LOG = LogManager()
|
|
27
|
+
|
|
28
|
+
PANEL_TITLE = 'Dicom2NiftiTask'
|
|
29
|
+
PANEL_NAME = 'dicom2niftitaskpanel'
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Dicom2NiftiTaskPanel(TaskPanel):
|
|
33
|
+
def __init__(self):
|
|
34
|
+
super(Dicom2NiftiTaskPanel, self).__init__()
|
|
35
|
+
self.set_title(PANEL_TITLE)
|
|
36
|
+
self._images_dir_line_edit = None
|
|
37
|
+
self._images_dir_select_button = None
|
|
38
|
+
self._output_dir_line_edit = None
|
|
39
|
+
self._output_dir_select_button = None
|
|
40
|
+
self._overwrite_checkbox = None
|
|
41
|
+
self._form_layout = None
|
|
42
|
+
self._run_task_button = None
|
|
43
|
+
self._settings = None
|
|
44
|
+
self._task = None
|
|
45
|
+
self._worker = None
|
|
46
|
+
self._thread = None
|
|
47
|
+
self.init_layout()
|
|
48
|
+
|
|
49
|
+
def images_dir_line_edit(self):
|
|
50
|
+
if not self._images_dir_line_edit:
|
|
51
|
+
self._images_dir_line_edit = QLineEdit(self.settings().get(f'{PANEL_NAME}/images_dir'))
|
|
52
|
+
return self._images_dir_line_edit
|
|
53
|
+
|
|
54
|
+
def images_dir_select_button(self):
|
|
55
|
+
if not self._images_dir_select_button:
|
|
56
|
+
self._images_dir_select_button = QPushButton('Select')
|
|
57
|
+
self._images_dir_select_button.clicked.connect(self.handle_images_dir_select_button)
|
|
58
|
+
return self._images_dir_select_button
|
|
59
|
+
|
|
60
|
+
def output_dir_line_edit(self):
|
|
61
|
+
if not self._output_dir_line_edit:
|
|
62
|
+
self._output_dir_line_edit = QLineEdit(self.settings().get(f'{PANEL_NAME}/output_dir'))
|
|
63
|
+
return self._output_dir_line_edit
|
|
64
|
+
|
|
65
|
+
def output_dir_select_button(self):
|
|
66
|
+
if not self._output_dir_select_button:
|
|
67
|
+
self._output_dir_select_button = QPushButton('Select')
|
|
68
|
+
self._output_dir_select_button.clicked.connect(self.handle_output_dir_select_button)
|
|
69
|
+
return self._output_dir_select_button
|
|
70
|
+
|
|
71
|
+
def overwrite_checkbox(self):
|
|
72
|
+
if not self._overwrite_checkbox:
|
|
73
|
+
self._overwrite_checkbox = QCheckBox('')
|
|
74
|
+
self._overwrite_checkbox.setChecked(self.settings().get_bool(f'{PANEL_NAME}/overwrite', True))
|
|
75
|
+
return self._overwrite_checkbox
|
|
76
|
+
|
|
77
|
+
def form_layout(self):
|
|
78
|
+
if not self._form_layout:
|
|
79
|
+
self._form_layout = QFormLayout()
|
|
80
|
+
if is_macos():
|
|
81
|
+
self._form_layout.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow)
|
|
82
|
+
return self._form_layout
|
|
83
|
+
|
|
84
|
+
def run_task_button(self):
|
|
85
|
+
if not self._run_task_button:
|
|
86
|
+
self._run_task_button = QPushButton('Run task')
|
|
87
|
+
self._run_task_button.clicked.connect(self.handle_run_task_button)
|
|
88
|
+
return self._run_task_button
|
|
89
|
+
|
|
90
|
+
def settings(self):
|
|
91
|
+
if not self._settings:
|
|
92
|
+
self._settings = Settings()
|
|
93
|
+
return self._settings
|
|
94
|
+
|
|
95
|
+
def init_layout(self):
|
|
96
|
+
images_dir_layout = QHBoxLayout()
|
|
97
|
+
images_dir_layout.addWidget(self.images_dir_line_edit())
|
|
98
|
+
images_dir_layout.addWidget(self.images_dir_select_button())
|
|
99
|
+
output_dir_layout = QHBoxLayout()
|
|
100
|
+
output_dir_layout.addWidget(self.output_dir_line_edit())
|
|
101
|
+
output_dir_layout.addWidget(self.output_dir_select_button())
|
|
102
|
+
self.form_layout().addRow('Images directory', images_dir_layout)
|
|
103
|
+
self.form_layout().addRow('Output directory', output_dir_layout)
|
|
104
|
+
self.form_layout().addRow('Overwrite', self.overwrite_checkbox())
|
|
105
|
+
layout = QVBoxLayout()
|
|
106
|
+
layout.addLayout(self.form_layout())
|
|
107
|
+
layout.addWidget(self.run_task_button())
|
|
108
|
+
self.setLayout(layout)
|
|
109
|
+
self.setObjectName(PANEL_NAME)
|
|
110
|
+
|
|
111
|
+
def handle_images_dir_select_button(self):
|
|
112
|
+
last_directory = self.settings().get('last_directory')
|
|
113
|
+
directory = QFileDialog.getExistingDirectory(dir=last_directory)
|
|
114
|
+
if directory:
|
|
115
|
+
self.images_dir_line_edit().setText(directory)
|
|
116
|
+
self.settings().set('last_directory', directory)
|
|
117
|
+
|
|
118
|
+
def handle_output_dir_select_button(self):
|
|
119
|
+
last_directory = self.settings().get('last_directory')
|
|
120
|
+
directory = QFileDialog.getExistingDirectory(dir=last_directory)
|
|
121
|
+
if directory:
|
|
122
|
+
self.output_dir_line_edit().setText(directory)
|
|
123
|
+
self.settings().set('last_directory', directory)
|
|
124
|
+
|
|
125
|
+
def handle_run_task_button(self):
|
|
126
|
+
errors = self.check_inputs_and_parameters()
|
|
127
|
+
if len(errors) > 0:
|
|
128
|
+
error_message = 'Following errors were encountered:\n'
|
|
129
|
+
for error in errors:
|
|
130
|
+
error_message += f' - {error}\n'
|
|
131
|
+
QMessageBox.information(self, 'Error', error_message)
|
|
132
|
+
else:
|
|
133
|
+
LOG.info('Running task...')
|
|
134
|
+
self.run_task_button().setEnabled(False)
|
|
135
|
+
self.save_inputs_and_parameters()
|
|
136
|
+
self._task = Dicom2NiftiTask(
|
|
137
|
+
inputs={'images': self.images_dir_line_edit().text()},
|
|
138
|
+
params=None,
|
|
139
|
+
output=self.output_dir_line_edit().text(),
|
|
140
|
+
overwrite=self.overwrite_checkbox().isChecked(),
|
|
141
|
+
)
|
|
142
|
+
self._worker = Worker(self._task)
|
|
143
|
+
self._thread = QThread()
|
|
144
|
+
self._worker.moveToThread(self._thread)
|
|
145
|
+
self._thread.started.connect(self._worker.run)
|
|
146
|
+
self._worker.progress.connect(self.handle_progress)
|
|
147
|
+
self._worker.status.connect(self.handle_status)
|
|
148
|
+
self._worker.finished.connect(self.handle_finished)
|
|
149
|
+
self._worker.finished.connect(self._thread.quit)
|
|
150
|
+
self._worker.finished.connect(self._worker.deleteLater)
|
|
151
|
+
self._thread.finished.connect(self._thread.deleteLater)
|
|
152
|
+
self._thread.start()
|
|
153
|
+
|
|
154
|
+
@Slot(int)
|
|
155
|
+
def handle_progress(self, progress):
|
|
156
|
+
LOG.info(f'Progress: {progress} / 100%')
|
|
157
|
+
|
|
158
|
+
@Slot(str)
|
|
159
|
+
def handle_status(self, status):
|
|
160
|
+
LOG.info(f'Status: {status}')
|
|
161
|
+
|
|
162
|
+
@Slot()
|
|
163
|
+
def handle_finished(self):
|
|
164
|
+
self.run_task_button().setEnabled(True)
|
|
165
|
+
|
|
166
|
+
# HELPERS
|
|
167
|
+
|
|
168
|
+
def check_inputs_and_parameters(self):
|
|
169
|
+
errors = []
|
|
170
|
+
if self.images_dir_line_edit().text() == '':
|
|
171
|
+
errors.append('Empty images directory path')
|
|
172
|
+
if not os.path.isdir(self.images_dir_line_edit().text()):
|
|
173
|
+
errors.append('Images directory does not exist')
|
|
174
|
+
if self.output_dir_line_edit().text() == '':
|
|
175
|
+
errors.append('Empty output directory path')
|
|
176
|
+
if os.path.isdir(self.output_dir_line_edit().text()) and not self.overwrite_checkbox().isChecked():
|
|
177
|
+
errors.append('Output directory exists but overwrite=False. Please remove output directory first')
|
|
178
|
+
return errors
|
|
179
|
+
|
|
180
|
+
def save_inputs_and_parameters(self):
|
|
181
|
+
self.settings().set(f'{PANEL_NAME}/images_dir', self.images_dir_line_edit().text())
|
|
182
|
+
self.settings().set(f'{PANEL_NAME}/output_dir', self.output_dir_line_edit().text())
|
|
183
|
+
self.settings().set(f'{PANEL_NAME}/overwrite', self.overwrite_checkbox().isChecked())
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2.0.3
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/commands/createpngsfromsegmentations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/core/tasks/calculatescorestask/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mosamatic2-2.0.3/src/mosamatic2/ui/widgets → mosamatic2-2.0.4/src/mosamatic2/ui}/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mosamatic2-2.0.3 → mosamatic2-2.0.4}/src/mosamatic2/ui/resources/images/body-composition.jpg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|