example use-case: Convolving BinCodex Data

The main purpose of this code is to convolve population-synthesis results with star-formation rates. A recently developed new format for population-synthesis output is the BinCodex format (Valli et al. 2023). This section shows how to modify the BinCodex datafiles and convolve that data.

We will open an example BinCodex file(s), extract the data frame, store it in an input hdf5 file fit for convolution, configure the convolution and perform a simple convolution.

[1]:
import os
import json
import copy
import h5py

import numpy as np
import astropy.units as u
import pkg_resources
import pandas as pd

from syntheticstellarpopconvolve import convolve, default_convolution_config, default_convolution_instruction
from syntheticstellarpopconvolve.general_functions import temp_dir, generate_boilerplate_outputfile

TMP_DIR = temp_dir("notebooks", "notebook_convolution_usecase_bincodex", clean_path=True)


# Create output file
output_hdf5_filename = os.path.join(TMP_DIR, 'output_hdf5.h5')
generate_boilerplate_outputfile(output_hdf5_filename)
[2]:
# load as RLOF event-data as pandas df
example_BinCodex_events_filename = pkg_resources.resource_filename(
    "syntheticstellarpopconvolve", 'example_data/example_BinCodex.h5'
)

# Load T0 data
example_BinCodex_T0_events = pd.read_hdf(
    example_BinCodex_events_filename,
    "T0",
)

# Load header info
example_BinCodex_T0_header = pd.read_hdf(
    example_BinCodex_events_filename,
    "header",
)

# Add metallicity as a column
example_BinCodex_T0_events['metallicity'] = float(example_BinCodex_T0_header.iloc[0]['Z'])

# Add normalized_yield as a column manually. This column should be the product of the probability of system a system and a conversion factor to make it per-unit-mass
# NOTE: newer versions of BinCodex may have this column included (or at least based on probability)
example_BinCodex_T0_events['normalized_yield'] = 1

# store the data frame in the hdf5file
example_BinCodex_T0_events.to_hdf(
    output_hdf5_filename, key="input_data/BinCodex_T0"
)
[3]:
print(example_BinCodex_T0_events)
   ID  UID  SID       time  event  semiMajor  eccentricity  type1     mass1  \
0   0    0    2      0.000   -1.0    4.96684           0.0  121.0  0.862931
1   0    0    3    440.859    0.0    2.00180           0.0  121.0  0.862931
2   0    0    7    445.006   52.0    0.00462           0.0  121.0  0.823353
3   0    0    7    445.006   52.0    0.00000           0.0  121.0  0.000000
4   0    0    7   2626.830   52.0    0.00000           0.0  121.0  0.000000
5   0    0    7   2668.960   52.0    0.00000           0.0  121.0  0.000000
6   0    0    7   2774.230   52.0    0.00000           0.0  121.0  0.000000
7   0    0    7   2906.240   52.0    0.00000           0.0  121.0  0.000000
8   0    0    7   2911.490   52.0    0.00000           0.0  121.0  0.000000
9   0    0    7  14000.000   84.0    0.00000           0.0  121.0  0.000000

    radius1    Teff1  massHeCore1  type2     mass2    radius2    Teff2  \
0  0.773353  3.69997          0.0  121.0  0.783703   0.717585  3.66599
1  0.776227  3.70069          0.0  121.0  0.783703   0.719233  3.66659
2  0.753309  3.68261          0.0  121.0  0.787951   0.889135  3.62332
3  0.753309  3.68261          0.0  121.0  1.611300   1.487400  3.87599
4  0.753309  3.68261          0.0  122.0  1.611300   2.924200  3.81782
5  0.753309  3.68261          0.0  123.0  1.611110   3.856370  3.70539
6  0.753309  3.68261          0.0  124.0  1.563530  12.382800  3.66911
7  0.753309  3.68261          0.0  125.0  1.534280  24.455200  3.63692
8  0.748175  3.68410          0.0   21.0  0.584791   0.017989  5.03419
9  0.748175  3.68410          0.0   21.0  0.584791   0.017989  3.47811

   massHeCore2  metallicity  normalized_yield
0     0.000000         0.02                 1
1     0.000000         0.02                 1
2     0.000000         0.02                 1
3     0.000000         0.02                 1
4     0.169898         0.02                 1
5     0.183317         0.02                 1
6     0.472814         0.02                 1
7     0.520958         0.02                 1
8     0.584791         0.02                 1
9     0.584791         0.02                 1
[4]:
#
convolution_config = copy.copy(default_convolution_config)
convolution_config['output_filename'] = output_hdf5_filename
convolution_config['tmp_dir'] = TMP_DIR

###
# convolution instructions
convolution_config['convolution_instructions'] = [
    {
        **default_convolution_instruction,
        'input_data_name': 'BinCodex_T0',
        'output_data_name': 'BinCodex_T0',
        'data_column_dict': {
            # required
            'delay_time': 'time',
            'normalized_yield': 'normalized_yield',
            # # optional*
            # 'metallicity': 'metallicity',
        },
    },
]

#
convolution_config['convolution_lookback_time_bin_edges'] = np.arange(2, 4, 0.5) * u.Gyr

# construct the sfr-dict (NOTE: this uses absolute SFR, not metallicity dependent)
sfr_dict = {}
sfr_dict['lookback_time_bin_edges'] = (np.arange(0, 10, 1) * u.Gyr).to(u.yr)
sfr_dict['starformation_rate_array'] = 0.25 * np.ones(sfr_dict['lookback_time_bin_edges'].shape[0]-1) * u.Msun/u.yr # example of a constant star-formation rate. this could be anything of course.

# store
convolution_config['SFR_info'] = sfr_dict

# convolve
convolve(config=convolution_config)
[check_and_prepare_output_file.py:44 - check_and_prepare_output_file ] 2025-03-10 11:29:56,841: tried to store config in output file, but was already present.
[convolution_by_integration.py:33 - convolution_by_integration_post_convolution_hook_wrapper ] 2025-03-10 11:29:56,958: Handling post-convolution function hook call for convolution by integration
[convolution_by_integration.py:33 - convolution_by_integration_post_convolution_hook_wrapper ] 2025-03-10 11:29:56,969: Handling post-convolution function hook call for convolution by integration
[convolution_by_integration.py:33 - convolution_by_integration_post_convolution_hook_wrapper ] 2025-03-10 11:29:56,975: Handling post-convolution function hook call for convolution by integration
[convolve_populations.py:192 - store_convolution_result_entries ] 2025-03-10 11:29:57,011: Storing yield
[convolve_populations.py:192 - store_convolution_result_entries ] 2025-03-10 11:29:57,020: Storing yield
[convolve_populations.py:192 - store_convolution_result_entries ] 2025-03-10 11:29:57,024: Storing yield
[6]:
# Show some of the content
with h5py.File(convolution_config['output_filename'], 'r') as output_hdf5_file:
    print(output_hdf5_file['output_data/'].keys())
    print(output_hdf5_file['output_data/BinCodex_T0/'].keys())
    print(output_hdf5_file['output_data/BinCodex_T0/BinCodex_T0'].keys())
    print(output_hdf5_file['output_data/BinCodex_T0/BinCodex_T0/convolution_results'].keys())
    print(output_hdf5_file['output_data/BinCodex_T0/BinCodex_T0/convolution_results/2.25 Gyr'].keys())



    print(output_hdf5_file['output_data/BinCodex_T0/BinCodex_T0/convolution_results/2.25 Gyr/yield'][()])
<KeysViewHDF5 ['BinCodex_T0']>
<KeysViewHDF5 ['BinCodex_T0']>
<KeysViewHDF5 ['convolution_results']>
<KeysViewHDF5 ['2.25 Gyr', '2.75 Gyr', '3.25 Gyr']>
<KeysViewHDF5 ['yield']>
[0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25 0.25]
[ ]: