diff --git a/env/environment-3.10.yml b/env/environment-3.10.yml index 3b9b3b08..0f456da7 100644 --- a/env/environment-3.10.yml +++ b/env/environment-3.10.yml @@ -4,7 +4,7 @@ channels: - defaults dependencies: - astropy>=5.3.1 - - bokeh=2.4.3 + - bokeh>=3.2.2 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 @@ -35,7 +35,7 @@ dependencies: - docutils>=0.16 - flask_wtf>=1.1.1 - h5py>=3.9.0 - - hotsoss>=0.1.8 + - hotsoss>=0.1.9 - gunicorn>=21.1.0 - numpy>=1.25.1 - platon>=5.4 @@ -47,6 +47,6 @@ dependencies: - scipy>=1.11.1 - sphinx_astropy>=1.9.1 - svo-filters>=0.4.4 - - werkzeug>=2.3.6 + - werkzeug==2.0.3 - jwst_gtvt>=1.0.0 - astroquery>=0.4.6 diff --git a/env/environment-3.11.yml b/env/environment-3.11.yml index 7ede496c..4206bd96 100644 --- a/env/environment-3.11.yml +++ b/env/environment-3.11.yml @@ -4,7 +4,7 @@ channels: - defaults dependencies: - astropy>=5.3.1 - - bokeh=2.4.3 + - bokeh>=3.2.2 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 @@ -35,7 +35,7 @@ dependencies: - docutils>=0.16 - flask_wtf>=1.1.1 - h5py>=3.9.0 - - hotsoss>=0.1.8 + - hotsoss>=0.1.9 - gunicorn>=21.1.0 - numpy>=1.25.1 - platon>=5.4 @@ -47,6 +47,6 @@ dependencies: - scipy>=1.11.1 - sphinx_astropy>=1.9.1 - svo-filters>=0.4.4 - - werkzeug>=2.3.6 + - werkzeug==2.0.3 - jwst_gtvt>=1.0.0 - astroquery>=0.4.6 diff --git a/env/environment-3.9.yml b/env/environment-3.9.yml index d50e4afa..44f0813b 100644 --- a/env/environment-3.9.yml +++ b/env/environment-3.9.yml @@ -4,7 +4,7 @@ channels: - defaults dependencies: - astropy>=5.3.1 - - bokeh=2.4.3 + - bokeh>=3.2.2 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 @@ -35,8 +35,9 @@ dependencies: - docutils>=0.16 - flask_wtf>=1.1.1 - h5py>=3.9.0 - - hotsoss>=0.1.8 + - hotsoss>=0.1.9 - gunicorn>=21.1.0 + - markupsafe==2.0.1 - numpy>=1.25.1 - platon>=5.4 - pyerfa>=2.0.0 @@ -47,6 +48,6 @@ dependencies: - scipy>=1.11.1 - sphinx_astropy>=1.9.1 - svo-filters>=0.4.4 - - werkzeug>=2.3.6 + - werkzeug==2.0.3 - jwst_gtvt>=1.0.0 - - astroquery>=0.4.6 + - astroquery>=0.4.6 \ No newline at end of file diff --git a/exoctk/contam_visibility/contamination_figure.py b/exoctk/contam_visibility/contamination_figure.py index d1453ec7..309ac6a7 100755 --- a/exoctk/contam_visibility/contamination_figure.py +++ b/exoctk/contam_visibility/contamination_figure.py @@ -1,9 +1,10 @@ import os import sys +from itertools import groupby, count from astropy.io import fits from bokeh.layouts import gridplot -from bokeh.models import Range1d, LinearColorMapper +from bokeh.models import Range1d, LinearColorMapper, CrosshairTool, HoverTool, Span from bokeh.palettes import PuBu from bokeh.plotting import figure import numpy as np @@ -214,8 +215,7 @@ def miriContam(cube, paRange=[0, 360]): return contamO1 -def contam(cube, instrument, targetName='noName', paRange=[0, 360], - badPAs=np.asarray([]), tmpDir="", fig='', to_html=True): +def contam(cube, instrument, targetName='noName', paRange=[0, 360], badPAs=[]): rows, cols = cube.shape[1], cube.shape[2] @@ -241,10 +241,7 @@ def contam(cube, instrument, targetName='noName', paRange=[0, 360], xlim0 = 5 xlim1 = 12 - TOOLS = 'pan, box_zoom, crosshair, reset' - - bad_PA_color = '#dddddd' - bad_PA_alpha = 0.7 + TOOLS = 'pan, box_zoom, reset' dPA = 1 # Order 1~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -255,22 +252,17 @@ def contam(cube, instrument, targetName='noName', paRange=[0, 360], color_mapper = LinearColorMapper(palette=PuBu[8][::-1][2:], low=-4, high=1) color_mapper.low_color = 'white' color_mapper.high_color = 'black' + width = Span(dimension="width", line_width=1) + height = Span(dimension="height", line_width=1) orders = 'Orders 1 & 2' if instrument.startswith('NRCA') else 'Order 1' - s2 = figure(tools=TOOLS, width=500, height=500, title='{} {} Contamination with {}'.format(orders, targetName, instrument), x_range=Range1d(xlim0, xlim1), y_range=Range1d(ylim0, ylim1)) + s2 = figure(tools=TOOLS, width=800, height=600, title='{} {} Contamination with {}'.format(orders, targetName, instrument), x_range=Range1d(xlim0, xlim1), y_range=Range1d(ylim0, ylim1)) + o1_crosshair = CrosshairTool(overlay=[width, height]) + s2.add_tools(o1_crosshair) contamO1 = contamO1 if 'NRCA' in instrument else contamO1.T contamO1 = np.fliplr(contamO1) if (instrument == 'MIRIM_SLITLESSPRISM') or (instrument == 'NRCA5_GRISM256_F322W2') else contamO1 - # fig_data = np.clip(contamO1, 1.e-10, 1.) # [:, :361] # might this - fig_data = np.log10(np.clip(contamO1, 1.e-10, 1.)) # [:, :361] # might this - - # index have something to - # do w the choppiness - # of o1 in all instruments - # return(fig_data) - - X = xlim1 if (instrument == 'MIRIM_SLITLESSPRISM') or (instrument == 'NRCA5_GRISM256_F322W2') else xlim0 - DW = xlim0 - xlim1 if (instrument == 'MIRIM_SLITLESSPRISM') or (instrument == 'NRCA5_GRISM256_F322W2') else xlim1 - xlim0 + fig_data = np.log10(np.clip(contamO1, 1.e-10, 1.)) # Begin plotting ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -279,30 +271,11 @@ def contam(cube, instrument, targetName='noName', paRange=[0, 360], if not instrument.startswith('NIS'): s2.yaxis.axis_label = 'Aperture Position Angle (degrees)' - # Add bad PAs - bad_PA_color = '#555555' - bad_PA_alpha = 0.6 - if len(badPAs) > 0: - - tops, bottoms, lefts, rights = [], [], [], [] - for idx in range(0, len(badPAs)): - PAgroup = badPAs[idx] - top_idx = np.max(PAgroup) - bot_idx = np.min(PAgroup) - - tops.append(top_idx) - bottoms.append(bot_idx) - lefts.append(xlim0) - rights.append(xlim1) - - s2.quad(top=tops, bottom=bottoms, - left=lefts, right=rights, - color=bad_PA_color, alpha=bad_PA_alpha) - # Line plot #ax = 1 if 'NIRCam' in instrument else 0 channels = cols if 'NRCA' in instrument else rows - s3 = figure(tools=TOOLS, width=150, height=500, x_range=Range1d(0, 100), y_range=s2.y_range, title=None) + s3 = figure(tools=TOOLS, width=150, height=600, x_range=Range1d(0, 100), y_range=s2.y_range, title=None) + s3.add_tools(o1_crosshair) try: s3.line(100 * np.sum(contamO1 >= 0.001, axis=1) / channels, PA - dPA / 2, line_color='blue', legend_label='> 0.001') @@ -313,8 +286,34 @@ def contam(cube, instrument, targetName='noName', paRange=[0, 360], s3.xaxis.axis_label = '% channels contam.' s3.yaxis.major_label_text_font_size = '0pt' + s3.ygrid.grid_line_color = None + + # Add shaded region for bad PAs + bad_PA_color = '#555555' + bad_PA_alpha = 0.6 + if len(badPAs) > 0: + + # Group bad PAs + badPA_groups = [list(map(int, g)) for _, g in groupby(badPAs, lambda n, c=count(): n-next(c))] + + tops, bottoms, lefts, rights, lefts_line, rights_line = [], [], [], [], [], [] + for idx in range(0, len(badPA_groups)): + PAgroup = badPA_groups[idx] + top_idx = np.max(PAgroup) + bot_idx = np.min(PAgroup) + + tops.append(top_idx) + bottoms.append(bot_idx) + lefts.append(xlim0) + rights.append(xlim1) + lefts_line.append(0) + rights_line.append(100) + + s2.quad(top=tops, bottom=bottoms, left=lefts, right=rights, color=bad_PA_color, alpha=bad_PA_alpha) + s3.quad(top=tops, bottom=bottoms, left=lefts_line, right=rights_line, color=bad_PA_color, alpha=bad_PA_alpha) # ~~~~~~ Order 2 ~~~~~~ + # Contam plot if instrument.startswith('NIS'): xlim0 = lamO2.min() @@ -322,29 +321,17 @@ def contam(cube, instrument, targetName='noName', paRange=[0, 360], ylim0 = PA.min() - 0.5 * dPA ylim1 = PA.max() + 0.5 * dPA xlim0 = 0.614 - s5 = figure(tools=TOOLS, width=500, height=500, title='Order 2 {} Contamination with {}'.format(targetName, instrument), x_range=Range1d(xlim0, xlim1), y_range=s2.y_range) + s5 = figure(tools=TOOLS, width=800, height=600, title='Order 2 {} Contamination with {}'.format(targetName, instrument), x_range=Range1d(xlim0, xlim1), y_range=s2.y_range) fig_data = np.log10(np.clip(contamO2.T, 1.e-10, 1.))[:, 300:] s5.image([fig_data], x=xlim0, y=ylim0, dw=xlim1 - xlim0, dh=ylim1 - ylim0, color_mapper=color_mapper) s5.xaxis.axis_label = 'Wavelength (um)' s5.yaxis.axis_label = 'Aperture Position Angle (degrees)' - - if len(badPAs) > 0: - - tops, bottoms, lefts, rights = [], [], [], [] - for idx in range(0, len(badPAs)): - PAgroup = badPAs[idx] - top_idx = np.max(PAgroup) - bot_idx = np.min(PAgroup) - - tops.append(top_idx) - bottoms.append(bot_idx) - lefts.append(xlim0) - rights.append(xlim1) - - s5.quad(top=tops, bottom=bottoms, left=lefts, right=rights, color=bad_PA_color, alpha=bad_PA_alpha) + o2_crosshair = CrosshairTool(overlay=[width, height]) + s5.add_tools(o2_crosshair) # Line plot - s6 = figure(tools=TOOLS, width=150, height=500, y_range=s2.y_range, x_range=Range1d(0, 100), title=None) + s6 = figure(tools=TOOLS, width=150, height=600, y_range=s2.y_range, x_range=Range1d(0, 100), title=None) + s6.add_tools(o2_crosshair) try: s6.line(100 * np.sum(contamO2 >= 0.001, axis=0) / rows, PA - dPA / 2, line_color='blue', legend_label='> 0.001') @@ -355,23 +342,30 @@ def contam(cube, instrument, targetName='noName', paRange=[0, 360], s6.xaxis.axis_label = '% channels contam.' s6.yaxis.major_label_text_font_size = '0pt' + s6.ygrid.grid_line_color = None - if len(badPAs) > 0: + # Add shaded region for bad PAs + if len(badPAs) > 0: - tops, bottoms, lefts, rights = [], [], [], [] - for idx in range(0, len(badPAs)): - PAgroup = badPAs[idx] - top_idx = np.max(PAgroup) - bot_idx = np.min(PAgroup) + # Group bad PAs + badPA_groups = [list(map(int, g)) for _, g in groupby(badPAs, lambda n, c=count(): n - next(c))] - tops.append(top_idx) - bottoms.append(bot_idx) - lefts.append(0) - rights.append(100) + tops, bottoms, lefts, rights, lefts_line, rights_line = [], [], [], [], [], [] + for idx in range(0, len(badPA_groups)): + PAgroup = badPA_groups[idx] + top_idx = np.max(PAgroup) + bot_idx = np.min(PAgroup) - s3.quad(top=tops, bottom=bottoms, left=lefts, right=rights, color=bad_PA_color, alpha=bad_PA_alpha) - if instrument.startswith('NIS'): - s6.quad(top=tops, bottom=bottoms, left=rights, right=lefts, color=bad_PA_color, alpha=bad_PA_alpha) + tops.append(top_idx) + bottoms.append(bot_idx) + lefts.append(xlim0) + rights.append(xlim1) + lefts_line.append(0) + rights_line.append(100) + + s5.quad(top=tops, bottom=bottoms, left=lefts, right=rights, color=bad_PA_color, alpha=bad_PA_alpha) + s6.quad(top=tops, bottom=bottoms, left=lefts_line, right=rights_line, color=bad_PA_color, + alpha=bad_PA_alpha) # ~~~~~~ Plotting ~~~~~~ diff --git a/exoctk/contam_visibility/field_simulator.py b/exoctk/contam_visibility/field_simulator.py index 19725946..cee46c7e 100755 --- a/exoctk/contam_visibility/field_simulator.py +++ b/exoctk/contam_visibility/field_simulator.py @@ -32,7 +32,8 @@ import regions from ..utils import get_env_variables, check_for_data -from .visibilityPA import using_gtvt +# from .visibilityPA import using_gtvt +from .new_vis_plot import build_visibility_plot, get_exoplanet_positions from .contamination_figure import contam Vizier.columns = ["**", "+_r"] @@ -375,7 +376,7 @@ def calc_v3pa(V3PA, stars, aperture, data=None, c0x0=885, c0y0=1462, c1x0=-0.11, star['yord1'] = star['yord0'] - y_sweet + aper['subarr_y'][1] + y_shift # Just stars in FOV (Should always have at least 1, the target) - lft, rgt, top, bot = 700, 5000, 2000, 1400 + lft, rgt, top, bot = 700, 5100, 1940, 1400 FOVstars = stars[(lft < stars['xord0']) & (stars['xord0'] < rgt) & (bot < stars['yord0']) & (stars['yord0'] < top)] if verbose: @@ -390,19 +391,15 @@ def calc_v3pa(V3PA, stars, aperture, data=None, c0x0=885, c0y0=1462, c1x0=-0.11, if plot: # Set up hover tool tips = [('Name', '@name'), ('RA', '@ra'), ('DEC', '@dec'), ('scale', '@fluxscale'), ('Teff', '@Teff'), ('ord0', '@xord0{int}, @yord0{int}')] - hover = HoverTool(tooltips=tips, names=['stars']) + hover = HoverTool(tooltips=tips, name='stars') crosshair = CrosshairTool(dimensions="height") + taptool = TapTool(behavior='select', callback=OpenURL(url="@url")) # Make the plot - tools = ['pan', crosshair, 'reset', 'box_zoom', 'wheel_zoom', 'save', hover] + tools = ['pan', crosshair, 'reset', 'box_zoom', 'wheel_zoom', 'save', taptool, hover] fig = figure(title='Generated FOV from Gaia EDR3', width=900, height=subY, match_aspect=True, tools=tools) fig.title = '({}, {}) at PA={} in {}'.format(stars[0]['ra'], stars[0]['dec'], V3PA, aperture.AperName) - # Add clickable order 0 - taptool = fig.select(type=TapTool) - taptool.behavior = 'select' - taptool.callback = OpenURL(url="@url") - # Plot config scale = 'log' color_map = 'Viridis256' @@ -653,7 +650,7 @@ def plot_traces(star_table, fig, color='red'): return fig -def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, plot=False, multi=True, verbose=True): +def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, plot=False, multi=True, verbose=True): """Produce a contamination field simulation at the given sky coordinates Parameters @@ -668,8 +665,6 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p A dictionary of parameters for a binary companion with keys {'name', 'ra', 'dec', 'fluxscale', 'teff'} n_jobs: int Number of cores to use (-1 = All) - pa_list: sequence - The position angles to calculate Returns ------- @@ -684,7 +679,7 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p ------- from exoctk.contam_visibility import field_simulator as fs ra, dec = 91.872242, -25.594934 - targ, data, plt = fs.field_simulation(ra, dec, 'NIS_SUBSTRIP256') + targframe, starcube, results = fs.field_simulation(ra, dec, 'NIS_SUBSTRIP256') """ # Check for contam tool data check_for_data('exoctk_contam') @@ -720,25 +715,41 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p stars = add_star(stars, **binComp) # Set the number of cores for multiprocessing - max_cores = cpu_count() + max_cores = 8 if n_jobs == -1 or n_jobs > max_cores: n_jobs = max_cores - # List of PAs - if pa_list is None: - pa_list = np.arange(0, 360, 1) + # Get full list from ephemeris + ra_hms, dec_dms = re.sub('[a-z]', ':', targetcrd.to_string('hmsdms')).split(' ') + goodPAs = get_exoplanet_positions(ra_hms, dec_dms, in_FOR=True) + + # Get all observable PAs and convert to ints + goodPA_vals = list(goodPAs[~goodPAs['{}_min_pa_angle'.format(inst['inst'].upper())].isna()]['{}_min_pa_angle'.format(inst['inst'].upper())]) + list(goodPAs[~goodPAs['{}_nominal_angle'.format(inst['inst'].upper())].isna()]['{}_nominal_angle'.format(inst['inst'].upper())]) + list(goodPAs[~goodPAs['{}_max_pa_angle'.format(inst['inst'].upper())].isna()]['{}_max_pa_angle'.format(inst['inst'].upper())]) + goodPA_ints = np.sort(np.unique(np.array(goodPA_vals).astype(int))) + + # Group good PAs to find gaps in visibility + good_groups = [] + current_group = [goodPA_ints[0]] + max_gap = 7 # Biggest PA gap considered to still be observable + for i in range(1, len(goodPA_ints)): + if goodPA_ints[i] - current_group[-1] <= max_gap: + current_group.append(goodPA_ints[i]) + else: + good_groups.append(current_group) + current_group = [goodPA_ints[i]] + + good_groups.append(current_group) + good_group_bounds = [(min(grp), max(grp)) for grp in good_groups] + goodPA_list = np.concatenate([np.arange(grp[0], grp[1]+1) for grp in good_group_bounds]).ravel() + + # Flatten list and check against 360 angles to get all bad PAs + # badPA_list = [pa for pa in pa_list if pa not in goodPA_list] # Time it if verbose: - print('Calculating target contamination from {} neighboring sources at {} position angles...'.format(len(stars), len(pa_list))) + print('Calculating target contamination from {} neighboring sources in position angle ranges {}...'.format(len(stars), good_group_bounds)) start = time.time() - # Exclude PAs where target is not visible to speed up calculation - ra_hms, dec_dms = re.sub('[a-z]', ':', targetcrd.to_string('hmsdms')).split(' ') - minPA, maxPA, _, _, _, badPAs = using_gtvt(ra_hms[:-1], dec_dms[:-1], inst['inst']) - badPA_list = np.concatenate([np.array(i) for i in badPAs]) - good_pa_list = [pa for pa in pa_list if pa not in badPA_list] - # Calculate contamination of all stars at each PA # ----------------------------------------------- # To multiprocess, or not to multiprocess. That is the question. @@ -749,13 +760,13 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p if multi: pl = pool.ThreadPool(n_jobs) func = partial(calc_v3pa, stars=stars, aperture=aper, plot=False, verbose=False) - results = pl.map(func, good_pa_list) + results = pl.map(func, goodPA_list) pl.close() pl.join() else: results = [] - for pa in good_pa_list: + for pa in goodPA_list: result = calc_v3pa(pa, stars=stars, aperture=aper, plot=False, verbose=False) results.append(result) @@ -827,7 +838,7 @@ def contam_slider_plot(contam_results, threshold=0.05, plot=False): source_available = ColumnDataSource(data=contam_dict) # Define plot elements - plt = figure(plot_width=900, plot_height=300, tools=['reset', 'box_zoom', 'wheel_zoom', 'save']) + plt = figure(width=900, height=300, tools=['reset', 'box_zoom', 'wheel_zoom', 'save']) plt.line('col', 'contam1', source=source_visible, color='blue', line_width=2, line_alpha=0.6, legend_label='Order 1') plt.line('col', 'contam2', source=source_visible, color='red', line_width=2, line_alpha=0.6, legend_label='Order 2') @@ -871,7 +882,7 @@ def contam_slider_plot(contam_results, threshold=0.05, plot=False): viz_ord3 = np.array([1 if i > threshold else 0 for i in np.nanmax(order3_contam, axis=1)]) # Make the plot - viz_plt = figure(plot_width=900, plot_height=200, x_range=Range1d(0, 359)) + viz_plt = figure(width=900, height=200, x_range=Range1d(0, 359)) viz_plt.step(np.arange(360), np.mean(order1_contam, axis=1), color='blue', mode="center") viz_plt.step(np.arange(360), np.mean(order2_contam, axis=1), color='red', mode="center") viz_plt.step(np.arange(360), np.mean(order3_contam, axis=1), color='green', mode="center") @@ -995,10 +1006,6 @@ def old_plot_contamination(targframe_o1, targframe_o2, targframe_o3, starcube, w The wavelength min and max badPAs: list The list of position angles with no visibility - minPA: int - The minimum position angle to plot - maxPA: int - The maximum position angle to plot Returns ------- @@ -1040,7 +1047,7 @@ def old_plot_contamination(targframe_o1, targframe_o2, targframe_o3, starcube, w contam = np.log10(np.clip(contam, 1.e-10, 1.)) # Hover tool - hover = HoverTool(tooltips=[("Wavelength", "$x"), ("PA", "$y"), ('Value', '@data')], names=['contam']) + hover = HoverTool(tooltips=[("Wavelength", "$x"), ("PA", "$y"), ('Value', '@data')], name='contam') tools = ['pan', 'box_zoom', 'crosshair', 'reset', hover] trplot = figure(tools=tools, width=600, height=500, title=title, x_range=Range1d(*wlims), y_range=Range1d(0, PAs)) diff --git a/exoctk/contam_visibility/new_vis_plot.py b/exoctk/contam_visibility/new_vis_plot.py new file mode 100644 index 00000000..4cddc59b --- /dev/null +++ b/exoctk/contam_visibility/new_vis_plot.py @@ -0,0 +1,71 @@ +from astropy.time import Time + +from bokeh.models import Band, ColumnDataSource, HoverTool +from bokeh.plotting import figure, show + +from jwst_gtvt.jwst_tvt import Ephemeris +from jwst_gtvt.plotting import get_visibility_windows + + +def get_exoplanet_positions(ra, dec, in_FOR=None): + """Use the jwst_gtvt to obtain positions of exoplanet. + """ + + eph = Ephemeris() + exoplanet_data = eph.get_fixed_target_positions(ra, dec) + + if in_FOR is None: + return exoplanet_data + else: + return exoplanet_data.loc[exoplanet_data['in_FOR']==in_FOR] + + +def build_visibility_plot(target_name, instrument, ra, dec): + """Build bokeh figure for visibility windows + """ + + instrument = instrument.upper() + + if instrument not in ['NIRCAM', 'NIRISS', 'MIRI', 'NIRSPEC']: + raise ValueError(f'{instrument} not supported for this tool!') + + nominal_angle_column_name = instrument + '_nominal_angle' + min_pa_column_name = instrument + '_min_pa_angle' + max_pa_column_name = instrument + '_max_pa_angle' + + # obtain exoplanet data and filter visibility windows + exoplanet_df = get_exoplanet_positions(ra, dec, in_FOR=True) + window_indices = get_visibility_windows(exoplanet_df.index.tolist()) + + exoplanet_df['times'] = Time(exoplanet_df['MJD'], format='mjd').datetime + + # source = ColumnDataSource(exoplanet_df) + + # define bokeh figure + TOOLTIPS = [ + ("Date", "@times{%F}"), + ("Nominal Position Angle", "@{}".format(nominal_angle_column_name)), + ("Min Position Angle", "@{}".format(min_pa_column_name)), + ("Max Position Angle", "@{}".format(max_pa_column_name)),] + + p = figure(title=f"{target_name} Visibility with {instrument}", + height=400, width=800, x_axis_type='datetime') + + p.xaxis.axis_label = 'Date' + p.yaxis.axis_label = 'Available Aperture Position Angles (Degrees)' + + for start, end in window_indices: + data_to_plot = exoplanet_df.loc[start:end] + source = ColumnDataSource(data_to_plot) + + p.line("times", instrument + "_nominal_angle", line_dash=(10, 7), line_width=1, source=source, legend_label="Nominal Angle") + + band = Band(base='times', lower=instrument + '_min_pa_angle', upper=instrument + '_max_pa_angle', source=source, + level='underlay', fill_alpha=1.0, line_width=4, line_color='green') + + p.add_layout(band) + p.xaxis.major_label_orientation = 3.14/4 + + p.add_tools(HoverTool(tooltips=TOOLTIPS, formatters={'@times': 'datetime'})) + + return p \ No newline at end of file diff --git a/exoctk/contam_visibility/visibilityPA.py b/exoctk/contam_visibility/visibilityPA.py index 93312005..eb3c1daf 100755 --- a/exoctk/contam_visibility/visibilityPA.py +++ b/exoctk/contam_visibility/visibilityPA.py @@ -135,7 +135,7 @@ def checkVisPA(ra, dec, targetName=None, ephFileName=None, fig=None): if fig is None or fig: tools = 'crosshair, reset, hover, save' radec = ', '.join([str(ra), str(dec)]) - fig = figure(tools=tools, plot_width=800, plot_height=400, + fig = figure(tools=tools, width=800, height=400, x_axis_type='datetime', title=targetName or radec) @@ -236,9 +236,9 @@ def using_gtvt(ra, dec, instrument, targetName='noName', ephFileName=None, outpu """ # Getting calculations from GTVT (General Target Visibility Tool) - blockPrint() + # blockPrint() tab = get_table(ra, dec) - enablePrint() + # enablePrint() gd = tab['Date'] paMin = tab[str(instrument) + ' min'] @@ -285,8 +285,8 @@ def using_gtvt(ra, dec, instrument, targetName='noName', ephFileName=None, outpu # Time to plot if output == 'bokeh': fig = figure(tools=TOOLS, - plot_width=800, - plot_height=400, + width=800, + height=400, x_axis_type='datetime', title='{} Visibility with {}'.format(targetName, instrument)) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 38d1c450..2618b0f0 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -17,7 +17,7 @@ from exoctk import log_exoctk from exoctk.contam_visibility.new_vis_plot import build_visibility_plot, get_exoplanet_positions -from exoctk.contam_visibility import visibilityPA as vpa +#from exoctk.contam_visibility import visibilityPA as vpa from exoctk.contam_visibility import field_simulator as fs from exoctk.contam_visibility import contamination_figure as cf from exoctk.contam_visibility.miniTools import contamVerify @@ -477,14 +477,11 @@ def contam_visibility(): # 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), instrument, targetName=str(title)) - vis_plot = build_visibility_plot(str(title), instrument, str(form.ra.data), str(form.dec.data)) table = get_exoplanet_positions(str(form.ra.data), str(form.dec.data)) + # Make output table - fh = io.StringIO() - table.to_csv(fh, index=False) - visib_table = fh.getvalue() + vis_table = table.to_csv() # Get scripts vis_js = INLINE.render_js() @@ -530,6 +527,9 @@ def contam_visibility(): # Make the plot # contam_plot = fs.contam_slider_plot(results) + # Get bad PA list from missing angles between 0 and 360 + badPAs = [j for j in np.arange(0, 360) if j not in [i['pa'] for i in results]] + # Make old contam plot starCube = np.zeros((362, 2048, 256)) starCube[0, :, :] = (targframe[0]).T[::-1, ::-1] @@ -561,7 +561,7 @@ def contam_visibility(): return render_template('contam_visibility_results.html', form=form, vis_plot=vis_div, - vis_table=visib_table, + vis_table=vis_table, vis_script=vis_script, vis_js=vis_js, vis_css=vis_css, contam_plot=contam_div, contam_script=contam_script, @@ -726,8 +726,8 @@ def empty_fields(form): # 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 + bk_plot.width = 580 + bk_plot.height = 280 js_resources = INLINE.render_js() css_resources = INLINE.render_css() filt_script, filt_plot = components(bk_plot) @@ -1010,14 +1010,16 @@ def save_visib_result(): flask.Response object with the results of the visibility only calculation. """ - - visib_table = flask.request.form['data_file'] - targname = flask.request.form['targetname'] + visib_table = request.form['vis_table'] + targname = request.form['targetname'] targname = targname.replace(' ', '_') # no spaces - instname = flask.request.form['instrumentname'] + instname = request.form['instrumentname'] + + resp = make_response(visib_table) + resp.headers["Content-Disposition"] = "attachment; filename={}_{}_visibility.csv".format(targname, instname) + resp.headers["Content-Type"] = "text/csv" - return flask.Response(visib_table, mimetype="text/dat", - headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) + return resp @app_exoctk.route('/admin') diff --git a/exoctk/exoctk_app/templates/contam_visibility_results.html b/exoctk/exoctk_app/templates/contam_visibility_results.html index 032a61ba..dcdfdb4f 100644 --- a/exoctk/exoctk_app/templates/contam_visibility_results.html +++ b/exoctk/exoctk_app/templates/contam_visibility_results.html @@ -54,8 +54,8 @@