From a9ca52d9cbf0072d871b0b5717b06c0ea1455fa5 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 19 Jul 2023 10:22:15 -0400 Subject: [PATCH 01/30] Added alternate model grid function that just selects the model with the closest model parameters --- exoctk/contam_visibility/visibilityPA.py | 4 +- exoctk/modelgrid.py | 100 +++++++++++++++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/exoctk/contam_visibility/visibilityPA.py b/exoctk/contam_visibility/visibilityPA.py index 080ec085..d0bb4f25 100755 --- a/exoctk/contam_visibility/visibilityPA.py +++ b/exoctk/contam_visibility/visibilityPA.py @@ -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'] diff --git a/exoctk/modelgrid.py b/exoctk/modelgrid.py index d2496010..5894db44 100644 --- a/exoctk/modelgrid.py +++ b/exoctk/modelgrid.py @@ -17,6 +17,7 @@ import astropy.table as at import astropy.units as q from astropy.utils.exceptions import AstropyWarning +from bokeh.plotting import figure import h5py import numpy as np from scipy.interpolate import RegularGridInterpolator @@ -30,6 +31,105 @@ ON_GITHUB_ACTIONS = os.path.expanduser('~') in ['/home/runner', '/Users/runner'] +def model_atmosphere(teff_float, logg_float=5., feh_float=0., atlas='ACES', air=False, plot=False): + """ + Get the spectrum of a model atmosphere with the closest atmospheric parameters + + Parameters + ---------- + teff_float: float + The effective temperature + logg_float: float + The log surface gravity + feh_float: float + The metallicity + aplha_float: float + The alpha element enhancement + atlas: str + The atlas to use + air: bool + Convert vacuum wavelengths (default) to air + plot: bool + Plot the spectra + + Returns + ------- + + """ + # Glob all files in the given atlas directory + atlas_path = '/Users/jfilippazzo/Desktop/{}/'.format(atlas) + file_paths = glob(os.path.join(atlas_path, '*')) + filenames = [os.path.basename(i) for i in file_paths] + + # List of available model parameters by parsing filenames + teff_lst = np.sort(np.unique([float(i[3:8]) for i in filenames])) + logg_lst = np.sort(np.unique([float(i[9:12]) for i in filenames])) + feh_lst = np.sort(np.unique([float(i[13:17]) for i in filenames])) + + # Get closest value + teff = min(teff_lst, key=lambda x: abs(x - teff_float)) + logg = min(logg_lst, key=lambda x: abs(x - logg_float)) + feh = min(feh_lst, key=lambda x: abs(x - feh_float)) + + # Generate the correct filename from the given parameters with format 'lte03000-4.50-0.0.PHOENIX-ACES-AGSS-COND-SPECINT-2011.fits' + teff_str = str(int(teff)).zfill(5) + logg_str = '{:.2f}'.format(logg) + feh_str = ('+' if feh > 0 else '')+'{:.1f}'.format(feh) + filepath = os.path.join(atlas_path, 'lte{}-{}{}.PHOENIX-ACES-AGSS-COND-SPECINT-2011.fits'.format(teff_str, logg_str, feh_str)) + + # Get the data + hdul = fits.open(filepath) + mu = hdul[1].data + flux = hdul[0].data + head = hdul[0].header + hdul.close() + wave = np.arange(head['CRVAL1'], head['CRVAL1']+(head['NAXIS1']*head['CDELT1']), head['CDELT1']) + + def nrefrac(wavelength, density=1.0): + """Calculate refractive index of air from Cauchy formula. + + Note that Phoenix delivers synthetic spectra in the vaccum and that a line + shift is necessary to adapt these synthetic spectra for comparisons to + observations from the ground. For this, divide the vacuum wavelengths by + (1+1.e-6*nrefrac) as returned from the function below to get the air + wavelengths (or use the equation for AIR from it). + + Input: wavelength in Angstrom, density of air in amagat (relative to STP, + e.g. ~10% decrease per 1000m above sea level). + Returns N = (n-1) * 1.e6. + """ + + # The IAU standard for conversion from air to vacuum wavelengths is given + # in Morton (1991, ApJS, 77, 119). For vacuum wavelengths (VAC) in + # Angstroms, convert to air wavelength (AIR) via: + + # AIR = VAC / (1.0 + 2.735182E-4 + 131.4182 / VAC^2 + 2.76249E8 / VAC^4) + wl2inv = (1.e4/wavelength)**2 + refracstp = 272.643 + 1.2288 * wl2inv + 3.555e-2 * wl2inv**2 + + return density * refracstp + + # Vacuum or air? + wave = nrefrac(wave) if air else wave + + # Put data into dict that works with LDC code + spec_dict = {} + spec_dict['wave'] = wave / 10000. # Convert from A to um + spec_dict['flux'] = flux + spec_dict['mu'] = mu + spec_dict['filename'] = filepath + + # Make a plot... or don't. See if I care. + if plot: + fig = figure(title="Teff={}, log(g)={}, [Fe/H]={}".format(teff, logg, feh)) + colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple'] + for idx, mu_val in enumerate(mu[::10][:7]): + fig.line(wave, 10**flux[idx], legend_label='mu = {}'.format(mu_val), color=colors[idx]) + return spec_dict, fig + + else: + return spec_dict + class ModelGrid(object): """ Creates a ModelGrid object which contains a multi-parameter From c78a90f7f467b96b8a87697480ed0d021879ecfc Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 19 Jul 2023 10:25:44 -0400 Subject: [PATCH 02/30] Changed arg names --- exoctk/modelgrid.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/exoctk/modelgrid.py b/exoctk/modelgrid.py index 5894db44..adb876e7 100644 --- a/exoctk/modelgrid.py +++ b/exoctk/modelgrid.py @@ -31,20 +31,18 @@ ON_GITHUB_ACTIONS = os.path.expanduser('~') in ['/home/runner', '/Users/runner'] -def model_atmosphere(teff_float, logg_float=5., feh_float=0., atlas='ACES', air=False, plot=False): +def model_atmosphere(teff, logg=5., feh=0., atlas='ACES', air=False, plot=False): """ Get the spectrum of a model atmosphere with the closest atmospheric parameters Parameters ---------- - teff_float: float + teff: float The effective temperature - logg_float: float + logg: float The log surface gravity - feh_float: float + feh: float The metallicity - aplha_float: float - The alpha element enhancement atlas: str The atlas to use air: bool @@ -67,14 +65,14 @@ def model_atmosphere(teff_float, logg_float=5., feh_float=0., atlas='ACES', air= feh_lst = np.sort(np.unique([float(i[13:17]) for i in filenames])) # Get closest value - teff = min(teff_lst, key=lambda x: abs(x - teff_float)) - logg = min(logg_lst, key=lambda x: abs(x - logg_float)) - feh = min(feh_lst, key=lambda x: abs(x - feh_float)) + teff_val = min(teff_lst, key=lambda x: abs(x - teff)) + logg_val = min(logg_lst, key=lambda x: abs(x - logg)) + feh_val = min(feh_lst, key=lambda x: abs(x - feh)) # Generate the correct filename from the given parameters with format 'lte03000-4.50-0.0.PHOENIX-ACES-AGSS-COND-SPECINT-2011.fits' - teff_str = str(int(teff)).zfill(5) - logg_str = '{:.2f}'.format(logg) - feh_str = ('+' if feh > 0 else '')+'{:.1f}'.format(feh) + teff_str = str(int(teff_val)).zfill(5) + logg_str = '{:.2f}'.format(logg_val) + feh_str = ('+' if feh_val > 0 else '')+'{:.1f}'.format(feh_val) filepath = os.path.join(atlas_path, 'lte{}-{}{}.PHOENIX-ACES-AGSS-COND-SPECINT-2011.fits'.format(teff_str, logg_str, feh_str)) # Get the data @@ -114,6 +112,9 @@ def nrefrac(wavelength, density=1.0): # Put data into dict that works with LDC code spec_dict = {} + spec_dict['Teff'] = teff_val + spec_dict['logg'] = logg_val + spec_dict['FeH'] = feh_val spec_dict['wave'] = wave / 10000. # Convert from A to um spec_dict['flux'] = flux spec_dict['mu'] = mu @@ -121,7 +122,7 @@ def nrefrac(wavelength, density=1.0): # Make a plot... or don't. See if I care. if plot: - fig = figure(title="Teff={}, log(g)={}, [Fe/H]={}".format(teff, logg, feh)) + fig = figure(title="Teff={}, log(g)={}, [Fe/H]={}".format(teff_val, logg_val, feh_val)) colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple'] for idx, mu_val in enumerate(mu[::10][:7]): fig.line(wave, 10**flux[idx], legend_label='mu = {}'.format(mu_val), color=colors[idx]) From 6d03187647431260e6a82c18d16f25a9f884e728 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 19 Jul 2023 10:36:09 -0400 Subject: [PATCH 03/30] Added print statement --- exoctk/modelgrid.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/exoctk/modelgrid.py b/exoctk/modelgrid.py index adb876e7..4acdfc35 100644 --- a/exoctk/modelgrid.py +++ b/exoctk/modelgrid.py @@ -52,7 +52,8 @@ def model_atmosphere(teff, logg=5., feh=0., atlas='ACES', air=False, plot=False) Returns ------- - + dict, bokeh.plotting.figure + A dictionary of the spectra and optionally a plot """ # Glob all files in the given atlas directory atlas_path = '/Users/jfilippazzo/Desktop/{}/'.format(atlas) @@ -68,6 +69,7 @@ def model_atmosphere(teff, logg=5., feh=0., atlas='ACES', air=False, plot=False) teff_val = min(teff_lst, key=lambda x: abs(x - teff)) logg_val = min(logg_lst, key=lambda x: abs(x - logg)) feh_val = min(feh_lst, key=lambda x: abs(x - feh)) + print('Closest model to [{}, {}, {}] => [{}, {}, {}]'.format(teff, logg, feh, teff_val, logg_val, feh_val)) # Generate the correct filename from the given parameters with format 'lte03000-4.50-0.0.PHOENIX-ACES-AGSS-COND-SPECINT-2011.fits' teff_str = str(int(teff_val)).zfill(5) From 57ec4a4bcb0f2f1f6503d8ecae50c45a7f220cff Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 19 Jul 2023 15:55:22 -0400 Subject: [PATCH 04/30] Updated LDC and ModelGrid to skip interpolation and just get closest model --- exoctk/limb_darkening/limb_darkening_fit.py | 27 ++++++++++--- exoctk/modelgrid.py | 44 ++++++++++++--------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/exoctk/limb_darkening/limb_darkening_fit.py b/exoctk/limb_darkening/limb_darkening_fit.py index 6283564c..51116a96 100755 --- a/exoctk/limb_darkening/limb_darkening_fit.py +++ b/exoctk/limb_darkening/limb_darkening_fit.py @@ -198,7 +198,7 @@ def bootstrap_errors(mu_vals, func, coeffs, errors, n_samples=1000): return dn_err, up_err def calculate(self, Teff, logg, FeH, profile, mu_min=0.05, ld_min=0.01, - bandpass=None, name=None, color=None, **kwargs): + bandpass=None, name=None, color=None, interp=False, **kwargs): """ Calculates the limb darkening coefficients for a given synthetic spectrum. If the model grid does not contain a spectrum of the @@ -230,6 +230,8 @@ def calculate(self, Teff, logg, FeH, profile, mu_min=0.05, ld_min=0.01, A name for the calculation color: str (optional) A color for the plotted result + interp: bool + Interpolate spectra to given model parameters """ # Define the limb darkening profile function ldfunc = ld_profile(profile) @@ -237,8 +239,11 @@ def calculate(self, Teff, logg, FeH, profile, mu_min=0.05, ld_min=0.01, if not ldfunc: raise ValueError("No such LD profile:", profile) - # Get the grid point - grid_point = self.get_model(Teff, logg, FeH) + # Get the grid point (and update parameters if no interpolation) + grid_point = self.get_model(Teff, logg, FeH, interp=interp) + Teff = grid_point['Teff'] + logg = grid_point['logg'] + FeH = grid_point['FeH'] # Retrieve the wavelength, flux, mu, and effective radius wave = grid_point.get('wave') @@ -377,7 +382,7 @@ def calculate(self, Teff, logg, FeH, profile, mu_min=0.05, ld_min=0.01, except ValueError: print("Could not calculate coefficients at {}".format(wave_eff)) - def get_model(self, teff, logg, feh): + def get_model(self, teff, logg, feh, interp=False): """ Method to grab cached model or fetch new one @@ -389,12 +394,24 @@ def get_model(self, teff, logg, feh): The log surface gravity of the desired model feh: float The metallicity of the desired model + interp: bool + Interpolate the model spectra to the given parameters Returns ------- dict The stellar intensity model """ + if not interp: + + teff_val, logg_val, feh_val = teff, logg, feh + + # Find the closest of each parameter + teff = min(self.model_grid.Teff_vals, key=lambda x: abs(x - teff)) + logg = min(self.model_grid.logg_vals, key=lambda x: abs(x - logg)) + feh = min(self.model_grid.FeH_vals, key=lambda x: abs(x - feh)) + print('Closest model to [{}, {}, {}] => [{}, {}, {}]'.format(teff_val, logg_val, feh_val, teff, logg, feh)) + # Check if it is stored params = '{}_{}_{}_{}'.format(self.model_grid.path.split('/')[-2], teff, logg, feh) @@ -402,7 +419,7 @@ def get_model(self, teff, logg, feh): if params in self.model_cache: model = self.model_cache[params] else: - model = self.model_grid.get(teff, logg, feh) + model = self.model_grid.get(teff, logg, feh, interp=interp) self.model_cache[params] = model print("Saving model '{}'".format(params)) diff --git a/exoctk/modelgrid.py b/exoctk/modelgrid.py index 4acdfc35..94849fe0 100644 --- a/exoctk/modelgrid.py +++ b/exoctk/modelgrid.py @@ -17,7 +17,6 @@ import astropy.table as at import astropy.units as q from astropy.utils.exceptions import AstropyWarning -from bokeh.plotting import figure import h5py import numpy as np from scipy.interpolate import RegularGridInterpolator @@ -31,7 +30,7 @@ ON_GITHUB_ACTIONS = os.path.expanduser('~') in ['/home/runner', '/Users/runner'] -def model_atmosphere(teff, logg=5., feh=0., atlas='ACES', air=False, plot=False): +def model_atmosphere(teff, logg=5., feh=0., atlas='ACES', air=False): """ Get the spectrum of a model atmosphere with the closest atmospheric parameters @@ -47,8 +46,6 @@ def model_atmosphere(teff, logg=5., feh=0., atlas='ACES', air=False, plot=False) The atlas to use air: bool Convert vacuum wavelengths (default) to air - plot: bool - Plot the spectra Returns ------- @@ -122,16 +119,19 @@ def nrefrac(wavelength, density=1.0): spec_dict['mu'] = mu spec_dict['filename'] = filepath - # Make a plot... or don't. See if I care. - if plot: - fig = figure(title="Teff={}, log(g)={}, [Fe/H]={}".format(teff_val, logg_val, feh_val)) - colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple'] - for idx, mu_val in enumerate(mu[::10][:7]): - fig.line(wave, 10**flux[idx], legend_label='mu = {}'.format(mu_val), color=colors[idx]) - return spec_dict, fig + # # Make a plot... or don't. See if I care. + # if plot: + # fig = figure(title="Teff={}, log(g)={}, [Fe/H]={}".format(teff_val, logg_val, feh_val)) + # colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'purple'] + # for idx, mu_val in enumerate(mu[::10][:7]): + # fig.line(wave, 10**flux[idx], legend_label='mu = {}'.format(mu_val), color=colors[idx]) + # return spec_dict, fig + # + # else: + # return spec_dict + + return spec_dict - else: - return spec_dict class ModelGrid(object): """ @@ -551,11 +551,22 @@ def toQ(val): # If not on the grid, interpolate to it else: + # Call grid_interp method if interp: spec_dict = self.grid_interp(Teff, logg, FeH) + + # If no interpolation, just get the closest else: - return + + # Find the closest of each parameter + teff_val = min(self.Teff_vals, key=lambda x: abs(x - Teff)) + logg_val = min(self.logg_vals, key=lambda x: abs(x - logg)) + feh_val = min(self.FeH_vals, key=lambda x: abs(x - FeH)) + print('Closest model to [{}, {}, {}] => [{}, {}, {}]'.format(Teff, logg, FeH, teff_val, logg_val, feh_val)) + + # Run `get` method again with on-grid points + spec_dict = self.get(teff_val, logg_val, feh_val) return spec_dict @@ -564,7 +575,7 @@ def toQ(val): ' model not in grid.') return - def grid_interp(self, Teff, logg, FeH, plot=False): + def grid_interp(self, Teff, logg, FeH): """ Interpolate the grid to the desired parameters @@ -577,9 +588,6 @@ def grid_interp(self, Teff, logg, FeH, plot=False): FeH: float The logarithm of the ratio of the metallicity and solar metallicity (dex) - plot: bool - Plot the interpolated spectrum along - with the 8 neighboring grid spectra Returns ------- From 9a02df5e8eb3f3769a186053331ed295139aee18 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Fri, 21 Jul 2023 12:21:15 -0400 Subject: [PATCH 05/30] Updated hotsoss to v0.1.9 for python 3.9+ support --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 91e930a9..def1b01e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -14,7 +14,7 @@ flask==1.1.2 flask_wtf==0.14.3 gunicorn==20.1.0 h5py==3.2.1 -hotsoss==0.1.8 +hotsoss==0.1.9 ipython==7.22.0 matplotlib==3.4.1 numpy>=1.21.4 From 9ab9c33c89a2a52ab939436012fcb2def46efc6b Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Fri, 21 Jul 2023 14:56:30 -0400 Subject: [PATCH 06/30] Upgraded svo_filters to v0.5.0 for py10 support --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index def1b01e..1aaeb663 100644 --- a/requirements.txt +++ b/requirements.txt @@ -33,7 +33,7 @@ scp==0.13.3 sphinx==3.5.3 sphinx_astropy==1.3 sphinx-automodapi==0.13 -svo_filters==0.4.1 +svo_filters>=0.5.0 sqlalchemy==1.4.4 wtforms==2.3.3 git+https://github.com/spacetelescope/jwst_gtvt.git@7013b58 From fd5b70494e7dce3ea83ebc07e65a22631f59fdbe Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 16 Aug 2023 11:32:49 -0400 Subject: [PATCH 07/30] Bumped hotsoss version to v0.1.9 --- env/environment-3.8.yml | 2 +- env/environment-3.9.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/env/environment-3.8.yml b/env/environment-3.8.yml index acb0677f..283d96bf 100644 --- a/env/environment-3.8.yml +++ b/env/environment-3.8.yml @@ -36,7 +36,7 @@ dependencies: - docutils==0.15.2 - flask_wtf==0.14.3 - h5py>=3.8.0 - - hotsoss==0.1.8 + - hotsoss==0.1.9 - gunicorn==20.0.4 - numpy>=1.24.2 - platon==5.1.2 diff --git a/env/environment-3.9.yml b/env/environment-3.9.yml index 81b31bcc..cd8e1d10 100644 --- a/env/environment-3.9.yml +++ b/env/environment-3.9.yml @@ -35,7 +35,7 @@ dependencies: - docutils==0.15.2 - flask_wtf==0.14.3 - h5py>=3.8.0 - - hotsoss==0.1.8 + - hotsoss==0.1.9 - gunicorn==20.0.4 - numpy>=1.24.2 - platon==5.1.2 From 2d0820df9bf007d80b5c87be0d49a5e75b1ead7c Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Mon, 28 Aug 2023 12:02:07 -0400 Subject: [PATCH 08/30] Bumper hotsoss to v0.1.9 --- env/environment-3.10.yml | 2 +- env/environment-3.11.yml | 2 +- env/environment-3.9.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/env/environment-3.10.yml b/env/environment-3.10.yml index 3b9b3b08..afd59f99 100644 --- a/env/environment-3.10.yml +++ b/env/environment-3.10.yml @@ -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 diff --git a/env/environment-3.11.yml b/env/environment-3.11.yml index 7ede496c..6a0b7dd9 100644 --- a/env/environment-3.11.yml +++ b/env/environment-3.11.yml @@ -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 diff --git a/env/environment-3.9.yml b/env/environment-3.9.yml index 3a24a66c..96bb4a7e 100644 --- a/env/environment-3.9.yml +++ b/env/environment-3.9.yml @@ -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 From fc4492f2931380c08bd86a5eba7a99e651949960 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Mon, 28 Aug 2023 13:59:16 -0400 Subject: [PATCH 09/30] Loosened up dependencies --- env/environment-3.10.yml | 2 +- env/environment-3.11.yml | 2 +- env/environment-3.9.yml | 2 +- requirements.txt | 78 ++++++++++++++++++++-------------------- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/env/environment-3.10.yml b/env/environment-3.10.yml index afd59f99..5e7d16e5 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.1 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 diff --git a/env/environment-3.11.yml b/env/environment-3.11.yml index 6a0b7dd9..7cd8f62d 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.1 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 diff --git a/env/environment-3.9.yml b/env/environment-3.9.yml index 96bb4a7e..846f14e4 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.1 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 diff --git a/requirements.txt b/requirements.txt index 1aaeb663..3e5e8bbb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,40 +1,40 @@ -asteval==0.9.16 -astropy>=4.2 -bandit==1.7.0 -batman-package==2.4.8 -bibtexparser==1.2.0 -bokeh==2.3.0 -boto3==1.17.42 -corner==2.2.1 -cython==0.29.22 -docopt==0.6.2 -docutils==0.16 -flake8==3.9.0 -flask==1.1.2 -flask_wtf==0.14.3 -gunicorn==20.1.0 -h5py==3.2.1 -hotsoss==0.1.9 -ipython==7.22.0 -matplotlib==3.4.1 -numpy>=1.21.4 -numpydoc==1.1.0 -pandas==1.3.5 -paramiko==2.10.1 -platon==5.1.2 -pysiaf==0.10.0 -pysynphot==1.0.0 -pytest==6.2.2 -pyvo==1.1 -pyyaml==5.4.1 -regions==0.5 -scipy==1.6.2 -scp==0.13.3 -sphinx==3.5.3 -sphinx_astropy==1.3 -sphinx-automodapi==0.13 +asteval>=0.9.16 +astropy>=5.3.1 +bandit>=1.7.0 +batman-package>=2.4.8 +bibtexparser>=1.2.0 +bokeh>=3.2.1 +boto3>=1.17.42 +corner>=2.2.1 +cython>=0.29.22 +docopt>=0.6.2 +docutils>=0.16 +flake8>=3.9.0 +flask>=1.1.2 +flask_wtf>=0.14.3 +gunicorn>=20.1.0 +h5py>=3.2.1 +hotsoss>=0.1.9 +ipython>=7.22.0 +jwst-gtvt>=1.0.0 +matplotlib>=3.4.1 +numpy>=1.25.1 +numpydoc>=1.1.0 +pandas>=2.0.3 +paramiko>=2.10.1 +platon>=5.1.2 +pysiaf>=0.10.0 +pysynphot>=2.0.0 +pytest>=6.2.2 +pyvo>=1.1 +pyyaml>=5.4.1 +regions>=0.5 +scipy>=1.11.1 +scp>=0.13.3 +sphinx>=3.5.3 +sphinx_astropy>=1.3 +sphinx-automodapi>=0.13 svo_filters>=0.5.0 -sqlalchemy==1.4.4 -wtforms==2.3.3 -git+https://github.com/spacetelescope/jwst_gtvt.git@7013b58 -astroquery>=0.4.2 \ No newline at end of file +sqlalchemy>=1.4.4 +wtforms>=2.3.3 +astroquery>=0.4.6 \ No newline at end of file From 1302925882ba7b586dd4842cfa14a833a4bfcf1b Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Mon, 28 Aug 2023 14:10:42 -0400 Subject: [PATCH 10/30] Updated Panel to TabPanel for bokeh --- exoctk/limb_darkening/limb_darkening_fit.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/exoctk/limb_darkening/limb_darkening_fit.py b/exoctk/limb_darkening/limb_darkening_fit.py index 51116a96..238c04e5 100755 --- a/exoctk/limb_darkening/limb_darkening_fit.py +++ b/exoctk/limb_darkening/limb_darkening_fit.py @@ -14,8 +14,7 @@ import astropy.table as at from astropy.utils.exceptions import AstropyWarning import bokeh.plotting as bkp -from bokeh.models import Range1d -from bokeh.models.widgets import Panel, Tabs +from bokeh.models import Range1d, TabPanel, Tabs import matplotlib import matplotlib.pyplot as plt from matplotlib import rc @@ -541,7 +540,7 @@ def plot_tabs(self, show=False, **kwargs): fig.xaxis.axis_label = 'mu' fig.yaxis.axis_label = 'Intensity' - tabs.append(Panel(child=fig, title=str(wav))) + tabs.append(TabPanel(child=fig, title=str(wav))) # Make the final tabbed figure final = Tabs(tabs=tabs) From 04800defcdd7a5f8370f0e5edb26a5e162c8360d Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Mon, 28 Aug 2023 14:58:49 -0400 Subject: [PATCH 11/30] Updated LDC tests for bokeh 3.0 --- exoctk/limb_darkening/limb_darkening_fit.py | 4 ++-- exoctk/tests/test_limb_darkening.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exoctk/limb_darkening/limb_darkening_fit.py b/exoctk/limb_darkening/limb_darkening_fit.py index 238c04e5..f8701d3f 100755 --- a/exoctk/limb_darkening/limb_darkening_fit.py +++ b/exoctk/limb_darkening/limb_darkening_fit.py @@ -532,7 +532,7 @@ def plot_tabs(self, show=False, **kwargs): # Plot it TOOLS = 'box_zoom, box_select, crosshair, reset, hover' - fig = bkp.figure(tools=TOOLS, x_range=Range1d(0, 1), y_range=Range1d(0, 1), plot_width=800, plot_height=400) + fig = bkp.figure(tools=TOOLS, x_range=Range1d(0, 1), y_range=Range1d(0, 1), width=800, height=400) self.plot(wave_eff=wav, fig=fig) # Plot formatting @@ -546,7 +546,7 @@ def plot_tabs(self, show=False, **kwargs): final = Tabs(tabs=tabs) # Put the names back - self.results['name'] = old_names + self.results['name'] = old_names if show: bkp.show(final) diff --git a/exoctk/tests/test_limb_darkening.py b/exoctk/tests/test_limb_darkening.py index 27b270df..18c0c592 100755 --- a/exoctk/tests/test_limb_darkening.py +++ b/exoctk/tests/test_limb_darkening.py @@ -128,8 +128,8 @@ def test_ldc_plot(): # Regular plot fig = ld_session.plot() - assert str(type(fig)) == "" + assert str(type(fig)) == "" # Tabbed plot fig = ld_session.plot_tabs() - assert str(type(fig)) in ["", ""] + assert str(type(fig)) in ["", ""] From 979a8c7af1ac72a0ad643c8d0db9bf864e6932d6 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Tue, 29 Aug 2023 10:56:12 -0400 Subject: [PATCH 12/30] Merging develop into ldc_fix --- exoctk/contam_visibility/field_simulator.py | 16 ++--- exoctk/contam_visibility/visibilityPA.py | 6 +- exoctk/exoctk_app/app_exoctk.py | 6 +- exoctk/tests/test_contam_visibility.py | 66 ++++++++++----------- 4 files changed, 49 insertions(+), 45 deletions(-) diff --git a/exoctk/contam_visibility/field_simulator.py b/exoctk/contam_visibility/field_simulator.py index 19725946..c46c7602 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"] @@ -735,8 +736,13 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p # 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]) + # minPA, maxPA, _, _, _, badPAs = using_gtvt(ra_hms[:-1], dec_dms[:-1], inst['inst']) + # badPA_list = np.concatenate([np.array(i) for i in badPAs]) + + # Exclude PAs where target is not visible to speed up calculation + table = get_exoplanet_positions(ra_hms, dec_dms) + badPA_list = table[~table['in_FOR']] + good_pa_list = [pa for pa in pa_list if pa not in badPA_list] # Calculate contamination of all stars at each PA @@ -995,10 +1001,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 ------- diff --git a/exoctk/contam_visibility/visibilityPA.py b/exoctk/contam_visibility/visibilityPA.py index abd73a44..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) @@ -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..925a3cc5 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 @@ -478,9 +478,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)) + badPAs = table[~'in_FOR'] + print(badPAs) + # Make output table fh = io.StringIO() table.to_csv(fh, index=False) diff --git a/exoctk/tests/test_contam_visibility.py b/exoctk/tests/test_contam_visibility.py index fca9d1d3..172a1160 100644 --- a/exoctk/tests/test_contam_visibility.py +++ b/exoctk/tests/test_contam_visibility.py @@ -34,17 +34,17 @@ ON_GITHUB_ACTIONS = '/home/runner' in os.path.expanduser('~') or '/Users/runner' in os.path.expanduser('~') -def test_checkVisPA(): - """Tests the ``checkVisPA`` function in the ``visibilityPA`` module""" - - ra = '24.3544618' - dec = '-45.6777937' - pa_good, pa_bad, gd, figure = visibilityPA.checkVisPA(ra, dec) - - assert isinstance(pa_good, list) and len(pa_good) > 0 - assert isinstance(pa_bad, list) and len(pa_bad) > 0 - assert isinstance(gd, list) and len(gd) > 0 - assert isinstance(figure, object) +# def test_checkVisPA(): +# """Tests the ``checkVisPA`` function in the ``visibilityPA`` module""" +# +# ra = '24.3544618' +# dec = '-45.6777937' +# pa_good, pa_bad, gd, figure = visibilityPA.checkVisPA(ra, dec) +# +# assert isinstance(pa_good, list) and len(pa_good) > 0 +# assert isinstance(pa_bad, list) and len(pa_bad) > 0 +# assert isinstance(gd, list) and len(gd) > 0 +# assert isinstance(figure, object) @pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Need access to trace data FITS files. Please try running locally') @@ -69,25 +69,25 @@ def test_resolve_target(): assert dec == -45.6777937 -@pytest.mark.skipif(sys.version_info > (3, 9), reason='jwst_gtvt does not currently support python>=3.9.') -def test_using_gtvt(): - """Test to see that gtvt works for all instruments""" - for instrument in ['NIRISS', 'NIRCam', 'NIRSpec', 'MIRI']: - - # this ra/dec has bad PAs - ra = "-66" - dec = "44" - paMin, paMax, gd, fig, table, grouped_badPAs = visibilityPA.using_gtvt(ra, dec, instrument, targetName="Target", output="bokeh") - assert grouped_badPAs is not None - - # this ra/dec has 100% coverage (no bad PAs) - ra = '88' - dec = '-64' - output = visibilityPA.using_gtvt(ra, dec, instrument, targetName="Target", output="bokeh") - - assert output is not None - assert len(output) == 6 - - paMin, paMax, gd, fig, table, grouped_badPAs = output - - assert len(grouped_badPAs) == 0 +# @pytest.mark.skipif(sys.version_info > (3, 9), reason='jwst_gtvt does not currently support python>=3.9.') +# def test_using_gtvt(): +# """Test to see that gtvt works for all instruments""" +# for instrument in ['NIRISS', 'NIRCam', 'NIRSpec', 'MIRI']: +# +# # this ra/dec has bad PAs +# ra = "-66" +# dec = "44" +# paMin, paMax, gd, fig, table, grouped_badPAs = visibilityPA.using_gtvt(ra, dec, instrument, targetName="Target", output="bokeh") +# assert grouped_badPAs is not None +# +# # this ra/dec has 100% coverage (no bad PAs) +# ra = '88' +# dec = '-64' +# output = visibilityPA.using_gtvt(ra, dec, instrument, targetName="Target", output="bokeh") +# +# assert output is not None +# assert len(output) == 6 +# +# paMin, paMax, gd, fig, table, grouped_badPAs = output +# +# assert len(grouped_badPAs) == 0 From 946cd05b797cb8da5976afe41e02423e3c6e9c56 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Tue, 29 Aug 2023 11:37:56 -0400 Subject: [PATCH 13/30] Adding new_vis_plot.py module --- exoctk/contam_visibility/new_vis_plot.py | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 exoctk/contam_visibility/new_vis_plot.py diff --git a/exoctk/contam_visibility/new_vis_plot.py b/exoctk/contam_visibility/new_vis_plot.py new file mode 100644 index 00000000..f632534c --- /dev/null +++ b/exoctk/contam_visibility/new_vis_plot.py @@ -0,0 +1,68 @@ +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): + """Use the jwst_gtvt to obtain positions of exoplanet. + """ + + eph = Ephemeris() + exoplanet_data = eph.get_fixed_target_positions(ra, dec) + data_in_FOR = exoplanet_data.loc[exoplanet_data['in_FOR']==True] + + return data_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) + 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}", + plot_height=400, plot_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 From 82f9d197f34d79e3d68c311eef8cd8577422e74b Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Tue, 29 Aug 2023 14:46:47 -0400 Subject: [PATCH 14/30] Added tests for new_vis_plot.py --- exoctk/contam_visibility/new_vis_plot.py | 8 ++-- exoctk/tests/test_contam_visibility.py | 49 ++++++------------------ 2 files changed, 16 insertions(+), 41 deletions(-) diff --git a/exoctk/contam_visibility/new_vis_plot.py b/exoctk/contam_visibility/new_vis_plot.py index f632534c..c759abf1 100644 --- a/exoctk/contam_visibility/new_vis_plot.py +++ b/exoctk/contam_visibility/new_vis_plot.py @@ -7,15 +7,15 @@ from jwst_gtvt.plotting import get_visibility_windows -def get_exoplanet_positions(ra, dec): +def get_exoplanet_positions(ra, dec, in_FOR=True): """Use the jwst_gtvt to obtain positions of exoplanet. """ eph = Ephemeris() exoplanet_data = eph.get_fixed_target_positions(ra, dec) - data_in_FOR = exoplanet_data.loc[exoplanet_data['in_FOR']==True] + exo_data = exoplanet_data.loc[exoplanet_data['in_FOR']==in_FOR] - return data_in_FOR + return exo_data def build_visibility_plot(target_name, instrument, ra, dec): """Build bokeh figure for visibility windows @@ -46,7 +46,7 @@ def build_visibility_plot(target_name, instrument, ra, dec): ("Max Position Angle", "@{}".format(max_pa_column_name)),] p = figure(title=f"{target_name} Visibility with {instrument}", - plot_height=400, plot_width=800, x_axis_type='datetime') + height=400, width=800, x_axis_type='datetime') p.xaxis.axis_label = 'Date' p.yaxis.axis_label = 'Available Aperture Position Angles (Degrees)' diff --git a/exoctk/tests/test_contam_visibility.py b/exoctk/tests/test_contam_visibility.py index 172a1160..47831245 100644 --- a/exoctk/tests/test_contam_visibility.py +++ b/exoctk/tests/test_contam_visibility.py @@ -6,6 +6,7 @@ Authors ------- + Joe Filippazzo Matthew Bourque Ben Falk @@ -26,25 +27,23 @@ import pytest from exoctk.contam_visibility import field_simulator -from exoctk.contam_visibility import miniTools from exoctk.contam_visibility import resolve -from exoctk.contam_visibility import visibilityPA +from exoctk.contam_visibility import new_vis_plot # Determine if tests are being run on Github Actions ON_GITHUB_ACTIONS = '/home/runner' in os.path.expanduser('~') or '/Users/runner' in os.path.expanduser('~') -# def test_checkVisPA(): -# """Tests the ``checkVisPA`` function in the ``visibilityPA`` module""" -# -# ra = '24.3544618' -# dec = '-45.6777937' -# pa_good, pa_bad, gd, figure = visibilityPA.checkVisPA(ra, dec) -# -# assert isinstance(pa_good, list) and len(pa_good) > 0 -# assert isinstance(pa_bad, list) and len(pa_bad) > 0 -# assert isinstance(gd, list) and len(gd) > 0 -# assert isinstance(figure, object) +def test_new_vis_plot(): + """Tests the `new_vis_plot.py` module""" + ra, dec = '24.3544618', '-45.6777937' # WASP-18 + table = new_vis_plot.get_exoplanet_positions(ra, dec) + + assert str(type(table)) == "" + + plt = new_vis_plot.build_visibility_plot('WASP-18b', 'NIRISS', ra, dec) + + assert str(type(plt)) == "" @pytest.mark.skipif(ON_GITHUB_ACTIONS, reason='Need access to trace data FITS files. Please try running locally') @@ -67,27 +66,3 @@ def test_resolve_target(): assert ra == 24.3544618 assert dec == -45.6777937 - - -# @pytest.mark.skipif(sys.version_info > (3, 9), reason='jwst_gtvt does not currently support python>=3.9.') -# def test_using_gtvt(): -# """Test to see that gtvt works for all instruments""" -# for instrument in ['NIRISS', 'NIRCam', 'NIRSpec', 'MIRI']: -# -# # this ra/dec has bad PAs -# ra = "-66" -# dec = "44" -# paMin, paMax, gd, fig, table, grouped_badPAs = visibilityPA.using_gtvt(ra, dec, instrument, targetName="Target", output="bokeh") -# assert grouped_badPAs is not None -# -# # this ra/dec has 100% coverage (no bad PAs) -# ra = '88' -# dec = '-64' -# output = visibilityPA.using_gtvt(ra, dec, instrument, targetName="Target", output="bokeh") -# -# assert output is not None -# assert len(output) == 6 -# -# paMin, paMax, gd, fig, table, grouped_badPAs = output -# -# assert len(grouped_badPAs) == 0 From bae34a346bcd96db5a6a01f248b176b3e4e771de Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Tue, 29 Aug 2023 15:17:39 -0400 Subject: [PATCH 15/30] Fixed plotting stuff --- exoctk/contam_visibility/field_simulator.py | 14 ++++---------- exoctk/exoctk_app/app_exoctk.py | 3 +-- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/exoctk/contam_visibility/field_simulator.py b/exoctk/contam_visibility/field_simulator.py index c46c7602..3d8232a8 100755 --- a/exoctk/contam_visibility/field_simulator.py +++ b/exoctk/contam_visibility/field_simulator.py @@ -685,7 +685,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') @@ -736,13 +736,7 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p # 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]) - - # Exclude PAs where target is not visible to speed up calculation - table = get_exoplanet_positions(ra_hms, dec_dms) - badPA_list = table[~table['in_FOR']] - + badPA_list = list(get_exoplanet_positions(ra_hms, dec_dms, in_FOR=False)['V3PA']) good_pa_list = [pa for pa in pa_list if pa not in badPA_list] # Calculate contamination of all stars at each PA @@ -833,7 +827,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') @@ -877,7 +871,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") diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 925a3cc5..ca18af0a 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -480,8 +480,7 @@ def contam_visibility(): # 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)) - badPAs = table[~'in_FOR'] - print(badPAs) + badPAs = list(get_exoplanet_positions(str(form.ra.data), str(form.dec.data), in_FOR=False)['V3PA']) # Make output table fh = io.StringIO() From 24e940e3f82f40d26f748c7fc6177867c7a0a4a7 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Tue, 29 Aug 2023 17:29:14 -0400 Subject: [PATCH 16/30] Fixed bokeh plot_width issue in LDC and added wavelength ranges to mode grid radio buttons on form --- exoctk/exoctk_app/app_exoctk.py | 4 ++-- exoctk/exoctk_app/templates/limb_darkening.html | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index ca18af0a..885cb5ff 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -727,8 +727,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) diff --git a/exoctk/exoctk_app/templates/limb_darkening.html b/exoctk/exoctk_app/templates/limb_darkening.html index 95c5c45d..db6f5351 100644 --- a/exoctk/exoctk_app/templates/limb_darkening.html +++ b/exoctk/exoctk_app/templates/limb_darkening.html @@ -43,8 +43,10 @@

