Skip to content
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

DM-28093: Change isrTask (and relevant configs) to use physicalLabel #174

Merged
merged 4 commits into from
Mar 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 2 additions & 7 deletions python/lsst/ip/isr/fringe.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

from lsst.pipe.base import Task, Struct, timeMethod
from lsst.pex.config import Config, Field, ListField, ConfigField
from .isrFunctions import checkFilter

afwDisplay.setDefaultMaskTransparency(75)

Expand Down Expand Up @@ -253,13 +254,7 @@ def checkFilter(self, exposure):
If True, then the exposure has a filter listed in the
configuration, and should have the fringe applied.
"""
filterObj = afwImage.Filter(exposure.getFilter().getId())
# TODO: remove this check along with the config option in DM-27177
if self.config.useFilterAliases:
filterNameSet = set(filterObj.getAliases() + [filterObj.getName()])
else:
filterNameSet = set([filterObj.getName(), ])
return bool(len(filterNameSet.intersection(self.config.filters)))
return checkFilter(exposure, self.config.filters, log=self.log)

def removePedestal(self, fringe):
"""Remove pedestal from fringe exposure.
Expand Down
36 changes: 36 additions & 0 deletions python/lsst/ip/isr/isrFunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -865,3 +865,39 @@ def setBadRegions(exposure, badStatistic="MEDIAN"):
imageArray[:] = numpy.where(badPixels, value, imageArray)

return badPixels.sum(), value


def checkFilter(exposure, filterList, log):
"""Check to see if an exposure is in a filter specified by a list.

The goal of this is to provide a unified filter checking interface
for all filter dependent stages.

Parameters
----------
exposure : `lsst.afw.image.Exposure`
Exposure to examine.
filterList : `list` [`str`]
List of physical_filter names to check.
log : `lsst.log.Log`
Logger to handle messages.
czwa marked this conversation as resolved.
Show resolved Hide resolved

Returns
-------
result : `bool`
True if the exposure's filter is contained in the list.
"""
thisFilter = exposure.getFilterLabel()
if thisFilter is None:
log.warn("No FilterLabel attached to this exposure!")
return False

if thisFilter.physicalLabel in filterList:
return True
elif thisFilter.bandLabel in filterList:
if log:
log.warn("Physical filter (%s) should be used instead of band %s for filter configurations (%s)",
thisFilter.physicalLabel, thisFilter.bandLabel, filterList)
return True
else:
return False
23 changes: 10 additions & 13 deletions python/lsst/ip/isr/isrTask.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,8 +1076,7 @@ def readIsrData(self, dataRef, rawExposure):
dateObs = None

ccd = rawExposure.getDetector()
# TODO DM-28093: change this to: rawExposure.getFilterLabel().physicalLabel
filterName = afwImage.Filter(rawExposure.getFilter().getId()).getName() # Canonical name for filter
filterLabel = rawExposure.getFilterLabel()
rawExposure.mask.addMaskPlane("UNMASKEDNAN") # needed to match pre DM-15862 processing.
biasExposure = (self.getIsrExposure(dataRef, self.config.biasDataProductName)
if self.config.doBias else None)
Expand Down Expand Up @@ -1166,7 +1165,7 @@ def readIsrData(self, dataRef, rawExposure):
illumMaskedImage = (self.getIsrExposure(dataRef,
self.config.illuminationCorrectionDataProductName).getMaskedImage()
if (self.config.doIlluminationCorrection
and filterName in self.config.illumFilters)
and filterLabel in self.config.illumFilters)
else None)

