Exemple #1
0
def test_get_target_data(planet_name, planet_data):
    """Test that the canonical name of the planet is returned by exomast"""

    data, _ = get_target_data(planet_name)

    # these are some params that the webapp uses for it's tools
    exomast_params = [
        'Fe/H', 'Teff', 'stellar_gravity', 'transit_duration', 'RA', 'DEC'
    ]

    for value in exomast_params:
        assert data[value] == planet_data[value]
def phase_overlap_constraint(target_name,
                             period=None,
                             t0=None,
                             obs_duration=None,
                             window_size=None):
    ''' The main function to calculate the phase overlap constraints.
        We will update to allow a user to just plug in the target_name 
        and get the other variables.
        
        Parameters
        ----------
        period : float
            The period of the transit in days. 
        t0 : float
            The start time in BJD or HJD.
        obs_duration : float
            The duration of the observation in hours.
        winSize : float
            The window size of transit in hours. Default is 1 hour.
        target_name : string
            The name of the target transit. 
        
        Returns
        -------
        minphase : float
            The minimum phase constraint.
        maxphase : float
            The maximum phase constraint. '''

    if obs_duration == None:
        if period == None:
            data = get_target_data(target_name)

            period = data['orbital_period']
            transit_dur = data['transit_duration']
            t0 = data['transit_time']

        obs_duration = calculate_obsDur(transit_dur)

    minphase, maxphase = calculate_phase(period, obs_duration, window_size)

    # Is this the return that we want? Do we need to use t0 for something?
    print('MINIMUM PHASE: {}, MAXIMUM PHASE: {}'.format(minphase, maxphase))
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 groups_integrations():
    """The groups and integrations calculator form page"""

    # Print out pandeia sat values
    with open(
            resource_filename(
                'exoctk',
                'data/groups_integrations/groups_integrations_input_data.json')
    ) as f:
        sat_data = json.load(f)['fullwell']
    # Load default form
    form = fv.GroupsIntsForm()

    if request.method == 'GET':

        # http://0.0.0.0:5000/groups_integrations?k_mag=8.131&transit_duration=0.09089&target=WASP-18+b
        target_name = request.args.get('target')
        form.targname.data = target_name

        k_mag = request.args.get('k_mag')
        form.kmag.data = k_mag

        # According to Kevin the obs_dur = 3*trans_dur+1 hours
        # transit_dur is in days from exomast, convert first.
        try:
            trans_dur = float(request.args.get('transit_duration'))
            trans_dur *= u.day.to(u.hour)
            obs_dur = 3 * trans_dur + 1
            form.obs_duration.data = obs_dur
        except TypeError:
            trans_dur = request.args.get('transit_duration')
            if trans_dur == None:
                pass
            else:
                err = 'The Transit Duration from ExoMAST experienced some issues. Try a different spelling or source.'
                return render_template('groups_integrations_error.html',
                                       err=err)
        return render_template('groups_integrations.html',
                               form=form,
                               sat_data=sat_data)

    # 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 Kmag
                kmag = data.get('Kmag')

                # Transit duration in exomast is in days, need it in hours
                if form.time_unit.data == 'day':
                    trans_dur = data.get('transit_duration')
                    obs_dur = 3 * trans_dur + (1 / 24.)
                else:
                    trans_dur = data.get('transit_duration')
                    trans_dur *= u.Unit('day').to('hour')
                    obs_dur = 3 * trans_dur + 1

                # Model guess
                logg_targ = data.get('stellar_gravity') or 4.5
                teff_targ = data.get('Teff') or 5500
                arr = np.array([tuple(i[1].split()) for i in form.mod.choices],
                               dtype=[('spt', 'O'), ('teff', '>f4'),
                                      ('logg', '>f4')])
                mod_table = at.Table(arr)

                # If high logg, remove giants from guess list
                if logg_targ < 4:
                    mod_table = filter_table(mod_table, logg=">=4")
                teff = min(arr['teff'], key=lambda x: abs(x - teff_targ))
                mod_table.add_column(
                    at.Column(np.array([i[0] for i in form.mod.choices]),
                              name='value'))
                mod_table = filter_table(mod_table, teff="<={}".format(teff))
                mod_table.sort(['teff', 'logg'])

                # Set the form values
                form.mod.data = mod_table[-1]['value']
                form.kmag.data = kmag
                form.obs_duration.data = obs_dur
                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('groups_integrations.html',
                               form=form,
                               sat_data=sat_data)

    if form.validate_on_submit() and form.calculate_submit.data:

        # Get the form data
        ins = form.ins.data
        params = {
            'ins':
            ins,
            'mag':
            form.kmag.data,
            'obs_time':
            form.obs_duration.data,
            'sat_max':
            form.sat_max.data,
            'sat_mode':
            form.sat_mode.data,
            'time_unit':
            form.time_unit.data,
            'band':
            'K',
            'mod':
            form.mod.data,
            'filt'.format(ins):
            getattr(form, '{}_filt'.format(ins)).data,
            'subarray'.format(ins):
            getattr(form, '{}_subarray'.format(ins)).data,
            'filt_ta'.format(ins):
            getattr(form, '{}_filt_ta'.format(ins)).data,
            'subarray_ta'.format(ins):
            getattr(form, '{}_subarray_ta'.format(ins)).data
        }

        # Get ngroups
        params['n_group'] = 'optimize' if form.n_group.data == 0 else int(
            form.n_group.data)

        # Also get the data path in there
        params['infile'] = resource_filename(
            'exoctk',
            'data/groups_integrations/groups_integrations_input_data.json')

        # Convert the obs_time to hours
        if params['time_unit'] == 'day':
            params['obs_time'] = params['obs_time'] * 24
            params['time_unit'] = 'hours'

        # Run the calculation
        results = perform_calculation(params)
        if type(results) == dict:
            results_dict = results
            one_group_error = ""
            zero_group_error = ""
            if results_dict['n_group'] == 1:
                one_group_error = 'Be careful! This only predicts one group, and you may be in danger of oversaturating!'
            if results_dict['max_ta_groups'] == 0:
                zero_group_error = 'Be careful! This oversaturated the TA in the minimum groups. Consider a different TA setup.'
            if results_dict['max_ta_groups'] == -1:
                zero_group_error = 'This object is too faint to reach the required TA SNR in this filter. Consider a different TA setup.'
                results_dict['min_sat_ta'] = 0
                results_dict['t_duration_ta_max'] = 0
                results_dict['max_sat_ta'] = 0
                results_dict['t_duration_ta_max'] = 0
            if results_dict['max_sat_prediction'] > results_dict['sat_max']:
                one_group_error = 'This many groups will oversaturate the detector! Proceed with caution!'
            # Do some formatting for a prettier end product
            results_dict['filt'] = results_dict['filt'].upper()
            results_dict['filt_ta'] = results_dict['filt_ta'].upper()
            results_dict['band'] = results_dict['band'].upper()
            results_dict['mod'] = results_dict['mod'].upper()
            if results_dict['ins'] == 'niriss':
                if results_dict['subarray_ta'] == 'nrm':
                    results_dict['subarray_ta'] = 'SUBTASOSS -- BRIGHT'
                else:
                    results_dict['subarray_ta'] = 'SUBTASOSS -- FAINT'
            results_dict['subarray'] = results_dict['subarray'].upper()
            results_dict['subarray_ta'] = results_dict['subarray_ta'].upper()

            form_dict = {
                'miri': 'MIRI',
                'nircam': 'NIRCam',
                'nirspec': 'NIRSpec',
                'niriss': 'NIRISS'
            }
            results_dict['ins'] = form_dict[results_dict['ins']]

            return render_template('groups_integrations_results.html',
                                   results_dict=results_dict,
                                   one_group_error=one_group_error,
                                   zero_group_error=zero_group_error)

        else:
            err = results
            return render_template('groups_integrations_error.html', err=err)

    return render_template('groups_integrations.html',
                           form=form,
                           sat_data=sat_data)
