def parse_infile_names(self): """try to get subject and possibly group names from infiles fill self.snames and self.gnames, if possible 1. get SID - if files look like out.ss_review.SID.txt, that is a good start - else, look for varying part of filename 2. get GID - replace SID in infile names and for varying group name """ rv, slist = UTIL.list_minus_pref_suf(self.infiles,'out.ss_review.','.txt') if rv < 0: return if rv > 0: if self.verb > 1: print('++ trying to get SID from glob form') slist = UTIL.list_minus_glob_form(self.infiles, strip='dir') else: if self.verb > 1: print("++ have SIDs from 'out.ss_review' form") if len(slist) == 0: if self.verb > 1: print("-- empty SID list") return # make sure names are unique and not empty if not UTIL.vals_are_unique(slist): if self.verb > 1: print('-- SIDs not detected: not unique') return minlen = min([len(ss) for ss in slist]) if minlen < 1: if self.verb > 1: print('-- SIDs not detected: some would be empty') return # we have a subject list self.snames = slist # now go for GID, start by replacing SIDs in infiles newfiles = [fname.replace(slist[ind], 'SUBJ') for ind, fname in enumerate(self.infiles)] if UTIL.vals_are_constant(newfiles) and self.verb > 1: print('-- no groups detected from filenames') return # okay, try to make a group list glist = UTIL.list_minus_glob_form(newfiles) # cannot have dirs in result for gid in glist: if gid.find('/') >= 0: if self.verb>1: print('-- no GIDs, dirs vary in multiple places') return minlen = min([len(ss) for ss in glist]) if minlen < 1: if self.verb > 1: print('-- GIDs not detected: some would be empty') return if self.verb > 1: print("++ have GIDs from infiles") self.gnames = glist
def make_labels(self, ilines): """parse a list of the form LABEL : VALUES ... and return a LABEL list (with no trailing separator (':')) initialize maxcounts, subjcounts here """ llist = [] for lind, lstr in enumerate(ilines): # get label and value list rv, label, vals = self.get_label_vals(lstr) if rv < 1: continue nvals = len(vals) # label = self.find_parent_label(label) if self.verb > 2: print('++ label: %s, %d val(s)' % (label, nvals)) llist.append(label) self.maxcounts[label] = nvals self.subjcounts[label] = 0 if not UTIL.vals_are_unique(llist): print('** warning: labels are not unique, will use only last values') llist = UTIL.get_unique_sublist(llist) return 0, llist
def set_ids_from_dsets(self, prefix='', suffix='', hpad=0, tpad=0, dpre=0): """use the varying part of the dataset names for subject IDs If hpad > 0 or tpad > 0, expand into the head or tail of the dsets. If prefix or suffix is passed, apply them. return 0 on success, 1 on error """ if hpad < 0 or tpad < 0: print('** set_ids_from_dsets: will not apply negative padding') return 1 # try filenames without paths, first dlist = [s.dset.split('/')[-1] for s in self.subjects] if UTIL.vals_are_constant(dlist): print('** constant dataset names (%s)' % dlist[0]) print(' trying directories...') dlist = [s.dset for s in self.subjects] slist = UTIL.list_minus_glob_form(dlist, hpad, tpad, keep_dent_pre=dpre) # in the case of diretories, check for success # (maybe we can try to skip past them, that might be okay) for index in range(len(slist)): if '/' in slist[index]: posn = slist[index].rfind('/') slist[index] = slist[index][posn + 1:] if len(slist[index]) < 1: print( '** failed to extract subject IDs from directory list') print(' (directories do not vary at single level)') return 1 if len(slist) != len(self.subjects): print('** failed to set SIDs from dset names\n' \ ' dsets = %s\n' \ ' slist = %s' % (dlist, slist)) return 1 if not UTIL.vals_are_unique(slist): print('** cannot set IDs from dsets, labels not unique: %s' % slist) print('-- labels come from dsets: %s' % dlist) return 1 for ind, subj in enumerate(self.subjects): subj.sid = '%s%s%s' % (prefix, slist[ind], suffix) return 0
def check_inputs(self): """check for required inputs: anat, epi (check existence?)""" if self.uvars.is_empty('anat'): self.errors.append('** unspecified anatomical dataset') if self.uvars.is_empty('epi'): self.errors.append('** unspecified EPI dataset') if len(self.uvars.cost_list) < 1: self.errors.append('** unspecified cost function(s)') if not UTIL.vals_are_unique(self.uvars.cost_list): self.errors.append('** cost functions are not unique') return len(self.errors)
def restrict_ids_to_dsets(self, valid_ids=[], require=1): """restrict subject IDs to those in valid_ids list require all valid_ids to exist, or fail return 0 on success """ # bail if either list is empty if len(self.subjects) == 0: return 0 if len(valid_ids) == 0: return 0 # check that valid_ids are unique if not UTIL.vals_are_unique(valid_ids): print('** restrict_ids: ids are not unique') return 1 # check that all valid_ids exist, and generate new subject list all_ids = [subj.sid for subj in self.subjects] new_subjs = [] missing = 0 missed_id = '' # example of missing ID for sid in valid_ids: if sid in all_ids: old_index = all_ids.index(sid) new_subjs.append(self.subjects[old_index]) else: if self.verb > 1: print( "** restrict_ids: cannot restrict to missing ID '%s'" % sid) missed_id = sid missing += 1 if missing: print("** restrict_ids: missing %d of %d IDs" \ % (missing,len(valid_ids))) print(" IDs look like: %s" % ' '.join(all_ids[:3])) print(" missing IDs look like: %s" % missed_id) if require: return 1 else: print("-- restrict_ids: allowing %d missing IDs..." % missing) # apply restricted list self.subjects = new_subjs return 0
def remove_ids_from_dsets(self, remove_ids=[], require=1): """restrict subject IDs to those not in remove_ids list if require: require all remove_ids to exist, or fail return 0 on success """ # bail if either list is empty if len(self.subjects) == 0: return 0 if len(remove_ids) == 0: return 0 # check that remove_ids are unique if not UTIL.vals_are_unique(remove_ids): print('** remove_ids: ids are not unique') return 1 # check that all remove_ids exist, and fail if not all_ids = [subj.sid for subj in self.subjects] missing = 0 for sid in remove_ids: if sid not in all_ids: if self.verb > 1: print("** remove_ids: cannot remove missing ID '%s'" % sid) missed_id = sid missing += 1 if missing and (require or self.verb > 1): print("** remove_ids: missing %d of %d IDs" \ % (missing,len(remove_ids))) print(" IDs look like: %s" % ' '.join(all_ids[:3])) print(" missing IDs look like: %s" % missed_id) # if required, this is fatal if require: return 1 else: print("-- remove_ids: allowing %d missing IDs..." % missing) # generate a new subject list new_subjs = [] for sindex, sid in enumerate(all_ids): if sid not in remove_ids: new_subjs.append(self.subjects[sindex]) # apply remove list self.subjects = new_subjs return 0
def check_inputs(self): """check for required inputs: anat, epi (check existence?)""" if self.uvars.is_empty('anat'): self.errors.append('** unspecified anatomical dataset') if self.uvars.is_empty('epi'): self.errors.append('** unspecified EPI dataset') if len(self.uvars.cost_list) < 1: self.errors.append('** unspecified cost function(s)') if not UTIL.vals_are_unique(self.uvars.cost_list): self.errors.append('** cost functions are not unique') if self.uvars.align_centers == 'yes' and self.uvars.giant_move == 'no': self.warnings.append( \ "** 'align centers' without 'giant move' is dangerous,\n" \ " consider adding 'giant move'") return len(self.errors)
def create_review_table(self, labels=[]): """fill value lines for each infile for each label if dict[label]: append values append any needed empty spaces """ passed_labels = 0 if labels == []: labels = self.labels else: passed_labels = 1 # be sure each label is in proper list for label in labels: if not label in self.labels: print("** review_table: given label '%s' not in list" % label) return 1, [] if len(labels) < 1: return 1, [] # labels, starting with input files RT = [] tline = [] nfiles = len(self.infiles) # -------------------- # labels, starting with input files # start with subject, if possible dosubj = len(self.snames) == len(self.infiles) dogrp = len(self.gnames) == len(self.infiles) doinfiles = (not dogrp and not dosubj) # if "subject ID" is label[0], and they are unique, # then clear dosubj and doinfiles if labels[0] == 'subject ID': # if subject IDs are uniq and fir label = labels[0] sid_list = [self.ldict[ind][label] for ind in range(nfiles)] if UTIL.vals_are_unique(sid_list): dosubj = 0 doinfiles = 0 # allow user to force inclusion if self.show_infiles: doinfiles = 1 # ------------------------------------------------------------ # first 2 lines, fill header lines # -------------------- # main header of labels tline = [] if doinfiles: tline.append('infile') if dogrp: tline.append('group') if dosubj: tline.append('subject') # add value positions for label in labels: nf = self.maxcounts[label]-1 tline.append('%s'%label) tline.extend(['']*nf) RT.append(tline) tline = [] # -------------------- # and value labels if doinfiles: tline.append('value') if dogrp: tline.append('value') if dosubj: tline.append('value') for label in labels: nf = self.maxcounts[label] for ind in range(nf): tline.append('value_%d' % (ind+1)) RT.append(tline) # ------------------------------------------------------------ # add value lines, one per input file for ind, infile in enumerate(self.infiles): tline = [] # current line to add to table # first is infile, if requested or nothing else to show if doinfiles: if infile == '-': tline.append('stdin') else: tline.append('%s' % infile) # then possibly group if dogrp: tline.append('%s' % self.gnames[ind]) # then possibly subject if dosubj: tline.append('%s' % self.snames[ind]) for label in labels: nf = self.maxcounts[label] try: vals = self.ldict[ind][label] except: if self.verb > 2: print('** infile %s missing key %s'%(infile,label)) vals = [] nv = len(vals) if nv > 0: tline.extend(vals) if nf > nv: tline.extend(['']*(nf-nv)) RT.append(tline) return 0, RT