Skip to content

Commit

Permalink
Merge pull request #856 from BradleySappington/pep8speaks
Browse files Browse the repository at this point in the history
Additional Pep8speaks updates
  • Loading branch information
mperrin committed May 22, 2024
2 parents 5d521c9 + 656a3e4 commit dfd4528
Show file tree
Hide file tree
Showing 28 changed files with 461 additions and 363 deletions.
2 changes: 1 addition & 1 deletion .pep8speaks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ message: # Customize the comment made by the bot
no_errors: "There are no PEP8 issues in this Pull Request."

scanner:
diff_only: False # If True, errors caused by only the patch are shown
diff_only: True # If True, errors caused by only the patch are shown

pycodestyle:
max-line-length: 125 # Default is 79 in PEP8
Expand Down
2 changes: 1 addition & 1 deletion dev_utils/compute_psf_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

if not os.environ.get('WEBBPSF_PATH'):
os.environ['WEBBPSF_PATH'] = '/grp/jwst/ote/webbpsf-data'
import webbpsf # noqa
import webbpsf # noqa

N_PROCESSES = 16

Expand Down
10 changes: 5 additions & 5 deletions dev_utils/field_dependence/basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,19 @@

os.environ['PINT_ARRAY_PROTOCOL_FALLBACK'] = '0'

import pint # noqa
import pint # noqa

units = pint.UnitRegistry()
Q_ = units.Quantity

# Silence NEP 18 warning
import warnings # noqa
import warnings # noqa

with warnings.catch_warnings():
warnings.simplefilter('ignore')
Q_([])



def embed(n, m):
# Return vector of indices needed to pull an array of length m from the center of an array of (larger) length n, or
# conversely insert an array of length m into an array of length n.
Expand Down Expand Up @@ -216,7 +215,7 @@ def numpolys(self):
def numpolys(self, new_numpolys):
polynomials_copy = self._polynomials
self._polynomials = np.zeros((new_numpolys, self._pts_x, self._pts_y))
self._polynomials[0 : self._numpolys, :, :] = polynomials_copy
self._polynomials[0: self._numpolys, :, :] = polynomials_copy # noqa
self._numpolys = new_numpolys

def project(self, in_data):
Expand Down Expand Up @@ -480,7 +479,8 @@ def __init__(self, *args, **kwargs):
# next_order_start = (self._term_order[index] + 1) * (self._term_order[index] + 2) / 2
# radial_term_index = order_start + self._term_order[index] / 2
# if index < radial_term_index:
# self._polynomial_map[index] = next_order_start - (index - order_start) * 2 - (self._term_order[index] - 1) / 2
# self._polynomial_map[index] =
# next_order_start - (index - order_start) * 2 - (self._term_order[index] - 1) / 2
# elif index > radial_term_index:
# self._polynomial_map[index] =
#
Expand Down
13 changes: 7 additions & 6 deletions dev_utils/field_dependence/read_codev_dat_fits.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ def main():
]

# Zernike fitting order for each instrument
order= {'fgs': 15,
'nircam': 15,
'miri': 15,
'nirspec': 15,
'niriss': 15
}
order = {
'fgs': 15,
'nircam': 15,
'miri': 15,
'nirspec': 15,
'niriss': 15
}

# Define the origin of the CodeV coordinate system in V2/V3 space
v2_origin_degrees = 0
Expand Down
10 changes: 5 additions & 5 deletions dev_utils/wfe_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

inst = webbpsf.NIRCam()
inst.filter = "F430M"
inst.detector_position = (1024,1024)
inst.detector_position = (1024, 1024)

# Baseline test: No SI WFE, no distortion
inst.include_si_wfe = False
%timeit psf = inst.calc_psf(add_distortion=False, monochromatic=4.3e-6) # noqa
%timeit psf = inst.calc_psf(add_distortion=False, monochromatic=4.3e-6) # noqa
# Result: 911 ms ± 5.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit psf = inst.calc_psf(add_distortion=False, nlambda=ncores) # noqa
# Result: 5.62 s ± 177 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Expand All @@ -26,8 +26,8 @@
# Result: 6.1 s ± 96.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# Use pixel (0,0) to force extrapolation algorithm
inst.detector_position = (0,0)
%timeit psf = inst.calc_psf(add_distortion=False, monochromatic=4.3e-6) # noqa
inst.detector_position = (0, 0)
%timeit psf = inst.calc_psf(add_distortion=False, monochromatic=4.3e-6) # noqa
# Result: 1.8 s ± 12.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit psf = inst.calc_psf(add_distortion=False, nlambda=ncores) # noqa
%timeit psf = inst.calc_psf(add_distortion=False, nlambda=ncores) # noqa
# Result: 6.53 s ± 85.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"

