Beispiel #1
0
def cf(date_dir, atmfile, filters):
	"""
	Call above functions to calculate cf and plot them
	"""
	# Read atmfile
	molecules, p, T, abundances = mat.readatm(atmfile)
	nlayers = len(p)

	# Read tau.dat
	file = date_dir + 'tau.dat'
	tau, wns = readTauDat(file, nlayers)

	# Calculate BB, reverse the order of p and T
	p = p[::-1]
	T = T[::-1]
	BB = Planck(T, wns)

	# Call cf_eq() to calculate cf
	cf = cf_eq(BB, p, tau, nlayers, wns)

	# Call filter_cf() to calculate cf
	filt_cf, filt_cf_norm = filter_cf(filters, nlayers, wns, cf)

	############ Plotting ################

	print("  Plotting contribution functions.\n")
	# Not normalized cf
	plt.figure(4)
	plt.clf()
	gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1]) 
	ax0 = plt.subplot(gs[0])
	for i in np.arange(len(filt_cf)):
		(head, tail) = os.path.split(filters[i])
		lbl = tail[:-4]
		ax0.semilogy(filt_cf[i], p, '-', linewidth = 1, label=lbl)
	ax0.legend(loc='center left', bbox_to_anchor=(1.0, 0.5), prop={'size':8})
	ax0.set_ylim(max(p), min(p))
	ax0.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
	ax0.set_xlabel('Contribution functions', fontsize=14)
	ax0.set_ylabel('Pressure [bar]' , fontsize=14)
	plt.savefig(date_dir + 'ContrFuncs.png')

	# Normalized cf
	plt.figure(5)
	plt.clf()
	gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1]) 
	ax0 = plt.subplot(gs[0])
	for i in np.arange(len(filt_cf_norm)):
		(head, tail) = os.path.split(filters[i])
		lbl = tail[:-4]
		ax0.semilogy(filt_cf_norm[i], p, '--', linewidth = 1, label=lbl)

	ax0.legend(loc='center left', bbox_to_anchor=(1,0.5), prop={'size':8})
	ax0.set_ylim(max(p), min(p))
	ax0.set_xlim(0, 1.0)
	ax0.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
	ax0.set_xlabel('Normalized contribution functions', fontsize=14)
	ax0.set_ylabel('Pressure [bar]' , fontsize=14)
	plt.savefig(date_dir + 'NormContrFuncs.png')
Beispiel #2
0
def cf(date_dir, atmfile, filters):
    """
	Call above functions to calculate cf and plot them
	"""
    # Read atmfile
    molecules, p, T, abundances = mat.readatm(atmfile)
    nlayers = len(p)

    # Read tau.dat
    file = date_dir + 'tau.dat'
    tau, wns = readTauDat(file, nlayers)

    # Calculate BB, reverse the order of p and T
    p = p[::-1]
    T = T[::-1]
    BB = Planck(T, wns)

    # Call cf_eq() to calculate cf
    cf = cf_eq(BB, p, tau, nlayers, wns)

    # Call filter_cf() to calculate cf
    filt_cf, filt_cf_norm = filter_cf(filters, nlayers, wns, cf)

    ############ Plotting ################

    print("  Plotting contribution functions.\n")
    # Not normalized cf
    plt.figure(4)
    plt.clf()
    gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
    ax0 = plt.subplot(gs[0])
    for i in np.arange(len(filt_cf)):
        (head, tail) = os.path.split(filters[i])
        lbl = tail[:-4]
        ax0.semilogy(filt_cf[i], p, '-', linewidth=1, label=lbl)
    ax0.legend(loc='center left', bbox_to_anchor=(1.0, 0.5), prop={'size': 8})
    ax0.set_ylim(max(p), min(p))
    ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
    ax0.set_xlabel('Contribution functions', fontsize=14)
    ax0.set_ylabel('Pressure [bar]', fontsize=14)
    plt.savefig(date_dir + 'ContrFuncs.png')

    # Normalized cf
    plt.figure(5)
    plt.clf()
    gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
    ax0 = plt.subplot(gs[0])
    for i in np.arange(len(filt_cf_norm)):
        (head, tail) = os.path.split(filters[i])
        lbl = tail[:-4]
        ax0.semilogy(filt_cf_norm[i], p, '--', linewidth=1, label=lbl)

    ax0.legend(loc='center left', bbox_to_anchor=(1, 0.5), prop={'size': 8})
    ax0.set_ylim(max(p), min(p))
    ax0.set_xlim(0, 1.0)
    ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
    ax0.set_xlabel('Normalized contribution functions', fontsize=14)
    ax0.set_ylabel('Pressure [bar]', fontsize=14)
    plt.savefig(date_dir + 'NormContrFuncs.png')
Beispiel #3
0
def transmittance(date_dir, atmfile, filters, fext='.png', plot=True):
    """
  """
    # Read atmfile
    molecules, p, T, abundances = mat.readatm(date_dir + atmfile)
    nlayers = len(p)
    p = p[::-1]  # top to bottom of the atmosphere
    # Read tau.dat
    foo = date_dir + 'tau.dat'
    tau, wns = readTauDat(foo, nlayers)
    # Transmittance:
    transmit = np.exp(-tau)
    # Band intgrate it:
    filt_tr = filter_cf(filters, nlayers, wns, transmit)
    nfilters = len(filters)

    meanwl = np.zeros(nfilters)
    for i in np.arange(nfilters):
        filtwaven, filttransm = w.readfilter(filters[i])
        meanwn = np.sum(filtwaven * filttransm) / np.sum(filttransm)
        meanwl[i] = 1e4 / meanwn
    maxmeanwl = np.max(meanwl)
    minmeanwl = np.min(meanwl)
    colors = (meanwl - minmeanwl) / (maxmeanwl - minmeanwl)

    if plot:
        print("  Plotting contribution functions.\n")
        # Not normalized cf
        plt.figure(4, figsize=(8, 6.5))
        plt.clf()
        gs = gridspec.GridSpec(1, 2, width_ratios=[20, 1], wspace=0.05)
        ax0 = plt.subplot(gs[0])
        ax1 = plt.subplot(gs[1])
        for i in np.arange(nfilters):
            (head, tail) = os.path.split(filters[i])
            lbl = tail[:-4]
            ax0.semilogy(filt_tr[i],
                         p,
                         '-',
                         color=plt.cm.rainbow(colors[i]),
                         linewidth=1,
                         label=lbl)
        norm = matplotlib.colors.Normalize(vmin=minmeanwl, vmax=maxmeanwl)
        cbar = matplotlib.colorbar.ColorbarBase(ax1,
                                                cmap=plt.cm.rainbow,
                                                norm=norm,
                                                orientation='vertical')
        cbar.set_label("Mean Wavelength (\u00b5m)", fontsize=14)
        ax0.set_ylim(max(p), min(p))
        ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
        ax0.set_xlabel('Transmittance', fontsize=14)
        ax0.set_ylabel('Pressure (bar)', fontsize=14)
        plt.savefig(date_dir + 'Transmittance' + fext, bbox_inches='tight')
        plt.close()

    return filt_tr[:, ::-1]
Beispiel #4
0
def plotabun(date_dir, atmfile, molfit, fext='.png', fs=15):
    '''
    Plot abundance profiles from best fit run.

    Input
    -----
    date_dir: string
      Path to BART output directory

    atmfile: string
      Name of best fit atmospheric file

    molfit:  1D string array
      Molecules to plot

    fext: string
      File extension for the plots to be saved.
      Options: .png, .pdf
      Default: .png

    fs: int
       Font size for plots.
    '''
    # Import best fit atmosphere results
    species, pressure, temp, abundances = mat.readatm(date_dir + atmfile)

    # Create array of indices for species to plot
    molfitindex = np.zeros(len(molfit), dtype='int')

    k = 0
    # Find the index of each species within the atmosphere file
    for i in range(len(species)):
        for j in range(len(molfit)):
            if species[i] == molfit[j]:
                molfitindex[k] = i
                k += 1

    plt.clf()

    # Plot the abundance profile of each species
    for i in range(len(molfit)):
        plt.loglog(abundances[:,molfitindex[i]], pressure,
                   label=species[molfitindex[i]], linewidth=4)

    plt.legend(loc='upper left')
    plt.xlabel('Molar Mixing Fraction', fontsize=fs)
    plt.ylabel('Pressure (bar)', fontsize=fs)
    plt.ylim(np.amin(pressure), np.amax(pressure))
    plt.title('Best Fit Abundance Profiles')
    plt.gca().invert_yaxis()
    plt.savefig(date_dir + 'abun_profiles' + fext, bbox_inches='tight')
Beispiel #5
0
def transmittance(date_dir, atmfile, filters, plot=True):
    """
  """
    # Read atmfile
    molecules, p, T, abundances = mat.readatm(date_dir + atmfile)
    nlayers = len(p)
    p = p[::-1]  # top to bottom of the atmosphere
    # Read tau.dat
    foo = date_dir + 'tau.dat'
    tau, wns = readTauDat(foo, nlayers)
    # Transmittance:
    transmit = np.exp(-tau)
    # Band intgrate it:
    filt_tr = filter_cf(filters, nlayers, wns, transmit)
    nfilters = len(filters)

    colors = plt.cm.rainbow(np.asarray(np.linspace(0, 255, nfilters), np.int))
    if plot:
        print("  Plotting contribution functions.\n")
        # Not normalized cf
        plt.figure(4)
        plt.clf()
        gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
        ax0 = plt.subplot(gs[0])
        colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
        ax0.set_prop_cycle(plt.cycler('color', colormap))
        for i in np.arange(len(filt_tr)):
            (head, tail) = os.path.split(filters[i])
            lbl = tail[:-4]
            ax0.semilogy(filt_tr[i],
                         p,
                         '-',
                         linewidth=1.5,
                         label=lbl,
                         color=colors[i])
        lgd = ax0.legend(loc='center left',
                         bbox_to_anchor=(1.0, 0.5),
                         ncol=nfilters // 30 + 1,
                         prop={'size': 8})
        ax0.set_ylim(max(p), min(p))
        ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
        ax0.set_xlabel('Transmittance', fontsize=14)
        ax0.set_ylabel('Pressure (bar)', fontsize=14)
        plt.savefig(date_dir + 'Transmittance.png')

    return filt_tr[:, ::-1]
