def _generate_subject_DROI_details(subjects, sid, h, eccentricity_range=None, angles=None, min_variance_explained=0, method=None): from neuropythy.util import curry import six, pyrsistent as pyr, numpy as np paradigm_order = ['dorsal', 'ventral', 'vertical', 'horizontal'] roi_eccens = VisualPerformanceFieldsDataset.roi_eccens roi_angles = VisualPerformanceFieldsDataset.roi_angles if angles is None or angles is Ellipsis: angles = roi_angles e = eccentricity_range if e is None or e is Ellipsis: e = list(VisualPerformanceFieldsDataset.roi_eccens) if pimms.is_list(e) and all(pimms.is_tuple(q) for q in e): f = VisualPerformanceFieldsDataset._generate_subject_DROI_details res = [f(subjects, sid, h, eccentricity_range=q) for q in e] q = res[0] def _merge(p, a): r = {} for k in six.iterkeys(q[p][a]): u = [u[p][a][k] for u in res if len(u[p][a][k]) > 0] if len(u) == 0: u = np.asarray([], dtype=np.float) else: u = np.concatenate(u) r[k] = u return pyr.pmap(r) return pyr.pmap({ k: pimms.lmap({a: curry(_merge, k, a) for a in angles}) for k in paradigm_order }) f0 = VisualPerformanceFieldsDataset._generate_subject_DROI_data f = lambda sid, h, k: f0(subjects[sid], h, k, eccentricity_range=e, results='all', min_variance_explained=min_variance_explained, method=method) lm0 = pimms.lmap({k: curry(f, sid, h, k) for k in angles}) pfn = lambda p: pimms.lmap( {k: curry(lambda k: lm0[k][p], k) for k in angles}) return pimms.lmap({p: curry(pfn, p) for p in paradigm_order})
def subject(path, name=Ellipsis, meta_data=None, check_path=True, filter=None, default_alignment=Ellipsis): ''' subject(name) yields an HCP-based Subject object for the subject with the given name or path. Subjects are cached and not reloaded, so multiple calls to subject(name) will yield the same immutable subject object. The name argument is allowed to take a variety of forms: * a local (absolute or relative) path to a valid HCP subject directory * a url or pseudo-path to a valid HCP subject * an integer, in which case the neuropythy.data['hcp'] dataset is used (i.e., the subject data are auto-downloaded from the HCP Amazon-S3 bucket as required) If you request a subject by path, the HCP module has no way of knowing for sure if that subject should be auto-downloaded, so is not; if you want subjects to be auto-downloaded from the HCP database, you should represent the subjects by their integer ids. Note that subects returned by hcp_subject() are always persistent Immutable objects; this means that you must create a transient version of the subject to modify it via the member function sub.transient(). Better, you can make copies of the objects with desired modifications using the copy method--see the pimms library documentation regarding immutable classes and objects. If you wish to modify all subjects loaded by this function, you may set its attribute 'filter' to a function or list of functions that take a single argument (a subject object) and returns a single argument (a potentially-modified subject object). The argument name may alternately be a pseudo_path object or a path that can be converted into a pseudo_path object. The following options are accepted: * name (default: Ellipsis) may optionally specify the subject's name; if Ellipsis, then attempts to deduce the name from the initial argument (which may be a name or a path). * meta_data (default: None) may optionally be a map that contains meta-data to be passed along to the subject object (note that this meta-data will not be cached). * check_path (default: True) may optionally be set to False to ignore the requirement that a directory contain at least the mri/, label/, and surf/ directories to be considered a valid HCP subject directory. Subject objects returned when this argument is not True are not cached. Additionally, check_path may be set to None instead of False, indicating that no sanity checks or search should be performed whatsoever: the string name should be trusted to be an exact relative or absolute path to a valid HCP subejct. * filter (default: None) may optionally specify a filter that should be applied to the subject before returning. This must be a function that accepts as an argument the subject object and returns a (potentially) modified subject object. Filtered subjects are cached by using the id of the filters as part of the cache key. * default_alignment (default: Ellipsis) specifies the default alignment to use with HCP subjects; this may be either 'MSMAll' or 'MSMSulc'; the deafult (Ellipsis) indicates that the 'hcp_default_alignment' configuration value should be used (by default this is 'MSMAll'). ''' from neuropythy import data if pimms.is_str(default_alignment): default_alignment = to_default_alignment_value(default_alignment) elif default_alignment in (Ellipsis, None): default_alignment = config['hcp_default_alignment'] # first thing: if the sid is an integer, we try to get the subject from the hcp dataset; # in this case, because the hcp dataset actually calls down through here (with a pseudo-path), # we don't need to run any of the filters that are run below (they have already been run) if pimms.is_int(path): try: return data['hcp'].subjects[path] except Exception: pass # convert the path to a pseudo-dir; this may fail if the user is requesting a subject by name... try: pdir = to_pseudo_path(path) except Exception: pdir = None if pdir is None: # search for a subject with this name tmp = find_subject_path(path, check_path=check_path) if tmp is not None: pdir = to_pseudo_path(tmp) path = tmp if pdir is None: # It's possible that we need to check the hcp dataset try: return data['hcp'].subjects[int(path)] except: pass raise ValueError('could not find HCP subject: %s' % (path, )) path = pdir.actual_source_path # okay, before we continue, lets check the cache... tup = (path, default_alignment) if tup in subject._cache: sub = subject._cache[tup] else: # extract the name if need-be if name is Ellipsis: import re (pth, name) = (path, '.') while name == '.': (pth, name) = pdir._path_data['pathmod'].split(pth) name = name.split(':')[-1] name = pdir._path_data['pathmod'].split(name)[1] if '.tar' in name: name = name.split('.tar')[0] # make the filemap fmap = subject_file_map(pdir, name=name) # and make the subject! sub = subject_from_filemap(fmap, name=name, check_path=check_path, meta_data=meta_data, default_alignment=default_alignment) if mri.is_subject(sub): sub = sub.persist() sub = sub.with_meta(file_map=fmap) subject._cache[(path, default_alignment)] = sub # okay, we have the initial subject; let's organize the filters if pimms.is_list(subject.filter) or pimms.is_tuple(subject.filter): filts = list(subject.filter) else: filts = [] if pimms.is_list(filter) or pimms.is_tuple(filter): filter = list(filter) else: filter = [] filts = filts + filter if len(filts) == 0: return sub fids = tuple([id(f) for f in filts]) tup = fids + (path, default_alignment) if tup in subject._cache: return subject._cache[tup] for f in filts: sub = f(sub) if mri.is_subject(sub): subject._cache[tup] = sub return sub.persist()