Commit 106c685e authored by Médéric Boquien's avatar Médéric Boquien

Add the possibility the indicate the distance of the object in Mpc in the input file.

parent 4020a2a3
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
## Unreleased ## Unreleased
### Added ### Added
- It is now possible to optionally indicate the distance in Mpc in the input file. If present it will be used in lieu of the distance computed from the redshift. This is especially useful in the nearby universe where the redshift is a very poor indicator of the actual distance. (Médéric Boquien)
### Changed ### Changed
### Fixed ### Fixed
### Optimised ### Optimised
......
...@@ -11,6 +11,7 @@ from astropy import log ...@@ -11,6 +11,7 @@ from astropy import log
from astropy.cosmology import WMAP7 as cosmo from astropy.cosmology import WMAP7 as cosmo
import numpy as np import numpy as np
from scipy import optimize from scipy import optimize
from scipy.constants import parsec
from scipy.special import erf from scipy.special import erf
log.setLevel('ERROR') log.setLevel('ERROR')
...@@ -29,7 +30,7 @@ def save_chi2(obs, variable, models, chi2, values): ...@@ -29,7 +30,7 @@ def save_chi2(obs, variable, models, chi2, values):
@lru_cache(maxsize=None) @lru_cache(maxsize=None)
def compute_corr_dz(model_z, obs_z): def compute_corr_dz(model_z, obs_dist):
"""The mass-dependent physical properties are computed assuming the """The mass-dependent physical properties are computed assuming the
redshift of the model. However because we round the observed redshifts to redshift of the model. However because we round the observed redshifts to
two decimals, there can be a difference of 0.005 in redshift between the two decimals, there can be a difference of 0.005 in redshift between the
...@@ -42,16 +43,13 @@ def compute_corr_dz(model_z, obs_z): ...@@ -42,16 +43,13 @@ def compute_corr_dz(model_z, obs_z):
---------- ----------
model_z: float model_z: float
Redshift of the model. Redshift of the model.
obs_z: float obs_dist: float
Redshift of the observed object. Luminosity distance of the observed object.
""" """
if model_z == obs_z: if model_z == 0.:
return 1. return (obs_dist / (10. * parsec))**2.
if model_z > 0.: return (obs_dist / cosmo.luminosity_distance(model_z).value)**2.
return (cosmo.luminosity_distance(obs_z).value /
cosmo.luminosity_distance(model_z).value)**2.
return (cosmo.luminosity_distance(obs_z).value * 1e5)**2.
def dchi2_over_ds2(s, obs_values, obs_errors, mod_values): def dchi2_over_ds2(s, obs_values, obs_errors, mod_values):
......
...@@ -173,7 +173,7 @@ def analysis(idx, obs): ...@@ -173,7 +173,7 @@ def analysis(idx, obs):
z = np.array( z = np.array(
gbl_models.conf['sed_modules_params']['redshifting']['redshift']) gbl_models.conf['sed_modules_params']['redshifting']['redshift'])
wz = slice(np.abs(obs.redshift-z).argmin(), None, z.size) wz = slice(np.abs(obs.redshift-z).argmin(), None, z.size)
corr_dz = compute_corr_dz(z[wz.start], obs.redshift) corr_dz = compute_corr_dz(z[wz.start], obs.distance)
else: # We do not know the redshift so we use the full grid else: # We do not know the redshift so we use the full grid
wz = slice(0, None, 1) wz = slice(0, None, 1)
corr_dz = 1. corr_dz = 1.
...@@ -263,12 +263,13 @@ def bestfit(oidx, obs): ...@@ -263,12 +263,13 @@ def bestfit(oidx, obs):
_, scaling = compute_chi2(fluxes[:, None], intprops[:, None], _, scaling = compute_chi2(fluxes[:, None], intprops[:, None],
extprops[:, None], obs, extprops[:, None], obs,
gbl_conf['analysis_params']['lim_flag']) gbl_conf['analysis_params']['lim_flag'])
corr_dz = compute_corr_dz(obs.redshift, obs.distance)
gbl_results.best.properties[oidx, :] = [sed.info[k] for k in gbl_results.best.properties[oidx, :] = [sed.info[k] for k in
gbl_results.best.propertiesnames] gbl_results.best.propertiesnames]
iprop = [i for i, k in enumerate(gbl_results.best.propertiesnames) iprop = [i for i, k in enumerate(gbl_results.best.propertiesnames)
if k in gbl_results.best.massproportional] if k in gbl_results.best.massproportional]
gbl_results.best.properties[oidx, iprop] *= scaling gbl_results.best.properties[oidx, iprop] *= scaling * corr_dz
gbl_results.best.fluxes[oidx, :] = fluxes * scaling gbl_results.best.fluxes[oidx, :] = fluxes * scaling
if gbl_conf['analysis_params']["save_best_sed"]: if gbl_conf['analysis_params']["save_best_sed"]:
......
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
# Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt # Licensed under the CeCILL-v2 licence - see Licence_CeCILL_V2-en.txt
# Author: Médéric Boquien # Author: Médéric Boquien
from astropy.cosmology import WMAP7 as cosmo
from astropy.table import Column from astropy.table import Column
import numpy as np import numpy as np
from scipy.constants import parsec
from ..utils import read_table from ..utils import read_table
from .utils import get_info from .utils import get_info
...@@ -33,6 +35,15 @@ class Observation(object): ...@@ -33,6 +35,15 @@ class Observation(object):
def __init__(self, row, cls): def __init__(self, row, cls):
self.redshift = row['redshift'] self.redshift = row['redshift']
self.id = row['id'] self.id = row['id']
if 'distance' in row.colnames and np.isfinite(row['distance']):
self.distance = row['distance'] * parsec * 1e6
else:
if self.redshift == 0.:
self.distance = 10. * parsec
elif self.redshift > 0:
self.distance = cosmo.luminosity_distance(self.redshift).value
else:
self.distance = np.nan
self.fluxes = np.array([row[band] for band in cls.bands]) self.fluxes = np.array([row[band] for band in cls.bands])
self.fluxes_err = np.array([row[band + '_err'] for band in cls.bands]) self.fluxes_err = np.array([row[band + '_err'] for band in cls.bands])
self.intprops = np.array([row[prop] for prop in cls.intprops]) self.intprops = np.array([row[prop] for prop in cls.intprops])
...@@ -82,6 +93,10 @@ class ObservationsManagerPassbands(object): ...@@ -82,6 +93,10 @@ class ObservationsManagerPassbands(object):
threshold) threshold)
self._add_model_error(modelerror) self._add_model_error(modelerror)
# Rebuild the quantities to fit after vetting them
self.tofit = self.bands + self.intprops + self.extprops
self.tofit_err = self.bands_err + self.intprops_err + self.extprops_err
self.observations = list([Observation(row, self) for row in self.table]) self.observations = list([Observation(row, self) for row in self.table])
def __len__(self): def __len__(self):
...@@ -116,8 +131,8 @@ class ObservationsManagerPassbands(object): ...@@ -116,8 +131,8 @@ class ObservationsManagerPassbands(object):
"in the observation table.".format(item)) "in the observation table.".format(item))
for item in self.table.colnames: for item in self.table.colnames:
if (item != 'id' and item != 'redshift' and item not in self.tofit + if (item != 'id' and item != 'redshift' and item != 'distance' and
self.tofit_err): item not in self.tofit + self.tofit_err):
self.table.remove_column(item) self.table.remove_column(item)
print("Warning: {} in the input file but not to be taken into" print("Warning: {} in the input file but not to be taken into"
" account in the fit.".format(item)) " account in the fit.".format(item))
......
...@@ -68,10 +68,12 @@ class Configuration(object): ...@@ -68,10 +68,12 @@ class Configuration(object):
self.config.comments['data_file'] = wrap( self.config.comments['data_file'] = wrap(
"File containing the input data. The columns are 'id' (name of the" "File containing the input data. The columns are 'id' (name of the"
" object), 'redshift' (if 0 the distance is assumed to be 10 pc), " " object), 'redshift' (if 0 the distance is assumed to be 10 pc), "
"the filter names for the fluxes, and the filter names with the " "'distance' (Mpc, optional, if present it will be used in lieu "
"'_err' suffix for the uncertainties. The fluxes and the " "of the distance computed from the redshift), the filter names for"
"uncertainties must be in mJy. This file is optional to generate " " the fluxes, and the filter names with the '_err' suffix for the "
"the configuration file, in particular for the savefluxes module.") "uncertainties. The fluxes and the uncertainties must be in mJy. "
"This file is optional to generate the configuration file, in "
"particular for the savefluxes module.")
self.spec['data_file'] = "string()" self.spec['data_file'] = "string()"
self.config['parameters_file'] = "" self.config['parameters_file'] = ""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment