def test_min_max_mass_single_kstar(self): # Send in a single typed binary with both components # being the same type for ii in range(len(kstar_single)): m_list = utils.mass_min_max_select(kstar_single[ii], kstar_single[ii]) self.assertEqual(np.sum([m_list]), MASS_SUM_SINGLE[ii])
def get_independent_sampler(final_kstar1, final_kstar2, primary_model, ecc_model, SFH_model, component_age, met, size, **kwargs): """Something Parameters ---------- final_kstar1 : `int` name of the format to be registered final_kstar2 : `int` the class that the sampler returns """ if type(final_kstar1) in [int, float]: final_kstar1 = [final_kstar1] if type(final_kstar2) in [int, float]: final_kstar2 = [final_kstar2] sampled_mass = 0.0 primary_min, primary_max, secondary_min, secondary_max = mass_min_max_select( final_kstar1, final_kstar2) initconditions = Sample() mass1, total_mass1 = initconditions.sample_primary(primary_min, primary_max, primary_model, size=size) # add in the total sampled primary mass sampled_mass += total_mass1 mass1_binary, mass_singles = initconditions.binary_select(mass1) mass2_binary = initconditions.sample_secondary(mass1_binary) # add in the sampled secondary mass sampled_mass += np.sum(mass2_binary) porb = initconditions.sample_porb(mass1_binary, mass2_binary, size=mass1_binary.size) ecc = initconditions.sample_ecc(ecc_model, size=mass1_binary.size) tphysf, metallicity = initconditions.sample_SFH( SFH_model, component_age=component_age, met=met, size=mass1_binary.size) metallicity[metallicity < 1e-4] = 1e-4 metallicity[metallicity > 0.03] = 0.03 kstar1 = initconditions.set_kstar(mass1_binary) kstar2 = initconditions.set_kstar(mass2_binary) return InitialBinaryTable.MultipleBinary(mass1_binary, mass2_binary, porb, ecc, tphysf, kstar1, kstar2, metallicity), sampled_mass, size
def get_independent_sampler(final_kstar1, final_kstar2, primary_model, ecc_model, SFH_model, component_age, met, size, **kwargs): sampled_mass = 0.0 primary_min, primary_max, secondary_min, secondary_max = mass_min_max_select(final_kstar1, final_kstar2) initconditions = Sample() mass1, total_mass1 = initconditions.sample_primary(primary_min, primary_max, primary_model, size=size) # add in the total sampled primary mass sampled_mass += total_mass1 mass1_binary, mass_singles = initconditions.binary_select(mass1) mass2_binary = initconditions.sample_secondary(mass1_binary) # add in the sampled secondary mass sampled_mass += np.sum(mass2_binary) porb = initconditions.sample_porb(mass1_binary, mass2_binary, size=mass1_binary.size) ecc = initconditions.sample_ecc(ecc_model, size = mass1_binary.size) tphysf = initconditions.sample_SFH(SFH_model, component_age=component_age, size = mass1_binary.size) kstar1 = initconditions.set_kstar(mass1_binary) kstar2 = initconditions.set_kstar(mass2_binary) metallicity = met * np.ones(mass1_binary.size) return InitialBinaryTable.MultipleBinary(mass1_binary, mass2_binary, porb, ecc, tphysf, kstar1, kstar2, metallicity, sampled_mass=sampled_mass, n_sampled=size)
def get_independent_sampler(final_kstar1, final_kstar2, primary_model, ecc_model, SFH_model, binfrac_model, component_age, met, size, **kwargs): """Generates an initial binary sample according to user specified models Parameters ---------- final_kstar1 : `int or list` Int or list of final kstar1 final_kstar2 : `int or list` Int or list of final kstar2 primary_model : `str` Model to sample primary mass; choices include: kroupa93, kroupa01, salpeter55 ecc_model : `str` Model to sample eccentricity; choices include: thermal, uniform SFH_model : `str` Model to sample star formation history (or birth time); choices include: const, burst, delta_burst binfrac_model : `str or float` Model for binary fraction; choices include: vanHaaften or a fraction where 1.0 is 100% binaries component_age : `float` Sets the maximum age of the component; in the case of a delta burst, every binary is evolved for the component age met : `float` Sets the metallicity of the binary population where solar metallicity is 0.02 size : `int` Size of the population to sample Returns ------- InitialBinaryTable : `pandas.DataFrame` DataFrame in the format of the InitialBinaryTable mass_singles : `float` Total mass in single stars needed to generate population mass_binaries : `float` Total mass in binaries needed to generate population n_singles : `int` Number of single stars needed to generate a population n_binaries : `int` Number of binaries needed to generate a population """ if type(final_kstar1) in [int, float]: final_kstar1 = [final_kstar1] if type(final_kstar2) in [int, float]: final_kstar2 = [final_kstar2] primary_min, primary_max, secondary_min, secondary_max = mass_min_max_select( final_kstar1, final_kstar2) initconditions = Sample() #set up multiplier if the mass sampling is inefficient multiplier = 1 mass1_binary = [] mass2_binary = [] binfrac = [] # track the mass in singles and the mass in binaries mass_singles = 0.0 mass_binaries = 0.0 # track the total number of stars sampled n_singles = 0 n_binaries = 0 while len(mass1_binary) < size: mass1, total_mass1 = initconditions.sample_primary(primary_model, size=size * multiplier) mass1_binaries, mass_single, binfrac_binaries = initconditions.binary_select( mass1, binfrac_model=binfrac_model) mass2_binaries = initconditions.sample_secondary(mass1_binaries) # track the mass sampled mass_singles += np.sum(mass_single) mass_binaries += np.sum(mass1_binaries) mass_binaries += np.sum(mass2_binaries) # track the total number sampled n_singles += len(mass_single) n_binaries += len(mass1_binaries) # select out the primaries and secondaries that will produce the final kstars ind_select_primary, = np.where((mass1_binaries > primary_min) & (mass1_binaries < primary_max)) ind_select_secondary, = np.where((mass2_binaries > secondary_min) & (mass2_binaries < secondary_max)) ind_select = list( set(ind_select_primary).intersection(ind_select_secondary)) mass1_binary.extend(mass1_binaries[ind_select]) mass2_binary.extend(mass2_binaries[ind_select]) binfrac.extend(binfrac_binaries[ind_select]) # check to see if we should increase the multiplier factor to sample the population more quickly if len(mass1_binary) < size / 100: # well this size clearly is not working time to increase # the multiplier by an order of magnitude multiplier *= 10 mass1_binary = np.array(mass1_binary) mass2_binary = np.array(mass2_binary) binfrac = np.asarray(binfrac) ecc = initconditions.sample_ecc(ecc_model, size=mass1_binary.size) porb = initconditions.sample_porb(mass1_binary, mass2_binary, ecc, size=mass1_binary.size) tphysf, metallicity = initconditions.sample_SFH( SFH_model, component_age=component_age, met=met, size=mass1_binary.size) metallicity[metallicity < 1e-4] = 1e-4 metallicity[metallicity > 0.03] = 0.03 kstar1 = initconditions.set_kstar(mass1_binary) kstar2 = initconditions.set_kstar(mass2_binary) return InitialBinaryTable.InitialBinaries( mass1_binary, mass2_binary, porb, ecc, tphysf, kstar1, kstar2, metallicity, binfrac=binfrac), mass_singles, mass_binaries, n_singles, n_binaries
def get_multidim_sampler(final_kstar1, final_kstar2, rand_seed, nproc, SF_start, SF_duration, met, size, **kwargs): """adapted version of Maxwell Moe's IDL code that generates a population of single and binary stars Below is the adapted version of Maxwell Moe's IDL code that generates a population of single and binary stars based on the paper Mind your P's and Q's By Maxwell Moe and Rosanne Di Stefano The python code has been adopted by Mads Sørensen Version history: V. 0.1; 2017/02/03 By Mads Sørensen - This is a pure adaption from IDL to Python. - The function idl_tabulate is similar to the IDL function int_tabulated except, this function seems to be slightly more exact in its solution. Therefore, relative to the IDL code, there are small numerical differences. Comments below beginning with ; is the original nodes by Maxwell Moe. Please read these careful for understanding the script. ; NOTE - This version produces only the statistical distributions of ; single stars, binaries, and inner binaries in hierarchical triples. ; Outer tertiaries in hierarchical triples are NOT generated. ; Moreover, given a set of companions, all with period P to ; primary mass M1, this version currently uses an approximation to ; determine the fraction of those companions that are inner binaries ; vs. outer triples. Nevertheless, this approximation reproduces ; the overall multiplicity statistics. ; Step 1 - Tabulate probably density functions of periods, ; mass ratios, and eccentricities based on ; analytic fits to corrected binary star populations. ; Step 2 - Implement Monte Carlo method to generate stellar ; population from those density functions. Parameters ---------- final_kstar1 : `list` or `int` Int or list of final kstar1 final_kstar2 : `list` or `int` Int or list of final kstar2 rand_seed : `int` Int to seed random number generator nproc : `int` Number of processors to use to generate population SF_start : `float` Time in the past when star formation initiates in Myr SF_duration : `float` Duration of constant star formation beginning from SF_Start in Myr met : `float` Sets the metallicity of the binary population where solar metallicity is 0.02 size : `int` Size of the population to sample **porb_lo : `float` Lower limit in days for the orbital period distribution **porb_hi: `float` Upper limit in days for the orbital period distribution Returns ------- InitialBinaryTable : `pandas.DataFrame` DataFrame in the format of the InitialBinaryTable mass_singles : `float` Total mass in single stars needed to generate population mass_binaries : `float` Total mass in binaries needed to generate population n_singles : `int` Number of single stars needed to generate a population n_binaries : `int` Number of binaries needed to generate a population """ if type(final_kstar1) in [int, float]: final_kstar1 = [final_kstar1] if type(final_kstar2) in [int, float]: final_kstar2 = [final_kstar2] porb_lo = kwargs.pop('porb_lo', 0.15) porb_hi = kwargs.pop('porb_hi', 8.0) primary_min, primary_max, secondary_min, secondary_max = mass_min_max_select( final_kstar1, final_kstar2) initconditions = MultiDim() mass1_binary, mass2_binary, porb, ecc, mass_singles, mass_binaries, n_singles, n_binaries, binfrac = initconditions.initial_sample( primary_min, secondary_min, primary_max, secondary_max, porb_lo, porb_hi, rand_seed, size=size, nproc=nproc) tphysf, metallicity = initconditions.sample_SFH(SF_start=SF_start, SF_duration=SF_duration, met=met, size=mass1_binary.size) kstar1 = initconditions.set_kstar(mass1_binary) kstar2 = initconditions.set_kstar(mass2_binary) metallicity[metallicity < 1e-4] = 1e-4 metallicity[metallicity > 0.03] = 0.03 return InitialBinaryTable.InitialBinaries( mass1_binary, mass2_binary, porb, ecc, tphysf, kstar1, kstar2, metallicity, binfrac=binfrac), mass_singles, mass_binaries, n_singles, n_binaries
def test_min_max_mass_multiple_kstar(self): # Send in a range of types for a binary for both components m_list = utils.mass_min_max_select(kstar_double, kstar_double) self.assertEqual(np.sum([m_list]), MASS_SUM_MULTIPLE)
def get_multidim_sampler(final_kstar1, final_kstar2, rand_seed, nproc, SFH_model, component_age, met, size, **kwargs): """adapted version of Maxwell Moe's IDL code that generates a population of single and binary stars Below is the adapted version of Maxwell Moe's IDL code that generates a population of single and binary stars based on the paper Mind your P's and Q's By Maxwell Moe and Rosanne Di Stefano The python code has been adopted by Mads Sørensen Version history: V. 0.1; 2017/02/03 By Mads Sørensen - This is a pure adaption from IDL to Python. - The function idl_tabulate is similar to the IDL function int_tabulated except, this function seems to be slightly more exact in its solution. Therefore, relative to the IDL code, there are small numerical differences. Comments below beginning with ; is the original nodes by Maxwell Moe. Please read these careful for understanding the script. ; NOTE - This version produces only the statistical distributions of ; single stars, binaries, and inner binaries in hierarchical triples. ; Outer tertiaries in hierarchical triples are NOT generated. ; Moreover, given a set of companions, all with period P to ; primary mass M1, this version currently uses an approximation to ; determine the fraction of those companions that are inner binaries ; vs. outer triples. Nevertheless, this approximation reproduces ; the overall multiplicity statistics. ; Step 1 - Tabulate probably density functions of periods, ; mass ratios, and eccentricities based on ; analytic fits to corrected binary star populations. ; Step 2 - Implement Monte Carlo method to generate stellar ; population from those density functions. """ if type(final_kstar1) in [int, float]: final_kstar1 = [final_kstar1] if type(final_kstar2) in [int, float]: final_kstar2 = [final_kstar2] porb_lo = kwargs.pop('porb_lo', 0.15) porb_hi = kwargs.pop('porb_hi', 8.0) primary_min, primary_max, secondary_min, secondary_max = mass_min_max_select( final_kstar1, final_kstar2) initconditions = MultiDim() mass1_binary, mass2_binary, porb, ecc, sampled_mass, n_sampled = initconditions.initial_sample( primary_min, secondary_min, primary_max, secondary_max, porb_lo, porb_hi, rand_seed, size=size, nproc=nproc) tphysf, metallicity = initconditions.sample_SFH(SFH_model, component_age, met, size=size) kstar1 = initconditions.set_kstar(mass1_binary) kstar2 = initconditions.set_kstar(mass2_binary) metallicity[metallicity < 1e-4] = 1e-4 metallicity[metallicity > 0.03] = 0.03 return InitialBinaryTable.MultipleBinary( mass1_binary, mass2_binary, porb, ecc, tphysf, kstar1, kstar2, metallicity), sampled_mass, n_sampled