Skip to content

Commit

Permalink
Merge pull request #451 from lsst/tickets/DM-38882
Browse files Browse the repository at this point in the history
DM-38882: Update LSSTCam and TS8 physical filter names
  • Loading branch information
jchiang87 committed May 19, 2023
2 parents 76b7d47 + e4c1369 commit f55ae41
Show file tree
Hide file tree
Showing 7 changed files with 340 additions and 43 deletions.
3 changes: 3 additions & 0 deletions python/lsst/obs/lsst/_instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from .filters import (LSSTCAM_FILTER_DEFINITIONS, LATISS_FILTER_DEFINITIONS,
LSSTCAM_IMSIM_FILTER_DEFINITIONS, TS3_FILTER_DEFINITIONS,
TS8_FILTER_DEFINITIONS, COMCAM_FILTER_DEFINITIONS,
GENERIC_FILTER_DEFINITIONS,
)

from .translators import LatissTranslator, LsstCamTranslator, \
Expand Down Expand Up @@ -233,6 +234,7 @@ class LsstCamPhoSim(LsstCam):
instrument = "LSSTCam-PhoSim"
policyName = "phosim"
translatorClass = LsstCamPhoSimTranslator
filterDefinitions = GENERIC_FILTER_DEFINITIONS
visitSystem = VisitSystem.ONE_TO_ONE

def getRawFormatter(self, dataId):
Expand Down Expand Up @@ -298,6 +300,7 @@ class LsstUCDCam(LsstCam):
instrument = "LSST-UCDCam"
policyName = "ucd"
translatorClass = LsstUCDCamTranslator
filterDefinitions = GENERIC_FILTER_DEFINITIONS
visitSystem = VisitSystem.ONE_TO_ONE

def getRawFormatter(self, dataId):
Expand Down
76 changes: 68 additions & 8 deletions python/lsst/obs/lsst/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,11 @@ def addFilter(filter_dict, band, physical_filter):
)


# The LSST Filters from L. Jones 05/14/2020
#
# N.b. DM-26623 requests that these physical names be updated once
# the camera team has decided upon the final values (CAP-617)
EmptyFilter = FilterDefinition(physical_filter="empty", band="white",
alias={"no_filter", "open"})

LsstCamFiltersBaseline = FilterDefinitionCollection(
FilterDefinition(physical_filter="empty", band="white",
alias={"no_filter", "open"}),
# Generic filters used by PhoSim and UCDCam
LsstCamFiltersGeneric = FilterDefinitionCollection(
FilterDefinition(physical_filter="u", band="u"),
FilterDefinition(physical_filter="g", band="g"),
FilterDefinition(physical_filter="r", band="r"),
Expand All @@ -61,6 +58,18 @@ def addFilter(filter_dict, band, physical_filter):
FilterDefinition(physical_filter="y", band="y"),
)

# The LSST Filters from Tony Johnson, 05/09/2023, in DM-38882.
LsstCamFiltersBaseline = FilterDefinitionCollection(
FilterDefinition(physical_filter="ph_5", band="white"), # pinhole filter
FilterDefinition(physical_filter="ef_43", band="white"), # "empty" filter
FilterDefinition(physical_filter="u_24", band="u"),
FilterDefinition(physical_filter="g_6", band="g"),
FilterDefinition(physical_filter="r_57", band="r"),
FilterDefinition(physical_filter="i_39", band="i"),
FilterDefinition(physical_filter="z_20", band="z"),
FilterDefinition(physical_filter="y_10", band="y"),
)

#
# Define the filters present in the BOT.
# According to Tony Johnson the possible physical filters are
Expand Down Expand Up @@ -131,6 +140,46 @@ def addFilter(filter_dict, band, physical_filter):
for physical_filter, filter_defn in physical_filters.items():
BOTFilters.append(FilterDefinition(**filter_defn))

#
# These are the filters used by the CCOB for both TS8 and LSSTCam.
# For the testing of LSSTCam at SLAC, they will be combined with the
# real LSSTCam filters, so we include those combinations in the CCOB
# filter definitions.
#
CCOB_filter_map = {
"": "white",
"HIGH": "white",
"LOW": "white",
"uv": "u",
"blue": "g",
"red": "r",
"nm750": "i",
"nm850": "z",
"nm960": "y",
}

CCOBFilters = []
for lsst_filter_def in (EmptyFilter, *LsstCamFiltersBaseline):
lsstcam_filter = lsst_filter_def.physical_filter
lsstcam_band = lsst_filter_def.band
for ccob_filter, ccob_band in CCOB_filter_map.items():
if lsstcam_band != "white" and ccob_band != "white" and band != ccob_band:
# Skip disallowed filter combinations based on band values.
continue
if ccob_filter == "":
# This would correspond to an entry already in
# LSSTCamFilterBaseline
continue
filters = lsstcam_filter, ccob_filter
physical_filter = FILTER_DELIMITER.join(filters).strip(FILTER_DELIMITER)
if lsstcam_band == "white":
band = ccob_band
else:
band = lsstcam_band
if physical_filter == "":
physical_filter = "empty"
CCOBFilters.append(FilterDefinition(band=band, physical_filter=physical_filter))

#
# The filters that we might see in the real LSSTCam (including in SLAC)
#
Expand All @@ -139,8 +188,15 @@ def addFilter(filter_dict, band, physical_filter):
# for all the BOT composite filters (i.e. "u~ND_OD1.0")
#
LSSTCAM_FILTER_DEFINITIONS = FilterDefinitionCollection(
EmptyFilter,
*LsstCamFiltersBaseline,
*BOTFilters,
*CCOBFilters,
)

GENERIC_FILTER_DEFINITIONS = FilterDefinitionCollection(
EmptyFilter,
*LsstCamFiltersGeneric,
)

#
Expand All @@ -152,7 +208,8 @@ def addFilter(filter_dict, band, physical_filter):
FilterDefinition(physical_filter="550CutOn")]

TS3_FILTER_DEFINITIONS = FilterDefinitionCollection(
*LsstCamFiltersBaseline,
EmptyFilter,
*LsstCamFiltersGeneric,
*TS3Filters,
)
#
Expand All @@ -164,8 +221,11 @@ def addFilter(filter_dict, band, physical_filter):
FilterDefinition(physical_filter="550CutOn")]

TS8_FILTER_DEFINITIONS = FilterDefinitionCollection(
EmptyFilter,
*LsstCamFiltersGeneric,
*LsstCamFiltersBaseline,
*TS8Filters,
*CCOBFilters,
)


Expand Down
8 changes: 8 additions & 0 deletions python/lsst/obs/lsst/translators/lsst.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,6 +662,14 @@ def to_physical_filter(self):
if not joined:
joined = "unknown"

# Remove blank and "empty" fields.
joined = FILTER_DELIMITER.join(_ for _ in joined.split(FILTER_DELIMITER)
if _ and _ != "empty")

# Return "empty" if joined is blank at this point.
if not joined:
joined = "empty"

return joined

@cache_translation
Expand Down
28 changes: 1 addition & 27 deletions python/lsst/obs/lsst/translators/lsstCam.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
import logging
import astropy.units as u

from astro_metadata_translator import cache_translation
from astro_metadata_translator.translators.helpers import is_non_science

from .lsst import LsstBaseTranslator, SIMONYI_TELESCOPE, FILTER_DELIMITER
from .lsst import LsstBaseTranslator, SIMONYI_TELESCOPE

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -138,28 +137,3 @@ def can_translate(cls, header, filename=None):
if instrume == cls.supported_instrument.lower():
return True
return False

@cache_translation
def to_physical_filter(self):
"""Calculate the physical filter name.
Returns
-------
filter : `str`
Name of filter. Can be a combination of FILTER and FILTER2
headers joined by a "~" if FILTER2 is set and not empty.
Returns "UNKNOWN" if no filter is declared.
"""
physical_filter = self._determine_primary_filter()

filter2 = None
if self.is_key_ok("FILTER2"):
self._used_these_cards("FILTER2")
filter2 = self._header["FILTER2"]
if self._is_filter_empty(filter2):
filter2 = None

if filter2:
physical_filter = f"{physical_filter}{FILTER_DELIMITER}{filter2}"

return physical_filter
19 changes: 12 additions & 7 deletions python/lsst/obs/lsst/translators/ts8.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ def to_detector_serial(self):
def to_physical_filter(self):
"""Return the filter name.
Uses the FILTPOS header.
Uses the FILTPOS header for older TS8 data. Newer data can use
the base class implementation.
Returns
-------
Expand All @@ -197,19 +198,23 @@ def to_physical_filter(self):
Notes
-----
The calculations here are examples rather than being accurate.
They need to be fixed once the camera acquisition system does
this properly.
The FILTPOS handling is retained for backwards compatibility.
"""

default = "unknown"
try:
filter_pos = self._header["FILTPOS"]
self._used_these_cards("FILTPOS")
except KeyError:
log.warning("%s: FILTPOS key not found in header (assuming %s)",
self._log_prefix, default)
return default
# TS8 data from 2023-05-09 and later should be following
# DM-38882 conventions.
physical_filter = super().to_physical_filter()
# Some TS8 taken prior to 2023-05-09 have the string
# 'unspecified' as the FILTER keyword and don't really
# follow any established convention.
if 'unspecified' in physical_filter:
return default
return physical_filter

try:
return {
Expand Down

0 comments on commit f55ae41

Please sign in to comment.