Beispiel #1
0
def callTransit(atmfile, tepfile, MCfile, stepsize, molfit, tconfig, date_dir):

    # read atmfile
    molecules, pressure, temp, abundances = mat.readatm(atmfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # get star data
    R_star, T_star, sma = get_starData(tepfile)

    # get best parameters
    bestP, uncer, SN, mean = read_MCMC_out(MCfile)

    # get all params
    params = get_params(bestP, stepsize)

    # get PTparams and abundances factors
    nparams = len(params)
    nmol = len(molfit)
    nPTparams = nparams - nmol
    PTparams  = params[:nPTparams]
    AbunFact  = params[nPTparams:]

    # HARDCODED !!!!!!!!!!!!
    T_int = 100 # K

    # call PT line profile to calculate temperature
    T_line = pt.PT_line(pressure, PTparams, R_star, T_star, T_int, sma, grav)

    # write best-fit atmospheric file
    write_atmfile(atmfile, molfit, T_line, params, date_dir)

    # bestFit atm file
    bestFit_atm = date_dir + 'bestFit.atm'

    # write new bestFit Transit config
    bestFit_tconfig(tconfig, date_dir)
def plot_bestFit_Spectrum(spec, clr, specs, atmfile, filters, kurucz, tepfile,
                          outflux, data, uncert, direct):
    '''
    Plot Transit spectrum
    '''
    # get star data
    R_star, T_star, sma, gstar = bf.get_starData(tepfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # convert Rp to m
    Rp = Rp * 1000

    # ratio planet to star
    rprs = Rp / R_star

    # read kurucz file
    starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, T_star, gstar)

    # read best-fit spectrum output file, take wn and spectra values
    (head, tail) = os.path.split(outflux)
    specwn, bestspectrum = rt.readspectrum(direct + '/' + tail, wn=True)

    # convert wn to wl
    specwl = 1e4 / specwn

    # number of filters
    nfilters = len(filters)

    # read and resample the filters:
    nifilter = []  # Normalized interpolated filter
    istarfl = []  # interpolated stellar flux
    wnindices = []  # wavenumber indices used in interpolation
    meanwn = []  # Filter mean wavenumber
    for i in np.arange(nfilters):
        # read filter:
        filtwaven, filttransm = w.readfilter(filters[i])
        meanwn.append(np.sum(filtwaven * filttransm) / sum(filttransm))
        # resample filter and stellar spectrum:
        nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                          starwn, starfl)
        nifilter.append(nifilt)
        istarfl.append(strfl)
        wnindices.append(wnind)

    # convert mean wn to mean wl
    meanwl = 1e4 / np.asarray(meanwn)

    # band-integrate the flux-ratio or modulation:
    bandflux = np.zeros(nfilters, dtype='d')
    bandmod = np.zeros(nfilters, dtype='d')
    for i in np.arange(nfilters):
        fluxrat = (bestspectrum[wnindices[i]] / istarfl[i]) * rprs * rprs
        bandflux[i] = w.bandintegrate(fluxrat, specwn, nifilter[i],
                                      wnindices[i])
        bandmod[i] = w.bandintegrate(bestspectrum[wnindices[i]], specwn,
                                     nifilter[i], wnindices[i])

    # stellar spectrum on specwn:
    sinterp = si.interp1d(starwn, starfl)
    sflux = sinterp(specwn)
    frat = bestspectrum / sflux * rprs * rprs

    ###################### plot figure #############################

    plt.rcParams["mathtext.default"] = 'rm'
    matplotlib.rcParams.update({'mathtext.default': 'rm'})
    #matplotlib.rcParams.update({'fontsize': 10,})
    matplotlib.rcParams.update({
        'axes.labelsize': 16,
        #'text.fontsize':   10,
        'legend.fontsize': 14,
        'xtick.labelsize': 20,
        'ytick.labelsize': 20,
    })

    plt.figure(2, (8.5, 5))
    plt.clf()
    #plt.xlim(0.60, 5.5)

    #plt.xlim(min(specwl),max(specwl))

    # plot eclipse spectrum
    #gfrat = gaussf(frat, 0)
    plt.semilogx(specwl,
                 frat * 1e3,
                 clr,
                 lw=1.5,
                 label="Spectrum",
                 linewidth=4)
    #cornflowerblue, lightskyblue
    #plt.errorbar(meanwl, data*1e3, uncert*1e3, fmt="ko", label="Data", alpha=0.7)
    plt.errorbar(meanwl,
                 data * 1e3,
                 uncert * 1e3,
                 fmt=".",
                 color='k',
                 zorder=100,
                 capsize=2,
                 capthick=1,
                 label="Data",
                 alpha=0.7)
    #plt.plot(meanwl, bandflux*1e3, "ko", label="model")
    plt.ylabel(r"$F_p/F_s$ (10$^{-3}$)", fontsize=24)

    leg = plt.legend(loc="upper left")
    #leg.draw_frame(False)
    leg.get_frame().set_alpha(0.5)

    ax = plt.subplot(111)
    ax.set_xscale('log')

    ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
    ax.set_xticks([0.7, 0.8, 0.9, 1.0, 2.0, 3.0, 4.0, 5.0])
    ax.set_xticklabels(["0.7", "", "", "1.0", "2.0", "3.0", "4.0", "5.0"])

    plt.xlabel(r"${\rm Wavelength\ \ (um)}$", fontsize=24)

    nfilters = len(filters)
    # plot filter bandpasses
    for i in np.arange(nfilters - 15):
        (head, tail) = os.path.split(filters[i])
        lbl = tail[:-4]
        # read filter:
        wn, respons = w.readfilter(filters[i])
        respons = respons / 3 - 0.4
        wl = 10000.0 / wn
        #plt.plot(wl, respons, color='crimson', linewidth =1)
        if lbl == 'spitzer_irac1_sa' or lbl == 'spitzer_irac2_sa':
            respons = respons * 2 + 0.4
            plt.plot(wl, respons, color='grey', linewidth=1, alpha=0.5)
            #plt.plot(wl, respons*2, color='orangered', linewidth =1)
        elif lbl == 'Wang-Hband' or lbl == 'Wang-Kband':
            plt.plot(wl, respons, 'grey', linewidth=1, alpha=0.5)
        elif lbl == 'VLT_1190' or lbl == 'VLT_2090':
            plt.plot(wl, respons, color='grey', linewidth=2, alpha=0.5)
            #plt.plot(wl, respons, color='firebrick', linewidth =2)
        elif lbl == 'GROND_K_JB' or lbl == 'GROND_i_JB':
            plt.plot(wl, respons, 'grey', linewidth=1, alpha=0.5)
        elif lbl == 'Zhou_Ks':
            plt.plot(wl, respons, 'grey', linewidth=1, alpha=0.5)

    plt.ylim(-0.4, 7)

    plt.text(1.9, 3, specs, color=clr, fontsize=26)

    ###################### INSET PT and ABUN FIGURE ####################
    b = plt.axes([.21, .45, .14, .24])

    # read atmfile
    molecules, pres, temp, abundances = mat.readatm(atmfile)

    plt.semilogy(temp, pres, color='r', linewidth=3)
    plt.xlim(1000, 2200)
    plt.ylim(max(pres), min(pres))
    b.minorticks_off()
    yticks = [1e2, 1e1, 1, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5]
    ylabels = [
        "10$^{2}$", "", "10$^{0}$", "", "10$^{-2}$", "", "10$^{-4}$", ""
    ]
    plt.yticks(yticks, ylabels, fontsize=8)
    xticks = [1000, 1200, 1400, 1600, 1800, 2000, 2200]
    xlabels = ["", "1200", "", "", "1800", ""]
    plt.xticks(xticks, xlabels, fontsize=12)
    plt.xlabel('T (K)', fontsize=12)
    plt.ylabel('P (bar)', fontsize=12)

    # ############################## SECOND INSET ABUN
    c = plt.axes([.35, .45, .14, .24])

    # Sets the second argument given as the species names
    species = spec

    # Open the atmospheric file and read
    f = open(atmfile, 'r')
    lines = np.asarray(f.readlines())
    f.close()

    # Get molecules names
    imol = np.where(lines == "#SPECIES\n")[0][0] + 1
    molecules = lines[imol].split()
    nmol = len(molecules)
    for m in np.arange(nmol):
        molecules[m] = molecules[m].partition('_')[0]

    nspec = 1

    # Populate column numbers for requested species and
    #          update list of species if order is not appropriate
    columns = []
    spec = []
    for i in np.arange(nmol):
        if molecules[i] == species:
            columns.append(i + 3)  # defines p, T +2 or rad, p, T +3
            spec.append(species)

    # Convert spec to tuple
    spec = tuple(spec)

    # Concatenate spec with pressure for data and columns
    data = tuple(np.concatenate((['p'], spec)))
    usecols = tuple(np.concatenate(
        ([1], columns)))  # defines p as 0 columns, or p as 1 columns

    # Load all data for all interested species
    data = np.loadtxt(atmfile, dtype=float, comments='#', delimiter=None,    \
                converters=None, skiprows=13, usecols=usecols, unpack=True)

    plt.loglog(data[1], data[0], '-', color=clr, \
                                    linewidth=3)

    plt.ylim(max(pres), min(pres))
    c.minorticks_off()
    yticks = [1e2, 1e1, 1, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5]
    ylabels = []
    plt.yticks(yticks, ylabels)
    plt.xlim(1e-12, 1e-2)
    xticks = [1e-11, 1e-9, 1e-7, 1e-5, 1e-3]
    xlabels = ["10$^{-11}$", "", "10$^{-5}$", "", "10$^{-3}$"]
    plt.xticks(xticks, xlabels, fontsize=12)
    plt.xlabel('Mix. fraction', fontsize=12)

    plt.subplots_adjust(bottom=0.16)

    spec = spec[0]
    print(spec)

    plt.savefig(spec + "_transSpec_new.png")
    plt.savefig(spec + "_transSpec_new.ps")
