From 175d730d1c2d995b99356d72c1c7ab6f4777b675 Mon Sep 17 00:00:00 2001 From: Aymeric Galan Date: Mon, 7 Apr 2025 12:16:16 +0200 Subject: [PATCH 1/2] Make some Observation and Instrument properties optional (falls back on 'Unspecified' classes) --- coolest/api/composable_models.py | 38 +++++++++++++++++++++---- coolest/template/classes/grid.py | 30 ++++++++++++++++--- coolest/template/classes/instrument.py | 15 +++++----- coolest/template/classes/noise.py | 11 +++++++ coolest/template/classes/observation.py | 19 ++++++++++--- coolest/template/classes/psf.py | 16 +++++++++++ coolest/template/json.py | 25 +++++++--------- 7 files changed, 120 insertions(+), 34 deletions(-) diff --git a/coolest/api/composable_models.py b/coolest/api/composable_models.py index db934a0..802f745 100644 --- a/coolest/api/composable_models.py +++ b/coolest/api/composable_models.py @@ -363,12 +363,26 @@ def evaluate_deflection(self, x, y): alpha_y += a_y return alpha_x, alpha_y - def evaluate_convergence(self, x, y): + def evaluate_convergence(self, x, y, mode='point', last_n_samples=None): """Evaluates the lensing convergence (i.e., 2D mass density) at given coordinates""" - kappa = np.zeros_like(x) - for k, (profile, params) in enumerate(zip(self.profile_list, self.param_list)): - kappa += profile.convergence(x, y, **params) - return kappa + self._check_eval_mode(mode) + if mode == 'point' or self._posterior_bool is False: + return self._eval_conv_point(x, y, self.param_list) + elif mode == 'posterior': + return self._eval_conv_posterior(x, y, self.post_param_list, last_n_samples) + + def _eval_conv_point(self, x, y, param_list): + psi = np.zeros_like(x) + for k, profile in enumerate(self.profile_list): + psi += profile.convergence(x, y, **param_list[k]) + return psi + + def _eval_conv_posterior(self, x, y, param_list, last_n_samples): + # map the point function at each sample + use_all_samples = last_n_samples is None or last_n_samples <= 0 + val_list = param_list if use_all_samples else param_list[-last_n_samples:] + mapped = map(partial(self._eval_conv_point, x, y), val_list) + return np.array(list(mapped)) def evaluate_hessian(self, x, y): """Evaluates the lensing Hessian components at given coordinates""" @@ -403,6 +417,20 @@ def ray_shooting(self, x, y): x_rs, y_rs = x - alpha_x, y - alpha_y return x_rs, y_rs + def shear(self, x, y): + """evaluates the reduce shear gamma""" + H_xx, H_xy, _, H_yy = self.evaluate_hessian(x, y) + gamma1 = 1.0 / 2 * (H_xx - H_yy) + gamma2 = H_xy + return gamma1, gamma2 + + def reduced_shear(self, x, y): + """evaluates the reduce shear g = gamma / 1 - kappa""" + kappa = self.evaluate_convergence(x, y) + gamma1, gamma2 = self.evaluate_convergence(x, y) + x_rs, y_rs = x - alpha_x, y - alpha_y + return gamma + class ComposableLensModel(object): """Given a COOLEST object, evaluates a selection of entity and diff --git a/coolest/template/classes/grid.py b/coolest/template/classes/grid.py index 4d571f0..092652e 100644 --- a/coolest/template/classes/grid.py +++ b/coolest/template/classes/grid.py @@ -13,12 +13,10 @@ 'Grid', 'PixelatedRegularGrid', 'IrregularGrid', + 'PixelatedRegularGridStack', ] -SUPPORTED_CHOICES = [ - 'PixelatedRegularGrid', - 'IrregularGrid', -] +SUPPORTED_CHOICES = list(set(__all__) - {'Grid'}) class Grid(APIBaseObject): @@ -295,3 +293,27 @@ def get_xyz(self, directory=None): y = data.field(1) z = data.field(2) return x, y, z + + +class UnspecifiedGrid(Grid): + """Class that represents a generic grid of values, with just (optional) + FITS information. This may be used for e.g., as a workaround for storing + other than standard photometric data, such as interferometric data. + + Parameters + ---------- + fits_path : str + Optional to some FITS file in which the values (and perhaps the coordinates) + are stored. This should be relative to the final COOLEST template file. + **kwargs_file : dic, optional + Any remaining keyword arguments for FitsFile + """ + + def __init__(self, + fits_path: str = None, + **kwargs_file) -> None: + super().__init__(fits_path, **kwargs_file) + self.set_grid( + fits_path, + check_fits_file=kwargs_file.get('check_fits_file', False) + ) diff --git a/coolest/template/classes/instrument.py b/coolest/template/classes/instrument.py index 2d58b57..594b353 100644 --- a/coolest/template/classes/instrument.py +++ b/coolest/template/classes/instrument.py @@ -1,6 +1,6 @@ __author__ = 'aymgal' -from coolest.template.classes.psf import PSF +from coolest.template.classes.psf import PSF, UnspecifiedPSF from coolest.template.classes.base import APIBaseObject @@ -12,28 +12,29 @@ class Instrument(APIBaseObject): Parameters ---------- pixel_size : float - Size in arcseconds of a single detector pixel. + Size in arcseconds of a single detector pixel, by default None. name : str, optional Name of the instrument, by default "" band : str, optional Name of the filter, by default "" readout_noise : float, optional - Readout noise (in electrons), by default 0. + Readout noise (in electrons) when it is relevant to the instrument, + by default None. psf : PSF, optional - Instance of PSF object, by default None + Instance of PSF object, by default None (i.e. UnspecifiedPSF). """ def __init__(self, - pixel_size: float, + pixel_size: float = None, name: str = "", band: str = "", - readout_noise: float = 0., + readout_noise: float = None, psf: PSF = None) -> None: self.name = name self.band = band self.pixel_size = pixel_size self.readout_noise = readout_noise if psf is None: - psf = PSF() + psf = UnspecifiedPSF() self.psf = psf super().__init__() diff --git a/coolest/template/classes/noise.py b/coolest/template/classes/noise.py index 6e00b40..20328ab 100644 --- a/coolest/template/classes/noise.py +++ b/coolest/template/classes/noise.py @@ -11,6 +11,7 @@ 'NoiseRealization', 'InstrumentalNoise', 'DrizzledNoise', + 'UnspecifiedNoise', ] SUPPORTED_CHOICES = list(set(__all__) - {'Noise'}) @@ -124,3 +125,13 @@ def __init__(self, background_rms: float = 0.0, if wht_map is None: wht_map = PixelatedRegularGrid() super().__init__(ntype, background_rms=background_rms, wht_map=wht_map) + + +class UnspecifiedNoise(Noise): + """Noise type that can be used when the noise can not be properly specified, + or noise properties are unknown. May be used for e.g. interferometric data. + """ + + def __init__(self) -> None: + ntype = self.__class__.__name__ + super().__init__(ntype) diff --git a/coolest/template/classes/observation.py b/coolest/template/classes/observation.py index ff5abef..a0b55ea 100644 --- a/coolest/template/classes/observation.py +++ b/coolest/template/classes/observation.py @@ -1,9 +1,10 @@ __author__ = 'aymgal' from typing import Union +import math -from coolest.template.classes.grid import PixelatedRegularGrid -from coolest.template.classes.noise import Noise +from coolest.template.classes.grid import PixelatedRegularGrid, UnspecifiedGrid +from coolest.template.classes.noise import Noise, UnspecifiedNoise from coolest.template.classes.base import APIBaseObject @@ -37,13 +38,13 @@ def __init__(self, # magnification_ratios: list = None ) -> None: if pixels is None: - pixels = PixelatedRegularGrid() + pixels = UnspecifiedGrid() self.pixels = pixels self.exposure_time = exposure_time self.mag_zero_point = mag_zero_point # magnitude zero-point (corresponds to 1 electron per second on the detector) self.mag_sky_brightness = mag_sky_brightness # sky brightness (magnitude per arcsec^2) if noise is None: - noise = Noise() + noise = UnspecifiedNoise() self.noise = noise # self.time_delays = time_delays # self.magnification_ratios = magnification_ratios @@ -51,6 +52,16 @@ def __init__(self, def check_consistency_with_instrument(self, instrument): """Checks that the data image is consistent with instrument properties""" + instru_pix_size = instrument.pixel_size + obs_pix_size = self.pixels.pixel_size + if instru_pix_size is None: + # when the instrument pixel size is undefined, we don't check anything + return + isclose_bool = math.isclose(instru_pix_size, obs_pix_size, + rel_tol=1e-09, abs_tol=0.0) + if obs_pix_size not in (0, None) and not isclose_bool: + raise ValueError(f"Pixel size of observation ({obs_pix_size}) is inconsistent with " + f"the instrument pixel size ({instru_pix_size})") width = abs(self.pixels.field_of_view_x[1] - self.pixels.field_of_view_x[0]) height = abs(self.pixels.field_of_view_y[1] - self.pixels.field_of_view_y[0]) num_pix_ra = round(width / instrument.pixel_size) diff --git a/coolest/template/classes/psf.py b/coolest/template/classes/psf.py index 74d105b..a0ca123 100644 --- a/coolest/template/classes/psf.py +++ b/coolest/template/classes/psf.py @@ -8,6 +8,7 @@ 'PSF', 'PixelatedPSF', 'GaussianPSF', + 'UnspecifiedPSF', ] SUPPORTED_CHOICES = list(set(__all__) - {'PSF'}) @@ -75,3 +76,18 @@ def __init__(self, fwhm: float = 0.0, description: str = None) -> None: psf_type = self.__class__.__name__ super().__init__(psf_type, description=description, fwhm=fwhm) + + +class UnspecifiedPSF(PSF): + """Can be used when the PSF is not, or can not be specified. May be used + with e.g. interferometric data. + + Parameters + ---------- + description : str, optional + Any details regarding the way the PSF has been estimated, by default None + """ + + def __init__(self, description: str = None) -> None: + psf_type = self.__class__.__name__ + super().__init__(psf_type, description=description) \ No newline at end of file diff --git a/coolest/template/json.py b/coolest/template/json.py index baf8657..df6a9c3 100644 --- a/coolest/template/json.py +++ b/coolest/template/json.py @@ -1,7 +1,6 @@ import os import json import jsonpickle -import math from coolest.template.standard import COOLEST from coolest.template.lazy import * @@ -88,7 +87,7 @@ def dump_jsonpickle(self): with open(json_path, 'w') as f: f.write(result) - def load(self, skip_jsonpickle=False, validate=True, verbose=True): + def load(self, skip_jsonpickle=False, as_object=True, validate=True, verbose=True): """Read the JSON template file and build up the corresponding COOLEST object. It will first try to load the '_pyAPI' template if it exists using `jsonpickle`, otherwise it will fall back to reading the pure json template. @@ -97,6 +96,10 @@ def load(self, skip_jsonpickle=False, validate=True, verbose=True): ---------- skip_jsonpickle : bool, optional If True, will not try to read the _pyAPI template with jsonpickle first, by default False + as_object : bool, optional + If False, returns the JSON as a plain dictionary instead, by default True + validate : bool, optional + If True, performs some consistency checks on the COOLEST object, by default True verbose : bool, optional If True, prints useful output for debugging, by default False @@ -108,12 +111,15 @@ def load(self, skip_jsonpickle=False, validate=True, verbose=True): json_path = self.path + '.json' jsonpickle_path = self.path + self._api_suffix + '.json' if os.path.exists(jsonpickle_path) and not skip_jsonpickle: + if not as_object: + raise ValueError("Cannot load the JSON template with jsonpickle as a dictionary") instance = self.load_jsonpickle(jsonpickle_path) else: if verbose: print(f"Template file '{jsonpickle_path}' not found, now trying to read '{json_path}'.") - instance = self.load_simple(json_path, as_object=True, validate=validate) - assert isinstance(instance, COOLEST) + instance = self.load_simple(json_path, as_object=as_object, validate=validate) + if as_object: + assert isinstance(instance, COOLEST) return instance def load_simple(self, json_path, as_object=True, validate=True): @@ -124,7 +130,7 @@ def load_simple(self, json_path, as_object=True, validate=True): json_path: str Path to the json file to be read. as_object : bool, optional - _description_, by default True + If False, returns the JSON as a plain dictionary instead, by default True Returns ------- @@ -228,15 +234,6 @@ class constructors called during instantiation of the COOLEST object. ValueError In case observed instrumental pixel sizes are inconsistent """ - # PIXEL SIZE - instru_pix_size = coolest.instrument.pixel_size - obs_pix_size = coolest.observation.pixels.pixel_size - isclose_bool = math.isclose(instru_pix_size, obs_pix_size, - rel_tol=1e-09, abs_tol=0.0) - if obs_pix_size not in (0, None) and not isclose_bool: - raise ValueError(f"Pixel size of observation ({obs_pix_size}) is inconsistent with " - f"the instrument pixel size ({instru_pix_size})") - # INSTANCE METHODS coolest.observation.check_consistency_with_instrument(coolest.instrument) if coolest.likelihoods is not None: coolest.likelihoods.check_consistency_with_observation(coolest.observation) From 164e4de8644b3e6e8b4959b20fd6d04b184902eb Mon Sep 17 00:00:00 2001 From: Aymeric Galan Date: Mon, 7 Apr 2025 12:17:06 +0200 Subject: [PATCH 2/2] Update template generation notebook with example using unspecified properties --- docs/notebooks/02-generate_template.ipynb | 410 ++++++++++- .../template_dir/coolest_template.json | 5 +- .../template_dir/coolest_template_doc.json | 11 +- .../template_dir/coolest_template_mock.json | 4 +- .../template_dir/coolest_template_pyAPI.json | 11 +- .../coolest_template_unspecified.json | 643 ++++++++++++++++++ 6 files changed, 1067 insertions(+), 17 deletions(-) create mode 100644 docs/notebooks/template_dir/coolest_template_unspecified.json diff --git a/docs/notebooks/02-generate_template.ipynb b/docs/notebooks/02-generate_template.ipynb index 826f608..f9eb273 100644 --- a/docs/notebooks/02-generate_template.ipynb +++ b/docs/notebooks/02-generate_template.ipynb @@ -11,7 +11,7 @@ "\n", "__author__: @aymgal\n", "\n", - "__last update__: 11/07/23" + "__last update__: 07/04/25" ] }, { @@ -210,11 +210,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "[,\n", - " ,\n", - " ,\n", - " ,\n", - " ]\n" + "[,\n", + " ,\n", + " ,\n", + " ,\n", + " ]\n" ] } ], @@ -319,7 +319,7 @@ "output_type": "stream", "text": [ "All parameters with name 'q' that are not fixed:\n", - "[, , , ]\n", + "[, , , ]\n", "\n" ] } @@ -390,6 +390,402 @@ " check_external_files=True)\n", "serializer_doc.dump_simple()" ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Cases with unspecified data properties\n", + "\n", + "For instance, interferometric data have specific needs when it comes to defined noise properties, the PSF model, etc. In COOLEST you can set the corresponding properties of the `Instrument` and `Observation` of the template with `None` when these are not well defined, or not yet properly supported by the standard." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Template file '/Users/aymgal/Science/packages/my_packages/coolest/docs/notebooks/template_dir/coolest_template_unspecified_pyAPI.json' not found, now trying to read '/Users/aymgal/Science/packages/my_packages/coolest/docs/notebooks/template_dir/coolest_template_unspecified.json'.\n" + ] + } + ], + "source": [ + "# Observation with no 'pixels' nor properly defined noise\n", + "observation_unspecified = Observation(pixels=None, noise=None)\n", + "\n", + "# Instrument with no properly defined PSF nor readout noise\n", + "instrument_unspecified = Instrument(\n", + " pixel_size=None, # pixel size\n", + " name='interferometric instrument with no PSF',\n", + " readout_noise=None, \n", + " band='350 GHz',\n", + " psf=None,\n", + ")\n", + "\n", + "# Master object for the standard\n", + "coolest_unspecified = COOLEST(\n", + " 'MAP',\n", + " origin,\n", + " entity_list,\n", + " observation_unspecified, \n", + " instrument_unspecified, \n", + " cosmology,\n", + ")\n", + "\n", + "# export as human-readable JSON file\n", + "serializer = JSONSerializer(\n", + " os.path.join(os.getcwd(), TEMPLATE_DIR, TEMPLATE_NAME+\"_unspecified\"), \n", + " obj=coolest_unspecified,\n", + " check_external_files=False,\n", + ")\n", + "serializer.dump_simple()\n", + "\n", + "# check that loading the content again works well\n", + "coolest_unspecified_2 = serializer.load()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Load the template just as a dictionary" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Template file '/Users/aymgal/Science/packages/my_packages/coolest/docs/notebooks/template_dir/coolest_template_unspecified_pyAPI.json' not found, now trying to read '/Users/aymgal/Science/packages/my_packages/coolest/docs/notebooks/template_dir/coolest_template_unspecified.json'.\n", + "{'coordinates_origin': {'dec': '-08d45m51.48s', 'ra': '00h11m20.244s'},\n", + " 'cosmology': {'H0': 73.0, 'Om0': 0.3, 'astropy_name': 'FlatLambdaCDM'},\n", + " 'instrument': {'band': '350 GHz',\n", + " 'name': 'interferometric instrument with no PSF',\n", + " 'pixel_size': None,\n", + " 'psf': {'description': None, 'type': 'UnspecifiedPSF'},\n", + " 'readout_noise': None},\n", + " 'lensing_entities': [{'mass_model': [{'id': '0-massfield-mass-0-ExternalShear',\n", + " 'parameters': {'gamma_ext': {'fixed': False,\n", + " 'id': '0-massfield-mass-0-ExternalShear-gamma_ext',\n", + " 'point_estimate': {'value': 0.07},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'phi_ext': {'fixed': False,\n", + " 'id': '0-massfield-mass-0-ExternalShear-phi_ext',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}}},\n", + " 'type': 'ExternalShear'}],\n", + " 'name': 'my lovely external shear',\n", + " 'redshift': 0.5,\n", + " 'type': 'MassField'},\n", + " {'light_model': [{'id': '1-galaxy-light-0-Sersic',\n", + " 'parameters': {'I_eff': {'fixed': False,\n", + " 'id': '1-galaxy-light-0-Sersic-I_eff',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'center_x': {'fixed': False,\n", + " 'id': '1-galaxy-light-0-Sersic-center_x',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'center_y': {'fixed': False,\n", + " 'id': '1-galaxy-light-0-Sersic-center_y',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'n': {'fixed': False,\n", + " 'id': '1-galaxy-light-0-Sersic-n',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'phi': {'fixed': False,\n", + " 'id': '1-galaxy-light-0-Sersic-phi',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'q': {'fixed': False,\n", + " 'id': '1-galaxy-light-0-Sersic-q',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'theta_eff': {'fixed': False,\n", + " 'id': '1-galaxy-light-0-Sersic-theta_eff',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}}},\n", + " 'type': 'Sersic'},\n", + " {'id': '1-galaxy-light-1-Sersic',\n", + " 'parameters': {'I_eff': {'fixed': False,\n", + " 'id': '1-galaxy-light-1-Sersic-I_eff',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'center_x': {'fixed': False,\n", + " 'id': '1-galaxy-light-1-Sersic-center_x',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'center_y': {'fixed': False,\n", + " 'id': '1-galaxy-light-1-Sersic-center_y',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'n': {'fixed': False,\n", + " 'id': '1-galaxy-light-1-Sersic-n',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'phi': {'fixed': False,\n", + " 'id': '1-galaxy-light-1-Sersic-phi',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'q': {'fixed': False,\n", + " 'id': '1-galaxy-light-1-Sersic-q',\n", + " 'point_estimate': {'value': 0.89},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'theta_eff': {'fixed': False,\n", + " 'id': '1-galaxy-light-1-Sersic-theta_eff',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}}},\n", + " 'type': 'Sersic'}],\n", + " 'mass_model': [{'id': '1-galaxy-mass-0-PEMD',\n", + " 'parameters': {'center_x': {'fixed': False,\n", + " 'id': '1-galaxy-mass-0-PEMD-center_x',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'center_y': {'fixed': False,\n", + " 'id': '1-galaxy-mass-0-PEMD-center_y',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'gamma': {'fixed': False,\n", + " 'id': '1-galaxy-mass-0-PEMD-gamma',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'mean': 2.0,\n", + " 'type': 'GaussianPrior',\n", + " 'width': 0.2}},\n", + " 'phi': {'fixed': False,\n", + " 'id': '1-galaxy-mass-0-PEMD-phi',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'q': {'fixed': False,\n", + " 'id': '1-galaxy-mass-0-PEMD-q',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'theta_E': {'fixed': False,\n", + " 'id': '1-galaxy-mass-0-PEMD-theta_E',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}}},\n", + " 'type': 'PEMD'},\n", + " {'id': '1-galaxy-mass-1-PixelatedRegularGridPotential',\n", + " 'parameters': {'pixels': {'field_of_view_x': [-3.0,\n", + " 1.0],\n", + " 'field_of_view_y': [-2.0,\n", + " 2.0],\n", + " 'fits_file': {'path': 'regul_grid_image.fits'},\n", + " 'id': '1-galaxy-mass-1-PixelatedRegularGridPotential-pixels',\n", + " 'num_pix_x': 0,\n", + " 'num_pix_y': 0}},\n", + " 'type': 'PixelatedRegularGridPotential'}],\n", + " 'name': 'a lens galaxy',\n", + " 'redshift': 0.5,\n", + " 'type': 'Galaxy'},\n", + " {'light_model': [{'id': '2-galaxy-light-0-Sersic',\n", + " 'parameters': {'I_eff': {'fixed': False,\n", + " 'id': '2-galaxy-light-0-Sersic-I_eff',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'center_x': {'fixed': False,\n", + " 'id': '2-galaxy-light-0-Sersic-center_x',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'center_y': {'fixed': False,\n", + " 'id': '2-galaxy-light-0-Sersic-center_y',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'n': {'fixed': False,\n", + " 'id': '2-galaxy-light-0-Sersic-n',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'phi': {'fixed': False,\n", + " 'id': '2-galaxy-light-0-Sersic-phi',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'q': {'fixed': False,\n", + " 'id': '2-galaxy-light-0-Sersic-q',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': None,\n", + " 'median': None,\n", + " 'percentile_16th': None,\n", + " 'percentile_84th': None},\n", + " 'prior': {'type': None}},\n", + " 'theta_eff': {'fixed': False,\n", + " 'id': '2-galaxy-light-0-Sersic-theta_eff',\n", + " 'point_estimate': {'value': None},\n", + " 'posterior_stats': {'mean': 0.11,\n", + " 'median': 0.15,\n", + " 'percentile_16th': 0.03,\n", + " 'percentile_84th': 0.05},\n", + " 'prior': {'type': None}}},\n", + " 'type': 'Sersic'}],\n", + " 'mass_model': [],\n", + " 'name': 'a source galaxy',\n", + " 'redshift': 2.0,\n", + " 'type': 'Galaxy'},\n", + " {'light_model': [{'id': '3-galaxy-light-0-PixelatedRegularGrid',\n", + " 'parameters': {'pixels': {'field_of_view_x': [-3.0,\n", + " 1.0],\n", + " 'field_of_view_y': [-2.0,\n", + " 2.0],\n", + " 'fits_file': {'path': 'regul_grid_image.fits'},\n", + " 'id': '3-galaxy-light-0-PixelatedRegularGrid-pixels',\n", + " 'num_pix_x': 0,\n", + " 'num_pix_y': 0}},\n", + " 'type': 'PixelatedRegularGrid'}],\n", + " 'mass_model': [],\n", + " 'name': 'another source',\n", + " 'redshift': 1.5,\n", + " 'type': 'Galaxy'},\n", + " {'light_model': [{'id': '4-galaxy-light-0-IrregularGrid',\n", + " 'parameters': {'pixels': {'field_of_view_x': [0,\n", + " 0],\n", + " 'field_of_view_y': [0,\n", + " 0],\n", + " 'fits_file': {'path': 'irreg_grid_pixels.fits'},\n", + " 'id': '4-galaxy-light-0-IrregularGrid-pixels',\n", + " 'num_pix': 0}},\n", + " 'type': 'IrregularGrid'}],\n", + " 'mass_model': [],\n", + " 'name': 'a VKL source',\n", + " 'redshift': 1.2,\n", + " 'type': 'Galaxy'}],\n", + " 'likelihoods': None,\n", + " 'meta': {'coolest.__version__': '0.1.9'},\n", + " 'mode': 'MAP',\n", + " 'observation': {'exposure_time': None,\n", + " 'mag_sky_brightness': None,\n", + " 'mag_zero_point': None,\n", + " 'noise': {'type': 'UnspecifiedNoise'},\n", + " 'pixels': {'fits_file': {'path': None}}},\n", + " 'standard': 'COOLEST'}\n" + ] + } + ], + "source": [ + "# One can also print the content of the JSON just as plan dictionary\n", + "pprint(serializer.load(as_object=False))" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { diff --git a/docs/notebooks/template_dir/coolest_template.json b/docs/notebooks/template_dir/coolest_template.json index 6b66f33..c0ee444 100644 --- a/docs/notebooks/template_dir/coolest_template.json +++ b/docs/notebooks/template_dir/coolest_template.json @@ -636,7 +636,10 @@ "type": "Galaxy" } ], - "meta": {}, + "likelihoods": null, + "meta": { + "coolest.__version__": "0.1.9" + }, "mode": "MAP", "observation": { "exposure_time": null, diff --git a/docs/notebooks/template_dir/coolest_template_doc.json b/docs/notebooks/template_dir/coolest_template_doc.json index 3873de8..33867d6 100644 --- a/docs/notebooks/template_dir/coolest_template_doc.json +++ b/docs/notebooks/template_dir/coolest_template_doc.json @@ -12,7 +12,7 @@ }, "instrument": { "band": "F160W", - "documentation": "Defines the instrument used for the observation.\n This includes the name of the telescope and detector, the filter, \n the pixel size, the readout noise and the point spread function (PSF).\n\n Parameters\n ----------\n pixel_size : float\n Size in arcseconds of a single detector pixel.\n name : str, optional\n Name of the instrument, by default \"\"\n band : str, optional\n Name of the filter, by default \"\"\n readout_noise : float, optional\n Readout noise (in electrons), by default 0.\n psf : PSF, optional\n Instance of PSF object, by default None", + "documentation": "Defines the instrument used for the observation.\n This includes the name of the telescope and detector, the filter, \n the pixel size, the readout noise and the point spread function (PSF).\n\n Parameters\n ----------\n pixel_size : float\n Size in arcseconds of a single detector pixel, by default None.\n name : str, optional\n Name of the instrument, by default \"\"\n band : str, optional\n Name of the filter, by default \"\"\n readout_noise : float, optional\n Readout noise (in electrons) when it is relevant to the instrument, \n by default None.\n psf : PSF, optional\n Instance of PSF object, by default None (i.e. UnspecifiedPSF).", "name": "some instrument", "pixel_size": 0.08, "psf": { @@ -43,7 +43,7 @@ "documentation": "Generic field of massive objects, for instance an external shear field.\n\n Parameters\n ----------\n name : str\n Name associated to that shear component.\n redshift : float\n Redshift associated to that shear component, if needed.\n mass_model : MassModel, optional\n Mass model of the field, by default None", "mass_model": [ { - "documentation": "External shear defined with a strength and orientation.\n \n This profile is described by the following parameters:\n\n - 'gamma_ext': strength of the shear field\n - 'phi_ext': orientation of the shear field", + "documentation": "External shear defined with a strength and orientation.\n The 'origin' of the external shear is by convention fixed to coordinates (0, 0).\n \n This profile is described by the following parameters:\n\n - 'gamma_ext': strength of the shear field\n - 'phi_ext': orientation of the shear field", "parameters": { "gamma_ext": { "definition_range": { @@ -528,10 +528,13 @@ "type": "Galaxy" } ], - "meta": {}, + "likelihoods": null, + "meta": { + "coolest.__version__": "0.1.9" + }, "mode": "DOC", "observation": { - "documentation": "Defines the observation itself, that is the image pixels, \n the exposure time, the noise model and/or properties, the magnitude \n zero-point and sky brightness.\n\n Parameters\n ----------\n pixels : PixelatedRegularGrid, optional\n Regular 2D Grid instance for the observed / mock data pixels, by default None\n noise : Noise, optional\n Instance of a Noise object associated with the modeling \n of the data pixels, by default None\n mag_zero_point : float, optional\n Zero-point magnitude, which corresponds to the 1 electron per second\n hitting the detecor (given in mag), by default None\n mag_sky_brightness : float, optional\n Magnitude due to sky brightness (given in mag per arcsec^2), \n by default None", + "documentation": "Defines the observation itself, that is the image pixels, \n the exposure time, the noise model and/or properties, the magnitude \n zero-point and sky brightness.\n\n Parameters\n ----------\n pixels : PixelatedRegularGrid, optional\n Regular 2D Grid instance for the observed / mock data pixels, by default None\n noise : Noise, optional\n Instance of a Noise object associated with the modeling \n of the data pixels, by default None\n mag_zero_point : float, optional\n Zero-point magnitude, which corresponds to the 1 electron per second\n hitting the detector (given in mag), by default None\n mag_sky_brightness : float, optional\n Magnitude due to sky brightness (given in mag per arcsec^2), \n by default None", "exposure_time": null, "mag_sky_brightness": null, "mag_zero_point": null, diff --git a/docs/notebooks/template_dir/coolest_template_mock.json b/docs/notebooks/template_dir/coolest_template_mock.json index a5207cf..041db84 100644 --- a/docs/notebooks/template_dir/coolest_template_mock.json +++ b/docs/notebooks/template_dir/coolest_template_mock.json @@ -433,7 +433,9 @@ "type": "Galaxy" } ], - "meta": {}, + "meta": { + "coolest.__version__": "0.1.9" + }, "mode": "MOCK", "observation": { "exposure_time": null, diff --git a/docs/notebooks/template_dir/coolest_template_pyAPI.json b/docs/notebooks/template_dir/coolest_template_pyAPI.json index ab805a6..eb30983 100644 --- a/docs/notebooks/template_dir/coolest_template_pyAPI.json +++ b/docs/notebooks/template_dir/coolest_template_pyAPI.json @@ -83,7 +83,7 @@ } }, "id": "0-massfield-mass-0-ExternalShear", - "documentation": "External shear defined with a strength and orientation.\n \n This profile is described by the following parameters:\n\n - 'gamma_ext': strength of the shear field\n - 'phi_ext': orientation of the shear field" + "documentation": "External shear defined with a strength and orientation.\n The 'origin' of the external shear is by convention fixed to coordinates (0, 0).\n \n This profile is described by the following parameters:\n\n - 'gamma_ext': strength of the shear field\n - 'phi_ext': orientation of the shear field" } ] }, @@ -1104,7 +1104,7 @@ "with_target_shot_noise": true, "documentation": "Noise properties are computed directly based on the observed \n or modeled flux, and on the Instrument (e.g., readout noise) and \n Observation (e.g., exposure time, sky brightness, etc.) properties.\n\n Parameters\n ----------\n with_readout_noise : bool, optional\n If True, the noise includes readout noise from the detector, by default True\n with_sky_shot_noise : bool, optional\n If True, the noise includes shot noise from sky background flux \n (as the Gaussian approximation of the Poisson noise), by default True\n with_target_shot_noise : bool, optional\n If True, the noise includes shot noise from the target flux \n (as the Gaussian approximation of the Poisson noise), by default True" }, - "documentation": "Defines the observation itself, that is the image pixels, \n the exposure time, the noise model and/or properties, the magnitude \n zero-point and sky brightness.\n\n Parameters\n ----------\n pixels : PixelatedRegularGrid, optional\n Regular 2D Grid instance for the observed / mock data pixels, by default None\n noise : Noise, optional\n Instance of a Noise object associated with the modeling \n of the data pixels, by default None\n mag_zero_point : float, optional\n Zero-point magnitude, which corresponds to the 1 electron per second\n hitting the detecor (given in mag), by default None\n mag_sky_brightness : float, optional\n Magnitude due to sky brightness (given in mag per arcsec^2), \n by default None" + "documentation": "Defines the observation itself, that is the image pixels, \n the exposure time, the noise model and/or properties, the magnitude \n zero-point and sky brightness.\n\n Parameters\n ----------\n pixels : PixelatedRegularGrid, optional\n Regular 2D Grid instance for the observed / mock data pixels, by default None\n noise : Noise, optional\n Instance of a Noise object associated with the modeling \n of the data pixels, by default None\n mag_zero_point : float, optional\n Zero-point magnitude, which corresponds to the 1 electron per second\n hitting the detector (given in mag), by default None\n mag_sky_brightness : float, optional\n Magnitude due to sky brightness (given in mag per arcsec^2), \n by default None" }, "instrument": { "py/object": "coolest.template.classes.instrument.Instrument", @@ -1141,7 +1141,7 @@ }, "documentation": "PSF modeled as a 2D image.\n\n Parameters\n ----------\n pixels : PixelatedRegularGrid, optional\n Grid class that holds pixel values and the extent of \n the PSF kernel, by default None\n description : str, optional\n Any details regarding the way the PSF has been estimated, by default None" }, - "documentation": "Defines the instrument used for the observation.\n This includes the name of the telescope and detector, the filter, \n the pixel size, the readout noise and the point spread function (PSF).\n\n Parameters\n ----------\n pixel_size : float\n Size in arcseconds of a single detector pixel.\n name : str, optional\n Name of the instrument, by default \"\"\n band : str, optional\n Name of the filter, by default \"\"\n readout_noise : float, optional\n Readout noise (in electrons), by default 0.\n psf : PSF, optional\n Instance of PSF object, by default None" + "documentation": "Defines the instrument used for the observation.\n This includes the name of the telescope and detector, the filter, \n the pixel size, the readout noise and the point spread function (PSF).\n\n Parameters\n ----------\n pixel_size : float\n Size in arcseconds of a single detector pixel, by default None.\n name : str, optional\n Name of the instrument, by default \"\"\n band : str, optional\n Name of the filter, by default \"\"\n readout_noise : float, optional\n Readout noise (in electrons) when it is relevant to the instrument, \n by default None.\n psf : PSF, optional\n Instance of PSF object, by default None (i.e. UnspecifiedPSF)." }, "cosmology": { "py/object": "coolest.template.classes.cosmology.Cosmology", @@ -1150,6 +1150,9 @@ "astropy_name": "FlatLambdaCDM", "documentation": "Defines the cosmological model. \n Currently, only FlatLambdaCDM from astropy is supported, based on H0 and Omega_m.\n\n Parameters\n ----------\n H0 : float\n Hubble constant, in km/s/Mpc\n Om0 : float\n Matter density at present time\n astropy_name : str, optional\n `astropy` model name, by default 'FlatLambdaCDM'" }, + "likelihoods": null, "standard": "COOLEST", - "meta": {} + "meta": { + "coolest.__version__": "0.1.9" + } } \ No newline at end of file diff --git a/docs/notebooks/template_dir/coolest_template_unspecified.json b/docs/notebooks/template_dir/coolest_template_unspecified.json new file mode 100644 index 0000000..4cab9c3 --- /dev/null +++ b/docs/notebooks/template_dir/coolest_template_unspecified.json @@ -0,0 +1,643 @@ +{ + "coordinates_origin": { + "dec": "-08d45m51.48s", + "ra": "00h11m20.244s" + }, + "cosmology": { + "H0": 73.0, + "Om0": 0.3, + "astropy_name": "FlatLambdaCDM" + }, + "instrument": { + "band": "350 GHz", + "name": "interferometric instrument with no PSF", + "pixel_size": null, + "psf": { + "description": null, + "type": "UnspecifiedPSF" + }, + "readout_noise": null + }, + "lensing_entities": [ + { + "mass_model": [ + { + "id": "0-massfield-mass-0-ExternalShear", + "parameters": { + "gamma_ext": { + "fixed": false, + "id": "0-massfield-mass-0-ExternalShear-gamma_ext", + "point_estimate": { + "value": 0.07 + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "phi_ext": { + "fixed": false, + "id": "0-massfield-mass-0-ExternalShear-phi_ext", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + } + }, + "type": "ExternalShear" + } + ], + "name": "my lovely external shear", + "redshift": 0.5, + "type": "MassField" + }, + { + "light_model": [ + { + "id": "1-galaxy-light-0-Sersic", + "parameters": { + "I_eff": { + "fixed": false, + "id": "1-galaxy-light-0-Sersic-I_eff", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "center_x": { + "fixed": false, + "id": "1-galaxy-light-0-Sersic-center_x", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "center_y": { + "fixed": false, + "id": "1-galaxy-light-0-Sersic-center_y", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "n": { + "fixed": false, + "id": "1-galaxy-light-0-Sersic-n", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "phi": { + "fixed": false, + "id": "1-galaxy-light-0-Sersic-phi", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "q": { + "fixed": false, + "id": "1-galaxy-light-0-Sersic-q", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "theta_eff": { + "fixed": false, + "id": "1-galaxy-light-0-Sersic-theta_eff", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + } + }, + "type": "Sersic" + }, + { + "id": "1-galaxy-light-1-Sersic", + "parameters": { + "I_eff": { + "fixed": false, + "id": "1-galaxy-light-1-Sersic-I_eff", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "center_x": { + "fixed": false, + "id": "1-galaxy-light-1-Sersic-center_x", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "center_y": { + "fixed": false, + "id": "1-galaxy-light-1-Sersic-center_y", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "n": { + "fixed": false, + "id": "1-galaxy-light-1-Sersic-n", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "phi": { + "fixed": false, + "id": "1-galaxy-light-1-Sersic-phi", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "q": { + "fixed": false, + "id": "1-galaxy-light-1-Sersic-q", + "point_estimate": { + "value": 0.89 + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "theta_eff": { + "fixed": false, + "id": "1-galaxy-light-1-Sersic-theta_eff", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + } + }, + "type": "Sersic" + } + ], + "mass_model": [ + { + "id": "1-galaxy-mass-0-PEMD", + "parameters": { + "center_x": { + "fixed": false, + "id": "1-galaxy-mass-0-PEMD-center_x", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "center_y": { + "fixed": false, + "id": "1-galaxy-mass-0-PEMD-center_y", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "gamma": { + "fixed": false, + "id": "1-galaxy-mass-0-PEMD-gamma", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "mean": 2.0, + "type": "GaussianPrior", + "width": 0.2 + } + }, + "phi": { + "fixed": false, + "id": "1-galaxy-mass-0-PEMD-phi", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "q": { + "fixed": false, + "id": "1-galaxy-mass-0-PEMD-q", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "theta_E": { + "fixed": false, + "id": "1-galaxy-mass-0-PEMD-theta_E", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + } + }, + "type": "PEMD" + }, + { + "id": "1-galaxy-mass-1-PixelatedRegularGridPotential", + "parameters": { + "pixels": { + "field_of_view_x": [ + -3.0, + 1.0 + ], + "field_of_view_y": [ + -2.0, + 2.0 + ], + "fits_file": { + "path": "regul_grid_image.fits" + }, + "id": "1-galaxy-mass-1-PixelatedRegularGridPotential-pixels", + "num_pix_x": 0, + "num_pix_y": 0 + } + }, + "type": "PixelatedRegularGridPotential" + } + ], + "name": "a lens galaxy", + "redshift": 0.5, + "type": "Galaxy" + }, + { + "light_model": [ + { + "id": "2-galaxy-light-0-Sersic", + "parameters": { + "I_eff": { + "fixed": false, + "id": "2-galaxy-light-0-Sersic-I_eff", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "center_x": { + "fixed": false, + "id": "2-galaxy-light-0-Sersic-center_x", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "center_y": { + "fixed": false, + "id": "2-galaxy-light-0-Sersic-center_y", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "n": { + "fixed": false, + "id": "2-galaxy-light-0-Sersic-n", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "phi": { + "fixed": false, + "id": "2-galaxy-light-0-Sersic-phi", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "q": { + "fixed": false, + "id": "2-galaxy-light-0-Sersic-q", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": null, + "median": null, + "percentile_16th": null, + "percentile_84th": null + }, + "prior": { + "type": null + } + }, + "theta_eff": { + "fixed": false, + "id": "2-galaxy-light-0-Sersic-theta_eff", + "point_estimate": { + "value": null + }, + "posterior_stats": { + "mean": 0.11, + "median": 0.15, + "percentile_16th": 0.03, + "percentile_84th": 0.05 + }, + "prior": { + "type": null + } + } + }, + "type": "Sersic" + } + ], + "mass_model": [], + "name": "a source galaxy", + "redshift": 2.0, + "type": "Galaxy" + }, + { + "light_model": [ + { + "id": "3-galaxy-light-0-PixelatedRegularGrid", + "parameters": { + "pixels": { + "field_of_view_x": [ + -3.0, + 1.0 + ], + "field_of_view_y": [ + -2.0, + 2.0 + ], + "fits_file": { + "path": "regul_grid_image.fits" + }, + "id": "3-galaxy-light-0-PixelatedRegularGrid-pixels", + "num_pix_x": 0, + "num_pix_y": 0 + } + }, + "type": "PixelatedRegularGrid" + } + ], + "mass_model": [], + "name": "another source", + "redshift": 1.5, + "type": "Galaxy" + }, + { + "light_model": [ + { + "id": "4-galaxy-light-0-IrregularGrid", + "parameters": { + "pixels": { + "field_of_view_x": [ + 0, + 0 + ], + "field_of_view_y": [ + 0, + 0 + ], + "fits_file": { + "path": "irreg_grid_pixels.fits" + }, + "id": "4-galaxy-light-0-IrregularGrid-pixels", + "num_pix": 0 + } + }, + "type": "IrregularGrid" + } + ], + "mass_model": [], + "name": "a VKL source", + "redshift": 1.2, + "type": "Galaxy" + } + ], + "likelihoods": null, + "meta": { + "coolest.__version__": "0.1.9" + }, + "mode": "MAP", + "observation": { + "exposure_time": null, + "mag_sky_brightness": null, + "mag_zero_point": null, + "noise": { + "type": "UnspecifiedNoise" + }, + "pixels": { + "fits_file": { + "path": null + } + } + }, + "standard": "COOLEST" +} \ No newline at end of file