Skip to content

Commit

Permalink
Merge pull request #34 from 1313e/dev
Browse files Browse the repository at this point in the history
Mark release of v1.2.2.
  • Loading branch information
1313e authored Dec 11, 2019
2 parents 531ecc7 + 2f7c399 commit 7ae4bad
Show file tree
Hide file tree
Showing 22 changed files with 486 additions and 147 deletions.
4 changes: 2 additions & 2 deletions docs/source/user/hdf5.inc
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ HDF5-files can be viewed freely by the user using the `HDFView`_ application mad
----

The general file contains:
- Attributes (9/10): Describe the general non-changeable properties of the emulator, which include:
- Attributes (11/12): Describe the general non-changeable properties of the emulator, which include:

- Emulator type and method;
- Gaussian parameters;
- Name of used :class:`~prism.modellink.ModelLink` subclass;
- Used *PRISM* version;
- Polynomial order;
- Regression parameters;
- Bools for using mock data or regression covariance;
- Mock data parameters if mock data was used.

Expand Down
9 changes: 9 additions & 0 deletions docs/source/user/parameters.inc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ Below are descriptions of all the parameters that can be provided to *PRISM* in
This number is multiplied by the difference between the upper and lower value boundaries of the model parameters to obtain the Gaussian correlation length for every model parameter.
This value must be positive, normalized and either a scalar or a list of :attr:`~prism.modellink.ModelLink.n_par` scalars (where the values correspond to the sorted list of model parameters).

:attr:`~prism.emulator.Emulator.f_infl` (Default: 0.2)
.. versionadded:: 1.2.2

The residual variance inflation factor.
The variance values for all known samples in an emulator iteration are inflated by this number multiplied by :attr:`~prism.emulator.Emulator.rsdl_var`.
This can be used to adjust for the underestimation of the emulator variance.
Setting this to zero causes no variance inflation to be performed.
This value must be non-negative.

:attr:`~prism.Pipeline.impl_cut` (Default: [0.0, 4.0, 3.8, 3.5])
A list of implausibility cut-off values that specifies the maximum implausibility values a parameter set is allowed to have to be considered 'plausible'.
A zero can be used as a filler value, either taking on the preceding value or acting as a wildcard if the preceding value is a wildcard or non-existent.
Expand Down
2 changes: 1 addition & 1 deletion prism/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

# %% VERSIONS
# Default/Latest/Current version
__version__ = '1.2.1'
__version__ = '1.2.2'

# Compatibility versions
compat_version = ['1.0.0rc12']
10 changes: 5 additions & 5 deletions prism/_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@

# Description of proj_par
proj_par_doc =\
"""proj_par : 1D array_like of {{int, str}} or None{0}{1}
"""proj_par : 1D array_like of {{int; str}} or None{0}{1}
For which model parameters to construct the projection figures.
If 1D array_like, construct projection figures for all combinations
of provided model parameters that are active, with a string
Expand Down Expand Up @@ -424,18 +424,18 @@ class that was created for drawing *{0}*.
--------------
keyword : {1}
String specifying the type of data that needs to be saved.
data : {{int, float, str, array_like}} or dict
data : {{int; float; str; array_like}} or dict
The actual data that needs to be saved at data keyword `keyword`.
If dict, save every item individually.
Generates
---------
The specified data is saved to the HDF5-file."""
save_data_doc_p = save_data_doc.format(
"", "{'impl_par', 'impl_sam', 'n_eval_sam'}")
"", "{'impl_par'; 'impl_sam'; 'n_eval_sam'}")
save_data_doc_e = save_data_doc.format(
std_emul_i_doc+"\n\t"+lemul_s_doc+"\n\t", "{'active_par', "
"'active_par_data', 'cov_mat', 'exp_dot_term', 'mod_real_set', "
std_emul_i_doc+"\n\t"+lemul_s_doc+"\n\t", "{'active_par'; "
"'active_par_data'; 'cov_mat'; 'exp_dot_term'; 'mod_real_set'; "
"'regression'}")
save_data_doc_pr = save_data_doc.format(std_emul_i_doc+"\n\t",
"{'nD_proj_hcube'}")
4 changes: 2 additions & 2 deletions prism/_gui/widgets/overview.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def show_unavailable_context_menu(self):
"""

# If there is currently at least one item selected, show context menu
if len(self.proj_list_u.selectedItems()):
if self.proj_list_u.selectedItems():
self.context_menu_u.popup(QG.QCursor.pos())

# This function shows a list of projection figures in the viewing area
Expand Down Expand Up @@ -761,7 +761,7 @@ def save_projection_figures(self, list_items=None, *, choose=False):
**options)

