Skip to content

Commit

Permalink
Merge pull request #224 from karllark/joss_review2
Browse files Browse the repository at this point in the history
Updates based on 2nd JOSS review
  • Loading branch information
karllark authored Aug 14, 2024
2 parents 010ca10 + 2e36501 commit 670dfe0
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 77 deletions.
101 changes: 101 additions & 0 deletions docs/dust_extinction/dev_model.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
##################
Base Model Classes
##################

All the extinction models are based on either provided in dust_extinction
or an astropy.modeling `FittableModel`.

For examples of how all the classes in ``dust_extinction`` are used, see the
implemented models.

.. _allmods:

All
===

All of these classes used in ``dust_extinction`` are based on the
`Model <https://docs.astropy.org/en/stable/modeling/>`_ astropy.modeling class.
See the astropy docs for the full details of all that is possible with this class.

All dust extinction models have the following:

* A member variable `x_range` that that define the valid range of wavelengths. These are defined in inverse microns for historical reasons.
* A member function `evaluate` that computes the extinction at a given `x` and any model parameter values. The `x` values are checked to be within the valid `x_range`. The `x` values should have astropy.units. If they do not, then they are assumed to be in inverse microns and a warning is issued stating such.

FittableModel
=============

The ``dust_extinction`` shape models are based on the astropy `FittableModel`.
One general use case for these models is to fit observed dust extinction curves.
See :ref:`fit_curves`. These models follow the standard astropy setup for such
models. This includes defining the parameters to be fit with the `Parameter`
function.

Thus all `shape` models have:

* The member variable `x_range` and function `evaluate` (see :ref:`allmods`)
* Member parameters that are defined with the astropy `Parameter` function. This includes default starting values and any standard bounds on the parameters. The number and name of the paramaeters varies by `shape` model.
* The `evaluate` function that calculates the extinction curve based on the input parameters.

BaseExtModel
============

The :class:`~dust_extinction.baseclasses.BaseExtModel` provides the base model for all
the rest of the `dust_extinction` models. This model provides the
`extinguish` member function (see :ref:`extinguish_example`).

All of the `average` models are based on `BaseExtModel` directly. Thus
all the `average` models have:

* The member variable `x_range` and function `evaluate` (see :ref:`allmods`). The `evaluate` function may interpolate the observed average extinction curve or it may be based on a `shape` fit to the observed data.
* The member function `extinguish`.
* A member parameter `Rv` that gives the ratio of absolute to selective extinction (i.e., R(V) = A(V)/E(B-V)). This is not set with the astropy `Parameter` function as is included for reference.
* Member variables that give the tabulated observed extinction curve as a function of wavelength. The variables for this information are `obsdata_x` and `obsdata_axav`. The accuracy of this tabulated information is given as `obsdata_tolerance` and this is used for the automated testing and in plotting. Some models also have an `obsdata_azav_unc` if such is available from the literature.

BaseExtRvModel
==============

The :class:`~dust_extinction.baseclasses.BaseExtRvModel` provides the base model for all
the ``dust_extinction`` models that are depending on `Rv` only. `Rv` is the
ratio of absolute to selective extinction (i.e., R(V) = A(V)/E(B-V)).

These are the majority of the `parameter_average` models and they have:

* The member variable `x_range` and function `evaluate` (see :ref:`allmods`). The `evaluate` function that calculates the extinction curve based on the `Rv` value.
* The member function `extinguish`.
* A member variable `Rv` defined using the astropy `Parameter` function.
* A member variable `Rv_range` that provides the valid range of `Rv` values.
* A validator member function called `Rv` tagged with `@Rv.validator` that validates the input `Rv` based on the `Rv_range`.

BaseExtRvAfAModel
=================

The :class:`~dust_extinction.baseclasses.BaseExtRvAfAModel` provides the base model for all
the ``dust_extinction`` models that are depending on `RvA` and `fA`.
These models are a mixture of two ``dust_extinction`` models where the A component
is dependent on `Rv` and the B component is not.
The `RvA` gives the R(V) value of component A and `fA` gives the fraction of the A
component and (1 - fA) gives the fraction of the B component.

These `parameter_average` models have:

* The member variable `x_range` and function `evaluate` (see :ref:`allmods`). The `evaluate` function that calculates the extinction curve based on the `Rv` and `fA` values.
* The member function `extinguish`.
* Member variables `RvA` and `fA` defined using the astropy `Parameter` function.
* A member variable `RvA_range` that provides the valid range of `RvA` values.
* A member variable `fA_range` that provides the valid range of `fA` values.
* A validator member function called `RvA` tagged with `@RvA.validator` that validates the input `Rv` based on the `Rv_range`.
* A validator member function called `fA` tagged with `@fA.validator` that validates the input `fA` based on the `fA_range`.

BaseExtGrainModel
=================

The :class:`~dust_extinction.baseclasses.BaseExtGrainModel` provides the base model for all
the ``dust_extinction`` models that are based on dust grain models. All these
models are provided as tabulated data tables.

