Source code for posydon.popsyn.sample_from_file

"""Get the initial parameters for a binary population."""


__authors__ = [
    "Matthias Kruckow <Matthias.Kruckow@unige.ch>",
]


import os
import numpy as np
import pandas as pd
from posydon.popsyn.independent_sample import (generate_orbital_periods,
                                               generate_orbital_separations,
                                               generate_eccentricities,
                                               generate_primary_masses,
                                               generate_secondary_masses)
from posydon.utils.posydonwarning import Pwarn

PRIMARY_MASS_NAMES = ['s1_mass', 'primary_mass', 'mass_1', 'm_1', 'm1']
SECONDARY_MASS_NAMES = ['s2_mass', 'secondary_mass', 'mass_2', 'm_2', 'm2']
PERIOD_NAMES = ['orbital_period', 'period', 'p_orb', 'porb', 'p']
SEPARATION_NAMES = ['orbital_separation', 'separation', 'semi-major_axis',\
                    'semi_major_axis', 'a']
ECCENTRICITY_NAMES = ['eccentricity', 'ecc', 'e']
PRIMARY_KICK_VELOCITY_NAMES = ['s1_natal_kick_array_0', 'w_1', 'w1']
SECONDARY_KICK_VELOCITY_NAMES = ['s2_natal_kick_array_0', 'w_2', 'w2']
PRIMARY_KICK_AZIMUTHAL_ANGLE_NAMES = ['s1_natal_kick_array_1', 'phi_1', 'phi1']
SECONDARY_KICK_AZIMUTHAL_ANGLE_NAMES = ['s2_natal_kick_array_1', 'phi_2',\
                                        'phi2']
PRIMARY_KICK_POLAR_ANGLE_NAMES = ['s1_natal_kick_array_2', 'theta_1', 'theta1']
SECONDARY_KICK_POLAR_ANGLE_NAMES = ['s2_natal_kick_array_2', 'theta_2',\
                                    'theta2']
PRIMARY_KICK_MEAN_ANOMALY_NAMES = ['s1_natal_kick_array_3', 'mean_anomaly_1',\
                                   'mean_anomaly1']
SECONDARY_KICK_MEAN_ANOMALY_NAMES = ['s2_natal_kick_array_3',\
                                     'mean_anomaly_2', 'mean_anomaly2']