def plot_bestFit_Spectrum(filters,
                          kurucz,
                          tepfile,
                          solution,
                          output,
                          data,
                          uncert,
                          date_dir,
                          fs=15):
    '''
    Plot BART best-model spectrum

    Parameters
    ----------
    filters : list, strings. Paths to filter files corresponding to data.
    kurucz  : string. Path to Kurucz stellar model file.
    tepfile : string. Path to Transiting ExoPlanet (TEP) file.
    solution: string. Observing geometry. 'eclipse' or 'transit'.
    output  : string. Best-fit spectrum output file name.
    data    : 1D array. Eclipse or transit depths.
    uncert  : 1D array. Uncertainties for data values.
    date_dir: string. Path to directory where the plot will be saved.
    fs      : int.    Font size for plots.
    '''
    # get star data
    R_star, T_star, sma, gstar = get_starData(tepfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # convert Rp to m
    Rp = Rp * 1000

    # ratio planet to star
    rprs = Rp / R_star

    # read kurucz file
    starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, T_star, gstar)

    # read best-fit spectrum output file, take wn and spectra values
    if solution == 'eclipse':
        specwn, bestspectrum = rt.readspectrum(date_dir + output, wn=True)
        # print on screen
        print("  Plotting BART best-fit eclipse spectrum figure.")
    elif solution == 'transit':
        specwn, bestspectrum = rt.readspectrum(date_dir + output, wn=True)
        # print on screen
        print("  Plotting BART best-fit modulation spectrum figure.")

    # convert wn to wl
    specwl = 1e4 / specwn

    # number of filters
    nfilters = len(filters)

    # read and resample the filters:
    nifilter = []  # Normalized interpolated filter
    istarfl = []  # interpolated stellar flux
    wnindices = []  # wavenumber indices used in interpolation
    meanwn = []  # Filter mean wavenumber
    for i in np.arange(nfilters):
        # read filter:
        filtwaven, filttransm = w.readfilter(filters[i])
        meanwn.append(np.sum(filtwaven * filttransm) / sum(filttransm))
        # resample filter and stellar spectrum:
        nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                          starwn, starfl)
        nifilter.append(nifilt)
        istarfl.append(strfl)
        wnindices.append(wnind)

    # convert mean wn to mean wl
    meanwl = 1e4 / np.asarray(meanwn)

    # band-integrate the flux-ratio or modulation:
    bandflux = np.zeros(nfilters, dtype='d')
    bandmod = np.zeros(nfilters, dtype='d')
    for i in np.arange(nfilters):
        fluxrat = (bestspectrum[wnindices[i]] / istarfl[i]) * rprs * rprs
        bandflux[i] = w.bandintegrate(fluxrat, specwn, nifilter[i],
                                      wnindices[i])
        bandmod[i] = w.bandintegrate(bestspectrum[wnindices[i]], specwn,
                                     nifilter[i], wnindices[i])

    # stellar spectrum on specwn:
    sinterp = si.interp1d(starwn, starfl)
    sflux = sinterp(specwn)
    frat = bestspectrum / sflux * rprs * rprs

    # plot figure
    plt.rcParams["mathtext.default"] = 'rm'
    matplotlib.rcParams.update({'mathtext.default': 'rm'})
    matplotlib.rcParams.update({'font.size': fs - 2})
    plt.figure(3, (8.5, 6))
    plt.clf()

    # depending on solution plot eclipse or modulation spectrum
    if solution == 'eclipse':
        gfrat = gaussf(frat, 2)
        plt.semilogx(specwl, gfrat * 1e3, "b", lw=1.5, label="Best-fit")
        plt.errorbar(meanwl, data * 1e3, uncert * 1e3, fmt="or", label="data")
        plt.plot(meanwl, bandflux * 1e3, "ok", label="model", alpha=1.0)
        plt.ylabel(r"$F_p/F_s$ (10$^{-3}$)", fontsize=fs)

    elif solution == 'transit':
        gmodel = gaussf(bestspectrum, 2)
        plt.semilogx(specwl, gmodel, "b", lw=1.5, label="Best-fit")
        plt.errorbar(meanwl, data, uncert, fmt="or", label="data")
        plt.plot(meanwl, bandmod, "ok", label="model", alpha=0.5)
        plt.ylabel(r"$(R_p/R_s)^2$", fontsize=fs)

    leg = plt.legend(loc="best")
    leg.get_frame().set_alpha(0.5)
    ax = plt.subplot(111)
    ax.set_xscale('log')
    plt.xlabel("${\\rm Wavelength\ \ (\u03bcm)}$", fontsize=fs)
    #plt.xticks(size=fs)
    #plt.yticks(size=fs)
    formatter = matplotlib.ticker.FuncFormatter(
        lambda y, _: '{:.8g}'.format(y))
    ax.get_xaxis().set_major_formatter(formatter)
    ax.get_xaxis().set_minor_formatter(formatter)
    plt.xlim(min(specwl), max(specwl))
    plt.savefig(date_dir + "BART-bestFit-Spectrum.png")
    plt.close()
def callTransit(atmfile,
                tepfile,
                MCfile,
                stepsize,
                molfit,
                solution,
                p0,
                tconfig,
                date_dir,
                burnin,
                abun_file,
                PTtype,
                PTfunc,
                T_int,
                T_int_type,
                filters,
                ctf=None,
                fs=15):
    """
    Call Transit to produce best-fit outputs.
    Plot MCMC posterior PT plot.

    Parameters:
    -----------
    atmfile: String
       Atmospheric file.
    tepfile: String
       Transiting extra-solar planet file.
    MCfile: String
       File with MCMC log and best-fitting results.
    stepsize: 1D float ndarray
       Specified step sizes for each parameter.
    molfit: 1D String ndarray
       List of molecule names to modify their abundances.
    solution: String
       Flag to indicate transit or eclipse geometry
    p0: Float
       Atmosphere's 'surface' pressure level.
    tconfig: String
       Transit  configuration file.
    date_dir: String
       Directory where to store results.
    burnin: Integer
    abun_file: String
       Elemental abundances file.
    PTtype: String
       Pressure-temperature profile type ('line' for Line et al. 2013, 
       'madhu_noinv' or 'madhu_inv' for Madhusudhan & Seager 2009, 
       'iso' for isothermal)
    PTfunc: pointer to function
       Determines the method of evaluating the PT profile's temperature
    T_int: float.
       Internal temperature of the planet.
    T_int_type: string.
       Method to evaluate `T_int`. 
       'const' for constant value of `T_int`, 
       'thorngren' for Thorngren et al. (2019)
    filters: list, strings.
       Filter files associated with the eclipse/transit depths
    ctf: 2D array.
       Contribution or transmittance functions corresponding to `filters`
    fs: int
       Font size for plots.
    """
    # make sure burnin is an integer
    burnin = int(burnin)

    # read atmfile
    molecules, pressure, temp, abundances = mat.readatm(atmfile)
    # get surface gravity
    grav, Rp = mat.get_g(tepfile)
    # get star data if needed
    if PTtype == 'line':
        R_star, T_star, sma, gstar = get_starData(tepfile)
        PTargs = [R_star, T_star, T_int, sma, grav * 1e2, T_int_type]
    else:
        PTargs = None  # For non-Line profiles

    # Get best parameters
    bestP, uncer = read_MCMC_out(MCfile)
    allParams = bestP

    # get PTparams and abundances factors
    nparams = len(allParams)
    nmol = len(molfit)
    nradfit = int(solution == 'transit')
    nPTparams = nparams - nmol - nradfit

    PTparams = allParams[:nPTparams]

    # call PT profile generator to calculate temperature
    best_T = pt.PT_generator(pressure, PTparams, PTfunc, PTargs)

    # Plot best PT profile
    plt.figure(1)
    plt.clf()
    plt.semilogy(best_T, pressure, '-', color='r')
    plt.xlim(0.9 * min(best_T), 1.1 * max(best_T))
    plt.ylim(max(pressure), min(pressure))
    plt.title('Best PT', fontsize=fs)
    plt.xlabel('T (K)', fontsize=fs)
    plt.ylabel('logP (bar)', fontsize=fs)
    # Save plot to current directory
    plt.savefig(date_dir + 'Best_PT.png')

    # Update R0, if needed:
    if nradfit:
        Rp = allParams[nPTparams]

    # write best-fit atmospheric file
    write_atmfile(atmfile, abun_file, molfit, best_T,
                  allParams[nPTparams + nradfit:], date_dir, p0, Rp, grav)

    # write new bestFit Transit config
    if solution == 'transit':
        bestFit_tconfig(tconfig, date_dir, allParams[nPTparams])
    else:
        bestFit_tconfig(tconfig, date_dir)

    # Call Transit with the best-fit tconfig
    Transitdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                              "..", "modules", "transit", "")
    bf_tconfig = os.path.join(date_dir, 'bestFit_tconfig.cfg')
    Tcall = os.path.join(Transitdir, "transit", "transit")
    subprocess.call(["{:s} -c {:s}".format(Tcall, bf_tconfig)],
                    shell=True,
                    cwd=date_dir)

    # ========== plot MCMC PT profiles ==========
    # get MCMC data:
    MCMCdata = os.path.join(date_dir, "output.npy")
    data = np.load(MCMCdata)
    nchains, npars, niter = np.shape(data)

    # stuck chains:
    data_stack = data[0, :, burnin:]
    for c in np.arange(1, nchains):
        data_stack = np.hstack((data_stack, data[c, :, burnin:]))

    # create array of PT profiles
    PTprofiles = np.zeros((np.shape(data_stack)[1], len(pressure)))

    # current PT parameters for each chain, iteration
    curr_PTparams = PTparams

    # fill-in PT profiles array
    if ctf is None:
        print("  Plotting MCMC PT profile figure.")
    for k in np.arange(0, np.shape(data_stack)[1]):
        j = 0
        for i in np.arange(len(PTparams)):
            if stepsize[i] != 0.0:
                curr_PTparams[i] = data_stack[j, k]
                j += 1
            else:
                pass
        PTprofiles[k] = pt.PT_generator(pressure, curr_PTparams, PTfunc,
                                        PTargs)

    # get percentiles (for 1,2-sigma boundaries):
    low1 = np.percentile(PTprofiles, 15.87, axis=0)
    hi1 = np.percentile(PTprofiles, 84.13, axis=0)
    low2 = np.percentile(PTprofiles, 2.28, axis=0)
    hi2 = np.percentile(PTprofiles, 97.72, axis=0)
    median = np.median(PTprofiles, axis=0)

    # plot figure
    plt.figure(2, dpi=300)
    plt.clf()
    if ctf is not None:
        plt.subplots_adjust(wspace=0.15)
        ax1 = plt.subplot(121)
    else:
        ax1 = plt.subplot(111)
    ax1.fill_betweenx(pressure,
                      low2,
                      hi2,
                      facecolor="#62B1FF",
                      edgecolor="0.5")
    ax1.fill_betweenx(pressure,
                      low1,
                      hi1,
                      facecolor="#1873CC",
                      edgecolor="#1873CC")
    plt.semilogy(median, pressure, "-", lw=2, label='Median', color="k")
    plt.semilogy(best_T, pressure, "-", lw=2, label="Best fit", color="r")
    plt.ylim(pressure[0], pressure[-1])
    plt.legend(loc="best")
    plt.xlabel("Temperature  (K)", size=fs)
    plt.ylabel("Pressure  (bar)", size=fs)
    if ctf is not None:
        nfilters = len(filters)
        # Add contribution or transmittance functions
        ax2 = plt.subplot(122, sharey=ax1)
        colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
        ax2.set_prop_cycle(plt.cycler('color', colormap))
        # Plot with filter labels
        for i in np.arange(len(filters)):
            (head, tail) = os.path.split(filters[i])
            lbl = tail[:-4]
            ax2.semilogy(ctf[i], pressure, '--', linewidth=1, label=lbl)
        # Hide y axis tick labels
        plt.setp(ax2.get_yticklabels(), visible=False)
        # Place legend off figure in case there are many filters
        lgd = ax2.legend(loc='center left',
                         bbox_to_anchor=(1.05, 0.5),
                         ncol=nfilters // 25 + int(nfilters % 25 != 0),
                         prop={'size': 8})
        if solution == 'eclipse':
            ax2.set_xlabel('Normalized Contribution\nFunctions', fontsize=fs)
        else:
            ax2.set_xlabel('Transmittance', fontsize=fs)

    # save figure
    if ctf is not None:
        savefile = date_dir + "MCMC_PTprofiles_cf.png"
        plt.savefig(savefile, bbox_extra_artists=(lgd, ), bbox_inches='tight')
    else:
        savefile = date_dir + "MCMC_PTprofiles.png"
        plt.savefig(savefile)
    plt.close()
Beispiel #5
0
def plot_bestFit_Spectrum(filters, kurucz, tepfile, solution, output, data,
                                                          uncert, date_dir):
    '''
    Plot BART best-model spectrum
    '''
    # get star data
    R_star, T_star, sma, gstar = get_starData(tepfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # convert Rp to m
    Rp = Rp * 1000

    # ratio planet to star
    rprs = Rp/R_star
  
    # read kurucz file
    starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, T_star, gstar)

    # read best-fit spectrum output file, take wn and spectra values
    if solution == 'eclipse':
        specwn, bestspectrum = rt.readspectrum(date_dir + output, wn=True)
        # print on screen
        print("  Plotting BART best-fit eclipse spectrum figure.")
    elif solution == 'transit':
        specwn, bestspectrum = rt.readspectrum(date_dir + output, wn=True)
        # print on screen
        print("  Plotting BART best-fit modulation spectrum figure.")

    # convert wn to wl
    specwl = 1e4/specwn

    # number of filters
    nfilters = len(filters)

    # read and resample the filters:
    nifilter  = [] # Normalized interpolated filter
    istarfl   = [] # interpolated stellar flux
    wnindices = [] # wavenumber indices used in interpolation
    meanwn    = [] # Filter mean wavenumber
    for i in np.arange(nfilters):
        # read filter:
        filtwaven, filttransm = w.readfilter(filters[i])
        meanwn.append(np.sum(filtwaven*filttransm)/sum(filttransm))
        # resample filter and stellar spectrum:
        nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                            starwn,    starfl)
        nifilter.append(nifilt)
        istarfl.append(strfl)
        wnindices.append(wnind)

    # convert mean wn to mean wl
    meanwl = 1e4/np.asarray(meanwn)

    # band-integrate the flux-ratio or modulation:
    bandflux = np.zeros(nfilters, dtype='d')
    bandmod  = np.zeros(nfilters, dtype='d')
    for i in np.arange(nfilters):
        fluxrat = (bestspectrum[wnindices[i]]/istarfl[i]) * rprs*rprs
        bandflux[i] = w.bandintegrate(fluxrat, specwn, nifilter[i],
                                                                 wnindices[i])
        bandmod[i]  = w.bandintegrate(bestspectrum[wnindices[i]],
                                            specwn, nifilter[i], wnindices[i])

    # stellar spectrum on specwn:
    sinterp = si.interp1d(starwn, starfl)
    sflux = sinterp(specwn)
    frat = bestspectrum/sflux * rprs * rprs

    # plot figure
    plt.rcParams["mathtext.default"] = 'rm'
    matplotlib.rcParams.update({'mathtext.default':'rm'})
    matplotlib.rcParams.update({'font.size':10})
    plt.figure(3, (8.5, 5))
    plt.clf()

    # depending on solution plot eclipse or modulation spectrum
    if solution == 'eclipse':
        gfrat = gaussf(frat, 2)
        plt.semilogx(specwl, gfrat*1e3, "b", lw=1.5, label="Best-fit")
        plt.errorbar(meanwl, data*1e3, uncert*1e3, fmt="or", label="data")
        plt.plot(meanwl, bandflux*1e3, "ok", label="model", alpha=1.0)
        plt.ylabel(r"$F_p/F_s$ (10$^{3}$)", fontsize=12)

    elif solution == 'transit':
        gmodel = gaussf(bestspectrum, 2)
        plt.semilogx(specwl, gmodel, "b", lw=1.5, label="Best-fit")
        # Check units!
        plt.errorbar(meanwl, data, uncert, fmt="or", label="data")
        plt.plot(meanwl, bandmod, "ok", label="model", alpha=0.5)
        plt.ylabel(r"$(R_p/R_s)^2$", fontsize=12)

    leg = plt.legend(loc="lower right")
    leg.get_frame().set_alpha(0.5)
    ax = plt.subplot(111)
    ax.set_xscale('log')
    plt.xlabel(r"${\rm Wavelength\ \ (um)}$", fontsize=12)  
    ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
    ax.set_xticks(np.arange(min(specwl),max(specwl),1))
    plt.xlim(min(specwl),max(specwl))
    plt.savefig(date_dir + "BART-bestFit-Spectrum.png")
Beispiel #6
0
def callTransit(atmfile, tepfile, MCfile, stepsize, molfit, solution,
                p0, tconfig, date_dir, params, burnin, abun_file):
    """
    Call Transit to produce best-fit outputs.
    Plot MCMC posterior PT plot.

    Parameters:
    -----------
    atmfile: String
       Atmospheric file.
    tepfile: String
       Transiting extra-solar planet file.
    MCfile: String
       File with MCMC log and best-fitting results.
    stepsize: 1D float ndarray
       FINDME
    molfit: 1D String ndarray
       List of molecule names to modify their abundances.
    solution: String
       Flag to indicate transit or eclipse geometry
    p0: Float
       Atmosphere's 'surface' pressure level.
    tconfig: String
       Transit  configuration file.
    date_dir: String
       Directory where to store results.
    params: 1D float ndarray
    burnin: Integer
    abun_file: String
       Elemental abundances file.
    """

    # read atmfile
    molecules, pressure, temp, abundances = mat.readatm(atmfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # get star data
    R_star, T_star, sma, gstar = get_starData(tepfile)

    # get best parameters
    bestP, uncer, SN, mean = read_MCMC_out(MCfile)

    # get all params
    allParams = get_params(bestP, stepsize, params)

    # get PTparams and abundances factors
    nparams = len(allParams)
    nmol = len(molfit)
    nradfit = int(solution == 'transit')
    nPTparams = nparams - nmol - nradfit
    PTparams  = allParams[:nPTparams]

    # FINDME: Hardcoded value:
    T_int = 100  # K

    # call PT line profile to calculate temperature
    best_T = pt.PT_line(pressure, PTparams, R_star, T_star, T_int,
                        sma, grav*1e2)

    # Plot best PT profile
    plt.figure(1)
    plt.clf()
    plt.semilogy(best_T, pressure, '-', color = 'r')
    plt.xlim(0.9*min(best_T), 1.1*max(best_T))
    plt.ylim(max(pressure), min(pressure))
    plt.title('Best PT', fontsize=14)
    plt.xlabel('T [K]'     , fontsize=14)
    plt.ylabel('logP [bar]', fontsize=14)
    # Save plot to current directory
    plt.savefig(date_dir + 'Best_PT.png') 

    # Update R0, if needed:
    if nradfit:
      Rp = allParams[nPTparams]
    # Mean molecular mass:
    mu  = mat.mean_molar_mass(abun_file, atmfile)
    # Re-calculate the layers' radii using the Hydrostatic-equilibrium calc:
    # (Has to be in reversed order since the interpolation requires the
    #  pressure array in increasing order)
    rad = mat.radpress(pressure[::-1], best_T[::-1], mu[::-1], p0, Rp, grav)
    rad = rad[::-1]

    # write best-fit atmospheric file
    write_atmfile(atmfile, molfit, rad, best_T, allParams[nPTparams+nradfit:],
                  date_dir)

    # bestFit atm file
    bestFit_atm = date_dir + 'bestFit.atm'

    # write new bestFit Transit config
    bestFit_tconfig(tconfig, date_dir)

    # ========== plot MCMC PT profiles ==========

    # get MCMC data:
    MCMCdata = date_dir + "/output.npy"
    data = np.load(MCMCdata)
    nchains, npars, niter = np.shape(data)

    # stuck chains:
    data_stack = data[0,:,burnin:]
    for c in np.arange(1, nchains):
        data_stack = np.hstack((data_stack, data[c, :, burnin:]))

    # create array of PT profiles
    PTprofiles = np.zeros((np.shape(data_stack)[1], len(pressure)))

    # current PT parameters for each chain, iteration
    curr_PTparams = PTparams

    # fill-in PT profiles array
    print("  Plotting MCMC PT profile figure.")
    for k in np.arange(0, np.shape(data_stack)[1]):
        j = 0
        for i in np.arange(len(PTparams)):
            if stepsize[i] != 0.0:
                curr_PTparams[i] = data_stack[j,k]
                j +=1
            else:
                pass
        PTprofiles[k] = pt.PT_line(pressure, curr_PTparams, R_star, T_star,
                                   T_int, sma, grav*1e2)

    # get percentiles (for 1,2-sigma boundaries):
    low1 = np.percentile(PTprofiles, 16.0, axis=0)
    hi1  = np.percentile(PTprofiles, 84.0, axis=0)
    low2 = np.percentile(PTprofiles,  2.5, axis=0)
    hi2  = np.percentile(PTprofiles, 97.5, axis=0)
    median = np.median(PTprofiles, axis=0)

    # plot figure
    plt.figure(2)
    plt.clf()
    ax=plt.subplot(111)
    ax.fill_betweenx(pressure, low2, hi2, facecolor="#62B1FF", edgecolor="0.5")
    ax.fill_betweenx(pressure, low1, hi1, facecolor="#1873CC",
                                                           edgecolor="#1873CC")
    plt.semilogy(median, pressure, "-", lw=2, label='Median',color="k")
    plt.semilogy(best_T, pressure, "-", lw=2, label="Best fit", color="r")
    plt.ylim(pressure[0], pressure[-1])
    plt.legend(loc="best")
    plt.xlabel("Temperature  (K)", size=15)
    plt.ylabel("Pressure  (bar)",  size=15)

    # save figure
    savefile = date_dir + "MCMC_PTprofiles.png" 
    plt.savefig(savefile)
Beispiel #7
0
def plot_bestFit_Spectrum(filters, kurucz, tepfile, solution, output, data,
                                                          uncert, date_dir):
    '''
    Plot BART best-model spectrum
    '''
    # get star data
    R_star, T_star, sma, gstar = get_starData(tepfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # convert Rp to m
    Rp = Rp * 1000

    # ratio planet to star
    rprs = Rp/R_star
  
    # read kurucz file
    starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, T_star, gstar)

    # read best-fit spectrum output file, take wn and spectra values
    if solution == 'eclipse':
        specwn, bestspectrum = rt.readspectrum(date_dir + output, wn=True)
        # print on screen
        print("  Plotting BART best-fit eclipse spectrum figure.")
    elif solution == 'transit':
        specwn, bestspectrum = rt.readspectrum(date_dir + output, wn=True)
        # print on screen
        print("  Plotting BART best-fit modulation spectrum figure.")

    # convert wn to wl
    specwl = 1e4/specwn

    # number of filters
    nfilters = len(filters)

    # read and resample the filters:
    nifilter  = [] # Normalized interpolated filter
    istarfl   = [] # interpolated stellar flux
    wnindices = [] # wavenumber indices used in interpolation
    meanwn    = [] # Filter mean wavenumber
    for i in np.arange(nfilters):
        # read filter:
        filtwaven, filttransm = w.readfilter(filters[i])
        meanwn.append(np.sum(filtwaven*filttransm)/sum(filttransm))
        # resample filter and stellar spectrum:
        nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                            starwn,    starfl)
        nifilter.append(nifilt)
        istarfl.append(strfl)
        wnindices.append(wnind)

    # convert mean wn to mean wl
    meanwl = 1e4/np.asarray(meanwn)

    # band-integrate the flux-ratio or modulation:
    bandflux = np.zeros(nfilters, dtype='d')
    bandmod  = np.zeros(nfilters, dtype='d')
    for i in np.arange(nfilters):
        fluxrat = (bestspectrum[wnindices[i]]/istarfl[i]) * rprs*rprs
        bandflux[i] = w.bandintegrate(fluxrat, specwn, nifilter[i],
                                                                 wnindices[i])
        bandmod[i]  = w.bandintegrate(bestspectrum[wnindices[i]],
                                            specwn, nifilter[i], wnindices[i])

    # stellar spectrum on specwn:
    sinterp = si.interp1d(starwn, starfl)
    sflux = sinterp(specwn)
    frat = bestspectrum/sflux * rprs * rprs

    # plot figure
    plt.rcParams["mathtext.default"] = 'rm'
    matplotlib.rcParams.update({'mathtext.default':'rm'})
    matplotlib.rcParams.update({'font.size':10})
    plt.figure(3, (8.5, 5))
    plt.clf()

    # depending on solution plot eclipse or modulation spectrum
    if solution == 'eclipse':
        gfrat = gaussf(frat, 2)
        plt.semilogx(specwl, gfrat*1e3, "b", lw=1.5, label="Best-fit")
        plt.errorbar(meanwl, data*1e3, uncert*1e3, fmt="or", label="data")
        plt.plot(meanwl, bandflux*1e3, "ok", label="model", alpha=1.0)
        plt.ylabel(r"$F_p/F_s$ (10$^{3}$)", fontsize=12)

    elif solution == 'transit':
        gmodel = gaussf(bestspectrum, 2)
        plt.semilogx(specwl, gmodel, "b", lw=1.5, label="Best-fit")
        # Check units!
        plt.errorbar(meanwl, data, uncert, fmt="or", label="data")
        plt.plot(meanwl, bandmod, "ok", label="model", alpha=0.5)
        plt.ylabel(r"$(R_p/R_s)^2$", fontsize=12)

    leg = plt.legend(loc="lower right")
    leg.get_frame().set_alpha(0.5)
    ax = plt.subplot(111)
    ax.set_xscale('log')
    plt.xlabel(r"${\rm Wavelength\ \ (um)}$", fontsize=12)  
    ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
    ax.set_xticks(np.arange(round(min(specwl)),max(specwl),1))
    plt.xlim(min(specwl),max(specwl))
    plt.savefig(date_dir + "BART-bestFit-Spectrum.png")
Beispiel #8
0
def callTransit(atmfile, tepfile, MCfile, stepsize, molfit, solution,
                p0, tconfig, date_dir, params, burnin, abun_file):
    """
    Call Transit to produce best-fit outputs.
    Plot MCMC posterior PT plot.

    Parameters:
    -----------
    atmfile: String
       Atmospheric file.
    tepfile: String
       Transiting extra-solar planet file.
    MCfile: String
       File with MCMC log and best-fitting results.
    stepsize: 1D float ndarray
       FINDME
    molfit: 1D String ndarray
       List of molecule names to modify their abundances.
    solution: String
       Flag to indicate transit or eclipse geometry
    p0: Float
       Atmosphere's 'surface' pressure level.
    tconfig: String
       Transit  configuration file.
    date_dir: String
       Directory where to store results.
    params: 1D float ndarray
    burnin: Integer
    abun_file: String
       Elemental abundances file.
    """

    # read atmfile
    molecules, pressure, temp, abundances = mat.readatm(atmfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # get star data
    R_star, T_star, sma, gstar = get_starData(tepfile)

    # Get best parameters
    bestP, uncer = read_MCMC_out(MCfile)

    # get all params
    #allParams = get_params(bestP, stepsize, params)
    allParams = bestP

    # get PTparams and abundances factors
    nparams = len(allParams)
    nmol = len(molfit)
    nradfit = int(solution == 'transit')
    nPTparams = nparams - nmol - nradfit
    PTparams  = allParams[:nPTparams]

    # FINDME: Hardcoded value:
    T_int = 100  # K

    # call PT line profile to calculate temperature
    best_T = pt.PT_line(pressure, PTparams, R_star, T_star, T_int,
                        sma, grav*1e2)

    # Plot best PT profile
    plt.figure(1)
    plt.clf()
    plt.semilogy(best_T, pressure, '-', color = 'r')
    plt.xlim(0.9*min(best_T), 1.1*max(best_T))
    plt.ylim(max(pressure), min(pressure))
    plt.title('Best PT', fontsize=14)
    plt.xlabel('T [K]'     , fontsize=14)
    plt.ylabel('logP [bar]', fontsize=14)
    # Save plot to current directory
    plt.savefig(date_dir + 'Best_PT.png') 

    # Update R0, if needed:
    if nradfit:
      Rp = allParams[nPTparams]
    # Mean molecular mass:
    mu  = mat.mean_molar_mass(abun_file, atmfile)
    # Re-calculate the layers' radii using the Hydrostatic-equilibrium calc:
    # (Has to be in reversed order since the interpolation requires the
    #  pressure array in increasing order)
    rad = mat.radpress(pressure[::-1], best_T[::-1], mu[::-1], p0, Rp, grav)
    rad = rad[::-1]

    # write best-fit atmospheric file
    write_atmfile(atmfile, molfit, rad, best_T, allParams[nPTparams+nradfit:],
                  date_dir)

    # bestFit atm file
    bestFit_atm = date_dir + 'bestFit.atm'

    # write new bestFit Transit config
    bestFit_tconfig(tconfig, date_dir)

    # ========== plot MCMC PT profiles ==========

    # get MCMC data:
    MCMCdata = date_dir + "/output.npy"
    data = np.load(MCMCdata)
    nchains, npars, niter = np.shape(data)

    # stuck chains:
    data_stack = data[0,:,burnin:]
    for c in np.arange(1, nchains):
        data_stack = np.hstack((data_stack, data[c, :, burnin:]))

    # create array of PT profiles
    PTprofiles = np.zeros((np.shape(data_stack)[1], len(pressure)))

    # current PT parameters for each chain, iteration
    curr_PTparams = PTparams

    # fill-in PT profiles array
    print("  Plotting MCMC PT profile figure.")
    for k in np.arange(0, np.shape(data_stack)[1]):
        j = 0
        for i in np.arange(len(PTparams)):
            if stepsize[i] != 0.0:
                curr_PTparams[i] = data_stack[j,k]
                j +=1
            else:
                pass
        PTprofiles[k] = pt.PT_line(pressure, curr_PTparams, R_star, T_star,
                                   T_int, sma, grav*1e2)

    # get percentiles (for 1,2-sigma boundaries):
    low1 = np.percentile(PTprofiles, 16.0, axis=0)
    hi1  = np.percentile(PTprofiles, 84.0, axis=0)
    low2 = np.percentile(PTprofiles,  2.5, axis=0)
    hi2  = np.percentile(PTprofiles, 97.5, axis=0)
    median = np.median(PTprofiles, axis=0)

    # plot figure
    plt.figure(2)
    plt.clf()
    ax=plt.subplot(111)
    ax.fill_betweenx(pressure, low2, hi2, facecolor="#62B1FF", edgecolor="0.5")
    ax.fill_betweenx(pressure, low1, hi1, facecolor="#1873CC",
                                                           edgecolor="#1873CC")
    plt.semilogy(median, pressure, "-", lw=2, label='Median',color="k")
    plt.semilogy(best_T, pressure, "-", lw=2, label="Best fit", color="r")
    plt.ylim(pressure[0], pressure[-1])
    plt.legend(loc="best")
    plt.xlabel("Temperature  (K)", size=15)
    plt.ylabel("Pressure  (bar)",  size=15)

    # save figure
    savefile = date_dir + "MCMC_PTprofiles.png" 
    plt.savefig(savefile)
        0.000614,  0.000732])

uncert = np.array([  1.30000000e-04,   1.50000000e-04,   8.90000000e-05,
         8.40000000e-05,   1.70000000e-04,   2.90000000e-04,
         3.20000000e-04,   1.40000000e-04,   4.20000000e-04,
         2.20000000e-04,   2.70000000e-04,   4.50000000e-05,
         3.90000000e-05,   3.80000000e-05,   3.60000000e-05,
         3.70000000e-05,   3.30000000e-05,   3.40000000e-05,
         3.00000000e-05,   3.60000000e-05,   3.60000000e-05,
         3.30000000e-05,   3.50000000e-05,   3.60000000e-05,
         3.70000000e-05,   4.20000000e-05])

# get star data
R_star, T_star, sma, gstar = bf.get_starData(tep_name)
# get surface gravity
grav, Rp = mat.get_g(tep_name)
# convert Rp to m
Rp = Rp * 1000
# ratio planet to star
rprs = Rp/R_star
# read kurucz file
starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, T_star, gstar)

###################### plot figure #############################

plt.rcParams["mathtext.default"] = 'rm'
matplotlib.rcParams.update({'mathtext.default':'rm'})
matplotlib.rcParams.update({'axes.labelsize': 16,
                                'xtick.labelsize': 14,
                                'ytick.labelsize': 14,})