These `grain_model` models have:

* The member variable `x_range` and function `evaluate` (see :ref:`allmods`). The `evaluate` function thats interpolates the model extinction curve.
* The member function `extinguish`.
* A member parameter `possnames` that is a dictionary with a key that is a tag for the model (e.g., `MWRV31`) and a tuple that is (filename, Rv). This key is used when initialized a `grain_model`.
2 changes: 2 additions & 0 deletions docs/dust_extinction/extinguish.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _extinguish_example:

###############################
Extinguish or Unextinguish Data
###############################
Expand Down
2 changes: 2 additions & 0 deletions docs/dust_extinction/fit_extinction.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.. _fit_curves:

#####################
Fit Extinction Curves
#####################
Expand Down
4 changes: 2 additions & 2 deletions docs/dust_extinction/references.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ G21: `Gordon et al. 2021, ApJ, 916, 33
G23: `Gordon et al. 2023, ApJ, 950, 86
<https://ui.adsabs.harvard.edu/abs/2023ApJ...950...86G>`_

G24: `Gordon et al. 2024, ApJ, in press
<https://ui.adsabs.harvard.edu/abs/2024arXiv240512792G>`_
G24: `Gordon et al. 2024, ApJ, 970, 51
<https://ui.adsabs.harvard.edu/abs/2024ApJ...970...51G>`_

HD23: `Hensley & Draine 2023, ApJ, 948, 55
<https://ui.adsabs.harvard.edu/abs/2023ApJ...948...55H>`_
Expand Down
8 changes: 8 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ User Documentation
Fitting extinction curves <dust_extinction/fit_extinction.rst>
References <dust_extinction/references.rst>

Dev Documentation
=================

.. toctree::
:maxdepth: 1

Model Base Classes (how to add a model) <dust_extinction/dev_model.rst>

Installation
============

Expand Down
59 changes: 55 additions & 4 deletions dust_extinction/baseclasses.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import numpy as np
from scipy.interpolate import interp1d

from astropy.modeling import Model, Parameter, InputParameterError

__all__ = ["BaseExtModel", "BaseExtRvModel", "BaseExtRvAfAModel"]
from .helpers import _get_x_in_wavenumbers, _test_valid_x_range

__all__ = ["BaseExtModel", "BaseExtRvModel", "BaseExtRvAfAModel", "BaseExtGrainModel"]


class BaseExtModel(Model):
"""
Base Extinction Model. Do not use.
Base Extinction Model. Do not use directly.
"""

n_inputs = 1
Expand Down Expand Up @@ -55,7 +58,7 @@ def extinguish(self, x, Av=None, Ebv=None):

class BaseExtRvModel(BaseExtModel):
"""
Base Extinction R(V)-dependent Model. Do not use.
Base Extinction R(V)-dependent Model. Do not use directly.
"""

