in pathology/dicom_proxy/frame_caching_util.py [0:0]
def _cache_entire_instance(dicom_instance: _DicomInstanceRequest) -> int:
"""Caches frames from entire DICOM instance.
Args:
dicom_instance: DICOM Store instance to downsample.
Returns:
Number of frames cached.
"""
with tempfile.TemporaryDirectory() as temp_dir:
path = os.path.join(temp_dir, 'instance.dcm')
dicom_instance.download_instance(path)
try:
render_params = get_cache_render_params(
dicom_instance.dicom_sop_instance_url, dicom_instance.metadata
)
except UnexpectedDicomTransferSyntaxError as exp:
cloud_logging_client.warning(
'Can not cache DICOM instance, instance encoded in unsupported'
' transfer syntax.',
{
'dicomWebInstance': dicom_instance.dicom_sop_instance_url,
'transfer_syntax_uid': (
dicom_instance.metadata.dicom_transfer_syntax
),
},
exp,
)
return 0
uauth = dicom_instance.user_auth
dicom_instance_url = dicom_instance.dicom_sop_instance_url
with pydicom.dcmread(path) as local_pydicom_instance:
number_of_frames = int(local_pydicom_instance.NumberOfFrames)
transfer_syntax_uid = str(
local_pydicom_instance.file_meta.TransferSyntaxUID
)
pixel_data = local_pydicom_instance.PixelData
redis = redis_cache.RedisCache()
frame_ttl = frame_retrieval_util.frame_cache_ttl()
set_frame_partial = functools.partial(
_set_cached_frame_from_gen,
redis,
uauth,
dicom_instance_url,
render_params,
frame_ttl,
)
if metadata_util.is_transfer_syntax_encapsulated(transfer_syntax_uid):
frame_data_generator = _get_encapsulated_data_frame(
pydicom_version_util.generate_frames(pixel_data, number_of_frames)
)
else:
frame_data_generator = _get_pixel_data_frame(pixel_data, number_of_frames)
# If running locally or processing small number of frames just iterate over
# frames and set cache from main in the thread.
if redis.is_localhost or number_of_frames < 100:
for frame_data in frame_data_generator:
set_frame_partial(frame_data)
else:
# If the number of frames is large create a thread pool and use pool to set
# Redis cache.
with concurrent.futures.ThreadPoolExecutor(max_workers=2) as th_pool:
th_pool.map(set_frame_partial, frame_data_generator)
return number_of_frames