Exemple #6
0
def phase_constraint(transit_type='primary'):
    # Load default form
    form = fv.PhaseConstraint()

    # 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.orbital_period.data = data.get('orbital_period')

                t_time = Time(data.get('transit_time'), format='mjd')
                form.transit_time.data = t_time.jd

                form.observation_duration.data = calculate_pre_duration(
                    data.get('transit_duration') * 24.0)

                form.inclination.data = data.get('inclination')
                if form.inclination.data is None:
                    form.inclination.data = np.nan

                form.omega.data = data.get('omega')
                if form.omega.data is None:
                    form.omega.data = np.nan

                form.eccentricity.data = data.get('eccentricity')
                if form.eccentricity.data is None:
                    form.omega.data = np.nan

                form.target_url.data = str(target_url)

                return render_template('phase_constraint.html', form=form)

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

    # Extract transit type:
    transit_type = form.transit_type.data
    if form.validate_on_submit() and form.calculate_submit.data:
        if transit_type == 'primary':
            minphase, maxphase = phase_overlap_constraint(
                target_name=form.targname.data,
                period=form.orbital_period.data,
                pretransit_duration=form.observation_duration.data,
                window_size=form.window_size.data)
        elif transit_type == 'secondary':
            if (0. <= form.eccentricity.data <
                    1) and (-360. <= form.omega.data <=
                            360.) and (0 <= form.inclination.data <= 90.):
                # Use dummy time-of-transit as it doesn't matter for the phase-constraint calculation
                # (phase = 1 is always transit)
                minphase, maxphase = phase_overlap_constraint(
                    target_name=form.targname.data,
                    period=form.orbital_period.data,
                    t0=1.,
                    pretransit_duration=form.observation_duration.data,
                    window_size=form.window_size.data,
                    secondary=True,
                    ecc=form.eccentricity.data,
                    omega=form.omega.data,
                    inc=form.inclination.data)
            else:
                minphase, maxphase = np.nan, np.nan
        else:
            minphase, maxphase = np.nan, np.nan
        form.minimum_phase.data = minphase
        form.maximum_phase.data = maxphase
    """
    if (form.eccentricity.data > 1.) or (form.eccentricity.data < 0.):
        form.eccentricity.data = None
    if np.abs(form.omega.data)>360.:
        form.omega.data = None
    if (form.inclination.data < 0) or (form.inclination.data>90.):
        form.inclination.data = None
    """
    # Send it back to the main page
    return render_template('phase_constraint.html', form=form)
