# AC85 point-lens reproduction package

Everything in this folder is synthetic or analytic. No detector strain is read.

## Run

    python3 reproduce.py          # recompute and compare with expected-outputs.json (exit 0 on pass)
    python3 reproduce.py --write  # overwrite expected-outputs.json

Tested with Python 3.9.6, numpy 2.0.2, scipy 1.13.1 and mpmath 1.3.0.
A full run takes about one minute.

## Files

| File | Role |
| --- | --- |
| point_lens_reference.py | Analytic point-lens amplification, Takahashi & Nakamura 2003 (arXiv:astro-ph/0305055v2) Eq. (17), and the geometric-optics limit Eq. (18), with mpmath at 60 digits. |
| independent_fresnel_integral.py | A second route to F(w, y) that never uses the hypergeometric closed form: the area of the region T < tau gives the time-domain response, then a piecewise-linear Fourier integral plus a fitted tail gives F. |
| signal_injection.py | Synthetic Gaussian noise from the Ajith 2011 (arXiv:1107.1267v4) Eq. (4.7) design-curve fit, a leading-order stationary-phase chirp, point-lens injections and a template search. |
| injection-inputs.json | Every injection input: source mass, unlensed SNR, template grid, seeds and the reporting threshold. |
| expected-outputs.json | The outputs of the last --write run, with the software versions used. |
| provenance.json | Sources, conventions and checksums. |

## Units and conventions

- Lens mass is the redshifted mass M_Lz in solar masses; G M_sun / c^3 = 4.925490947e-6 s
  (IAU 2015 nominal solar mass parameter, exact speed of light).
- Dimensionless frequency w = 8 pi G M_Lz f / c^3. Impact parameter y is in Einstein radii.
- Fourier convention h(f) = integral h(t) exp(+2 pi i f t) dt (Cutler & Flanagan 1994,
  arXiv:gr-qc/9402014v1, Eq. 20). A delay dt multiplies h(f) by exp(+2 pi i f dt).
- Arrival time T(x, y) = |x - y|^2 / 2 - ln|x| - phi_m(y), so the first image arrives at T = 0.
- Inner product <a, b> = 4 Re sum conj(a) b / S_n df over 20 Hz to the innermost stable orbit
  frequency (219.9 Hz for 10 + 10 solar masses).

## What is checked

1. Independent Fresnel integral against Eq. (17) on y in {0.1, 0.3, 1, 3} and
   w in {0.1, 1, 3, 10, 30}. Worst relative difference: 4.2e-4. The fitted tail coefficient
   c1 is close to 1/2, the analytic large-tau behaviour of the time-domain response.
   Agreement in phase as well as magnitude confirms the sign convention of Eq. (17).
2. Low-frequency limit: |F - 1| falls monotonically as w goes from 1e-2 to 1e-4
   (for y = 1: 2.2e-2, 3.3e-3, 4.4e-4).
3. High-frequency limit: the relative difference from Eq. (18) falls with w
   (for y = 1: 2.6e-3 at w = 30, 2.6e-5 at w = 1000). Small y converges more slowly and
   not monotonically, because the leftover difference oscillates with w
   (y = 0.3: 3.1e-2 at w = 30, 6.5e-3 at w = 100, 8.7e-3 at w = 300, 1.1e-3 at w = 1000).
4. Injections at unlensed SNR 20 (Delta ln L = best lensed minus best unlensed template
   log likelihood, amplitude, time and phase maximized):
   - M_Lz = 1000, y = 0.5: median Delta ln L = 110.2, all 20 trials above 4.
     Without noise the exact template gives 115.2.
   - M_Lz = 1000, y = 2: median 4.27, 52.5 percent of 40 trials above 4.
     Without noise the exact template gives 6.03.
   - No lens: median 2.49, 90th percentile 4.35, maximum 7.97, 11.7 percent of 120 trials above 4.
5. Search check (the rows ending in -noise-free): with noise switched off, the search
   recovers the injected lens mass to 0.001 percent and the exact-template Delta ln L to
   1e-8 for both lensed cases. The coarse grid alone reaches 109.3 instead of 115.2, and
   0.73 instead of 6.03.

## Failure cases kept on purpose

- Pure noise produces a lens preference above the threshold of 4 in 14 of 120 trials. The
  largest (seed 3058, 7.97) prefers M_Lz near 1150 and y = 1.5. The lens model has two
  extra parameters and many fringe phases to try, so noise always finds some preference.
- A faint second image (y = 2) at SNR 20 gives a median of 4.27, while 10 percent of
  noise-only trials exceed 4.35. Half of these lensed trials would pass the threshold, and
  so would about one noise trial in nine.
- The first search used only a coarse lens-mass grid (36 masses, about 15 percent apart).
  At y = 2 the 90 ms delay moves the fringe phase at 200 Hz by several radians between grid
  masses, so even without noise the best grid template reached Delta ln L = 0.73 instead of
  6.03. Its faint-image median, 2.79, was mostly noise. The search now scans 48 masses
  between the neighbours of the best grid mass for every y and polishes the best two.
- The first version of the template table used 1500 points in w. At y = 3 and w near 41 it
  sampled each fringe only about four times and its interpolation error reached 3.8 percent.
  6000 points bring it to 0.24 percent; the injection medians moved by less than 0.06.
- Lensed templates keep the true component mass and vary lens mass and impact parameter
  (y only on the grid 0.1 to 3). Unlensed templates vary the component masses (9.6 to 10.4
  solar masses) only. Spins, mass ratio, merger and ringdown, detector response and a
  microlens population around a galaxy are all absent, so these numbers are not
  sensitivities of a real search.
