def test_keyword_exception(self): """Test exception is raised by bad keyword.""" Args = namedtuple("args", ["keyword", "file"]) args = Args(["BadPatientName=*"], None) msg = r"Unable to parse element path component" with pytest.raises(ValueError, match=msg): create_dataset(args)
def test_file_read_exception(self): """Test exception is raised by bad file read.""" Args = namedtuple("args", ["keyword", "file"]) args = Args([], "no_such_file") # General exception msg = r"No such file or directory" with pytest.raises(Exception, match=msg): create_dataset(args)
def test_file_read_exception(self): """Test exception is raised by bad file read.""" Args = namedtuple('args', ['keyword', 'file']) args = Args([], 'no_such_file') # General exception msg = r"No such file or directory" with pytest.raises(Exception, match=msg): create_dataset(args)
def test_element_new(self): """Test creating an element using keywords.""" Args = namedtuple("args", ["keyword", "file"]) args = Args(["PatientName=*"], None) ds = create_dataset(args) ref = Dataset() ref.PatientName = "*" assert ds == ref
def test_element_new(self): """Test creating an element using keywords.""" Args = namedtuple('args', ['keyword', 'file']) args = Args(['PatientName=*'], None) ds = create_dataset(args) ref = Dataset() ref.PatientName = '*' assert ds == ref
def test_sequence_new(self): """Test creating a sequence using keywords.""" Args = namedtuple("args", ["keyword", "file"]) args = Args(["BeamSequence[0].PatientName=*"], None) ds = create_dataset(args) ref = Dataset() ref.BeamSequence = [Dataset()] ref.BeamSequence[0].PatientName = "*" assert ds == ref
def test_sequence_new(self): """Test creating a sequence using keywords.""" Args = namedtuple('args', ['keyword', 'file']) args = Args(['BeamSequence[0].PatientName=*'], None) ds = create_dataset(args) ref = Dataset() ref.BeamSequence = [Dataset()] ref.BeamSequence[0].PatientName = '*' assert ds == ref
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print(f"movescu.py v{__version__}") sys.exit() APP_LOGGER = setup_logging(args, "movescu") APP_LOGGER.debug(f"movescu.py v{__version__}") APP_LOGGER.debug("") # Create query (identifier) dataset try: # If you're looking at this to see how QR Move works then `identifer` # is a pydicom Dataset instance with your query keys, e.g.: # identifier = Dataset() # identifier.QueryRetrieveLevel = 'PATIENT' # identifier.PatientName = '*' identifier = create_dataset(args, APP_LOGGER) except Exception as exc: APP_LOGGER.exception(exc) sys.exit(1) # Create application entity ae = AE() # Start the Store SCP (optional) scp = None if args.store: transfer_syntax = ALL_TRANSFER_SYNTAXES[:] store_handlers = [(evt.EVT_C_STORE, handle_store, [args, APP_LOGGER])] ae.ae_title = args.store_aet for cx in AllStoragePresentationContexts: ae.add_supported_context(cx.abstract_syntax, transfer_syntax) scp = ae.start_server(("localhost", args.store_port), block=False, evt_handlers=store_handlers) ae.ae_title = args.calling_aet ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.network_timeout = args.network_timeout ae.requested_contexts = QueryRetrievePresentationContexts ae.supported_contexts = [] # Query/Retrieve Information Models if args.study: query_model = StudyRootQueryRetrieveInformationModelMove elif args.psonly: query_model = PatientStudyOnlyQueryRetrieveInformationModelMove else: query_model = PatientRootQueryRetrieveInformationModelMove # Extended Negotiation ext_neg = [] ext_opts = [args.relational_retrieval, args.enhanced_conversion] if any(ext_opts): app_info = b"" for option in ext_opts: app_info += b"\x01" if option else b"\x00" item = SOPClassExtendedNegotiation() item.sop_class_uid = query_model item.service_class_application_information = app_info ext_neg = [item] # Request association with remote AE assoc = ae.associate( args.addr, args.port, ae_title=args.called_aet, max_pdu=args.max_pdu, ext_neg=ext_neg, ) if assoc.is_established: # Send query move_aet = args.move_aet or args.calling_aet responses = assoc.send_c_move(identifier, move_aet, query_model) for (status, rsp_identifier) in responses: # If `status.Status` is one of the 'Pending' statuses then # `rsp_identifier` is the C-MOVE response's Identifier dataset if status and status.Status in [0xFF00, 0xFF01]: # `rsp_identifier` is a pydicom Dataset containing a query # response. You may want to do something interesting here... pass assoc.release() _EXIT_VALUE = 0 else: _EXIT_VALUE = 1 # Shutdown the Storage SCP (if used) if scp: scp.shutdown() sys.exit(_EXIT_VALUE)
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print(f"getscu.py v{__version__}") sys.exit() APP_LOGGER = setup_logging(args, "getscu") APP_LOGGER.debug(f"getscu.py v{__version__}") APP_LOGGER.debug("") # Create query (identifier) dataset try: # If you're looking at this to see how QR Get works then `identifer` # is a pydicom Dataset instance with your query keys, e.g.: # identifier = Dataset() # identifier.QueryRetrieveLevel = 'PATIENT' # identifier.PatientName = '*' identifier = create_dataset(args, APP_LOGGER) except Exception as exc: APP_LOGGER.exception(exc) sys.exit(1) # Exclude these SOP Classes _exclusion = [ EncapsulatedSTLStorage, EncapsulatedOBJStorage, EncapsulatedMTLStorage, ] store_contexts = [ cx for cx in StoragePresentationContexts if cx.abstract_syntax not in _exclusion ] # Create application entity # Binding to port 0 lets the OS pick an available port ae = AE(ae_title=args.calling_aet) ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.network_timeout = args.network_timeout # Extended Negotiation - SCP/SCU Role Selection ext_neg = [] ae.add_requested_context(PatientRootQueryRetrieveInformationModelGet) ae.add_requested_context(StudyRootQueryRetrieveInformationModelGet) ae.add_requested_context(PatientStudyOnlyQueryRetrieveInformationModelGet) for cx in store_contexts: ae.add_requested_context(cx.abstract_syntax) # Add SCP/SCU Role Selection Negotiation to the extended negotiation # We want to act as a Storage SCP ext_neg.append(build_role(cx.abstract_syntax, scp_role=True)) if args.study: query_model = StudyRootQueryRetrieveInformationModelGet elif args.psonly: query_model = PatientStudyOnlyQueryRetrieveInformationModelGet else: query_model = PatientRootQueryRetrieveInformationModelGet # Extended Negotiation - SOP Class Extended ext_opts = [args.relational_retrieval, args.enhanced_conversion] if any(ext_opts): app_info = b"" for option in ext_opts: app_info += b"\x01" if option else b"\x00" item = SOPClassExtendedNegotiation() item.sop_class_uid = query_model item.service_class_application_information = app_info ext_neg.append(item) # Request association with remote assoc = ae.associate( args.addr, args.port, ae_title=args.called_aet, ext_neg=ext_neg, evt_handlers=[(evt.EVT_C_STORE, handle_store, [args, APP_LOGGER])], max_pdu=args.max_pdu, ) if assoc.is_established: # Send query responses = assoc.send_c_get(identifier, query_model) for (status, rsp_identifier) in responses: # If `status.Status` is one of the 'Pending' statuses then # `rsp_identifier` is the C-GET response's Identifier dataset if status and status.Status in [0xFF00, 0xFF01]: # `rsp_identifier` is a pydicom Dataset containing a query # response. You may want to do something interesting here... pass assoc.release() else: sys.exit(1)
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print(f"findscu.py v{__version__}") sys.exit() APP_LOGGER = setup_logging(args, "findscu") APP_LOGGER.debug(f"findscu.py v{__version__}") APP_LOGGER.debug("") # Create query (identifier) dataset try: # If you're looking at this to see how QR Find works then `identifer` # is a pydicom Dataset instance with your query keys, e.g.: # identifier = Dataset() # identifier.QueryRetrieveLevel = 'PATIENT' # identifier.PatientName = '' identifier = create_dataset(args, APP_LOGGER) except Exception as exc: APP_LOGGER.exception(exc) sys.exit(1) # Create application entity # Binding to port 0 lets the OS pick an available port ae = AE(ae_title=args.calling_aet) # Set timeouts ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.network_timeout = args.network_timeout # Set the Presentation Contexts we are requesting the Find SCP support ae.requested_contexts = (QueryRetrievePresentationContexts + BasicWorklistManagementPresentationContexts) # Query/Retrieve Information Models if args.worklist: query_model = ModalityWorklistInformationFind elif args.study: query_model = StudyRootQueryRetrieveInformationModelFind elif args.psonly: query_model = PatientStudyOnlyQueryRetrieveInformationModelFind else: query_model = PatientRootQueryRetrieveInformationModelFind # Extended Negotiation ext_neg = [] ext_opts = [ args.relational_query, args.dt_matching, args.fuzzy_names, args.timezone_adj, args.enhanced_conversion, ] if not args.worklist and any(ext_opts): app_info = b"" for option in ext_opts: app_info += b"\x01" if option else b"\x00" item = SOPClassExtendedNegotiation() item.sop_class_uid = query_model item.service_class_application_information = app_info ext_neg = [item] elif args.worklist and any([args.fuzzy_names, args.timezone_adj]): app_info = b"\x01\x01" for option in [args.fuzzy_names, args.timezone_adj]: app_info += b"\x01" if option else b"\x00" item = SOPClassExtendedNegotiation() item.sop_class_uid = query_model item.service_class_application_information = app_info ext_neg = [item] # Request association with (QR/BWM) Find SCP assoc = ae.associate( args.addr, args.port, ae_title=args.called_aet, max_pdu=args.max_pdu, ext_neg=ext_neg, ) if assoc.is_established: # Send C-FIND request, `responses` is a generator responses = assoc.send_c_find(identifier, query_model) # Used to generate filenames if args.write used fname = generate_filename() for (status, rsp_identifier) in responses: # If `status.Status` is one of the 'Pending' statuses then # `rsp_identifier` is the C-FIND response's Identifier dataset if status and status.Status in [0xFF00, 0xFF01]: if args.write: rsp_identifier.file_meta = get_file_meta( assoc, query_model) rsp_identifier.save_as(next(fname), write_like_original=False) # Release the association assoc.release() else: sys.exit(1)
if args.version: print('findscu.py v{}'.format(__version__)) sys.exit() APP_LOGGER = setup_logging(args, 'findscu') APP_LOGGER.debug('findscu.py v{0!s}'.format(__version__)) APP_LOGGER.debug('') # Create query (identifier) dataset try: # If you're looking at this to see how QR Find works then `identifer` # is a pydicom Dataset instance with your query keys, e.g.: # identifier = Dataset() # identifier.QueryRetrieveLevel = 'PATIENT' # identifier.PatientName = '' identifier = create_dataset(args, APP_LOGGER) except Exception as exc: APP_LOGGER.exception(exc) raise exc sys.exit(1) # Create application entity # Binding to port 0 lets the OS pick an available port ae = AE(ae_title=args.calling_aet) # Set timeouts ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.network_timeout = args.network_timeout # Set the Presentation Contexts we are requesting the Find SCP support
def main(args=None): """Run the application.""" if args is not None: sys.argv = args args = _setup_argparser() if args.version: print('findscu.py v{}'.format(__version__)) sys.exit() APP_LOGGER = setup_logging(args, 'findscu') APP_LOGGER.debug('findscu.py v{0!s}'.format(__version__)) APP_LOGGER.debug('') # Create query (identifier) dataset try: # If you're looking at this to see how QR Find works then `identifer` # is a pydicom Dataset instance with your query keys, e.g.: # identifier = Dataset() # identifier.QueryRetrieveLevel = 'PATIENT' # identifier.PatientName = '' identifier = create_dataset(args, APP_LOGGER) except Exception as exc: APP_LOGGER.exception(exc) raise exc sys.exit(1) # Create application entity # Binding to port 0 lets the OS pick an available port ae = AE(ae_title=args.calling_aet) # Set timeouts ae.acse_timeout = args.acse_timeout ae.dimse_timeout = args.dimse_timeout ae.network_timeout = args.network_timeout # Set the Presentation Contexts we are requesting the Find SCP support ae.requested_contexts = (QueryRetrievePresentationContexts + BasicWorklistManagementPresentationContexts) # Query/Retrieve Information Models if args.worklist: query_model = ModalityWorklistInformationFind elif args.study: query_model = StudyRootQueryRetrieveInformationModelFind elif args.psonly: query_model = PatientStudyOnlyQueryRetrieveInformationModelFind else: query_model = PatientRootQueryRetrieveInformationModelFind # Request association with (QR/BWM) Find SCP assoc = ae.associate(args.addr, args.port, ae_title=args.called_aet, max_pdu=args.max_pdu) if assoc.is_established: # Send C-FIND request, `responses` is a generator responses = assoc.send_c_find(identifier, query_model) # Used to generate filenames if args.write used fname = generate_filename() for (status, rsp_identifier) in responses: # If `status.Status` is one of the 'Pending' statuses then # `rsp_identifier` is the C-FIND response's Identifier dataset if status and status.Status in [0xFF00, 0xFF01]: if args.write: rsp_identifier.file_meta = get_file_meta( assoc, query_model) rsp_identifier.save_as(next(fname), write_like_original=False) # Release the association assoc.release() else: sys.exit(1)