def SVO_passband(pb, pbzp=None, List = False): """ Read a SVO passband using https://github.com/hover2pi/svo_filters. Parameters ---------- pb : str pysynphot obsmode or obsmode listed in `pbzptmag.txt` pbzp : float, optional AB magnitude zeropoint of the passband List : Bool, optional List all filters available through SVO Returns ------- pb : :py:class:`pysynphot.ArrayBandpass` or :py:class:`pysynphot.obsbandpass.ObsModeBandpass` The passband data. Has ``dtype=[('wave', '<f8'), ('throughput', '<f8')]`` pbzp : float passband AB zeropoint - potentially NaN if this was not supplied. If NaN this can be computed assuming an AB source - i.e. a source with a flux density of 3631 jy has magnitude = 0 in the bandpass. Notes ----- Note that this is a straight read of a single passband from a file. The zeropoint returned is whatever was provided (even if the value is not useful) or NaN. To load the passband and get the correct zeropoint, use :py:func:`source_synphot.passband.load_pbs` See Also -------- :py:func:`astropy.table.Table.read` :py:func:`pysynphot.ObsBandpass` """ from svo_filters import svo from astropy import units as u if List: print(list(svo.filters()['Band'])) if pbzp is None: pbzp = np.nan try: pbdata = svo.Filter(pb) wav = pbdata.wave.to(u.Angstrom).flatten().value wav, ind = np.unique(wav, return_index=True) out = S.ArrayBandpass(wav, pbdata.throughput.flatten()[ind], waveunits='Angstrom', name=pb) except (OSError,IOError) as e: message = 'No passband called {} in SVO'.format(pb) out = None if out is None: raise ValueError(message) return out, pbzp
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]) return render_template('limb_darkening.html', filters=filt_list)
import numpy as np from svo_filters import svo EXOCTK_DATA = os.environ.get('EXOCTK_DATA') MODELGRID_DIR = os.path.join(EXOCTK_DATA, 'modelgrid/') FORTGRID_DIR = os.path.join(EXOCTK_DATA, 'fortney/') EXOCTKLOG_DIR = os.path.join(EXOCTK_DATA, 'exoctk_log/') GENERICGRID_DIR = os.path.join(EXOCTK_DATA, 'generic/') # Supported profiles PROFILES = ['uniform', 'linear', 'quadratic', 'square-root', 'logarithmic', 'exponential', '3-parameter', '4-parameter'] # Supported filters FILTERS = svo.filters() # Set the version VERSION = '0.2' def color_gen(colormap='viridis', key=None, n=10): """Color generator for Bokeh plots Parameters ---------- colormap: str, sequence The name of the color map Returns -------
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)