Ejemplo n.º 1
0
 def plot_histogram_Y_all(
     self,
     default_Y,
     bin_min=None,
     bin_max=None,
     num_bins=60,
     fig_format=(),
 ):
     fig = plot_histogram_Y(
         Y=self.Y_all,
         default_Y=default_Y,
         bin_min=bin_min,
         bin_max=bin_max,
         num_bins=num_bins,
         color=COLORS_DICT["all"],
         xaxes_title_text=self.model_output_name,
         trace_name="All parameters vary",
     )
     if "pdf" in fig_format:
         fig.write_image(
             self.create_figure_Y_all_histogram_filepath("pdf").as_posix()
         )
     if "html" in fig_format:
         fig.write_html(
             self.create_figure_Y_all_histogram_filepath("html").as_posix()
         )
     if "pickle" in fig_format:
         filepath = self.create_figure_Y_all_histogram_filepath("pickle").as_posix()
         write_pickle(fig, filepath)
     return fig
Ejemplo n.º 2
0
 def plot_convergence(
     self,
     sa_convergence_dict,
     parameter_inds=None,
     fig_format=[],
 ):
     """Plots sensitivity indices for model inputs ``parameter_inds`` for all convergence steps."""
     if parameter_inds is None:
         parameter_inds = np.random.randint(
             0, self.num_params, max(10, self.num_params // 10)
         )
     # Assign color to each parameter
     colors = {}
     for parameter in parameter_inds:
         colors[parameter] = "rgb({0},{1},{2})".format(
             np.random.randint(0, 256),
             np.random.randint(0, 256),
             np.random.randint(0, 256),
         )
     # Plot
     x = sa_convergence_dict["iterations"]
     sa_convergence_dict.pop("iterations")
     fig = make_subplots(
         rows=len(sa_convergence_dict),
         cols=1,
         subplot_titles=list(sa_convergence_dict.keys()),
     )
     for parameter in parameter_inds:
         row = 1
         for sa_index_name, sa_array in sa_convergence_dict.items():
             showlegend = False
             if row == 1:
                 showlegend = True
             fig.add_trace(
                 go.Scatter(
                     x=x,
                     y=sa_array[:, parameter],
                     mode="lines+markers",
                     showlegend=showlegend,
                     marker=dict(color=colors[parameter]),
                     name="Parameter " + str(parameter),
                     legendgroup=str(parameter),
                 ),
                 row=row,
                 col=1,
             )
             row += 1
     fig.show()
     if "pdf" in fig_format:
         fig.write_image(self.create_figure_convergence_filepath("pdf").as_posix())
     if "html" in fig_format:
         fig.write_html(self.create_figure_convergence_filepath("html").as_posix())
     if "pickle" in fig_format:
         filepath = self.create_figure_convergence_filepath("pickle").as_posix()
         write_pickle(fig, filepath)
     return fig
Ejemplo n.º 3
0
def get_cf_params_local_sa(lca, write_dir, const_factors=(0.1, 10)):
    """Local SA for characterization factors."""

    path_lsa_cf = Path(write_dir) / "LSA_scores_cf.pickle"

    if not path_lsa_cf.exists():

        bio_x_tech_x_demand = lca.biosphere_matrix * spsolve(
            lca.technosphere_matrix, lca.demand_array
        )

        path_lsa_include_inds_cf = Path(write_dir) / "include_inds_cf.pickle"
        inds_uncertain = np.where(lca.cf_params["uncertainty_type"] > 1)[0]

        if not path_lsa_include_inds_cf.exists():
            uncertain_cf_params_temp = lca.cf_params[inds_uncertain]
            # Exclude characterization factors that are not affected by given demand
            exclude_flows = np.where(bio_x_tech_x_demand == 0)[0]
            exclude_inds = np.array([])
            for flow in exclude_flows:
                exclude_inds = np.hstack(
                    [exclude_inds, np.where(uncertain_cf_params_temp["row"] == flow)[0]]
                )
            include_inds_temp = np.setdiff1d(
                np.arange(len(uncertain_cf_params_temp)), exclude_inds
            )
            write_pickle(include_inds_temp, path_lsa_include_inds_cf)
        else:
            include_inds_temp = read_pickle(path_lsa_include_inds_cf)

        include_inds = inds_uncertain[include_inds_temp]
        uncertain_cf_params = lca.cf_params[include_inds]
        flows = uncertain_cf_params["row"]
        bio_reverse_dict = lca.reverse_dict()[WHERE_BIO_REVERSE_DICT]

        lsa_scores_cf = {}
        for i, param in enumerate(uncertain_cf_params):
            flow = flows[i]
            input_ = bio_reverse_dict[flow]
            scores = []
            for const_factor in const_factors:
                characterization_vector = sum(deepcopy(lca.characterization_matrix))
                characterization_vector[0, flow] *= const_factor
                score = characterization_vector * bio_x_tech_x_demand
                scores.append(score[0])
            lsa_scores_cf[include_inds[i]] = {
                "input": input_,
                "scores": np.array(scores),
            }

        write_pickle(lsa_scores_cf, path_lsa_cf)

    else:
        lsa_scores_cf = read_pickle(path_lsa_cf)

    return lsa_scores_cf
Ejemplo n.º 4
0
 def get_graph_traversal_params(self, cutoff=1e-16, max_calc=1e16):
     fp_graph_traversal = self.write_dir / self.create_graph_traversal_filename(
         cutoff, max_calc
     )
     if fp_graph_traversal.exists():
         res = read_pickle(fp_graph_traversal)
     else:
         res = bc.GraphTraversal().calculate(
             self.lca, cutoff=cutoff, max_calc=max_calc
         )
         write_pickle(res, fp_graph_traversal)
     return res
Ejemplo n.º 5
0
 def run_convergence(self, parameter_inds=None, fig_format=()):
     """Calls function that computes converging indices, saves them and plots for model inputs ``parameter_inds``."""
     t0 = time.time()
     filepath_convergence_dict = self.create_convergence_dict_filepath()
     if filepath_convergence_dict.exists():
         print("{} already exists".format(filepath_convergence_dict.name))
         sa_convergence_dict = read_pickle(filepath_convergence_dict)
     else:
         sa_convergence_dict = self.generate_converging_gsa_indices()
         write_pickle(sa_convergence_dict, filepath_convergence_dict)
     t1 = time.time()
     print("Total convergence time -> {:8.3f} s".format(t1 - t0))
     fig = self.plot_convergence(sa_convergence_dict, parameter_inds, fig_format)
     return fig
def write_X_chunks(gsa, n_workers):
    X = gsa.generate_unitcube_samples_based_on_method(gsa.iterations)
    print(X.shape, gsa.dirpath_Y)
    iter_chunk = gsa.iterations // n_workers
    for i in range(n_workers):
        start = iter_chunk * i
        end = iter_chunk * (i + 1)
        if i == n_workers - 1:
            end = max(iter_chunk * (i + 1), gsa.iterations)
        print(i, start, end)
        X_chunk = X[start:end, :]
        filepath_X_chunk = gsa.dirpath_Y / "X.unitcube.{}.{}.pickle".format(
            i, n_workers)
        write_pickle(X_chunk, filepath_X_chunk)
Ejemplo n.º 7
0
 def plot_histogram_Y_all_Y_inf(
     self,
     influential_Y,
     num_influential,
     tag=None,
     fig_format=(),
     bin_min=None,
     bin_max=None,
     num_bins=60,
     showtitle=True,
 ):
     fig = plot_histogram_Y1_Y2(
         self.Y_all,
         influential_Y,
         default_Y=None,
         bin_min=bin_min,
         bin_max=bin_max,
         num_bins=num_bins,
         trace_name1="All parameters vary",
         trace_name2="Only influential vary",
         color1="#636EFA",
         color2="#EF553B",
         color_default_Y="red",
         opacity=0.65,
         xaxes_title_text=self.model_output_name,
         showtitle=showtitle,
     )
     if "pdf" in fig_format:
         fig.write_image(
             self.create_figure_Y_all_Y_inf_histogram_filepath(
                 num_influential, tag, "pdf"
             ).as_posix()
         )
     if "html" in fig_format:
         fig.write_html(
             self.create_figure_Y_all_Y_inf_histogram_filepath(
                 num_influential, tag, "html"
             ).as_posix()
         )
     if "pickle" in fig_format:
         filepath = self.create_figure_Y_all_Y_inf_histogram_filepath(
             num_influential, tag, "pickle"
         ).as_posix()
         write_pickle(fig, filepath)
     return fig
Ejemplo n.º 8
0
def get_tech_params_local_sa(
    where_tech_lsa, lca, write_dir, const_factors=(0.1, 10), tag=None
):
    """Local SA for technosphere exchanges."""

    path_lsa_tech = Path(write_dir) / "LSA_scores_tech_{}.pickle".format(tag)

    if not path_lsa_tech.exists():
        # 1. lca related
        d = lca.demand_array
        B = lca.biosphere_matrix
        C = sum(lca.characterization_matrix)
        reverse_dict = lca.reverse_dict()[0]
        # 2. Find zero indices using Local SA
        where_tech_lsa.sort()
        num_params = len(where_tech_lsa)
        tech_params_lsa = lca.tech_params[where_tech_lsa]
        rows = tech_params_lsa["row"]
        cols = tech_params_lsa["col"]
        # 3. Constant factor
        const_factor = np.tile(const_factors, (num_params, 1))
        N = const_factor.shape[1]
        # 4. Preparation for saving of the results
        lsa_scores_tech = {}
        # 5. Run LSA
        for i, where in enumerate(where_tech_lsa):
            scores = np.empty(N)
            scores[:] = np.nan
            for j in range(N):
                A = deepcopy(lca.technosphere_matrix)
                A[rows[i], cols[i]] *= const_factor[i, j]
                scores[j] = C * B * spsolve(A, d)
                del A
            lsa_scores_tech[int(where)] = dict(
                input=reverse_dict[rows[i]],
                output=reverse_dict[cols[i]],
                scores=deepcopy(scores),
            )
        # 6. Save results
        write_pickle(lsa_scores_tech, path_lsa_tech)
    else:
        lsa_scores_tech = read_pickle(path_lsa_tech)

    return lsa_scores_tech
def compute_scores_per_worker(option, num_params, iterations, i_worker,
                              n_workers, setup_lca_model, path_base):
    if option == "corr":
        gsa = setup_corr(num_params, iterations, setup_lca_model, path_base)
    elif option == "salt":
        gsa = setup_salt(num_params, iterations, setup_lca_model, path_base)
    elif option == "delt":
        gsa = setup_delt(num_params, iterations, setup_lca_model, path_base)
    elif option == "xgbo":
        gsa = setup_xgbo(num_params, iterations, setup_lca_model, path_base)
    gsa.dirpath_Y.mkdir(parents=True, exist_ok=True)
    filepath_X_chunk = gsa.dirpath_Y / "X.unitcube.{}.{}.pickle".format(
        i_worker, n_workers)
    X_chunk_unitcube = read_pickle(filepath_X_chunk)
    X_chunk_rescaled = gsa.model.rescale(X_chunk_unitcube)
    del X_chunk_unitcube
    scores = gsa.model(X_chunk_rescaled)
    Y_filename = "{}.{}.pickle".format(i_worker, n_workers)
    filepath = gsa.dirpath_Y / Y_filename
    write_pickle(scores, filepath)
    return scores
Ejemplo n.º 10
0
 def plot_correlation_Y_all_Y_inf(
     self,
     influential_Y,
     num_influential,
     tag=None,
     fig_format=(),
     showtitle=True,
 ):
     fig = plot_correlation_Y1_Y2(
         Y1=self.Y_all,
         Y2=influential_Y,
         start=0,
         end=80,
         trace_name1="All parameters vary",
         trace_name2="Only influential vary",
         yaxes1_title_text=self.model_output_name,
         xaxes2_title_text=self.model_output_name,
         yaxes2_title_text=self.model_output_name,
         showtitle=showtitle,
     )
     if "pdf" in fig_format:
         fig.write_image(
             self.create_figure_Y_all_Y_inf_correlation_filepath(
                 num_influential, tag, "pdf"
             ).as_posix()
         )
     if "html" in fig_format:
         fig.write_html(
             self.create_figure_Y_all_Y_inf_correlation_filepath(
                 num_influential, tag, "html"
             ).as_posix()
         )
     if "pickle" in fig_format:
         filepath = self.create_figure_Y_all_Y_inf_correlation_filepath(
             num_influential, tag, "pickle"
         ).as_posix()
         write_pickle(fig, filepath)
     return fig
Ejemplo n.º 11
0
    def get_bootstrap_rankings_2(
        self, bootstrap_data, sa_mean_results, tag, num_ranks=10, rho_choice="spearmanr"
    ):
        """Get clustered rankings from bootstrap sensitivity indices.

        Parameters
        ----------
        bootstrap_data : dict
            Dictionary where keys are sensitivity methods names and values are arrays with sensitivity indices from
            bootstrapping in rows for each model input in columns.
        sa_mean_results : dict
            Dictionary where keys are sensitivity methods names and values are mean results for each model input
            over all bootstrap samples.
        tag : str
            Tag to save clustered rankings.
        num_ranks : int
            Number of clusters.

        Returns
        -------
        bootstrap_rankings : dict
            Dictionary where keys are sensitivity methods names and values are clustered ranks for all model inputs.

        """
        bootstrap_rankings = {}
        for sa_name in self.sa_names:
            num_bootstrap = bootstrap_data[sa_name][0].shape[0]
            filepath_bootstrap_rankings = self.create_bootstrap_rankings_filepath(
                num_ranks,
                "{}_v2".format(tag),
                sa_name,
                num_bootstrap,
            )
            if filepath_bootstrap_rankings.exists():
                bootstrap_rankings_arr = read_pickle(filepath_bootstrap_rankings)
            else:
                num_combinations = num_bootstrap * (num_bootstrap - 1) // 2
                bootstrap_rankings_arr = np.zeros((0, num_combinations))
                bootstrap_rankings_arr[:] = np.nan
                # TODO  change smth  here
                if sa_name == "total_gain":
                    means = self.bootstrap_data[sa_name][-1][0, :]
                else:
                    means = sa_mean_results[sa_name][-1, :]
                breaks = jenkspy.jenks_breaks(means, nb_class=num_ranks)
                # mean_ranking = self.get_one_clustered_ranking(means, num_ranks, breaks)
                # mean_ranking = mean_ranking.astype(int)
                for i in range(len(self.iterations[sa_name])):
                    bootstrap_data_sa = bootstrap_data[sa_name][i]
                    rankings = np.zeros((0, self.num_params))
                    for data in bootstrap_data_sa:
                        rankings = np.vstack(
                            [
                                rankings,
                                self.get_one_clustered_ranking(data, num_ranks, breaks),
                            ]
                        )
                    rankings = rankings.astype(int)
                    rho_arr = np.zeros(num_combinations)
                    rho_arr[:] = np.nan
                    k = 0
                    for i, r1 in enumerate(rankings[:-1]):
                        rho, _ = compute_rho_choice(
                            rankings[i + 1 :, :], r1, rho_choice=rho_choice
                        )
                        rho_arr[k : k + num_bootstrap - i - 1] = rho
                        k += num_bootstrap - i - 1
                    bootstrap_rankings_arr = np.vstack(
                        [bootstrap_rankings_arr, rho_arr]
                    )
                write_pickle(bootstrap_rankings_arr, filepath_bootstrap_rankings)
            bootstrap_rankings[sa_name] = bootstrap_rankings_arr
        return bootstrap_rankings
Ejemplo n.º 12
0
    lca.lcia()

    ei_tech_group = [
        g for g in lca.technosphere_mm.groups
        if "tech" in g.label and "ecoinvent" in g.label
    ]
    assert len(ei_tech_group) == 1
    ei_tech_group = ei_tech_group[0]
    tech_params = ei_tech_group.package.data[2]

    cutoff = 0.01
    max_calc = 1e3
    sct_tech_params_filename = "tech_params_cutoff{}_maxcalc{}.pickle".format(
        cutoff, int(max_calc))
    sct_tech_params_filepath = write_dir_sct / sct_tech_params_filename
    if not sct_tech_params_filepath.exists():
        tech_params_sct = filter_uncertain_technosphere_exchanges(lca,
                                                                  cutoff=1e-6)
        write_pickle(tech_params_sct, sct_tech_params_filepath)
    else:
        tech_params_sct = read_pickle(sct_tech_params_filepath)

    # Local SA
    model = LCAModel(
        demand,
        uncertain_method,
        write_dir,
    )

    print()
 # -> salib
 filename = "saltelli.sampling.salib.k{}.kstep{}.N{}.pickle".format(
     input_last, input_step, iterations_const)
 filepath = path_base / filename
 if filepath.exists():
     saltelli_sampling_salib_inputs = read_pickle(filepath)
 else:
     saltelli_sampling_salib_inputs = {}
     for ind, k in enumerate(inputs):
         problem = {"num_vars": k, "bounds": [[0, 1] * k]}
         t1 = time.time()
         x = salib_saltelli_sample(problem, saltelli_lcm // (ind + 1),
                                   calc_second_order, seed, skip_values)
         t2 = time.time()
         saltelli_sampling_salib_inputs[k] = t2 - t1
     write_pickle(saltelli_sampling_salib_inputs, filepath)
 # -> gsa_framework
 filename = "saltelli.sampling.gsafr.k{}.kstep{}.N{}.pickle".format(
     input_last, input_step, iterations_const)
 filepath = path_base / filename
 if filepath.exists():
     saltelli_sampling_gsafr_inputs = read_pickle(filepath)
 else:
     saltelli_sampling_gsafr_inputs = {}
     for ind, k in enumerate(inputs):
         saltelli_iterations = (k + 2) * saltelli_lcm // (ind + 1)
         t1 = time.time()
         x = saltelli_samples(saltelli_iterations, k, skip_values)
         t2 = time.time()
         saltelli_sampling_gsafr_inputs[k] = t2 - t1
     write_pickle(saltelli_sampling_gsafr_inputs, filepath)
Ejemplo n.º 14
0
def get_bio_params_local_sa(lca, write_dir, const_factors=(0.1, 10)):
    """Local SA for biosphere parameters."""

    path_lsa_bio = Path(write_dir) / "LSA_scores_bio.pickle"

    if not path_lsa_bio.exists():
        tech_x_demand = spsolve(lca.technosphere_matrix, lca.demand_array)
        characterization_vector = sum(lca.characterization_matrix)

        path_include_inds_bio = Path(write_dir) / "include_inds_bio.pickle"
        inds_uncertain = np.where(lca.bio_params["uncertainty_type"] > 1)[0]

        if not path_include_inds_bio.exists():
            uncertain_bio_params_temp = lca.bio_params[inds_uncertain]
            # Exclude bio exchanges that are not selected with the demand vector
            exclude_cols = np.where(tech_x_demand == 0)[0]
            exclude_inds = np.array([])
            for col in exclude_cols:
                exclude_inds = np.hstack(
                    [exclude_inds, np.where(uncertain_bio_params_temp["col"] == col)[0]]
                )
            # Exclude bio exchanges that are not included in the given lcia method
            exclude_rows = np.where(characterization_vector.toarray()[0] == 0)[0]
            for row in exclude_rows:
                exclude_inds = np.hstack(
                    [exclude_inds, np.where(uncertain_bio_params_temp["row"] == row)[0]]
                )
            print(
                "Excluding {}/{} biosphere exchanges".format(
                    len(exclude_inds), len(uncertain_bio_params_temp)
                )
            )
            exclude_inds = np.sort(exclude_inds)
            include_inds_temp = np.setdiff1d(
                np.arange(len(uncertain_bio_params_temp)), exclude_inds
            )
            write_pickle(include_inds_temp, path_include_inds_bio)
        else:
            include_inds_temp = read_pickle(path_include_inds_bio)

        include_inds = inds_uncertain[include_inds_temp]
        uncertain_bio_params = lca.bio_params[include_inds]
        nbio = len(uncertain_bio_params)
        rows = uncertain_bio_params["row"]
        cols = uncertain_bio_params["col"]
        bio_reverse_dict = lca.reverse_dict()[2]
        tech_reverse_dict = lca.reverse_dict()[0]

        lsa_scores_bio = {}
        for i, param in enumerate(uncertain_bio_params):
            if i % 1000 == 0:
                print("{}/{}".format(i, nbio))
            row, col = rows[i], cols[i]
            input_ = bio_reverse_dict[row]
            output_ = tech_reverse_dict[col]
            scores = []
            for const_factor in const_factors:
                biosphere_matrix = deepcopy(lca.biosphere_matrix)
                biosphere_matrix[row, col] *= const_factor
                score = characterization_vector * (biosphere_matrix * tech_x_demand)
                scores.append(score[0])
            lsa_scores_bio[include_inds[i]] = {
                "input": input_,
                "output": output_,
                "scores": np.array(scores),
            }
        write_pickle(lsa_scores_bio, path_lsa_bio)
    else:
        lsa_scores_bio = read_pickle(path_lsa_bio)

    return lsa_scores_bio