docs: def show_tree_cache(self, label, current_node=None):
          '''
          Show tree and cache info with color represent _status
          Optionally accpet current_node arg to highlight the current node we are in
          '''
          import os
          import tempfile
          import subprocess
  
          assert DEBUG, "Please use dr tree visualization functions in debug mode"
  
          cache_path = os.path.abspath('profiles')
          def string_for(self, my_name):
  
              color_mapping = {'new' : 'grey', 'pending':'red', 'cached':'yellow', 'done': 'green'}
              if hasattr(self, 'label'):
                  my_name = self.label
              my_name = '%s (%s)' % (my_name, str(self.__class__.__name__))
              result = []
              if not hasattr(self, 'dterms'):
                  return result
              for dterm in self.dterms:
                  if hasattr(self, dterm):
                      dtval = getattr(self, dterm)
                      if hasattr(dtval, 'dterms') or hasattr(dtval, 'terms'):
                          child_label = getattr(dtval, 'label') if hasattr(dtval, 'label') else dterm
                          child_label = '%s (%s)' % (child_label, str(dtval.__class__.__name__))
                          src = 'aaa%d' % (id(self))
                          dst = 'aaa%d' % (id(dtval))
  
                          s = ''
                          color = color_mapping[dtval._status] if hasattr(dtval, '_status') else 'grey'
                          if dtval == current_node:
                              color = 'blue'
                          if isinstance(dtval, Concatenate) and len(dtval.dr_cached) > 0:
                              s = 'dr_cached\n'
                              for k, v in dtval.dr_cached.items():
                                  if v is not None:
                                      issparse = sp.issparse(v)
                                      size = v.size 
                                      if issparse:
                                          size = v.shape[0] * v.shape[1]
                                          nonzero = len(v.data)
                                      else:
                                          nonzero = np.count_nonzero(v)  
                                      s += '\nsparse: %s\nsize: %d\nnonzero: %d\n' % (issparse, size, nonzero)
                              # if dtval.called_dr_wrt:
                              # #   dtval.called_dr_wrt = False
                              #     color = 'brown3'
                              # else:
                              #     color = 'azure1'
                          elif len(dtval._cache['drs']) > 0:
                              s = '_cache\n'
                              
                              for k, v in dtval._cache['drs'].items():
                                  if v is not None:
                                      issparse = sp.issparse(v)
                                      size = v.size
                                      if issparse:
                                          size = v.shape[0] * v.shape[1]
                                          nonzero = len(v.data)
                                      else:
                                          nonzero = np.count_nonzero(v)     
  
                                      s += '\nsparse: %s\nsize: %d\nnonzero: %d\n' % (issparse, size, nonzero)
                                      if hasattr(dtval, '_cache_info'):
                                          s += '\ncache hit:%s\n' % dtval._cache_info[k]
                              # if hasattr(dtval,'called_dr_wrt') and dtval.called_dr_wrt:
                              # #   dtval.called_dr_wrt = False
                              #     color = 'brown3'
                              # else:
                              #     color = 'azure1'
                          result += ['%s -> %s;' % (src, dst)]
                          # Do not overwrite src
                          #result += ['%s [label="%s"];' % (src, my_name)]
                          result += ['%s [label="%s\n%s\n", color=%s, style=filled];' %
                                     (dst, child_label, s, color)]
                          result += string_for(getattr(self, dterm), dterm)
              return result
              
  
          dot_file_contents = 'digraph G {\n%s\n}' % '\n'.join(list(set(string_for(self, 'root'))))
          dot_file_name = os.path.join(cache_path, label)
          png_file_name = os.path.join(cache_path, label+'.png')
          with open(dot_file_name, 'w') as dot_file:
              with open(png_file_name, 'w') as png_file:
                  dot_file.write(dot_file_contents)
                  dot_file.flush()
  
                  png_file = tempfile.NamedTemporaryFile(suffix='.png', delete=False)
                  subprocess.call(['dot', '-Tpng', '-o', png_file.name, dot_file.name])
  
          import webbrowser
          webbrowser.open('file://' + png_file.name)
          
          self.loop_children_do(self.reset_flag)