Source code for SALib.util.util_funcs
import pkgutil
import csv
from warnings import warn
import numpy as np
[docs]def avail_approaches(pkg):
"""Create list of available modules.
Parameters
----------
pkg : module
module to inspect
Returns
---------
method : list
A list of available submodules
"""
methods = [modname for importer, modname, ispkg in
pkgutil.walk_packages(path=pkg.__path__)
if modname not in
['common_args', 'directions', 'sobol_sequence']
and 'test' not in modname]
return methods
[docs]def read_param_file(filename, delimiter=None):
"""Unpacks a parameter file into a dictionary
Reads a parameter file of format::
Param1,0,1,Group1,dist1
Param2,0,1,Group2,dist2
Param3,0,1,Group3,dist3
(Group and Dist columns are optional)
Returns a dictionary containing:
- names - the names of the parameters
- bounds - a list of lists of lower and upper bounds
- num_vars - a scalar indicating the number of variables
(the length of names)
- groups - a list of group names (strings) for each variable
- dists - a list of distributions for the problem,
None if not specified or all uniform
Parameters
----------
filename : str
The path to the parameter file
delimiter : str, default=None
The delimiter used in the file to distinguish between columns
"""
names = []
bounds = []
groups = []
dists = []
num_vars = 0
fieldnames = ['name', 'lower_bound', 'upper_bound', 'group', 'dist']
with open(filename, 'r') as csvfile:
dialect = csv.Sniffer().sniff(csvfile.read(1024), delimiters=delimiter)
csvfile.seek(0)
reader = csv.DictReader(
csvfile, fieldnames=fieldnames, dialect=dialect)
for row in reader:
if row['name'].strip().startswith('#'):
pass
else:
num_vars += 1
names.append(row['name'])
bounds.append(
[float(row['lower_bound']), float(row['upper_bound'])])
# If the fourth column does not contain a group name, use
# the parameter name
if row['group'] is None:
groups.append(row['name'])
elif row['group'] == 'NA':
groups.append(row['name'])
else:
groups.append(row['group'])
# If the fifth column does not contain a distribution
# use uniform
if row['dist'] is None:
dists.append('unif')
else:
dists.append(row['dist'])
if groups == names:
groups = None
elif len(set(groups)) == 1:
raise ValueError("""Only one group defined, results will not be
meaningful""")
# setting dists to none if all are uniform
# because non-uniform scaling is not needed
if all([d == 'unif' for d in dists]):
dists = None
return {'names': names, 'bounds': bounds, 'num_vars': num_vars,
'groups': groups, 'dists': dists}
def _check_groups(problem):
"""Check if there is more than 1 group."""
groups = problem.get('groups')
if not groups:
return False
if len(set(groups)) == 1:
return False
return groups
def _check_bounds(bounds):
"""Check user supplied distribution bounds for validity.
Parameters
----------
problem : dict
The problem definition
Returns
-------
tuple : containing upper and lower bounds
"""
b = np.array(bounds)
lower_bounds = b[:, 0]
upper_bounds = b[:, 1]
if np.any(lower_bounds >= upper_bounds):
raise ValueError("Bounds are not legal")
return lower_bounds, upper_bounds