def _cache_entire_instance()

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