Exemple #7
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)
Exemple #8
0
def resolve_target(targetName):
    data = get_target_data(targetName)[0]
    ra = data['RA']
    dec = data['DEC']

    return ra, dec
Exemple #9
0
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('<', '&lt')
            profiles = [str(p).replace('<', '&lt') 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('<', '&lt')
                logg = str(request.form['logg']).replace('<', '&lt')
                feh = str(request.form['feh']).replace('<', '&lt')
                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)
Exemple #10
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)
Exemple #11
0
def phase_overlap_constraint(target_name,
                             period=None,
                             t0=None,
                             pretransit_duration=None,
                             transit_dur=None,
                             window_size=None,
                             secondary=False,
                             ecc=None,
                             omega=None,
                             inc=None,
                             winn_approx=False,
                             get_secondary_time=False):
    """The main function to calculate the phase overlap constraints.

    We will update to allow a user to just plug in the target_name and
    get the other variables.

    Parameters
    ----------
    target_name : string
        The name of the target transiting planet.
    period : float
        The period of the transit in days.
    t0 : float
        The transit mid-time in BJD or HJD (only useful if
        time-of-secondary eclipse wants to be returned).
    pretransit_duration : float
        The duration of the observations *before* transit/eclipse in
        hours.
    transit_dur : float
        The duration of the transit/eclipse in hours.
    window_size : float
        The window size of transit in hours. Default is 1 hour.
    secondary : boolean
        If True, phase constraint will be the one for the secondary
        eclipse. Default is primary (i.e., transits).
    ecc : float
        Eccentricity of the orbit. Needed only if secondary is True.
    omega : float
        Argument of periastron of the orbit in degrees. Needed only if
        secondary is True.
    inc : float
        Inclination of the orbit in degrees. Needed only if secondary is
        true.
    winn_approx : boolean
        If True, instead of running the whole Kepler equation
        calculation, time of secondary eclipse is calculated using eq.
        (6) in Winn (2010; https://arxiv.org/abs/1001.2010v5)
    get_secondary_time : boolean
        If True, this function also returns the time-of-mid secondary
        eclipse.

    Returns
    -------
    minphase : float
        The minimum phase constraint.
    maxphase : float
        The maximum phase constraint.
    tsec : float
        (optional) If get_secondary_time is True, the time of secondary
        eclipse in the same units as input t0.
    """

    gotdata = False
    # If secondary eclipse, check eccentricity, omega and inclination are given. If not, get data from exoMAST:
    if secondary:
        if ecc is None:
            data = get_target_data(target_name)
            gotdata = True
            ecc = data[0]['eccentricity']
            if ecc is None:
                raise Exception(
                    'User needs to input eccentricity, as the value was not found at exoMAST {}.'
                    .format(target_name))
        if omega is None:
            if not gotdata:
                data = get_target_data(target_name)
                gotdata = True
            omega = data[0]['omega']
            if omega is None:
                raise Exception(
                    'User needs to input argument of periastron (omega), as the value was not found at exoMAST for {}.'
                    .format(target_name))
        if inc is None:
            if not gotdata:
                data = get_target_data(target_name)
                gotdata = True
            inc = data[0]['inclination']
            if inc is None:
                raise Exception(
                    'User needs to input inclination of the orbit, as the value was not found at exoMAST for {}.'
                    .format(target_name))

    # If pre-transit duration or period is not given, extract it from transit duration using the Tdwell equation:
    if pretransit_duration is None or period is None:
        if not gotdata:
            data = get_target_data(target_name)
            gotdata = True
        # If period is not given, extract it:
        if period is None:
            period = data[0]['orbital_period']
            t0 = Time(data[0]['transit_time'], format='mjd')
            print('Retrieved period is {}. Retrieved t0 is {}.'.format(
                period, t0))
        # If transit/eclipse duration not supplied by the user, extract it from the get_target_data function:
        if transit_dur is None and pretransit_duration is None:
            # Transit duration from get_target_data comes in days:
            transit_dur = data[0]['transit_duration'] * 24.
            if secondary:
                # Factor from equation (16) in Winn (2010). This is, of course, an approximation.
                # TODO: Implement equation (13) in the same paper. Needs optimization plus numerical integration.
                factor = np.sqrt(1. - ecc**2) / (1. -
                                                 ecc * np.sin(omega *
                                                              (np.pi / 180.)))
                transit_dur = transit_dur * factor
        if pretransit_duration is None:
            pretransit_duration = calculate_pre_duration(transit_dur)
            print(
                'Retrieved transit/eclipse duration is: {} hrs; implied pre mid-transit/eclipse on-target time: {} hrs.'
                .format(transit_dur, pretransit_duration))
    print(
        'Performing calculations with Period: {}, t0: {}, ecc: {}, omega: {} degs, inc: {} degs.'
        .format(period, t0, ecc, omega, inc))
    if get_secondary_time:
        minphase, maxphase, tsec = calculate_phase(
            period,
            pretransit_duration,
            window_size,
            t0=t0,
            ecc=ecc,
            omega=omega,
            inc=inc,
            secondary=secondary,
            winn_approx=winn_approx,
            get_secondary_time=get_secondary_time)
        print('MINIMUM PHASE: {}, MAXIMUM PHASE: {}, TSEC: {}'.format(
            minphase, maxphase, tsec))
        return minphase, maxphase, tsec
    else:
        minphase, maxphase = calculate_phase(
            period,
            pretransit_duration,
            window_size,
            t0=t0,
            ecc=ecc,
            omega=omega,
            inc=inc,
            secondary=secondary,
            winn_approx=winn_approx,
            get_secondary_time=get_secondary_time)
        print('MINIMUM PHASE: {}, MAXIMUM PHASE: {}'.format(
            minphase, maxphase))
        return minphase, maxphase