def mcquillan_rapid_rotator_bins(): '''Plot the rapid rotator bins in the full McQuillan sample.''' mcq = cache.mcquillan_corrected_splitter() ebs = cache.eb_splitter_with_DSEP() dwarfs = mcq.subsample(["Dwarfs", "Right Statistics Teff"]) eb_dwarfs = ebs.subsample(["Dwarfs", "Right Statistics Teff"]) periodbins = np.flipud(np.array([1.5, 7, 10])) f, axes = plt.subplots(1, 2, figsize=(24, 12), sharex=True, sharey=True) cons_limit = -0.3 mcq_period_indices = np.digitize(dwarfs["Prot"], periodbins) eb_period_indices = np.digitize(eb_dwarfs["period"], periodbins) Protstr = r"$P_{\mathrm{rot}}$" titles = [ "{1} > {0:g} day".format(periodbins[0], Protstr), "{0:g} day < {2} <= {1:g} day".format(periodbins[2], periodbins[1], Protstr) ] eblabel = "EB" rotlabel = "McQuillan" for i, title, ax in zip(range(0, 4, 2), titles, np.ravel(axes)): mcq_periodbin = dwarfs[mcq_period_indices == i] eb_periodbin = eb_dwarfs[eb_period_indices == i] hr.absmag_teff_plot(mcq_periodbin["SDSS-Teff"], mcq_periodbin["Corrected K Excess"], marker=".", color=bc.black, ls="", axis=ax, zorder=1, label=rotlabel) hr.absmag_teff_plot(eb_periodbin["SDSS-Teff"], eb_periodbin["Corrected K Excess"], marker="*", color=bc.pink, ls="", ms=24, axis=ax, zorder=2, label=eblabel) eblabel = rotlabel = "" ax.set_ylabel("") ax.set_xlabel("") ax.set_title(title) ax.plot([4000, 5250], [cons_limit, cons_limit], marker="", ls="--", color=bc.violet, lw=6, zorder=3) ax.plot([3500, 6500], [-0.0, -0.0], 'k-', lw=2, zorder=4) axes[0].set_ylabel("Corrected $M_{Ks}$ Excess") axes[0].set_xlabel("$T_{\mathrm{eff}}$ (K)") axes[1].set_xlabel("$T_{\mathrm{eff}}$ (K)") axes[0].set_xlim(5250, 4000) axes[0].set_ylim(0.3, -1.25) axes[0].legend(loc="upper right")
def verify_eb_rapid_rotator_rate(): '''Compare the rate of EBs to the rate of rapid rotators.''' mcq = cache.mcquillan_corrected_splitter() nomcq = cache.mcquillan_nondetections_corrected_splitter() eb_split = cache.eb_splitter_with_DSEP() mcq_dwarfs = mcq.subsample(["Dwarfs", "Right Statistics Teff"]) nomcq_dwarfs = nomcq.subsample(["Dwarfs", "Right Statistics Teff"]) generic_columns = ["kepid", "Corrected K Excess"] dwarfs = vstack( [mcq_dwarfs[generic_columns], nomcq_dwarfs[generic_columns]]) dwarf_ebs = eb_split.subsample(["Dwarfs", "Right Statistics Teff"]) # We only want detached systems dwarf_ebs = dwarf_ebs[dwarf_ebs["period"] > 1] # Check the intersection between the two samples. dwarfs = au.filter_column_from_subtable(dwarfs, "kepid", dwarf_ebs["kepid"]) f, ax = plt.subplots(1, 1, dpi=dpi, figsize=figsize) # Now bin the EBs period_bins, dp = np.linspace(1.5, 12.5, 11 + 1, retstep=True) period_bins = period_bins period_bin_centers = np.sqrt(period_bins[1:] * period_bins[:-1]) eb_hist, _ = np.histogram(dwarf_ebs["period"], bins=period_bins) totalobjs = len(dwarfs) + len(dwarf_ebs) normalized_ebs = eb_hist / totalobjs eb_upperlim = (au.poisson_upper(eb_hist, 1) - eb_hist) / totalobjs eb_lowerlim = (eb_hist - au.poisson_lower(eb_hist, 1)) / totalobjs ax.step(period_bins, np.append(normalized_ebs, [0]), where="post", color=bc.red, ls="-", label="EBs", alpha=0.5) ax.set_xscale("linear") # Bin the rapid rotators rapid_hist, _ = np.histogram(mcq_dwarfs["Prot"], bins=period_bins) normalized_rapid = rapid_hist / totalobjs rapid_upperlim = (au.poisson_upper(rapid_hist, 1) - rapid_hist) / totalobjs rapid_lowerlim = (rapid_hist - au.poisson_lower(rapid_hist, 1)) / totalobjs ax.step(period_bins, np.append(normalized_rapid, [0]), where="post", color=bc.blue, ls="-", label="Rapid rotators") ax.errorbar(period_bin_centers, normalized_rapid, yerr=[rapid_lowerlim, rapid_upperlim], marker="", ls="", color=bc.blue, capsize=5) # To calculate the eclipse probability, I need masses and radii. masses = samp.calc_model_over_feh_fixed_age_alpha( np.log10(dwarf_ebs["SDSS-Teff"]), mist.MISTIsochrone.logteff_col, mist.MISTIsochrone.mass_col, 0.08, 1e9) radii = masses eclipse_prob = ebs.eclipse_probability(dwarf_ebs["period"], radii * 1.5, masses * 1.5) # For empty bins, this is the default eclipse probability. default_probs = ebs.eclipse_probability(period_bin_centers, 0.7, 0.7) # To translate from eb fraction to rapid fraction. correction_factor = (np.maximum(0, 0.92 - eclipse_prob) / eclipse_prob) default_correction = (np.maximum(0, 0.92 - default_probs) / default_probs) pred_hist, _ = np.histogram(dwarf_ebs["period"], bins=period_bins, weights=correction_factor) normalized_pred = pred_hist / totalobjs scale_factor = np.where(normalized_ebs, normalized_pred / normalized_ebs, default_correction) pred_upperlim = eb_upperlim * scale_factor pred_lowerlim = eb_lowerlim * scale_factor ax.step(period_bins, np.append(normalized_pred, [0]), where="post", color=bc.red, linestyle=":", label="Predicted Rapid Rotators from EBs") ax.errorbar(period_bin_centers, normalized_pred, yerr=[pred_lowerlim, pred_upperlim], marker="", ls="", color=bc.red, capsize=5) ax.set_xlabel("Period (day)") ax.set_ylabel("Normalized Period Distribution") ax.legend(loc="upper left") ax.set_xlim(1.5, 12.5) # Calculate the total rate of synchronized binaries. num_rapid = np.count_nonzero( np.logical_and(mcq_dwarfs["Prot"] > 1.5, mcq_dwarfs["Prot"] < 7)) total_rapid = num_rapid total_rapid_upper = au.poisson_upper_exact(total_rapid, 1) - total_rapid total_rapid_lower = total_rapid - au.poisson_lower_exact(total_rapid, 1) print("Rapid rate is {0:.5f} + {1:.6f} - {2:.6f}".format( total_rapid / totalobjs, total_rapid_upper / totalobjs, total_rapid_lower / totalobjs)) # Print the predicted number of rapid rotators from the eclipsing binaries. rapid = np.logical_and(dwarf_ebs["period"] > 1.5, dwarf_ebs["period"] < 7) pred_rapid = np.sum(correction_factor[rapid]) pred_num = np.count_nonzero(rapid) scale = pred_rapid / pred_num pred_rate = pred_rapid / totalobjs raw_upper = au.poisson_upper(pred_num, 1) - pred_num raw_lower = au.poisson_lower(pred_num, 1) - pred_num upper_pred = raw_upper * scale / totalobjs lower_pred = raw_lower * scale / totalobjs print("Predicted Rate is {0:.5f} + {1:.6f} - {2:.6f}".format( pred_rate, upper_pred, lower_pred)) # Calculate the total rate of synchronized binaries. num_rapid = np.count_nonzero( np.logical_and(mcq_dwarfs["Prot"] > 1.5, mcq_dwarfs["Prot"] < 7)) num_ebs = np.count_nonzero( np.logical_and(dwarf_ebs["period"] > 1.5, dwarf_ebs["period"] < 7)) total_rapid = num_rapid + num_ebs total_rapid_upper = au.poisson_upper_exact(total_rapid, 1) - total_rapid total_rapid_lower = total_rapid - au.poisson_lower_exact(total_rapid, 1) total_rate = total_rapid / 0.92 / totalobjs total_rate_upper = total_rapid_upper / 0.92 / totalobjs total_rate_lower = total_rapid_lower / 0.92 / totalobjs print("Total rate is {0:.5f} + {1:.6f} - {2:.6f}".format( total_rate, total_rate_upper, total_rate_lower))
def binary_fractions_with_period(): '''Measure the binary fraction with period.''' mcq = cache.mcquillan_corrected_splitter() nomcq = cache.mcquillan_nondetections_corrected_splitter() ebs = cache.eb_splitter_with_DSEP() mcq_dwarfs = mcq.subsample(["Dwarfs", "Right Statistics Teff"]) nomcq_dwarfs = nomcq.subsample(["Dwarfs", "Right Statistics Teff"]) generic_columns = ["Corrected K Excess"] dwarfs = vstack( [mcq_dwarfs[generic_columns], nomcq_dwarfs[generic_columns]]) dwarf_ebs = ebs.subsample(["Dwarfs", "Right Statistics Teff"]) f, ax2 = plt.subplots(1, 1, dpi=dpi, figsize=figsize) cons_limit = -0.3 # Create the histograms period_bins, dp = np.linspace(1.5, 21.5, 20 + 1, retstep=True, endpoint=True) # These are for the conservative sample. singles03 = mcq_dwarfs["Prot"][ mcq_dwarfs["Corrected K Excess"] >= cons_limit] binaries03 = mcq_dwarfs["Prot"][ mcq_dwarfs["Corrected K Excess"] < cons_limit] single_ebs03 = dwarf_ebs["period"][ dwarf_ebs["Corrected K Excess"] >= cons_limit] binary_ebs03 = dwarf_ebs["period"][ dwarf_ebs["Corrected K Excess"] < cons_limit] binary_rot_hist03, _ = np.histogram(binaries03, bins=period_bins) binary_eb_hist03, _ = np.histogram(binary_ebs03, bins=period_bins) single_rot_hist03, _ = np.histogram(singles03, bins=period_bins) single_eb_hist03, _ = np.histogram(single_ebs03, bins=period_bins) full_rot_hist, _ = np.histogram(mcq_dwarfs["Prot"], bins=period_bins) full_eb_hist, _ = np.histogram(dwarf_ebs["period"], bins=period_bins) # The total number of binaries and singles in the full sample. summed_binaries03 = ( np.count_nonzero(mcq_dwarfs["Corrected K Excess"] < cons_limit) + np.count_nonzero(dwarf_ebs["Corrected K Excess"] < cons_limit) + np.count_nonzero(nomcq_dwarfs["Corrected K Excess"] < cons_limit)) summed_singles03 = ( np.count_nonzero(mcq_dwarfs["Corrected K Excess"] >= cons_limit) + np.count_nonzero(dwarf_ebs["Corrected K Excess"] >= cons_limit) + np.count_nonzero(nomcq_dwarfs["Corrected K Excess"] >= cons_limit)) # The binary fraction for the full sample fullsamp_frac03 = (summed_binaries03 / (len(mcq_dwarfs) + len(dwarf_ebs) + len(nomcq_dwarfs))) # Sum up the binaries, single, and total histograms total_binaries03 = binary_rot_hist03 + binary_eb_hist03 total_singles03 = single_rot_hist03 + single_eb_hist03 total = full_rot_hist + full_eb_hist # Measure the binary fraction frac03 = total_binaries03 / total frac_uppers03 = au.binomial_upper(total_binaries03, total) - frac03 frac_lowers03 = frac03 - au.binomial_lower(total_binaries03, total) period_mids = (period_bins[1:] + period_bins[:-1]) / 2 ax2.step(period_bins, np.append(frac03, [0]), where="post", color=bc.black, ls="-", label="", lw=3) ax2.errorbar(period_bins[:-1] + dp / 2, frac03, yerr=[frac_lowers03, frac_uppers03], color=bc.black, ls="", marker="") ax2.plot([1, 50], [fullsamp_frac03, fullsamp_frac03], ls=":", marker="", color=bc.black, lw=3) ax2.set_xlabel("Rotation Period (day)") ax2.set_ylabel("Photometric Binary Function") ax2.set_xlim(1.5, 21.5) ax2.set_ylim(0, 1) ax2.set_title(r"$\Delta {0} < {1:g}$ mag".format(MKstr.strip("$"), cons_limit))
def distribution_singles_binaries(): '''Plot the distribution of singles and binaries.''' mcq = cache.mcquillan_corrected_splitter() nomcq = cache.mcquillan_nondetections_corrected_splitter() ebs = cache.eb_splitter_with_DSEP() mcq_dwarfs = mcq.subsample(["Dwarfs", "Right Statistics Teff"]) nomcq_dwarfs = nomcq.subsample(["Dwarfs", "Right Statistics Teff"]) generic_columns = ["Corrected K Excess"] dwarfs = vstack( [mcq_dwarfs[generic_columns], nomcq_dwarfs[generic_columns]]) dwarf_ebs = ebs.subsample(["Dwarfs", "Right Statistics Teff"]) f, ax = plt.subplots(1, 1, dpi=dpi, figsize=figsize, sharex=True) cons_limit = -0.3 # Create the histograms period_bins, dp = np.linspace(1.5, 21.5, 20 + 1, retstep=True, endpoint=True) # These are for the conservative sample. singles03 = mcq_dwarfs["Prot"][ mcq_dwarfs["Corrected K Excess"] >= cons_limit] binaries03 = mcq_dwarfs["Prot"][ mcq_dwarfs["Corrected K Excess"] < cons_limit] single_ebs03 = dwarf_ebs["period"][ dwarf_ebs["Corrected K Excess"] >= cons_limit] binary_ebs03 = dwarf_ebs["period"][ dwarf_ebs["Corrected K Excess"] < cons_limit] binary_rot_hist03, _ = np.histogram(binaries03, bins=period_bins) binary_eb_hist03, _ = np.histogram(binary_ebs03, bins=period_bins) single_rot_hist03, _ = np.histogram(singles03, bins=period_bins) single_eb_hist03, _ = np.histogram(single_ebs03, bins=period_bins) full_rot_hist, _ = np.histogram(mcq_dwarfs["Prot"], bins=period_bins) full_eb_hist, _ = np.histogram(dwarf_ebs["period"], bins=period_bins) # The total number of binaries and singles in the full sample. summed_binaries03 = ( np.count_nonzero(mcq_dwarfs["Corrected K Excess"] < cons_limit) + np.count_nonzero(dwarf_ebs["Corrected K Excess"] < cons_limit) + np.count_nonzero(nomcq_dwarfs["Corrected K Excess"] < cons_limit)) summed_singles03 = ( np.count_nonzero(mcq_dwarfs["Corrected K Excess"] >= cons_limit) + np.count_nonzero(dwarf_ebs["Corrected K Excess"] >= cons_limit) + np.count_nonzero(nomcq_dwarfs["Corrected K Excess"] >= cons_limit)) # The binary fraction for the full sample fullsamp_frac03 = (summed_binaries03 / (len(mcq_dwarfs) + len(dwarf_ebs) + len(nomcq_dwarfs))) # Sum up the binaries, single, and total histograms total_binaries03 = binary_rot_hist03 + binary_eb_hist03 total_singles03 = single_rot_hist03 + single_eb_hist03 total = full_rot_hist + full_eb_hist # Measure the binary fraction frac03 = total_binaries03 / total frac_uppers03 = au.binomial_upper(total_binaries03, total) - frac03 frac_lowers03 = frac03 - au.binomial_lower(total_binaries03, total) normalized_binaries03 = total_binaries03 / summed_binaries03 normalized_binaries_upper03 = ( (au.poisson_upper(total_binaries03, 1) - total_binaries03) / summed_binaries03) normalized_binaries_lower03 = ( (total_binaries03 - au.poisson_lower(total_binaries03, 1)) / summed_binaries03) normalized_singles03 = total_singles03 / summed_singles03 normalized_singles_upper03 = ( (au.poisson_upper(total_singles03, 1) - total_singles03) / summed_singles03) normalized_singles_lower03 = ( (total_singles03 - au.poisson_lower(total_singles03, 1)) / summed_singles03) ax.step(period_bins, np.append(normalized_binaries03, [0]), where="post", color=bc.algae, ls="-", label="Photometric Binaries") ax.step(period_bins, np.append(normalized_singles03, [0]), where="post", color=bc.purple, linestyle="--", label="Photometric Singles") ax.errorbar( period_bins[:-1] + dp / 2 - dp / 10, normalized_binaries03, yerr=[normalized_binaries_lower03, normalized_binaries_upper03], color=bc.algae, ls="", marker="") ax.errorbar(period_bins[:-1] + dp / 2 + dp / 10, normalized_singles03, yerr=[normalized_singles_lower03, normalized_singles_upper03], color=bc.purple, ls="", marker="") ax.set_xlabel("Rotation Period (day)") ax.set_ylabel("Normalized Period Distribution") ax.set_ylim(0, 0.035) ax.legend(loc="lower right")