コード例 #1
0
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)
コード例 #2
0
def limb_darkening():
    """Returns the rendered limb darkening form page.

    Returns
    -------
    ``flask.render_template`` obj
        The rendered template for the limb-darkening page.
    """
    # Load default form
    form = fv.LimbDarkeningForm()

    # Planet properties
    planet_properties = [
        'transit_duration', 'orbital_period', 'rp_rs', 'a_rs', 'inclination',
        'eccentricity', 'omega'
    ]

    def empty_fields(form):
        form.transit_duration.data = form.transit_duration.data or ''
        form.orbital_period.data = form.orbital_period.data or ''
        form.rp_rs.data = form.rp_rs.data or ''
        form.a_rs.data = form.a_rs.data or ''
        form.inclination.data = form.inclination.data or ''
        form.eccentricity.data = form.eccentricity.data or ''
        form.omega.data = form.omega.data or ''

        return form

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

                # Update the planet data
                form.transit_duration.data = data.get('transit_duration')
                form.orbital_period.data = data.get('orbital_period')
                form.rp_rs.data = data.get('Rp/Rs')
                form.a_rs.data = data.get('a/Rs')
                form.inclination.data = data.get('inclination')
                form.eccentricity.data = data.get('eccentricity')
                form.omega.data = data.get('omega')

            except Exception:
                form.target_url.data = ''
                form.targname.errors = [
                    "Sorry, could not resolve '{}' in exoMAST.".format(
                        form.targname.data)
                ]

        # Ensure planet fields are not None
        form = empty_fields(form)

        # 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 = Throughput(form.bandpass.data, **kwargs)

        # Update the form data
        form.wave_min.data = bandpass.wave_min.value
        form.wave_max.data = bandpass.wave_max.value

        # Ensure planet fields are not None
        form = empty_fields(form)

        # 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', float(teff_rng[0]))
        setattr(form.teff.validators[1], 'max', float(teff_rng[1]))
        setattr(
            form.teff.validators[1], 'message',
            'Effective temperature must be between {} and {}'.format(
                *teff_rng))
        setattr(form.logg.validators[1], 'min', float(logg_rng[0]))
        setattr(form.logg.validators[1], 'max', float(logg_rng[1]))
        setattr(form.logg.validators[1], 'message',
                'Surface gravity must be between {} and {}'.format(*logg_rng))
        setattr(form.feh.validators[1], 'min', float(feh_rng[0]))
        setattr(form.feh.validators[1], 'max', float(feh_rng[1]))
        setattr(form.feh.validators[1], 'message',
                'Metallicity must be between {} and {}'.format(*feh_rng))

        # Ensure planet fields are not None
        form = empty_fields(form)

        # 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:

        # Form inputs for logging
        form_input = dict(request.form)

        # Get the stellar parameters
        star_params = [
            float(form.teff.data),
            float(form.logg.data),
            float(form.feh.data)
        ]

        # 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
        kwargs = {
            'n_bins': form.n_bins.data,
            'wave_min': form.wave_min.data * u.um,
            'wave_max': form.wave_max.data * u.um
        }

        # Make filter object and plot
        bandpass = Throughput(form.bandpass.data, **kwargs)
        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)

        # Check if spam coefficients can be calculated
        planet_data = {
            param: getattr(form, param).data
            for param in planet_properties
        }
        planet_data['Rp/Rs'] = planet_data['rp_rs']
        planet_data['a/Rs'] = planet_data['a_rs']
        spam_calc = all([
            val is not None and val != '' for key, val in planet_data.items()
        ])
        if spam_calc:

            # Make sure non-linear profile is included for spam calculation if all planet parameters are provided
            if '4-parameter' not in form.profiles.data:
                ld.calculate(*star_params,
                             '4-parameter',
                             mu_min=float(form.mu_min.data),
                             bandpass=bandpass)

            # Calculate spam coeffs
            planet_data = {key: float(val) for key, val in planet_data.items()}
            ld.spam(planet_data=planet_data)

        # Draw tabbed figure
        final = ld.plot_tabs()

        # Get HTML
        script, div = components(final)

        # Store the tables as a string
        keep_cols = [
            'Teff', 'logg', 'FeH', 'profile', 'filter', 'wave_min', 'wave_eff',
            'wave_max', 'c1', 'e1', 'c2', 'e2', 'c3', 'e3', 'c4', 'e4'
        ]
        print_table = ld.results[[
            col for col in keep_cols if col in ld.results.colnames
        ]]
        file_as_string = '\n'.join(
            print_table.pformat(max_lines=-1, max_width=-1))

        # 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_eff', 'wave_min', 'wave_max'] + co_cols]
            table.rename_column('wave_eff',
                                '\(\lambda_\mbox{eff}\hspace{5px}(\mu m)\)')
            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=-1, max_lines=-1, 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)

            # Add the profile to the form inputs
            form_input[profile] = 'true'

        # Log the successful form inputs
        log_exoctk.log_form_input(form_input, 'limb_darkening', DB)

        # Make a table for each profile with a row for each wavelength bin
        profile_spam_tables = ''
        spam_file_as_string = ''
        if ld.spam_results is not None:

            # Store SPAM tables as string
            keep_cols = [
                'Teff', 'logg', 'FeH', 'profile', 'filter', 'wave_min',
                'wave_eff', 'wave_max', 'c1', 'c2'
            ]
            print_spam_table = ld.spam_results[[
                col for col in keep_cols if col in ld.spam_results.colnames
            ]]
            spam_file_as_string = '\n'.join(
                print_spam_table.pformat(max_lines=-1, max_width=-1))
            profile_spam_tables = []
            for profile in list(np.unique(ld.spam_results['profile'])):

                # 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.spam_results, profile=profile)
                co_cols = [
                    c for c in ld.spam_results.colnames
                    if c.startswith('c') and c not in ['coeffs', 'color']
                ]
                table = table[['wave_eff', 'wave_min', 'wave_max'] + co_cols]
                table.rename_column(
                    'wave_eff', '\(\lambda_\mbox{eff}\hspace{5px}(\mu m)\)')
                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=-1, max_lines=-1, 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_spam_tables.append(html_table)

        return render_template('limb_darkening_results.html',
                               form=form,
                               table=profile_tables,
                               spam_table=profile_spam_tables,
                               script=script,
                               plot=div,
                               spam_file_as_string=repr(spam_file_as_string),
                               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)