@@ -37,6 +37,13 @@ def get_paths(fs_subject, hemi, type="patch", freesurfer_subject_dir=None):
3737 Directory of freesurfer subjects. Defaults to the value for
3838 the environment variable 'SUBJECTS_DIR' (which should be set
3939 by freesurfer)
40+
41+ Returns
42+ -------
43+ path : str
44+ Path template (with an unfilled `{name}` field) for the requested
45+ file type. `None` is returned if `type` does not match any of
46+ 'patch', 'surf', 'curv', or 'slim'.
4047 """
4148 if freesurfer_subject_dir is None :
4249 freesurfer_subject_dir = os .environ ['SUBJECTS_DIR' ]
@@ -113,6 +120,9 @@ def flatten(fs_subject, hemi, patch, freesurfer_subject_dir=None, save_every=Non
113120
114121 Returns
115122 -------
123+ success : bool
124+ True if the user confirmed and `mris_flatten` was run. False if the
125+ user declined the confirmation prompt (in which case nothing is run).
116126
117127 Notes
118128 -----
@@ -352,6 +362,11 @@ def _remove_disconnected_polys(polys):
352362
353363 This filtering is useful to remove disconnected vertices resulting from a
354364 poor surface cut.
365+
366+ Returns
367+ -------
368+ polys : ndarray
369+ The subset of `polys` belonging to the largest connected component.
355370 """
356371 n_points = np .max (polys ) + 1
357372 import scipy .sparse as sp
@@ -388,6 +403,12 @@ def _move_disconnect_points_to_zero(pts, polys):
388403 This cleaning step is useful after _remove_disconnected_polys, to
389404 avoid using this points in boundaries computations (through pts.max(axis=0)
390405 here and there).
406+
407+ Returns
408+ -------
409+ pts : ndarray
410+ `pts`, with the coordinates of any point not referenced by `polys`
411+ set to zero.
391412 """
392413 mask = np .zeros (len (pts ), dtype = bool )
393414 mask [np .unique (polys )] = True
@@ -406,7 +427,19 @@ def make_fiducial(fs_subject, freesurfer_subject_dir=None):
406427
407428
408429def parse_surf (filename ):
409- """
430+ """Parse a freesurfer binary surface file.
431+
432+ Parameters
433+ ----------
434+ filename : str
435+ Path to a freesurfer surface file (e.g. `lh.smoothwm`).
436+
437+ Returns
438+ -------
439+ pts : ndarray, shape (n_verts, 3)
440+ Vertex coordinates.
441+ polys : ndarray, shape (n_faces, 3)
442+ Triangle faces, as vertex indices into `pts`.
410443 """
411444 with open (filename , 'rb' ) as fp :
412445 #skip magic
@@ -465,15 +498,38 @@ def write_patch(filename, pts, edges=None):
465498
466499
467500def parse_curv (filename ):
468- """
501+ """Parse a freesurfer binary curvature file.
502+
503+ Parameters
504+ ----------
505+ filename : str
506+ Path to a freesurfer curvature file (e.g. `lh.curv`).
507+
508+ Returns
509+ -------
510+ curv : ndarray, shape (n_verts,)
511+ Per-vertex scalar value stored in the file (e.g. curvature, sulcal
512+ depth, or thickness, depending on which file was read).
469513 """
470514 with open (filename , 'rb' ) as fp :
471515 fp .seek (15 )
472516 return np .frombuffer (fp .read (), dtype = '>f4' ).byteswap ().view (np .dtype ('>f4' ).newbyteorder ('=' ))
473517
474518
475519def parse_patch (filename ):
476- """
520+ """Parse a freesurfer binary patch file.
521+
522+ Parameters
523+ ----------
524+ filename : str
525+ Path to a freesurfer patch file (e.g. `lh.flatten.patch.3d`).
526+
527+ Returns
528+ -------
529+ data : structured ndarray
530+ One record per vertex in the patch, with fields 'vert' (1-indexed
531+ vertex number; negative for boundary/edge vertices), 'x', 'y', 'z'
532+ (the vertex's coordinates in the patch).
477533 """
478534 with open (filename , 'rb' ) as fp :
479535 header , = struct .unpack ('>i' , fp .read (4 ))
@@ -486,6 +542,18 @@ def parse_patch(filename):
486542
487543def get_surf (subject , hemi , type , patch = None , flatten_step = None , freesurfer_subject_dir = None ):
488544 """Read freesurfer surface file
545+
546+ Returns
547+ -------
548+ pts : ndarray
549+ Vertex coordinates for this surface (or patch, if `patch` is given).
550+ polys : ndarray
551+ Triangle faces for this surface (or patch).
552+ idx : ndarray
553+ If `type` is "patch", a per-vertex flag array (1 for interior
554+ vertices, -1 for boundary/edge vertices, 0 for vertices not in the
555+ patch). Otherwise, the curvature values for this surface/hemisphere,
556+ as returned by `get_curv`.
489557 """
490558 if type == "patch" :
491559 assert patch is not None
@@ -599,6 +667,14 @@ def get_label(cx_subject, label, fs_subject=None, fs_dir=None, src_subject='fsav
599667 Freesurfer subject directory; None defaults to OS environment variable
600668 hemisphere : list | tuple
601669
670+ Returns
671+ -------
672+ idx : ndarray
673+ Vertex indices (into the pycortex fiducial surface) that have label
674+ values, with right-hemisphere indices offset by the number of left-
675+ hemisphere vertices.
676+ values : ndarray
677+ Label value for each vertex in `idx`.
602678 """
603679 if fs_dir is None :
604680 fs_dir = os .environ ['SUBJECTS_DIR' ]
@@ -619,6 +695,26 @@ def get_label(cx_subject, label, fs_subject=None, fs_dir=None, src_subject='fsav
619695
620696
621697def _mri_surf2surf_command (src_subj , trg_subj , input_file , output_file , hemi ):
698+ """Build the `mri_surf2surf` command-line argument list.
699+
700+ Parameters
701+ ----------
702+ src_subj : str
703+ Freesurfer name of the source subject.
704+ trg_subj : str
705+ Freesurfer name of the target subject.
706+ input_file : str
707+ Path to the source `.gii` file to resample.
708+ output_file : str
709+ Path to write the resampled `.gii` file to.
710+ hemi : str in ("lh", "rh")
711+ Hemisphere.
712+
713+ Returns
714+ -------
715+ cmd : list of str
716+ Argument list suitable for `subprocess`, e.g. `sp.Popen(cmd)`.
717+ """
622718 # mri_surf2surf --srcsubject <source subject name> --srcsurfval
623719 # <sourcefile> --trgsubject <target suhject name> --trgsurfval <target
624720 # file> --hemi <hemifield>
@@ -633,6 +729,19 @@ def _mri_surf2surf_command(src_subj, trg_subj, input_file, output_file, hemi):
633729
634730
635731def _check_datatype (data ):
732+ """Downcast 64-bit dtypes to their 32-bit equivalent for gifti export.
733+
734+ Parameters
735+ ----------
736+ data : ndarray
737+ Array whose dtype should be checked.
738+
739+ Returns
740+ -------
741+ dtype : numpy dtype
742+ `np.int32` if `data` is `int64`, `np.float32` if `data` is
743+ `float64`, otherwise `data`'s own dtype unchanged.
744+ """
636745 dtype = data .dtype
637746 if dtype == np .int64 :
638747 return np .int32
@@ -659,7 +768,12 @@ def mri_surf2surf(data, source_subj, target_subj, hemi, subjects_dir=None):
659768
660769 hemi: str in ("lh", "rh")
661770 string indicating hemisphere.
662-
771+
772+ Returns
773+ =======
774+ output_data : ndarray, shape=(n_imgs, n_target_verts)
775+ `data` resampled onto the target subject's vertices.
776+
663777 Notes
664778 =====
665779 Requires path to mri_surf2surf or freesurfer environment to be active.
@@ -709,6 +823,11 @@ def _read_sphere_reg(subject, hemi, subjects_dir=None):
709823
710824 These are the coordinates on which freesurfer's spherical registration
711825 defines the cross-subject vertex correspondence used by ``mri_surf2surf``.
826+
827+ Returns
828+ -------
829+ pts : ndarray, shape (n_verts, 3)
830+ Registered sphere vertex coordinates for this subject/hemisphere.
712831 """
713832 surf_file = get_paths (subject , hemi , 'surf' ,
714833 freesurfer_subject_dir = subjects_dir ).format (
@@ -882,8 +1001,14 @@ def get_curv(fs_subject, hemi, type='wm', freesurfer_subject_dir=None):
8821001 type : str
8831002 'wm' or other type of surface (e.g. 'fiducial' or 'pial')
8841003 freesurfer_subject_dir : str
885- directory for Freesurfer subjects (defaults to value for the
1004+ directory for Freesurfer subjects (defaults to value for the
8861005 environment variable $SUBJECTS_DIR if None)
1006+
1007+ Returns
1008+ -------
1009+ curv : ndarray
1010+ Per-vertex curvature (or other surface-info) values for this subject
1011+ and hemisphere.
8871012 """
8881013 if type == "wm" :
8891014 curv_file = get_paths (fs_subject , hemi , 'curv' , freesurfer_subject_dir = freesurfer_subject_dir ).format (name = '' )
@@ -909,6 +1034,13 @@ def show_surf(subject, hemi, type, patch=None, curv=True, freesurfer_subject_dir
9091034 curv : bool
9101035
9111036 freesurfer_subject_dir :
1037+
1038+ Returns
1039+ -------
1040+ fig : mayavi figure
1041+ The mayavi figure the surface was plotted into.
1042+ surf : mayavi surface object
1043+ The rendered surface object within `fig`.
9121044 """
9131045 warnings .warn (('Deprecated and probably broken! Try `cortex.segment.show_surf()`\n '
9141046 'which uses a third-party program (meshlab, available for linux & mac\n '
@@ -952,7 +1084,23 @@ def picker_callback(picker):
9521084 return fig , surf
9531085
9541086def write_dot (fname , pts , polys , name = "test" ):
955- """
1087+ """Write a mesh's edge graph out as a Graphviz .dot file.
1088+
1089+ Parameters
1090+ ----------
1091+ fname : str
1092+ Path to write the .dot file to.
1093+ pts : ndarray
1094+ Vertex coordinates, used to compute edge lengths.
1095+ polys : ndarray
1096+ Triangle faces defining the mesh's edges.
1097+ name : str, optional
1098+ Name to give the graph in the .dot file. Default is "test".
1099+
1100+ Returns
1101+ -------
1102+ None
1103+ Writes `fname` as a side effect; has no return value.
9561104 """
9571105 import networkx as nx
9581106 def iter_surfedges (tris ):
@@ -975,7 +1123,20 @@ def iter_surfedges(tris):
9751123
9761124
9771125def read_dot (fname , pts ):
978- """
1126+ """Read 2D vertex layout positions back out of a Graphviz .dot file.
1127+
1128+ Parameters
1129+ ----------
1130+ fname : str
1131+ Path to a .dot file previously written by `write_dot` and laid out
1132+ by Graphviz.
1133+ pts : array-like
1134+ Only used for its length, to preallocate the output array.
1135+
1136+ Returns
1137+ -------
1138+ data : ndarray, shape (len(pts), 2)
1139+ 2D (x, y) layout position for each vertex.
9791140 """
9801141 import re
9811142 parse = re .compile (r'\s(\d+)\s\[label="", pos="([\d\.]+),([\d\.]+)".*];' )
@@ -994,7 +1155,24 @@ def read_dot(fname, pts):
9941155
9951156
9961157def write_decimated (path , pts , polys ):
997- """
1158+ """Decimate a surface mesh and write it out as a freesurfer surface plus
1159+ a matching full-resolution patch file.
1160+
1161+ Parameters
1162+ ----------
1163+ path : str
1164+ Path prefix to write to; `.smoothwm` and `.full.patch.3d` suffixes
1165+ are appended for the surface and patch files, respectively.
1166+ pts : ndarray
1167+ Vertex coordinates of the mesh to decimate.
1168+ polys : ndarray
1169+ Triangle faces of the mesh to decimate.
1170+
1171+ Returns
1172+ -------
1173+ None
1174+ Writes `path + '.smoothwm'` and `path + '.full.patch.3d'` as a side
1175+ effect; has no return value.
9981176 """
9991177 from .polyutils import boundary_edges , decimate
10001178 dpts , dpolys = decimate (pts , polys )
@@ -1013,7 +1191,29 @@ def write_decimated(path, pts, polys):
10131191
10141192
10151193class SpringLayout (object ):
1016- """
1194+ """Relaxes a mesh's vertex positions using a spring-force model, where
1195+ each edge acts as a spring with its rest length set by the distance
1196+ between the corresponding vertices in a (possibly different) reference
1197+ mesh `dpts`.
1198+
1199+ Parameters
1200+ ----------
1201+ pts : ndarray
1202+ Initial vertex coordinates to relax.
1203+ polys : ndarray
1204+ Triangle faces defining the mesh's edges/springs.
1205+ dpts : ndarray, optional
1206+ Vertex coordinates used to set each spring's rest (target) length.
1207+ Defaults to `pts`, i.e. the mesh starts at its own rest lengths.
1208+ pins : array-like, optional
1209+ Indices of vertices that should remain fixed (not moved) during
1210+ relaxation.
1211+ stepsize : float, optional
1212+ Step size used to scale vertex movement at each iteration. Default 1.
1213+ neighborhood : int, optional
1214+ Number of times to expand each vertex's neighbor set by one more hop,
1215+ widening the set of springs attached to it. Default 0 (immediate
1216+ mesh neighbors only).
10171217 """
10181218 def __init__ (self , pts , polys , dpts = None , pins = None , stepsize = 1 , neighborhood = 0 ):
10191219 self .pts = pts
@@ -1102,7 +1302,24 @@ def view_step(self):
11021302 self .figure .mlab_source .set (x = self .pts [:,0 ], y = self .pts [:,1 ], z = self .pts [:,2 ])
11031303
11041304def stretch_mwall (pts , polys , mwall ):
1105- """
1305+ """Stretch the medial wall vertices of an inflated surface out into a
1306+ flat disc, as a starting point for flattening.
1307+
1308+ Parameters
1309+ ----------
1310+ pts : ndarray
1311+ Vertex coordinates of the (typically inflated) surface.
1312+ polys : ndarray
1313+ Triangle faces of the surface.
1314+ mwall : array-like
1315+ Indices of the medial wall vertices to stretch out.
1316+
1317+ Returns
1318+ -------
1319+ layout : SpringLayout
1320+ A `SpringLayout` initialized with the medial wall vertices pinned at
1321+ their new, stretched-out positions and the original `pts` as the
1322+ rest-length reference, ready to be relaxed with `.run()`.
11061323 """
11071324 inflated = pts .copy ()
11081325 center = pts [mwall ].mean (0 )
0 commit comments