Beispiel #6
0
def plotabun(date_dir, atmfile, molfit):
    '''
    Plot abundance profiles from best fit run.

    Input
    -----
    date_dir: string
      Path to BART output directory
    
    atmfile: string
      Name of best fit atmospheric file

    molfit:  1D string array
      Molecules to plot
    '''

    # Import best fit atmosphere results
    species, pressure, temp, abundances = mat.readatm(date_dir + atmfile)

    # Create array of indices for species to plot 
    molfitindex = np.zeros(len(molfit), dtype='int')

    k = 0

    # Find the index of each species within the atmosphere file
    for i in range(len(species)):
        for j in range(len(molfit)):
            if species[i] == molfit[j]:
                molfitindex[k] = i
                k += 1

    plt.clf()

    # Plot the abundance profile of each species
    for i in range(len(molfit)):
        plt.loglog(abundances[:,molfitindex[i]], pressure, label=species[molfitindex[i]], linewidth=4)

    plt.legend(loc='upper left')
    plt.xlabel('Molar Mixing Fraction')
    plt.ylabel('Pressure (bars)')
    plt.title('Best Fit Abundance Profiles')

    plt.gca().invert_yaxis()
    
    plt.savefig(date_dir + 'abun_profiles.png')
Beispiel #7
0
def transmittance(date_dir, atmfile, filters, plot=True):
  """
  """
  # Read atmfile
  molecules, p, T, abundances = mat.readatm(date_dir + atmfile)
  nlayers = len(p)
  p = p[::-1]  # top to bottom of the atmosphere
  # Read tau.dat
  foo      = date_dir + 'tau.dat'
  tau, wns = readTauDat(foo, nlayers)
  # Transmittance:
  transmit = np.exp(-tau)
  # Band intgrate it:
  filt_tr  = filter_cf(filters, nlayers, wns, transmit)
  nfilters = len(filters)

  colors = plt.cm.rainbow(np.asarray(np.linspace(0, 255, nfilters), np.int))
  if plot:
    print("  Plotting contribution functions.\n")
    # Not normalized cf
    plt.figure(4)
    plt.clf()
    gs       = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
    ax0      = plt.subplot(gs[0])
    colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
    ax0.set_prop_cycle(plt.cycler('color', colormap))
    for i in np.arange(len(filt_tr)):
      (head, tail) = os.path.split(filters[i])
      lbl         = tail[:-4]
      ax0.semilogy(filt_tr[i], p, '-', linewidth = 1.5, label=lbl,
                   color=colors[i])
    lgd = ax0.legend(loc='center left', bbox_to_anchor=(1.0, 0.5), 
                     ncol=nfilters//30 + 1, prop={'size':8})
    ax0.set_ylim(max(p), min(p))
    ax0.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
    ax0.set_xlabel('Transmittance', fontsize=14)
    ax0.set_ylabel('Pressure (bar)' , fontsize=14)
    plt.savefig(date_dir + 'Transmittance.png')

  return filt_tr[:,::-1]
Beispiel #8
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)
Beispiel #9
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 #10
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)
def cf(date_dir, atmfile, filters, plot=True, fs=15):
    """
  Call above functions to calculate cf and plot them
  """
    # Read atmfile
    molecules, p, T, abundances = mat.readatm(date_dir + atmfile)
    nlayers = len(p)

    # Read tau.dat
    foo = date_dir + 'tau.dat'
    tau, wns = readTauDat(foo, nlayers)

    # Calculate BB, reverse the order of p and T
    p = p[::-1]
    T = T[::-1]
    BB = Planck(T, wns)

    # Call cf_eq() to calculate cf
    cf = cf_eq(BB, p, tau, nlayers, wns)

    # Call filter_cf() to calculate cf
    filt_cf, filt_cf_norm = filter_cf(filters,
                                      nlayers,
                                      wns,
                                      cf,
                                      normalize=True)
    nfilters = len(filters)

    meanwl = np.zeros(nfilters)
    for i in np.arange(nfilters):
        filtwaven, filttransm = w.readfilter(filters[i])
        meanwn = np.sum(filtwaven * filttransm) / np.sum(filttransm)
        meanwl[i] = 1e4 / meanwn
    maxmeanwl = np.max(meanwl)
    minmeanwl = np.min(meanwl)
    colors = (meanwl - minmeanwl) / (maxmeanwl - minmeanwl)

    if plot:
        print("  Plotting contribution functions.\n")
        # Not normalized cf
        plt.figure(4)
        plt.clf()
        gs = gridspec.GridSpec(1, 2, width_ratios=[20, 1], wspace=0.05)
        ax0 = plt.subplot(gs[0])
        ax1 = plt.subplot(gs[1])
        for i in np.arange(len(filt_cf)):
            (head, tail) = os.path.split(filters[i])
            lbl = tail[:-4]
            ax0.semilogy(filt_cf[i],
                         p,
                         '-',
                         color=plt.cm.rainbow(colors[i]),
                         linewidth=1,
                         label=lbl)
        norm = matplotlib.colors.Normalize(vmin=minmeanwl, vmax=maxmeanwl)
        cbar = matplotlib.colorbar.ColorbarBase(ax1,
                                                cmap=plt.cm.rainbow,
                                                norm=norm,
                                                orientation='vertical')
        cbar.set_label("Mean Wavelength (\u00b5m)", fontsize=fs)
        cbar.ax.tick_params(labelsize=fs - 4)
        ax0.set_ylim(max(p), min(p))
        ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
        ax0.set_xlabel('Contribution Functions', fontsize=fs)
        ax0.set_ylabel('Pressure (bar)', fontsize=fs)
        plt.xticks(size=fs - 4)
        plt.yticks(size=fs - 4)
        plt.savefig(date_dir + 'ContrFuncs.png', bbox_inches='tight')

        # Normalized cf
        plt.figure(5, figsize=(8, 6.5))
        plt.clf()
        gs = gridspec.GridSpec(1, 2, width_ratios=[20, 1], wspace=0.05)
        ax0 = plt.subplot(gs[0])
        ax1 = plt.subplot(gs[1])
        for i in np.arange(len(filt_cf_norm)):
            (head, tail) = os.path.split(filters[i])
            lbl = tail[:-4]
            ax0.semilogy(filt_cf_norm[i],
                         p,
                         '--',
                         color=plt.cm.rainbow(colors[i]),
                         linewidth=1,
                         label=lbl)
        norm = matplotlib.colors.Normalize(vmin=minmeanwl, vmax=maxmeanwl)
        cbar = matplotlib.colorbar.ColorbarBase(ax1,
                                                cmap=plt.cm.rainbow,
                                                norm=norm,
                                                orientation='vertical')
        cbar.set_label("Mean Wavelength (\u00b5m)", fontsize=fs)
        cbar.ax.tick_params(labelsize=fs - 4)
        ax0.set_ylim(max(p), min(p))
        ax0.set_xlim(0, 1.0)
        ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
        ax0.set_xlabel('Normalized Contribution Functions', fontsize=fs)
        ax0.set_ylabel('Pressure (bar)', fontsize=fs)
        plt.xticks(size=fs - 4)
        plt.yticks(size=fs - 4)
        plt.savefig(date_dir + 'NormContrFuncs.png', bbox_inches='tight')

    return filt_cf[:, ::-1], filt_cf_norm[:, ::-1]
Beispiel #12
0
def cf(date_dir, atmfile, filters, plot=True):
  """
  Call above functions to calculate cf and plot them
  """
  # Read atmfile
  molecules, p, T, abundances = mat.readatm(date_dir + atmfile)
  nlayers = len(p)

  # Read tau.dat
  foo      = date_dir + 'tau.dat'
  tau, wns = readTauDat(foo, nlayers)

  # Calculate BB, reverse the order of p and T
  p = p[::-1]
  T = T[::-1]
  BB = Planck(T, wns)

  # Call cf_eq() to calculate cf
  cf = cf_eq(BB, p, tau, nlayers, wns)

  # Call filter_cf() to calculate cf
  filt_cf, filt_cf_norm = filter_cf(filters, nlayers, wns, cf, normalize=True)

  if plot:
    print("  Plotting contribution functions.\n")
    # Not normalized cf
    plt.figure(4)
    plt.clf()
    gs       = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
    ax0      = plt.subplot(gs[0])
    colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
    ax0.set_prop_cycle(plt.cycler('color', colormap))
    for i in np.arange(len(filt_cf)):
      (head, tail) = os.path.split(filters[i])
      lbl          = tail[:-4]
      ax0.semilogy(filt_cf[i], p, '-', linewidth = 1, label=lbl)
    lgd = ax0.legend(loc='center left', bbox_to_anchor=(1.0, 0.5), 
                     ncol=len(filt_cf)//30 + 1, prop={'size':8})
    ax0.set_ylim(max(p), min(p))
    ax0.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
    ax0.set_xlabel('Contribution Functions', fontsize=14)
    ax0.set_ylabel('Pressure (bar)' , fontsize=14)
    plt.savefig(date_dir + 'ContrFuncs.png', bbox_extra_artists=(lgd,), 
                bbox_inches='tight')

    # Normalized cf
    plt.figure(5)
    plt.clf()
    gs       = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
    ax0      = plt.subplot(gs[0])
    colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
    ax0.set_prop_cycle(plt.cycler('color', colormap))
    for i in np.arange(len(filt_cf_norm)):
      (head, tail) = os.path.split(filters[i])
      lbl          = tail[:-4]
      ax0.semilogy(filt_cf_norm[i], p, '--', linewidth = 1, label=lbl)

    lgd = ax0.legend(loc='center left', bbox_to_anchor=(1,0.5), 
                     ncol=len(filt_cf)//30 + 1, prop={'size':8})
    ax0.set_ylim(max(p), min(p))
    ax0.set_xlim(0, 1.0)
    ax0.ticklabel_format(style='sci', axis='x', scilimits=(0,0))
    ax0.set_xlabel('Normalized Contribution Functions', fontsize=14)
    ax0.set_ylabel('Pressure (bar)' , fontsize=14)
    plt.savefig(date_dir + 'NormContrFuncs.png', bbox_extra_artists=(lgd,), 
                bbox_inches='tight')

  return filt_cf[:,::-1], filt_cf_norm[:,::-1]
    'xtick.labelsize': 14,
    'ytick.labelsize': 14,
})

# 4 mol uniform
atmfile = './7species_7opac_uniform/bestFit.atm'
params = np.array([
    -0.6, -0.4, 0.0, 0.0, 1.09, -1.07, -1.168, 1.784, -1.749, -3.0, 3.0, -4.5
])
logfile = './7species_7opac_uniform/MCMC.log'
stepsize = np.array(
    [0.01, 0.01, 0.0, 0.0, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01])
MCMCdata = './7species_7opac_uniform/output.npy'

# read atmfile
molecules, pressure, temp, abundances = mat.readatm(atmfile)
# get surface gravity
grav, Rp = mat.get_g(tep_name)
# convert gravity to cm/s^2
grav = grav * 1e2
# get star data
R_star, T_star, sma, gstar = bf.get_starData(tep_name)
# get best parameters
bestP, uncer = bf.read_MCMC_out(logfile)
# get all params
allParams = bf.get_params(bestP, stepsize, params)
# get PTparams and abundances factors
nparams = len(allParams)
nmol = len(molfit)
nPTparams = nparams - nmol
PTparams = allParams[:nPTparams]
Beispiel #14
0
def cf(date_dir, atmfile, filters, plot=True):
    """
  Call above functions to calculate cf and plot them
  """
    # Read atmfile
    molecules, p, T, abundances = mat.readatm(date_dir + atmfile)
    nlayers = len(p)

    # Read tau.dat
    foo = date_dir + 'tau.dat'
    tau, wns = readTauDat(foo, nlayers)

    # Calculate BB, reverse the order of p and T
    p = p[::-1]
    T = T[::-1]
    BB = Planck(T, wns)

    # Call cf_eq() to calculate cf
    cf = cf_eq(BB, p, tau, nlayers, wns)

    # Call filter_cf() to calculate cf
    filt_cf, filt_cf_norm = filter_cf(filters,
                                      nlayers,
                                      wns,
                                      cf,
                                      normalize=True)

    if plot:
        print("  Plotting contribution functions.\n")
        # Not normalized cf
        plt.figure(4)
        plt.clf()
        gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
        ax0 = plt.subplot(gs[0])
        colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
        ax0.set_prop_cycle(plt.cycler('color', colormap))
        for i in np.arange(len(filt_cf)):
            (head, tail) = os.path.split(filters[i])
            lbl = tail[:-4]
            ax0.semilogy(filt_cf[i], p, '-', linewidth=1, label=lbl)
        lgd = ax0.legend(loc='center left',
                         bbox_to_anchor=(1.0, 0.5),
                         ncol=len(filt_cf) // 30 + 1,
                         prop={'size': 8})
        ax0.set_ylim(max(p), min(p))
        ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
        ax0.set_xlabel('Contribution Functions', fontsize=14)
        ax0.set_ylabel('Pressure (bar)', fontsize=14)
        plt.savefig(date_dir + 'ContrFuncs.png',
                    bbox_extra_artists=(lgd, ),
                    bbox_inches='tight')

        # Normalized cf
        plt.figure(5)
        plt.clf()
        gs = gridspec.GridSpec(1, 2, width_ratios=[5, 1])
        ax0 = plt.subplot(gs[0])
        colormap = plt.cm.rainbow(np.linspace(0, 1, len(filters)))
        ax0.set_prop_cycle(plt.cycler('color', colormap))
        for i in np.arange(len(filt_cf_norm)):
            (head, tail) = os.path.split(filters[i])
            lbl = tail[:-4]
            ax0.semilogy(filt_cf_norm[i], p, '--', linewidth=1, label=lbl)

        lgd = ax0.legend(loc='center left',
                         bbox_to_anchor=(1, 0.5),
                         ncol=len(filt_cf) // 30 + 1,
                         prop={'size': 8})
        ax0.set_ylim(max(p), min(p))
        ax0.set_xlim(0, 1.0)
        ax0.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
        ax0.set_xlabel('Normalized Contribution Functions', fontsize=14)
        ax0.set_ylabel('Pressure (bar)', fontsize=14)
        plt.savefig(date_dir + 'NormContrFuncs.png',
                    bbox_extra_artists=(lgd, ),
                    bbox_inches='tight')

    return filt_cf[:, ::-1], filt_cf_norm[:, ::-1]
Beispiel #15
0
def get_widths(cfile):
  """
  Calculate the max and min Lorentz and Doppler broadening HWHM for
  the given configuration file.

  Parameters:
  -----------
  cfile: String
     A BART configuration file.
  """

  # Read config:
  config = ConfigParser.SafeConfigParser()
  config.optionxform = str  # This one enable Uppercase in arguments
  config.read([cfile])
  defaults = dict(config.items("MCMC"))

  # Get min-max wavenumber:
  try:
    wnmin = 1.0/(float(defaults["wlhigh"])*float(defaults["wlfct"]))
  except:
    wnmin = float(defaults["wnlow"]) * float(defaults["wnfct"])
  try:
    wnmax = 1.0/(float(defaults["wllow"])*float(defaults["wlfct"]))
  except:
    wnmax = float(defaults["wnhigh"]) * float(defaults["wnfct"])

  # Read atmospheric file:
  molecs, pressure, temps, abun = ma.readatm(defaults["atmfile"])

  # Get min-max temperatures:
  try:
    tmin = float(defaults["tlow"])
  except:
    tmin = np.amin(temps)
  try:
    tmax = float(defaults["thigh"])
  except:
    tmax = np.amax(temps)

  # Get min-max pressures: 
  pmin = np.amin(pressure) * 1e6
  pmax = np.amax(pressure) * 1e6

  # Get masses:
  molfile = scriptsdir + "/../modules/transit/inputs/molecules.dat"
  ID, mol, mass, diam = readmol(molfile)

  # Keep only molecules from the atmospheric file:
  mask = np.zeros(len(mol), int)
  for i in np.arange(len(mol)):
    mask[i] = mol[i] in molecs

  mol  = mol [np.where(mask)]
  mass = mass[np.where(mask)] * sc.u * 1e3  # grams
  diam = diam[np.where(mask)] * sc.angstrom * 100  # cm

  # Sort molecules according to the order in the atmospheric file:
  isort = np.zeros(len(mol), int)
  for i in np.arange(len(mol)):
    isort[i] = np.where(np.asarray(mol) == molecs[i])[0][0]
  mol  = mol [isort]
  mass = mass[isort]
  diam = diam[isort]

  # Calculate minimum and maximum Doppler widths:
  dmin = Doppler(wnmin, tmin, np.amin(mass))
  dmax = Doppler(wnmax, tmax, np.amax(mass))

  iH2 = np.where(mol == 'H2')[0]
  iHe = np.where(mol == 'He')[0]

  # Calculate minimum and maximum Lorentz widths:
  lmin = Lorentz(pmin, tmax, mass, iH2, iHe, abun[-1], diam, True)
  lmax = Lorentz(pmax, tmin, mass, iH2, iHe, abun[ 0], diam, False)

  print("Doppler minimum and maximum HWHM (cm-1): {:.3e}, {:.3e}\n"
        "Lorentz minimum and maximum HWHM (cm-1): {:.3e}, {:.3e}".
        format(dmin, dmax, lmin, lmax))