# Struct should include only kwargs to run()
Expand Down Expand Up @@ -1332,8 +1331,7 @@ def run(self, ccdExposure, camera=None, bias=None, linearizer=None,
return self.runDataRef(ccdExposure)

ccd = ccdExposure.getDetector()
# TODO DM-28093: change this to: ccdExposure.getFilterLabel().physicalLabel
filterName = afwImage.Filter(ccdExposure.getFilter().getId()).getName() # Canonical name for filter
filterLabel = ccdExposure.getFilterLabel()

if not ccd:
assert not self.config.doAssembleCcd, "You need a Detector to run assembleCcd."
Expand All @@ -1352,14 +1350,14 @@ def run(self, ccdExposure, camera=None, bias=None, linearizer=None,
raise RuntimeError("Must supply a flat exposure if config.doFlat=True.")
if self.config.doDefect and defects is None:
raise RuntimeError("Must supply defects if config.doDefect=True.")
if (self.config.doFringe and filterName in self.fringe.config.filters
if (self.config.doFringe and filterLabel in self.fringe.config.filters
and fringes.fringes is None):
# The `fringes` object needs to be a pipeBase.Struct, as
# we use it as a `dict` for the parameters of
# `FringeTask.run()`. The `fringes.fringes` `list` may
# not be `None` if `doFringe=True`. Otherwise, raise.
raise RuntimeError("Must supply fringe exposure as a pipeBase.Struct.")
if (self.config.doIlluminationCorrection and filterName in self.config.illumFilters
if (self.config.doIlluminationCorrection and filterLabel in self.config.illumFilters
and illumMaskedImage is None):
raise RuntimeError("Must supply an illumcor if config.doIlluminationCorrection=True.")

Expand Down Expand Up @@ -1606,7 +1604,7 @@ def run(self, ccdExposure, camera=None, bias=None, linearizer=None,
if self.config.qa.doThumbnailFlattened:
flattenedThumb = isrQa.makeThumbnail(ccdExposure, isrQaConfig=self.config.qa)

if self.config.doIlluminationCorrection and filterName in self.config.illumFilters:
if self.config.doIlluminationCorrection and filterLabel in self.config.illumFilters:
self.log.info("Performing illumination correction.")
isrFunctions.illuminationCorrection(ccdExposure.getMaskedImage(),
illumMaskedImage, illumScale=self.config.illumScale,
Expand Down Expand Up @@ -2479,12 +2477,11 @@ def roughZeroPoint(self, exposure):
exposure : `lsst.afw.image.Exposure`
Exposure to process.
"""
# TODO DM-28093: change this to: exposure.getFilterLabel().physicalLabel
filterName = afwImage.Filter(exposure.getFilter().getId()).getName() # Canonical name for filter
if filterName in self.config.fluxMag0T1:
fluxMag0 = self.config.fluxMag0T1[filterName]
filterLabel = exposure.getFilterLabel()
if filterLabel in self.config.fluxMag0T1:
fluxMag0 = self.config.fluxMag0T1[filterLabel]
else:
self.log.warn("No rough magnitude zero point set for filter %s.", filterName)
self.log.warn("No rough magnitude zero point set for filter %s.", filterLabel)
fluxMag0 = self.config.defaultFluxMag0T1

expTime = exposure.getInfo().getVisitInfo().getExposureTime()
Expand Down
3 changes: 2 additions & 1 deletion python/lsst/ip/isr/straylight.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from lsst.pex.config import Config, Field, ListField
from lsst.pipe.base import Task
from lsst.geom import Angle
from .isrFunctions import checkFilter


class StrayLightConfig(Config):
Expand Down Expand Up @@ -114,7 +115,7 @@ def checkFilter(self, exposure):
If True, then the exposure has a filter listed in the
configuration, and should have the fringe applied.
"""
return exposure.getFilter().getName() in self.config.filters
return checkFilter(exposure, self.config.filters, log=self.log)


class StrayLightData(ABC):
Expand Down
13 changes: 4 additions & 9 deletions tests/test_fringes.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import lsst.utils.tests
import lsst.afw.math as afwMath
import lsst.afw.image as afwImage
import lsst.afw.image.utils as afwImageUtils
import lsst.pipe.base as pipeBase
from lsst.ip.isr.fringe import FringeTask

Expand Down Expand Up @@ -78,7 +77,7 @@ def createFringe(width, height, xFreq, xOffset, yFreq, yOffset):
array[x, y] = np.sin(xFreq*x + xOffset) + np.sin(yFreq*y + yOffset)
mi = afwImage.makeMaskedImage(image)
exp = afwImage.makeExposure(mi)
exp.setFilter(afwImage.Filter('FILTER'))
exp.setFilterLabel(afwImage.FilterLabel(band='y', physical='FILTER'))
return exp


Expand All @@ -88,16 +87,12 @@ class FringeTestCase(lsst.utils.tests.TestCase):
def setUp(self):
self.size = 512
self.config = FringeTask.ConfigClass()
self.config.filters = ['FILTER']
self.config.filters = ['FILTER', 'y']
self.config.num = 5000
self.config.small = 1
self.config.large = 128
self.config.pedestal = False
self.config.iterations = 10
afwImageUtils.defineFilter('FILTER', lambdaEff=0)

def tearDown(self):
afwImageUtils.resetFilters()

def checkFringe(self, task, exp, fringes, stddevMax):
"""Run fringe subtraction and verify.
Expand Down Expand Up @@ -221,7 +216,7 @@ def testMultiple(self, pedestal=0.0):
image.scaledPlus(s, f.getMaskedImage().getImage())
mi = afwImage.makeMaskedImage(image)
exp = afwImage.makeExposure(mi)
exp.setFilter(afwImage.Filter('FILTER'))
exp.setFilterLabel(afwImage.FilterLabel(physical='FILTER'))

task = FringeTask(name="multiFringe", config=self.config)
self.checkFringe(task, exp, fringeList, stddevMax=1.0e-2)
Expand Down Expand Up @@ -268,7 +263,6 @@ def test_readFringes(self):
def test_multiFringes(self):
"""Test that multi-fringe results are handled correctly by the task.
"""
self.config.filters.append("_unknown_")
self.config.large = 16
task = FringeTask(name="multiFringeMock", config=self.config)

Expand All @@ -279,6 +273,7 @@ def test_multiFringes(self):
dataRef = isrMock.FringeDataRefMock(config=config)

exp = dataRef.get("raw")
exp.setFilterLabel(afwImage.FilterLabel(physical='FILTER'))
medianBefore = np.nanmedian(exp.getImage().getArray())
fringes = task.readFringes(dataRef, assembler=None)

Expand Down