示例#1
0
def create_trans(subject, db_fs, db_bv, fname_out):
    """
       Get transformations of the surface from a file that containes filename
       matrix transformations
    """
    trans_list = []

    trans_name = [
        op.join(db_fs, '{0}/mri/transforms/{0}_orig_TO_meshes.trm'), 'inv ' +
        op.join(db_fs, '{0}/mri/transforms/orig_{0}_TO_Scanner_Based.trm'),
        op.join(
            db_bv,
            '{0}/t1mri/default_acquisition/registration/RawT1-{0}_default_acquisition_TO_Scanner_Based.trm'
        )
    ]

    for name in trans_name:
        split = name.split()
        inv_bool = ('inv' == split[0])
        if inv_bool:
            name = split[1]
        else:
            name = split[0]

        print(name)
        format_name = name.format(subject)
        print(format_name)

        # if not os.path.exists(format_name):
        #     print("error, {} is not an existing path, will try to add \
        #           subject_dir {}".format(format_name, database))
        #
        #     format_name = os.path.join(database, format_name)
        #     print(format_name)
        #     assert os.path.exists(format_name), "Breaking, even when add \
        #         subject_dir, file {} do not exists".format(name)

        with open(format_name, 'r') as matfile:
            lines = matfile.read().strip().split("\n")
            lines_list = [l.split() for l in lines]
            translation = lines_list.pop(0)

            # transpose the rotations
            transpose = list(zip(*lines_list))

            # append translations
            transpose.append(translation)

            # create the matrix
            mat_str = np.array(list(zip(*transpose)))
            mat = mat_str.astype(np.float)
            mat = np.vstack([mat, [0, 0, 0, 1]])

            if inv_bool:
                mat = inv(mat)

            # add line por computing translation
            trans_list.append(mat)

    trans = None
    for trans_cour in trans_list:
        if trans is None:
            trans = trans_cour
        else:
            trans = np.dot(trans, trans_cour)

    if fname_out.endswith('fif'):
        write_trans(fname_out, trans)

    else:
        with open(fname_out, 'w') as matfile:
            # un autre nom semblerait judiceiux pour eviter la confuction
            # avec le matfile de la partie precedente de la fonction
            for i in range(len(trans)):
                for j in range(len(trans[i])):
                    matfile.write(str(trans[i][j]) + ' ')
                matfile.write('\n')

    return trans
示例#2
0
def create_trans(subject, fname, fname_out):
    """
       Get transformations of the surface from a file that containes filename matrix transformations
    """

    trans_list = []

    with open(fname, 'r') as textfile:
        trans_name = textfile.read().strip().split("\n")

        for name in trans_name:
            split = name.split()
            inv_bool = ('inv' == split[0])
            if inv_bool:
                name = split[1]
            else:
                name = split[0]

            name = name.format(subject)

            with open(name, 'r') as matfile:
                lines = matfile.read().strip().split("\n")
                lines_list = [l.split() for l in lines]
                translation = lines_list.pop(0)

                #transpose the rotations
                transpose = list(zip(*lines_list))

                #append translations
                transpose.append(translation)

                #create the matrix
                mat_str = np.array(list(zip(*transpose)))
                #mat_str= np.array(lines_list)
                mat = mat_str.astype(np.float)
                mat = np.vstack([mat, [0, 0, 0, 1]])

                if inv_bool:
                    mat = inv(mat)

                #add line por computing translation
                trans_list.append(mat)
        res = None
        trans = None
        for trans_cour in trans_list:
            if trans is None:
                trans = trans_cour
            else:
                trans = np.dot(trans, trans_cour)

    if fname_out.endswith('fif'):
        write_trans(fname_out, trans)

    else:
        with open(fname_out, 'w') as matfile:
            for i in range(len(trans)):
                for j in range(len(trans[i])):
                    matfile.write(str(trans[i][j]) + ' ')
                matfile.write('\n')

    return trans
示例#3
0
def create_trans(subject, fname, fname_out):
    """
       Get transformations of the surface from a file that containes filename matrix transformations
    """

    trans_list = []

    with open(fname, 'r') as textfile:
        trans_name = textfile.read().strip().split('\n')

        for name in trans_name:
            split = name.split()
            inv_bool = ('inv' == split[0])
            if inv_bool:
                name = split[1]
            else:
                name = split[0]

            name = name.format(subject)

            with open(name, 'r') as matfile:
                lines = matfile.read().strip().split('\r')
                lines_list = [l.split() for l in lines]
                translation = lines_list.pop(0)

                # transpose the rotations
                transpose = list(zip(*lines_list))

                # append translations
                transpose.append(translation)

                # create the matrix
                mat_str = np.array(list(zip(*transpose)))
                mat = mat_str.astype(np.float)
                mat = np.reshape(mat, (3, 4), order='F')
                mat = np.vstack([mat, [1, 0, 0, 0]])
                mat = np.transpose(mat)
                mat = np.rot90(mat, 3)
                # Neer to rotate
                if inv_bool:
                    mat = inv(mat)

                # add line por computing translation
                trans_list.append(mat)
        res = None
        trans = None
        # Why do we need the next loop?
        for trans_cour in trans_list:
            if trans is None:
                trans = trans_cour
            else:
                trans = np.dot(trans, trans_cour)

    if fname_out.endswith('fif'):
        # Create Transform class
        X = mne.Transform(1, 2, trans)
        write_trans(fname_out, X)

    else:
        with open(fname_out, 'w') as matfile:
            for i in range(len(trans)):
                for j in range(len(trans[i])):
                    matfile.write(str(trans[i][j]) + ' ')
                matfile.write('\n')

    return trans
示例#4
0
def contAvg_headpos(condition, method='median', folder=[], summary=False):
    """
    Calculate average transformation from dewar to head coordinates, based 
    on the continous head position estimated from MaxFilter

    Parameters
    ----------
    condition : str
        String containing part of common filename, e.g. "task" for files 
        task-1.fif, task-2.fif, etc. Consistent naiming of files is mandatory!
    method : str
        How to calculate "average, "mean" or "median" (default = "median")
    folder : str
        Path to input files. Default = current dir.

    Returns
    -------
    MNE-Python transform object
        4x4 transformation matrix
    """
    # Check that the method works
    method = method.lower()

    if method not in ['median', 'mean']:
        raise RuntimeError(
            'Wrong method. Must be either \"mean\" or "median"!')
    if not condition:
        raise RuntimeError('You must provide a conditon!')

    # Get and set folders
    if not folder:
        rawdir = getcwd()  # [!] Match up with bash script !
    else:
        rawdir = folder

    print(rawdir)
    quatdir = op.join(rawdir, 'quat_files')

    mean_trans_folder = op.join(rawdir, 'trans_files')
    if not op.exists(mean_trans_folder):  # Make sure output folder exists
        mkdir(mean_trans_folder)

    mean_trans_file = op.join(mean_trans_folder, condition + '-trans.fif')
    if op.isfile(mean_trans_file):
        warnings.warn(
            'N"%s\" already exists is %s. Delete if you want to rerun' %
            (mean_trans_file, mean_trans_folder), RuntimeWarning)
        return

    # Change to subject dir
    files2combine = find_condition_files(quatdir, condition)
    files2combine.sort()

    if not files2combine:
        raise RuntimeError('No files called \"%s\" found in %s' %
                           (condition, quatdir))

    allfiles = []
    for ff in files2combine:
        fl = ff.split('_')[0]
        tmplist = [f for f in listdir(quatdir) if fl in f and '_quat' in f]

        #Fix order
        if len(tmplist) > 1:
            tmplist.sort()
            if any("-" in f for f in tmplist):
                firstfile = tmplist[
                    -1]  # The file without a number will always be last!
                tmpfs = sorted(tmplist[:-1],
                               key=lambda a: int(re.split('-|.fif', a)[-2])
                               )  # Assuming consistent naming!!!
                tmplist[0] = firstfile
                tmplist[1:] = tmpfs
                allfiles = allfiles + tmplist

    if len(allfiles) > 1:
        print('Files used for average head pos:')
        for ib in range(len(allfiles)):
            print('{:d}: {:s}'.format(ib + 1, allfiles[ib]))
    else:
        print('Will find average head pos in %s' % files2combine)

    # LOAD DATA
    # raw = read_raw_fif(op.join(quatdir,firstfile), preload=True, allow_maxshield=True, verbose=False).pick_types(meg=False, chpi=True)
    # Use files2combine instead of allfiles as MNE will find split files automatically.
    for idx, ffs in enumerate(files2combine):
        if idx == 0:
            raw = read_raw_fif(op.join(quatdir, ffs),
                               preload=True,
                               allow_maxshield=True).pick_types(meg=False,
                                                                chpi=True)
        else:
            raw.append(
                read_raw_fif(op.join(quatdir, ffs),
                             preload=True,
                             allow_maxshield=True).pick_types(meg=False,
                                                              chpi=True))

    quat, times = raw.get_data(return_times=True)
    gof = quat[6, ]  # Godness of fit channel
    # fs = raw.info['sfreq']

    # In case "record raw" started before "cHPI"
    if np.any(gof < 0.98):
        begsam = np.argmax(gof > 0.98)
        raw.crop(tmin=raw.times[begsam])
        quat = quat[:, begsam:].copy()
        times = times[begsam:].copy()

    # Make summaries
    if summary:
        plot_movement(quat, times, dirname=rawdir, identifier=condition)
        total_dist_moved(quat,
                         times,
                         write=True,
                         dirname=rawdir,
                         identifier=condition)

    # Get continous transformation
    print('Reading transformation. This will take a while...')
    H = np.empty([4, 4, len(times)])  # Initiate transforms
    init_rot_angles = np.empty([len(times), 3])

    for i, t in enumerate(times):
        Hi = np.eye(4, 4)
        Hi[0:3, 3] = quat[3:6, i].copy()
        Hi[:3, :3] = quat_to_rot(quat[0:3, i])
        init_rot_angles[i, :] = rotation_angles(Hi[:3, :3])
        assert (np.sum(Hi[-1]) == 1.0)  # sanity check result
        H[:, :, i] = Hi.copy()

    if method in ["mean"]:
        H_mean = np.mean(H, axis=2)  # stack, then average over new dim
        mean_rot_xfm = rotation3d(*tuple(
            np.mean(init_rot_angles,
                    axis=0)))  # stack, then average, then make new xfm
    elif method in ["median"]:
        H_mean = np.median(H, axis=2)  # stack, then average over new dim
        mean_rot_xfm = rotation3d(*tuple(
            np.median(init_rot_angles,
                      axis=0)))  # stack, then average, then make new xfm

    H_mean[:3, :3] = mean_rot_xfm
    assert (np.sum(H_mean[-1]) == 1.0)  # sanity check result

    # Create the mean structure and save as .fif
    mean_trans = raw.info['dev_head_t']  # use the last info as a template
    mean_trans['trans'] = H_mean.copy()

    # Write file
    write_trans(mean_trans_file, mean_trans)
    print("Wrote " + mean_trans_file)

    return mean_trans
示例#5
0
def initAvg_headpos(condition=[], folder=[]):
    """
    Write the average head position based of the initial fit of several 
    independent  files and save to a trans fif file

    Parameters
    ----------
    condition : str
        String containing part of common filename, e.g. "task" for files 
        task_a.fif, task_b.fif, etc. Consistent naiming of files is mandatory! 
        If no condition is provided, it will average all files in folder.
    folder : str
        Path to input files. Default = current dir.

    Returns
    -------
    None
        
    """

    if not folder:
        rawdir = getcwd()
    else:
        rawdir = folder

    # Change to subject dir
    if not condition:
        files2combine = listdir(rawdir)
        print('Using all files in %s' % rawdir)
    else:
        files2combine = glob.glob('%s*' % condition)

    if not files2combine:
        print('No files called \"%s\" found in %s' % (condition, rawdir))
        return
    elif len(files2combine) < 2:
        warnings.warn(
            'Only one file, please check!',
            RuntimeWarning)  # [!!!] should it just copy the initial headpos?

    # Define output
    mean_trans_folder = path.join(rawdir, 'trans_files')
    if not path.exists(mean_trans_folder):
        mkdir(mean_trans_folder)

    mean_trans_file = path.join(mean_trans_folder, condition + '-trans.fif')
    if op.isfile(mean_trans_file):
        warnings.warn(
            'N"%s\" already exists is %s. Delete if you want to rerun' %
            (mean_trans_file, mean_trans_folder), RuntimeWarning)
        return

    files2combine = [f for f in files2combine
                     if '.fif' in f]  # Make sure only fif files
    files2combine.sort()

    print('Files used for average head pos:')
    for ib in range(len(files2combine)):
        print('{:d}: {:s}'.format(ib + 1, files2combine[ib]))

    init_xfm = []
    init_rot = []
    for ff in files2combine:
        fname = path.join(rawdir, ff)  # first file is enough NOT ANYMORE!
        with warnings.catch_warnings(
        ):  # suppress some annoying warnings for now
            warnings.simplefilter("ignore")
            info = Raw(fname,
                       preload=False,
                       verbose=False,
                       allow_maxshield=True).info
            print(
                'Ignore the warning above. We\'ll run MaxFilter in a few moments...'
            )

        init_xfm += [info['dev_head_t']['trans']]
        # translations: info['dev_head_t']['trans'][:, 3][:-1]
        init_rot += [info['dev_head_t']['trans'][:3, :3]]

    mean_init_xfm = np.mean(np.stack(init_xfm),
                            axis=0)  # stack, then average over new dim
    init_rot_angles = [rotation_angles(m) for m in init_rot]

    mean_init_rot_xfm = rotation3d(*tuple(
        np.mean(np.stack(init_rot_angles),
                axis=0)))  # stack, then average, then make new xfm

    assert (np.sum(mean_init_xfm[-1]) == 1.0)  # sanity check result
    mean_trans = info['dev_head_t']  # use the last info as a template
    mean_trans['trans'] = mean_init_xfm  # replace the transformation
    mean_trans[
        'trans'][:3, :3] = mean_init_rot_xfm  # replace the rotation part

    mean_init_headpos = mean_trans['trans'][:-1, -1]  # meters
    print('Mean head position (device coords): ({:.1f}, {:.1f}, {:.1f}) mm'.\
          format(*tuple(mean_init_headpos*1e3)))
    print('Discrepancies from mean:')
    for ib, xfm in enumerate(init_xfm):
        diff = 1e3 * (xfm[:-1, -1] - mean_init_headpos)
        rmsdiff = np.linalg.norm(diff)
        print('\tSession {:d}: norm {:.1f} mm ({:.1f}, {:.1f}, {:.1f}) mm '.\
              format(ib + 1, rmsdiff, *tuple(diff)))

    mean_rots = rotation_angles(
        mean_trans['trans'][:3, :3])  # these are in radians
    mean_rots_deg = tuple([180. * rot / np.pi
                           for rot in mean_rots])  # convert to deg
    print('Mean head rotations (around x, y & z axes): ({:.1f}, {:.1f}, {:.1f}) deg'.\
          format(*mean_rots_deg))
    print('Block discrepancies from mean:')
    for ib, rot in enumerate(init_rot):
        cur_rots = rotation_angles(rot)
        diff = tuple([
            180. * cr / np.pi - mr for cr, mr in zip(cur_rots, mean_rots_deg)
        ])
        print('\tSession {:d}: ({:.1f}, {:.1f}, {:.1f}) deg '.\
              format(ib + 1, *tuple(diff)))

    # Write trans file
    write_trans(mean_trans_file, mean_trans)
    print("Wrote " + mean_trans_file)
