ler.image_properties.cross_section_njit

Module for analytical caustic computation and cross-section evaluation.

Provides numba-accelerated routines for computing critical curves, caustic boundaries, polygon areas, and lensing cross sections for EPL (Elliptical Power-Law) + external shear lens models. All core functions are decorated with @njit for high performance.

Usage:

Basic workflow example:

>>> from ler.image_properties.cross_section_njit import caustic_points_epl_shear
>>> pts = caustic_points_epl_shear(theta_E=1.0, q=0.8, phi=0.0, gamma=2.0, gamma1=0.03, gamma2=-0.01)

Copyright (C) 2026 Phurailatpam Hemantakumar. Distributed under MIT License.

Module Contents

Functions

phi_q2_ellipticity(phi, q)

Convert lens orientation and axis ratio to ellipticity components.

ellipticity2phi_q(e1, e2)

Convert complex ellipticity moduli to orientation angle and axis ratio.

omega(phi, t, q[, niter_max, tol])

Evaluate the complex angular function Omega for the EPL profile.

cdot(a, b)

Compute the real-valued dot product of two complex numbers.

pol_to_cart(r, th)

Convert polar coordinates to Cartesian coordinates.

cart_to_pol(x, y)

Convert Cartesian coordinates to polar coordinates.

caustic_points_epl_shear(theta_E, q, phi, gamma, ...)

Calculates the 2D coordinates of the caustic for a SINGLE lens.

caustic_area_epl_shear(q, phi, gamma, gamma1, gamma2, ...)

Calculates the area of the double caustic for a SINGLE lens.

half_symmetric_polygon_area(xh, yh)

Area of a centrally symmetric closed polygon from half-boundary samples.

polygon_area(xv, yv)

Compute the area of a simple polygon using the Shoelace formula.

make_cross_section_area_reinit(Da_instance[, num_th, ...])

Make a jitted function to compute double-caustic cross sections.

cross_section_epl_shear_unit(e1, e2, gamma, gamma1, gamma2)

Compute double-caustic cross sections for batched lens parameters.

Attributes

C_LIGHT

PI

TWO_PI

EPS

ler.image_properties.cross_section_njit.C_LIGHT = '299792458.0'[source]
ler.image_properties.cross_section_njit.PI[source]
ler.image_properties.cross_section_njit.TWO_PI[source]
ler.image_properties.cross_section_njit.EPS = '1e-16'[source]
ler.image_properties.cross_section_njit.phi_q2_ellipticity(phi, q)[source]

Convert lens orientation and axis ratio to ellipticity components.

Parameters:
phifloat

Position angle of the lens major axis in radians.

qfloat

Axis ratio (minor/major), where 0 < q <= 1.

Returns:
e1float

First ellipticity component.

e2float

Second ellipticity component.

Examples

>>> e1, e2 = phi_q2_ellipticity(phi=0.25, q=0.8)
ler.image_properties.cross_section_njit.ellipticity2phi_q(e1, e2)[source]

Convert complex ellipticity moduli to orientation angle and axis ratio.

Parameters:
e1float

First ellipticity component.

e2float

Second ellipticity component.

Returns:
phifloat

Orientation angle in radians.

qfloat

Axis ratio (minor/major).

Examples

>>> phi, q = ellipticity2phi_q(0.1, 0.05)
ler.image_properties.cross_section_njit.omega(phi, t, q, niter_max=200, tol=1e-16)[source]

Evaluate the complex angular function Omega for the EPL profile.

This series expansion converges geometrically with ratio f = (1 - q)/(1 + q). The fastmath flag provides ~4x speedup due to the reduction nature of the summation.

Parameters:
phinumpy.ndarray

Azimuthal angles in radians.

tfloat

EPL slope exponent (t = gamma - 1).

qfloat

Axis ratio.

niter_maxint

Maximum number of series terms.

default: 200

tolfloat

Convergence tolerance.

default: 1e-16

Returns:
omegasnumpy.ndarray

Complex Omega values at each angle.

Examples

>>> import numpy as np
>>> phi = np.linspace(0, 2 * np.pi, 100)
>>> omegas = omega(phi, t=1.0, q=0.8)
ler.image_properties.cross_section_njit.cdot(a, b)[source]

Compute the real-valued dot product of two complex numbers.

Equivalent to Re(a) * Re(b) + Im(a) * Im(b).

Parameters:
acomplex

First complex number.

bcomplex

Second complex number.

Returns:
resultfloat

Real-valued dot product.

Examples

>>> cdot(1+2j, 3+4j)
11.0
ler.image_properties.cross_section_njit.pol_to_cart(r, th)[source]

Convert polar coordinates to Cartesian coordinates.

Parameters:
rfloat or numpy.ndarray

Radial coordinate.

thfloat or numpy.ndarray

Polar angle in radians.

Returns:
xfloat or numpy.ndarray

Cartesian x-coordinate.

yfloat or numpy.ndarray

Cartesian y-coordinate.

Examples

>>> x, y = pol_to_cart(1.0, np.pi / 4)
ler.image_properties.cross_section_njit.cart_to_pol(x, y)[source]

Convert Cartesian coordinates to polar coordinates.

The returned angle is wrapped to [0, 2π).

Parameters:
xfloat or numpy.ndarray

