Skip to content

Commit

Permalink
Merge branch 'lenstronomy:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
sibirrer committed May 22, 2024
2 parents f1b150e + 3e20ba7 commit 938eac1
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 1 deletion.
2 changes: 2 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
codecov:
token: 69d31c95-1c33-44f1-883e-0886d62a01d4
comment: # this is a top-level key
layout: " diff, flags, files"
behavior: default
Expand Down
69 changes: 69 additions & 0 deletions lenstronomy/LightModel/Profiles/lineprofile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import numpy as np


__all__ = ["LineProfile"]


class LineProfile(object):
"""Horizontal line segment class.
The line extends `length` arcseconds from
(`start_x`, `start_y`) at an angle `angle` degrees to the horizontal. Line `width`
is centered in the perpendicular direction, e.g. a profile with 1 arcsecond width
and `angle=0` will span -0.5 to 0.5 in the y-direction. Surface brightness is
constant and given by `amp`.
"""

param_names = ["amp", "angle", "length", "width", "start_x", "start_y"]
lower_limit_default = {
"amp": 0,
"angle": -180,
"length": 0.01,
"width": 0.01,
"start_x": -100,
"start_y": -100,
}
upper_limit_default = {
"amp": 10,
"angle": 180,
"length": 10,
"width": 5,
"start_x": 100,
"start_y": 100,
}

def __init__(self):
pass

def function(self, x, y, amp, angle, length, width, start_x=0, start_y=0):
"""Surface brightness per angular unit.
:param x: x-coordinate on sky
:param y: y-coordinate on sky
:param amp: constant surface brightness of line
:param angle: angle of line to the horizontal (degrees)
:param length: length of line (arcseconds)
:param width: width of line (arcseconds), line width extends symmetrically
:param start_x: ra coordinate of start of line
:param start_y: dec-coordinate of start of line
:return: surface brightness, raise as definition is not defined
"""
ang = -np.deg2rad(angle)
x_ = np.cos(ang) * (x - start_x) + np.sin(ang) * (y - start_y)
y_ = np.cos(ang) * (y - start_y) - np.sin(ang) * (x - start_x)
flux = np.zeros_like(x_)
flux[(x_ >= 0) * (x_ <= length) * (abs(y_) <= width / 2)] = amp
return flux

def total_flux(self, amp, angle, length, width, start_x=0, start_y=0):
"""Integrated flux of the profile.
:param amp: constant surface brightness of line
:param angle: angle of line to the horizontal (degrees)
:param length: length of line (arcseconds)
:param width: width of line (arcseconds), line width extends symmetrically
:param start_x: ra coordinate of start of line
:param start_y: dec-coordinate of start of line
:return: total flux
"""
return amp * length * width
6 changes: 6 additions & 0 deletions lenstronomy/LightModel/light_model_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"SLIT_STARLETS_GEN2",
"LINEAR",
"LINEAR_ELLIPSE",
"LINE_PROFILE",
]


Expand Down Expand Up @@ -193,6 +194,10 @@ def __init__(self, light_model_list, smoothing=0.001, sersic_major_axis=None):
from lenstronomy.LightModel.Profiles.linear import LinearEllipse

self.func_list.append(LinearEllipse())
elif profile_type == "LINE_PROFILE":
from lenstronomy.LightModel.Profiles.lineprofile import LineProfile

