Skip to content

Commit 058ddfc

Browse files
jose-rfjpre-commit-ci[bot]SachidanandAlle
authored
Add feature "include dicom files" (#1664)
* Add tag model to the dict label_info in the function onSaveLabel Signed-off-by: Jose Raniery <[email protected]> * Add checkbox includeDicomFilesCheckBox in settings Signed-off-by: Jose Raniery <[email protected]> * Add dicom files in the tmpdir Signed-off-by: Jose Raniery <[email protected]> * Add call of function onUploadImage in the function onClickSegmentation to include dicom files, if marked in settings, prior segmentation Signed-off-by: Jose Raniery <[email protected]> * Rename loop variable in function get_dicom_files according to flake8 F402 error Signed-off-by: Jose Raniery <[email protected]> * Refactor transforms after PR check Signed-off-by: Jose Raniery <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * fix dicom header with the original study and series uids Signed-off-by: Jose Raniery <[email protected]> * update dicom transfer method by sending only the first slice due to overhead Signed-off-by: Jose Raniery <[email protected]> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci Signed-off-by: Jose Raniery <[email protected]> --------- Signed-off-by: Jose Raniery <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: SACHIDANAND ALLE <[email protected]>
1 parent a786e6b commit 058ddfc

File tree

1 file changed

+76
-2
lines changed

1 file changed

+76
-2
lines changed

plugins/slicer/MONAILabel/MONAILabel.py

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from urllib.parse import quote_plus
2121

2222
import ctk
23+
import DICOMScalarVolumePlugin
2324
import qt
2425
import SampleData
2526
import SimpleITK as sitk
@@ -28,6 +29,7 @@
2829
import vtk
2930
import vtkSegmentationCore
3031
from MONAILabelLib import GenericAnatomyColors, MONAILabelClient
32+
from pydicom import dcmread
3133
from slicer.i18n import tr as _
3234
from slicer.i18n import translate
3335
from slicer.ScriptedLoadableModule import *
@@ -190,6 +192,19 @@ def __init__(self, parent):
190192
str(qt.SIGNAL("valueAsIntChanged(int)")),
191193
)
192194

195+
includeDicomFilesCheckBox = qt.QCheckBox()
196+
includeDicomFilesCheckBox.checked = False
197+
includeDicomFilesCheckBox.toolTip = _(
198+
"Enable this option to include dicom files in server-client data exchange"
199+
)
200+
groupLayout.addRow(_("Include DICOM files:"), includeDicomFilesCheckBox)
201+
parent.registerProperty(
202+
"MONAILabel/includeDicomFiles",
203+
ctk.ctkBooleanMapper(includeDicomFilesCheckBox, "checked", str(qt.SIGNAL("toggled(bool)"))),
204+
"valueAsInt",
205+
str(qt.SIGNAL("valueAsIntChanged(int)")),
206+
)
207+
193208
vBoxLayout.addWidget(groupBox)
194209
vBoxLayout.addStretch(1)
195210

@@ -1392,6 +1407,14 @@ def getPermissionForImageDataUpload(self):
13921407
dontShowAgainSettingsKey="MONAILabel/showImageDataSendWarning",
13931408
)
13941409

