Ejemplo n.º 1
0
   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
Ejemplo n.º 2
0
   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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
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)
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
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
Ejemplo n.º 7
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)
Ejemplo n.º 8
0
   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