コード例 #1
0
def generate_output_file(fname_in, fname_out, verbose=1):
    """
    Generate output file. Only works for images (e.g., nifti, nifti_gz)
    :param fname_in:
    :param fname_out:
    :param verbose:
    :return: fname_out
    """
    # import stuff
    import shutil  # for moving files
    path_in, file_in, ext_in = extract_fname(fname_in)
    path_out, file_out, ext_out = extract_fname(fname_out)
    # if input image does not exist, give error
    if not os.path.isfile(fname_in):
        printv('  ERROR: File '+fname_in+' does not exist. Exit program.', 1, 'error')
        sys.exit(2)
    # if input and output fnames are the same, do nothing and exit function
    if fname_in == fname_out:
        printv('  WARNING: fname_in and fname_out are the same. Do nothing.', verbose, 'warning')
        print '  File created: '+path_out+file_out+ext_out
        return path_out+file_out+ext_out
    # if fname_out already exists in nii or nii.gz format
    if os.path.isfile(path_out+file_out+ext_out):
        printv('  WARNING: File '+path_out+file_out+ext_out+' already exists. Deleting it...', 1, 'warning')
        os.remove(path_out+file_out+ext_out)
    if ext_in != ext_out:
        # Generate output file
        '''
        # TRY TO UNCOMMENT THIS LINES AND RUN IT IN AN OTHER STATION THAN EVANS (testing of sct_label_vertebrae and sct_smooth_spinalcord never stops with this lines on evans)
        if ext_in == '.nii.gz' and ext_out == '.nii':  # added to resolve issue #728
            run('gunzip -f ' + fname_in)
            os.rename(path_in + file_in + '.nii', fname_out)
        else:
        '''
        from sct_convert import convert
        convert(fname_in, fname_out)
    else:
        # Generate output file without changing the extension
        shutil.move(fname_in, fname_out)

    # # Move file to output folder (keep the same extension as input)
    # shutil.move(fname_in, path_out+file_out+ext_in)
    # # convert to nii (only if necessary)
    # if ext_out == '.nii' and ext_in != '.nii':
    #     convert(path_out+file_out+ext_in, path_out+file_out+ext_out)
    #     os.remove(path_out+file_out+ext_in)  # remove nii.gz file
    # # convert to nii.gz (only if necessary)
    # if ext_out == '.nii.gz' and ext_in != '.nii.gz':
    #     convert(path_out+file_out+ext_in, path_out+file_out+ext_out)
    #     os.remove(path_out+file_out+ext_in)  # remove nii file
    # display message
    printv('  File created: '+path_out+file_out+ext_out, verbose)
    # if verbose:
    #     print '  File created: '+path_out+file_out+ext_out
    return path_out+file_out+ext_out
コード例 #2
0
 def setup_debug_folder(self):
     """
     Sets up the folder for the step by step files for this algorithm
     The folder's absolute path can be found in the self.debug_folder property
     :return: None
     """
     if self.produce_output:
         import time
         from sct_utils import slash_at_the_end
         folder = slash_at_the_end('scad_output_'+time.strftime("%y%m%d%H%M%S"), 1)
         sct.run('mkdir '+folder, self.verbose)
         self.debug_folder = os.path.abspath(folder)
         conv.convert(str(self.input_image.absolutepath), str(self.debug_folder)+"/raw.nii.gz")
コード例 #3
0
def scad_propseg_validation(folder_input, contrast):
    from sct_get_centerline import ind2sub
    import time
    import math
    import numpy
    import sct_convert as cnv

    t0 = time.time()

    current_folder = os.getcwd()
    os.chdir(folder_input)

    try:
        patients = next(os.walk('.'))[1]
        for i in patients:
            directory = i + "/" + str(contrast)
            try:
                os.chdir(directory)
            except Exception, e:
                print str(i)+" : "+contrast+" directory not found"
            try:
                if os.path.isfile(i+"_"+contrast+".nii.gz"):
                    raw_image = Image(i+"_"+contrast+".nii.gz")
                elif os.path.isfile(contrast+".nii.gz"):
                    raw_image = Image(contrast+".nii.gz")
                else:
                    raise Exception("Patient scan not found")

                if os.path.isfile(i+"_"+contrast+"_manual_segmentation.nii.gz"):
                    manual_segmentation  = i+"_"+contrast+"_manual_segmentation.nii.gz"
                    # Using propseg default
                    sct.run("sct_propseg -i "+raw_image.absolutepath+" -t "+contrast)
                    cnv.convert(raw_image.file_name+"_seg.nii.gz", "propseg_default.nii.gz")
                    # Using scad
                    scad = SCAD(raw_image, contrast=contrast, rm_tmp_file=1, verbose=1)
                    scad.execute()
                    # Using propseg with scad
                    sct.run("sct_propseg -i "+raw_image.absolutepath+" -t "+contrast+" -init-centerline "+scad.output_filename)
                    cnv.convert(raw_image.file_name+"_seg.nii.gz", "propseg_scad.nii.gz")
                    # Calculate dice of propseg_default
                    sct.run("sct_dice_coefficient propseg_default.nii.gz "+manual_segmentation+" -o propseg_default_result.txt")
                    # Calculate dice of propseg_scad
                    sct.run("sct_dice_coefficient propseg_scad.nii.gz "+manual_segmentation+" -o propseg_scad_result.txt")
                else:
                    printv("Cannot find the manual segmentation", type="warning")

            except Exception, e:
                print e.message

            os.chdir(folder_input)
コード例 #4
0
def generate_output_file(fname_in, fname_out, verbose=1):
    """
    Generate output file. Only works for images (e.g., nifti, nifti_gz)
    :param fname_in:
    :param fname_out:
    :param verbose:
    :return: fname_out
    """
    # import stuff
    import shutil  # for moving files
    path_in, file_in, ext_in = extract_fname(fname_in)
    path_out, file_out, ext_out = extract_fname(fname_out)
    # if input image does not exist, give error
    if not os.path.isfile(fname_in):
        printv('  ERROR: File '+fname_in+' does not exist. Exit program.', 1, 'error')
        sys.exit(2)
    # if input and output fnames are the same, do nothing and exit function
    if fname_in == fname_out:
        printv('  WARNING: fname_in and fname_out are the same. Do nothing.', verbose, 'warning')
        print '  File created: '+path_out+file_out+ext_out
        return path_out+file_out+ext_out
    # if fname_out already exists in nii or nii.gz format
    if os.path.isfile(path_out+file_out+ext_out):
        printv('  WARNING: File '+path_out+file_out+ext_out+' already exists. Deleting it...', 1, 'warning')
        os.remove(path_out+file_out+ext_out)
    if ext_in != ext_out:
        # Generate output file
        from sct_convert import convert
        convert(fname_in, fname_out)
    else:
        # Generate output file without changing the extension
        shutil.move(fname_in, fname_out)

    # # Move file to output folder (keep the same extension as input)
    # shutil.move(fname_in, path_out+file_out+ext_in)
    # # convert to nii (only if necessary)
    # if ext_out == '.nii' and ext_in != '.nii':
    #     convert(path_out+file_out+ext_in, path_out+file_out+ext_out)
    #     os.remove(path_out+file_out+ext_in)  # remove nii.gz file
    # # convert to nii.gz (only if necessary)
    # if ext_out == '.nii.gz' and ext_in != '.nii.gz':
    #     convert(path_out+file_out+ext_in, path_out+file_out+ext_out)
    #     os.remove(path_out+file_out+ext_in)  # remove nii file
    # display message
    printv('  File created: '+path_out+file_out+ext_out, verbose)
    # if verbose:
    #     print '  File created: '+path_out+file_out+ext_out
    return path_out+file_out+ext_out
コード例 #5
0
def register_slicewise(fname_src,
                        fname_dest,
                        fname_mask='',
                        warp_forward_out='step0Warp.nii.gz',
                        warp_inverse_out='step0InverseWarp.nii.gz',
                        paramreg=None,
                        ants_registration_params=None,
                        path_qc='./',
                        verbose=0):

    # create temporary folder
    path_tmp = sct.tmp_create(verbose)

    # copy data to temp folder
    sct.printv('\nCopy input data to temp folder...', verbose)
    convert(fname_src, path_tmp+'src.nii')
    convert(fname_dest, path_tmp+'dest.nii')
    if fname_mask != '':
        convert(fname_mask, path_tmp+'mask.nii.gz')

    # go to temporary folder
    chdir(path_tmp)

    # Calculate displacement
    if paramreg.algo == 'centermass':
        # translation of center of mass between source and destination in voxel space
        register2d_centermassrot('src.nii', 'dest.nii', fname_warp=warp_forward_out, fname_warp_inv=warp_inverse_out, rot=0, poly=int(paramreg.poly), path_qc=path_qc, verbose=verbose)
    elif paramreg.algo == 'centermassrot':
        # translation of center of mass and rotation based on source and destination first eigenvectors from PCA.
        register2d_centermassrot('src.nii', 'dest.nii', fname_warp=warp_forward_out, fname_warp_inv=warp_inverse_out, rot=1, poly=int(paramreg.poly), path_qc=path_qc, verbose=verbose, pca_eigenratio_th=float(paramreg.pca_eigenratio_th))
    elif paramreg.algo == 'columnwise':
        # scaling R-L, then column-wise center of mass alignment and scaling
        register2d_columnwise('src.nii', 'dest.nii', fname_warp=warp_forward_out, fname_warp_inv=warp_inverse_out, verbose=verbose, path_qc=path_qc, smoothWarpXY=int(paramreg.smoothWarpXY))
    else:
        # convert SCT flags into ANTs-compatible flags
        algo_dic = {'translation': 'Translation', 'rigid': 'Rigid', 'affine': 'Affine', 'syn': 'SyN', 'bsplinesyn': 'BSplineSyN', 'centermass': 'centermass'}
        paramreg.algo = algo_dic[paramreg.algo]
        # run slicewise registration
        register2d('src.nii', 'dest.nii', fname_mask=fname_mask, fname_warp=warp_forward_out, fname_warp_inv=warp_inverse_out, paramreg=paramreg, ants_registration_params=ants_registration_params, verbose=verbose)

    sct.printv('\nMove warping fields to parent folder...', verbose)
    sct.run('mv '+warp_forward_out+' ../')
    sct.run('mv '+warp_inverse_out+' ../')

    # go back to parent folder
    chdir('../')
コード例 #6
0
def main():

    # Initialization
    fsloutput = 'export FSLOUTPUTTYPE=NIFTI; ' # for faster processing, all outputs are in NIFTI
    fname_data = ''
    fname_bvecs = ''
    fname_bvals = ''
    path_out = ''
    average = param.average
    verbose = param.verbose
    remove_tmp_files = param.remove_tmp_files
    start_time = time.time()

    # get path of the toolbox
    status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Parameters for debug mode
    if param.debug:
        fname_data = path_sct+'/testing/data/errsm_23/dmri/dmri.nii.gz'
        fname_bvecs = path_sct+'/testing/data/errsm_23/dmri/bvecs.txt'
        average = 1
        verbose = 1
    else:
        # Check input parameters
        try:
            opts, args = getopt.getopt(sys.argv[1:],'ha:b:i:m:o:r:v:')
        except getopt.GetoptError:
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ("-a"):
                average = int(arg)
            elif opt in ("-b"):
                fname_bvecs = arg
            elif opt in ("-i"):
                fname_data = arg
            elif opt in ('-m'):
                fname_bvals = arg
            elif opt in ("-o"):
                path_out = arg
            elif opt in ("-r"):
                remove_temp_file = int(arg)
            elif opt in ('-v'):
                verbose = int(arg)

    # display usage if a mandatory argument is not provided
    if fname_data == '' or fname_bvecs == '':
        usage()

    # check existence of input files
    sct.check_file_exist(fname_data, verbose)
    sct.check_file_exist(fname_bvecs, verbose)
    if not fname_bvals == '':
        sct.check_file_exist(fname_bvals, verbose)

    # print arguments
    sct.printv('\nInput parameters:', verbose)
    sct.printv('  input file ............'+fname_data, verbose)
    sct.printv('  bvecs file ............'+fname_bvecs, verbose)
    sct.printv('  average ...............'+str(average), verbose)

    # Get full path
    fname_data = os.path.abspath(fname_data)
    fname_bvecs = os.path.abspath(fname_bvecs)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    # # get output folder
    # if path_out == '':
    #     path_out = ''

    # create temporary folder
    sct.printv('\nCreate temporary folder...', verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, verbose)

    # copy files into tmp folder and convert to nifti
    sct.printv('\nCopy files into temporary folder...', verbose)
    from sct_convert import convert
    if not convert(fname_data, path_tmp+'dmri.nii'):
        sct.printv('ERROR in convert.', 1, 'error')
    sct.run('cp '+fname_bvecs+' '+path_tmp+'bvecs', verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # Get size of data
    sct.printv('\nGet dimensions data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('dmri.nii').dim
    sct.printv('.. '+str(nx)+' x '+str(ny)+' x '+str(nz)+' x '+str(nt), verbose)

    # Identify b=0 and DWI images
    index_b0, index_dwi, nb_b0, nb_dwi = identify_b0(fname_bvecs, fname_bvals, param.bval_min, verbose)

    # Split into T dimension
    sct.printv('\nSplit along T dimension...', verbose)
    from sct_split_data import split_data
    if not split_data('dmri.nii', 3, '_T'):
        sct.printv('ERROR in split_data.', 1, 'error')

    # Merge b=0 images
    sct.printv('\nMerge b=0...', verbose)
    cmd = 'sct_concat_data -dim t -o b0.nii -i '
    for it in range(nb_b0):
        cmd = cmd + 'dmri_T' + str(index_b0[it]).zfill(4) + '.nii,'
    cmd = cmd[:-1]  # remove ',' at the end of the string
    status, output = sct.run(cmd, param.verbose)

    # Average b=0 images
    if average:
        sct.printv('\nAverage b=0...', verbose)
        sct.run('sct_maths -i b0.nii -o b0_mean.nii -mean t', verbose)

    # Merge DWI
    sct.printv('\nMerge DWI...', verbose)
    cmd = 'sct_concat_data -dim t -o dwi.nii -i '
    for it in range(nb_dwi):
        cmd = cmd + 'dmri_T' + str(index_dwi[it]).zfill(4) + '.nii,'
    cmd = cmd[:-1]  # remove ',' at the end of the string
    status, output = sct.run(cmd, param.verbose)


    # Average DWI images
    if average:
        sct.printv('\nAverage DWI...', verbose)
        sct.run('sct_maths -i dwi.nii -o dwi_mean.nii -mean t', verbose)
        # if not average_data_across_dimension('dwi.nii', 'dwi_mean.nii', 3):
        #     sct.printv('ERROR in average_data_across_dimension', 1, 'error')
        # sct.run(fsloutput + 'fslmaths dwi -Tmean dwi_mean', verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    sct.generate_output_file(path_tmp+'b0.nii', path_out+'b0'+ext_data, verbose)
    sct.generate_output_file(path_tmp+'dwi.nii', path_out+'dwi'+ext_data, verbose)
    if average:
        sct.generate_output_file(path_tmp+'b0_mean.nii', path_out+'b0_mean'+ext_data, verbose)
        sct.generate_output_file(path_tmp+'dwi_mean.nii', path_out+'dwi_mean'+ext_data, verbose)

    # Remove temporary files
    if remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...', verbose)
        sct.run('rm -rf '+path_tmp, verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s', verbose)

    # to view results
    sct.printv('\nTo view results, type: ', verbose)
    if average:
        sct.printv('fslview b0 b0_mean dwi dwi_mean &\n', verbose)
    else:
        sct.printv('fslview b0 dwi &\n', verbose)
コード例 #7
0
def main(args=None):

    # initialization
    start_time = time.time()
    param = Param()

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    param.fname_data = arguments['-i']
    if '-g' in arguments:
        param.group_size = arguments['-g']
    if '-m' in arguments:
        param.fname_mask = arguments['-m']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-x' in arguments:
        param.interp = arguments['-x']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-r' in arguments:
        param.remove_temp_files = int(arguments['-r'])
    if '-v' in arguments:
        param.verbose = int(arguments['-v'])

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  input file ............' + param.fname_data, param.verbose)

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    path_tmp = sct.tmp_create(basename="fmri_moco", verbose=param.verbose)

    # Copying input data to tmp folder and convert to nii
    # TODO: no need to do that (takes time for nothing)
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(param.fname_data, os.path.join(path_tmp, "fmri.nii"), squeeze_data=False)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # run moco
    fmri_moco(param)

    # come back
    os.chdir(curdir)

    # Generate output files
    fname_fmri_moco = os.path.join(path_out, file_data + param.suffix + ext_data)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    if os.path.isfile(os.path.join(path_tmp, "fmri" + param.suffix + '.nii')):
        sct.printv(os.path.join(path_tmp, "fmri" + param.suffix + '.nii'))
        sct.printv(os.path.join(path_out, file_data + param.suffix + ext_data))
    sct.generate_output_file(os.path.join(path_tmp, "fmri" + param.suffix + '.nii'), os.path.join(path_out, file_data + param.suffix + ext_data), param.verbose)
    sct.generate_output_file(os.path.join(path_tmp, "fmri" + param.suffix + '_mean.nii'), os.path.join(path_out, file_data + param.suffix + '_mean' + ext_data), param.verbose)

    # Delete temporary files
    if param.remove_temp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.rmtree(path_tmp, verbose=param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's', param.verbose)

    sct.display_viewer_syntax([fname_fmri_moco, file_data], mode='ortho,ortho')
コード例 #8
0
def create_mask(param):
    fsloutput = 'export FSLOUTPUTTYPE=NIFTI; '  # for faster processing, all outputs are in NIFTI

    # parse argument for method
    method_type = param.process[0]
    # check method val
    if not method_type == 'center':
        method_val = param.process[1]

    # check existence of input files
    if method_type == 'centerline':
        sct.check_file_exist(method_val, param.verbose)

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    # Get output folder and file name
    if param.fname_out == '':
        param.fname_out = param.file_prefix + file_data + ext_data

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.tmp_create(param.verbose)
    # )sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    # sct.run('mkdir '+path_tmp, param.verbose)

    sct.printv('\nCheck orientation...', param.verbose)
    orientation_input = get_orientation(Image(param.fname_data))
    sct.printv('.. ' + orientation_input, param.verbose)
    reorient_coordinates = False

    # copy input data to tmp folder
    convert(param.fname_data, path_tmp + 'data.nii')
    if method_type == 'centerline':
        convert(method_val, path_tmp + 'centerline.nii.gz')
    if method_type == 'point':
        convert(method_val, path_tmp + 'point.nii.gz')

    # go to tmp folder
    os.chdir(path_tmp)

    # reorient to RPI
    sct.printv('\nReorient to RPI...', param.verbose)
    # if not orientation_input == 'RPI':
    sct.run('sct_image -i data.nii -o data_RPI.nii -setorient RPI -v 0',
            verbose=False)
    if method_type == 'centerline':
        sct.run(
            'sct_image -i centerline.nii.gz -o centerline_RPI.nii.gz -setorient RPI -v 0',
            verbose=False)
    if method_type == 'point':
        sct.run(
            'sct_image -i point.nii.gz -o point_RPI.nii.gz -setorient RPI -v 0',
            verbose=False)
    #
    # if method_type == 'centerline':
    #     orientation_centerline = get_orientation_3d(method_val, filename=True)
    #     if not orientation_centerline == 'RPI':
    #         sct.run('sct_image -i ' + method_val + ' -o ' + path_tmp + 'centerline.nii.gz' + ' -setorient RPI -v 0', verbose=False)
    #     else:
    #         convert(method_val, path_tmp+'centerline.nii.gz')

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data_RPI.nii').dim
    sct.printv(
        '  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt),
        param.verbose)
    # in case user input 4d data
    if nt != 1:
        sct.printv(
            'WARNING in ' + os.path.basename(__file__) +
            ': Input image is 4d but output mask will 3D.', param.verbose,
            'warning')
        # extract first volume to have 3d reference
        nii = Image('data_RPI.nii')
        data3d = nii.data[:, :, :, 0]
        nii.data = data3d
        nii.save()

    if method_type == 'coord':
        # parse to get coordinate
        coord = map(int, method_val.split('x'))

    if method_type == 'point':
        # get file name
        fname_point = method_val
        # extract coordinate of point
        sct.printv('\nExtract coordinate of point...', param.verbose)
        # TODO: change this way to remove dependence to sct.run. ProcessLabels.display_voxel returns list of coordinates
        status, output = sct.run(
            'sct_label_utils -i point_RPI.nii.gz -display', param.verbose)
        # parse to get coordinate
        coord = output[output.find('Position=') + 10:-17].split(',')

    if method_type == 'center':
        # set coordinate at center of FOV
        coord = round(float(nx) / 2), round(float(ny) / 2)

    if method_type == 'centerline':
        # get name of centerline from user argument
        fname_centerline = 'centerline_RPI.nii.gz'
    else:
        # generate volume with line along Z at coordinates 'coord'
        sct.printv('\nCreate line...', param.verbose)
        fname_centerline = create_line(param, 'data_RPI.nii', coord, nz)

    # create mask
    sct.printv('\nCreate mask...', param.verbose)
    centerline = nibabel.load(fname_centerline)  # open centerline
    hdr = centerline.get_header()  # get header
    hdr.set_data_dtype('uint8')  # set imagetype to uint8
    spacing = hdr.structarr['pixdim']
    data_centerline = centerline.get_data()  # get centerline
    # if data is 2D, reshape with empty third dimension
    if len(data_centerline.shape) == 2:
        data_centerline_shape = list(data_centerline.shape)
        data_centerline_shape.append(1)
        data_centerline = data_centerline.reshape(data_centerline_shape)
    z_centerline_not_null = [
        iz for iz in range(0, nz, 1) if data_centerline[:, :, iz].any()
    ]
    # get center of mass of the centerline
    cx = [0] * nz
    cy = [0] * nz
    for iz in range(0, nz, 1):
        if iz in z_centerline_not_null:
            cx[iz], cy[iz] = ndimage.measurements.center_of_mass(
                numpy.array(data_centerline[:, :, iz]))
    # create 2d masks
    file_mask = 'data_mask'
    for iz in range(nz):
        if iz not in z_centerline_not_null:
            # write an empty nifty volume
            img = nibabel.Nifti1Image(data_centerline[:, :, iz], None, hdr)
            nibabel.save(img, (file_mask + str(iz) + '.nii'))
        else:
            center = numpy.array([cx[iz], cy[iz]])
            mask2d = create_mask2d(param,
                                   center,
                                   param.shape,
                                   param.size,
                                   nx,
                                   ny,
                                   even=param.even,
                                   spacing=spacing)
            # Write NIFTI volumes
            img = nibabel.Nifti1Image(mask2d, None, hdr)
            nibabel.save(img, (file_mask + str(iz) + '.nii'))
    # merge along Z
    # cmd = 'fslmerge -z mask '

    # CHANGE THAT CAN IMPACT SPEED:
    # related to issue #755, we cannot open more than 256 files at one time.
    # to solve this issue, we do not open more than 100 files
    '''
    im_list = []
    im_temp = []
    for iz in range(nz_not_null):
        if iz != 0 and iz % 100 == 0:
            im_temp.append(concat_data(im_list, 2))
            im_list = [Image(file_mask + str(iz) + '.nii')]
        else:
            im_list.append(Image(file_mask+str(iz)+'.nii'))

    if im_temp:
        im_temp.append(concat_data(im_list, 2))
        im_out = concat_data(im_temp, 2, no_expand=True)
    else:
        im_out = concat_data(im_list, 2)
    '''
    fname_list = [file_mask + str(iz) + '.nii' for iz in range(nz)]
    im_out = concat_data(fname_list, dim=2)
    im_out.setFileName('mask_RPI.nii.gz')
    im_out.save()

    # reorient if necessary
    # if not orientation_input == 'RPI':
    sct.run(
        'sct_image -i mask_RPI.nii.gz -o mask.nii.gz -setorient ' +
        orientation_input, param.verbose)

    # copy header input --> mask
    im_dat = Image('data.nii')
    im_mask = Image('mask.nii.gz')
    im_mask = copy_header(im_dat, im_mask)
    im_mask.save()

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp + 'mask.nii.gz', param.fname_out)

    # Remove temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...', param.verbose)
        sct.run('rm -rf ' + path_tmp, param.verbose, error_exit='warning')

    # to view results
    sct.printv('\nDone! To view results, type:', param.verbose)
    sct.printv(
        'fslview ' + param.fname_data + ' ' + param.fname_out +
        ' -l Red -t 0.5 &', param.verbose, 'info')
コード例 #9
0
def main(args=None):
    if args is None:
        args = sys.argv[1:]

    # initialize parameters
    param = Param()

    # Initialization
    fname_output = ''
    path_out = ''
    fname_src_seg = ''
    fname_dest_seg = ''
    fname_src_label = ''
    fname_dest_label = ''
    generate_warpinv = 1

    start_time = time.time()
    # get path of the toolbox
    status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # get default registration parameters
    # step1 = Paramreg(step='1', type='im', algo='syn', metric='MI', iter='5', shrink='1', smooth='0', gradStep='0.5')
    step0 = Paramreg(
        step='0',
        type='im',
        algo='syn',
        metric='MI',
        iter='0',
        shrink='1',
        smooth='0',
        gradStep='0.5',
        slicewise='0',
        dof='Tx_Ty_Tz_Rx_Ry_Rz')  # only used to put src into dest space
    step1 = Paramreg(step='1', type='im')
    paramreg = ParamregMultiStep([step0, step1])

    parser = get_parser(paramreg=paramreg)

    arguments = parser.parse(args)

    # get arguments
    fname_src = arguments['-i']
    fname_dest = arguments['-d']
    if '-iseg' in arguments:
        fname_src_seg = arguments['-iseg']
    if '-dseg' in arguments:
        fname_dest_seg = arguments['-dseg']
    if '-ilabel' in arguments:
        fname_src_label = arguments['-ilabel']
    if '-dlabel' in arguments:
        fname_dest_label = arguments['-dlabel']
    if '-o' in arguments:
        fname_output = arguments['-o']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-owarp' in arguments:
        fname_output_warp = arguments['-owarp']
    else:
        fname_output_warp = ''
    if '-initwarp' in arguments:
        fname_initwarp = os.path.abspath(arguments['-initwarp'])
    else:
        fname_initwarp = ''
    if '-initwarpinv' in arguments:
        fname_initwarpinv = os.path.abspath(arguments['-initwarpinv'])
    else:
        fname_initwarpinv = ''
    if '-m' in arguments:
        fname_mask = arguments['-m']
    else:
        fname_mask = ''
    padding = arguments['-z']
    if "-param" in arguments:
        paramreg_user = arguments['-param']
        # update registration parameters
        for paramStep in paramreg_user:
            paramreg.addStep(paramStep)

    identity = int(arguments['-identity'])
    interp = arguments['-x']
    remove_temp_files = int(arguments['-r'])
    verbose = int(arguments['-v'])

    # sct.printv(arguments)
    sct.printv('\nInput parameters:')
    sct.printv('  Source .............. ' + fname_src)
    sct.printv('  Destination ......... ' + fname_dest)
    sct.printv('  Init transfo ........ ' + fname_initwarp)
    sct.printv('  Mask ................ ' + fname_mask)
    sct.printv('  Output name ......... ' + fname_output)
    # sct.printv('  Algorithm ........... '+paramreg.algo)
    # sct.printv('  Number of iterations  '+paramreg.iter)
    # sct.printv('  Metric .............. '+paramreg.metric)
    sct.printv('  Remove temp files ... ' + str(remove_temp_files))
    sct.printv('  Verbose ............. ' + str(verbose))

    # update param
    param.verbose = verbose
    param.padding = padding
    param.fname_mask = fname_mask
    param.remove_temp_files = remove_temp_files

    # Get if input is 3D
    sct.printv('\nCheck if input data are 3D...', verbose)
    sct.check_if_3d(fname_src)
    sct.check_if_3d(fname_dest)

    # Check if user selected type=seg, but did not input segmentation data
    if 'paramreg_user' in locals():
        if True in [
                'type=seg' in paramreg_user[i]
                for i in range(len(paramreg_user))
        ]:
            if fname_src_seg == '' or fname_dest_seg == '':
                sct.printv(
                    '\nERROR: if you select type=seg you must specify -iseg and -dseg flags.\n',
                    1, 'error')

    # Extract path, file and extension
    path_src, file_src, ext_src = sct.extract_fname(fname_src)
    path_dest, file_dest, ext_dest = sct.extract_fname(fname_dest)

    # check if source and destination images have the same name (related to issue #373)
    # If so, change names to avoid conflict of result files and warns the user
    suffix_src, suffix_dest = '_reg', '_reg'
    if file_src == file_dest:
        suffix_src, suffix_dest = '_src_reg', '_dest_reg'

    # define output folder and file name
    if fname_output == '':
        path_out = '' if not path_out else path_out  # output in user's current directory
        file_out = file_src + suffix_src
        file_out_inv = file_dest + suffix_dest
        ext_out = ext_src
    else:
        path, file_out, ext_out = sct.extract_fname(fname_output)
        path_out = path if not path_out else path_out
        file_out_inv = file_out + '_inv'

    # create QC folder
    sct.create_folder(param.path_qc)

    # create temporary folder
    path_tmp = sct.tmp_create()

    # copy files to temporary folder
    from sct_convert import convert
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               verbose)
    convert(fname_src, path_tmp + 'src.nii')
    convert(fname_dest, path_tmp + 'dest.nii')

    if fname_src_seg:
        convert(fname_src_seg, path_tmp + 'src_seg.nii')
        convert(fname_dest_seg, path_tmp + 'dest_seg.nii')

    if fname_src_label:
        convert(fname_src_label, path_tmp + 'src_label.nii')
        convert(fname_dest_label, path_tmp + 'dest_label.nii')

    if fname_mask != '':
        convert(fname_mask, path_tmp + 'mask.nii.gz')

    # go to tmp folder
    os.chdir(path_tmp)

    # reorient destination to RPI
    sct.run('sct_image -i dest.nii -setorient RPI -o dest_RPI.nii')
    if fname_dest_seg:
        sct.run('sct_image -i dest_seg.nii -setorient RPI -o dest_seg_RPI.nii')
    if fname_dest_label:
        sct.run(
            'sct_image -i dest_label.nii -setorient RPI -o dest_label_RPI.nii')

    if identity:
        # overwrite paramreg and only do one identity transformation
        step0 = Paramreg(step='0',
                         type='im',
                         algo='syn',
                         metric='MI',
                         iter='0',
                         shrink='1',
                         smooth='0',
                         gradStep='0.5')
        paramreg = ParamregMultiStep([step0])

    # Put source into destination space using header (no estimation -- purely based on header)
    # TODO: Check if necessary to do that
    # TODO: use that as step=0
    # sct.printv('\nPut source into destination space using header...', verbose)
    # sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[dest_pad.nii,src.nii,1,16] -c 0 -f 1 -s 0 -o [regAffine,src_regAffine.nii] -n BSpline[3]', verbose)
    # if segmentation, also do it for seg

    # initialize list of warping fields
    warp_forward = []
    warp_inverse = []

    # initial warping is specified, update list of warping fields and skip step=0
    if fname_initwarp:
        sct.printv('\nSkip step=0 and replace with initial transformations: ',
                   param.verbose)
        sct.printv('  ' + fname_initwarp, param.verbose)
        # sct.run('cp '+fname_initwarp+' warp_forward_0.nii.gz', verbose)
        warp_forward = [fname_initwarp]
        start_step = 1
        if fname_initwarpinv:
            warp_inverse = [fname_initwarpinv]
        else:
            sct.printv(
                '\nWARNING: No initial inverse warping field was specified, therefore the inverse warping field will NOT be generated.',
                param.verbose, 'warning')
            generate_warpinv = 0
    else:
        start_step = 0

    # loop across registration steps
    for i_step in range(start_step, len(paramreg.steps)):
        sct.printv('\n--\nESTIMATE TRANSFORMATION FOR STEP #' + str(i_step),
                   param.verbose)
        # identify which is the src and dest
        if paramreg.steps[str(i_step)].type == 'im':
            src = 'src.nii'
            dest = 'dest_RPI.nii'
            interp_step = 'spline'
        elif paramreg.steps[str(i_step)].type == 'seg':
            src = 'src_seg.nii'
            dest = 'dest_seg_RPI.nii'
            interp_step = 'nn'
        elif paramreg.steps[str(i_step)].type == 'label':
            src = 'src_label.nii'
            dest = 'dest_label_RPI.nii'
            interp_step = 'nn'
        else:
            # src = dest = interp_step = None
            sct.printv('ERROR: Wrong image type.', 1, 'error')
        # if step>0, apply warp_forward_concat to the src image to be used
        if i_step > 0:
            sct.printv('\nApply transformation from previous step',
                       param.verbose)
            sct.run(
                'sct_apply_transfo -i ' + src + ' -d ' + dest + ' -w ' +
                ','.join(warp_forward) + ' -o ' + sct.add_suffix(src, '_reg') +
                ' -x ' + interp_step, verbose)
            src = sct.add_suffix(src, '_reg')
        # register src --> dest
        warp_forward_out, warp_inverse_out = register(src, dest, paramreg,
                                                      param, str(i_step))
        warp_forward.append(warp_forward_out)
        warp_inverse.insert(0, warp_inverse_out)

    # Concatenate transformations
    sct.printv('\nConcatenate transformations...', verbose)
    sct.run(
        'sct_concat_transfo -w ' + ','.join(warp_forward) +
        ' -d dest.nii -o warp_src2dest.nii.gz', verbose)
    sct.run(
        'sct_concat_transfo -w ' + ','.join(warp_inverse) +
        ' -d src.nii -o warp_dest2src.nii.gz', verbose)

    # Apply warping field to src data
    sct.printv('\nApply transfo source --> dest...', verbose)
    sct.run(
        'sct_apply_transfo -i src.nii -o src_reg.nii -d dest.nii -w warp_src2dest.nii.gz -x '
        + interp, verbose)
    sct.printv('\nApply transfo dest --> source...', verbose)
    sct.run(
        'sct_apply_transfo -i dest.nii -o dest_reg.nii -d src.nii -w warp_dest2src.nii.gz -x '
        + interp, verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    # generate: src_reg
    fname_src2dest = sct.generate_output_file(path_tmp + 'src_reg.nii',
                                              path_out + file_out + ext_out,
                                              verbose)
    # generate: forward warping field
    if fname_output_warp == '':
        fname_output_warp = path_out + 'warp_' + file_src + '2' + file_dest + '.nii.gz'
    sct.generate_output_file(path_tmp + 'warp_src2dest.nii.gz',
                             fname_output_warp, verbose)
    if generate_warpinv:
        # generate: dest_reg
        fname_dest2src = sct.generate_output_file(
            path_tmp + 'dest_reg.nii', path_out + file_out_inv + ext_dest,
            verbose)
        # generate: inverse warping field
        sct.generate_output_file(
            path_tmp + 'warp_dest2src.nii.gz',
            path_out + 'warp_' + file_dest + '2' + file_src + '.nii.gz',
            verbose)

    # Delete temporary files
    if remove_temp_files:
        sct.printv('\nRemove temporary files...', verbose)
        sct.run('rm -rf ' + path_tmp, verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv(
        '\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) + 's',
        verbose)
    sct.printv('\nTo view results, type:', verbose)
    if generate_warpinv:
        sct.printv('fslview ' + fname_src + ' ' + fname_dest2src + ' &',
                   verbose, 'info')
    sct.printv('fslview ' + fname_dest + ' ' + fname_src2dest + ' &\n',
               verbose, 'info')
コード例 #10
0
def moco(param):

    # retrieve parameters
    file_data = param.file_data
    file_target = param.file_target
    folder_mat = param.mat_moco  # output folder of mat file
    todo = param.todo
    suffix = param.suffix
    verbose = param.verbose

    # other parameters
    file_mask = 'mask.nii'

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  Input file ............' + file_data, param.verbose)
    sct.printv('  Reference file ........' + file_target, param.verbose)
    sct.printv('  Polynomial degree .....' + param.poly, param.verbose)
    sct.printv('  Smoothing kernel ......' + param.smooth, param.verbose)
    sct.printv('  Gradient step .........' + param.gradStep, param.verbose)
    sct.printv('  Metric ................' + param.metric, param.verbose)
    sct.printv('  Sampling ..............' + param.sampling, param.verbose)
    sct.printv('  Todo ..................' + todo, param.verbose)
    sct.printv('  Mask  .................' + param.fname_mask, param.verbose)
    sct.printv('  Output mat folder .....' + folder_mat, param.verbose)

    # create folder for mat files
    sct.create_folder(folder_mat)

    # Get size of data
    sct.printv('\nData dimensions:', verbose)
    im_data = Image(param.file_data)
    nx, ny, nz, nt, px, py, pz, pt = im_data.dim
    sct.printv(
        ('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt)),
        verbose)

    # copy file_target to a temporary file
    sct.printv('\nCopy file_target to a temporary file...', verbose)
    file_target = "target.nii.gz"
    convert(param.file_target, file_target)

    # If scan is sagittal, split src and target along Z (slice)
    if param.is_sagittal:
        dim_sag = 2  # TODO: find it
        # z-split data (time series)
        im_z_list = split_data(im_data, dim=dim_sag, squeeze_data=False)
        file_data_splitZ = []
        for im_z in im_z_list:
            im_z.save()
            file_data_splitZ.append(im_z.absolutepath)
        # z-split target
        im_targetz_list = split_data(Image(file_target),
                                     dim=dim_sag,
                                     squeeze_data=False)
        file_target_splitZ = []
        for im_targetz in im_targetz_list:
            im_targetz.save()
            file_target_splitZ.append(im_targetz.absolutepath)
        # z-split mask (if exists)
        if not param.fname_mask == '':
            im_maskz_list = split_data(Image(file_mask),
                                       dim=dim_sag,
                                       squeeze_data=False)
            file_mask_splitZ = []
            for im_maskz in im_maskz_list:
                im_maskz.save()
                file_mask_splitZ.append(im_maskz.absolutepath)
        # initialize file list for output matrices
        file_mat = np.empty((nz, nt), dtype=object)

    # axial orientation
    else:
        file_data_splitZ = [file_data]  # TODO: make it absolute like above
        file_target_splitZ = [file_target]  # TODO: make it absolute like above
        # initialize file list for output matrices
        file_mat = np.empty((1, nt), dtype=object)

        # deal with mask
        if not param.fname_mask == '':
            convert(param.fname_mask, file_mask, squeeze_data=False)
            im_maskz_list = [Image(file_mask)
                             ]  # use a list with single element

    # Loop across file list, where each file is either a 2D volume (if sagittal) or a 3D volume (otherwise)
    # file_mat = tuple([[[] for i in range(nt)] for i in range(nz)])

    file_data_splitZ_moco = []
    sct.printv(
        '\nRegister. Loop across Z (note: there is only one Z if orientation is axial'
    )
    for file in file_data_splitZ:
        iz = file_data_splitZ.index(file)
        # Split data along T dimension
        # sct.printv('\nSplit data along T dimension.', verbose)
        im_z = Image(file)
        list_im_zt = split_data(im_z, dim=3)
        file_data_splitZ_splitT = []
        for im_zt in list_im_zt:
            im_zt.save(verbose=0)
            file_data_splitZ_splitT.append(im_zt.absolutepath)
        # file_data_splitT = file_data + '_T'

        # Motion correction: initialization
        index = np.arange(nt)
        file_data_splitT_num = []
        file_data_splitZ_splitT_moco = []
        failed_transfo = [0 for i in range(nt)]

        # Motion correction: Loop across T
        for indice_index in tqdm(range(nt),
                                 unit='iter',
                                 unit_scale=False,
                                 desc="Z=" + str(iz) + "/" +
                                 str(len(file_data_splitZ) - 1),
                                 ascii=True,
                                 ncols=80):

            # create indices and display stuff
            it = index[indice_index]
            file_mat[iz][it] = os.path.join(
                folder_mat,
                "mat.Z") + str(iz).zfill(4) + 'T' + str(it).zfill(4)
            file_data_splitZ_splitT_moco.append(
                sct.add_suffix(file_data_splitZ_splitT[it], '_moco'))
            # deal with masking
            if not param.fname_mask == '':
                input_mask = im_maskz_list[iz]
            else:
                input_mask = None
            # run 3D registration
            failed_transfo[it] = register(param,
                                          file_data_splitZ_splitT[it],
                                          file_target_splitZ[iz],
                                          file_mat[iz][it],
                                          file_data_splitZ_splitT_moco[it],
                                          im_mask=input_mask)

            # average registered volume with target image
            # N.B. use weighted averaging: (target * nb_it + moco) / (nb_it + 1)
            if param.iterAvg and indice_index < 10 and failed_transfo[
                    it] == 0 and not param.todo == 'apply':
                im_targetz = Image(file_target_splitZ[iz])
                data_targetz = im_targetz.data
                data_mocoz = Image(file_data_splitZ_splitT_moco[it]).data
                data_targetz = (data_targetz * (indice_index + 1) +
                                data_mocoz) / (indice_index + 2)
                im_targetz.data = data_targetz
                im_targetz.save(verbose=0)

        # Replace failed transformation with the closest good one
        fT = [i for i, j in enumerate(failed_transfo) if j == 1]
        gT = [i for i, j in enumerate(failed_transfo) if j == 0]
        for it in range(len(fT)):
            abs_dist = [np.abs(gT[i] - fT[it]) for i in range(len(gT))]
            if not abs_dist == []:
                index_good = abs_dist.index(min(abs_dist))
                sct.printv(
                    '  transfo #' + str(fT[it]) + ' --> use transfo #' +
                    str(gT[index_good]), verbose)
                # copy transformation
                sct.copy(file_mat[iz][gT[index_good]] + 'Warp.nii.gz',
                         file_mat[iz][fT[it]] + 'Warp.nii.gz')
                # apply transformation
                sct_apply_transfo.main(args=[
                    '-i', file_data_splitZ_splitT[fT[it]], '-d', file_target,
                    '-w', file_mat[iz][fT[it]] + 'Warp.nii.gz', '-o',
                    file_data_splitZ_splitT_moco[fT[it]], '-x', param.interp
                ])
            else:
                # exit program if no transformation exists.
                sct.printv(
                    '\nERROR in ' + os.path.basename(__file__) +
                    ': No good transformation exist. Exit program.\n', verbose,
                    'error')
                sys.exit(2)

        # Merge data along T
        file_data_splitZ_moco.append(sct.add_suffix(file, suffix))
        if todo != 'estimate':
            im_out = concat_data(file_data_splitZ_splitT_moco, 3)
            im_out.save(file_data_splitZ_moco[iz])

    # If sagittal, merge along Z
    if param.is_sagittal:
        im_out = concat_data(file_data_splitZ_moco, 2)
        dirname, basename, ext = sct.extract_fname(file_data)
        path_out = os.path.join(dirname, basename + suffix + ext)
        im_out.save(path_out)

    return file_mat
コード例 #11
0
def check_and_correct_segmentation(fname_segmentation, fname_centerline, folder_output='', threshold_distance=5.0,
                                   remove_temp_files=1, verbose=0):
    """
    This function takes the outputs of isct_propseg (centerline and segmentation) and check if the centerline of the
    segmentation is coherent with the centerline provided by the isct_propseg, especially on the edges (related
    to issue #1074).
    Args:
        fname_segmentation: filename of binary segmentation
        fname_centerline: filename of binary centerline
        threshold_distance: threshold, in mm, beyond which centerlines are not coherent
        verbose:

    Returns: None
    """
    sct.printv('\nCheck consistency of segmentation...', verbose)
    # creating a temporary folder in which all temporary files will be placed and deleted afterwards
    path_tmp = sct.tmp_create(basename="propseg", verbose=verbose)
    from sct_convert import convert
    convert(fname_segmentation, os.path.join(path_tmp, "tmp.segmentation.nii.gz"), verbose=0)
    convert(fname_centerline, os.path.join(path_tmp, "tmp.centerline.nii.gz"), verbose=0)
    fname_seg_absolute = os.path.abspath(fname_segmentation)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # convert segmentation image to RPI
    im_input = Image('tmp.segmentation.nii.gz')
    image_input_orientation = im_input.orientation

    sct_image.main("-i tmp.segmentation.nii.gz -setorient RPI -o tmp.segmentation_RPI.nii.gz -v 0".split())
    sct_image.main("-i tmp.centerline.nii.gz -setorient RPI -o tmp.centerline_RPI.nii.gz -v 0".split())

    # go through segmentation image, and compare with centerline from propseg
    im_seg = Image('tmp.segmentation_RPI.nii.gz')
    im_centerline = Image('tmp.centerline_RPI.nii.gz')

    # Get size of data
    sct.printv('\nGet data dimensions...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = im_seg.dim

    # extraction of centerline provided by isct_propseg and computation of center of mass for each slice
    # the centerline is defined as the center of the tubular mesh outputed by propseg.
    centerline, key_centerline = {}, []
    for i in range(nz):
        slice = im_centerline.data[:, :, i]
        if np.any(slice):
            x_centerline, y_centerline = ndi.measurements.center_of_mass(slice)
            centerline[str(i)] = [x_centerline, y_centerline]
            key_centerline.append(i)

    minz_centerline = np.min(key_centerline)
    maxz_centerline = np.max(key_centerline)
    mid_slice = int((maxz_centerline - minz_centerline) / 2)

    # for each slice of the segmentation, check if only one object is present. If not, remove the slice from segmentation.
    # If only one object (the spinal cord) is present in the slice, check if its center of mass is close to the centerline of isct_propseg.
    slices_to_remove = [False] * nz  # flag that decides if the slice must be removed
    for i in range(minz_centerline, maxz_centerline + 1):
        # extraction of slice
        slice = im_seg.data[:, :, i]
        distance = -1
        label_objects, nb_labels = ndi.label(slice)  # count binary objects in the slice
        if nb_labels > 1:  # if there is more that one object in the slice, the slice is removed from the segmentation
            slices_to_remove[i] = True
        elif nb_labels == 1:  # check if the centerline is coherent with the one from isct_propseg
            x_centerline, y_centerline = ndi.measurements.center_of_mass(slice)
            slice_nearest_coord = min(key_centerline, key=lambda x: abs(x - i))
            coord_nearest_coord = centerline[str(slice_nearest_coord)]
            distance = np.sqrt(((x_centerline - coord_nearest_coord[0]) * px) ** 2 +
                               ((y_centerline - coord_nearest_coord[1]) * py) ** 2 +
                               ((i - slice_nearest_coord) * pz) ** 2)

            if distance >= threshold_distance:  # threshold must be adjusted, default is 5 mm
                slices_to_remove[i] = True

    # Check list of removal and keep one continuous centerline (improve this comment)
    # Method:
    # starting from mid-centerline (in both directions), the first True encountered is applied to all following slices
    slice_to_change = False
    for i in range(mid_slice, nz):
        if slice_to_change:
            slices_to_remove[i] = True
        elif slices_to_remove[i]:
            slice_to_change = True

    slice_to_change = False
    for i in range(mid_slice, 0, -1):
        if slice_to_change:
            slices_to_remove[i] = True
        elif slices_to_remove[i]:
            slice_to_change = True

    for i in range(0, nz):
        # remove the slice
        if slices_to_remove[i]:
            im_seg.data[:, :, i] *= 0

    # saving the image
    im_seg.save('tmp.segmentation_RPI_c.nii.gz')

    # replacing old segmentation with the corrected one
    sct_image.main('-i tmp.segmentation_RPI_c.nii.gz -setorient {} -o {} -v 0'.
                   format(image_input_orientation, fname_seg_absolute).split())

    os.chdir(curdir)

    # display information about how much of the segmentation has been corrected

    # remove temporary files
    if remove_temp_files:
        # sct.printv("\nRemove temporary files...", verbose)
        sct.rmtree(path_tmp)
コード例 #12
0
    def register(self):
        # accentuate separation WM/GM
        self.im_gm = thr_im(self.im_gm, 0.01, self.param.thr)
        self.im_wm = thr_im(self.im_wm, 0.01, self.param.thr)
        self.im_template_gm = thr_im(self.im_template_gm, 0.01, self.param.thr)
        self.im_template_wm = thr_im(self.im_template_wm, 0.01, self.param.thr)

        ## create multilabel images:
        # copy GM images to keep header information
        im_automatic_ml = self.im_gm.copy()
        im_template_ml = self.im_template_gm.copy()

        # create multi-label segmentation with GM*200 + WM*100 (100 and 200 encoded in self.param.gap)
        im_automatic_ml.data = self.param.gap[1] * self.im_gm.data + self.param.gap[0] * self.im_wm.data
        im_template_ml.data = (
            self.param.gap[1] * self.im_template_gm.data + self.param.gap[0] * self.im_template_wm.data
        )

        # set new names
        fname_automatic_ml = "multilabel_automatic_seg.nii.gz"
        fname_template_ml = "multilabel_template_seg.nii.gz"
        im_automatic_ml.setFileName(fname_automatic_ml)
        im_template_ml.setFileName(fname_template_ml)

        # Create temporary folder and put files in it
        tmp_dir = sct.tmp_create()

        path_gm, file_gm, ext_gm = sct.extract_fname(fname_gm)
        path_warp_template2target, file_warp_template2target, ext_warp_template2target = sct.extract_fname(
            self.fname_warp_template2target
        )

        convert(fname_gm, tmp_dir + file_gm + ext_gm)
        convert(fname_warp_template, tmp_dir + file_warp_template2target + ext_warp_template2target, squeeze_data=0)
        if self.fname_warp_target2template is not None:
            path_warp_target2template, file_warp_target2template, ext_warp_target2template = sct.extract_fname(
                self.fname_warp_target2template
            )
            convert(
                self.fname_warp_target2template,
                tmp_dir + file_warp_target2template + ext_warp_target2template,
                squeeze_data=0,
            )

        os.chdir(tmp_dir)
        # save images
        im_automatic_ml.save()
        im_template_ml.save()

        # apply template2image warping field
        if self.apply_warp_template == 1:
            fname_template_ml_new = sct.add_suffix(fname_template_ml, "_r")
            sct.run(
                "sct_apply_transfo -i "
                + fname_template_ml
                + " -d "
                + fname_automatic_ml
                + " -w "
                + file_warp_template2target
                + ext_warp_template2target
                + " -o "
                + fname_template_ml_new
            )
            fname_template_ml = fname_template_ml_new

        nx, ny, nz, nt, px, py, pz, pt = im_automatic_ml.dim
        size_mask = int(22.5 / px)
        fname_mask = "square_mask.nii.gz"
        sct.run(
            "sct_create_mask -i "
            + fname_automatic_ml
            + " -p centerline,"
            + fname_automatic_ml
            + " -f box -size "
            + str(size_mask)
            + " -o "
            + fname_mask
        )

        fname_automatic_ml, xi, xf, yi, yf, zi, zf = crop_im(fname_automatic_ml, fname_mask)
        fname_template_ml, xi, xf, yi, yf, zi, zf = crop_im(fname_template_ml, fname_mask)

        #        fname_automatic_ml_smooth = sct.add_suffix(fname_automatic_ml, '_smooth')
        #        sct.run('sct_maths -i '+fname_automatic_ml+' -smooth '+str(self.param.smooth)+','+str(self.param.smooth)+',0 -o '+fname_automatic_ml_smooth)
        #        fname_automatic_ml = fname_automatic_ml_smooth

        path_automatic_ml, file_automatic_ml, ext_automatic_ml = sct.extract_fname(fname_automatic_ml)
        path_template_ml, file_template_ml, ext_template_ml = sct.extract_fname(fname_template_ml)

        # Register multilabel images together
        cmd_reg = (
            "sct_register_multimodal -i "
            + fname_template_ml
            + " -d "
            + fname_automatic_ml
            + " -param "
            + self.param.param_reg
        )
        if "centermass" in self.param.param_reg:
            fname_template_ml_seg = sct.add_suffix(fname_template_ml, "_bin")
            sct.run("sct_maths -i " + fname_template_ml + " -bin 0 -o " + fname_template_ml_seg)

            fname_automatic_ml_seg = sct.add_suffix(fname_automatic_ml, "_bin")
            # sct.run('sct_maths -i '+fname_automatic_ml+' -thr 50 -o '+fname_automatic_ml_seg)
            sct.run("sct_maths -i " + fname_automatic_ml + " -bin 50 -o " + fname_automatic_ml_seg)

            cmd_reg += " -iseg " + fname_template_ml_seg + " -dseg " + fname_automatic_ml_seg

        sct.run(cmd_reg)
        fname_warp_multilabel_template2auto = "warp_" + file_template_ml + "2" + file_automatic_ml + ".nii.gz"
        fname_warp_multilabel_auto2template = "warp_" + file_automatic_ml + "2" + file_template_ml + ".nii.gz"

        self.fname_warp_template2gm = "warp_template2" + file_gm + ".nii.gz"
        # fname_warp_multilabel_template2auto = pad_im(fname_warp_multilabel_template2auto, nx, ny, nz, xi, xf, yi, yf, zi, zf)
        # fname_warp_multilabel_auto2template = pad_im(fname_warp_multilabel_auto2template, nx, ny, nz, xi, xf, yi, yf, zi, zf)

        sct.run(
            "sct_concat_transfo -w "
            + file_warp_template2target
            + ext_warp_template2target
            + ","
            + fname_warp_multilabel_template2auto
            + " -d "
            + file_gm
            + ext_gm
            + " -o "
            + self.fname_warp_template2gm
        )

        if self.fname_warp_target2template is not None:
            path_script = os.path.dirname(__file__)
            path_sct = os.path.dirname(path_script)
            if self.template == "MNI-Poly-AMU":
                fname_dest = path_sct + "/data/MNI-Poly-AMU/template/MNI-Poly-AMU_T2.nii.gz"
            elif self.template == "PAM50":
                fname_dest = path_sct + "/data/PAM50/template/PAM50_t2.nii.gz"

            self.fname_warp_gm2template = "warp_" + file_gm + "_gm2template.nii.gz"
            sct.run(
                "sct_concat_transfo -w "
                + fname_warp_multilabel_auto2template
                + ","
                + file_warp_target2template
                + ext_warp_target2template
                + " -d "
                + fname_dest
                + " -o "
                + self.fname_warp_gm2template
            )

        os.chdir("..")

        # sct.generate_output_file(tmp_dir+fname_warp_multilabel_template2auto, self.param.output_folder+'warp_template_multilabel2automatic_seg_multilabel.nii.gz')
        # sct.generate_output_file(tmp_dir+fname_warp_multilabel_auto2template, self.param.output_folder+'warp_automatic_seg_multilabel2template_multilabel.nii.gz')

        sct.generate_output_file(
            tmp_dir + self.fname_warp_template2gm, self.param.output_folder + self.fname_warp_template2gm
        )
        if self.fname_warp_target2template is not None:
            sct.generate_output_file(
                tmp_dir + self.fname_warp_gm2template, self.param.output_folder + self.fname_warp_gm2template
            )

        if self.param.qc:
            fname_grid_warped = visualize_warp(
                tmp_dir + fname_warp_multilabel_template2auto, rm_tmp=self.param.remove_tmp
            )
            path_grid_warped, file_grid_warped, ext_grid_warped = sct.extract_fname(fname_grid_warped)
            sct.generate_output_file(fname_grid_warped, self.param.output_folder + file_grid_warped + ext_grid_warped)

        if self.param.remove_tmp:
            sct.run("rm -rf " + tmp_dir, error_exit="warning")
コード例 #13
0
    def apply(self):
        # Initialization
        fname_src = self.input_filename  # source image (moving)
        fname_warp_list = self.warp_input  # list of warping fields
        fname_out = self.output_filename  # output
        fname_dest = self.fname_dest  # destination image (fix)
        verbose = self.verbose
        remove_temp_files = self.remove_temp_files
        crop_reference = self.crop  # if = 1, put 0 everywhere around warping field, if = 2, real crop

        interp = sct.get_interpolation('isct_antsApplyTransforms', self.interp)

        # Parse list of warping fields
        sct.printv('\nParse list of warping fields...', verbose)
        use_inverse = []
        fname_warp_list_invert = []
        # fname_warp_list = fname_warp_list.replace(' ', '')  # remove spaces
        # fname_warp_list = fname_warp_list.split(",")  # parse with comma
        for i in range(len(fname_warp_list)):
            # Check if inverse matrix is specified with '-' at the beginning of file name
            if fname_warp_list[i].find('-') == 0:
                use_inverse.append('-i ')
                fname_warp_list[i] = fname_warp_list[i][1:]  # remove '-'
            else:
                use_inverse.append('')
            sct.printv(
                '  Transfo #' + str(i) + ': ' + use_inverse[i] +
                fname_warp_list[i], verbose)
            fname_warp_list_invert.append(use_inverse[i] + fname_warp_list[i])

        # need to check if last warping field is an affine transfo
        isLastAffine = False
        path_fname, file_fname, ext_fname = sct.extract_fname(
            fname_warp_list_invert[-1])
        if ext_fname in ['.txt', '.mat']:
            isLastAffine = True

        # check if destination file is 3d
        if not sct.check_if_3d(fname_dest):
            sct.printv('ERROR: Destination data must be 3d')

        # N.B. Here we take the inverse of the warp list, because sct_WarpImageMultiTransform concatenates in the reverse order
        fname_warp_list_invert.reverse()

        # Extract path, file and extension
        path_src, file_src, ext_src = sct.extract_fname(fname_src)
        path_dest, file_dest, ext_dest = sct.extract_fname(fname_dest)

        # Get output folder and file name
        if fname_out == '':
            path_out = ''  # output in user's current directory
            file_out = file_src + '_reg'
            ext_out = ext_src
            fname_out = path_out + file_out + ext_out

        # Get dimensions of data
        sct.printv('\nGet dimensions of data...', verbose)
        from msct_image import Image
        nx, ny, nz, nt, px, py, pz, pt = Image(fname_src).dim
        # nx, ny, nz, nt, px, py, pz, pt = sct.get_dimension(fname_src)
        sct.printv(
            '  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' +
            str(nt), verbose)

        # if 3d
        if nt == 1:
            # Apply transformation
            sct.printv('\nApply transformation...', verbose)
            if nz in [0, 1]:
                dim = '2'
            else:
                dim = '3'
            sct.run(
                'isct_antsApplyTransforms -d ' + dim + ' -i ' + fname_src +
                ' -o ' + fname_out + ' -t ' +
                ' '.join(fname_warp_list_invert) + ' -r ' + fname_dest +
                interp, verbose)

        # if 4d, loop across the T dimension
        else:
            # create temporary folder
            sct.printv('\nCreate temporary folder...', verbose)
            path_tmp = sct.slash_at_the_end(
                'tmp.' + time.strftime("%y%m%d%H%M%S"), 1)
            # sct.run('mkdir '+path_tmp, verbose)
            sct.run('mkdir ' + path_tmp, verbose)

            # convert to nifti into temp folder
            sct.printv(
                '\nCopying input data to tmp folder and convert to nii...',
                verbose)
            from sct_convert import convert
            convert(fname_src, path_tmp + 'data.nii', squeeze_data=False)
            sct.run('cp ' + fname_dest + ' ' + path_tmp + file_dest + ext_dest)
            fname_warp_list_tmp = []
            for fname_warp in fname_warp_list:
                path_warp, file_warp, ext_warp = sct.extract_fname(fname_warp)
                sct.run('cp ' + fname_warp + ' ' + path_tmp + file_warp +
                        ext_warp)
                fname_warp_list_tmp.append(file_warp + ext_warp)
            fname_warp_list_invert_tmp = fname_warp_list_tmp[::-1]

            os.chdir(path_tmp)
            # split along T dimension
            sct.printv('\nSplit along T dimension...', verbose)
            from sct_image import split_data
            im_dat = Image('data.nii')
            im_header = im_dat.hdr
            data_split_list = split_data(im_dat, 3)
            for im in data_split_list:
                im.save()

            # apply transfo
            sct.printv('\nApply transformation to each 3D volume...', verbose)
            for it in range(nt):
                file_data_split = 'data_T' + str(it).zfill(4) + '.nii'
                file_data_split_reg = 'data_reg_T' + str(it).zfill(4) + '.nii'
                status, output = sct.run(
                    'isct_antsApplyTransforms -d 3 -i ' + file_data_split +
                    ' -o ' + file_data_split_reg + ' -t ' +
                    ' '.join(fname_warp_list_invert_tmp) + ' -r ' + file_dest +
                    ext_dest + interp, verbose)

            # Merge files back
            sct.printv('\nMerge file back...', verbose)
            from sct_image import concat_data
            import glob
            path_out, name_out, ext_out = sct.extract_fname(fname_out)
            # im_list = [Image(file_name) for file_name in glob.glob('data_reg_T*.nii')]
            # concat_data use to take a list of image in input, now takes a list of file names to open the files one by one (see issue #715)
            fname_list = glob.glob('data_reg_T*.nii')
            im_out = concat_data(fname_list, 3, im_header['pixdim'])
            im_out.setFileName(name_out + ext_out)
            im_out.save(squeeze_data=False)

            os.chdir('..')
            sct.generate_output_file(path_tmp + name_out + ext_out, fname_out)
            # Delete temporary folder if specified
            if int(remove_temp_files):
                sct.printv('\nRemove temporary files...', verbose)
                sct.run('rm -rf ' + path_tmp, verbose, error_exit='warning')

        # 2. crop the resulting image using dimensions from the warping field
        warping_field = fname_warp_list_invert[-1]
        # if last warping field is an affine transfo, we need to compute the space of the concatenate warping field:
        if isLastAffine:
            sct.printv(
                'WARNING: the resulting image could have wrong apparent results. You should use an affine transformation as last transformation...',
                verbose, 'warning')
        elif crop_reference == 1:
            ImageCropper(input_file=fname_out,
                         output_file=fname_out,
                         ref=warping_field,
                         background=0).crop()
            # sct.run('sct_crop_image -i '+fname_out+' -o '+fname_out+' -ref '+warping_field+' -b 0')
        elif crop_reference == 2:
            ImageCropper(input_file=fname_out,
                         output_file=fname_out,
                         ref=warping_field).crop()
            # sct.run('sct_crop_image -i '+fname_out+' -o '+fname_out+' -ref '+warping_field)

        # display elapsed time
        sct.printv('\nDone! To view results, type:', verbose)
        sct.printv('fslview ' + fname_dest + ' ' + fname_out + ' &\n', verbose,
                   'info')
コード例 #14
0
def main():

    # Initialization
    fname_anat = ''
    fname_point = ''
    slice_gap = param.gap
    remove_tmp_files = param.remove_tmp_files
    gaussian_kernel = param.gaussian_kernel
    start_time = time.time()
    verbose = 1

    # get path of the toolbox
    status, path_sct = commands.getstatusoutput('echo $SCT_DIR')
    path_sct = sct.slash_at_the_end(path_sct, 1)

    # Parameters for debug mode
    if param.debug == 1:
        sct.printv('\n*** WARNING: DEBUG MODE ON ***\n\t\t\tCurrent working directory: '+os.getcwd(), 'warning')
        status, path_sct_testing_data = commands.getstatusoutput('echo $SCT_TESTING_DATA_DIR')
        fname_anat = path_sct_testing_data+'/t2/t2.nii.gz'
        fname_point = path_sct_testing_data+'/t2/t2_centerline_init.nii.gz'
        slice_gap = 5

    else:
        # Check input param
        try:
            opts, args = getopt.getopt(sys.argv[1:],'hi:p:g:r:k:')
        except getopt.GetoptError as err:
            print str(err)
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ('-i'):
                fname_anat = arg
            elif opt in ('-p'):
                fname_point = arg
            elif opt in ('-g'):
                slice_gap = int(arg)
            elif opt in ('-r'):
                remove_tmp_files = int(arg)
            elif opt in ('-k'):
                gaussian_kernel = int(arg)

    # display usage if a mandatory argument is not provided
    if fname_anat == '' or fname_point == '':
        usage()

    # check existence of input files
    sct.check_file_exist(fname_anat)
    sct.check_file_exist(fname_point)

    # extract path/file/extension
    path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat)
    path_point, file_point, ext_point = sct.extract_fname(fname_point)

    # extract path of schedule file
    # TODO: include schedule file in sct
    # TODO: check existence of schedule file
    file_schedule = path_sct + param.schedule_file

    # Get input image orientation
    input_image_orientation = get_orientation(fname_anat)

    # Display arguments
    print '\nCheck input arguments...'
    print '  Anatomical image:     '+fname_anat
    print '  Orientation:          '+input_image_orientation
    print '  Point in spinal cord: '+fname_point
    print '  Slice gap:            '+str(slice_gap)
    print '  Gaussian kernel:      '+str(gaussian_kernel)
    print '  Degree of polynomial: '+str(param.deg_poly)

    # create temporary folder
    print('\nCreate temporary folder...')
    path_tmp = 'tmp.'+time.strftime("%y%m%d%H%M%S")
    sct.create_folder(path_tmp)
    print '\nCopy input data...'
    sct.run('cp '+fname_anat+ ' '+path_tmp+'/tmp.anat'+ext_anat)
    sct.run('cp '+fname_point+ ' '+path_tmp+'/tmp.point'+ext_point)

    # go to temporary folder
    os.chdir(path_tmp)

    # convert to nii
    convert('tmp.anat'+ext_anat, 'tmp.anat.nii')
    convert('tmp.point'+ext_point, 'tmp.point.nii')

    # Reorient input anatomical volume into RL PA IS orientation
    print '\nReorient input volume to RL PA IS orientation...'
    #sct.run(sct.fsloutput + 'fslswapdim tmp.anat RL PA IS tmp.anat_orient')
    set_orientation('tmp.anat.nii', 'RPI', 'tmp.anat_orient.nii')
    # Reorient binary point into RL PA IS orientation
    print '\nReorient binary point into RL PA IS orientation...'
    # sct.run(sct.fsloutput + 'fslswapdim tmp.point RL PA IS tmp.point_orient')
    set_orientation('tmp.point.nii', 'RPI', 'tmp.point_orient.nii')

    # Get image dimensions
    print '\nGet image dimensions...'
    nx, ny, nz, nt, px, py, pz, pt = Image('tmp.anat_orient.nii').dim
    print '.. matrix size: '+str(nx)+' x '+str(ny)+' x '+str(nz)
    print '.. voxel size:  '+str(px)+'mm x '+str(py)+'mm x '+str(pz)+'mm'

    # Split input volume
    print '\nSplit input volume...'
    split_data('tmp.anat_orient.nii', 2, '_z')
    file_anat_split = ['tmp.anat_orient_z'+str(z).zfill(4) for z in range(0, nz, 1)]
    split_data('tmp.point_orient.nii', 2, '_z')
    file_point_split = ['tmp.point_orient_z'+str(z).zfill(4) for z in range(0, nz, 1)]

    # Extract coordinates of input point
    # sct.printv('\nExtract the slice corresponding to z='+str(z_init)+'...', verbose)
    #
    data_point = Image('tmp.point_orient.nii').data
    x_init, y_init, z_init = unravel_index(data_point.argmax(), data_point.shape)
    sct.printv('Coordinates of input point: ('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')', verbose)

    # Create 2D gaussian mask
    sct.printv('\nCreate gaussian mask from point...', verbose)
    xx, yy = mgrid[:nx, :ny]
    mask2d = zeros((nx, ny))
    radius = round(float(gaussian_kernel+1)/2)  # add 1 because the radius includes the center.
    sigma = float(radius)
    mask2d = exp(-(((xx-x_init)**2)/(2*(sigma**2)) + ((yy-y_init)**2)/(2*(sigma**2))))

    # Save mask to 2d file
    file_mask_split = ['tmp.mask_orient_z'+str(z).zfill(4) for z in range(0,nz,1)]
    nii_mask2d = Image('tmp.anat_orient_z0000.nii')
    nii_mask2d.data = mask2d
    nii_mask2d.setFileName(file_mask_split[z_init]+'.nii')
    nii_mask2d.save()
    #
    # # Get the coordinates of the input point
    # print '\nGet the coordinates of the input point...'
    # data_point = Image('tmp.point_orient.nii').data
    # x_init, y_init, z_init = unravel_index(data_point.argmax(), data_point.shape)
    # print '('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')'

    # x_init, y_init, z_init = (data > 0).nonzero()
    # x_init = x_init[0]
    # y_init = y_init[0]
    # z_init = z_init[0]
    # print '('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')'
    #
    # numpy.unravel_index(a.argmax(), a.shape)
    #
    # file = nibabel.load('tmp.point_orient.nii')
    # data = file.get_data()
    # x_init, y_init, z_init = (data > 0).nonzero()
    # x_init = x_init[0]
    # y_init = y_init[0]
    # z_init = z_init[0]
    # print '('+str(x_init)+', '+str(y_init)+', '+str(z_init)+')'
    #
    # # Extract the slice corresponding to z=z_init
    # print '\nExtract the slice corresponding to z='+str(z_init)+'...'
    # file_point_split = ['tmp.point_orient_z'+str(z).zfill(4) for z in range(0,nz,1)]
    # nii = Image('tmp.point_orient.nii')
    # data_crop = nii.data[:, :, z_init:z_init+1]
    # nii.data = data_crop
    # nii.setFileName(file_point_split[z_init]+'.nii')
    # nii.save()
    #
    # # Create gaussian mask from point
    # print '\nCreate gaussian mask from point...'
    # file_mask_split = ['tmp.mask_orient_z'+str(z).zfill(4) for z in range(0,nz,1)]
    # sct.run(sct.fsloutput+'fslmaths '+file_point_split[z_init]+' -s '+str(gaussian_kernel)+' '+file_mask_split[z_init])
    #
    # # Obtain max value from mask
    # print '\nFind maximum value from mask...'
    # file = nibabel.load(file_mask_split[z_init]+'.nii')
    # data = file.get_data()
    # max_value_mask = numpy.max(data)
    # print '..'+str(max_value_mask)
    #
    # # Normalize mask beween 0 and 1
    # print '\nNormalize mask beween 0 and 1...'
    # sct.run(sct.fsloutput+'fslmaths '+file_mask_split[z_init]+' -div '+str(max_value_mask)+' '+file_mask_split[z_init])

    ## Take the square of the mask
    #print '\nCalculate the square of the mask...'
    #sct.run(sct.fsloutput+'fslmaths '+file_mask_split[z_init]+' -mul '+file_mask_split[z_init]+' '+file_mask_split[z_init])

    # initialize variables
    file_mat = ['tmp.mat_z'+str(z).zfill(4) for z in range(0,nz,1)]
    file_mat_inv = ['tmp.mat_inv_z'+str(z).zfill(4) for z in range(0,nz,1)]
    file_mat_inv_cumul = ['tmp.mat_inv_cumul_z'+str(z).zfill(4) for z in range(0,nz,1)]

    # create identity matrix for initial transformation matrix
    fid = open(file_mat_inv_cumul[z_init], 'w')
    fid.write('%i %i %i %i\n' %(1, 0, 0, 0) )
    fid.write('%i %i %i %i\n' %(0, 1, 0, 0) )
    fid.write('%i %i %i %i\n' %(0, 0, 1, 0) )
    fid.write('%i %i %i %i\n' %(0, 0, 0, 1) )
    fid.close()

    # initialize centerline: give value corresponding to initial point
    x_centerline = [x_init]
    y_centerline = [y_init]
    z_centerline = [z_init]
    warning_count = 0

    # go up (1), then down (2) in reference to the binary point
    for iUpDown in range(1, 3):

        if iUpDown == 1:
            # z increases
            slice_gap_signed = slice_gap
        elif iUpDown == 2:
            # z decreases
            slice_gap_signed = -slice_gap
            # reverse centerline (because values will be appended at the end)
            x_centerline.reverse()
            y_centerline.reverse()
            z_centerline.reverse()

        # initialization before looping
        z_dest = z_init # point given by user
        z_src = z_dest + slice_gap_signed

        # continue looping if 0 < z < nz
        while 0 <= z_src and z_src <= nz-1:

            # print current z:
            print 'z='+str(z_src)+':'

            # estimate transformation
            sct.run(fsloutput+'flirt -in '+file_anat_split[z_src]+' -ref '+file_anat_split[z_dest]+' -schedule '+file_schedule+ ' -verbose 0 -omat '+file_mat[z_src]+' -cost normcorr -forcescaling -inweight '+file_mask_split[z_dest]+' -refweight '+file_mask_split[z_dest])

            # display transfo
            status, output = sct.run('cat '+file_mat[z_src])
            print output

            # check if transformation is bigger than 1.5x slice_gap
            tx = float(output.split()[3])
            ty = float(output.split()[7])
            norm_txy = linalg.norm([tx, ty],ord=2)
            if norm_txy > 1.5*slice_gap:
                print 'WARNING: Transformation is too large --> using previous one.'
                warning_count = warning_count + 1
                # if previous transformation exists, replace current one with previous one
                if os.path.isfile(file_mat[z_dest]):
                    sct.run('cp '+file_mat[z_dest]+' '+file_mat[z_src])

            # estimate inverse transformation matrix
            sct.run('convert_xfm -omat '+file_mat_inv[z_src]+' -inverse '+file_mat[z_src])

            # compute cumulative transformation
            sct.run('convert_xfm -omat '+file_mat_inv_cumul[z_src]+' -concat '+file_mat_inv[z_src]+' '+file_mat_inv_cumul[z_dest])

            # apply inverse cumulative transformation to initial gaussian mask (to put it in src space)
            sct.run(fsloutput+'flirt -in '+file_mask_split[z_init]+' -ref '+file_mask_split[z_init]+' -applyxfm -init '+file_mat_inv_cumul[z_src]+' -out '+file_mask_split[z_src])

            # open inverse cumulative transformation file and generate centerline
            fid = open(file_mat_inv_cumul[z_src])
            mat = fid.read().split()
            x_centerline.append(x_init + float(mat[3]))
            y_centerline.append(y_init + float(mat[7]))
            z_centerline.append(z_src)
            #z_index = z_index+1

            # define new z_dest (target slice) and new z_src (moving slice)
            z_dest = z_dest + slice_gap_signed
            z_src = z_src + slice_gap_signed


    # Reconstruct centerline
    # ====================================================================================================

    # reverse back centerline (because it's been reversed once, so now all values are in the right order)
    x_centerline.reverse()
    y_centerline.reverse()
    z_centerline.reverse()

    # fit centerline in the Z-X plane using polynomial function
    print '\nFit centerline in the Z-X plane using polynomial function...'
    coeffsx = polyfit(z_centerline, x_centerline, deg=param.deg_poly)
    polyx = poly1d(coeffsx)
    x_centerline_fit = polyval(polyx, z_centerline)
    # calculate RMSE
    rmse = linalg.norm(x_centerline_fit-x_centerline)/sqrt( len(x_centerline) )
    # calculate max absolute error
    max_abs = max( abs(x_centerline_fit-x_centerline) )
    print '.. RMSE (in mm): '+str(rmse*px)
    print '.. Maximum absolute error (in mm): '+str(max_abs*px)

    # fit centerline in the Z-Y plane using polynomial function
    print '\nFit centerline in the Z-Y plane using polynomial function...'
    coeffsy = polyfit(z_centerline, y_centerline, deg=param.deg_poly)
    polyy = poly1d(coeffsy)
    y_centerline_fit = polyval(polyy, z_centerline)
    # calculate RMSE
    rmse = linalg.norm(y_centerline_fit-y_centerline)/sqrt( len(y_centerline) )
    # calculate max absolute error
    max_abs = max( abs(y_centerline_fit-y_centerline) )
    print '.. RMSE (in mm): '+str(rmse*py)
    print '.. Maximum absolute error (in mm): '+str(max_abs*py)

    # display
    if param.debug == 1:
        import matplotlib.pyplot as plt
        plt.figure()
        plt.plot(z_centerline,x_centerline,'.',z_centerline,x_centerline_fit,'r')
        plt.legend(['Data','Polynomial Fit'])
        plt.title('Z-X plane polynomial interpolation')
        plt.show()

        plt.figure()
        plt.plot(z_centerline,y_centerline,'.',z_centerline,y_centerline_fit,'r')
        plt.legend(['Data','Polynomial Fit'])
        plt.title('Z-Y plane polynomial interpolation')
        plt.show()

    # generate full range z-values for centerline
    z_centerline_full = [iz for iz in range(0, nz, 1)]

    # calculate X and Y values for the full centerline
    x_centerline_fit_full = polyval(polyx, z_centerline_full)
    y_centerline_fit_full = polyval(polyy, z_centerline_full)

    # Generate fitted transformation matrices and write centerline coordinates in text file
    print '\nGenerate fitted transformation matrices and write centerline coordinates in text file...'
    file_mat_inv_cumul_fit = ['tmp.mat_inv_cumul_fit_z'+str(z).zfill(4) for z in range(0,nz,1)]
    file_mat_cumul_fit = ['tmp.mat_cumul_fit_z'+str(z).zfill(4) for z in range(0,nz,1)]
    fid_centerline = open('tmp.centerline_coordinates.txt', 'w')
    for iz in range(0, nz, 1):
        # compute inverse cumulative fitted transformation matrix
        fid = open(file_mat_inv_cumul_fit[iz], 'w')
        fid.write('%i %i %i %f\n' %(1, 0, 0, x_centerline_fit_full[iz]-x_init) )
        fid.write('%i %i %i %f\n' %(0, 1, 0, y_centerline_fit_full[iz]-y_init) )
        fid.write('%i %i %i %i\n' %(0, 0, 1, 0) )
        fid.write('%i %i %i %i\n' %(0, 0, 0, 1) )
        fid.close()
        # compute forward cumulative fitted transformation matrix
        sct.run('convert_xfm -omat '+file_mat_cumul_fit[iz]+' -inverse '+file_mat_inv_cumul_fit[iz])
        # write centerline coordinates in x, y, z format
        fid_centerline.write('%f %f %f\n' %(x_centerline_fit_full[iz], y_centerline_fit_full[iz], z_centerline_full[iz]) )
    fid_centerline.close()


    # Prepare output data
    # ====================================================================================================

    # write centerline as text file
    for iz in range(0, nz, 1):
        # compute inverse cumulative fitted transformation matrix
        fid = open(file_mat_inv_cumul_fit[iz], 'w')
        fid.write('%i %i %i %f\n' %(1, 0, 0, x_centerline_fit_full[iz]-x_init) )
        fid.write('%i %i %i %f\n' %(0, 1, 0, y_centerline_fit_full[iz]-y_init) )
        fid.write('%i %i %i %i\n' %(0, 0, 1, 0) )
        fid.write('%i %i %i %i\n' %(0, 0, 0, 1) )
        fid.close()

    # write polynomial coefficients
    savetxt('tmp.centerline_polycoeffs_x.txt',coeffsx)
    savetxt('tmp.centerline_polycoeffs_y.txt',coeffsy)

    # apply transformations to data
    print '\nApply fitted transformation matrices...'
    file_anat_split_fit = ['tmp.anat_orient_fit_z'+str(z).zfill(4) for z in range(0,nz,1)]
    file_mask_split_fit = ['tmp.mask_orient_fit_z'+str(z).zfill(4) for z in range(0,nz,1)]
    file_point_split_fit = ['tmp.point_orient_fit_z'+str(z).zfill(4) for z in range(0,nz,1)]
    for iz in range(0, nz, 1):
        # forward cumulative transformation to data
        sct.run(fsloutput+'flirt -in '+file_anat_split[iz]+' -ref '+file_anat_split[iz]+' -applyxfm -init '+file_mat_cumul_fit[iz]+' -out '+file_anat_split_fit[iz])
        # inverse cumulative transformation to mask
        sct.run(fsloutput+'flirt -in '+file_mask_split[z_init]+' -ref '+file_mask_split[z_init]+' -applyxfm -init '+file_mat_inv_cumul_fit[iz]+' -out '+file_mask_split_fit[iz])
        # inverse cumulative transformation to point
        sct.run(fsloutput+'flirt -in '+file_point_split[z_init]+' -ref '+file_point_split[z_init]+' -applyxfm -init '+file_mat_inv_cumul_fit[iz]+' -out '+file_point_split_fit[iz]+' -interp nearestneighbour')

    # Merge into 4D volume
    print '\nMerge into 4D volume...'
    # sct.run(fsloutput+'fslmerge -z tmp.anat_orient_fit tmp.anat_orient_fit_z*')
    # sct.run(fsloutput+'fslmerge -z tmp.mask_orient_fit tmp.mask_orient_fit_z*')
    # sct.run(fsloutput+'fslmerge -z tmp.point_orient_fit tmp.point_orient_fit_z*')
    concat_data(glob.glob('tmp.anat_orient_fit_z*.nii'), 'tmp.anat_orient_fit.nii', dim=2)
    concat_data(glob.glob('tmp.mask_orient_fit_z*.nii'), 'tmp.mask_orient_fit.nii', dim=2)
    concat_data(glob.glob('tmp.point_orient_fit_z*.nii'), 'tmp.point_orient_fit.nii', dim=2)

    # Copy header geometry from input data
    print '\nCopy header geometry from input data...'
    copy_header('tmp.anat_orient.nii', 'tmp.anat_orient_fit.nii')
    copy_header('tmp.anat_orient.nii', 'tmp.mask_orient_fit.nii')
    copy_header('tmp.anat_orient.nii', 'tmp.point_orient_fit.nii')

    # Reorient outputs into the initial orientation of the input image
    print '\nReorient the centerline into the initial orientation of the input image...'
    set_orientation('tmp.point_orient_fit.nii', input_image_orientation, 'tmp.point_orient_fit.nii')
    set_orientation('tmp.mask_orient_fit.nii', input_image_orientation, 'tmp.mask_orient_fit.nii')

    # Generate output file (in current folder)
    print '\nGenerate output file (in current folder)...'
    os.chdir('..')  # come back to parent folder
    #sct.generate_output_file('tmp.centerline_polycoeffs_x.txt','./','centerline_polycoeffs_x','.txt')
    #sct.generate_output_file('tmp.centerline_polycoeffs_y.txt','./','centerline_polycoeffs_y','.txt')
    #sct.generate_output_file('tmp.centerline_coordinates.txt','./','centerline_coordinates','.txt')
    #sct.generate_output_file('tmp.anat_orient.nii','./',file_anat+'_rpi',ext_anat)
    #sct.generate_output_file('tmp.anat_orient_fit.nii', file_anat+'_rpi_align'+ext_anat)
    #sct.generate_output_file('tmp.mask_orient_fit.nii', file_anat+'_mask'+ext_anat)
    fname_output_centerline = sct.generate_output_file(path_tmp+'/tmp.point_orient_fit.nii', file_anat+'_centerline'+ext_anat)

    # Delete temporary files
    if remove_tmp_files == 1:
        print '\nRemove temporary files...'
        sct.run('rm -rf '+path_tmp)

    # print number of warnings
    print '\nNumber of warnings: '+str(warning_count)+' (if >10, you should probably reduce the gap and/or increase the kernel size'

    # display elapsed time
    elapsed_time = time.time() - start_time
    print '\nFinished! \n\tGenerated file: '+fname_output_centerline+'\n\tElapsed time: '+str(int(round(elapsed_time)))+'s\n'
コード例 #15
0
def main():

    # initialization
    start_time = time.time()
    path_out = '.'
    param_user = ''

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # get path of the toolbox
    status, param.path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Parameters for debug mode
    if param.debug:
        # get path of the testing data
        status, path_sct_data = commands.getstatusoutput('echo $SCT_TESTING_DATA_DIR')
        param.fname_data = path_sct_data+'/dmri/dmri.nii.gz'
        param.fname_bvecs = path_sct_data+'/dmri/bvecs.txt'
        param.fname_mask = path_sct_data+'/dmri/dmri.nii.gz'
        param.remove_tmp_files = 0
        param.verbose = 1
        param.run_eddy = 0
        param.otsu = 0
        param.group_size = 5
        param.iterative_averaging = 1
    else:
        parser = get_parser()
        arguments = parser.parse(sys.argv[1:])

        param.fname_data = arguments['-i']
        param.fname_bvecs = arguments['-bvec']

        if '-bval' in arguments:
            param.fname_bvals = arguments['-bval']
        if '-g' in arguments:
            param.group_size = arguments['-g']
        if 'm' in arguments:
            param.fname_mask = arguments['-m']
        if '-param' in arguments:
            param.param = arguments['-param']
        if '-thr' in arguments:
            param.otsu = arguments['-thr']
        if '-x' in arguments:
            param.interp = arguments['-x']
        if '-ofolder' in arguments:
            path_out = arguments['-ofolder']
        if '-r' in arguments:
            param.remove_tmp_files = int(arguments['-r'])
        if '-v' in arguments:
            param.verbose = int(arguments['-v'])

        '''
            # Some old options that wasn't in the doc ...
            elif opt in ('-e'):
                param.run_eddy = int(arg)
            elif opt in ('-f'):
                param.spline_fitting = int(arg)
        '''

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    if param.fname_bvals != '':
        param.fname_bvals = os.path.abspath(param.fname_bvals)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_mask, file_mask, ext_mask = sct.extract_fname(param.fname_mask)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, param.verbose)

    # names of files in temporary folder
    ext = '.nii'
    dmri_name = 'dmri'
    mask_name = 'mask'
    bvecs_fname = 'bvecs.txt'

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    sct.run('cp '+param.fname_data+' '+path_tmp+dmri_name+ext_data, param.verbose)
    sct.run('cp '+param.fname_bvecs+' '+path_tmp+bvecs_fname, param.verbose)
    if param.fname_mask != '':
        sct.run('cp '+param.fname_mask+' '+path_tmp+mask_name+ext_mask, param.verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # convert dmri to nii format
    convert(dmri_name+ext_data, dmri_name+ext)

    # update field in param (because used later).
    # TODO: make this cleaner...
    if param.fname_mask != '':
        param.fname_mask = mask_name+ext_mask

    # run moco
    dmri_moco(param)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    path_out = sct.slash_at_the_end(path_out, 1)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp+dmri_name+param.suffix+ext, path_out+file_data+param.suffix+ext_data, param.verbose)
    sct.generate_output_file(path_tmp+'b0_mean.nii', path_out+'b0'+param.suffix+'_mean'+ext_data, param.verbose)
    sct.generate_output_file(path_tmp+'dwi_mean.nii', path_out+'dwi'+param.suffix+'_mean'+ext_data, param.verbose)

    # Delete temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.run('rm -rf '+path_tmp, param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s', param.verbose)

    #To view results
    sct.printv('\nTo view results, type:', param.verbose)
    sct.printv('fslview -m ortho,ortho '+param.path_out+file_data+param.suffix+' '+file_data+' &\n', param.verbose, 'info')
コード例 #16
0
def main(args=None):
    import numpy as np
    import spinalcordtoolbox.image as msct_image

    # Initialization
    fname_mt0 = ''
    fname_mt1 = ''
    file_out = param.file_out
    # register = param.register
    # remove_temp_files = param.remove_temp_files
    # verbose = param.verbose

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Check input parameters
    parser = get_parser()
    arguments = parser.parse(args)

    fname_mt0 = arguments['-mt0']
    fname_mt1 = arguments['-mt1']
    remove_temp_files = int(arguments['-r'])
    verbose = int(arguments['-v'])

    # Extract path/file/extension
    path_mt0, file_mt0, ext_mt0 = sct.extract_fname(fname_mt0)
    path_out, file_out, ext_out = '', file_out, ext_mt0

    # create temporary folder
    path_tmp = sct.tmp_create()

    # Copying input data to tmp folder and convert to nii
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               verbose)
    from sct_convert import convert
    convert(fname_mt0, os.path.join(path_tmp, "mt0.nii"), dtype=np.float32)
    convert(fname_mt1, os.path.join(path_tmp, "mt1.nii"), dtype=np.float32)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # compute MTR
    sct.printv('\nCompute MTR...', verbose)
    nii_mt1 = msct_image.Image('mt1.nii')
    data_mt1 = nii_mt1.data
    data_mt0 = msct_image.Image('mt0.nii').data
    data_mtr = 100 * (data_mt0 - data_mt1) / data_mt0
    # save MTR file
    nii_mtr = nii_mt1
    nii_mtr.data = data_mtr
    nii_mtr.save("mtr.nii")
    # sct.run(fsloutput+'fslmaths -dt double mt0.nii -sub mt1.nii -mul 100 -div mt0.nii -thr 0 -uthr 100 mtr.nii', verbose)

    # come back
    os.chdir(curdir)

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    sct.generate_output_file(os.path.join(path_tmp, "mtr.nii"),
                             os.path.join(path_out, file_out + ext_out))

    # Remove temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.rmtree(path_tmp)

    sct.display_viewer_syntax([fname_mt0, fname_mt1, file_out])
コード例 #17
0
def moco(param):

    # retrieve parameters
    file_data = param.file_data
    file_target = param.file_target
    folder_mat = param.mat_moco  # output folder of mat file
    todo = param.todo
    suffix = param.suffix
    verbose = param.verbose

    # other parameters
    file_mask = 'mask.nii'

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  Input file ............' + file_data, param.verbose)
    sct.printv('  Reference file ........' + file_target, param.verbose)
    sct.printv('  Polynomial degree .....' + param.poly, param.verbose)
    sct.printv('  Smoothing kernel ......' + param.smooth, param.verbose)
    sct.printv('  Gradient step .........' + param.gradStep, param.verbose)
    sct.printv('  Metric ................' + param.metric, param.verbose)
    sct.printv('  Sampling ..............' + param.sampling, param.verbose)
    sct.printv('  Todo ..................' + todo, param.verbose)
    sct.printv('  Mask  .................' + param.fname_mask, param.verbose)
    sct.printv('  Output mat folder .....' + folder_mat, param.verbose)

    # create folder for mat files
    sct.create_folder(folder_mat)

    # Get size of data
    sct.printv('\nData dimensions:', verbose)
    im_data = Image(param.file_data)
    nx, ny, nz, nt, px, py, pz, pt = im_data.dim
    sct.printv(('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt)), verbose)

    # copy file_target to a temporary file
    sct.printv('\nCopy file_target to a temporary file...', verbose)
    file_target = "target.nii.gz"
    convert(param.file_target, file_target)

    # If scan is sagittal, split src and target along Z (slice)
    if param.is_sagittal:
        dim_sag = 2  # TODO: find it
        # z-split data (time series)
        im_z_list = split_data(im_data, dim=dim_sag, squeeze_data=False)
        file_data_splitZ = []
        for im_z in im_z_list:
            im_z.save()
            file_data_splitZ.append(im_z.absolutepath)
        # z-split target
        im_targetz_list = split_data(Image(file_target), dim=dim_sag, squeeze_data=False)
        file_target_splitZ = []
        for im_targetz in im_targetz_list:
            im_targetz.save()
            file_target_splitZ.append(im_targetz.absolutepath)
        # z-split mask (if exists)
        if not param.fname_mask == '':
            im_maskz_list = split_data(Image(file_mask), dim=dim_sag, squeeze_data=False)
            file_mask_splitZ = []
            for im_maskz in im_maskz_list:
                im_maskz.save()
                file_mask_splitZ.append(im_maskz.absolutepath)
        # initialize file list for output matrices
        file_mat = np.empty((nz, nt), dtype=object)

    # axial orientation
    else:
        file_data_splitZ = [file_data]  # TODO: make it absolute like above
        file_target_splitZ = [file_target]  # TODO: make it absolute like above
        # initialize file list for output matrices
        file_mat = np.empty((1, nt), dtype=object)

        # deal with mask
        if not param.fname_mask == '':
            convert(param.fname_mask, file_mask, squeeze_data=False)
            im_maskz_list = [Image(file_mask)]  # use a list with single element

    # Loop across file list, where each file is either a 2D volume (if sagittal) or a 3D volume (otherwise)
    # file_mat = tuple([[[] for i in range(nt)] for i in range(nz)])

    file_data_splitZ_moco = []
    sct.printv('\nRegister. Loop across Z (note: there is only one Z if orientation is axial')
    for file in file_data_splitZ:
        iz = file_data_splitZ.index(file)
        # Split data along T dimension
        # sct.printv('\nSplit data along T dimension.', verbose)
        im_z = Image(file)
        list_im_zt = split_data(im_z, dim=3)
        file_data_splitZ_splitT = []
        for im_zt in list_im_zt:
            im_zt.save(verbose=0)
            file_data_splitZ_splitT.append(im_zt.absolutepath)
        # file_data_splitT = file_data + '_T'

        # Motion correction: initialization
        index = np.arange(nt)
        file_data_splitT_num = []
        file_data_splitZ_splitT_moco = []
        failed_transfo = [0 for i in range(nt)]

        # Motion correction: Loop across T
        for indice_index in tqdm(range(nt), unit='iter', unit_scale=False,
                                 desc="Z=" + str(iz) + "/" + str(len(file_data_splitZ)-1), ascii=True, ncols=80):

            # create indices and display stuff
            it = index[indice_index]
            file_mat[iz][it] = os.path.join(folder_mat, "mat.Z") + str(iz).zfill(4) + 'T' + str(it).zfill(4)
            file_data_splitZ_splitT_moco.append(sct.add_suffix(file_data_splitZ_splitT[it], '_moco'))
            # deal with masking
            if not param.fname_mask == '':
                input_mask = im_maskz_list[iz]
            else:
                input_mask = None
            # run 3D registration
            failed_transfo[it] = register(param, file_data_splitZ_splitT[it], file_target_splitZ[iz], file_mat[iz][it],
                                          file_data_splitZ_splitT_moco[it], im_mask=input_mask)

            # average registered volume with target image
            # N.B. use weighted averaging: (target * nb_it + moco) / (nb_it + 1)
            if param.iterAvg and indice_index < 10 and failed_transfo[it] == 0 and not param.todo == 'apply':
                im_targetz = Image(file_target_splitZ[iz])
                data_targetz = im_targetz.data
                data_mocoz = Image(file_data_splitZ_splitT_moco[it]).data
                data_targetz = (data_targetz * (indice_index + 1) + data_mocoz) / (indice_index + 2)
                im_targetz.data = data_targetz
                im_targetz.save(verbose=0)

        # Replace failed transformation with the closest good one
        fT = [i for i, j in enumerate(failed_transfo) if j == 1]
        gT = [i for i, j in enumerate(failed_transfo) if j == 0]
        for it in range(len(fT)):
            abs_dist = [np.abs(gT[i] - fT[it]) for i in range(len(gT))]
            if not abs_dist == []:
                index_good = abs_dist.index(min(abs_dist))
                sct.printv('  transfo #' + str(fT[it]) + ' --> use transfo #' + str(gT[index_good]), verbose)
                # copy transformation
                sct.copy(file_mat[iz][gT[index_good]] + 'Warp.nii.gz', file_mat[iz][fT[it]] + 'Warp.nii.gz')
                # apply transformation
                sct_apply_transfo.main(args=['-i', file_data_splitZ_splitT[fT[it]],
                                             '-d', file_target,
                                             '-w', file_mat[iz][fT[it]] + 'Warp.nii.gz',
                                             '-o', file_data_splitZ_splitT_moco[fT[it]],
                                             '-x', param.interp])
            else:
                # exit program if no transformation exists.
                sct.printv('\nERROR in ' + os.path.basename(__file__) + ': No good transformation exist. Exit program.\n', verbose, 'error')
                sys.exit(2)

        # Merge data along T
        file_data_splitZ_moco.append(sct.add_suffix(file, suffix))
        if todo != 'estimate':
            im_out = concat_data(file_data_splitZ_splitT_moco, 3)
            im_out.save(file_data_splitZ_moco[iz])

    # If sagittal, merge along Z
    if param.is_sagittal:
        im_out = concat_data(file_data_splitZ_moco, 2)
        dirname, basename, ext = sct.extract_fname(file_data)
        path_out = os.path.join(dirname, basename + suffix + ext)
        im_out.save(path_out)

    return file_mat
コード例 #18
0
    def register(self):
        # accentuate separation WM/GM
        self.im_gm = thr_im(self.im_gm, 0.01, self.param.thr)
        self.im_wm = thr_im(self.im_wm, 0.01, self.param.thr)
        self.im_template_gm = thr_im(self.im_template_gm, 0.01, self.param.thr)
        self.im_template_wm = thr_im(self.im_template_wm, 0.01, self.param.thr)

        # create multilabel images:
        # copy GM images to keep header information
        im_automatic_ml = self.im_gm.copy()
        im_template_ml = self.im_template_gm.copy()

        # create multi-label segmentation with GM*200 + WM*100 (100 and 200 encoded in self.param.gap)
        im_automatic_ml.data = self.param.gap[
            1] * self.im_gm.data + self.param.gap[0] * self.im_wm.data
        im_template_ml.data = self.param.gap[
            1] * self.im_template_gm.data + self.param.gap[
                0] * self.im_template_wm.data

        # set new names
        fname_automatic_ml = 'multilabel_automatic_seg.nii.gz'
        fname_template_ml = 'multilabel_template_seg.nii.gz'
        im_automatic_ml.setFileName(fname_automatic_ml)
        im_template_ml.setFileName(fname_template_ml)

        # Create temporary folder and put files in it
        tmp_dir = sct.tmp_create()

        path_gm, file_gm, ext_gm = sct.extract_fname(fname_gm)
        path_warp_template2target, file_warp_template2target, ext_warp_template2target = sct.extract_fname(
            self.fname_warp_template2target)

        convert(fname_gm, tmp_dir + file_gm + ext_gm)
        convert(fname_warp_template,
                tmp_dir + file_warp_template2target + ext_warp_template2target,
                squeeze_data=0)
        if self.fname_warp_target2template is not None:
            path_warp_target2template, file_warp_target2template, ext_warp_target2template = sct.extract_fname(
                self.fname_warp_target2template)
            convert(self.fname_warp_target2template,
                    tmp_dir + file_warp_target2template +
                    ext_warp_target2template,
                    squeeze_data=0)

        os.chdir(tmp_dir)
        # save images
        im_automatic_ml.save()
        im_template_ml.save()

        # apply template2image warping field
        if self.apply_warp_template == 1:
            fname_template_ml_new = sct.add_suffix(fname_template_ml, '_r')
            sct.run('sct_apply_transfo -i ' + fname_template_ml + ' -d ' +
                    fname_automatic_ml + ' -w ' + file_warp_template2target +
                    ext_warp_template2target + ' -o ' + fname_template_ml_new)
            fname_template_ml = fname_template_ml_new

        nx, ny, nz, nt, px, py, pz, pt = im_automatic_ml.dim
        size_mask = int(22.5 / px)
        fname_mask = 'square_mask.nii.gz'
        sct.run('sct_create_mask -i ' + fname_automatic_ml +
                ' -p centerline,' + fname_automatic_ml + ' -f box -size ' +
                str(size_mask) + ' -o ' + fname_mask)

        fname_automatic_ml, xi, xf, yi, yf, zi, zf = crop_im(
            fname_automatic_ml, fname_mask)
        fname_template_ml, xi, xf, yi, yf, zi, zf = crop_im(
            fname_template_ml, fname_mask)

        #        fname_automatic_ml_smooth = sct.add_suffix(fname_automatic_ml, '_smooth')
        #        sct.run('sct_maths -i '+fname_automatic_ml+' -smooth '+str(self.param.smooth)+','+str(self.param.smooth)+',0 -o '+fname_automatic_ml_smooth)
        #        fname_automatic_ml = fname_automatic_ml_smooth

        path_automatic_ml, file_automatic_ml, ext_automatic_ml = sct.extract_fname(
            fname_automatic_ml)
        path_template_ml, file_template_ml, ext_template_ml = sct.extract_fname(
            fname_template_ml)

        # Register multilabel images together
        cmd_reg = 'sct_register_multimodal -i ' + fname_template_ml + ' -d ' + fname_automatic_ml + ' -param ' + self.param.param_reg
        if 'centermass' in self.param.param_reg:
            fname_template_ml_seg = sct.add_suffix(fname_template_ml, '_bin')
            sct.run('sct_maths -i ' + fname_template_ml + ' -bin 0 -o ' +
                    fname_template_ml_seg)

            fname_automatic_ml_seg = sct.add_suffix(fname_automatic_ml, '_bin')
            # sct.run('sct_maths -i '+fname_automatic_ml+' -thr 50 -o '+fname_automatic_ml_seg)
            sct.run('sct_maths -i ' + fname_automatic_ml + ' -bin 50 -o ' +
                    fname_automatic_ml_seg)

            cmd_reg += ' -iseg ' + fname_template_ml_seg + ' -dseg ' + fname_automatic_ml_seg

        sct.run(cmd_reg)
        fname_warp_multilabel_template2auto = 'warp_' + file_template_ml + '2' + file_automatic_ml + '.nii.gz'
        fname_warp_multilabel_auto2template = 'warp_' + file_automatic_ml + '2' + file_template_ml + '.nii.gz'

        self.fname_warp_template2gm = sct.extract_fname(
            self.fname_warp_template2target
        )[1] + '_reg_gm' + sct.extract_fname(
            self.fname_warp_template2target)[2]
        # fname_warp_multilabel_template2auto = pad_im(fname_warp_multilabel_template2auto, nx, ny, nz, xi, xf, yi, yf, zi, zf)
        # fname_warp_multilabel_auto2template = pad_im(fname_warp_multilabel_auto2template, nx, ny, nz, xi, xf, yi, yf, zi, zf)

        sct.run('sct_concat_transfo -w ' + file_warp_template2target +
                ext_warp_template2target + ',' +
                fname_warp_multilabel_template2auto + ' -d ' + file_gm +
                ext_gm + ' -o ' + self.fname_warp_template2gm)

        if self.fname_warp_target2template is not None:
            if self.fname_template_dest is None:
                path_script = os.path.dirname(__file__)
                path_sct = os.path.dirname(path_script)
                if self.template == 'MNI-Poly-AMU':
                    self.fname_template_dest = path_sct + '/data/MNI-Poly-AMU/template/MNI-Poly-AMU_T2.nii.gz'
                elif self.template == 'PAM50':
                    self.fname_template_dest = path_sct + '/data/PAM50/template/PAM50_t2.nii.gz'

            self.fname_warp_gm2template = sct.extract_fname(
                self.fname_warp_target2template
            )[1] + '_reg_gm' + sct.extract_fname(
                self.fname_warp_target2template)[2]
            sct.run('sct_concat_transfo -w ' +
                    fname_warp_multilabel_auto2template + ',' +
                    file_warp_target2template + ext_warp_target2template +
                    ' -d ' + self.fname_template_dest + ' -o ' +
                    self.fname_warp_gm2template)

        os.chdir('..')

        # sct.generate_output_file(tmp_dir+fname_warp_multilabel_template2auto, self.param.output_folder+'warp_template_multilabel2automatic_seg_multilabel.nii.gz')
        # sct.generate_output_file(tmp_dir+fname_warp_multilabel_auto2template, self.param.output_folder+'warp_automatic_seg_multilabel2template_multilabel.nii.gz')

        sct.generate_output_file(
            tmp_dir + self.fname_warp_template2gm,
            self.param.output_folder + self.fname_warp_template2gm)
        if self.fname_warp_target2template is not None:
            sct.generate_output_file(
                tmp_dir + self.fname_warp_gm2template,
                self.param.output_folder + self.fname_warp_gm2template)

        if self.param.qc:
            fname_grid_warped = visualize_warp(
                tmp_dir + fname_warp_multilabel_template2auto,
                rm_tmp=self.param.remove_tmp)
            path_grid_warped, file_grid_warped, ext_grid_warped = sct.extract_fname(
                fname_grid_warped)
            sct.generate_output_file(
                fname_grid_warped,
                self.param.output_folder + file_grid_warped + ext_grid_warped)

        if self.param.remove_tmp:
            sct.run('rm -rf ' + tmp_dir, error_exit='warning')
コード例 #19
0
def main(path_out, param_user):

    # initialization
    start_time = time.time()

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # get path of the toolbox
    status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Parameters for debug mode
    if param.debug:
        # get path of the testing data
        status, path_sct_data = commands.getstatusoutput('echo $SCT_TESTING_DATA_DIR')
        param.fname_data = path_sct_data+'/fmri/fmri.nii.gz'
        #param.fname_mask = path_sct_data+'/fmri/fmri.nii.gz'
        param.verbose = 1
        param.group_size = 3
        #param_user = '******'

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  input file ............'+param.fname_data, param.verbose)

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, param.verbose)

    # Copying input data to tmp folder and convert to nii
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(param.fname_data, path_tmp+'fmri.nii')
    # sct.run('cp '+param.fname_data+' '+path_tmp+'fmri'+ext_data, param.verbose)
    #
    # go to tmp folder
    os.chdir(path_tmp)
    #
    # # convert fmri to nii format
    # convert('fmri'+ext_data, 'fmri.nii')

    # run moco
    fmri_moco(param)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    path_out = sct.slash_at_the_end(path_out, 1)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    if os.path.isfile(path_tmp+'fmri'+param.suffix+'.nii'):
        print path_tmp+'fmri'+param.suffix+'.nii'
        print path_out+file_data+param.suffix+ext_data
    sct.generate_output_file(path_tmp+'fmri'+param.suffix+'.nii', path_out+file_data+param.suffix+ext_data, param.verbose)
    sct.generate_output_file(path_tmp+'fmri'+param.suffix+'_mean.nii', path_out+file_data+param.suffix+'_mean'+ext_data, param.verbose)

    # Delete temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.run('rm -rf '+path_tmp, param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s', param.verbose)

    #To view results
    sct.printv('\nTo view results, type:', param.verbose)
    sct.printv('fslview -m ortho,ortho '+param.path_out+file_data+param.suffix+' '+file_data+' &\n', param.verbose, 'info')
コード例 #20
0
def main():

    # Initialization
    fname_data = ''
    interp_factor = param.interp_factor
    remove_temp_files = param.remove_temp_files
    verbose = param.verbose
    suffix = param.suffix
    smoothing_sigma = param.smoothing_sigma

    # start timer
    start_time = time.time()

    # get path of the toolbox
    path_sct = os.environ.get("SCT_DIR",
                              os.path.dirname(os.path.dirname(__file__)))

    # Parameters for debug mode
    if param.debug:
        fname_data = os.path.join(path_sct, 'testing', 'data', 'errsm_23',
                                  't2', 't2_manual_segmentation.nii.gz')
        remove_temp_files = 0
        param.mask_size = 10
    else:
        # Check input parameters
        try:
            opts, args = getopt.getopt(sys.argv[1:], 'hi:v:r:s:')
        except getopt.GetoptError:
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ('-i'):
                fname_data = arg
            elif opt in ('-r'):
                remove_temp_files = int(arg)
            elif opt in ('-s'):
                smoothing_sigma = arg
            elif opt in ('-v'):
                verbose = int(arg)

    # display usage if a mandatory argument is not provided
    if fname_data == '':
        usage()

    # sct.printv(arguments)
    sct.printv('\nCheck parameters:')
    sct.printv('  segmentation ........... ' + fname_data)
    sct.printv('  interp factor .......... ' + str(interp_factor))
    sct.printv('  smoothing sigma ........ ' + str(smoothing_sigma))

    # check existence of input files
    sct.printv('\nCheck existence of input files...')
    sct.check_file_exist(fname_data, verbose)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    path_tmp = sct.tmp_create(basename="binary_to_trilinear", verbose=verbose)

    from sct_convert import convert
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               param.verbose)
    convert(fname_data, os.path.join(path_tmp, "data.nii"))

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim
    sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), verbose)

    # upsample data
    sct.printv('\nUpsample data...', verbose)
    sct.run([
        "sct_resample", "-i", "data.nii", "-x", "linear", "-vox",
        str(nx * interp_factor) + 'x' + str(ny * interp_factor) + 'x' +
        str(nz * interp_factor), "-o", "data_up.nii"
    ], verbose)

    # Smooth along centerline
    sct.printv('\nSmooth along centerline...', verbose)
    sct.run([
        "sct_smooth_spinalcord", "-i", "data_up.nii", "-s", "data_up.nii",
        "-smooth",
        str(smoothing_sigma), "-r",
        str(remove_temp_files), "-v",
        str(verbose)
    ], verbose)

    # downsample data
    sct.printv('\nDownsample data...', verbose)
    sct.run([
        "sct_resample", "-i", "data_up_smooth.nii", "-x", "linear", "-vox",
        str(nx) + 'x' + str(ny) + 'x' + str(nz), "-o",
        "data_up_smooth_down.nii"
    ], verbose)

    # come back
    os.chdir(curdir)

    # Generate output files
    sct.printv('\nGenerate output files...')
    fname_out = sct.generate_output_file(
        os.path.join(path_tmp, "data_up_smooth_down.nii"),
        '' + file_data + suffix + ext_data)

    # Delete temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.rmtree(path_tmp)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) +
               's')

    # to view results
    sct.printv('\nTo view results, type:')
    sct.printv('fslview ' + file_data + ' ' + file_data + suffix + ' &\n')
コード例 #21
0
def get_centerline_from_point(input_image, point_file, gap=4, gaussian_kernel=4, remove_tmp_files=1):

    # Initialization
    fname_anat = input_image
    fname_point = point_file
    slice_gap = gap
    remove_tmp_files = remove_tmp_files
    gaussian_kernel = gaussian_kernel
    start_time = time()
    verbose = 1

    # get path of the toolbox
    status, path_sct = commands.getstatusoutput("echo $SCT_DIR")
    path_sct = sct.slash_at_the_end(path_sct, 1)

    # Parameters for debug mode
    if param.debug == 1:
        sct.printv("\n*** WARNING: DEBUG MODE ON ***\n\t\t\tCurrent working directory: " + os.getcwd(), "warning")
        status, path_sct_testing_data = commands.getstatusoutput("echo $SCT_TESTING_DATA_DIR")
        fname_anat = path_sct_testing_data + "/t2/t2.nii.gz"
        fname_point = path_sct_testing_data + "/t2/t2_centerline_init.nii.gz"
        slice_gap = 5

    # check existence of input files
    sct.check_file_exist(fname_anat)
    sct.check_file_exist(fname_point)

    # extract path/file/extension
    path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat)
    path_point, file_point, ext_point = sct.extract_fname(fname_point)

    # extract path of schedule file
    # TODO: include schedule file in sct
    # TODO: check existence of schedule file
    file_schedule = path_sct + param.schedule_file

    # Get input image orientation
    input_image_orientation = get_orientation_3d(fname_anat, filename=True)

    # Display arguments
    print "\nCheck input arguments..."
    print "  Anatomical image:     " + fname_anat
    print "  Orientation:          " + input_image_orientation
    print "  Point in spinal cord: " + fname_point
    print "  Slice gap:            " + str(slice_gap)
    print "  Gaussian kernel:      " + str(gaussian_kernel)
    print "  Degree of polynomial: " + str(param.deg_poly)

    # create temporary folder
    print ("\nCreate temporary folder...")
    path_tmp = "tmp." + strftime("%y%m%d%H%M%S")
    sct.create_folder(path_tmp)
    print "\nCopy input data..."
    sct.run("cp " + fname_anat + " " + path_tmp + "/tmp.anat" + ext_anat)
    sct.run("cp " + fname_point + " " + path_tmp + "/tmp.point" + ext_point)

    # go to temporary folder
    os.chdir(path_tmp)

    # convert to nii
    im_anat = convert("tmp.anat" + ext_anat, "tmp.anat.nii")
    im_point = convert("tmp.point" + ext_point, "tmp.point.nii")

    # Reorient input anatomical volume into RL PA IS orientation
    print "\nReorient input volume to RL PA IS orientation..."
    set_orientation(im_anat, "RPI")
    im_anat.setFileName("tmp.anat_orient.nii")
    # Reorient binary point into RL PA IS orientation
    print "\nReorient binary point into RL PA IS orientation..."
    # sct.run(sct.fsloutput + 'fslswapdim tmp.point RL PA IS tmp.point_orient')
    set_orientation(im_point, "RPI")
    im_point.setFileName("tmp.point_orient.nii")

    # Get image dimensions
    print "\nGet image dimensions..."
    nx, ny, nz, nt, px, py, pz, pt = Image("tmp.anat_orient.nii").dim
    print ".. matrix size: " + str(nx) + " x " + str(ny) + " x " + str(nz)
    print ".. voxel size:  " + str(px) + "mm x " + str(py) + "mm x " + str(pz) + "mm"

    # Split input volume
    print "\nSplit input volume..."
    im_anat_split_list = split_data(im_anat, 2)
    file_anat_split = []
    for im in im_anat_split_list:
        file_anat_split.append(im.absolutepath)
        im.save()

    im_point_split_list = split_data(im_point, 2)
    file_point_split = []
    for im in im_point_split_list:
        file_point_split.append(im.absolutepath)
        im.save()

    # Extract coordinates of input point
    data_point = Image("tmp.point_orient.nii").data
    x_init, y_init, z_init = unravel_index(data_point.argmax(), data_point.shape)
    sct.printv("Coordinates of input point: (" + str(x_init) + ", " + str(y_init) + ", " + str(z_init) + ")", verbose)

    # Create 2D gaussian mask
    sct.printv("\nCreate gaussian mask from point...", verbose)
    xx, yy = mgrid[:nx, :ny]
    mask2d = zeros((nx, ny))
    radius = round(float(gaussian_kernel + 1) / 2)  # add 1 because the radius includes the center.
    sigma = float(radius)
    mask2d = exp(-(((xx - x_init) ** 2) / (2 * (sigma ** 2)) + ((yy - y_init) ** 2) / (2 * (sigma ** 2))))

    # Save mask to 2d file
    file_mask_split = ["tmp.mask_orient_Z" + str(z).zfill(4) for z in range(0, nz, 1)]
    nii_mask2d = Image("tmp.anat_orient_Z0000.nii")
    nii_mask2d.data = mask2d
    nii_mask2d.setFileName(file_mask_split[z_init] + ".nii")
    nii_mask2d.save()

    # initialize variables
    file_mat = ["tmp.mat_Z" + str(z).zfill(4) for z in range(0, nz, 1)]
    file_mat_inv = ["tmp.mat_inv_Z" + str(z).zfill(4) for z in range(0, nz, 1)]
    file_mat_inv_cumul = ["tmp.mat_inv_cumul_Z" + str(z).zfill(4) for z in range(0, nz, 1)]

    # create identity matrix for initial transformation matrix
    fid = open(file_mat_inv_cumul[z_init], "w")
    fid.write("%i %i %i %i\n" % (1, 0, 0, 0))
    fid.write("%i %i %i %i\n" % (0, 1, 0, 0))
    fid.write("%i %i %i %i\n" % (0, 0, 1, 0))
    fid.write("%i %i %i %i\n" % (0, 0, 0, 1))
    fid.close()

    # initialize centerline: give value corresponding to initial point
    x_centerline = [x_init]
    y_centerline = [y_init]
    z_centerline = [z_init]
    warning_count = 0

    # go up (1), then down (2) in reference to the binary point
    for iUpDown in range(1, 3):

        if iUpDown == 1:
            # z increases
            slice_gap_signed = slice_gap
        elif iUpDown == 2:
            # z decreases
            slice_gap_signed = -slice_gap
            # reverse centerline (because values will be appended at the end)
            x_centerline.reverse()
            y_centerline.reverse()
            z_centerline.reverse()

        # initialization before looping
        z_dest = z_init  # point given by user
        z_src = z_dest + slice_gap_signed

        # continue looping if 0 <= z < nz
        while 0 <= z_src < nz:

            # print current z:
            print "z=" + str(z_src) + ":"

            # estimate transformation
            sct.run(
                fsloutput
                + "flirt -in "
                + file_anat_split[z_src]
                + " -ref "
                + file_anat_split[z_dest]
                + " -schedule "
                + file_schedule
                + " -verbose 0 -omat "
                + file_mat[z_src]
                + " -cost normcorr -forcescaling -inweight "
                + file_mask_split[z_dest]
                + " -refweight "
                + file_mask_split[z_dest]
            )

            # display transfo
            status, output = sct.run("cat " + file_mat[z_src])
            print output

            # check if transformation is bigger than 1.5x slice_gap
            tx = float(output.split()[3])
            ty = float(output.split()[7])
            norm_txy = linalg.norm([tx, ty], ord=2)
            if norm_txy > 1.5 * slice_gap:
                print "WARNING: Transformation is too large --> using previous one."
                warning_count = warning_count + 1
                # if previous transformation exists, replace current one with previous one
                if os.path.isfile(file_mat[z_dest]):
                    sct.run("cp " + file_mat[z_dest] + " " + file_mat[z_src])

            # estimate inverse transformation matrix
            sct.run("convert_xfm -omat " + file_mat_inv[z_src] + " -inverse " + file_mat[z_src])

            # compute cumulative transformation
            sct.run(
                "convert_xfm -omat "
                + file_mat_inv_cumul[z_src]
                + " -concat "
                + file_mat_inv[z_src]
                + " "
                + file_mat_inv_cumul[z_dest]
            )

            # apply inverse cumulative transformation to initial gaussian mask (to put it in src space)
            sct.run(
                fsloutput
                + "flirt -in "
                + file_mask_split[z_init]
                + " -ref "
                + file_mask_split[z_init]
                + " -applyxfm -init "
                + file_mat_inv_cumul[z_src]
                + " -out "
                + file_mask_split[z_src]
            )

            # open inverse cumulative transformation file and generate centerline
            fid = open(file_mat_inv_cumul[z_src])
            mat = fid.read().split()
            x_centerline.append(x_init + float(mat[3]))
            y_centerline.append(y_init + float(mat[7]))
            z_centerline.append(z_src)
            # z_index = z_index+1

            # define new z_dest (target slice) and new z_src (moving slice)
            z_dest = z_dest + slice_gap_signed
            z_src = z_src + slice_gap_signed

    # Reconstruct centerline
    # ====================================================================================================

    # reverse back centerline (because it's been reversed once, so now all values are in the right order)
    x_centerline.reverse()
    y_centerline.reverse()
    z_centerline.reverse()

    # fit centerline in the Z-X plane using polynomial function
    print "\nFit centerline in the Z-X plane using polynomial function..."
    coeffsx = polyfit(z_centerline, x_centerline, deg=param.deg_poly)
    polyx = poly1d(coeffsx)
    x_centerline_fit = polyval(polyx, z_centerline)
    # calculate RMSE
    rmse = linalg.norm(x_centerline_fit - x_centerline) / sqrt(len(x_centerline))
    # calculate max absolute error
    max_abs = max(abs(x_centerline_fit - x_centerline))
    print ".. RMSE (in mm): " + str(rmse * px)
    print ".. Maximum absolute error (in mm): " + str(max_abs * px)

    # fit centerline in the Z-Y plane using polynomial function
    print "\nFit centerline in the Z-Y plane using polynomial function..."
    coeffsy = polyfit(z_centerline, y_centerline, deg=param.deg_poly)
    polyy = poly1d(coeffsy)
    y_centerline_fit = polyval(polyy, z_centerline)
    # calculate RMSE
    rmse = linalg.norm(y_centerline_fit - y_centerline) / sqrt(len(y_centerline))
    # calculate max absolute error
    max_abs = max(abs(y_centerline_fit - y_centerline))
    print ".. RMSE (in mm): " + str(rmse * py)
    print ".. Maximum absolute error (in mm): " + str(max_abs * py)

    # display
    if param.debug == 1:
        import matplotlib.pyplot as plt

        plt.figure()
        plt.plot(z_centerline, x_centerline, ".", z_centerline, x_centerline_fit, "r")
        plt.legend(["Data", "Polynomial Fit"])
        plt.title("Z-X plane polynomial interpolation")
        plt.show()

        plt.figure()
        plt.plot(z_centerline, y_centerline, ".", z_centerline, y_centerline_fit, "r")
        plt.legend(["Data", "Polynomial Fit"])
        plt.title("Z-Y plane polynomial interpolation")
        plt.show()

    # generate full range z-values for centerline
    z_centerline_full = [iz for iz in range(0, nz, 1)]

    # calculate X and Y values for the full centerline
    x_centerline_fit_full = polyval(polyx, z_centerline_full)
    y_centerline_fit_full = polyval(polyy, z_centerline_full)

    # Generate fitted transformation matrices and write centerline coordinates in text file
    print "\nGenerate fitted transformation matrices and write centerline coordinates in text file..."
    file_mat_inv_cumul_fit = ["tmp.mat_inv_cumul_fit_z" + str(z).zfill(4) for z in range(0, nz, 1)]
    file_mat_cumul_fit = ["tmp.mat_cumul_fit_z" + str(z).zfill(4) for z in range(0, nz, 1)]
    fid_centerline = open("tmp.centerline_coordinates.txt", "w")
    for iz in range(0, nz, 1):
        # compute inverse cumulative fitted transformation matrix
        fid = open(file_mat_inv_cumul_fit[iz], "w")
        fid.write("%i %i %i %f\n" % (1, 0, 0, x_centerline_fit_full[iz] - x_init))
        fid.write("%i %i %i %f\n" % (0, 1, 0, y_centerline_fit_full[iz] - y_init))
        fid.write("%i %i %i %i\n" % (0, 0, 1, 0))
        fid.write("%i %i %i %i\n" % (0, 0, 0, 1))
        fid.close()
        # compute forward cumulative fitted transformation matrix
        sct.run("convert_xfm -omat " + file_mat_cumul_fit[iz] + " -inverse " + file_mat_inv_cumul_fit[iz])
        # write centerline coordinates in x, y, z format
        fid_centerline.write(
            "%f %f %f\n" % (x_centerline_fit_full[iz], y_centerline_fit_full[iz], z_centerline_full[iz])
        )
    fid_centerline.close()

    # Prepare output data
    # ====================================================================================================

    # write centerline as text file
    for iz in range(0, nz, 1):
        # compute inverse cumulative fitted transformation matrix
        fid = open(file_mat_inv_cumul_fit[iz], "w")
        fid.write("%i %i %i %f\n" % (1, 0, 0, x_centerline_fit_full[iz] - x_init))
        fid.write("%i %i %i %f\n" % (0, 1, 0, y_centerline_fit_full[iz] - y_init))
        fid.write("%i %i %i %i\n" % (0, 0, 1, 0))
        fid.write("%i %i %i %i\n" % (0, 0, 0, 1))
        fid.close()

    # write polynomial coefficients
    savetxt("tmp.centerline_polycoeffs_x.txt", coeffsx)
    savetxt("tmp.centerline_polycoeffs_y.txt", coeffsy)

    # apply transformations to data
    print "\nApply fitted transformation matrices..."
    file_anat_split_fit = ["tmp.anat_orient_fit_z" + str(z).zfill(4) for z in range(0, nz, 1)]
    file_mask_split_fit = ["tmp.mask_orient_fit_z" + str(z).zfill(4) for z in range(0, nz, 1)]
    file_point_split_fit = ["tmp.point_orient_fit_z" + str(z).zfill(4) for z in range(0, nz, 1)]
    for iz in range(0, nz, 1):
        # forward cumulative transformation to data
        sct.run(
            fsloutput
            + "flirt -in "
            + file_anat_split[iz]
            + " -ref "
            + file_anat_split[iz]
            + " -applyxfm -init "
            + file_mat_cumul_fit[iz]
            + " -out "
            + file_anat_split_fit[iz]
        )
        # inverse cumulative transformation to mask
        sct.run(
            fsloutput
            + "flirt -in "
            + file_mask_split[z_init]
            + " -ref "
            + file_mask_split[z_init]
            + " -applyxfm -init "
            + file_mat_inv_cumul_fit[iz]
            + " -out "
            + file_mask_split_fit[iz]
        )
        # inverse cumulative transformation to point
        sct.run(
            fsloutput
            + "flirt -in "
            + file_point_split[z_init]
            + " -ref "
            + file_point_split[z_init]
            + " -applyxfm -init "
            + file_mat_inv_cumul_fit[iz]
            + " -out "
            + file_point_split_fit[iz]
            + " -interp nearestneighbour"
        )

    # Merge into 4D volume
    print "\nMerge into 4D volume..."
    # im_anat_list = [Image(fname) for fname in glob.glob('tmp.anat_orient_fit_z*.nii')]
    fname_anat_list = glob.glob("tmp.anat_orient_fit_z*.nii")
    im_anat_concat = concat_data(fname_anat_list, 2)
    im_anat_concat.setFileName("tmp.anat_orient_fit.nii")
    im_anat_concat.save()

    # im_mask_list = [Image(fname) for fname in glob.glob('tmp.mask_orient_fit_z*.nii')]
    fname_mask_list = glob.glob("tmp.mask_orient_fit_z*.nii")
    im_mask_concat = concat_data(fname_mask_list, 2)
    im_mask_concat.setFileName("tmp.mask_orient_fit.nii")
    im_mask_concat.save()

    # im_point_list = [Image(fname) for fname in 	glob.glob('tmp.point_orient_fit_z*.nii')]
    fname_point_list = glob.glob("tmp.point_orient_fit_z*.nii")
    im_point_concat = concat_data(fname_point_list, 2)
    im_point_concat.setFileName("tmp.point_orient_fit.nii")
    im_point_concat.save()

    # Copy header geometry from input data
    print "\nCopy header geometry from input data..."
    im_anat = Image("tmp.anat_orient.nii")
    im_anat_orient_fit = Image("tmp.anat_orient_fit.nii")
    im_mask_orient_fit = Image("tmp.mask_orient_fit.nii")
    im_point_orient_fit = Image("tmp.point_orient_fit.nii")
    im_anat_orient_fit = copy_header(im_anat, im_anat_orient_fit)
    im_mask_orient_fit = copy_header(im_anat, im_mask_orient_fit)
    im_point_orient_fit = copy_header(im_anat, im_point_orient_fit)
    for im in [im_anat_orient_fit, im_mask_orient_fit, im_point_orient_fit]:
        im.save()

    # Reorient outputs into the initial orientation of the input image
    print "\nReorient the centerline into the initial orientation of the input image..."
    set_orientation("tmp.point_orient_fit.nii", input_image_orientation, "tmp.point_orient_fit.nii")
    set_orientation("tmp.mask_orient_fit.nii", input_image_orientation, "tmp.mask_orient_fit.nii")

    # Generate output file (in current folder)
    print "\nGenerate output file (in current folder)..."
    os.chdir("..")  # come back to parent folder
    fname_output_centerline = sct.generate_output_file(
        path_tmp + "/tmp.point_orient_fit.nii", file_anat + "_centerline" + ext_anat
    )

    # Delete temporary files
    if remove_tmp_files == 1:
        print "\nRemove temporary files..."
        sct.run("rm -rf " + path_tmp, error_exit="warning")

    # print number of warnings
    print "\nNumber of warnings: " + str(
        warning_count
    ) + " (if >10, you should probably reduce the gap and/or increase the kernel size"

    # display elapsed time
    elapsed_time = time() - start_time
    print "\nFinished! \n\tGenerated file: " + fname_output_centerline + "\n\tElapsed time: " + str(
        int(round(elapsed_time))
    ) + "s\n"
コード例 #22
0
def main(args=None):

    # Initialization
    # fname_anat = ''
    # fname_centerline = ''
    sigma = 3 # default value of the standard deviation for the Gaussian smoothing (in terms of number of voxels)
    # remove_temp_files = param.remove_temp_files
    # verbose = param.verbose
    start_time = time.time()

    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    fname_anat = arguments['-i']
    fname_centerline = arguments['-s']
    if '-smooth' in arguments:
        sigma = arguments['-smooth']
    if '-r' in arguments:
        remove_temp_files = int(arguments['-r'])
    if '-v' in arguments:
        verbose = int(arguments['-v'])

    # Display arguments
    print '\nCheck input arguments...'
    print '  Volume to smooth .................. ' + fname_anat
    print '  Centerline ........................ ' + fname_centerline
    print '  Sigma (mm) ........................ '+str(sigma)
    print '  Verbose ........................... '+str(verbose)

    # Check that input is 3D:
    from msct_image import Image
    nx, ny, nz, nt, px, py, pz, pt = Image(fname_anat).dim
    dim = 4  # by default, will be adjusted later
    if nt == 1:
        dim = 3
    if nz == 1:
        dim = 2
    if dim == 4:
        sct.printv('WARNING: the input image is 4D, please split your image to 3D before smoothing spinalcord using :\n'
                   'sct_image -i '+fname_anat+' -split t -o '+fname_anat, verbose, 'warning')
        sct.printv('4D images not supported, aborting ...', verbose, 'error')

    # Extract path/file/extension
    path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat)
    path_centerline, file_centerline, ext_centerline = sct.extract_fname(fname_centerline)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, verbose)

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose)
    sct.run('cp '+fname_anat+' '+path_tmp+'anat'+ext_anat, verbose)
    sct.run('cp '+fname_centerline+' '+path_tmp+'centerline'+ext_centerline, verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # convert to nii format
    convert('anat'+ext_anat, 'anat.nii')
    convert('centerline'+ext_centerline, 'centerline.nii')

    # Change orientation of the input image into RPI
    print '\nOrient input volume to RPI orientation...'
    fname_anat_rpi = set_orientation('anat.nii', 'RPI', filename=True)
    move(fname_anat_rpi, 'anat_rpi.nii')
    # Change orientation of the input image into RPI
    print '\nOrient centerline to RPI orientation...'
    fname_centerline_rpi = set_orientation('centerline.nii', 'RPI', filename=True)
    move(fname_centerline_rpi, 'centerline_rpi.nii')

    # Straighten the spinal cord
    # straighten segmentation
    sct.printv('\nStraighten the spinal cord using centerline/segmentation...', verbose)
    # check if warp_curve2straight and warp_straight2curve already exist (i.e. no need to do it another time)
    if os.path.isfile('../warp_curve2straight.nii.gz') and os.path.isfile('../warp_straight2curve.nii.gz') and os.path.isfile('../straight_ref.nii.gz'):
        # if they exist, copy them into current folder
        sct.printv('WARNING: Straightening was already run previously. Copying warping fields...', verbose, 'warning')
        shutil.copy('../warp_curve2straight.nii.gz', 'warp_curve2straight.nii.gz')
        shutil.copy('../warp_straight2curve.nii.gz', 'warp_straight2curve.nii.gz')
        shutil.copy('../straight_ref.nii.gz', 'straight_ref.nii.gz')
        # apply straightening
        sct.run('sct_apply_transfo -i anat_rpi.nii -w warp_curve2straight.nii.gz -d straight_ref.nii.gz -o anat_rpi_straight.nii -x spline', verbose)
    else:
        sct.run('sct_straighten_spinalcord -i anat_rpi.nii -s centerline_rpi.nii -qc 0 -x spline', verbose)

    # Smooth the straightened image along z
    print '\nSmooth the straightened image along z...'
    sct.run('sct_maths -i anat_rpi_straight.nii -smooth 0,0,'+str(sigma)+' -o anat_rpi_straight_smooth.nii', verbose)

    # Apply the reversed warping field to get back the curved spinal cord
    print '\nApply the reversed warping field to get back the curved spinal cord...'
    sct.run('sct_apply_transfo -i anat_rpi_straight_smooth.nii -o anat_rpi_straight_smooth_curved.nii -d anat.nii -w warp_straight2curve.nii.gz -x spline', verbose)

    # replace zeroed voxels by original image (issue #937)
    sct.printv('\nReplace zeroed voxels by original image...', verbose)
    nii_smooth = Image('anat_rpi_straight_smooth_curved.nii')
    data_smooth = nii_smooth.data
    data_input = Image('anat.nii').data
    indzero = np.where(data_smooth == 0)
    data_smooth[indzero] = data_input[indzero]
    nii_smooth.data = data_smooth
    nii_smooth.setFileName('anat_rpi_straight_smooth_curved_nonzero.nii')
    nii_smooth.save()

    # come back to parent folder
    os.chdir('..')

    # Generate output file
    print '\nGenerate output file...'
    sct.generate_output_file(path_tmp+'/anat_rpi_straight_smooth_curved_nonzero.nii', file_anat+'_smooth'+ext_anat)

    # Remove temporary files
    if remove_temp_files == 1:
        print('\nRemove temporary files...')
        sct.run('rm -rf '+path_tmp)

    # Display elapsed time
    elapsed_time = time.time() - start_time
    print '\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s\n'

    # to view results
    sct.printv('Done! To view results, type:', verbose)
    sct.printv('fslview '+file_anat+' '+file_anat+'_smooth &\n', verbose, 'info')
コード例 #23
0
def create_mask():

    fsloutput = 'export FSLOUTPUTTYPE=NIFTI; '  # for faster processing, all outputs are in NIFTI

    # display usage if a mandatory argument is not provided
    if param.fname_data == '' or param.method == '':
        sct.printv('\nERROR: All mandatory arguments are not provided. See usage (add -h).\n', 1, 'error')

    # parse argument for method
    method_list = param.method.replace(' ', '').split(',')  # remove spaces and parse with comma
    # method_list = param.method.split(',')  # parse with comma
    method_type = method_list[0]

    # check existence of method type
    if not method_type in param.method_list:
        sct.printv('\nERROR in '+os.path.basename(__file__)+': Method "'+method_type+'" is not recognized. See usage (add -h).\n', 1, 'error')

    # check method val
    if not method_type == 'center':
        method_val = method_list[1]
    del method_list

    # check existence of shape
    if not param.shape in param.shape_list:
        sct.printv('\nERROR in '+os.path.basename(__file__)+': Shape "'+param.shape+'" is not recognized. See usage (add -h).\n', 1, 'error')

    # check existence of input files
    sct.printv('\ncheck existence of input files...', param.verbose)
    sct.check_file_exist(param.fname_data, param.verbose)
    if method_type == 'centerline':
        sct.check_file_exist(method_val, param.verbose)

    # check if orientation is RPI
    sct.printv('\nCheck if orientation is RPI...', param.verbose)
    status, output = sct.run('sct_orientation -i '+param.fname_data)
    if not output == 'RPI':
        sct.printv('\nERROR in '+os.path.basename(__file__)+': Orientation of input image should be RPI. Use sct_orientation to put your image in RPI.\n', 1, 'error')

    # display input parameters
    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  data ..................'+param.fname_data, param.verbose)
    sct.printv('  method ................'+method_type, param.verbose)

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    # Get output folder and file name
    if param.fname_out == '':
        param.fname_out = param.file_prefix+file_data+ext_data
    #fname_out = os.path.abspath(path_out+file_out+ext_out)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, param.verbose)

    # Copying input data to tmp folder and convert to nii
    # NB: cannot use c3d here because c3d cannot convert 4D data.
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(param.fname_data, path_tmp+'data.nii')
    # sct.run('cp '+param.fname_data+' '+path_tmp+'data'+ext_data, param.verbose)
    if method_type == 'centerline':
        convert(method_val, path_tmp+'centerline.nii.gz')
        # sct.run('isct_c3d '+method_val+' -o '+path_tmp+'/centerline.nii.gz')

    # go to tmp folder
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim
    sct.printv('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), param.verbose)
    # in case user input 4d data
    if nt != 1:
        sct.printv('WARNING in '+os.path.basename(__file__)+': Input image is 4d but output mask will 3D.', param.verbose, 'warning')
        # extract first volume to have 3d reference
        nii = Image('data.nii')
        data3d = nii.data[:,:,:,0]
        nii.data = data3d
        nii.save()

    if method_type == 'coord':
        # parse to get coordinate
        coord = map(int, method_val.split('x'))

    if method_type == 'point':
        # get file name
        fname_point = method_val
        # extract coordinate of point
        sct.printv('\nExtract coordinate of point...', param.verbose)
        status, output = sct.run('sct_label_utils -i '+fname_point+' -t display-voxel', param.verbose)
        # parse to get coordinate
        coord = output[output.find('Position=')+10:-17].split(',')

    if method_type == 'center':
        # set coordinate at center of FOV
        coord = round(float(nx)/2), round(float(ny)/2)

    if method_type == 'centerline':
        # get name of centerline from user argument
        fname_centerline = 'centerline.nii.gz'
    else:
        # generate volume with line along Z at coordinates 'coord'
        sct.printv('\nCreate line...', param.verbose)
        fname_centerline = create_line('data.nii', coord, nz)

    # create mask
    sct.printv('\nCreate mask...', param.verbose)
    centerline = nibabel.load(fname_centerline)  # open centerline
    hdr = centerline.get_header()  # get header
    hdr.set_data_dtype('uint8')  # set imagetype to uint8
    data_centerline = centerline.get_data()  # get centerline
    z_centerline = [iz for iz in range(0, nz, 1) if data_centerline[:, :, iz].any()]
    nz = len(z_centerline)
    # get center of mass of the centerline
    cx = [0] * nz
    cy = [0] * nz
    for iz in range(0, nz, 1):
        cx[iz], cy[iz] = ndimage.measurements.center_of_mass(numpy.array(data_centerline[:, :, z_centerline[iz]]))
    # create 2d masks
    file_mask = 'data_mask'
    for iz in range(nz):
        center = numpy.array([cx[iz], cy[iz]])
        mask2d = create_mask2d(center, param.shape, param.size, nx, ny)
        # Write NIFTI volumes
        img = nibabel.Nifti1Image(mask2d, None, hdr)
        nibabel.save(img, (file_mask+str(iz)+'.nii'))
    # merge along Z
    # cmd = 'fslmerge -z mask '
    cmd = 'sct_concat_data -dim z -o mask.nii.gz -i '
    for iz in range(nz):
        cmd = cmd + file_mask+str(iz)+'.nii,'
    # remove ',' at the end of the string
    cmd = cmd[:-1]
    status, output = sct.run(cmd, param.verbose)

    # copy geometry
    copy_header('data.nii', 'mask.nii.gz')

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp+'mask.nii.gz', param.fname_out)

    # Remove temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...', param.verbose)
        sct.run('rm -rf '+path_tmp, param.verbose)

    # to view results
    sct.printv('\nDone! To view results, type:', param.verbose)
    sct.printv('fslview '+param.fname_data+' '+param.fname_out+' -l Red -t 0.5 &', param.verbose, 'info')
    print
コード例 #24
0
def fmri_moco(param):

    file_data = "fmri.nii"
    mat_final = 'mat_final/'
    ext_mat = 'Warp.nii.gz'  # warping field

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    im_data = Image(param.fname_data)
    nx, ny, nz, nt, px, py, pz, pt = im_data.dim
    sct.printv(
        '  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt),
        param.verbose)

    # Get orientation
    sct.printv('\nData orientation: ' + im_data.orientation, param.verbose)
    if im_data.orientation[2] in 'LR':
        param.is_sagittal = True
        sct.printv('  Treated as sagittal')
    elif im_data.orientation[2] in 'IS':
        param.is_sagittal = False
        sct.printv('  Treated as axial')
    else:
        param.is_sagittal = False
        sct.printv(
            'WARNING: Orientation seems to be neither axial nor sagittal.')

    # Adjust group size in case of sagittal scan
    if param.is_sagittal and param.group_size != 1:
        sct.printv(
            'For sagittal data group_size should be one for more robustness. Forcing group_size=1.',
            1, 'warning')
        param.group_size = 1

    # Split into T dimension
    sct.printv('\nSplit along T dimension...', param.verbose)
    im_data_split_list = split_data(im_data, 3)
    for im in im_data_split_list:
        x_dirname, x_basename, x_ext = sct.extract_fname(im.absolutepath)
        # Make further steps slurp the data to avoid too many open files (#2149)
        im.absolutepath = os.path.join(x_dirname, x_basename + ".nii.gz")
        im.save()

    # assign an index to each volume
    index_fmri = list(range(0, nt))

    # Number of groups
    nb_groups = int(math.floor(nt / param.group_size))

    # Generate groups indexes
    group_indexes = []
    for iGroup in range(nb_groups):
        group_indexes.append(index_fmri[(iGroup *
                                         param.group_size):((iGroup + 1) *
                                                            param.group_size)])

    # add the remaining images to the last fMRI group
    nb_remaining = nt % param.group_size  # number of remaining images
    if nb_remaining > 0:
        nb_groups += 1
        group_indexes.append(index_fmri[len(index_fmri) -
                                        nb_remaining:len(index_fmri)])

    # groups
    for iGroup in tqdm(range(nb_groups),
                       unit='iter',
                       unit_scale=False,
                       desc="Merge within groups",
                       ascii=True,
                       ncols=80):
        # get index
        index_fmri_i = group_indexes[iGroup]
        nt_i = len(index_fmri_i)

        # Merge Images
        file_data_merge_i = sct.add_suffix(file_data, '_' + str(iGroup))
        # cmd = fsloutput + 'fslmerge -t ' + file_data_merge_i
        # for it in range(nt_i):
        #     cmd = cmd + ' ' + file_data + '_T' + str(index_fmri_i[it]).zfill(4)

        im_fmri_list = []
        for it in range(nt_i):
            im_fmri_list.append(im_data_split_list[index_fmri_i[it]])
        im_fmri_concat = concat_data(im_fmri_list, 3,
                                     squeeze_data=True).save(file_data_merge_i)

        file_data_mean = sct.add_suffix(file_data, '_mean_' + str(iGroup))
        if file_data_mean.endswith(".nii"):
            file_data_mean += ".gz"  # #2149
        if param.group_size == 1:
            # copy to new file name instead of averaging (faster)
            # note: this is a bandage. Ideally we should skip this entire for loop if g=1
            convert(file_data_merge_i, file_data_mean)
        else:
            # Average Images
            sct.run([
                'sct_maths', '-i', file_data_merge_i, '-o', file_data_mean,
                '-mean', 't'
            ],
                    verbose=0)
        # if not average_data_across_dimension(file_data_merge_i+'.nii', file_data_mean+'.nii', 3):
        #     sct.printv('ERROR in average_data_across_dimension', 1, 'error')
        # cmd = fsloutput + 'fslmaths ' + file_data_merge_i + ' -Tmean ' + file_data_mean
        # sct.run(cmd, param.verbose)

    # Merge groups means. The output 4D volume will be used for motion correction.
    sct.printv('\nMerging volumes...', param.verbose)
    file_data_groups_means_merge = 'fmri_averaged_groups.nii'
    im_mean_list = []
    for iGroup in range(nb_groups):
        file_data_mean = sct.add_suffix(file_data, '_mean_' + str(iGroup))
        if file_data_mean.endswith(".nii"):
            file_data_mean += ".gz"  # #2149
        im_mean_list.append(Image(file_data_mean))
    im_mean_concat = concat_data(im_mean_list,
                                 3).save(file_data_groups_means_merge)

    # Estimate moco
    sct.printv(
        '\n-------------------------------------------------------------------------------',
        param.verbose)
    sct.printv('  Estimating motion...', param.verbose)
    sct.printv(
        '-------------------------------------------------------------------------------',
        param.verbose)
    param_moco = param
    param_moco.file_data = 'fmri_averaged_groups.nii'
    param_moco.file_target = sct.add_suffix(file_data,
                                            '_mean_' + param.num_target)
    if param_moco.file_target.endswith(".nii"):
        param_moco.file_target += ".gz"  # #2149
    param_moco.path_out = ''
    param_moco.todo = 'estimate_and_apply'
    param_moco.mat_moco = 'mat_groups'
    file_mat = moco.moco(param_moco)

    # TODO: if g=1, no need to run the block below (already applied)
    if param.group_size == 1:
        # if flag g=1, it means that all images have already been corrected, so we just need to rename the file
        sct.mv('fmri_averaged_groups_moco.nii', 'fmri_moco.nii')
    else:
        # create final mat folder
        sct.create_folder(mat_final)

        # Copy registration matrices
        sct.printv('\nCopy transformations...', param.verbose)
        for iGroup in range(nb_groups):
            for data in range(
                    len(group_indexes[iGroup])
            ):  # we cannot use enumerate because group_indexes has 2 dim.
                # fetch all file_mat_z for given t-group
                list_file_mat_z = file_mat[:, iGroup]
                # loop across file_mat_z and copy to mat_final folder
                for file_mat_z in list_file_mat_z:
                    # we want to copy 'mat_groups/mat.ZXXXXTYYYYWarp.nii.gz' --> 'mat_final/mat.ZXXXXTYYYZWarp.nii.gz'
                    # Notice the Y->Z in the under the T index: the idea here is to use the single matrix from each group,
                    # and apply it to all images belonging to the same group.
                    sct.copy(
                        file_mat_z + ext_mat,
                        mat_final + file_mat_z[11:20] + 'T' +
                        str(group_indexes[iGroup][data]).zfill(4) + ext_mat)

        # Apply moco on all fmri data
        sct.printv(
            '\n-------------------------------------------------------------------------------',
            param.verbose)
        sct.printv('  Apply moco', param.verbose)
        sct.printv(
            '-------------------------------------------------------------------------------',
            param.verbose)
        param_moco.file_data = 'fmri.nii'
        param_moco.file_target = sct.add_suffix(file_data, '_mean_' + str(0))
        if param_moco.file_target.endswith(".nii"):
            param_moco.file_target += ".gz"
        param_moco.path_out = ''
        param_moco.mat_moco = mat_final
        param_moco.todo = 'apply'
        file_mat = moco.moco(param_moco)

    # copy geometric information from header
    # NB: this is required because WarpImageMultiTransform in 2D mode wrongly sets pixdim(3) to "1".
    im_fmri = Image('fmri.nii')
    im_fmri_moco = Image('fmri_moco.nii')
    im_fmri_moco.header = im_fmri.header
    im_fmri_moco.save()

    # Extract and output the motion parameters
    if param.output_motion_param:
        from sct_image import multicomponent_split
        import csv
        #files_warp = []
        files_warp_X, files_warp_Y = [], []
        moco_param = []
        for fname_warp in file_mat[0]:
            # Cropping the image to keep only one voxel in the XY plane
            im_warp = Image(fname_warp + ext_mat)
            im_warp.data = np.expand_dims(np.expand_dims(
                im_warp.data[0, 0, :, :, :], axis=0),
                                          axis=0)

            # These three lines allow to generate one file instead of two, containing X, Y and Z moco parameters
            #fname_warp_crop = fname_warp + '_crop_' + ext_mat
            #files_warp.append(fname_warp_crop)
            #im_warp.save(fname_warp_crop)

            # Separating the three components and saving X and Y only (Z is equal to 0 by default).
            im_warp_XYZ = multicomponent_split(im_warp)

            fname_warp_crop_X = fname_warp + '_crop_X_' + ext_mat
            im_warp_XYZ[0].save(fname_warp_crop_X)
            files_warp_X.append(fname_warp_crop_X)

            fname_warp_crop_Y = fname_warp + '_crop_Y_' + ext_mat
            im_warp_XYZ[1].save(fname_warp_crop_Y)
            files_warp_Y.append(fname_warp_crop_Y)

            # Calculating the slice-wise average moco estimate to provide a QC file
            moco_param.append([
                np.mean(np.ravel(im_warp_XYZ[0].data)),
                np.mean(np.ravel(im_warp_XYZ[1].data))
            ])

        # These two lines allow to generate one file instead of two, containing X, Y and Z moco parameters
        #im_warp_concat = concat_data(files_warp, dim=3)
        #im_warp_concat.save('fmri_moco_params.nii')

        # Concatenating the moco parameters into a time series for X and Y components.
        im_warp_concat = concat_data(files_warp_X, dim=3)
        im_warp_concat.save('fmri_moco_params_X.nii')

        im_warp_concat = concat_data(files_warp_Y, dim=3)
        im_warp_concat.save('fmri_moco_params_Y.nii')

        # Writing a TSV file with the slicewise average estimate of the moco parameters, as it is a useful QC file.
        with open('fmri_moco_params.tsv', 'wt') as out_file:
            tsv_writer = csv.writer(out_file, delimiter='\t')
            tsv_writer.writerow(['X', 'Y'])
            for mocop in moco_param:
                tsv_writer.writerow([mocop[0], mocop[1]])

    # Average volumes
    sct.printv('\nAveraging data...', param.verbose)
    sct_maths.main(args=[
        '-i', 'fmri_moco.nii', '-o', 'fmri_moco_mean.nii', '-mean', 't', '-v',
        '0'
    ])
コード例 #25
0
def main(args=None):

    # initialization
    start_time = time.time()
    path_out = '.'
    param = Param()

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # get path of the toolbox
    # status, param.path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    param.fname_data = arguments['-i']
    param.fname_bvecs = arguments['-bvec']

    if '-bval' in arguments:
        param.fname_bvals = arguments['-bval']
    if '-bvalmin' in arguments:
        param.bval_min = arguments['-bvalmin']
    if '-g' in arguments:
        param.group_size = arguments['-g']
    if '-m' in arguments:
        param.fname_mask = arguments['-m']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-thr' in arguments:
        param.otsu = arguments['-thr']
    if '-x' in arguments:
        param.interp = arguments['-x']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-r' in arguments:
        param.remove_tmp_files = int(arguments['-r'])
    if '-v' in arguments:
        param.verbose = int(arguments['-v'])

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    if param.fname_bvals != '':
        param.fname_bvals = os.path.abspath(param.fname_bvals)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_mask, file_mask, ext_mask = sct.extract_fname(param.fname_mask)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.' + time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir ' + path_tmp, param.verbose)

    # names of files in temporary folder
    ext = '.nii'
    dmri_name = 'dmri'
    mask_name = 'mask'
    bvecs_fname = 'bvecs.txt'

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               param.verbose)
    convert(param.fname_data, path_tmp + dmri_name + ext)
    sct.run('cp ' + param.fname_bvecs + ' ' + path_tmp + bvecs_fname,
            param.verbose)
    if param.fname_mask != '':
        sct.run(
            'cp ' + param.fname_mask + ' ' + path_tmp + mask_name + ext_mask,
            param.verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # update field in param (because used later).
    # TODO: make this cleaner...
    if param.fname_mask != '':
        param.fname_mask = mask_name + ext_mask

    # run moco
    dmri_moco(param)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    path_out = sct.slash_at_the_end(path_out, 1)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp + dmri_name + param.suffix + ext,
                             path_out + file_data + param.suffix + ext_data,
                             param.verbose)
    sct.generate_output_file(
        path_tmp + 'b0_mean.nii',
        path_out + 'b0' + param.suffix + '_mean' + ext_data, param.verbose)
    sct.generate_output_file(
        path_tmp + 'dwi_mean.nii',
        path_out + 'dwi' + param.suffix + '_mean' + ext_data, param.verbose)

    # Delete temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.run('rm -rf ' + path_tmp, param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv(
        '\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) + 's',
        param.verbose)

    # To view results
    sct.printv('\nTo view results, type:', param.verbose)
    sct.printv(
        'fslview -m ortho,ortho ' + param.path_out + file_data + param.suffix +
        ' ' + file_data + ' &\n', param.verbose, 'info')
コード例 #26
0
def create_mask():
    fsloutput = 'export FSLOUTPUTTYPE=NIFTI; '  # for faster processing, all outputs are in NIFTI

    # parse argument for method
    method_type = param.process[0]
    # check method val
    if not method_type == 'center':
        method_val = param.process[1]

    # check existence of input files
    if method_type == 'centerline':
        sct.check_file_exist(method_val, param.verbose)

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    # Get output folder and file name
    if param.fname_out == '':
        param.fname_out = param.file_prefix+file_data+ext_data

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.tmp_create(param.verbose)
    # )sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    # sct.run('mkdir '+path_tmp, param.verbose)

    sct.printv('\nCheck orientation...', param.verbose)
    orientation_input = get_orientation(Image(param.fname_data))
    sct.printv('.. '+orientation_input, param.verbose)
    reorient_coordinates = False

    # copy input data to tmp folder
    convert(param.fname_data, path_tmp+'data.nii')
    if method_type == 'centerline':
        convert(method_val, path_tmp+'centerline.nii.gz')
    if method_type == 'point':
        convert(method_val, path_tmp+'point.nii.gz')

    # go to tmp folder
    os.chdir(path_tmp)

    # reorient to RPI
    sct.printv('\nReorient to RPI...', param.verbose)
    # if not orientation_input == 'RPI':
    sct.run('sct_image -i data.nii -o data_RPI.nii -setorient RPI -v 0', verbose=False)
    if method_type == 'centerline':
        sct.run('sct_image -i centerline.nii.gz -o centerline_RPI.nii.gz -setorient RPI -v 0', verbose=False)
    if method_type == 'point':
        sct.run('sct_image -i point.nii.gz -o point_RPI.nii.gz -setorient RPI -v 0', verbose=False)
    #
    # if method_type == 'centerline':
    #     orientation_centerline = get_orientation_3d(method_val, filename=True)
    #     if not orientation_centerline == 'RPI':
    #         sct.run('sct_image -i ' + method_val + ' -o ' + path_tmp + 'centerline.nii.gz' + ' -setorient RPI -v 0', verbose=False)
    #     else:
    #         convert(method_val, path_tmp+'centerline.nii.gz')

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data_RPI.nii').dim
    sct.printv('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), param.verbose)
    # in case user input 4d data
    if nt != 1:
        sct.printv('WARNING in '+os.path.basename(__file__)+': Input image is 4d but output mask will 3D.', param.verbose, 'warning')
        # extract first volume to have 3d reference
        nii = Image('data_RPI.nii')
        data3d = nii.data[:,:,:,0]
        nii.data = data3d
        nii.save()

    if method_type == 'coord':
        # parse to get coordinate
        coord = map(int, method_val.split('x'))

    if method_type == 'point':
        # get file name
        fname_point = method_val
        # extract coordinate of point
        sct.printv('\nExtract coordinate of point...', param.verbose)
        # TODO: change this way to remove dependence to sct.run. ProcessLabels.display_voxel returns list of coordinates
        status, output = sct.run('sct_label_utils -i point_RPI.nii.gz -display', param.verbose)
        # parse to get coordinate
        coord = output[output.find('Position=')+10:-17].split(',')

    if method_type == 'center':
        # set coordinate at center of FOV
        coord = round(float(nx)/2), round(float(ny)/2)

    if method_type == 'centerline':
        # get name of centerline from user argument
        fname_centerline = 'centerline_RPI.nii.gz'
    else:
        # generate volume with line along Z at coordinates 'coord'
        sct.printv('\nCreate line...', param.verbose)
        fname_centerline = create_line('data_RPI.nii', coord, nz)

    # create mask
    sct.printv('\nCreate mask...', param.verbose)
    centerline = nibabel.load(fname_centerline)  # open centerline
    hdr = centerline.get_header()  # get header
    hdr.set_data_dtype('uint8')  # set imagetype to uint8
    spacing = hdr.structarr['pixdim']
    data_centerline = centerline.get_data()  # get centerline
    z_centerline_not_null = [iz for iz in range(0, nz, 1) if data_centerline[:, :, iz].any()]
    # get center of mass of the centerline
    cx = [0] * nz
    cy = [0] * nz
    for iz in range(0, nz, 1):
        if iz in z_centerline_not_null:
            cx[iz], cy[iz] = ndimage.measurements.center_of_mass(numpy.array(data_centerline[:, :, iz]))
    # create 2d masks
    file_mask = 'data_mask'
    for iz in range(nz):
        if iz not in z_centerline_not_null:
            # write an empty nifty volume
            img = nibabel.Nifti1Image(data_centerline[:, :, iz], None, hdr)
            nibabel.save(img, (file_mask + str(iz) + '.nii'))
        else:
            center = numpy.array([cx[iz], cy[iz]])
            mask2d = create_mask2d(center, param.shape, param.size, nx, ny, even=param.even, spacing=spacing)
            # Write NIFTI volumes
            img = nibabel.Nifti1Image(mask2d, None, hdr)
            nibabel.save(img, (file_mask+str(iz)+'.nii'))
    # merge along Z
    # cmd = 'fslmerge -z mask '

    # CHANGE THAT CAN IMPACT SPEED:
    # related to issue #755, we cannot open more than 256 files at one time.
    # to solve this issue, we do not open more than 100 files
    '''
    im_list = []
    im_temp = []
    for iz in range(nz_not_null):
        if iz != 0 and iz % 100 == 0:
            im_temp.append(concat_data(im_list, 2))
            im_list = [Image(file_mask + str(iz) + '.nii')]
        else:
            im_list.append(Image(file_mask+str(iz)+'.nii'))

    if im_temp:
        im_temp.append(concat_data(im_list, 2))
        im_out = concat_data(im_temp, 2, no_expand=True)
    else:
        im_out = concat_data(im_list, 2)
    '''
    fname_list = [file_mask + str(iz) + '.nii' for iz in range(nz)]
    im_out = concat_data(fname_list, dim=2)
    im_out.setFileName('mask_RPI.nii.gz')
    im_out.save()

    # reorient if necessary
    # if not orientation_input == 'RPI':
    sct.run('sct_image -i mask_RPI.nii.gz -o mask.nii.gz -setorient ' + orientation_input, param.verbose)

    # copy header input --> mask
    im_dat = Image('data.nii')
    im_mask = Image('mask.nii.gz')
    im_mask = copy_header(im_dat, im_mask)
    im_mask.save()

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp+'mask.nii.gz', param.fname_out)

    # Remove temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...', param.verbose)
        sct.run('rm -rf '+path_tmp, param.verbose, error_exit='warning')

    # to view results
    sct.printv('\nDone! To view results, type:', param.verbose)
    sct.printv('fslview '+param.fname_data+' '+param.fname_out+' -l Red -t 0.5 &', param.verbose, 'info')
    print
コード例 #27
0
def fmri_moco(param):

    file_data = "fmri.nii"
    mat_final = 'mat_final/'
    ext_mat = 'Warp.nii.gz'  # warping field

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    im_data = Image(param.fname_data)
    nx, ny, nz, nt, px, py, pz, pt = im_data.dim
    sct.printv('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt), param.verbose)

    # Get orientation
    sct.printv('\nData orientation: ' + im_data.orientation, param.verbose)
    if im_data.orientation[2] in 'LR':
        param.is_sagittal = True
        sct.printv('  Treated as sagittal')
    elif im_data.orientation[2] in 'IS':
        param.is_sagittal = False
        sct.printv('  Treated as axial')
    else:
        param.is_sagittal = False
        sct.printv('WARNING: Orientation seems to be neither axial nor sagittal.')

    # Adjust group size in case of sagittal scan
    if param.is_sagittal and param.group_size != 1:
        sct.printv('For sagittal data group_size should be one for more robustness. Forcing group_size=1.', 1, 'warning')
        param.group_size = 1

    # Split into T dimension
    sct.printv('\nSplit along T dimension...', param.verbose)
    im_data_split_list = split_data(im_data, 3)
    for im in im_data_split_list:
        x_dirname, x_basename, x_ext = sct.extract_fname(im.absolutepath)
        # Make further steps slurp the data to avoid too many open files (#2149)
        im.absolutepath = os.path.join(x_dirname, x_basename + ".nii.gz")
        im.save()

    # assign an index to each volume
    index_fmri = list(range(0, nt))

    # Number of groups
    nb_groups = int(math.floor(nt / param.group_size))

    # Generate groups indexes
    group_indexes = []
    for iGroup in range(nb_groups):
        group_indexes.append(index_fmri[(iGroup * param.group_size):((iGroup + 1) * param.group_size)])

    # add the remaining images to the last fMRI group
    nb_remaining = nt%param.group_size  # number of remaining images
    if nb_remaining > 0:
        nb_groups += 1
        group_indexes.append(index_fmri[len(index_fmri) - nb_remaining:len(index_fmri)])

    # groups
    for iGroup in tqdm(range(nb_groups), unit='iter', unit_scale=False, desc="Merge within groups", ascii=True, ncols=80):
        # get index
        index_fmri_i = group_indexes[iGroup]
        nt_i = len(index_fmri_i)

        # Merge Images
        file_data_merge_i = sct.add_suffix(file_data, '_' + str(iGroup))
        # cmd = fsloutput + 'fslmerge -t ' + file_data_merge_i
        # for it in range(nt_i):
        #     cmd = cmd + ' ' + file_data + '_T' + str(index_fmri_i[it]).zfill(4)

        im_fmri_list = []
        for it in range(nt_i):
            im_fmri_list.append(im_data_split_list[index_fmri_i[it]])
        im_fmri_concat = concat_data(im_fmri_list, 3, squeeze_data=True).save(file_data_merge_i)

        file_data_mean = sct.add_suffix(file_data, '_mean_' + str(iGroup))
        if file_data_mean.endswith(".nii"):
            file_data_mean += ".gz" # #2149
        if param.group_size == 1:
            # copy to new file name instead of averaging (faster)
            # note: this is a bandage. Ideally we should skip this entire for loop if g=1
            convert(file_data_merge_i, file_data_mean)
        else:
            # Average Images
            sct.run(['sct_maths', '-i', file_data_merge_i, '-o', file_data_mean, '-mean', 't'], verbose=0)
        # if not average_data_across_dimension(file_data_merge_i+'.nii', file_data_mean+'.nii', 3):
        #     sct.printv('ERROR in average_data_across_dimension', 1, 'error')
        # cmd = fsloutput + 'fslmaths ' + file_data_merge_i + ' -Tmean ' + file_data_mean
        # sct.run(cmd, param.verbose)

    # Merge groups means. The output 4D volume will be used for motion correction.
    sct.printv('\nMerging volumes...', param.verbose)
    file_data_groups_means_merge = 'fmri_averaged_groups.nii'
    im_mean_list = []
    for iGroup in range(nb_groups):
        file_data_mean = sct.add_suffix(file_data, '_mean_' + str(iGroup))
        if file_data_mean.endswith(".nii"):
            file_data_mean += ".gz" # #2149
        im_mean_list.append(Image(file_data_mean))
    im_mean_concat = concat_data(im_mean_list, 3).save(file_data_groups_means_merge)

    # Estimate moco
    sct.printv('\n-------------------------------------------------------------------------------', param.verbose)
    sct.printv('  Estimating motion...', param.verbose)
    sct.printv('-------------------------------------------------------------------------------', param.verbose)
    param_moco = param
    param_moco.file_data = 'fmri_averaged_groups.nii'
    param_moco.file_target = sct.add_suffix(file_data, '_mean_' + param.num_target)
    if param_moco.file_target.endswith(".nii"):
        param_moco.file_target += ".gz" # #2149
    param_moco.path_out = ''
    param_moco.todo = 'estimate_and_apply'
    param_moco.mat_moco = 'mat_groups'
    file_mat = moco.moco(param_moco)

    # TODO: if g=1, no need to run the block below (already applied)
    if param.group_size == 1:
        # if flag g=1, it means that all images have already been corrected, so we just need to rename the file
        sct.mv('fmri_averaged_groups_moco.nii', 'fmri_moco.nii')
    else:
        # create final mat folder
        sct.create_folder(mat_final)

        # Copy registration matrices
        sct.printv('\nCopy transformations...', param.verbose)
        for iGroup in range(nb_groups):
            for data in range(len(group_indexes[iGroup])):  # we cannot use enumerate because group_indexes has 2 dim.
                # fetch all file_mat_z for given t-group
                list_file_mat_z = file_mat[:, iGroup]
                # loop across file_mat_z and copy to mat_final folder
                for file_mat_z in list_file_mat_z:
                    # we want to copy 'mat_groups/mat.ZXXXXTYYYYWarp.nii.gz' --> 'mat_final/mat.ZXXXXTYYYZWarp.nii.gz'
                    # Notice the Y->Z in the under the T index: the idea here is to use the single matrix from each group,
                    # and apply it to all images belonging to the same group.
                    sct.copy(file_mat_z + ext_mat,
                             mat_final + file_mat_z[11:20] + 'T' + str(group_indexes[iGroup][data]).zfill(4) + ext_mat)

        # Apply moco on all fmri data
        sct.printv('\n-------------------------------------------------------------------------------', param.verbose)
        sct.printv('  Apply moco', param.verbose)
        sct.printv('-------------------------------------------------------------------------------', param.verbose)
        param_moco.file_data = 'fmri.nii'
        param_moco.file_target = sct.add_suffix(file_data, '_mean_' + str(0))
        if param_moco.file_target.endswith(".nii"):
            param_moco.file_target += ".gz"
        param_moco.path_out = ''
        param_moco.mat_moco = mat_final
        param_moco.todo = 'apply'
        moco.moco(param_moco)

    # copy geometric information from header
    # NB: this is required because WarpImageMultiTransform in 2D mode wrongly sets pixdim(3) to "1".
    im_fmri = Image('fmri.nii')
    im_fmri_moco = Image('fmri_moco.nii')
    im_fmri_moco.header = im_fmri.header
    im_fmri_moco.save()

    # Average volumes
    sct.printv('\nAveraging data...', param.verbose)
    sct_maths.main(args=['-i', 'fmri_moco.nii',
                         '-o', 'fmri_moco_mean.nii',
                         '-mean', 't',
                         '-v', '0'])
コード例 #28
0
def main():

    # initialization
    start_time = time.time()
    path_out = '.'
    param_user = ''

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # get path of the toolbox
    status, param.path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Parameters for debug mode
    if param.debug:
        # get path of the testing data
        status, path_sct_data = commands.getstatusoutput('echo $SCT_TESTING_DATA_DIR')
        param.fname_data = path_sct_data+'/dmri/dmri.nii.gz'
        param.fname_bvecs = path_sct_data+'/dmri/bvecs.txt'
        param.fname_mask = path_sct_data+'/dmri/dmri.nii.gz'
        param.remove_tmp_files = 0
        param.verbose = 1
        param.run_eddy = 0
        param.otsu = 0
        param.group_size = 5
        param.iterative_averaging = 1
    else:
        # Check input parameters
        try:
            opts, args = getopt.getopt(sys.argv[1:], 'hi:a:b:e:f:g:m:o:p:r:t:v:x:')
        except getopt.GetoptError:
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ('-a'):
                param.fname_bvals = arg
            elif opt in ('-b'):
                param.fname_bvecs = arg
            elif opt in ('-e'):
                param.run_eddy = int(arg)
            elif opt in ('-f'):
                param.spline_fitting = int(arg)
            elif opt in ('-g'):
                param.group_size = int(arg)
            elif opt in ('-i'):
                param.fname_data = arg
            elif opt in ('-m'):
                param.fname_mask = arg
            elif opt in ('-o'):
                path_out = arg
            elif opt in ('-p'):
                param_user = arg
            elif opt in ('-r'):
                param.remove_tmp_files = int(arg)
            elif opt in ('-t'):
                param.otsu = int(arg)
            elif opt in ('-v'):
                param.verbose = int(arg)
            elif opt in ('-x'):
                param.interp = arg

    # display usage if a mandatory argument is not provided
    if param.fname_data == '' or param.fname_bvecs == '':
        sct.printv('ERROR: All mandatory arguments are not provided. See usage.', 1, 'error')
        usage()

    # parse argument for param
    if not param_user == '':
        param.param = param_user.replace(' ', '').split(',')  # remove spaces and parse with comma
        # TODO: check integrity of input
        # param.param = [i for i in range(len(param_user))]
        del param_user

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  input file ............'+param.fname_data, param.verbose)
    sct.printv('  bvecs file ............'+param.fname_bvecs, param.verbose)
    sct.printv('  bvals file ............'+param.fname_bvals, param.verbose)
    sct.printv('  mask file .............'+param.fname_mask, param.verbose)

    # check existence of input files
    sct.printv('\nCheck file existence...', param.verbose)
    sct.check_file_exist(param.fname_data, param.verbose)
    sct.check_file_exist(param.fname_bvecs, param.verbose)
    if not param.fname_bvals == '':
        sct.check_file_exist(param.fname_bvals, param.verbose)
    if not param.fname_mask == '':
        sct.check_file_exist(param.fname_mask, param.verbose)

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    if param.fname_bvals != '':
        param.fname_bvals = os.path.abspath(param.fname_bvals)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_mask, file_mask, ext_mask = sct.extract_fname(param.fname_mask)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, param.verbose)

    # Copying input data to tmp folder
    # NB: cannot use c3d here because c3d cannot convert 4D data.
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    sct.run('cp '+param.fname_data+' '+path_tmp+'dmri'+ext_data, param.verbose)
    sct.run('cp '+param.fname_bvecs+' '+path_tmp+'bvecs.txt', param.verbose)
    if param.fname_mask != '':
        sct.run('cp '+param.fname_mask+' '+path_tmp+'mask'+ext_mask, param.verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # convert dmri to nii format
    convert('dmri'+ext_data, 'dmri.nii')

    # update field in param (because used later).
    # TODO: make this cleaner...
    if param.fname_mask != '':
        param.fname_mask = 'mask'+ext_mask

    # run moco
    dmri_moco(param)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    path_out = sct.slash_at_the_end(path_out, 1)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp+'dmri'+param.suffix+'.nii', path_out+file_data+param.suffix+ext_data, param.verbose)
    sct.generate_output_file(path_tmp+'b0_mean.nii', path_out+'b0'+param.suffix+'_mean'+ext_data, param.verbose)
    sct.generate_output_file(path_tmp+'dwi_mean.nii', path_out+'dwi'+param.suffix+'_mean'+ext_data, param.verbose)

    # Delete temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.run('rm -rf '+path_tmp, param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s', param.verbose)

    #To view results
    sct.printv('\nTo view results, type:', param.verbose)
    sct.printv('fslview -m ortho,ortho '+param.path_out+file_data+param.suffix+' '+file_data+' &\n', param.verbose, 'info')
コード例 #29
0
ファイル: moco.py プロジェクト: cinnnnn/spinalcordtoolbox
def moco(param):
    """
    Main function that performs motion correction.

    :param param:
    :return:
    """
    # retrieve parameters
    file_data = param.file_data
    file_target = param.file_target
    folder_mat = param.mat_moco  # output folder of mat file
    todo = param.todo
    suffix = param.suffix
    verbose = param.verbose

    # other parameters
    file_mask = 'mask.nii'

    printv('\nInput parameters:', param.verbose)
    printv('  Input file ............ ' + file_data, param.verbose)
    printv('  Reference file ........ ' + file_target, param.verbose)
    printv('  Polynomial degree ..... ' + param.poly, param.verbose)
    printv('  Smoothing kernel ...... ' + param.smooth, param.verbose)
    printv('  Gradient step ......... ' + param.gradStep, param.verbose)
    printv('  Metric ................ ' + param.metric, param.verbose)
    printv('  Sampling .............. ' + param.sampling, param.verbose)
    printv('  Todo .................. ' + todo, param.verbose)
    printv('  Mask  ................. ' + param.fname_mask, param.verbose)
    printv('  Output mat folder ..... ' + folder_mat, param.verbose)

    try:
        os.makedirs(folder_mat)
    except FileExistsError:
        pass

    # Get size of data
    printv('\nData dimensions:', verbose)
    im_data = Image(param.file_data)
    nx, ny, nz, nt, px, py, pz, pt = im_data.dim
    printv(
        ('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt)),
        verbose)

    # copy file_target to a temporary file
    printv('\nCopy file_target to a temporary file...', verbose)
    file_target = "target.nii.gz"
    convert(param.file_target, file_target, verbose=0)

    # Check if user specified a mask
    if not param.fname_mask == '':
        # Check if this mask is soft (i.e., non-binary, such as a Gaussian mask)
        im_mask = Image(param.fname_mask)
        if not np.array_equal(im_mask.data, im_mask.data.astype(bool)):
            # If it is a soft mask, multiply the target by the soft mask.
            im = Image(file_target)
            im_masked = im.copy()
            im_masked.data = im.data * im_mask.data
            im_masked.save(
                verbose=0)  # silence warning about file overwritting

    # If scan is sagittal, split src and target along Z (slice)
    if param.is_sagittal:
        dim_sag = 2  # TODO: find it
        # z-split data (time series)
        im_z_list = split_data(im_data, dim=dim_sag, squeeze_data=False)
        file_data_splitZ = []
        for im_z in im_z_list:
            im_z.save(verbose=0)
            file_data_splitZ.append(im_z.absolutepath)
        # z-split target
        im_targetz_list = split_data(Image(file_target),
                                     dim=dim_sag,
                                     squeeze_data=False)
        file_target_splitZ = []
        for im_targetz in im_targetz_list:
            im_targetz.save(verbose=0)
            file_target_splitZ.append(im_targetz.absolutepath)
        # z-split mask (if exists)
        if not param.fname_mask == '':
            im_maskz_list = split_data(Image(file_mask),
                                       dim=dim_sag,
                                       squeeze_data=False)
            file_mask_splitZ = []
            for im_maskz in im_maskz_list:
                im_maskz.save(verbose=0)
                file_mask_splitZ.append(im_maskz.absolutepath)
        # initialize file list for output matrices
        file_mat = np.empty((nz, nt), dtype=object)

    # axial orientation
    else:
        file_data_splitZ = [file_data]  # TODO: make it absolute like above
        file_target_splitZ = [file_target]  # TODO: make it absolute like above
        # initialize file list for output matrices
        file_mat = np.empty((1, nt), dtype=object)

        # deal with mask
        if not param.fname_mask == '':
            convert(param.fname_mask, file_mask, squeeze_data=False, verbose=0)
            im_maskz_list = [Image(file_mask)
                             ]  # use a list with single element

    # Loop across file list, where each file is either a 2D volume (if sagittal) or a 3D volume (otherwise)
    # file_mat = tuple([[[] for i in range(nt)] for i in range(nz)])

    file_data_splitZ_moco = []
    printv(
        '\nRegister. Loop across Z (note: there is only one Z if orientation is axial)'
    )
    for file in file_data_splitZ:
        iz = file_data_splitZ.index(file)
        # Split data along T dimension
        # printv('\nSplit data along T dimension.', verbose)
        im_z = Image(file)
        list_im_zt = split_data(im_z, dim=3)
        file_data_splitZ_splitT = []
        for im_zt in list_im_zt:
            im_zt.save(verbose=0)
            file_data_splitZ_splitT.append(im_zt.absolutepath)
        # file_data_splitT = file_data + '_T'

        # Motion correction: initialization
        index = np.arange(nt)
        file_data_splitT_num = []
        file_data_splitZ_splitT_moco = []
        failed_transfo = [0 for i in range(nt)]

        # Motion correction: Loop across T
        for indice_index in sct_progress_bar(range(nt),
                                             unit='iter',
                                             unit_scale=False,
                                             desc="Z=" + str(iz) + "/" +
                                             str(len(file_data_splitZ) - 1),
                                             ascii=False,
                                             ncols=80):

            # create indices and display stuff
            it = index[indice_index]
            file_mat[iz][it] = os.path.join(
                folder_mat,
                "mat.Z") + str(iz).zfill(4) + 'T' + str(it).zfill(4)
            file_data_splitZ_splitT_moco.append(
                add_suffix(file_data_splitZ_splitT[it], '_moco'))
            # deal with masking (except in the 'apply' case, where masking is irrelevant)
            input_mask = None
            if not param.fname_mask == '' and not param.todo == 'apply':
                # Check if mask is binary
                if np.array_equal(im_maskz_list[iz].data,
                                  im_maskz_list[iz].data.astype(bool)):
                    # If it is, pass this mask into register() to be used
                    input_mask = im_maskz_list[iz]
                else:
                    # If not, do not pass this mask into register() because ANTs cannot handle non-binary masks.
                    #  Instead, multiply the input data by the Gaussian mask.
                    im = Image(file_data_splitZ_splitT[it])
                    im_masked = im.copy()
                    im_masked.data = im.data * im_maskz_list[iz].data
                    im_masked.save(
                        verbose=0)  # silence warning about file overwritting

            # run 3D registration
            failed_transfo[it] = register(param,
                                          file_data_splitZ_splitT[it],
                                          file_target_splitZ[iz],
                                          file_mat[iz][it],
                                          file_data_splitZ_splitT_moco[it],
                                          im_mask=input_mask)

            # average registered volume with target image
            # N.B. use weighted averaging: (target * nb_it + moco) / (nb_it + 1)
            if param.iterAvg and indice_index < 10 and failed_transfo[
                    it] == 0 and not param.todo == 'apply':
                im_targetz = Image(file_target_splitZ[iz])
                data_targetz = im_targetz.data
                data_mocoz = Image(file_data_splitZ_splitT_moco[it]).data
                data_targetz = (data_targetz * (indice_index + 1) +
                                data_mocoz) / (indice_index + 2)
                im_targetz.data = data_targetz
                im_targetz.save(verbose=0)

        # Replace failed transformation with the closest good one
        fT = [i for i, j in enumerate(failed_transfo) if j == 1]
        gT = [i for i, j in enumerate(failed_transfo) if j == 0]
        for it in range(len(fT)):
            abs_dist = [np.abs(gT[i] - fT[it]) for i in range(len(gT))]
            if not abs_dist == []:
                index_good = abs_dist.index(min(abs_dist))
                printv(
                    '  transfo #' + str(fT[it]) + ' --> use transfo #' +
                    str(gT[index_good]), verbose)
                # copy transformation
                copy(file_mat[iz][gT[index_good]] + 'Warp.nii.gz',
                     file_mat[iz][fT[it]] + 'Warp.nii.gz')
                # apply transformation
                sct_apply_transfo.main(args=[
                    '-i', file_data_splitZ_splitT[fT[it]], '-d', file_target,
                    '-w', file_mat[iz][fT[it]] + 'Warp.nii.gz', '-o',
                    file_data_splitZ_splitT_moco[fT[it]], '-x', param.interp
                ])
            else:
                # exit program if no transformation exists.
                printv(
                    '\nERROR in ' + os.path.basename(__file__) +
                    ': No good transformation exist. Exit program.\n', verbose,
                    'error')
                sys.exit(2)

        # Merge data along T
        file_data_splitZ_moco.append(add_suffix(file, suffix))
        if todo != 'estimate':
            im_out = concat_data(file_data_splitZ_splitT_moco, 3)
            im_out.absolutepath = file_data_splitZ_moco[iz]
            im_out.save(verbose=0)

    # If sagittal, merge along Z
    if param.is_sagittal:
        # TODO: im_out.dim is incorrect: Z value is one
        im_out = concat_data(file_data_splitZ_moco, 2)
        dirname, basename, ext = extract_fname(file_data)
        path_out = os.path.join(dirname, basename + suffix + ext)
        im_out.absolutepath = path_out
        im_out.save(verbose=0)

    return file_mat, im_out
コード例 #30
0
def main(args=None):

    # initialization
    start_time = time.time()
    param = Param()

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    param.fname_data = arguments['-i']
    if '-g' in arguments:
        param.group_size = arguments['-g']
    if '-m' in arguments:
        param.fname_mask = arguments['-m']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-x' in arguments:
        param.interp = arguments['-x']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-r' in arguments:
        param.remove_temp_files = int(arguments['-r'])
    param.verbose = int(arguments.get('-v'))
    sct.init_sct(log_level=param.verbose, update=True)  # Update log level

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  input file ............' + param.fname_data, param.verbose)

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    path_tmp = sct.tmp_create(basename="fmri_moco", verbose=param.verbose)

    # Copying input data to tmp folder and convert to nii
    # TODO: no need to do that (takes time for nothing)
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(param.fname_data, os.path.join(path_tmp, "fmri.nii"), squeeze_data=False)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # run moco
    fmri_moco(param)

    # come back
    os.chdir(curdir)

    # Generate output files
    fname_fmri_moco = os.path.join(path_out, file_data + param.suffix + ext_data)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(os.path.join(path_tmp, "fmri" + param.suffix + '.nii'), fname_fmri_moco, param.verbose)
    sct.generate_output_file(os.path.join(path_tmp, "fmri" + param.suffix + '_mean.nii'), os.path.join(path_out, file_data + param.suffix + '_mean' + ext_data), param.verbose)

    # Delete temporary files
    if param.remove_temp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.rmtree(path_tmp, verbose=param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's', param.verbose)

    sct.display_viewer_syntax([fname_fmri_moco, file_data], mode='ortho,ortho')
コード例 #31
0
def main():

    # Initialization
    fname_data = ''
    interp_factor = param.interp_factor
    remove_temp_files = param.remove_temp_files
    verbose = param.verbose
    suffix = param.suffix
    smoothing_sigma = param.smoothing_sigma

    # start timer
    start_time = time.time()

    # get path of the toolbox
    status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Parameters for debug mode
    if param.debug:
        fname_data = path_sct + '/testing/data/errsm_23/t2/t2_manual_segmentation.nii.gz'
        remove_temp_files = 0
        param.mask_size = 10
    else:
        # Check input parameters
        try:
            opts, args = getopt.getopt(sys.argv[1:], 'hi:v:r:s:')
        except getopt.GetoptError:
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ('-i'):
                fname_data = arg
            elif opt in ('-r'):
                remove_temp_files = int(arg)
            elif opt in ('-s'):
                smoothing_sigma = arg
            elif opt in ('-v'):
                verbose = int(arg)

    # display usage if a mandatory argument is not provided
    if fname_data == '':
        usage()

    # sct.printv(arguments)
    sct.printv('\nCheck parameters:')
    sct.printv('  segmentation ........... ' + fname_data)
    sct.printv('  interp factor .......... ' + str(interp_factor))
    sct.printv('  smoothing sigma ........ ' + str(smoothing_sigma))

    # check existence of input files
    sct.printv('\nCheck existence of input files...')
    sct.check_file_exist(fname_data, verbose)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    # create temporary folder
    sct.printv('\nCreate temporary folder...')
    path_tmp = 'tmp.' + time.strftime("%y%m%d%H%M%S")
    sct.run('mkdir ' + path_tmp)

    from sct_convert import convert
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               param.verbose)
    convert(fname_data, path_tmp + '/data.nii')

    # go to tmp folder
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim
    sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), verbose)

    # upsample data
    sct.printv('\nUpsample data...', verbose)
    sct.run(
        'sct_resample -i data.nii -x linear -vox ' + str(nx * interp_factor) +
        'x' + str(ny * interp_factor) + 'x' + str(nz * interp_factor) +
        ' -o data_up.nii', verbose)

    # Smooth along centerline
    sct.printv('\nSmooth along centerline...', verbose)
    sct.run(
        'sct_smooth_spinalcord -i data_up.nii -s data_up.nii' + ' -smooth ' +
        str(smoothing_sigma) + ' -r ' + str(remove_temp_files) + ' -v ' +
        str(verbose), verbose)

    # downsample data
    sct.printv('\nDownsample data...', verbose)
    sct.run(
        'sct_resample -i data_up_smooth.nii -x linear -vox ' + str(nx) + 'x' +
        str(ny) + 'x' + str(nz) + ' -o data_up_smooth_down.nii', verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...')
    fname_out = sct.generate_output_file(path_tmp + '/data_up_smooth_down.nii',
                                         '' + file_data + suffix + ext_data)

    # Delete temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.run('rm -rf ' + path_tmp)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) +
               's')

    # to view results
    sct.printv('\nTo view results, type:')
    sct.printv('fslview ' + file_data + ' ' + file_data + suffix + ' &\n')
コード例 #32
0
ファイル: moco.py プロジェクト: cinnnnn/spinalcordtoolbox
def moco_wrapper(param):
    """
    Wrapper that performs motion correction.

    :param param: ParamMoco class
    :return: None
    """
    file_data = 'data.nii'  # corresponds to the full input data (e.g. dmri or fmri)
    file_data_dirname, file_data_basename, file_data_ext = extract_fname(
        file_data)
    file_b0 = 'b0.nii'
    file_datasub = 'datasub.nii'  # corresponds to the full input data minus the b=0 scans (if param.is_diffusion=True)
    file_datasubgroup = 'datasub-groups.nii'  # concatenation of the average of each file_datasub
    file_mask = 'mask.nii'
    file_moco_params_csv = 'moco_params.tsv'
    file_moco_params_x = 'moco_params_x.nii.gz'
    file_moco_params_y = 'moco_params_y.nii.gz'
    ext_data = '.nii.gz'  # workaround "too many open files" by slurping the data
    # TODO: check if .nii can be used
    mat_final = 'mat_final/'
    # ext_mat = 'Warp.nii.gz'  # warping field

    # Start timer
    start_time = time.time()

    printv('\nInput parameters:', param.verbose)
    printv('  Input file ............ ' + param.fname_data, param.verbose)
    printv('  Group size ............ {}'.format(param.group_size),
           param.verbose)

    # Get full path
    # param.fname_data = os.path.abspath(param.fname_data)
    # param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    # if param.fname_bvals != '':
    #     param.fname_bvals = os.path.abspath(param.fname_bvals)

    # Extract path, file and extension
    # path_data, file_data, ext_data = extract_fname(param.fname_data)
    # path_mask, file_mask, ext_mask = extract_fname(param.fname_mask)

    path_tmp = tmp_create(basename="moco")

    # Copying input data to tmp folder
    printv('\nCopying input data to tmp folder and convert to nii...',
           param.verbose)
    convert(param.fname_data, os.path.join(path_tmp, file_data))
    if param.fname_mask != '':
        convert(param.fname_mask,
                os.path.join(path_tmp, file_mask),
                verbose=param.verbose)
        # Update field in param (because used later in another function, and param class will be passed)
        param.fname_mask = file_mask

    # Build absolute output path and go to tmp folder
    curdir = os.getcwd()
    path_out_abs = os.path.abspath(param.path_out)
    os.chdir(path_tmp)

    # Get dimensions of data
    printv('\nGet dimensions of data...', param.verbose)
    im_data = Image(file_data)
    nx, ny, nz, nt, px, py, pz, pt = im_data.dim
    printv('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), param.verbose)

    # Get orientation
    printv('\nData orientation: ' + im_data.orientation, param.verbose)
    if im_data.orientation[2] in 'LR':
        param.is_sagittal = True
        printv('  Treated as sagittal')
    elif im_data.orientation[2] in 'IS':
        param.is_sagittal = False
        printv('  Treated as axial')
    else:
        param.is_sagittal = False
        printv(
            'WARNING: Orientation seems to be neither axial nor sagittal. Treated as axial.'
        )

    printv(
        "\nSet suffix of transformation file name, which depends on the orientation:"
    )
    if param.is_sagittal:
        param.suffix_mat = '0GenericAffine.mat'
        printv(
            "Orientation is sagittal, suffix is '{}'. The image is split across the R-L direction, and the "
            "estimated transformation is a 2D affine transfo.".format(
                param.suffix_mat))
    else:
        param.suffix_mat = 'Warp.nii.gz'
        printv(
            "Orientation is axial, suffix is '{}'. The estimated transformation is a 3D warping field, which is "
            "composed of a stack of 2D Tx-Ty transformations".format(
                param.suffix_mat))

    # Adjust group size in case of sagittal scan
    if param.is_sagittal and param.group_size != 1:
        printv(
            'For sagittal data group_size should be one for more robustness. Forcing group_size=1.',
            1, 'warning')
        param.group_size = 1

    if param.is_diffusion:
        # Identify b=0 and DWI images
        index_b0, index_dwi, nb_b0, nb_dwi = \
            sct_dmri_separate_b0_and_dwi.identify_b0(param.fname_bvecs, param.fname_bvals, param.bval_min,
                                                     param.verbose)

        # check if dmri and bvecs are the same size
        if not nb_b0 + nb_dwi == nt:
            printv(
                '\nERROR in ' + os.path.basename(__file__) +
                ': Size of data (' + str(nt) + ') and size of bvecs (' +
                str(nb_b0 + nb_dwi) +
                ') are not the same. Check your bvecs file.\n', 1, 'error')
            sys.exit(2)

    # ==================================================================================================================
    # Prepare data (mean/groups...)
    # ==================================================================================================================

    # Split into T dimension
    printv('\nSplit along T dimension...', param.verbose)
    im_data_split_list = split_data(im_data, 3)
    for im in im_data_split_list:
        x_dirname, x_basename, x_ext = extract_fname(im.absolutepath)
        im.absolutepath = os.path.join(x_dirname, x_basename + ".nii.gz")
        im.save()

    if param.is_diffusion:
        # Merge and average b=0 images
        printv('\nMerge and average b=0 data...', param.verbose)
        im_b0_list = []
        for it in range(nb_b0):
            im_b0_list.append(im_data_split_list[index_b0[it]])
        im_b0 = concat_data(im_b0_list, 3).save(file_b0, verbose=0)
        # Average across time
        im_b0.mean(dim=3).save(add_suffix(file_b0, '_mean'))

        n_moco = nb_dwi  # set number of data to perform moco on (using grouping)
        index_moco = index_dwi

    # If not a diffusion scan, we will motion-correct all volumes
    else:
        n_moco = nt
        index_moco = list(range(0, nt))

    nb_groups = int(math.floor(n_moco / param.group_size))

    # Generate groups indexes
    group_indexes = []
    for iGroup in range(nb_groups):
        group_indexes.append(index_moco[(iGroup *
                                         param.group_size):((iGroup + 1) *
                                                            param.group_size)])

    # add the remaining images to a new last group (in case the total number of image is not divisible by group_size)
    nb_remaining = n_moco % param.group_size  # number of remaining images
    if nb_remaining > 0:
        nb_groups += 1
        group_indexes.append(index_moco[len(index_moco) -
                                        nb_remaining:len(index_moco)])

    _, file_dwi_basename, file_dwi_ext = extract_fname(file_datasub)
    # Group data
    list_file_group = []
    for iGroup in sct_progress_bar(range(nb_groups),
                                   unit='iter',
                                   unit_scale=False,
                                   desc="Merge within groups",
                                   ascii=False,
                                   ncols=80):
        # get index
        index_moco_i = group_indexes[iGroup]
        n_moco_i = len(index_moco_i)
        # concatenate images across time, within this group
        file_dwi_merge_i = os.path.join(file_dwi_basename + '_' + str(iGroup) +
                                        ext_data)
        im_dwi_list = []
        for it in range(n_moco_i):
            im_dwi_list.append(im_data_split_list[index_moco_i[it]])
        im_dwi_out = concat_data(im_dwi_list, 3).save(file_dwi_merge_i,
                                                      verbose=0)
        # Average across time
        list_file_group.append(
            os.path.join(file_dwi_basename + '_' + str(iGroup) + '_mean' +
                         ext_data))
        im_dwi_out.mean(dim=3).save(list_file_group[-1])

    # Merge across groups
    printv('\nMerge across groups...', param.verbose)
    # file_dwi_groups_means_merge = 'dwi_averaged_groups'
    im_dw_list = []
    for iGroup in range(nb_groups):
        im_dw_list.append(list_file_group[iGroup])
    concat_data(im_dw_list, 3).save(file_datasubgroup, verbose=0)

    # Cleanup
    del im, im_data_split_list

    # ==================================================================================================================
    # Estimate moco
    # ==================================================================================================================

    # Initialize another class instance that will be passed on to the moco() function
    param_moco = deepcopy(param)

    if param.is_diffusion:
        # Estimate moco on b0 groups
        printv(
            '\n-------------------------------------------------------------------------------',
            param.verbose)
        printv('  Estimating motion on b=0 images...', param.verbose)
        printv(
            '-------------------------------------------------------------------------------',
            param.verbose)
        param_moco.file_data = 'b0.nii'
        # Identify target image
        if index_moco[0] != 0:
            # If first DWI is not the first volume (most common), then there is a least one b=0 image before. In that
            # case select it as the target image for registration of all b=0
            param_moco.file_target = os.path.join(
                file_data_dirname, file_data_basename + '_T' +
                str(index_b0[index_moco[0] - 1]).zfill(4) + ext_data)
        else:
            # If first DWI is the first volume, then the target b=0 is the first b=0 from the index_b0.
            param_moco.file_target = os.path.join(
                file_data_dirname, file_data_basename + '_T' +
                str(index_b0[0]).zfill(4) + ext_data)
        # Run moco
        param_moco.path_out = ''
        param_moco.todo = 'estimate_and_apply'
        param_moco.mat_moco = 'mat_b0groups'
        file_mat_b0, _ = moco(param_moco)

    # Estimate moco across groups
    printv(
        '\n-------------------------------------------------------------------------------',
        param.verbose)
    printv('  Estimating motion across groups...', param.verbose)
    printv(
        '-------------------------------------------------------------------------------',
        param.verbose)
    param_moco.file_data = file_datasubgroup
    param_moco.file_target = list_file_group[
        0]  # target is the first volume (closest to the first b=0 if DWI scan)
    param_moco.path_out = ''
    param_moco.todo = 'estimate_and_apply'
    param_moco.mat_moco = 'mat_groups'
    file_mat_datasub_group, _ = moco(param_moco)

    # Spline Regularization along T
    if param.spline_fitting:
        # TODO: fix this scenario (haven't touched that code for a while-- it is probably buggy)
        raise NotImplementedError()
        # spline(mat_final, nt, nz, param.verbose, np.array(index_b0), param.plot_graph)

    # ==================================================================================================================
    # Apply moco
    # ==================================================================================================================

    # If group_size>1, assign transformation to each individual ungrouped 3d volume
    if param.group_size > 1:
        file_mat_datasub = []
        for iz in range(len(file_mat_datasub_group)):
            # duplicate by factor group_size the transformation file for each it
            #  example: [mat.Z0000T0001Warp.nii] --> [mat.Z0000T0001Warp.nii, mat.Z0000T0001Warp.nii] for group_size=2
            file_mat_datasub.append(
                functools.reduce(operator.iconcat,
                                 [[i] * param.group_size
                                  for i in file_mat_datasub_group[iz]], []))
    else:
        file_mat_datasub = file_mat_datasub_group

    # Copy transformations to mat_final folder and rename them appropriately
    copy_mat_files(nt, file_mat_datasub, index_moco, mat_final, param)
    if param.is_diffusion:
        copy_mat_files(nt, file_mat_b0, index_b0, mat_final, param)

    # Apply moco on all dmri data
    printv(
        '\n-------------------------------------------------------------------------------',
        param.verbose)
    printv('  Apply moco', param.verbose)
    printv(
        '-------------------------------------------------------------------------------',
        param.verbose)
    param_moco.file_data = file_data
    param_moco.file_target = list_file_group[
        0]  # reference for reslicing into proper coordinate system
    param_moco.path_out = ''  # TODO not used in moco()
    param_moco.mat_moco = mat_final
    param_moco.todo = 'apply'
    file_mat_data, im_moco = moco(param_moco)

    # copy geometric information from header
    # NB: this is required because WarpImageMultiTransform in 2D mode wrongly sets pixdim(3) to "1".
    im_moco.header = im_data.header
    im_moco.save(verbose=0)

    # Average across time
    if param.is_diffusion:
        # generate b0_moco_mean and dwi_moco_mean
        args = [
            '-i', im_moco.absolutepath, '-bvec', param.fname_bvecs, '-a', '1',
            '-v', '0'
        ]
        if not param.fname_bvals == '':
            # if bvals file is provided
            args += ['-bval', param.fname_bvals]
        fname_b0, fname_b0_mean, fname_dwi, fname_dwi_mean = sct_dmri_separate_b0_and_dwi.main(
            args=args)
    else:
        fname_moco_mean = add_suffix(im_moco.absolutepath, '_mean')
        im_moco.mean(dim=3).save(fname_moco_mean)

    # Extract and output the motion parameters (doesn't work for sagittal orientation)
    printv('Extract motion parameters...')
    if param.output_motion_param:
        if param.is_sagittal:
            printv(
                'Motion parameters cannot be generated for sagittal images.',
                1, 'warning')
        else:
            files_warp_X, files_warp_Y = [], []
            moco_param = []
            for fname_warp in file_mat_data[0]:
                # Cropping the image to keep only one voxel in the XY plane
                im_warp = Image(fname_warp + param.suffix_mat)
                im_warp.data = np.expand_dims(np.expand_dims(
                    im_warp.data[0, 0, :, :, :], axis=0),
                                              axis=0)

                # These three lines allow to generate one file instead of two, containing X, Y and Z moco parameters
                #fname_warp_crop = fname_warp + '_crop_' + ext_mat
                # files_warp.append(fname_warp_crop)
                # im_warp.save(fname_warp_crop)

                # Separating the three components and saving X and Y only (Z is equal to 0 by default).
                im_warp_XYZ = multicomponent_split(im_warp)

                fname_warp_crop_X = fname_warp + '_crop_X_' + param.suffix_mat
                im_warp_XYZ[0].save(fname_warp_crop_X)
                files_warp_X.append(fname_warp_crop_X)

                fname_warp_crop_Y = fname_warp + '_crop_Y_' + param.suffix_mat
                im_warp_XYZ[1].save(fname_warp_crop_Y)
                files_warp_Y.append(fname_warp_crop_Y)

                # Calculating the slice-wise average moco estimate to provide a QC file
                moco_param.append([
                    np.mean(np.ravel(im_warp_XYZ[0].data)),
                    np.mean(np.ravel(im_warp_XYZ[1].data))
                ])

            # These two lines allow to generate one file instead of two, containing X, Y and Z moco parameters
            #im_warp_concat = concat_data(files_warp, dim=3)
            # im_warp_concat.save('fmri_moco_params.nii')

            # Concatenating the moco parameters into a time series for X and Y components.
            im_warp_concat = concat_data(files_warp_X, dim=3)
            im_warp_concat.save(file_moco_params_x)

            im_warp_concat = concat_data(files_warp_Y, dim=3)
            im_warp_concat.save(file_moco_params_y)

            # Writing a TSV file with the slicewise average estimate of the moco parameters. Useful for QC
            with open(file_moco_params_csv, 'wt') as out_file:
                tsv_writer = csv.writer(out_file, delimiter='\t')
                tsv_writer.writerow(['X', 'Y'])
                for mocop in moco_param:
                    tsv_writer.writerow([mocop[0], mocop[1]])

    # Generate output files
    printv('\nGenerate output files...', param.verbose)
    fname_moco = os.path.join(
        path_out_abs,
        add_suffix(os.path.basename(param.fname_data), param.suffix))
    generate_output_file(im_moco.absolutepath, fname_moco)
    if param.is_diffusion:
        generate_output_file(fname_b0_mean, add_suffix(fname_moco, '_b0_mean'))
        generate_output_file(fname_dwi_mean,
                             add_suffix(fname_moco, '_dwi_mean'))
    else:
        generate_output_file(fname_moco_mean, add_suffix(fname_moco, '_mean'))
    if os.path.exists(file_moco_params_csv):
        generate_output_file(file_moco_params_x,
                             os.path.join(path_out_abs, file_moco_params_x),
                             squeeze_data=False)
        generate_output_file(file_moco_params_y,
                             os.path.join(path_out_abs, file_moco_params_y),
                             squeeze_data=False)
        generate_output_file(file_moco_params_csv,
                             os.path.join(path_out_abs, file_moco_params_csv))

    # Delete temporary files
    if param.remove_temp_files == 1:
        printv('\nDelete temporary files...', param.verbose)
        rmtree(path_tmp, verbose=param.verbose)

    # come back to working directory
    os.chdir(curdir)

    # display elapsed time
    elapsed_time = time.time() - start_time
    printv(
        '\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's',
        param.verbose)

    display_viewer_syntax([
        os.path.join(
            param.path_out,
            add_suffix(os.path.basename(param.fname_data), param.suffix)),
        param.fname_data
    ],
                          mode='ortho,ortho')
コード例 #33
0
    def execute(self):
        print 'Execution of the SCAD algorithm in '+str(os.getcwd())

        original_name = self.input_image.file_name
        vesselness_file_name = "imageVesselNessFilter.nii.gz"
        raw_file_name = "raw.nii"

        self.setup_debug_folder()

        if self.debug:
            import matplotlib.pyplot as plt # import for debug purposes

        # create tmp and copy input
        path_tmp = self.create_temporary_path()
        conv.convert(self.input_image.absolutepath, path_tmp+raw_file_name)

        if self.vesselness_provided:
            sct.run('cp '+vesselness_file_name+' '+path_tmp+vesselness_file_name)
        os.chdir(path_tmp)

        # get input image information
        img = Image(raw_file_name)

        # save original orientation and change image to RPI
        self.raw_orientation = img.change_orientation()

        # get body symmetry
        if self.enable_symmetry:
            from msct_image import change_data_orientation
            sym = SymmetryDetector(raw_file_name, self.contrast, crop_xy=0)
            self.raw_symmetry = sym.execute()
            img.change_orientation(self.raw_orientation)
            self.output_debug_file(img, self.raw_symmetry, "body_symmetry")
            img.change_orientation()

        # vesselness filter
        if not self.vesselness_provided:
            sct.run('sct_vesselness -i '+raw_file_name+' -t ' + self._contrast+" -radius "+str(self.spinalcord_radius))

        # load vesselness filter data and perform minimum path on it
        img = Image(vesselness_file_name)
        img.change_orientation()
        self.minimum_path_data, self.J1_min_path, self.J2_min_path = get_minimum_path(img.data, invert=1, debug=1)
        self.output_debug_file(img, self.minimum_path_data, "minimal_path")
        self.output_debug_file(img, self.J1_min_path, "J1_minimal_path")
        self.output_debug_file(img, self.J2_min_path, "J2_minimal_path")

        # Apply an exponent to the minimum path
        self.minimum_path_powered = np.power(self.minimum_path_data, self.minimum_path_exponent)
        self.output_debug_file(img, self.minimum_path_powered, "minimal_path_power_"+str(self.minimum_path_exponent))

        # Saving in Image since smooth_minimal_path needs pixel dimensions
        img.data = self.minimum_path_powered

        # smooth resulting minimal path
        self.smoothed_min_path = smooth_minimal_path(img)
        self.output_debug_file(img, self.smoothed_min_path.data, "minimal_path_smooth")

        # normalise symmetry values between 0 and 1
        if self.enable_symmetry:
            normalised_symmetry = normalize_array_histogram(self.raw_symmetry)
            self.output_debug_file(img, self.smoothed_min_path.data, "minimal_path_smooth")

        # multiply normalised symmetry data with the minimum path result
            from msct_image import change_data_orientation
            self.spine_detect_data = np.multiply(self.smoothed_min_path.data, change_data_orientation(np.power(normalised_symmetry, self.symmetry_exponent), self.raw_orientation, "RPI"))
            self.output_debug_file(img, self.spine_detect_data, "symmetry_x_min_path")
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(self.spine_detect_data, self.spine_detect_data.shape)
        else:
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(self.smoothed_min_path.data, self.smoothed_min_path.data.shape)
        self.output_debug_file(img, self.centerline_with_outliers, "centerline_with_outliers")

        # saving centerline with outliers to have
        img.data = self.centerline_with_outliers
        img.change_orientation()
        img.file_name = "centerline_with_outliers"
        img.save()

        # use a b-spline to smooth out the centerline
        x, y, z, dx, dy, dz = smooth_centerline("centerline_with_outliers.nii.gz")

        # save the centerline
        nx, ny, nz, nt, px, py, pz, pt = img.dim
        img.data = np.zeros((nx, ny, nz))
        for i in range(0, np.size(x)-1):
            img.data[int(x[i]), int(y[i]), int(z[i])] = 1

        self.output_debug_file(img, img.data, "centerline")
        img.change_orientation(self.raw_orientation)
        img.file_name = "centerline"
        img.save()

        # copy back centerline
        os.chdir('../')
        conv.convert(path_tmp+img.file_name+img.ext, self.output_filename)
        if self.rm_tmp_file == 1:
            import shutil
            shutil.rmtree(path_tmp)
コード例 #34
0
def generate_output_file(fname_in, fname_out, squeeze_data=True, verbose=1):
    """
    Copy fname_in to fname_out with a few convenient checks: make sure input file exists, if fname_out exists send a
    warning, if input and output NIFTI format are different (nii vs. nii.gz) convert by unzipping or zipping, and
    display nice message at the end.
    :param fname_in:
    :param fname_out:
    :param verbose:
    :return: fname_out
    """
    from sct_convert import convert
    path_in, file_in, ext_in = extract_fname(fname_in)
    path_out, file_out, ext_out = extract_fname(fname_out)
    # create output path (ignore if it already exists)
    pathlib.Path(path_out).mkdir(parents=True, exist_ok=True)
    # if input image does not exist, give error
    if not os.path.isfile(fname_in):
        printv(
            '  ERROR: File ' + fname_in +
            ' is not a regular file. Exit program.', 1, 'error')
        sys.exit(2)
    # if input and output fnames are the same, do nothing and exit function
    if fname_in == fname_out:
        printv('  WARNING: fname_in and fname_out are the same. Do nothing.',
               verbose, 'warning')
        printv('  File created: ' + os.path.join(path_out, file_out + ext_out))
        return os.path.join(path_out, file_out + ext_out)
    # if fname_out already exists in nii or nii.gz format
    if os.path.isfile(os.path.join(path_out, file_out + ext_out)):
        printv(
            '  WARNING: File ' + os.path.join(path_out, file_out + ext_out) +
            ' already exists. Deleting it...', 1, 'warning')
        os.remove(os.path.join(path_out, file_out + ext_out))
    if ext_in != ext_out:
        # Generate output file
        '''
        # TRY TO UNCOMMENT THIS LINES AND RUN IT IN AN OTHER STATION THAN EVANS (testing of sct_label_vertebrae and sct_smooth_spinalcord never stops with this lines on evans)
        if ext_in == '.nii.gz' and ext_out == '.nii':  # added to resolve issue #728
            run('gunzip -f ' + fname_in)
            os.rename(os.path.join(path_in, file_in + '.nii'), fname_out)
        else:
        '''
        convert(fname_in, fname_out, squeeze_data=squeeze_data, verbose=0)
    else:
        # Generate output file without changing the extension
        shutil.move(fname_in, fname_out)

    # # Move file to output folder (keep the same extension as input)
    # shutil.move(fname_in, path_out+file_out+ext_in)
    # # convert to nii (only if necessary)
    # if ext_out == '.nii' and ext_in != '.nii':
    #     convert(os.path.join(path_out, file_out+ext_in), os.path.join(path_out, file_out+ext_out))
    #     os.remove(os.path.join(path_out, file_out+ext_in))  # remove nii.gz file
    # # convert to nii.gz (only if necessary)
    # if ext_out == '.nii.gz' and ext_in != '.nii.gz':
    #     convert(os.path.join(path_out, file_out+ext_in), os.path.join(path_out, file_out+ext_out))
    #     os.remove(os.path.join(path_out, file_out+ext_in))  # remove nii file
    # display message
    printv('  File created: ' + os.path.join(path_out, file_out + ext_out),
           verbose)
    # if verbose:
    #     printv('  File created: '+ os.path.join(path_out, file_out+ext_out))
    return os.path.join(path_out, file_out + ext_out)
コード例 #35
0
def create_mask():
    fsloutput = 'export FSLOUTPUTTYPE=NIFTI; '  # for faster processing, all outputs are in NIFTI

    # parse argument for method
    method_type = param.process[0]
    # check method val
    if not method_type == 'center':
        method_val = param.process[1]

    # check existence of input files
    if method_type == 'centerline':
        sct.check_file_exist(method_val, param.verbose)

    # check if orientation is RPI
    sct.printv('\nCheck if orientation is RPI...', param.verbose)
    ori = get_orientation(param.fname_data, filename=True)
    if not ori == 'RPI':
        sct.printv('\nERROR in '+os.path.basename(__file__)+': Orientation of input image should be RPI. Use sct_image -setorient to put your image in RPI.\n', 1, 'error')

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    # Get output folder and file name
    if param.fname_out == '':
        param.fname_out = param.file_prefix+file_data+ext_data
    #fname_out = os.path.abspath(path_out+file_out+ext_out)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, param.verbose)

    # Copying input data to tmp folder and convert to nii
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(param.fname_data, path_tmp+'data.nii')
    # sct.run('cp '+param.fname_data+' '+path_tmp+'data'+ext_data, param.verbose)
    if method_type == 'centerline':
        convert(method_val, path_tmp+'centerline.nii.gz')

    # go to tmp folder
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim
    sct.printv('  ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), param.verbose)
    # in case user input 4d data
    if nt != 1:
        sct.printv('WARNING in '+os.path.basename(__file__)+': Input image is 4d but output mask will 3D.', param.verbose, 'warning')
        # extract first volume to have 3d reference
        nii = Image('data.nii')
        data3d = nii.data[:,:,:,0]
        nii.data = data3d
        nii.save()

    if method_type == 'coord':
        # parse to get coordinate
        coord = map(int, method_val.split('x'))

    if method_type == 'point':
        # get file name
        fname_point = method_val
        # extract coordinate of point
        sct.printv('\nExtract coordinate of point...', param.verbose)
        status, output = sct.run('sct_label_utils -i '+fname_point+' -p display-voxel', param.verbose)
        # parse to get coordinate
        coord = output[output.find('Position=')+10:-17].split(',')

    if method_type == 'center':
        # set coordinate at center of FOV
        coord = round(float(nx)/2), round(float(ny)/2)

    if method_type == 'centerline':
        # get name of centerline from user argument
        fname_centerline = 'centerline.nii.gz'
    else:
        # generate volume with line along Z at coordinates 'coord'
        sct.printv('\nCreate line...', param.verbose)
        fname_centerline = create_line('data.nii', coord, nz)

    # create mask
    sct.printv('\nCreate mask...', param.verbose)
    centerline = nibabel.load(fname_centerline)  # open centerline
    hdr = centerline.get_header()  # get header
    hdr.set_data_dtype('uint8')  # set imagetype to uint8
    data_centerline = centerline.get_data()  # get centerline
    z_centerline = [iz for iz in range(0, nz, 1) if data_centerline[:, :, iz].any()]
    nz = len(z_centerline)
    # get center of mass of the centerline
    cx = [0] * nz
    cy = [0] * nz
    for iz in range(0, nz, 1):
        cx[iz], cy[iz] = ndimage.measurements.center_of_mass(numpy.array(data_centerline[:, :, z_centerline[iz]]))
    # create 2d masks
    file_mask = 'data_mask'
    for iz in range(nz):
        center = numpy.array([cx[iz], cy[iz]])
        mask2d = create_mask2d(center, param.shape, param.size, nx, ny, param.even)
        # Write NIFTI volumes
        img = nibabel.Nifti1Image(mask2d, None, hdr)
        nibabel.save(img, (file_mask+str(iz)+'.nii'))
    # merge along Z
    # cmd = 'fslmerge -z mask '
    im_list = []
    for iz in range(nz):
        im_list.append(Image(file_mask+str(iz)+'.nii'))
    im_out = concat_data(im_list, 2)
    im_out.setFileName('mask.nii.gz')
    im_out.save()

    # copy geometry
    im_dat = Image('data.nii')
    im_mask = Image('mask.nii.gz')
    im_mask = copy_header(im_dat, im_mask)
    im_mask.save()

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp+'mask.nii.gz', param.fname_out)

    # Remove temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...', param.verbose)
        sct.run('rm -rf '+path_tmp, param.verbose, error_exit='warning')

    # to view results
    sct.printv('\nDone! To view results, type:', param.verbose)
    sct.printv('fslview '+param.fname_data+' '+param.fname_out+' -l Red -t 0.5 &', param.verbose, 'info')
    print
コード例 #36
0
def main(args=None):
    if args is None:
        args = sys.argv[1:]

    # initialize parameters
    param = Param()

    # Initialization
    fname_output = ''
    path_out = ''
    fname_src_seg = ''
    fname_dest_seg = ''
    fname_src_label = ''
    fname_dest_label = ''
    generate_warpinv = 1

    start_time = time.time()
    # get path of the toolbox
    status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # get default registration parameters
    # step1 = Paramreg(step='1', type='im', algo='syn', metric='MI', iter='5', shrink='1', smooth='0', gradStep='0.5')
    step0 = Paramreg(step='0', type='im', algo='syn', metric='MI', iter='0', shrink='1', smooth='0', gradStep='0.5', slicewise='0', dof='Tx_Ty_Tz_Rx_Ry_Rz')  # only used to put src into dest space
    step1 = Paramreg(step='1', type='im')
    paramreg = ParamregMultiStep([step0, step1])

    parser = get_parser(paramreg=paramreg)

    arguments = parser.parse(args)

    # get arguments
    fname_src = arguments['-i']
    fname_dest = arguments['-d']
    if '-iseg' in arguments:
        fname_src_seg = arguments['-iseg']
    if '-dseg' in arguments:
        fname_dest_seg = arguments['-dseg']
    if '-ilabel' in arguments:
        fname_src_label = arguments['-ilabel']
    if '-dlabel' in arguments:
        fname_dest_label = arguments['-dlabel']
    if '-o' in arguments:
        fname_output = arguments['-o']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-owarp' in arguments:
        fname_output_warp = arguments['-owarp']
    else:
        fname_output_warp = ''
    if '-initwarp' in arguments:
        fname_initwarp = os.path.abspath(arguments['-initwarp'])
    else:
        fname_initwarp = ''
    if '-initwarpinv' in arguments:
        fname_initwarpinv = os.path.abspath(arguments['-initwarpinv'])
    else:
        fname_initwarpinv = ''
    if '-m' in arguments:
        fname_mask = arguments['-m']
    else:
        fname_mask = ''
    padding = arguments['-z']
    if "-param" in arguments:
        paramreg_user = arguments['-param']
        # update registration parameters
        for paramStep in paramreg_user:
            paramreg.addStep(paramStep)

    identity = int(arguments['-identity'])
    interp = arguments['-x']
    remove_temp_files = int(arguments['-r'])
    verbose = int(arguments['-v'])

    # print arguments
    print '\nInput parameters:'
    print '  Source .............. '+fname_src
    print '  Destination ......... '+fname_dest
    print '  Init transfo ........ '+fname_initwarp
    print '  Mask ................ '+fname_mask
    print '  Output name ......... '+fname_output
    # print '  Algorithm ........... '+paramreg.algo
    # print '  Number of iterations  '+paramreg.iter
    # print '  Metric .............. '+paramreg.metric
    print '  Remove temp files ... '+str(remove_temp_files)
    print '  Verbose ............. '+str(verbose)

    # update param
    param.verbose = verbose
    param.padding = padding
    param.fname_mask = fname_mask
    param.remove_temp_files = remove_temp_files

    # Get if input is 3D
    sct.printv('\nCheck if input data are 3D...', verbose)
    sct.check_if_3d(fname_src)
    sct.check_if_3d(fname_dest)


    # Check if user selected type=seg, but did not input segmentation data
    if 'paramreg_user' in locals():
        if True in ['type=seg' in paramreg_user[i] for i in range(len(paramreg_user))]:
            if fname_src_seg == '' or fname_dest_seg == '':
                sct.printv('\nERROR: if you select type=seg you must specify -iseg and -dseg flags.\n', 1, 'error')

    # Extract path, file and extension
    path_src, file_src, ext_src = sct.extract_fname(fname_src)
    path_dest, file_dest, ext_dest = sct.extract_fname(fname_dest)

    # check if source and destination images have the same name (related to issue #373)
    # If so, change names to avoid conflict of result files and warns the user
    suffix_src, suffix_dest = '_reg', '_reg'
    if file_src == file_dest:
        suffix_src, suffix_dest = '_src_reg', '_dest_reg'

    # define output folder and file name
    if fname_output == '':
        path_out = '' if not path_out else path_out  # output in user's current directory
        file_out = file_src + suffix_src
        file_out_inv = file_dest + suffix_dest
        ext_out = ext_src
    else:
        path, file_out, ext_out = sct.extract_fname(fname_output)
        path_out = path if not path_out else path_out
        file_out_inv = file_out + '_inv'

    # create QC folder
    sct.create_folder(param.path_qc)

    # create temporary folder
    path_tmp = sct.tmp_create()

    # copy files to temporary folder
    from sct_convert import convert
    sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose)
    convert(fname_src, path_tmp+'src.nii')
    convert(fname_dest, path_tmp+'dest.nii')

    if fname_src_seg:
        convert(fname_src_seg, path_tmp+'src_seg.nii')
        convert(fname_dest_seg, path_tmp+'dest_seg.nii')

    if fname_src_label:
        convert(fname_src_label, path_tmp+'src_label.nii')
        convert(fname_dest_label, path_tmp+'dest_label.nii')

    if fname_mask != '':
        convert(fname_mask, path_tmp+'mask.nii.gz')

    # go to tmp folder
    os.chdir(path_tmp)

    # reorient destination to RPI
    sct.run('sct_image -i dest.nii -setorient RPI -o dest_RPI.nii')
    if fname_dest_seg:
        sct.run('sct_image -i dest_seg.nii -setorient RPI -o dest_seg_RPI.nii')
    if fname_dest_label:
        sct.run('sct_image -i dest_label.nii -setorient RPI -o dest_label_RPI.nii')

    if identity:
        # overwrite paramreg and only do one identity transformation
        step0 = Paramreg(step='0', type='im', algo='syn', metric='MI', iter='0', shrink='1', smooth='0', gradStep='0.5')
        paramreg = ParamregMultiStep([step0])

    # Put source into destination space using header (no estimation -- purely based on header)
    # TODO: Check if necessary to do that
    # TODO: use that as step=0
    # sct.printv('\nPut source into destination space using header...', verbose)
    # sct.run('isct_antsRegistration -d 3 -t Translation[0] -m MI[dest_pad.nii,src.nii,1,16] -c 0 -f 1 -s 0 -o [regAffine,src_regAffine.nii] -n BSpline[3]', verbose)
    # if segmentation, also do it for seg

    # initialize list of warping fields
    warp_forward = []
    warp_inverse = []

    # initial warping is specified, update list of warping fields and skip step=0
    if fname_initwarp:
        sct.printv('\nSkip step=0 and replace with initial transformations: ', param.verbose)
        sct.printv('  '+fname_initwarp, param.verbose)
        # sct.run('cp '+fname_initwarp+' warp_forward_0.nii.gz', verbose)
        warp_forward = [fname_initwarp]
        start_step = 1
        if fname_initwarpinv:
            warp_inverse = [fname_initwarpinv]
        else:
            sct.printv('\nWARNING: No initial inverse warping field was specified, therefore the inverse warping field will NOT be generated.', param.verbose, 'warning')
            generate_warpinv = 0
    else:
        start_step = 0

    # loop across registration steps
    for i_step in range(start_step, len(paramreg.steps)):
        sct.printv('\n--\nESTIMATE TRANSFORMATION FOR STEP #'+str(i_step), param.verbose)
        # identify which is the src and dest
        if paramreg.steps[str(i_step)].type == 'im':
            src = 'src.nii'
            dest = 'dest_RPI.nii'
            interp_step = 'spline'
        elif paramreg.steps[str(i_step)].type == 'seg':
            src = 'src_seg.nii'
            dest = 'dest_seg_RPI.nii'
            interp_step = 'nn'
        elif paramreg.steps[str(i_step)].type == 'label':
            src = 'src_label.nii'
            dest = 'dest_label_RPI.nii'
            interp_step = 'nn'
        else:
            # src = dest = interp_step = None
            sct.printv('ERROR: Wrong image type.', 1, 'error')
        # if step>0, apply warp_forward_concat to the src image to be used
        if i_step > 0:
            sct.printv('\nApply transformation from previous step', param.verbose)
            sct.run('sct_apply_transfo -i '+src+' -d '+dest+' -w '+','.join(warp_forward)+' -o '+sct.add_suffix(src, '_reg')+' -x '+interp_step, verbose)
            src = sct.add_suffix(src, '_reg')
        # register src --> dest
        warp_forward_out, warp_inverse_out = register(src, dest, paramreg, param, str(i_step))
        warp_forward.append(warp_forward_out)
        warp_inverse.insert(0, warp_inverse_out)

    # Concatenate transformations
    sct.printv('\nConcatenate transformations...', verbose)
    sct.run('sct_concat_transfo -w '+','.join(warp_forward)+' -d dest.nii -o warp_src2dest.nii.gz', verbose)
    sct.run('sct_concat_transfo -w '+','.join(warp_inverse)+' -d dest.nii -o warp_dest2src.nii.gz', verbose)

    # Apply warping field to src data
    sct.printv('\nApply transfo source --> dest...', verbose)
    sct.run('sct_apply_transfo -i src.nii -o src_reg.nii -d dest.nii -w warp_src2dest.nii.gz -x '+interp, verbose)
    sct.printv('\nApply transfo dest --> source...', verbose)
    sct.run('sct_apply_transfo -i dest.nii -o dest_reg.nii -d src.nii -w warp_dest2src.nii.gz -x '+interp, verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    # generate: src_reg
    fname_src2dest = sct.generate_output_file(path_tmp+'src_reg.nii', path_out+file_out+ext_out, verbose)
    # generate: forward warping field
    if fname_output_warp == '':
        fname_output_warp = path_out+'warp_'+file_src+'2'+file_dest+'.nii.gz'
    sct.generate_output_file(path_tmp+'warp_src2dest.nii.gz', fname_output_warp, verbose)
    if generate_warpinv:
        # generate: dest_reg
        fname_dest2src = sct.generate_output_file(path_tmp+'dest_reg.nii', path_out+file_out_inv+ext_dest, verbose)
        # generate: inverse warping field
        sct.generate_output_file(path_tmp+'warp_dest2src.nii.gz', path_out+'warp_'+file_dest+'2'+file_src+'.nii.gz', verbose)

    # Delete temporary files
    if remove_temp_files:
        sct.printv('\nRemove temporary files...', verbose)
        sct.run('rm -rf '+path_tmp, verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s', verbose)
    sct.printv('\nTo view results, type:', verbose)
    sct.printv('fslview '+fname_dest+' '+fname_src2dest+' &', verbose, 'info')
    if generate_warpinv:
        sct.printv('fslview '+fname_src+' '+fname_dest2src+' &\n', verbose, 'info')
コード例 #37
0
def main():

    # initialization
    start_time = time.time()
    path_out = '.'
    param_user = ''

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # get path of the toolbox
    status, param.path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Parameters for debug mode
    if param.debug:
        # get path of the testing data
        status, path_sct_data = commands.getstatusoutput(
            'echo $SCT_TESTING_DATA_DIR')
        param.fname_data = path_sct_data + '/dmri/dmri.nii.gz'
        param.fname_bvecs = path_sct_data + '/dmri/bvecs.txt'
        param.fname_mask = path_sct_data + '/dmri/dmri.nii.gz'
        param.remove_tmp_files = 0
        param.verbose = 1
        param.run_eddy = 0
        param.otsu = 0
        param.group_size = 5
        param.iterative_averaging = 1
    else:
        # Check input parameters
        try:
            opts, args = getopt.getopt(sys.argv[1:],
                                       'hi:a:b:e:f:g:m:o:p:r:t:v:x:')
        except getopt.GetoptError:
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ('-a'):
                param.fname_bvals = arg
            elif opt in ('-b'):
                param.fname_bvecs = arg
            elif opt in ('-e'):
                param.run_eddy = int(arg)
            elif opt in ('-f'):
                param.spline_fitting = int(arg)
            elif opt in ('-g'):
                param.group_size = int(arg)
            elif opt in ('-i'):
                param.fname_data = arg
            elif opt in ('-m'):
                param.fname_mask = arg
            elif opt in ('-o'):
                path_out = arg
            elif opt in ('-p'):
                param_user = arg
            elif opt in ('-r'):
                param.remove_tmp_files = int(arg)
            elif opt in ('-t'):
                param.otsu = int(arg)
            elif opt in ('-v'):
                param.verbose = int(arg)
            elif opt in ('-x'):
                param.interp = arg

    # display usage if a mandatory argument is not provided
    if param.fname_data == '' or param.fname_bvecs == '':
        sct.printv(
            'ERROR: All mandatory arguments are not provided. See usage.', 1,
            'error')
        usage()

    # parse argument for param
    if not param_user == '':
        param.param = param_user.replace(' ', '').split(
            ',')  # remove spaces and parse with comma
        # TODO: check integrity of input
        # param.param = [i for i in range(len(param_user))]
        del param_user

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  input file ............' + param.fname_data, param.verbose)
    sct.printv('  bvecs file ............' + param.fname_bvecs, param.verbose)
    sct.printv('  bvals file ............' + param.fname_bvals, param.verbose)
    sct.printv('  mask file .............' + param.fname_mask, param.verbose)

    # check existence of input files
    sct.printv('\nCheck file existence...', param.verbose)
    sct.check_file_exist(param.fname_data, param.verbose)
    sct.check_file_exist(param.fname_bvecs, param.verbose)
    if not param.fname_bvals == '':
        sct.check_file_exist(param.fname_bvals, param.verbose)
    if not param.fname_mask == '':
        sct.check_file_exist(param.fname_mask, param.verbose)

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    if param.fname_bvals != '':
        param.fname_bvals = os.path.abspath(param.fname_bvals)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_mask, file_mask, ext_mask = sct.extract_fname(param.fname_mask)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.' + time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir ' + path_tmp, param.verbose)

    # Copying input data to tmp folder
    # NB: cannot use c3d here because c3d cannot convert 4D data.
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               param.verbose)
    sct.run('cp ' + param.fname_data + ' ' + path_tmp + 'dmri' + ext_data,
            param.verbose)
    sct.run('cp ' + param.fname_bvecs + ' ' + path_tmp + 'bvecs.txt',
            param.verbose)
    if param.fname_mask != '':
        sct.run('cp ' + param.fname_mask + ' ' + path_tmp + 'mask' + ext_mask,
                param.verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # convert dmri to nii format
    convert('dmri' + ext_data, 'dmri.nii')

    # update field in param (because used later).
    # TODO: make this cleaner...
    if param.fname_mask != '':
        param.fname_mask = 'mask' + ext_mask

    # run moco
    dmri_moco(param)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    path_out = sct.slash_at_the_end(path_out, 1)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(path_tmp + 'dmri' + param.suffix + '.nii',
                             path_out + file_data + param.suffix + ext_data,
                             param.verbose)
    sct.generate_output_file(
        path_tmp + 'b0_mean.nii',
        path_out + 'b0' + param.suffix + '_mean' + ext_data, param.verbose)
    sct.generate_output_file(
        path_tmp + 'dwi_mean.nii',
        path_out + 'dwi' + param.suffix + '_mean' + ext_data, param.verbose)

    # Delete temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.run('rm -rf ' + path_tmp, param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv(
        '\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) + 's',
        param.verbose)

    #To view results
    sct.printv('\nTo view results, type:', param.verbose)
    sct.printv(
        'fslview -m ortho,ortho ' + param.path_out + file_data + param.suffix +
        ' ' + file_data + ' &\n', param.verbose, 'info')
コード例 #38
0
def main(args=None):

    # initialization
    start_time = time.time()
    param = Param()

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    param.fname_data = arguments['-i']
    if '-g' in arguments:
        param.group_size = arguments['-g']
    if '-m' in arguments:
        param.fname_mask = arguments['-m']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-x' in arguments:
        param.interp = arguments['-x']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-r' in arguments:
        param.remove_tmp_files = int(arguments['-r'])
    if '-v' in arguments:
        param.verbose = int(arguments['-v'])

    sct.printv('\nInput parameters:', param.verbose)
    sct.printv('  input file ............' + param.fname_data, param.verbose)

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', param.verbose)
    path_tmp = sct.slash_at_the_end('tmp.' + time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir ' + path_tmp, param.verbose)

    # Copying input data to tmp folder and convert to nii
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               param.verbose)
    convert(param.fname_data, path_tmp + 'fmri.nii')

    # go to tmp folder
    os.chdir(path_tmp)

    # run moco
    fmri_moco(param)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    path_out = sct.slash_at_the_end(path_out, 1)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    if os.path.isfile(path_tmp + 'fmri' + param.suffix + '.nii'):
        sct.printv(path_tmp + 'fmri' + param.suffix + '.nii')
        sct.printv(path_out + file_data + param.suffix + ext_data)
    sct.generate_output_file(path_tmp + 'fmri' + param.suffix + '.nii',
                             path_out + file_data + param.suffix + ext_data,
                             param.verbose)
    sct.generate_output_file(
        path_tmp + 'fmri' + param.suffix + '_mean.nii',
        path_out + file_data + param.suffix + '_mean' + ext_data,
        param.verbose)

    # Delete temporary files
    if param.remove_tmp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.run('rm -rf ' + path_tmp, param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv(
        '\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) + 's',
        param.verbose)

    # To view results
    sct.printv('\nTo view results, type:', param.verbose)
    sct.printv(
        'fslview -m ortho,ortho ' + param.path_out + file_data + param.suffix +
        ' ' + file_data + ' &\n', param.verbose, 'info')
コード例 #39
0
def main():

    # Initialization
    fname_mt0 = ''
    fname_mt1 = ''
    file_out = param.file_out
    # register = param.register
    # remove_tmp_files = param.remove_tmp_files
    # verbose = param.verbose

    # get path of the toolbox
    # status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Check input parameters
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    fname_mt0 = arguments['-mt0']
    fname_mt1 = arguments['-mt1']
    remove_tmp_files = int(arguments['-r'])
    verbose = int(arguments['-v'])

    # Extract path/file/extension
    path_mt0, file_mt0, ext_mt0 = sct.extract_fname(fname_mt0)
    path_out, file_out, ext_out = '', file_out, ext_mt0

    # create temporary folder
    path_tmp = sct.tmp_create()

    # Copying input data to tmp folder and convert to nii
    sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose)
    from sct_convert import convert
    convert(fname_mt0, path_tmp+'mt0.nii', type='float32')
    convert(fname_mt1, path_tmp+'mt1.nii', type='float32')

    # go to tmp folder
    os.chdir(path_tmp)

    # compute MTR
    sct.printv('\nCompute MTR...', verbose)
    from msct_image import Image
    nii_mt1 = Image('mt1.nii')
    data_mt1 = nii_mt1.data
    data_mt0 = Image('mt0.nii').data
    data_mtr = 100 * (data_mt0 - data_mt1) / data_mt0
    # save MTR file
    nii_mtr = nii_mt1
    nii_mtr.data = data_mtr
    nii_mtr.setFileName('mtr.nii')
    nii_mtr.save()
    # sct.run(fsloutput+'fslmaths -dt double mt0.nii -sub mt1.nii -mul 100 -div mt0.nii -thr 0 -uthr 100 mtr.nii', verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    sct.generate_output_file(path_tmp+'mtr.nii', path_out+file_out+ext_out)

    # Remove temporary files
    if remove_tmp_files == 1:
        print('\nRemove temporary files...')
        sct.run('rm -rf '+path_tmp)

    # to view results
    sct.printv('\nDone! To view results, type:', verbose)
    sct.printv('fslview '+fname_mt0+' '+fname_mt1+' '+file_out+' &\n', verbose, 'info')
コード例 #40
0
def main(args=None):
    if not args:
        args = sys.argv[1:]

    # initialize parameters
    param = Param()
    # call main function
    parser = get_parser()
    arguments = parser.parse(args)

    fname_data = arguments['-i']
    fname_bvecs = arguments['-bvec']
    average = arguments['-a']
    verbose = int(arguments['-v'])
    remove_temp_files = int(arguments['-r'])
    path_out = arguments['-ofolder']

    if '-bval' in arguments:
        fname_bvals = arguments['-bval']
    else:
        fname_bvals = ''
    if '-bvalmin' in arguments:
        param.bval_min = arguments['-bvalmin']

    # Initialization
    start_time = time.time()

    # sct.printv(arguments)
    sct.printv('\nInput parameters:', verbose)
    sct.printv('  input file ............' + fname_data, verbose)
    sct.printv('  bvecs file ............' + fname_bvecs, verbose)
    sct.printv('  bvals file ............' + fname_bvals, verbose)
    sct.printv('  average ...............' + str(average), verbose)

    # Get full path
    fname_data = os.path.abspath(fname_data)
    fname_bvecs = os.path.abspath(fname_bvecs)
    if fname_bvals:
        fname_bvals = os.path.abspath(fname_bvals)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    # # get output folder
    # if path_out == '':
    #     path_out = ''

    # create temporary folder
    path_tmp = sct.tmp_create(basename="dmri_separate", verbose=verbose)

    # copy files into tmp folder and convert to nifti
    sct.printv('\nCopy files into temporary folder...', verbose)
    ext = '.nii'
    dmri_name = 'dmri'
    b0_name = 'b0'
    b0_mean_name = b0_name + '_mean'
    dwi_name = 'dwi'
    dwi_mean_name = dwi_name + '_mean'

    from sct_convert import convert
    if not convert(fname_data, os.path.join(path_tmp, dmri_name + ext)):
        sct.printv('ERROR in convert.', 1, 'error')
    sct.copy(fname_bvecs, os.path.join(path_tmp, "bvecs"), verbose=verbose)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # Get size of data
    im_dmri = Image(dmri_name + ext)
    sct.printv('\nGet dimensions data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = im_dmri.dim
    sct.printv(
        '.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt),
        verbose)

    # Identify b=0 and DWI images
    sct.printv(fname_bvals)
    index_b0, index_dwi, nb_b0, nb_dwi = identify_b0(fname_bvecs, fname_bvals,
                                                     param.bval_min, verbose)

    # Split into T dimension
    sct.printv('\nSplit along T dimension...', verbose)
    im_dmri_split_list = split_data(im_dmri, 3)
    for im_d in im_dmri_split_list:
        im_d.save()

    # Merge b=0 images
    sct.printv('\nMerge b=0...', verbose)
    from sct_image import concat_data
    l = []
    for it in range(nb_b0):
        l.append(dmri_name + '_T' + str(index_b0[it]).zfill(4) + ext)
    im_out = concat_data(l, 3).save(b0_name + ext)

    # Average b=0 images
    if average:
        sct.printv('\nAverage b=0...', verbose)
        sct.run([
            'sct_maths', '-i', b0_name + ext, '-o', b0_mean_name + ext,
            '-mean', 't'
        ], verbose)

    # Merge DWI
    l = []
    for it in range(nb_dwi):
        l.append(dmri_name + '_T' + str(index_dwi[it]).zfill(4) + ext)
    im_out = concat_data(l, 3).save(dwi_name + ext)

    # Average DWI images
    if average:
        sct.printv('\nAverage DWI...', verbose)
        sct.run([
            'sct_maths', '-i', dwi_name + ext, '-o', dwi_mean_name + ext,
            '-mean', 't'
        ], verbose)
        # if not average_data_across_dimension('dwi.nii', 'dwi_mean.nii', 3):
        #     sct.printv('ERROR in average_data_across_dimension', 1, 'error')
        # sct.run(fsloutput + 'fslmaths dwi -Tmean dwi_mean', verbose)

    # come back
    os.chdir(curdir)

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    sct.generate_output_file(os.path.join(path_tmp, b0_name + ext),
                             os.path.join(path_out, b0_name + ext_data),
                             verbose)
    sct.generate_output_file(os.path.join(path_tmp, dwi_name + ext),
                             os.path.join(path_out, dwi_name + ext_data),
                             verbose)
    if average:
        sct.generate_output_file(
            os.path.join(path_tmp, b0_mean_name + ext),
            os.path.join(path_out, b0_mean_name + ext_data), verbose)
        sct.generate_output_file(
            os.path.join(path_tmp, dwi_mean_name + ext),
            os.path.join(path_out, dwi_mean_name + ext_data), verbose)

    # Remove temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...', verbose)
        sct.rmtree(path_tmp, verbose=verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv(
        '\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's',
        verbose)

    # to view results
    sct.printv('\nTo view results, type: ', verbose)
    if average:
        sct.display_viewer_syntax(['b0', 'b0_mean', 'dwi', 'dwi_mean'])
    else:
        sct.display_viewer_syntax(['b0', 'dwi'])
コード例 #41
0
def main():
    
    # Initialization
    fname_data = ''
    interp_factor = param.interp_factor
    remove_temp_files = param.remove_temp_files
    verbose = param.verbose
    suffix = param.suffix
    smoothing_sigma = param.smoothing_sigma

    # start timer
    start_time = time.time()
    
    # get path of the toolbox
    status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Parameters for debug mode
    if param.debug:
        fname_data = path_sct+'/testing/data/errsm_23/t2/t2_manual_segmentation.nii.gz'
        remove_temp_files = 0
        param.mask_size = 10
    else:
        # Check input parameters
        try:
            opts, args = getopt.getopt(sys.argv[1:],'hi:v:r:s:')
        except getopt.GetoptError:
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ('-i'):
                fname_data = arg
            elif opt in ('-r'):
                remove_temp_files = int(arg)
            elif opt in ('-s'):
                smoothing_sigma = arg
            elif opt in ('-v'):
                verbose = int(arg)

    # display usage if a mandatory argument is not provided
    if fname_data == '':
        usage()

    # print arguments
    print '\nCheck parameters:'
    print '  segmentation ........... '+fname_data
    print '  interp factor .......... '+str(interp_factor)
    print '  smoothing sigma ........ '+str(smoothing_sigma)

    # check existence of input files
    print('\nCheck existence of input files...')
    sct.check_file_exist(fname_data, verbose)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    # create temporary folder
    print('\nCreate temporary folder...')
    path_tmp = 'tmp.'+time.strftime("%y%m%d%H%M%S")
    sct.run('mkdir '+path_tmp)

    from sct_convert import convert
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(fname_data, path_tmp+'/data.nii')

    # go to tmp folder
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim
    sct.printv('.. '+str(nx)+' x '+str(ny)+' x '+str(nz), verbose)

    # upsample data
    sct.printv('\nUpsample data...', verbose)
    sct.run('sct_resample -i data.nii -x linear -vox '+str(nx*interp_factor)+'x'+str(ny*interp_factor)+'x'+str(nz*interp_factor)+' -o data_up.nii', verbose)

    # Smooth along centerline
    sct.printv('\nSmooth along centerline...', verbose)
    sct.run('sct_smooth_spinalcord -i data_up.nii -s data_up.nii'+' -smooth '+str(smoothing_sigma)+' -r '+str(remove_temp_files)+' -v '+str(verbose), verbose)

    # downsample data
    sct.printv('\nDownsample data...', verbose)
    sct.run('sct_resample -i data_up_smooth.nii -x linear -vox '+str(nx)+'x'+str(ny)+'x'+str(nz)+' -o data_up_smooth_down.nii', verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    print('\nGenerate output files...')
    fname_out = sct.generate_output_file(path_tmp+'/data_up_smooth_down.nii', ''+file_data+suffix+ext_data)

    # Delete temporary files
    if remove_temp_files == 1:
        print '\nRemove temporary files...'
        sct.run('rm -rf '+ path_tmp)

    # display elapsed time
    elapsed_time = time.time() - start_time
    print '\nFinished! Elapsed time: '+str(int(round(elapsed_time)))+'s'

    # to view results
    print '\nTo view results, type:'
    print 'fslview '+file_data+' '+file_data+suffix+' &\n'
コード例 #42
0
def check_and_correct_segmentation(fname_segmentation,
                                   fname_centerline,
                                   folder_output='',
                                   threshold_distance=5.0,
                                   remove_temp_files=1,
                                   verbose=0):
    """
    This function takes the outputs of isct_propseg (centerline and segmentation) and check if the centerline of the
    segmentation is coherent with the centerline provided by the isct_propseg, especially on the edges (related
    to issue #1074).
    Args:
        fname_segmentation: filename of binary segmentation
        fname_centerline: filename of binary centerline
        threshold_distance: threshold, in mm, beyond which centerlines are not coherent
        verbose:

    Returns: None
    """
    sct.printv('\nCheck consistency of segmentation...', verbose)
    # creating a temporary folder in which all temporary files will be placed and deleted afterwards
    path_tmp = sct.tmp_create(basename="propseg", verbose=verbose)
    from sct_convert import convert
    convert(fname_segmentation,
            os.path.join(path_tmp, "tmp.segmentation.nii.gz"),
            squeeze_data=False,
            verbose=0)
    convert(fname_centerline,
            os.path.join(path_tmp, "tmp.centerline.nii.gz"),
            squeeze_data=False,
            verbose=0)
    fname_seg_absolute = os.path.abspath(fname_segmentation)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # convert segmentation image to RPI
    im_input = Image('tmp.segmentation.nii.gz')
    image_input_orientation = orientation(im_input, get=True, verbose=False)

    sct_image.main(
        "-i tmp.segmentation.nii.gz -setorient RPI -o tmp.segmentation_RPI.nii.gz -v 0"
        .split())
    sct_image.main(
        "-i tmp.centerline.nii.gz -setorient RPI -o tmp.centerline_RPI.nii.gz -v 0"
        .split())

    # go through segmentation image, and compare with centerline from propseg
    im_seg = Image('tmp.segmentation_RPI.nii.gz')
    im_centerline = Image('tmp.centerline_RPI.nii.gz')

    # Get size of data
    sct.printv('\nGet data dimensions...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = im_seg.dim

    # extraction of centerline provided by isct_propseg and computation of center of mass for each slice
    # the centerline is defined as the center of the tubular mesh outputed by propseg.
    centerline, key_centerline = {}, []
    for i in range(nz):
        slice = im_centerline.data[:, :, i]
        if np.any(slice):
            x_centerline, y_centerline = ndi.measurements.center_of_mass(slice)
            centerline[str(i)] = [x_centerline, y_centerline]
            key_centerline.append(i)

    minz_centerline = np.min(key_centerline)
    maxz_centerline = np.max(key_centerline)
    mid_slice = int((maxz_centerline - minz_centerline) / 2)

    # for each slice of the segmentation, check if only one object is present. If not, remove the slice from segmentation.
    # If only one object (the spinal cord) is present in the slice, check if its center of mass is close to the centerline of isct_propseg.
    slices_to_remove = [
        False
    ] * nz  # flag that decides if the slice must be removed
    for i in range(minz_centerline, maxz_centerline + 1):
        # extraction of slice
        slice = im_seg.data[:, :, i]
        distance = -1
        label_objects, nb_labels = ndi.label(
            slice)  # count binary objects in the slice
        if nb_labels > 1:  # if there is more that one object in the slice, the slice is removed from the segmentation
            slices_to_remove[i] = True
        elif nb_labels == 1:  # check if the centerline is coherent with the one from isct_propseg
            x_centerline, y_centerline = ndi.measurements.center_of_mass(slice)
            slice_nearest_coord = min(key_centerline, key=lambda x: abs(x - i))
            coord_nearest_coord = centerline[str(slice_nearest_coord)]
            distance = np.sqrt((
                (x_centerline - coord_nearest_coord[0]) * px)**2 + (
                    (y_centerline - coord_nearest_coord[1]) * py)**2 +
                               ((i - slice_nearest_coord) * pz)**2)

            if distance >= threshold_distance:  # threshold must be adjusted, default is 5 mm
                slices_to_remove[i] = True

    # Check list of removal and keep one continuous centerline (improve this comment)
    # Method:
    # starting from mid-centerline (in both directions), the first True encountered is applied to all following slices
    slice_to_change = False
    for i in range(mid_slice, nz):
        if slice_to_change:
            slices_to_remove[i] = True
        elif slices_to_remove[i]:
            slice_to_change = True

    slice_to_change = False
    for i in range(mid_slice, 0, -1):
        if slice_to_change:
            slices_to_remove[i] = True
        elif slices_to_remove[i]:
            slice_to_change = True

    for i in range(0, nz):
        # remove the slice
        if slices_to_remove[i]:
            im_seg.data[:, :, i] *= 0

    # saving the image
    im_seg.setFileName('tmp.segmentation_RPI_c.nii.gz')
    im_seg.save()

    # replacing old segmentation with the corrected one
    sct_image.main(
        '-i tmp.segmentation_RPI_c.nii.gz -setorient {} -o {} -v 0'.format(
            image_input_orientation, fname_seg_absolute).split())

    os.chdir(curdir)

    # display information about how much of the segmentation has been corrected

    # remove temporary files
    if remove_temp_files:
        # sct.printv("\nRemove temporary files...", verbose)
        sct.rmtree(path_tmp)
コード例 #43
0
def main(args = None):

    orientation = ''
    change_header = ''
    fname_out = ''

    if not args:
        args = sys.argv[1:]

    # Building the command, do sanity checks
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])
    fname_in = arguments['-i']
    if '-o' in arguments:
        fname_out = arguments['-o']
    if '-s' in arguments:
        orientation = arguments['-s']
    if '-a' in arguments:
        change_header = arguments['-a']
    remove_tmp_files = int(arguments['-r'])
    verbose = int(arguments['-v'])
    inversion = False  # change orientation

    # create temporary folder
    sct.printv('\nCreate temporary folder...', verbose)
    path_tmp = 'tmp.'+time.strftime("%y%m%d%H%M%S/")
    status, output = sct.run('mkdir '+path_tmp, verbose)

    # copy file in temp folder
    sct.printv('\nCopy files to tmp folder...', verbose)
    convert(fname_in, path_tmp+'data.nii', verbose=0)

    # go to temp folder
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim
    sct.printv(str(nx) + ' x ' + str(ny) + ' x ' + str(nz)+ ' x ' + str(nt), verbose)

    # if data are 3d, directly set or get orientation
    if nt == 1:
        if orientation != '':
            # set orientation
            sct.printv('\nChange orientation...', verbose)
            if change_header == '':
                set_orientation('data.nii', orientation, 'data_orient.nii')
            else:
                set_orientation('data.nii', change_header, 'data_orient.nii', True)
        else:
            # get orientation
            sct.printv('\nGet orientation...', verbose)
            print get_orientation('data.nii')
    else:
        # split along T dimension
        sct.printv('\nSplit along T dimension...', verbose)
        im = Image('data.nii')
        im_split_list = split_data(im, 3)
        for im_s in im_split_list:
            im_s.save()
        if orientation != '':
            # set orientation
            sct.printv('\nChange orientation...', verbose)
            for it in range(nt):
                file_data_split = 'data_T'+str(it).zfill(4)+'.nii'
                file_data_split_orient = 'data_orient_T'+str(it).zfill(4)+'.nii'
                set_orientation(file_data_split, orientation, file_data_split_orient)
            # Merge files back
            sct.printv('\nMerge file back...', verbose)
            from glob import glob
            im_data_list = [Image(fname) for fname in glob('data_orient_T*.nii')]
            im_concat = concat_data(im_data_list, 3)
            im_concat.setFileName('data_orient.nii')
            im_concat.save()

        else:
            sct.printv('\nGet orientation...', verbose)
            print get_orientation('data_T0000.nii')

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    if orientation != '':
        # Build fname_out
        if fname_out == '':
            path_data, file_data, ext_data = sct.extract_fname(fname_in)
            fname_out = path_data+file_data+'_'+orientation+ext_data
        sct.printv('\nGenerate output files...', verbose)
        sct.generate_output_file(path_tmp+'data_orient.nii', fname_out)

    # Remove temporary files
    if remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...', verbose)
        sct.run('rm -rf '+path_tmp, verbose)
コード例 #44
0
def main(args=None):

    # initialization
    start_time = time.time()
    path_out = '.'
    param = Param()

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    param.fname_data = arguments['-i']
    param.fname_bvecs = arguments['-bvec']

    if '-bval' in arguments:
        param.fname_bvals = arguments['-bval']
    if '-bvalmin' in arguments:
        param.bval_min = arguments['-bvalmin']
    if '-g' in arguments:
        param.group_size = arguments['-g']
    if '-m' in arguments:
        param.fname_mask = arguments['-m']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-thr' in arguments:
        param.otsu = arguments['-thr']
    if '-x' in arguments:
        param.interp = arguments['-x']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-r' in arguments:
        param.remove_temp_files = int(arguments['-r'])
    param.verbose = int(arguments.get('-v'))
    sct.init_sct(log_level=param.verbose, update=True)  # Update log level

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    if param.fname_bvals != '':
        param.fname_bvals = os.path.abspath(param.fname_bvals)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_mask, file_mask, ext_mask = sct.extract_fname(param.fname_mask)

    path_tmp = sct.tmp_create(basename="dmri_moco", verbose=param.verbose)

    # names of files in temporary folder
    mask_name = 'mask'
    bvecs_fname = 'bvecs.txt'

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               param.verbose)
    convert(param.fname_data, os.path.join(path_tmp, "dmri.nii"))
    sct.copy(param.fname_bvecs,
             os.path.join(path_tmp, bvecs_fname),
             verbose=param.verbose)
    if param.fname_mask != '':
        sct.copy(param.fname_mask,
                 os.path.join(path_tmp, mask_name + ext_mask),
                 verbose=param.verbose)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # update field in param (because used later).
    # TODO: make this cleaner...
    if param.fname_mask != '':
        param.fname_mask = mask_name + ext_mask

    # run moco
    fname_data_moco_tmp = dmri_moco(param)

    # generate b0_moco_mean and dwi_moco_mean
    args = [
        '-i', fname_data_moco_tmp, '-bvec', 'bvecs.txt', '-a', '1', '-v', '0'
    ]
    if not param.fname_bvals == '':
        # if bvals file is provided
        args += ['-bval', param.fname_bvals]
    fname_b0, fname_b0_mean, fname_dwi, fname_dwi_mean = sct_dmri_separate_b0_and_dwi.main(
        args=args)

    # come back
    os.chdir(curdir)

    # Generate output files
    fname_dmri_moco = os.path.join(path_out,
                                   file_data + param.suffix + ext_data)
    fname_dmri_moco_b0_mean = sct.add_suffix(fname_dmri_moco, '_b0_mean')
    fname_dmri_moco_dwi_mean = sct.add_suffix(fname_dmri_moco, '_dwi_mean')
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(fname_data_moco_tmp, fname_dmri_moco,
                             param.verbose)
    sct.generate_output_file(fname_b0_mean, fname_dmri_moco_b0_mean,
                             param.verbose)
    sct.generate_output_file(fname_dwi_mean, fname_dmri_moco_dwi_mean,
                             param.verbose)

    # Delete temporary files
    if param.remove_temp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.rmtree(path_tmp, verbose=param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv(
        '\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's',
        param.verbose)

    sct.display_viewer_syntax([fname_dmri_moco, file_data], mode='ortho,ortho')
コード例 #45
0
def main(args=None):

    # initialization
    start_time = time.time()
    path_out = '.'
    param = Param()

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    param.fname_data = arguments['-i']
    param.fname_bvecs = arguments['-bvec']

    if '-bval' in arguments:
        param.fname_bvals = arguments['-bval']
    if '-bvalmin' in arguments:
        param.bval_min = arguments['-bvalmin']
    if '-g' in arguments:
        param.group_size = arguments['-g']
    if '-m' in arguments:
        param.fname_mask = arguments['-m']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-thr' in arguments:
        param.otsu = arguments['-thr']
    if '-x' in arguments:
        param.interp = arguments['-x']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-r' in arguments:
        param.remove_temp_files = int(arguments['-r'])
    param.verbose = int(arguments.get('-v'))
    sct.init_sct(log_level=param.verbose, update=True)  # Update log level

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    if param.fname_bvals != '':
        param.fname_bvals = os.path.abspath(param.fname_bvals)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_mask, file_mask, ext_mask = sct.extract_fname(param.fname_mask)

    path_tmp = sct.tmp_create(basename="dmri_moco", verbose=param.verbose)

    # names of files in temporary folder
    mask_name = 'mask'
    bvecs_fname = 'bvecs.txt'

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(param.fname_data, os.path.join(path_tmp, "dmri.nii"))
    sct.copy(param.fname_bvecs, os.path.join(path_tmp, bvecs_fname), verbose=param.verbose)
    if param.fname_mask != '':
        sct.copy(param.fname_mask, os.path.join(path_tmp, mask_name + ext_mask), verbose=param.verbose)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # update field in param (because used later).
    # TODO: make this cleaner...
    if param.fname_mask != '':
        param.fname_mask = mask_name + ext_mask

    # run moco
    fname_data_moco_tmp = dmri_moco(param)

    # generate b0_moco_mean and dwi_moco_mean
    args = ['-i', fname_data_moco_tmp, '-bvec', 'bvecs.txt', '-a', '1', '-v', '0']
    if not param.fname_bvals == '':
        # if bvals file is provided
        args += ['-bval', param.fname_bvals]
    fname_b0, fname_b0_mean, fname_dwi, fname_dwi_mean = sct_dmri_separate_b0_and_dwi.main(args=args)

    # come back
    os.chdir(curdir)

    # Generate output files
    fname_dmri_moco = os.path.join(path_out, file_data + param.suffix + ext_data)
    fname_dmri_moco_b0_mean = sct.add_suffix(fname_dmri_moco, '_b0_mean')
    fname_dmri_moco_dwi_mean = sct.add_suffix(fname_dmri_moco, '_dwi_mean')
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(fname_data_moco_tmp, fname_dmri_moco, param.verbose)
    sct.generate_output_file(fname_b0_mean, fname_dmri_moco_b0_mean, param.verbose)
    sct.generate_output_file(fname_dwi_mean, fname_dmri_moco_dwi_mean, param.verbose)

    # Delete temporary files
    if param.remove_temp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.rmtree(path_tmp, verbose=param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's', param.verbose)

    sct.display_viewer_syntax([fname_dmri_moco, file_data], mode='ortho,ortho')
コード例 #46
0
    def execute(self):
        print 'Execution of the SCAD algorithm in ' + str(os.getcwd())

        original_name = self.input_image.file_name
        vesselness_file_name = "imageVesselNessFilter.nii.gz"
        raw_file_name = "raw.nii"

        self.setup_debug_folder()

        if self.debug:
            import matplotlib.pyplot as plt  # import for debug purposes

        # create tmp and copy input
        path_tmp = self.create_temporary_path()
        conv.convert(self.input_image.absolutepath, path_tmp + raw_file_name)

        if self.vesselness_provided:
            sct.run('cp ' + vesselness_file_name + ' ' + path_tmp +
                    vesselness_file_name)
        os.chdir(path_tmp)

        # get input image information
        img = Image(raw_file_name)

        # save original orientation and change image to RPI
        self.raw_orientation = img.change_orientation()

        # get body symmetry
        if self.enable_symmetry:
            from msct_image import change_data_orientation
            sym = SymmetryDetector(raw_file_name, self.contrast, crop_xy=0)
            self.raw_symmetry = sym.execute()
            img.change_orientation(self.raw_orientation)
            self.output_debug_file(img, self.raw_symmetry, "body_symmetry")
            img.change_orientation()

        # vesselness filter
        if not self.vesselness_provided:
            sct.run('isct_vesselness -i ' + raw_file_name + ' -t ' +
                    self._contrast + " -radius " + str(self.spinalcord_radius))

        # load vesselness filter data and perform minimum path on it
        img = Image(vesselness_file_name)
        self.output_debug_file(img, img.data, "Vesselness_Filter")
        img.change_orientation()
        self.minimum_path_data, self.J1_min_path, self.J2_min_path = get_minimum_path(
            img.data, invert=1, debug=1)
        self.output_debug_file(img, self.minimum_path_data, "minimal_path")
        self.output_debug_file(img, self.J1_min_path, "J1_minimal_path")
        self.output_debug_file(img, self.J2_min_path, "J2_minimal_path")

        # Apply an exponent to the minimum path
        self.minimum_path_powered = np.power(self.minimum_path_data,
                                             self.minimum_path_exponent)
        self.output_debug_file(
            img, self.minimum_path_powered,
            "minimal_path_power_" + str(self.minimum_path_exponent))

        # Saving in Image since smooth_minimal_path needs pixel dimensions
        img.data = self.minimum_path_powered

        # smooth resulting minimal path
        self.smoothed_min_path = smooth_minimal_path(img)
        self.output_debug_file(img, self.smoothed_min_path.data,
                               "minimal_path_smooth")

        # normalise symmetry values between 0 and 1
        if self.enable_symmetry:
            normalised_symmetry = normalize_array_histogram(self.raw_symmetry)
            self.output_debug_file(img, self.smoothed_min_path.data,
                                   "minimal_path_smooth")

            # multiply normalised symmetry data with the minimum path result
            from msct_image import change_data_orientation
            self.spine_detect_data = np.multiply(
                self.smoothed_min_path.data,
                change_data_orientation(
                    np.power(normalised_symmetry, self.symmetry_exponent),
                    self.raw_orientation, "RPI"))
            self.output_debug_file(img, self.spine_detect_data,
                                   "symmetry_x_min_path")
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(
                self.spine_detect_data, self.spine_detect_data.shape)
        else:
            # extract the centerline from the minimal path image
            self.centerline_with_outliers = get_centerline(
                self.smoothed_min_path.data, self.smoothed_min_path.data.shape)
        self.output_debug_file(img, self.centerline_with_outliers,
                               "centerline_with_outliers")

        # saving centerline with outliers to have
        img.data = self.centerline_with_outliers
        img.change_orientation()
        img.file_name = "centerline_with_outliers"
        img.save()

        # use a b-spline to smooth out the centerline
        x, y, z, dx, dy, dz = smooth_centerline(
            "centerline_with_outliers.nii.gz")

        # save the centerline
        nx, ny, nz, nt, px, py, pz, pt = img.dim
        img.data = np.zeros((nx, ny, nz))
        for i in range(0, np.size(x) - 1):
            img.data[int(x[i]), int(y[i]), int(z[i])] = 1

        self.output_debug_file(img, img.data, "centerline")
        img.change_orientation(self.raw_orientation)
        img.file_name = "centerline"
        img.save()

        # copy back centerline
        os.chdir('../')
        conv.convert(path_tmp + img.file_name + img.ext, self.output_filename)
        if self.rm_tmp_file == 1:
            import shutil
            shutil.rmtree(path_tmp)

        print "To view the output with FSL :"
        sct.printv(
            "fslview " + self.input_image.absolutepath + " " +
            self.output_filename + " -l Red", self.verbose, "info")
コード例 #47
0
def main(args=None):

    # initialization
    start_time = time.time()
    path_out = '.'
    param = Param()

    # reducing the number of CPU used for moco (see issue #201)
    os.environ["ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS"] = "1"

    # get path of the toolbox
    # status, param.path_sct = sct.run('echo $SCT_DIR')

    # check user arguments
    if not args:
        args = sys.argv[1:]

    # Get parser info
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    param.fname_data = arguments['-i']
    param.fname_bvecs = arguments['-bvec']

    if '-bval' in arguments:
        param.fname_bvals = arguments['-bval']
    if '-bvalmin' in arguments:
        param.bval_min = arguments['-bvalmin']
    if '-g' in arguments:
        param.group_size = arguments['-g']
    if '-m' in arguments:
        param.fname_mask = arguments['-m']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-thr' in arguments:
        param.otsu = arguments['-thr']
    if '-x' in arguments:
        param.interp = arguments['-x']
    if '-ofolder' in arguments:
        path_out = arguments['-ofolder']
    if '-r' in arguments:
        param.remove_temp_files = int(arguments['-r'])
    if '-v' in arguments:
        param.verbose = int(arguments['-v'])

    # Get full path
    param.fname_data = os.path.abspath(param.fname_data)
    param.fname_bvecs = os.path.abspath(param.fname_bvecs)
    if param.fname_bvals != '':
        param.fname_bvals = os.path.abspath(param.fname_bvals)
    if param.fname_mask != '':
        param.fname_mask = os.path.abspath(param.fname_mask)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)
    path_mask, file_mask, ext_mask = sct.extract_fname(param.fname_mask)

    path_tmp = sct.tmp_create(basename="dmri_moco", verbose=param.verbose)

    # names of files in temporary folder
    ext = '.nii'
    dmri_name = 'dmri'
    mask_name = 'mask'
    bvecs_fname = 'bvecs.txt'

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               param.verbose)
    convert(param.fname_data, os.path.join(path_tmp, dmri_name + ext))
    sct.copy(param.fname_bvecs,
             os.path.join(path_tmp, bvecs_fname),
             verbose=param.verbose)
    if param.fname_mask != '':
        sct.copy(param.fname_mask,
                 os.path.join(path_tmp, mask_name + ext_mask),
                 verbose=param.verbose)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # update field in param (because used later).
    # TODO: make this cleaner...
    if param.fname_mask != '':
        param.fname_mask = mask_name + ext_mask

    # run moco
    dmri_moco(param)

    # come back
    os.chdir(curdir)

    # Generate output files
    fname_dmri_moco = os.path.join(path_out,
                                   file_data + param.suffix + ext_data)
    sct.create_folder(path_out)
    sct.printv('\nGenerate output files...', param.verbose)
    sct.generate_output_file(
        os.path.join(path_tmp, dmri_name + param.suffix + ext),
        os.path.join(path_out, file_data + param.suffix + ext_data),
        param.verbose)
    sct.generate_output_file(
        os.path.join(path_tmp, "b0_mean.nii"),
        os.path.join(path_out, 'b0' + param.suffix + '_mean' + ext_data),
        param.verbose)
    sct.generate_output_file(
        os.path.join(path_tmp, "dwi_mean.nii"),
        os.path.join(path_out, 'dwi' + param.suffix + '_mean' + ext_data),
        param.verbose)

    # Delete temporary files
    if param.remove_temp_files == 1:
        sct.printv('\nDelete temporary files...', param.verbose)
        sct.rmtree(path_tmp, verbose=param.verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv(
        '\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) + 's',
        param.verbose)

    sct.display_viewer_syntax([fname_dmri_moco, file_data], mode='ortho,ortho')
コード例 #48
0
def main(args=None):
    # initialize parameters
    param = Param()
    # call main function
    parser = get_parser()
    if args:
        arguments = parser.parse_args(args)
    else:
        arguments = parser.parse_args(args=None if sys.argv[1:] else ['--help'])

    fname_data = arguments.i
    fname_bvecs = arguments.bvec
    average = arguments.a
    verbose = int(arguments.v)
    init_sct(log_level=verbose, update=True)  # Update log level
    remove_temp_files = arguments.r
    path_out = arguments.ofolder

    fname_bvals = arguments.bval
    if arguments.bvalmin:
        param.bval_min = arguments.bvalmin

    # Initialization
    start_time = time.time()

    # printv(arguments)
    printv('\nInput parameters:', verbose)
    printv('  input file ............' + fname_data, verbose)
    printv('  bvecs file ............' + fname_bvecs, verbose)
    printv('  bvals file ............' + fname_bvals, verbose)
    printv('  average ...............' + str(average), verbose)

    # Get full path
    fname_data = os.path.abspath(fname_data)
    fname_bvecs = os.path.abspath(fname_bvecs)
    if fname_bvals:
        fname_bvals = os.path.abspath(fname_bvals)

    # Extract path, file and extension
    path_data, file_data, ext_data = extract_fname(fname_data)

    # create temporary folder
    path_tmp = tmp_create(basename="dmri_separate")

    # copy files into tmp folder and convert to nifti
    printv('\nCopy files into temporary folder...', verbose)
    ext = '.nii'
    dmri_name = 'dmri'
    b0_name = file_data + '_b0'
    b0_mean_name = b0_name + '_mean'
    dwi_name = file_data + '_dwi'
    dwi_mean_name = dwi_name + '_mean'

    if not convert(fname_data, os.path.join(path_tmp, dmri_name + ext)):
        printv('ERROR in convert.', 1, 'error')
    copy(fname_bvecs, os.path.join(path_tmp, "bvecs"), verbose=verbose)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # Get size of data
    im_dmri = Image(dmri_name + ext)
    printv('\nGet dimensions data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = im_dmri.dim
    printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt), verbose)

    # Identify b=0 and DWI images
    printv(fname_bvals)
    index_b0, index_dwi, nb_b0, nb_dwi = identify_b0(fname_bvecs, fname_bvals, param.bval_min, verbose)

    # Split into T dimension
    printv('\nSplit along T dimension...', verbose)
    im_dmri_split_list = split_data(im_dmri, 3)
    for im_d in im_dmri_split_list:
        im_d.save()

    # Merge b=0 images
    printv('\nMerge b=0...', verbose)
    from sct_image import concat_data
    l = []
    for it in range(nb_b0):
        l.append(dmri_name + '_T' + str(index_b0[it]).zfill(4) + ext)
    im_out = concat_data(l, 3).save(b0_name + ext)

    # Average b=0 images
    if average:
        printv('\nAverage b=0...', verbose)
        run_proc(['sct_maths', '-i', b0_name + ext, '-o', b0_mean_name + ext, '-mean', 't'], verbose)

    # Merge DWI
    l = []
    for it in range(nb_dwi):
        l.append(dmri_name + '_T' + str(index_dwi[it]).zfill(4) + ext)
    im_out = concat_data(l, 3).save(dwi_name + ext)

    # Average DWI images
    if average:
        printv('\nAverage DWI...', verbose)
        run_proc(['sct_maths', '-i', dwi_name + ext, '-o', dwi_mean_name + ext, '-mean', 't'], verbose)

    # come back
    os.chdir(curdir)

    # Generate output files
    fname_b0 = os.path.abspath(os.path.join(path_out, b0_name + ext_data))
    fname_dwi = os.path.abspath(os.path.join(path_out, dwi_name + ext_data))
    fname_b0_mean = os.path.abspath(os.path.join(path_out, b0_mean_name + ext_data))
    fname_dwi_mean = os.path.abspath(os.path.join(path_out, dwi_mean_name + ext_data))
    printv('\nGenerate output files...', verbose)
    generate_output_file(os.path.join(path_tmp, b0_name + ext), fname_b0, verbose=verbose)
    generate_output_file(os.path.join(path_tmp, dwi_name + ext), fname_dwi, verbose=verbose)
    if average:
        generate_output_file(os.path.join(path_tmp, b0_mean_name + ext), fname_b0_mean, verbose=verbose)
        generate_output_file(os.path.join(path_tmp, dwi_mean_name + ext), fname_dwi_mean, verbose=verbose)

    # Remove temporary files
    if remove_temp_files == 1:
        printv('\nRemove temporary files...', verbose)
        rmtree(path_tmp, verbose=verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's', verbose)

    return fname_b0, fname_b0_mean, fname_dwi, fname_dwi_mean
コード例 #49
0
def main(args=None):

    # Initialization
    # fname_anat = ''
    # fname_centerline = ''
    sigma = 3  # default value of the standard deviation for the Gaussian smoothing (in terms of number of voxels)
    # remove_temp_files = param.remove_temp_files
    # verbose = param.verbose
    start_time = time.time()

    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    fname_anat = arguments['-i']
    fname_centerline = arguments['-s']
    if '-smooth' in arguments:
        sigma = arguments['-smooth']
    if '-r' in arguments:
        remove_temp_files = int(arguments['-r'])
    if '-v' in arguments:
        verbose = int(arguments['-v'])

    # Display arguments
    sct.printv('\nCheck input arguments...')
    sct.printv('  Volume to smooth .................. ' + fname_anat)
    sct.printv('  Centerline ........................ ' + fname_centerline)
    sct.printv('  Sigma (mm) ........................ ' + str(sigma))
    sct.printv('  Verbose ........................... ' + str(verbose))

    # Check that input is 3D:
    from msct_image import Image
    nx, ny, nz, nt, px, py, pz, pt = Image(fname_anat).dim
    dim = 4  # by default, will be adjusted later
    if nt == 1:
        dim = 3
    if nz == 1:
        dim = 2
    if dim == 4:
        sct.printv(
            'WARNING: the input image is 4D, please split your image to 3D before smoothing spinalcord using :\n'
            'sct_image -i ' + fname_anat + ' -split t -o ' + fname_anat,
            verbose, 'warning')
        sct.printv('4D images not supported, aborting ...', verbose, 'error')

    # Extract path/file/extension
    path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat)
    path_centerline, file_centerline, ext_centerline = sct.extract_fname(
        fname_centerline)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', verbose)
    path_tmp = sct.slash_at_the_end('tmp.' + time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir ' + path_tmp, verbose)

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               verbose)
    sct.run('cp ' + fname_anat + ' ' + path_tmp + 'anat' + ext_anat, verbose)
    sct.run(
        'cp ' + fname_centerline + ' ' + path_tmp + 'centerline' +
        ext_centerline, verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # convert to nii format
    convert('anat' + ext_anat, 'anat.nii')
    convert('centerline' + ext_centerline, 'centerline.nii')

    # Change orientation of the input image into RPI
    sct.printv('\nOrient input volume to RPI orientation...')
    fname_anat_rpi = set_orientation('anat.nii', 'RPI', filename=True)
    move(fname_anat_rpi, 'anat_rpi.nii')
    # Change orientation of the input image into RPI
    sct.printv('\nOrient centerline to RPI orientation...')
    fname_centerline_rpi = set_orientation('centerline.nii',
                                           'RPI',
                                           filename=True)
    move(fname_centerline_rpi, 'centerline_rpi.nii')

    # Straighten the spinal cord
    # straighten segmentation
    sct.printv('\nStraighten the spinal cord using centerline/segmentation...',
               verbose)
    # check if warp_curve2straight and warp_straight2curve already exist (i.e. no need to do it another time)
    if os.path.isfile('../warp_curve2straight.nii.gz') and os.path.isfile(
            '../warp_straight2curve.nii.gz') and os.path.isfile(
                '../straight_ref.nii.gz'):
        # if they exist, copy them into current folder
        sct.printv(
            'WARNING: Straightening was already run previously. Copying warping fields...',
            verbose, 'warning')
        shutil.copy('../warp_curve2straight.nii.gz',
                    'warp_curve2straight.nii.gz')
        shutil.copy('../warp_straight2curve.nii.gz',
                    'warp_straight2curve.nii.gz')
        shutil.copy('../straight_ref.nii.gz', 'straight_ref.nii.gz')
        # apply straightening
        sct.run(
            'sct_apply_transfo -i anat_rpi.nii -w warp_curve2straight.nii.gz -d straight_ref.nii.gz -o anat_rpi_straight.nii -x spline',
            verbose)
    else:
        sct.run(
            'sct_straighten_spinalcord -i anat_rpi.nii -s centerline_rpi.nii -qc 0 -x spline',
            verbose)

    # Smooth the straightened image along z
    sct.printv('\nSmooth the straightened image along z...')
    sct.run(
        'sct_maths -i anat_rpi_straight.nii -smooth 0,0,' + str(sigma) +
        ' -o anat_rpi_straight_smooth.nii', verbose)

    # Apply the reversed warping field to get back the curved spinal cord
    sct.printv(
        '\nApply the reversed warping field to get back the curved spinal cord...'
    )
    sct.run(
        'sct_apply_transfo -i anat_rpi_straight_smooth.nii -o anat_rpi_straight_smooth_curved.nii -d anat.nii -w warp_straight2curve.nii.gz -x spline',
        verbose)

    # replace zeroed voxels by original image (issue #937)
    sct.printv('\nReplace zeroed voxels by original image...', verbose)
    nii_smooth = Image('anat_rpi_straight_smooth_curved.nii')
    data_smooth = nii_smooth.data
    data_input = Image('anat.nii').data
    indzero = np.where(data_smooth == 0)
    data_smooth[indzero] = data_input[indzero]
    nii_smooth.data = data_smooth
    nii_smooth.setFileName('anat_rpi_straight_smooth_curved_nonzero.nii')
    nii_smooth.save()

    # come back to parent folder
    os.chdir('..')

    # Generate output file
    sct.printv('\nGenerate output file...')
    sct.generate_output_file(
        path_tmp + '/anat_rpi_straight_smooth_curved_nonzero.nii',
        file_anat + '_smooth' + ext_anat)

    # Remove temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.run('rm -rf ' + path_tmp)

    # Display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) +
               's\n')

    # to view results
    sct.printv('Done! To view results, type:', verbose)
    sct.printv('fslview ' + file_anat + ' ' + file_anat + '_smooth &\n',
               verbose, 'info')
コード例 #50
0
def main(args=None):

    # Initialization
    # fname_anat = ''
    # fname_centerline = ''
    sigma = 3  # default value of the standard deviation for the Gaussian smoothing (in terms of number of voxels)
    param = Param()
    # remove_temp_files = param.remove_temp_files
    # verbose = param.verbose
    start_time = time.time()

    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    fname_anat = arguments['-i']
    fname_centerline = arguments['-s']
    if '-smooth' in arguments:
        sigma = arguments['-smooth']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-r' in arguments:
        remove_temp_files = int(arguments['-r'])
    if '-v' in arguments:
        verbose = int(arguments['-v'])

    # Display arguments
    sct.printv('\nCheck input arguments...')
    sct.printv('  Volume to smooth .................. ' + fname_anat)
    sct.printv('  Centerline ........................ ' + fname_centerline)
    sct.printv('  Sigma (mm) ........................ ' + str(sigma))
    sct.printv('  Verbose ........................... ' + str(verbose))

    # Check that input is 3D:
    from spinalcordtoolbox.image import Image
    nx, ny, nz, nt, px, py, pz, pt = Image(fname_anat).dim
    dim = 4  # by default, will be adjusted later
    if nt == 1:
        dim = 3
    if nz == 1:
        dim = 2
    if dim == 4:
        sct.printv(
            'WARNING: the input image is 4D, please split your image to 3D before smoothing spinalcord using :\n'
            'sct_image -i ' + fname_anat + ' -split t -o ' + fname_anat,
            verbose, 'warning')
        sct.printv('4D images not supported, aborting ...', verbose, 'error')

    # Extract path/file/extension
    path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat)
    path_centerline, file_centerline, ext_centerline = sct.extract_fname(
        fname_centerline)

    path_tmp = sct.tmp_create(basename="smooth_spinalcord", verbose=verbose)

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               verbose)
    sct.copy(fname_anat, os.path.join(path_tmp, "anat" + ext_anat))
    sct.copy(fname_centerline,
             os.path.join(path_tmp, "centerline" + ext_centerline))

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # convert to nii format
    convert('anat' + ext_anat, 'anat.nii')
    convert('centerline' + ext_centerline, 'centerline.nii')

    # Change orientation of the input image into RPI
    sct.printv('\nOrient input volume to RPI orientation...')
    fname_anat_rpi = msct_image.Image("anat.nii") \
     .change_orientation("RPI", generate_path=True) \
     .save() \
     .absolutepath

    # Change orientation of the input image into RPI
    sct.printv('\nOrient centerline to RPI orientation...')
    fname_centerline_rpi = msct_image.Image("centerline.nii") \
     .change_orientation("RPI", generate_path=True) \
     .save() \
     .absolutepath

    # Straighten the spinal cord
    # straighten segmentation
    sct.printv('\nStraighten the spinal cord using centerline/segmentation...',
               verbose)
    cache_sig = sct.cache_signature(
        input_files=[fname_anat_rpi, fname_centerline_rpi],
        input_params={"x": "spline"},
    )
    cachefile = os.path.join(curdir, "straightening.cache")
    if sct.cache_valid(cachefile, cache_sig) and os.path.isfile(
            os.path.join(
                curdir, 'warp_curve2straight.nii.gz')) and os.path.isfile(
                    os.path.join(
                        curdir,
                        'warp_straight2curve.nii.gz')) and os.path.isfile(
                            os.path.join(curdir, 'straight_ref.nii.gz')):
        # if they exist, copy them into current folder
        sct.printv('Reusing existing warping field which seems to be valid',
                   verbose, 'warning')
        sct.copy(os.path.join(curdir, 'warp_curve2straight.nii.gz'),
                 'warp_curve2straight.nii.gz')
        sct.copy(os.path.join(curdir, 'warp_straight2curve.nii.gz'),
                 'warp_straight2curve.nii.gz')
        sct.copy(os.path.join(curdir, 'straight_ref.nii.gz'),
                 'straight_ref.nii.gz')
        # apply straightening
        sct.run([
            'sct_apply_transfo', '-i', fname_anat_rpi, '-w',
            'warp_curve2straight.nii.gz', '-d', 'straight_ref.nii.gz', '-o',
            'anat_rpi_straight.nii', '-x', 'spline'
        ], verbose)
    else:
        sct.run([
            'sct_straighten_spinalcord', '-i', fname_anat_rpi, '-o',
            'anat_rpi_straight.nii', '-s', fname_centerline_rpi, '-x',
            'spline', '-param', 'algo_fitting=' + param.algo_fitting
        ], verbose)
        sct.cache_save(cachefile, cache_sig)

    # Smooth the straightened image along z
    sct.printv('\nSmooth the straightened image along z...')
    sct.run([
        'sct_maths', '-i', 'anat_rpi_straight.nii', '-smooth',
        '0,0,' + str(sigma), '-o', 'anat_rpi_straight_smooth.nii'
    ], verbose)

    # Apply the reversed warping field to get back the curved spinal cord
    sct.printv(
        '\nApply the reversed warping field to get back the curved spinal cord...'
    )
    sct.run([
        'sct_apply_transfo', '-i', 'anat_rpi_straight_smooth.nii', '-o',
        'anat_rpi_straight_smooth_curved.nii', '-d', 'anat.nii', '-w',
        'warp_straight2curve.nii.gz', '-x', 'spline'
    ], verbose)

    # replace zeroed voxels by original image (issue #937)
    sct.printv('\nReplace zeroed voxels by original image...', verbose)
    nii_smooth = Image('anat_rpi_straight_smooth_curved.nii')
    data_smooth = nii_smooth.data
    data_input = Image('anat.nii').data
    indzero = np.where(data_smooth == 0)
    data_smooth[indzero] = data_input[indzero]
    nii_smooth.data = data_smooth
    nii_smooth.save('anat_rpi_straight_smooth_curved_nonzero.nii')

    # come back
    os.chdir(curdir)

    # Generate output file
    sct.printv('\nGenerate output file...')
    sct.generate_output_file(
        os.path.join(path_tmp, "anat_rpi_straight_smooth_curved_nonzero.nii"),
        file_anat + '_smooth' + ext_anat)

    # Remove temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.rmtree(path_tmp)

    # Display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' +
               str(int(np.round(elapsed_time))) + 's\n')

    sct.display_viewer_syntax([file_anat, file_anat + '_smooth'],
                              verbose=verbose)
コード例 #51
0
def main():

    # Initialization
    fname_mt0 = ''
    fname_mt1 = ''
    file_out = param.file_out
    # register = param.register
    # remove_tmp_files = param.remove_tmp_files
    # verbose = param.verbose

    # get path of the toolbox
    # status, path_sct = commands.getstatusoutput('echo $SCT_DIR')

    # Check input parameters
    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    fname_mt0 = arguments['-mt0']
    fname_mt1 = arguments['-mt1']
    remove_tmp_files = int(arguments['-r'])
    verbose = int(arguments['-v'])

    # Extract path/file/extension
    path_mt0, file_mt0, ext_mt0 = sct.extract_fname(fname_mt0)
    path_out, file_out, ext_out = '', file_out, ext_mt0

    # create temporary folder
    path_tmp = sct.tmp_create()

    # Copying input data to tmp folder and convert to nii
    sct.printv('\nCopying input data to tmp folder and convert to nii...',
               verbose)
    from sct_convert import convert
    convert(fname_mt0, path_tmp + 'mt0.nii', type='float32')
    convert(fname_mt1, path_tmp + 'mt1.nii', type='float32')

    # go to tmp folder
    os.chdir(path_tmp)

    # compute MTR
    sct.printv('\nCompute MTR...', verbose)
    from msct_image import Image
    nii_mt1 = Image('mt1.nii')
    data_mt1 = nii_mt1.data
    data_mt0 = Image('mt0.nii').data
    data_mtr = 100 * (data_mt0 - data_mt1) / data_mt0
    # save MTR file
    nii_mtr = nii_mt1
    nii_mtr.data = data_mtr
    nii_mtr.setFileName('mtr.nii')
    nii_mtr.save()
    # sct.run(fsloutput+'fslmaths -dt double mt0.nii -sub mt1.nii -mul 100 -div mt0.nii -thr 0 -uthr 100 mtr.nii', verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    sct.generate_output_file(path_tmp + 'mtr.nii',
                             path_out + file_out + ext_out)

    # Remove temporary files
    if remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.run('rm -rf ' + path_tmp)

    # to view results
    sct.printv('\nDone! To view results, type:', verbose)
    sct.printv(
        'fslview ' + fname_mt0 + ' ' + fname_mt1 + ' ' + file_out + ' &\n',
        verbose, 'info')
コード例 #52
0
    def crop_with_gui(self):
        import matplotlib.pyplot as plt
        import matplotlib.image as mpimg
        # Initialization
        fname_data = self.input_filename
        suffix_out = '_crop'
        remove_temp_files = self.rm_tmp_files
        verbose = self.verbose

        # Check file existence
        sct.printv('\nCheck file existence...', verbose)
        sct.check_file_exist(fname_data, verbose)

        # Get dimensions of data
        sct.printv('\nGet dimensions of data...', verbose)
        nx, ny, nz, nt, px, py, pz, pt = Image(fname_data).dim
        sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz),
                   verbose)
        # check if 4D data
        if not nt == 1:
            sct.printv(
                '\nERROR in ' + os.path.basename(__file__) +
                ': Data should be 3D.\n', 1, 'error')
            sys.exit(2)

        # sct.printv(arguments)
        sct.printv('\nCheck parameters:')
        sct.printv('  data ................... ' + fname_data)

        # Extract path/file/extension
        path_data, file_data, ext_data = sct.extract_fname(fname_data)
        path_out, file_out, ext_out = '', file_data + suffix_out, ext_data

        path_tmp = sct.tmp_create() + "/"

        # copy files into tmp folder
        from sct_convert import convert
        sct.printv('\nCopying input data to tmp folder and convert to nii...',
                   verbose)
        convert(fname_data, os.path.join(path_tmp, "data.nii"))

        # go to tmp folder
        curdir = os.getcwd()
        os.chdir(path_tmp)

        # change orientation
        sct.printv('\nChange orientation to RPI...', verbose)
        Image('data.nii').change_orientation("RPI").save('data_rpi.nii')

        # get image of medial slab
        sct.printv('\nGet image of medial slab...', verbose)
        image_array = nibabel.load('data_rpi.nii').get_data()
        nx, ny, nz = image_array.shape
        scipy.misc.imsave('image.jpg', image_array[math.floor(nx / 2), :, :])

        # Display the image
        sct.printv('\nDisplay image and get cropping region...', verbose)
        fig = plt.figure()
        # fig = plt.gcf()
        # ax = plt.gca()
        ax = fig.add_subplot(111)
        img = mpimg.imread("image.jpg")
        implot = ax.imshow(img.T)
        implot.set_cmap('gray')
        plt.gca().invert_yaxis()
        # mouse callback
        ax.set_title(
            'Left click on the top and bottom of your cropping field.\n Right click to remove last point.\n Close window when your done.'
        )
        line, = ax.plot([], [], 'ro')  # empty line
        cropping_coordinates = LineBuilder(line)
        plt.show()
        # disconnect callback
        # fig.canvas.mpl_disconnect(line)

        # check if user clicked two times
        if len(cropping_coordinates.xs) != 2:
            sct.printv(
                '\nERROR: You have to select two points. Exit program.\n', 1,
                'error')
            sys.exit(2)

        # convert coordinates to integer
        zcrop = [int(i) for i in cropping_coordinates.ys]

        # sort coordinates
        zcrop.sort()

        # crop image
        sct.printv('\nCrop image...', verbose)
        nii = Image('data_rpi.nii')
        data_crop = nii.data[:, :, zcrop[0]:zcrop[1]]
        nii.data = data_crop
        nii.absolutepath = 'data_rpi_crop.nii'
        nii.save()

        # come back
        os.chdir(curdir)

        sct.printv('\nGenerate output files...', verbose)
        sct.generate_output_file(os.path.join(path_tmp, "data_rpi_crop.nii"),
                                 os.path.join(path_out, file_out + ext_out))

        # Remove temporary files
        if remove_temp_files == 1:
            sct.printv('\nRemove temporary files...')
            sct.rmtree(path_tmp)

        sct.display_viewer_syntax(
            files=[os.path.join(path_out, file_out + ext_out)])
コード例 #53
0
def main():

# Initialization
    fname_anat = ''
    fname_centerline = ''
    fwhm = param.fwhm
    width=param.width
    remove_temp_files = param.remove_temp_files
    start_time = time.time()
    verbose = param.verbose

    # extract path of the script
    path_script = os.path.dirname(__file__) + '/'

    # Parameters for debug mode
    if param.debug == 1:
        print '\n*** WARNING: DEBUG MODE ON ***\n'
        fname_anat = '/home/django/ibouchard/errsm_22_t2_cropped_rpi.nii.gz'
        fname_centerline = '/home/django/ibouchard//errsm_22_t2_cropped_centerline.nii.gz'
        fwhm=1
        width=20

    # Check input param
    try:
        opts, args = getopt.getopt(sys.argv[1:], 'hi:c:f:w:r:')
    except getopt.GetoptError as err:
        print str(err)
        usage()
    for opt, arg in opts:
        if opt == '-h':
            usage()
        elif opt in ('-i'):
            fname_anat = arg
        elif opt in ('-c'):
            fname_centerline = arg
        elif opt in ('-f'):
            fwhm = int(arg)
        elif opt in ('w'):
            width=int(arg)
        elif opt in ('-r'):
            remove_temp_files = int(arg)

    # display usage if a mandatory argument is not provided
    if fname_anat == '' or fname_centerline == '':
        usage()

    # check existence of input files
    sct.check_file_exist(fname_anat)
    sct.check_file_exist(fname_centerline)

    # extract path/file/extension
    path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat)

    # extract path/file/extension
    path_centerline, file_centerline, ext_centerline = sct.extract_fname(fname_centerline)

    # Display arguments
    print '\nCheck input arguments...'
    print '.. Anatomical image:           ' + fname_anat
    print '.. Centerline:                 ' + fname_centerline
    print '.. Full width at half maximum:  ' + str(fwhm)
    print '.. Width of the square window: ' + str(width)

    # create temporary folder
    sct.printv('\nCreate temporary folder...', verbose)
    path_tmp = sct.slash_at_the_end('tmp.'+time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir '+path_tmp, verbose)

    # Copying input data to tmp folder and convert to nii
    sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose)
    sct.run('cp '+fname_anat+' '+path_tmp+'data'+ext_anat, verbose)
    sct.run('cp '+fname_centerline+' '+path_tmp+'centerline'+ext_centerline, verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # convert to nii format
    convert('data'+ext_anat, 'data.nii')
    convert('centerline'+ext_centerline, 'centerline.nii')

    # # Get dimensions of data
    # sct.printv('\nGet dimensions of data...', param.verbose)
    # nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim

    #
    # #Delete existing tmp file in the current folder to avoid problems
    #     #Delete existing tmp file in the current folder to avoid problems
    # if os.path.isfile('tmp.anat.nii'):
    #     sct.run('rm tmp.anat.nii')
    # if os.path.isfile('tmp.centerline.nii'):
    #     sct.run('rm tmp.centerline.nii')
    #
    # # Convert to nii and delete nii.gz if still existing
    # print '\nCopy input data...'
    # sct.run('cp ' + fname_anat + ' tmp.anat'+ext_anat)
    # convert('data'+ext_data, 'data.nii')
    #
    # sct.run('fslchfiletype NIFTI tmp.anat')
    # if os.path.isfile('tmp.anat.nii.gz'):
    #     sct.run('rm tmp.anat.nii.gz')
    # print '.. Anatomical image copied'
    # sct.run('cp ' + fname_centerline + ' tmp.centerline'+ext_centerline)
    # sct.run('fslchfiletype NIFTI tmp.centerline')
    # if os.path.isfile('tmp.centerline.nii.gz'):
    #     sct.run('rm tmp.centerline.nii.gz')
    # print '.. Centerline image copied'


    # Open anatomical image
    #==========================================================================================
    # Reorient input anatomical volume into RL PA IS orientation
    print '\nReorient input volume to RL PA IS orientation...'
    sct.run(sct.fsloutput + 'fslswapdim tmp.anat RL PA IS tmp.anat_orient')


    print '\nGet dimensions of input anatomical image...'
    nx_a, ny_a, nz_a, nt_a, px_a, py_a, pz_a, pt_a = sct.get_dimension('tmp.anat_orient')
    #nx_a, ny_a, nz_a, nt_a, px_a, py_a, pz_a, pt_a = sct.get_dimension(fname_anat)
    print '.. matrix size: ' + str(nx_a) + ' x ' + str(ny_a) + ' x ' + str(nz_a)
    print '.. voxel size:  ' + str(px_a) + 'mm x ' + str(py_a) + 'mm x ' + str(pz_a) + 'mm'

    print '\nOpen anatomical volume...'
    file = nibabel.load('tmp.anat_orient.nii')
    #file = nibabel.load(fname_anat)
    data_anat = file.get_data()
    data_anat=np.array(data_anat)

    data_anat_smoothed=np.copy(data_anat)


    # Open centerline
    #==========================================================================================
    # Reorient binary point into RL PA IS orientation
    print '\nReorient centerline volume into RL PA IS orientation...'
    sct.run(sct.fsloutput + 'fslswapdim tmp.centerline RL PA IS tmp.centerline_orient')

    print '\nGet dimensions of input centerline...'
    nx, ny, nz, nt, px, py, pz, pt = sct.get_dimension('tmp.centerline_orient')
    #nx, ny, nz, nt, px, py, pz, pt = sct.get_dimension(fname_centerline)
    print '.. matrix size: ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz)
    print '.. voxel size:  ' + str(px) + 'mm x ' + str(py) + 'mm x ' + str(pz) + 'mm'

    print '\nOpen centerline volume...'
    file = nibabel.load('tmp.centerline_orient.nii')
    #file = nibabel.load(fname_centerline)
    data_centerline = file.get_data()

    #Loop across z and associate x,y coordinate with the point having maximum intensity
    x_centerline = [0 for iz in range(0, nz, 1)]
    y_centerline = [0 for iz in range(0, nz, 1)]
    z_centerline = [iz for iz in range(0, nz, 1)]
    for iz in range(0, nz, 1):
        x_centerline[iz], y_centerline[iz] = np.unravel_index(data_centerline[:, :, iz].argmax(),
                                                              data_centerline[:, :, iz].shape)
    del data_centerline


    # Fit polynomial function through centerline
    #==========================================================================================

    #Fit centerline in the Z-X plane using polynomial function
    print '\nFit centerline in the Z-X plane using polynomial function...'
    coeffsx = np.polyfit(z_centerline, x_centerline, deg=param.deg_poly)
    polyx = np.poly1d(coeffsx)
    x_centerline_fit = np.polyval(polyx, z_centerline)

    #Fit centerline in the Z-Y plane using polynomial function
    print '\nFit centerline in the Z-Y plane using polynomial function...'
    coeffsy = np.polyfit(z_centerline, y_centerline, deg=param.deg_poly)
    polyy = np.poly1d(coeffsy)
    y_centerline_fit = np.polyval(polyy, z_centerline)

    # Find tangent function of centerline along z
    #==========================================================================================

    # Find tangent to centerline in zx plane, along z
    print '\nFind tangent to centerline along z, in the Z-X plane...'
    poly_tangent_xz = np.polyder(polyx)
    tangent_xz = np.polyval(poly_tangent_xz, z_centerline)

    # Find tangent to centerline in zy plane, along z
    print '\nFind tangent to centerline along z, in the Z-Y plane...'
    poly_tangent_yz = np.polyder(polyy)
    tangent_yz = np.polyval(poly_tangent_yz, z_centerline)

	# Create a Gaussian kernel with users parameters
    #==========================================================================================
    print '\nGenerate a Gaussian kernel with users parameters...     '

    # Convert the fwhm given by users in standard deviation (sigma) and find the size of gaussian kernel knowing
    # that size_kernel=(6*sigma-1) must be odd
    sigma = int(np.round((fwhm/pz_a)*(math.sqrt(1/(2*(math.log(2)))))))
    size_kernel= (np.round(6*sigma))
    if size_kernel%2==0:
        size_kernel=size_kernel-1


    #Creates an  1D-array impulsion and apply a gaussian filter. The result is a Gaussian kernel.
    kernel_temp = np.zeros(size_kernel)
    kernel_temp[math.ceil(size_kernel/2)] = 1
    kernel= ndimage.filters.gaussian_filter1d(kernel_temp, sigma, order=0)
    sum_kernel=np.sum(kernel)

    print '.. Full width at half maximum: ' + str(fwhm)
    print '.. Kernel size : '+str(size_kernel)
    print '.. Sigma (Standard deviation): ' + str(sigma)

    del kernel_temp


    ## Smooth along the spinal cord
    ##==========================================================================================
    print '\nSmooth along the spinal cord...'


    print '\n Voxel position along z axis...'

    # Initialisations
    position=np.zeros(3)
    flag=np.zeros((nx_a,ny_a,nz_a))
    data_weight=np.ones((nx_a,ny_a,nz_a))
    smoothing_array=np.zeros(size_kernel)
    x_near=np.zeros(2)
    y_near=np.zeros(2)
    z_near=np.zeros(2)
    floor_position=np.zeros(3)
    ceil_position=np.zeros(3)
    position_d=np.zeros(3)

    #For every voxel along z axis,
    for iz in range(0,nz_a,1):

        print '.. '+str(iz+1)+ '/'+str(nz_a)

        # Determine the square area to smooth around the centerline
        xmin=x_centerline[iz]-int(width/2)
        xmax=x_centerline[iz]+int(width/2)
        ymin=y_centerline[iz]-int(width/2)
        ymax=y_centerline[iz]+int(width/2)

        #Find the angle between the tangent and the x axis in xz plane.
        theta_xz = -(math.atan(tangent_xz[iz]))

        #Find the angle between the tangent and the y axis in yz plane.
        theta_yz = -(math.atan(tangent_yz[iz]))

        #Construct a rotation array around y axis.
        Rxz=np.zeros((3,3))
        Rxz[1,1]=1
        Rxz[0,0]=(math.cos(theta_xz))
        Rxz[2,0]=(math.sin(theta_xz))
        Rxz[0,2]=-(math.sin(theta_xz))
        Rxz[2,2]=(math.cos(theta_xz))

        #Construct a rotation array around x axis.
        Ryz=np.zeros((3,3))
        Ryz[0,0]=1
        Ryz[1,1]=(math.cos(theta_yz))
        Ryz[1,2]=(math.sin(theta_yz))
        Ryz[2,1]=-(math.sin(theta_yz))
        Ryz[2,2]=(math.cos(theta_yz))


        #For every voxels in the given plane, included in the square area
        for ix in range(xmin,xmax,1):
            for iy in range(ymin,ymax,1):

                #The area to smooth has the same high as the 1D mask length
                isize=0
                centerline_point=[np.copy(x_centerline[iz]), np.copy(y_centerline[iz]), np.copy(iz)]


                #For every voxels along the line orthogonal to the considered plane and included in the kernel.
                #(Here we full a vector called smoothing_array, which has the same length as the kernel, is oriented in the direction of centerline and contains interpolated values of intensity)
                for isize in range(0,size_kernel, 1):

                    #Find the position in the xy plane, before rotation
                    position = [ix, iy, iz+isize-(np.floor(size_kernel/2))]

                    #Find the position after rotation by multiplying the position centered on centerline point with rotation array around x and y axis.
                    new_position= np.dot((np.dot((np.subtract(np.copy(position),centerline_point)), Rxz)), Ryz) + centerline_point

                    #If the resulting voxel is out of image boundaries, pad the smoothing array with a zero
                    if (new_position[0]<0)or (new_position[1]<0)or(new_position[2]<0)or(new_position[0]>nx_a-1)or (new_position[1]>ny_a-1)or(new_position[2]>nz_a-1):
                        smoothing_array[isize]=0
                    #Otherwise, fill the smoothing array with the linear interpolation of values around the actual position
                    else:

                    # Trilinear interpolation
                    #==========================================================================================================================================
                    # Determine the coordinates in grid surrounding the position of the central voxel and perform a trilinear interpolation
                        x_near[0]=np.copy(np.floor(new_position[0]))
                        x_near[1]=np.copy(np.ceil(new_position[0]))
                        xd=(new_position[0]-x_near[0])
                        y_near[0]=np.copy(np.floor(new_position[1]))
                        y_near[1]=np.copy(np.ceil(new_position[1]))
                        yd=(new_position[1]-y_near[0])
                        z_near[0]=np.copy(np.floor(new_position[2]))
                        z_near[1]=np.copy(np.ceil(new_position[2]))
                        zd=(new_position[2]-z_near[0])

                        c00=((data_anat[x_near[0],y_near[0],z_near[0]])*(1-xd))+((data_anat[x_near[1],y_near[0],z_near[0]])*(xd))
                        c10=((data_anat[x_near[0],y_near[1],z_near[0]])*(1-xd))+((data_anat[x_near[1],y_near[1],z_near[0]])*(xd))
                        c01=((data_anat[x_near[0],y_near[0],z_near[1]])*(1-xd))+((data_anat[x_near[1],y_near[0],z_near[1]])*(xd))
                        c11=((data_anat[x_near[0],y_near[1],z_near[1]])*(1-xd))+((data_anat[x_near[1],y_near[1],z_near[1]])*(xd))

                        c0=c00*(1-yd)+c10*yd
                        c1=c01*(1-yd)+c11*yd

                        smoothing_array[isize]=c0*(1-zd)+c1*zd

                    #If actual position is in the z=z_centerline plane, save the coordinates in the variable central_position. (Otherwise, don't save it).
                    if isize==(np.floor(size_kernel/2)):
                        central_position=np.copy(new_position)


                #If the central_position is out of boundaries, don't consider it anymore.
                if (central_position[0]<0)or (central_position[1]<0)or(central_position[2]<0)or(central_position[0]>nx_a-1)or (central_position[1]>ny_a-1)or(central_position[2]>nz_a-1):
                    continue

                else:
                    #Otherwise, perform the convolution of the smoothing_array and the kernel for the central voxel only (equivalent to element-wise multiply). Normalize the result.
                    result=((np.sum(np.copy(smoothing_array)*kernel))/sum_kernel)

                    # Determine the coordinates in grid surrounding the position of the central voxel
                    for i in range(0,3,1):
                        floor_position[i]=math.floor(central_position[i])
                        ceil_position[i]=math.ceil(central_position[i])
                        position_d[i]=central_position[i]-floor_position[i]



                    # Reverse trilinear interpolation
                    #==========================================================================================================================================
                    # Split the resuling intensity given by the convolution between the 8 voxels surrounding the point where the convolution is calculated (central_position).
                    # The array data_anat_smoothed is the the volume os the anatomical image smoothed alog the spinal cord.
                    # The array flag is a volume that indicates if a the corresponding voxel in the anatomical image is inside the smoothing area around the spinal cord and if there is already been an operation on this voxel.
                    # The default value of flag is 0. If it is set to 1, it means there is an operation on the corresponding voxel in anatomical image. Then we clear both the data_anat_smoothed and data_weight corresponding voxel to 0.
                    # The array data_weight represent the is represent the sum of weights used to calculate the intensity for every voxel. In a perfect case, this sum would be 1, but because there is an angle between
                    # two adjacent planes, the sum will be lower so we need to normalize the result. The default value for data_weight is 1, but once there is an operation on the corresponding voxel (flag=1), we accumulate the weights used.

                    if (flag[ceil_position[0],ceil_position[1],ceil_position[2]]==0):
                        data_anat_smoothed[ceil_position[0],ceil_position[1],ceil_position[2]]=0
                        data_weight[ceil_position[0],ceil_position[1],ceil_position[2]]=0
                        flag[ceil_position[0],ceil_position[1],ceil_position[2]]=1
                    weight=(position_d[0])*(position_d[1])*(position_d[2])
                    data_anat_smoothed[ceil_position[0],ceil_position[1],ceil_position[2]]=data_anat_smoothed[ceil_position[0],ceil_position[1],ceil_position[2]]+(weight*result)
                    data_weight[ceil_position[0],ceil_position[1],ceil_position[2]]=data_weight[ceil_position[0],ceil_position[1],ceil_position[2]]+(weight)

                    if (flag[floor_position[0],floor_position[1],floor_position[2]]==0):
                        data_anat_smoothed[floor_position[0],floor_position[1],floor_position[2]]=0
                        data_weight[floor_position[0],floor_position[1],floor_position[2]]=0
                        flag[floor_position[0],floor_position[1],floor_position[2]]=1
                    weight=(1-position_d[0])*(1-position_d[1])*(1-position_d[2])
                    data_anat_smoothed[floor_position[0],floor_position[1],floor_position[2]]=data_anat_smoothed[floor_position[0],floor_position[1],floor_position[2]]+(weight*result)
                    data_weight[floor_position[0],floor_position[1],floor_position[2]]=data_weight[floor_position[0],floor_position[1],floor_position[2]]+(weight)


                    if (flag[ceil_position[0],floor_position[1],floor_position[2]]==0):
                        data_anat_smoothed[ceil_position[0],floor_position[1],floor_position[2]]=0
                        data_weight[ceil_position[0],floor_position[1],floor_position[2]]=0
                        flag[ceil_position[0],floor_position[1],floor_position[2]]=1
                    weight=(position_d[0])*(1-position_d[1])*(1-position_d[2])
                    data_anat_smoothed[ceil_position[0],floor_position[1],floor_position[2]]=data_anat_smoothed[ceil_position[0],floor_position[1],floor_position[2]]+(weight*result)
                    data_weight[ceil_position[0],floor_position[1],floor_position[2]]=data_weight[ceil_position[0],floor_position[1],floor_position[2]]+(weight)

                    if (flag[ceil_position[0],ceil_position[1],floor_position[2]]==0):
                        data_anat_smoothed[ceil_position[0],ceil_position[1],floor_position[2]]=0
                        data_weight[ceil_position[0],ceil_position[1],floor_position[2]]=0
                        flag[ceil_position[0],ceil_position[1],floor_position[2]]=1
                    weight=(position_d[0])*(position_d[1])*(1-position_d[2])
                    data_anat_smoothed[ceil_position[0],ceil_position[1],floor_position[2]]=data_anat_smoothed[ceil_position[0],ceil_position[1],floor_position[2]]+(weight*result)
                    data_weight[ceil_position[0],ceil_position[1],floor_position[2]]=data_weight[ceil_position[0],ceil_position[1],floor_position[2]]+(weight)

                    if (flag[ceil_position[0],floor_position[1],ceil_position[2]]==0):
                        data_anat_smoothed[ceil_position[0],floor_position[1],ceil_position[2]]=0
                        data_weight[ceil_position[0],floor_position[1],ceil_position[2]]=0
                        flag[ceil_position[0],floor_position[1],ceil_position[2]]=1
                    weight=(position_d[0])*(1-position_d[1])*(position_d[2])
                    data_anat_smoothed[ceil_position[0],floor_position[1],ceil_position[2]]=data_anat_smoothed[ceil_position[0],floor_position[1],ceil_position[2]]+(weight*result)
                    data_weight[ceil_position[0],floor_position[1],ceil_position[2]]=data_weight[ceil_position[0],floor_position[1],ceil_position[2]]+(weight)

                    if (flag[floor_position[0],ceil_position[1],floor_position[2]]==0):
                        data_anat_smoothed[floor_position[0],ceil_position[1],floor_position[2]]=0
                        data_weight[floor_position[0],ceil_position[1],floor_position[2]]=0
                        flag[floor_position[0],ceil_position[1],floor_position[2]]=1
                    weight=(1-position_d[0])*(position_d[1])*(1-position_d[2])
                    data_anat_smoothed[floor_position[0],ceil_position[1],floor_position[2]]=data_anat_smoothed[floor_position[0],ceil_position[1],floor_position[2]]+(weight*result)
                    data_weight[floor_position[0],ceil_position[1],floor_position[2]]=data_weight[floor_position[0],ceil_position[1],floor_position[2]]+(weight)

                    if (flag[floor_position[0],ceil_position[1],ceil_position[2]]==0):
                        data_anat_smoothed[floor_position[0],ceil_position[1],ceil_position[2]]=0
                        data_weight[floor_position[0],ceil_position[1],ceil_position[2]]=0
                        flag[floor_position[0],ceil_position[1],ceil_position[2]]=1
                    weight=(1-position_d[0])*(position_d[1])*(position_d[2])
                    data_anat_smoothed[floor_position[0],ceil_position[1], ceil_position[2]]= data_anat_smoothed[floor_position[0],ceil_position[1], ceil_position[2]]+(weight*result)
                    data_weight[floor_position[0],ceil_position[1], ceil_position[2]]= data_weight[floor_position[0],ceil_position[1], ceil_position[2]]+(weight)

                    if (flag[floor_position[0],floor_position[1],ceil_position[2]]==0):
                        data_anat_smoothed[floor_position[0],floor_position[1],ceil_position[2]]=0
                        flag[floor_position[0],floor_position[1],ceil_position[2]]=1
                        data_weight[floor_position[0],floor_position[1],ceil_position[2]]=0
                    weight=(1-position_d[0])*(1-position_d[1])*(position_d[2])
                    data_anat_smoothed[floor_position[0],floor_position[1],ceil_position[2]]=data_anat_smoothed[floor_position[0],floor_position[1],ceil_position[2]]+(weight*result)
                    data_weight[floor_position[0],floor_position[1],ceil_position[2]]=data_weight[floor_position[0],floor_position[1],ceil_position[2]]+(weight)


    # Once we covered the whole spinal cord along z, we normalize the resulting image considering the weight used to calculate each voxel intensity
    data_anat_smoothed=data_anat_smoothed/data_weight



    #Generate output file
    #==========================================================================================

    # Write NIFTI volumes
    print '\nWrite NIFTI volumes...'
    if os.path.isfile('tmp.im_smoothed.nii'):
        sct.run('rm tmp.im_smoothed.nii')
    img = nibabel.Nifti1Image(data_anat_smoothed, None)
    nibabel.save(img, 'tmp.im_smoothed.nii')
    print '.. File created: tmp.im_smoothed.nii'

    #Copy header geometry from input data
    print '\nCopy header geometry from input data and reorient the volume...'
    sct.run(sct.fsloutput+'fslcpgeom tmp.anat_orient.nii tmp.im_smoothed.nii ')

    #Generate output file
    print '\nGenerate output file (in current folder)...'
    sct.generate_output_file('tmp.im_smoothed.nii','./',file_anat+'_smoothed',ext_anat)

    # Delete temporary files
    if remove_temp_files == 1:
        print '\nDelete temporary files...'
        sct.run('rm tmp.anat.nii')
        sct.run('rm tmp.centerline.nii')
        sct.run('rm tmp.anat_orient.nii')
        sct.run('rm tmp.centerline_orient.nii')


    #Display elapsed time
    elapsed_time = time.time() - start_time
    print '\nFinished!'
    print '.. '+str(int(round(elapsed_time)))+'s\n'
コード例 #54
0
    def crop_with_gui(self):
        import matplotlib.pyplot as plt
        import matplotlib.image as mpimg
        # Initialization
        fname_data = self.input_filename
        suffix_out = '_crop'
        remove_temp_files = self.rm_tmp_files
        verbose = self.verbose

        # Check file existence
        sct.printv('\nCheck file existence...', verbose)
        sct.check_file_exist(fname_data, verbose)

        # Get dimensions of data
        sct.printv('\nGet dimensions of data...', verbose)
        nx, ny, nz, nt, px, py, pz, pt = Image(fname_data).dim
        sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), verbose)
        # check if 4D data
        if not nt == 1:
            sct.printv('\nERROR in ' + os.path.basename(__file__) + ': Data should be 3D.\n', 1, 'error')
            sys.exit(2)

        # sct.printv(arguments)
        sct.printv('\nCheck parameters:')
        sct.printv('  data ................... ' + fname_data)

        # Extract path/file/extension
        path_data, file_data, ext_data = sct.extract_fname(fname_data)
        path_out, file_out, ext_out = '', file_data + suffix_out, ext_data

        path_tmp = sct.tmp_create() + "/"

        # copy files into tmp folder
        from sct_convert import convert
        sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose)
        convert(fname_data, os.path.join(path_tmp, "data.nii"))

        # go to tmp folder
        curdir = os.getcwd()
        os.chdir(path_tmp)

        # change orientation
        sct.printv('\nChange orientation to RPI...', verbose)
        Image('data.nii').change_orientation("RPI").save('data_rpi.nii')

        # get image of medial slab
        sct.printv('\nGet image of medial slab...', verbose)
        image_array = nibabel.load('data_rpi.nii').get_data()
        nx, ny, nz = image_array.shape
        scipy.misc.imsave('image.jpg', image_array[math.floor(nx / 2), :, :])

        # Display the image
        sct.printv('\nDisplay image and get cropping region...', verbose)
        fig = plt.figure()
        # fig = plt.gcf()
        # ax = plt.gca()
        ax = fig.add_subplot(111)
        img = mpimg.imread("image.jpg")
        implot = ax.imshow(img.T)
        implot.set_cmap('gray')
        plt.gca().invert_yaxis()
        # mouse callback
        ax.set_title('Left click on the top and bottom of your cropping field.\n Right click to remove last point.\n Close window when your done.')
        line, = ax.plot([], [], 'ro')  # empty line
        cropping_coordinates = LineBuilder(line)
        plt.show()
        # disconnect callback
        # fig.canvas.mpl_disconnect(line)

        # check if user clicked two times
        if len(cropping_coordinates.xs) != 2:
            sct.printv('\nERROR: You have to select two points. Exit program.\n', 1, 'error')
            sys.exit(2)

        # convert coordinates to integer
        zcrop = [int(i) for i in cropping_coordinates.ys]

        # sort coordinates
        zcrop.sort()

        # crop image
        sct.printv('\nCrop image...', verbose)
        nii = Image('data_rpi.nii')
        data_crop = nii.data[:, :, zcrop[0]:zcrop[1]]
        nii.data = data_crop
        nii.absolutepath = 'data_rpi_crop.nii'
        nii.save()

        # come back
        os.chdir(curdir)

        sct.printv('\nGenerate output files...', verbose)
        sct.generate_output_file(os.path.join(path_tmp, "data_rpi_crop.nii"), os.path.join(path_out, file_out + ext_out))

        # Remove temporary files
        if remove_temp_files == 1:
            sct.printv('\nRemove temporary files...')
            sct.rmtree(path_tmp)

        sct.display_viewer_syntax(files=[os.path.join(path_out, file_out + ext_out)])
コード例 #55
0
def create_mask():

    fsloutput = "export FSLOUTPUTTYPE=NIFTI; "  # for faster processing, all outputs are in NIFTI

    # display usage if a mandatory argument is not provided
    if param.fname_data == "" or param.method == "":
        sct.printv("\nERROR: All mandatory arguments are not provided. See usage (add -h).\n", 1, "error")

    # parse argument for method
    method_list = param.method.replace(" ", "").split(",")  # remove spaces and parse with comma
    # method_list = param.method.split(',')  # parse with comma
    method_type = method_list[0]

    # check existence of method type
    if not method_type in param.method_list:
        sct.printv(
            "\nERROR in "
            + os.path.basename(__file__)
            + ': Method "'
            + method_type
            + '" is not recognized. See usage (add -h).\n',
            1,
            "error",
        )

    # check method val
    if not method_type == "center":
        method_val = method_list[1]
    del method_list

    # check existence of shape
    if not param.shape in param.shape_list:
        sct.printv(
            "\nERROR in "
            + os.path.basename(__file__)
            + ': Shape "'
            + param.shape
            + '" is not recognized. See usage (add -h).\n',
            1,
            "error",
        )

    # check existence of input files
    sct.printv("\ncheck existence of input files...", param.verbose)
    sct.check_file_exist(param.fname_data, param.verbose)
    if method_type == "centerline":
        sct.check_file_exist(method_val, param.verbose)

    # check if orientation is RPI
    sct.printv("\nCheck if orientation is RPI...", param.verbose)
    status, output = sct.run("sct_orientation -i " + param.fname_data)
    if not output == "RPI":
        sct.printv(
            "\nERROR in "
            + os.path.basename(__file__)
            + ": Orientation of input image should be RPI. Use sct_orientation to put your image in RPI.\n",
            1,
            "error",
        )

    # display input parameters
    sct.printv("\nInput parameters:", param.verbose)
    sct.printv("  data .................." + param.fname_data, param.verbose)
    sct.printv("  method ................" + method_type, param.verbose)

    # Extract path/file/extension
    path_data, file_data, ext_data = sct.extract_fname(param.fname_data)

    # Get output folder and file name
    if param.fname_out == "":
        param.fname_out = param.file_prefix + file_data + ext_data
    # fname_out = os.path.abspath(path_out+file_out+ext_out)

    # create temporary folder
    sct.printv("\nCreate temporary folder...", param.verbose)
    path_tmp = sct.slash_at_the_end("tmp." + time.strftime("%y%m%d%H%M%S"), 1)
    sct.run("mkdir " + path_tmp, param.verbose)

    # Copying input data to tmp folder and convert to nii
    # NB: cannot use c3d here because c3d cannot convert 4D data.
    sct.printv("\nCopying input data to tmp folder and convert to nii...", param.verbose)
    convert(param.fname_data, path_tmp + "data.nii")
    # sct.run('cp '+param.fname_data+' '+path_tmp+'data'+ext_data, param.verbose)
    if method_type == "centerline":
        convert(method_val, path_tmp + "centerline.nii.gz")
        # sct.run('isct_c3d '+method_val+' -o '+path_tmp+'/centerline.nii.gz')

    # go to tmp folder
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv("\nGet dimensions of data...", param.verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image("data.nii").dim
    sct.printv("  " + str(nx) + " x " + str(ny) + " x " + str(nz) + " x " + str(nt), param.verbose)
    # in case user input 4d data
    if nt != 1:
        sct.printv(
            "WARNING in " + os.path.basename(__file__) + ": Input image is 4d but output mask will 3D.",
            param.verbose,
            "warning",
        )
        # extract first volume to have 3d reference
        nii = Image("data.nii")
        data3d = nii.data[:, :, :, 0]
        nii.data = data3d
        nii.save()

    if method_type == "coord":
        # parse to get coordinate
        coord = map(int, method_val.split("x"))

    if method_type == "point":
        # get file name
        fname_point = method_val
        # extract coordinate of point
        sct.printv("\nExtract coordinate of point...", param.verbose)
        status, output = sct.run("sct_label_utils -i " + fname_point + " -t display-voxel", param.verbose)
        # parse to get coordinate
        coord = output[output.find("Position=") + 10 : -17].split(",")

    if method_type == "center":
        # set coordinate at center of FOV
        coord = round(float(nx) / 2), round(float(ny) / 2)

    if method_type == "centerline":
        # get name of centerline from user argument
        fname_centerline = "centerline.nii.gz"
    else:
        # generate volume with line along Z at coordinates 'coord'
        sct.printv("\nCreate line...", param.verbose)
        fname_centerline = create_line("data.nii", coord, nz)

    # create mask
    sct.printv("\nCreate mask...", param.verbose)
    centerline = nibabel.load(fname_centerline)  # open centerline
    hdr = centerline.get_header()  # get header
    hdr.set_data_dtype("uint8")  # set imagetype to uint8
    data_centerline = centerline.get_data()  # get centerline
    z_centerline = [iz for iz in range(0, nz, 1) if data_centerline[:, :, iz].any()]
    nz = len(z_centerline)
    # get center of mass of the centerline
    cx = [0] * nz
    cy = [0] * nz
    for iz in range(0, nz, 1):
        cx[iz], cy[iz] = ndimage.measurements.center_of_mass(numpy.array(data_centerline[:, :, z_centerline[iz]]))
    # create 2d masks
    file_mask = "data_mask"
    for iz in range(nz):
        center = numpy.array([cx[iz], cy[iz]])
        mask2d = create_mask2d(center, param.shape, param.size, nx, ny)
        # Write NIFTI volumes
        img = nibabel.Nifti1Image(mask2d, None, hdr)
        nibabel.save(img, (file_mask + str(iz) + ".nii"))
    # merge along Z
    # cmd = 'fslmerge -z mask '
    cmd = "sct_concat_data -dim z -o mask.nii.gz -i "
    for iz in range(nz):
        cmd = cmd + file_mask + str(iz) + ".nii,"
    # remove ',' at the end of the string
    cmd = cmd[:-1]
    status, output = sct.run(cmd, param.verbose)

    # copy geometry
    copy_header("data.nii", "mask.nii.gz")

    # come back to parent folder
    os.chdir("..")

    # Generate output files
    sct.printv("\nGenerate output files...", param.verbose)
    sct.generate_output_file(path_tmp + "mask.nii.gz", param.fname_out)

    # Remove temporary files
    if param.remove_tmp_files == 1:
        sct.printv("\nRemove temporary files...", param.verbose)
        sct.run("rm -rf " + path_tmp, param.verbose)

    # to view results
    sct.printv("\nDone! To view results, type:", param.verbose)
    sct.printv("fslview " + param.fname_data + " " + param.fname_out + " -l Red -t 0.5 &", param.verbose, "info")
    print
コード例 #56
0
def main(args=None):
    if not args:
        args = sys.argv[1:]

    # initialize parameters
    param = Param()
    # call main function
    parser = get_parser()
    arguments = parser.parse(args)

    fname_data = arguments['-i']
    fname_bvecs = arguments['-bvec']
    average = arguments['-a']
    verbose = int(arguments.get('-v'))
    sct.init_sct(log_level=verbose, update=True)  # Update log level
    remove_temp_files = int(arguments['-r'])
    path_out = arguments['-ofolder']

    if '-bval' in arguments:
        fname_bvals = arguments['-bval']
    else:
        fname_bvals = ''
    if '-bvalmin' in arguments:
        param.bval_min = arguments['-bvalmin']

    # Initialization
    start_time = time.time()

    # sct.printv(arguments)
    sct.printv('\nInput parameters:', verbose)
    sct.printv('  input file ............' + fname_data, verbose)
    sct.printv('  bvecs file ............' + fname_bvecs, verbose)
    sct.printv('  bvals file ............' + fname_bvals, verbose)
    sct.printv('  average ...............' + str(average), verbose)

    # Get full path
    fname_data = os.path.abspath(fname_data)
    fname_bvecs = os.path.abspath(fname_bvecs)
    if fname_bvals:
        fname_bvals = os.path.abspath(fname_bvals)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    # create temporary folder
    path_tmp = sct.tmp_create(basename="dmri_separate", verbose=verbose)

    # copy files into tmp folder and convert to nifti
    sct.printv('\nCopy files into temporary folder...', verbose)
    ext = '.nii'
    dmri_name = 'dmri'
    b0_name = file_data + '_b0'
    b0_mean_name = b0_name + '_mean'
    dwi_name = file_data + '_dwi'
    dwi_mean_name = dwi_name + '_mean'

    if not convert(fname_data, os.path.join(path_tmp, dmri_name + ext)):
        sct.printv('ERROR in convert.', 1, 'error')
    sct.copy(fname_bvecs, os.path.join(path_tmp, "bvecs"), verbose=verbose)

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # Get size of data
    im_dmri = Image(dmri_name + ext)
    sct.printv('\nGet dimensions data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = im_dmri.dim
    sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt), verbose)

    # Identify b=0 and DWI images
    sct.printv(fname_bvals)
    index_b0, index_dwi, nb_b0, nb_dwi = identify_b0(fname_bvecs, fname_bvals, param.bval_min, verbose)

    # Split into T dimension
    sct.printv('\nSplit along T dimension...', verbose)
    im_dmri_split_list = split_data(im_dmri, 3)
    for im_d in im_dmri_split_list:
        im_d.save()

    # Merge b=0 images
    sct.printv('\nMerge b=0...', verbose)
    from sct_image import concat_data
    l = []
    for it in range(nb_b0):
        l.append(dmri_name + '_T' + str(index_b0[it]).zfill(4) + ext)
    im_out = concat_data(l, 3).save(b0_name + ext)

    # Average b=0 images
    if average:
        sct.printv('\nAverage b=0...', verbose)
        sct.run(['sct_maths', '-i', b0_name + ext, '-o', b0_mean_name + ext, '-mean', 't'], verbose)

    # Merge DWI
    l = []
    for it in range(nb_dwi):
        l.append(dmri_name + '_T' + str(index_dwi[it]).zfill(4) + ext)
    im_out = concat_data(l, 3).save(dwi_name + ext)

    # Average DWI images
    if average:
        sct.printv('\nAverage DWI...', verbose)
        sct.run(['sct_maths', '-i', dwi_name + ext, '-o', dwi_mean_name + ext, '-mean', 't'], verbose)

    # come back
    os.chdir(curdir)

    # Generate output files
    fname_b0 = os.path.abspath(os.path.join(path_out, b0_name + ext_data))
    fname_dwi = os.path.abspath(os.path.join(path_out, dwi_name + ext_data))
    fname_b0_mean = os.path.abspath(os.path.join(path_out, b0_mean_name + ext_data))
    fname_dwi_mean = os.path.abspath(os.path.join(path_out, dwi_mean_name + ext_data))
    sct.printv('\nGenerate output files...', verbose)
    sct.generate_output_file(os.path.join(path_tmp, b0_name + ext), fname_b0, verbose)
    sct.generate_output_file(os.path.join(path_tmp, dwi_name + ext), fname_dwi, verbose)
    if average:
        sct.generate_output_file(os.path.join(path_tmp, b0_mean_name + ext), fname_b0_mean, verbose)
        sct.generate_output_file(os.path.join(path_tmp, dwi_mean_name + ext), fname_dwi_mean, verbose)

    # Remove temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...', verbose)
        sct.rmtree(path_tmp, verbose=verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's', verbose)

    return fname_b0, fname_b0_mean, fname_dwi, fname_dwi_mean
コード例 #57
0
def main():

    # Initialization
    fname_data = ''
    interp_factor = param.interp_factor
    remove_temp_files = param.remove_temp_files
    verbose = param.verbose
    suffix = param.suffix
    smoothing_sigma = param.smoothing_sigma

    # start timer
    start_time = time.time()

    # Parameters for debug mode
    if param.debug:
        fname_data = os.path.join(sct.__data_dir__, 'sct_testing_data', 't2', 't2_seg.nii.gz')
        remove_temp_files = 0
        param.mask_size = 10
    else:
        # Check input parameters
        try:
            opts, args = getopt.getopt(sys.argv[1:], 'hi:v:r:s:')
        except getopt.GetoptError:
            usage()
        if not opts:
            usage()
        for opt, arg in opts:
            if opt == '-h':
                usage()
            elif opt in ('-i'):
                fname_data = arg
            elif opt in ('-r'):
                remove_temp_files = int(arg)
            elif opt in ('-s'):
                smoothing_sigma = arg
            elif opt in ('-v'):
                verbose = int(arg)

    # display usage if a mandatory argument is not provided
    if fname_data == '':
        usage()

    # sct.printv(arguments)
    sct.printv('\nCheck parameters:')
    sct.printv('  segmentation ........... ' + fname_data)
    sct.printv('  interp factor .......... ' + str(interp_factor))
    sct.printv('  smoothing sigma ........ ' + str(smoothing_sigma))

    # check existence of input files
    sct.printv('\nCheck existence of input files...')
    sct.check_file_exist(fname_data, verbose)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    path_tmp = sct.tmp_create(basename="binary_to_trilinear", verbose=verbose)

    from sct_convert import convert
    sct.printv('\nCopying input data to tmp folder and convert to nii...', param.verbose)
    convert(fname_data, os.path.join(path_tmp, "data.nii"))

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # Get dimensions of data
    sct.printv('\nGet dimensions of data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = Image('data.nii').dim
    sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz), verbose)

    # upsample data
    sct.printv('\nUpsample data...', verbose)
    sct.run(["sct_resample",
     "-i", "data.nii",
     "-x", "linear",
     "-vox", str(nx * interp_factor) + 'x' + str(ny * interp_factor) + 'x' + str(nz * interp_factor),
     "-o", "data_up.nii"], verbose)

    # Smooth along centerline
    sct.printv('\nSmooth along centerline...', verbose)
    sct.run(["sct_smooth_spinalcord",
     "-i", "data_up.nii",
     "-s", "data_up.nii",
     "-smooth", str(smoothing_sigma),
     "-r", str(remove_temp_files),
     "-v", str(verbose)], verbose)

    # downsample data
    sct.printv('\nDownsample data...', verbose)
    sct.run(["sct_resample",
     "-i", "data_up_smooth.nii",
     "-x", "linear",
     "-vox", str(nx) + 'x' + str(ny) + 'x' + str(nz),
     "-o", "data_up_smooth_down.nii"], verbose)

    # come back
    os.chdir(curdir)

    # Generate output files
    sct.printv('\nGenerate output files...')
    fname_out = sct.generate_output_file(os.path.join(path_tmp, "data_up_smooth_down.nii"), '' + file_data + suffix + ext_data)

    # Delete temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.rmtree(path_tmp)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's')

    # to view results
    sct.printv('\nTo view results, type:')
    sct.printv('fslview ' + file_data + ' ' + file_data + suffix + ' &\n')
コード例 #58
0
def main(args=None):

    # Initialization
    param = Param()
    start_time = time.time()

    parser = get_parser()
    arguments = parser.parse(sys.argv[1:])

    fname_anat = arguments['-i']
    fname_centerline = arguments['-s']
    if '-smooth' in arguments:
        sigma = arguments['-smooth']
    if '-param' in arguments:
        param.update(arguments['-param'])
    if '-r' in arguments:
        remove_temp_files = int(arguments['-r'])
    verbose = int(arguments.get('-v'))
    sct.init_sct(log_level=verbose, update=True)  # Update log level

    # Display arguments
    sct.printv('\nCheck input arguments...')
    sct.printv('  Volume to smooth .................. ' + fname_anat)
    sct.printv('  Centerline ........................ ' + fname_centerline)
    sct.printv('  Sigma (mm) ........................ ' + str(sigma))
    sct.printv('  Verbose ........................... ' + str(verbose))

    # Check that input is 3D:
    from spinalcordtoolbox.image import Image
    nx, ny, nz, nt, px, py, pz, pt = Image(fname_anat).dim
    dim = 4  # by default, will be adjusted later
    if nt == 1:
        dim = 3
    if nz == 1:
        dim = 2
    if dim == 4:
        sct.printv('WARNING: the input image is 4D, please split your image to 3D before smoothing spinalcord using :\n'
                   'sct_image -i ' + fname_anat + ' -split t -o ' + fname_anat, verbose, 'warning')
        sct.printv('4D images not supported, aborting ...', verbose, 'error')

    # Extract path/file/extension
    path_anat, file_anat, ext_anat = sct.extract_fname(fname_anat)
    path_centerline, file_centerline, ext_centerline = sct.extract_fname(fname_centerline)

    path_tmp = sct.tmp_create(basename="smooth_spinalcord", verbose=verbose)

    # Copying input data to tmp folder
    sct.printv('\nCopying input data to tmp folder and convert to nii...', verbose)
    sct.copy(fname_anat, os.path.join(path_tmp, "anat" + ext_anat))
    sct.copy(fname_centerline, os.path.join(path_tmp, "centerline" + ext_centerline))

    # go to tmp folder
    curdir = os.getcwd()
    os.chdir(path_tmp)

    # convert to nii format
    convert('anat' + ext_anat, 'anat.nii')
    convert('centerline' + ext_centerline, 'centerline.nii')

    # Change orientation of the input image into RPI
    sct.printv('\nOrient input volume to RPI orientation...')
    fname_anat_rpi = msct_image.Image("anat.nii") \
     .change_orientation("RPI", generate_path=True) \
     .save() \
     .absolutepath

    # Change orientation of the input image into RPI
    sct.printv('\nOrient centerline to RPI orientation...')
    fname_centerline_rpi = msct_image.Image("centerline.nii") \
     .change_orientation("RPI", generate_path=True) \
     .save() \
     .absolutepath

    # Straighten the spinal cord
    # straighten segmentation
    sct.printv('\nStraighten the spinal cord using centerline/segmentation...', verbose)
    cache_sig = sct.cache_signature(input_files=[fname_anat_rpi, fname_centerline_rpi],
                                    input_params={"x": "spline"})
    cachefile = os.path.join(curdir, "straightening.cache")
    if sct.cache_valid(cachefile, cache_sig) and os.path.isfile(os.path.join(curdir, 'warp_curve2straight.nii.gz')) and os.path.isfile(os.path.join(curdir, 'warp_straight2curve.nii.gz')) and os.path.isfile(os.path.join(curdir, 'straight_ref.nii.gz')):
        # if they exist, copy them into current folder
        sct.printv('Reusing existing warping field which seems to be valid', verbose, 'warning')
        sct.copy(os.path.join(curdir, 'warp_curve2straight.nii.gz'), 'warp_curve2straight.nii.gz')
        sct.copy(os.path.join(curdir, 'warp_straight2curve.nii.gz'), 'warp_straight2curve.nii.gz')
        sct.copy(os.path.join(curdir, 'straight_ref.nii.gz'), 'straight_ref.nii.gz')
        # apply straightening
        sct.run(['sct_apply_transfo', '-i', fname_anat_rpi, '-w', 'warp_curve2straight.nii.gz', '-d', 'straight_ref.nii.gz', '-o', 'anat_rpi_straight.nii', '-x', 'spline'], verbose)
    else:
        sct.run(['sct_straighten_spinalcord', '-i', fname_anat_rpi, '-o', 'anat_rpi_straight.nii', '-s', fname_centerline_rpi, '-x', 'spline', '-param', 'algo_fitting='+param.algo_fitting], verbose)
        sct.cache_save(cachefile, cache_sig)
        # move warping fields locally (to use caching next time)
        sct.copy('warp_curve2straight.nii.gz', os.path.join(curdir, 'warp_curve2straight.nii.gz'))
        sct.copy('warp_straight2curve.nii.gz', os.path.join(curdir, 'warp_straight2curve.nii.gz'))

    # Smooth the straightened image along z
    sct.printv('\nSmooth the straightened image...')
    sigma_smooth = ",".join([str(i) for i in sigma])
    sct_maths.main(args=['-i', 'anat_rpi_straight.nii',
                         '-smooth', sigma_smooth,
                         '-o', 'anat_rpi_straight_smooth.nii',
                         '-v', '0'])
    # Apply the reversed warping field to get back the curved spinal cord
    sct.printv('\nApply the reversed warping field to get back the curved spinal cord...')
    sct.run(['sct_apply_transfo', '-i', 'anat_rpi_straight_smooth.nii', '-o', 'anat_rpi_straight_smooth_curved.nii', '-d', 'anat.nii', '-w', 'warp_straight2curve.nii.gz', '-x', 'spline'], verbose)

    # replace zeroed voxels by original image (issue #937)
    sct.printv('\nReplace zeroed voxels by original image...', verbose)
    nii_smooth = Image('anat_rpi_straight_smooth_curved.nii')
    data_smooth = nii_smooth.data
    data_input = Image('anat.nii').data
    indzero = np.where(data_smooth == 0)
    data_smooth[indzero] = data_input[indzero]
    nii_smooth.data = data_smooth
    nii_smooth.save('anat_rpi_straight_smooth_curved_nonzero.nii')

    # come back
    os.chdir(curdir)

    # Generate output file
    sct.printv('\nGenerate output file...')
    sct.generate_output_file(os.path.join(path_tmp, "anat_rpi_straight_smooth_curved_nonzero.nii"),
                             file_anat + '_smooth' + ext_anat)

    # Remove temporary files
    if remove_temp_files == 1:
        sct.printv('\nRemove temporary files...')
        sct.rmtree(path_tmp)

    # Display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(np.round(elapsed_time))) + 's\n')

    sct.display_viewer_syntax([file_anat, file_anat + '_smooth'], verbose=verbose)
コード例 #59
0
def main(args=None):
    if not args:
        args = sys.argv[1:]

    # initialize parameters
    param = Param()
    # call main function
    parser = get_parser()
    arguments = parser.parse(args)

    fname_data = arguments['-i']
    fname_bvecs = arguments['-bvec']
    average = arguments['-a']
    verbose = int(arguments['-v'])
    remove_tmp_files = int(arguments['-r'])
    path_out = arguments['-ofolder']

    if '-bval' in arguments:
        fname_bvals = arguments['-bval']
    else:
        fname_bvals = ''
    if '-bvalmin' in arguments:
        param.bval_min = arguments['-bvalmin']

    # Initialization
    start_time = time.time()

    # sct.printv(arguments)
    sct.printv('\nInput parameters:', verbose)
    sct.printv('  input file ............' + fname_data, verbose)
    sct.printv('  bvecs file ............' + fname_bvecs, verbose)
    sct.printv('  bvals file ............' + fname_bvals, verbose)
    sct.printv('  average ...............' + str(average), verbose)

    # Get full path
    fname_data = os.path.abspath(fname_data)
    fname_bvecs = os.path.abspath(fname_bvecs)
    if fname_bvals:
        fname_bvals = os.path.abspath(fname_bvals)

    # Extract path, file and extension
    path_data, file_data, ext_data = sct.extract_fname(fname_data)

    # # get output folder
    # if path_out == '':
    #     path_out = ''

    # create temporary folder
    sct.printv('\nCreate temporary folder...', verbose)
    path_tmp = sct.slash_at_the_end('tmp.' + time.strftime("%y%m%d%H%M%S"), 1)
    sct.run('mkdir ' + path_tmp, verbose)

    # copy files into tmp folder and convert to nifti
    sct.printv('\nCopy files into temporary folder...', verbose)
    ext = '.nii'
    dmri_name = 'dmri'
    b0_name = 'b0'
    b0_mean_name = b0_name + '_mean'
    dwi_name = 'dwi'
    dwi_mean_name = dwi_name + '_mean'

    from sct_convert import convert
    if not convert(fname_data, path_tmp + dmri_name + ext):
        sct.printv('ERROR in convert.', 1, 'error')
    sct.run('cp ' + fname_bvecs + ' ' + path_tmp + 'bvecs', verbose)

    # go to tmp folder
    os.chdir(path_tmp)

    # Get size of data
    im_dmri = Image(dmri_name + ext)
    sct.printv('\nGet dimensions data...', verbose)
    nx, ny, nz, nt, px, py, pz, pt = im_dmri.dim
    sct.printv('.. ' + str(nx) + ' x ' + str(ny) + ' x ' + str(nz) + ' x ' + str(nt), verbose)

    # Identify b=0 and DWI images
    sct.printv(fname_bvals)
    index_b0, index_dwi, nb_b0, nb_dwi = identify_b0(fname_bvecs, fname_bvals, param.bval_min, verbose)

    # Split into T dimension
    sct.printv('\nSplit along T dimension...', verbose)
    im_dmri_split_list = split_data(im_dmri, 3)
    for im_d in im_dmri_split_list:
        im_d.save()

    # Merge b=0 images
    sct.printv('\nMerge b=0...', verbose)
    cmd = 'sct_image -concat t -o ' + b0_name + ext + ' -i '
    for it in range(nb_b0):
        cmd = cmd + dmri_name + '_T' + str(index_b0[it]).zfill(4) + ext + ','
    cmd = cmd[:-1]  # remove ',' at the end of the string
    # WARNING: calling concat_data in python instead of in command line causes a non understood issue
    status, output = sct.run(cmd, param.verbose)

    # Average b=0 images
    if average:
        sct.printv('\nAverage b=0...', verbose)
        sct.run('sct_maths -i ' + b0_name + ext + ' -o ' + b0_mean_name + ext + ' -mean t', verbose)

    # Merge DWI
    cmd = 'sct_image -concat t -o ' + dwi_name + ext + ' -i '
    for it in range(nb_dwi):
        cmd = cmd + dmri_name + '_T' + str(index_dwi[it]).zfill(4) + ext + ','
    cmd = cmd[:-1]  # remove ',' at the end of the string
    # WARNING: calling concat_data in python instead of in command line causes a non understood issue
    status, output = sct.run(cmd, param.verbose)

    # Average DWI images
    if average:
        sct.printv('\nAverage DWI...', verbose)
        sct.run('sct_maths -i ' + dwi_name + ext + ' -o ' + dwi_mean_name + ext + ' -mean t', verbose)
        # if not average_data_across_dimension('dwi.nii', 'dwi_mean.nii', 3):
        #     sct.printv('ERROR in average_data_across_dimension', 1, 'error')
        # sct.run(fsloutput + 'fslmaths dwi -Tmean dwi_mean', verbose)

    # come back to parent folder
    os.chdir('..')

    # Generate output files
    sct.printv('\nGenerate output files...', verbose)
    sct.generate_output_file(path_tmp + b0_name + ext, path_out + b0_name + ext_data, verbose)
    sct.generate_output_file(path_tmp + dwi_name + ext, path_out + dwi_name + ext_data, verbose)
    if average:
        sct.generate_output_file(path_tmp + b0_mean_name + ext, path_out + b0_mean_name + ext_data, verbose)
        sct.generate_output_file(path_tmp + dwi_mean_name + ext, path_out + dwi_mean_name + ext_data, verbose)

    # Remove temporary files
    if remove_tmp_files == 1:
        sct.printv('\nRemove temporary files...', verbose)
        sct.run('rm -rf ' + path_tmp, verbose)

    # display elapsed time
    elapsed_time = time.time() - start_time
    sct.printv('\nFinished! Elapsed time: ' + str(int(round(elapsed_time))) + 's', verbose)

    # to view results
    sct.printv('\nTo view results, type: ', verbose)
    if average:
        sct.printv('fslview b0 b0_mean dwi dwi_mean &\n', verbose)
    else:
        sct.printv('fslview b0 dwi &\n', verbose)