示例#6
0
def contAvg_headpos(condition, method='median', folder=[]):
    """
    Calculate average transformation from dewar to head coordinates, based 
    on the continous head position estimated from MaxFilter

    Parameters
    ----------
    condition : str
        String containing part of common filename, e.g. "task" for files 
        task-1.fif, task-2.fif, etc. Consistent naiming of files is mandatory!
    method : str
        How to calculate "average, "mean" or "median" (default = "median")
    folder : str
        Path to input files. Default = current dir.

    Returns
    -------
    MNE-Python transform object
        4x4 transformation matrix
    """
    # Check that the method works
    if method not in ['median', 'mean']:
        raise RuntimeError(
            'Wrong method. Must be either \"mean\" or "median"!')
    if not condition:
        raise RuntimeError('You must provide a conditon!')

    # Get and set folders
    if not folder:
        rawdir = getcwd()  # [!] Match up with bash script !
    else:
        rawdir = folder

    print(rawdir)
    quatdir = op.join(rawdir, 'quat_files')

    mean_trans_folder = op.join(rawdir, 'trans_files')
    if not op.exists(mean_trans_folder):  # Make sure output folder exists
        mkdir(mean_trans_folder)

    mean_trans_file = op.join(mean_trans_folder, condition + '-trans.fif')
    if op.isfile(mean_trans_file):
        raise RuntimeError(
            'N"%s\" already exists is %s. Delete aif you want to rerun' %
            (mean_trans_file, mean_trans_folder))

    # Change to subject dir