1410+
def get_dicom_files(self):
1411+
dicom_files = []
1412+
for path, subdir, files in os.walk(self.tmpdir):
1413+
for file in files:
1414+
if file[-3:] == "dcm":
1415+
dicom_files.append(os.path.join(path, file))
1416+
return dicom_files
1417+
13951418
def onUploadImage(self, init_sample=True, session=False):
13961419
volumeNode = slicer.mrmlScene.GetFirstNodeByClass("vtkMRMLScalarVolumeNode")
13971420
image_id = volumeNode.GetName()
@@ -1407,12 +1430,55 @@ def onUploadImage(self, init_sample=True, session=False):
14071430
start = time.time()
14081431
slicer.util.saveNode(volumeNode, in_file)
14091432
logging.info(f"Saved Input Node into {in_file} in {time.time() - start:3.1f}s")
1410-
self.reportProgress(30)
1433+
last_report_progress = 30
1434+
self.reportProgress(last_report_progress)
1435+
1436+
# if includeDicomFilesCheckBox is marked, save original dicom files on the server
1437+
if slicer.util.settingsValue("MONAILabel/includeDicomFiles", False, converter=slicer.util.toBool):
1438+
start = time.time()
1439+
shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(slicer.mrmlScene)
1440+
volumeShItemID = shNode.GetItemByDataNode(volumeNode)
1441+
1442+
seriesInstanceUID = shNode.GetItemUID(volumeShItemID, "DICOM")
1443+
instUids = slicer.dicomDatabase.instancesForSeries(seriesInstanceUID)
1444+
studyInstanceUID = slicer.dicomDatabase.instanceValue(instUids[0], "0020,000D")
1445+
1446+
exporter = DICOMScalarVolumePlugin.DICOMScalarVolumePluginClass()
1447+
exportables = exporter.examineForExport(volumeShItemID)
1448+
for exp in exportables:
1449+
exp.directory = self.tmpdir
1450+
exporter.export(exportables)
1451+
logging.info(f"Saved dicom files in {time.time() - start:3.1f}s")
1452+
last_report_progress = 50
1453+
self.reportProgress(last_report_progress)
14111454

14121455
if session:
14131456
self.current_sample["session_id"] = self.logic.create_session(in_file)["session_id"]
14141457
else:
14151458
self.logic.upload_image(in_file, image_id)
1459+
1460+
# if includeDicomFilesCheckBox is marked, save original dicom files on the client
1461+
if slicer.util.settingsValue("MONAILabel/includeDicomFiles", False, converter=slicer.util.toBool):
1462+
dcm_filenames = self.get_dicom_files()
1463+
1464+
# send to server only the first slice due to transfer overhead
1465+
dcm_filenames.sort()
1466+
dcm_filenames = dcm_filenames[:1]
1467+
1468+
report_progress_increment = round(last_report_progress / len(dcm_filenames), 1)
1469+
for dcm_fullpath in dcm_filenames:
1470+
# set original study and series UIDs
1471+
dcm = dcmread(dcm_fullpath)
1472+
dcm.StudyInstanceUID = studyInstanceUID
1473+
dcm.SeriesInstanceUID = seriesInstanceUID
1474+
dcm.save_as(dcm_fullpath)
1475+
1476+
dcm_filename = dcm_fullpath.split("/")[-1]
1477+
dcm_filename = ".".join(dcm_filename.split(".")[:-1])
1478+
self.logic.upload_image(dcm_fullpath, dcm_filename)
1479+
last_report_progress += report_progress_increment
1480+
self.reportProgress(last_report_progress)
1481+
14161482
self.current_sample["session"] = False
14171483
self.reportProgress(100)
14181484

@@ -1509,7 +1575,11 @@ def onSaveLabel(self):
15091575
self.reportProgress(30)
15101576

15111577
self.updateServerSettings()
1512-
result = self.logic.save_label(self.current_sample["id"], label_in, {"label_info": label_info})
1578+
result = self.logic.save_label(
1579+
self.current_sample["id"],
1580+
label_in,
1581+
{"label_info": label_info, "model": model},
1582+
)
15131583
self.fetchInfo()
15141584

15151585
if slicer.util.settingsValue("MONAILabel/autoUpdateModelV2", False, converter=slicer.util.toBool):
@@ -1555,6 +1625,10 @@ def onClickSegmentation(self):
15551625
if not self.current_sample:
15561626
return
15571627

1628+
if self.current_sample.get("session"):
1629+
if not self.onUploadImage(init_sample=False):
1630+
return
1631+
15581632
start = time.time()
15591633
result_file = None
15601634
try:

0 commit comments

Comments
 (0)