          return compiled_stats
  
  
  class Calculations():
      """ Class to pull raw data for given session(s) and perform calculations """
      def __init__(self, session, display="loss", loss_keys=["loss"], selections=["raw"],
                   avg_samples=500, smooth_amount=0.90, flatten_outliers=False, is_totals=False):
          logger.debug("Initializing %s: (session: %s, display: %s, loss_keys: %s, selections: %s, "
                       "avg_samples: %s, smooth_amount: %s, flatten_outliers: %s, is_totals: %s",
                       self.__class__.__name__, session, display, loss_keys, selections, avg_samples,
                       smooth_amount, flatten_outliers, is_totals)
  
          warnings.simplefilter("ignore", np.RankWarning)
  
          self.session = session
          self.display = display
 
</s> remove     def __init__(self, root, cli_opts, statusbar, session):
        logger.debug("Initializing %s: (root %s, cli_opts: %s, statusbar: %s, session: %s)",
                     self.__class__.__name__, root, cli_opts, statusbar, session)
 </s> add     def __init__(self, root, cli_opts, statusbar):
        logger.debug("Initializing %s: (root %s, cli_opts: %s, statusbar: %s)",
                     self.__class__.__name__, root, cli_opts, statusbar) </s> remove             hrs, mins, secs = convert_time(summary["elapsed"])
            summary["start"] = time.strftime("%x %X", time.localtime(summary["start"]))
            summary["end"] = time.strftime("%x %X", time.localtime(summary["end"]))
            summary["elapsed"] = "{}:{}:{}".format(hrs, mins, secs)
            summary["rate"] = "{0:.1f}".format(summary["rate"])
        return compiled_stats
 </s> add             hrs, mins, secs = self._convert_time(summary["elapsed"])
            stats = dict()
            for key in summary:
                if key not in ("start", "end", "elapsed", "rate"):
                    stats[key] = summary[key]
                    continue
                stats["start"] = time.strftime("%x %X", time.localtime(summary["start"]))
                stats["end"] = time.strftime("%x %X", time.localtime(summary["end"]))
                stats["elapsed"] = "{}:{}:{}".format(hrs, mins, secs)
                stats["rate"] = "{0:.1f}".format(summary["rate"])
            retval.append(stats)
        return retval

    @classmethod
    def _convert_time(cls, timestamp):
        """ Convert time stamp to total hours, minutes and seconds.

        Parameters
        ----------
        timestamp: float
            The Unix timestamp to be converted

        Returns
        -------
        tuple
            (`hours`, `minutes`, `seconds`) as ints
        """
        hrs = int(timestamp // 3600)
        if hrs < 10:
            hrs = "{0:02d}".format(hrs)
        mins = "{0:02d}".format((int(timestamp % 3600) // 60))
        secs = "{0:02d}".format((int(timestamp % 3600) % 60))
        return hrs, mins, secs </s> remove     session: :class:`lib.gui.stats.Session`
        The current training Session
 </s> add  </s> remove         self.session = session
        self.display = display
        self.loss_keys = loss_keys
        self.selections = selections
        self.is_totals = is_totals
        self.args = {"avg_samples": avg_samples,
                     "smooth_amount": smooth_amount,
                     "flatten_outliers": flatten_outliers}
        self.iterations = 0
        self.stats = None
 </s> add         self._session_id = session_id

        self._display = display
        self._loss_keys = loss_keys if isinstance(loss_keys, list) else [loss_keys]
        self._selections = selections if isinstance(selections, list) else [selections]
        self._is_totals = session_id is None
        self._args = dict(avg_samples=avg_samples,
                          smooth_amount=smooth_amount,
                          flatten_outliers=flatten_outliers)
        self._iterations = 0
        self._limit = 0
        self._start_iteration = 0
        self._stats = dict() </s> remove                  "statusbar: %s, session: %s)", root, cli_opts, statusbar, session)
    _CONFIG = Config(root, cli_opts, statusbar, session)
 </s> add                  "statusbar: %s)", root, cli_opts, statusbar)
    _CONFIG = Config(root, cli_opts, statusbar)
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
          return compiled_stats
  
  
  class Calculations():
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
    """ Class that performs calculations on the :class:`GlobalSession` raw data for the given
    session id.

    Parameters
    ----------
    session_id: int or ``None``
        The session id number for the selected session from the Analysis tab. Should be ``None``
        if all sessions are being calculated
    display: {"loss", "rate"}, optional
        Whether to display a graph for loss or training rate. Default: `"loss"`
    loss_keys: list, optional
        The list of loss keys to display on the graph. Default: `["loss"]`
    selections: list, optional
        The selected annotations to display. Default: `["raw"]`
    avg_samples: int, optional
        The number of samples to use for performing moving average calculation. Default: `500`.
    smooth_amount: float, optional
        The amount of smoothing to apply for performing smoothing calculation. Default: `0.9`.
    flatten_outliers: bool, optional
        ``True`` if values significantly away from the average should be excluded, otherwise
        ``False``. Default: ``False``
    """
    def __init__(self, session_id,
                 display="loss",
                 loss_keys="loss",
                 selections="raw",
                 avg_samples=500,
                 smooth_amount=0.90,
                 flatten_outliers=False):
        logger.debug("Initializing %s: (session_id: %s, display: %s, loss_keys: %s, "
                     "selections: %s, avg_samples: %s, smooth_amount: %s, flatten_outliers: %s)",
                     self.__class__.__name__, session_id, display, loss_keys, selections,
                     avg_samples, smooth_amount, flatten_outliers)
  
          warnings.simplefilter("ignore", np.RankWarning)
  
          self.session = session
          self.display = display
keep keep keep keep replace replace replace replace replace replace replace keep keep keep keep keep
 GUI - Stats optimization (#1067)

* Faster stat loading + caching

* Compress data in cache

* Optimize some calculations

* Vectorize smoothing

* stats.Calculations optimized

* Load latest training data from live iterator

* Add options to training graph 
lib/gui/stats.py