def _anonymize_files(dicom_directory_in, dicom_directory_out, fields_to_keep): """ See anonymize_file for more information. series_UID and instance_UID will create a new UID respectively for the series for each directory or for the instance for each file. Note that for a multi-series dataset it is thus required that each series is in its own directory. """ # Make sure we have absolute paths dicom_directory_in = os.path.abspath(dicom_directory_in) dicom_directory_out = os.path.abspath(dicom_directory_out) # looping over all files for root, _, file_names in os.walk(dicom_directory_in): # New directory for file_name in file_names: # Create instance_UID fields_to_keep['SOPInstanceUID'] = pydicom.uid.generate_uid() dicom_file_in = os.path.join(root, file_name) current_dir = root[len(dicom_directory_in) + 1:] dicom_file_out = os.path.join(dicom_directory_out, current_dir, file_name) if compressed_dicom.is_dicom_file(dicom_file_in): logging.info("Processing " + dicom_file_in) _anonymize_file(dicom_file_in, dicom_file_out, fields_to_keep) else: logging.info("Skipping " + dicom_file_in + ", no dicom file")
def test_is_dicom_file(self): input_file = os.path.join(test_data.GENERIC_COMPRESSED, 'IM-0001-0001-0001.dcm') assert is_dicom_file(input_file) temporary_directory = tempfile.mkdtemp() try: # test for empty file non_dicom1 = os.path.join(temporary_directory, 'non_dicom.dcm') open(non_dicom1, 'a').close() assert not is_dicom_file(non_dicom1) # test for non empty file non_dicom2 = os.path.join(temporary_directory, 'non_dicom2.dcm') with open(non_dicom2, 'w') as file_2: file_2.write(''.join(random.SystemRandom().choice(string.digits) for _ in range(300))) assert not is_dicom_file(non_dicom2) finally: shutil.rmtree(temporary_directory)
def test_is_dicom_file(self): input_file = os.path.join(test_data.GENERIC_COMPRESSED, 'IM-0001-0001-0001.dcm') assert is_dicom_file(input_file) temporary_directory = tempfile.mkdtemp() try: # test for empty file non_dicom1 = os.path.join(temporary_directory, 'non_dicom.dcm') open(non_dicom1, 'a').close() assert not is_dicom_file(non_dicom1) # test for non empty file non_dicom2 = os.path.join(temporary_directory, 'non_dicom2.dcm') with open(non_dicom2, 'w') as file_2: file_2.write(''.join( random.SystemRandom().choice(string.digits) for _ in range(300))) assert not is_dicom_file(non_dicom2) finally: shutil.rmtree(temporary_directory)
def _get_first_header(dicom_directory): """ Function to get the first dicom file form a directory and return the header Useful to determine the type of data to convert :param dicom_directory: directory with dicom files """ # looping over all files for root, _, file_names in os.walk(dicom_directory): # go over all the files and try to read the dicom header for file_name in file_names: file_path = os.path.join(root, file_name) # check wither it is a dicom file if not compressed_dicom.is_dicom_file(file_path): continue # read the headers return compressed_dicom.read_file(file_path, stop_before_pixels=True, force=dicom2nifti.settings.pydicom_read_force) # no dicom files found raise ConversionError('NO_DICOM_FILES_FOUND')
def read_dicom_directory(dicom_directory, stop_before_pixels=False): """ Read all dicom files in a given directory (stop before pixels) :type stop_before_pixels: bool :type dicom_directory: six.string_types :param stop_before_pixels: Should we stop reading before the pixeldata (handy if we only want header info) :param dicom_directory: Directory with dicom data :return: List of dicom objects """ dicom_input = [] for root, _, files in os.walk(dicom_directory): for dicom_file in files: file_path = os.path.join(root, dicom_file) if compressed_dicom.is_dicom_file(file_path): dicom_headers = compressed_dicom.read_file(file_path, defer_size=100, stop_before_pixels=stop_before_pixels, force=dicom2nifti.settings.pydicom_read_force) dicom_input.append(dicom_headers) return dicom_input
def _get_first_header(dicom_directory): """ Function to get the first dicom file form a directory and return the header Useful to determine the type of data to convert :param dicom_directory: directory with dicom files """ # looping over all files for root, _, file_names in os.walk(dicom_directory): # go over all the files and try to read the dicom header for file_name in file_names: file_path = os.path.join(root, file_name) # check wither it is a dicom file if not compressed_dicom.is_dicom_file(file_path): continue # read the headers return compressed_dicom.read_file(file_path, stop_before_pixels=True, force=dicom2nifti.settings.pydicom_read_force) # no dicom files found raise ConversionError('NO_DICOM_FILES_FOUND')
def read_dicom_directory(dicom_directory, stop_before_pixels=False): """ Read all dicom files in a given directory (stop before pixels) :type stop_before_pixels: bool :type dicom_directory: six.string_types :param stop_before_pixels: Should we stop reading before the pixeldata (handy if we only want header info) :param dicom_directory: Directory with dicom data :return: List of dicom objects """ dicom_input = [] for root, _, files in os.walk(dicom_directory): for dicom_file in files: file_path = os.path.join(root, dicom_file) if compressed_dicom.is_dicom_file(file_path): dicom_headers = compressed_dicom.read_file(file_path, defer_size="1 KB", stop_before_pixels=stop_before_pixels, force=dicom2nifti.settings.pydicom_read_force) if is_valid_imaging_dicom(dicom_headers): dicom_input.append(dicom_headers) return dicom_input
def convert_directory(dicom_directory, output_folder, compression=True, reorient=True): """ This function will order all dicom files by series and order them one by one :param compression: enable or disable gzip compression :param reorient: reorient the dicoms according to LAS orientation :param output_folder: folder to write the nifti files to :param dicom_directory: directory with dicom files """ # sort dicom files by series uid dicom_series = {} for root, _, files in os.walk(dicom_directory): for dicom_file in files: file_path = os.path.join(root, dicom_file) # noinspection PyBroadException try: if compressed_dicom.is_dicom_file(file_path): # read the dicom as fast as possible # (max length for SeriesInstanceUID is 64 so defer_size 100 should be ok) dicom_headers = compressed_dicom.read_file(file_path, defer_size="1 KB", stop_before_pixels=False, force=dicom2nifti.settings.pydicom_read_force) if not _is_valid_imaging_dicom(dicom_headers): logger.info("Skipping: %s" % file_path) continue logger.info("Organizing: %s" % file_path) if dicom_headers.SeriesInstanceUID not in dicom_series: dicom_series[dicom_headers.SeriesInstanceUID] = [] dicom_series[dicom_headers.SeriesInstanceUID].append(dicom_headers) except: # Explicitly capturing all errors here to be able to continue processing all the rest logger.warning("Unable to read: %s" % file_path) traceback.print_exc() # start converting one by one for series_id, dicom_input in iteritems(dicom_series): base_filename = "" # noinspection PyBroadException try: # construct the filename for the nifti base_filename = "" if 'SeriesNumber' in dicom_input[0]: base_filename = _remove_accents('%s' % dicom_input[0].SeriesNumber) if 'SeriesDescription' in dicom_input[0]: base_filename = _remove_accents('%s_%s' % (base_filename, dicom_input[0].SeriesDescription)) elif 'SequenceName' in dicom_input[0]: base_filename = _remove_accents('%s_%s' % (base_filename, dicom_input[0].SequenceName)) elif 'ProtocolName' in dicom_input[0]: base_filename = _remove_accents('%s_%s' % (base_filename, dicom_input[0].ProtocolName)) else: base_filename = _remove_accents(dicom_input[0].SeriesInstanceUID) logger.info('--------------------------------------------') logger.info('Start converting %s' % base_filename) if compression: nifti_file = os.path.join(output_folder, base_filename + '.nii.gz') else: nifti_file = os.path.join(output_folder, base_filename + '.nii') convert_dicom.dicom_array_to_nifti(dicom_input, nifti_file, reorient) gc.collect() except: # Explicitly capturing app exceptions here to be able to continue processing logger.info("Unable to convert: %s" % base_filename) traceback.print_exc()
def convert_directory(dicom_directory, output_folder, compression=True, reorient=True): """ This function will order all dicom files by series and order them one by one :param compression: enable or disable gzip compression :param reorient: reorient the dicoms according to LAS orientation :param output_folder: folder to write the nifti files to :param dicom_directory: directory with dicom files """ # sort dicom files by series uid dicom_series = {} for root, _, files in os.walk(dicom_directory): for dicom_file in files: file_path = os.path.join(root, dicom_file) # noinspection PyBroadException try: if compressed_dicom.is_dicom_file(file_path): # read the dicom as fast as possible # (max length for SeriesInstanceUID is 64 so defer_size 100 should be ok) dicom_headers = compressed_dicom.read_file(file_path, defer_size="1 KB", stop_before_pixels=False, force=dicom2nifti.settings.pydicom_read_force) if not _is_valid_imaging_dicom(dicom_headers): logger.info("Skipping: %s" % file_path) continue logger.info("Organizing: %s" % file_path) if dicom_headers.SeriesInstanceUID not in dicom_series: dicom_series[dicom_headers.SeriesInstanceUID] = [] dicom_series[dicom_headers.SeriesInstanceUID].append(dicom_headers) except: # Explicitly capturing all errors here to be able to continue processing all the rest logger.warning("Unable to read: %s" % file_path) traceback.print_exc() # start converting one by one for series_id, dicom_input in dicom_series.items(): base_filename = "" # noinspection PyBroadException try: # construct the filename for the nifti base_filename = "" if 'SeriesNumber' in dicom_input[0]: base_filename = _remove_accents('%s' % dicom_input[0].SeriesNumber) if 'SeriesDescription' in dicom_input[0]: base_filename = _remove_accents('%s_%s' % (base_filename, dicom_input[0].SeriesDescription)) elif 'SequenceName' in dicom_input[0]: base_filename = _remove_accents('%s_%s' % (base_filename, dicom_input[0].SequenceName)) elif 'ProtocolName' in dicom_input[0]: base_filename = _remove_accents('%s_%s' % (base_filename, dicom_input[0].ProtocolName)) else: base_filename = _remove_accents(dicom_input[0].SeriesInstanceUID) logger.info('--------------------------------------------') logger.info('Start converting %s' % base_filename) if compression: nifti_file = os.path.join(output_folder, base_filename + '.nii.gz') else: nifti_file = os.path.join(output_folder, base_filename + '.nii') convert_dicom.dicom_array_to_nifti(dicom_input, nifti_file, reorient) gc.collect() except: # Explicitly capturing app exceptions here to be able to continue processing logger.info("Unable to convert: %s" % base_filename) traceback.print_exc()