question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

how to use pynetdicom to get Orthanc dicom image?

See original GitHub issue

how to use pynetdicom to get Orthanc dicom image?

hello ! i have build Orthanc PACS server in windows for test "use python load PACS image " by this video https://www.youtube.com/watch?v=bsW4gYO4xrY&feature=youtu.be

in the video , radiant can simple to get dicom image from Orthanc . so i want to do that in python

now i can use “send_c_find” to get some dicom info, but dont have Modality this parameter. and i use “send_c_move” want to get dicom image but always show "Move SCP Result: 0xc000 (Failure) "

question 1 is : how to get more parameter in “send_c_find” ? question 2 is : how to get dicom image by “send_c_move” in windows Orthanc ?

here is my code

def handle_store(event):
    mode_prefixes = {
        'CT Image Storage' : 'CT',
        'Enhanced CT Image Storage' : 'CTE',
        'MR Image Storage' : 'MR',
        'Enhanced MR Image Storage' : 'MRE',
        'Positron Emission Tomography Image Storage' : 'PT',
        'Enhanced PET Image Storage' : 'PTE',
        'RT Image Storage' : 'RI',
        'RT Dose Storage' : 'RD',
        'RT Plan Storage' : 'RP',
        'RT Structure Set Storage' : 'RS',
        'Computed Radiography Image Storage' : 'CR',
        'Ultrasound Image Storage' : 'US',
        'Enhanced Ultrasound Image Storage' : 'USE',
        'X-Ray Angiographic Image Storage' : 'XA',
        'Enhanced XA Image Storage' : 'XAE',
        'Nuclear Medicine Image Storage' : 'NM',
        'Secondary Capture Image Storage' : 'SC'
    }
    ds = event.dataset
    try:
        sop_class = ds.SOPClassUID
        sop_instance = ds.SOPInstanceUID
    except Exception as exc:
        # Unable to decode dataset
        return 0xC210

    try:
        # Get the elements we need
        mode_prefix = mode_prefixes[sop_class.name]
    except KeyError:
        mode_prefix = 'UN'

    filename = '{0!s}.{1!s}'.format(mode_prefix, sop_instance)
    LOGGER.info('Storing DICOM file: {0!s}'.format(filename))

    if os.path.exists(filename):
        LOGGER.warning('DICOM file already exists, overwriting')
    # Presentation context
    cx = event.context
    meta = Dataset()
    meta.MediaStorageSOPClassUID = sop_class
    meta.MediaStorageSOPInstanceUID = sop_instance
    meta.ImplementationClassUID = PYNETDICOM_IMPLEMENTATION_UID
    meta.TransferSyntaxUID = cx.transfer_syntax

    # The following is not mandatory, set for convenience
    meta.ImplementationVersionName = PYNETDICOM_IMPLEMENTATION_VERSION

    ds.file_meta = meta
    ds.is_little_endian = cx.transfer_syntax.is_little_endian
    ds.is_implicit_VR = cx.transfer_syntax.is_implicit_VR

    status_ds = Dataset()
    status_ds.Status = 0x0000

    # Try to save to output-directory
    filename = os.path.join(os.getcwd(), filename)
    print(filename)

    try:
        ds.save_as(filename, write_like_original=False)
        status_ds.Status = 0x0000 # Success
    except IOError:
        LOGGER.error('Could not write file to specified directory:')
        LOGGER.error("    {0!s}".format(os.path.dirname(filename)))
        LOGGER.error('Directory may not exist or you may not have write '
                    'permission')
        # Failed - Out of Resources - IOError
        status_ds.Status = 0xA700
    except:
        LOGGER.error('Could not write file to specified directory:')
        LOGGER.error("    {0!s}".format(os.path.dirname(filename)))
        # Failed - Out of Resources - Miscellaneous error
        status_ds.Status = 0xA701
    return status_ds
def on_c_store(ds, context, info):
    print("ON_C_STORE")
    meta = Dataset()
    meta.MediaStorageSOPClassUID = ds.SOPClassUID
    meta.MediaStorageSOPInstanceUID = ds.SOPInstanceUID
    meta.ImplementationClassUID = PYNETDICOM_IMPLEMENTATION_UID
    meta.ImplementationVersionName = PYNETDICOM_IMPLEMENTATION_VERSION
    meta.TransferSyntaxUID = context.transfer_syntax

    ds.file_meta = meta

    ds.is_little_endian = context.transfer_syntax.is_little_endian
    ds.is_implicit_VR = context.transfer_syntax.is_implicit_VR

    ds.save_as(ds.SOPInstanceUID, write_like_original=False)

    return 0x0000
