The Binary Population Object

The BinaryPopulation class is the main object for handling the evolution of binary populations in POSYDON. posydon-popsyn and PopulationRunner build upon it to provide a more user-friendly interface for simulating populations.

However, its features are useful if you want to adapt part of the population synthesis, for example, to test a specific population of binaries with custom parameters.

The initialization of the BinaryPopulation object

To create a BinaryPopulation object, you need to provide a set of parameters that define the population’s characteristics. The easiest way is to load in the parameters from the default population ini file.

import os
import shutil
from posydon.config import PATH_TO_POSYDON

path_to_params = os.path.join(PATH_TO_POSYDON, "posydon/popsyn/population_params_default.ini")
shutil.copyfile(path_to_params, './population_params.ini')

Here’s an example of how to initialize a BinaryPopulation object:

from posydon.popsyn.binarypopulation import BinaryPopulation
from posydon.popsyn.io import binarypop_kwargs_from_ini

# Load the parameters from the ini file
ini_kwargs = binarypop_kwargs_from_ini('./population_params.ini')

# Create the BinaryPopulation object
population = BinaryPopulation(**ini_kwargs)

print(population.number_of_binaries)

This code will create a BinaryPopulation object with the parameters defined in the population_params.ini file and print the number of binaries in the population. You can adapt the ini_kwargs dictionary to change the parameters of the population, such as the number of binaries and the metallicity.

You can also skip the read in from the ini file and create the BinaryPopulation object directly. This performs the same task as the previous example, but automatically.

from posydon.popsyn.binarypopulation import BinaryPopulation

population = BinaryPopulation.from_ini('./population_params.ini')

print(population.number_of_binaries)

On initialization, the BinaryPopulation class will initialize the following attributes:

Core Attributes

Attribute

Description

kwargs

Dictionary containing all initialization parameters, starting with defaults and updated with user inputs

number_of_binaries

Total number of binaries in the population

population_properties

SimulationProperties instance containing the evolution steps and configuration

metallicity

Metallicity value for the population [Z/Z_sun]

metallicities

List of metallicity values, defaults to [metallicity] for single metallicity populations

history_verbose

Boolean flag controlling verbosity of evolution history output

entropy

Entropy value used for random number generation seeding

RNG

NumPy random number generator instance for reproducible sampling

manager

PopulationManager instance that handles binary creation, evolution, and data management

to_df

Method reference to manager’s to_df method for converting binaries to DataFrame

to_oneline_df

Method reference to manager’s to_oneline_df method for converting binaries to summary DataFrame

find_failed

Method reference to manager’s find_failed method for identifying failed binary evolutions

During the initialization, the BinaryPopulation creates a PopulationManager and SimulationProperties instance.

Several variables are only set when running with MPI or job arrays, which are used for parallel processing of the population synthesis. These will not be used in a standard run of the BinaryPopulation class, but are set when using the posydon-popsyn or PopulationRunner classes.

Conditional Attributes (MPI/Job Array)

Attribute

Description

comm

MPI communicator object (only when running with MPI)

JOB_ID

Job array ID for parallel processing (only when using job arrays)

rank

Process rank for parallel processing (set when using MPI or job arrays)

size

Total number of processes (set when using MPI or job arrays)

Evolving the population

With the population parameters defined, you can evolve the population using the evolve method. This method will

  1. Sample the initial system parameters (single or binary systems).

  2. Evolve each binary system through its evolutionary steps.

Here’s an example of how to evolve the population:

population.evolve()

Additional kwargs can be passed to the evolve method to control the evolution process, such as:

Additional evolve kwargs

Parameter

Description

Default

indices

Custom binary indices to use instead of range(number_of_binaries). If running with MPI, indices are split between processes

None

breakdown_to_df

Convert binaries to dataframe and remove from memory after evolution to save RAM

True

tqdm

Whether to show a progress bar during evolution

False

from_hdf

Whether to load the population from an HDF5 file instead of evolving it

False

optimize_ram

Enable RAM optimization by processing binaries in batches. Uses dump_rate from the ini file

True

ram_per_cpu

Amount of RAM per CPU for batch size calculation (in GB)

None

temp_directory

Directory path for storing temporary batch files during evolution

“batches”

Depending on the parameters, evolve will create a temporary directory to store the batches of binaries during the evolution process. Within this folder, a batch will write dump_rate binaries to a temporary file: {dump_rate}_evolution.batch. At the end of the evolution, these files will be merged into a single HDF5 file: evolution.combined.

If you’re running with SLURM or MPI, all different processes will write to the same folder, with different batch indicators for each process: {dump_rate}_evolution.batch.{rank}.

Note

The merging of different processes is different from the merging of batches within a single process! We recommend running this with the PopulationRunner class, which will handle the batch writing and merging the output of multiple processes automatically into a single HDF5 file.

When evolving a population, you can read the starting conditions from an HDF5 file or sample the initial conditions from the given population parameters. See POSYDON Population Synthesis Configuration Guide for more details about the population parameters file.

Accessing the evolved population

Depending on the initialization parameters, the evolved population can be accessed in different ways.

  1. If not written to file with breakdown_to_df=False, the population is stored in memory as a list of BinaryStar objects. You can access the individual binaries using the manager attribute:

  1. If breakdown_to_df=True, the population is removed from memory and written to the population file. You can access the population with the normal Population class. Make sure the file name has .h5 extension, as this is required for the Population class to read the file correctly.

BinaryGenerator class

The BinaryGenerator class is a helper class for generating binary systems based on the population parameters. It can be used to create a population of binaries with specific characteristics, such as mass ratios, metallicity, and initial conditions. Please see the BinaryGenerator documentation for more details on how to use this class.