-
Notifications
You must be signed in to change notification settings - Fork 189
Closed
Labels
Description
Common DICOM Client code
PatientRootQueryRetrieveInformationModelMove = (
sop_class._QR_CLASSES["PatientRootQueryRetrieveInformationModelMove"]
)
class DicomClient:
def __init__(
self,
*,
local_node: DcmNode,
remote_node: DcmNode
):
self._local_node = local_node
self._remote_node = remote_node
@contextmanager
def _association(
self,
ae: ApplicationEntity,
evt_handlers: Optional[List[EventHandlerType]] = None
) -> Association:
assoc = ae.associate(
addr=self._remote_node.host,
port=self._remote_node.port,
ae_title=self._remote_node.ae_title,
evt_handlers=evt_handlers
)
if not assoc.is_established:
raise FailedAssociationError
try:
yield assoc
finally:
assoc.release()
def _handle_store(self, datasets: List[Dataset]) -> Callable[[Event], int]:
def handle_store(event: Event) -> int:
dataset = event.dataset
dataset.file_meta = event.file_meta
datasets.append(dataset)
return 0x0000
return handle_store
def send_c_move(
self,
*,
query: Dataset,
datasets: List[Dataset]
) -> None:
ae = ApplicationEntity(ae_title=self._remote_node.ae_title)
ae.add_requested_context(
PatientRootQueryRetrieveInformationModelMove,
ImplicitVRLittleEndian
)
ae.supported_contexts = StoragePresentationContexts
evt_handlers = [(events.EVT_C_STORE, self._handle_store(datasets=datasets))]
scp = ae.start_server(
address=(self._local_node.host, self._local_node.port),
block=False,
evt_handlers=evt_handlers
)
with self._association(ae=ae, evt_handlers=evt_handlers) as assoc:
assoc.send_c_move(
query,
self._local_node.ae_title,
PatientRootQueryRetrieveInformationModelMove
)
scp.shutdown()
Simple python script code
def main() -> None:
dicom_client = DicomClient(
local_node=DcmNode(host='localhost', ae_title='TSAMI', port=1111),
remote_node=DcmNode(host='localhost', ae_title='CONQUESTSRV1', port=5678)
)
query = Dataset()
query.QueryRetrieveLevel = "STUDY"
query.StudyID = "433724515"
datasets = []
start_perf_counter = time.perf_counter()
dicom_client.send_c_move(query=query, datasets=datasets)
print(len(datasets), time.perf_counter() - start_perf_counter)
if __name__ == "__main__":
main()
Output: 384 2.6142295409990766
Flask application with gunicorn with gthread worker (in one process and one thread)
app = Flask(__name__)
dicom_client = DicomClient(
local_node=DcmNode(host='localhost', ae_title='MY-AE-TITLE', port=1111),
remote_node=DcmNode(host='localhost', ae_title='CONQUESTSRV1', port=5678)
)
@app.route('/')
def hello():
query = Dataset()
query.QueryRetrieveLevel = "STUDY"
query.StudyID = "433724515"
datasets = []
start_perf_counter = time.perf_counter()
dicom_client.send_c_move(query=query, datasets=datasets)
print(len(datasets), time.perf_counter() - start_perf_counter)
return "ok"
gunicorn --bind "127.0.0.1:8000" --worker-class "gthread" test:app
Output: 384 5.645078083998669
Why is this happening and how to fix it?