Coverage for pesummary/core/file/_lazy/base.py: 0.0%
90 statements
« prev ^ index » next coverage.py v7.4.4, created at 2025-11-05 13:38 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2025-11-05 13:38 +0000
1# Licensed under an MIT style license -- see LICENSE.md
3import numpy as np
4from ....utils.parameters import Parameters
6__author__ = ["Charlie Hoy <charlie.hoy@ligo.org>"]
9class _LazyRead(object):
10 """Base class for a lazy read object
12 Parameters
13 ----------
14 drop_non_numeric: bool, optional
15 if True, remove all non_numeric values from the posterior samples
16 table
17 remove_nan_likelihood_samples: bool, optional
18 if True. remove all rows in the posterior samples table that have 'nan'
19 likelihood
21 Attributes
22 ----------
23 parameters: pesummary.utils.parameters.Parameters
24 list of parameters in the posterior samples table
25 samples: np.ndarray
26 2D array of samples in the posterior samples table
27 samples_dict: pesummary.utils.samples_dict.SamplesDict
28 dictionary displaying the posterior samples table.
29 """
30 def __init__(
31 self, *args, drop_non_numeric=True, remove_nan_likelihood_samples=True,
32 **kwargs
33 ):
34 super().__init__(*args, **kwargs)
35 self.mcmc_samples = False
36 self.drop_non_numeric = drop_non_numeric
37 self.remove_nan_likelihood_samples = remove_nan_likelihood_samples
39 @property
40 def parameters(self):
41 if not hasattr(self, "_parameters"):
42 _ = self.samples
43 self._parameters = [str(i) for i in self._parameters]
44 return Parameters(self._parameters)
46 @property
47 def samples(self):
48 if hasattr(self, "_samples"):
49 return self._samples
50 self.grab_samples_from_file()
51 if not self._is_array:
52 self._convert_samples_to_array()
53 if self.drop_non_numeric:
54 self.remove_non_numeric_values_from_samples()
55 if self.remove_nan_likelihood_samples:
56 self.remove_nan_likelihood_values_from_samples()
57 return self._samples
59 @property
60 def _is_array(self):
61 if not np.issubdtype(type(self._samples[0]), np.number):
62 return True
63 return False
65 def _convert_samples_to_array(self):
66 self._samples_dict = {
67 key: [item] for key, item in self.samples_dict.items()
68 }
70 def remove_non_numeric_values_from_samples(self):
71 numeric_cols = []
72 for i in range(self._samples.shape[1]):
73 try:
74 original_dtype = self._samples[:, i].dtype
75 # this will fail if non-numeric dtype
76 self._samples[:, i].astype(np.complex128)
77 numeric_cols.append(i)
78 self._samples[:, i].astype(original_dtype)
79 except (ValueError, TypeError):
80 from pesummary.utils.utils import logger
81 logger.warning(
82 f"Removing '{self._parameters[i]}' from the posterior "
83 f"table as it contains non-numeric values. To prevent "
84 f"this, pass 'drop_non_numeric=False' when loading the "
85 f"file."
86 )
87 continue
88 if not len(numeric_cols):
89 self._parameters = []
90 self._samples = []
91 else:
92 self._parameters = self._parameters[numeric_cols]
93 self._samples = self._samples[:, numeric_cols]
95 def remove_nan_likelihood_values_from_samples(self):
96 if "log_likelihood" not in self._parameters:
97 return
98 ind = self.parameters.index("log_likelihood")
99 likelihoods = self._samples[:,ind]
100 inds = np.isnan(likelihoods)
101 if not sum(inds):
102 return
103 msg = (
104 f"Posterior table contains {sum(inds)} samples with 'nan' log "
105 f"likelihood. "
106 )
107 msg += "Removing samples from posterior table."
108 logger.warn(msg)
109 self._samples = self._samples[~inds,:]
111 @property
112 def samples_dict(self):
113 # if samples_dict has already been initialized, use this
114 if hasattr(self, "_samples_dict"):
115 return self._samples_dict
116 return self._generate_samples_dict()
118 def _generate_samples_dict(self):
119 from pesummary.utils.samples_dict import (
120 SamplesDict, MCMCSamplesDict
121 )
122 if self.mcmc_samples:
123 return MCMCSamplesDict(
124 self.parameters, [np.array(i).T for i in self.samples]
125 )
126 return SamplesDict(self.parameters, np.array(self.samples).T)
128 def __repr__(self):
129 return self.summary()
131 def _parameter_summary(self, parameters, parameters_to_show=4):
132 """Return a summary of the parameter stored
134 Parameters
135 ----------
136 parameters: list
137 list of parameters to create a summary for
138 parameters_to_show: int, optional
139 number of parameters to show. Default 4.
140 """
141 params = parameters
142 if len(parameters) > parameters_to_show:
143 params = parameters[:2] + ["..."] + parameters[-2:]
144 return ", ".join(params)
146 def summary(
147 self, parameters_to_show=4, show_parameters=True, show_nsamples=True
148 ):
149 """Return a summary of the contents of the file
151 Parameters
152 ----------
153 parameters_to_show: int, optional
154 number of parameters to show. Default 4
155 show_parameters: Bool, optional
156 if True print a list of the parameters stored
157 show_nsamples: Bool, optional
158 if True print how many samples are stored in the file
159 """
160 string = ""
161 if self.filename is not None:
162 string += "file: {}\n".format(self.filename)
163 string += "cls: {}.{}\n".format(
164 self.__class__.__module__, self.__class__.__name__
165 )
166 if show_nsamples:
167 string += "nsamples: {}\n".format(len(self.samples))
168 if show_parameters:
169 string += "parameters: {}".format(
170 self._parameter_summary(
171 self.parameters, parameters_to_show=parameters_to_show
172 )
173 )
174 return string