Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@

import logging

from pynetdicom import AE, StoragePresentationContexts, evt
import pydicom.uid as dicom_uid
from pynetdicom import AE, evt
from pynetdicom.sop_class import (
DigitalMammographyXRayImageStorageForPresentation, # type: ignore[attr-defined]
DigitalMammographyXRayImageStorageForProcessing, # type: ignore[attr-defined]
ModalityPerformedProcedureStep, # type: ignore[attr-defined]
ModalityWorklistInformationFind, # type: ignore[attr-defined]
)
Expand Down Expand Up @@ -56,8 +59,17 @@ def start(self):
"""Start the PACS server and listen for incoming connections."""
logger.info(f"Starting PACS server: {self.ae_title} on port {self.port}")

transfer_syntaxes = [
dicom_uid.JPEGLosslessSV1, # Hologic preferred
dicom_uid.ExplicitVRLittleEndian,
dicom_uid.ImplicitVRLittleEndian,
dicom_uid.ExplicitVRBigEndian,
dicom_uid.JPEGLSLossless,
dicom_uid.JPEG2000Lossless,
]
self.ae = AE(ae_title=self.ae_title)
self.ae.supported_contexts = StoragePresentationContexts
self.ae.add_supported_context(DigitalMammographyXRayImageStorageForPresentation, transfer_syntaxes)
self.ae.add_supported_context(DigitalMammographyXRayImageStorageForProcessing, transfer_syntaxes)

handlers = [
(evt.EVT_C_ECHO, CEcho().call),
Expand Down
13 changes: 0 additions & 13 deletions src/services/dicom/c_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@

from pydicom import Dataset, dcmwrite
from pynetdicom.events import Event
from pynetdicom.sop_class import (
DigitalMammographyXRayImageStorageForPresentation, # type: ignore
DigitalMammographyXRayImageStorageForProcessing, # type: ignore
)

from services.dicom import FAILURE, SUCCESS
from services.dicom.image_compressor import ImageCompressor
Expand All @@ -18,11 +14,6 @@


class CStore:
VALID_SOP_CLASSES = [
DigitalMammographyXRayImageStorageForPresentation,
DigitalMammographyXRayImageStorageForProcessing,
]

def __init__(
self,
storage: PACSStorage,
Expand All @@ -42,10 +33,6 @@ def call(self, event: Event) -> int:
ds = event.dataset
ds.file_meta = event.file_meta

if ds.file_meta.MediaStorageSOPClassUID not in self.VALID_SOP_CLASSES:
logger.error(f"Invalid SOP Class UID: {ds.file_meta.MediaStorageSOPClassUID}")
return FAILURE

sop_instance_uid = ds.get("SOPInstanceUID", "")
accession_number = ds.get("AccessionNumber", "")
patient_id = ds.get("PatientID")
Expand Down
5 changes: 5 additions & 0 deletions tests/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from pynetdicom import evt
from pynetdicom.sop_class import ( # pyright: ignore[reportAttributeAccessIssue]
DigitalMammographyXRayImageStorageForPresentation,
DigitalMammographyXRayImageStorageForProcessing,
ModalityPerformedProcedureStep,
ModalityWorklistInformationFind,
)
Expand Down Expand Up @@ -51,6 +53,9 @@ def test_start(self, mock_c_store, mock_c_echo, mock_ae, _mock_pacs_storage, _mo
assert subject.ae == mock_ae.return_value

mock_ae.assert_called_once_with(ae_title="SCREENING_PACS")
add_context_calls = [call.args[0] for call in mock_ae.return_value.add_supported_context.call_args_list]
assert DigitalMammographyXRayImageStorageForPresentation in add_context_calls
assert DigitalMammographyXRayImageStorageForProcessing in add_context_calls
mock_ae.return_value.start_server.assert_called_once_with(
("0.0.0.0", 4244),
block=True,
Expand Down
Loading