8000 JP-3622 Update refpix step for NIR detectors to use convolution kernel by penaguerrero · Pull Request #8726 · spacetelescope/jwst · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

JP-3622 Update refpix step for NIR detectors to use convolution kernel #8726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 82 commits into from
Dec 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
e646d20
initial code
penaguerrero Aug 26, 2024
8868e05
Merge branch 'master' into jp3622
penaguerrero Aug 27, 2024
503b8cb
Merge branch 'master' into jp3622
penaguerrero Aug 28, 2024
ee89fd2
minor change
penaguerrero Aug 28, 2024
f42375b
testing
penaguerrero Aug 28, 2024
afd5ccd
continuing with implementation
penaguerrero Aug 29, 2024
0499d27
add message when processing zero frame
penaguerrero Aug 30, 2024
29da573
Merge branch 'master' into jp3622
penaguerrero Aug 30, 2024
8875b13
adding the PR number
penaguerrero Aug 30, 2024
dfe6a59
Merge branch 'master' into jp3622
penaguerrero Sep 4, 2024
cbbecb0
Merge branch 'master' into jp3622
penaguerrero Sep 5, 2024
c83c338
adding unit tests
penaguerrero Sep 5, 2024
be3c9e3
adding missing argument
penaguerrero Sep 5, 2024
f81c798
Merge branch 'master' into jp3622
penaguerrero Sep 5, 2024
5d6798a
adding documentation
penaguerrero Sep 6, 2024
98ce09b
Merge branch 'master' into jp3622
penaguerrero Sep 9, 2024
d031c43
Merge branch 'master' into jp3622
penaguerrero Sep 11, 2024
2aa98c0
Merge branch 'master' into jp3622
penaguerrero Sep 11, 2024
89374dc
smoothing integration of code
penaguerrero Sep 11, 2024
06b21ec
Merge branch 'master' into jp3622
penaguerrero Sep 11, 2024
3c00577
fixing test to match changes
penaguerrero Sep 11, 2024
52a3dad
Merge branch 'master' into jp3622
penaguerrero Sep 12, 2024
d629b37
Merge branch 'master' into jp3622
penaguerrero Sep 13, 2024
7533039
Merge branch 'master' into jp3622
penaguerrero Sep 16, 2024
0c39e5b
Merge branch 'master' into jp3622
penaguerrero Sep 17, 2024
1b0310c
Merge branch 'master' into jp3622
penaguerrero Sep 18, 2024
4339dff
Merge branch 'master' into jp3622
penaguerrero Sep 19, 2024
c1dbe1c
Merge branch 'master' into jp3622
penaguerrero Sep 20, 2024
09eb003
Merge branch 'master' into jp3622
penaguerrero Sep 20, 2024
103da88
Merge branch 'master' into jp3622
penaguerrero Sep 23, 2024
f426fbb
Merge branch 'main' into jp3622
penaguerrero Sep 23, 2024
a4eb93f
adding PR changes
penaguerrero Sep 23, 2024
d3c67fc
Merge branch 'main' into jp3622
penaguerrero Sep 24, 2024
53cc1d5
Merge branch 'main' into jp3622
penaguerrero Sep 24, 2024
67072b7
Merge branch 'main' into jp3622
penaguerrero Sep 25, 2024
46c219b
Merge branch 'main' into jp3622
penaguerrero Sep 30, 2024
76eb300
Merge branch 'main' into jp3622
penaguerrero Oct 1, 2024
64ca640
Merge branch 'main' into jp3622
penaguerrero Oct 1, 2024
f16cc7a
Merge branch 'main' into jp3622
penaguerrero Oct 2, 2024
846004c
Merge branch 'main' into jp3622
penaguerrero Oct 7, 2024
0e49387
Merge branch 'main' into jp3622
penaguerrero Oct 10, 2024
1d76a49
Merge branch 'main' into jp3622
penaguerrero Oct 14, 2024
f0a511a
Merge branch 'main' into jp3622
penaguerrero Oct 22, 2024
1c4d97b
setting default for use_conv_kernel to False
penaguerrero Oct 22, 2024
9e8f04a
Merge branch 'main' into jp3622
penaguerrero Oct 22, 2024
c9f959f
Merge branch 'main' into jp3622
penaguerrero Nov 19, 2024
19cb9b5
Merge branch 'main' into jp3622
penaguerrero Nov 19, 2024
1af8832
Bugfix to optimized convolution
drlaw1558 Nov 19, 2024
e6e6ef2
Merge pull request #3 from drlaw1558/jp3622drl
penaguerrero Nov 20, 2024
d1fae72
bug fixes and improved description
penaguerrero Nov 20, 2024
b0830b9
removed manual change
penaguerrero Nov 20, 2024
0897322
Merge branch 'main' into jp3622
penaguerrero Nov 20, 2024
788a6d8
Merge branch 'main' into jp3622
penaguerrero Nov 21, 2024
6329bd9
Merge branch 'main' into jp3622
penaguerrero Nov 21, 2024
5410012
Merge branch 'main' into jp3622
penaguerrero Nov 26, 2024
1db5135
Merge branch 'main' into jp3622
penaguerrero Nov 26, 2024
282024b
added regtest
penaguerrero Nov 26, 2024
45ec59e
matching datamodel changes
penaguerrero Nov 26, 2024
969d4e1
Merge branch 'main' into jp3622
penaguerrero Dec 4, 2024
e26f929
Merge branch 'main' into jp3622
penaguerrero Dec 4, 2024
b936c82
changing conv_kernel references to sirs_kernel and other fixes
penaguerrero Dec 4, 2024
6f82896
Update jwst/refpix/refpix_step.py
penaguerrero Dec 5, 2024
cdcca93
changing running_median for median for refpix_algorithm
penaguerrero Dec 5, 2024
4c783cf
fixing documentation
penaguerrero Dec 5, 2024
fa341af
Merge branch 'main' into jp3622
penaguerrero Dec 9, 2024
8e222e6
Merge branch 'main' into jp3622
penaguerrero Dec 9, 2024
21a58c2
Merge branch 'main' into jp3622
penaguerrero Dec 11, 2024
444a698
Merge branch 'main' into jp3622
penaguerrero Dec 12, 2024
4f89601
Merge branch 'main' into jp3622
penaguerrero Dec 13, 2024
6519488
setting changes file back to main
penaguerrero Dec 13, 2024
6d11777
Update docs/jwst/refpix/arguments.rst
penaguerrero Dec 13, 2024
b25fe16
Delete changes/8726.refpix.rst
penaguerrero Dec 13, 2024
03d3e79
updating parameter name for algorithm used
penaguerrero Dec 13, 2024
0146567
Update jwst/refpix/optimized_convolution.py
penaguerrero Dec 13, 2024
1f2a46c
Update jwst/refpix/optimized_convolution.py
penaguerrero Dec 13, 2024
8924120
fixing tests and adding description of changes
penaguerrero Dec 13, 2024
ac4a3d8
adding more info to change description
penaguerrero Dec 13, 2024
d6a14dc
fixing tests
penaguerrero Dec 13, 2024
789aa88
Merge branch 'main' into jp3622
penaguerrero Dec 13, 2024
607ba81
Merge branch 'main' into jp3622
melanieclarke Dec 13, 2024
0543480
Merge branch 'main' into jp3622
melanieclarke Dec 13, 2024
8146963
Merge branch 'main' into jp3622
tapastro Dec 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/8726.refpix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Implemented SIRS algorithm instead of running median for side pixels of NIR full-frame data. Running median is still default.
22 changes: 22 additions & 0 deletions docs/jwst/refpix/arguments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,25 @@ in IRS2 mode will be processed along with the normal pixels and preserved
in the output. This option is intended for calibration or diagnostic reductions
only. For normal science operation, this argument should always be False,
so that interleaved pixels are stripped before continuing processing.