intersphinx_mapping.update( # noqa - defined in star import
intersphinx_mapping.update( # noqa - defined in star import
{
"poppy": ("http://poppy-optics.readthedocs.io/", None),
}
Expand Down
11 changes: 7 additions & 4 deletions docs/exts/numfig.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from docutils.nodes import SkipNode, Text, caption, figure, raw, reference
from sphinx.roles import XRefRole

# Element classes

# Element classes
class page_ref(reference):
pass


class num_ref(reference):
pass

Expand All @@ -15,10 +16,12 @@ class num_ref(reference):
def skip_page_ref(self, node):
raise SkipNode


def latex_visit_page_ref(self, node):
self.body.append("\\pageref{%s:%s}" % (node['refdoc'], node['reftarget']))
raise SkipNode


def latex_visit_num_ref(self, node):
fields = node['reftarget'].split('#')
if len(fields) > 1:
Expand Down Expand Up @@ -57,7 +60,6 @@ def doctree_resolved(app, doctree, docname):

i += 1


# replace numfig nodes with links
if app.builder.name != 'latex':
for ref_info in doctree.traverse(num_ref):
Expand All @@ -75,16 +77,17 @@ def doctree_resolved(app, doctree, docname):
target_doc = app.builder.env.figid_docname_map[target]
link = "%s#%s" % (app.builder.get_relative_uri(docname, target_doc),
target)
html = '<a class="pageref" href="%s">%s</a>' % (link, labelfmt %(figids[target]))
html = '<a class="pageref" href="%s">%s</a>' % (link, labelfmt % (figids[target]))
ref_info.replace_self(raw(html, html, format='html'))
else:
ref_info.replace_self(Text(labelfmt % (figids[target])))


def clean_env(app):
app.builder.env.i=1
app.builder.env.i = 1
app.builder.env.figid_docname_map = {}


def setup(app):
app.add_config_value('number_figures', True, True)
app.add_config_value('figure_caption_prefix', "Figure", True)
Expand Down
2 changes: 1 addition & 1 deletion webbpsf/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -400,4 +400,4 @@
# See Gaspar et al. 2021 for illustrative figures.
# This is a rough approximation of a detector-position-dependent phenomenon
MIRI_CRUCIFORM_INNER_RADIUS_PIX = 12
MIRI_CRUCIFORM_RADIAL_SCALEFACTOR = 0.005 # Brightness factor for the diffuse circular halo
MIRI_CRUCIFORM_RADIAL_SCALEFACTOR = 0.005 # Brightness factor for the diffuse circular halo
87 changes: 48 additions & 39 deletions webbpsf/detectors.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import copy

import os

import astropy.convolution
import numpy as np
import scipy
import webbpsf
from webbpsf import utils, constants
from astropy.convolution.kernels import CustomKernel
import scipy.signal as signal
from astropy.convolution import convolve
from astropy.convolution.kernels import CustomKernel
from astropy.io import fits
import astropy.convolution
import scipy.signal as signal

import webbpsf
from webbpsf import constants, utils


def get_detector_ipc_model(inst, header):
Expand Down Expand Up @@ -60,7 +61,8 @@ def get_detector_ipc_model(inst, header):

# PPC effect
# read the SCA extension for the detector
## TODO: This depends on detector coordinates, and which readout amplifier. if in subarray, then the PPC effect is always like in amplifier 1
# TODO: This depends on detector coordinates, and which readout amplifier.
# If in subarray, then the PPC effect is always like in amplifier 1
sca_path_ppc = os.path.join(utils.get_webbpsf_data_path(), 'NIRCam', 'IPC', 'KERNEL_PPC_CUBE.fits')
kernel_ppc = CustomKernel(fits.open(sca_path_ppc)[det2sca[det]].data[0]) # we read the first slice in the cube

Expand Down Expand Up @@ -167,7 +169,8 @@ def apply_detector_ipc(psf_hdulist, extname='DET_DIST'):
"""

# In cases for which the user has asked for the IPC to be applied to a not-present extension, we have nothing to add this to
# In cases for which the user has asked for the IPC
# to be applied to a not-present extension, we have nothing to add this to
if extname not in psf_hdulist:
webbpsf.webbpsf_core._log.debug(f'Skipping IPC simulation since ext {extname} is not found')
return
Expand Down Expand Up @@ -283,9 +286,11 @@ def oversample_ipc_model(kernel, oversample):

# Functions for applying MIRI Detector Scattering Effect

# Lookup tables of shifts of the cruciform, estimated roughly from F560W ePSFs (ePSFs by Libralatto, shift estimate by Perrin)
cruciform_xshifts = scipy.interpolate.interp1d([0, 357, 1031], [1.5,0.5,-0.9], kind='linear', fill_value='extrapolate')
cruciform_yshifts = scipy.interpolate.interp1d([0, 511, 1031], [1.6,0,-1.6], kind='linear', fill_value='extrapolate')
# Lookup tables of shifts of the cruciform
# Estimated roughly from F560W ePSFs (ePSFs by Libralatto, shift estimate by Perrin)
cruciform_xshifts = scipy.interpolate.interp1d([0, 357, 1031], [1.5, 0.5, -0.9], kind='linear', fill_value='extrapolate')
cruciform_yshifts = scipy.interpolate.interp1d([0, 511, 1031], [1.6, 0, -1.6], kind='linear', fill_value='extrapolate')


def _make_miri_scattering_kernel_2d(in_psf, kernel_amp, oversample=1, wavelength=5.5, detector_position=(0, 0)):
"""Improved / more complex model of the MIRI cruciform, with parameterization to model
Expand All @@ -310,13 +315,13 @@ def _make_miri_scattering_kernel_2d(in_psf, kernel_amp, oversample=1, wavelength
"""
# make output array
npix = in_psf.shape[0]
cen = (npix-1) // 2
kernel_2d = np.zeros( (npix, npix), float)
cen = (npix - 1) // 2
kernel_2d = np.zeros((npix, npix), float)

### make 1d kernels for the main cruciform bright lines
# make 1d kernels for the main cruciform bright lines
# Compute 1d indices
x = np.arange(npix, dtype=float)
x -= (npix-1)/2
x -= (npix - 1) / 2
x /= oversample
y = x # we're working in 1d in this part, but clarify let's have separate coords for each axis

Expand All @@ -330,19 +335,22 @@ def _make_miri_scattering_kernel_2d(in_psf, kernel_amp, oversample=1, wavelength

# Add in the offset copies of the main 1d kernels
# Empirically, the 'center' of the cruciform shifts inwards towards the center of the detector
# i.e. for the upper right corner, the cruciform shifts down and left a bit, etc.
# i.e. for the upper right corner, the cruciform shifts down and left a bit, etc.
yshift = cruciform_yshifts(detector_position[1])
xshift = cruciform_xshifts(detector_position[0])
kernel_2d[cen + int(round(yshift*oversample))] = kernel_x
kernel_2d[:, cen + int(round(xshift*oversample))] = kernel_y
kernel_2d[cen + int(round(yshift * oversample))] = kernel_x
kernel_2d[:, cen + int(round(xshift * oversample))] = kernel_y

### create and add in the more diffuse radial term
# create and add in the more diffuse radial term
# Model this as an expoential falloff outside the inner radius, times some scale factor relative to the above
y, x = np.indices(kernel_2d.shape)
r = np.sqrt((x-cen)**2 + (y-cen)**2) / oversample
radial_term = np.exp(-r/2/webbpsf.constants.MIRI_CRUCIFORM_INNER_RADIUS_PIX) * kernel_amp \
* (r > webbpsf.constants.MIRI_CRUCIFORM_INNER_RADIUS_PIX) \
* webbpsf.constants.MIRI_CRUCIFORM_RADIAL_SCALEFACTOR
r = np.sqrt((x - cen) ** 2 + (y - cen) ** 2) / oversample
radial_term = (
np.exp(-r / 2 / webbpsf.constants.MIRI_CRUCIFORM_INNER_RADIUS_PIX)
* kernel_amp
* (r > webbpsf.constants.MIRI_CRUCIFORM_INNER_RADIUS_PIX)
* webbpsf.constants.MIRI_CRUCIFORM_RADIAL_SCALEFACTOR
)

kernel_2d += radial_term

Expand Down Expand Up @@ -373,9 +381,9 @@ def _apply_miri_scattering_kernel_2d(in_psf, kernel_2d, oversample):
"""

# Convolve the input PSF with the kernel for scattering
im_conv = astropy.convolution.convolve_fft(in_psf, kernel_2d, boundary='fill', fill_value=0.0,
normalize_kernel=False, nan_treatment='fill', allow_huge = True)

im_conv = astropy.convolution.convolve_fft(
in_psf, kernel_2d, boundary='fill', fill_value=0.0, normalize_kernel=False, nan_treatment='fill', allow_huge=True
)

# Normalize.
# Note, it appears we do need to correct the amplitude for the sampling factor. Might as well do that here.
Expand Down Expand Up @@ -489,9 +497,13 @@ def apply_miri_scattering(hdulist_or_filename=None, kernel_amp=None, old_method=
in_psf = psf[ext].data

# create cruciform model using improved method using a 2d convolution kernel, attempting to model more physics.
kernel_2d = _make_miri_scattering_kernel_2d(in_psf, kernel_amp, oversample,
detector_position= (hdu_list[0].header['DET_X'], hdu_list[0].header['DET_Y']),
wavelength = hdu_list[0].header['WAVELEN']*1e6 )
kernel_2d = _make_miri_scattering_kernel_2d(
in_psf,
kernel_amp,
oversample,
detector_position=(hdu_list[0].header['DET_X'], hdu_list[0].header['DET_Y']),
wavelength=hdu_list[0].header['WAVELEN'] * 1e6,
)
im_conv_both = _apply_miri_scattering_kernel_2d(in_psf, kernel_2d, oversample)

# Add this 2D scattered light output to the PSF
Expand All @@ -511,25 +523,22 @@ def apply_miri_scattering(hdulist_or_filename=None, kernel_amp=None, old_method=
return psf


def _show_miri_cruciform_kernel(filt, npix=101, oversample=4, detector_position=(512,512), ax=None):
""" utility function for viewing/visualizing the cruciform kernel
"""
def _show_miri_cruciform_kernel(filt, npix=101, oversample=4, detector_position=(512, 512), ax=None):
"""utility function for viewing/visualizing the cruciform kernel"""
import matplotlib

placeholder = np.zeros((npix*oversample, npix*oversample))
placeholder = np.zeros((npix * oversample, npix * oversample))
kernel_amp = get_miri_cruciform_amplitude(filt)
extent =[-npix/2, npix/2, -npix/2, npix/2]
extent = [-npix / 2, npix / 2, -npix / 2, npix / 2]

kernel_2d = _make_miri_scattering_kernel_2d(placeholder, kernel_amp, oversample,
detector_position= detector_position)
kernel_2d = _make_miri_scattering_kernel_2d(placeholder, kernel_amp, oversample, detector_position=detector_position)
norm = matplotlib.colors.LogNorm(1e-6, 1)
cmap = matplotlib.cm.viridis
cmap.set_bad(cmap(0))
if ax is None:
ax = matplotlib.pyplot.gca()
ax.imshow(kernel_2d, norm=norm, cmap=cmap, extent=extent, origin='lower')
ax.set_title(f"MIRI cruciform model for {filt}, position {detector_position}, oversample {oversample}")
ax.plot(0,0,marker='+', color='yellow')
ax.set_title(f'MIRI cruciform model for {filt}, position {detector_position}, oversample {oversample}')
ax.plot(0, 0, marker='+', color='yellow')

matplotlib.pyplot.colorbar(mappable=ax.images[0])

1 change: 0 additions & 1 deletion webbpsf/gridded_library.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,6 @@ def tuple_to_int(t):
if isinstance(t, tuple):
return (int(t[0]), int(t[1]))


def show_grid_helper(grid, data, title='Grid of PSFs', vmax=0, vmin=0, scale='log'):
npsfs = grid.data.shape[0]
n = int(np.sqrt(npsfs))
Expand Down
Loading

0 comments on commit dfd4528

Please sign in to comment.