Simulation¶
Each simulation is encapsulated as an object that is responsible for finding the location of each dataset in the simulation, loading it — which may involve downloading and caching the relevant file — and returning an object that can be used to access that piece of data.
Location¶
We begin by simply loading the simulation. There are one required and two optional pieces of information needed to identify a simulation:
SXS ID
This identifies the simulation type and includes a number. For example, "SXS:BBH:0001", which identifies this simulation as a product of the SXS collaboration, specifies that it is a binary black hole simulation, and that it has been assigned the number "0001" in that series. Note that these numbers are not necessarily sequential. Nor do they necessarily correspond to the relative age of the simulation; that information is contained in the metadata itself in the various
date_*keys.Version
This identifies the version of the data — like "v3.0". Unlike the SXS ID, this is an optional specifier. If not provided, the most recent version is used. All versions refer to the same underlying simulation, but the raw data may have been processed differently, may be provided in incompatible formats, etc. For exploratory work, it is often convenient to simply use the most recent version. However, for reproducibility, it is important to specify the version of the data you use for a given analysis.
Lev (resolution)
This identifies the resolution of the simulation — like "Lev5". This is also optional. If not provided, the highest resolution is used. Note that there is no consistency in the "Lev"s provided for different simulations, nor is there necessarily even consistency in the meaning of the "Lev" between different simulations (they are not always directly comparable). Again, for reproducibility, it is important to specify the resolution of the data you use for a given analysis.
These three pieces of information may be combined into a single string as in any of the following examples of valid inputs:
SXS:BBH:0001
SXS:BBH:0001v2.0
SXS:BBH:0001/Lev5
SXS:BBH:0001v2.0/Lev5
The full specification including ID, version, and Lev is called the "location", but any of these can be provided to load the simulation:
sxs.load("SXS:BBH:0001")
sxs.load("SXS:BBH:0001v2.0")
sxs.load("SXS:BBH:0001/Lev5")
sxs.load("SXS:BBH:0001v2.0/Lev5")
Deprecated or superseded¶
Many simulations are now quite old, and do not have the benefit of years of refinements to the simulation code. As a result, the SXS collaboration has deprecated many of them, and replaced them with newer simulations of (nearly) the same physical parameters.
By default, a deprecated simulation raise an error if you attempt to load it. However, you can still load it if you want to, by choosing one of the following options:
- Pass
ignore_deprecation=Trueto load the latest available version. This completely bypasses even checking for deprecation or supersession. No warnings or errors will be issued. - Manually choose a different simulation from the catalog.
- Pass
auto_supersede=0.01to load a match "closer" than 0.01 in the catalog if one exists; and error otherwise. Here, "closeness" is measured in terms of a simplistic metric on the metadata — specifically the basic information like masses, spins, and eccentricity measured at the reference time. This is imperfect, because it ignores the evolution of these quantities, which may differ for different simulations even when they represent the same physical system. - Pass
auto_supersede=Trueto load the "closest" match in the catalog, even if it is quite "far" away. - Include the version number, as in 'SXS:BBH:0001v2.0', to load a specific version. A warning will be issued that the simulation is deprecated, but it will be loaded anyway.
In this case, "SXS:BBH:0001" is deprecated, and has been superseded by the newer simulation "SXS:BBH:1132". We can automatically load the superseding simulation with
import sxs
sim = sxs.load("SXS:BBH:0001", auto_supersede=True)
Loading SXS simulations using latest tag 'v3.0.0a10', published at 2025-04-23T15:08:30Z.
/Users/boyle/.continuum/current/envs/science/lib/python3.12/site-packages/sxs/simulations/simulation.py:236: UserWarning: Simulation 'SXS:BBH:0001v2.0' is being automatically superseded by 'SXS:BBH:1132'. The distance between them in the given metadata metric is 3.33e-07. warn(message)
Note that, because we did not load a tagged version of the simulations
catalog [with, e.g., sxs.load("dataframe", tag="3.0.0")] before
loading the waveform, sxs just found the most recent tag and loaded
that version of the catalog, then used the information there to find
which simulation to automatically supersede with.
We can see that, even though we requested "SXS:BBH:0001", the location of the output simulation object is "SXS:BBH:1132". A warning is printed, even though we asked for the superseding simulation, so that it is clear which simulation we are actually using, though we can also access this programmatically:
sim.location
'SXS:BBH:1132v3.0/Lev4'
Note that the version "v3.0" and "Lev4" were automatically chosen as the highest values, respectively.
Metadata¶
Having loaded the simulation, the only thing loaded so far is the
metadata about the simulation. This is encapsulated in the metadata
attribute of the simulation object. This is a dictionary-like object
that contains all of the metadata about the simulation, including the
SXS ID, version, and Lev, as well as the masses and spins of the black
holes, the reference time, and other important information, such as
where to find the various types of data for this simulation. These
fields are described in detail in the most recent SXS catalog
paper, and are used in
constructing the catalog dataframe described on the previous
page.
We can see its contents here:
sim.metadata
Metadata([('simulation_name', 'BBH_SKS_d23.1_q1_sA_0_0_0_sB_0_0_0/Lev4'),
('keywords', []),
('alternative_names', ['PRIVATE:BBH:0143', 'SXS:BBH:1132']),
('metadata_format_revision', 2),
('metadata_content_revision', 1),
('internal_minor_version', 0),
('internal_changelog', {}),
('citation_dois', ['10.1088/1361-6382/ab34e2']),
('initial_separation', 23.12716512),
('initial_orbital_frequency', 0.00851783),
('initial_adot', -4.675904e-06),
('initial_ADM_energy', 0.994987997679003),
('initial_ADM_linear_momentum',
[-2.156564e-10, 3.97011e-10, 4.51632e-11]),
('initial_ADM_angular_momentum',
[3.54751846e-08, 1.445901368e-07, 1.3091640743018833]),
('initial_dimensionless_spin1',
[1.2758e-12, -3.8937e-12, -6.57154e-10]),
('initial_dimensionless_spin2',
[-3.554e-13, 9.477e-13, -3.283941e-10]),
('initial_data_type', 'BBH_SKS'),
('initial_mass1', 0.4999999855169243),
('initial_mass2', 0.4999999855057323),
('object1', 'bh'),
('object2', 'bh'),
('initial_position1', [11.563582584517457, 3.69708105e-08, 0.0]),
('initial_position2', [-11.563582535482544, 3.69708105e-08, 0.0]),
('t_relaxed_algorithm',
{'algorithm': 'RMS', 'reason': 'SmallTJunk'}),
('relaxation_time', 170.0),
('reference_time', 170.0),
('reference_dimensionless_spin1',
[1.1730355045230556e-10,
-3.3723474601082626e-10,
-1.1349397619762191e-07]),
('reference_mass1', 0.5000000336269459),
('reference_dimensionless_spin2',
[-7.340680125141453e-11,
2.2316822624244634e-10,
-1.1371062991019911e-07]),
('reference_mass2', 0.5000000335880593),
('reference_position1',
[1.447091488492068, 11.650624665246074, 2.621942143450669e-09]),
('reference_position2',
[-1.447091547338091, -11.650624523323035, 2.4672241341874733e-09]),
('reference_orbital_frequency',
[-7.129406006201152e-15,
-5.581743807566877e-14,
0.00853972880002455]),
('common_horizon_time', 25474.41047033414),
('number_of_orbits_from_start', 53.41547707495209),
('number_of_orbits_from_reference_time', 53.18536243923161),
('reference_eccentricity', 2.7e-05),
('reference_mean_anomaly', 1.010533),
('remnant_mass', 0.951608906492193),
('remnant_dimensionless_spin',
[-3.1265099981564997e-12,
-2.4461331610839638e-11,
0.6864342921339575]),
('remnant_velocity',
[-3.4023240606177755e-09,
-8.28900285473014e-10,
1.427625994038291e-08]),
('spec_revisions', ['InitialCommit-26573-g5935362']),
('spells_revision', '593536299f649bb020ee4fa66645853abf050cb3'),
('date_run_earliest', '2014-07-23T17:10:24'),
('date_run_latest', '2014-10-08T11:34:36'),
('date_link_earliest', '2014-07-21T17:37:37-07:00'),
('date_postprocessing', '2025-01-27T19:42:35.265745-08:00'),
('pbj_info',
{'base_lev': 'Lev4',
'transition_time': 0.0,
'base_lev_bitwise_identical': 'true'}),
('job_archiver_email', 'glovelace@fullerton.edu'),
('postprocess_revision', 1),
('number_of_orbits', 53.41547707495209),
('object_types', 'BHBH'),
('initial_mass_ratio', 1.000000000022384),
('reference_mass_ratio', 1.0000000000777731),
('reference_chi_eff', -1.1360230305390596e-07),
('reference_chi1_perp', 3.570537737425681e-10),
('reference_chi2_perp', 2.3493108639847596e-10),
('lev_numbers', [-1, 0, 1, 2, 3, 4]),
('directory',
'Public/No_BFI/Misc/BBH_SKS_d23.1_q1_sA_0_0_0_sB_0_0_0'),
('mtime', '2025-02-18T22:39:53.721928+00:00'),
('files',
{'Lev4:Strain_N2.json': {'checksum': 'md5:1020f262b0af290df6cf2df4752dac68',
'size': 2227,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev4%3AStrain_N2.json/content'},
'Lev3:Strain_N2.h5': {'checksum': 'md5:63daf18dcda060a4530b80db36890388',
'size': 3084901,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev3%3AStrain_N2.h5/content'},
'Lev3:Strain_N2.json': {'checksum': 'md5:a6f965e84dcf1a3d3fb558382a85740c',
'size': 2231,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev3%3AStrain_N2.json/content'},
'Lev4:ExtraWaveforms.h5': {'checksum': 'md5:b953095ed7f79cc98e09cc343b9c89a8',
'size': 27377504,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev4%3AExtraWaveforms.h5/content'},
'Lev4:ExtraWaveforms.json': {'checksum': 'md5:5214a5fe40a893b9444d22b4daa288d7',
'size': 17428,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev4%3AExtraWaveforms.json/content'},
'Lev4:Horizons.h5': {'checksum': 'md5:087ec029d2275a6e6ce43b6681a8ad3c',
'size': 8030172,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev4%3AHorizons.h5/content'},
'Lev4:metadata.json': {'checksum': 'md5:cca29db318f2e49c67e98bc9fbd158c3',
'size': 3346,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev4%3Ametadata.json/content'},
'Lev1:Strain_N2.json': {'checksum': 'md5:e2a19ccab79a74f1443a898efd60cd52',
'size': 2230,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev1%3AStrain_N2.json/content'},
'Lev-1:ExtraWaveforms.h5': {'checksum': 'md5:83bf398ede3960e2a3eac6ebe82b9139',
'size': 34081902,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev-1%3AExtraWaveforms.h5/content'},
'Lev-1:ExtraWaveforms.json': {'checksum': 'md5:a24f5d915a093a60675c7f93ea1ea6fe',
'size': 17449,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev-1%3AExtraWaveforms.json/content'},
'Lev2:ExtraWaveforms.h5': {'checksum': 'md5:3dff3e3ec96c3dd4f5847c1f1e38937f',
'size': 28433541,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev2%3AExtraWaveforms.h5/content'},
'Lev-1:Horizons.h5': {'checksum': 'md5:174db3cf67d9a6e56bf7ed31adf6c4cc',
'size': 8084479,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev-1%3AHorizons.h5/content'},
'Lev-1:metadata.json': {'checksum': 'md5:de69e0fe435d1f3186e18f15a4225a58',
'size': 3363,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev-1%3Ametadata.json/content'},
'Lev2:ExtraWaveforms.json': {'checksum': 'md5:347b7451eb725abdac327e6a90aa9205',
'size': 17456,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev2%3AExtraWaveforms.json/content'},
'Lev-1:Strain_N2.h5': {'checksum': 'md5:33d8529c2b86e0bc56943a311bd3be4e',
'size': 3403539,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev-1%3AStrain_N2.h5/content'},
'Lev-1:Strain_N2.json': {'checksum': 'md5:35f70f052993549f51d7a02f96d830a7',
'size': 2230,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev-1%3AStrain_N2.json/content'},
'Lev2:Horizons.h5': {'checksum': 'md5:db3e51078fdcf2b742507ea022c0ee39',
'size': 8006313,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev2%3AHorizons.h5/content'},
'Lev0:ExtraWaveforms.h5': {'checksum': 'md5:ffcac5fd5f2d96eac3fc813248ef7d5b',
'size': 30858934,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev0%3AExtraWaveforms.h5/content'},
'Lev0:ExtraWaveforms.json': {'checksum': 'md5:ba172233a0e640fd63a3de76dd745b17',
'size': 17449,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev0%3AExtraWaveforms.json/content'},
'Lev0:Horizons.h5': {'checksum': 'md5:0b97f2842eda185695e7f4f7b30db770',
'size': 7770322,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev0%3AHorizons.h5/content'},
'Lev0:metadata.json': {'checksum': 'md5:0dcab3a0b554ede2b68ad5925c6791a9',
'size': 3353,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev0%3Ametadata.json/content'},
'Lev0:Strain_N2.h5': {'checksum': 'md5:0fbe2605e7b2df2c1762ce670da2f407',
'size': 2992484,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev0%3AStrain_N2.h5/content'},
'Lev0:Strain_N2.json': {'checksum': 'md5:6ca3802c600ff01c69fa7b036fa74f75',
'size': 2230,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev0%3AStrain_N2.json/content'},
'Lev2:metadata.json': {'checksum': 'md5:792c47f41857482167f8abe94e38d05d',
'size': 3339,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev2%3Ametadata.json/content'},
'Lev1:ExtraWaveforms.h5': {'checksum': 'md5:0a08107de3556898aa15827dc3e24479',
'size': 28171157,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev1%3AExtraWaveforms.h5/content'},
'Lev1:ExtraWaveforms.json': {'checksum': 'md5:a93a3e31ed697be008df1c728d54d704',
'size': 17449,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev1%3AExtraWaveforms.json/content'},
'Lev2:Strain_N2.h5': {'checksum': 'md5:15b545c82452fae57012202528152640',
'size': 2692410,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev2%3AStrain_N2.h5/content'},
'Lev4:Strain_N2.h5': {'checksum': 'md5:5e40c8e74ef0ea6df0cccdbc30a404b1',
'size': 2650416,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev4%3AStrain_N2.h5/content'},
'Lev1:Horizons.h5': {'checksum': 'md5:9e7d5e58cc782fe826b65551a8ed4924',
'size': 7921259,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev1%3AHorizons.h5/content'},
'Lev3:Horizons.h5': {'checksum': 'md5:ff0730fc423375e75c2f5290a6dbdc3f',
'size': 7941997,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev3%3AHorizons.h5/content'},
'Lev1:metadata.json': {'checksum': 'md5:12dc2b562c1ffd37a9db6b2df16078a4',
'size': 3355,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev1%3Ametadata.json/content'},
'Lev2:Strain_N2.json': {'checksum': 'md5:94162f9b584cc478a59602d64b7f658c',
'size': 2231,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev2%3AStrain_N2.json/content'},
'Lev1:Strain_N2.h5': {'checksum': 'md5:fb0d6dc8189538edee3609d1bb70abd3',
'size': 2736289,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev1%3AStrain_N2.h5/content'},
'Lev3:ExtraWaveforms.h5': {'checksum': 'md5:0afbc2ceb9a196e517eace83831c9924',
'size': 30418704,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev3%3AExtraWaveforms.h5/content'},
'Lev3:metadata.json': {'checksum': 'md5:6713a5d71ffcd2e6796ebc33ef6c19e5',
'size': 3354,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev3%3Ametadata.json/content'},
'Lev3:ExtraWaveforms.json': {'checksum': 'md5:eb38fcf50f53e613ba09074580816298',
'size': 17456,
'link': 'https://data.caltech.edu/api/records/m963g-9ma21/files/Lev3%3AExtraWaveforms.json/content'}}),
('DOI_versions',
['', 'v1.2', 'v1.3', 'v1.4', 'v1.5', 'v2.0', 'v3.0'])])
However, one important point to note about the metadata is that it is
not always in a format we might expect. For example, the
reference_eccentricity field will often be a string like
"<7.2e-05", which makes it awkward to compute with. These sorts of
issues are avoided with the dataframe interface described on the
previous page by forcing fields to have consistent types.
We can extract the metadata for this one simulation in a format consistent with other simulations as a pandas.Series object with the attribute sim.series. (Here, we'll use pandas explicitly to display the series with a little more detail.)
import pandas as pd
with pd.option_context("max_colwidth", 46, "display.min_rows", 30):
display(sim.series)
deprecated False
reference_mass_ratio 1.0
reference_chi_eff -0.0
reference_chi1_perp 0.0
reference_chi2_perp 0.0
reference_eccentricity 0.000027
reference_eccentricity_bound 0.000027
reference_time 170.0
reference_dimensionless_spin1_x 0.0
reference_dimensionless_spin1_y -0.0
reference_dimensionless_spin1_z -0.0
reference_dimensionless_spin1_mag 0.0
reference_dimensionless_spin1 [1.1730355045230556e-10, -3.37234746010826...
reference_dimensionless_spin2_x -0.0
reference_dimensionless_spin2_y 0.0
...
initial_dimensionless_spin2_y 0.0
initial_dimensionless_spin2_z -0.0
initial_dimensionless_spin2_mag 0.0
initial_dimensionless_spin2 [-3.554e-13, 9.477e-13, -3.283941e-10]
initial_position1 [11.563582584517457, 3.69708105e-08, 0.0]
initial_position2 [-11.563582535482544, 3.69708105e-08, 0.0]
number_of_orbits 53.415477
number_of_orbits_from_start 53.415477
number_of_orbits_from_reference_time 53.185362
DOI_versions [, v1.2, v1.3, v1.4, v1.5, v2.0, v3.0]
keywords []
date_link_earliest 2014-07-22 00:37:37
date_run_earliest 2014-07-23 17:10:24
date_run_latest 2014-10-08 11:34:36
date_postprocessing 2025-01-28 03:42:35.265745
Name: SXS:BBH:1132, Length: 87, dtype: object
Various relevant pieces of information about the simulation are also available as attributes of the simulation object. For example, we may wish to know which versions are available:
sim.versions
['', 'v1.2', 'v1.3', 'v1.4', 'v1.5', 'v2.0', 'v3.0']
In this case, the generic version, '', as well as multiple older
versions from the first ('v1.x'), second ('v2.0'), and latest ('v3.0')
versions of the catalog are available, because SXS:BBH:1132 is a
fairly old simulation.
These versions track modifications to the files representing the data and — together with the SXS ID — establish the unique identifier for the data set. This unique identifier is also published as a DOI. The DOI prefix for SXS data is 10.26138, and the full DOI for any simulation is given by combining these:
sim.url
'https://doi.org/10.26138/SXS:BBH:1132v3.0'
These DOIs are permanent and can be used to refer to the data in publications, in the same way that DOIs for journal articles are used. They point to deposits of the data in the Zenodo or CaltechDATA repository, which are long-term, open-access archives. This is also where the data are automatically obtained when you load a particular data set for the first time.
Data¶
Besides the metadata, the remaining data sets are loaded lazily. This means that we can access the data as needed, but the cost in time and resources is not paid unless and until the data is actually accessed. Specifically, the time to download the data if needed, the disk space required to cache it if desired, the time to load the data from disk, and the memory required to store it are all deferred to the point of use.
For example, we can access data describing the horizons as
sim.horizons
<sxs.horizons.Horizons at 0x145a2f110>
And data describing the waveform as
sim.h
WaveformModes([[-3.84045085e-02-5.89198155e-03j, -5.77778752e-08+5.89152049e-07j,
-2.04127826e-03-7.59793532e-09j, ...,
-1.69433081e-05+1.02668263e-04j, -5.52232115e-09+3.01949886e-08j,
-1.36598721e-07-1.89939464e-04j],
[-4.08725041e-02-6.17793871e-03j, -1.12721753e-07+1.22522360e-06j,
-2.61140490e-03+2.24617634e-08j, ...,
1.58363235e-04-1.07098592e-04j, 1.88905886e-08+8.79536268e-09j,
-2.16597212e-04+1.81872383e-04j],
[-4.41104676e-02-6.91220296e-03j, 6.66523849e-08+4.93630433e-07j,
-2.35699925e-03+3.70045888e-08j, ...,
1.61960978e-04-2.16341762e-04j, -2.32333702e-08-9.77603142e-08j,
-1.86282822e-04+3.95645415e-04j],
...,
[-1.34434621e-04-2.50412266e-04j, 2.01020405e-10-1.69444925e-10j,
8.78545565e-02+3.45608094e-11j, ...,
1.69202525e-07+2.06979377e-08j, -6.86001843e-11+5.93489900e-11j,
8.13201650e-07-8.93233959e-08j],
[-1.34415470e-04-2.50381871e-04j, 2.00183632e-10-1.69581744e-10j,
8.78545432e-02+3.45608094e-11j, ...,
1.68807536e-07+2.04880956e-08j, -6.74600154e-11+5.88283689e-11j,
8.20193040e-07-8.53407431e-08j],
[-1.34398286e-04-2.50352600e-04j, 2.00935881e-10-1.70606621e-10j,
8.78545297e-02+3.45608094e-11j, ...,
1.68399374e-07+2.02860162e-08j, -6.75278754e-11+5.87496367e-11j,
8.27516487e-07-8.17295573e-08j]], time=array([1.42956063e+00, 3.26477767e+00, 5.08975190e+00, ...,
2.58566851e+04, 2.58567851e+04, 2.58568851e+04]), time_axis=0)
The objects returned will be the subject of the next two notebooks in this series: