def mag_data(hemi, retinotopy='<STR_LIT>', surface='<STR_LIT>', mask=None,<EOL>weights=Ellipsis, weight_min=<NUM_LIT:0>, weight_transform=Ellipsis,<EOL>visual_area=None, visual_area_mask=Ellipsis,<EOL>eccentricity_range=None, polar_angle_range=None):
if is_mag_data(hemi): return hemi<EOL>elif pimms.is_lazy_map(hemi) and pimms.is_vector(hemi.keys(), '<STR_LIT:int>'): return hemi<EOL>if mri.is_subject(hemi): hemi = (hemi.lh. hemi.rh)<EOL>if pimms.is_vector(hemi):<EOL><INDENT>return tuple([mag_data(h, retinotopy=retinotopy, surface=surface, mask=mask,<EOL>weights=weights, weight_min=weight_min,<EOL>weight_transform=weight_transform, visual_area=visual_area,<EOL>visual_area_mask=visual_area_mask,<EOL>eccentricity_range=eccentricity_range,<EOL>polar_angle_range=polar_angle_range)<EOL>for h in hemi])<EOL><DEDENT>mesh = geo.to_mesh((hemi, surface))<EOL>retino = retinotopy_data(hemi, retinotopy)<EOL>if weights is Ellipsis: weights = retino.get('<STR_LIT>', None)<EOL>mask = hemi.mask(mask, indices=True)<EOL>(arng,erng) = (polar_angle_range, eccentricity_range)<EOL>(ang,ecc) = (retino['<STR_LIT>'], retino['<STR_LIT>'])<EOL>if pimms.is_str(arng):<EOL><INDENT>tmp = to_hemi_str(arng)<EOL>arng = (-<NUM_LIT>,<NUM_LIT:0>) if tmp == '<STR_LIT>' else (<NUM_LIT:0>,<NUM_LIT>) if tmp == '<STR_LIT>' else (-<NUM_LIT>,<NUM_LIT>)<EOL><DEDENT>elif arng is None:<EOL><INDENT>tmp = ang[mask]<EOL>tmp = tmp[np.isfinite(tmp)]<EOL>arng = (np.min(tmp), np.max(tmp))<EOL><DEDENT>if erng is None:<EOL><INDENT>tmp = ecc[mask]<EOL>tmp = tmp[np.isfinite(tmp)]<EOL>erng = (<NUM_LIT:0>, np.max(tmp))<EOL><DEDENT>elif pimms.is_scalar(erng): erng = (<NUM_LIT:0>, erng)<EOL>(ang,wgt) = hemi.property(retino['<STR_LIT>'], weights=weights, weight_min=weight_min,<EOL>weight_transform=weight_transform, yield_weight=True)<EOL>ecc = hemi.property(retino['<STR_LIT>'], weights=weights, weight_min=weight_min,<EOL>weight_transform=weight_transform, data_range=erng)<EOL>((mn,mx),mid) = (arng, np.mean(arng))<EOL>oks = mask[np.isfinite(ang[mask])]<EOL>u = ang[oks]<EOL>u = np.mod(u + <NUM_LIT> - mid, <NUM_LIT>) - <NUM_LIT> + mid<EOL>ang[oks[np.where((mn <= u) & (u < mx))[<NUM_LIT:0>]]] = np.inf<EOL>bad = np.where(np.isinf(ang) | np.isinf(ecc))[<NUM_LIT:0>]<EOL>ang[bad] = np.inf<EOL>ecc[bad] = np.inf<EOL>wgt[bad] = <NUM_LIT:0><EOL>wgt *= zinv(np.sum(wgt[mask]))<EOL>vcoords = np.asarray(as_retinotopy(retino, '<STR_LIT>'))<EOL>scoords = mesh.coordinates<EOL>if visual_area is Ellipsis: visual_area = retino.get('<STR_LIT>', None)<EOL>if visual_area is not None: retino['<STR_LIT>'] = visual_area<EOL>if wgt is not None: retino['<STR_LIT>'] = wgt<EOL>rdata = pimms.persist(retino)<EOL>(tmn,tmx) = [np.pi/<NUM_LIT> * u for u in arng]<EOL>if tmx - tmn >= <NUM_LIT:2>*np.pi: (tmn,tmx) = (-np.pi,np.pi)<EOL>(emn,emx) = erng<EOL>rarea = <NUM_LIT:0.5> * (emx*emx - emn*emn) * (tmx - tmn)<EOL>def finish_mag_data(mask):<EOL><INDENT>if len(mask) == <NUM_LIT:0>: return None<EOL>submesh = mesh.submesh(mask)<EOL>mdata = pyr.pmap({k:(v[mask]   if pimms.is_vector(v) else<EOL>v[:,mask] if pimms.is_matrix(v) else<EOL>None)<EOL>for (k,v) in six.iteritems(rdata)})<EOL>fs = submesh.tess.indexed_faces<EOL>(vx, sx)  = [x[:,mask]                        for x in (vcoords, scoords)]<EOL>(vfx,sfx) = [np.asarray([x[:,f] for f in fs]) for x in (vx,      sx)]<EOL>(va, sa)  = [geo.triangle_area(*x)            for x in (vfx, sfx)]<EOL>return pyr.m(surface_coordinates=sx, visual_coordinates=vx,<EOL>surface_areas=sa,       visual_areas=va,<EOL>mesh=mesh,              submesh=submesh,<EOL>retinotopy_data=rdata,  masked_data=mdata,<EOL>mask=mask,              area_of_range=rarea)<EOL><DEDENT>if visual_area is None: return finish_mag_data(mask)<EOL>visual_area = hemi.property(visual_area, mask=mask, null=<NUM_LIT:0>, dtype=np.int)<EOL>vam = (np.unique(visual_area)                    if visual_area_mask is None     else<EOL>np.setdiff1d(np.unique(visual_area), [<NUM_LIT:0>]) if visual_area_mask is Ellipsis else<EOL>np.unique(list(visual_area_mask)))<EOL>return pimms.lazy_map({va: curry(finish_mag_data, mask[visual_area[mask] == va])<EOL>for va in vam})<EOL>
mag_data(hemi) yields a map of visual/cortical magnification data for the given hemisphere.
mag_data(mesh) uses the given mesh.
mag_data([arg1, arg2...]) maps over the given hemisphere or mesh arguments.
mag_data(subject) is equivalent to mag_data([subject.lh, subject.rh]).
mag_data(mdata) for a valid magnification data map mdata (i.e., is_mag_data(mdata) is True or
  mdata is a lazy map with integer keys) always yields mdata without considering any additional
  arguments.

