Skip to content

Commit

Permalink
Use a generator to get bytes of pydicom.Datasets (#78)
Browse files Browse the repository at this point in the history
in `store_instances` of `DICOMwebClient`.

The `store_instances` method accepts a set of DICOM frames, dumps
them to bytes, and, finally, encodes them into a multipart/related
request.

The above process results in storing the original DICOM frames in
memory 3 times:

1. as the original `pydicom.Dataset` instances passed
   into `store_instances`
2. as bytes encoded in `store_instances`
3. as the concatenation of the above bytes created in
   `_encode_multipart_message`

Using a generator in `store_instances` reduces memory footprint by
1/3, since the original `pydicom.Dataset`s are dumped into bytes
one by one while the multipart request body is being created by
`_encode_multipart_message`.
  • Loading branch information
pchristos authored Feb 26, 2023
1 parent 3f91d8d commit e9c271a
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions src/dicomweb_client/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -2638,17 +2638,19 @@ def store_instances(
Information about status of stored instances
"""
def _iter_encoded_datasets(datasets):
for ds in datasets:
with BytesIO() as b:
pydicom.dcmwrite(b, ds)
encoded_ds = b.getvalue()
yield encoded_ds

message = 'store instances'
if study_instance_uid is not None:
message += f' of study "{study_instance_uid}"'
logger.info(message)
url = self._get_studies_url(_Transaction.STORE, study_instance_uid)
encoded_datasets = list()
for ds in datasets:
with BytesIO() as b:
pydicom.dcmwrite(b, ds)
encoded_ds = b.getvalue()
encoded_datasets.append(encoded_ds)
encoded_datasets = _iter_encoded_datasets(datasets)
return self._http_post_multipart_application_dicom(
url,
encoded_datasets
Expand Down

0 comments on commit e9c271a

Please sign in to comment.