Previous: Limb darkening · Documentation home · Next: Coordinates and conventions
VBMicrolensing correspondence: AccuracyControl.md. The
s=0.8,q=0.1, source-position, source-radius, and tolerance examples are retained.
Use the same lens and source values while changing only the requested absolute accuracy:
import lcbinint
s, q, y1, y2, rho = 0.8, 0.1, 0.01, 0.01, 0.01
mag_1e3 = lcbinint.binary_ray_shooting(
y1, y2, s=s, q=q, rho=rho,
options=lcbinint.Options(tol=1e-3),
)
print("Magnification (accuracy at 1.e-3) =", mag_1e3)
mag_1e4 = lcbinint.binary_ray_shooting(
y1, y2, s=s, q=q, rho=rho,
options=lcbinint.Options(tol=1e-4),
)
print("Magnification (accuracy at 1.e-4) =", mag_1e4)mag_rel_1e1 = lcbinint.binary_ray_shooting(
y1, y2, s=s, q=q, rho=rho,
options=lcbinint.Options(reltol=1e-1),
)
print("Magnification (relative precision at 1.e-1) =", mag_rel_1e1)lcbinint uses one budget at each epoch:
tol + reltol * max(abs(magnification), 1)
tol is the absolute term and reltol is the relative term. If either term is
set explicitly, the other term is zero unless it is also supplied. If both are
left at zero, the calibrated default is equivalent to 1e-4 + 1e-3 * max(abs(magnification), 1).
The returned value is not made accurate merely by requesting a tolerance.
Inspect finite_source_converged and finite_source_error_estimates when the
result matters scientifically.
A finite-source light curve can move between several methods from epoch to epoch:
| Reported method | Meaning |
|---|---|
point_source |
Source size is safely negligible at this position. |
hexadecapole |
A fourth-order finite-source expansion is locally safe. |
source_plane_quadrature |
The source disk is integrated in the source plane. |
inverse_ray_cartesian |
A Cartesian inverse-ray grid resolves the finite images. |
inverse_ray_polar |
A polar inverse-ray grid is selected for suitable high-magnification geometry. |
inverse_ray_grid controls the full inverse-ray backend; it does not disable
the safe point-source or hexadecapole fast paths.
automatic = lcbinint.Options(
nbin="auto",
inverse_ray_grid="auto",
tol=1e-4,
reltol=1e-3,
)
fixed_cartesian = lcbinint.Options(
nbin=800,
inverse_ray_grid="cartesian",
tol=1e-4,
reltol=1e-3,
)
fixed_polar = lcbinint.Options(
nbin=800,
polar_nbin=800,
inverse_ray_grid="polar",
tol=1e-4,
reltol=1e-3,
)nbin="auto" predicts one resolution for each binary-lens epoch from the
calibrated law, rounds upward, and evaluates it once. Its embedded error
indicator is diagnostic and does not trigger a larger grid. A fixed integer is
useful for reproducibility experiments and is also one-shot.
| Option | Purpose | Normal choice |
|---|---|---|
tol, reltol |
Absolute and relative finite-source error budget. | Set both for a scientific accuracy target. |
nbin |
Automatic or fixed source-grid resolution. | "auto" |
max_source_bins |
Ceiling applied to the automatic resolution prediction. | Leave at the calibrated default unless diagnostics require more. |
inverse_ray_grid |
"auto", "cartesian", or "polar". |
"auto" |
polar_nbin |
Optional independent polar resolution. | None |
caustic_bins |
Sampling used only for caustic/critical-curve visualization. | Increase for denser scatter plots. |
hex_tol |
Fourth-order self-consistency threshold. | Leave at the default unless validating method selection. |
point_source_threshold |
Geometric point-source safety margin. | Advanced validation only. |
import numpy as np
import matplotlib.pyplot as plt
params = {
"s": 0.9, "q": 0.1, "u0": 0.0, "alpha": 1.0,
"rho": 0.01, "tE": 30.0, "t0": 7500,
}
t = np.linspace(7470, 7530, 300)
curve = lcbinint.LightCurve(options=automatic)
info = curve.info(t, params)
method_names = list(dict.fromkeys(info.finite_source_method_names))
method_index = {name: index for index, name in enumerate(method_names, start=1)}
selected = [method_index[name] for name in info.finite_source_method_names]
# Fixed, colorblind-friendly palette; reserve vermilion for caustics below.
method_colors = ["#0173B2", "#DE8F05", "#029E73", "#CC78BC", "#56B4E9"]
fig, (mag_ax, method_ax) = plt.subplots(2, 1, sharex=True, figsize=(4.8, 3.8))
mag_ax.plot(t, info.magnifications)
mag_ax.set_ylabel("Magnification")
for color_index, name in enumerate(method_names):
mask = np.asarray(info.finite_source_method_names) == name
method_ax.scatter(
t[mask], np.asarray(selected)[mask], s=10,
color=method_colors[color_index],
)
method_ax.set_yticks(range(1, len(method_names) + 1))
method_ax.set(xlabel="Time", ylabel="Method")
fig.tight_layout()
plt.show()Use the same colors to show where each method is selected along the source trajectory. Each uninterrupted run is drawn as one line segment; caustics are red.
methods = np.asarray(info.finite_source_method_names)
trajectory = curve.source_trajectory(t, params)
caustics = curve.caustics(params)
plt.figure(figsize=(2.8, 2.8))
for x, y in zip(caustics.x, caustics.y):
plt.plot(x, y, color="#6C6C6C", lw=1.1)
display_x = np.asarray(trajectory.x)
display_y = np.asarray(trajectory.y)
for color_index, name in enumerate(method_names):
indices = np.flatnonzero(methods == name)
breaks = np.where(np.diff(indices) != 1)[0] + 1
for run in np.split(indices, breaks):
if len(run) > 1:
plt.plot(
display_x[run], display_y[run],
color=method_colors[color_index], lw=1.2,
)
elif len(run) == 1:
plt.plot(
display_x[run], display_y[run], color=method_colors[color_index],
marker="o", markersize=2.5,
)
plt.xlabel("X")
plt.ylabel("Y")
plt.axis("equal")
plt.show()The method numbers in the lower panel are:
point_source— point-source approximation.hexadecapole— fourth-order finite-source approximation.inverse_ray_cartesian— Cartesian inverse ray shooting.source_plane_quadrature— direct source-plane integration.inverse_ray_polar— polar inverse ray shooting.
For the calibration evidence and the exact retry rules, continue to Numerical methods.
Previous: Limb darkening · Documentation home · Next: Coordinates and conventions

