Ejemplo n.º 1
0
def save_subject_template(sub,
                          template='benson14',
                          directory=None,
                          create_directory=True):
    '''
    save_subject_template(sub) writes out a set of mgz files in the given subject's analyses
      directory; the files are the angle, eccen, and varea label files for the subject's left and
      right hemispheres, as predicted by the Benson et al. (2014) template of retinotopy.
    The option template may be given to specify 'benson14' or 'benson17' models.
    '''
    template = template.lower()
    fssub = ny.freesurfer_subject(sub)
    (lhdat, rhdat) = ny.vision.predict_retinotopy(fssub, template=template)
    for (hdat, hnm) in [(lhdat, 'lh'), (rhdat, 'rh')]:
        for (datkey, datname) in [('polar_angle', 'angle'),
                                  ('eccentricity', 'eccen'),
                                  ('visual_area', 'varea')]:
            dat = hdat[datkey]
            flnm = os.path.join(analyses_path(), sub,
                                hnm + '.' + datname + '_' + template + '.mgz')
            img = nibabel.freesurfer.mghformat.MGHImage(
                np.asarray(
                    [[dat]],
                    dtype=(np.int32 if datname == 'varea' else np.float32)),
                np.eye(4))
            img.to_filename(flnm)
    return None
Ejemplo n.º 2
0
def import_benson14_surface_from_freesurfer(subject):
    if isinstance(subject, basestring):
        subject = neuro.freesurfer_subject(subject)
    if not isinstance(subject, neurofs.Subject):
        raise ValueError('Subject given to FreeSurferAnatomyModule object is not a neuropythy' + \
                         ' FreeSurfer subject or string')
    # make sure there are template volume files that match this subject
    lang = os.path.join(subject.directory, 'surf', 'lh.angle_benson14.mgz')
    lecc = os.path.join(subject.directory, 'surf', 'lh.eccen_benson14.mgz')
    llab = os.path.join(subject.directory, 'surf', 'lh.v123roi_benson14.mgz')
    rang = os.path.join(subject.directory, 'surf', 'rh.angle_benson14.mgz')
    recc = os.path.join(subject.directory, 'surf', 'rh.eccen_benson14.mgz')
    rlab = os.path.join(subject.directory, 'surf', 'rh.v123roi_benson14.mgz')
    if not os.path.exists(lang) or not os.path.exists(lecc) or not os.path.exists(llab) \
       or not os.path.exists(rang) or not os.path.exists(recc) or not os.path.exists(rlab):
        # Apply the template first...
        benson14_retinotopy_command(subject.directory)
    if not os.path.exists(lang) or not os.path.exists(lecc) or not os.path.exists(llab) \
       or not os.path.exists(rang) or not os.path.exists(recc) or not os.path.exists(rlab):
        raise ValueError('No areas template found/created for subject: ' + lab)
    l_angle_mgz = fs.mghformat.load(lang)
    l_eccen_mgz = fs.mghformat.load(lecc)
    l_label_mgz = fs.mghformat.load(llab)
    r_angle_mgz = fs.mghformat.load(rang)
    r_eccen_mgz = fs.mghformat.load(recc)
    r_label_mgz = fs.mghformat.load(rlab)
    return {
        'subject': subject,
        'lh_polar_angle_mgh': l_angle_mgz,
        'lh_eccentricity_mgh': l_eccen_mgz,
        'lh_v123_labels_mgh': l_label_mgz,
        'rh_polar_angle_mgh': r_angle_mgz,
        'rh_eccentricity_mgh': r_eccen_mgz,
        'rh_v123_labels_mgh': r_label_mgz
    }
Ejemplo n.º 3
0
def import_benson14_volumes_from_freesurfer(subject):
    if isinstance(subject, basestring):
        subject = neuro.freesurfer_subject(subject)
    if not isinstance(subject, neurofs.Subject):
        raise ValueError('Subject given to FreeSurferAnatomyModule object is not a neuropythy' + \
                         ' FreeSurfer subject or string')
    # make sure there are template volume files that match this subject
    ang = os.path.join(subject.directory, 'mri', 'angle_benson14.mgz')
    ecc = os.path.join(subject.directory, 'mri', 'eccen_benson14.mgz')
    lab = os.path.join(subject.directory, 'mri', 'v123roi_benson14.mgz')
    if not os.path.exists(ang) or not os.path.exists(
            ecc) or not os.path.exists(lab):
        # Apply the template first...
        benson14_retinotopy_command(subject.directory)
    if not os.path.exists(ang) or not os.path.exists(
            ecc) or not os.path.exists(lab):
        raise ValueError('No areas template found/created for subject: ' + lab)
    angle_mgz = fs.mghformat.load(ang)
    eccen_mgz = fs.mghformat.load(ecc)
    label_mgz = fs.mghformat.load(lab)
    ribbon_mgzs = (subject.LH.ribbon, subject.RH.ribbon)
    return {
        'subject': subject,
        'polar_angle_mgh': angle_mgz,
        'eccentricity_mgh': eccen_mgz,
        'v123_labels_mgh': label_mgz,
        'ribbon_mghs': ribbon_mgzs
    }
Ejemplo n.º 4
0
 def test_interpolation(self):
     '''
     test_interpolation() performs a variety of high-level tests involving interpolation using
       neuropythy that should catch major errors to important components.
     '''
     logging.info('neuropythy: Testing interpolation...')
     def choose(coll, k): return np.random.choice(coll, k, False)
     # to do these tests, we use the builtin dataset from Benson and Winawer (2018); see also
     # help(ny.data['benson_winawer_2018']) for more information on this dataset.
     dset = ny.data['benson_winawer_2018']
     self.assertTrue(os.path.isdir(dset.cache_directory))
     # pick 1 of the subjects at random
     allsubs = [dset.subjects['S12%02d' % (s+1)] for s in range(8)]
     subs = choose(allsubs, 1)
     fsa = ny.freesurfer_subject('fsaverage')
     def check_dtypes(a,b):
         for tt in [np.integer, np.floating, np.bool_, np.complexfloating]:
             self.assertEqual(np.issubdtype(a.dtype, tt), np.issubdtype(b.dtype, tt))
     def calc_interp(hem, interhem, ps):
         for p in ps: self.assertEqual(np.sum(~np.isfinite(hem.prop(p))), 0)
         us = hem.interpolate(interhem, ps)
         for u in us: self.assertEqual(np.sum(~np.isfinite(u)), 0)
         vs = interhem.interpolate(hem, us)
         for v in vs: self.assertEqual(np.sum(~np.isfinite(v)), 0)
         return vs
     def check_interp(hem, ps, vs):
         for (p,v) in zip(ps,vs):
             logging.info('neuropythy:         * %s', p)
             p = hem.prop(p)
             self.assertEqual(len(p), len(v))
             self.assertLessEqual(np.min(p), np.min(v))
             self.assertGreaterEqual(np.max(p), np.max(v))
             check_dtypes(p, v)
             self.assertGreater(np.corrcoef(p, v)[0,0], 0.6)
     for sub in subs:
         logging.info('neuropythy: - Testing subject %s', sub.name)
         # left hemisphere should have a negative mean x-value, right a positive mean x-value
         self.assertTrue(np.mean(sub.lh.white_surface.coordinates, axis=1)[0] < 0)
         self.assertTrue(np.mean(sub.rh.pial_surface.coordinates, axis=1)[0] > 0)
         # some simple ideas: if we interpolate the properties from one subject to another and
         # then interpolate back, we should get approximately, if not exactly, the same thing
         # for this pick a couple random properties:
         ps = ['prf_variance_explained', 'inf-prf10_visual_area']
         intersub = choose(allsubs, 1)[0]
         logging.info('neuropythy:   - Testing properties %s via subject %s', ps, intersub.name)
         logging.info('neuropythy:     - Testing LH interpolation')
         vs = calc_interp(sub.lh, intersub.lh, ps)
         check_interp(sub.lh, ps, vs)
         logging.info('neuropythy:     - Testing RH interpolation')
         vs = calc_interp(sub.rh, intersub.rh, ps)
         check_interp(sub.rh, ps, vs)
Ejemplo n.º 5
0
 def test_path(self):
     '''
     test_path() ensures that the neuropythy.geometry.path and .path_trace data structures are
       working correctly.
     '''
     logging.info('neuropythy: Testing Path and PathTrace')
     # simple box: should have an area of ~1600 in a flatmap and something close in a sphere
     pts = [(-20,-20), (20,-20), (20,20), (-20,20)]
     # use a simple map projection
     mpj = ny.map_projection('occipital_pole', 'lh', radius=np.pi/3)
     ctx = ny.freesurfer_subject('fsaverage').lh
     trc = ny.geometry.path_trace(mpj, pts, closed=True)
     fmp = mpj(ctx)
     pth = trc.to_path(fmp)
     self.assertTrue(np.isclose(1600, pth.surface_area))
Ejemplo n.º 6
0
def import_freesurfer_subject(subject):
    '''
    import_freesurfer_subject is a calculator that requires a subject id (subject) and yields a
    Neuropythy FreeSurfer subject object, freesurfer_subject.

      @ subject Must be one of (a) the name of a FreeSurfer subject found on the subject path,
        (b) a path to a FreeSurfer subject directory, or (c) a neuropythy FreeSurfer subject
        object.
    '''
    if isinstance(subject, basestring):
        subject = neuro.freesurfer_subject(subject)
    if not isinstance(subject, neuro.Subject):
        raise ValueError(
            'Value given for subject is neither a string nor a neuropythy subject'
        )
    return subject
Ejemplo n.º 7
0
def import_freesurfer_subject(subject=None):
    '''
    import_freesurfer_subject is a calculator that requires a subject id (subject) and yields a
    Neuropythy FreeSurfer subject object, freesurfer_subject.

      @ subject Must be one of (a) the name of a FreeSurfer subject found on the subject path,
        (b) a path to a FreeSurfer subject directory, (c) a neuropythy FreeSurfer subject object, or
        (d) None, indicating that the pRF data does not come from a subject.
    '''
    if subject is None:
        return None
    if pimms.is_str(subject):
        subject = ny.freesurfer_subject(subject)
    if not ny.is_subject(subject):
        raise ValueError(
            'Value given for subject is neither a string nor a neuropythy subject'
        )
    return subject
Ejemplo n.º 8
0
def aggregate_hemi(hem):
    global _subject_hemi_cache
    hem = hem.lower()
    if 'agg' not in _subject_hemi_cache:
        _subject_hemi_cache['agg'] = {}
    aggcch = _subject_hemi_cache['agg']
    if hem in aggcch: return aggcch[hem]
    aggdat = aggregate_data(hem)
    agghem = getattr(ny.freesurfer_subject('fsaverage'), hem.upper())
    agghem = agghem.using(
        properties=reduce(lambda p, x: p.without(x) if x in p else p, [
            'PRF_polar_angle', 'PRF_eccentricity', 'PRF_size',
            'PRF_variance_explained', 'predicted_polar_angle',
            'predicted_visual_area', 'predicted_eccentricity', 'polar_angle',
            'eccentricity', 'visual_area'
        ], agghem.properties))
    agghem = agghem.using(properties=agghem.properties.using(
        polar_angle=aggdat['polar_angle'],
        eccentricity=aggdat['eccentricity'],
        variance_explained=aggdat['variance_explained'],
        prf_size=aggdat['prf_size']))
    aggcch[hem] = agghem
    return agghem