Cartesian x-coordinate.

yfloat or numpy.ndarray

Cartesian y-coordinate.

Returns:
rfloat or numpy.ndarray

Radial coordinate.

thetafloat or numpy.ndarray

Polar angle in radians, wrapped to [0, 2π).

Examples

>>> r, theta = cart_to_pol(1.0, 1.0)
ler.image_properties.cross_section_njit.caustic_points_epl_shear(theta_E, q, phi, gamma, gamma1, gamma2, num_th=500, maginf=-100.0, quad=False)[source]

Calculates the 2D coordinates of the caustic for a SINGLE lens. Accepts scalar float values.

Parameters:
theta_Efloat

Einstein radius.

qfloat

Axis ratio.

phifloat

Position angle of the lens major axis in radians.

gammafloat

EPL slope exponent.

gamma1float

First shear component.

gamma2float

Second shear component.

num_thint

Number of angular samples.

default: 500

maginffloat

Magnification cut threshold.

default: -100.0

quadbool

If True, return the quad (inner) caustic. If False, return the double (outer) caustic.

default: False

Returns:
rotatednumpy.ndarray

Shape (2, num_th) Cartesian coordinates of the caustic.

Examples

>>> pts = caustic_points_epl_shear(theta_E=1.0, q=0.8, phi=0.0, gamma=2.0, gamma1=0.03, gamma2=-0.01)
>>> pts_quad = caustic_points_epl_shear(theta_E=1.0, q=0.8, phi=0.0, gamma=2.0, gamma1=0.03, gamma2=-0.01, quad=True)
ler.image_properties.cross_section_njit.caustic_area_epl_shear(q, phi, gamma, gamma1, gamma2, theta_E, theta, cos_th, sin_th, cos_2th, sin_2th, maginf=-100.0)[source]

Calculates the area of the double caustic for a SINGLE lens. Accepts scalar float values.

Parameters:
qfloat

Axis ratio.

phifloat

Position angle of the lens major axis in radians.

gammafloat

EPL slope exponent.

gamma1float

First shear component.

gamma2float

Second shear component.

theta_Efloat

Einstein radius.

thetanumpy.ndarray

Array of angles.

cos_thnumpy.ndarray

Array of cosine of angles.

sin_thnumpy.ndarray

Array of sine of angles.

cos_2thnumpy.ndarray

Array of cosine of 2*angles.

sin_2thnumpy.ndarray

Array of sine of 2*angles.

maginffloat

Magnification cut threshold.

default: -100.0

Returns:
areafloat

Area of the caustic.

Examples

>>> import numpy as np
>>> num_th = 500
>>> theta = np.linspace(0, 2*np.pi*(num_th//2 - 1)/num_th, num_th//2)
>>> area = caustic_area_epl_shear(0.8, 0.0, 2.0, 0.03, -0.01, 1.0, theta, np.cos(theta), np.sin(theta), np.cos(2*theta), np.sin(2*theta))
ler.image_properties.cross_section_njit.half_symmetric_polygon_area(xh, yh)[source]

Area of a centrally symmetric closed polygon from half-boundary samples.

The full boundary is [v_0, …, v_{h-1}, -v_0, …, -v_{h-1}], so the total area is twice the area of the half polygon closed by -v_0. This avoids allocating temporary arrays of length h+1.

ler.image_properties.cross_section_njit.polygon_area(xv, yv)[source]

Compute the area of a simple polygon using the Shoelace formula.

Parameters:
xvnumpy.ndarray

x-coordinates of the polygon vertices.

yvnumpy.ndarray

y-coordinates of the polygon vertices.

Returns:
areafloat

Area of the polygon.

Examples

>>> import numpy as np
>>> area = polygon_area(np.array([0., 1., 0.]), np.array([0., 0., 1.]))
ler.image_properties.cross_section_njit.make_cross_section_area_reinit(Da_instance, num_th=500, maginf=-100.0)[source]

Make a jitted function to compute double-caustic cross sections.

Drop-in replacement with trig arrays closed over (faster), safe memory layout, and optional chunking for huge batches.

Parameters:
Da_instancecallable

Angular diameter distance function.

num_thint

Number of points to sample.

default: 500

maginffloat

Magnification cut threshold.

default: -100.0

Returns:
cross_section_areacallable

Jitted function to compute cross section areas.

Examples

>>> cross_section_fn = make_cross_section_area_reinit(Da_instance)
ler.image_properties.cross_section_njit.cross_section_epl_shear_unit(e1, e2, gamma, gamma1, gamma2, num_th=500, maginf=-100.0)[source]

Compute double-caustic cross sections for batched lens parameters.

Parameters:
e1numpy.ndarray

First ellipticity component array.

e2numpy.ndarray

Second ellipticity component array.

gammanumpy.ndarray

EPL slope exponent array.

gamma1numpy.ndarray

First shear component array.

gamma2numpy.ndarray

Second shear component array.

num_thint

Number of points to sample.

default: 500

maginffloat

Magnification cut threshold.

default: -100.0

Returns:
cross_section_areacallable

Jitted function to compute cross section areas.

Examples

>>> import numpy as np
>>> calculate_area = cross_section_epl_shear_unit(np.array([0.1]), np.array([0.05]), np.array([2.0]), np.array([0.03]), np.array([-0.01]))