Skip to content

Commit 8aeaaa9

Browse files
committed
Minor overall fixing [skip ci]
1 parent a69612b commit 8aeaaa9

File tree

9 files changed

+99
-87
lines changed

9 files changed

+99
-87
lines changed

gui/SinglePatientComponent/CentralAreaExecutionWidget.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -216,38 +216,3 @@ def on_run_reporting(self):
216216

217217
def on_process_message(self, mess):
218218
print("Collected message: {}.\n".format(mess))
219-
220-
def assertion_input_compatible(self, tumor_type: str) -> bool:
221-
# Making sure an MRI series with the proper sequence type has been loaded and tagged.
222-
if tumor_type != 'Low-Grade Glioma':
223-
valid_ids = SoftwareConfigResources.getInstance().get_active_patient().get_all_mri_volumes_for_sequence_type(MRISequenceType.T1c)
224-
if len(valid_ids) == 0:
225-
box = QMessageBox(self)
226-
box.setWindowTitle("Missing contrast-enhanced MRI scan")
227-
box.setText("Please make sure to load a contrast-enhanced MRI scan for running this task.\n"
228-
"Also make sure to properly fill in the sequence type attribute for the loaded "
229-
"MRI Series in the right-hand panel!")
230-
box.setIcon(QMessageBox.Warning)
231-
box.setStyleSheet("""QLabel{
232-
color: rgba(0, 0, 0, 1);
233-
background-color: rgba(255, 255, 255, 1);
234-
}""")
235-
box.exec()
236-
return False
237-
else:
238-
valid_ids = SoftwareConfigResources.getInstance().get_active_patient().get_all_mri_volumes_for_sequence_type(MRISequenceType.FLAIR)
239-
if len(valid_ids) == 0:
240-
box = QMessageBox(self)
241-
box.setWindowTitle("Missing FLAIR MRI scan")
242-
box.setText("Please make sure to load a contrast-enhanced MRI scan for running this task.\n"
243-
"Also make sure to properly fill in the sequence type attribute for the loaded "
244-
"MRI Series in the right-hand panel!")
245-
box.setIcon(QMessageBox.Warning)
246-
box.setStyleSheet("""QLabel{
247-
color: rgba(0, 0, 0, 1);
248-
background-color: rgba(255, 255, 255, 1);
249-
}""")
250-
box.exec()
251-
return False
252-
253-
return True

gui/SinglePatientComponent/LayersInteractorSidePanel/ActionsInteractor/ActionsInteractorWidget.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ def __set_advanced_interface(self):
117117
self.advanced_actions_groupbox_layout.addLayout(self.timestamp_target_layout)
118118
self.advanced_actions_groupbox_layout.addLayout(self.segmentation_class_layout)
119119
self.advanced_actions_groupbox_layout.addWidget(self.run_action_pushbutton)
120-
self.layout.addWidget(self.advanced_actions_groupbox)
120+
# self.layout.addWidget(self.advanced_actions_groupbox) # Disabling for now, not sure how to have it.
121121

122122
def __set_connections(self):
123123
self.run_folder_classification.clicked.connect(self.on_execute_folders_classification)
@@ -454,6 +454,7 @@ def reset(self):
454454
self.run_segmentation_postop.setEnabled(False)
455455
self.run_rads_preop.setEnabled(False)
456456
self.run_rads_postop.setEnabled(False)
457+
self.run_rads_surgical.setStyleSheet(False)
457458
self.action_type_combobox.setEnabled(False)
458459
self.action_type_combobox.setCurrentIndex(0)
459460
self.timestamp_target_combobox.setEnabled(False)
@@ -478,11 +479,16 @@ def refresh(self) -> None:
478479
self.timestamp_target_combobox.addItems(items)
479480