The data structure returned by magdata is a lazy map containing the keys:
  * 'surface_coordinates': a (2 x N) or (3 x N) matrix of the mesh coordinates in the mask
    (usually in mm).
  * 'visual_coordinates': a (2 x N) matrix of the (x,y) visual field coordinates (in degrees).
  * 'surface_areas': a length N vector of the surface areas of the faces in the mesh.
  * 'visual_areas': a length N vector of the areas of the faces in the visual field.
  * 'mesh': the full mesh from which the surface coordinates are obtained.
  * 'submesh': the submesh of mesh of just the vertices in the mask (may be identical to mesh).
  * 'mask': the mask used.
  * 'retinotopy_data': the full set of retinotopy_data from the hemi/mesh; note that this will
    include the key 'weights' of the weights actually used and 'visual_area' of the found or
    specified visual area.
  * 'masked_data': the subsampled retinotopy data from the hemi/mesh.
Note that if a visual_area property is found or provided (see options below), instead of
yielding a map of the above, a lazy map whose keys are the visual areas and whose values are the
maps described above is yielded instead.

The following named options are accepted (in order):
  * retinotopy ('any') specifies the value passed to the retinotopy_data function to obtain the
    retinotopic mapping data; this may be a map of such data.
  * surface ('midgray') specifies the surface to use.
  * mask (None) specifies the mask to use.
  * weights, weight_min, weight_transform (Ellipsis, 0, Ellipsis) are used as in the
    to_property() function  in neuropythy.geometry except weights, which, if equal to Ellipsis,
    attempts to use the weights found by retinotopy_data() if any.
  * visual_area (Ellipsis) specifies the property to use for the visual area label; Ellipsis is
    equivalent to whatever visual area label is found by the retinotopy_data() function if any.
  * visual_area_mask (Ellipsis) specifies which visual areas to include in the returned maps,
    assuming a visual_area property is found; Ellipsis is equivalent to everything but 0; None
    is equivalent to everything.
  * eccentricity_range (None) specifies the eccentricity range to include.
  * polar_angle_range (None) specifies the polar_angle_range to include.