code: def read_history(source, iter=False):
      """read parameter history and cost history from the given source
  
      source is a monitor, logfile, support file, solver restart file, dataset, etc
      iter is a bool, where if True, `iter` is also returned
  
      Returns (iter, params, cost) if iter is True, else returns (params, cost), where
          - iter is a list of tuples of ints (iteration, id), where id may be None
          - params is input to cost; a list of lists of floats
          - cost is output of cost; a list of floats, or a list of tuples of floats
      """
      monitor = solver = data = arxiv = False
      from mystic.monitors import Monitor, Null
      from mystic.abstract_solver import AbstractSolver
      from mystic.math.legacydata import dataset
      from klepto.archives import archive, cache
      import io
  
      file = io.IOBase
      if isinstance(source, file):
          return read_history(source.name, iter)
      if isinstance(source, str):
          import re
  
          source = re.sub(
              r"\.py*.$", "", source
          )  # strip off .py* extension
      elif isinstance(source, Monitor):
          monitor = True
      elif isinstance(source, dataset):
          data = True
      elif isinstance(source, cache):
          source = source.__archive__
          arxiv = True
      elif isinstance(source, archive):
          arxiv = True
      elif isinstance(source, AbstractSolver):
          solver = True
      elif isinstance(
          source, Null
      ):  # XXX: or source.x, source.y or Error?
          return ([], [], []) if iter else ([], [])
      else:
          raise IOError("a history filename or instance is required")
      ids = None
      try:  # read standard logfile (or monitor)
          if monitor:
              if iter:
                  params, cost, ids = read_monitor(source, id=True)
                  if not len(ids):
                      ids = None
                  ids = _process_ids(ids, len(cost))
              else:
                  params, cost = read_monitor(source)
          elif data:
              params, cost = source.coords, source.values
              if iter:
                  ids = _process_ids(source.ids, len(cost))
          elif arxiv:  # NOTE: does not store ids
              params = list(list(k) for k in source.keys())
              cost = source.values()
              cost = cost if type(cost) is list else list(cost)
              if iter:
                  ids = _process_ids(None, len(cost))
          elif solver:  # NOTE: ids are single-valued, unless ensemble
              params, cost = (
                  source.solution_history,
                  source.energy_history,
              )
              if iter:
                  ids = _process_ids(source.id, len(cost))
          else:
              try:
                  from mystic.solvers import LoadSolver
  
                  return read_history(LoadSolver(source), iter)
              except:  # KeyError
                  ids, params, cost = logfile_reader(source, iter=True)
                  if iter:
                      ids = _process_ids(ids, len(cost))
                  # FIXME: doesn't work for multi-id logfile; select id?
          params, cost = raw_to_support(params, cost)
      except:
          return read_raw_file(
              source + ".py", iter
          )  # NOTE: assumes 'support' format
      return (ids, params, cost) if iter else (params, cost)
  
imports: from mystic.tools import list_or_tuple_or_ndarray
  from mystic.tools import isNull
  import sys
label_desc: Use image node_id 1 for calling a global function with example usage: read_history(source, iter) and returns: unknown, read_history, read_raw_file, read_history, unknown