示例#1
0
def insert_hdr_ext(args):
    """Function for anonymising input NIfTI-MRS files.

    :param args: Command line arguments parsed in spec2nii.py
    :return: List of anonymised images
    :rtype: [nib.nifti2.Nifti2Image,]
    :return: List of output names
    :rtype: [str,]
    """
    # Load data
    nifti_mrs_img = nib.load(args.file)

    with open(args.json_file) as jf:
        new_hdr = json.load(jf)

    # Make new NIfTI-MRS image
    mod_out = nifti_mrs.NIfTI_MRS(
        nifti_mrs_img.get_fdata(dtype=nifti_mrs_img.get_data_dtype()),
        nifti_mrs_img.affine, nifti_mrs_img.header['pixdim'][4], new_hdr)

    # Process output name.
    if args.fileout:
        fname_out = [
            args.fileout,
        ]
    else:
        fname_out = [
            args.file.with_suffix('').with_suffix('').name,
        ]

    return [
        mod_out,
    ], fname_out
示例#2
0
def read_data_list_pair(data_file, list_file, spar_file):

    df, num_dict, coord_dict, os_dict = _read_list(list_file)
    sorted_data_dict = _read_data(data_file, df)

    spar_params = read_spar(spar_file)

    # Dwelltime
    dwelltime = 1.0 / float(spar_params["sample_frequency"])

    # Orientation
    affine = _philips_orientation(spar_params)
    orientation = NIFTIOrient(affine)

    data_out = []
    name_out = []
    for data_type in sorted_data_dict:
        data = sorted_data_dict[data_type]
        name = data_type

        # Meta
        meta = spar_to_nmrs_hdrext(spar_params)
        meta.set_standard_def('OriginalFile',
                              [data_file.name, list_file.name, spar_file.name])

        kept_ind = []
        for ii, sha in zip(indicies, data.shape[1:]):
            if sha > 1:
                kept_ind.append(ii)

        out_data = data.squeeze()
        if len(kept_ind) > 3:
            raise TooManyDimError(
                'Number of additional dimensions > 3.'
                f' Dimensions are {kept_ind} with shape {out_data.shape[1:]}.'
                ' NIFTI-MRS can only handle three dynamic dimensions. Unsure how to proceed.'
            )

        unknown_counter = 0
        for idx, ki in enumerate(kept_ind):
            if ki in defaults:
                meta.set_dim_info(idx,
                                  defaults[ki],
                                  info=f'data/list dim {ki}')
            else:
                meta.set_dim_info(idx,
                                  f'DIM_USER_{unknown_counter}',
                                  info=f'data/list dim {ki}')
                unknown_counter += 1

        # Insert spatial dimensions
        out_data = out_data.reshape((1, 1, 1) + out_data.shape)
        # Apply conjugate
        out_data = out_data.conj()

        data_out.append(
            nifti_mrs.NIfTI_MRS(out_data, orientation.Q44, dwelltime, meta))
        name_out.append(name)

    return data_out, name_out
示例#3
0
def _process_svs_pfile(pfile):
    '''Handle SVS data

    :param Pfile pfile: Pfile object
    :return: List of NIFTI MRS data objects
    :return: List of file name suffixes
    '''
    psd = pfile.hdr.rhi_psdname.decode('utf-8').lower()

    if psd == 'probe-p':
        data, meta, dwelltime, fname_suffix = _process_probe_p(pfile)
    elif psd == 'oslaser':
        data, meta, dwelltime, fname_suffix = _process_oslaser(pfile)
    else:
        raise UnsupportedPulseSequenceError(
            'Unrecognised sequence, psdname must be "prob-p" or "oslaser".')

    orientation = NIFTIOrient(_calculate_affine(pfile))

    out_nmrs = []
    for dd, mm in zip(data, meta):
        out_nmrs.append(nifti_mrs.NIfTI_MRS(dd, orientation.Q44, dwelltime,
                                            mm))

    return out_nmrs, fname_suffix
