Skip to content

Commit

Permalink
Merge branch '_repr_'
Browse files Browse the repository at this point in the history
  • Loading branch information
rpoleski committed Feb 16, 2023
2 parents 55f826e + 7587699 commit e402809
Show file tree
Hide file tree
Showing 15 changed files with 411 additions and 39 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

[**Detailed documentation: https://rpoleski.github.io/MulensModel/**](https://rpoleski.github.io/MulensModel/)

[Latest release: 2.14.0](https://github.com/rpoleski/MulensModel/releases/latest) and we're working on further developing the code.
[Latest release: 2.15.0](https://github.com/rpoleski/MulensModel/releases/latest) and we're working on further developing the code.

MulensModel can generate a microlensing light curve for a given set of microlensing parameters, fit that light curve to some data, and return a chi2 value. That chi2 can then be input into an arbitrary likelihood function to find the best-fit parameters.

Expand Down
1 change: 1 addition & 0 deletions documents/examples_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Tutorials MulensModel:
* [Example 21](../examples/example_21_external_mass_sheet.py) - binary lens with external mass sheet: shear and convergence as parameters,
* [Example 22](../examples/example_22_pointlens_external_mass_sheet.py) - point lens with external mass sheet, i.e., Chang-Refsdal approximation,
* [Example 23](../examples/example_23_logo_inspiration.py) - 2L1S and 1L2S lightcurves plotted as an inspiration for MM logo,
* [Example 24](../examples/example_24_repr.py) - print intances of different MM classes,
* Three files producing plots presented in paper describing MulensModel: [plots_1.py](../examples/plots_1.py), [plots_2.py](../examples/plots_2.py), and [plots_3.py](../examples/plots_3.py).

[MulensModel documentation](https://rpoleski.github.io/MulensModel/) includes description of input and output of every function.
Expand Down
68 changes: 68 additions & 0 deletions examples/example_24_repr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
Output information about datasets, model, and event.
Created from example_05_MB08310.py
From `Janczak et al. 2010, ApJ 711, 731
<https://ui.adsabs.harvard.edu/abs/2010ApJ...711..731J/abstract>`_.
"""
import glob
import os

import MulensModel as mm


# Read in MB08310 data files (see data/MB08310) as MulensData objects.
# Grabbing all data files in the MB08310 folder
files = glob.glob(os.path.join(mm.DATA_PATH, "photometry_files",
"MB08310", "*.tbl"))

coordinates = "17:54:14.53 −34:46:40.99"

filters = {'Auck': 'R', 'Bron': 'R', 'Canopus': 'I', 'CTIO_H': 'H',
'CTIO_I': 'I', 'Danish': 'I', 'MOA': 'R'}

# Read in the data
datasets_default = []
for file_ in sorted(files):
file_elements = os.path.basename(file_).split('_')
name = file_elements[0]
if name == 'CTIO':
name += '_'
name += file_elements[1]

data = mm.MulensData(
file_name=file_, comments=["\\", "|"], bandpass=filters[name])
if name == 'MOA':
data.scale_errorbars(1.6, 0.001)

datasets_default.append(data)


print("Printing datasets:")
for data in datasets_default:
print(data)

# Define basic point lens model
t_0 = 2454656.39975
u_0 = 0.00300
t_E = 11.14
t_star = 0.05487
plens_model = mm.Model({'t_0': t_0, 'u_0': u_0, 't_E': t_E, 't_star': t_star})
method = 'finite_source_uniform_Gould94'
plens_model.set_magnification_methods([t_0-2.*t_star, method, t_0+2.*t_star])
plens_model.set_limb_coeff_u('I', 0.547)
plens_model.set_limb_coeff_u('V', 0.714)
plens_model.set_limb_coeff_u('R', 0.633)
plens_model.set_limb_coeff_u('H', 0.368)

print('\nPrinting model:')
print(plens_model)

# Combine the data and model into an event
event_default = mm.Event(
datasets=datasets_default, model=plens_model, coords=coordinates)
event_default.data_ref = 6

print("\nPrinting event:")
print(event_default)

5 changes: 5 additions & 0 deletions source/MulensModel/coordinates.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class Coordinates(SkyCoord):
unit=(u.hourangle, u.deg) where u is defined by "import
astropy.units as u".
You can print an instance of this class.
.. _astropy.SkyCoord:
http://docs.astropy.org/en/stable/api/astropy.coordinates.SkyCoord.html
Expand Down Expand Up @@ -83,6 +85,9 @@ def _calculate_projected(self):
north, direction)
self._north_projected = np.cross(direction, self._east_projected)

def __repr__(self):
return self.to_string(style="hmsdms", sep=":", precision=2)

@property
def galactic_l(self):
"""
Expand Down
31 changes: 31 additions & 0 deletions source/MulensModel/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class Event(object):
in negative flux, then we calculate chi^2 in flux space but only for the
epochs with negative model flux.
You can print an instance of this class. Information on model and datasets
will be provided.
.. _astropy.SkyCoord:
http://docs.astropy.org/en/stable/api/astropy.coordinates.SkyCoord.html
"""
Expand Down Expand Up @@ -113,6 +116,28 @@ def __init__(
else:
self.fix_source_flux_ratio = fix_source_flux_ratio

def __repr__(self):
if self.model is None:
out = "No model"
else:
out = 'model:\n{:}'.format(self.model)

if self.datasets is None:
out += "\nNo datasets"
else:
if isinstance(self.data_ref, (int)):
data_ref = self.datasets[self.data_ref]
else:
data_ref = self.data_ref

out += '\ndatasets:'
for dataset in self.datasets:
out += "\n" + str(dataset)
if dataset == data_ref:
out += " *data_ref*"

return out

def plot(self, t_range=None, residuals=True, show_errorbars=None,
show_bad=None, legend=True, trajectory=None, title=None,
subtract_2450000=True, subtract_2460000=False, data_ref=None):
Expand Down Expand Up @@ -816,6 +841,12 @@ def _set_datasets(self, new_value):
self._datasets = None
return

if len(set(new_value)) != len(new_value):
raise ValueError(
'Duplicated instances of MulensData are not allowed in '
'the Event class (though you can make 2 identical instances '
'and then Event will work).')

self._datasets = new_value
self._fits = None # reset the fits if the data changed

Expand Down
4 changes: 4 additions & 0 deletions source/MulensModel/limbdarkeningcoeffs.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ class LimbDarkeningCoeffs(object):
Note that the gamma convention has fixed total flux.
You can print an instance of this class.
"""

def __init__(self):
self._gammas_for_band = dict()

def __repr__(self):
return self._gammas_for_band.__repr__()

def set_limb_coeff_gamma(self, bandpass, gamma):
"""
Remembers limb darkening gamma coefficient for given band.
Expand Down
18 changes: 17 additions & 1 deletion source/MulensModel/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class Model(object):
model = Model(parameters={'t_0': 2456789.0, ....})
print(model)
This will provide information on parameter values, coordinates,
methods used for magnification calculations, and
limb-darkening coefficients.
"""

def __init__(
Expand Down Expand Up @@ -108,7 +111,20 @@ def __init__(
self._bandpasses = []

def __repr__(self):
return '{0}'.format(self.parameters)
out = '{0}'.format(self.parameters)
if self.coords is not None:
out += '\ncoords: {0}'.format(self.coords)

out += '\ndefault magnification method: {0}'.format(
self._default_magnification_method)
if self._methods is not None:
out += '\nother magnification methods: {0}'.format(self._methods)

if len(self.bandpasses) > 0:
out += '\nlimb-darkening coeffs (gamma): {0}'.format(
self._limb_darkening_coeffs)

return out

def plot_magnification(
self, times=None, t_range=None, t_start=None, t_stop=None, dt=None,
Expand Down
14 changes: 5 additions & 9 deletions source/MulensModel/modelparameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ def __repr__(self):
if 'pi_E' in keys:
keys.remove('pi_E')
keys |= {'pi_E_E', 'pi_E_N'}
if 'pi_E_E' in keys or 'pi_E_N' in keys:
keys |= {'t_0_par'}

# Below we define dict of dicts. Key of inner ones: 'width',
# 'precision', and optional: 'unit' and 'name'.
Expand All @@ -376,6 +378,7 @@ def __repr__(self):
't_star': {'width': 13, 'precision': 6, 'unit': 'd'},
'pi_E_N': {'width': 9, 'precision': 5},
'pi_E_E': {'width': 9, 'precision': 5},
't_0_par': {'width': 13, 'precision': 5, 'unit': 'HJD'},
's': {'width': 9, 'precision': 5},
'q': {'width': 12, 'precision': 8},
'alpha': {'width': 11, 'precision': 5, 'unit': 'deg'},
Expand All @@ -402,18 +405,11 @@ def __repr__(self):
formats[key]['unit'] = form['unit']
if 'name' in form:
raise KeyError('internal issue: {:}'.format(key))
formats_keys = [
't_0', 't_0_1', 't_0_2', 'u_0', 'u_0_1', 'u_0_2', 't_eff', 't_E',
'rho', 'rho_1', 'rho_2', 't_star', 't_star_1', 't_star_2',
'pi_E_N', 'pi_E_E', 's', 'q', 'alpha',
'convergence_K', 'shear_G', 'ds_dt', 'dalpha_dt',
'x_caustic_in', 'x_caustic_out', 't_caustic_in', 't_caustic_out',
]

variables = ''
values = ''

for key in formats_keys:
for key in formats.keys():
if key not in keys:
continue
form = formats[key]
Expand All @@ -429,7 +425,7 @@ def __repr__(self):
value = value.value
values += fmt_2.format(value)

return '{0}\n{1}\n'.format(variables, values)
return '{0}\n{1}'.format(variables, values)

def _check_valid_combination_2_sources(self, keys):
"""
Expand Down
36 changes: 35 additions & 1 deletion source/MulensModel/mulensdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ class MulensData(object):
``**kwargs``:
Kwargs passed to np.loadtxt(). Works only if ``file_name`` is set.
You can print an instance of this class, which always provides label and
information on the total number of epochs and the number of bad epochs.
If applicable, additional information is provided: bandpass,
ephemerides file, color used for plotting, and errorbar scaling.
.. _instructions:
https://github.com/rpoleski/MulensModel/blob/master/documents/Horizons_manual.md
Expand Down Expand Up @@ -151,8 +156,37 @@ def __init__(self, data_list=None, file_name=None,
# Set up satellite properties (if applicable)
self._ephemerides_file = ephemerides_file

def __repr__(self):
if 'label' in self.plot_properties:
name = self.plot_properties['label']
else:
name = self._file_name

out = "{:25} n_epochs ={:>5}, n_bad ={:>5}".format(
name+":", self.n_epochs, np.sum(self.bad))

if self.bandpass is not None:
out += ', band = {0}'.format(self.bandpass)

if self._ephemerides_file is not None:
out += ', eph_file = {0}'.format(self.ephemerides_file)

if 'color' in self.plot_properties:
out += ', color = {0}'.format(self.plot_properties['color'])

if self._errorbars_scale is not None:
out += ', Errorbar scaling:'
if self._errorbars_scale['factor'] is not None:
out += ' factor = {:}'.format(self._errorbars_scale['factor'])

if self._errorbars_scale['minimum'] is not None:
out += ' minimum = {:}'.format(
self._errorbars_scale['minimum'])

return out

def _import_photometry(self, data_list, **kwargs):
"""import time, brightnes, and its uncertainy"""
"""import time, brightness, and its uncertainty"""
# Import the photometry...
if data_list is not None and self._file_name is not None:
raise ValueError(
Expand Down
7 changes: 7 additions & 0 deletions source/MulensModel/tests/test_Coords.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,10 @@ def test_v_Earth_projected():
np.testing.assert_almost_equal(
[-3.60, 22.95],
coords.v_Earth_projected(2455042.34,), decimal=2)


def test_repr():
"""Checks if coords can be printed"""
text = "17:53:50.79 -33:59:25.00"
coords = mm.Coordinates(text)
assert str(coords) == text
Loading

0 comments on commit e402809

Please sign in to comment.