docs: def subject(sid, subjects_path=None, meta_data=None, default_alignment='MSMAll'):
      '''
      subject(sid) yields a HCP Subject object for the subject with the given subject id; sid may be a
        path to a subject or a subject id, in which case the subject paths are searched for it.
      subject(None, path) yields a non-standard HCP subject at the given path.
      subject(sid, path) yields the specific HCP Subject at the given path.
  
      Subjects are cached and not reloaded.  Note that subects returned by 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.
  
      This function works with the neuropythy.hcp.auto_download() function; if you have enabled auto-
      downloading, then subjects returned from this subject may be downloading themselves lazily.
      '''
      if subjects_path is None:
          if os.path.isdir(str(sid)):
              (fdir, fnm) = os.path.split(str(sid))
              try: sid = to_subject_id(fnm)
              except Exception: sid = None
              pth = fdir
          else:
              sid = to_subject_id(sid)
              fnm = str(sid)
              fdir = find_subject_path(sid)
              if fdir is None: raise ValueError('Could not locate subject with id \'%s\'' % sid)
              pth = os.path.split(fdir)[0]
      else:
          if sid is None:
              (pth, fnm) = os.path.split(subjects_path)
          else:
              sid = to_subject_id(sid)
              fnm = str(sid)
              fdir = subjects_path
      fdir = os.path.abspath(os.path.join(pth, fnm))
      if fdir in subject._cache: return subject._cache[fdir]
      sub = Subject(sid, fdir, meta_data=meta_data, default_alignment=default_alignment).persist()
      if isinstance(sub, Subject): subject._cache[fdir] = sub
      return sub