22 """Classes to allow obs packages to define the filters used by an Instrument 23 and for use by `lsst.afw.image.Filter`, gen2 dataIds, and gen3 Dimensions. 26 __all__ = (
"FilterDefinition",
"FilterDefinitionCollection")
29 import collections.abc
33 import lsst.afw.image.utils
37 """An order-preserving collection of `FilterDefinition`s. 42 The filters in this collection. 46 """Whether these filters have been defined via 47 `~lsst.afw.image.utils.defineFilter`. If so, set to ``self`` to identify 48 the filter collection that defined them. 61 return "FilterDefinitions(" +
', '.join(str(f)
for f
in self.
_filters) +
')' 64 """Define all the filters to `lsst.afw.image.Filter`. 66 `~lsst.afw.image.Filter` objects are singletons, so we protect against 67 filters being defined multiple times. 72 Raised if any other `FilterDefinitionCollection` has already called 79 FilterDefinitionCollection._defined = self
84 msg = f
"afw Filters were already defined on: {self._defined}" 85 raise RuntimeError(msg)
89 """Reset the afw Filter definitions and clear the `defined` singleton. 90 Use this in unittests that define different filters. 92 lsst.afw.image.utils.resetFilters()
96 @dataclasses.dataclass(frozen=
True)
98 """The definition of an instrument's filter bandpass. 100 This class is used to interface between the `~lsst.afw.image.Filter` class 101 and the Gen2 `~lsst.daf.persistence.CameraMapper` and Gen3 102 `~lsst.obs.base.Instruments` and ``physical_filter``/``abstract_filter`` 103 `~lsst.daf.butler.Dimension`. 105 This class is likely temporary, until we have a better versioned filter 106 definition system that includes complete transmission information. 110 """The name of a filter associated with a particular instrument: unique for 111 each piece of glass. This should match the exact filter name used in the 112 observatory's metadata. 114 This name is used to define the ``physical_filter`` gen3 Butler Dimension. 116 If neither ``abstract_filter`` or ``afw_name`` is defined, this is used 117 as the `~lsst.afw.image.Filter` ``name``, otherwise it is added to the 118 list of `~lsst.afw.image.Filter` aliases. 122 """The effective wavelength of this filter (nm).""" 124 abstract_filter: str =
None 125 """The generic name of a filter not associated with a particular instrument 126 (e.g. `r` for the SDSS Gunn r-band, which could be on SDSS, LSST, or HSC). 128 Not all filters have an abstract filter: engineering or test filters may 129 not have a genericly-termed filter name. 131 If specified and if `afw_name` is None, this is used as the 132 `~lsst.afw.image.Filter` ``name`` field, otherwise it is added to the list 133 of `~lsst.afw.image.Filter` aliases. 137 """If not None, the name of the `~lsst.afw.image.Filter` object. 139 This is distinct from physical_filter and abstract_filter to maintain 140 backwards compatibility in some obs packages. 141 For example, for HSC there are two distinct ``r`` and ``i`` filters, named 142 ``r/r2`` and ``i/i2``. 145 lambdaMin: float = np.nan
146 """The minimum wavelength of this filter (nm; defined as 1% throughput)""" 147 lambdaMax: float = np.nan
148 """The maximum wavelength of this filter (nm; defined as 1% throughput)""" 150 alias: set = frozenset()
151 """Alternate names for this filter. These are added to the 152 `~lsst.afw.image.Filter` alias list. 157 if not isinstance(self.alias, frozenset):
158 object.__setattr__(self,
'alias', frozenset(self.alias))
161 txt = f
"FilterDefinition(physical_filter='{self.physical_filter}', lambdaEff='{self.lambdaEff}'" 162 if self.abstract_filter
is not None:
163 txt += f
", abstract_filter='{self.abstract_filter}'" 164 if self.afw_name
is not None:
165 txt += f
", afw_name='{self.afw_name}'" 166 if not np.isnan(self.lambdaMin):
167 txt += f
", lambdaMin='{self.lambdaMin}'" 168 if not np.isnan(self.lambdaMax):
169 txt += f
", lambdaMax='{self.lambdaMax}'" 170 if len(self.alias) != 0:
171 txt += f
", alias='{self.alias}'" 175 """Declare the filters via afw.image.Filter. 177 aliases =
set(self.alias)
178 name = self.physical_filter
179 if self.abstract_filter
is not None:
180 name = self.abstract_filter
181 aliases.add(self.physical_filter)
182 if self.afw_name
is not None:
184 aliases.add(self.physical_filter)
186 if self.afw_name
is not None:
187 if self.abstract_filter
is not None:
188 aliases.add(self.abstract_filter)
189 lsst.afw.image.utils.defineFilter(name,
190 lambdaEff=self.lambdaEff,
191 lambdaMin=self.lambdaMin,
192 lambdaMax=self.lambdaMax,
193 alias=sorted(aliases))
def __init__(self, filters)
def __getitem__(self, key)