예제 #1
0
파일: diff.py 프로젝트: aboehle/OsirisDRP
def fits_osiris_allclose(a, b):
    """Assert that two OSIRIS fits files are close."""
    
    a = fits.open(a)
    b = fits.open(b)
    
    try:
        del a[0].header['COMMENT']
        del b[0].header['COMMENT']
    
        report = StringIO()
        diff = FITSDiff(
            a, b,
            ignore_keywords=["COMMENT"],
            ignore_comments=["SIMPLE"],
            ignore_fields=[],
            ignore_blanks=True,
            ignore_blank_cards=True,
            tolerance=1e-5)
        diff.report(fileobj=report)
        assert diff.identical, report.getvalue()
    
    finally:
        a.close()
        b.close()
예제 #2
0
def fits_osiris_allclose(a, b):
    """Assert that two OSIRIS fits files are close."""

    a = fits.open(a)
    b = fits.open(b)

    try:
        del a[0].header['COMMENT']
        del b[0].header['COMMENT']

        report = StringIO()
        diff = FITSDiff(a,
                        b,
                        ignore_keywords=["COMMENT"],
                        ignore_comments=["SIMPLE"],
                        ignore_fields=[],
                        ignore_blanks=True,
                        ignore_blank_cards=True,
                        tolerance=1e-5)
        diff.report(fileobj=report)
        assert diff.identical, report.getvalue()

    finally:
        a.close()
        b.close()
예제 #3
0
def exotransmit_portal():
    """ 
    Run Exo-Transmit taking inputs from the HTML form and plot the results
    """
    if exotransmit_dir is None:
        return render_template(
            'tor_error.html',
            tor_err=
            "There seems to be no directory in place for exo-transmit...")

    # Grab the inputs arguments from the URL
    args = flask.request.args
    # Get all the form arguments in the url with defaults
    eos, tp, g, R_p, R_s, P, Rayleigh, invalid = _param_validation(args)
    if invalid:
        return flask.render_template('exotransmit_validation.html',
                                     invalid=invalid)
    if args:
        x, y = exotransmit_run(eos, tp, g, R_p, R_s, P, Rayleigh)
    else:
        x, y = np.loadtxt(os.path.join(exotransmit_dir, 'Spectra/default.dat'),
                          skiprows=2,
                          unpack=True)

    tab = at.Table(data=[x / 1e-6, y / 100])
    fh = StringIO()
    tab.write(fh, format='ascii.no_header')
    table_string = fh.getvalue()

    fig = figure(plot_width=1100, plot_height=400, responsive=False)
    fig.line(x / 1e-6, y / 100, color='Black', line_width=0.5)
    fig.xaxis.axis_label = 'Wavelength (um)'
    fig.yaxis.axis_label = 'Transit Depth'

    js_resources = INLINE.render_js()
    css_resources = INLINE.render_css()

    script, div = components(fig)

    html = flask.render_template(
        'exotransmit_portal.html',
        plot_script=script,
        plot_div=div,
        js_resources=js_resources,
        css_resources=css_resources,
        eos_files=os.listdir(os.path.join(exotransmit_dir, 'EOS')),
        tp_files=os.listdir(os.path.join(exotransmit_dir, 'T_P')),
        tp=tp,
        eos=eos,
        g=g,
        R_p=R_p,
        R_s=R_s,
        P=P,
        Rayleigh=Rayleigh,
        table_string=table_string)
    return encode_utf8(html)
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
def fortney():
    """
    Pull up Forntey Grid plot the results and download
    """

    # Grab the inputs arguments from the URL
    args = flask.request.args

    temp, chem, cloud, pmass, m_unit, reference_radius, r_unit, rstar, rstar_unit = _param_fort_validation(args)

    # get sqlite database
    try:
        db = create_engine('sqlite:///' + FORTGRID_DIR)
        header = pd.read_sql_table('header', db)
    except:
        raise Exception('Fortney Grid File Path is incorrect, or not initialized')

    if args:
        rstar = float(rstar)
        rstar = (rstar * u.Unit(rstar_unit)).to(u.km)
        reference_radius = float(reference_radius)
        rplan = (reference_radius * u.Unit(r_unit)).to(u.km)

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

        temp = float(temp)
        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(pmass)
        mass = (pmass * u.Unit(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 = StringIO()
    tab.write(fh, format='ascii.no_header')
    table_string = fh.getvalue()

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

    js_resources = INLINE.render_js()
    css_resources = INLINE.render_css()

    script, div = components(fig)

    html = flask.render_template('fortney.html',
                                 plot_script=script,
                                 plot_div=div,
                                 js_resources=js_resources,
                                 css_resources=css_resources,
                                 temp=list(map(str, header.temp.unique())),
                                 table_string=table_string
                                 )
    return encode_utf8(html)
예제 #7
0
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.
    """

    # Check for Fortney Grid database
    print(
        os.path.join(get_env_variables()['exoctk_data'],
                     'fortney/fortney_models.db'))
    try:
        db = create_engine('sqlite:///' + os.path.join(
            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 = 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
예제 #8
0
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.
    """

    # Find path to the database.
    database_path = os.path.join(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 = 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