480481
def on_enable_actions(self):
482+
"""
483+
@TODO. Should be triggered also when changing the active patient, if it has image content (right now if the
484+
patient is loaded from the batch mode, it is not triggered).
485+
"""
481486
self.run_folder_classification.setEnabled(True)
482487
self.run_segmentation_preop.setEnabled(True)
483488
self.run_segmentation_postop.setEnabled(True)
484489
self.run_rads_preop.setEnabled(True)
485490
self.run_rads_postop.setEnabled(True)
491+
self.run_rads_surgical.setEnabled(True)
486492
self.action_type_combobox.setEnabled(True)
487493
self.timestamp_target_combobox.setEnabled(True)
488494
self.segmentation_class_combobox.setEnabled(True)

gui/SinglePatientComponent/LayersInteractorSidePanel/TimestampsInteractor/TimestampsLayerInteractor.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,19 @@ def on_radiological_sequences_imported(self):
414414
self.timestamps_widget[i].on_radiological_sequences_imported()
415415

416416
def on_process_started(self) -> None:
417-
self.timestamps_widget[list(self.timestamps_widget.keys())[self.timestamp_selector_combobox.currentIndex()]].on_process_started()
418-
self.timestamp_add_pushbutton.setEnabled(False)
419-
self.timestamp_remove_pushbutton.setEnabled(False)
417+
"""
418+
When a process is starting, some options have to be disabled if viewing in single mode. Unsure what happens
419+
when switching from study to patient mode while a batch process is ongoing...
420+
While in study mode, the timestamp widgets are not created.
421+
"""
422+
if len(self.timestamps_widget) != 0:
423+
self.timestamps_widget[list(self.timestamps_widget.keys())[self.timestamp_selector_combobox.currentIndex()]].on_process_started()
424+
self.timestamp_add_pushbutton.setEnabled(False)
425+
self.timestamp_remove_pushbutton.setEnabled(False)
420426

421427
def on_process_finished(self) -> None:
422-
self.timestamps_widget[list(self.timestamps_widget.keys())[self.timestamp_selector_combobox.currentIndex()]].on_process_finished()
423-
self.timestamp_add_pushbutton.setEnabled(True)
424-
self.timestamp_remove_pushbutton.setEnabled(True)
425-
self.timestamp_selector_combobox.setCurrentIndex(0)
428+
if len(self.timestamps_widget) != 0:
429+
self.timestamps_widget[list(self.timestamps_widget.keys())[self.timestamp_selector_combobox.currentIndex()]].on_process_finished()
430+
self.timestamp_add_pushbutton.setEnabled(True)
431+
self.timestamp_remove_pushbutton.setEnabled(True)
432+
self.timestamp_selector_combobox.setCurrentIndex(0)

gui/SinglePatientComponent/PatientResultsSidePanel/SurgicalReportingWidget.py

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,26 @@ def __set_interface(self):
6969
self.resection_category_layout.addWidget(self.resection_category_label)
7070
self.layout.addLayout(self.resection_category_layout)
7171

72+
self.postoperative_flairchanges_volume_layout = QHBoxLayout()
73+
self.postoperative_flairchanges_volume_layout.setSpacing(0)
74+
self.postoperative_flairchanges_volume_layout.setContentsMargins(0, 0, 0, 0)
75+
self.postoperative_flairchanges_volume_header_label = QLabel("Postoperative FLAIR changes volume: ")
76+
self.postoperative_flairchanges_volume_label = QLabel(" - ml")
77+
self.postoperative_flairchanges_volume_layout.addWidget(self.postoperative_flairchanges_volume_header_label)
78+
self.postoperative_flairchanges_volume_layout.addStretch(1)
79+
self.postoperative_flairchanges_volume_layout.addWidget(self.postoperative_flairchanges_volume_label)
80+
self.layout.addLayout(self.postoperative_flairchanges_volume_layout)
81+
82+
self.postoperative_cavity_volume_layout = QHBoxLayout()
83+
self.postoperative_cavity_volume_layout.setSpacing(0)
84+
self.postoperative_cavity_volume_layout.setContentsMargins(0, 0, 0, 0)
85+
self.postoperative_cavity_volume_header_label = QLabel("Postoperative cavity volume: ")
86+
self.postoperative_cavity_volume_label = QLabel(" - ml")
87+
self.postoperative_cavity_volume_layout.addWidget(self.postoperative_cavity_volume_header_label)
88+
self.postoperative_cavity_volume_layout.addStretch(1)
89+
self.postoperative_cavity_volume_layout.addWidget(self.postoperative_cavity_volume_label)
90+
self.layout.addLayout(self.postoperative_cavity_volume_layout)
91+
7292
self.layout.addStretch(1)
7393

7494
def __set_layout_dimensions(self):
@@ -84,6 +104,12 @@ def __set_layout_dimensions(self):
84104
self.resection_category_header_label.setFixedHeight(20)
85105
self.resection_category_label.setFixedHeight(20)
86106

107+
self.postoperative_flairchanges_volume_header_label.setFixedHeight(20)
108+
self.postoperative_flairchanges_volume_label.setFixedHeight(20)
109+
110+
self.postoperative_cavity_volume_header_label.setFixedHeight(20)
111+
self.postoperative_cavity_volume_label.setFixedHeight(20)
112+
87113
def __set_connections(self):
88114
pass
89115

@@ -159,6 +185,38 @@ def set_stylesheets(self, selected: bool) -> None:
159185
font-size:13px;
160186
}""")
161187

188+
self.postoperative_flairchanges_volume_header_label.setStyleSheet("""
189+
QLabel{
190+
color: """ + font_color + """;
191+
text-align:left;
192+
font:semibold;
193+
font-size:14px;
194+
}""")
195+
196+
self.postoperative_flairchanges_volume_label.setStyleSheet("""
197+
QLabel{
198+
color: """ + font_color + """;
199+
text-align:right;
200+
font:semibold;
201+
font-size:14px;
202+
}""")
203+
204+
self.postoperative_cavity_volume_header_label.setStyleSheet("""
205+
QLabel{
206+
color: """ + font_color + """;
207+
text-align:left;
208+
font:semibold;
209+
font-size:14px;
210+
}""")
211+
212+
self.postoperative_cavity_volume_label.setStyleSheet("""
213+
QLabel{
214+
color: """ + font_color + """;
215+
text-align:right;
216+
font:semibold;
217+
font-size:14px;
218+
}""")
219+
162220
def adjustSize(self):
163221
pass
164222

@@ -172,10 +230,14 @@ def populate_from_report(self) -> None:
172230
# No report has been generated for the patient, skipping the rest.
173231
return
174232

175-
self.preoperative_tumor_volume_label.setText(str(report_json['preop_volume']) + ' ml')
176-
self.postoperative_tumor_volume_label.setText(str(report_json['postop_volume']) + ' ml')
177-
self.extent_resection_label.setText(str(np.round(report_json['eor'], 2)) + ' %')
233+
self.preoperative_tumor_volume_label.setText(str(round(report_json['preop_volume'], 3)) + ' ml')
234+
self.postoperative_tumor_volume_label.setText(str(round(report_json['postop_volume'], 3)) + ' ml')
235+
self.extent_resection_label.setText(str(round(report_json['eor'], 2)) + ' %')
178236
self.resection_category_label.setText(report_json['resection_category'])
237+
if report_json['flairchanges_postop_volume'] is not None:
238+
self.postoperative_flairchanges_volume_label.setText(str(round(report_json['flairchanges_postop_volume'], 3)) + ' ml')
239+
if report_json['cavity_postop_volume'] is not None:
240+
self.postoperative_cavity_volume_label.setText(str(round(report_json['cavity_postop_volume'], 3)) + ' ml')
179241

180242
def on_size_request(self):
181243
self.resizeRequested.emit()

gui/StudyBatchComponent/StudiesSidePanel/SingleStudyWidget.py

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ def __set_batch_processing_part(self):
152152
self.batch_processing_layout.setContentsMargins(0, 0, 0, 0)
153153
self.batch_processing_combobox = QComboBox()
154154
self.batch_processing_combobox.addItems(["folders_classification", "preop_segmentation", "preop_reporting",
155-
"postop_segmentation", "postop_reporting"])
155+
"postop_segmentation", "postop_reporting", "surgical_reporting"])
156156
self.batch_processing_run_pushbutton = QPushButton()
157157
self.batch_processing_run_pushbutton.setToolTip("Execute the selected process.")
158158
self.batch_processing_run_pushbutton.setIcon(QIcon(QPixmap(os.path.join(os.path.dirname(os.path.realpath(__file__)),
@@ -593,22 +593,10 @@ def __on_run_pipeline(self) -> None:
593593

594594
if code == 0: # Operation was cancelled by the user
595595
return
596-
597-
if diag.tumor_type == 'Glioblastoma':
598-
self.model_name = "MRI_GBM"
599-
elif diag.tumor_type == 'Low-Grade Glioma':
600-
self.model_name = "MRI_LGGlioma"
601-
elif diag.tumor_type == 'Metastasis':
602-
self.model_name = "MRI_Metastasis"
603-
elif diag.tumor_type == 'Meningioma':
604-
self.model_name = "MRI_Meningioma"
605-
if UserPreferencesStructure.getInstance().segmentation_tumor_model_type != "Tumor":
606-
self.model_name = self.model_name + '_multiclass'
607-
if diag.tumor_type == 'Low-Grade Glioma':
608-
self.model_name = "MRI_GBM_multiclass"
596+
self.tumor_type = diag.tumor_type
609597

610598
self.on_processing_started()
611-
self.batch_pipeline_execution_requested.emit(self.uid, pipeline_task, self.model_name)
599+
self.batch_pipeline_execution_requested.emit(self.uid, pipeline_task, self.tumor_type)
612600

613601
def on_patients_loading_started(self):
614602
self.include_single_patient_folder_pushbutton.setEnabled(False)

gui/StudyBatchComponent/StudiesSidePanel/StudiesSidePanelWidget.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,9 @@ def on_study_imported(self, study_uid):
298298
self.single_study_widgets[study_uid].manual_header_pushbutton_clicked(True)
299299
self.__on_study_selection(True, study_uid)
300300

301-
def on_batch_pipeline_execution_requested(self, study_id, pipeline_task, model_name):
301+
def on_batch_pipeline_execution_requested(self, study_id, pipeline_task, tumor_type):
302302
self.bottom_add_study_pushbutton.setEnabled(False)
303-
self.batch_pipeline_execution_requested.emit(study_id, pipeline_task, model_name)
303+
self.batch_pipeline_execution_requested.emit(study_id, pipeline_task, tumor_type)
304304

305305
def on_processing_advanced(self):
306306
self.single_study_widgets[SoftwareConfigResources.getInstance().active_study_name].on_processing_advanced()

gui/StudyBatchComponent/StudyBatchWidget.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,21 +161,21 @@ def on_study_imported(self, study_uid: str):
161161
for pat_uid in SoftwareConfigResources.getInstance().get_study(study_uid).included_patients_uids.keys():
162162
self.patient_imported.emit(pat_uid)
163163

164-
def on_batch_pipeline_execution_wrapper(self, study_uid: str, pipeline_task: str, model_name: str) -> None:
164+
def on_batch_pipeline_execution_wrapper(self, study_uid: str, pipeline_task: str, tumor_type: str) -> None:
165165
run_segmentation_thread = threading.Thread(target=self.on_batch_pipeline_execution, args=(study_uid,
166166
pipeline_task,
167-
model_name,))
167+
tumor_type,))
168168
run_segmentation_thread.daemon = True # using daemon thread the thread is killed gracefully if program is abruptly closed
169169
run_segmentation_thread.start()
170170

171-
def on_batch_pipeline_execution(self, study_uid, pipeline_task, model_name):
171+
def on_batch_pipeline_execution(self, study_uid, pipeline_task, tumor_type):
172172
from utils.backend_logic import pipeline_main_wrapper
173173
self.on_process_started()
174174
study = SoftwareConfigResources.getInstance().study_parameters[study_uid]
175175
patients_uid = study.included_patients_uids
176176
for u in patients_uid:
177177
code, results = pipeline_main_wrapper(pipeline_task=pipeline_task,
178-
model_name=model_name,
178+
tumor_type=tumor_type,
179179
patient_parameters=SoftwareConfigResources.getInstance().patients_parameters[u])
180180
# Not iterating over the image results as the redrawing will be done when the active patient is changed.
181181
if 'Report' in list(results.keys()):

gui/UtilsWidgets/CustomQDialog/SoftwareSettingsDialog.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def __set_processing_segmentation_options_interface(self):
196196
self.processing_segmentation_models_inputs_groupbox.setTitle("Segmentation models inputs")
197197
self.processing_segmentation_models_inputs_groupboxlayout = QVBoxLayout()
198198
self.processing_segmentation_models_inputs_groupbox.setLayout(self.processing_segmentation_models_inputs_groupboxlayout)
199-
self.processing_segmentation_options_base_layout.addWidget(self.processing_segmentation_models_inputs_groupbox)
199+
# self.processing_segmentation_options_base_layout.addWidget(self.processing_segmentation_models_inputs_groupbox)
200200

201201
self.processing_segmentation_models_groupbox = QGroupBox()
202202
self.processing_segmentation_models_groupbox.setTitle("Segmentation models runtime")

utils/logic/PipelineCreationHandler.py

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -444,32 +444,16 @@ def __create_surgical_reporting_pipeline(tumor_type: str) -> dict:
444444

445445
return pip
446446

447-
def __create_custom_pipeline(task, tumor_type, patient_parameters):
447+
def __create_custom_pipeline(task: str, tumor_type: str, patient_parameters: PatientParameters) -> dict:
448448
split_task = task.split('_')
449449
pip = {}
450450
pip_num_int = 0
451451

452452
if split_task[0] == "Classification":
453-
pip_num_int = pip_num_int + 1
454-
pip_num = str(pip_num_int)
455-
pip[pip_num] = {}
456-
pip[pip_num]["task"] = 'Classification'
457-
pip[pip_num]["inputs"] = {}
458-
pip[pip_num]["target"] = ["MRSequence"]
459-
pip[pip_num]["model"] = 'MRI_SequenceClassifier'
460-
pip[pip_num]["description"] = "Classification of the MRI sequence type for all input scans"
461-
download_model(model_name='MRI_SequenceClassifier')
453+
include_radiological_volume_classifier(pip=pip, pip_num_start=pip_num_int)
462454
elif split_task[0] == "Segmentation":
463455
if not UserPreferencesStructure.getInstance().use_manual_sequences:
464-
pip_num_int = pip_num_int + 1
465-
pip_num = str(pip_num_int)
466-
pip[pip_num] = {}
467-
pip[pip_num]["task"] = 'Classification'
468-
pip[pip_num]["inputs"] = {}
469-
pip[pip_num]["target"] = ["MRSequence"]
470-
pip[pip_num]["model"] = 'MRI_SequenceClassifier'
471-
pip[pip_num]["description"] = "Classification of the MRI sequence type for all input scans"
472-
download_model(model_name='MRI_SequenceClassifier')
456+
include_radiological_volume_classifier(pip=pip, pip_num_start=pip_num_int)
473457

474458
base_model_name = "MRI_" if SoftwareConfigResources.getInstance().software_medical_specialty == "neurology" else "CT_"
475459
timestamp_order = int(split_task[2][1:])

0 commit comments

Comments
 (0)