Skip to content

Commit

Permalink
Merge pull request #9 from jdavies-st/rename-rcselfcalstep
Browse files Browse the repository at this point in the history
Rename RcSelfCalStep to OpenPixelStep
  • Loading branch information
jdavies-st authored Mar 6, 2024
2 parents fdfe214 + 6cf7b30 commit b58f5b3
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 30 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Algorithms for cleaning JWST data.
- `SnowblindStep`: mask cosmic ray showers and snowballs
- `JumpPlusStep`: Propagate JUMP_DET and SATURATED flags in GROUPDQ properly for frame-averaged groups
- `PersistenceFlagStep`: flag pixels effected by persistence exposure-to-exposure
- `RcSelfCalStep`: flag new hot pixels, open pixels or RC pixels
- `OpenPixelStep`: flag new open pixels, hot pixels, or open adjacent pixels


## Installation
Expand Down Expand Up @@ -31,6 +31,7 @@ In Python, we can insert `SnowblindStep` and `JumpPlusStep` after `JumpStep` as
steps = {
"jump": {
"save_results": True,
"flag_large_events": False,
"post_hooks": [
"snowblind.SnowblindStep",
"snowblind.JumpPlusStep",
Expand Down
6 changes: 3 additions & 3 deletions src/snowblind/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from .snowblind import SnowblindStep
from .jump_plus import JumpPlusStep
from .rc_selfcal import RcSelfCalStep
from .selfcal import OpenPixelStep
from .persist import PersistenceFlagStep


Expand All @@ -16,7 +16,7 @@
'__version__',
'SnowblindStep',
'JumpPlusStep',
'RcSelfCalStep',
'OpenPixelStep',
'PersistenceFlagStep',
]

Expand All @@ -27,6 +27,6 @@ def _get_steps():
return [
("snowblind.SnowblindStep", 'snowblind', False),
("snowblind.JumpPlusStep", 'jump_plus', False),
("snowblind.RcSelfCalStep", 'rc_selfcal', False),
("snowblind.OpenPixelStep", 'open_pixel', False),
("snowblind.PersistenceFlagStep", 'persist', False),
]
36 changes: 17 additions & 19 deletions src/snowblind/rc_selfcal.py → src/snowblind/selfcal.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
from os.path import commonprefix
import warnings

from astropy.stats import sigma_clipped_stats
from astropy.io import fits
import numpy as np
from jwst import datamodels
from jwst.stpipe import Step


RC = datamodels.dqflags.pixel["RC"]
OPEN = datamodels.dqflags.pixel["OPEN"]
ADJ_OPEN = datamodels.dqflags.pixel["ADJ_OPEN"]
DO_NOT_USE = datamodels.dqflags.pixel["DO_NOT_USE"]


class RcSelfCalStep(Step):
"""Removes cross-shaped and other defects caused by RC-type bad pixels in NIR detectors
class OpenPixelStep(Step):
"""Flags cross-shaped and hot pixel defects caused by open pixels in NIR detectors
Input is an assocation (or glob pattern of files) of all images in visit or program ID
on which ones wishes to do a self-cal. These are split into separate detector stacks,
Expand All @@ -21,19 +22,19 @@ class RcSelfCalStep(Step):
stage 3 pipelines such as tweakreg, skymatch and outlier detection.
Like outlier_detection, the input and output science images are the same, and only the
data quality (DQ) array has new pixels flagged as DO_NOT_USE and RC.
data quality (DQ) array has new pixels flagged as DO_NOT_USE and ADJ_OPEN.
This should be run after flatfielding is finished in image2 pipeline. It is fine to
insert it anywhere in the level3 pipeline before resample.
"""
spec = """
threshold = float(default=3.0) # threshold in sigma to flag hot pixels above median
save_mask = boolean(default=False) # write out per-detector bad-pixel masks
threshold = float(default=3.0) # threshold in sigma to flag hot pixels above local background
save_mask = boolean(default=False) # write out per-detector bad-pixel mask and median
output_use_model = boolean(default=True)
output_use_index = boolean(default=False)
"""

class_alias = "rc_selfcal"
class_alias = "open_pixel"

def process(self, input_data):
with datamodels.open(input_data) as images:
Expand All @@ -55,20 +56,17 @@ def process(self, input_data):
mask, median = self.create_hotpixel_mask(image_stack)
self.log.info(f"Flagged {mask.sum()} pixels with {self.threshold} sigma")
if self.save_mask:
fits.HDUList(
fits.PrimaryHDU(
data=mask.astype(np.uint8)
)
).writeto(f"{detector.lower()}_rcflag_mask.fits", overwrite=True)
fits.HDUList(
fits.PrimaryHDU(
data=median
)
).writeto(f"{detector.lower()}_rcflag_median.fits", overwrite=True)
filename_prefix = f"{commonprefix([f.meta.filename for f in models])}_{detector.lower()}_{self.class_alias}"
mask_model = datamodels.MaskModel(data=mask.astype(np.uint8))
mask_model.meta.filename = f"{filename_prefix}.fits"
self.save_model(mask_model, suffix="mask", force=True)
median_model = datamodels.ImageModel(data=median)
median_model.meta.filename = f"{filename_prefix}.fits"
self.save_model(median_model, suffix="median", force=True)

for result in results:
if result.meta.instrument.detector == detector:
result.dq |= (mask * (DO_NOT_USE | RC)).astype(np.uint32)
result.dq |= (mask * (DO_NOT_USE | ADJ_OPEN)).astype(np.uint32)

return results

Expand Down
14 changes: 7 additions & 7 deletions tests/test_rc_selfcal.py → tests/test_selfcal.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import numpy as np
from jwst import datamodels

from snowblind import RcSelfCalStep
from snowblind import OpenPixelStep


RC = datamodels.dqflags.pixel["RC"]
ADJ_OPEN = datamodels.dqflags.pixel["ADJ_OPEN"]
DO_NOT_USE = datamodels.dqflags.pixel["DO_NOT_USE"]
GOOD = datamodels.dqflags.pixel["GOOD"]


def test_init():
step = RcSelfCalStep(threshold=4.5)
step = OpenPixelStep(threshold=4.5)

assert step.threshold == 4.5

Expand Down Expand Up @@ -41,11 +41,11 @@ def test_call():
image.data[8, 8] += 3 * stddev

# Run the step and see if they're recovered
results = RcSelfCalStep.call(images, threshold=3.0)
results = OpenPixelStep.call(images, threshold=3.0)

for result in results:
assert result.dq[2, 2] == RC | DO_NOT_USE
assert result.dq[3, 5] == RC | DO_NOT_USE
assert result.dq[8, 8] == RC | DO_NOT_USE
assert result.dq[2, 2] == ADJ_OPEN | DO_NOT_USE
assert result.dq[3, 5] == ADJ_OPEN | DO_NOT_USE
assert result.dq[8, 8] == ADJ_OPEN | DO_NOT_USE

assert result.dq[5, 5] == GOOD

0 comments on commit b58f5b3

Please sign in to comment.