"""
Utility functions for photometry.
"""
import spectres
import numpy as np
from species.core import box
from species.read import read_model, read_calibration, read_filter, read_planck
[docs]def multi_photometry(datatype,
spectrum,
filters,
parameters):
"""
Parameters
----------
datatype : str
Data type ('model' or 'calibration').
spectrum : str
Spectrum name (e.g., 'drift-phoenix').
filters : tuple(str, )
Filter IDs.
parameters : dict
Parameters and values for the spectrum
Returns
-------
species.core.box.SynphotBox
Box with synthetic photometry.
"""
print('Calculating synthetic photometry...', end='')
flux = {}
if datatype == 'model':
for item in filters:
if spectrum == 'planck':
readmodel = read_planck.ReadPlanck(filter_name=item)
else:
readmodel = read_model.ReadModel(spectrum, filter_name=item)
flux[item] = readmodel.get_flux(parameters)
elif datatype == 'calibration':
for item in filters:
readcalib = read_calibration.ReadCalibration(spectrum, filter_name=item)
flux[item] = readcalib.get_flux(parameters)
print(' [DONE]')
return box.create_box('synphot', name='synphot', flux=flux)
[docs]def apparent_to_absolute(app_mag,
distance):
"""
Parameters
----------
app_mag : float or numpy.ndarray
Apparent magnitude (mag).
distance : float or numpy.ndarray
Distance (pc).
Returns
-------
float or numpy.ndarray
Absolute magnitude (mag).
"""
return app_mag - 5.*np.log10(distance) + 5.
[docs]def get_residuals(datatype,
spectrum,
parameters,
filters,
objectbox,
inc_phot=True,
inc_spec=False):
"""
Parameters
----------
datatype : str
Data type ('model' or 'calibration').
spectrum : str
Name of the atmospheric model or calibration spectrum.
parameters : dict
Parameters and values for the spectrum
filters : tuple(str, )
Filter IDs. All available photometry of the object is used if set to None.
objectbox : species.core.box.ObjectBox
Box with the photometry and/or spectrum of an object.
inc_phot : bool
Include photometry.
inc_spec : bool
Include spectrum.
Returns
-------
species.core.box.ResidualsBox
Box with the photometry and/or spectrum residuals.
"""
if filters is None:
filters = objectbox.filters
if inc_phot:
model_phot = multi_photometry(datatype=datatype,
spectrum=spectrum,
filters=filters,
parameters=parameters)
res_phot = np.zeros((2, len(objectbox.flux)))
for i, item in enumerate(filters):
transmission = read_filter.ReadFilter(item)
res_phot[0, i] = transmission.mean_wavelength()
res_phot[1, i] = (objectbox.flux[item][0]-model_phot.flux[item])/objectbox.flux[item][1]
else:
res_phot = None
print('Calculating residuals...', end='')
if inc_spec:
wavel_range = (0.9*objectbox.spectrum[0, 0], 1.1*objectbox.spectrum[-1, 0])
if spectrum == 'planck':
readmodel = read_planck.ReadPlanck(wavel_range=wavel_range)
model = readmodel.get_spectrum(model_param=parameters, spec_res=1000.)
else:
readmodel = read_model.ReadModel(spectrum, wavel_range=wavel_range)
model = readmodel.get_model(model_param=parameters, spec_res=1000.)
wl_new = objectbox.spectrum[:, 0]
flux_new = spectres.spectres(new_spec_wavs=wl_new,
old_spec_wavs=model.wavelength,
spec_fluxes=model.flux,
spec_errs=None)
res_spec = np.zeros((2, objectbox.spectrum.shape[0]))
res_spec[0, :] = wl_new
res_spec[1, :] = (objectbox.spectrum[:, 1]-flux_new)/objectbox.spectrum[:, 2]
else:
res_spec = None
print(' [DONE]')
return box.create_box(boxtype='residuals',
name=objectbox.name,
photometry=res_phot,
spectrum=res_spec)