find the most important observation(s) by sequentially evaluating
        the importance of the observations in obslist_dict. The most important observations
        from each iteration is added to base_obslist and removed obslist_dict for the
        next iteration.  In this way, the added observation importance values include
        the conditional information from the last iteration.

        Parameters
        ----------
        forecast : str
            name of the forecast to use in the ranking process.  If
            more than one forecast has been listed, this argument is required
        niter : int
            number of sequential iterations
        obslist_dict dict:
            nested dictionary-list of  groups of observations
            that are to be treated as gained.  key values become
            row labels in result dataframe. If None, then test every observation
            individually
        base_obslist : list
            observation names to treat as the "existing" observations.
            The values of obslist_dict will be added to this list during testing.
            If None, then each list in the values of obslist_dict will be
            treated as an individual calibration dataset.
        reset_zero_weight : (boolean or float)
            a flag to reset observations with zero weight in either
            obslist_dict or base_obslist. If the value of reset_zero_weights
            can be cast to a float,then that value will be assigned to
            zero weight obs.  Otherwise, zero weight obs will be given a weight of 1.0

        Returns
        -------
        pandas.DataFrame : pandas.DataFrame
            DataFrame with columns of best obslist_dict key for each iteration.
            Columns of forecast variance percent reduction for this iteration,
            (percent reduction compared to initial base case)


        Example
        -------
        ``>>>import pyemu``

        ``>>>sc = pyemu.Schur(jco="pest.jcb")``

        ``>>>df = sc.next_most_added_importance_obs(forecast="fore1",``

        ``>>>      base_obslist=sc.pst.nnz_obs_names,reset_zero=True``

def next_most_important_added_obs(self,forecast=None,niter=3, obslist_dict=None,
                                      base_obslist=None,
                                      reset_zero_weight=False):
        """find the most important observation(s) by sequentially evaluating
        the importance of the observations in obslist_dict. The most important observations
        from each iteration is added to base_obslist and removed obslist_dict for the
        next iteration.  In this way, the added observation importance values include
        the conditional information from the last iteration.

        Parameters
        ----------
        forecast : str
            name of the forecast to use in the ranking process.  If
            more than one forecast has been listed, this argument is required
        niter : int
            number of sequential iterations
        obslist_dict dict:
            nested dictionary-list of  groups of observations
            that are to be treated as gained.  key values become
            row labels in result dataframe. If None, then test every observation
            individually
        base_obslist : list
            observation names to treat as the "existing" observations.
            The values of obslist_dict will be added to this list during testing.
            If None, then each list in the values of obslist_dict will be
            treated as an individual calibration dataset.
        reset_zero_weight : (boolean or float)
            a flag to reset observations with zero weight in either
            obslist_dict or base_obslist. If the value of reset_zero_weights
            can be cast to a float,then that value will be assigned to
            zero weight obs.  Otherwise, zero weight obs will be given a weight of 1.0

        Returns
        -------
        pandas.DataFrame : pandas.DataFrame
            DataFrame with columns of best obslist_dict key for each iteration.
            Columns of forecast variance percent reduction for this iteration,
            (percent reduction compared to initial base case)


        Example
        -------
        ``>>>import pyemu``

        ``>>>sc = pyemu.Schur(jco="pest.jcb")``

        ``>>>df = sc.next_most_added_importance_obs(forecast="fore1",``

        ``>>>      base_obslist=sc.pst.nnz_obs_names,reset_zero=True``
        """


        if forecast is None:
            assert self.forecasts.shape[1] == 1,"forecast arg list one and only one" +\
                                            " forecast"
            forecast = self.forecasts[0].col_names[0]
        #elif forecast not in self.prediction_arg:
        #    raise Exception("forecast {0} not found".format(forecast))

        else:
            forecast = forecast.lower()
            found = False
            for fore in self.forecasts.col_names:
                if fore == forecast:
                    found = True
                    break
            if not found:
                raise Exception("forecast {0} not found".format(forecast))




        if base_obslist:
            obs_being_used = list(base_obslist)
        else:
            obs_being_used = []

        best_case, best_results = [],[]
        for iiter in range(niter):
            self.log("next most important added obs iteration {0}".format(iiter+1))
            df = self.get_added_obs_importance(obslist_dict=obslist_dict,
                                                   base_obslist=obs_being_used,
                                                   reset_zero_weight=reset_zero_weight)

            if iiter == 0:
                init_base = df.loc["base",forecast].copy()
            fore_df = df.loc[:,forecast]
            fore_diff_df = fore_df - fore_df.loc["base"]
            fore_diff_df.sort_values(inplace=True)
            iter_best_name = fore_diff_df.index[0]
            iter_best_result = df.loc[iter_best_name,forecast]
            iter_base_result = df.loc["base",forecast]
            diff_percent_init = 100.0 * (init_base -
                                              iter_best_result) / init_base
            diff_percent_iter = 100.0 * (iter_base_result -
                                              iter_best_result) / iter_base_result
            self.log("next most important added obs iteration {0}".format(iiter+1))


            best_results.append([iter_best_name,iter_best_result,
                                 diff_percent_iter,diff_percent_init])
            best_case.append(iter_best_name)

            if iter_best_name.lower() == "base":
                break

            if obslist_dict is None:
                onames = [iter_best_name]
            else:
                onames = obslist_dict.pop(iter_best_name)
            if not isinstance(onames,list):
                onames = [onames]
            obs_being_used.extend(onames)
        columns = ["best_obs",forecast+"_variance",
                   "unc_reduce_iter_base","unc_reduce_initial_base"]
        return pd.DataFrame(best_results,index=best_case,columns=columns)