* ``--refpix_algorithm``

The ``refpix_algorithm`` argument is only relevant for all NIR full-frame
data, and can be set to 'median' (default) to use the running median or
'sirs' to use the Simple Improved Reference Subtraction (SIRS).

* ``--sigreject``

The ``sigreject`` argument is the number of sigmas to reject as outliers in the
SIRS algorithm. The value is expected to be a float.

* ``--gaussmooth``

The ``gaussmooth`` argument is the width of Gaussian smoothing kernel to use as
a low-pass filter. The numerical value is expected to be a float.

* ``--halfwidth``

The ``halfwidth`` argument is the half-width of convolution kernel to build. The
numerical value is expected to be an integer.

12 changes: 12 additions & 0 deletions docs/jwst/refpix/description.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ NIR Detector Data
(set by the step parameter ``side_gain``, which defaults to 1.0) is
subtracted from the full group on a row-by-row basis. Note that the ``odd_even_rows``
parameter is ignored for NIR data when the side reference pixels are processed.
If the ``--refpix_algorithm`` option is set to 'sirs', the Simple Improved
Reference Subtraction (SIRS) method will be used instead of the running median.
The SIRS revision uses the left and right side reference pixels as described
in https://doi.org/10.1117/1.JATIS.8.2.028002. This implementation uses a
mathematically equivalent formulation using convolution kernels rather than
Fourier transforms, with the convolution kernel truncated where the weights
approach zero. There are two convolution kernels for each readout channel,
one for each of the left and right reference pixels. These kernels are the
Fourier transforms of the weight coefficients (further description in the paper).
The approach implemented here makes nearly optimal use of the reference pixels.
It reduces read noise by 5-10% relative to a running median filter of the
reference pixels, and reduces 1/f "striping" noise by a larger factor than this.
#. Transform the data back to the JWST focal plane, or DMS, frame.

MIR Detector Data
Expand Down
180 changes: 180 additions & 0 deletions jwst/refpix/optimized_convolution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#
# Module for using the Simple Improved Reference Subtraction (SIRS) algorithm
# to improve the 1/f noise, only for full frame non-IRS2 NIR data
#

import logging
import numpy as np

log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)


def make_kernels(sirs_kernel_model, detector, gaussmooth, halfwidth):
"""
Make convolution kernels from Fourier coefficients in the reference file.

Parameters:
-----------

sirs_kernel_model : `~jwst.datamodels.SIRSKernelModel`
Data model containing the Fourier coefficients from the reference files for
Simple Improved Reference Subtraction (SIRS)

detector : str
Name of the detector of the input data

gaussmooth : 5D32 float
Width of Gaussian smoothing kernel to use as a low-pass filter on reference file's coefficients

halfwidth : int
Half-width of convolution kernel to build from reference file's coefficients

Returns:
--------
kernels: list
List of kernels appropriate for convolution with the left and right reference pixels.

"""

gamma, zeta = get_conv_kernel_coeffs(sirs_kernel_model, detector)
if gamma is None or zeta is None:
log.info(f'Optimized convolution kernel coefficients NOT found for detector {detector}')
return None

kernels_left = []
kernels_right = []
for chan in range(gamma.shape[0]):
n = len(gamma[chan]) - 1
kernel_left = np.fft.fftshift(np.fft.irfft(gamma[chan]))[n - halfwidth:n + halfwidth + 1]
kernel_right = np.fft.fftshift(np.fft.irfft(zeta[chan]))[n - halfwidth:n + halfwidth + 1]

x = np.arange(-halfwidth, halfwidth + 1)
window = np.exp(-x ** 2 / (2 * gaussmooth ** 2))
window /= np.sum(window)

kernel_right = np.convolve(kernel_right, window, mode='same')
kernel_left = np.convolve(kernel_left, window, mode='same')

kernels_right += [kernel_right]
kernels_left += [kernel_left]

return [kernels_left, kernels_right]


def get_conv_kernel_coeffs(sirs_kernel_model, detector):
"""
Get the convolution kernels coefficients from the reference file

Parameters:
-----------

sirs_kernel_model : `~jwst.datamodels.SIRSKernelModel`
Data model containing the Fourier coefficients from the reference files for
Simple Improved Reference Subtraction (SIRS)

detector : str
Name of the detector of the input data

Returns:
--------

gamma: numpy array
Fourier coefficients

zeta: numpy array
Fourier coefficients
"""
mdl_dict = sirs_kernel_model.to_flat_dict()
gamma, zeta = None, None
for item in mdl_dict:
det = item.split(sep='.')[0]
if detector.lower() == det.lower():
arr_name = item.split(sep='.')[1]
if arr_name == 'gamma':
gamma = np.array(mdl_dict[item])
elif arr_name == 'zeta':
zeta = np.array(mdl_dict[item])
if gamma is not None and zeta is not None:
break
return gamma, zeta


def apply_conv_kernel(data, kernels, sigreject=4.0):
"""
Apply the convolution kernel.

Parameters:
-----------

data : 2-D numpy array
Data to be corrected

kernels : list
List containing the left and right kernels

sigreject: float
Number of sigmas to reject as outliers

Returns:
--------

data : 2-D numpy array
Data model with convolution
"""
data = data.astype(float)
npix = data.shape[-1]

kernels_l, kernels_r = kernels
nchan = len(kernels_l)

L = data[:, :4]
R = data[:, -4:]

# Find the approximate standard deviations of the reference pixels
# using an outlier-robust median approach. Mask pixels that differ
# by more than sigreject sigma from this level.
# NOTE: The Median Absolute Deviation (MAD) is calculated as the
# median of the absolute differences between data values and their
# median. For normal distribution MAD is equal to 1.48 times the
# standard deviation but is a more robust estimate of the dispersion
# of data values.The calculation of MAD is straightforward but
# time-consuming, especially if MAD estimates are needed for the
# local environment around every pixel of a large image. The
# calculation is MAD = np.median(np.abs(x-np.median(x))).
# Reference: https://www.interstellarmedium.org/numerical_tools/mad/
MAD = 1.48
medL = np.median(L)
sigL = MAD * np.median(np.abs(L - medL))
medR = np.median(R)
sigR = MAD * np.median(np.abs(R - medR))

# nL and nR are the number of good reference pixels in the left and right
# channel in each row. These will be used in lieu of replacing the values
# of those pixels directly.
goodL = 1 * (np.abs(L - medL) <= sigreject * sigL)
nL = np.sum(goodL, axis=1)
goodR = 1 * (np.abs(R - medR) <= sigreject * sigR)
nR = np.sum(goodR, axis=1)

# Average of the left and right channels, replacing masked pixels with zeros.
# Appropriate normalization factors will be computed later.
L = np.sum(L * goodL, axis=1) / 4
R = np.sum(R * goodR, axis=1) / 4
for chan in range(nchan):
kernel_l = kernels_l[chan]
kernel_r = kernels_r[chan]

# Compute normalizations so that we don't have to directly
# replace the values of flagged/masked reference pixels.
normL = np.convolve(np.ones(nL.shape), kernel_l, mode='same')
normL /= np.convolve(nL / 4, kernel_l, mode='same')
normR = np.convolve(np.ones(nR.shape), kernel_r, mode='same')
normR /= np.convolve(nR / 4, kernel_r, mode='same')
template = np.convolve(L, kernel_l, mode='same') * normL
template += np.convolve(R, kernel_r, mode='same') * normR
data[:, chan * npix * 3 // 4:(chan + 1) * npix * 3 // 4] -= template[:, np.newaxis]

log.debug('Optimized convolution kernel applied')
return data

Loading
Loading
0