Rv = Parameter(
Expand Down Expand Up @@ -89,7 +92,7 @@ def Rv(self, value):

class BaseExtRvAfAModel(BaseExtModel):
"""
Base Extinction R(V)_A, f_A -dependent Model. Do not use.
Base Extinction R(V)_A, f_A -dependent Model. Do not use directly.
"""

RvA = Parameter(
Expand Down Expand Up @@ -152,3 +155,51 @@ def fA(self, value):
+ " and "
+ str(self.fA_range[1])
)


class BaseExtGrainModel(BaseExtModel):
r"""
Base for Grain Models
Parameters
----------
None
Raises
------
None
"""

def evaluate(self, in_x):
"""
Generic dust grain model function
Parameters
----------
in_x: float
expects either x in units of wavelengths or frequency
or assumes wavelengths in wavenumbers [1/micron]
internally wavenumbers are used
Returns
-------
axav: np array (float)
A(x)/A(V) extinction curve [mag]
Raises
------
ValueError
Input x values outside of defined range
"""
x = _get_x_in_wavenumbers(in_x)

# check that the wavenumbers are within the defined range
_test_valid_x_range(x, self.x_range, self.__class__.__name__)

# define the function allowing for spline interpolation
# fill value needed to handle numerical issues at the edges
# the x values has already been checked to be in range
f = interp1d(self.data_x, self.data_axav, fill_value="extrapolate")

return f(x)
67 changes: 9 additions & 58 deletions dust_extinction/grain_models.py
Original file line number Diff line number Diff line change
@@ -1,67 +1,18 @@
import importlib.resources as importlib_resources

from scipy.interpolate import interp1d
import numpy as np

from astropy.table import Table
from astropy.modeling import InputParameterError
from astropy.io.fits import getdata

from .helpers import _get_x_in_wavenumbers, _test_valid_x_range
from .baseclasses import BaseExtModel
from dust_extinction.baseclasses import BaseExtGrainModel

__all__ = ["DBP90", "WD01", "D03", "ZDA04", "C11", "J13", "HD23"]


class GMBase(BaseExtModel):
r"""
Base for Grain Models

Parameters
----------
None
Raises
------
None
"""

def evaluate(self, in_x):
"""
WD01 function
Parameters
----------
in_x: float
expects either x in units of wavelengths or frequency
or assumes wavelengths in wavenumbers [1/micron]
internally wavenumbers are used
Returns
-------
axav: np array (float)
A(x)/A(V) extinction curve [mag]
Raises
------
ValueError
Input x values outside of defined range
"""
x = _get_x_in_wavenumbers(in_x)

# check that the wavenumbers are within the defined range
_test_valid_x_range(x, self.x_range, self.__class__.__name__)

# define the function allowing for spline interpolation
# fill value needed to handle numerical issues at the edges
# the x values has already been checked to be in range
f = interp1d(self.data_x, self.data_axav, fill_value="extrapolate")

return f(x)
__all__ = ["DBP90", "WD01", "D03", "ZDA04", "C11", "J13", "HD23"]


class DBP90(GMBase):
class DBP90(BaseExtGrainModel):
r"""
Desert et al (1990) Grain Models
Expand Down Expand Up @@ -144,7 +95,7 @@ def __init__(self, modelname="MWRV31", **kwargs):
super().__init__(**kwargs)


class WD01(GMBase):
class WD01(BaseExtGrainModel):
r"""
Weingartner & Draine (2001) Grain Models
Expand Down Expand Up @@ -238,7 +189,7 @@ def __init__(self, modelname="MWRV31", **kwargs):
super().__init__(**kwargs)


class D03(GMBase):
class D03(BaseExtGrainModel):
r"""
Draine (2003) Grain Models
Expand Down Expand Up @@ -330,7 +281,7 @@ def __init__(self, modelname="MWRV31", **kwargs):
super().__init__(**kwargs)


class ZDA04(GMBase):
class ZDA04(BaseExtGrainModel):
r"""
Zubko, Dwek, & Arendt (2004) Grain Models
Expand Down Expand Up @@ -413,7 +364,7 @@ def __init__(self, modelname="BARE-GR-S", **kwargs):
super().__init__(**kwargs)


class C11(GMBase):
class C11(BaseExtGrainModel):
r"""
Compiegne et al (2011) Grain Models
Expand Down Expand Up @@ -496,7 +447,7 @@ def __init__(self, modelname="MWRV31", **kwargs):
super().__init__(**kwargs)


class J13(GMBase):
class J13(BaseExtGrainModel):
r"""
Jones et al (2013) Grain Models
Expand Down Expand Up @@ -579,7 +530,7 @@ def __init__(self, modelname="MWRV31", **kwargs):
super().__init__(**kwargs)


class HD23(GMBase):
class HD23(BaseExtGrainModel):
r"""
Hensley & Draine (2023) Grain Model
Expand Down
27 changes: 14 additions & 13 deletions paper/paper.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,22 @@ width=70% }

The wavelength dependence of extinction for a model is computed by passing a
wavelength or frequency vector with units. Each model has a valid wavelength
range that is enforced, as extrapolation is not supported. The model output is in
the standard $A(\lambda)/A(V)$ units where $A(\lambda)$ is the extinction at
wavelength $\lambda$ and $A(V)$ is the extinction in the V band. Every model has
a helper `extinguish` function that alternatively provides the fractional
effects of extinction for a specific dust column (e.g., $A(V)$ value). This
allows for the effects of dust to be modeled for or removed from an observation.
range that is enforced, as extrapolation is not supported. The model output is
in the standard $A(\lambda)/A(V)$ units where $A(\lambda)$ is the extinction in
magnitudes at wavelength $\lambda$ and $A(V)$ is the extinction in magnitudes
in the V band. Every model has a helper `extinguish` function that
alternatively provides the fractional effects of extinction for a specific dust
column (e.g., $A(V)$ value). This allows for the effects of dust to be modeled
for or removed from an observation.

This package does not implement dust attenuation models[^1]. Dust attenuation
results when observing more complex systems like a star with nearby,
circumstellar dust or a galaxy with many stars extinguished by different amounts
of dust. In both cases, the wavelength dependence of effects of dust are
dependent not just on the dust grain properties, but also the effects of the
dust radiative transfer [@Steinacker13]. Specifically, these effects are the averaging of sources
extinguished by differing amount of dust and the inclusion of a significant
number of photons scattered into the observing beam.
results when observing more complex systems such as a star with nearby,
circumstellar dust or a galaxy with many stars extinguished by different
amounts of dust. In both cases, the wavelength dependence of effects of dust
are dependent not just on the dust grain properties, but also the effects of
the dust radiative transfer [@Steinacker13]. Specifically, these effects are
the averaging of sources extinguished by differing amount of dust and the
inclusion of a significant number of photons scattered into the observing beam.

[^1]: See [karllark/dust_attenuation](https://github.com/karllark/dust_attenuation).

Expand Down

0 comments on commit 670dfe0

Please sign in to comment.