def convert_dicom_to_json()

in python/shared/research_pacs/shared/dicom_json.py [0:0]


def convert_dicom_to_json(dicom):
  """
  Convert a pydicom Dataset to a JSON document. The dict returned has the following structure, 
  and is used to index DICOM data elements into the PostgreSQL database, or to evaluate a DICOM 
  query on a given DICOM file:
  
  {
    "HexaNumber": str or list of str
    "SequenceHexaNumber": dict or list of dict
  }
  
  Example:
  
  {
    "00080008": ["DERIVED, "PRIMARY"],
    "00100010": "Patient Name",
    "00082112": {
      "00081150": "value"
    }
  }
  
  Args:
    dicom: pydicom Dataset
    
  """
  logger.debug('Converting a DICOM file to a JSON document')
  # Function that modifies recursively the content of the JSON document returned by the pydicom 
  # `to_json_dict()` function to make it easier to index and search DICOM data elements in the 
  # PostgreSQL database
  def process_level(level_dict):
    new_level_dict = {}
    for tag, element in level_dict.items():
      # `element` may not contain an attribute `Value` if the tag is empty, or if it contains a 
      # binary value like PixelData
      if not 'Value' in element:
        new_level_dict[tag] = ''
      else:
        # `element['Value']` should be a list, whatever the tag VM (Value Multiplicity)
        if isinstance(element['Value'], list):
          # Parse the content of `element['Value']` differently if the VR is SQ, PN or something 
          # else. Numbers are converted to strings.
          if element['vr'] == 'SQ':
            new_level_dict[tag] = [process_level(i) for i in element['Value']]
          elif element['vr'] == 'PN':
            new_level_dict[tag] = [i['Alphabetic'] if 'Alphabetic' in i else str(i) for i in element['Value']]
          else:
            new_level_dict[tag] = [str(i) for i in element['Value']]
          # If there is a single item in the list, remove the list and keep only the item value
          if len(new_level_dict[tag]) == 1:
            new_level_dict[tag] = new_level_dict[tag][0]
    return new_level_dict
  
  # Generate and return a JSON document that contains both dataset and meta header information
  try:
    j = process_level(dicom.to_json_dict())
    j.update(process_level(dicom.file_meta.to_json_dict()))
    return j
  except Exception as e:
    err_msg = f'Failed to convert the DICOM file to a JSON document - {e}'
    logger.debug(err_msg)
    raise Exception(err_msg)