mosamatic2 2.0.24__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.
Files changed (136) hide show
  1. models.py +259 -0
  2. mosamatic2/__init__.py +0 -0
  3. mosamatic2/app.py +32 -0
  4. mosamatic2/cli.py +50 -0
  5. mosamatic2/commands/__init__.py +0 -0
  6. mosamatic2/commands/boadockerpipeline.py +48 -0
  7. mosamatic2/commands/calculatemaskstatistics.py +59 -0
  8. mosamatic2/commands/calculatescores.py +73 -0
  9. mosamatic2/commands/createdicomsummary.py +61 -0
  10. mosamatic2/commands/createpngsfromsegmentations.py +65 -0
  11. mosamatic2/commands/defaultdockerpipeline.py +84 -0
  12. mosamatic2/commands/defaultpipeline.py +70 -0
  13. mosamatic2/commands/dicom2nifti.py +55 -0
  14. mosamatic2/commands/liveranalysispipeline.py +61 -0
  15. mosamatic2/commands/rescaledicomimages.py +54 -0
  16. mosamatic2/commands/segmentmusclefatl3tensorflow.py +55 -0
  17. mosamatic2/commands/selectslicefromscans.py +66 -0
  18. mosamatic2/commands/totalsegmentator.py +77 -0
  19. mosamatic2/constants.py +27 -0
  20. mosamatic2/core/__init__.py +0 -0
  21. mosamatic2/core/data/__init__.py +5 -0
  22. mosamatic2/core/data/dicomimage.py +27 -0
  23. mosamatic2/core/data/dicomimageseries.py +26 -0
  24. mosamatic2/core/data/dixonseries.py +22 -0
  25. mosamatic2/core/data/filedata.py +26 -0
  26. mosamatic2/core/data/multidicomimage.py +30 -0
  27. mosamatic2/core/data/multiniftiimage.py +26 -0
  28. mosamatic2/core/data/multinumpyimage.py +26 -0
  29. mosamatic2/core/data/niftiimage.py +13 -0
  30. mosamatic2/core/data/numpyimage.py +13 -0
  31. mosamatic2/core/managers/__init__.py +0 -0
  32. mosamatic2/core/managers/logmanager.py +45 -0
  33. mosamatic2/core/managers/logmanagerlistener.py +3 -0
  34. mosamatic2/core/pipelines/__init__.py +4 -0
  35. mosamatic2/core/pipelines/boadockerpipeline/__init__.py +0 -0
  36. mosamatic2/core/pipelines/boadockerpipeline/boadockerpipeline.py +70 -0
  37. mosamatic2/core/pipelines/defaultdockerpipeline/__init__.py +0 -0
  38. mosamatic2/core/pipelines/defaultdockerpipeline/defaultdockerpipeline.py +28 -0
  39. mosamatic2/core/pipelines/defaultpipeline/__init__.py +0 -0
  40. mosamatic2/core/pipelines/defaultpipeline/defaultpipeline.py +90 -0
  41. mosamatic2/core/pipelines/liveranalysispipeline/__init__.py +0 -0
  42. mosamatic2/core/pipelines/liveranalysispipeline/liveranalysispipeline.py +48 -0
  43. mosamatic2/core/pipelines/pipeline.py +14 -0
  44. mosamatic2/core/singleton.py +9 -0
  45. mosamatic2/core/tasks/__init__.py +13 -0
  46. mosamatic2/core/tasks/applythresholdtosegmentationstask/__init__.py +0 -0
  47. mosamatic2/core/tasks/applythresholdtosegmentationstask/applythresholdtosegmentationstask.py +117 -0
  48. mosamatic2/core/tasks/calculatemaskstatisticstask/__init__.py +0 -0
  49. mosamatic2/core/tasks/calculatemaskstatisticstask/calculatemaskstatisticstask.py +104 -0
  50. mosamatic2/core/tasks/calculatescorestask/__init__.py +0 -0
  51. mosamatic2/core/tasks/calculatescorestask/calculatescorestask.py +152 -0
  52. mosamatic2/core/tasks/createdicomsummarytask/__init__.py +0 -0
  53. mosamatic2/core/tasks/createdicomsummarytask/createdicomsummarytask.py +88 -0
  54. mosamatic2/core/tasks/createpngsfromsegmentationstask/__init__.py +0 -0
  55. mosamatic2/core/tasks/createpngsfromsegmentationstask/createpngsfromsegmentationstask.py +101 -0
  56. mosamatic2/core/tasks/dicom2niftitask/__init__.py +0 -0
  57. mosamatic2/core/tasks/dicom2niftitask/dicom2niftitask.py +45 -0
  58. mosamatic2/core/tasks/rescaledicomimagestask/__init__.py +0 -0
  59. mosamatic2/core/tasks/rescaledicomimagestask/rescaledicomimagestask.py +64 -0
  60. mosamatic2/core/tasks/segmentationnifti2numpytask/__init__.py +0 -0
  61. mosamatic2/core/tasks/segmentationnifti2numpytask/segmentationnifti2numpytask.py +57 -0
  62. mosamatic2/core/tasks/segmentationnumpy2niftitask/__init__.py +0 -0
  63. mosamatic2/core/tasks/segmentationnumpy2niftitask/segmentationnumpy2niftitask.py +86 -0
  64. mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/__init__.py +0 -0
  65. mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/paramloader.py +39 -0
  66. mosamatic2/core/tasks/segmentmusclefatl3tensorflowtask/segmentmusclefatl3tensorflowtask.py +122 -0
  67. mosamatic2/core/tasks/segmentmusclefatt4pytorchtask/__init__.py +0 -0
  68. mosamatic2/core/tasks/segmentmusclefatt4pytorchtask/paramloader.py +39 -0
  69. mosamatic2/core/tasks/segmentmusclefatt4pytorchtask/segmentmusclefatt4pytorchtask.py +128 -0
  70. mosamatic2/core/tasks/selectslicefromscanstask/__init__.py +0 -0
  71. mosamatic2/core/tasks/selectslicefromscanstask/selectslicefromscanstask.py +249 -0
  72. mosamatic2/core/tasks/task.py +50 -0
  73. mosamatic2/core/tasks/totalsegmentatortask/__init__.py +0 -0
  74. mosamatic2/core/tasks/totalsegmentatortask/totalsegmentatortask.py +75 -0
  75. mosamatic2/core/utils.py +405 -0
  76. mosamatic2/server.py +146 -0
  77. mosamatic2/ui/__init__.py +0 -0
  78. mosamatic2/ui/mainwindow.py +426 -0
  79. mosamatic2/ui/resources/VERSION +1 -0
  80. mosamatic2/ui/resources/icons/mosamatic2.icns +0 -0
  81. mosamatic2/ui/resources/icons/mosamatic2.ico +0 -0
  82. mosamatic2/ui/resources/icons/spinner.gif +0 -0
  83. mosamatic2/ui/resources/images/body-composition.jpg +0 -0
  84. mosamatic2/ui/settings.py +62 -0
  85. mosamatic2/ui/utils.py +36 -0
  86. mosamatic2/ui/widgets/__init__.py +0 -0
  87. mosamatic2/ui/widgets/dialogs/__init__.py +0 -0
  88. mosamatic2/ui/widgets/dialogs/dialog.py +16 -0
  89. mosamatic2/ui/widgets/dialogs/helpdialog.py +9 -0
  90. mosamatic2/ui/widgets/panels/__init__.py +0 -0
  91. mosamatic2/ui/widgets/panels/defaultpanel.py +31 -0
  92. mosamatic2/ui/widgets/panels/logpanel.py +65 -0
  93. mosamatic2/ui/widgets/panels/mainpanel.py +82 -0
  94. mosamatic2/ui/widgets/panels/pipelines/__init__.py +0 -0
  95. mosamatic2/ui/widgets/panels/pipelines/boadockerpipelinepanel.py +195 -0
  96. mosamatic2/ui/widgets/panels/pipelines/defaultdockerpipelinepanel.py +314 -0
  97. mosamatic2/ui/widgets/panels/pipelines/defaultpipelinepanel.py +302 -0
  98. mosamatic2/ui/widgets/panels/pipelines/liveranalysispipelinepanel.py +187 -0
  99. mosamatic2/ui/widgets/panels/pipelines/pipelinepanel.py +6 -0
  100. mosamatic2/ui/widgets/panels/settingspanel.py +16 -0
  101. mosamatic2/ui/widgets/panels/stackedpanel.py +22 -0
  102. mosamatic2/ui/widgets/panels/tasks/__init__.py +0 -0
  103. mosamatic2/ui/widgets/panels/tasks/applythresholdtosegmentationstaskpanel.py +271 -0
  104. mosamatic2/ui/widgets/panels/tasks/calculatemaskstatisticstaskpanel.py +215 -0
  105. mosamatic2/ui/widgets/panels/tasks/calculatescorestaskpanel.py +238 -0
  106. mosamatic2/ui/widgets/panels/tasks/createdicomsummarytaskpanel.py +206 -0
  107. mosamatic2/ui/widgets/panels/tasks/createpngsfromsegmentationstaskpanel.py +247 -0
  108. mosamatic2/ui/widgets/panels/tasks/dicom2niftitaskpanel.py +183 -0
  109. mosamatic2/ui/widgets/panels/tasks/rescaledicomimagestaskpanel.py +184 -0
  110. mosamatic2/ui/widgets/panels/tasks/segmentationnifti2numpytaskpanel.py +192 -0
  111. mosamatic2/ui/widgets/panels/tasks/segmentationnumpy2niftitaskpanel.py +213 -0
  112. mosamatic2/ui/widgets/panels/tasks/segmentmusclefatl3tensorflowtaskpanel.py +216 -0
  113. mosamatic2/ui/widgets/panels/tasks/segmentmusclefatt4pytorchtaskpanel.py +217 -0
  114. mosamatic2/ui/widgets/panels/tasks/selectslicefromscanstaskpanel.py +193 -0
  115. mosamatic2/ui/widgets/panels/tasks/taskpanel.py +6 -0
  116. mosamatic2/ui/widgets/panels/tasks/totalsegmentatortaskpanel.py +195 -0
  117. mosamatic2/ui/widgets/panels/visualizations/__init__.py +0 -0
  118. mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/__init__.py +0 -0
  119. mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/liversegmentpicker.py +96 -0
  120. mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/liversegmentviewer.py +130 -0
  121. mosamatic2/ui/widgets/panels/visualizations/liversegmentvisualization/liversegmentvisualization.py +120 -0
  122. mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/__init__.py +0 -0
  123. mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/sliceselectionviewer.py +61 -0
  124. mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/sliceselectionvisualization.py +133 -0
  125. mosamatic2/ui/widgets/panels/visualizations/sliceselectionvisualization/slicetile.py +63 -0
  126. mosamatic2/ui/widgets/panels/visualizations/slicevisualization/__init__.py +0 -0
  127. mosamatic2/ui/widgets/panels/visualizations/slicevisualization/custominteractorstyle.py +80 -0
  128. mosamatic2/ui/widgets/panels/visualizations/slicevisualization/sliceviewer.py +116 -0
  129. mosamatic2/ui/widgets/panels/visualizations/slicevisualization/slicevisualization.py +141 -0
  130. mosamatic2/ui/widgets/panels/visualizations/visualization.py +6 -0
  131. mosamatic2/ui/widgets/splashscreen.py +101 -0
  132. mosamatic2/ui/worker.py +29 -0
  133. mosamatic2-2.0.24.dist-info/METADATA +43 -0
  134. mosamatic2-2.0.24.dist-info/RECORD +136 -0
  135. mosamatic2-2.0.24.dist-info/WHEEL +4 -0
  136. mosamatic2-2.0.24.dist-info/entry_points.txt +5 -0
