Skip to content

Commit 3e8cbd5

Browse files
thjsalyveskinisguillot
authored
Postprocessing bugfixes and updates - tag v2.0.3. (#312)
* Fixing the bug with cornerplot parameter limits for X-PSI versions above 2.0 Fixes #301 * Option for setting CI precision for corner plots. * CHANGELOG update * Postprocess fix for many photospheres (#313) * Photosphere setter function added in Star.py for postprocessing. * Extra line removed. * Error and special case handling for precision settings. * Precisions given as list of ints or Nones, giving warning instead of error if not using it correctly, and fixing a bug in implementation. * Postprocessing figure adjustments (#315) * Minor ticks back to corner plots by default. * Install getdist and nestcheck from source suggested for latest updates. * Fix to combining multiple runs. (#316) * Ready for version update Co-authored-by: Yves Kini <kiniyves@gmail.com> Co-authored-by: Sebastien Guillot <sebguillot60@gmail.com> * Use NestCheck both with and without hyphens in file names. (#317) * Use NestCheck both with and without hyphens in file names. * Error handling improved and simplified. * Date update in Changelog. --------- Co-authored-by: Yves Kini <kiniyves@gmail.com> Co-authored-by: Sebastien Guillot <sebguillot60@gmail.com>
1 parent a5d8cde commit 3e8cbd5

10 files changed

Lines changed: 147 additions & 90 deletions

File tree

CHANGELOG.rst

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,37 @@ and this project adheres to
3434
.. ^^^^^^^^^^^
3535
3636
37+
[v2.0.3] - 2023-07-11
38+
~~~~~~~~~~~~~~~~~~~~~
39+
40+
Summary
41+
^^^^^^^
42+
43+
* Updates and bug fixes in post-processing.
44+
45+
Fixed
46+
^^^^^
47+
48+
* Fixed a bug when defining ``param_plot_lims`` in ``xpsi/PostProcessing/_corner.py`` caused by ``tight_gap_fraction`` being only defined in the customized GetDist version that is not used anymore. That parameter is now defined in X-PSI instead (T.S., Y.K., S.G.).
49+
50+
* Fixed a bug when combining multiple runs in ``xpsi/PostProcessing/_runs.py``, which caused the combination sometimes fail since PolyChord (instead of MultiNest) default was used for the initial live point likelihoods in dead-birth files. This bug appeared after switching to use a non-customized version of NestCheck (after X-PSI version 2.0.0). Now the newest NestCheck version allows to change this value, and this change is now done within X-PSI. If trying to use an older NestCheck version, an error is raised (T.S., Y.K.).
51+
52+
* Fixed the hyphens in the file names in ``xpsi/PostProcessing/_backends.py`` when reading MultiNest output files with the newest NestCheck version from GitHub, although trying still to read the filenames also with the older syntax to allow older NestCheck versions for other things than combining runs (T.S.).
53+
54+
Added
55+
^^^^^
56+
* Added a keyword argument in ``xpsi/PostProcessing/_corner.py`` to allow user to define the decimal precisions for all the credible intervals printed in the figures (T.S.).
57+
58+
* Added a photosphere setter in ``xpsi/Star.py`` which should allow producing residual and signal plots for models with multiple photosphere objects as explained in ``https://github.com/xpsi-group/xpsi/issues/304`` (Y.K, T.S.).
59+
60+
* Added minor ticks back to corner plots in ``xpsi/PostProcessing/_corner.py``. Previously, these ticks were produced by the customized older GetDist version (T.S.).
61+
62+
Attribution
63+
^^^^^^^^^^^
64+
65+
Tuomo Salmi, Yves Kini, Sebastien Guillot
66+
67+
3768
[v2.0.2] - 2023-06-09
3869
~~~~~~~~~~~~~~~~~~~~~
3970

@@ -55,6 +86,7 @@ Fixed
5586

5687
Attribution
5788
^^^^^^^^^^^
89+
5890
Tuomo Salmi
5991

6092

@@ -77,6 +109,7 @@ Added
77109

78110
Attribution
79111
^^^^^^^^^^^
112+
80113
Tuomo Salmi,
81114
Evert Rol,
82115
Martin Heemskerk

docs/source/Post-processing.ipynb

Lines changed: 20 additions & 68 deletions
Large diffs are not rendered by default.

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
# The short X.Y version.
8181
version = '2.0'
8282
# The full version, including alpha/beta/rc tags.
83-
release = '2.0.2'
83+
release = '2.0.3'
8484

8585
# The language for content autogenerated by Sphinx. Refer to documentation
8686
# for a list of supported languages.

docs/source/install.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ post-processing:
115115
116116
conda install -c conda-forge getdist h5py nestcheck fgivenx
117117
118+
.. note::
119+
120+
However, to get the most updated versions of getdist and nestcheck (which may be needed by
121+
some of the X-PSI post-processing features), they should be installed from the source
122+
(https://github.com/cmbant/getdist and https://github.com/ejhigson/nestcheck)
123+
by cloning the repositories and running ``python setup.py install`` in them.
124+
118125
In addition, some optional miscellaneous packages are:
119126

120127
#. `jupyter <https://jupyter-notebook.readthedocs.io/en/stable/>`_ if you want to run X-PSI in a notebook.

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ def EXTENSION(modname):
289289

290290
setup(
291291
name = 'xpsi',
292-
version = '2.0.2',
292+
version = '2.0.3',
293293
author = 'The X-PSI Core Team',
294294
author_email = 'A.L.Watts@uva.nl',
295295
url = 'https://github.com/xpsi-group/xpsi',

xpsi/PostProcessing/_backends.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,20 @@ def __init__(self, root, base_dir, use_nestcheck, transform=None,
103103
except KeyError:
104104
print('Root %r sampling implementation not specified... '
105105
'assuming MultiNest for nestcheck...')
106-
self._nc_bcknd = process_multinest_run(root,
106+
try:
107+
self._nc_bcknd = process_multinest_run(root,
107108
base_dir=base_dir)
109+
except FileNotFoundError:
110+
self._nc_bcknd = process_multinest_run(root+"-",
111+
base_dir=base_dir)
108112
else:
109113
if kwargs['implementation'] == 'multinest':
110-
self._nc_bcknd = process_multinest_run(root,
114+
try:
115+
self._nc_bcknd = process_multinest_run(root,
111116
base_dir=base_dir)
117+
except FileNotFoundError:
118+
self._nc_bcknd = process_multinest_run(root+"-",
119+
base_dir=base_dir)
112120
elif kwargs['implementation'] == 'polychord':
113121
self._nc_bcknd = process_polychord_run(root,
114122
base_dir=base_dir)

xpsi/PostProcessing/_corner.py

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,13 @@ def plot(self,
148148
distributions. If ``bootstrap and not separate_plots`` then
149149
the density distribution linewidth is set to zero if not
150150
explicitly specified with kwarg ``lw_1d``.
151-
In addition, keyword arguments for avoiding unnecessary re-drawing of prior samples (``force_draw``, ``prior_samples_fnames`` and ``priors_identical``).
151+
In addition, keyword arguments for avoiding unnecessary re-drawing of prior samples
152+
(``force_draw``, ``prior_samples_fnames`` and ``priors_identical``).
153+
Param``precisions`` (a list of integers or Nones) can be used to define the decimal number
154+
precision for each credible interval plotted. In case of 2 parameters, one can do e.g.
155+
precisions=[2,None] to use 2 digit decimal precision for the first parameter and use the
156+
default automatic precision for the second.
157+
152158
153159
"""
154160
self.set_subset(IDs, combine, combine_all,
@@ -445,6 +451,7 @@ def _plot_triangle(self,
445451
"""
446452
#self.val_cred = []
447453
self.credible_interval_1d_all_show=credible_interval_1d_all_show
454+
tight_gap_fraction = 0.13 # space between ticks and the edge
448455

449456
if credible_interval_1d_all_show:
450457
KL_divergence=False
@@ -546,6 +553,15 @@ def _plot_triangle(self,
546553
else:
547554
plotter.legend.set_frame_on(legend_frameon)
548555

556+
params = self.params
557+
for j in range(len(params.names)):
558+
for i in range(j,len(params.names)):
559+
ax = plotter.subplots[i,j]
560+
ax.xaxis.set_minor_locator(AutoMinorLocator())
561+
for i in range(j):
562+
ax = plotter.subplots[j,i]
563+
ax.yaxis.set_minor_locator(AutoMinorLocator())
564+
549565
# add custom parameter plotting limits and updated autolocation
550566
with fragile(verbose(param_plot_lims,
551567
'Applying bespoke parameter viewing intervals',
@@ -575,7 +591,7 @@ def _plot_triangle(self,
575591
axis = plotter.subplots[-1,j].xaxis
576592
xmin, xmax = axis.get_view_interval()
577593
width = xmax - xmin
578-
gap_wanted = width * plotter.settings.tight_gap_fraction
594+
gap_wanted = width * tight_gap_fraction
579595
tick = [x for x in axis.get_major_ticks() if xmin <= x.get_loc() <= xmax]
580596

581597
if tick[0].get_loc() - xmin < gap_wanted:
@@ -588,7 +604,7 @@ def _plot_triangle(self,
588604
axis = plotter.subplots[j,0].yaxis
589605
xmin, xmax = axis.get_view_interval()
590606
width = xmax - xmin
591-
gap_wanted = width * plotter.settings.tight_gap_fraction
607+
gap_wanted = width * tight_gap_fraction
592608
tick = [x for x in axis.get_major_ticks() if xmin <= x.get_loc() <= xmax]
593609

594610
if tick[0].get_loc() - xmin < gap_wanted:
@@ -640,6 +656,19 @@ def _plot_triangle(self,
640656

641657
self.credible_intervals=OrderedDict()
642658

659+
if "precisions" in kwargs:
660+
precisions = kwargs.get('precisions')
661+
if (not isinstance(precisions, list)) or (not all((isinstance(element, int) or element==None) for element in precisions)):
662+
print("Warning: Precisions need to be given as a list of integers or Nones. " +
663+
"Using the automatic default precisions instead.")
664+
precisions = [None]*plotter.subplots.shape[0]
665+
elif len(precisions) != plotter.subplots.shape[0]:
666+
print("Warning: Precisions list has wrong number of dimensions. " +
667+
"Using the automatic default precisions instead.")
668+
precisions = [None]*plotter.subplots.shape[0]
669+
else:
670+
precisions = [None]*plotter.subplots.shape[0]
671+
643672
if credible_interval_1d_all_show and self.all_same(self.get_attr("parent_ID")):
644673
for r in range(len(self.subset_to_plot)):
645674

@@ -656,7 +685,8 @@ def _plot_triangle(self,
656685
annotate_xy=annotate_xy,
657686
sixtyeight=sixtyeight,
658687
ninety=ninety,
659-
compute_all_intervals=compute_all_intervals)
688+
compute_all_intervals=compute_all_intervals,
689+
precisions=precisions)
660690

661691
self.credible_intervals[id]=self.val_cred
662692
else:
@@ -673,7 +703,8 @@ def _plot_triangle(self,
673703
annotate_xy=annotate_xy,
674704
sixtyeight=sixtyeight,
675705
ninety=ninety,
676-
compute_all_intervals=compute_all_intervals)
706+
compute_all_intervals=compute_all_intervals,
707+
precisions=precisions)
677708

678709
self.credible_intervals[id]=self.val_cred
679710

@@ -846,7 +877,7 @@ def KL(ns_run, logw):
846877
'Added 1D marginal credible intervals')
847878
def _add_credible_interval(self, plotter, posterior, bootstrap, n_simulate,
848879
annotate, annotate_xy, sixtyeight,
849-
ninety, compute_all_intervals):
880+
ninety, compute_all_intervals, precisions=None):
850881
"""
851882
Estimate 1-:math:`\sigma` credible interval in one-dimension on a
852883
combined run, or if such a run does not exist, on the run with
@@ -863,6 +894,10 @@ def _add_credible_interval(self, plotter, posterior, bootstrap, n_simulate,
863894
``False`` plots 95% credible interval about the median -- i.e.,
864895
symmetric quantiles about the median.
865896
"""
897+
898+
if precisions is None:
899+
precisions = [None]*plotter.subplots.shape[0]
900+
866901
diag = [plotter.subplots[i,i] for i in range(plotter.subplots.shape[0])]
867902

868903
run = self.run #posterior.subset_to_plot[0]
@@ -882,7 +917,7 @@ def estimator(*args, **kwargs):
882917

883918
quantiles = [0.159, 0.5, 0.841] if sixtyeight else ([0.05,0.5,0.95] if ninety else [0.025, 0.5, 0.975])
884919

885-
def format_CI(name, cred, summary, additional=2, sscript=False):
920+
def format_CI(name, cred, summary, additional=2, sscript=False, precision=None):
886921

887922
if len(cred.shape) > 1:
888923
_qs = (cred[1,1],
@@ -893,9 +928,12 @@ def format_CI(name, cred, summary, additional=2, sscript=False):
893928
_qs = (cred[1],
894929
cred[1] - cred[0],
895930
cred[2] - cred[1])
896-
897931
_p = max(_precision(_qs[0]), _precision(_qs[1]), _precision(_qs[2]))
898-
_f = '%.' + str(_p + additional) + 'f'
932+
933+
if precision is None:
934+
_f = '%.' + str(_p + additional) + 'f'
935+
else:
936+
_f = '%.' + str(precision) + 'f'
899937

900938
if name: name += ' '
901939

@@ -955,7 +993,8 @@ def calculate_intervals(quantiles):
955993
cred,
956994
68 if sixtyeight else (90 if ninety else 95),
957995
additional=1,
958-
sscript=True)
996+
sscript=True,
997+
precision=precisions[i])
959998

960999
title = ax.get_title()
9611000
if title:
@@ -1004,6 +1043,7 @@ def calculate_intervals(quantiles):
10041043

10051044

10061045
if compute_all_intervals:
1046+
10071047
yield format_CI(self.params.names[i],
10081048
cred,
10091049
68 if sixtyeight else (90 if ninety else 95))
@@ -1061,7 +1101,8 @@ def calculate_intervals(quantiles):
10611101
cred,
10621102
68 if sixtyeight else (90 if ninety else 95),
10631103
additional=1,
1064-
sscript=True)
1104+
sscript=True,
1105+
precision=precisions[i])
10651106

10661107
title = ax.get_title()
10671108
if title:

xpsi/PostProcessing/_runs.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,24 @@ def _combine(self, combine_all, overwrite):
185185
run['output']['base_dir'] = base_dir
186186
run['output']['file_root'] = file_root
187187

188-
write_run_output(run,
189-
write_dead = True,
190-
write_stats = True,
191-
posteriors = True,
192-
stats_means_errs = True,
193-
n_simulate = 1000)
188+
try:
189+
#use MultiNest initial likelihood (logl_init) instead of the default PolyChord
190+
write_run_output(run,
191+
write_dead = True,
192+
write_stats = True,
193+
posteriors = True,
194+
stats_means_errs = True,
195+
n_simulate = 1000,
196+
logl_init = -0.179769313486231571E+309)
197+
except TypeError as e:
198+
if str(e) == "Unexpected **kwargs: {'logl_init': -1.7976931348623157e+308}":
199+
raise TypeError("The used nestcheck version does not support combining "
200+
"MultiNest runs in X-PSI. To use this feature, nestcheck version newer "
201+
"than in this commit: "
202+
"https://github.com/ejhigson/nestcheck/commit/513ef962ef7b0d66377686f9fe0a9e354dad48b3 "
203+
"should be used (see installation instructions for installing it from github).")
204+
else:
205+
raise
194206

195207
kwargs = {'kde_settings': self.kde_settings,
196208
'ID': 'combined',

xpsi/Star.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ def photospheres(self):
6262
""" Get the list of photosphere objects. """
6363
return self._photospheres
6464

65+
@photospheres.setter
66+
def photospheres(self, obj):
67+
self._photospheres = [obj]
68+
6569
def activate_fast_mode(self, activate):
6670
try:
6771
for photosphere in self._photospheres:

xpsi/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
55
"""
66

7-
__version__ = "2.0.2"
7+
__version__ = "2.0.3"
88
__author__ = "The X-PSI Core Team"
99

1010
try:

0 commit comments

Comments
 (0)