Ejemplo n.º 9
0
def aggregate(hemi, model='benson17', steps=5000, scale=1.0):
    '''
    aggregate(hemi) yields a hemisphere mesh object for the fsaverage_sym subject with data from
      both the group average retinotopy and the 'Benson14' registered predictions of retinotopy
      stored in the properties. The mesh's coordinates have been registered to the V123 retinotopy
      model.

    The following options are accepted:
      * model (default: 'benson17') specifies the retinotopy model to use.
      * steps (default: None) specifies the number of steps to run in the minimization; if
        None, then uses 10000 for benson17 model and 20000 for the schira model.
      * scale (default: 1.0) specifies the scale of the retinotopy potential field term relative to
        the scale of the mesh-based terms.
    '''
    global _agg_cache
    model = model.lower()
    hemi = hemi.lower()
    tpl = (hemi, model, steps, scale)
    if tpl in _agg_cache: return _agg_cache[tpl]
    dat = aggregate_register(hemi,
                             model=model,
                             steps=steps,
                             scale=scale,
                             exclusion_threshold=exclusion_threshold)
    pre = dat['prediction']
    varea = pre['visual_area'] if 'visual_area' in pre else pre['V123_label']
    mesh = ny.freesurfer_subject('fsaverage_sym').LH.sphere_surface
    mesh = mesh.using(coordinates=dat['registered_coordinates'],
                      properties=mesh.properties.using(
                          PRF_polar_angle=dat['sub_polar_angle'],
                          PRF_eccentricity=dat['sub_eccentricity'],
                          weight=dat['sub_weight'],
                          predicted_polar_angle=pre['polar_angle'],
                          predicted_eccentricity=pre['eccentricity'],
                          predicted_visual_area=varea))
    _agg_cache[tpl] = mesh
    return mesh
Ejemplo n.º 10
0
def subject_hemi(sub, hem, ds=None):
    global _subject_hemi_cache, _subject_hemi_cache_ds
    if ds is None:
        if sub not in _subject_hemi_cache:
            _subject_hemi_cache[sub] = {}
        scache = _subject_hemi_cache[sub]
        hem = hem.lower()
        if hem not in scache:
            gsdat = subject_data(sub, hem, 0)
            hemi = getattr(ny.freesurfer_subject(sub), hem.upper())
            hemi = hemi.using(
                properties=reduce(lambda p, x: p.without(x) if x in p else p, [
                    'PRF_polar_angle', 'PRF_eccentricity', 'PRF_size',
                    'PRF_variance_explained', 'predicted_polar_angle',
                    'predicted_visual_area', 'predicted_eccentricity',
                    'polar_angle', 'eccentricity', 'visual_area'
                ], hemi.properties))
            hemi = hemi.using(properties=hemi.properties.using(
                gold_polar_angle=gsdat['polar_angle'],
                gold_eccentricity=gsdat['eccentricity'],
                gold_variance_explained=gsdat['variance_explained'],
                gold_prf_size=gsdat['prf_size']))
            scache[hem] = hemi
        return scache[hem]
    elif (sub, hem, ds) in _subject_hemi_cache_ds:
        return _subject_hemi_cache_ds[(sub, hem, ds)]
    else:
        shemi = subject_hemi(sub, hem)
        sdat = subject_data(sub, hem, ds)
        shemi = shemi.using(properties=shemi.properties.using(
            polar_angle=sdat['polar_angle'],
            eccentricity=sdat['eccentricity'],
            variance_explained=sdat['variance_explained'],
            prf_size=sdat['prf_size']))
        _subject_hemi_cache_ds[(sub, hem, ds)] = shemi
        return shemi
Ejemplo n.º 11
0
def main(args):
    # Parse the arguments...
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'reg',
        metavar='registration_file',
        nargs=1,
        help=('The distort2anat_tkreg.dat or similar file: the registration'
              ' file, in FreeSurfer\'s tkreg format, to apply to the EPIs.'))
    parser.add_argument(
        'epis',
        metavar='EPI',
        type=str,
        nargs='+',
        help='The EPI files to be converted to anatomical orientation')
    parser.add_argument(
        '-t',
        '--tag',
        required=False,
        default='-',
        dest='tag',
        nargs=1,
        help=('A tag to append to the output filenames; if given as - or'
              ' omitted, overwrites original files.'))
    parser.add_argument(
        '-s',
        '--surf',
        required=False,
        default=False,
        dest='surface',
        action='store_true',
        help=('If provided, instructs the script to also produce files of the '
              'time-series resampled on the cortical surface.'))
    parser.add_argument(
        '-o',
        '--out',
        required=False,
        default='.',
        dest='outdir',
        help=(
            'The output directory to which the files should be written; by'
            ' default this is the current directory (.); note that if this'
            ' directory also contains the EPI files and there is no tag given,'
            ' then the EPIs will be overwritten.'))
    parser.add_argument(
        '-m',
        '--method',
        required=False,
        default='linear',
        dest='method',
        help=('The method to use for volume-to-surface interpolation; this may'
              ' be nearest or linear; the default is linear.'))
    parser.add_argument(
        '-l',
        '--layer',
        required=False,
        default='midgray',
        dest='layer',
        help=(
            'Specifies the cortical layer to user in interpolation from volume'
            ' to surface. By default, uses midgray. May be set to a value'
            ' between 0 (white) and 1 (pial) to specify an intermediate surface'
            ' or may be simply white, pial, or midgray.'))
    parser.add_argument(
        '-d',
        '--subjects-dir',
        required=False,
        default=None,
        dest='sdir',
        help=('Specifies the subjects directory to use; by default uses the'
              ' environment variable SUBJECTS_DIR.'))
    parser.add_argument('-v',
                        '--verbose',
                        required=False,
                        default=False,
                        action='store_true',
                        dest='verbose',
                        help='Print verbose output')
    if args[0].startswith('python'): args = args[2:]
    else: args = args[1:]
    args = parser.parse_args(args)
    # Check some of the arguments...
    epis = args.epis
    if len(epis) < 1: raise RuntimeError('No EPIs given')
    tag = args.tag[0]
    if tag == '-': tag = ''
    dosurf = args.surface
    outdir = args.outdir
    if not os.path.isdir(outdir):
        raise RuntimeError('Directory %s does not exist' % outdir)
    if args.verbose:

        def note(*args):
            six.print_(*args, flush=True)
            return True
    else:

        def note(*args):
            return False

    try:
        args.layer = float(args.layer)
    except:
        pass
    # Read in the registration file
    args.reg = args.reg[0]
    if not os.path.isfile(args.reg):
        raise RuntimeError('Given registration file not found: %s' % args.reg)
    with open(args.reg, 'r') as f:
        lines = []
        while True:
            s = f.readline()
            if s is None or s == '': break
            lines.append(s)
    # This tells us some info...
    sub = lines[0].strip()
    if args.sdir is not None:
        ny.add_subject_path(args.sdir)
    try:
        sub = ny.freesurfer_subject(sub)
    except:
        raise ValueError(
            'No subject %s; you may need to set your SUBJECTS_DIR' % sub)
    affine = np.asarray([[float(ss) for ss in s.split()] for s in lines[4:8]])
    affinv = np.linalg.inv(affine)
    displm = sub.lh.affine
    # loop over the given EPIs
    for epi in epis:
        note('Processing EPI %s...' % epi)
        # import the epi file..
        img = ny.load(epi, to='image')
        # edit the header...
        note('   - Correcting volume orientation...')
        new_affine = np.dot(displm,
                            np.dot(affinv, ny.freesurfer.tkr_vox2ras(img)))
        newimg = nib.Nifti1Image(img.dataobj, new_affine, img.header)
        (epi_dir, epi_flnm) = os.path.split(epi)
        if epi_flnm[:-4] in ['.mgz', '.mgh', '.nii']:
            pre = epi_flnm[:-4]
            suf = epi_flnm[-4:]
        else:
            pre = epi_flnm[:-7]
            suf = epi_flnm[-7:]
        srf_flnm = pre + tag + '.mgz'
        epi_flnm = pre + tag + suf
        newimg.to_filename(os.path.join(args.outdir, epi_flnm))
        # okay, now project to the surface
        if args.surface:
            note('   - Projecting to surface...')
            (ldat, rdat) = sub.image_to_cortex(newimg,
                                               surface=args.layer,
                                               method=args.method,
                                               dtype=np.float32)
            # we need to fix the dimensions...
            for (d, h) in zip([ldat, rdat], ['lh', 'rh']):
                if d.shape[-1] == 1:
                    # then this should properly be a 3d MGH image, not a 4d one.
                    im = nib.freesurfer.mghformat.MGHImage(
                        np.transpose(reduce(np.expand_dims, [-1], d),
                                     (0, 2, 1)), np.eye(4))
                else:
                    im = nib.freesurfer.mghformat.MGHImage(
                        np.transpose(reduce(np.expand_dims, [-1, -1], d),
                                     (0, 2, 3, 1)), np.eye(4))
                im.to_filename(os.path.join(args.outdir, h + '.' + srf_flnm))
    # That's it!
    return 0