# If filename was provided, save image
if(filename != ''):
if filename:
fig.savefig(filename)
# Else, break the loop
else:
Expand Down
31 changes: 24 additions & 7 deletions prism/_gui/widgets/preferences/custom_boxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from itertools import chain

# Package imports
import cmasher as cmr
from e13tools.utils import docstring_substitute
from matplotlib import cm, rcParams
from matplotlib.colors import BASE_COLORS, CSS4_COLORS, to_rgba
Expand Down Expand Up @@ -437,10 +438,20 @@ def __init__(self, *args, **kwargs):

# This function creates a combobox with colormaps
def init(self):
# Obtain a list with default colormaps that should be at the top
std_cmaps = sset(['cividis', 'dusk', 'freeze', 'gothic', 'heat',
'inferno', 'magma', 'plasma', 'rainforest',
'sunburst', 'viridis'])
# Define set of CMasher colormaps that should be at the top
cmr_cmaps = sset(['dusk', 'freeze', 'gothic', 'heat', 'rainforest',
'sunburst'])

# Check that all of those colormaps are available in CMasher
cmr_cmaps.intersection_update(cmr.cm.cmap_d)

# Obtain a set with default MPL colormaps that should be at the top
std_cmaps = sset(['cividis', 'inferno', 'magma', 'plasma', 'viridis'])

# Add CMasher colormaps to it
std_cmaps.update(['cmr.'+cmap for cmap in cmr_cmaps])

# Obtain reversed set of recommended colormaps
std_cmaps_r = sset([cmap+'_r' for cmap in std_cmaps])

# Obtain a list with all colormaps and their reverses
Expand All @@ -464,8 +475,13 @@ def init(self):
cmap_icons[cmap] = self.create_cmap_icon(cmap, cmap_size)
ColorMapBox.cmap_icons = cmap_icons

# Create a layout for this widget
box_layout = QW.QHBoxLayout(self)
box_layout.setContentsMargins(0, 0, 0, 0)
self.setToolTip("Colormap to be used for the corresponding plot type")

# Create a combobox for cmaps
cmaps_box = QW_QComboBox(self)
cmaps_box = QW_QComboBox()
for cmap in chain(*cmaps):
cmap_icon = self.cmap_icons[cmap]
cmaps_box.addItem(cmap_icon, cmap)
Expand All @@ -478,9 +494,10 @@ def init(self):
# Set remaining properties
set_box_value(cmaps_box, rcParams['image.cmap'])
cmaps_box.setIconSize(QC.QSize(*cmap_size))
cmaps_box.setToolTip("Colormap to be used for the corresponding plot "
"type")
cmaps_box.currentTextChanged.connect(self.cmap_selected)

# Add cmaps_box to layout
box_layout.addWidget(cmaps_box)
self.cmaps_box = cmaps_box

# This function creates an icon of a colormap
Expand Down
6 changes: 3 additions & 3 deletions prism/_gui/widgets/preferences/kwargs_dicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ def get_box_value(self):
entry_type = get_box_value(entry_type_item.widget())

# If the entry_type is empty or banned, skip this row
if(entry_type == '' or entry_type in self.banned_entries):
if not entry_type or entry_type in self.banned_entries:
continue

# Obtain the value of the corresponding field box
Expand Down Expand Up @@ -419,7 +419,7 @@ def set_box_value(self, page_dict):
entry_type = get_box_value(entry_type_item.widget())