from pydicom.dataset import Dataset
from pynetdicom import AE
from pynetdicom.sop_class import (
    PatientRootQueryRetrieveInformationModelFind,
    PatientRootQueryRetrieveInformationModelGet,
    ProtocolApprovalInformationModelGet,
    BasicWorklistManagementServiceClass,
    CTImageStorage,
    StudyRootQueryRetrieveInformationModelGet,
    MRImageStorage,
    VerificationSOPClass,
    PatientRootQueryRetrieveInformationModelMove,
    )

from pynetdicom import (
    AE, 
    evt,
    build_role,
    BasicWorklistManagementPresentationContexts,
    PYNETDICOM_IMPLEMENTATION_UID,
    PYNETDICOM_IMPLEMENTATION_VERSION,
    StoragePresentationContexts,
    )
from pydicom.uid import (
    ImplicitVRLittleEndian,
    ExplicitVRLittleEndian,
    ExplicitVRBigEndian)

# Initialise the Application Entity
myAETITE = b'RADIANT'
seAETITE = b'ORTHANC'
seIP = '127.0.0.1'
sePORT = 4242
#sePORT = 11112
#sePORT = 104

ae = AE()
ae.ae_title = myAETITE
print('PatientRootQueryRetrieveInformationModelGet = ', PatientRootQueryRetrieveInformationModelGet)
ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet)
ae.add_requested_context(StudyRootQueryRetrieveInformationModelGet)
ae.add_requested_context(MRImageStorage)
ae.add_supported_context(VerificationSOPClass)
ae.add_requested_context(PatientRootQueryRetrieveInformationModelMove)
role = build_role(CTImageStorage, scp_role=True)
ext_neg = []
ext_neg.append(role)
ae.on_c_store = on_c_store
ae.add_requested_context('1.2.840.10008.5.1.4.1.1.4',
    [ImplicitVRLittleEndian,
    ExplicitVRLittleEndian,
    ExplicitVRBigEndian,])

# Create our Identifier (query) dataset
ds = Dataset()
ds.PatientName = '*'
ds.QueryRetrieveLevel = 'STUDY'
print('TEST 219484 ae.associate ')
assoc = ae.associate(seIP, sePORT, ae_title=seAETITE, ext_neg=ext_neg)
print('TEST 013625 after ae.associate ')
i = 0
is_established = 'N'
hresponses = 'N'
if assoc.is_established:
    print('TEST 944960 assoc.is_established ')
    is_established = 'Y'
    print('TEST 416830 send_c_move ')
    responses = assoc.send_c_move(ds,
        query_model=MRImageStorage,
        move_aet=myAETITE,
        )
    print('TEST 459893 before in responses ')
    i = 0
    for (status, identifier) in responses:
        print('TEST 454379 after in responses')
        hresponses = 'Y'
        if status and identifier:
            i += 1
            print('##############################')
            print('C-FIND query status: 0x{0:04x}'.format(status.Status))
            print('status = ', status)
            print('type(status) = ', type(status))
            print('status.Status = ', status.Status)
            print('type(identifier) = ', type(identifier))
            print('identifier = ',identifier)
            print('status.keys()  = ', status.keys() )
            print('identifier.keys()  = ', identifier.keys() )
            print('status.items()  = ', status.items() )
            for elem in identifier.elements():
                print('elem = ', elem)
            if status.Status in (0xff00, 0xff01):
                print(identifier)
            print('##############################')
        else:
            print('Connection timed out, was aborted or received invalid response')
    print('############# FIND ', i)
    assoc.release()
else:
    print('Association rejected, aborted or never connected')

thanks for everyone~

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:12 (6 by maintainers)

github_iconTop GitHub Comments

3reactions
scaramallioncommented, May 15, 2020

Yes, that sounds correct. Glad to help

0reactions
zoearthmooncommented, May 15, 2020

@scaramallion Thank you very much ~ You are so nice

Read more comments on GitHub >

github_iconTop Results From Across the Web

Re: Connect to ORTHANC with Pynetdicom - Google Groups
I am running on MacOS using ./Orthanc --verbose. I wish to query and retrieve images based on the Patient ID. So far, i...
Read more >
Python plugin for Orthanc
This plugin can be used to write Orthanc plugins using the Python programming language instead of the more complex C/C++ programming languages. Python...
Read more >
How to Import DICOM Images into your Orthanc DICOM Server
After our DICOM images are imported, we go over some of the different Orthanc DICOM features such as anonymization and the DICOMDIR.
Read more >
How to Send DICOM Images with StoreSCU - YouTube
This DICOM Training / DICOM Tutorial video shows you how to send DICOM images from one DICOM device to your Orthanc DICOM server...
Read more >
Magician's Corner: 8: How to Connect an Artificial Intelligence ...
This is a practical example of how to both get images needed by an AI tool for inference, and how to store the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found