def fortney_download(): """Download the fortney grid data""" fortney_data = os.path.join(get_env_variables()['fortgrid_dir'], 'fortney_grid.db') return send_file(fortney_data, attachment_filename='fortney_grid.db', as_attachment=True)
def fortney_grid(args, write_plot=False, write_table=False): """ Function to grab a Fortney Grid model, plot it, and make a table. Parameters ---------- args : dict Dictionary of arguments for the Fortney Grid. Must include : temp chem cloud pmass m_unit reference_radius r_unit rstar rstar_unit write_plot : bool, optional Whether or not to save the bokeh plot, defaults to False. write_table : bool, optional Whether or not to save the ascii table, defaults to False. Returns ------- fig : bokeh object The unsaved bokeh plot. fh : ascii table object The unsaved ascii table. temp_out : list of str of int The list of temperatures in the model grid. """ utils.check_for_data('fortney') # Check for Fortney Grid database print( os.path.join(utils.get_env_variables()['exoctk_data'], 'fortney/fortney_models.db')) try: db = create_engine( 'sqlite:///' + os.path.join(utils.get_env_variables()['exoctk_data'], 'fortney/fortney_models.db')) header = pd.read_sql_table('header', db) except: raise Exception( 'Fortney Grid File Path is incorrect, or not initialized') if args: rstar = float(args['rstar']) rstar = (rstar * u.Unit(args['rstar_unit'])).to(u.km) reference_radius = float(args['reference_radius']) rplan = (reference_radius * u.Unit(args['r_unit'])).to(u.km) temp = float(args['temp']) # clouds cloud = args['cloud'] if cloud.find('flat') != -1: flat = int(cloud[4:]) ray = 0 elif cloud.find('ray') != -1: ray = int(cloud[3:]) flat = 0 elif int(cloud) == 0: flat = 0 ray = 0 else: flat = 0 ray = 0 print('No cloud parameter not specified, default no clouds added') # chemistry chem = args['chem'] if chem == 'noTiO': noTiO = True if chem == 'eqchem': noTiO = False # grid does not allow clouds for cases with TiO flat = 0 ray = 0 fort_grav = 25.0 * u.m / u.s**2 df = header.loc[(header.gravity == fort_grav) & (header.temp == temp) & (header.noTiO == noTiO) & (header.ray == ray) & (header.flat == flat)] wave_planet = np.array( pd.read_sql_table(df['name'].values[0], db)['wavelength'])[::-1] r_lambda = np.array( pd.read_sql_table(df['name'].values[0], db)['radius']) * u.km # All fortney models have fixed 1.25 radii z_lambda = r_lambda - (1.25 * u.R_jup).to(u.km) # Scale with planetary mass pmass = float(args['pmass']) mass = (pmass * u.Unit(args['m_unit'])).to(u.kg) # Convert radius to m for gravity units gravity = constants.G * (mass) / (rplan.to(u.m))**2.0 # Scale lambbda (this technically ignores the fact that scaleheight # is altitude dependent) therefore, it will not be valide for very # very low gravities z_lambda = z_lambda * fort_grav / gravity # Create new wavelength dependent R based on scaled ravity r_lambda = z_lambda + rplan # Finally compute (rp/r*)^2 flux_planet = np.array(r_lambda**2 / rstar**2) x = wave_planet y = flux_planet[::-1] else: df = pd.read_sql_table('t1000g25_noTiO', db) x, y = df['wavelength'], df['radius']**2.0 / 7e5**2.0 tab = at.Table(data=[x, y]) fh = io.StringIO() tab.write(fh, format='ascii.no_header') if write_table: tab.write('fortney.dat', format='ascii.no_header') fig = figure(plot_width=1100, plot_height=400) fig.line(x, 1e6 * (y - np.mean(y)), color='Black', line_width=0.5) fig.xaxis.axis_label = 'Wavelength (um)' fig.yaxis.axis_label = 'Rel. Transit Depth (ppm)' if write_plot: output_file('fortney.html') save(fig) # Return temperature list for the fortney grid page temp_out = list(map(str, header.temp.unique())) return fig, fh, temp_out
def generic_grid(input_args, write_plot=False, write_table=False): """ Build a plot and table from the generic grid results. Parameters ---------- input_args : dict A dictionary of the form output from the generic grid form. If manual input must include : r_star : The radius of the star. r_planet : The radius of the planet. gravity : The gravity. temperature : The temperature. condensation : local or rainout metallicity c_o : carbon/oxygen ratio haze cloud write_plot : bool, optional Whether to write the plot out. Defaults to False. write_table : bool, optional Whether to write the table out. Defaults to Fals. Returns ------- plot : bokeh object Unsaved bokeh plot. table : ascii table object Unsaved ascii table. closest_match : dict A dictionary with the parameters/model name of the closest match in the grid. error_message : str An error message, or lack therof. """ utils.check_for_data('generic') # Find path to the database. database_path = os.path.join(utils.get_env_variables()['exoctk_data'], 'generic/generic_grid_db.hdf5') # Build rescaled model solution, inputs, closest_match, error_message = rescale_generic_grid( input_args, database_path) # Build file out tab = at.Table(data=[solution['wv'], solution['spectra']]) fh = io.StringIO() tab.write(fh, format='ascii.no_header') if write_table: tab.write('generic.dat') # Plot fig = figure(title='Rescaled Generic Grid Transmission Spectra'.upper(), plot_width=1100, plot_height=400) fig.x_range.start = 0.3 fig.x_range.end = 5 fig.line(solution['wv'], solution['spectra'], color='Black', line_width=1) fig.xaxis.axis_label = 'Wavelength (um)' fig.yaxis.axis_label = 'Transit Depth (Rp/R*)^2' if write_plot: output_file('generic.html') save(fig) return fig, fh, closest_match, error_message
from exoctk.utils import filter_table, get_env_variables, get_target_data, get_canonical_name from exoctk.modelgrid import ModelGrid from exoctk.phase_constraint_overlap.phase_constraint_overlap import phase_overlap_constraint, calculate_pre_duration import log_exoctk from svo_filters import svo # FLASK SET UP app_exoctk = Flask(__name__) # define the cache config keys, remember that it can be done in a settings file app_exoctk.config['CACHE_TYPE'] = 'null' app_exoctk.config['SECRET_KEY'] = 'Thisisasecret!' # Load the database to log all form submissions if get_env_variables()['exoctklog_dir'] is None: dbpath = ':memory:' else: dbpath = os.path.realpath( os.path.join(get_env_variables()['exoctklog_dir'], 'exoctk_log.db')) if not os.path.isfile(dbpath): log_exoctk.create_db(dbpath) try: DB = log_exoctk.load_db(dbpath) except IOError: DB = None # Redirect to the index @app_exoctk.route('/') @app_exoctk.route('/index')
class LimbDarkeningForm(BaseForm): """Form validation for the limb_darkening tool""" # Model grid modelgrid_dir = get_env_variables()['modelgrid_dir'] default_modelgrid = os.path.join(modelgrid_dir, 'ATLAS9/') mg = ModelGrid(default_modelgrid, resolution=500) teff_rng = mg.Teff_vals.min(), mg.Teff_vals.max() logg_rng = mg.logg_vals.min(), mg.logg_vals.max() feh_rng = mg.FeH_vals.min(), mg.FeH_vals.max() modeldir = RadioField( 'modeldir', default=default_modelgrid, choices=[(os.path.join(modelgrid_dir, 'ATLAS9/'), 'Kurucz ATLAS9'), (os.path.join(modelgrid_dir, 'ACES/'), 'Phoenix ACES')], validators=[InputRequired('A model grid is required!')]) # Stellar parameters teff = DecimalField( 'teff', default=3500, validators=[ InputRequired('An effective temperature is required!'), NumberRange( min=float(teff_rng[0]), max=float(teff_rng[1]), message= 'Effective temperature must be between {} and {} for this model grid' .format(*teff_rng)) ]) logg = DecimalField( 'logg', default=4.5, validators=[ InputRequired('A surface gravity is required!'), NumberRange( min=float(logg_rng[0]), max=float(logg_rng[1]), message= 'Surface gravity must be between {} and {} for this model grid' .format(*logg_rng)) ]) feh = DecimalField( 'feh', default=0.0, validators=[ InputRequired('A surface gravity is required!'), NumberRange( min=float(feh_rng[0]), max=float(feh_rng[1]), message= 'Metallicity must be between {} and {} for this model grid'. format(*feh_rng)) ]) mu_min = DecimalField('mu_min', default=0.1, validators=[ InputRequired('A minimum mu value is required!'), NumberRange( min=0.0, max=1.0, message='Minimum mu must be between 0 and 1') ]) # LD profile profiles = MultiCheckboxField( 'profiles', choices=[(x, x) for x in PROFILES], validators=[InputRequired('At least one profile is required!')]) # Bandpass default_filter = 'Kepler.K' defilt = svo.Filter(default_filter) bandpass = SelectField('bandpass', default=default_filter, choices=[('tophat', 'Top Hat')] + [(filt, filt) for filt in FILTERS_LIST], validators=[InputRequired('A filter is required!')]) wave_min = DecimalField( 'wave_min', default=defilt.wave_min.value, validators=[ NumberRange( min=0, max=30, message='Minimum wavelength must be between 0 and 30 microns!') ]) wave_max = DecimalField( 'wave_max', default=defilt.wave_max.value, validators=[ NumberRange( min=0, max=30, message='Maximum wavelength must be between 0 and 30 microns!') ]) n_bins = IntegerField('n_bins', default=1) # Form submits calculate_submit = SubmitField('Calculate Coefficients') filter_submit = SubmitField('Filter Selected') modelgrid_submit = SubmitField('Model Grid Selected')
class LimbDarkeningForm(BaseForm): """Form validation for the limb_darkening tool""" # Model grid modelgrid_dir = get_env_variables()['modelgrid_dir'] default_modelgrid = os.path.join(modelgrid_dir, 'ATLAS9/') mg = ModelGrid(default_modelgrid, resolution=500) teff_rng = mg.Teff_vals.min(), mg.Teff_vals.max() logg_rng = mg.logg_vals.min(), mg.logg_vals.max() feh_rng = mg.FeH_vals.min(), mg.FeH_vals.max() modeldir = RadioField( 'modeldir', default=default_modelgrid, choices=[(os.path.join(modelgrid_dir, 'ATLAS9/'), 'Kurucz ATLAS9'), (os.path.join(modelgrid_dir, 'ACES/'), 'Phoenix ACES')], validators=[InputRequired('A model grid is required!')]) # Stellar parameters teff = DecimalField( 'teff', default=3500, validators=[ InputRequired('An effective temperature is required!'), NumberRange( min=float(teff_rng[0]), max=float(teff_rng[1]), message= 'Effective temperature must be between {} and {} for this model grid' .format(*teff_rng)) ]) logg = DecimalField( 'logg', default=4.5, validators=[ InputRequired('A surface gravity is required!'), NumberRange( min=float(logg_rng[0]), max=float(logg_rng[1]), message= 'Surface gravity must be between {} and {} for this model grid' .format(*logg_rng)) ]) feh = DecimalField( 'feh', default=0.0, validators=[ InputRequired('A surface gravity is required!'), NumberRange( min=float(feh_rng[0]), max=float(feh_rng[1]), message= 'Metallicity must be between {} and {} for this model grid'. format(*feh_rng)) ]) mu_min = DecimalField('mu_min', default=0.1, validators=[ InputRequired('A minimum mu value is required!'), NumberRange( min=0.0, max=1.0, message='Minimum mu must be between 0 and 1') ]) # Planet parameters td_rng = [0, 50] transit_duration = DecimalField( 'transit_duration', default='', validators=[ Optional(), NumberRange( min=int(td_rng[0]), max=int(td_rng[1]), message='Transit duration must be between {} and {}'.format( *td_rng)) ]) op_rng = [0, 1000] orbital_period = DecimalField( 'orbital_period', default='', validators=[ Optional(), NumberRange( min=int(op_rng[0]), max=int(op_rng[1]), message='Orbital period must be between {} and {}'.format( *op_rng)) ]) rp_rng = [0, 1] rp_rs = DecimalField( 'rp_rs', default='', validators=[ Optional(), NumberRange( min=int(rp_rng[0]), max=int(rp_rng[1]), message='Planet radius must be between {} and {}'.format( *rp_rng)) ]) a_rng = [0, 100] a_rs = DecimalField( 'a_rs', default='', validators=[ Optional(), NumberRange( min=int(a_rng[0]), max=int(a_rng[1]), message='Semi-major axis must be between {} and {}'.format( *a_rng)) ]) inc_rng = [0, 180] inclination = DecimalField( 'inclination', default='', validators=[ Optional(), NumberRange(min=int(inc_rng[0]), max=int(inc_rng[1]), message='Inclination must be between {} and {}'.format( *inc_rng)) ]) ecc_rng = [0, 1] eccentricity = DecimalField( 'eccentricity', default='', validators=[ Optional(), NumberRange( min=int(ecc_rng[0]), max=int(ecc_rng[1]), message='Eccentricity must be between {} and {}'.format( *ecc_rng)) ]) w_rng = [0, 360] omega = DecimalField( 'omega', default='', validators=[ Optional(), NumberRange( min=int(w_rng[0]), max=int(w_rng[1]), message='Omega must be between {} and {}'.format(*w_rng)) ]) # LD profile profiles = MultiCheckboxField( 'profiles', choices=[(x, x) for x in PROFILES], validators=[InputRequired('At least one profile is required!')]) # Bandpass default_filter = 'NIRSpec.CLEAR.PRISM.S200A1' defilt = Throughput(default_filter) bandpass = SelectField('bandpass', default=default_filter, choices=[('tophat', 'Top Hat')] + [(filt, filt) for filt in FILTERS_LIST], validators=[InputRequired('A filter is required!')]) wave_min = DecimalField( 'wave_min', default=defilt.wave_min.value, validators=[ NumberRange( min=0, max=30, message='Minimum wavelength must be between 0 and 30 microns!') ]) wave_max = DecimalField( 'wave_max', default=defilt.wave_max.value, validators=[ NumberRange( min=0, max=30, message='Maximum wavelength must be between 0 and 30 microns!') ]) n_bins = IntegerField('n_bins', default=30) # Form submits calculate_submit = SubmitField('Calculate Coefficients') filter_submit = SubmitField('Filter Selected') modelgrid_submit = SubmitField('Model Grid Selected')
from exoctk.throughputs import Throughput from matplotlib.backends.backend_pdf import PdfPages from svo_filters import svo # FLASK SET UP app_exoctk = Flask(__name__) # define the cache config keys, remember that it can be done in a settings file app_exoctk.config['CACHE_TYPE'] = 'null' app_exoctk.config['SECRET_KEY'] = 'Thisisasecret!' # Load the database to log all form submissions if get_env_variables()['exoctklog_dir'] is None: dbpath = ':memory:' else: dbpath = os.path.realpath(os.path.join(get_env_variables()['exoctklog_dir'], 'exoctk_log.db')) if not os.path.isfile(dbpath): log_exoctk.create_db(dbpath) try: DB = log_exoctk.load_db(dbpath) except IOError: DB = None # Redirect to the index @app_exoctk.route('/') @app_exoctk.route('/index') def index():