Exemple #1
0
def test_mpi(verbose=False, plot=False, npoints=8, turn_mpi_off_after=True):
    phoebe.reset_settings()
    phoebe.mpi_on(4)

    b = phoebe.Bundle.default_binary()

    b.add_dataset('lc', times=np.linspace(0, 1, npoints))

    if verbose: print("calling compute")
    b.run_compute(irrad_method='none', ntriangles=1000, detach=True)
    if verbose:
        print("attaching to model")
        print(b['model'].status)
    b['model'].attach()

    if verbose: print("model received")

    if plot:
        b.plot(show=True)

    phoebe.reset_settings()
    if turn_mpi_off_after:
        # we need to turn this off for the next test in nosetests... but
        # if running from python or mpirun, we don't want to release all the
        # workers or they'll just pickup all the previous tasks
        phoebe.mpi_off()

    return b
Exemple #2
0
 def __init__(self,
              input_vals,
              input_sigmas,
              flux,
              times,
              sigmas,
              settings='standard',
              exp_time=False,
              ncores=32):
     if settings == 'standard':
         self.alpha = 1
         self.gamma = 2
         self.rho = 0.5
         self.sigma = 0.5
     elif settings == 'agressive':
         self.alpha = 2
         self.gamma = 2
         self.rho = 0.95
         self.sigma = 0.95
     self.ncores = ncores
     self.history = binary_history(input_vals)
     self.start = time.time()
     self.vertices = []
     self.units = units()
     self.chi_history = []
     self.sd_history = []
     self.steps = []
     self.dims = len(input_vals) + 1
     self.vals = input_vals
     self.input_sigmas = input_sigmas
     self.flux = flux
     self.times = times
     self.sigmas = sigmas
     self.exp_time = exp_time
     self.start_nprocs = int(self.ncores / self.dims)
     if self.dims * self.start_nprocs > self.ncores:
         self.start_nprocs = self.start_nprocs - 1
     self.shrink_nprocs = int(self.ncores / (self.dims - 1))
     if (self.dims - 1) * self.shrink_nprocs > self.ncores:
         self.shrink_nprocs = self.shrink_nprocs - 1
     self.nprocs = int(self.ncores / 3)
     if 3 * self.nprocs > self.ncores:
         self.shrink_nprocs = self.nprocs - 1
     vert_vals = [input_vals.copy()]
     for key in input_vals.keys():
         ex_vert_vals = input_vals.copy()
         ex_vert_vals[key] = ex_vert_vals[key] + input_sigmas[key]
         vert_vals.append(ex_vert_vals)
     mult_input = []
     for each in vert_vals:
         mult_input.append((each, flux, times, sigmas, exp_time))
     phoebe.mpi_on(nprocs=self.start_nprocs)
     with mp.Pool(self.dims) as p:
         self.vertices = p.starmap(vertex_multi, mult_input)
     self.sort()
     self.initial_vertex = self.vertices[0]
Exemple #3
0
 def calculate_points(self):
     self.calculate_reflected_point(self.alpha)
     self.calculate_expanded_point(self.gamma)
     self.calculate_contracted_point(self.rho)
     mult_input = []
     mult_input.append((self.reflected_point_vals, self.flux, self.times,
                        self.sigmas, self.exp_time))
     mult_input.append((self.expanded_point_vals, self.flux, self.times,
                        self.sigmas, self.exp_time))
     mult_input.append((self.contracted_point_vals, self.flux, self.times,
                        self.sigmas, self.exp_time))
     phoebe.mpi_on(nprocs=self.nprocs)
     with mp.Pool(processes=3) as p:
         calculated_points = p.starmap(vertex_multi, mult_input)
     self.reflected_point = calculated_points[0]
     self.expanded_point = calculated_points[1]
     self.contracted_point = calculated_points[2]
Exemple #4
0
def initialize_phoebe(output_dir=None, mpi_ncores=0, logger=True):
    if output_dir != None:
        try:
            os.mkdir(output_dir)
        except:
            shutil.rmtree(output_dir)
            os.mkdir(output_dir)
    if logger:
        sys.stdout = Logger(output_dir)
    phoebe.logger(
        clevel='ERROR')  # ignore warnings - for tqdm to work properly
    phoebe.interactive_checks_off()
    phoebe.check_visible_off()
    phoebe.interactive_constraints_off()
    if mpi_ncores != 0:
        phoebe.mpi_on(nprocs=mpi_ncores)
    return output_dir
Exemple #5
0
 def shrink(self):
     phoebe.mpi_on(nprocs=self.shrink_nprocs)
     new_vertices = [self.vertices[0]]
     mult_input = []
     for vert in self.vertices[1:]:
         new_vals = self.centroid_vals.copy()
         for key in self.centroid_vals.keys():
             new_vals[key] = self.vertices[0].vals[key] + self.sigma * (
                 vert.vals[key] - self.vertices[0].vals[key])
         mult_input.append(
             (new_vals, self.flux, self.times, self.sigmas, self.exp_time))
     with mp.Pool(self.dims - 1) as p:
         new_calculated = p.starmap(vertex_multi, mult_input)
     for each in new_calculated:
         new_vertices.append(each)
     self.vertices = new_vertices
     self.last_step = 'Shrink'
     self.standard_deviation()
Exemple #6
0
def test_mpi(plot=False, npoints=8):
    phoebe.reset_settings()
    phoebe.mpi_on(4)

    b = phoebe.Bundle.default_binary()

    b.add_dataset('lc', times=np.linspace(0, 1, npoints))

    if plot: print "calling compute"
    b.run_compute(irrad_method='none', model='phoebe2model')
    if plot: print "model received"

    if plot:
        b.plot(show=True)

    phoebe.reset_settings()
    phoebe.mpi_off()

    return b
Exemple #7
0
def test_mpi(plot=False, npoints=8):
    phoebe.reset_settings()
    phoebe.mpi_on(4)

    b = phoebe.Bundle.default_binary()

    b.add_dataset('lc', times=np.linspace(0,1,npoints))

    if plot: print "calling compute"
    b.run_compute(irrad_method='none', ntriangles=1000, detach=True)
    if plot:
        print "attaching to model"
        print b['model'].status
    b['model'].attach()

    if plot: print "model received"

    if plot:
        b.plot(show=True)

    phoebe.reset_settings()
    phoebe.mpi_off()

    return b
