示例#1
0
文件: stats.py 项目: cgrudz/DAPPER
    def replay(self, figlist="default", speed=np.inf, t1=0, t2=None, **kwargs):
        """Replay LivePlot with what's been stored in 'self'.

        - t1, t2: time window to plot.
        - 'figlist' and 'speed': See LivePlot's doc.

        .. note:: `store_u` (whether to store non-obs-time stats) must
        have been `True` to have smooth graphs as in the actual LivePlot.

        .. note:: Ensembles are generally not stored in the stats
        and so cannot be replayed.
        """
        # Time settings
        tseq = self.HMM.tseq
        if t2 is None:
            t2 = t1 + tseq.Tplot

        # Ens does not get stored in stats, so we cannot replay that.
        # If the LPs are initialized with P0!=None, then they will avoid ens plotting.
        # TODO 4: This system for switching from Ens to stats must be replaced.
        #       It breaks down when M is very large.
        try:
            P0 = np.full_like(self.HMM.X0.C.full, np.nan)
        except AttributeError:  # e.g. if X0 is defined via sampling func
            P0 = np.eye(self.HMM.Nx)

        LP = liveplotting.LivePlot(self,
                                   figlist,
                                   P=P0,
                                   speed=speed,
                                   Tplot=t2 - t1,
                                   replay=True,
                                   **kwargs)
        plt.pause(.01)  # required when speed=inf

        # Remember: must use progbar to unblock read1.
        # Let's also make a proper description.
        desc = self.xp.da_method + " (replay)"

        # Play through assimilation cycles
        for k, ko, t, _dt in progbar(tseq.ticker, desc):
            if t1 <= t <= t2:
                if ko is not None:
                    LP.update((k, ko, 'f'), None, None)
                    LP.update((k, ko, 'a'), None, None)
                LP.update((k, ko, 'u'), None, None)

        # Pause required when speed=inf.
        # On Mac, it was also necessary to do it for each fig.
        if LP.any_figs:
            for _name, updater in LP.figures.items():
                if plt.fignum_exists(_name) and getattr(
                        updater, 'is_active', 1):
                    plt.figure(_name)
                    plt.pause(0.01)
示例#2
0
    def assess(self,
               k,
               kObs=None,
               faus=None,
               E=None,
               w=None,
               mu=None,
               Cov=None):
        """Common interface for both assess_ens and _ext.

        The _ens assessment function gets called if E is not None,
        and _ext if mu is not None.

        faus: One or more of ['f',' a', 'u'], indicating
              that the result should be stored in (respectively)
              the forecast/analysis/universal attribute.
              Default: 'u' if kObs is None else 'au' ('a' and 'u').
        """
        # Initial consistency checks.
        if k == 0:
            if kObs is not None:
                raise KeyError("DAPPER convention: no obs at t=0."
                               " Helps avoid bugs.")
            if faus is None:
                faus = 'u'
            if self._is_ens == True:
                if E is None:
                    raise TypeError("Expected ensemble input but E is None")
                if mu is not None:
                    raise TypeError(
                        "Expected ensemble input but mu/Cov is not None")
            else:
                if E is not None:
                    raise TypeError("Expected mu/Cov input but E is not None")
                if mu is None:
                    raise TypeError("Expected mu/Cov input but mu is None")

        # Default. Don't add more defaults. It just gets confusing.
        if faus is None:
            faus = 'u' if kObs is None else 'au'

        # Select assessment call and arguments
        if self._is_ens:
            _assess = self.assess_ens
            _prms = {'E': E, 'w': w}
        else:
            _assess = self.assess_ext
            _prms = {'mu': mu, 'P': Cov}

        for sub in faus:

            # Skip assessment if ('u' and stats not stored or plotted)
            if k != 0 and kObs == None:
                if not (self.store_u or self.LP_instance.any_figs):
                    continue

            # Silence repeat warnings caused by zero variance
            with np.errstate(divide='call', invalid='call'):
                np.seterrcall(warn_zero_variance)

                # Assess
                stats_now = Avrgs()
                _assess(stats_now, self.xx[k], **_prms)
                self.derivative_stats(stats_now)
                self.summarize_marginals(stats_now)

            # Write current stats to series
            for name, val in stats_now.items():
                stat = struct_tools.deep_getattr(self, name)
                isFaust = isinstance(stat, series.FAUSt)
                stat[(k, kObs, sub) if isFaust else kObs] = val

            # LivePlot -- Both init and update must come after the assessment.
            try:
                self.LP_instance.update((k, kObs, sub), E, Cov)
            except AttributeError:
                self.LP_instance = liveplotting.LivePlot(
                    self, self.liveplots, (k, kObs, sub), E, Cov)
示例#3
0
文件: stats.py 项目: cgrudz/DAPPER
    def assess(self, k, ko=None, faus=None, E=None, w=None, mu=None, Cov=None):
        """Common interface for both `Stats.assess_ens` and `Stats.assess_ext`.

        The `_ens` assessment function gets called if `E is not None`,
        and `_ext` if `mu is not None`.

        faus: One or more of `['f',' a', 'u', 's']`, indicating
              that the result should be stored in (respectively)
              the forecast/analysis/universal attribute.
              Default: `'u' if ko is None else 'au' ('a' and 'u')`.
        """
        # Initial consistency checks.
        if k == 0:
            if ko is not None:
                raise KeyError(
                    "DAPPER convention: no obs at t=0. Helps avoid bugs.")
            if self._is_ens == True:
                if E is None:
                    raise TypeError("Expected ensemble input but E is None")
                if mu is not None:
                    raise TypeError(
                        "Expected ensemble input but mu/Cov is not None")
            else:
                if E is not None:
                    raise TypeError("Expected mu/Cov input but E is not None")
                if mu is None:
                    raise TypeError("Expected mu/Cov input but mu is None")

        # Default. Don't add more defaults. It just gets confusing.
        if faus is None:
            faus = 'u' if ko is None else 'au'

        # TODO 4: for faus="au" (e.g.) we don't need to re-**compute** stats,
        #         merely re-write them?
        for sub in faus:

            # Skip assessment if ('u' and stats not stored or plotted)
            if k != 0 and ko == None:
                if not (self.store_u or self.LP_instance.any_figs):
                    continue

            # Silence repeat warnings caused by zero variance
            with np.errstate(divide='call', invalid='call'):
                np.seterrcall(warn_zero_variance)

                # Assess
                stats_now = Avrgs()
                if self._is_ens:
                    self.assess_ens(stats_now, self.xx[k], E, w)
                else:
                    self.assess_ext(stats_now, self.xx[k], mu, Cov)
                self.derivative_stats(stats_now)
                self.summarize_marginals(stats_now)

            self.write(stats_now, k, ko, sub)

            # LivePlot -- Both init and update must come after the assessment.
            try:
                self.LP_instance.update((k, ko, sub), E, Cov)
            except AttributeError:
                self.LP_instance = liveplotting.LivePlot(
                    self, self.liveplots, (k, ko, sub), E, Cov)