Tutorials
Working with
CHIME/FRB data.
Every catalog on this site can be queried through a public API or downloaded as files. These Python examples cover both, along with the raw data behind the catalogs.

Public API
Query the API
Read-only JSON over HTTPS for every published catalog. No key or sign-up needed.
Open /api/v1 (opens in a new tab)| Endpoint | Returns |
|---|---|
/api/v1 | Every endpoint and its parameters. |
/api/v1/catalogs | Every catalog, with its DOI, papers, versions and row counts. |
/api/v1/catalogs/{catalog} | One version of a catalog: its columns with units and descriptions, its files and its row counts. |
/api/v1/catalogs/{catalog}/bursts | The rows, one per burst or sub-burst (per source in the Repeaters Catalog), a page at a time: follow links.next until it is null. |
/api/v1/catalogs/{catalog}/bursts/{name} | Every row of one burst, its plots and its neighbours. The name matches in any case or spacing. |
01List the catalogs
Each catalog comes with its DOI, papers, versions and row counts. Its id (catalog2, basecat1, repeaters, catalog1) goes in the other endpoints.
import requests
API = "https://chime-frb.ca/api/v1"
catalogs = requests.get(f"{API}/catalogs").json()["catalogs"]
for catalog in catalogs:
print(catalog["id"], catalog["latest_version"])02Filter and sort bursts
The ten bursts with the highest dispersion measure, with only the columns needed. Every column key is in the catalog’s glossary.
import requests
API = "https://chime-frb.ca/api/v1"
response = requests.get(
f"{API}/catalogs/catalog2/bursts",
params={
"fields": "ra,dec,dm_fitb",
"sort": "dm_fitb",
"order": "desc",
"per_page": 10,
},
)
response.raise_for_status()
for row in response.json()["rows"]:
print(row["tns_name"], row["dm_fitb"])| Parameter | Meaning |
|---|---|
q | Search burst names, event IDs, repeater names and previous names. |
view | all (default), repeat or one-off. |
sort | A column key to sort by. Missing values sort last. |
order | asc (default) or desc. |
page | Page number, from 1 (the default). |
per_page | Rows per page, up to 1,000 (default 100). |
fields | Column keys to return, separated by commas. Keys that name the row, such as tns_name and sub_num, always come too. |
version | A catalog version, e.g. 20251231. Without it, the latest; each catalog lists its versions. |
03Fetch a whole catalog
Rows come a page at a time: follow links.next until it is null. Naming a version, here 20251231, keeps an analysis reproducible, since older versions stay available when a new one is published.
import pandas as pd
import requests
API = "https://chime-frb.ca/api/v1"
# Pin the version so results stay the same when a new one is published.
url = f"{API}/catalogs/catalog2/bursts?version=20251231&per_page=1000"
rows = []
while url:
page = requests.get(url).json()
rows += page["rows"]
url = page["links"]["next"]
bursts = pd.DataFrame(rows)
print(len(bursts), "rows") # one per burst or sub-burst04Look up one burst
Every row of FRB20180725A (one per sub-burst), its plots, and links to the bursts before and after it. Names match whatever their case or spacing, so frb 20180725a works too.
import requests
API = "https://chime-frb.ca/api/v1"
burst = requests.get(f"{API}/catalogs/catalog2/bursts/FRB20180725A").json()
print(burst["rows"][0]["dm_fitb"]) # one row per sub-burst
# Save its plots
for plot in burst["plots"]:
with open(f"FRB20180725A_{plot['key']}.png", "wb") as file:
file.write(requests.get(plot["url"]).content)Values are exactly as published. Missing values are null, or empty strings in text fields such as notes; Baseband Catalog 1 marks missing measurements -9999.
Errors come back as JSON with a status and a message: 400 for a parameter the API doesn’t understand, 404 for an unknown catalog, version, burst or endpoint, and 503 if the database is briefly unavailable. Try again shortly.
Downloads
Read the catalog files
Each catalog page offers its files under Downloads. Catalog 2 comes as CSV, JSON, FITS and NumPy; the other catalogs work the same way, with their own file names.
01Find the files
The API lists each version’s files, so scripts can fetch them.
import requests
API = "https://chime-frb.ca/api/v1"
catalog = requests.get(f"{API}/catalogs/catalog2").json()
for file in catalog["downloads"]:
print(file["format"], file["url"])02Read them in Python
Each tab reads the same Catalog 2 table into Python. Missing measurements are NaN in the files.
import pandas as pd
bursts = pd.read_csv("chimefrbcat2.csv")
print(bursts[["tns_name", "ra", "dec", "dm_fitb"]].head())
# Bursts from repeating sources have a repeater name
repeats = bursts[bursts["repeater_name"].notna()]
print(repeats["repeater_name"].nunique(), "repeating sources")Raw data
Work with raw data
Each catalog’s raw data, such as waterfalls, localizations and baseband data, is archived permanently at the Canadian Astronomy Data Centre (CADC), where the catalog’s DOI points. Browse an archive, download the files you need, then open them as below.
01HDF5 files
Waterfalls, localizations and baseband data usually come as HDF5 files, ending in .h5. visit lists what a file holds; then read the datasets you need. This waterfall file keeps its dynamic spectrum in frb/wfall and its plot limits in frb/extent, as in the CHIME/FRB Open Data waterfall tutorial (opens in a new tab).
import h5py
import matplotlib.pyplot as plt
with h5py.File("FRB20180725A_waterfall.h5", "r") as file:
file.visit(print) # every group and dataset in the file
wfall = file["frb/wfall"][:] # intensity, frequency × time
extent = file["frb/extent"][:] # the plot's time and frequency limits
plt.imshow(wfall, aspect="auto", interpolation="none", extent=extent)
plt.xlabel("Time [ms]")
plt.ylabel("Frequency [MHz]")
plt.show()02Pickle files
Some localization files are pickled Python dictionaries, with the confidence map in Z and its limits in extent. This example comes from the previous public site.
import pickle
# Unpickle only files you trust: loading a pickle can run code.
with open("localization_contour.pkl", "rb") as file:
localization = pickle.load(file)
print(list(localization.keys()))
# ['event_id', 'Z', 'extent', 'results']
print(localization["Z"]) # 2D array of confidence valuesOther formats, such as msgpack intensity data and filterbank files, are described in the CHIME/FRB Open Data documentation (opens in a new tab), alongside tutorials for exposure maps, the beam model, injections and VOEvents, and the cfod Python package (opens in a new tab).
Tutorials and documentation
Step-by-step guides from CHIME/FRB Open Data: reading the catalogs, plotting waterfalls and localizations, exposure maps, the beam model and VOEvents.
chime-frb-open-data.github.io (opens in a new tab)Ask the community
Questions, bug reports and feature requests go to the CHIME/FRB Open Data community on GitHub, where others can find the answers too.
GitHub Issues (opens in a new tab)