Beispiel #10
0
def plot_bestFit_Spectrum(low, high, xtic, xlab, spec, clr, specs, atmfile,
                          filters, kurucz, tepfile, outflux, data, uncert,
                          direct):
    '''
    Plot Transit spectrum
    '''
    # get star data
    R_star, T_star, sma, gstar = bf.get_starData(tepfile)

    # get surface gravity
    grav, Rp = mat.get_g(tepfile)

    # convert Rp to m
    Rp = Rp * 1000

    # ratio planet to star
    rprs = Rp / R_star

    # read kurucz file
    starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, T_star, gstar)

    # read best-fit spectrum output file, take wn and spectra values
    (head, tail) = os.path.split(outflux)
    specwn, bestspectrum = rt.readspectrum(direct + '/' + tail, wn=True)

    # convert wn to wl
    specwl = 1e4 / specwn

    # number of filters
    nfilters = len(filters)

    # read and resample the filters:
    nifilter = []  # Normalized interpolated filter
    istarfl = []  # interpolated stellar flux
    wnindices = []  # wavenumber indices used in interpolation
    meanwn = []  # Filter mean wavenumber
    for i in np.arange(nfilters):
        # read filter:
        filtwaven, filttransm = w.readfilter(filters[i])
        meanwn.append(np.sum(filtwaven * filttransm) / sum(filttransm))
        # resample filter and stellar spectrum:
        nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                          starwn, starfl)
        nifilter.append(nifilt)
        istarfl.append(strfl)
        wnindices.append(wnind)

    # convert mean wn to mean wl
    meanwl = 1e4 / np.asarray(meanwn)

    # band-integrate the flux-ratio or modulation:
    bandflux = np.zeros(nfilters, dtype='d')
    bandmod = np.zeros(nfilters, dtype='d')
    for i in np.arange(nfilters):
        fluxrat = (bestspectrum[wnindices[i]] / istarfl[i]) * rprs * rprs
        bandflux[i] = w.bandintegrate(fluxrat, specwn, nifilter[i],
                                      wnindices[i])
        bandmod[i] = w.bandintegrate(bestspectrum[wnindices[i]], specwn,
                                     nifilter[i], wnindices[i])

    # stellar spectrum on specwn:
    sinterp = si.interp1d(starwn, starfl)
    sflux = sinterp(specwn)
    frat = bestspectrum / sflux * rprs * rprs

    ###################### plot figure #############################

    plt.rcParams["mathtext.default"] = 'rm'
    matplotlib.rcParams.update({'mathtext.default': 'rm'})
    matplotlib.rcParams.update({
        'axes.labelsize': 16,
        'xtick.labelsize': 20,
        'ytick.labelsize': 20,
    })

    plt.figure(2, (8.5, 5))
    plt.clf()

    # smooth the spectrum a fit
    gfrat = gaussf(frat, 2)

    # plot eclipse spectrum
    plt.semilogx(specwl,
                 gfrat * 1e3,
                 clr,
                 lw=1.5,
                 label="Spectrum",
                 linewidth=4)
    plt.errorbar(meanwl,
                 data * 1e3,
                 uncert * 1e3,
                 fmt="ko",
                 label="Data",
                 alpha=0.7)
    plt.ylabel(r"$F_p/F_s$ (10$^{-3}$)", fontsize=24)

    leg = plt.legend(loc="upper left")
    leg.get_frame().set_alpha(0.5)
    ax = plt.subplot(111)
    ax.set_xscale('log')
    plt.xlabel(r"${\rm Wavelength\ \ (um)}$", fontsize=24)
    ax.get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())
    plt.gca().xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
    ax.set_xticks([0.7, 0.8, 0.9, 1.0, 2.0, 3.0, 4.0, 5.0])
    ax.set_xticklabels(["0.7", "", "", "1.0", "2.0", "3.0", "4.0", "5.0"])
    plt.xlim(min(specwl), max(specwl))

    nfilters = len(filters)
    # plot filter bandpasses
    for i in np.arange(nfilters - 15):
        (head, tail) = os.path.split(filters[i])
        lbl = tail[:-4]
        # read filter:
        wn, respons = w.readfilter(filters[i])
        respons = respons / 3 - 0.4
        wl = 10000.0 / wn
        #plt.plot(wl, respons, color='crimson', linewidth =1)
        if lbl == 'spitzer_irac1_sa' or lbl == 'spitzer_irac2_sa':
            respons = respons * 2 + 0.4
            plt.plot(wl, respons, color='grey', linewidth=1, alpha=0.5)
            #plt.plot(wl, respons*2, color='orangered', linewidth =1)
        elif lbl == 'Wang-Hband' or lbl == 'Wang-Kband':
            plt.plot(wl, respons, 'grey', linewidth=1, alpha=0.5)
        elif lbl == 'VLT_1190' or lbl == 'VLT_2090':
            plt.plot(wl, respons, color='grey', linewidth=2, alpha=0.5)
            #plt.plot(wl, respons, color='firebrick', linewidth =2)
        elif lbl == 'GROND_K_JB' or lbl == 'GROND_i_JB':
            plt.plot(wl, respons, 'grey', linewidth=1, alpha=0.5)
        elif lbl == 'Zhou_Ks':
            plt.plot(wl, respons, 'grey', linewidth=1, alpha=0.5)

    plt.ylim(-0.4, 7)
    plt.text(1.9, 3, specs, color=clr, fontsize=26)

    plt.subplots_adjust(bottom=0.20)

    plt.savefig(spec + "_BestFit-transSpec.png")
    plt.savefig(spec + "_BestFit-transSpec.ps")
def retrievedPT(datadir,
                atmfile,
                tepfile,
                nmol,
                solution,
                outname,
                outdir=None,
                T_int=100.):
    """
    Inputs
    ------
    datadir:  string. Path/to/directory containing BART-formatted output.
    atmfile:  string. Path/to/atmospheric model file.
    tepfile:  string. Path/to/Transiting ExoPlanet file.
    nmol:     int.    Number of molecules being fit by MCMC.
    solution: string. Geometry of the system. 'eclipse' or 'transit'. 
    outname:  string. File name of resulting plot.
    outdir:   string. Path/to/dir to save `outname`. If None, defaults 
                      to the results directory of BARTTest if `datadir` is 
                      within BARTTest.
    T_int:    float.  Internal planetary temperature. Default is 100 K.
    """
    # Set outdir if not specified
    if outdir is None:
        try:
            if datadir[-1] != '/':
                datadir = datadir + '/'
            outdir = 'results'.join(datadir.rsplit('code-output',            \
                                                   1)).rsplit('/', 2)[0] + '/'
            if not os.path.isdir(outdir):
                os.makedirs(outdir)
        except:
            print("Data directory not located within BARTTest.")
            print("Please specify an output directory `outdir` and try again.")
            sys.exit(1)

    # Read g_surf and R_planet from TEP file
    grav, Rp = ma.get_g(tepfile)

    # Read star data from TEP file, and semi-major axis
    R_star, T_star, sma, gstar = bf.get_starData(tepfile)

    # Read atmfile
    mols, atminfo = readatm(atmfile)
    pressure = atminfo[:, 1]

    # Read MCMC output file
    MCfile = datadir + 'MCMC.log'
    bestP, uncer = bf.read_MCMC_out(MCfile)
    allParams = bestP
    # Get number of burned iterations
    foo = open(MCfile, 'r')
    lines = foo.readlines()
    foo.close()
    line = [
        foop for foop in lines if " Burned in iterations per chain:" in foop
    ]
    burnin = int(line[0].split()[-1])

    # Figure out number of parameters
    nparams = len(allParams)
    nradfit = int(solution == 'transit')
    nPTparams = nparams - nmol - nradfit
    PTparams = allParams[:nPTparams]

    # Plot the best PT profile
    kappa, gamma1, gamma2, alpha, beta = PTparams
    best_T = pt.PT_line(pressure, kappa, gamma1, gamma2, alpha, beta, R_star,
                        T_star, T_int, sma, grav * 1e2, 'const')

    # Load MCMC data
    MCMCdata = datadir + 'output.npy'
    data = np.load(MCMCdata)
    nchains, npars, niter = np.shape(data)

    # Make datacube from MCMC data
    data_stack = data[0, :, burnin:]
    for c in np.arange(1, nchains):
        data_stack = np.hstack((data_stack, data[c, :, burnin:]))

    # Datacube of PT profiles
    PTprofiles = np.zeros((np.shape(data_stack)[1], len(pressure)))

    curr_PTparams = PTparams

    for k in np.arange(0, np.shape(data_stack)[1]):
        j = 0
        for i in np.arange(len(PTparams)):
            curr_PTparams[i] = data_stack[j, k]
            j += 1
        kappa, gamma1, gamma2, alpha, beta = curr_PTparams
        PTprofiles[k] = pt.PT_line(pressure, kappa, gamma1, gamma2, alpha,
                                   beta, R_star, T_star, T_int, sma,
                                   grav * 1e2, 'const')

    # Get percentiles (for 1, 2-sigma boundaries):
    low1 = np.percentile(PTprofiles, 16.0, axis=0)
    hi1 = np.percentile(PTprofiles, 84.0, axis=0)
    low2 = np.percentile(PTprofiles, 2.5, axis=0)
    hi2 = np.percentile(PTprofiles, 97.5, axis=0)
    median = np.median(PTprofiles, axis=0)

    # Plot and save figure
    plt.figure(2)
    plt.clf()
    ax = plt.subplot(111)
    ax.fill_betweenx(pressure, low2, hi2, facecolor="#62B1FF", edgecolor="0.5")
    ax.fill_betweenx(pressure,
                     low1,
                     hi1,
                     facecolor="#1873CC",
                     edgecolor="#1873CC")
    plt.semilogy(median, pressure, "-", lw=2, label='Median', color="k")
    plt.semilogy(best_T, pressure, "-", lw=2, label="Best fit", color="r")
    plt.semilogy(atminfo[:, 2], pressure, "--", lw=2, label='Input', color='r')
    plt.ylim(pressure[0], pressure[-1])
    plt.legend(loc="best")
    plt.xlabel("Temperature  (K)", size=15)
    plt.ylabel("Pressure  (bar)", size=15)
    plt.savefig(outdir + outname)
    plt.close()