Limb Darkening Calculator

{% if subfield.label.text == 'Kurucz ATLAS9' %} {{ subfield(style='margin-left:0px;', id='atlas9', checked='checked') }}{{ subfield.label }} + Wavelength Range: 0.1\(\mu\)m - 30.0\(\mu\)m {% else %} {{ subfield(style='margin-left:0px;', id='aces') }}{{ subfield.label }} + Wavelength Range: 0.1\(\mu\)m - 2.6\(\mu\)m {% endif %}
{% endfor %} From 0ab536d8badeb59611888a3c68ab27d424fd32f8 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 10:18:53 -0400 Subject: [PATCH 17/30] bohel plot keyword fix --- env/environment-3.10.yml | 2 +- env/environment-3.11.yml | 2 +- env/environment-3.9.yml | 5 +++-- exoctk/forward_models/forward_models.py | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/env/environment-3.10.yml b/env/environment-3.10.yml index 5e7d16e5..4673a6d1 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>=3.2.1 + - bokeh>=3.2.2 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 diff --git a/env/environment-3.11.yml b/env/environment-3.11.yml index 7cd8f62d..a95673d9 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>=3.2.1 + - bokeh>=3.2.2 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 diff --git a/env/environment-3.9.yml b/env/environment-3.9.yml index 846f14e4..e7fe43f9 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>=3.2.1 + - bokeh>=3.2.2 - cython>=0.29.35 - docopt>=0.6.2 - docutils>=0.16 @@ -37,6 +37,7 @@ dependencies: - h5py>=3.9.0 - 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.2.2 - jwst_gtvt>=1.0.0 - astroquery>=0.4.6 \ No newline at end of file diff --git a/exoctk/forward_models/forward_models.py b/exoctk/forward_models/forward_models.py index 3cd55f8b..08d6e952 100644 --- a/exoctk/forward_models/forward_models.py +++ b/exoctk/forward_models/forward_models.py @@ -148,7 +148,7 @@ def fortney_grid(args, write_plot=False, write_table=False): if write_table: tab.write('fortney.dat', format='ascii.no_header') - fig = figure(plot_width=1100, plot_height=400) + fig = figure(width=1100, 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)' @@ -215,7 +215,7 @@ def generic_grid(input_args, write_plot=False, write_table=False): tab.write('generic.dat') # Plot - fig = figure(title='Rescaled Generic Grid Transmission Spectra'.upper(), plot_width=1100, plot_height=400) + fig = figure(title='Rescaled Generic Grid Transmission Spectra'.upper(), width=1100, height=400) fig.x_range.start = 0.3 fig.x_range.end = 5 fig.line(solution['wv'], solution['spectra'], color='Black', line_width=1) From 2f2cf7a1680cde4860457d6c01d15049f9983d8f Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 10:19:07 -0400 Subject: [PATCH 18/30] pinning werkzeug --- env/environment-3.10.yml | 2 +- env/environment-3.11.yml | 2 +- env/environment-3.9.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/env/environment-3.10.yml b/env/environment-3.10.yml index 4673a6d1..0f456da7 100644 --- a/env/environment-3.10.yml +++ b/env/environment-3.10.yml @@ -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 a95673d9..4206bd96 100644 --- a/env/environment-3.11.yml +++ b/env/environment-3.11.yml @@ -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 e7fe43f9..44f0813b 100644 --- a/env/environment-3.9.yml +++ b/env/environment-3.9.yml @@ -48,6 +48,6 @@ dependencies: - scipy>=1.11.1 - sphinx_astropy>=1.9.1 - svo-filters>=0.4.4 - - werkzeug>=2.2.2 + - werkzeug==2.0.3 - jwst_gtvt>=1.0.0 - astroquery>=0.4.6 \ No newline at end of file From 2f0795ae759eba88bb6340b14407959812a2877a Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 10:33:05 -0400 Subject: [PATCH 19/30] Trying to fix visibility table download button --- exoctk/exoctk_app/app_exoctk.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 885cb5ff..984e7d27 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -1017,8 +1017,7 @@ def save_visib_result(): targname = targname.replace(' ', '_') # no spaces instname = flask.request.form['instrumentname'] - return flask.Response(visib_table, mimetype="text/dat", - headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) + return flask.Response(visib_table, mimetype="text/csv", headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) @app_exoctk.route('/admin') From d2517fd0701b99a7a05d4cc9f98e49167bfff5a1 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 10:59:14 -0400 Subject: [PATCH 20/30] Trying download button --- exoctk/exoctk_app/app_exoctk.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 984e7d27..d7e43e87 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -1013,12 +1013,12 @@ def save_visib_result(): """ visib_table = flask.request.form['data_file'] - targname = flask.request.form['targetname'] - targname = targname.replace(' ', '_') # no spaces - instname = flask.request.form['instrumentname'] - - return flask.Response(visib_table, mimetype="text/csv", headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) + # targname = flask.request.form['targetname'] + # targname = targname.replace(' ', '_') # no spaces + # instname = flask.request.form['instrumentname'] + # return flask.Response(visib_table, mimetype="text/csv", headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) + return flask.Response(visib_table, mimetype="text/csv", headers={"Content-disposition": "attachment; filename=target_visibility.csv"}) @app_exoctk.route('/admin') @requires_auth From ea1844fd1c38af9c7846c3d537265bcc909b21e2 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 11:05:09 -0400 Subject: [PATCH 21/30] Trying by passing DF to form --- exoctk/exoctk_app/app_exoctk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index d7e43e87..3782e0bf 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -483,9 +483,9 @@ def contam_visibility(): badPAs = list(get_exoplanet_positions(str(form.ra.data), str(form.dec.data), in_FOR=False)['V3PA']) # Make output table - fh = io.StringIO() + # fh = io.StringIO() table.to_csv(fh, index=False) - visib_table = fh.getvalue() + # visib_table = fh.getvalue() # Get scripts vis_js = INLINE.render_js() From d391c89e14c40bcbe81151a02f4a4b77c2c760d5 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 11:41:16 -0400 Subject: [PATCH 22/30] Save as dat --- exoctk/exoctk_app/app_exoctk.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 3782e0bf..836a5622 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -483,9 +483,8 @@ def contam_visibility(): badPAs = list(get_exoplanet_positions(str(form.ra.data), str(form.dec.data), in_FOR=False)['V3PA']) # Make output table - # fh = io.StringIO() - table.to_csv(fh, index=False) - # visib_table = fh.getvalue() + visib_table = Table.from_pandas(table) + file_as_string = '\n'.join(visib_table.pformat(max_lines=-1, max_width=-1)) # Get scripts vis_js = INLINE.render_js() @@ -562,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=file_as_string, vis_script=vis_script, vis_js=vis_js, vis_css=vis_css, contam_plot=contam_div, contam_script=contam_script, @@ -1013,12 +1012,12 @@ def save_visib_result(): """ visib_table = flask.request.form['data_file'] - # targname = flask.request.form['targetname'] - # targname = targname.replace(' ', '_') # no spaces - # instname = flask.request.form['instrumentname'] + targname = flask.request.form['targetname'] + targname = targname.replace(' ', '_') # no spaces + instname = flask.request.form['instrumentname'] + + return flask.Response(visib_table, mimetype="text/dat", headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) - # return flask.Response(visib_table, mimetype="text/csv", headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) - return flask.Response(visib_table, mimetype="text/csv", headers={"Content-disposition": "attachment; filename=target_visibility.csv"}) @app_exoctk.route('/admin') @requires_auth From 505d5d84b046b3568112a108e1e75e16cfb665fa Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 11:47:13 -0400 Subject: [PATCH 23/30] typo --- exoctk/exoctk_app/app_exoctk.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 836a5622..08cecc3d 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -483,7 +483,7 @@ def contam_visibility(): badPAs = list(get_exoplanet_positions(str(form.ra.data), str(form.dec.data), in_FOR=False)['V3PA']) # Make output table - visib_table = Table.from_pandas(table) + visib_table = at.Table.from_pandas(table) file_as_string = '\n'.join(visib_table.pformat(max_lines=-1, max_width=-1)) # Get scripts @@ -1016,7 +1016,7 @@ def save_visib_result(): targname = targname.replace(' ', '_') # no spaces instname = flask.request.form['instrumentname'] - return flask.Response(visib_table, mimetype="text/dat", headers={"Content-disposition": "attachment; filename={}_{}_visibility.csv".format(targname, instname)}) + return flask.Response(visib_table, mimetype="text/dat", headers={"Content-disposition": "attachment; filename={}_{}_visibility.dat".format(targname, instname)}) @app_exoctk.route('/admin') From c40a34355da4515239c2aa54e9ba1d3d32bfe7de Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Wed, 30 Aug 2023 12:32:03 -0400 Subject: [PATCH 24/30] Fixing visib download --- exoctk/exoctk_app/app_exoctk.py | 17 ++++++++++------- .../templates/contam_visibility_results.html | 4 ++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 08cecc3d..25accb63 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -484,7 +484,7 @@ def contam_visibility(): # Make output table visib_table = at.Table.from_pandas(table) - file_as_string = '\n'.join(visib_table.pformat(max_lines=-1, max_width=-1)) + vis_table = '\n'.join(visib_table.pformat(max_lines=-1, max_width=-1)) # Get scripts vis_js = INLINE.render_js() @@ -561,7 +561,7 @@ def contam_visibility(): return render_template('contam_visibility_results.html', form=form, vis_plot=vis_div, - vis_table=file_as_string, + vis_table=vis_table, vis_script=vis_script, vis_js=vis_js, vis_css=vis_css, contam_plot=contam_div, contam_script=contam_script, @@ -1010,13 +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.dat".format(targname, instname) + resp.headers["Content-Type"] = "text/dat" - return flask.Response(visib_table, mimetype="text/dat", headers={"Content-disposition": "attachment; filename={}_{}_visibility.dat".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..f85f75e9 100644 --- a/exoctk/exoctk_app/templates/contam_visibility_results.html +++ b/exoctk/exoctk_app/templates/contam_visibility_results.html @@ -54,8 +54,8 @@

