ler.image_properties.cross_section_njit

Module for analytical caustic computation and cross-section evaluation of EPL (Elliptical Power-Law) + external shear lens models.

Provides numba-accelerated routines for computing critical curves, caustic boundaries, polygon areas, and lensing cross sections. All core functions are decorated with @njit for high performance.

Usage:

Compute the double-caustic boundary for a single lens:

>>> from ler.image_properties.cross_section_njit import caustics_epl_shear
>>> pts = caustics_epl_shear(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.

pol_to_ell(r, theta, q)

Convert polar coordinates to elliptical coordinates.

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

Evaluate the complex angular function Omega for the EPL profile.

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

Scalar version of omega that avoids temporary array allocation.

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.

caustics_epl_shear(q, phi, gamma, gamma1, gamma2[, ...])

Analytically compute the caustics of an EPL + external shear lens model.

polygon_area(xv, yv)

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

caustic_double_area(q, phi, gamma, gamma1, gamma2[, ...])

Compute the area enclosed by the double caustic of an EPL + shear lens.

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

Create a JIT-compiled cross-section evaluator for batched systems.

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

Compute double-caustic cross sections for batched lens parameters.

Attributes

C_LIGHT

ler.image_properties.cross_section_njit.C_LIGHT = '299792458.0'[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.pol_to_ell(r, theta, q)[source]

Convert polar coordinates to elliptical coordinates.

Parameters:
rfloat or numpy.ndarray

Radial coordinate.

thetafloat or numpy.ndarray

Polar angle in radians.

qfloat

Axis ratio.

Returns:
rellfloat or numpy.ndarray

Elliptical radial coordinate.

phifloat or numpy.ndarray

Elliptical angle in radians.

Examples

>>> rell, phi = pol_to_ell(1.0, 0.5, 0.8)
ler.image_properties.cross_section_njit.omega(phi, t, q, omegas, 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.

omegasnumpy.ndarray

Pre-allocated complex output buffer with the same shape as phi. Filled in-place.

niter_maxint

Maximum number of series terms.

default: 200

tolfloat

Convergence tolerance.

default: 1e-16

Returns:
omegasnumpy.ndarray

Complex Omega values at each angle (same object as input buffer).

Examples

>>> import numpy as np
>>> phi = np.linspace(0, 2 * np.pi, 100)
>>> result = np.empty_like(phi, dtype=np.complex128)
>>> omega(phi, t=1.0, q=0.8, omegas=result)
ler.image_properties.cross_section_njit.omega_scalar(phi, t, q, niter_max=200, tol=1e-16)[source]

Scalar version of omega that avoids temporary array allocation.

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.caustics_epl_shear(q, phi, gamma, gamma1, gamma2, theta_E=1.0, num_th=500, maginf=-100.0, sourceplane=True, return_which='double')[source]

Analytically compute the caustics of an EPL + external shear lens model.

For gamma > 2 the outer critical curve does not exist. In that case the routine finds the curve at a finite magnification maginf instead of the true caustic.

Parameters:
qfloat

Lens axis ratio.

phifloat

Lens position angle in radians.

gammafloat

EPL power-law slope.

gamma1float

External shear component 1.

gamma2float

External shear component 2.

theta_Efloat

Einstein radius.

default: 1.0

num_thint

Number of azimuthal samples for the boundary curve.

default: 500

maginffloat

Magnification cutoff for the outer curve.

default: -100.0

sourceplanebool

If True, map critical curves to the source plane.

default: True

return_whichstr

Which boundary to return.

Options:

  • ‘double’: Double-image region boundary

  • ‘quad’: Quad-image region boundary

  • ‘caustic’: Inner caustic (astroid) only

  • ‘cut’: Outer cut curve only

default: ‘double’

Returns:
ptsnumpy.ndarray

2×N array of (x, y) boundary coordinates.

Examples

>>> pts = caustics_epl_shear(
...     q=0.8, phi=0.0, gamma=2.0, gamma1=0.03, gamma2=-0.01
... )
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

Polygon vertex x-coordinates.

yvnumpy.ndarray

Polygon vertex y-coordinates.

Returns:
areafloat

The enclosed geometric area.

Examples

>>> area = polygon_area(np.array([0.0, 1.0, 0.0]), np.array([0.0, 0.0, 1.0]))
ler.image_properties.cross_section_njit.caustic_double_area(q, phi, gamma, gamma1, gamma2, theta_E=1.0, num_th=500, maginf=-100.0, sourceplane=True, return_which='double')[source]

Compute the area enclosed by the double caustic of an EPL + shear lens.

Parameters:
qfloat

Lens axis ratio.

phifloat

Lens position angle in radians.

gammafloat

Power-law slope.

gamma1float

External shear component 1.

gamma2float

External shear component 2.

theta_Efloat

Einstein radius. default: 1.0

num_thint

Number of angular samples. default: 500

maginffloat

Magnification cutoff parameter. default: -100.0

Returns:
areafloat

Area of the double caustic in units of theta_E^2.

Examples

>>> area = caustic_double_area(0.8, 0.0, 2.0, 0.03, -0.01)
ler.image_properties.cross_section_njit.make_cross_section_reinit(Da_instance, num_th=500, maginf=-100.0, sourceplane=True, return_which='double')[source]

Create a JIT-compiled cross-section evaluator for batched systems.

Parameters:
Da_instancecallable

Angular-diameter-distance function that accepts redshift arrays.

num_thint

Number of angular samples for caustic construction. default: 500

maginffloat

Magnification cutoff used by the caustic routine. default: -100.0

Returns:
cross_section_reinitcallable

Parallel numba function with signature (zs, zl, sigma, q, phi, gamma, gamma1, gamma2) returning the double-caustic cross section array.

Examples

>>> cross_section = make_cross_section_reinit(Da_instance)
>>> cs = cross_section(zs, zl, sigma, q, phi, gamma, gamma1, gamma2)
ler.image_properties.cross_section_njit.cross_section_epl_shear_unit(e1, e2, gamma, gamma1, gamma2, theta_E=None, num_th=500, maginf=-100.0, sourceplane=True, return_which='double')[source]

Compute double-caustic cross sections for batched lens parameters.

Parameters:
e1numpy.ndarray

Lens ellipticity component 1.

e2numpy.ndarray

Lens ellipticity component 2.

gammanumpy.ndarray

EPL slopes.

gamma1numpy.ndarray

External shear component 1.

gamma2numpy.ndarray

External shear component 2.

theta_Enumpy.ndarray or None

Einstein radius in angular units. If None, assumed to be 1.0 for all

Returns
-------
csnumpy.ndarray

Cross section values in angular units.