docs: def _run_node(self, node):
          '''
          calc_dict._run_node(node) calculates the results of the given calculation node in the
          calc_dict's calculation plan and caches the results in the calc_dict. This should only
          be called by calc_dict itself internally.
          '''
          #print IMap.indent, ('Node: %s' % node.name) #dbg
          #IMap.indent = '  ' + IMap.indent #dbg
          #
          # We need to pause here and handle caching, if needed.
          res = None
          if ('memoize' in self.afferents and self.afferents['memoize']) and node.memoize:
              memdat = self.plan._memoized_data
              try:
                  h = qhash({k:self.afferents[k] for k in self.plan.afferent_dependencies[node.name]})
                  ho = (node.name, h)
                  if ho in memdat:
                      # memoization success; no need to memoize the result after processing it
                      res = memdat[ho]
                      h = None
                      ho = None
                      #print(IMap.indent, 'retrieved') #dbg
                  else:
                      cpath = self.afferents['cache_directory'] \
                              if node.cache and 'cache_directory' in self.afferents else \
                              None
                      if cpath is not None:
                          ureg = self.afferents['unit_registry'] \
                                 if 'unit_registry' in self.afferents else \
                                 'pimms'
                          cpath = os.path.join(cpath, node.name, ('0' + str(-h)) if h < 0 else str(h))
                          try:
                              res = self._uncache(cpath, node, ureg)
                              cpath = None
                              #print(IMap.indent, 'loaded cache') #dbg
                          except: pass
              except:
                  # memoization failure, must run the node normally (don't memoize/cache)
                  h = None
                  ho = None
                  res = None
          else:
              h = None
              ho = None
          # ensure we have a result
          if res is None: res = node(self)
          # process the result:
          effs = reduce(lambda m,v: m.set(v[0],v[1]), six.iteritems(res), self.efferents)
          object.__setattr__(self, 'efferents', effs)
          # Handle the caching if needed:
          if h is not None:
              memdat[ho] = res
              #if cpath is None: print IMap.indent, 'hashed' #dbg
              if cpath is not None:
                  try:
                      self._cache(cpath, res)
                      #print IMap.indent, 'saved cache' #dbg
                  except: pass