Beispiel #12
0
def callTransit(atmfile, tepfile,  MCfile, stepsize,  molfit,  solution, p0, 
                tconfig, date_dir, burnin, abun_file, PTtype,  PTfunc, 
                filters, ctf=None):
    """
    Call Transit to produce best-fit outputs.
    Plot MCMC posterior PT plot.

    Parameters:
    -----------
    atmfile: String
       Atmospheric file.
    tepfile: String
       Transiting extra-solar planet file.
    MCfile: String
       File with MCMC log and best-fitting results.
    stepsize: 1D float ndarray
       Specified step sizes for each parameter.
    molfit: 1D String ndarray
       List of molecule names to modify their abundances.
    solution: String
       Flag to indicate transit or eclipse geometry
    p0: Float
       Atmosphere's 'surface' pressure level.
    tconfig: String
       Transit  configuration file.
    date_dir: String
       Directory where to store results.
    burnin: Integer
    abun_file: String
       Elemental abundances file.
    PTtype: String
       Pressure-temperature profile type ('line' for Line et al. 2013, 
       'madhu_noinv' or 'madhu_inv' for Madhusudhan & Seager 2009, 
       'iso' for isothermal)
    PTfunc: pointer to function
       Determines the method of evaluating the PT profile's temperature
    filters: list, strings.
       Filter files associated with the eclipse/transit depths
    ctf: 2D array.
       Contribution or transmittance functions corresponding to `filters`
    """
    # make sure burnin is an integer
    burnin = int(burnin)

    # read atmfile
    molecules, pressure, temp, abundances = mat.readatm(atmfile)
    # get surface gravity
    grav, Rp = mat.get_g(tepfile)
    # get star data if needed
    if PTtype == 'line':
      R_star, T_star, sma, gstar = get_starData(tepfile)
      # FINDME: Hardcoded value:
      T_int  = 100  # K
      PTargs = [R_star, T_star, T_int, sma, grav*1e2]
    else:
      PTargs = None # For non-Line profiles

    # Get best parameters
    bestP, uncer = read_MCMC_out(MCfile)
    allParams    = bestP

    # get PTparams and abundances factors
    nparams   = len(allParams)
    nmol      = len(molfit)
    nradfit   = int(solution == 'transit')
    nPTparams = nparams - nmol - nradfit

    PTparams  = allParams[:nPTparams]

    # call PT profile generator to calculate temperature
    best_T = pt.PT_generator(pressure, PTparams, PTfunc, PTargs)

    # Plot best PT profile
    plt.figure(1)
    plt.clf()
    plt.semilogy(best_T, pressure, '-', color = 'r')
    plt.xlim(0.9*min(best_T), 1.1*max(best_T))
    plt.ylim(max(pressure), min(pressure))
    plt.title('Best PT', fontsize=14)
    plt.xlabel('T (K)'     , fontsize=14)
    plt.ylabel('logP (bar)', fontsize=14)
    # Save plot to current directory
    plt.savefig(date_dir + 'Best_PT.png')

    # Update R0, if needed:
    if nradfit:
      Rp = allParams[nPTparams]

    # write best-fit atmospheric file
    write_atmfile(atmfile, abun_file, molfit, best_T,
                  allParams[nPTparams+nradfit:], date_dir, p0, Rp, grav)

    # write new bestFit Transit config
    if solution == 'transit':
      bestFit_tconfig(tconfig, date_dir, allParams[nPTparams])
    else:
      bestFit_tconfig(tconfig, date_dir)

    # Call Transit with the best-fit tconfig
    Transitdir      = os.path.dirname(os.path.realpath(__file__)) + \
                      "/../modules/transit/"
    bf_tconfig      = date_dir   + 'bestFit_tconfig.cfg'
    Tcall           = Transitdir + "/transit/transit"
    subprocess.call(["{:s} -c {:s}".format(Tcall, bf_tconfig)],
shell=True, cwd=date_dir)

    # ========== plot MCMC PT profiles ==========
    # get MCMC data:
    MCMCdata = date_dir + "/output.npy"
    data = np.load(MCMCdata)
    nchains, npars, niter = np.shape(data)

    # stuck chains:
    data_stack = data[0,:,burnin:]
    for c in np.arange(1, nchains):
        data_stack = np.hstack((data_stack, data[c, :, burnin:]))

    # create array of PT profiles
    PTprofiles = np.zeros((np.shape(data_stack)[1], len(pressure)))

    # current PT parameters for each chain, iteration
    curr_PTparams = PTparams

    # fill-in PT profiles array
    if ctf is None:
        print("  Plotting MCMC PT profile figure.")
    for k in np.arange(0, np.shape(data_stack)[1]):
        j = 0
        for i in np.arange(len(PTparams)):
            if stepsize[i] != 0.0:
                curr_PTparams[i] = data_stack[j,k]
                j +=1
            else:
                pass
        PTprofiles[k] = pt.PT_generator(pressure, curr_PTparams, 
                                        PTfunc, PTargs)

    # get percentiles (for 1,2-sigma boundaries):
    low1   = np.percentile(PTprofiles, 16.0, axis=0)
    hi1    = np.percentile(PTprofiles, 84.0, axis=0)
    low2   = np.percentile(PTprofiles,  2.5, axis=0)
    hi2    = np.percentile(PTprofiles, 97.5, axis=0)
    median = np.median(    PTprofiles,       axis=0)

    # plot figure
    plt.figure(2, dpi=300)
    plt.clf()
    if ctf is not None:
        plt.subplots_adjust(wspace=0.15)
        ax1=plt.subplot(121)
    else:
        ax1=plt.subplot(111)
    ax1.fill_betweenx(pressure, low2, hi2, facecolor="#62B1FF", 
                      edgecolor="0.5")
    ax1.fill_betweenx(pressure, low1, hi1, facecolor="#1873CC",
                      edgecolor="#1873CC")
    plt.semilogy(median, pressure, "-", lw=2, label='Median',color="k")
    plt.semilogy(best_T, pressure, "-", lw=2, label="Best fit", color="r")
    plt.ylim(pressure[0], pressure[-1])
    plt.legend(loc="best")
    plt.xlabel("Temperature  (K)", size=15)
    plt.ylabel("Pressure  (bar)",  size=15)
    if ctf is not None:
        # Add contribution or transmittance functions
        ax2=plt.subplot(122, sharey=ax1)
        colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
        ax2.set_prop_cycle(plt.cycler('color', colormap))
        # Plot with filter labels
        for i in np.arange(len(filters)):
            (head, tail) = os.path.split(filters[i])
            lbl          = tail[:-4]
            ax2.semilogy(ctf[i], pressure, '--',  linewidth = 1, label=lbl)
        # Hide y axis tick labels
        plt.setp(ax2.get_yticklabels(), visible=False)
        # Place legend off figure in case there are many filters
        lgd = ax2.legend(loc='center left', bbox_to_anchor=(1,0.5), 
                         ncol=len(filters)//30 + 1, prop={'size':8})
        if solution == 'eclipse':
            ax2.set_xlabel('Normalized Contribution\nFunctions',  fontsize=15)
        else:
            ax2.set_xlabel('Transmittance', fontsize=15)
    

    # save figure
    if ctf is not None:
        savefile = date_dir + "MCMC_PTprofiles_cf.png"
        plt.savefig(savefile, bbox_extra_artists=(lgd,), bbox_inches='tight')
    else:
        savefile = date_dir + "MCMC_PTprofiles.png"
        plt.savefig(savefile)