def binary_star_mesh(star1_params,
                     star2_params,
                     binary_params,
                     observation_times,
                     use_blackbody_atm=False,
                     make_mesh_plots=True,
                     mesh_temp=False,
                     mesh_temp_cmap=None,
                     plot_name=None,
                     print_diagnostics=False,
                     par_compute=False,
                     num_par_processes=8,
                     num_triangles=1500):
    """Compute the light curve for a binary system
    
    Keyword arguments:
    star1_params -- Tuple of parameters for the primary star
    star2_params -- Tuple of parameters for the secondary star
    binary_params -- Tuple of parameters for the binary system configuration
    observation_times -- Tuple of observation times,
        with numpy array of MJDs in each band
        (kp_MJDs, h_MJDs, mesh_MJDs) = observation_times
    use_blackbody_atm -- Use blackbody atmosphere
        instead of default Castelli & Kurucz (default False)
    make_mesh_plots -- Make a mesh plot of the binary system (default False)
    plot_name
    print_diagnostics
    par_compute
    num_par_processes
    """

    if par_compute:
        # TODO: Need to implement parallelization correctly
        phoebe.mpi_on(nprocs=num_par_processes)
    else:
        phoebe.mpi_off()

    # Read in the stellar parameters of the binary components
    (star1_mass, star1_rad, star1_teff, star1_logg, star1_mag_Kp, star1_mag_H,
     star1_pblum_Kp, star1_pblum_H) = star1_params
    (star2_mass, star2_rad, star2_teff, star2_logg, star2_mag_Kp, star2_mag_H,
     star2_pblum_Kp, star2_pblum_H) = star2_params

    # Read in the parameters of the binary system
    (binary_period, binary_ecc, binary_inc, t0) = binary_params

    err_out = (np.array([-1.]), np.array([-1.]))

    # Check for high temp ck2004 atmosphere limits
    if not use_blackbody_atm:
        # log g = 3.5, high temp bounds (above 31e3 K)
        if star1_teff > (31000 * u.K) and (4.0 > star1_logg > 3.5):
            star1_teff_round = 30995.0 * u.K

            if print_diagnostics:
                print('Star 1 out of C&K 2004 grid')
                print('star1_logg = {0:.4f}'.format(star1_logg))
                print('Rounding down star1_teff')
                print('{0:.4f} -> {1:.4f}'.format(star1_teff,
                                                  star1_teff_round))

            star1_teff = star1_teff_round
        if star2_teff > (31000 * u.K) and (4.0 > star2_logg > 3.5):
            star2_teff_round = 30995.0 * u.K

            if print_diagnostics:
                print('Star 2 out of C&K 2004 grid')
                print('star2_logg = {0:.4f}'.format(star2_logg))
                print('Rounding down star2_teff')
                print('{0:.4f} -> {1:.4f}'.format(star2_teff,
                                                  star2_teff_round))

            star2_teff = star2_teff_round

        # log g = 4.0, high temp bounds (above 40e3 K)
        if star1_teff > (40000 * u.K) and (4.5 > star1_logg > 4.0):
            star1_teff_round = 39995.0 * u.K

            print('Star 1 out of C&K 2004 grid')
            print('star1_logg = {0:.4f}'.format(star1_logg))
            print('Rounding down star1_teff')
            print('{0:.4f} -> {1:.4f}'.format(star1_teff, star1_teff_round))

            star1_teff = star1_teff_round
        if star2_teff > (40000 * u.K) and (4.0 > star2_logg > 3.50):
            star2_teff_round = 39995.0 * u.K

            print('Star 2 out of C&K 2004 grid')
            print('star2_logg = {0:.4f}'.format(star2_logg))
            print('Rounding down star2_teff')
            print('{0:.4f} -> {1:.4f}'.format(star2_teff, star2_teff_round))

            star2_teff = star2_teff_round

    # Set up binary model
    b = phoebe.default_binary()

    ## Set a default distance
    b.set_value('distance', 10 * u.pc)

    ## Set period, semimajor axis, and mass ratio (q)
    binary_sma = ((binary_period**2. * const.G * (star1_mass + star2_mass)) /
                  (4. * np.pi**2.))**(1. / 3.)

    binary_q = star2_mass / star1_mass

    if print_diagnostics:
        print('\nBinary orbit checks')
        print('Binary SMA: {0}'.format(binary_sma.to(u.AU)))
        print('Binary Mass Ratio (q): {0}'.format(binary_q))

    b.set_value('period@orbit', binary_period)
    b.set_value('sma@binary@component', binary_sma)
    b.set_value('q@binary@component', binary_q)

    ## Inclination
    b.set_value('incl@orbit', binary_inc)

    # Check for overflow
    ## Variables to help store the non-detached binary cases
    star1_semidetached = False
    star2_semidetached = False

    star1_overflow = False
    star2_overflow = False

    ## Get the max radii for both component stars
    star1_rad_max = b.get_value('requiv_max@primary@component') * u.solRad
    star2_rad_max = b.get_value('requiv_max@secondary@component') * u.solRad

    ## Check for semidetached cases
    if print_diagnostics:
        print('\nSemidetached checks')
        print('Star 1: {0}'.format(
            np.abs((star1_rad - star1_rad_max) / star1_rad_max)))
        print('Star 2: {0}'.format(
            np.abs((star2_rad - star2_rad_max) / star2_rad_max)))

    semidet_cut = 0.001  # (within 0.1% of max radii)
    semidet_cut = 0.015  # (within 1.5% of max radii)

    if np.abs((star1_rad - star1_rad_max) / star1_rad_max) < semidet_cut:
        star1_semidetached = True
    if np.abs((star2_rad - star2_rad_max) / star2_rad_max) < semidet_cut:
        star2_semidetached = True

    ## Check for overflow
    if (star1_rad > star1_rad_max) and not star1_semidetached:
        star1_overflow = True

    if (star2_rad > star2_rad_max) and not star2_semidetached:
        star2_overflow = True

    ### Check for if both stars are overflowing; which star overflows more?
    ### Choose that star to be overflowing more
    if star1_overflow and star2_overflow:
        if (star1_rad - star1_rad_max) >= (star2_rad - star2_rad_max):
            star2_overflow = False
        else:
            star1_overflow = False

    if print_diagnostics:
        print('\nOverflow Checks')
        print('Star 1 Semidetached: {0}'.format(star1_semidetached))
        print('Star 2 Semidetached: {0}'.format(star2_semidetached))
        print('Star 1 Overflow: {0}'.format(star1_overflow))
        print('Star 2 Overflow: {0}'.format(star2_overflow))

    # If star 2 is overflowing, have to re set up model:
    # Calling this same binary_star_lc function again,
    # with star 2 as primary and star 1 as secondary.
    # Change t0 = t0 - per/2 to make sure phase is correct,
    # wrt stars 1 and 2 being in same respective position
    if star2_overflow and not star1_overflow:
        redo_binary_params = (binary_period, binary_ecc, binary_inc,
                              t0 - (binary_period.to(u.d).value / 2.))

        return binary_star_lc(star2_params,
                              star1_params,
                              redo_binary_params,
                              observation_times,
                              use_blackbody_atm=use_blackbody_atm,
                              make_mesh_plots=make_mesh_plots,
                              mesh_temp=mesh_temp,
                              mesh_temp_cmap=mesh_temp_cmap,
                              plot_name=plot_name,
                              print_diagnostics=print_diagnostics,
                              par_compute=par_compute,
                              num_par_processes=num_par_processes,
                              num_triangles=num_triangles)

    ## If none of these overflow cases, set variable to store if binary is detached
    binary_detached = (not star1_semidetached) and \
                      (not star2_semidetached) and \
                      (not star1_overflow) and \
                      (not star2_overflow)

    ### Set non-zero eccentricity only if binary is detached
    if binary_detached:
        b.set_value('ecc@binary@component', binary_ecc)
    else:
        b.set_value('ecc@binary@component', 0.)

    ## Change set up for contact or semidetached cases
    if star1_overflow or star2_overflow:
        b = phoebe.default_binary(contact_binary=True)

        ### Reset all necessary binary properties for contact system
        b.set_value('distance', 10 * u.pc)

        b.set_value('period@orbit', binary_period)
        b.set_value('sma@binary@component', binary_sma)
        b.set_value('q@binary@component', binary_q)
        b.set_value('incl@orbit', binary_inc)

    if star1_semidetached and not star2_overflow:
        b.add_constraint('semidetached', 'primary')
    if star2_semidetached and not star1_overflow:
        b.add_constraint('semidetached', 'secondary')

    # Set up compute
    if use_blackbody_atm:
        b.add_compute('phoebe',
                      compute='detailed',
                      irrad_method='wilson',
                      atm='blackbody')
    else:
        b.add_compute('phoebe', compute='detailed', irrad_method='wilson')

    # Set the parameters of the component stars of the system
    ## Primary
    b.set_value('teff@primary@component', star1_teff)
    # b.set_value('logg@primary@component', star1_logg)
    if (not star1_semidetached) and (not star2_overflow):
        b.set_value('requiv@primary@component', star1_rad)

    ## Secondary
    b.set_value('teff@secondary@component', star2_teff)
    # b.set_value('logg@secondary@component', star2_logg)
    if (not star2_semidetached) and (not star1_overflow) and (
            not star2_overflow):
        try:
            b.set_value('requiv@secondary@component', star2_rad)
        except:
            print('\nOverflow Checks')
            print('Star 1 Semidetached: {0}'.format(star1_semidetached))
            print('Star 2 Semidetached: {0}'.format(star2_semidetached))
            print('Star 1 Overflow: {0}'.format(star1_overflow))
            print('Star 2 Overflow: {0}'.format(star2_overflow))

            print("Cannot set secondary radius: {0}".format(sys.exc_info()[0]))

            return err_out

    # Set the number of triangles in the mesh
    # Detached stars
    if len(b.filter('ntriangles@primary@detailed@compute')) == 1:
        b.set_value('ntriangles@primary@detailed@compute', num_triangles)

    if len(b.filter('ntriangles@secondary@detailed@compute')) == 1:
        b.set_value('ntriangles@secondary@detailed@compute', num_triangles)

    # Contact envelope
    if len(b.filter('ntriangles@contact_envelope@detailed@compute')) == 1:
        if print_diagnostics:
            print('Setting number of triangles for contact envelope')
        b.set_value('ntriangles@contact_envelope@detailed@compute',
                    num_triangles * 2.)

    # Phase the observation times
    ## Read in observation times
    (kp_MJDs, h_MJDs, mesh_MJDs) = observation_times

    ## Phase the observation times
    kp_phased_days = (
        (kp_MJDs - t0) % binary_period.to(u.d).value) / binary_period.to(
            u.d).value
    h_phased_days = ((h_MJDs - t0) %
                     binary_period.to(u.d).value) / binary_period.to(u.d).value
    mesh_phased_days = (
        (mesh_MJDs - t0) % binary_period.to(u.d).value) / binary_period.to(
            u.d).value

    # Add light curve datasets
    ## Kp
    kp_phases_sorted_inds = np.argsort(kp_phased_days)

    kp_model_times = (kp_phased_days) * binary_period.to(u.d).value
    kp_model_times = kp_model_times[kp_phases_sorted_inds]

    # b.add_dataset(phoebe.dataset.lc, time=kp_model_times,
    #               dataset='mod_lc_Kp', passband='Keck_NIRC2:Kp')
    if use_blackbody_atm:
        b.add_dataset(phoebe.dataset.lc,
                      time=kp_model_times,
                      dataset='mod_lc_Kp',
                      passband='Keck_NIRC2:Kp')
        b.set_value('ld_mode@primary@mod_lc_Kp', 'manual')
        b.set_value('ld_mode@secondary@mod_lc_Kp', 'manual')
        b.set_value('ld_func@primary@mod_lc_Kp', 'logarithmic')
        b.set_value('ld_func@secondary@mod_lc_Kp', 'logarithmic')
    else:
        b.add_dataset(phoebe.dataset.lc,
                      time=kp_model_times,
                      dataset='mod_lc_Kp',
                      passband='Keck_NIRC2:Kp')

    ## H
    h_phases_sorted_inds = np.argsort(h_phased_days)

    h_model_times = (h_phased_days) * binary_period.to(u.d).value
    h_model_times = h_model_times[h_phases_sorted_inds]

    # b.add_dataset(phoebe.dataset.lc, times=h_model_times,
    #               dataset='mod_lc_H', passband='Keck_NIRC2:H')
    if use_blackbody_atm:
        b.add_dataset(phoebe.dataset.lc,
                      times=h_model_times,
                      dataset='mod_lc_H',
                      passband='Keck_NIRC2:H')
        b.set_value('ld_mode@primary@mod_lc_H', 'manual')
        b.set_value('ld_mode@secondary@mod_lc_H', 'manual')
        b.set_value('ld_func@primary@mod_lc_H', 'logarithmic')
        b.set_value('ld_func@secondary@mod_lc_H', 'logarithmic')
    else:
        b.add_dataset(phoebe.dataset.lc,
                      times=h_model_times,
                      dataset='mod_lc_H',
                      passband='Keck_NIRC2:H')

    # Add mesh dataset if making mesh plot
    mesh_phases_sorted_inds = np.argsort(mesh_phased_days)

    mesh_model_times = (mesh_phased_days) * binary_period.to(u.d).value
    mesh_model_times = mesh_model_times[mesh_phases_sorted_inds]

    if make_mesh_plots:
        b.add_dataset('mesh', times=mesh_model_times, dataset='mod_mesh')

        if mesh_temp:
            b['columns@mesh'] = ['teffs', 'loggs']

    # Set the passband luminosities for the stars
    b.set_value('pblum_mode@mod_lc_Kp', 'decoupled')
    b.set_value('pblum_mode@mod_lc_H', 'decoupled')

    b.set_value('pblum@primary@mod_lc_Kp', star1_pblum_Kp)
    b.set_value('pblum@primary@mod_lc_H', star1_pblum_H)

    b.set_value('pblum@secondary@mod_lc_Kp', star2_pblum_Kp)
    b.set_value('pblum@secondary@mod_lc_H', star2_pblum_H)

    # Run compute
    # if print_diagnostics:
    #     print("Trying inital compute run")
    #     b.run_compute(compute='detailed', model='run',
    #                   progressbar=False)

    try:
        b.run_compute(compute='detailed', model='run', progressbar=False)
    except:
        if print_diagnostics:
            print("Error during primary binary compute: {0}".format(
                sys.exc_info()[0]))
        return err_out

    # Save out mesh plot
    if make_mesh_plots:
        ## Plot Nerdery
        plt.rc('font', family='serif')
        plt.rc('font', serif='Computer Modern Roman')
        plt.rc('text', usetex=True)
        plt.rc('text.latex', preamble=r"\usepackage{gensymb}")

        plt.rc('xtick', direction='in')
        plt.rc('ytick', direction='in')
        # plt.rc('xtick', top = True)
        # plt.rc('ytick', right = True)

        suffix_str = ''
        if plot_name is not None:
            suffix_str = '_' + plot_name

        ## Mesh plot
        mesh_plot_out = []

        if mesh_temp:
            b['mod_mesh@model'].plot(
                fc='teffs',
                fcmap=mesh_temp_cmap,
                ec='face',
                animate=True,
                save='./binary_mesh{0}.gif'.format(suffix_str),
                save_kwargs={'writer': 'imagemagick'})
            for (mesh_model_time,
                 mesh_index) in zip(mesh_model_times,
                                    range(len(mesh_model_times))):
                plt.clf()
                new_fig = plt.figure()
                (mesh_af_fig, mesh_plt_fig) = b['mod_mesh@model'].plot(
                    fig=new_fig,
                    time=mesh_model_time,
                    fc='teffs',
                    fcmap=mesh_temp_cmap,
                    ec='face',
                    save='./binary_mesh_{0}.pdf'.format(mesh_index))
                mesh_plot_out.append(mesh_plt_fig)
                plt.close(new_fig)
        else:
            b['mod_mesh@model'].plot(
                animate=True,
                save='./binary_mesh{0}.gif'.format(suffix_str),
                save_kwargs={'writer': 'imagemagick'})
            for mesh_model_time in mesh_model_times:
                mesh_plot_out.append(b['mod_mesh@model'].plot(
                    time=mesh_model_time,
                    save='./binary_mesh.pdf'.format(suffix_str)))

    # Get fluxes
    ## Kp
    model_fluxes_Kp = np.array(
        b['fluxes@lc@mod_lc_Kp@model'].value) * u.W / (u.m**2.)
    model_mags_Kp = -2.5 * np.log10(model_fluxes_Kp / flux_ref_Kp) + 0.03

    ## H
    model_fluxes_H = np.array(
        b['fluxes@lc@mod_lc_H@model'].value) * u.W / (u.m**2.)
    model_mags_H = -2.5 * np.log10(model_fluxes_H / flux_ref_H) + 0.03

    if print_diagnostics:
        print('\nFlux Checks')
        print('Fluxes, Kp: {0}'.format(model_fluxes_Kp))
        print('Mags, Kp: {0}'.format(model_mags_Kp))
        print('Fluxes, H: {0}'.format(model_fluxes_H))
        print('Mags, H: {0}'.format(model_mags_H))

    if make_mesh_plots:
        return (model_mags_Kp, model_mags_H, mesh_plot_out)
    else:
        return (model_mags_Kp, model_mags_H)