#    files2combine = glob.glob('%s*' % condition)
    files2combine = [
        f for f in listdir(quatdir) if condition in f and '_quat' in f
    ]

    if not files2combine:
        raise RuntimeError('No files called \"%s\" found in %s' %
                           (condition, quatdir))
    elif len(files2combine) > 1:
        print('Files used for average head pos:')
        for ib in range(len(files2combine)):
            print('{:d}: {:s}'.format(ib + 1, files2combine[ib]))
    else:
        print('Will find average head pos in %s' % files2combine)

    # LOAD DATA
    for idx, ffs in enumerate(files2combine):
        #        print op.join(quatdir,ffs)
        if idx == 0:
            raw = read_raw_fif(op.join(quatdir, ffs),
                               preload=True,
                               allow_maxshield=True).pick_types(meg=False,
                                                                chpi=True)
        else:
            raw.append(
                read_raw_fif(op.join(quatdir, ffs),
                             preload=True,
                             allow_maxshield=True).pick_types(meg=False,
                                                              chpi=True))

    quat, times = raw.get_data(return_times=True)
    gof = quat[6, ]  # Godness of fit channel
    fs = raw.info['sfreq']

    # In case "record raw" started before "cHPI"
    if np.any(gof < 0.98):
        begsam = np.argmax(gof > 0.98)

        raw.crop(tmin=raw.times[begsam])
        quat = quat[:, begsam:].copy()
        times = times[begsam:].copy()

    # Get continous transformation
    print('Reading transformation. This will take a while...')
    H = np.empty([4, 4, len(times)])  # Initiate transforms
    init_rot_angles = np.empty([len(times), 3])

    for i, t in enumerate(times):
        Hi = np.eye(4, 4)
        Hi[0:3, 3] = quat[3:6, i].copy()
        Hi[:3, :3] = quat_to_rot(quat[0:3, i])
        init_rot_angles[i, :] = rotation_angles(Hi[:3, :3])
        assert (np.sum(Hi[-1]) == 1.0)  # sanity check result
        H[:, :, i] = Hi.copy()

    if method in ["mean"]:
        H_mean = np.mean(H, axis=2)  # stack, then average over new dim
        mean_rot_xfm = rotation3d(*tuple(
            np.mean(init_rot_angles,
                    axis=0)))  # stack, then average, then make new xfm
    elif method in ["median"]:
        H_mean = np.median(H, axis=2)  # stack, then average over new dim
        mean_rot_xfm = rotation3d(*tuple(
            np.median(init_rot_angles,
                      axis=0)))  # stack, then average, then make new xfm

    H_mean[:3, :3] = mean_rot_xfm
    assert (np.sum(H_mean[-1]) == 1.0)  # sanity check result

    # Create the mean structure and save as .fif
    mean_trans = raw.info['dev_head_t']  # use the last info as a template
    mean_trans['trans'] = H_mean.copy()

    #    plot_alignment(raw.info,subject='0406',subjects_dir='/home/mikkel/PD_motor/fs_subjects_dir/',dig=True, meg='helmet')

    # Write file
    write_trans(mean_trans_file, mean_trans)
    print("Wrote " + mean_trans_file)

    return mean_trans
示例#7
0
if len(sys.argv) != 3:
    print("usage: {} subject $ds".format(sys.argv[0]))
    sys.exit(1)

subject = sys.argv[1]
dsname = sys.argv[2]

try:
    FShome = os.environ['FREESURFER_HOME']
except KeyError:
    print("You must set the FREESURFER_HOME environment variable!")
    sys.exit(1)

try:
    Subjdir = os.environ['SUBJECTS_DIR']
except KeyError:
    Subjdir = op.join(FShome, "subjects")
    print("Note: Using the default SUBJECTS_DIR:", Subjdir)

name = op.join(Subjdir, subject, "bem", "{}-fiducials.fif".format(subject))
fids = read_fiducials(name)
fidc = _fiducial_coords(fids[0])

raw = read_raw_ctf(dsname, clean_names = True, preload = False)
fidd = _fiducial_coords(raw.info['dig'])

xform = fit_matched_points(fidd, fidc, weights = [1, 10, 1])
t = Transform(FIFF.FIFFV_COORD_HEAD, FIFF.FIFFV_COORD_MRI, xform)
name = op.join(Subjdir, subject, "bem", "{}-trans.fif".format(subject))
write_trans(name, t)