示例#4
0
def read_sdat_spar_pair(sdat_file, spar_file, tag=None):

    spar_params = read_spar(spar_file)
    data = read_sdat(sdat_file, spar_params['samples'], spar_params['rows'])

    if data.ndim < 4:
        data = data.reshape((1, 1, 1) + data.shape)

    # Move to right handed frame
    data = data.conj()

    # Dwelltime
    dwelltime = 1.0 / float(spar_params["sample_frequency"])

    # Meta
    meta = spar_to_nmrs_hdrext(spar_params)
    meta.set_standard_def('OriginalFile', [sdat_file.name])

    if tag is not None:
        meta.set_dim_info(0, tag)

    # Orientation
    if spar_params["volume_selection_enable"] == "yes":
        affine = _philips_orientation(spar_params)
    else:
        # Use default affine
        affine = np.diag(np.array([10000, 10000, 10000, 1]))
    orientation = NIFTIOrient(affine)

    return [
        nifti_mrs.NIfTI_MRS(data, orientation.Q44, dwelltime, meta),
    ]
示例#5
0
def read_bruker(args):
    """

    :param args:
    :return list imageOut: 
    :return list fileoutNames:
    """
    imageOut = []
    fileoutNames = []

    # for all Bruker datasets compliant all queries
    for data, properties in yield_bruker(args):
            orientation = NIFTIOrient(np.reshape(np.array(properties['affine']), (4,4)))
            imageOut.append(
                nifti_mrs.NIfTI_MRS(data,
                                   orientation.Q44,
                                   properties['dwell_s'],
                                   nifti_mrs.hdr_ext(
                                       properties['SpectrometerFrequency'],
                                       properties['ResonantNucleus']
                                   ))
            )           
            fileoutNames.append(properties['id'])

    return imageOut, fileoutNames
示例#6
0
def _process_mrsi_pfile(pfile):
    '''Handle MRSI data

    :param Pfile pfile: Pfile object
    :return: List of NIFTI MRS data objects
    :return: List of file name suffixes
    '''
    psd = pfile.hdr.rhi_psdname.decode('utf-8').lower()

    if psd != 'probe-p':
        raise UnsupportedPulseSequenceError('Unrecognised sequence, psdname must be "probe-p".')

    warn('The interpretation of pfile CSI data is poorly tested; rotations or transpositions of the'
         ' CSI grid could be present. Spec2nii currently lacks a complete set of CSI test data.'
         ' Please get in touch to help solve this issue!')

    data = np.transpose(pfile.map.raw_data, [0, 1, 2, 5, 4, 3])
    if data.shape[5] == 1:
        data = data.squeeze(axis=5)

    # Perform fft
    def fft_and_shift(x, axis):
        return np.fft.fftshift(np.fft.fft(x, axis=axis), axes=axis)

    data = fft_and_shift(data, 0)
    data = fft_and_shift(data, 1)
    data = fft_and_shift(data, 2)

    dwelltime = 1 / pfile.hdr.rhr_spectral_width
    meta = _populate_metadata(pfile)
    orientation = NIFTIOrient(_calculate_affine_mrsi(pfile))

    return [nifti_mrs.NIfTI_MRS(data, orientation.Q44, dwelltime, meta), ], ['', ]
示例#7
0
文件: jmrui.py 项目: wexeee/spec2nii
def jmrui_mrui(args):
    '''Process .mrui format files.'''

    data, header, str_info = read_mrui(args.file)

    newshape = (1, 1, 1) + data.shape
    data = data.reshape(newshape)

    # meta-data
    dwelltime = header['sampling_interval'] * 1E-3

    meta = jmrui_hdr_to_obj_mrui(header, str_info)
    meta.set_standard_def('OriginalFile', [
        args.file.name,
    ])

    if data.ndim > 4:
        meta.set_dim_info(0, 'DIM_USER_0', info='jMRUI frames')

    # Read optional affine file
    if args.affine:
        affine = np.loadtxt(args.affine)
    else:
        tmp = np.array([10000, 10000, 10000, 1])
        affine = np.diag(tmp)

    nifti_orientation = NIFTIOrient(affine)

    img_out = [
        nifti_mrs.NIfTI_MRS(data, nifti_orientation.Q44, dwelltime, meta),
    ]

    # File names
    if args.fileout:
        fname_out = [
            args.fileout,
        ]
    else:
        fname_out = [
            args.file.stem,
        ]

    # Place in data output format
    return img_out, fname_out
