code: def forecast(self,parensemble=None):
          
          if parensemble is None:
              parensemble = self.parensemble
          self.logger.log("evaluating ensemble")
          failed_runs, obsensemble = self._calc_obs(parensemble)
  
  
          if failed_runs is not None:
              self.logger.warn("dropping failed realizations")
              parensemble.loc[failed_runs, :] = np.NaN
              parensemble = parensemble.dropna()
              obsensemble.loc[failed_runs, :] = np.NaN
              obsensemble = obsensemble.dropna()
          self.logger.log("evaluating ensemble")
  
          return obsensemble
docs: for the enkf formulation, this simply moves the ensemble forward by running the model
          once for each realization