docs: def calc_atlas_projections(subject_cortices, atlas_cortices, atlas_map, worklog, atlases=Ellipsis):
      '''
      calc_atlas_projections calculates the lazy map of atlas projections.
  
      Afferent parameters:
        @ atlases 
          The atlases that should be applied to the subject. This can be specified as a list/tuple of
          atlas names or as a string where the atlas names are separated by whitespace, commas, or
          semicolons. For example, to specify the 'benson14' atlas as well as the 'wang15' atlas, then
          ('benson14', 'wang15'), 'benson14 wang15' or 'benson14,wang15' would all be acceptable. To
          specify an atlas version, separate the atlas-name and the version with a colon (:), such as
          'benson14:2.5'. If no version is provided, then the highest version found is used. If
          atlases is set to None or Ellipsis (the default), this is equivalent to 'benson14,wang15'.
  
      Efferent values:
        @ atlas_properties 
          The atlas properties is a nested pimms lazy map whose key-path are like those of the
          atlas_map afferent parameter but which contains only those atlases requested via the atlases
          afferent parameter and whose deepest values are interpolated property vectors for the 
          target subject.
        @ atlas_version_tags 
          Each atlas can be specified as <atlas> or <atlas>:<version>; if the version is specified,
          then the version tag string (e.g., '.v1_5') is included in this dictionary; if only <atlas>
          was specified then this string is ''. If <atlas>: is specified, then the version string for
          whichever atlas was used is included.
      '''
      # Parse the atlases argument first:
      if atlases is Ellipsis:   atlases = ('benson14', 'wang15')
      if pimms.is_str(atlases): atlases = tuple(re.split(r'([,;]|\s)+', atlases)[::2])
      def _atlas_to_atlver(atl):
          atl0 = atl
          if not pimms.is_vector(atl):
              if ':' in atl:
                  atl = atl.split(':')
                  if len(atl) != 2: raise ValueError('Cannot parse atlas spec: %s' % atl0)
              else: atl = [atl, None]
          if len(atl) != 2: raise ValueError('Improperly specified atlas: %s' % atl0)
          if pimms.is_str(atl[1]):
              if len(atl[1]) == 0: atl = (atl[0], None)
              else:
                  if atl[1][0] == 'v': atl[1] = atl[1][1:]
                  try: atl = (atl[0], tuple([int(x) for x in re.split(r'[-_.]+', atl[1])]))
                  except Exception:
                      raise ValueError('Could not parse atlas version string: %s' % atl[1])
          elif pimms.is_int(atl[1]):  atl = (atl[0], (atl[1],))
          elif pimms.is_real(atl[1]): atl = (atl[0], (int(atl[1]), int(10*(atl[1] - int(atl[1]))),))
          elif pimms.is_vector(atl[1], int): atl = (atl[0], tuple(atl[1]))
          elif atl[1] is not None:
              raise ValueError('atlas version must be a string (like "v1_5_1") or a list of ints')
          else: atl = tuple(atl)
          return atl + (atl0,)
      # Okay, let's find these versions of the atlases in the atlas_map...
      worklog('Preparing Atlases...')
      wl = worklog.indent()
      atl_props = AutoDict()
      avt = AutoDict()
      # keyfn is for sorting versions (newest version last)
      keyfn = lambda k:((np.inf,)     if k is None                 else
                        k + (np.inf,) if len(k) == 0 or k[-1] != 0 else 
                        k)
      for (atl,version,atl0) in [_atlas_to_atlver(atl) for atl in atlases]:
          if atl not in atlas_map: raise ValueError('Could not find an atlas named %s' % atl)
          atldat = atlas_map[atl]
          # if the version is None, we pick the highest of the available versions
          if version is None: v = sorted(atldat.keys(), key=keyfn)[-1]
          elif version in atldat: v = version
          else: raise ValueError('Could not find specific version %s of atlas %s' % (version,atl))
          # update the atlas-version-tag data
          wl('Atlas: %s, Version: %s' % (atl, v))
          avt[atl][v] = '' if v is None or ':' not in atl0 else ('.v' + '_'.join(map(str, v)))
          lmaps = atlas_map[atl][v]
          # convert these maps into interpolated properties...
          for (h,hmap) in six.iteritems(lmaps):
              hmap = pimms.lazy_map(
                  {m:curry(
                      lambda hmap,h,m: atlas_cortices[h].interpolate(
                          subject_cortices[h],
                          hmap[m]),
                      hmap, h, m)
                   for m in six.iterkeys(hmap)})
              lmaps = lmaps.set(h, hmap)
          # add the lmaps (the persistent/lazy maps for this atlas version) in the atlprops
          atl_props[atl][v] = lmaps
      # That's all; we can return atl_props once we persist it
      return {'atlas_properties':  pimms.persist(atl_props),
              'atlas_version_tags': pimms.persist(avt)}