Exemple #9
0
# Accessing/Changing MPI Settings
# --------------------

# To check the currently adopted settings, as well as quickly access information needed for manually doing your own parallelization, access the phoebe.mpi object.

# In[2]:

print(phoebe.mpi.enabled)

# In[3]:

print(phoebe.mpi.mode)

# In[4]:

phoebe.mpi_on()

# In[5]:

print(phoebe.mpi.enabled)

# In[6]:

print(phoebe.mpi.mode)

# In[7]:

print(phoebe.mpi.myrank)

# In[8]:
Exemple #10
0
def binary_star_lc(star1_params, star2_params, binary_params, observation_times,
        use_blackbody_atm=False,
        use_compact_object=False,
        make_mesh_plots=False, mesh_temp=False, mesh_temp_cmap=None,
        plot_name=None,
        print_diagnostics=False, par_compute=False, num_par_processes=8,
        num_triangles=1500):
    """Compute the light curve for a binary system
    
    Keyword arguments:
    star1_params -- Tuple of parameters for the primary star
    star2_params -- Tuple of parameters for the secondary star
    binary_params -- Tuple of parameters for the binary system configuration
    observation_times -- Tuple of observation times,
        with numpy array of MJDs in each band and for the RVs
        (kp_MJDs, h_MJDs, rv_MJDs) = observation_times
    use_blackbody_atm -- Use blackbody atmosphere
        instead of default Castelli & Kurucz (default False)
    use_compact_object -- Set eclipse_method to 'only_horizon',
            necessary for compact companions without eclipses (default False)
    make_mesh_plots -- Make a mesh plot of the binary system (default False)
    plot_name
    print_diagnostics
    par_compute
    num_par_processes
    """
    
    if par_compute:
        # TODO: Need to implement parallelization correctly
        phoebe.mpi_on(nprocs=num_par_processes)
    else:
        phoebe.mpi_off()
    
    # Read in the stellar parameters of the binary components
    (star1_mass, star1_rad, star1_teff, star1_logg,
     [star1_mag_Kp, star1_mag_H],
     [star1_pblum_Kp, star1_pblum_H]) = star1_params
    (star2_mass, star2_rad, star2_teff, star2_logg,
     [star2_mag_Kp, star2_mag_H],
     [star2_pblum_Kp, star2_pblum_H]) = star2_params
    
    # Read in the parameters of the binary system
    (binary_period, binary_ecc, binary_inc, t0) = binary_params
    
    err_out = (np.array([-1.]), np.array([-1.]),
               np.array([-1.]), np.array([-1.]))
    if make_mesh_plots:
        err_out = (np.array([-1.]), np.array([-1.]),
                   np.array([-1.]), np.array([-1.]),
                   np.array([-1.]))
    
    # Check for high temp ck2004 atmosphere limits
    if not use_blackbody_atm:
        # log g = 3.5, high temp bounds (above 31e3 K)
        if star1_teff > (31000 * u.K) and (4.0 > star1_logg > 3.5):
            star1_teff_round = 30995.0 * u.K
            
            if print_diagnostics:
                print('Star 1 out of C&K 2004 grid')
                print('star1_logg = {0:.4f}'.format(star1_logg))
                print('Rounding down star1_teff')
                print('{0:.4f} -> {1:.4f}'.format(star1_teff, star1_teff_round))
            
            star1_teff = star1_teff_round
        if star2_teff > (31000 * u.K) and (4.0 > star2_logg > 3.5):
            star2_teff_round = 30995.0 * u.K
            
            if print_diagnostics:
                print('Star 2 out of C&K 2004 grid')
                print('star2_logg = {0:.4f}'.format(star2_logg))
                print('Rounding down star2_teff')
                print('{0:.4f} -> {1:.4f}'.format(star2_teff, star2_teff_round))
            
            star2_teff = star2_teff_round
        
        # log g = 4.0, high temp bounds (above 40e3 K)
        if star1_teff > (40000 * u.K) and (4.5 > star1_logg > 4.0):
            star1_teff_round = 39995.0 * u.K
            
            print('Star 1 out of C&K 2004 grid')
            print('star1_logg = {0:.4f}'.format(star1_logg))
            print('Rounding down star1_teff')
            print('{0:.4f} -> {1:.4f}'.format(star1_teff, star1_teff_round))
            
            star1_teff = star1_teff_round
        if star2_teff > (40000 * u.K) and (4.0 > star2_logg > 3.50):
            star2_teff_round = 39995.0 * u.K
            
            print('Star 2 out of C&K 2004 grid')
            print('star2_logg = {0:.4f}'.format(star2_logg))
            print('Rounding down star2_teff')
            print('{0:.4f} -> {1:.4f}'.format(star2_teff, star2_teff_round))
            
            star2_teff = star2_teff_round
    
    # Set up binary model
    b = phoebe.default_binary()
    
    ## Set a default distance
    b.set_value('distance', 10 * u.pc)
    
    ## Set period, semimajor axis, and mass ratio (q)
    binary_sma = ((binary_period**2. * const.G * (star1_mass + star2_mass)) / (4. * np.pi**2.))**(1./3.)
    
    binary_q = star2_mass / star1_mass
    
    if print_diagnostics:
        print('\nBinary orbit checks')
        print('Binary SMA: {0}'.format(binary_sma.to(u.AU)))
        print('Binary Mass Ratio (q): {0}'.format(binary_q))
    
    b.set_value('period@orbit', binary_period)
    b.set_value('sma@binary@component', binary_sma)
    b.set_value('q@binary@component', binary_q)
    
    ## Inclination
    b.set_value('incl@orbit', binary_inc)
    
    # Check for overflow
    ## Variables to help store the non-detached binary cases
    star1_semidetached = False
    star2_semidetached = False
    
    star1_overflow = False
    star2_overflow = False
    
    ## Get the max radii for both component stars
    star1_rad_max = b.get_value('requiv_max@primary@component') * u.solRad
    star2_rad_max = b.get_value('requiv_max@secondary@component') * u.solRad
    
    ## Check for semidetached cases
    if print_diagnostics:
        print('\nSemidetached checks')
        print('Star 1: {0}'.format(np.abs((star1_rad - star1_rad_max) / star1_rad_max)))
        print('Star 2: {0}'.format(np.abs((star2_rad - star2_rad_max) / star2_rad_max)))
    
    semidet_cut = 0.001   # (within 0.1% of max radii)
    semidet_cut = 0.015   # (within 1.5% of max radii)
    
    if np.abs((star1_rad - star1_rad_max) / star1_rad_max) < semidet_cut:
        star1_semidetached = True
    if np.abs((star2_rad - star2_rad_max) / star2_rad_max) < semidet_cut:
        star2_semidetached = True
    
    ## Check for overflow
    if (star1_rad > star1_rad_max) and not star1_semidetached:
        star1_overflow = True
    
    if (star2_rad > star2_rad_max) and not star2_semidetached:
        star2_overflow = True
    
    
    
    ### Check for if both stars are overflowing; which star overflows more?
    ### Choose that star to be overflowing more
    if star1_overflow and star2_overflow:
        if (star1_rad - star1_rad_max) >= (star2_rad - star2_rad_max):
            star2_overflow = False
        else:
            star1_overflow = False
    
    
    if print_diagnostics:
        print('\nOverflow Checks')
        print('Star 1 Semidetached: {0}'.format(star1_semidetached))
        print('Star 2 Semidetached: {0}'.format(star2_semidetached))
        print('Star 1 Overflow: {0}'.format(star1_overflow))
        print('Star 2 Overflow: {0}'.format(star2_overflow))
    
    # If star 2 is overflowing, have to re set up model:
    # Calling this same binary_star_lc function again,
    # with star 2 as primary and star 1 as secondary.
    # Change t0 = t0 - per/2 to make sure phase is correct,
    # wrt stars 1 and 2 being in same respective position
    if star2_overflow and not star1_overflow:
        redo_binary_params = (binary_period, binary_ecc, binary_inc,
                              t0 - (binary_period.to(u.d).value/2.))
        
        return binary_star_lc(star2_params, star1_params,
                    redo_binary_params,
                    observation_times,
                    use_blackbody_atm=use_blackbody_atm,
                    make_mesh_plots=make_mesh_plots,
                    mesh_temp=mesh_temp, mesh_temp_cmap=mesh_temp_cmap,
                    plot_name=plot_name,
                    print_diagnostics=print_diagnostics,
                    par_compute=par_compute, num_par_processes=num_par_processes,
                    num_triangles=num_triangles)
    
    ## If none of these overflow cases, set variable to store if binary is detached
    binary_detached = (not star1_semidetached) and \
                      (not star2_semidetached) and \
                      (not star1_overflow) and \
                      (not star2_overflow)
    
    ### Set non-zero eccentricity only if binary is detached
    if binary_detached:
        b.set_value('ecc@binary@component', binary_ecc)
    else:
        b.set_value('ecc@binary@component', 0.)
    
    ## Change set up for contact or semidetached cases
    if star1_overflow or star2_overflow:
        b = phoebe.default_binary(contact_binary=True)
        
        ### Reset all necessary binary properties for contact system
        b.set_value('distance', 10 * u.pc)
        
        b.set_value('period@orbit', binary_period)
        b.set_value('sma@binary@component', binary_sma)
        b.set_value('q@binary@component', binary_q)
        b.set_value('incl@orbit', binary_inc)
    
    if star1_semidetached and not star2_overflow:
        b.add_constraint('semidetached', 'primary')
    if star2_semidetached and not star1_overflow:
        b.add_constraint('semidetached', 'secondary')
    
    # Set up compute
    if use_blackbody_atm:
        b.add_compute('phoebe', compute='detailed',
                      irrad_method='wilson', atm='blackbody')
        
        b.set_value('atm@primary@detailed', 'blackbody')
        b.set_value('atm@secondary@detailed', 'blackbody')
    else:
        b.add_compute('phoebe', compute='detailed', irrad_method='wilson')
    
    # Set the parameters of the component stars of the system
    ## Primary
    b.set_value('teff@primary@component', star1_teff)
    # b.set_value('logg@primary@component', star1_logg)
    if (not star1_semidetached) and (not star2_overflow):
        b.set_value('requiv@primary@component', star1_rad)
    
    ## Secondary
    b.set_value('teff@secondary@component', star2_teff)
    # b.set_value('logg@secondary@component', star2_logg)
    if (not star2_semidetached) and (not star1_overflow) and (not star2_overflow):
        try:
            b.set_value('requiv@secondary@component', star2_rad)
        except:
            print('\nOverflow Checks')
            print('Star 1 Semidetached: {0}'.format(star1_semidetached))
            print('Star 2 Semidetached: {0}'.format(star2_semidetached))
            print('Star 1 Overflow: {0}'.format(star1_overflow))
            print('Star 2 Overflow: {0}'.format(star2_overflow))
            
            print("Cannot set secondary radius: {0}".format(sys.exc_info()[0]))
            
            return err_out
    
    
    # Set the number of triangles in the mesh
    # Detached stars
    if len(b.filter('ntriangles@primary@detailed@compute')) == 1: 
        b.set_value('ntriangles@primary@detailed@compute', num_triangles)
        
    if len(b.filter('ntriangles@secondary@detailed@compute')) == 1: 
        b.set_value('ntriangles@secondary@detailed@compute', num_triangles)
    
    # Contact envelope
    if len(b.filter('ntriangles@contact_envelope@detailed@compute')) == 1:
       if print_diagnostics:
           print('Setting number of triangles for contact envelope')
       b.set_value('ntriangles@contact_envelope@detailed@compute',
                   num_triangles * 2.)
    
    # Phase the observation times
    ## Read in observation times
    (kp_MJDs, h_MJDs, rv_MJDs) = observation_times
    
    ## Phase the observation times
    kp_phased_days = ((kp_MJDs - t0) % binary_period.to(u.d).value) / binary_period.to(u.d).value
    h_phased_days = ((h_MJDs - t0) % binary_period.to(u.d).value) / binary_period.to(u.d).value
    rv_phased_days = ((rv_MJDs - t0) % binary_period.to(u.d).value) / binary_period.to(u.d).value
    
    # Add light curve datasets
    if use_blackbody_atm:
        b.set_value_all('ld_mode_bol', 'manual')
        b.set_value_all('ld_func_bol', 'linear')
        b.set_value_all('ld_coeffs_bol', [0.0])
    
    # Check for compact companion
    if use_compact_object:
        b.set_value('irrad_method@detailed', 'none')
    
    ## Kp
    kp_phases_sorted_inds = np.argsort(kp_phased_days)
    
    kp_model_times = (kp_phased_days) * binary_period.to(u.d).value
    kp_model_times = kp_model_times[kp_phases_sorted_inds]
    
    if use_blackbody_atm:
        b.add_dataset(phoebe.dataset.lc, time=kp_model_times,
                      dataset='mod_lc_Kp', passband='Keck_NIRC2:Kp')
        
        b.set_value_all('ld_mode@mod_lc_Kp', 'manual')
        
        b.set_value_all('ld_func@mod_lc_Kp', 'linear')
        
        b.set_value_all('ld_coeffs@mod_lc_Kp', [0.0])
    else:
        b.add_dataset(phoebe.dataset.lc, time=kp_model_times,
                      dataset='mod_lc_Kp', passband='Keck_NIRC2:Kp')
    
    ## H
    h_phases_sorted_inds = np.argsort(h_phased_days)
    
    h_model_times = (h_phased_days) * binary_period.to(u.d).value
    h_model_times = h_model_times[h_phases_sorted_inds]
    
    if use_blackbody_atm:
        b.add_dataset(phoebe.dataset.lc, times=h_model_times,
                      dataset='mod_lc_H', passband='Keck_NIRC2:H')
        
        b.set_value_all('ld_mode@mod_lc_H', 'manual')
        
        b.set_value_all('ld_func@mod_lc_H', 'linear')
        
        b.set_value_all('ld_coeffs@mod_lc_H', [0.0])
    else:
        b.add_dataset(phoebe.dataset.lc, times=h_model_times,
                      dataset='mod_lc_H', passband='Keck_NIRC2:H')
    
    ## RV
    rv_phases_sorted_inds = np.argsort(rv_phased_days)
    
    rv_model_times = (rv_phased_days) * binary_period.to(u.d).value
    rv_model_times = rv_model_times[rv_phases_sorted_inds]
    
    if use_blackbody_atm:
        b.add_dataset(phoebe.dataset.rv, time=rv_model_times,
                      dataset='mod_rv', passband='Keck_NIRC2:Kp')
        
        b.set_value_all('ld_mode@mod_rv', 'manual')
        
        b.set_value_all('ld_func@mod_rv', 'linear')
        
        b.set_value_all('ld_coeffs@mod_rv', [0.0])
    else:
        b.add_dataset(phoebe.dataset.rv, time=rv_model_times,
                      dataset='mod_rv', passband='Keck_NIRC2:Kp')
    
    
    # Add mesh dataset if making mesh plot
    if make_mesh_plots:
        b.add_dataset('mesh', times=[(binary_period/4.).to(u.d).value],
                      dataset='mod_mesh')
        if mesh_temp:
            b['columns@mesh'] = ['teffs', 'loggs', 'areas',
                                 '*@mod_lc_Kp', '*@mod_lc_H']
    
    # Set the passband luminosities for the stars
    b.set_value('pblum_mode@mod_lc_Kp', 'decoupled')
    b.set_value('pblum_mode@mod_lc_H', 'decoupled')
    
    b.set_value('pblum@primary@mod_lc_Kp', star1_pblum_Kp)
    b.set_value('pblum@primary@mod_lc_H', star1_pblum_H)
    
    b.set_value('pblum@secondary@mod_lc_Kp', star2_pblum_Kp)
    b.set_value('pblum@secondary@mod_lc_H', star2_pblum_H)
    
    # Run compute
    # Determine eclipse method
    if use_compact_object:
        eclipse_method = 'only_horizon'
    else:
        eclipse_method = 'native'
    
    if print_diagnostics:
        print("Trying inital compute run")
        b.run_compute(compute='detailed', model='run',
                      progressbar=False, eclipse_method=eclipse_method)
    else:
        try:
            b.run_compute(compute='detailed', model='run',
                          progressbar=False, eclipse_method=eclipse_method)
        except:
            if print_diagnostics:
                print("Error during primary binary compute: {0}".format(sys.exc_info()[0]))
            return err_out
    
    
    # Save out mesh plot
    if make_mesh_plots:
        ## Plot Nerdery
        plt.rc('font', family='serif')
        plt.rc('font', serif='Computer Modern Roman')
        plt.rc('text', usetex=True)
        plt.rc('text.latex', preamble=r"\usepackage{gensymb}")

        plt.rc('xtick', direction = 'in')
        plt.rc('ytick', direction = 'in')
        # plt.rc('xtick', top = True)
        # plt.rc('ytick', right = True)
        
        suffix_str = ''
        if plot_name is not None:
            suffix_str = '_' + plot_name
        
        ## Mesh plot
        if mesh_temp:
            mesh_plot_out = b['mod_mesh@model'].plot(save='./binary_mesh{0}.pdf'.format(suffix_str),
                                                     fc='teffs',
                                                     fcmap=mesh_temp_cmap,
                                                     ec='none')
                                                     
            # print(mesh_plot_out.axs)
            
            # Extract and output mesh quantities
            mesh_quant_names = ['teffs', 'loggs', 'areas', 'abs_intensities']
            mesh_quant_do_filt = [False, False, False, True]
            mesh_quant_units = [u.K, 1.0, u.solRad**2, u.W / (u.m**3)]
            
            mesh_quant_filts = ['mod_lc_Kp', 'mod_lc_H']            
            mesh_quants_pri = {}
            mesh_quants_sec = {}
            
            for (quant, do_filt,
                 quant_unit) in zip(mesh_quant_names, mesh_quant_do_filt,
                                    mesh_quant_units):
                if do_filt:
                    for filt in mesh_quant_filts:
                        quant_pri = b['{0}@primary@{1}'.format(quant, filt)].value *\
                                    quant_unit
                        quant_sec = b['{0}@secondary@{1}'.format(quant, filt)].value *\
                                    quant_unit
                    
                        mesh_quants_pri['{0}_{1}'.format(quant, filt)] = quant_pri
                        mesh_quants_sec['{0}_{1}'.format(quant, filt)] = quant_sec
                else:
                    quant_pri = b['{0}@primary'.format(quant)].value * quant_unit
                    quant_sec = b['{0}@secondary'.format(quant)].value * quant_unit
                    
                    mesh_quants_pri[quant] = quant_pri
                    mesh_quants_sec[quant] = quant_sec
            
            # Construct mesh tables for each star and output
            mesh_pri_table = Table(mesh_quants_pri)
            mesh_pri_table.sort(['teffs'], reverse=True)
            with open('mesh_pri.txt', 'w') as out_file:
                for line in mesh_pri_table.pformat_all():
                    out_file.write(line + '\n')
            mesh_pri_table.write('mesh_pri.h5', format='hdf5',
                                 path='data', serialize_meta=True,
                                 overwrite=True)
            mesh_pri_table.write('mesh_pri.fits', format='fits',
                                 overwrite=True)
            
            mesh_sec_table = Table(mesh_quants_sec)
            mesh_sec_table.sort(['teffs'], reverse=True)
            with open('mesh_sec.txt', 'w') as out_file:
                for line in mesh_sec_table.pformat_all():
                    out_file.write(line + '\n')
            mesh_sec_table.write('mesh_sec.h5', format='hdf5',
                                 path='data', serialize_meta=True,
                                 overwrite=True)
            mesh_sec_table.write('mesh_sec.fits', format='fits',
                                 overwrite=True)
        else:
            mesh_plot_out = b['mod_mesh@model'].plot(save='./binary_mesh{0}.pdf'.format(suffix_str))
    
    
    # Get fluxes
    ## Kp
    model_fluxes_Kp = np.array(b['fluxes@lc@mod_lc_Kp@model'].value) * u.W / (u.m**2.)
    model_mags_Kp = -2.5 * np.log10(model_fluxes_Kp / flux_ref_Kp) + 0.03
    
    ## H
    model_fluxes_H = np.array(b['fluxes@lc@mod_lc_H@model'].value) * u.W / (u.m**2.)
    model_mags_H = -2.5 * np.log10(model_fluxes_H / flux_ref_H) + 0.03
    
    # Get RVs
    model_RVs_pri = np.array(b['rvs@primary@run@rv@model'].value) * u.km / u.s
    model_RVs_sec = np.array(b['rvs@secondary@run@rv@model'].value) * u.km / u.s
    
    
    if print_diagnostics:
        print("\nFlux Checks")
        print("Fluxes, Kp: {0}".format(model_fluxes_Kp))
        print("Mags, Kp: {0}".format(model_mags_Kp))
        print("Fluxes, H: {0}".format(model_fluxes_H))
        print("Mags, H: {0}".format(model_mags_H))
        
        print("\nRV Checks")
        print("RVs, Primary: {0}".format(model_RVs_pri))
        print("RVs, Secondary: {0}".format(model_RVs_sec))
        
    if make_mesh_plots:
        return (model_mags_Kp, model_mags_H,
                model_RVs_pri, model_RVs_sec,
                mesh_plot_out)
    else:
        return (model_mags_Kp, model_mags_H,
                model_RVs_pri, model_RVs_sec)