[docs] def infer_key(available_keys=[], allowed_keys=[]): """Infer key from list of allowed keys. Parameters ---------- available_keys : iterable object of str, e.g. list of str Collection of available keys. allowed_keys : iterable object of str, e.g. list of str Collection of allowed keys. Returns ------- key : str The first matched key. """ for k in allowed_keys: for key in available_keys: if key.casefold() == k.casefold(): return key return ''
[docs] def get_samples_from_file(orbital_scheme='', **kwargs): """Read a population of binaries at ZAMS from a file. Parameters ---------- orbital_scheme : str Scheme to get the orbit: 'separation', 'period' **kwargs : dictionary kwargs from BinaryPopulation class, which should contain read_samples_from_file Returns ------- orbital_scheme_set : ndarray of floats orbital separations/periods depending on the scheme eccentricity_set : ndarray of floats eccentricities m1_set : ndarray of floats primary masses m2_set : ndarray of floats secondary masses """ if 'read_samples_from_file' in kwargs: filename = kwargs['read_samples_from_file'] else: raise KeyError("In get_samples_from_file no 'read_samples_from_file'" " in kwargs.") # Check for number of binaries and save its value if 'number_of_binaries' in kwargs: number_of_binaries = kwargs['number_of_binaries'] else: number_of_binaries = 0 # Check and read file into dataframe if os.path.isfile(filename): df = pd.read_csv(filename) else: raise FileNotFoundError(f'{filename} not found!') # Get number of data frame entries set_n = len(df) # Get eccentricities key = infer_key(available_keys=df.keys(), allowed_keys=ECCENTRICITY_NAMES) if key=='': Pwarn(f'No eccentricity column found in {filename}, hence get' ' independent random ones.', "ReplaceValueWarning") kwargs['number_of_binaries'] = set_n eccentricity_set = generate_eccentricities(**kwargs) else: eccentricity_set = np.array(df[key]) # Get primary masses key = infer_key(available_keys=df.keys(), allowed_keys=PRIMARY_MASS_NAMES) if key=='': Pwarn(f'No primary mass column found in {filename}, hence get' ' independent random ones.', "ReplaceValueWarning") kwargs['number_of_binaries'] = set_n m1_set = generate_primary_masses(**kwargs) else: m1_set = np.array(df[key]) # Get secondary masses key = infer_key(available_keys=df.keys(), allowed_keys=SECONDARY_MASS_NAMES) if key=='': Pwarn(f'No secondary mass column found in {filename}, hence get' ' independent random ones.', "ReplaceValueWarning") kwargs['number_of_binaries'] = set_n m2_set = generate_secondary_masses(m1_set, **kwargs) else: m2_set = np.array(df[key]) if orbital_scheme == 'separation': # Get orbital separations key = infer_key(available_keys=df.keys(), allowed_keys=SEPARATION_NAMES) if key=='': Pwarn(f'No separation column found in {filename}, hence get' ' independent random ones.', "ReplaceValueWarning") kwargs['number_of_binaries'] = set_n orbital_scheme_set = generate_orbital_separations(**kwargs) else: orbital_scheme_set = np.array(df[key]) elif orbital_scheme == 'period': # Get orbital periods key = infer_key(available_keys=df.keys(), allowed_keys=PERIOD_NAMES) if key=='': Pwarn(f'No period column found in {filename}, hence get' ' independent random ones.', "ReplaceValueWarning") kwargs['number_of_binaries'] = set_n orbital_scheme_set = generate_orbital_periods(m1_set, **kwargs) else: orbital_scheme_set = np.array(df[key]) else: raise ValueError("Allowed orbital schemes are separation or period.") if number_of_binaries>0: if 'index' in kwargs: index = kwargs['index'] else: index = 0 # Expand the sets by doubling them as long as it is needed while len(orbital_scheme_set)<index+number_of_binaries: orbital_scheme_set = np.append(orbital_scheme_set,\ orbital_scheme_set, axis=0) eccentricity_set = np.append(eccentricity_set, eccentricity_set,\ axis=0) m1_set = np.append(m1_set, m1_set, axis=0) m2_set = np.append(m2_set, m2_set, axis=0) # Only return the requested set size return orbital_scheme_set[index:index+number_of_binaries],\ eccentricity_set[index:index+number_of_binaries],\ m1_set[index:index+number_of_binaries],\ m2_set[index:index+number_of_binaries] else: return orbital_scheme_set, eccentricity_set, m1_set, m2_set
[docs] def get_kick_samples_from_file(**kwargs): """Read a kicks for population of binaries from a file. Parameters ---------- **kwargs : dictionary kwargs from BinaryPopulation class, which should contain read_samples_from_file Returns ------- s1_natal_kick_array_set : ndarray of floats natal kick array for the primary star containing: kick velocity, azimuthal angle, polar angle, mean anomaly s2_natal_kick_array_set : ndarray of floats natal kick array for the secondary star containing: kick velocity, azimuthal angle, polar angle, mean anomaly """ if 'read_samples_from_file' in kwargs: filename = kwargs['read_samples_from_file'] else: raise KeyError("In get_kick_samples_from_file no " "'read_samples_from_file' in kwargs.") # Check and read file into dataframe if os.path.isfile(filename): df = pd.read_csv(filename) else: raise FileNotFoundError(f'{filename} not found!') # Get number of data frame entries set_n = len(df) ## Get primary kick # Velocity key = infer_key(available_keys=df.keys(),\ allowed_keys=PRIMARY_KICK_VELOCITY_NAMES) if key=='': Pwarn(f'No kick velocity column of primary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") w_set = np.array(set_n*[None]) else: w_set = np.array(df[key]) # Azimuthal angle key = infer_key(available_keys=df.keys(),\ allowed_keys=PRIMARY_KICK_AZIMUTHAL_ANGLE_NAMES) if key=='': Pwarn(f'No azimuthal angle column of primary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") phi_set = np.array(set_n*[None]) else: phi_set = np.array(df[key]) # Polar angle key = infer_key(available_keys=df.keys(),\ allowed_keys=PRIMARY_KICK_POLAR_ANGLE_NAMES) if key=='': Pwarn(f'No polar angle column of primary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") theta_set = np.array(set_n*[None]) else: theta_set = np.array(df[key]) # Mean anomaly key = infer_key(available_keys=df.keys(),\ allowed_keys=PRIMARY_KICK_MEAN_ANOMALY_NAMES) if key=='': Pwarn(f'No mean anomaly column of primary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") mean_anomaly_set = np.array(set_n*[None]) else: mean_anomaly_set = np.array(df[key]) kick_1_set = np.transpose(np.array([w_set, phi_set, theta_set,\ mean_anomaly_set])) ## Get secondary kick # Velocity key = infer_key(available_keys=df.keys(),\ allowed_keys=SECONDARY_KICK_VELOCITY_NAMES) if key=='': Pwarn(f'No kick velocity column of secondary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") w_set = np.array(set_n*[None]) else: w_set = np.array(df[key]) # Azimuthal angle key = infer_key(available_keys=df.keys(),\ allowed_keys=SECONDARY_KICK_AZIMUTHAL_ANGLE_NAMES) if key=='': Pwarn(f'No azimuthal angle column of secondary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") phi_set = np.array(set_n*[None]) else: phi_set = np.array(df[key]) # Polar angle key = infer_key(available_keys=df.keys(),\ allowed_keys=SECONDARY_KICK_POLAR_ANGLE_NAMES) if key=='': Pwarn(f'No polar angle column of secondary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") theta_set = np.array(set_n*[None]) else: theta_set = np.array(df[key]) # Mean anomaly key = infer_key(available_keys=df.keys(),\ allowed_keys=SECONDARY_KICK_MEAN_ANOMALY_NAMES) if key=='': Pwarn(f'No mean anomaly column of secondary found in {filename},' ' hence do not set them.', "ReplaceValueWarning") mean_anomaly_set = np.array(set_n*[None]) else: mean_anomaly_set = np.array(df[key]) kick_2_set = np.transpose(np.array([w_set, phi_set, theta_set,\ mean_anomaly_set])) if 'number_of_binaries' in kwargs: number_of_binaries = kwargs['number_of_binaries'] if 'index' in kwargs: index = kwargs['index'] else: index = 0 # expand the sets by doubling them as long as it is needed while len(kick_1_set)<index+number_of_binaries: kick_1_set = np.append(kick_1_set, kick_1_set, axis=0) kick_2_set = np.append(kick_2_set, kick_2_set, axis=0) # only return the requested set size return kick_1_set[index:index+number_of_binaries],\ kick_2_set[index:index+number_of_binaries] else: return kick_1_set, kick_2_set