示例#8
0
def lcm_raw(args):
    '''Processing for LCModel .RAW (and .H2O) files.
    Currently only handles one FID per file.
    '''
    # Read data from file
    data, header = readLCModelRaw(args.file, conjugate=True)

    newshape = (1, 1, 1) + data.shape
    data = data.reshape(newshape)

    # meta
    dwelltime = header['dwelltime']

    meta = nifti_mrs.hdr_ext(header['centralFrequency'],
                             args.nucleus)

    meta.set_standard_def('ConversionMethod', f'spec2nii v{spec2nii_ver}')
    conversion_time = datetime.now().isoformat(sep='T', timespec='milliseconds')
    meta.set_standard_def('ConversionTime', conversion_time)
    meta.set_standard_def('OriginalFile', [basename(args.file), ])

    # Read optional affine file
    if args.affine:
        affine = np.loadtxt(args.affine)
    else:
        tmp = np.array([10000, 10000, 10000, 1])
        affine = np.diag(tmp)

    nifti_orientation = NIFTIOrient(affine)

    img_out = [nifti_mrs.NIfTI_MRS(data,
                                   nifti_orientation.Q44,
                                   dwelltime,
                                   meta), ]

    # File names
    if args.fileout:
        fname_out = [args.fileout, ]
    else:
        fname_out = [splitext(basename(args.file))[0], ]

    # Place in data output format
    return img_out, fname_out
示例#9
0
def text(args):
    '''Processing for simple ascii formatted columns of data.'''
    # Read text from file
    data = np.loadtxt(args.file)
    data = data[:, 0] + 1j * data[:, 1]

    newshape = (1, 1, 1) + data.shape
    data = data.reshape(newshape)

    # Interpret required arguments (frequency and bandwidth)
    dwelltime = 1.0 / args.bandwidth

    meta = nifti_mrs.hdr_ext(args.imagingfreq,
                             args.nucleus)

    meta.set_standard_def('ConversionMethod', 'spec2nii')
    conversion_time = datetime.now().isoformat(sep='T', timespec='milliseconds')
    meta.set_standard_def('ConversionTime', conversion_time)
    meta.set_standard_def('OriginalFile', [basename(args.file), ])

    # Read optional affine file
    if args.affine:
        affine = np.loadtxt(args.affine)
    else:
        tmp = np.array([10000, 10000, 10000, 1])
        affine = np.diag(tmp)

    nifti_orientation = NIFTIOrient(affine)

    img_out = [nifti_mrs.NIfTI_MRS(data,
                                   nifti_orientation.Q44,
                                   dwelltime,
                                   meta), ]

    # File names
    if args.fileout:
        fname_out = [args.fileout, ]
    else:
        fname_out = [splitext(basename(args.file))[0], ]

    # Place in data output format
    return img_out, fname_out
示例#10
0
def read_bruker(args):
    """

    :param args:
    :return list imageOut:
    :return list fileoutNames:
    """
    imageOut = []
    fileoutNames = []

    # for all Bruker datasets compliant all queries
    for data, orientation, dwelltime, meta, name in yield_bruker(args):
        imageOut.append(
            nifti_mrs.NIfTI_MRS(data,
                                orientation.Q44,
                                dwelltime,
                                meta)
        )
        fileoutNames.append(name)

    return imageOut, fileoutNames
示例#11
0
def assemble_nifti_mrs(data, dwellTime, orientation, meta_obj, dim_tags):

    for idx, dt in zip(range(data.ndim - 4), dim_tags):
        meta_obj.set_dim_info(idx, dt)

    return nifti_mrs.NIfTI_MRS(data, orientation.Q44, dwellTime, meta_obj)
