def get_starData(tepfile):
    """
    Extract the Stellar temperature, radius, and mass from a TEP file.

    Parameters
    ----------
    tepfile: string. Path to Transiting ExoPlanet (TEP) file.

    Returns
    -------
    Rstar: float. Radius of the star in meters.
    Tstar: float. Temperature of the star in Kelvin.
    sma  : float. Semimajor axis in meters.
    gstar: float. Logarithm of the star's surface gravity in cgs units.
    """
    # Open tepfile to read and get data:
    tep = rd.File(tepfile)

    # Get star temperature in Kelvin:
    Tstar = np.float(tep.getvalue('Ts')[0])

    # Get star radius in MKS units:
    Rstar = np.float(tep.getvalue('Rs')[0]) * c.Rsun

    # Get semi major axis in meters:
    sma = np.float(tep.getvalue('a')[0]) * sc.au

    # Get star loggstar:
    gstar = np.float(tep.getvalue('loggstar')[0])

    return Rstar, Tstar, sma, gstar
Exemple #2
0
def initialPT2(date_dir, params, pressfile, mode, PTfunc, tepfile, tint=100.0):
  """
  Compute a Temperature profile.

  Parameters:
  -----------
  params: 1D Float ndarray
    Array of fitting parameters.
  pressfile: String
    File name of the pressure array.
  mode: String
    Chose the PT model: 'madhu' or 'line'.
  tepfile: String
    Filename of the planet's TEP file.
  tint: Float
    Internal planetary temperature.
  """
  # Read pressures from file:
  pressure = pt.read_press_file(pressfile)

  # For extra PT arguments:
  PTargs = None

  # Read the TEP file:
  tep = rd.File(tepfile)
  # Stellar radius (in meters):
  rstar = float(tep.getvalue('Rs')[0]) * c.Rsun
  # Stellar temperature in K:
  tstar = float(tep.getvalue('Ts')[0])
  # 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

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

  # Calculate temperature
  Temp =  pt.PT_generator(pressure, params, PTfunc, PTargs)

  # Plot PT profile
  plt.figure(1)
  plt.semilogy(Temp, pressure, '-', color = 'r')
  plt.xlim(0.9*min(Temp), 1.1*max(Temp))
  plt.ylim(max(pressure), min(pressure))
  plt.title('Initial PT Line', fontsize=14)
  plt.xlabel('T (K)'     , fontsize=14)
  plt.ylabel('logP (bar)', fontsize=14)

  # Save plot to current directory
  plt.savefig(date_dir + 'InitialPT.png') 

  return Temp
Exemple #3
0
def planet_Teff(tepfile):
    '''
     Calculates planetary effective temperature. Calls tep reader 
     and gets data needed for effective temperature calculation.
     The effective temperature is calculated assuming zero albedo, and 
     zero redistribution to the night side, i.e uniform dayside 
     redistribution.

     Parameters
     ----------
     tepfile: string
           Name of the tep ASCII file.
 
     Returns
     -------
     Teff: float
           Effective temperature of the planet. 

     Revisions
     ---------
     2014-04-05   Jasmina    Written by.
     2014-08-15   Patricio   Added source for the radius of the sun.
     '''

    # Opens tepfile to read and get data
    tep = rd.File(tepfile)

    # Get stellar temperature in K
    stellarT = tep.getvalue('Ts')
    Tstar = np.float(stellarT[0])

    # Get stellar radius in units of Rsun
    stellarR = tep.getvalue('Rs')
    Rstar = np.float(stellarR[0])

    # Get semimajor axis in AU
    semimajor = tep.getvalue('a')
    a = np.float(semimajor[0])

    # Sun radius in meters:
    # Source: http://nssdc.gsfc.nasa.gov/planetary/factsheet/sunfact.html
    Rsun = 696000000.0  # m

    # Radius fo the star and semimajor axis in m
    Rstar = Rstar * Rsun  # m
    a = a * sc.au  # m

    # Effective temperature of the planet
    # Teff^4 = Teff*^4 * f * (Rstar/a)^2 * (1-A)
    # Zero albedo, no energy redistribution to the night side A=0, f=1/2
    Teff = Tstar * (Rstar / a)**0.5 * (1. / 2.)**0.25

    return Teff
Exemple #4
0
def get_starData(tepfile):
    """
    Extract the Stellar temperature, radius, and mass from a TEP file.
    """
    # Open tepfile to read and get data:
    tep = rd.File(tepfile)

    # Get star mass in Mjup:
    Tstar = np.float(tep.getvalue('Ts')[0])

    # Get star radius in MKS units:
    Rstar = np.float(tep.getvalue('Rs')[0]) * c.Rsun

    # Get semi major axis in meters:
    sma = np.float(tep.getvalue('a')[0]) * sc.au

    # Get star loggstar:
    gstar = np.float(tep.getvalue('loggstar')[0])

    return Rstar, Tstar, sma, gstar
