def second_generation_mass_spin( dataset, alpha, beta, mmin, mmax, lam, mpp, sigpp, ): second_generation_mass = two_component_primary_mass_ratio( dataset=dataset, alpha=alpha, beta=beta * 4, mmin=mmin * 2, mmax=mmax * 2, lam=lam, mpp=mpp * 2, sigpp=sigpp * 2, ) alpha_2g, beta_2g, _ = mu_chi_var_chi_max_to_alpha_beta_max(mu_chi=0.67, var_chi=0.01, amax=1) second_generation_spin = iid_spin_magnitude_beta(dataset=dataset, alpha_chi=alpha_2g, beta_chi=beta_2g, amax=1) return second_generation_mass * second_generation_spin
def test_two_component_primary_mass_ratio_zero_below_mmin(self): m2s = self.dataset["mass_1"] * self.dataset["mass_ratio"] for ii in range(self.n_test): parameters = self.power_prior.sample() parameters.update(self.gauss_prior.sample()) p_m = mass.two_component_primary_mass_ratio(self.dataset, **parameters) self.assertEqual(xp.max(p_m[m2s <= parameters["mmin"]]), 0.0)
def test_single_peak_delta_m_zero_matches_two_component_primary_mass_ratio(self): max_diffs = list() for ii in range(self.n_test): parameters = self.power_prior.sample() parameters.update(self.gauss_prior.sample()) p_m1 = mass.two_component_primary_mass_ratio(self.dataset, **parameters) parameters["delta_m"] = 0 p_m2 = mass.SinglePeakSmoothedMassDistribution()(self.dataset, **parameters) max_diffs.append(_max_abs_difference(p_m1, p_m2)) self.assertAlmostEqual(max(max_diffs), 0.0)
def first_generation_mass_ratio(self, alpha, beta, mmin, mmax, lam, mpp, sigpp): first_generation_mass = two_component_primary_mass_ratio( dataset=self.first_generation_data, alpha=alpha, beta=beta, mmin=mmin, mmax=mmax, lam=lam, mpp=mpp, sigpp=sigpp, ) return trapz(first_generation_mass, self.mass_1s, axis=0)
def first_generation_mass_ratio(self, alpha, beta, mmin, mmax, lam, mpp, sigpp): grid_shift = (mmin - self.mass_1s[0] - self.dm / 2) % self.dm self.first_generation_data['mass_1'] += grid_shift first_generation_mass = two_component_primary_mass_ratio( dataset=self.first_generation_data, alpha=alpha, beta=beta, mmin=mmin, mmax=mmax, lam=lam, mpp=mpp, sigpp=sigpp, ) self.first_generation_data['mass_1'] -= grid_shift return trapz(first_generation_mass, self.mass_1s, axis=0)
def first_generation_mass_spin_big_grid( dataset, alpha, beta, mmin, mmax, lam, mpp, sigpp, alpha_chi, beta_chi, delta_chi, ): first_generation_mass = two_component_primary_mass_ratio( dataset=dataset, alpha=alpha, beta=beta, mmin=mmin, mmax=mmax, lam=lam, mpp=mpp, sigpp=sigpp, ) first_generation_spin = first_generation_spin_magnitude_big_grid( dataset["a_1"], alpha=alpha_chi, beta=beta_chi, delta=delta_chi, a_max=1, spin_array=dataset['a_1'] [:, 0, 0, 0]) * first_generation_spin_magnitude_big_grid( dataset["a_2"], alpha=alpha_chi, beta=beta_chi, delta=delta_chi, a_max=1, spin_array=dataset['a_2'][0, :, 0, 0]) return first_generation_mass * first_generation_spin
def first_generation_mass_spin( dataset, alpha, beta, mmin, mmax, lam, mpp, sigpp, alpha_chi, beta_chi, delta_chi, ): first_generation_mass = two_component_primary_mass_ratio( dataset=dataset, alpha=alpha, beta=beta, mmin=mmin, mmax=mmax, lam=lam, mpp=mpp, sigpp=sigpp, ) first_generation_spin = first_generation_spin_magnitude( dataset["a_1"], alpha=alpha_chi, beta=beta_chi, delta=delta_chi, a_max=1, ) * first_generation_spin_magnitude( dataset["a_2"], alpha=alpha_chi, beta=beta_chi, delta=delta_chi, a_max=1, ) return first_generation_mass * first_generation_spin
def two_component_primary_mass_ratio_dynamical_without_spins( dataset, alpha, beta, mmin, mmax, lam, mpp, sigpp, branch_1=0.12, branch_2=0.01, ): """ Power law model for two-dimensional mass distribution, modelling primary mass and conditional mass ratio distribution. p(m1, q) = p(m1) * p(q | m1) We also include the effect of dynamical mergers leading to 1.5 and 2nd generation mergers. Parameters ---------- dataset: dict Dictionary of numpy arrays for 'mass_1' and 'mass_ratio'. alpha: float Negative power law exponent for more massive black hole. mmin: float Minimum black hole mass. mmax: float Maximum black hole mass. beta: float Power law exponent of the mass ratio distribution. lam: float Fraction of black holes in the Gaussian component. mpp: float Mean of the Gaussian component. sigpp: float Standard deviation fo the Gaussian component. branch_1: float Ratio of 1.5 generation mergers to 1st generation mergers. The default value comes from a conversation with Eric Thrane. branch_2: float Ratio of 2nd generation mergers to 1st generation mergers. The default value comes from a conversation with Eric Thrane. """ btot = 1 + branch_1 + branch_2 fraction_1_5 = branch_1 / btot fraction_2 = branch_2 / btot fraction_1 = 1 - fraction_1_5 - fraction_2 if fraction_1 < 0: return np.zeros_like(dataset["mass_1"]) # assert branch_0 >= 0, "Branching fractions greater than 1." first_generation = two_component_primary_mass_ratio( dataset=dataset, alpha=alpha, beta=beta, mmin=mmin, mmax=mmax, lam=lam, mpp=mpp, sigpp=sigpp, ) params = dict(mmin=mmin * 2, mmax=mmax * 2, lam=lam, mpp=mpp * 2, sigpp=sigpp * 2) one_point_five_generation = two_component_single( dataset["mass_1"], alpha=alpha, ** params) * one_point_five_generation_mass_ratio( dataset, spectal_index=beta * 1.5, mmin=mmin) second_generation = two_component_primary_mass_ratio( dataset=dataset, alpha=alpha, beta=beta * 4, mmin=mmin * 2, mmax=mmax * 2, lam=lam, mpp=mpp * 2, sigpp=sigpp * 2, ) return (fraction_1 * first_generation + fraction_1_5 * one_point_five_generation + fraction_2 * second_generation)