示例#12
0
def multi_file_dicom(files_in, fname_out, tag, verbose):
    """Parse a list of Siemens DICOM files"""

    # Convert each file (combine after)
    data_list = []
    orientation_list = []
    dwelltime_list = []
    meta_list = []
    series_num = []
    inst_num = []
    reference = []
    str_suffix = []
    mainStr = ''
    for idx, fn in enumerate(files_in):
        if verbose:
            print(f'Converting dicom file {fn}')

        img = nibabel.nicom.dicomwrappers.wrapper_from_file(fn)

        mrs_type = svs_or_CSI(img)

        if mrs_type == 'SVS':
            specDataCmplx, orientation, dwelltime, meta_obj = process_siemens_svs(
                img, verbose=verbose)

            newshape = (1, 1, 1) + specDataCmplx.shape
            specDataCmplx = specDataCmplx.reshape(newshape)

        else:
            specDataCmplx, orientation, dwelltime, meta_obj = process_siemens_csi(
                img, verbose=verbose)

        data_list.append(specDataCmplx)
        orientation_list.append(orientation)
        dwelltime_list.append(dwelltime)
        meta_list.append(meta_obj)

        series_num.append(int(img.dcm_data.SeriesNumber))
        inst_num.append(int(img.dcm_data.InstanceNumber))

        ref_ind, str_suf = identify_integrated_references(
            img, img.dcm_data.InstanceNumber)
        reference.append(ref_ind)
        str_suffix.append(str_suf)

        if idx == 0:
            if fname_out:
                mainStr = fname_out
            elif 'SeriesDescription' in img.dcm_data:
                mainStr = img.dcm_data.SeriesDescription
            elif 'SeriesInstanceUID' in img.dcm_data:
                mainStr = img.dcm_data.SeriesInstanceUID
            else:
                raise missingTagError(
                    "Neither SeriesDescription or SeriesInstanceUID tags defined."
                    " Please specify an output filename using '-f'")

    # Sort by series and instance number
    data_list = np.asarray(data_list)
    orientation_list = np.asarray(orientation_list)
    dwelltime_list = np.asarray(dwelltime_list)
    meta_list = np.asarray(meta_list)
    series_num = np.asarray(series_num)
    inst_num = np.asarray(inst_num)
    reference = np.asarray(reference)
    str_suffix = np.asarray(str_suffix)
    files_in = np.asarray(files_in)

    sort_index = np.lexsort((inst_num, series_num))  # Sort by series then inst

    data_list = data_list[sort_index, :]
    orientation_list = orientation_list[sort_index]
    dwelltime_list = dwelltime_list[sort_index]
    meta_list = meta_list[sort_index]
    series_num = series_num[sort_index]
    inst_num = inst_num[sort_index]
    reference = reference[sort_index]
    str_suffix = str_suffix[sort_index]
    files_in = files_in[sort_index]

    group_ind = []
    for sn in np.unique(series_num):
        for rn in np.unique(reference):
            group_ind.append(
                list(
                    np.where(np.logical_and(series_num == sn,
                                            reference == rn))[0]))

    if verbose:
        print(f'Sorted series numbers: {series_num}')
        print(f'Sorted instance numbers: {inst_num}')
        print(f'Sorted reference index: {reference}')
        print(f'Output groups: {group_ind}')

    nifti_mrs_out, fnames_out = [], []
    for idx, gr in enumerate(group_ind):

        # If data shape, orientation, dwelltime match then
        # proceed
        def not_equal(lst):
            return lst[:-1] != lst[1:]

        if not_equal([d.shape for d in data_list[gr]])\
                and not_equal([o.Q44.tolist() for o in orientation_list[gr]])\
                and not_equal(dwelltime_list[gr]):
            raise inconsistentDataError(
                'Shape, orientation and dwelltime must match in combined data.'
            )

        fnames_out.append(mainStr + str_suffix[gr[0]])

        dt_used = dwelltime_list[gr[0]]
        or_used = orientation_list[gr[0]]

        # Add original files to nifti meta information.
        meta_used = meta_list[gr[0]]
        meta_used.set_standard_def('OriginalFile',
                                   [str(ff) for ff in files_in[gr]])

        # Combine data into 5th dimension if needed
        data_in_gr = data_list[gr]
        if len(data_in_gr) > 1:
            combined_data = np.stack(data_in_gr, axis=-1)
        else:
            combined_data = data_in_gr[0]

        # Add dimension information (if not None for default)
        if tag:
            meta_used.set_dim_info(0, tag)

        # Create NIFTI MRS object.
        try:
            nifti_mrs_out.append(
                nifti_mrs.NIfTI_MRS(combined_data, or_used.Q44, dt_used,
                                    meta_used))
        except np.linalg.LinAlgError:
            warnings.warn("""The quartenion passes to NIfTI_MRS was singular.
                           Most likely your slice position is not well defined. I have set it to None."""
                          )
            nifti_mrs_out.append(
                nifti_mrs.NIfTI_MRS(combined_data, None, dt_used, meta_used))

    # If there are any identical names then append an index
    seen = np.unique(fnames_out)
    if seen.size < len(fnames_out):
        seen_count = np.zeros(seen.shape, dtype=int)
        fnames_out_checked = []
        for fn in fnames_out:
            if fn in seen:
                seen_index = seen == fn
                fnames_out_checked.append(fn +
                                          f'_{seen_count[seen_index][0]:03}')
                seen_count[seen_index] += 1
            else:
                fnames_out_checked.append(fn)

        return nifti_mrs_out, fnames_out_checked
    else:
        return nifti_mrs_out, fnames_out
