示例#1
0
    def run_server(self, use_abort):
        called = [False]

        def store_callback(message):
            called[0] = True
            return 0

        association = odil.Association()
        association.set_tcp_timeout(1)
        association.receive_association("v4", 11113)

        store_scp = odil.StoreSCP(association)
        store_scp.set_callback(store_callback)

        message = association.receive_message()
        store_scp(message)

        termination_ok = False

        try:
            association.receive_message()
        except odil.AssociationReleased:
            termination_ok = True

        if called[0] and termination_ok:
            sys.exit(0)
        else:
            sys.exit(1)
示例#2
0
    def run_server(self):
        called = False

        association = odil.Association()
        association.set_tcp_timeout(1)
        association.receive_association("v4", 11113)

        get_scp = odil.GetSCP(association)
        generator = Generator()
        get_scp.set_generator(generator)

        message = association.receive_message()
        get_scp(message)

        termination_ok = False

        try:
            association.receive_message()
        except odil.AssociationReleased:
            termination_ok = True
        except odil.AssociationAborted:
            pass

        if called and termination_ok:
            return 0
        else:
            return 1
示例#3
0
    def run_server(self, use_abort):
        called = [False]

        def echo_callback(message):
            called[0] = True
            return 0

        association = odil.Association()
        association.set_tcp_timeout(1)
        association.receive_association("v4", 11113)

        echo_scp = odil.EchoSCP(association)
        echo_scp.set_callback(echo_callback)

        dispatcher = odil.SCPDispatcher(association)
        dispatcher.set_echo_scp(echo_scp)

        dispatcher.dispatch()

        termination_ok = False

        try:
            association.receive_message()
        except odil.AssociationReleased:
            termination_ok = True

        if called[0] and termination_ok:
            sys.exit(0)
        else:
            sys.exit(1)
示例#4
0
    def run_server(self):
        association = odil.Association()
        association.set_tcp_timeout(1)
        association.receive_association("v4", 11113)

        find_scp = odil.FindSCP(association)
        generator = Generator()
        find_scp.set_generator(generator)

        message = association.receive_message()
        find_scp(message)

        termination_ok = False

        try:
            association.receive_message()
        except odil.AssociationReleased:
            termination_ok = True
        except odil.AssociationAborted:
            pass

        if termination_ok:
            sys.exit(0)
        else:
            sys.exit(1)
示例#5
0
def find(host, port, calling_ae_title, called_ae_title, level, keys,
         decode_uids):
    query = odil.DataSet()
    for key in keys:
        if "=" in key:
            key, value = key.split("=", 1)
            value = value.split("\\")
        else:
            value = None

        tag = getattr(odil.registry, key)

        if value is not None:
            vr = odil.registry.public_dictionary[tag].vr
            if vr in ["DS", "FL", "FD"]:
                value = [float(x) for x in value]
            elif vr in ["IS", "SL", "SS", "UL", "US"]:
                value = [int(x) for x in value]

            query.add(tag, value)
        else:
            query.add(tag)

    sop_class = getattr(
        odil.registry,
        "{}RootQueryRetrieveInformationModelFind".format(level.capitalize()))

    find_pc = odil.AssociationParameters.PresentationContext(
        1, sop_class, [
            odil.registry.ImplicitVRLittleEndian,
            odil.registry.ExplicitVRLittleEndian
        ], odil.AssociationParameters.PresentationContext.Role.SCU)

    association = odil.Association()
    association.set_peer_host(host)
    association.set_peer_port(port)
    association.update_parameters()\
        .set_calling_ae_title(calling_ae_title)\
        .set_called_ae_title(called_ae_title) \
        .set_presentation_contexts([find_pc])
    association.associate()
    logging.info("Association established")

    find = odil.FindSCU(association)
    find.set_affected_sop_class(sop_class)
    data_sets = find.find(query)
    print("{} answer{}".format(len(data_sets),
                               "s" if len(data_sets) > 1 else ""))

    max_length = 0
    for data_set in data_sets:
        max_length = max(max_length, find_max_name_length(data_set))

    for data_set in data_sets:
        print_data_set(data_set, decode_uids, "", max_length,
                       odil.Value.Strings())
        print()

    association.release()
    logging.info("Association released")
