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.

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