self.func_list.append(LineProfile())
else:
raise ValueError(
"No light model of type %s found! Supported are the following models: %s"
Expand Down Expand Up @@ -291,6 +296,7 @@ def total_flux(self, kwargs_list, norm=False, k=None):
"GAUSSIAN_ELLIPSE",
"MULTI_GAUSSIAN",
"MULTI_GAUSSIAN_ELLIPSE",
"LINE_PROFILE",
]:
kwargs_new = kwargs_list_standard[i].copy()
if norm is True:
Expand Down
3 changes: 3 additions & 0 deletions lenstronomy/LightModel/linear_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def functions_split(self, x, y, kwargs_list, k=None):
"ELLIPSOID",
"LINEAR",
"LINEAR_ELLIPSE",
"LINE_PROFILE",
]:
kwargs_new = kwargs_list[i].copy()
new = {"amp": 1}
Expand Down Expand Up @@ -156,6 +157,7 @@ def num_param_linear_list(self, kwargs_list):
"ELLIPSOID",
"LINEAR",
"LINEAR_ELLIPSE",
"LINE_PROFILE",
]:
n_list += [1]
elif model in ["MULTI_GAUSSIAN", "MULTI_GAUSSIAN_ELLIPSE"]:
Expand Down Expand Up @@ -215,6 +217,7 @@ def update_linear(self, param, i, kwargs_list):
"ELLIPSOID",
"LINEAR",
"LINEAR_ELLIPSE",
"LINE_PROFILE",
]:
kwargs_list[k]["amp"] = param[i]
i += 1
Expand Down
35 changes: 35 additions & 0 deletions test/test_LightModel/test_Profiles/test_lineprofile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from lenstronomy.LightModel.Profiles.lineprofile import LineProfile
import numpy as np
import numpy.testing as npt


class TestLineProfile(object):
def setup_method(self):
self.lineprofile = LineProfile()

def test_function(self):
amp = 1
length = 1
width = 0.01
angle = 57
x = np.array([0, 1, 0.5 * np.cos(np.deg2rad(-angle))])
y = np.array([0, 0, 0.5 * np.sin(np.deg2rad(-angle))])
x_single = 0.2 * np.cos(np.deg2rad(-angle))
y_single = 0.2 * np.sin(np.deg2rad(-angle))
flux_true = np.array([amp, 0, amp])
flux = self.lineprofile.function(x, y, amp, angle, length, width)
single_flux_true = amp
single_flux = self.lineprofile.function(
x_single, y_single, amp, angle, length, width
)
npt.assert_equal(flux_true, flux)
npt.assert_equal(single_flux_true, single_flux)

def test_total_flux(self):
amp = 1
length = 1
width = 0.01
angle = 57
total_flux = self.lineprofile.total_flux(amp, angle, length, width)
total_flux_true = length * width * amp
npt.assert_equal(total_flux_true, total_flux)
20 changes: 19 additions & 1 deletion test/test_LightModel/test_light_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def setup_method(self):
"INTERPOL",
"SHAPELETS_POLAR_EXP",
"ELLIPSOID",
"LINE_PROFILE",
]
phi_G, q = 0.5, 0.8
e1, e2 = param_util.phi_q2_ellipticity(phi_G, q)
Expand Down Expand Up @@ -129,6 +130,14 @@ def setup_method(self):
"center_x": 0,
"center_y": 0,
}, # 'ELLIPSOID'
{
"amp": 1,
"length": 1.0,
"width": 0.01,
"angle": 57,
"start_x": 0,
"start_y": 0,
}, # 'LINE_PROFILE'
]

self.LightModel = LightModel(
Expand Down Expand Up @@ -176,7 +185,7 @@ def test_param_name_list_latex(self):

def test_num_param_linear(self):
num = self.LightModel.num_param_linear(self.kwargs, list_return=False)
assert num == 19
assert num == 20

num_list = self.LightModel.num_param_linear(self.kwargs, list_return=True)
assert num_list[0] == 1
Expand All @@ -199,6 +208,7 @@ def test_total_flux(self):
"GAUSSIAN_ELLIPSE",
"MULTI_GAUSSIAN",
"MULTI_GAUSSIAN_ELLIPSE",
"LINE_PROFILE",
]
kwargs_list = [
{
Expand Down Expand Up @@ -247,6 +257,14 @@ def test_total_flux(self):
"center_x": 0,
"center_y": 0,
}, # 'MULTI_GAUSSIAN_ELLIPSE'
{
"amp": 1,
"length": 1.0,
"width": 0.01,
"angle": 57,
"start_x": 0,
"start_y": 0,
}, # 'LINE_PROFILE'
]
lightModel = LightModel(light_model_list=light_model_list)
total_flux_list = lightModel.total_flux(kwargs_list)
Expand Down

0 comments on commit 938eac1

Please sign in to comment.