def compute_n_sample(self): """Use the fixed population and total mass sampled to generate the fixed population to compute the number of systems in the Milky Way realization Parameters ---------- fixedpop : DataFrame Contains binary parameters from an evolved population generated by the runFixedPop executable fixed_mass : float Total mass sampled to generate the fixed population gx_component : str Milky Way component for which we are generating the population realization; choose from 'ThinDisk', 'ThickDisk', 'Bulge' Returns ------- n_samp : int The number of systems in the Milky Way realization """ # Compute the mass weighted number of systems # in a realistic Milky Way pop ####################################################################### component_mass = MC_sample.select_component_mass(self.gx_component) n_samp = MC_sample.mass_weighted_number(self.fixed_pop, self.fixed_mass, component_mass) return n_samp
def test_select_component_mass(self): # Check that the Galactic component masses are selected properly thin_mass = MC_samp.select_component_mass(GX_COMPONENT_THIN) self.assertEqual(thin_mass, GX_COMPONENT_MASS_THIN) thick_mass = MC_samp.select_component_mass(GX_COMPONENT_THICK) self.assertEqual(thick_mass, GX_COMPONENT_MASS_THICK) bulge_mass = MC_samp.select_component_mass(GX_COMPONENT_BULGE) self.assertEqual(bulge_mass, GX_COMPONENT_MASS_BULGE)
def test_sample_exponential_vertical(self): # Check that the mean & variance of the sampled distribution matches # the analytical mean & variance of the radial exponential distribution exp_vertical_sample = MC_samp.sample_exponential_vertical( N_SAMP, EXP_VERT_SCALE_HEIGHT) dist_mean = np.mean(exp_vertical_sample) self.assertTrue(np.abs(dist_mean - (EXP_VERT_MEAN_TEST)) < 1e-3) dist_var = np.var(exp_vertical_sample) self.assertTrue(np.abs(dist_var - EXP_VERT_VAR_TEST) < 1e-3)
def test_sample_sech_squared(self): # Check that the mean & variance of the sampled distribution matches # the analytical mean & variance of the sech squared distribution sech_squared_sample = MC_samp.sample_sech_squared( N_SAMP, 2 * SECH_SQUARED_SCALE_HEIGHT) dist_mean = np.mean(sech_squared_sample) self.assertTrue(np.abs(dist_mean - SECH_SQUARED_MEAN_TEST) < 1e-3) dist_var = np.var(sech_squared_sample) self.assertTrue(np.abs(dist_var - SECH_SQUARED_VAR_TEST) < 1e-3)
def test_mass_weighted_number(self): # Check that the total population number is scaled properly by mass n_pop = MC_samp.mass_weighted_number(FIXED_POP, MASS_FIXED, GX_COMPONENT_MASS_THIN) self.assertEqual(n_pop, N_GX)
def test_galactic_positions(self): # Check that the galactic positions are sampled properly xGX, yGX, zGX, inc, OMEGA, omega = MC_samp.galactic_positions( 'ThinDisk', N_SAMP, model='McMillan') self.assertTrue( np.abs( np.mean((xGX**2 + yGX**2)**0.5) - MCMILLAN_THINDISK_MEAN_TEST_XY) < 1e-2) self.assertTrue( np.abs(np.mean(zGX) - MCMILLAN_THINDISK_MEAN_TEST_Z) < 1e-2) self.assertTrue(np.abs(np.mean(inc) - 1.0) < 1e-2) self.assertTrue(np.abs(np.mean(OMEGA) - np.pi) < 1e-2) self.assertTrue(np.abs(np.mean(omega) - np.pi) < 1e-2) xGX, yGX, zGX, inc, OMEGA, omega = MC_samp.galactic_positions( 'ThinDisk', N_SAMP, model='sech_squared') self.assertTrue( np.abs( np.mean((xGX**2 + yGX**2)**0.5) - SECHSQUARE_THINDISK_MEAN_TEST_XY) < 1e-2) self.assertTrue( np.abs(np.mean(zGX) - SECHSQUARE_THINDISK_MEAN_TEST_Z) < 1e-2) self.assertTrue(np.abs(np.mean(inc) - 1.0) < 1e-2) self.assertTrue(np.abs(np.mean(OMEGA) - np.pi) < 1e-2) self.assertTrue(np.abs(np.mean(omega) - np.pi) < 1e-2) xGX, yGX, zGX, inc, OMEGA, omega = MC_samp.galactic_positions( 'ThinDisk', N_SAMP, model='double_exp') self.assertTrue( np.abs( np.mean((xGX**2 + yGX**2)**0.5) - DOUBLEEXP_THINDISK_MEAN_TEST_XY) < 1e-2) self.assertTrue( np.abs(np.mean(zGX) - DOUBLEEXP_THINDISK_MEAN_TEST_Z) < 1e-2) self.assertTrue(np.abs(np.mean(inc) - 1.0) < 1e-2) self.assertTrue(np.abs(np.mean(OMEGA) - np.pi) < 1e-2) self.assertTrue(np.abs(np.mean(omega) - np.pi) < 1e-2) xGX, yGX, zGX, inc, OMEGA, omega = MC_samp.galactic_positions( 'Bulge', N_SAMP, model='exp_squared') self.assertTrue( np.abs( np.mean((xGX**2 + yGX**2 + zGX**2)**0.5) - DOUBLEEXP_BULGE_MEAN_TEST_XYZ) < 1e-2) self.assertTrue(np.abs(np.mean(inc) - 1.0) < 1e-2) self.assertTrue(np.abs(np.mean(OMEGA) - np.pi) < 1e-2) self.assertTrue(np.abs(np.mean(omega) - np.pi) < 1e-2) xGX, yGX, zGX, inc, OMEGA, omega = MC_samp.galactic_positions( 'Bulge', 50000, model='McMillan') self.assertTrue( np.abs( np.mean((xGX**2 + yGX**2)**0.5) - MCMILLAN_BULGE_MEAN_TEST_XY) < 1e-1) self.assertTrue(np.abs(np.mean(zGX) - 0.0 < 1e-2)) self.assertTrue(np.abs(np.mean(inc) - 1.0) < 1e-2) self.assertTrue(np.abs(np.mean(OMEGA) - np.pi) < 1e-2) self.assertTrue(np.abs(np.mean(omega) - np.pi) < 1e-2) xGX, yGX, zGX, inc, OMEGA, omega = MC_samp.galactic_positions( 'ThickDisk', N_SAMP, model='McMillan') self.assertTrue( np.abs( np.mean((xGX**2 + yGX**2)**0.5) - MCMILLAN_THICKDISK_MEAN_TEST_XY) < 1e-2) self.assertTrue( np.abs(np.mean(zGX) - MCMILLAN_THICKDISK_MEAN_TEST_Z) < 1e-2) self.assertTrue(np.abs(np.mean(inc) - 1.0) < 1e-2) self.assertTrue(np.abs(np.mean(OMEGA) - np.pi) < 1e-2) self.assertTrue(np.abs(np.mean(omega) - np.pi) < 1e-2) xGX, yGX, zGX, inc, OMEGA, omega = MC_samp.galactic_positions( 'ThinDisk', N_SAMP, model='double_exp') self.assertTrue( np.abs( np.mean((xGX**2 + yGX**2)**0.5) - DOUBLEEXP_THICKDISK_MEAN_TEST_XY) < 1e-2) self.assertTrue( np.abs(np.mean(zGX) - DOUBLEEXP_THICKDISK_MEAN_TEST_Z) < 1e-2) self.assertTrue(np.abs(np.mean(inc) - 1.0) < 1e-2) self.assertTrue(np.abs(np.mean(OMEGA) - np.pi) < 1e-2) self.assertTrue(np.abs(np.mean(omega) - np.pi) < 1e-2)
def sample_population(self): """Once the fixed population is evolved, we Monte-Carlo sample the binary parameters to generate a Milky Way realization. Parameters ---------- fixedpop : DataFrame Contains binary parameters from an evolved population generated by the runFixedPop executable n_samp : int The number of systems in the Milky Way realization gx_component : str Milky Way component for which we are generating the population realization; choose from 'ThinDisk', 'ThickDisk', 'Bulge' gx_model : str Model for spatial distribution of binaries in the Galactic component; Default='McMillan' dat_list : list List containing the parameters to MC sample to generate the Galactic realization Returns ------- realization : DataFrame Milky Way population realization of size n_samp """ if not hasattr(self, 'n_samp'): self.n_samp = self.compute_n_sample() # Based on the user supplied filter flags, filter the # population to reduce the sample to only the relevant population ####################################################################### # Transform the fixed population to have limits between 0 and 1 # then transform to logit space to maintain the population boundaries # and create a KDE using knuth's rule to select the bandwidth ####################################################################### dat_kde = utils.dat_transform(self.fixed_pop, self.dat_list) bw = utils.knuth_bw_selector(dat_kde) dat_kernel = stats.gaussian_kde(dat_kde, bw_method=bw) # Sample from the KDE ####################################################################### binary_dat_trans = dat_kernel.resample(self.n_samp) binary_dat = utils.dat_un_transform(binary_dat_trans, self.fixed_pop, self.dat_list) # Sample positions and orientations for each sampled binary ####################################################################### xGx, yGx, zGx, inc, OMEGA, omega = MC_sample.galactic_positions( self.gx_component, size=len(binary_dat[0]), model=self.gx_model) binary_sample_positions = np.vstack([xGx, yGx, zGx, inc, OMEGA, omega]) # Create a single DataFrame for the Galactic realization ####################################################################### if 'ecc' not in self.dat_list: full_sample = np.vstack( [binary_dat, np.zeros(self.n_samp), binary_sample_positions]).T column_list = self.dat_list + [ 'ecc', 'xGx', 'yGx', 'zGx', 'inc', 'OMEGA', 'omega' ] else: full_sample = np.concatenate([binary_dat, binary_sample_positions]).T column_list = self.dat_list + [ 'xGx', 'yGx', 'zGx', 'inc', 'OMEGA', 'omega' ] realization = pd.DataFrame(full_sample,\ columns = column_list) return realization