Exemplo n.º 1
0
 def test_normal_execution(self):
     """ Test the normal behaviour of the function.
     """
     # Test execution
     value = get_values(self.dataset_or_dcmpath, "get_echo_time")
     self.assertEqual(value, 240.)
     tag = STANDARD_EXTRACTOR["get_echo_time"][0]
     values = walk(self.dataset_or_dcmpath, tag, stack_values=False)
     self.assertEqual(values, [240.])
     values = walk(self.dataset_or_dcmpath, tag, stack_values=True)
     self.assertEqual(values, [240.])
Exemplo n.º 2
0
def add_meta_to_nii(nii_file, dicom_dir, dcm_tags, outdir, prefix="f",
                    additional_information=None):
    """ Add dicom tags to Nifti1 image header.

    All selected dicom tag values are set in the 'descrip' Nifti header
    field.

    Parameters
    ----------
    nii_file: str
        The nifti image to fill.
    dicom_dir: str
        The directory containing the dicoms used to generate the nifti image.
        We assume here that this folder contains only Dicom files.
    dcm_tags: list
        A list of 3-uplet of the form (name, tag, stack_values) that will
        be inserted in the 'descrip' Nifti header field. If we want to stack
        all the Dicom dataset values, the 'stack_values' option mist be set to
        True.
    outdir: str
        The destination folder.
    prefix: str (optional, default 'f')
        The output image name prefix.
    additional_information: dict (optional, default None)
        A free dictionary items to be inserted in the 'descrip' image
        header field.

    Returns
    -------
    filled_nii_file: str
        The nifti image with filled header.
    """
    # Set default
    if additional_information is None:
        additional_information = {}

    # Create the destination image path
    if not os.path.isdir(outdir):
        os.makedirs(outdir)

    # Load the first listed dicom image
    dicom_files = os.listdir(dicom_dir)
    dataset = dicom.read_file(os.path.join(dicom_dir, dicom_files[0]),
                              force=True)

    # Load the nifti1 image
    niiimage = nibabel.load(nii_file)

    # Check that we have a nifti1 format image
    filled_nii_file = os.path.join(outdir, prefix + os.path.basename(nii_file))
    if isinstance(niiimage, nibabel.nifti1.Nifti1Image):

        # Fill the nifti1 header
        header = niiimage.get_header()

        # > slice_duration: Time for 1 slice
        repetition_time = get_values(dataset, "get_repetition_time")
        if repetition_time is not None and len(niiimage.shape) > 2:
            repetition_time = float(repetition_time)
            header.set_dim_info(slice=2)
            nb_slices = header.get_n_slices()
            slice_duration = round(repetition_time / nb_slices, 0)
            header.set_slice_duration(slice_duration)

        # > add free dicom fields
        # enhances storage: the value is burried under one or several layer(s)
        # of sequence
        content = {}
        for name, tag, stack_values in dcm_tags:
            content[str(name)] = walk(dataset, tag, stack_values=stack_values)

        # > add/update free content
        content.update(additional_information)

        # Overwrite the 'descrip' header filed
        free_field = numpy.array(json.dumps(content),
                                 dtype=header["descrip"].dtype)
        niiimage.get_header()["descrip"] = free_field

        # Update the image header
        niiimage.update_header()

        # Save the filled image
        nibabel.save(niiimage, filled_nii_file)

    # Unknwon image format
    else:
        raise ValueError(
            "'{0}' is not a Nifti1 image but a '{1}' image.".format(
                nii_file, type(niiimage)))

    return filled_nii_file