Ejemplo n.º 12
0
    elif f.startswith('sub-'): sub = f
    elif f == 'derivatives': derpth = os.path.join(pp, f)
if derpth is None: die('Could not find derivatives path')
if sub is None: die('Could not deduce subject from BIDS path')
if os.path.isdir(os.path.join(derpth, 'freesurfer')):
    sub = os.path.join(derpth, 'freesurfer', 'sub-' + sub)
elif 'SUBJECTS_DIR' in os.environ:
    tmp = os.path.join(os.environ['SUBJECTS_DIR'], sub)
    if os.path.isdir(tmp): sub = tmp
else: die('No derivatives/freesurfer or $SUBJECTS_DIR/%s directory found', sub)

print('FreeSurfer Path: %s' % sub)
print('Image Path:      %s' % pth)

try:
    sub = ny.freesurfer_subject(sub)
    lh = sub.lh
    rh = sub.rh
except:
    raise die('Failed to load freesurfer subject')

sys.stdout.write('\nPreparing flat-maps...')
sys.stdout.flush()
try:
    mps_post = {
        h: ny.map_projection('occipital_pole', h, radius=np.pi / 2)
        for h in ['lh', 'rh']
    }
    mps_ante = {
        h: mp.copy(center=-mp.center, center_right=-mp.center_right)
        for (h, mp) in six.iteritems(mps_post)
Ejemplo n.º 13
0
def main(args):
    # Parse the arguments...
    parser = argparse.ArgumentParser()
    parser.add_argument('sub', metavar='subject', nargs=1,
                        help=('The FreeSurfer subject ID or directory.'))
    parser.add_argument('outdir', metavar='directory', type=str, nargs=1,
                        help='The directory containing the output nifti files.')
    parser.add_argument('-x', '--no-surf', required=False, default=True,
                        dest='surface', action='store_false',
                        help=('If provided, instructs the script not to produce files of the '
                              'pRF parameters resampled onto the cortical surface.'))
    parser.add_argument('-m', '--method', required=False, default='linear', dest='method',
                        help=('The method to use for volume-to-surface interpolation; this may'
                              ' be nearest or linear; the default is linear.'))
    parser.add_argument('-l', '--layer', required=False, default='midgray', dest='layer',
                        help=('Specifies the cortical layer to user in interpolation from volume'
                              ' to surface. By default, uses midgray. May be set to a value'
                              ' between 0 (white) and 1 (pial) to specify an intermediate surface'
                              ' or may be simply white, pial, or midgray.'))
    parser.add_argument('-d', '--subjects-dir', required=False, default=None, dest='sdir',
                        help=('Specifies the subjects directory to use; by default uses the'
                              ' environment variable SUBJECTS_DIR.'))
    parser.add_argument('-y', '--no-invert-y', required=False, default=True, dest='invert_y',
                        action='store_false',
                        help=('If provided, does not invert the y-coordinate exported from'
                              ' VistaSoft; by default this inversion is performed.'))
    parser.add_argument('-v', '--verbose', required=False, default=False, action='store_true',
                        dest='verbose', help='Print verbose output')
    if args[0].startswith('python'): args = args[2:]
    else: args = args[1:]
    args = parser.parse_args(args)
    # Check some of the arguments...
    sub = ny.freesurfer_subject(args.sub[0])
    dosurf = args.surface
    outdir = args.outdir[0]
    if not os.path.isdir(outdir):
        raise RuntimeError('Directory %s does not exist' % outdir)
    else:
        os.chdir(outdir)
    if args.verbose:
        def note(*args):
            six.print_(*args, flush=True)
            return True
    else:
        def note(*args):
            return False
    try: args.layer = float(args.layer)
    except: pass
    # figure out what datasets are here...
    dsets = [fl[:-13] for fl in os.listdir('.') if fl.endswith('-xcrds.nii.gz')]
    # loop over the given EPIs
    for ds in dsets:
        note('Processing Dataset %s...' % ds)
        # import the files...
        note('  - Importing parameters...')
        (x,y,s,v) = [ny.load('%s-%s.nii.gz' % (ds, suff), to='image')
                     for suff in ['xcrds','ycrds','sigma','vexpl']]
        # fix polar angle/eccen
        note('  - Creating polar angle/eccentricity images...')
        ang = np.arctan2(-y.get_data() if args.invert_y else y.get_data(), x.get_data())
        ang = np.mod((90.0 - 180.0/np.pi * ang) + 180, 360) - 180
        a = nib.Nifti1Image(ang, x.affine, x.header)
        e = nib.Nifti1Image(np.sqrt(y.get_data()**2 + x.get_data()**2), x.affine, x.header)
        a.to_filename('%s-angle.nii.gz' % ds)
        e.to_filename('%s-eccen.nii.gz' % ds)
        # surfaces...
        if not dosurf: continue
        note('  - Projecting to surface...')
        to_output = {'xcrds':x, 'ycrds':y, 'sigma': s, 'vexpl': v}
        xy = ([0,0],[0,0])
        for (dname,im) in six.iteritems(to_output):
            (ldat, rdat) = sub.image_to_cortex(im, args.layer,
                                               method=args.method, dtype=np.float32,
                                               weights=v)
            if dname == 'xcrds':
                xy[0][0] = ldat
                xy[1][0] = rdat
            elif dname == 'ycrds':
                xy[0][1] = ldat
                xy[1][1] = rdat
            # we need to fix the dimensions...
            for (d,h) in zip([ldat,rdat], ['lh','rh']):
                ny.save('%s.%s-%s.mgz' % (h, ds, dname), d)
        # Special handling for the angle and eccen (avoids need for circular averaging)
        xy = (np.asarray(xy[0]), np.asarray(xy[1]))
        (lecc,recc) = [np.sqrt(np.sum(u**2, axis=0)) for u in xy]
        (lang,rang) = [np.arctan2(-u[1] if args.invert_y else u[1], u[0])
                       for u in (xy[0] * ny.util.zinv(lecc), xy[1] * ny.util.zinv(recc))]
        (lang,rang) = [np.mod((90 - 180/np.pi * aa) + 180, 360) - 180 for aa in (lang,rang)]
        # export these...
        for (h,nm,dat) in [('lh','eccen',lecc), ('lh','angle',lang),
                           ('rh','eccen',recc), ('rh','angle',rang)]:
            ny.save('%s.%s-%s.mgz' % (h, ds, nm), dat)
    # That's it!
    return 0
Ejemplo n.º 14
0
def die(s, *argv):
    if len(argv) > 0: s = s % tuple(argv)
    sys.stderr.write(s + '\n')
    sys.stderr.flush()
    sys.exit(1)


if sys.argv != 4:
    dir('SYNTAX: fsnative_to_fsaverage.py <freesurfer_subject_id_or_path> <coordinates_file> <out>'
        )

# load the freesurfer subject
sid = sys.argv[1]
try:
    sub = ny.freesurfer_subject(sid)
except Exception:
    die('Could not load freesurfer subject: %s', sid)

# load the coords file
coords = pandas.read_csv(sys.argv[2], sep=' ', header=None)
coords = coords[[1, 2, 3]].values

# find nearest for each of these points on the subject's pial surface
lpial = sub.lh.pial_surface
rpial = sub.rh.pial_surface
(nl, nr) = (lpial.vertex_count, rpial.vertex_count)
n = nl + nr
pial = np.vstack([lpial.coordinates.T, rpial.coordinates.T])
try:
    sh = space.cKDTree(pial)