code: def dcm_dir_2_numpy(
      input_folder,
      verbose=False,
      harden_orientation=False,
      return_all=False,
  ):
      """Uses pydicom to stack an alphabetical list of DICOM files. TODO: Make it
      take slice_order into account.
      """
  
      if verbose:
          print("Searching for dicom files...")
  
      found_files = grab_files_recursive(input_folder)
  
      if verbose:
          print(("Found", len(found_files), "in directory. \n"))
          print("Checking DICOM compatability...")
  
      dicom_files = []
      for file in found_files:
          try:
              temp_dicom = pydicom.read_file(file)
              dicom_files += [
                  [
                      file,
                      temp_dicom.data_element(
                          "SeriesInstanceUID"
                      ).value,
                  ]
              ]
          except:
              continue
  
      if verbose:
          print(
              (
                  "Found",
                  len(dicom_files),
                  "DICOM files in directory. \n",
              )
          )
          print("Counting volumes..")
  
      unique_dicoms = defaultdict(list)
      for dicom_file in dicom_files:
          UID = dicom_file[1]
          unique_dicoms[UID] += [dicom_file[0]]
  
      if verbose:
          print(
              (
                  "Found",
                  len(list(unique_dicoms.keys())),
                  "unique volumes \n",
              )
          )
          print("Saving out files from these volumes.")
  
      for UID in list(unique_dicoms.keys()):
          # Bad behavior: Currently outputs first DICOM found.
          # Unsure about error-checking with DICOM.
  
          # if True:
          try:
              # Grab DICOMs for a certain Instance
              current_files = unique_dicoms[UID]
              current_dicoms = [
                  pydicom.read_file(dcm) for dcm in unique_dicoms[UID]
              ]
  
              # Sort DICOMs by Instance.
              dicom_instances = [
                  x.data_element("InstanceNumber").value
                  for x in current_dicoms
              ]
              current_dicoms = [
                  x
                  for _, x in sorted(
                      zip(dicom_instances, current_dicoms)
                  )
              ]
              current_files = [
                  x
                  for _, x in sorted(
                      zip(dicom_instances, current_files)
                  )
              ]
              first_dicom, last_dicom = (
                  current_dicoms[0],
                  current_dicoms[-1],
              )
  
              if verbose:
                  print(("Loading...", input_folder))
  
          except:
              print(
                  "Could not read DICOM volume SeriesDescription. Skipping UID...",
                  str(UID),
              )
              continue
  
          try:
              # Extract patient position information for affine creation.
              output_affine = np.eye(4)
              image_position_patient = np.array(
                  first_dicom.data_element("ImagePositionPatient").value
              ).astype(float)
              image_orientation_patient = np.array(
                  first_dicom.data_element(
                      "ImageOrientationPatient"
                  ).value
              ).astype(float)
              last_image_position_patient = np.array(
                  last_dicom.data_element("ImagePositionPatient").value
              ).astype(float)
              pixel_spacing_patient = np.array(
                  first_dicom.data_element("PixelSpacing").value
              ).astype(float)
  
              # Create DICOM Space affine (don't fully understand, TODO)
              output_affine[0:3, 0] = (
                  pixel_spacing_patient[0]
                  * image_orientation_patient[0:3]
              )
              output_affine[0:3, 1] = (
                  pixel_spacing_patient[1]
                  * image_orientation_patient[3:6]
              )
              output_affine[0:3, 2] = (
                  image_position_patient - last_image_position_patient
              ) / (1 - len(current_dicoms))
              output_affine[0:3, 3] = image_position_patient
  
              # Transformations from DICOM to Nifti Space (don't fully understand, TOO)
              cr_flip = np.eye(4)
              cr_flip[0:2, 0:2] = [[0, 1], [1, 0]]
              neg_flip = np.eye(4)
              neg_flip[0:2, 0:2] = [[-1, 0], [0, -1]]
              output_affine = np.matmul(
                  neg_flip, np.matmul(output_affine, cr_flip)
              )
  
              # Create numpy array data...
              output_numpy = []
              for i in range(len(current_dicoms)):
                  try:
                      output_numpy += [
                          get_dicom_pixel_array(
                              current_dicoms[i], current_files[i]
                          )
                      ]
                  except Exception as e:
                      print("{}".format(e.msg))
                      print(
                          (
                              "Warning, error at slice",
                              i,
                              "in folder",
                              input_folder,
                          )
                      )
              output_numpy = np.stack(output_numpy, -1)
  
              # If preferred, harden to identity matrix space (LPS, maybe?)
              # Also unsure of the dynamic here, but they work.
              if harden_orientation:
                  cx, cy, cz = np.argmax(
                      np.abs(output_affine[0:3, 0:3]), axis=0
                  )
  
                  output_numpy = np.transpose(
                      output_numpy, (cx, cy, cz)
                  )
  
                  harden_matrix = np.eye(4)
                  for dim, i in enumerate([cx, cy, cz]):
                      harden_matrix[i, i] = 0
                      harden_matrix[dim, i] = 1
                  output_affine = np.matmul(
                      output_affine, harden_matrix
                  )
  
                  flip_matrix = np.eye(4)
                  for i in range(3):
                      if output_affine[i, i] < 0:
                          flip_matrix[i, i] = -1
                          output_numpy = np.flip(output_numpy, i)
  
                  output_affine = np.matmul(output_affine, flip_matrix)
  
              if return_all:
                  return (
                      output_numpy,
                      None,
                      output_affine,
                  )  # TODO provide DICOM tags without doubling memory
              else:
                  return output_numpy
  
          except:
              print("Could not read DICOM at folder...", input_folder)
  
imports: import os
  import numpy
  import nibabel
  import nrrd
  import pydicom
  import subprocess
  from collections import defaultdict
  from imageio import imwrite, imread
  from deepneuro.utilities.util import grab_files_recursive, quotes
label_desc: Use image node_id 5 for calling a global function with example usage: dcm_dir_2_numpy(input_folder, verbose, harden_orientation, return_all) and returns: output_numpy,  None,  output_affine, output_numpy