import torch
from ...param import forward
from ...backend_obj import ArrayLike
from ...utils.decorators import ignore_numpy_warnings
from .._shared_methods import parametric_initialize, parametric_segment_initialize
from ...utils.parametric_profiles import sersic_np
from .. import func
def _x0_func(model, R, F):
return 2.0, R[4], 10 ** F[4]
[docs]
class SersicMixin:
"""Sersic radial light profile (Sersic 1963).
This is a classic profile used widely in galaxy modelling. It can be a good
starting point for many extended objects. The functional form of the Sersic
profile is defined as:
$$I(R) = I_e * \\exp(- b_n((R/R_e)^{1/n} - 1))$$
It is a generalization of a gaussian, exponential, and de-Vaucouleurs
profile. The Sersic index `n` controls the shape of the profile, with `n=1`
being an exponential profile, `n=4` being a de-Vaucouleurs profile, and
`n=0.5` being a Gaussian profile.
**Parameters:**
- `n`: Sersic index which controls the shape of the brightness profile
- `Re`: half light radius [arcsec]
- `Ie`: intensity at the half light radius [flux/arcsec^2]
"""
_model_type = "sersic"
_parameter_specs = {
"n": {"units": "none", "valid": (0.36, 8), "shape": (), "dynamic": True},
"Re": {"units": "arcsec", "valid": (0, None), "shape": (), "dynamic": True},
"Ie": {"units": "flux/arcsec^2", "valid": (0, None), "shape": (), "dynamic": True},
}
[docs]
@torch.no_grad()
@ignore_numpy_warnings
def initialize(self):
super().initialize()
parametric_initialize(
self, self.target[self.window], sersic_np, ("n", "Re", "Ie"), _x0_func
)
[docs]
@forward
def radial_model(self, R: ArrayLike, n: ArrayLike, Re: ArrayLike, Ie: ArrayLike) -> ArrayLike:
return func.sersic(R, n, Re, Ie)
[docs]
class iSersicMixin:
"""Sersic radial light profile (Sersic 1963).
This is a classic profile used widely in galaxy modelling. It can be a good
starting point for many extended objects. The functional form of the Sersic
profile is defined as:
$$I(R) = I_e * \\exp(- b_n((R/R_e)^{1/n} - 1))$$
It is a generalization of a gaussian, exponential, and de-Vaucouleurs
profile. The Sersic index `n` controls the shape of the profile, with `n=1`
being an exponential profile, `n=4` being a de-Vaucouleurs profile, and
`n=0.5` being a Gaussian profile.
`n`, `Re`, and `Ie` are batched by their first dimension, allowing for
multiple Sersic profiles to be defined at once.
**Parameters:**
- `n`: Sersic index which controls the shape of the brightness profile
- `Re`: half light radius [arcsec]
- `Ie`: intensity at the half light radius [flux/arcsec^2]
"""
_model_type = "sersic"
_parameter_specs = {
"n": {"units": "none", "valid": (0.36, 8), "shape": (None,), "dynamic": True},
"Re": {"units": "arcsec", "valid": (0, None), "shape": (None,), "dynamic": True},
"Ie": {"units": "flux/arcsec^2", "valid": (0, None), "shape": (None,), "dynamic": True},
}
[docs]
@torch.no_grad()
@ignore_numpy_warnings
def initialize(self):
super().initialize()
parametric_segment_initialize(
model=self,
target=self.target[self.window],
prof_func=sersic_np,
params=("n", "Re", "Ie"),
x0_func=_x0_func,
segments=self.segments,
)
[docs]
@forward
def iradial_model(
self, i: int, R: ArrayLike, n: ArrayLike, Re: ArrayLike, Ie: ArrayLike
) -> ArrayLike:
return func.sersic(R, n[i], Re[i], Ie[i])
[docs]
class SersicPSFMixin:
"""Sersic radial light profile (Sersic 1963).
This is a classic profile used widely in galaxy modelling, though it
is simply a generalization of a Gaussian. It can be a good starting
point for many objects. The functional form of the Sersic profile is
defined as:
$$I(R) = I_e * \\exp(- b_n((R/R_e)^{1/n} - 1))$$
It includes the gaussian, exponential, and de-Vaucouleurs
profiles. The Sersic index `n` controls the shape of the profile, with `n=1`
being an exponential profile, `n=4` being a de-Vaucouleurs profile, and
`n=0.5` being a Gaussian profile.
**Parameters:**
- `n`: Sersic index which controls the shape of the brightness profile
- `Re`: half light radius [pix]
- `Ie`: intensity at the half light radius [flux/pix^2]
"""
_model_type = "sersic"
_parameter_specs = {
"n": {"units": "none", "valid": (0.36, 8), "shape": (), "dynamic": True},
"Re": {"units": "pix", "valid": (0, None), "shape": (), "dynamic": True},
"Ie": {
"units": "flux/pix^2",
"valid": (0, None),
"shape": (),
"dynamic": False,
"value": 1.0,
},
}
[docs]
@torch.no_grad()
@ignore_numpy_warnings
def initialize(self):
super().initialize()
parametric_initialize(
self, self.target[self.window], sersic_np, ("n", "Re", "Ie"), _x0_func
)
[docs]
@forward
def radial_model(self, R: ArrayLike, n: ArrayLike, Re: ArrayLike, Ie: ArrayLike) -> ArrayLike:
return func.sersic(R, n, Re, Ie)