Binary black hole population phenomenology: remnants, recoil kicks, retention, and hierarchical mergers
Project description
gwGenealogy
A Python toolkit for binary black-hole (BBH) phenomenology: sampling BBH populations, computing remnant properties, modeling hierarchical mergers with simple back-of-the-envelope calculations in dense stellar clusters, and analyzing remnant retention across astrophysical environments. For more detailed studies of hierarchical mergers in clusters, we recommend using rapster or other dedicated packages.
This package is a culmination of my works into understanding hierarchical mergers with my amazing collaborators Digvijay Wadekar and Konstantinos Kritos.
Comments/suggestions/criticisms are always welcome!
Package structure
gwGenealogy/
├── utils/ — Distribution samplers, coordinate transforms, conversions, statistics
├── binaries/ — BBH population sampling (masses, spins, redshifts, GWTC models), BBHRemnant
├── stellar/ — Stellar evolution (Fryer12, SEVN), Kroupa IMF, natal kicks
├── hosts/ — Plummer clusters, star cluster sampling, escape velocities, environment retention
├── core/ — Hierarchical mergers, BH seed growth, IMBH formation probability, retention grids
Installation
git clone https://github.com/tousifislam/gwGenealogy.git
cd gwGenealogy
pip install -e .
Dependencies
numpy,scipy,matplotlib,h5pygwModels>= 0.1.6— remnant mass, spin, and kick models (required; 0.1.6 adds the batchedflow.sample/log_probthe kick code relies on)surfinBH— NR surrogate remnant models (optional)
Quick start
Sample a BBH population and compute remnants
import numpy as np
from gwGenealogy.binaries import BBHs, BBHRemnant, sample_masses, sample_spins
m1, m2 = sample_masses(5000, m_min=5, m_max=50, m1_distribution='powerlaw', alpha=-2.35, seed=42)
chi1, chi2 = sample_spins(5000, chi_max=1.0, spin_magnitude='beta', spin_angles='isotropic', seed=43)
# sample_spins returns Cartesian spin vectors; BBHs takes magnitudes + angles
bbh = BBHs(m1=m1, m2=m2,
a1=np.linalg.norm(chi1, axis=1), a2=np.linalg.norm(chi2, axis=1),
theta1=np.arccos(chi1[:, 2] / np.linalg.norm(chi1, axis=1)),
theta2=np.arccos(chi2[:, 2] / np.linalg.norm(chi2, axis=1)),
phi1=np.arctan2(chi1[:, 1], chi1[:, 0]) % (2 * np.pi),
phi2=np.arctan2(chi2[:, 1], chi2[:, 0]) % (2 * np.pi))
rem = BBHRemnant(bbh=bbh, precessing=True)
# rem.Mf, rem.af, rem.vkick
Hierarchical mergers across generations
from gwGenealogy.core import HierarchicalMergersInClusterPopulation
sim = HierarchicalMergersInClusterPopulation(n_samples=50000, chi_max=0.2, m_min=3, m_max=60,
kick_model='gwmodel', seed=42)
data = sim.simulate(verbose=True)
fig, axes = sim.plot_generations(data)
BH seed growth and IMBH formation
from gwGenealogy.core import MonteCarloBHSeedGrowth
mc = MonteCarloBHSeedGrowth(v_esc=300, Z=0.005, chi_max=0.2, m_seed=10.0,
m_targets=[250], kick_model='gwmodel', seed=42)
result = mc.simulate(n_experiments=10000, verbose=True)
Retention probability grids
from gwGenealogy.core import BBHRetentionProbabilityOverChiq
import numpy as np
grid = BBHRetentionProbabilityOverChiq(
q_values=np.linspace(1, 10, 50),
chi_max_values=np.linspace(0.01, 1, 50),
v_esc_values=[50, 100, 200, 500],
kick_models=['hlz', 'gwmodel'], seed=42)
grid.compute(verbose=True)
fig, axes = grid.plot_heatmap_all_vesc()
GWTC population sampling
The GWTC population files are large (hundreds of MB) and are not bundled with
the package; fetch them once from Google Drive (requires pip install gdown):
from gwGenealogy.binaries import download_gwtc_data, sample_gwtc_population, available_catalogs
download_gwtc_data() # one-time: into ~/.gwGenealogy/data (or $GWGENEALOGY_DATA)
available_catalogs()
pop = sample_gwtc_population(50000, catalog='gwtc5', source='posterior', seed=42)
# pop['mass_1'], pop['a1'], pop['chi_eff'], pop['redshift'], ...
Environment retention
from gwGenealogy.hosts import compute_multi_environment_retention, ENVIRONMENTS
ret = compute_multi_environment_retention(v_kick_array)
# ret['GC'], ret['NSC'], ret['EG'], ret['DG'], ret['MW'], ret['M31']
Tutorials
| # | Notebook | Description |
|---|---|---|
| 01 | Distributions | Core distribution samplers and JSD |
| 02 | Stellar evolution | Kroupa IMF, Fryer12/SEVN remnants, natal kicks |
| 03 | BBH nonprecessing | BBHs + BBHRemnant with nonprecessing models |
| 04 | BBH precessing | BBHs + BBHRemnant with precessing and surrogate models |
| 05 | GWTC populations | GWTC-3/4/5 population sampling, posterior vs prior |
| 06 | Retention probability | 1G+1G retention heatmaps across kick models |
| 07 | Host environments | Plummer clusters, escape velocities, environment retention |
| 08 | Hierarchical mergers | Multi-generation mergers, pairing models, evolving v_esc |
| 09 | Seed growth | BH seed growth chains, v_esc sweeps, evolving v_esc |
| 10 | Displacement & return times | Apocentre displacement, dynamical friction return times, GC vs NSC |
| 11 | Single-cluster mergers | Hierarchical mergers in one cluster: mass/Z/pairing sweeps, evolving v_esc |
| 12 | Runaway SMBH progenitor | Inferring the progenitor of recoiling SMBH RBH-1 from its kick (flow log_prob inversion) |
Citations
If you use this package, please cite the relevant papers:
@article{Islam:2025drw,
author = "Islam, Tousif and Wadekar, Digvijay",
title = "{Accurate models for recoil velocity distribution in black hole
mergers with comparable to extreme mass-ratios and their
astrophysical implications}",
eprint = "2511.11536",
archivePrefix = "arXiv",
primaryClass = "gr-qc",
doi = "10.1103/4jvv-qg4h",
journal = "Phys. Rev. D",
volume = "113",
number = "10",
pages = "104017",
year = "2026"
}
@article{Islam:2026yxx,
author = "Islam, Tousif and Wadekar, Digvijay and Kritos, Konstantinos",
title = "{Kick matters: The impact of a new recoil model on the retention
of hierarchical black-hole remnants in globular clusters}",
eprint = "2603.10170",
archivePrefix = "arXiv",
primaryClass = "astro-ph.HE",
month = "3",
year = "2026"
}
@article{Islam:2026iyn,
author = "Islam, Tousif",
title = "{Inference of recoil kicks from binary black hole mergers up to
GWTC--4 and their astrophysical implications}",
eprint = "2604.04546",
archivePrefix = "arXiv",
primaryClass = "astro-ph.HE",
month = "4",
year = "2026"
}
@article{Islam:2026sjl,
author = "Islam, Tousif and Venumadhav, Tejaswi and Wadekar, Digvijay",
title = "{Progenitor of the recoiling super-massive black hole RBH-1
identified using HST/JWST imaging}",
eprint = "2601.18986",
archivePrefix = "arXiv",
primaryClass = "astro-ph.HE",
month = "1",
year = "2026"
}
Contact
For questions or issues, please reach out to tousifislam24@gmail.com.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gwgenealogy-0.1.0.tar.gz.
File metadata
- Download URL: gwgenealogy-0.1.0.tar.gz
- Upload date:
- Size: 916.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e660c7c38630e922d04e34f2687d1f04c6fdb1be5a86d9bb4cbc5fb2b55f0a18
|
|
| MD5 |
4494f512e5fd13e81796acc6b9f43577
|
|
| BLAKE2b-256 |
975b4e546cbe3323fafd24fae261e7e6f07d94fab5588c4dc098f03c19fc25f0
|
File details
Details for the file gwgenealogy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gwgenealogy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 925.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9896c663a47202cdda280214ff5084c05187ac2e1f91ea0bd99a27d2011c2a95
|
|
| MD5 |
25bc8748a04ec3ad3535931562827f08
|
|
| BLAKE2b-256 |
821187fa3e2aa38b345cb5c76b1eeb82ad3129d43822a0d2be58ea6d920911c2
|