# Delete this entry if not in page_dict or if it is not allowed
if(entry_type not in page_dict or (entry_type == '') or
if(entry_type not in page_dict or not entry_type or
entry_type in self.banned_entries):
self.remove_editable_entry(entry_type_item.widget())
continue
Expand Down Expand Up @@ -552,7 +552,7 @@ def entry_type_selected(self, entry_type, kwargs_box):
cur_box = self.kwargs_grid.itemAt(index+1).widget()

# Check what entry_type is given and act accordingly
if(entry_type == ''):
if not entry_type:
# If '' is selected, use an empty label widget
field_box = QW.QLabel('')
elif entry_type in self.banned_entries:
Expand Down
2 changes: 1 addition & 1 deletion prism/_gui/widgets/preferences/tests/test_kwargs_dicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class TestKwargsDictDialog_EntryTypes(object):
@pytest.mark.parametrize(
"page_name, entry_type, field_type, field_value",
[('impl_kwargs_2D', 'alpha', QW.QDoubleSpinBox, 0.5),
('impl_kwargs_3D', 'cmap', ColorMapBox, cm.get_cmap('rainforest')),
('impl_kwargs_3D', 'cmap', ColorMapBox, cm.get_cmap('cmr.freeze')),
('los_kwargs_2D', 'color', ColorBox, 'cyan'),
('fig_kwargs', 'dpi', QW.QSpinBox, 175),
('fig_kwargs', 'figsize', FigSizeBox, (13, 13)),
Expand Down
2 changes: 1 addition & 1 deletion prism/_gui/widgets/viewing_area.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def save_view(self):
**options)

# If filename was provided, save image
if(filename != ''):
if filename:
# Grab the current state of the projection area as a Pixmap
pixmap = self.proj_area.grab()

Expand Down
2 changes: 1 addition & 1 deletion prism/_internal.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ def check_vals(values, name, *args):
raise_error(err_msg, InputError, logger)

# Loop over all criteria
while len(args):
while args:
# Check for bool
if 'bool' in args:
# Convert values to str
Expand Down
59 changes: 27 additions & 32 deletions prism/_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,6 @@ def __repr__(self):

# Add the default parameter dicts to it
default_dict.update(self._get_default_parameters())
default_dict.update(self._emulator._get_default_parameters())
default_dict.update(self._Projection__get_default_parameters())

# Loop over all items in prism_dict and check if it is default
Expand All @@ -263,7 +262,9 @@ def __repr__(self):
par_repr.append("%r: %r" % (key, val))

# Convert par_repr from list to dict and add it to str_repr
str_repr.append("prism_par={%s}" % (", ".join(map(str, par_repr))))
if par_repr:
str_repr.append("prism_par={%s}"
% (", ".join(map(str, par_repr))))

# Add the emul_type representation if it is not default
emul_repr = "%s.%s" % (self._emulator.__class__.__module__,
Expand Down Expand Up @@ -1106,7 +1107,7 @@ def _get_paths(self, root_dir, working_dir, prefix):
emul_dirs.sort(key=lambda x: x[1], reverse=True)

# If no working directory exists, create a new one
if not len(emul_dirs):
if not emul_dirs:
working_dir = ''.join([prefix_new, '0'])
self._working_dir = path.join(self._root_dir, working_dir)
os.mkdir(self._working_dir)
Expand All @@ -1119,6 +1120,19 @@ def _get_paths(self, root_dir, working_dir, prefix):
logger.info("Working directories found, set to %r."
% (path.basename(self._working_dir)))

# If one specified a working directory, use it
elif isinstance(working_dir, str):
self._working_dir = path.join(self._root_dir, working_dir)
logger.info("Working directory set to %r." % (working_dir))

# Check if this directory already exists and create it if not
try:
os.mkdir(self._working_dir)
except OSError:
pass
else:
logger.info("Working directory did not exist, created it.")

# If one requested a new working directory
elif working_dir is True:
# Obtain list of working directories that satisfy naming scheme
Expand Down Expand Up @@ -1152,25 +1166,6 @@ def _get_paths(self, root_dir, working_dir, prefix):
logger.info("New working directory requested, created %r."
% (path.basename(working_dir)))

# If one specified a working directory, use it
elif isinstance(working_dir, str):
self._working_dir = path.join(self._root_dir, working_dir)
logger.info("Working directory set to %r." % (working_dir))

# Check if this directory already exists and create it if not
try:
os.mkdir(self._working_dir)
except OSError:
pass
else:
logger.info("Working directory did not exist, created it.")

# If one provided an integer, raise warning about it
elif isinstance(working_dir, int):
err_msg = ("Input argument 'working_dir' cannot be of type "
"int!")
raise_error(err_msg, TypeError, logger)

# If anything else is given, it is invalid
else:
err_msg = "Input argument 'working_dir' is invalid!"
Expand Down Expand Up @@ -2235,7 +2230,7 @@ def _evaluate_sam_set(self, emul_i, sam_set, exec_code):
sam_idx = self._comm.bcast(sam_idx, 0)

# Check that sam_idx is still holding plausible samples
if not len(sam_idx):
if not sam_idx.size:
# If not, stop analysis
break
else:
Expand Down Expand Up @@ -2327,9 +2322,9 @@ def analyze(self, *, impl_cut=None):

# Save impl_par to hdf5
self._save_data({
'impl_par': {
'impl_cut': self._impl_cut[emul_i],
'cut_idx': self._cut_idx[emul_i]}})
'impl_par': {
'impl_cut': self._impl_cut[emul_i],
'cut_idx': self._cut_idx[emul_i]}})

# Create an emulator evaluation sample set
eval_sam_set = self._get_eval_sam_set(emul_i)
Expand Down Expand Up @@ -2959,29 +2954,29 @@ def f(x):
'active_par_data' in ccheck_flat[i]]
print(" - {0: <{1}}\t{2}".format(
"'active_par_data'?", width-4, "No (%s)" % (ccheck_i) if
len(ccheck_i) else "Yes"))
ccheck_i else "Yes"))

