diff --git a/README.md b/README.md index ce97eb7..13538a8 100644 --- a/README.md +++ b/README.md @@ -67,22 +67,8 @@ Although it may work on other versions and/or operating system, please note that 8. (Optional) Set the SlicerCART module to launch at 3DSlicer startup. To do so, go to `Edit -> Application Settings -> Modules -> Default startup module` ### Trouble shooting + * Qt might need to be installed. The first five steps of the following procedure might be useful for this: [procedure](https://web.stanford.edu/dept/cs_edu/resources/qt/install-mac). -* If some modules are missing (`ModuleNotFoundError`), they must be added to the 3D Slicer environment by using the following commands in the Python Console: - `from slicer.util import pip_install` - `pip_install("XYZ")` where `XYZ` is replaced by the proper library - -> Minimally the following packages are not already available (copy and paste in the 3D Slicer python interactor): -> - - ```py - slicer.util.pip_install('pandas') - slicer.util.pip_install('nibabel') - slicer.util.pip_install('pynrrd') - slicer.util.pip_install('pyyaml') - slicer.util.pip_install('slicerio') - slicer.util.pip_install('PyQt5') - ``` ### Other extensions that could be useful * `SlicerJupyter` to be able to use Jupyter Notebooks connected to 3D Slicer. diff --git a/SlicerCART/src/SlicerCART.py b/SlicerCART/src/SlicerCART.py index 153cd50..f8c6f49 100644 --- a/SlicerCART/src/SlicerCART.py +++ b/SlicerCART/src/SlicerCART.py @@ -2,34 +2,81 @@ # pip install --user package_name import os import logging -import qt, slicer -from PyQt5 import QtCore +import slicer +import qt from slicer.ScriptedLoadableModule import * from slicer.util import VTKObservationMixin from glob import glob import re -import pandas as pd import time -import slicerio # cannot install in slicer -import nrrd -import yaml from pathlib import Path from threading import RLock from datetime import datetime -from bids_validator import BIDSValidator import filecmp import shutil -import nib import numpy as np import vtk import random import colorsys +import sys + + +# TODO: There is probably a more elegant way to install pacakages through the extension manager when the user installs the extension. +# TODO: check if the package installed with error + +# Dictionary of required python packages and their import names +REQUIRED_PYTHON_PACKAGES = { + "nibabel": "nibabel", + "pandas": "pandas", + "PyYAML": "yaml", + "pynrrd": "nrrd", + "slicerio": "slicerio", + "bids_validator": "bids_validator", + "PyQt5": "PyQt5" +} +def check_and_install_python_packages(): + missing_packages = [] + + for pip_name, import_name in REQUIRED_PYTHON_PACKAGES.items(): + try: + __import__(import_name) + except ImportError: + missing_packages.append(pip_name) + + if missing_packages: + msg = "SlicerCART module: The following required python packages are missing:" + msg += "\n" + "\n".join(missing_packages) + msg += "\nWould you like to install them now?" + response = qt.QMessageBox.question(slicer.util.mainWindow(), 'Install Extensions', msg, + qt.QMessageBox.Yes | qt.QMessageBox.No) + if response == qt.QMessageBox.Yes: + for pip_name in missing_packages: + slicer.util.pip_install(pip_name) + # Wait for the installation to complete + slicer.app.processEvents() + qt.QMessageBox.information(slicer.util.mainWindow(), 'Restart Slicer', + 'Slicer will now restart to complete the installation.') + slicer.app.restart() + else: + qt.QMessageBox.warning(slicer.util.mainWindow(), 'Missing Extensions', + 'The SlicerCART module cannot be loaded without the required extensions.') + + +check_and_install_python_packages() + +from bids_validator import BIDSValidator +import nibabel as nib +import nrrd +import pandas as pd +import slicerio +from PyQt5 import QtCore +import yaml -INPUT_FILE_EXTENSION = '*.nii.gz' +INPUT_FILE_EXTENSION = '*.nii.gz' INTERPOLATE_VALUE = 0 -DEFAULT_VOLUMES_DIRECTORY = '' +DEFAULT_VOLUMES_DIRECTORY = '' DEFAULT_SEGMENTATION_DIRECTORY = '' REQUIRE_VOLUME_DATA_HIERARCHY_BIDS_FORMAT = False @@ -45,6 +92,11 @@ CLASSIFICATION_CONFIG_FILE_PATH = os.path.join(Path(__file__).parent.resolve(), "classification_config.yml") GENERAL_CONFIG_FILE_PATH = os.path.join(Path(__file__).parent.resolve(), "general_config.yml") +CT_WINDOW_WIDTH = 90 +CT_WINDOW_LEVEL = 45 + + + TIMER_MUTEX = RLock() class LoadClassificationWindow(qt.QWidget): @@ -52,11 +104,9 @@ def __init__(self, segmenter, classificationInformation_df, parent = None): super(LoadClassificationWindow, self).__init__(parent) self.classificationInformation_df = classificationInformation_df - self.segmenter = segmenter layout = qt.QVBoxLayout() - self.versionTableView = qt.QTableWidget() layout.addWidget(self.versionTableView) @@ -66,7 +116,7 @@ def __init__(self, segmenter, classificationInformation_df, parent = None): versionLabel.setText('Classification version to load: ') versionLabel.setStyleSheet("font-weight: bold") buttonLayout.addWidget(versionLabel) - + self.versionDropdown = qt.QComboBox() buttonLayout.addWidget(self.versionDropdown) @@ -79,32 +129,32 @@ def __init__(self, segmenter, classificationInformation_df, parent = None): self.versionTableView.setRowCount(len(available_versions)) self.versionTableView.setColumnCount(4) - self.versionTableView.horizontalHeader().setStretchLastSection(True) - self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) + self.versionTableView.horizontalHeader().setStretchLastSection(True) + self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) for index, row in classificationInformation_df.iterrows(): - cell = qt.QTableWidgetItem(row['Classification version']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 0, cell) + cell = qt.QTableWidgetItem(row['Classification version']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 0, cell) self.versionTableView.setHorizontalHeaderItem(0, qt.QTableWidgetItem('Version')) - cell = qt.QTableWidgetItem(row['Annotator Name']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + cell = qt.QTableWidgetItem(row['Annotator Name']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) self.versionTableView.setItem(index, 1, cell) - self.versionTableView.setHorizontalHeaderItem(1, qt.QTableWidgetItem('Annotator')) + self.versionTableView.setHorizontalHeaderItem(1, qt.QTableWidgetItem('Annotator')) - cell = qt.QTableWidgetItem(row['Annotator degree']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 2, cell) + cell = qt.QTableWidgetItem(row['Annotator degree']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 2, cell) self.versionTableView.setHorizontalHeaderItem(2, qt.QTableWidgetItem('Degree')) - cell = qt.QTableWidgetItem(row['Date and time']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 3, cell) + cell = qt.QTableWidgetItem(row['Date and time']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 3, cell) self.versionTableView.setHorizontalHeaderItem(3, qt.QTableWidgetItem('Date and Time')) self.loadButton = qt.QPushButton('Load') @@ -120,8 +170,7 @@ def __init__(self, segmenter, classificationInformation_df, parent = None): self.resize(800, 400) def pushLoad(self): - selected_version = self.versionDropdown.currentText - + selected_version = self.versionDropdown.currentText selected_version_df = self.classificationInformation_df[self.classificationInformation_df['Classification version']==selected_version].reset_index(drop = True) for i, (objectName, label) in enumerate(self.segmenter.classification_config_yaml["checkboxes"].items()): @@ -129,10 +178,10 @@ def pushLoad(self): self.segmenter.checkboxWidgets[objectName].setChecked(True) elif selected_version_df.at[0, label] == 'No': self.segmenter.checkboxWidgets[objectName].setChecked(False) - + for i, (comboBoxName, options) in enumerate(self.segmenter.classification_config_yaml["comboboxes"].items()): self.segmenter.comboboxWidgets[comboBoxName].setCurrentText(selected_version_df.at[0, comboBoxName.replace("_", " ").capitalize()]) - + for i, (freeTextBoxObjectName, label) in enumerate(self.segmenter.classification_config_yaml["freetextboxes"].items()): saved_text = selected_version_df.at[0, label.capitalize()] if str(saved_text) != 'nan': @@ -150,7 +199,6 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): super(ShowSegmentVersionLegendWindow, self).__init__(parent) self.segmentationInformation_df = segmentationInformation_df - self.segmenter = segmenter layout = qt.QVBoxLayout() @@ -166,8 +214,8 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): self.versionTableView.setRowCount(len(self.segmenter.colorsSelectedVersionFilePathsForCompareSegmentVersions)) self.versionTableView.setColumnCount(5) - self.versionTableView.horizontalHeader().setStretchLastSection(True) - self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) + self.versionTableView.horizontalHeader().setStretchLastSection(True) + self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) for index, row in segmentationInformation_df.iterrows(): currentColor = None @@ -177,31 +225,31 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): colorItem = qt.QTableWidgetItem() colorItem.setBackground(qt.QBrush(qt.QColor(currentColor[0], currentColor[1], currentColor[2]))) - self.versionTableView.setItem(index, 0, colorItem) + self.versionTableView.setItem(index, 0, colorItem) self.versionTableView.setHorizontalHeaderItem(0, qt.QTableWidgetItem('Color')) - cell = qt.QTableWidgetItem(row['Segmentation version']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 1, cell) + cell = qt.QTableWidgetItem(row['Segmentation version']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 1, cell) self.versionTableView.setHorizontalHeaderItem(1, qt.QTableWidgetItem('Version')) - cell = qt.QTableWidgetItem(row['Annotator Name']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + cell = qt.QTableWidgetItem(row['Annotator Name']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) self.versionTableView.setItem(index, 2, cell) - self.versionTableView.setHorizontalHeaderItem(2, qt.QTableWidgetItem('Annotator')) + self.versionTableView.setHorizontalHeaderItem(2, qt.QTableWidgetItem('Annotator')) - cell = qt.QTableWidgetItem(row['Annotator degree']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 3, cell) + cell = qt.QTableWidgetItem(row['Annotator degree']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 3, cell) self.versionTableView.setHorizontalHeaderItem(3, qt.QTableWidgetItem('Degree')) - cell = qt.QTableWidgetItem(row['Date and time']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 4, cell) + cell = qt.QTableWidgetItem(row['Date and time']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 4, cell) self.versionTableView.setHorizontalHeaderItem(4, qt.QTableWidgetItem('Date and Time')) self.cancelButton = qt.QPushButton('Done') @@ -220,7 +268,7 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): super(CompareSegmentVersionsWindow, self).__init__(parent) self.segmentationInformation_df = segmentationInformation_df - + self.segmenter = segmenter layout = qt.QVBoxLayout() @@ -238,7 +286,7 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): labelLabel.setText('Label of interest for comparison ') labelLabel.setStyleSheet("font-weight: bold") buttonLayout.addWidget(labelLabel) - + self.labelDropdown = qt.QComboBox() for label in self.segmenter.label_config_yaml['labels']: self.labelDropdown.addItem(label['name']) @@ -253,40 +301,40 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): self.versionTableView.setRowCount(len(available_versions)) self.versionTableView.setColumnCount(5) - self.versionTableView.horizontalHeader().setStretchLastSection(True) - self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) + self.versionTableView.horizontalHeader().setStretchLastSection(True) + self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) for index, row in segmentationInformation_df.iterrows(): checkboxItem = qt.QTableWidgetItem() - checkboxItem.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled) - checkboxItem.setCheckState(QtCore.Qt.Unchecked) - checkboxItem.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 0, checkboxItem) + checkboxItem.setFlags(qt.Qt.ItemIsUserCheckable | qt.Qt.ItemIsEnabled) + checkboxItem.setCheckState(qt.Qt.Unchecked) + checkboxItem.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 0, checkboxItem) self.versionTableView.setHorizontalHeaderItem(0, qt.QTableWidgetItem('Select')) self.versionCheckboxWidgets[index] = checkboxItem - cell = qt.QTableWidgetItem(row['Segmentation version']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 1, cell) + cell = qt.QTableWidgetItem(row['Segmentation version']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 1, cell) self.versionTableView.setHorizontalHeaderItem(1, qt.QTableWidgetItem('Version')) - cell = qt.QTableWidgetItem(row['Annotator Name']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + cell = qt.QTableWidgetItem(row['Annotator Name']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) self.versionTableView.setItem(index, 2, cell) - self.versionTableView.setHorizontalHeaderItem(2, qt.QTableWidgetItem('Annotator')) + self.versionTableView.setHorizontalHeaderItem(2, qt.QTableWidgetItem('Annotator')) - cell = qt.QTableWidgetItem(row['Annotator degree']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 3, cell) + cell = qt.QTableWidgetItem(row['Annotator degree']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 3, cell) self.versionTableView.setHorizontalHeaderItem(3, qt.QTableWidgetItem('Degree')) - cell = qt.QTableWidgetItem(row['Date and time']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 4, cell) + cell = qt.QTableWidgetItem(row['Date and time']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 4, cell) self.versionTableView.setHorizontalHeaderItem(4, qt.QTableWidgetItem('Date and Time')) self.viewSegmentsButton = qt.QPushButton('Compare') @@ -329,11 +377,11 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): super(LoadSegmentationsWindow, self).__init__(parent) self.segmentationInformation_df = segmentationInformation_df - + self.segmenter = segmenter layout = qt.QVBoxLayout() - + self.versionTableView = qt.QTableWidget() layout.addWidget(self.versionTableView) @@ -343,7 +391,7 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): versionLabel.setText('Segmentation version to load: ') versionLabel.setStyleSheet("font-weight: bold") buttonLayout.addWidget(versionLabel) - + self.versionDropdown = qt.QComboBox() buttonLayout.addWidget(self.versionDropdown) @@ -356,30 +404,30 @@ def __init__(self, segmenter, segmentationInformation_df, parent = None): self.versionTableView.setRowCount(len(available_versions)) self.versionTableView.setColumnCount(4) - self.versionTableView.horizontalHeader().setStretchLastSection(True) - self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) + self.versionTableView.horizontalHeader().setStretchLastSection(True) + self.versionTableView.horizontalHeader().setSectionResizeMode(qt.QHeaderView.Stretch) for index, row in segmentationInformation_df.iterrows(): - cell = qt.QTableWidgetItem(row['Segmentation version']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 0, cell) + cell = qt.QTableWidgetItem(row['Segmentation version']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 0, cell) self.versionTableView.setHorizontalHeaderItem(0, qt.QTableWidgetItem('Version')) - cell = qt.QTableWidgetItem(row['Annotator Name']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + cell = qt.QTableWidgetItem(row['Annotator Name']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) self.versionTableView.setItem(index, 1, cell) - self.versionTableView.setHorizontalHeaderItem(1, qt.QTableWidgetItem('Annotator')) + self.versionTableView.setHorizontalHeaderItem(1, qt.QTableWidgetItem('Annotator')) - cell = qt.QTableWidgetItem(row['Annotator degree']) - cell.setFlags(QtCore.Qt.NoItemFlags) - cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) - self.versionTableView.setItem(index, 2, cell) + cell = qt.QTableWidgetItem(row['Annotator degree']) + cell.setFlags(qt.Qt.NoItemFlags) + cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) + self.versionTableView.setItem(index, 2, cell) self.versionTableView.setHorizontalHeaderItem(2, qt.QTableWidgetItem('Degree')) - cell = qt.QTableWidgetItem(row['Date and time']) - cell.setFlags(QtCore.Qt.NoItemFlags) + cell = qt.QTableWidgetItem(row['Date and time']) + cell.setFlags(qt.Qt.NoItemFlags) cell.setForeground(qt.QBrush(qt.QColor(0, 0, 0))) self.versionTableView.setItem(index, 3, cell) self.versionTableView.setHorizontalHeaderItem(3, qt.QTableWidgetItem('Date and Time')) @@ -515,6 +563,14 @@ def pushCancel(self): self.segmenter.ClearPHESegment() self.close() + + +class OptionalMethods(): + pass + + + + class SlicerCART(ScriptedLoadableModule): """Uses ScriptedLoadableModule base class, available at: https://github.com/Slicer/Slicer/blob/master/Base/Python/slicer/ScriptedLoadableModule.py @@ -529,7 +585,7 @@ def __init__(self, parent): # TODO: update with short description of the module and a link to online module documentation self.parent.helpText = """ This is an example of scripted loadable module bundled in an extension. -See more information in module documentation. +See more information in module documentation. """ # TODO: replace with organization, grant and thanks self.parent.acknowledgementText = """ @@ -792,6 +848,8 @@ def get_general_config_values(self): global IS_SEGMENTATION_REQUESTED global IS_SEMI_AUTOMATIC_PHE_TOOL_REQUESTED global INTERPOLATE_VALUE + global CT_WINDOW_WIDTH + global CT_WINDOW_LEVEL INPUT_FILE_EXTENSION = self.general_config_yaml["input_filetype"] DEFAULT_VOLUMES_DIRECTORY = self.general_config_yaml["default_volume_directory"] @@ -807,6 +865,9 @@ def get_general_config_values(self): # then BIDS not mandatory because it is not yet supported # therefore, either .nrrd or .nii.gz accepted REQUIRE_VOLUME_DATA_HIERARCHY_BIDS_FORMAT = False + CT_WINDOW_WIDTH = self.general_config_yaml["ct_window_width"] + CT_WINDOW_LEVEL = self.general_config_yaml["ct_window_level"] + elif MODALITY == 'MRI': # therefore, .nii.gz required INPUT_FILE_EXTENSION = '*.nii.gz' @@ -963,6 +1024,7 @@ def setupCheckboxes(self, number_of_columns): self.checkboxWidgets = {} for i, (objectName, label) in enumerate(self.classification_config_yaml["checkboxes"].items()): + print(objectName, label) checkbox = qt.QCheckBox() checkbox.setText(label) checkbox.setObjectName(objectName) @@ -973,6 +1035,7 @@ def setupCheckboxes(self, number_of_columns): self.ui.ClassificationGridLayout.addWidget(checkbox, row_index, column_index) self.checkboxWidgets[objectName] = checkbox + return row_index + 1 def setupComboboxes(self, start_row): @@ -1046,6 +1109,18 @@ def onSelectVolumesFolderButton(self): return # don't load any patient cases self.CasesPaths = sorted(glob(f'{self.CurrentFolder}{os.sep}**{os.sep}{INPUT_FILE_EXTENSION}', recursive = True)) + + if not self.CasesPaths: + msg_box = qt.QMessageBox() + msg_box.setWindowTitle("No files found") + msg_box.setIcon(qt.QMessageBox.Warning) + text = "No files found in the selected directory!" + text += "\n\nMake sure the configured extension is in the right format." + text += "\n\nThen restart the module" + msg_box.setText(text) + msg_box.exec() + return + self.Cases = sorted([os.path.split(i)[-1] for i in self.CasesPaths]) self.ui.SlicerDirectoryListView.clear() @@ -1546,11 +1621,12 @@ def cast_segmentation_to_uint8(self): input_path = os.path.basename(case) if input_path.endswith('.nii') or input_path.endswith('.nii.gz'): segm = nib.load(case) - segm_data = segm.get_fdata() + segm_data_dtype = segm.dataobj.dtype print(f'infile: {input_path}, dtype: {segm_data.dtype}') - if segm_data.dtype != np.uint8: + if segm_data_dtype != np.uint8: segm_data = segm_data.astype(np.uint8) - segm_nii = nib.Nifti1Image(segm_data, segm.affine) + segm.header.set_data_dtype(np.uint8) + segm_nii = nib.Nifti1Image(segm_data, segm.affine, segm.header) nib.save(segm_nii, case) print(f'converted file {input_path} to uint8') elif input_path.endswith('seg.nrrd'): diff --git a/SlicerCART/src/general_config.yml b/SlicerCART/src/general_config.yml index fdae993..074db36 100644 --- a/SlicerCART/src/general_config.yml +++ b/SlicerCART/src/general_config.yml @@ -3,13 +3,16 @@ input_filetype: '*.nii.gz' # '*.nrrd' or '*.nii.gz' default_volume_directory: '' default_segmentation_directory: '' -modality: 'MRI' # 'CT' or 'MRI' +modality: 'CT' # 'CT' or 'MRI' slice_view_color: 'Red' # 'Red' or 'Yellow' or 'Green' -interpolate_value: 0 +interpolate_value: 1 -impose_bids_format: True +impose_bids_format: False is_classification_requested: True is_segmentation_requested: True is_semi_automatic_phe_tool_requested: True + +ct_window_width: 85 +ct_window_level: 45 \ No newline at end of file