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