# Check if all regression processes have been done if requested
if self._emulator._method in ('regression', 'full'):
ccheck_i = [i for i in range(n_emul_s) if
'regression' in ccheck_flat[i]]
print(" - {0: <{1}}\t{2}".format(
"'regression'?", width-4, "No (%s)" % (ccheck_i) if
len(ccheck_i) else "Yes"))
ccheck_i else "Yes"))

# Check if all covariance matrices have been determined
ccheck_i = [i for i in range(n_emul_s) if
'cov_mat' in ccheck_flat[i]]
print(" - {0: <{1}}\t{2}".format(
"'cov_mat'?", width-4, "No (%s)" % (ccheck_i) if
len(ccheck_i) else "Yes"))
ccheck_i else "Yes"))

# Check if all exp_dot_terms have been determined
ccheck_i = [i for i in range(n_emul_s) if
'exp_dot_term' in ccheck_flat[i]]
print(" - {0: <{1}}\t{2}".format(
"'exp_dot_term'?", width-4, "No (%s)" % (ccheck_i) if
len(ccheck_i) else "Yes"))
ccheck_i else "Yes"))
print("-"*width)

# PARAMETER SPACE
Expand Down Expand Up @@ -3430,9 +3425,9 @@ def _process_call_str(pipeline_obj, string):
str_list = string.split('.')

# If the first element is 'pipe', it refers to a Pipeline attribute
if str_list.pop(0) == 'pipe':
if(str_list.pop(0) == 'pipe'):
# Remove 'pipe' again in case 'pipe.pipe.xxx' was provided
if len(str_list) and str_list[0] == 'pipe':
if str_list and (str_list[0] == 'pipe'):
str_list.pop(0)

# Retrieve the attribute that string refers to
Expand Down
14 changes: 7 additions & 7 deletions prism/_projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ def project(self, emul_i=None, proj_par=None, **kwargs):
implausibility (top/left) plot in the 2D projection figures. It
takes all arguments that can be provided to the
:func:`~matplotlib.pyplot.plot` function.
impl_kwargs_3D : dict. Default: {'cmap': 'rainforest_r'}
impl_kwargs_3D : dict. Default: {'cmap': 'cmr.rainforest_r'}
Dict of keyword arguments to be used for making the minimum
implausibility (top/left) plot in the 3D projection figures. It
takes all arguments that can be provided to the
Expand All @@ -148,7 +148,7 @@ def project(self, emul_i=None, proj_par=None, **kwargs):
(bottom/right) plot in the 2D projection figures. It takes all
arguments that can be provided to the
:func:`~matplotlib.pyplot.plot` function.
los_kwargs_3D : dict. Default: {'cmap': 'freeze'}
los_kwargs_3D : dict. Default: {'cmap': 'cmr.freeze'}
Dict of keyword arguments to be used for making the line-of-sight
(bottom/right) plot in the 3D projection figures. It takes all
arguments that can be provided to the
Expand Down Expand Up @@ -594,8 +594,8 @@ def __draw_3D_proj_fig(self, hcube, impl_min, impl_los, proj_res):
# Therefore, values up to max(z_los)/N has the color for 0
min_los = min(1, np.max(z_los))/self.__los_kwargs_3D['cmap'].N

# Set all z_min to impl_cut if its corresponding z_los <= min_los
z_min[z_los <= min_los] = impl_cut
# Set all z_min to impl_cut if its corresponding z_los < min_los
z_min[z_los < min_los] = impl_cut

# Create plotted parameter value grid
x = np.linspace(*self._modellink._par_rng[par1], gridsize[0])
Expand Down Expand Up @@ -818,7 +818,7 @@ def __get_req_hcubes(self, emul_i, proj_par):
hcubes.extend(proj_par[np_array(hcube_idx)].tolist())
if self.__proj_3D:
hcube_idx = list(combinations(range(len(proj_par)), 2))
if len(hcube_idx):
if hcube_idx:
hcubes.extend(proj_par[np_array(hcube_idx)].tolist())

# Add the emulator iteration in front of all hcubes
Expand Down Expand Up @@ -984,9 +984,9 @@ def __get_default_input_arguments(self):
# Create input argument dicts with default figure parameters
fig_kwargs = {'dpi': 100}
impl_kwargs_2D = {}
impl_kwargs_3D = {'cmap': 'rainforest_r'}
impl_kwargs_3D = {'cmap': 'cmr.rainforest_r'}
los_kwargs_2D = {}
los_kwargs_3D = {'cmap': 'freeze'}
los_kwargs_3D = {'cmap': 'cmr.freeze'}
line_kwargs_est = {'linestyle': '--',
'color': 'grey'}
line_kwargs_cut = {'color': 'r'}
Expand Down
Loading

0 comments on commit 7ae4bad

Please sign in to comment.