Exemple #5
0
def get_g(tepfile):
    '''
  Calculates planetary surface gravity. Calls tep reader and
  gets data needed for calculation (g = G*M/r^2). Returns
  surface gravity and surface radius.

  Parameters
  ----------
  tepfile: String
     Name of the tep ASCII file.

  Returns
  -------
  g: Float
     The planet surface gravity in m/s^2.
  Rp: Float
     The planet radius in km.

  Revisions
  ---------
  2014-06-11  Jasmina   Written by.
  2014-08-15  Patricio  Updated docstring.  Got NASA Jupiter values.
  '''
    # Open tepfile to read and get data:
    tep = rd.File(tepfile)

    # Get planet mass in kg:
    Mplanet = np.float(tep.getvalue('Mp')[0]) * c.Mjup
    # Get planet radius in m:
    Rplanet = np.float(tep.getvalue('Rp')[0]) * c.Rjup

    # Calculate the planet surface gravity in m/s^2:
    g = sc.G * Mplanet / (Rplanet**2)
    # Return Rp in km:
    Rp = Rplanet / 1000.0

    return g, Rp
Exemple #6
0
def makeTransit(cfile, tepfile, shareOpacity):
    """
  Make the transit configuration file.

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

    # Known transit arguments:
    known_args = [
        "radlow", "radhigh", "raddelt", "radfct", "wllow", "wlhigh", "wlfct",
        "wnlow", "wnhigh", "wndelt", "wnfct", "wnosamp", "tlow", "thigh",
        "tempdelt", "allowq", "nwidth", "opacityfile", "molfile", "toomuch",
        "tauiso", "outtau", "taulevel", "modlevel", "starrad", "transparent",
        "solution", "raygrid", "gsurf", "refpress", "refradius", "cloudrad",
        "cloudfct", "cloudext", "verb", "savefiles", "outtoomuch", "outsample",
        "outspec", "outintens", "linedb", "csfile", "orbpars", "orbparsfct"
    ]

    # Name of the configuration-file section:
    section = "MCMC"
    # Read BART configuration file:
    Bconfig = ConfigParser()
    Bconfig.read([cfile])

    # Keyword names of the arguments in the BART configuration file:
    args = Bconfig.options(section)

    # transit configuration filename:
    tcfile = open(Bconfig.get(section, "tconfig"), "w")

    # Keyword for the atmospheric file is different in transit:
    tcfile.write("atm {:s}\n".format(Bconfig.get(section, "atmfile")))

    # Default molfile path:
    if "molfile" not in args:
        tcfile.write("molfile {:s}\n".format(
            os.path.realpath(
                os.path.join(filedir, "..", "modules", "transit", "inputs",
                             "molecules.dat"))))

    # Calculate gsurf and refradius from the tepfile:
    tep = rd.File(tepfile)
    mplanet = float(tep.getvalue('Mp')[0]) * c.Mjup
    rplanet = float(tep.getvalue('Rp')[0]) * c.Rjup

    # Planetary radius reference level in km:
    Bconfig.set(section, "refradius", "{:.2f}".format(rplanet * 1e-3))
    # Planetary surface gravity in cm/s2:
    Bconfig.set(section, "gsurf",
                "{:.1f}".format(100 * sc.G * mplanet / rplanet**2))
    # Add these keywords:
    args = np.union1d(args, ["refradius", "gsurf"])

    # Reformat the cross-section inputs for Transit:
    cs = Bconfig.get(section, "csfile")
    Bconfig.set(section, "csfile", ",".join(cs.split()))

    # Print the known arguments to file:
    for key in np.intersect1d(args, known_args):
        # FINDME: Why am I splitting?
        values = Bconfig.get(section, key).split("\n")
        # Allow for no CIA file to be specified
        if not (key == 'csfile' and len(values) == 1 and values[0] == ''):
            for val in values:
                tcfile.write("{:s} {:s}\n".format(key, val))

    if shareOpacity:
        tcfile.write("shareOpacity \n")
    tcfile.close()
Exemple #7
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.
  """
    # 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")
    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("--filters",
                       action="store",
                       help="Waveband filter name [default: %(default)s]",
                       dest="filters",
                       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

    # Dictionary of functions to calculate temperature for PTtype
    PTfunc = {
        'iso': pt.PT_iso,
        'line': pt.PT_line,
        'madhu_noinv': pt.PT_NoInversion,
        'madhu_inv': pt.PT_Inversion
    }

    # 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") & \
                       (species != "H-") & (species != 'e-'))[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:
    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]
    else:
        PTargs = None

    # 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

    # 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.filters  # Filter files
    kurucz = args2.kurucz  # Kurucz file

    # Log10(stellar gravity)
    gstar = float(tep.getvalue('loggstar')[0])
    # Planet-to-star radius ratio:
    rprs = rplanet / rstar

    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)
        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)

        # Check for the MCMC-end flag:
        if params[0] == np.inf:
            break

        # Input converter calculate the profiles:
        try:
            tprofile[:] = pt.PT_generator(pressure, params[0:nPT],
                                          PTfunc[PTtype], 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):
            mu.comm_gather(comm, -np.ones(nfilters), MPI.DOUBLE)
            continue
        # 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)
        if np.any(q < 0.0):
            mu.comm_gather(comm, -np.ones(nfilters), MPI.DOUBLE)
            continue
        aprofiles[iH2] = ratio * q / (1.0 + ratio)
        aprofiles[iHe] = q / (1.0 + ratio)

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

        # Let transit calculate the model spectrum:
        spectrum = trm.run_transit(profiles.flatten(), nwave)

        # 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.comm_gather(comm, bandflux, MPI.DOUBLE)

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

    # Close communications and disconnect:
    mu.comm_disconnect(comm)
    trm.free_memory()