def limb_darkening(): """The limb darkening form page. """ # Load default form form = fv.LimbDarkeningForm() # Reload page with stellar data from ExoMAST if form.resolve_submit.data: if form.targname.data.strip() != '': try: # Resolve the target in exoMAST form.targname.data = get_canonical_name(form.targname.data) data, target_url = get_target_data(form.targname.data) # Update the form data form.feh.data = data.get('Fe/H') form.teff.data = data.get('Teff') form.logg.data = data.get('stellar_gravity') form.target_url.data = str(target_url) except: form.target_url.data = '' form.targname.errors = [ "Sorry, could not resolve '{}' in exoMAST.".format( form.targname.data) ] # Send it back to the main page return render_template('limb_darkening.html', form=form) # Reload page with appropriate filter data if form.filter_submit.data: kwargs = {} if form.bandpass.data == 'tophat': kwargs['n_bins'] = 1 kwargs['pixels_per_bin'] = 100 kwargs['wave_min'] = 1 * u.um kwargs['wave_max'] = 2 * u.um # Get the filter bandpass = svo.Filter(form.bandpass.data, **kwargs) # Update the form data form.wave_min.data = bandpass.wave_min.value form.wave_max.data = bandpass.wave_max.value # Send it back to the main page return render_template('limb_darkening.html', form=form) # Update validation values after a model grid is selected if form.modelgrid_submit.data: # Load the modelgrid mg = ModelGrid(form.modeldir.data, 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() # Update the validation parameters by setting validator attributes setattr(form.teff.validators[1], 'min', teff_rng[0]) setattr(form.teff.validators[1], 'max', teff_rng[1]) setattr( form.teff.validators[1], 'message', 'Effective temperature must be between {} and {}'.format( *teff_rng)) setattr(form.logg.validators[1], 'min', logg_rng[0]) setattr(form.logg.validators[1], 'max', logg_rng[1]) setattr(form.logg.validators[1], 'message', 'Surface gravity must be between {} and {}'.format(*logg_rng)) setattr(form.feh.validators[1], 'min', feh_rng[0]) setattr(form.feh.validators[1], 'max', feh_rng[1]) setattr(form.feh.validators[1], 'message', 'Metallicity must be between {} and {}'.format(*feh_rng)) # Send it back to the main page return render_template('limb_darkening.html', form=form) # Validate form and submit for results if form.validate_on_submit() and form.calculate_submit.data: # Get the stellar parameters star_params = [ float(form.teff.data), float(form.logg.data), float(form.feh.data) ] # Log the form inputs try: log_exoctk.log_form_input(request.form, 'limb_darkening', DB) except: pass # Load the model grid model_grid = ModelGrid(form.modeldir.data, resolution=500) form.modeldir.data = [ j for i, j in form.modeldir.choices if i == form.modeldir.data ][0] # Grism details if '.G' in form.bandpass.data.upper( ) and 'GAIA' not in form.bandpass.data.upper(): kwargs = { 'n_bins': form.n_bins.data, 'pixels_per_bin': form.n_pix.data, 'wl_min': form.wave_min.data * u.um, 'wl_max': form.wave_max.data * u.um } else: kwargs = {} # Make filter object and plot bandpass = svo.Filter(form.bandpass.data, **kwargs) bp_name = bandpass.name bk_plot = bandpass.plot(draw=False) bk_plot.plot_width = 580 bk_plot.plot_height = 280 js_resources = INLINE.render_js() css_resources = INLINE.render_css() filt_script, filt_plot = components(bk_plot) # Trim the grid to nearby grid points to speed up calculation full_rng = [ model_grid.Teff_vals, model_grid.logg_vals, model_grid.FeH_vals ] trim_rng = find_closest(full_rng, star_params, n=1, values=True) # Calculate the coefficients for each profile ld = lf.LDC(model_grid) for prof in form.profiles.data: ld.calculate(*star_params, prof, mu_min=float(form.mu_min.data), bandpass=bandpass) # Draw a figure for each wavelength bin tabs = [] for wav in np.unique(ld.results['wave_eff']): # Plot it TOOLS = 'box_zoom, box_select, crosshair, reset, hover' fig = figure(tools=TOOLS, x_range=Range1d(0, 1), y_range=Range1d(0, 1), plot_width=800, plot_height=400) ld.plot(wave_eff=wav, fig=fig) # Plot formatting fig.legend.location = 'bottom_right' fig.xaxis.axis_label = 'mu' fig.yaxis.axis_label = 'Intensity' tabs.append(Panel(child=fig, title=str(wav))) final = Tabs(tabs=tabs) # Get HTML script, div = components(final) # Store the tables as a string file_as_string = str(ld.results[[ c for c in ld.results.dtype.names if ld.results.dtype[c] != object ]]) # Make a table for each profile with a row for each wavelength bin profile_tables = [] for profile in form.profiles.data: # Make LaTeX for polynomials latex = lf.ld_profile(profile, latex=True) poly = '\({}\)'.format(latex).replace('*', '\cdot').replace('\e', 'e') # Make the table into LaTeX table = filter_table(ld.results, profile=profile) co_cols = [ c for c in ld.results.colnames if (c.startswith('c') or c.startswith('e')) and len(c) == 2 and not np.all([np.isnan(i) for i in table[c]]) ] table = table[['wave_min', 'wave_max'] + co_cols] table.rename_column('wave_min', '\(\lambda_\mbox{min}\hspace{5px}(\mu m)\)') table.rename_column('wave_max', '\(\lambda_\mbox{max}\hspace{5px}(\mu m)\)') # Add the results to the lists html_table = '\n'.join(table.pformat(max_width=500, html=True))\ .replace('<table', '<table id="myTable" class="table table-striped table-hover"') # Add the table title header = '<br></br><strong>{}</strong><br><p>\(I(\mu)/I(\mu=1)\) = {}</p>'.format( profile, poly) html_table = header + html_table profile_tables.append(html_table) return render_template('limb_darkening_results.html', form=form, table=profile_tables, script=script, plot=div, file_as_string=repr(file_as_string), filt_plot=filt_plot, filt_script=filt_script, js=js_resources, css=css_resources) return render_template('limb_darkening.html', form=form)
def contam_visibility(): """The contamination and visibility form page""" # Load default form form = fv.ContamVisForm() form.calculate_contam_submit.disabled = False if request.method == 'GET': # http://0.0.0.0:5000/contam_visibility?ra=24.354208334287005&dec=-45.677930555343636&target=WASP-18%20b target_name = request.args.get('target') form.targname.data = target_name ra = request.args.get('ra') form.ra.data = ra dec = request.args.get('dec') form.dec.data = dec return render_template('contam_visibility.html', form=form) # Reload page with stellar data from ExoMAST if form.resolve_submit.data: if form.targname.data.strip() != '': # Resolve the target in exoMAST try: form.targname.data = get_canonical_name(form.targname.data) data, url = get_target_data(form.targname.data) # Update the coordinates ra_deg = data.get('RA') dec_deg = data.get('DEC') # Set the form values form.ra.data = ra_deg form.dec.data = dec_deg form.target_url.data = url except: form.target_url.data = '' form.targname.errors = [ "Sorry, could not resolve '{}' in exoMAST.".format( form.targname.data) ] # Send it back to the main page return render_template('contam_visibility.html', form=form) # Reload page with appropriate mode data if form.mode_submit.data: # Update the button if form.inst.data != 'NIRISS': form.calculate_contam_submit.disabled = True else: form.calculate_contam_submit.disabled = False # Send it back to the main page return render_template('contam_visibility.html', form=form) if form.validate_on_submit() and (form.calculate_submit.data or form.calculate_contam_submit.data): try: # Log the form inputs try: log_exoctk.log_form_input(request.form, 'contam_visibility', DB) except: pass # Make plot title = form.targname.data or ', '.join( [form.ra.data, form.dec.data]) pG, pB, dates, vis_plot, table = vpa.using_gtvt( str(form.ra.data), str(form.dec.data), form.inst.data.split(' ')[0]) # Make output table vers = '0.3' today = datetime.datetime.now() fh = StringIO() fh.write('# Hi! This is your Visibility output file for... \n') fh.write('# Target: {} \n'.format(form.targname.data)) fh.write('# Instrument: {} \n'.format(form.inst.data)) fh.write('# \n') fh.write( '# This file was generated using ExoCTK v{} on {} \n'.format( vers, today)) fh.write('# Visit our GitHub: https://github.com/ExoCTK/exoctk \n') fh.write('# \n') table.write(fh, format='csv', delimiter=',') visib_table = fh.getvalue() # Format x axis day0 = datetime.date(2019, 6, 1) dtm = datetime.timedelta(days=367) #vis_plot.x_range = Range1d(day0, day0 + dtm) # TODO: Fix this so bad PAs are included pB = [] # Make plot TOOLS = 'crosshair, reset, hover, save' fig = figure(tools=TOOLS, plot_width=800, plot_height=400, x_axis_type='datetime', title=title) fh = StringIO() table.write(fh, format='ascii') visib_table = fh.getvalue() # Format x axis day0 = datetime.date(2019, 6, 1) dtm = datetime.timedelta(days=367) # Get scripts vis_js = INLINE.render_js() vis_css = INLINE.render_css() vis_script, vis_div = components(vis_plot) # Contamination plot too if form.calculate_contam_submit.data: # First convert ra and dec to HH:MM:SS ra_deg, dec_deg = float(form.ra.data), float(form.dec.data) sc = SkyCoord(ra_deg, dec_deg, unit='deg') ra_dec = sc.to_string('hmsdms') ra_hms, dec_dms = ra_dec.split(' ')[0], ra_dec.split(' ')[1] # Make field simulation contam_cube = fs.sossFieldSim(ra_hms, dec_dms, binComp=form.companion.data) contam_plot = cf.contam( contam_cube, title, paRange=[int(form.pa_min.data), int(form.pa_max.data)], badPA=pB, fig='bokeh') # Get scripts contam_js = INLINE.render_js() contam_css = INLINE.render_css() contam_script, contam_div = components(contam_plot) else: contam_script = contam_div = contam_js = contam_css = '' return render_template('contam_visibility_results.html', form=form, vis_plot=vis_div, vis_table=visib_table, vis_script=vis_script, vis_js=vis_js, vis_css=vis_css, contam_plot=contam_div, contam_script=contam_script, contam_js=contam_js, contam_css=contam_css) except IOError: #Exception as e: err = 'The following error occurred: ' + str(e) return render_template('groups_integrations_error.html', err=err) return render_template('contam_visibility.html', form=form)
def limb_darkening(): """The limb darkening form page""" # Get all the available filters filters = svo.filters()['Band'] # Make HTML for filters filt_list = '\n'.join(['<option value="{0}"{1}> {0}</option>'.format(b, ' selected' if b == 'Kepler.K' else '') for b in filters]) if request.method == 'POST': if request.form['submit'] == "Retrieve Parameters": target_name = request.form['targetname'] data = get_target_data(target_name) feh = data['Fe/H'] teff = data['Teff'] logg = data['stellar_gravity'] limbVars = {'targname':target_name, 'feh': feh, 'teff':teff, 'logg':logg} return render_template('limb_darkening.html', limbVars=limbVars, filters=filt_list) elif request.form['submit'] == "Calculate Coefficients": # Log the form inputs try: log_exoctk.log_form_input(request.form, 'limb_darkening', DB) except: pass # Get the input from the form modeldir = request.form['modeldir'] profiles = list(filter(None, [request.form.get(pf) for pf in PROFILES])) bandpass = request.form['bandpass'] # protect against injection attempts bandpass = bandpass.replace('<', '<') profiles = [str(p).replace('<', '<') for p in profiles] # Get models from local directory if necessary if modeldir == 'default': modeldir = MODELGRID_DIR # Throw error if input params are invalid try: teff = float(request.form['teff']) logg = float(request.form['logg']) feh = float(request.form['feh']) mu_min = float(request.form['mu_min']) except IOError: teff = str(request.form['teff']).replace('<', '<') logg = str(request.form['logg']).replace('<', '<') feh = str(request.form['feh']).replace('<', '<') message = 'Could not calculate limb darkening for those parameters.' return render_template('limb_darkening_error.html', teff=teff, logg=logg, feh=feh, band=bandpass or 'None', profile=', '.join(profiles), models=modeldir, message=message) n_bins = request.form.get('n_bins') pixels_per_bin = request.form.get('pixels_per_bin') wl_min = request.form.get('wave_min') wl_max = request.form.get('wave_max') model_grid = ModelGrid(modeldir, resolution=500) # No data, redirect to the error page if not hasattr(model_grid, 'data'): message = 'Could not find a model grid to load. Please check the path.' return render_template('limb_darkening_error.html', teff=teff, logg=logg, feh=feh, band=bandpass or 'None', profile=', '.join(profiles), models=model_grid.path, message=message) else: if len(model_grid.data) == 0: message = 'Could not calculate limb darkening with those parameters.' return render_template('limb_darkening_error.html', teff=teff, logg=logg, feh=feh, band=bandpass or 'None', profile=', '.join(profiles), models=model_grid.path, message=message) # Trim the grid to the correct wavelength # to speed up calculations, if a bandpass is given min_max = model_grid.wave_rng try: kwargs = {'n_bins': int(n_bins)} if n_bins else \ {'pixels_per_bin': int(pixels_per_bin)} if pixels_per_bin else\ {} if wl_min and wl_max: kwargs['wl_min'] = float(wl_min) * u.um kwargs['wl_max'] = float(wl_max) * u.um # Make filter object bandpass = svo.Filter(bandpass, **kwargs) bp_name = bandpass.name bk_plot = bandpass.plot(draw=False) bk_plot.plot_width = 580 bk_plot.plot_height = 280 min_max = (bandpass.wave_min.value, bandpass.wave_max.value) n_bins = bandpass.n_bins js_resources = INLINE.render_js() css_resources = INLINE.render_css() filt_script, filt_plot = components(bk_plot) except: message = 'Insufficient filter information. Please complete the form and try again!' return render_template('limb_darkening_error.html', teff=teff, logg=logg, feh=feh, band=bandpass or 'None', profile=', '.join(profiles), models=model_grid.path, message=message) # Trim the grid to nearby grid points to speed up calculation full_rng = [model_grid.Teff_vals, model_grid.logg_vals, model_grid.FeH_vals] trim_rng = find_closest(full_rng, [teff, logg, feh], n=1, values=True) if not trim_rng: message = 'Insufficient models grid points to calculate coefficients.' return render_template('limb_darkening_error.html', teff=teff, logg=logg, feh=feh, band=bp_name, profile=', '.join(profiles), models=model_grid.path, message=message) elif not profiles: message = 'No limb darkening profiles have been selected. Please select at least one.' return render_template('limb_darkening_error.html', teff=teff, logg=logg, feh=feh, band=bp_name, profile=', '.join(profiles), models=model_grid.path, message=message) else: try: model_grid.customize(Teff_rng=trim_rng[0], logg_rng=trim_rng[1], FeH_rng=trim_rng[2], wave_rng=min_max) except: message = 'Insufficient wavelength coverage to calculate coefficients.' return render_template('limb_darkening_error.html', teff=teff, logg=logg, feh=feh, band=bp_name, profile=', '.join(profiles), models=model_grid.path, message=message) # Calculate the coefficients for each profile ld = lf.LDC(model_grid) for prof in profiles: ld.calculate(teff, logg, feh, prof, mu_min=mu_min, bandpass=bandpass) # Draw a figure for each wavelength bin tabs = [] for wav in np.unique(ld.results['wave_eff']): # Plot it TOOLS = 'box_zoom, box_select, crosshair, reset, hover' fig = figure(tools=TOOLS, x_range=Range1d(0, 1), y_range=Range1d(0, 1), plot_width=800, plot_height=400) ld.plot(wave_eff=wav, fig=fig) # Plot formatting fig.legend.location = 'bottom_right' fig.xaxis.axis_label = 'mu' fig.yaxis.axis_label = 'Intensity' tabs.append(Panel(child=fig, title=str(wav))) final = Tabs(tabs=tabs) # Get HTML script, div = components(final) # Store the tables as a string file_as_string = str(ld.results[[c for c in ld.results.dtype.names if ld.results.dtype[c] != object]]) r_eff = mu_eff = '' # Make a table for each profile with a row for each wavelength bin profile_tables = [] for profile in profiles: # Make LaTeX for polynomials latex = lf.ld_profile(profile, latex=True) poly = '\({}\)'.format(latex).replace('*', '\cdot').replace('\e', 'e') # Make the table into LaTeX table = filter_table(ld.results, profile=profile) co_cols = [c for c in ld.results.colnames if (c.startswith('c') or c.startswith('e')) and len(c) == 2 and not np.all([np.isnan(i) for i in table[c]])] table = table[['wave_min', 'wave_max'] + co_cols] table.rename_column('wave_min', '\(\lambda_\mbox{min}\hspace{5px}(\mu m)\)') table.rename_column('wave_max', '\(\lambda_\mbox{max}\hspace{5px}(\mu m)\)') # Add the results to the lists html_table = '\n'.join(table.pformat(max_width=500, html=True))\ .replace('<table', '<table id="myTable" class="table table-striped table-hover"') # Add the table title header = '<br></br><strong>{}</strong><br><p>\(I(\mu)/I(\mu=1)\) = {}</p>'.format(profile, poly) html_table = header + html_table profile_tables.append(html_table) return render_template('limb_darkening_results.html', teff=teff, logg=logg, feh=feh, band=bp_name, mu=mu_eff, profile=', '.join(profiles), r=r_eff, models=model_grid.path, table=profile_tables, script=script, plot=div, file_as_string=repr(file_as_string), filt_plot=filt_plot, filt_script=filt_script, js=js_resources, css=css_resources) return render_template('limb_darkening.html', limbVars={}, filters=filt_list)
def contam_visibility(): """The contamination and visibility form page""" # Load default form form = fv.ContamVisForm() form.calculate_contam_submit.disabled = False if request.method == 'GET': # http://0.0.0.0:5000/contam_visibility?ra=24.354208334287005&dec=-45.677930555343636&target=WASP-18%20b target_name = request.args.get('target') form.targname.data = target_name ra = request.args.get('ra') form.ra.data = ra dec = request.args.get('dec') form.dec.data = dec return render_template('contam_visibility.html', form=form) # Reload page with stellar data from ExoMAST if form.resolve_submit.data: if form.targname.data.strip() != '': # Resolve the target in exoMAST try: form.targname.data = get_canonical_name(form.targname.data) data, url = get_target_data(form.targname.data) # Update the coordinates ra_deg = data.get('RA') dec_deg = data.get('DEC') # Set the form values form.ra.data = ra_deg form.dec.data = dec_deg form.target_url.data = url except Exception: form.target_url.data = '' form.targname.errors = [ "Sorry, could not resolve '{}' in exoMAST.".format( form.targname.data) ] # Send it back to the main page return render_template('contam_visibility.html', form=form) # Reload page with appropriate mode data if form.mode_submit.data: # Update the button if (form.inst.data == 'MIRI') or (form.inst.data == 'NIRSpec'): form.calculate_contam_submit.disabled = True else: form.calculate_contam_submit.disabled = False # Send it back to the main page return render_template('contam_visibility.html', form=form) if form.validate_on_submit() and (form.calculate_submit.data or form.calculate_contam_submit.data): try: # Log the form inputs try: log_exoctk.log_form_input(request.form, 'contam_visibility', DB) except Exception: pass # Make plot title = form.targname.data or ', '.join( [str(form.ra.data), str(form.dec.data)]) pG, pB, dates, vis_plot, table, badPAs = vpa.using_gtvt( str(form.ra.data), str(form.dec.data), form.inst.data.split(' ')[0], targetName=str(title)) # Make output table fh = StringIO() table.write(fh, format='csv', delimiter=',') visib_table = fh.getvalue() # Get scripts vis_js = INLINE.render_js() vis_css = INLINE.render_css() vis_script, vis_div = components(vis_plot) # Contamination plot too if form.calculate_contam_submit.data: # First convert ra and dec to HH:MM:SS ra_deg, dec_deg = float(form.ra.data), float(form.dec.data) sc = SkyCoord(ra_deg, dec_deg, unit='deg') ra_dec = sc.to_string('hmsdms') ra_hms, dec_dms = ra_dec.split(' ')[0], ra_dec.split(' ')[1] # Make field simulation contam_cube = fs.fieldSim(ra_hms, dec_dms, form.inst.data, binComp=form.companion.data) contam_plot = cf.contam( contam_cube, form.inst.data, targetName=str(title), paRange=[int(form.pa_min.data), int(form.pa_max.data)], badPAs=badPAs, fig='bokeh') # Get scripts contam_js = INLINE.render_js() contam_css = INLINE.render_css() contam_script, contam_div = components(contam_plot) else: contam_script = contam_div = contam_js = contam_css = '' return render_template('contam_visibility_results.html', form=form, vis_plot=vis_div, vis_table=visib_table, vis_script=vis_script, vis_js=vis_js, vis_css=vis_css, contam_plot=contam_div, contam_script=contam_script, contam_js=contam_js, contam_css=contam_css) except Exception as e: err = 'The following error occurred: ' + str(e) return render_template('groups_integrations_error.html', err=err) return render_template('contam_visibility.html', form=form)
def contam_visibility(): """The contamination and visibility form page""" # Log the form inputs try: log_exoctk.log_form_input(request.form, 'contam_visibility', DB) except: pass contamVars = {} if request.method == 'POST': tname = request.form['targetname'] contamVars['tname'] = tname contamVars['ra'], contamVars['dec'] = request.form['ra'], request.form['dec'] contamVars['PAmax'] = request.form['pamax'] contamVars['PAmin'] = request.form['pamin'] if request.form['bininfo'] != '': contamVars['binComp'] = list(map(float, request.form['bininfo'].split(', '))) else: contamVars['binComp'] = request.form['bininfo'] radec = ', '.join([contamVars['ra'], contamVars['dec']]) if contamVars['PAmax'] == '': contamVars['PAmax'] = 359 if contamVars['PAmin'] == '': contamVars['PAmin'] = 0 if request.form['submit'] == 'Resolve Target': contamVars['ra'], contamVars['dec'] = resolve.resolve_target(tname) return render_template('contam_visibility.html', contamVars=contamVars) else: try: contamVars['visPA'] = True # Make plot TOOLS = 'crosshair, reset, hover, save' fig = figure(tools=TOOLS, plot_width=800, plot_height=400, x_axis_type='datetime', title=contamVars['tname'] or radec) pG, pB, dates, vis_plot = vpa.checkVisPA(contamVars['ra'], contamVars['dec'], tname, fig=fig) # Format x axis day0 = datetime.date(2019, 6, 1) dtm = datetime.timedelta(days=367) vis_plot.x_range = Range1d(day0, day0 + dtm) # Get scripts vis_js = INLINE.render_js() vis_css = INLINE.render_css() vis_script, vis_div = components(vis_plot) if request.form['submit'] == 'Calculate Visibility and Contamination': contamVars['contam'] = True # Make field simulation contam_cube = fs.sossFieldSim(contamVars['ra'], contamVars['dec'], binComp=contamVars['binComp']) contam_plot = cf.contam(contam_cube, contamVars['tname'] or radec, paRange=[int(contamVars['PAmin']), int(contamVars['PAmax'])], badPA=pB, fig='bokeh') # Get scripts contam_js = INLINE.render_js() contam_css = INLINE.render_css() contam_script, contam_div = components(contam_plot) else: contamVars['contam'] = False contam_script = contam_div = contam_js = contam_css = '' return render_template('contam_visibility_results.html', contamVars=contamVars, vis_plot=vis_div, vis_script=vis_script, vis_js=vis_js, vis_css=vis_css, contam_plot=contam_div, contam_script=contam_script, contam_js=contam_js, contam_css=contam_css) except Exception as e: err = 'The following error occurred: ' + str(e) return render_template('groups_integrations_error.html', err=err) return render_template('contam_visibility.html', contamVars=contamVars)