Target Visibility

{{ vis_plot | safe }}
-
- +
+ From e85ffe2f234f36b66079bddb7b680f2b7cc25dd3 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Fri, 1 Sep 2023 14:04:35 -0400 Subject: [PATCH 25/30] Spruced up contam plot reeeeal nice --- .../contam_visibility/contamination_figure.py | 132 +++++++++--------- exoctk/contam_visibility/field_simulator.py | 39 ++++-- exoctk/contam_visibility/new_vis_plot.py | 11 +- exoctk/exoctk_app/app_exoctk.py | 12 +- 4 files changed, 106 insertions(+), 88 deletions(-) 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 3d8232a8..82278298 100755 --- a/exoctk/contam_visibility/field_simulator.py +++ b/exoctk/contam_visibility/field_simulator.py @@ -670,7 +670,7 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p n_jobs: int Number of cores to use (-1 = All) pa_list: sequence - The position angles to calculate + The position angles to consider Returns ------- @@ -729,16 +729,37 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p 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(' ') - badPA_list = list(get_exoplanet_positions(ra_hms, dec_dms, in_FOR=False)['V3PA']) - 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 +770,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) diff --git a/exoctk/contam_visibility/new_vis_plot.py b/exoctk/contam_visibility/new_vis_plot.py index c759abf1..4cddc59b 100644 --- a/exoctk/contam_visibility/new_vis_plot.py +++ b/exoctk/contam_visibility/new_vis_plot.py @@ -7,15 +7,18 @@ from jwst_gtvt.plotting import get_visibility_windows -def get_exoplanet_positions(ra, dec, in_FOR=True): +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) - exo_data = exoplanet_data.loc[exoplanet_data['in_FOR']==in_FOR] - return exo_data + 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 @@ -31,7 +34,7 @@ def build_visibility_plot(target_name, instrument, ra, dec): max_pa_column_name = instrument + '_max_pa_angle' # obtain exoplanet data and filter visibility windows - exoplanet_df = get_exoplanet_positions(ra, dec) + 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 diff --git a/exoctk/exoctk_app/app_exoctk.py b/exoctk/exoctk_app/app_exoctk.py index 25accb63..2618b0f0 100644 --- a/exoctk/exoctk_app/app_exoctk.py +++ b/exoctk/exoctk_app/app_exoctk.py @@ -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)) - badPAs = list(get_exoplanet_positions(str(form.ra.data), str(form.dec.data), in_FOR=False)['V3PA']) # Make output table - visib_table = at.Table.from_pandas(table) - vis_table = '\n'.join(visib_table.pformat(max_lines=-1, max_width=-1)) + 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] @@ -1016,8 +1016,8 @@ def save_visib_result(): instname = request.form['instrumentname'] resp = make_response(visib_table) - resp.headers["Content-Disposition"] = "attachment; filename={}_{}_visibility.dat".format(targname, instname) - resp.headers["Content-Type"] = "text/dat" + resp.headers["Content-Disposition"] = "attachment; filename={}_{}_visibility.csv".format(targname, instname) + resp.headers["Content-Type"] = "text/csv" return resp From f8903135b975ec7ffd7d5acfd083f033e0b9f1e6 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Fri, 1 Sep 2023 14:54:54 -0400 Subject: [PATCH 26/30] Hovertool kwarg update --- exoctk/contam_visibility/field_simulator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/exoctk/contam_visibility/field_simulator.py b/exoctk/contam_visibility/field_simulator.py index 82278298..667eb2ee 100755 --- a/exoctk/contam_visibility/field_simulator.py +++ b/exoctk/contam_visibility/field_simulator.py @@ -391,7 +391,7 @@ 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") # Make the plot @@ -1057,7 +1057,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)) From 0621b0f758665a253328f77892a6dd4b9ba2c548 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Fri, 1 Sep 2023 16:20:01 -0400 Subject: [PATCH 27/30] Reduced max cores to 8 --- exoctk/contam_visibility/field_simulator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exoctk/contam_visibility/field_simulator.py b/exoctk/contam_visibility/field_simulator.py index 667eb2ee..4fa688c2 100755 --- a/exoctk/contam_visibility/field_simulator.py +++ b/exoctk/contam_visibility/field_simulator.py @@ -721,7 +721,7 @@ 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 From 0b190ac752cc95cea94c830432189decfd32778c Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Fri, 1 Sep 2023 17:12:56 -0400 Subject: [PATCH 28/30] Superfluous line --- exoctk/contam_visibility/field_simulator.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/exoctk/contam_visibility/field_simulator.py b/exoctk/contam_visibility/field_simulator.py index 4fa688c2..d3726a0f 100755 --- a/exoctk/contam_visibility/field_simulator.py +++ b/exoctk/contam_visibility/field_simulator.py @@ -654,7 +654,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 @@ -669,8 +669,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 consider Returns ------- @@ -725,10 +723,6 @@ def field_simulation(ra, dec, aperture, binComp=None, n_jobs=-1, pa_list=None, p 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) From efcc196b9c0a65b436e25b6b6252d0ab8f09f412 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Tue, 5 Sep 2023 12:50:17 -0400 Subject: [PATCH 29/30] Fixed the tap tool for contam plots --- exoctk/contam_visibility/field_simulator.py | 10 +++------- .../templates/contam_visibility_results.html | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/exoctk/contam_visibility/field_simulator.py b/exoctk/contam_visibility/field_simulator.py index d3726a0f..cee46c7e 100755 --- a/exoctk/contam_visibility/field_simulator.py +++ b/exoctk/contam_visibility/field_simulator.py @@ -376,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: @@ -393,17 +393,13 @@ def calc_v3pa(V3PA, stars, aperture, data=None, c0x0=885, c0y0=1462, c1x0=-0.11, tips = [('Name', '@name'), ('RA', '@ra'), ('DEC', '@dec'), ('scale', '@fluxscale'), ('Teff', '@Teff'), ('ord0', '@xord0{int}, @yord0{int}')] 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' diff --git a/exoctk/exoctk_app/templates/contam_visibility_results.html b/exoctk/exoctk_app/templates/contam_visibility_results.html index f85f75e9..dcdfdb4f 100644 --- a/exoctk/exoctk_app/templates/contam_visibility_results.html +++ b/exoctk/exoctk_app/templates/contam_visibility_results.html @@ -103,6 +103,7 @@

Target Contamination at PA={{ pa_val }}

{% else %}
  • The top plot shows the simulated observation at the given position angle.
  • +
  • The circles show the detector location of the 0th order, which you can click to resolve in Vizier.
  • Red lines show the predicted order 1, 2, and 3 trace positions for the target (solid) as well as all contaminant sources (dashed).
  • The bottom plot shows the fractional contamination of orders 1 (blue), 2 (red), and 3 (green) in each detector column.
From 8382b561538dc3d1d96de3fc9c55e5834825c5f1 Mon Sep 17 00:00:00 2001 From: Joe Filippazzo Date: Tue, 26 Sep 2023 10:40:52 -0400 Subject: [PATCH 30/30] Fixed requirements so RTD build passes --- exoctk/exoctk_app/templates/limb_darkening.html | 2 +- requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/exoctk/exoctk_app/templates/limb_darkening.html b/exoctk/exoctk_app/templates/limb_darkening.html index db6f5351..0f9e97c9 100644 --- a/exoctk/exoctk_app/templates/limb_darkening.html +++ b/exoctk/exoctk_app/templates/limb_darkening.html @@ -4,7 +4,7 @@ {% block content %} -