示例#6
0
    def run_server(self, use_abort):
        called = False
        def echo_callback(message):
            called = True
            return 0

        association = odil.Association()
        association.set_tcp_timeout(1)
        association.receive_association("v4", 11113)

        echo_scp = odil.EchoSCP(association)
        echo_scp.set_callback(echo_callback)

        message = association.receive_message()
        echo_scp(message)
        
        termination_ok = False

        try:
            association.receive_message()
        except odil.AssociationReleased:
            if not use_abort:
                termination_ok = True
        except odil.AssociationAborted:
            if use_abort:
                termination_ok = True
        
        if called and termination_ok:
            return 0
        else:
            return 1
示例#7
0
    def test_parameters(self):
        parameters = odil.AssociationParameters()
        parameters.set_called_ae_title("foo")

        association = odil.Association()
        association.set_parameters(parameters)
        self.assertEqual(association.get_parameters().get_called_ae_title(),
                         "foo")
示例#8
0
def find_abstract_syntaxes(host, port, calling_ae_title, called_ae_title,
                           level, keys):
    """ Return the abstract syntaxes corresponding to the query, based on 
        SOP Classes in Study.
    """

    query = odil.DataSet()
    for key in keys:
        key, value = key.split("=", 1)
        value = value.split("\\")

        if key in ["QueryRetrieveLevel", "SOPClassesInStudy"]:
            continue

        tag = getattr(odil.registry, key)

        vr = odil.registry.public_dictionary[tag].vr
        if vr in ["DS", "FL", "FD"]:
            value = [float(x) for x in value]
        elif vr in ["IS", "SL", "SS", "UL", "US"]:
            value = [int(x) for x in value]

        query.add(tag, value)
    query.add("QueryRetrieveLevel", ["STUDY"])
    query.add("SOPClassesInStudy")

    find_syntax = getattr(
        odil.registry,
        "{}RootQueryRetrieveInformationModelFind".format(level.capitalize()))

    transfer_syntaxes = [
        odil.registry.ImplicitVRLittleEndian,
        odil.registry.ExplicitVRLittleEndian
    ]

    find_pc = odil.AssociationParameters.PresentationContext(
        1, find_syntax, transfer_syntaxes,
        odil.AssociationParameters.PresentationContext.Role.SCU)

    association = odil.Association()
    association.set_peer_host(host)
    association.set_peer_port(port)
    association.update_parameters()\
        .set_calling_ae_title(calling_ae_title)\
        .set_called_ae_title(called_ae_title) \
        .set_presentation_contexts([find_pc])
    association.associate()
    logging.info("Association established")

    find = odil.FindSCU(association)
    find.set_affected_sop_class(find_syntax)
    data_sets = find.find(query)
    sop_classes = set()
    for data_set in data_sets:
        if "SOPClassesInStudy" in data_set:
            sop_classes.update(data_set.as_string("SOPClassesInStudy"))
    return sop_classes
示例#9
0
 def setUp(self, contexts):
     self.association = odil.Association()
     self.association.set_peer_host(os.environ["ODIL_PEER_HOST_NAME"])
     self.association.set_peer_port(int(os.environ["ODIL_PEER_PORT"]))
     self.association.update_parameters()\
         .set_calling_ae_title(os.environ["ODIL_OWN_AET"])\
         .set_called_ae_title(os.environ["ODIL_PEER_AET"]) \
         .set_presentation_contexts(contexts)
     self.association.associate()
示例#10
0
def store(host, port, calling_ae_title, called_ae_title, filenames):
    transfer_syntaxes = [
        odil.registry.ExplicitVRLittleEndian,
        odil.registry.ImplicitVRLittleEndian,
    ]

    # Find all SOP classes to negotiate at association time. We don't need to
    # read the whole data set for this
    sop_classes = set()
    for filename in filenames:
        with odil.open(filename) as stream:
            _, data_set = odil.Reader.read_file(
                stream,
                halt_condition=lambda tag: tag > odil.registry.SOPClassUID)
        sop_classes.update(data_set.as_string("SOPClassUID"))

    presentation_contexts = [
        odil.AssociationParameters.PresentationContext(
            2 * i + 1, sop_class, transfer_syntaxes,
            odil.AssociationParameters.PresentationContext.Role.SCU)
        for i, sop_class in enumerate(sop_classes)
    ]

    # Create the association and the Store SCU
    association = odil.Association()
    association.set_peer_host(host)
    association.set_peer_port(port)
    association.update_parameters()\
        .set_calling_ae_title(calling_ae_title)\
        .set_called_ae_title(called_ae_title)\
        .set_presentation_contexts(presentation_contexts)
    association.associate()

    negotiated_parameters = association.get_negotiated_parameters()
    negotiated_pc = negotiated_parameters.get_presentation_contexts()

    store = odil.StoreSCU(association)

    for filename in filenames:
        with odil.open(filename) as stream:
            _, data_set = odil.Reader.read_file(stream)

        try:
            store.set_affected_sop_class(data_set)
            store.store(data_set)
        except Exception as e:
            print("Could not store {}: {}".format(filename, e))

    association.release()
示例#11
0
    def get_association(self, request):
        move_association = odil.Association()
        move_association.set_peer_host(self._association.get_peer_host())
        move_association.set_peer_port(11114)
        
        presentation_contexts = [
            odil.AssociationParameters.PresentationContext(
                1, odil.registry.RawDataStorage,
                [odil.registry.ImplicitVRLittleEndian], 
                odil.AssociationParameters.PresentationContext.Role.SCU)]
        
        move_association.update_parameters()\
            .set_calling_ae_title(
                self._association.get_negotiated_parameters().get_called_ae_title())\
            .set_called_ae_title(request.get_move_destination())\
            .set_presentation_contexts(presentation_contexts)

        return move_association
示例#12
0
    def get_association(self, request):
        move_association = odil.Association()
        move_association.set_peer_host(self._association.get_peer_host())
        move_association.set_peer_port(11114)

        presentation_contexts = []
        for entry in odil.registry.uids_dictionary:
            if entry.data().name[-7:] == "Storage":
                presentation_context = odil.AssociationParameters.PresentationContext(
                    1 + 2 * len(presentation_contexts), entry.key(),
                    [odil.registry.ImplicitVRLittleEndian], True, False)
                presentation_contexts.append(presentation_context)

        move_association.update_parameters()\
            .set_calling_ae_title(
                self._association.get_negotiated_parameters().get_called_ae_title())\
            .set_called_ae_title(request.get_move_destination())\
            .set_presentation_contexts(presentation_contexts)

        return move_association
示例#13
0
def echo(host, port, calling_ae_title, called_ae_title):
    association = odil.Association()
    association.set_peer_host(host)
    association.set_peer_port(port)
    association.update_parameters()\
        .set_calling_ae_title(calling_ae_title)\
        .set_called_ae_title(called_ae_title) \
        .set_presentation_contexts([
            odil.AssociationParameters.PresentationContext(
                3, odil.registry.VerificationSOPClass,
                [ odil.registry.ImplicitVRLittleEndian ], True, False
            )
        ])
    association.associate()
    logging.info("Association established")

    echo = odil.EchoSCU(association)
    echo.echo()
    logging.info("C-ECHO successful")

    association.release()
    logging.info("Association released")
示例#14
0
 def test_peer_port(self):
     association = odil.Association()
     association.set_peer_port(1234)
     self.assertEqual(association.get_peer_port(), 1234)
示例#15
0
文件: find.py 项目: nagyistge/odil
import odil

association = odil.Association()
association.set_peer_host("184.73.255.26")
association.set_peer_port(11112)

presentation_contexts = [
    odil.AssociationParameters.PresentationContext(
        1, odil.registry.StudyRootQueryRetrieveInformationModelFIND,
        [odil.registry.ExplicitVRLittleEndian], True, False),
    odil.AssociationParameters.PresentationContext(
        3, odil.registry.VerificationSOPClass,
        [odil.registry.ExplicitVRLittleEndian], True, False)
]

association.update_parameters()\
    .set_calling_ae_title("myself")\
    .set_called_ae_title("AWSPIXELMEDPUB") \
    .set_presentation_contexts(presentation_contexts)
association.associate()

query = odil.DataSet()
query.add(odil.registry.PatientName, odil.Value.Strings(["*"]))
query.add(odil.registry.QueryRetrieveLevel, odil.Value.Strings(["STUDY"]))
query.add(odil.registry.StudyDescription)
query.add(odil.registry.StudyDate)

find = odil.FindSCU(association)
find.set_affected_sop_class(
    odil.registry.StudyRootQueryRetrieveInformationModelFIND)
示例#16
0
def get(host, port, calling_ae_title, called_ae_title, level, keys, directory,
        iso_9660, layout, dicomdir, patient_key, study_key, series_key,
        image_key):

    if dicomdir and not iso_9660:
        raise Exception("Cannot create a DICOMDIR without ISO-9660 filenames")

    query = odil.DataSet()
    for key in keys:
        key, value = key.split("=", 1)
        value = value.split("\\")

        tag = getattr(odil.registry, key)

        vr = odil.registry.public_dictionary[tag].vr
        if vr in ["DS", "FL", "FD"]:
            value = [float(x) for x in value]
        elif vr in ["IS", "SL", "SS", "UL", "US"]:
            value = [int(x) for x in value]

        query.add(tag, value)

    get_syntax = getattr(
        odil.registry,
        "{}RootQueryRetrieveInformationModelGet".format(level.capitalize()))

    transfer_syntaxes = [
        odil.registry.ImplicitVRLittleEndian,
        odil.registry.ExplicitVRLittleEndian
    ]

    get_pc = odil.AssociationParameters.PresentationContext(
        1, get_syntax, transfer_syntaxes,
        odil.AssociationParameters.PresentationContext.Role.SCU)

    abstract_syntaxes = find_abstract_syntaxes(host, port, calling_ae_title,
                                               called_ae_title, level, keys)
    if not abstract_syntaxes:
        # Negotiate ALL storage syntaxes. Is there a better way to do this?
        abstract_syntaxes = [
            entry.key() for entry in odil.registry.uids_dictionary
            if entry.data().name.endswith("Storage")
        ]
    if len(abstract_syntaxes) > 126:
        raise Exception("Too many storage syntaxes")
    storage_pcs = [
        odil.AssociationParameters.PresentationContext(
            2 * (i + 1) + 1, uid, transfer_syntaxes,
            odil.AssociationParameters.PresentationContext.Role.SCP)
        for i, uid in enumerate(abstract_syntaxes)
    ]

    association = odil.Association()
    association.set_peer_host(host)
    association.set_peer_port(port)
    association.update_parameters()\
        .set_calling_ae_title(calling_ae_title)\
        .set_called_ae_title(called_ae_title) \
        .set_presentation_contexts([get_pc]+storage_pcs)
    association.associate()
    logging.info("Association established")

    get = odil.GetSCU(association)
    get.set_affected_sop_class(get_syntax)

    class Callback(object):
        def __init__(self, directory):
            self.directory = directory
            self.completed = 0
            self.remaining = 0
            self.failed = 0
            self.warning = 0
            self.stored = {}
            self.files = []
            self._study_ids = {}
            self._series_ids = {}

        def store(self, data_set):
            specific_character_set = odil.Value.Strings()
            if "SpecificCharacterSet" in data_set:
                specific_character_set = data_set.as_string(
                    "SpecificCharacterSet")
            as_unicode = lambda x: odil.as_unicode(x, specific_character_set)

            if layout == "flat":
                directory = ""
            elif layout == "tree":
                # Patient directory: <PatientName> or <PatientID>.
                patient_directory = None
                if "PatientName" in data_set and data_set.as_string(
                        "PatientName"):
                    patient_directory = data_set.as_string("PatientName")[0]
                else:
                    patient_directory = data_set.as_string("PatientID")[0]
                patient_directory = as_unicode(patient_directory)

                # Study directory: <StudyID>_<StudyDescription>, both parts are
                # optional. If both tags are missing or empty, default to a
                # numeric index based on StudyInstanceUID.
                study_directory = []
                if "StudyID" in data_set and data_set.as_string("StudyID"):
                    study_directory.append(data_set.as_string("StudyID")[0])
                if ("StudyDescription" in data_set
                        and data_set.as_string("StudyDescription")):
                    study_directory.append(
                        data_set.as_string("StudyDescription")[0])

                if not study_directory:
                    study_instance_uid = data_set.as_string(
                        "StudyInstanceUID")[0]
                    study_directory.append(
                        self._study_ids.setdefault(study_instance_uid,
                                                   1 + len(self._study_ids)))

                study_directory = "_".join(
                    as_unicode(x) for x in study_directory)

                # Study directory: <SeriesNumber>_<SeriesDescription>, both
                # parts are optional. If both tags are missing or empty, default
                # to a numeric index based on SeriesInstanceUID.
                series_directory = []
                if "SeriesNumber" in data_set and data_set.as_int(
                        "SeriesNumber"):
                    series_directory.append(
                        str(data_set.as_int("SeriesNumber")[0]))
                if ("SeriesDescription" in data_set
                        and data_set.as_string("SeriesDescription")):
                    series_directory.append(
                        data_set.as_string("SeriesDescription")[0])

                if not series_directory:
                    series_instance_uid = data_set.as_string(
                        "series_instance_uid")[0]
                    series_directory.append(
                        self._series_ids.setdefault(series_instance_uid,
                                                    1 + len(self._series_ids)))

                series_directory = "_".join(
                    as_unicode(x) for x in series_directory)

                if iso_9660:
                    patient_directory = to_iso_9660(patient_directory)
                    study_directory = to_iso_9660(study_directory)
                    series_directory = to_iso_9660(series_directory)
                directory = os.path.join(patient_directory, study_directory,
                                         series_directory)
                if not os.path.isdir(os.path.join(self.directory, directory)):
                    os.makedirs(os.path.join(self.directory, directory))
            else:
                raise NotImplementedError()

            self.stored.setdefault(directory, 0)

            if iso_9660:
                filename = "IM{:06d}".format(1 + self.stored[directory])
            else:
                filename = as_unicode(data_set.as_string("SOPInstanceUID")[0])

            with odil.open(os.path.join(self.directory, directory, filename),
                           "wb") as fd:
                odil.Writer.write_file(data_set, fd)

            self.stored[directory] += 1
            self.files.append(os.path.join(directory, filename))

        def get(self, message):
            for type_ in ["completed", "remaining", "failed", "warning"]:
                base = "number_of_{}_sub_operations".format(type_)
                if getattr(message, "has_{}".format(base))():
                    setattr(self, type_,
                            getattr(message, "get_{}".format(base))())
            logging.info(
                "Remaining: {}, completed: {}, failed: {}, warning: {}".format(
                    self.remaining, self.completed, self.failed, self.warning))

    if not os.path.isdir(directory):
        os.makedirs(directory)
    if len(os.listdir(directory)):
        logging.warning("{} is not empty".format(directory))

    callback = Callback(directory)
    get.get(query, callback.store, callback.get)
    print("Completed: {}, remaining: {}, failed: {}, warning: {}".format(
        callback.completed, callback.remaining, callback.failed,
        callback.warning))

    association.release()
    logging.info("Association released")

    if dicomdir:
        logging.info("Creating DICOMDIR")
        create_dicomdir([os.path.join(directory, x) for x in callback.files],
                        directory, patient_key, study_key, series_key,
                        image_key)
示例#17
0
 def test_update_parameters(self):
     association = odil.Association()
     association.update_parameters().set_called_ae_title("foo")
     self.assertEqual(association.get_parameters().get_called_ae_title(),
                      "foo")
示例#18
0
 def test_next_message_id(self):
     association = odil.Association()
     id1 = association.next_message_id()
     id2 = association.next_message_id()
     self.assertNotEqual(id1, id2)
示例#19
0
 def test_default_constructor(self):
     association = odil.Association()
     self.assertFalse(association.is_associated())
示例#20
0
 def test_peer_host(self):
     association = odil.Association()
     association.set_peer_host("pacs.example.com")
     self.assertEqual(association.get_peer_host(), "pacs.example.com")