docs: def niisort(
          fims,
          memlim=True
      ):
  
      ''' Sort all input NIfTI images and check their shape.
          Output dictionary of image files and their properties.
          Options:
              memlim -- when processing large numbers of frames the memory may
              not be large enough.  memlim causes that the output does not contain
              all the arrays corresponding to the images.
      '''
      # number of NIfTI images in folder
      Nim = 0
      # sorting list (if frame number is present in the form '_frm<dd>', where d is a digit)
      sortlist = []
  
      for f in fims:
          if f.endswith('.nii') or f.endswith('.nii.gz'):
              Nim += 1
              _match = re.search('(?<=_frm)\d*', f)
              if _match:
                  frm = int(_match.group(0))
                  freelists = [frm not in l for l in sortlist]
                  listidx = [i for i,f in enumerate(freelists) if f]
                  if listidx:
                      sortlist[listidx[0]].append(frm)
                  else:
                      sortlist.append([frm])
              else:
                  sortlist.append([None])
  
      if len(sortlist)>1:
          # if more than one dynamic set is given, the dynamic mode is cancelled.
          dyn_flg = False
          sortlist = range(Nim)
      elif len(sortlist)==1:
          dyn_flg = True
          sortlist = sortlist[0]
      else:
          raise ValueError('e> niisort input error.')
          
      
      # number of frames (can be larger than the # images)
      Nfrm = max(sortlist)+1
      # sort the list according to the frame numbers
      _fims = ['Blank']*Nfrm
      # list of NIfTI image shapes and data types used
      shape = []
      dtype = []
      _nii = []
      for i in range(Nim):
          if dyn_flg:
              _fims[sortlist[i]] = fims[i]
              _nii = nib.load(fims[i])
              dtype.append(_nii.get_data_dtype()) 
              shape.append(_nii.shape)
          else:
              _fims[i] = fims[i]
              _nii = nib.load(fims[i])
              dtype.append(_nii.get_data_dtype()) 
              shape.append(_nii.shape)
  
      # check if all images are of the same shape and data type
      if _nii and not shape.count(_nii.shape)==len(shape):
          raise ValueError('Input images are of different shapes.')
      if _nii and not dtype.count(_nii.get_data_dtype())==len(dtype):
          raise TypeError('Input images are of different data types.')
      # image shape must be 3D
      if _nii and not len(_nii.shape)==3:
          raise ValueError('Input image(s) must be 3D.')
  
      out = {'shape':_nii.shape[::-1],
              'files':_fims, 
              'sortlist':sortlist,
              'dtype':_nii.get_data_dtype(), 
              'N':Nim}
  
      if memlim and Nfrm>50:
          imdic = getnii(_fims[0], output='all')
          affine = imdic['affine']
      else:
          # get the images into an array
          _imin = np.zeros((Nfrm,)+_nii.shape[::-1], dtype=_nii.get_data_dtype())
          for i in range(Nfrm):
              if i in sortlist:
                  imdic = getnii(_fims[i], output='all')
                  _imin[i,:,:,:] = imdic['im']
                  affine = imdic['affine']
          out['im'] = _imin[:Nfrm,:,:,:]
  
      out['affine'] = affine
  
      return out