@@ -0,0 +1,84 @@
1
+ import click
2
+
3
+ from mosamatic2.core.pipelines import DefaultDockerPipeline
4
+
5
+
6
+ @click.command(help='Runs default L3 analysis pipeline through Docker')
7
+ @click.option(
8
+ '--images',
9
+ required=True,
10
+ type=click.Path(exists=True),
11
+ help='Directory with L3 images (no spaces allowed)',
12
+ )
13
+ @click.option(
14
+ '--model_files',
15
+ required=True,
16
+ type=click.Path(),
17
+ help='Input directory with AI model files (no spaces allowed)'
18
+ )
19
+ @click.option(
20
+ '--version',
21
+ required=True,
22
+ help='Docker image version'
23
+ )
24
+ @click.option(
25
+ '--output',
26
+ required=True,
27
+ type=click.Path(),
28
+ help='Output directory (no spaces allowed)'
29
+ )
30
+ @click.option(
31
+ '--overwrite',
32
+ type=click.BOOL,
33
+ default=False,
34
+ help='Overwrite [true|false]'
35
+ )
36
+ def defaultdockerpipeline(images, model_files, version, output, overwrite):
37
+ """
38
+ Runs default L3 analysis pipeline through Docker
39
+
40
+ Parameters
41
+ ----------
42
+ --images : str
43
+ Directory with L3 images. Warning: This directory path cannot contain any spaces!
44
+ Docker has issues working with that.
45
+
46
+ --model_files : str
47
+ Directory with AI model files. This directory can ONLY contain the following
48
+ files:
49
+
50
+ (1) contour_model-1.0.zip
51
+ (2) model-1.0.zip
52
+ (3) params-1.0.json
53
+
54
+ These files can be downloaded from:
55
+ https://mosamatic.rbeesoft.nl/wordpress/mosamatic/installation/
56
+
57
+ Warning: This directory path cannot contain any spaces!
58
+
59
+ --version : str
60
+ Docker image version, e.g., 2.0.16
61
+ Check https://hub.docker.com/repository/docker/brecheisen/mosamatic2-cli/general
62
+ for the latest version and older versions.
63
+
64
+ --output : str
65
+ Path to output directory (no spaces!)
66
+
67
+ --overwrite : bool
68
+ Overwrite contents output directory [true|false]
69
+ """
70
+ pipeline = DefaultDockerPipeline(
71
+ inputs={'images': images, 'model_files': model_files},
72
+ params={
73
+ 'target_size': 512,
74
+ 'model_type': 'tensorflow',
75
+ 'model_version': 1.0,
76
+ 'file_type': 'npy',
77
+ 'fig_width': 10,
78
+ 'fig_height': 10,
79
+ 'version': version,
80
+ },
81
+ output=output,
82
+ overwrite=overwrite,
83
+ )
84
+ pipeline.run()
@@ -0,0 +1,70 @@
1
+ import click
2
+
3
+ from mosamatic2.core.pipelines import DefaultPipeline
4
+
5
+
6
+ @click.command(help='Runs default L3 analysis pipeline')
7
+ @click.option(
8
+ '--images',
9
+ required=True,
10
+ type=click.Path(exists=True),
11
+ help='Directory with L3 images',
12
+ )
13
+ @click.option(
14
+ '--model_files',
15
+ required=True,
16
+ type=click.Path(),
17
+ help='Input directory with AI model files'
18
+ )
19
+ @click.option(
20
+ '--output',
21
+ required=True,
22
+ type=click.Path(),
23
+ help='Output directory'
24
+ )
25
+ @click.option(
26
+ '--overwrite',
27
+ type=click.BOOL,
28
+ default=False,
29
+ help='Overwrite [true|false]'
30
+ )
31
+ def defaultpipeline(images, model_files, output, overwrite):
32
+ """
33
+ Runs default L3 analysis pipeline
34
+
35
+ Parameters
36
+ ----------
37
+ --images : str
38
+ Directory with L3 images
39
+
40
+ --model_files : str
41
+ Directory with AI model files. This directory can ONLY contain the following
42
+ files:
43
+
44
+ (1) contour_model-1.0.zip
45
+ (2) model-1.0.zip
46
+ (3) params-1.0.json
47
+
48
+ These files can be downloaded from:
49
+ https://mosamatic.rbeesoft.nl/wordpress/mosamatic/installation/
50
+
51
+ --output : str
52
+ Path to output directory
53
+
54
+ --overwrite : bool
55
+ Overwrite contents output directory [true|false]
56
+ """
57
+ pipeline = DefaultPipeline(
58
+ inputs={'images': images, 'model_files': model_files},
59
+ params={
60
+ 'target_size': 512,
61
+ 'model_type': 'tensorflow',
62
+ 'model_version': 1.0,
63
+ 'file_type': 'npy',
64
+ 'fig_width': 10,
65
+ 'fig_height': 10,
66
+ },
67
+ output=output,
68
+ overwrite=overwrite,
69
+ )
70
+ pipeline.run()
@@ -0,0 +1,55 @@
1
+ import click
2
+
3
+ from mosamatic2.core.tasks import Dicom2NiftiTask
4
+
5
+
6
+ @click.command(help='Converts root directory with DICOM series to NIFTI format')
7
+ @click.option(
8
+ '--scans',
9
+ required=True,
10
+ type=click.Path(exists=True),
11
+ help='Root directory with DICOM scans (one for each patient)',
12
+ )
13
+ @click.option(
14
+ '--compressed',
15
+ type=click.BOOL,
16
+ default=True,
17
+ help='Compress with gzip [true|false] (default: True)'
18
+ )
19
+ @click.option(
20
+ '--output',
21
+ required=True,
22
+ type=click.Path(),
23
+ help='Output directory'
24
+ )
25
+ @click.option(
26
+ '--overwrite',
27
+ type=click.BOOL,
28
+ default=False,
29
+ help='Overwrite [true|false]'
30
+ )
31
+ def dicom2nifti(scans, compressed, output, overwrite):
32
+ """
33
+ Converts DICOM scans to NIFTI format.
34
+
35
+ Parameters
36
+ ----------
37
+ --scans : str
38
+ Root directory with DICOM scans (one subdirectory for each patient)
39
+
40
+ --compressed : bool
41
+ Whether to compress the NIFTI file with gzip or not (default: True)
42
+
43
+ --output : str
44
+ Path to output directory
45
+
46
+ --overwrite : bool
47
+ Overwrite contents output directory [true|false]
48
+ """
49
+ task = Dicom2NiftiTask(
50
+ inputs={'scans': scans},
51
+ params={'compressed': compressed},
52
+ output=output,
53
+ overwrite=overwrite,
54
+ )
55
+ task.run()
@@ -0,0 +1,61 @@
1
+ import click
2
+
3
+ from mosamatic2.core.pipelines import LiverAnalysisPipeline
4
+
5
+
6
+ @click.command(help='Runs liver analysis pipeline')
7
+ @click.option(
8
+ '--scans',
9
+ required=True,
10
+ type=click.Path(exists=True),
11
+ help='Root directory with scan directories for each patient (no spaces allowed)',
12
+ )
13
+ @click.option(
14
+ '--compressed',
15
+ default=True,
16
+ help='Whether to produce compressed NIFTI file or not (default: True)'
17
+ )
18
+ @click.option(
19
+ '--output',
20
+ required=True,
21
+ type=click.Path(),
22
+ help='Output directory (no spaces allowed)'
23
+ )
24
+ @click.option(
25
+ '--overwrite',
26
+ type=click.BOOL,
27
+ default=False,
28
+ help='Overwrite [true|false]'
29
+ )
30
+ def liveranalysispipeline(scans, compressed, output, overwrite):
31
+ """
32
+ Runs liver analysis pipeline. This pipeline run the following steps on each scan:
33
+
34
+ (1) DICOM to NIFTI conversion
35
+ (2) Extract liver segments using Total Segmentator
36
+ (3) Calculate segment statistics, e.g., volume (mL), mean HU, std HU and PNG image
37
+ of each segments HU histogram.
38
+
39
+ Parameters
40
+ ----------
41
+ --scans : str
42
+ Root directory with scan directories for each patient. Each scan directory should
43
+ contain DICOM images for a single scan only and nothing else. Also, the directory
44
+ paths cannot contain any spaces.
45
+
46
+ --compressed : str
47
+ Whether to produce compressed NIFTI file or not (default: True)
48
+
49
+ --output : str
50
+ Path to output directory. No spaces allowed.
51
+
52
+ --overwrite : bool
53
+ Overwrite contents output directory [true|false]
54
+ """
55
+ pipeline = LiverAnalysisPipeline(
56
+ inputs={'scans': scans},
57
+ params={'compressed': compressed},
58
+ output=output,
59
+ overwrite=overwrite,
60
+ )
61
+ pipeline.run()
@@ -0,0 +1,54 @@
1
+ import click
2
+
3
+ from mosamatic2.core.tasks import RescaleDicomImagesTask
4
+
5
+
6
+ @click.command(help='Rescale DICOM files to target size')
7
+ @click.option(
8
+ '--images',
9
+ required=True,
10
+ type=click.Path(exists=True),
11
+ help='Input 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
+ '--target_size',
21
+ default=512,
22
+ help='Target size of rescaled images (default: 512)'
23
+ )
24
+ @click.option(
25
+ '--overwrite',
26
+ type=click.BOOL,
27
+ default=False,
28
+ help='Overwrite [true|false]'
29
+ )
30
+ def rescaledicomimages(images, output, target_size, overwrite):
31
+ """
32
+ Rescales DICOM images to given (square) target size
33
+
34
+ Parameters
35
+ ----------
36
+ --images : str
37
+ Directory with input DICOM images
38
+
39
+ --output : str
40
+ Path to output directory
41
+
42
+ --target_size : int
43
+ Target size for rescaled images (default: 512)
44
+
45
+ --overwrite : bool
46
+ Overwrite contents output directory: [true|false]
47
+ """
48
+ task = RescaleDicomImagesTask(
49
+ inputs={'images': images},
50
+ params={'target_size': target_size},
51
+ output=output,
52
+ overwrite=overwrite
53
+ )
54
+ task.run()
@@ -0,0 +1,55 @@
1
+ import click
2
+
3
+ from mosamatic2.core.tasks import SegmentMuscleFatL3TensorFlowTask
4
+
5
+
6
+ @click.command(help='Extracts muscle and fat regions from CT images at L3 (uses PyTorch)')
7
+ @click.option(
8
+ '--images',
9
+ required=True,
10
+ type=click.Path(),
11
+ help='Input directory with images'
12
+ )
13
+ @click.option(
14
+ '--model_files',
15
+ required=True,
16
+ type=click.Path(),
17
+ help='Input directory with AI model files'
18
+ )
19
+ @click.option(
20
+ '--output',
21
+ required=True,
22
+ type=click.Path(),
23
+ help='Output directory'
24
+ )
25
+ @click.option(
26
+ '--overwrite',
27
+ default=False,
28
+ type=click.BOOL,
29
+ help='Overwrite [true|false]'
30
+ )
31
+ def segmentmusclefatl3tensorflow(images, model_files, output, overwrite):
32
+ """
33
+ Automatically segments muscle and fat tissue in CT images at L3 level.
34
+
35
+ Parameters
36
+ ----------
37
+ --images : str
38
+ Directory with input L3 images
39
+
40
+ --model_files : str
41
+ Directory with AI model files (model-1.0.zip, contour_model-1.0.zip, params-1.0.json)
42
+
43
+ --output : str
44
+ Path to output directory
45
+
46
+ --overwrite : bool
47
+ Overwrite contents output directory [true|false]
48
+ """
49
+ task = SegmentMuscleFatL3TensorFlowTask(
50
+ inputs={'images': images, 'model_files': model_files},
51
+ params={'model_version': 1.0},
52
+ output=output,
53
+ overwrite=overwrite,
54
+ )
55
+ task.run()
@@ -0,0 +1,66 @@
1
+ import click
2
+
3
+ from mosamatic2.core.tasks import SelectSliceFromScansTask
4
+
5
+
6
+ @click.command(help='Selects specific slice from CT scans')
7
+ @click.option(
8
+ '--scans',
9
+ required=True,
10
+ type=click.Path(exists=True),
11
+ help='Directory with scans (each patient separate subdirectory)',
12
+ )
13
+ @click.option(
14
+ '--output',
15
+ required=True,
16
+ type=click.Path(),
17
+ help='Output directory'
18
+ )
19
+ @click.option(
20
+ '--vertebra',
21
+ required=True,
22
+ default='L3',
23
+ help='Vertebral level for selecting slice (default: "L3")'
24
+ )
25
+ @click.option(
26
+ '--overwrite',
27
+ type=click.BOOL,
28
+ default=True,
29
+ help='Overwrite [true|false] (default: true)'
30
+ )
31
+ def selectslicefromscans(scans, vertebra, output, overwrite):
32
+ """
33
+ Selects specific slice from list of CT scans
34
+
35
+ Parameters
36
+ ----------
37
+ --scans : str
38
+ Directory to scans. Each patient's scan should be in a separate
39
+ subdirectory. For example:
40
+
41
+ /scans
42
+ /scans/patient1
43
+ /scans/patient1/file1.dcm
44
+ /scans/patient1/file2.dcm
45
+ ...
46
+ /scans/patient2
47
+ ...
48
+
49
+ --output : str
50
+ Path to output directory where selected slices will be placed. Each
51
+ slice's file name will be the same as the scan directory name, so in
52
+ the example above that would be "patient1", "patient2", etc.
53
+
54
+ --vertebra : str
55
+ Vertebral level where to take slice [L3|T4] (default: L3)
56
+
57
+ --overwrite : bool
58
+ Overwrite contents output directory [true|false] (default: true)
59
+ """
60
+ task = SelectSliceFromScansTask(
61
+ inputs={'scans': scans},
62
+ params={'vertebra': vertebra},
63
+ output=output,
64
+ overwrite=overwrite,
65
+ )
66
+ task.run()
@@ -0,0 +1,77 @@
1
+ import click
2
+
3
+ from mosamatic2.core.tasks import TotalSegmentatorTask
4
+
5
+
6
+ @click.command(help='Run Total Segmentator on CT scans')
7
+ @click.option(
8
+ '--scans',
9
+ required=True,
10
+ type=click.Path(exists=True),
11
+ help='Directory with scans (each patient separate subdirectory)',
12
+ )
13
+ @click.option(
14
+ '--output',
15
+ required=True,
16
+ type=click.Path(),
17
+ help='Output directory'
18
+ )
19
+ @click.option(
20
+ '--tasks',
21
+ default='total',
22
+ help='Comma-separated list of Total Segmentator tasks to run (no spaces!)'
23
+ )
24
+ @click.option(
25
+ '--format',
26
+ default='dicom',
27
+ help='Process scans in DICOM or NIFTI format [dicom|nifti] (default: dicom)'
28
+ )
29
+ @click.option(
30
+ '--overwrite',
31
+ type=click.BOOL,
32
+ default=False,
33
+ help='Overwrite [true|false]'
34
+ )
35
+ def totalsegmentator(scans, tasks, format, output, overwrite):
36
+ """
37
+ Run Total Segmentator on CT scans. If you want to run specialized tasks
38
+ like "liver_segments" or "liver_vessels" you need an educational license.
39
+ Check out https://github.com/wasserth/TotalSegmentator?tab=readme-ov-file
40
+ to find out how to get such a license.
41
+
42
+ Parameters
43
+ ----------
44
+ --scans : str
45
+ Directory to scans. Each patient's scan should be in a separate
46
+ subdirectory. For example:
47
+
48
+ /scans
49
+ /scans/patient1
50
+ /scans/patient1/file1.dcm
51
+ /scans/patient1/file2.dcm
52
+ ...
53
+ /scans/patient2
54
+ ...
55
+
56
+ --output : str
57
+ Path to output directory where selected slices will be placed. Each
58
+ slice's file name will be the same as the scan directory name, so in
59
+ the example above that would be "patient1", "patient2", etc.
60
+
61
+ --tasks : str
62
+ Comma-separated list of Total Segmentator tasks to run (no spaces!)
63
+
64
+ --format : str
65
+ Process scans in DICOM or NIFTI format. Options: [dicom|nifti]
66
+ Default is 'dicom'.
67
+
68
+ --overwrite : bool
69
+ Overwrite contents output directory [true|false]
70
+ """
71
+ task = TotalSegmentatorTask(
72
+ inputs={'scans': scans},
73
+ params={'tasks': tasks, 'format': format},
74
+ output=output,
75
+ overwrite=overwrite,
76
+ )
77
+ task.run()
@@ -0,0 +1,27 @@
1
+ MOSAMATIC2_BUNDLE_IDENTIFIER = 'org.mumc'
2
+ MOSAMATIC2_APP_NAME = 'mosamatic2'
3
+ MOSAMATIC2_VERSION_FILE = 'mosamatic2/ui/resources/VERSION'
4
+ MOSAMATIC2_IMAGES_DIR_PATH = 'mosamatic2/ui/resources/images'
5
+ MOSAMATIC2_ICONS_DIR_PATH = 'mosamatic2/ui/resources/icons'
6
+ MOSAMATIC2_APP_ICON_FILE_NAME_WIN = 'mosamatic2.ico'
7
+ MOSAMATIC2_APP_ICON_FILE_NAME_MAC = 'mosamatic2.icns'
8
+ MOSAMATIC2_BACKGROUND_IMAGE_FILE_NAME = 'body-composition.jpg'
9
+ MOSAMATIC2_BACKGROUND_IMAGE_OPACITY = 0.4
10
+
11
+ MOSAMATIC2_SERVER_PORT = 8000
12
+ MOSAMATIC2_SERVER_DEBUG = True
13
+
14
+ MOSAMATIC2_WINDOW_TITLE = 'Mosamatic'
15
+ MOSAMATIC2_WINDOW_W = 1000
16
+ MOSAMATIC2_WINDOW_H = 600
17
+ MOSAMATIC2_WINDOW_GEOMETRY_KEY = 'mainwindow/geometry'
18
+ MOSAMATIC2_WINDOW_STATE_KEY = 'mainwindow/state'
19
+
20
+ MOSAMATIC2_SPLASH_SCREEN_TITLE = MOSAMATIC2_WINDOW_TITLE
21
+ MOSAMATIC2_SPLASH_SCREEN_TITLE_STYLESHEET = 'color: rgb(64, 64, 64); font-weight: bold; font-size: 32pt;'
22
+ MOSAMATIC2_SPLASH_SCREEN_SUB_TEXT = 'This software is for research only'
23
+ MOSAMATIC2_SPLASH_SCREEN_SUB_TEXT_STYLE_SHEET = 'color: rgb(64, 64, 64); font-style: italic; font-size: 10pt;'
24
+ MOSAMATIC2_SPLASH_SCREEN_START_BUTTON_TEXT = 'Start Application'
25
+ MOSAMATIC2_SPLASH_SCREEN_QUIT_BUTTON_TEXT = 'Quit'
26
+ MOSAMATIC2_SPLASH_SCREEN_W = 600
27
+ MOSAMATIC2_SPLASH_SCREEN_H = 300
File without changes
@@ -0,0 +1,5 @@
1
+ from mosamatic2.core.data.filedata import FileData
2
+ from mosamatic2.core.data.dicomimage import DicomImage
3
+ from mosamatic2.core.data.dicomimageseries import DicomImageSeries
4
+ from mosamatic2.core.data.multidicomimage import MultiDicomImage
5
+ from mosamatic2.core.data.dixonseries import DixonSeries
@@ -0,0 +1,27 @@
1
+ from mosamatic2.core.data.filedata import FileData
2
+ from mosamatic2.core.utils import (
3
+ is_dicom,
4
+ load_dicom,
5
+ is_jpeg2000_compressed,
6
+ )
7
+ from mosamatic2.core.managers.logmanager import LogManager
8
+
9
+ LOG = LogManager()
10
+
11
+
12
+ class DicomImage(FileData):
13
+ def load(self):
14
+ if self.path():
15
+ p = load_dicom(self.path())
16
+ if p:
17
+ if is_jpeg2000_compressed(p):
18
+ p.decompress()
19
+ self.set_object(p)
20
+ return True
21
+ # if is_dicom(self.path()):
22
+ # p = load_dicom(self.path())
23
+ # if is_jpeg2000_compressed(p):
24
+ # p.decompress()
25
+ # self.set_object(p)
26
+ # return True
27
+ return False
@@ -0,0 +1,26 @@
1
+ import os
2
+ from mosamatic2.core.data.filedata import FileData
3
+ from mosamatic2.core.data.dicomimage import DicomImage
4
+
5
+
6
+ class DicomImageSeries(FileData):
7
+ def __init__(self):
8
+ super(DicomImageSeries, self).__init__()
9
+ self._images = []
10
+
11
+ def images(self):
12
+ return self._images
13
+
14
+ def load(self):
15
+ if self.path():
16
+ images = []
17
+ for f in os.listdir(self.path()):
18
+ f_path = os.path.join(self.path(), f)
19
+ image = DicomImage()
20
+ image.set_path(f_path)
21
+ if image.load():
22
+ images.append(image)
23
+ # Sort DICOM objects by instance number
24
+ self._images = sorted(images, key=lambda image: int(image.object().get('InstanceNumber')))
25
+ return True
26
+ return False
@@ -0,0 +1,22 @@
1
+ from mosamatic2.core.data.filedata import FileData
2
+
3
+
4
+ class DixonSeries(FileData):
5
+ def __init__(self):
6
+ super(DixonSeries, self).__init__()
7
+ self._series = {'ip': None, 'op': None, 'water': None, 'fat': None}
8
+
9
+ def ip(self):
10
+ return self._series['ip']
11
+
12
+ def op(self):
13
+ return self._series['op']
14
+
15
+ def water(self):
16
+ return self._series['water']
17
+
18
+ def fat(self):
19
+ return self._series['fat']
20
+
21
+ def load(self):
22
+ pass
@@ -0,0 +1,26 @@
1
+ import os
2
+
3
+
4
+ class FileData:
5
+ def __init__(self):
6
+ self._path = None
7
+ self._name = None
8
+ self._object = None
9
+
10
+ def path(self):
11
+ return self._path
12
+
13
+ def set_path(self, path):
14
+ self._path = path
15
+
16
+ def name(self):
17
+ return os.path.split(self.path())[1]
18
+
19
+ def object(self):
20
+ return self._object
21
+
22
+ def set_object(self, object):
23
+ self._object = object
24
+
25
+ def load(self):
26
+ raise NotImplementedError()