Beispiel #16
0
def main(comm):
  """
  This is a hacked version of MC3's func.py.
  This function directly call's the modeling function for the BART project.

  Modification History:
  ---------------------
  2014-04-19  patricio  Initial implementation.  [email protected]
  2014-06-25  patricio  Added support for inner-MPI loop.
  """
  # Parse arguments:
  cparser = argparse.ArgumentParser(description=__doc__, add_help=False,
                         formatter_class=argparse.RawDescriptionHelpFormatter)
  # Add config file option:
  cparser.add_argument("-c", "--config_file", 
                       help="Configuration file", metavar="FILE")
  # Remaining_argv contains all other command-line-arguments:
  args, remaining_argv = cparser.parse_known_args()

  # Get parameters from configuration file:
  cfile = args.config_file
  if cfile:
    config = ConfigParser.SafeConfigParser()
    config.optionxform = str
    config.read([cfile])
    defaults = dict(config.items("MCMC"))
  else:
    defaults = {}
  parser = argparse.ArgumentParser(parents=[cparser])
  parser.add_argument("--func",      dest="func",      type=mu.parray, 
                                     action="store",  default=None)
  parser.add_argument("--indparams", dest="indparams", type=mu.parray, 
                                     action="store",   default=[])
  parser.add_argument("--params",    dest="params",    type=mu.parray,
                                     action="store",   default=None,
                      help="Model-fitting parameters [default: %(default)s]")
  parser.add_argument("--molfit",    dest="molfit",    type=mu.parray,
                                     action="store",   default=None,
                      help="Molecules fit [default: %(default)s]")
  parser.add_argument("--Tmin",      dest="Tmin",      type=float,
                      action="store",  default=400.0,
                      help="Lower Temperature boundary [default: %(default)s]")
  parser.add_argument("--Tmax",      dest="Tmax",      type=float,
                      action="store",  default=3000.0,
                      help="Higher Temperature boundary [default: %(default)s]")
  parser.add_argument("--quiet",             action="store_true",
                      help="Set verbosity level to minimum",
                      dest="quiet")
  # Input-Converter Options:
  group = parser.add_argument_group("Input Converter Options")
  group.add_argument("--atmospheric_file",  action="store",
                     help="Atmospheric file [default: %(default)s]",
                     dest="atmfile", type=str,    default=None)
  group.add_argument("--PTtype",            action="store",
                     help="PT profile type.",
                     dest="PTtype",  type=str,    default="none")
                     #choices=('line', 'madhu'))
  group.add_argument("--tint",              action="store",
                     help="Internal temperature of the planet [default: "
                     "%(default)s].",
                     dest="tint",    type=float,  default=100.0)
  # transit Options:
  group = parser.add_argument_group("transit Options")
  group.add_argument("--config",  action="store",
                     help="transit configuration file [default: %(default)s]",
                     dest="config", type=str,    default=None)
  # Output-Converter Options:
  group = parser.add_argument_group("Output Converter Options")
  group.add_argument("--filter",                 action="store",
                     help="Waveband filter name [default: %(default)s]",
                     dest="filter",   type=mu.parray, default=None)
  group.add_argument("--tep_name",          action="store",
                     help="A TEP file [default: %(default)s]",
                     dest="tep_name", type=str,    default=None)
  group.add_argument("--kurucz_file",           action="store",
                     help="Stellar Kurucz file [default: %(default)s]",
                     dest="kurucz",   type=str,       default=None)
  group.add_argument("--solution",                    action="store",
                     help="Solution geometry [default: %(default)s]",
                     dest="solution", type=str,       default="None",
                     choices=('transit', 'eclipse'))

  parser.set_defaults(**defaults)
  args2, unknown = parser.parse_known_args(remaining_argv)

  # Quiet all threads except rank 0:
  rank = comm.Get_rank()
  verb = rank == 0

  # Get (Broadcast) the number of parameters and iterations from MPI:
  array1 = np.zeros(2, np.int)
  mu.comm_bcast(comm, array1)
  npars, niter = array1

  # :::::::  Initialize the Input converter ::::::::::::::::::::::::::
  atmfile  = args2.atmfile
  molfit   = args2.molfit
  PTtype   = args2.PTtype
  params   = args2.params
  tepfile  = args2.tep_name
  tint     = args2.tint
  Tmin     = args2.Tmin
  Tmax     = args2.Tmax
  solution = args2.solution  # Solution type

  # Extract necessary values from the TEP file:
  tep = rd.File(tepfile)
  # Stellar temperature in K:
  tstar = float(tep.getvalue('Ts')[0])
  # Stellar radius (in meters):
  rstar = float(tep.getvalue('Rs')[0]) * c.Rsun
  # Semi-major axis (in meters):
  sma   = float(tep.getvalue( 'a')[0]) * sc.au
  # Planetary radius (in meters):
  rplanet = float(tep.getvalue('Rp')[0]) * c.Rjup
  # Planetary mass (in kg):
  mplanet = float(tep.getvalue('Mp')[0]) * c.Mjup

  # Number of fitting parameters:
  nfree   = len(params)                 # Total number of free parameters
  nmolfit = len(molfit)                 # Number of molecular free parameters
  nradfit = int(solution == 'transit')  # 1 for transit, 0 for eclipse
  nPT     = nfree - nmolfit - nradfit   # Number of PT free parameters

  # Read atmospheric file to get data arrays:
  species, pressure, temp, abundances = mat.readatm(atmfile)
  # Reverse pressure order (for PT to work):
  pressure = pressure[::-1]
  nlayers  = len(pressure)   # Number of atmospheric layers
  nspecies = len(species)    # Number of species in the atmosphere
  mu.msg(verb, "There are {:d} layers and {:d} species.".format(nlayers,
                                                                nspecies))
  # Find index for Hydrogen and Helium:
  species = np.asarray(species)
  iH2     = np.where(species=="H2")[0]
  iHe     = np.where(species=="He")[0]
  # Get H2/He abundance ratio:
  ratio = (abundances[:,iH2] / abundances[:,iHe]).squeeze()
  # Find indices for the metals:
  imetals = np.where((species != "He") & (species != "H2"))[0]
  # Index of molecular abundances being modified:
  imol = np.zeros(nmolfit, dtype='i')
  for i in np.arange(nmolfit):
    imol[i] = np.where(np.asarray(species) == molfit[i])[0]

  # Pressure-Temperature profile:
  PTargs = [PTtype]
  if PTtype == "line":
    # Planetary surface gravity (in cm s-2):
    gplanet = 100.0 * sc.G * mplanet / rplanet**2
    # Additional PT arguments:
    PTargs += [rstar, tstar, tint, sma, gplanet]

  # Allocate arrays for receiving and sending data to master:
  freepars = np.zeros(nfree,                 dtype='d')
  profiles = np.zeros((nspecies+1, nlayers), dtype='d')
  # This are sub-sections of profiles, containing just the temperature and
  # the abundance profiles, respectively:
  tprofile  = profiles[0, :]
  aprofiles = profiles[1:,:]

  # Store abundance profiles:
  for i in np.arange(nspecies):
    aprofiles[i] = abundances[:, i]

  # :::::::  Spawn transit code  :::::::::::::::::::::::::::::::::::::
  # # transit configuration file:
  transitcfile = args2.tconfig
 
  # FINDME: Find a way to set verb to the transit subprocesses.
  # Silence all threads except rank 0:
  # if verb == 0:
  #   rargs = ["--quiet"]
  # else:
  #   rargs = []

  # Initialize the transit python module:
  transit_args = ["transit", "-c", transitcfile]
  trm.transit_init(len(transit_args), transit_args)

  # Get wavenumber array from transit:
  nwave  = trm.get_no_samples()
  specwn = trm.get_waveno_arr(nwave)

  # :::::::  Output Converter  :::::::::::::::::::::::::::::::::::::::
  ffile    = args2.filter    # Filter files
  kurucz   = args2.kurucz    # Kurucz file

  # Log10(stellar gravity)
  gstar = float(tep.getvalue('loggstar')[0])
  # Planet-to-star radius ratio:
  rprs  = rplanet / rstar
  mu.msg(verb, "OCON FLAG 10: {}, {}, {}".format(tstar, gstar, rprs))

  nfilters = len(ffile)  # Number of filters:

  # FINDME: Separate filter/stellar interpolation?
  # Get stellar model:
  starfl, starwn, tmodel, gmodel = w.readkurucz(kurucz, tstar, gstar)
  # Read and resample the filters:
  nifilter  = [] # Normalized interpolated filter
  istarfl   = [] # interpolated stellar flux
  wnindices = [] # wavenumber indices used in interpolation
  for i in np.arange(nfilters):
    # Read filter:
    filtwaven, filttransm = w.readfilter(ffile[i])
    # Check that filter boundaries lie within the spectrum wn range:
    if filtwaven[0] < specwn[0] or filtwaven[-1] > specwn[-1]:
      mu.exit(message="Wavenumber array ({:.2f} - {:.2f} cm-1) does not "
              "cover the filter[{:d}] wavenumber range ({:.2f} - {:.2f} "
              "cm-1).".format(specwn[0], specwn[-1], i, filtwaven[0],
                                                        filtwaven[-1]))

    # Resample filter and stellar spectrum:
    nifilt, strfl, wnind = w.resample(specwn, filtwaven, filttransm,
                                              starwn,    starfl)
    mu.msg(verb, "OCON FLAG 67: mean star flux: %.3e"%np.mean(strfl))
    nifilter.append(nifilt)
    istarfl.append(strfl)
    wnindices.append(wnind)

  # Allocate arrays for receiving and sending data to master:
  spectrum = np.zeros(nwave,    dtype='d')
  bandflux = np.zeros(nfilters, dtype='d')

  # Allocate array to receive parameters from MPI:
  params = np.zeros(npars, np.double)

  # ::::::  Main MCMC Loop  ::::::::::::::::::::::::::::::::::::::::::
  # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  while niter >= 0:
    niter -= 1
    # Receive parameters from MCMC:
    mu.comm_scatter(comm, params)
    #mu.msg(verb, "ICON FLAG 71: incon pars: {:s}".
    #             format(str(params).replace("\n", "")))

    # Input converter calculate the profiles:
    try:
      tprofile[:] = pt.PT_generator(pressure, params[0:nPT], PTargs)[::-1]
    except ValueError:
      mu.msg(verb, 'Input parameters give non-physical profile.')
      # FINDME: what to do here?

    # If the temperature goes out of bounds:
    if np.any(tprofile < Tmin) or np.any(tprofile > Tmax):
      print("Out of bounds")
      mu.comm_gather(comm, -np.ones(nfilters), MPI.DOUBLE)
      continue

    #mu.msg(verb, "T pars: \n{}\n".format(PTargs))
    mu.msg(verb-20, "Temperature profile: {}".format(tprofile))
    # Scale abundance profiles:
    for i in np.arange(nmolfit):
      m = imol[i]
      # Use variable as the log10:
      aprofiles[m] = abundances[:, m] * 10.0**params[nPT+nradfit+i]
    # Update H2, He abundances so sum(abundances) = 1.0 in each layer:
    q = 1.0 - np.sum(aprofiles[imetals], axis=0)
    aprofiles[iH2] = ratio * q / (1.0 + ratio)
    aprofiles[iHe] =         q / (1.0 + ratio)
    # print("qH2O: {}, Qmetals: {}, QH2: {}  p: {}".format(params[nPT],
    #                               q[50], profiles[iH2+1,50], profiles[:,50]))

    # Set the 'surface' level:
    if solution == "transit":
      trm.set_radius(params[nPT])

    if rank == 1:
      print("Iteration: {:05}".format(niter))
    # Let transit calculate the model spectrum:
    spectrum = trm.run_transit(profiles.flatten(), nwave)

    # Output converter band-integrate the spectrum:
    # Calculate the band-integrated intensity per filter:
    for i in np.arange(nfilters):
      if   solution == "eclipse":
        fluxrat = (spectrum[wnindices[i]]/istarfl[i]) * rprs*rprs
        bandflux[i] = w.bandintegrate(fluxrat, specwn,
                                      nifilter[i], wnindices[i])
      elif solution == "transit":
        bandflux[i] = w.bandintegrate(spectrum[wnindices[i]], specwn,
                                      nifilter[i], wnindices[i])

    # Send resutls back to MCMC:
    #mu.msg(verb, "OCON FLAG 95: Flux band integrated ({})".format(bandflux))
    #mu.msg(verb, "{}".format(params[nPT:]))
    mu.comm_gather(comm, bandflux, MPI.DOUBLE)
    #mu.msg(verb, "OCON FLAG 97: Sent results back to MCMC")

  # ::::::  End main Loop  :::::::::::::::::::::::::::::::::::::::::::
  # ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

  # Close communications and disconnect:
  mu.comm_disconnect(comm)
  mu.msg(verb, "FUNC FLAG 99: func out")

  # Close the transit communicators:
  trm.free_memory()
  mu.msg(verb, "FUNC FLAG OUT ~~ 100 ~~")
Beispiel #17
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)