示例#13
0
def read_varian(args):
    """read_varian -- load a varian fid.
    Note that this format is very flexible and some rather large assumptions are made.
    At the moment, this assumes little.
    :param file: path to the varian .fid directory, containing fid and procpar files.
    returns img_out, fname_out
    """
    dic, data = v.read(args.file)

    # extract number of coils
    number_of_coils = 0
    for i in dic['procpar']['rcvrs']['values'][0]:
        if re.search(i, 'y'):
            number_of_coils += 1

    # number of time points -- probably
    number_of_time_points = float(
        dic['procpar']['arraydim']['values'][0]) / number_of_coils
    if (not number_of_time_points.is_integer()):
        raise ValueError('Coil reshaping failed')

    number_of_time_points = int(number_of_time_points)

    # spectral number of points
    number_of_spectral_points = int(int(dic['np']) / 2)

    # reshape
    newshape = (1, 1, 1, number_of_spectral_points, number_of_coils,
                number_of_time_points)
    data = data.transpose()
    data = np.resize(data, newshape)

    # extract additional spectral metadata
    dwelltime = 1.0 / float(dic['procpar']['sw']['values'][0])
    imagingfreq = float(dic['procpar']['sfrq']['values'][0])
    nucleus = dic['procpar']['tn']['values'][0]
    # reshape to be in the form '13C' rather than 'C13'
    nucleus = nucleus[1:] + nucleus[0]

    try:
        repitition_time = float(dic['procpar']['tr']['values'][0])
    except KeyError:
        pass

    try:
        echotime = float(
            dic['procpar']['te']['values'][0])  # In ms if 'tis there
    except KeyError:
        pass
    try:
        echotime = float(dic['procpar']['pw']['values'][0]) + float(
            dic['procpar']['alfa']['values'][0])
    except KeyError:
        pass
    try:
        echotime = float(dic['procpar']['p1']['values'][0]) + float(
            dic['procpar']['alfa']['values'][0])
    except KeyError:
        pass

    # Parse 3D localisation
    sequence_name = dic['procpar']['seqfil']['values'][0]
    if (sequence_name.count('press') or sequence_name.count('steam')):
        affine = _varian_orientation_3d(dic)
    else:
        affine = np.diag(np.array([10000, 10000, 10000,
                                   1]))  # 10 m slab for now....

    # TODO: Jack should implement the affine matrix correctly for all sequences

    orientation = NIFTIOrient(affine)

    # create object
    meta = nifti_mrs.hdr_ext(imagingfreq, nucleus)
    meta.set_standard_def('ConversionMethod', f'spec2nii v{spec2nii_ver}')
    meta.set_standard_def('EchoTime', echotime)
    meta.set_standard_def('RepetitionTime', repitition_time)
    meta.set_standard_def('Manufacturer', 'Varian')
    meta.set_standard_def('ProtocolName',
                          dic['procpar']['seqfil']['values'][0])
    meta.set_standard_def('PatientName',
                          dic['procpar']['comment']['values'][0])

    # stuff that is nice to have:
    try:
        meta.set_standard_def('SoftwareVersions',
                              dic['procpar']['parver']['values'][0])
        meta.set_standard_def('TxCoil', dic['procpar']['rfcoil']['values'][0])
        meta.set_standard_def('RxCoil', dic['procpar']['rfcoil']['values'][0])
    except KeyError:
        warnings.warn('Expected standard metadata keying failed')
    try:
        meta.set_standard_def('InversionTime',
                              dic['procpar']['ti']['values'][0])
    except KeyError:
        pass
    try:
        meta.set_standard_def('ExcitationFlipAngle',
                              dic['procpar']['flip1']['values'][0])
    except KeyError:
        pass
    conversion_time = datetime.now().isoformat(sep='T',
                                               timespec='milliseconds')
    meta.set_standard_def('ConversionTime', conversion_time)
    meta.set_standard_def('OriginalFile', [basename(args.file)])

    # k-space
    meta.set_standard_def('kSpace', [False, False, False])

    # set tag dimensions
    meta.set_dim_info(0, "DIM_COIL")
    meta.set_dim_info(1, args.tag6)

    # Stuff full headers into user fields
    if args.dump_headers:
        meta.set_user_def(key='VarianProcpar',
                          doc='Varian procpar metadata.',
                          value=dic['procpar'])

    # File names
    if args.fileout:
        fname_out = [
            args.fileout,
        ]
    else:
        fname_out = [
            splitext(basename(args.file))[0],
        ]

    return [
        nifti_mrs.NIfTI_MRS(data, orientation.Q44, dwelltime, meta),
    ], fname_out
示例#14
0
def multi_file_dicom(files_in, fname_out, tag, verbose):
    """Parse a list of UIH DICOM files"""

    # Convert each file (combine after)
    data_list = []
    ref_list = []
    orientation_list = []
    dwelltime_list = []
    meta_list = []
    meta_ref_list = []
    mainStr = ''
    for idx, fn in enumerate(files_in):
        if verbose:
            print(f'Converting dicom file {fn}')

        img = nibabel.nicom.dicomwrappers.wrapper_from_file(fn)

        mrs_type = svs_or_CSI(img)

        if mrs_type == 'SVS':
            specDataCmplx, spec_ref, orientation, dwelltime, meta_obj, meta_ref_obj = _process_philips_svs(
                img, verbose)

            newshape = (1, 1, 1) + specDataCmplx.shape
            spec_data = specDataCmplx.reshape(newshape)
            spec_ref = spec_ref.reshape(newshape)

            # Data appears to require conjugation to meet standard's conventions.
            spec_data = spec_data.conj()
            spec_ref = spec_ref.conj()

        elif mrs_type == 'FID':
            specDataCmplx, spec_ref, orientation, dwelltime, meta_obj, meta_ref_obj = _process_philips_fid(
                img, verbose)

            newshape = (1, 1, 1) + specDataCmplx.shape
            spec_data = specDataCmplx.reshape(newshape)
            spec_ref = spec_ref.reshape(newshape)

            # Data appears to require conjugation to meet standard's conventions.
            spec_data = spec_data.conj()
            spec_ref = spec_ref.conj()
        else:
            raise CSINotHandledError(
                'CSI data is currently not handled for the Philips DICOM format.'
                'Please contact the developers if you have examples of this type of data.'
            )

        data_list.append(spec_data)
        ref_list.append(spec_ref)
        orientation_list.append(orientation)
        dwelltime_list.append(dwelltime)
        meta_list.append(meta_obj)
        meta_ref_list.append(meta_ref_obj)

        if idx == 0:
            if fname_out:
                mainStr = fname_out
            else:
                mainStr = img.dcm_data.SeriesDescription

    # If data shape, orientation and dwelltime match combine
    # into one NIFTI MRS object.
    # Otherwise return a list of files/names
    def all_equal(lst):
        return lst[:-1] == lst[1:]

    combine = all_equal([d.shape for d in data_list])\
        and all_equal([o.Q44.tolist() for o in orientation_list])\
        and all_equal(dwelltime_list)

    nifti_mrs_out, fnames_out = [], []
    if combine:
        # Combine files into single MRS NIfTI
        # Single file name
        fnames_out.append(mainStr)
        fnames_out.append(mainStr + '_ref')

        dt_used = dwelltime_list[0]
        or_used = orientation_list[0]

        # Add original files to nifti meta information.
        meta_used = meta_list[0]
        meta_used.set_standard_def('OriginalFile',
                                   [str(ff.name) for ff in files_in])
        meta_ref_used = meta_ref_list[0]
        meta_ref_used.set_standard_def('OriginalFile',
                                       [str(ff.name) for ff in files_in])

        # Combine data into 5th dimension if needed
        if len(data_list) > 1:
            combined_data = np.stack(data_list, axis=-1)
            combined_ref = np.stack(ref_list, axis=-1)
        else:
            combined_data = data_list[0]
            combined_ref = ref_list[0]

        # Add dimension information (if not None for default)
        if tag:
            meta_used.set_dim_info(0, tag)

        # Create NIFTI MRS object.
        nifti_mrs_out.append(
            nifti_mrs.NIfTI_MRS(combined_data, or_used.Q44, dt_used,
                                meta_used))
        nifti_mrs_out.append(
            nifti_mrs.NIfTI_MRS(combined_ref, or_used.Q44, dt_used,
                                meta_ref_used))
    else:
        for idx, (dd, rr, oo, dt, mm, mr, ff) in enumerate(
                zip(data_list, ref_list, orientation_list, dwelltime_list,
                    meta_list, meta_ref_list, files_in)):
            # Add original files to nifti meta information.
            mm.set_standard_def('OriginalFile', [
                str(ff.name),
            ])
            fnames_out.append(f'{mainStr}_{idx:03}')
            nifti_mrs_out.append(nifti_mrs.NIfTI_MRS(dd, oo.Q44, dt, mm))

            mr.set_standard_def('OriginalFile', [
                str(ff.name),
            ])
            fnames_out.append(f'{mainStr}_ref_{idx:03}')
            nifti_mrs_out.append(nifti_mrs.NIfTI_MRS(rr, oo.Q44, dt, mr))

    return nifti_mrs_out, fnames_out
示例#15
0
文件: uih.py 项目: wexeee/spec2nii
def multi_file_dicom(files_in, fname_out, tag, verbose):
    """Parse a list of UIH DICOM files"""

    # Convert each file (combine after)
    data_list = []
    orientation_list = []
    dwelltime_list = []
    meta_list = []
    mainStr = ''
    for idx, fn in enumerate(files_in):
        if verbose:
            print(f'Converting dicom file {fn}')

        img = nibabel.nicom.dicomwrappers.wrapper_from_file(fn)

        mrs_type = svs_or_CSI(img)

        if mrs_type == 'SVS':
            specDataCmplx, orientation, dwelltime, meta_obj = process_uih_svs(img, verbose)

            newshape = (1, 1, 1) + specDataCmplx.shape
            specDataCmplx = specDataCmplx.reshape(newshape)

        else:
            specDataCmplx, orientation, dwelltime, meta_obj = process_uih_csi(img, verbose)

        data_list.append(specDataCmplx)
        orientation_list.append(orientation)
        dwelltime_list.append(dwelltime)
        meta_list.append(meta_obj)

        if idx == 0:
            if fname_out:
                mainStr = fname_out
            else:
                mainStr = img.dcm_data.SeriesDescription

    # If data shape, orientation and dwelltime match combine
    # into one NIFTI MRS object.
    # Otherwise return a list of files/names
    def all_equal(lst):
        return lst[:-1] == lst[1:]

    combine = all_equal([d.shape for d in data_list])\
        and all_equal([o.Q44.tolist() for o in orientation_list])\
        and all_equal(dwelltime_list)

    nifti_mrs_out, fnames_out = [], []
    if combine:
        # Combine files into single MRS NIfTI
        # Single file name
        fnames_out.append(mainStr)

        dt_used = dwelltime_list[0]
        or_used = orientation_list[0]

        # Add original files to nifti meta information.
        meta_used = meta_list[0]
        meta_used.set_standard_def('OriginalFile', [str(ff.name) for ff in files_in])

        # Combine data into 5th dimension if needed
        if len(data_list) > 1:
            combined_data = np.stack(data_list, axis=-1)
        else:
            combined_data = data_list[0]

        # Add dimension information (if not None for default)
        if tag:
            meta_used.set_dim_info(0, tag)

        # Create NIFTI MRS object.
        nifti_mrs_out.append(nifti_mrs.NIfTI_MRS(combined_data, or_used.Q44, dt_used, meta_used))
    else:
        for idx, (dd, oo, dt, mm, ff) in enumerate(zip(data_list,
                                                   orientation_list,
                                                   dwelltime_list,
                                                   meta_list,
                                                   files_in)):
            # Add original files to nifti meta information.
            mm.set_standard_def('OriginalFile', [str(ff.name), ])
            fnames_out.append(f'{mainStr}_{idx:03}')
            nifti_mrs_out.append(nifti_mrs.NIfTI_MRS(dd, oo.Q44, dt, mm))

    return nifti_mrs_out, fnames_out