def binary_star_lc(star1_params,
                   star2_params,
                   binary_params,
                   observation_times,
                   use_blackbody_atm=False,
                   make_mesh_plots=False,
                   plot_name=None,
                   print_diagnostics=False,
                   par_compute=False,
                   num_par_processes=8,
                   num_triangles=1500):
    """Compute the light curve for a binary system
    
    Keyword arguments:
    star1_params -- Tuple of parameters for the primary star
    star2_params -- Tuple of parameters for the secondary star
    binary_params -- Tuple of parameters for the binary system configuration
    observation_times -- Tuple of observation times,
        with numpy array of MJDs in each band
        (kp_MJDs, h_MJDs) = observation_times
    use_blackbody_atm -- Use blackbody atmosphere
        instead of default Castelli & Kurucz (default False)
    make_mesh_plots -- Make a mesh plot of the binary system (default False)
    plot_name
    print_diagnostics
    par_compute
    num_par_processes
    """

    if par_compute:
        # TODO: Need to implement parallelization correctly
        phoebe.mpi_on(nprocs=num_par_processes)
    else:
        phoebe.mpi_off()

    # Read in the stellar parameters of the binary components
    (star1_mass, star1_rad, star1_teff, star1_mag_Kp,
     star1_mag_H) = star1_params
    (star2_mass, star2_rad, star2_teff, star2_mag_Kp,
     star2_mag_H) = star2_params

    # Read in the parameters of the binary system
    (binary_period, binary_ecc, binary_inc, t0) = binary_params

    err_out = (np.array([-1.]), np.array([-1.]))

    # Set up binary model
    b = phoebe.default_binary()

    ## Set period, semimajor axis, and mass ratio (q)
    binary_sma = ((binary_period**2. * const.G * (star1_mass + star2_mass)) /
                  (4. * np.pi**2.))**(1. / 3.)

    binary_q = star2_mass / star1_mass

    b.set_value('period@orbit', binary_period)
    b.set_value('sma@binary@component', binary_sma)
    b.set_value('q@binary@component', binary_q)

    ## Inclination
    b.set_value('incl@orbit', binary_inc)

    # Check for overflow
    ## Variables to help store the non-detached binary cases
    star1_semidetached = False
    star2_semidetached = False

    star1_overflow = False
    star2_overflow = False

    ## Get the max radii for both component stars
    star1_rad_max = b.get_value('requiv_max@primary@component') * u.solRad
    star2_rad_max = b.get_value('requiv_max@secondary@component') * u.solRad

    ## Check for semidetached cases
    if print_diagnostics:
        print('\nSemidetached checks')
        print(np.abs((star1_rad - star1_rad_max) / star1_rad_max))
        print(np.abs((star2_rad - star2_rad_max) / star2_rad_max))

    semidet_cut = 0.001  # (within 0.1% of max radii)
    semidet_cut = 0.015  # (within 1.5% of max radii)

    if np.abs((star1_rad - star1_rad_max) / star1_rad_max) < semidet_cut:
        star1_semidetached = True
    if np.abs((star2_rad - star2_rad_max) / star2_rad_max) < semidet_cut:
        star2_semidetached = True

    ## Check for overflow
    if (star1_rad > star1_rad_max) and not star1_semidetached:
        star1_overflow = True

    if (star2_rad > star2_rad_max) and not star2_semidetached:
        star2_overflow = True

    ### Check for if both stars are overflowing; which star overflows more?
    ### Choose that star to be overflowing more
    if star1_overflow and star2_overflow:
        if (star1_rad - star1_rad_max) >= (star2_rad - star2_rad_max):
            star2_overflow = False
        else:
            star1_overflow = False

    if print_diagnostics:
        print('\nOverflow Checks')
        print(star1_semidetached)
        print(star2_semidetached)
        print(star1_overflow)
        print(star2_overflow)

    ## If none of these overflow cases, set variable to store if binary is detached
    binary_detached = (not star1_semidetached) and (
        not star2_semidetached) and (not star1_overflow) and (
            not star2_overflow)

    ### Set non-zero eccentricity only if binary is detached
    if binary_detached:
        b.set_value('ecc@binary@component', binary_ecc)
    else:
        b.set_value('ecc@binary@component', 0.)

    ## Change set up for contact or semidetached cases
    if star1_overflow or star2_overflow:
        b = phoebe.default_binary(contact_binary=True)

        b.set_value('period@orbit', binary_period)
        b.set_value('sma@binary@component', binary_sma)
        b.set_value('q@binary@component', binary_q)
        b.set_value('incl@orbit', binary_inc)

    if star1_semidetached and not star2_overflow:
        b.add_constraint('semidetached', 'primary')
    if star2_semidetached and not star1_overflow:
        b.add_constraint('semidetached', 'secondary')

    # Set up compute
    if use_blackbody_atm:
        b.add_compute('phoebe',
                      compute='detailed',
                      irrad_method='wilson',
                      atm='blackbody')
    else:
        b.add_compute('phoebe', compute='detailed', irrad_method='wilson')

    # Set the parameters of the component stars of the system
    ## Primary
    b.set_value('teff@primary@component', star1_teff)
    if (not star1_semidetached) and (not star2_overflow):
        b.set_value('requiv@primary@component', star1_rad)

    ## Secondary
    b.set_value('teff@secondary@component', star2_teff)
    if (not star2_semidetached) and (not star1_overflow):
        b.set_value('requiv@secondary@component', star2_rad)

    # Set the number of triangles in the mesh
    b.set_value('ntriangles@primary@detailed@compute', num_triangles)
    b.set_value('ntriangles@secondary@detailed@compute', num_triangles)

    # Phase the observation times
    ## Read in observation times
    (kp_MJDs, h_MJDs) = observation_times

    ## Phase the observation times
    kp_phased_days = (
        (kp_MJDs - t0) % binary_period.to(u.d).value) / binary_period.to(
            u.d).value
    h_phased_days = ((h_MJDs - t0) %
                     binary_period.to(u.d).value) / binary_period.to(u.d).value

    # Add light curve datasets
    ## Kp
    kp_phases_sorted_inds = np.argsort(kp_phased_days)

    kp_model_times = (kp_phased_days) * binary_period.to(u.d).value
    kp_model_times = kp_model_times[kp_phases_sorted_inds]

    if use_blackbody_atm:
        b.add_dataset(phoebe.dataset.lc,
                      time=kp_model_times,
                      dataset='mod_lc_Kp',
                      passband='Keck_NIRC2:Kp',
                      ld_func='linear',
                      ld_coeffs=[0.0])
    else:
        b.add_dataset(phoebe.dataset.lc,
                      time=kp_model_times,
                      dataset='mod_lc_Kp',
                      passband='Keck_NIRC2:Kp')

    ## H
    h_phases_sorted_inds = np.argsort(h_phased_days)

    h_model_times = (h_phased_days) * binary_period.to(u.d).value
    h_model_times = h_model_times[h_phases_sorted_inds]

    if use_blackbody_atm:
        b.add_dataset(phoebe.dataset.lc,
                      times=h_model_times,
                      dataset='mod_lc_H',
                      passband='Keck_NIRC2:H',
                      ld_func='linear',
                      ld_coeffs=[0.0])
    else:
        b.add_dataset(phoebe.dataset.lc,
                      times=h_model_times,
                      dataset='mod_lc_H',
                      passband='Keck_NIRC2:H')

    # Add mesh dataset if making mesh plot
    if make_mesh_plots:
        b.add_dataset('mesh', times=[binary_period / 4.], dataset='mod_mesh')

    # Run compute
    # b.run_compute(compute='detailed', model='run')
    try:
        b.run_compute(compute='detailed', model='run')
    except:
        if print_diagnostics:
            print("Error during primary binary compute: {0}".format(
                sys.exc_info()[0]))
        return err_out

    # Save out mesh plot
    if make_mesh_plots:
        ## Plot Nerdery
        plt.rc('font', family='serif')
        plt.rc('font', serif='Computer Modern Roman')
        plt.rc('text', usetex=True)
        plt.rc('text.latex', preamble=r"\usepackage{gensymb}")

        plt.rc('xtick', direction='in')
        plt.rc('ytick', direction='in')
        plt.rc('xtick', top=True)
        plt.rc('ytick', right=True)

        suffix_str = ''
        if plot_name is not None:
            suffix_str = '_' + plot_name

        ## Mesh plot
        b['mod_mesh@model'].plot(
            save='./binary_mesh{0}.pdf'.format(suffix_str))

    # Get fluxes
    ## Kp
    model_fluxes_Kp = np.array(
        b['fluxes@lc@mod_lc_Kp@model'].value) * u.solLum / (
            4 * np.pi * u.m**2)  # * u.W / (u.m**2.)
    model_mags_Kp = -2.5 * np.log10(model_fluxes_Kp / flux_ref_Kp) + 0.03

    ## H
    model_fluxes_H = np.array(
        b['fluxes@lc@mod_lc_H@model'].value) * u.solLum / (
            4 * np.pi * u.m**2)  # * u.W / (u.m**2.)
    model_mags_H = -2.5 * np.log10(model_fluxes_H / flux_ref_H) + 0.03

    return (model_mags_Kp, model_mags_H)
Exemple #12
0
#% setup  general parameters
#logg_sun=4.43812
KeplerOffset = 2454833.0  # times relative to this offset will be prefixed by k

# number of threads to run simple fit
# if n_threads == 0 run simple fit without threading
n_threads = 0

machine = os.uname()[1]
#machine = '*****@*****.**'
if machine == 'user-Latitude-E5570':
    rootpath = r'/home/user/Dropbox/KBEER_phoebe_ipynb/'
    sys.path.append('/home/user/Dropbox/spyder/')  # path for pyBEER
    location = 'dell'
    if n_threads == 0:
        phoebe.mpi_on(nprocs=4)  #

elif machine == 'eshel-blue':
    rootpath = r'/home/eshel-blue/micha/dropboxClone/'
    sys.path.append(
        '/home/eshel-blue/micha/dropboxClone/spyder')  # path for pyBEER
    location = 'blue'
    if n_threads == 0:
        phoebe.mpi_on(nprocs=6)  #

elif machine == '*****@*****.**':
    rootpath = r'/storage/home/engelmic/KBEER/'
    sys.path.append('/storage/home/engelmic/scripts')  # path for pyBEER
    location = 'astro'

else: