Example #1
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
Example #2
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_reiview' 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):
         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
Example #3
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
Example #4
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_reiview' 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):
         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
Example #5
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
Example #6
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)
Example #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')

      return len(self.errors)
Example #8
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
Example #9
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
Example #10
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
Example #11
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)
Example #12
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)
Example #13
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