---
title: "Extend a microlensing limit to a spread of black hole masses"
description: "A standard-library Python script turns one published single-mass limit into a limit on a lognormal spread, with saved inputs, outputs, errors and refusals."
canonical_url: "https://sandboxphysics.com/stories/primordial-black-holes/extend-a-microlensing-limit-to-a-mass-spread/"
language: "en"
page_type: "story"
alternate_languages:
  zh-CN: "https://sandboxphysics.com/zh/stories/primordial-black-holes/extend-a-microlensing-limit-to-a-mass-spread/"
last_modified: "2026-11-12"
---

[Primordial black holes from early collapse to today’s limits](https://sandboxphysics.com/stories/primordial-black-holes/) Tutorial

# Extend a microlensing limit to a spread of black hole masses

Sandbox Physics · 2026-11-12

For a probe that is linear in the mass function, one published curve $f_{\max}(M)$ is enough to test any spread of masses. The script integrates $\psi/f_{\max}$ over $\ln M$ for a lognormal and reports the largest total fraction the Subaru microlensing table allows. At $10^{-8}\,\mathrm{M}_\odot$ a width of $\sigma=0.5$ moves the limit from 0.00949 to 0.00964; at $10^{-6}\,\mathrm{M}_\odot$ it moves from 0.169 to 0.160.

## Before you begin

The weighted-ratio rule from the L3 chapter, Python 3 and a terminal. No packages beyond the standard library.

## Tutorial materials

- [Download the script, tests, input tables, licence and expected outputs](https://sandboxphysics.com/stories/primordial-black-holes/materials/primordial-black-hole-extended-limit-v1.zip) · 9728 B
- [Read the README: units, hashes, error budget and refusals](https://sandboxphysics.com/stories/primordial-black-holes/materials/extended-limit-README.md) · 4594 B
- [Inspect the five saved cases](https://sandboxphysics.com/stories/primordial-black-holes/materials/extended-limit-results.json) · 1668 B

The archive holds Python source, JSON and the two unchanged MIT-licensed tables. It contains no Lab code.

## What the script computes

The input is a table of $\log_{10}f_{\max}$ against $\log_{10}(M/\mathrm{M}_\odot)$. The mass function is a lognormal in $M$ with total fraction $f$, central mass $M_c$ and width $\sigma$ in natural-log mass. The script evaluates the ratio below for $f=1$ and reports $f_{\rm allowed}=1/R$.

Because $R$ is linear in $f$, this one number answers the question for every amplitude. It is Eq. 12 of Carr et al. 2017 written per unit $\ln M$, the convention the Lab also uses.

$$
\psi(M)=\frac{f}{\sqrt{2\pi}\,\sigma}\exp\!\left[-\frac{\ln^2(M/M_c)}{2\sigma^2}\right],\qquad R=\int\mathrm{d}\ln M\,\frac{\psi(M)}{f_{\max}(M)},\qquad f_{\rm allowed}=\frac{f}{R}
$$

One $\sigma$ in $\ln M$ is $\sigma/\ln10$ decades; $\sigma=2$ spans about 0.87 dex.

Reading: Carr, Raidal, Tenkanen, Vaskonen & Veermäe · Primordial black hole constraints for extended mass functions · arXiv:1705.05567v3, Phys. Rev. D 96, 023514 (2017) · Carr, Iovino, Perna, Vaskonen & Veermäe · Primordial black holes: constraints, potential evidence and prospects · arXiv:2601.06024v2 (1 April 2026)

## Inputs, versions and licence

The archive holds two tables copied unchanged from the PBHconstraints repository at commit ef2fb03 (MIT licence, copyright 2026 Ville Vaskonen), with that licence file. SUB.dat is the Subaru HSC microlensing limit from M31 (Smyth et al. 2020). LIGO.dat is the LIGO-Virgo-KAGRA O3 merger limit (Andrés-Carcasona et al. 2024) and is included only so the script can refuse it. Each row is $\log_{10}(M/\mathrm{M}_\odot)$ and $\log_{10}f_{\max}$.

The README lists the SHA-256 of every file. The mapping from table to paper comes from the repository’s notebook; for this tutorial the two papers were read as arXiv abstracts only, so the archive makes no claim about how their curves were derived. The script was written and checked with Python 3.9.6.

Reading: Vaskonen · PBHconstraints digitized limits, commit ef2fb03 (MIT license) · Smyth, Profumo, English, Jeltema et al. · Updated constraints on asteroid-mass primordial black holes as dark matter · arXiv:1910.01285v2, Phys. Rev. D 101, 063005 (2020) · Andrés-Carcasona, Iovino, Vaskonen & Veermäe · Constraints on primordial black holes from LIGO-Virgo-KAGRA O3 events · arXiv:2405.05732v2, Phys. Rev. D 110, 023040 (2024)

## Run it and compare with the saved results

The test file checks normalisation, the narrow limit against a hand interpolation, grid convergence, the saved outputs to a relative $10^{-12}$ and the refusals. The second command writes the five tutorial cases; compare them with expected/results.json.

Saved results for the Subaru table, as largest allowed $f$: centred at $10^{-8}\,\mathrm{M}_\odot$, widths 0.005, 0.5, 1 and 2 give 0.0094879, 0.0096371, 0.0098154 and 0.010949, against a single-mass value of 0.0094880. Centred at $10^{-6}\,\mathrm{M}_\odot$, width 0.5 gives 0.15997 against 0.16890. The narrowest case reproduces the table to $2.2\times10^{-6}$, which checks the integrator.

```
unzip primordial-black-hole-extended-limit-v1.zip
cd primordial-black-hole-extended-limit-v1
python3 test_tutorial.py
python3 extend_constraint.py --cases --output rerun/results.json
python3 extend_constraint.py --table input/SUB.dat --central -8 --width 0.5
```

Reading: Vaskonen · PBHconstraints digitized limits, commit ef2fb03 (MIT license) · Smyth, Profumo, English, Jeltema et al. · Updated constraints on asteroid-mass primordial black holes as dark matter · arXiv:1910.01285v2, Phys. Rev. D 101, 063005 (2020)

## Numerical error and what it does not cover

The integral uses the trapezoid rule on a uniform $\log_{10}M$ grid, 400 points per $\sigma$ over $\pm9\sigma$. Halving or doubling the grid changes $R$ by less than $7\times10^{-8}$ for $\sigma=0.5$ and 2. The cut at $9\sigma$ drops a Gaussian tail of about $2\times10^{-19}$.

These errors are far below the uncertainty of a digitised curve, which the script does not propagate. Between table points it interpolates $\log_{10}f_{\max}$ linearly. Mass outside the table is dropped; the digitised curves stop where $f_{\max}$ reaches one, so dropping it can only lower $R$ and make the result weaker than the full curve would give.

Reading: Vaskonen · PBHconstraints digitized limits, commit ef2fb03 (MIT license)

## Inputs the script refuses

expected/failures.json lists four commands that must fail. LIGO.dat exits with code 3, because a merger rate depends on pairs of black holes and is not linear in $\psi$. A width of zero or NaN exits with 2. A centre of $10^{-3}\,\mathrm{M}_\odot$ exits with 5, because less than half of the distribution lies inside the Subaru table and the table cannot bound it. A table whose masses do not strictly increase exits with 4.

A refusal is a result. Eq. 12 applied to the merger table would still print a number, so the script checks linearity before it integrates.

```
python3 extend_constraint.py --table input/LIGO.dat --central 1 --width 0.5   # exit 3
python3 extend_constraint.py --central -8 --width 0                          # exit 2
python3 extend_constraint.py --central -3 --width 0.5                        # exit 5
```

Reading: Carr, Raidal, Tenkanen, Vaskonen & Veermäe · Primordial black hole constraints for extended mass functions · arXiv:1705.05567v3, Phys. Rev. D 96, 023514 (2017) · Andrés-Carcasona, Iovino, Vaskonen & Veermäe · Constraints on primordial black holes from LIGO-Virgo-KAGRA O3 events · arXiv:2405.05732v2, Phys. Rev. D 110, 023040 (2024)

## Assumptions that change the answer

The probe must be linear in $\psi$. Clustering, mergers and accretion that grows the black holes break this, as Sec. VI of the 2026 review lists. The script handles one table at a time. Combining probes in quadrature needs the extra assumptions in the L3 chapter and is not done here, and comparing $\psi$ with the lowest curve at each mass is wrong in any case.

The lognormal is an input, not a prediction. The Lab’s formation model gives a skewed spread, so its numbers differ slightly from the lognormal ones even at the same mass.

Reading: Carr, Iovino, Perna, Vaskonen & Veermäe · Primordial black holes: constraints, potential evidence and prospects · arXiv:2601.06024v2 (1 April 2026) · Carr, Raidal, Tenkanen, Vaskonen & Veermäe · Primordial black hole constraints for extended mass functions · arXiv:1705.05567v3, Phys. Rev. D 96, 023514 (2017)

## [Compare the Lab’s Subaru ratio with the script](https://sandboxphysics.com/labs/primordial-black-hole-mass-function/)

1. Choose “Ruled out by microlensing”. Read the Subaru ratio and the dark-matter fraction, and divide them. You should get about 112.
2. The script gives $1/0.0094879=105.4$ for a narrow spread at $10^{-8}\,\mathrm{M}_\odot$. Predict the sign of the difference before reading on.
3. The Lab’s mass function peaks near $10^{-8.1}\,\mathrm{M}_\odot$, where the table’s $1/f_{\max}$ is larger, so its ratio per unit fraction is higher.

[Previous: Testing a spread of black hole masses against many observations](https://sandboxphysics.com/stories/primordial-black-holes/test-a-mass-spread-against-many-limits/) [Next: How to read the 2026 primordial black hole review](https://sandboxphysics.com/stories/primordial-black-holes/read-the-2026-primordial-black-hole-review/)

## Sources and how much of each was read

1. [Carr, Iovino, Perna, Vaskonen & Veermäe · Primordial black holes: constraints, potential evidence and prospects · arXiv:2601.06024v2 (1 April 2026)](https://arxiv.org/abs/2601.06024v2)

   Review; arXiv lists the journal reference Riv. Nuovo Cim. (2026). Read in full: Sec. II.A.2 on non-Gaussianity, Sec. IV.C (gravitational waves), IV.E (accretion), V (asteroid-mass window), VI (Eqs. 25–29) and the captions of Figs. 2–6; parts of Sec. II and III.

2. [Carr, Raidal, Tenkanen, Vaskonen & Veermäe · Primordial black hole constraints for extended mass functions · arXiv:1705.05567v3, Phys. Rev. D 96, 023514 (2017)](https://arxiv.org/abs/1705.05567v3)

   Full text. The linear rule for one observable (Eq. 12) and the quadrature combination of several (Eq. 13), with the assumptions under which they hold.

3. [Vaskonen · PBHconstraints digitized limits, commit ef2fb03 (MIT license)](https://github.com/vianvask/PBHconstraints/tree/ef2fb03aa0f6c3fab58e9b23ee64331e88c75a86)

   Five tables used unchanged: EGR, SUB, OGLE, acc and LIGO, with SHA-256 hashes recorded. The table-to-paper mapping follows the repository notebook.

4. [Smyth, Profumo, English, Jeltema et al. · Updated constraints on asteroid-mass primordial black holes as dark matter · arXiv:1910.01285v2, Phys. Rev. D 101, 063005 (2020)](https://arxiv.org/abs/1910.01285v2)

   Abstract only. Larger source stars in M31 weaken the Subaru HSC microlensing limit by up to almost three orders of magnitude in some cases.

5. [Andrés-Carcasona, Iovino, Vaskonen & Veermäe · Constraints on primordial black holes from LIGO-Virgo-KAGRA O3 events · arXiv:2405.05732v2, Phys. Rev. D 110, 023040 (2024)](https://arxiv.org/abs/2405.05732v2)

   Abstract only. A hierarchical analysis of O3 mergers with several mass functions limits PBHs to at most about $10^{-3}$ of the dark matter between 1 and 200 solar masses.

## Keep reading

Black holes from the first second · Reading path

### Black holes from the first second

1. [Article **How to look for black holes that formed before the first stars**](https://sandboxphysics.com/stories/primordial-black-holes/how-to-find-black-holes-older-than-stars/)
2. [Article **When a dense patch of the early universe becomes a black hole**](https://sandboxphysics.com/stories/primordial-black-holes/how-an-early-overdensity-becomes-a-black-hole/)
3. [Article **How a rare Gaussian tail sets the number of primordial black holes**](https://sandboxphysics.com/stories/primordial-black-holes/how-a-rare-gaussian-tail-sets-the-abundance/)
4. [Article **Testing a spread of black hole masses against many observations**](https://sandboxphysics.com/stories/primordial-black-holes/test-a-mass-spread-against-many-limits/)
5. [You are here **Extend a microlensing limit to a spread of black hole masses**](https://sandboxphysics.com/stories/primordial-black-holes/extend-a-microlensing-limit-to-a-mass-spread/)
6. [Article **How to read the 2026 primordial black hole review**](https://sandboxphysics.com/stories/primordial-black-holes/read-the-2026-primordial-black-hole-review/)
