From 68a211db3e9322fd5d0b80f9200c5fbba59805f2 Mon Sep 17 00:00:00 2001 From: mateusz Date: Tue, 12 Dec 2023 09:12:25 +0100 Subject: [PATCH 01/13] example_16: added soft no negative blending flux constrains for both sources and color prior --- examples/example_16/ob03235_2_full.yaml | 11 +- examples/example_16/ulens_model_fit.py | 147 ++++++++++++++++++++++-- source/MulensModel/data | 1 - 3 files changed, 148 insertions(+), 11 deletions(-) delete mode 120000 source/MulensModel/data diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index b660b92e4..8b1fac17e 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -33,9 +33,18 @@ starting_parameters: s: uniform 1.09 1.11 alpha: gauss 224.0 1.0 fit_constraints: - negative_blending_flux_sigma_mag: 20. + negative_blending_flux_sigma_mag: 20. + #you can specific which source flux should be constrain : sigma source_number(s) + #negative_blending_flux_sigma_mag: 20. 2 # Alternative sharp constraint: # no_negative_blending_flux: True + #color constrains: gauss mu sigma flux_in_numerator flux_in_denominator + color : gauss 25. 5. 1 2 + #Alternative + #color source 1 : gauss 25. 5. 1 2 + #and/or + #color source 2 : gauss 25. 5. 1 2 + prior: t_E: Mroz et al. 2017 # Other possibility: diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index 614f29c2a..8a0d3bc4a 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -1414,7 +1414,15 @@ def _parse_fit_constraints(self): allowed_keys_flux = { "no_negative_blending_flux", "negative_blending_flux_sigma_mag"} - allowed_keys = {*allowed_keys_flux, "prior"} + + allowed_keys_color={'color', + 'color source 1', + 'color source 2',} + + + allowed_keys = {*allowed_keys_flux, + *allowed_keys_color, + "prior"} used_keys = set(self._fit_constraints.keys()) if len(used_keys - allowed_keys) > 0: raise ValueError('unrecognized constraint: {:}'.format( @@ -1426,10 +1434,70 @@ def _parse_fit_constraints(self): if "no_negative_blending_flux" not in self._fit_constraints: self._fit_constraints["no_negative_blending_flux"] = False - key = "negative_blending_flux_sigma_mag" - if key in used_keys: - self._fit_constraints[key] = mm.Utils.get_flux_from_mag( - self._fit_constraints[key]) + if len(used_keys.intersection(allowed_keys_color))>=2 and ('color' in used_keys): + raise ValueError( + 'you cannot specify both color and '+ str(used_keys.intersection(allowed_keys_color)-{'color'})) + + for key in self._fit_constraints.keys(): + value=self._fit_constraints[key] + + if key == "negative_blending_flux_sigma_mag" : + + if isinstance(value, float): + words=[value] + else: + words=value.split() + + if len(words)==1: + sets=[] + for (j,idset) in enumerate(self._datasets): + sets.append(int(j)+1) + + elif 2<=len(words)<=(len(self._datasets)+1): + sets=[] + for (j,idset) in enumerate(words[1:]): + if 0=settings[3]>=len(self._datasets)+1) or (0>=settings[4]>=len(self._datasets)+1): + raise ValueError( + 'dataset number specified in color prior do not match with provided datasets') + + + self._fit_constraints[key] = settings + + if 'prior' in self._fit_constraints: self._parse_fit_constraints_prior() @@ -1462,6 +1530,8 @@ def _parse_fit_constraints_prior(self): if settings[2] < 0.: raise ValueError('sigma cannot be negative: ' + words[2]) priors[key] = settings + + else: raise KeyError( "Unrecognized key in fit_constraints/prior: " + key) @@ -1966,6 +2036,7 @@ def _ln_prior(self, theta): value = self._model.parameters.parameters[parameter] ln_prior += self._get_ln_prior_for_1_parameter( value, prior_settings) + else: raise ValueError('prior not handled: ' + parameter) @@ -2092,11 +2163,69 @@ def _run_flux_checks_ln_prior(self, fluxes): return outside key = "negative_blending_flux_sigma_mag" + + if key in self._fit_constraints: - blend_index = self._n_fluxes_per_dataset - 1 - if fluxes[blend_index] < 0.: - sigma = self._fit_constraints[key] - inside += -0.5 * (fluxes[blend_index] / sigma)**2 + + for (i, dataset) in enumerate(self._datasets): + if i+1 in self._fit_constraints[key][1]: + blend_index = ((i+1)*self._n_fluxes_per_dataset )- 1 + if fluxes[blend_index] < 0.: + sigma = self._fit_constraints[key][0] + inside += -0.5 * (fluxes[blend_index] / sigma)**2 + + key='color' + + if key in self._fit_constraints: + settings=self._fit_constraints[key] + if self._n_fluxes_per_dataset == 2 : + index1=(settings[3]-1)*self._n_fluxes_per_dataset + index2=(settings[4]-1)*self._n_fluxes_per_dataset + value=fluxes[index1]/fluxes[index2] + inside +=self._get_ln_prior_for_1_parameter( + value, settings[:-2]) + + if self._n_fluxes_per_dataset == 3 : + index1=(settings[3]-1)*self._n_fluxes_per_dataset + index2=(settings[4]-1)*self._n_fluxes_per_dataset + value=fluxes[index1]/fluxes[index2] + inside +=self._get_ln_prior_for_1_parameter( + value, settings[:-2]) + + + index1=((settings[3]-1)*self._n_fluxes_per_dataset)+1 + index2=((settings[4]-1)*self._n_fluxes_per_dataset)+1 + value=fluxes[index1]/fluxes[index2] + inside +=self._get_ln_prior_for_1_parameter( + value, settings[:-2]) + + + + key= 'color source 1' + if key in self._fit_constraints: + settings=self._fit_constraints[key] + index1=(settings[3]-1)*self._n_fluxes_per_dataset + index2=(settings[4]-1)*self._n_fluxes_per_dataset + value=fluxes[index1]/fluxes[index2] + inside +=self._get_ln_prior_for_1_parameter( + value, settings[:-2]) + + + + + key= 'color source 2' + if key in self._fit_constraints: + settings=self._fit_constraints[key] + index1=(settings[3]-1)*self._n_fluxes_per_dataset+1 + index2=(settings[4]-1)*self._n_fluxes_per_dataset+1 + value=fluxes[index1]/fluxes[index2] + inside +=self._get_ln_prior_for_1_parameter( + value, settings[:-2]) + + + + + return inside diff --git a/source/MulensModel/data b/source/MulensModel/data deleted file mode 120000 index e67b45590..000000000 --- a/source/MulensModel/data +++ /dev/null @@ -1 +0,0 @@ -../../data \ No newline at end of file From af94ae7ce5b128bfe5566a844bb6794045183e6c Mon Sep 17 00:00:00 2001 From: Mateusz Mroz Date: Thu, 9 May 2024 18:50:23 +0200 Subject: [PATCH 02/13] Raphaels corrections --- examples/example_16/ob03235_2_full.yaml | 8 +- examples/example_16/ulens_model_fit.py | 218 ++++++++++-------------- 2 files changed, 92 insertions(+), 134 deletions(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index 322b672c9..4cc4aadcf 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -34,13 +34,13 @@ starting_parameters: alpha: gauss 224.0 1.0 fit_constraints: negative_blending_flux_sigma_mag: 20. - #you can specific which source flux should be constrain : sigma source_number(s) - #negative_blending_flux_sigma_mag: 20. 2 + #one can specify for which dateset soft prior on blending flux should be applied: sigma dataset_number(s) + #negative_blending_flux_sigma_mag: 20. 1 3 # Alternative sharp constraint: # no_negative_blending_flux: True - #color constrains: gauss mu sigma flux_in_numerator flux_in_denominator + #color constrains, where color=flux_S_dataset_no._k/flux_S_dataset_no._m: gauss mu sigma k m color : gauss 25. 5. 1 2 - #Alternative + #Alternative for binary source models: #color source 1 : gauss 25. 5. 1 2 #and/or #color source 2 : gauss 25. 5. 1 2 diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index 50b50d89c..aa437c4c5 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -306,13 +306,14 @@ class UlensModelFit(object): These files will have three columns: time, residuals, and uncertainties. """ + def __init__( self, photometry_files, starting_parameters=None, prior_limits=None, model=None, fixed_parameters=None, min_values=None, max_values=None, fitting_parameters=None, fit_constraints=None, plots=None, other_output=None - ): + ): self._check_MM_version() self._photometry_files = photometry_files self._starting_parameters_input = starting_parameters @@ -462,7 +463,7 @@ def _set_default_parameters(self): xi_argument_of_latitude_reference='\\xi_u', xi_eccentricity='\\xi_e', xi_omega_periapsis='\\xi_{\\omege}', - ) + ) self._latex_conversion_other = dict() def _guess_fitting_method(self): @@ -1442,12 +1443,11 @@ def _parse_fit_constraints(self): allowed_keys_flux = { "no_negative_blending_flux", "negative_blending_flux_sigma_mag"} - - allowed_keys_color={'color', - 'color source 1', - 'color source 2',} - - + + allowed_keys_color = {'color', + 'color source 1', + 'color source 2', } + allowed_keys = {*allowed_keys_flux, *allowed_keys_color, "prior"} @@ -1462,70 +1462,54 @@ def _parse_fit_constraints(self): if "no_negative_blending_flux" not in self._fit_constraints: self._fit_constraints["no_negative_blending_flux"] = False - if len(used_keys.intersection(allowed_keys_color))>=2 and ('color' in used_keys): + if len(used_keys.intersection(allowed_keys_color)) >= 2 and ('color' in used_keys): raise ValueError( - 'you cannot specify both color and '+ str(used_keys.intersection(allowed_keys_color)-{'color'})) - - for key in self._fit_constraints.keys(): - value=self._fit_constraints[key] - - if key == "negative_blending_flux_sigma_mag" : - - if isinstance(value, float): - words=[value] - else: - words=value.split() - - if len(words)==1: - sets=[] - for (j,idset) in enumerate(self._datasets): - sets.append(int(j)+1) - - elif 2<=len(words)<=(len(self._datasets)+1): - sets=[] - for (j,idset) in enumerate(words[1:]): - if 0=settings[3]>=len(self._datasets)+1) or (0>=settings[4]>=len(self._datasets)+1): - raise ValueError( - 'dataset number specified in color prior do not match with provided datasets') - - - self._fit_constraints[key] = settings - - + 'you cannot specify both color and ' + str(used_keys.intersection(allowed_keys_color)-{'color'})) + + for key in self._fit_constraints.keys(): + value = self._fit_constraints[key] + + if key == "negative_blending_flux_sigma_mag": + + if isinstance(value, (float, int)): + sigma = float(value) + sets = list(range(1, len(self._datasets) + 1)) + else: + sigma = float(value.split()[0]) + sets = list(map(int, value.split()[1:])) + if len(sets) > len(self._datasets): + raise ValueError( + 'dataset number specified in negative_blending_flux_sigma_mag do not match with provided datasets') + + self._fit_constraints[key] = [ + mm.Utils.get_flux_from_mag(sigma), sets] + + elif key in ['color', 'color source 1', 'color source 2']: + + words = value.split() + if len(words) != 5 or words[0] != 'gauss': + msg = "Something went wrong in parsing prior for " + msg += "{:}: {:}" + if len(words) == 3 and words[0] == 'gauss': + msg += ' color priors require the specification of datasets that should be used for color calculation ' + raise ValueError(msg.format(key, value)) + try: + settings = [words[0], float(words[1]), float( + words[2]), int(words[3]), int(words[4])] + except Exception: + raise ValueError('error in parsing: ' + words[1] + " " + + words[2] + " " + words[3] + " " + words[4]) + if settings[2] < 0.: + raise ValueError('sigma cannot be negative: ' + words[2]) + if settings[3] == settings[4]: + raise ValueError( + "in " + key + " fluxes have to be from different datasets") + + if (0 >= settings[3] >= len(self._datasets)+1) or (0 >= settings[4] >= len(self._datasets)+1): + raise ValueError( + 'dataset number specified in color prior do not match with provided datasets') + + self._fit_constraints[key] = settings if 'prior' in self._fit_constraints: self._parse_fit_constraints_prior() @@ -1558,8 +1542,7 @@ def _parse_fit_constraints_prior(self): if settings[2] < 0.: raise ValueError('sigma cannot be negative: ' + words[2]) priors[key] = settings - - + else: raise KeyError( "Unrecognized key in fit_constraints/prior: " + key) @@ -2067,7 +2050,7 @@ def _ln_prior(self, theta): value = self._model.parameters.parameters[parameter] ln_prior += self._get_ln_prior_for_1_parameter( value, prior_settings) - + else: raise ValueError('prior not handled: ' + parameter) @@ -2080,8 +2063,8 @@ def _check_valid_Cassan08_trajectory(self): """ sampling = self._model.parameters.uniform_caustic_sampling valid = sampling.check_valid_trajectory( - self._model.parameters.x_caustic_in, - self._model.parameters.x_caustic_out) + self._model.parameters.x_caustic_in, + self._model.parameters.x_caustic_out) return valid def _get_ln_prior_for_1_parameter(self, value, settings): @@ -2181,6 +2164,16 @@ def _get_fluxes(self): return fluxes + def _sumup_inside_prior(self, fluxes, key, inside, idx_plus): + + settings = self._fit_constraints[key] + index1 = (settings[3]-1)*self._n_fluxes_per_dataset + idx_plus + index2 = (settings[4]-1)*self._n_fluxes_per_dataset + idx_plus + value = fluxes[index1]/fluxes[index2] + inside += self._get_ln_prior_for_1_parameter(value, settings[:-2]) + + return inside + def _run_flux_checks_ln_prior(self, fluxes): """ Run the checks on fluxes - are they in the prior? @@ -2194,69 +2187,34 @@ def _run_flux_checks_ln_prior(self, fluxes): return outside key = "negative_blending_flux_sigma_mag" - - + if key in self._fit_constraints: - + for (i, dataset) in enumerate(self._datasets): - if i+1 in self._fit_constraints[key][1]: - blend_index = ((i+1)*self._n_fluxes_per_dataset )- 1 + if i+1 in self._fit_constraints[key][1]: + blend_index = ((i+1)*self._n_fluxes_per_dataset) - 1 if fluxes[blend_index] < 0.: sigma = self._fit_constraints[key][0] inside += -0.5 * (fluxes[blend_index] / sigma)**2 - - key='color' + + key = 'color' if key in self._fit_constraints: - settings=self._fit_constraints[key] - if self._n_fluxes_per_dataset == 2 : - index1=(settings[3]-1)*self._n_fluxes_per_dataset - index2=(settings[4]-1)*self._n_fluxes_per_dataset - value=fluxes[index1]/fluxes[index2] - inside +=self._get_ln_prior_for_1_parameter( - value, settings[:-2]) - - if self._n_fluxes_per_dataset == 3 : - index1=(settings[3]-1)*self._n_fluxes_per_dataset - index2=(settings[4]-1)*self._n_fluxes_per_dataset - value=fluxes[index1]/fluxes[index2] - inside +=self._get_ln_prior_for_1_parameter( - value, settings[:-2]) - - - index1=((settings[3]-1)*self._n_fluxes_per_dataset)+1 - index2=((settings[4]-1)*self._n_fluxes_per_dataset)+1 - value=fluxes[index1]/fluxes[index2] - inside +=self._get_ln_prior_for_1_parameter( - value, settings[:-2]) - - - - key= 'color source 1' + settings = self._fit_constraints[key] + if self._n_fluxes_per_dataset == 2: + inside = self._sumup_inside_prior(fluxes, key, inside, 0) + + if self._n_fluxes_per_dataset == 3: + inside = self._sumup_inside_prior(fluxes, key, inside, 0) + inside = self._sumup_inside_prior(fluxes, key, inside, 1) + + key = 'color source 1' if key in self._fit_constraints: - settings=self._fit_constraints[key] - index1=(settings[3]-1)*self._n_fluxes_per_dataset - index2=(settings[4]-1)*self._n_fluxes_per_dataset - value=fluxes[index1]/fluxes[index2] - inside +=self._get_ln_prior_for_1_parameter( - value, settings[:-2]) - - - - - key= 'color source 2' + inside = self._sumup_inside_prior(fluxes, key, inside, 0) + + key = 'color source 2' if key in self._fit_constraints: - settings=self._fit_constraints[key] - index1=(settings[3]-1)*self._n_fluxes_per_dataset+1 - index2=(settings[4]-1)*self._n_fluxes_per_dataset+1 - value=fluxes[index1]/fluxes[index2] - inside +=self._get_ln_prior_for_1_parameter( - value, settings[:-2]) - - - - - + inside = self._sumup_inside_prior(fluxes, key, inside, 1) return inside From f66f1313cbbbcb85daa35c673d1de0cbd1ecf441 Mon Sep 17 00:00:00 2001 From: Mateusz Mroz Date: Thu, 9 May 2024 19:00:00 +0200 Subject: [PATCH 03/13] s ch --- examples/example_16/ob03235_2_full.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index 4cc4aadcf..300241a03 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -34,7 +34,7 @@ starting_parameters: alpha: gauss 224.0 1.0 fit_constraints: negative_blending_flux_sigma_mag: 20. - #one can specify for which dateset soft prior on blending flux should be applied: sigma dataset_number(s) + #one can specify for which dateset soft constrain on blending flux should be applied: sigma dataset_number(s) #negative_blending_flux_sigma_mag: 20. 1 3 # Alternative sharp constraint: # no_negative_blending_flux: True From e8796b615f0476265504af2778ba221c228e3094 Mon Sep 17 00:00:00 2001 From: Mateusz Mroz Date: Thu, 9 May 2024 19:01:15 +0200 Subject: [PATCH 04/13] S ch --- examples/example_16/ob03235_2_full.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index 300241a03..ed82b83c7 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -34,7 +34,7 @@ starting_parameters: alpha: gauss 224.0 1.0 fit_constraints: negative_blending_flux_sigma_mag: 20. - #one can specify for which dateset soft constrain on blending flux should be applied: sigma dataset_number(s) + #one can specify for which dataset soft constrain on blending flux should be applied: sigma dataset_number(s) #negative_blending_flux_sigma_mag: 20. 1 3 # Alternative sharp constraint: # no_negative_blending_flux: True From 6bab7ad5a4fed82287dd54ce74fb2547f384f1d5 Mon Sep 17 00:00:00 2001 From: Mateusz Mroz Date: Mon, 13 May 2024 17:40:49 +0200 Subject: [PATCH 05/13] color constrains put outside _parse_fit_constraints() dataset for color and blending constrain can be define by index or lable --- examples/example_16/ob03235_2_full.yaml | 10 +- examples/example_16/ulens_model_fit.py | 129 +++++++++++++++++------- 2 files changed, 96 insertions(+), 43 deletions(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index ed82b83c7..c5bb512cb 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -38,13 +38,13 @@ fit_constraints: #negative_blending_flux_sigma_mag: 20. 1 3 # Alternative sharp constraint: # no_negative_blending_flux: True - #color constrains, where color=flux_S_dataset_no._k/flux_S_dataset_no._m: gauss mu sigma k m - color : gauss 25. 5. 1 2 + #color constrains, where color=flux_S_dataset_k/flux_S_dataset_m: gauss mu sigma k m + color : gauss 25. 5. "OGLE I-band" "OB03235_MOA.txt" #Alternative for binary source models: - #color source 1 : gauss 25. 5. 1 2 + #color source 1 : gauss 25. 5. "OGLE I-band" "OB03235_MOA.txt" #and/or - #color source 2 : gauss 25. 5. 1 2 - + #color source 2 : gauss 25. 5. 0 1 + prior: t_E: Mroz et al. 2017 # Other possibility: diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index aa437c4c5..66eed00bc 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -9,6 +9,7 @@ import warnings import math import numpy as np +import shlex from scipy.interpolate import interp1d from matplotlib import pyplot as plt from matplotlib import gridspec, rcParams, rcParamsDefault @@ -1470,49 +1471,66 @@ def _parse_fit_constraints(self): value = self._fit_constraints[key] if key == "negative_blending_flux_sigma_mag": + self._parse_fit_constraints_soft_blending(key, value) - if isinstance(value, (float, int)): - sigma = float(value) - sets = list(range(1, len(self._datasets) + 1)) - else: - sigma = float(value.split()[0]) - sets = list(map(int, value.split()[1:])) - if len(sets) > len(self._datasets): - raise ValueError( - 'dataset number specified in negative_blending_flux_sigma_mag do not match with provided datasets') + elif key in ['color', 'color source 1', 'color source 2']: + self._parse_fit_constraints_color(key, value) - self._fit_constraints[key] = [ - mm.Utils.get_flux_from_mag(sigma), sets] + if 'prior' in self._fit_constraints: + self._parse_fit_constraints_prior() - elif key in ['color', 'color source 1', 'color source 2']: + def _parse_fit_constraints_soft_blending(self, key, value): + """ + Check if soft fit constraint on blending flux are correctly defined. + """ + if isinstance(value, (float, int)): + sigma = float(value) + sets = list(range(1, len(self._datasets) + 1)) + else: + sigma = float(value.split()[0]) + sets = list(map(int, value.split()[1:])) + if len(sets) > len(self._datasets): + raise ValueError( + 'dataset number specified in negative_blending_flux_sigma_mag do not match with provided datasets') - words = value.split() - if len(words) != 5 or words[0] != 'gauss': - msg = "Something went wrong in parsing prior for " - msg += "{:}: {:}" - if len(words) == 3 and words[0] == 'gauss': - msg += ' color priors require the specification of datasets that should be used for color calculation ' - raise ValueError(msg.format(key, value)) - try: - settings = [words[0], float(words[1]), float( - words[2]), int(words[3]), int(words[4])] - except Exception: - raise ValueError('error in parsing: ' + words[1] + " " + - words[2] + " " + words[3] + " " + words[4]) - if settings[2] < 0.: - raise ValueError('sigma cannot be negative: ' + words[2]) - if settings[3] == settings[4]: - raise ValueError( - "in " + key + " fluxes have to be from different datasets") + self._fit_constraints[key] = [ + mm.Utils.get_flux_from_mag(sigma), sets] - if (0 >= settings[3] >= len(self._datasets)+1) or (0 >= settings[4] >= len(self._datasets)+1): - raise ValueError( - 'dataset number specified in color prior do not match with provided datasets') + def _parse_fit_constraints_color(self, key, value): + """ + Check if fit constraint on color are correctly defined. + """ + words = shlex.split(value, posix=False) + if len(words) != 5 or words[0] != 'gauss': + msg = "Something went wrong in parsing prior for " + msg += "{:}: {:}" + if len(words) == 3 and words[0] == 'gauss': + msg += ' color priors require the specification of datasets that should be used for color calculation ' + raise ValueError(msg.format(key, value)) + try: + settings = [words[0], float(words[1]), float( + words[2]), words[3], words[4]] + except Exception: + raise ValueError('error in parsing: ' + words[1] + " " + + words[2] + " " + words[3] + " " + words[4]) + if settings[2] < 0.: + raise ValueError('sigma cannot be negative: ' + words[2]) + if settings[3] == settings[4]: + raise ValueError( + "in " + key + " fluxes have to be from different datasets") - self._fit_constraints[key] = settings + if isinstance(settings[3], str) and isinstance(settings[4], str): + settings[3] = settings[3].strip('"') + settings[4] = settings[4].strip('"') + settings[3] = self._get_no_of_dataset_by_lable(settings[3]) + settings[4] = self._get_no_of_dataset_by_lable(settings[4]) - if 'prior' in self._fit_constraints: - self._parse_fit_constraints_prior() + if isinstance(settings[3], int) and isinstance(settings[4], int): + if (0 >= settings[3] >= len(self._datasets)-1) or (0 >= settings[4] >= len(self._datasets)-1): + raise ValueError( + 'dataset specified in color prior do not match with provided datasets') + + self._fit_constraints[key] = settings def _parse_fit_constraints_prior(self): """ @@ -1551,6 +1569,25 @@ def _parse_fit_constraints_prior(self): if len(priors) > 0: self._priors = priors + def _get_no_of_dataset_by_lable(self, label): + """ + Returns the index of a dataset with a specific label. + + Parameters + ---------- + label : str + Label of the dataset defined by MulensData.plot_properties['label']. + + Returns + ------- + int + Sequential index of the dataset [1,2,...,n_datasets] + """ + for (i, dataset) in enumerate(self._datasets): + if dataset.plot_properties['label'] == label: + return i + return -99 + def _read_prior_t_E_data(self): """ read data that specify t_E prior and parse them appropriately @@ -2165,10 +2202,26 @@ def _get_fluxes(self): return fluxes def _sumup_inside_prior(self, fluxes, key, inside, idx_plus): + """ + Calculates the contribution to the ln_prior from specified color constraints + Parameters + ---------- + fluxes : array + Array with fluxes of the current model. + key : str + inside : float + idx_plus : int + For a single source, idx_plus=0; + for a binary source, idx_plus=0 or 1. + + Returns + ------- + inside : float + """ settings = self._fit_constraints[key] - index1 = (settings[3]-1)*self._n_fluxes_per_dataset + idx_plus - index2 = (settings[4]-1)*self._n_fluxes_per_dataset + idx_plus + index1 = (settings[3])*self._n_fluxes_per_dataset + idx_plus + index2 = (settings[4])*self._n_fluxes_per_dataset + idx_plus value = fluxes[index1]/fluxes[index2] inside += self._get_ln_prior_for_1_parameter(value, settings[:-2]) From 71a02fbc975789bea4a7ddd104deaa054e9f6ba8 Mon Sep 17 00:00:00 2001 From: Mateusz Mroz Date: Mon, 13 May 2024 18:53:49 +0200 Subject: [PATCH 06/13] like previous --- examples/example_16/ob03235_2_full.yaml | 6 +-- examples/example_16/ulens_model_fit.py | 54 +++++++++++++++---------- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index c5bb512cb..59b38c9a3 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -33,13 +33,13 @@ starting_parameters: s: uniform 1.09 1.11 alpha: gauss 224.0 1.0 fit_constraints: - negative_blending_flux_sigma_mag: 20. + negative_blending_flux_sigma_mag: 20. #one can specify for which dataset soft constrain on blending flux should be applied: sigma dataset_number(s) - #negative_blending_flux_sigma_mag: 20. 1 3 + #negative_blending_flux_sigma_mag: 20. "OGLE I-band" 1 # Alternative sharp constraint: # no_negative_blending_flux: True #color constrains, where color=flux_S_dataset_k/flux_S_dataset_m: gauss mu sigma k m - color : gauss 25. 5. "OGLE I-band" "OB03235_MOA.txt" + color : gauss 25. 5. "OGLE I-band" 1 #Alternative for binary source models: #color source 1 : gauss 25. 5. "OGLE I-band" "OB03235_MOA.txt" #and/or diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index 66eed00bc..6b9b1fb74 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -1483,12 +1483,15 @@ def _parse_fit_constraints_soft_blending(self, key, value): """ Check if soft fit constraint on blending flux are correctly defined. """ - if isinstance(value, (float, int)): + if isinstance(value, float): sigma = float(value) - sets = list(range(1, len(self._datasets) + 1)) + sets = list(range(len(self._datasets))) + else: + sigma = float(value.split()[0]) - sets = list(map(int, value.split()[1:])) + sets = list(map(self._get_no_of_dataset, + shlex.split(value, posix=False)[1:])) if len(sets) > len(self._datasets): raise ValueError( 'dataset number specified in negative_blending_flux_sigma_mag do not match with provided datasets') @@ -1515,20 +1518,17 @@ def _parse_fit_constraints_color(self, key, value): words[2] + " " + words[3] + " " + words[4]) if settings[2] < 0.: raise ValueError('sigma cannot be negative: ' + words[2]) + + settings[3] = self._get_no_of_dataset(settings[3]) + settings[4] = self._get_no_of_dataset(settings[4]) + if settings[3] == settings[4]: raise ValueError( "in " + key + " fluxes have to be from different datasets") - if isinstance(settings[3], str) and isinstance(settings[4], str): - settings[3] = settings[3].strip('"') - settings[4] = settings[4].strip('"') - settings[3] = self._get_no_of_dataset_by_lable(settings[3]) - settings[4] = self._get_no_of_dataset_by_lable(settings[4]) - - if isinstance(settings[3], int) and isinstance(settings[4], int): - if (0 >= settings[3] >= len(self._datasets)-1) or (0 >= settings[4] >= len(self._datasets)-1): - raise ValueError( - 'dataset specified in color prior do not match with provided datasets') + if (0 >= settings[3] >= len(self._datasets)-1) or (0 >= settings[4] >= len(self._datasets)-1): + raise ValueError( + 'dataset specified in color prior do not match with provided datasets') self._fit_constraints[key] = settings @@ -1569,24 +1569,36 @@ def _parse_fit_constraints_prior(self): if len(priors) > 0: self._priors = priors - def _get_no_of_dataset_by_lable(self, label): + def _get_no_of_dataset(self, label): """ Returns the index of a dataset with a specific label. Parameters ---------- label : str - Label of the dataset defined by MulensData.plot_properties['label']. + Label of the dataset defined by MulensData.plot_properties['label'] + or sequential index of the dataset Returns ------- int - Sequential index of the dataset [1,2,...,n_datasets] + Sequential index of the dataset from [0,1,...,n_datasets-1] + """ - for (i, dataset) in enumerate(self._datasets): - if dataset.plot_properties['label'] == label: - return i - return -99 + if '"' in label: + label = label.strip('"') + + try: + ind = int(label) + if 0 <= ind <= len(self._datasets)-1: + return ind + except: + for (i, dataset) in enumerate(self._datasets): + + if dataset.plot_properties['label'] == label: + return i + raise KeyError( + "Unrecognized dataset lable in fit_constraints/prior: " + label) def _read_prior_t_E_data(self): """ @@ -2244,7 +2256,7 @@ def _run_flux_checks_ln_prior(self, fluxes): if key in self._fit_constraints: for (i, dataset) in enumerate(self._datasets): - if i+1 in self._fit_constraints[key][1]: + if i in self._fit_constraints[key][1]: blend_index = ((i+1)*self._n_fluxes_per_dataset) - 1 if fluxes[blend_index] < 0.: sigma = self._fit_constraints[key][0] From c7c558b688b12abbf5be855e5a8a9372612edb69 Mon Sep 17 00:00:00 2001 From: mjmroz Date: Tue, 14 May 2024 01:16:53 +0200 Subject: [PATCH 07/13] docstring improved --- examples/example_16/ulens_model_fit.py | 46 ++++++++++---------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index 6b9b1fb74..77737f450 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -1570,21 +1570,15 @@ def _parse_fit_constraints_prior(self): self._priors = priors def _get_no_of_dataset(self, label): - """ + """ Returns the index of a dataset with a specific label. - - Parameters - ---------- - label : str - Label of the dataset defined by MulensData.plot_properties['label'] + :param label: Label of the dataset defined by MulensData.plot_properties['label'] or sequential index of the dataset - - Returns - ------- - int - Sequential index of the dataset from [0,1,...,n_datasets-1] - + :type label: str + :return: Sequential index of the dataset from [0,1,...,n_datasets-1] + :rtype: int """ + if '"' in label: label = label.strip('"') @@ -2214,23 +2208,19 @@ def _get_fluxes(self): return fluxes def _sumup_inside_prior(self, fluxes, key, inside, idx_plus): + """Calculates the contribution to the ln_prior from specified color constraints + + :param fluxes: Array with fluxes of the current model. + :type fluxes: array + :param key: constrain key + :type key: str + :param inside: ln_prior contribution + :type inside: float + :param idx_plus: For a single source, idx_plus=0; for a binary source, idx_plus=0 or 1. + :type idx_plus: int + :return: evaluated ln_prior contribution + :rtype: float """ - Calculates the contribution to the ln_prior from specified color constraints - Parameters - ---------- - fluxes : array - Array with fluxes of the current model. - key : str - inside : float - idx_plus : int - For a single source, idx_plus=0; - for a binary source, idx_plus=0 or 1. - - Returns - ------- - inside : float - """ - settings = self._fit_constraints[key] index1 = (settings[3])*self._n_fluxes_per_dataset + idx_plus index2 = (settings[4])*self._n_fluxes_per_dataset + idx_plus From 570e74c221ba139d625eb3c2b4a4ccde68713313 Mon Sep 17 00:00:00 2001 From: Mateusz Mroz Date: Tue, 21 May 2024 17:26:27 +0200 Subject: [PATCH 08/13] docstrings updated, t_0_shift bug solved --- examples/example_16/ob03235_2_full.yaml | 6 ++-- examples/example_16/ulens_model_fit.py | 45 +++++++++++++++---------- 2 files changed, 30 insertions(+), 21 deletions(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index 59b38c9a3..32cc06d00 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -35,11 +35,11 @@ starting_parameters: fit_constraints: negative_blending_flux_sigma_mag: 20. #one can specify for which dataset soft constrain on blending flux should be applied: sigma dataset_number(s) - #negative_blending_flux_sigma_mag: 20. "OGLE I-band" 1 + #negative_blending_flux_sigma_mag: [20., "OGLE I-band", "OB03235_MOA.txt"] # Alternative sharp constraint: # no_negative_blending_flux: True - #color constrains, where color=flux_S_dataset_k/flux_S_dataset_m: gauss mu sigma k m - color : gauss 25. 5. "OGLE I-band" 1 + #color constrains, where color=flux_S_dataset_k/flux_S_dataset_m: [gauss, mu ,sigma, k, m ,] + color : ["gauss", 25., 5. , "OGLE I-band" ,"OB03235_MOA.txt" ] #Alternative for binary source models: #color source 1 : gauss 25. 5. "OGLE I-band" "OB03235_MOA.txt" #and/or diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index 77737f450..ec19892f1 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -1570,13 +1570,16 @@ def _parse_fit_constraints_prior(self): self._priors = priors def _get_no_of_dataset(self, label): - """ + """ Returns the index of a dataset with a specific label. - :param label: Label of the dataset defined by MulensData.plot_properties['label'] - or sequential index of the dataset - :type label: str - :return: Sequential index of the dataset from [0,1,...,n_datasets-1] - :rtype: int + Parameters : + label: *str* ,*int* + Label of the dataset defined by MulensData.plot_properties['label'], or name of the data file if label is not specified, + or a sequential index of the dataset. + + Returns : + idx: *int* Sequential index of the dataset from [0,1,...,n_datasets-1] + """ if '"' in label: @@ -2208,18 +2211,20 @@ def _get_fluxes(self): return fluxes def _sumup_inside_prior(self, fluxes, key, inside, idx_plus): - """Calculates the contribution to the ln_prior from specified color constraints - - :param fluxes: Array with fluxes of the current model. - :type fluxes: array - :param key: constrain key - :type key: str - :param inside: ln_prior contribution - :type inside: float - :param idx_plus: For a single source, idx_plus=0; for a binary source, idx_plus=0 or 1. - :type idx_plus: int - :return: evaluated ln_prior contribution - :rtype: float + """ + Calculates the contribution to the ln_prior from specified color constraints + Parameters : + fluxes: *array* + Array with fluxes of the current model. + key: *str* + constrain key. + inside: *float* + ln_prior contribution + idx_plus: *int* + For a single source, idx_plus=0; for a binary source, idx_plus=0 or 1. + Returns : + inside: *float* + Evaluated ln_prior contribution """ settings = self._fit_constraints[key] index1 = (settings[3])*self._n_fluxes_per_dataset + idx_plus @@ -2699,6 +2704,10 @@ def _shift_t_0_in_samples(self): if 'trace' in self._plots: self._samples[:, :, index] = ( self._samples[:, :, index] - self._shift_t_0_val) + + if name in self._fixed_parameters.keys() : + self._shift_t_0_val = int(self._fixed_parameters[name]) + def _get_fluxes_to_print_EMCEE(self): """ From 8e69d2f842b516ede8d64f0736fa2459906e0665 Mon Sep 17 00:00:00 2001 From: mjmroz Date: Wed, 12 Jun 2024 11:45:18 +0200 Subject: [PATCH 09/13] from last comment --- examples/example_16/ob03235_2_full.yaml | 12 +- examples/example_16/ulens_model_fit.py | 208 ++++++++++++++++-------- 2 files changed, 145 insertions(+), 75 deletions(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index 693570755..d59854b41 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -38,16 +38,16 @@ starting_parameters: # See also ob08092-o4_starting_file.yaml fit_constraints: negative_blending_flux_sigma_mag: 20. - #one can specify for which dataset soft constrain on blending flux should be applied: sigma dataset_number(s) - #negative_blending_flux_sigma_mag: [20., "OGLE I-band", "OB03235_MOA.txt"] + #one can specify for which dataset soft constrain on blending flux should be applied: sigma dataset_label(s) + negative_blending_flux_sigma_mag: 20. "OGLE I-band" "OB03235_MOA.txt" # Alternative sharp constraint: # no_negative_blending_flux: True - #color constrains, where color=flux_S_dataset_k/flux_S_dataset_m: [gauss, mu ,sigma, k, m ,] - color : ["gauss", 25., 5. , "OGLE I-band" ,"OB03235_MOA.txt" ] + #color constrains, where color=source_mag_from_dataset_k-source_mag_from_dataset_m: gauss, mu ,sigma, k, m + color : gauss 0.3 0.01 "OGLE I-band" "OB03235_MOA.txt" #Alternative for binary source models: - #color source 1 : gauss 25. 5. "OGLE I-band" "OB03235_MOA.txt" + #color source 1 : gauss 0.3 0.01 "OGLE I-band" "OB03235_MOA.txt" #and/or - #color source 2 : gauss 25. 5. 0 1 + #color source 2 : gauss 0.3 0.01 "OGLE I-band" "OB03235_MOA.txt" prior: t_E: Mroz et al. 2017 diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index a2b728a8b..b9137b19c 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -198,14 +198,14 @@ class UlensModelFit(object): saved to temporary files and deleted at the end. ``multimodal`` (*bool*) - do you want multiple modes in - the prosterior to be detected and reported separately? + the posterior to be detected and reported separately? ``n_live_points`` (*int*) - number of live points, default value is 400. ``sampling efficiency`` (*float*) - requested sampling efficiency. MultiNest documentation suggests 0.8 (default value) for parameter - estimatrion and 0.3 for evidence evalutation. + estimation and 0.3 for evidence evaluation. ``evidence tolerance`` (*float*) - requested tolerance of ln(Z) calculation; default is 0.5 and should work well in most cases. @@ -219,10 +219,31 @@ class UlensModelFit(object): blending flux if *True* ``'negative_blending_flux_sigma_mag'`` - impose a prior that - disfavours models with negative blending flux using gaussian prior + disfavors models with negative blending flux using gaussian prior for negative values; the value provided should be on the order of *20.* + ``'color'`` - specify gaussian prior for colors of the sources. + Parameters: + *mean* and *sigma* are floats in magnitudes. + + ``'color'`` - specify gaussian prior for colors of the sources. + Parameters: + *mean* and *sigma* are floats in magnitudes, *dataset_label* + are str defined in MulensData.plot_properties['label'] + + ``'color source 1'`` - specify gaussian prior for color of + the primary source in binary source model. + Parameters: + *mean* and *sigma* are floats in magnitudes, *dataset_label* + are str defined in MulensData.plot_properties['label'] + + ``'color source 2'`` - specify gaussian prior for color of + the secondary source in binary source model. + Parameters: + *mean* and *sigma* are floats in magnitudes, *dataset_label* + are str defined in MulensData.plot_properties['label'] + ``'prior'`` - specifies the priors for quantities. It's also a *dict*. Possible key-value pairs: @@ -480,7 +501,7 @@ def _guess_fitting_method(self): "Both starting_parameters and prior_limits were defined " "which makes impossible to choose the fitting method. " "These settings indicate EMCEE and pyMultiNest " - "rescpectively, and cannot be both set.") + "respectively, and cannot be both set.") method = "MultiNest" if method is None: raise ValueError( @@ -699,7 +720,7 @@ def _check_plots_parameters_best_model(self): for key in ['legend', 'rcParams', 'second Y scale']: if key in self._plots['best model']: if not isinstance(self._plots['best model'][key], dict): - msg = ('The value of {:} (in best model setttings)' + msg = ('The value of {:} (in best model settings)' 'must be a dictionary, but you provided {:}') args = [key, type(self._plots['best model'][key])] raise TypeError(msg.format(*args)) @@ -870,7 +891,7 @@ def _check_model_parameters(self): def _check_other_fit_parameters(self): """ - Check if there aren't any other inconsistenties between settings + Check if there aren't any other inconsistencies between settings """ if self._fit_method == "MultiNest": if self._min_values is not None or self._max_values is not None: @@ -991,7 +1012,7 @@ def _check_residual_files(self): """ Check if provided names of output files with residuals make sense. We do not check here if the number of files provided is the same - as the number of input datests. + as the number of input datasets. """ existing = [] names = [] @@ -1033,7 +1054,7 @@ def _get_datasets(self): out = '{:} vs {:}'.format( len(self._datasets), len(self._residuals_files)) raise ValueError('The number of datasets and files for ' - 'residuals ouptut do not match: ' + out) + 'residuals output do not match: ' + out) def _get_1_dataset(self, file_, kwargs): """ @@ -1301,7 +1322,7 @@ def _set_dict_safetly(self, target, source, keys_mapping): def _check_output_files_MultiNest(self): """ - Check if output files exist and warn about overwrtting them. + Check if output files exist and warn about overwriting them. If they directory doesn't exist then raise error. """ @@ -1436,7 +1457,7 @@ def _parse_fit_constraints(self): self._priors = None if self._fit_constraints is None: - self._fit_constraints = {"no_negative_blending_flux": False} + self._set_default_fit_constraints() return if isinstance(self._fit_constraints, list): @@ -1446,6 +1467,16 @@ def _parse_fit_constraints(self): "the code. Most probably what you need is:\n" + "fit_constraints = {'no_negative_blending_flux': True}") + self._parse_fit_constraints_keys() + self._parse_fit_constraints_fluxes() + + if 'prior' in self._fit_constraints: + self._parse_fit_constraints_prior() + + def _parse_fit_constraints_keys(self): + """ + Validate the keys in the provided fit_constraints. + """ allowed_keys_flux = { "no_negative_blending_flux", "negative_blending_flux_sigma_mag"} @@ -1467,22 +1498,37 @@ def _parse_fit_constraints(self): if "no_negative_blending_flux" not in self._fit_constraints: self._fit_constraints["no_negative_blending_flux"] = False - if len(used_keys.intersection(allowed_keys_color)) >= 2 and ('color' in used_keys): - raise ValueError( - 'you cannot specify both color and ' + str(used_keys.intersection(allowed_keys_color)-{'color'})) + self._check_color_constraints_conflict(allowed_keys_color) + + def _set_default_fit_constraints(self): + """ + Set default fitting constraints if none are provided. + + """ + self._fit_constraints = {"no_negative_blending_flux": False} + + def _check_color_constraints_conflict(self, allowed_keys_color): + """ + Check for conflicts among color constraints. + """ + used_keys = set(self._fit_constraints.keys()) - for key in self._fit_constraints.keys(): - value = self._fit_constraints[key] + if len(used_keys.intersection(allowed_keys_color)) >= 2: + if 'color' in used_keys: + raise ValueError( + 'You cannot specify both color and ' + + str(used_keys.intersection(allowed_keys_color)-{'color'})) + def _parse_fit_constraints_fluxes(self): + """msg += + Process each constraint fit_constraints. + """ + for key, value in self._fit_constraints.items(): if key == "negative_blending_flux_sigma_mag": self._parse_fit_constraints_soft_blending(key, value) - elif key in ['color', 'color source 1', 'color source 2']: self._parse_fit_constraints_color(key, value) - if 'prior' in self._fit_constraints: - self._parse_fit_constraints_prior() - def _parse_fit_constraints_soft_blending(self, key, value): """ Check if soft fit constraint on blending flux are correctly defined. @@ -1498,7 +1544,9 @@ def _parse_fit_constraints_soft_blending(self, key, value): shlex.split(value, posix=False)[1:])) if len(sets) > len(self._datasets): raise ValueError( - 'dataset number specified in negative_blending_flux_sigma_mag do not match with provided datasets') + "dataset number specified in" + + "negative_blending_flux_sigma_mag" + + "do not match with provided datasets") self._fit_constraints[key] = [ mm.Utils.get_flux_from_mag(sigma), sets] @@ -1507,12 +1555,15 @@ def _parse_fit_constraints_color(self, key, value): """ Check if fit constraint on color are correctly defined. """ + self._check_unique_datasets_labels() words = shlex.split(value, posix=False) + if len(words) != 5 or words[0] != 'gauss': msg = "Something went wrong in parsing prior for " msg += "{:}: {:}" if len(words) == 3 and words[0] == 'gauss': - msg += ' color priors require the specification of datasets that should be used for color calculation ' + msg += "color priors require the specification" + msg += "of datasets that should be used for color calculation" raise ValueError(msg.format(key, value)) try: settings = [words[0], float(words[1]), float( @@ -1528,14 +1579,26 @@ def _parse_fit_constraints_color(self, key, value): if settings[3] == settings[4]: raise ValueError( - "in " + key + " fluxes have to be from different datasets") - - if (0 >= settings[3] >= len(self._datasets)-1) or (0 >= settings[4] >= len(self._datasets)-1): + "in " + key + " color have to be from different datasets") + n = len(self._datasets)-1 + if (0 >= settings[3] >= n) or (0 >= settings[4] >= n): raise ValueError( - 'dataset specified in color prior do not match with provided datasets') + "label specified in color prior" + + "do not match with provided datasets") self._fit_constraints[key] = settings + def _check_unique_datasets_labels(self): + """ + Check if the labels of datasets are unique. + """ + labels = [ + dataset.plot_properties['label'] + for dataset in self._datasets + ] + if len(labels) != len(set(labels)): + raise ValueError("Declared labels of datasets must be unique.") + def _parse_fit_constraints_prior(self): """ Check if priors in fit constraint are correctly defined. @@ -1574,32 +1637,28 @@ def _parse_fit_constraints_prior(self): self._priors = priors def _get_no_of_dataset(self, label): - """ + """ Returns the index of a dataset with a specific label. Parameters : label: *str* ,*int* - Label of the dataset defined by MulensData.plot_properties['label'], or name of the data file if label is not specified, + Label of the dataset defined by + MulensData.plot_properties['label'], + or name of the data file if label is not specified, or a sequential index of the dataset. - + Returns : - idx: *int* Sequential index of the dataset from [0,1,...,n_datasets-1] + index: *int* + Sequential index of the dataset from [0,1,...,n_datasets-1] """ if '"' in label: label = label.strip('"') - - try: - ind = int(label) - if 0 <= ind <= len(self._datasets)-1: - return ind - except: - for (i, dataset) in enumerate(self._datasets): - - if dataset.plot_properties['label'] == label: - return i - raise KeyError( - "Unrecognized dataset lable in fit_constraints/prior: " + label) + for (i, dataset) in enumerate(self._datasets): + if dataset.plot_properties['label'] == label: + return i + raise KeyError( + "Unrecognized dataset label in fit_constraints/prior: " + label) def _read_prior_t_E_data(self): """ @@ -2214,26 +2273,29 @@ def _get_fluxes(self): return fluxes - def _sumup_inside_prior(self, fluxes, key, inside, idx_plus): + def _sumup_inside_prior(self, fluxes, key, inside, index_plus): """ - Calculates the contribution to the ln_prior from specified color constraints + Calculates the contribution to the ln_prior + from specified color constraints Parameters : - fluxes: *array* + fluxes: *array* Array with fluxes of the current model. key: *str* constrain key. inside: *float* ln_prior contribution - idx_plus: *int* - For a single source, idx_plus=0; for a binary source, idx_plus=0 or 1. + index_plus: *int* + For a single source, index_plus=0; + for a binary source, index_plus=0 or 1. Returns : inside: *float* Evaluated ln_prior contribution """ settings = self._fit_constraints[key] - index1 = (settings[3])*self._n_fluxes_per_dataset + idx_plus - index2 = (settings[4])*self._n_fluxes_per_dataset + idx_plus - value = fluxes[index1]/fluxes[index2] + index1 = (settings[3])*self._n_fluxes_per_dataset + index_plus + index2 = (settings[4])*self._n_fluxes_per_dataset + index_plus + value = mm.Utils.get_mag_from_flux( + fluxes[index1])-mm.Utils.get_mag_from_flux(fluxes[index2]) inside += self._get_ln_prior_for_1_parameter(value, settings[:-2]) return inside @@ -2250,36 +2312,45 @@ def _run_flux_checks_ln_prior(self, fluxes): if fluxes[blend_index] < 0.: return outside + inside += self._apply_negative_blending_flux_sigma_mag_prior(fluxes) + inside += self._apply_color_prior(fluxes) + + return inside + + def _apply_negative_blending_flux_sigma_mag_prior(self, fluxes): + """ + Apply the negative blending flux sigma magnitude priotr. + """ + inside = 0.0 key = "negative_blending_flux_sigma_mag" if key in self._fit_constraints: + sigma, datasets = self._fit_constraints[key] + for i, dataset in enumerate(self._datasets): + if i in datasets: + blend_index = ((i + 1) * self._n_fluxes_per_dataset) - 1 + if fluxes[blend_index] < 0.0: + inside += -0.5 * (fluxes[blend_index] / sigma) ** 2 - for (i, dataset) in enumerate(self._datasets): - if i in self._fit_constraints[key][1]: - blend_index = ((i+1)*self._n_fluxes_per_dataset) - 1 - if fluxes[blend_index] < 0.: - sigma = self._fit_constraints[key][0] - inside += -0.5 * (fluxes[blend_index] / sigma)**2 + return inside + def _apply_color_prior(self, fluxes): + """ + Apply the color constraints. + """ + inside = 0.0 key = 'color' - if key in self._fit_constraints: - settings = self._fit_constraints[key] - if self._n_fluxes_per_dataset == 2: - inside = self._sumup_inside_prior(fluxes, key, inside, 0) - - if self._n_fluxes_per_dataset == 3: - inside = self._sumup_inside_prior(fluxes, key, inside, 0) - inside = self._sumup_inside_prior(fluxes, key, inside, 1) + for i in range(self._n_fluxes_per_dataset - 1): + inside += self._sumup_inside_prior(fluxes, key, inside, i) key = 'color source 1' if key in self._fit_constraints: - inside = self._sumup_inside_prior(fluxes, key, inside, 0) + inside += self._sumup_inside_prior(fluxes, key, inside, 0) key = 'color source 2' if key in self._fit_constraints: - inside = self._sumup_inside_prior(fluxes, key, inside, 1) - + inside += self._sumup_inside_prior(fluxes, key, inside, 1) return inside def _update_best_model_EMCEE(self, ln_prob, theta, fluxes): @@ -2708,10 +2779,9 @@ def _shift_t_0_in_samples(self): if 'trace' in self._plots: self._samples[:, :, index] = ( self._samples[:, :, index] - self._shift_t_0_val) - - if name in self._fixed_parameters.keys() : - self._shift_t_0_val = int(self._fixed_parameters[name]) + if name in self._fixed_parameters.keys(): + self._shift_t_0_val = int(self._fixed_parameters[name]) def _get_fluxes_to_print_EMCEE(self): """ From e2bce87cea1926d2d8d39deadff0b42351d81cec Mon Sep 17 00:00:00 2001 From: mjmroz Date: Wed, 12 Jun 2024 11:50:00 +0200 Subject: [PATCH 10/13] small change --- examples/example_16/ulens_model_fit.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index b9137b19c..8d15c4df8 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -222,11 +222,7 @@ class UlensModelFit(object): disfavors models with negative blending flux using gaussian prior for negative values; the value provided should be on the order of *20.* - - ``'color'`` - specify gaussian prior for colors of the sources. - Parameters: - *mean* and *sigma* are floats in magnitudes. - + ``'color'`` - specify gaussian prior for colors of the sources. Parameters: *mean* and *sigma* are floats in magnitudes, *dataset_label* From 78ec79df1f610ed6677a152421e568e1a1d33953 Mon Sep 17 00:00:00 2001 From: mjmroz Date: Wed, 12 Jun 2024 12:12:46 +0200 Subject: [PATCH 11/13] small correction --- source/MulensModel/data | 1 + 1 file changed, 1 insertion(+) create mode 100644 source/MulensModel/data diff --git a/source/MulensModel/data b/source/MulensModel/data new file mode 100644 index 000000000..e67b45590 --- /dev/null +++ b/source/MulensModel/data @@ -0,0 +1 @@ +../../data \ No newline at end of file From 99d1f5bde0be3e62b2706ff612bf734624269dc2 Mon Sep 17 00:00:00 2001 From: mjmroz Date: Thu, 13 Jun 2024 03:15:39 +0200 Subject: [PATCH 12/13] final corrections --- examples/example_16/ob03235_2_full.yaml | 2 +- examples/example_16/ulens_model_fit.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example_16/ob03235_2_full.yaml b/examples/example_16/ob03235_2_full.yaml index d59854b41..6ae84dba5 100644 --- a/examples/example_16/ob03235_2_full.yaml +++ b/examples/example_16/ob03235_2_full.yaml @@ -39,7 +39,7 @@ starting_parameters: fit_constraints: negative_blending_flux_sigma_mag: 20. #one can specify for which dataset soft constrain on blending flux should be applied: sigma dataset_label(s) - negative_blending_flux_sigma_mag: 20. "OGLE I-band" "OB03235_MOA.txt" + #negative_blending_flux_sigma_mag: 20. "OGLE I-band" "OB03235_MOA.txt" # Alternative sharp constraint: # no_negative_blending_flux: True #color constrains, where color=source_mag_from_dataset_k-source_mag_from_dataset_m: gauss, mu ,sigma, k, m diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index 8d15c4df8..316dc6b99 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -39,7 +39,7 @@ except Exception: raise ImportError('\nYou have to install MulensModel first!\n') -__version__ = '0.36.3' +__version__ = '0.37.0' class UlensModelFit(object): From b7b18ab1bf0d28c067759006c6ae00400adee465 Mon Sep 17 00:00:00 2001 From: mjmroz Date: Thu, 13 Jun 2024 03:28:48 +0200 Subject: [PATCH 13/13] whitespace removed --- examples/example_16/ulens_model_fit.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example_16/ulens_model_fit.py b/examples/example_16/ulens_model_fit.py index 316dc6b99..571e59db5 100644 --- a/examples/example_16/ulens_model_fit.py +++ b/examples/example_16/ulens_model_fit.py @@ -222,7 +222,7 @@ class UlensModelFit(object): disfavors models with negative blending flux using gaussian prior for negative values; the value provided should be on the order of *20.* - + ``'color'`` - specify gaussian prior for colors of the sources. Parameters: *mean* and *sigma* are floats in magnitudes, *dataset_label*