Coverage for aixcalibuha/sensitivity_analysis/morris.py: 100%
25 statements
« prev ^ index » next coverage.py v7.4.1, created at 2024-01-27 10:48 +0000
« prev ^ index » next coverage.py v7.4.1, created at 2024-01-27 10:48 +0000
1"""
2Adds the MorrisAnalyzer to the available
3classes of sensitivity analysis.
4"""
5import numpy as np
6from SALib.sample import morris
7from SALib.analyze import morris as analyze_morris
8from aixcalibuha.sensitivity_analysis import SenAnalyzer
9from aixcalibuha import CalibrationClass
12class MorrisAnalyzer(SenAnalyzer):
13 """
14 Moris method from SALib https://salib.readthedocs.io/en/latest/api.html#method-of-morris
15 An elementary effects (One-At-A-Time) method which computes the sensitivity
16 measures 'mu', 'mu_star' and 'sigma' with a confidence interval for mu_star.
18 Additional arguments:
20 :keyword int num_levels:
21 Default num_samples, used for the morris-method
22 :keyword optimal_trajectories:
23 Used for the morris-method
24 :keyword bool local_optimization:
25 Default True, used for the morris-method
26 """
27 def __init__(self, sim_api, **kwargs):
28 super().__init__(
29 sim_api=sim_api,
30 **kwargs)
31 # Set additional kwargs
32 self.num_levels = kwargs.pop("num_levels", self.num_samples)
33 self.optimal_trajectories = kwargs.pop("optimal_trajectories", None)
34 self.local_optimization = kwargs.pop("local_optimization", True)
36 @property
37 def analysis_variables(self):
38 """The analysis variables of the sobol method"""
39 return ['mu_star', 'mu', 'sigma', 'mu_star_conf']
41 def analysis_function(self, x, y):
42 """
43 Use the SALib.analyze.morris method to analyze the simulation results.
45 :param np.array x:
46 the `X` parameter of the morris method (The NumPy matrix containing the model inputs)
47 :param np.array y:
48 The NumPy array containing the model outputs
49 :return:
50 returns the result of the SALib.analyze.sobol method (from the documentation:
51 a dictionary with cols `mu`, `mu_star`, `sigma`, and `mu_star_conf`, where each
52 entry is a list of size D (the number of parameters) containing the indices in the
53 same order as the parameter file.)
54 """
55 return analyze_morris.analyze(self.problem, x, y,
56 num_levels=self.num_levels)
58 def create_sampler_demand(self):
59 """
60 Function to create the sampler parameters for the morris method
61 """
62 return {'num_levels': self.num_levels,
63 'optimal_trajectories': self.optimal_trajectories,
64 'local_optimization': self.local_optimization}
66 def generate_samples(self):
67 """
68 Run the sampler specified for morris and return the results.
70 :return:
71 The list of samples generated as a NumPy array with one row per sample
72 and each row containing one value for each variable name in `problem['names']`.
73 :rtype: np.ndarray
74 """
75 return morris.sample(self.problem,
76 N=self.num_samples,
77 **self.create_sampler_demand())
79 def _get_res_dict(self, result: dict, cal_class: CalibrationClass, analysis_variable: str):
80 """
81 Convert the result object to a dict with the key
82 being the variable name and the value being the result
83 associated to self.analysis_variable.
84 """
85 if result is None:
86 names = cal_class.tuner_paras.get_names()
87 return dict(zip(names, np.zeros(len(names))))
88 return dict(zip(result['names'], result[analysis_variable]))