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")
34 import lsst.afw.image.utils
38 """An order-preserving collection of multiple `FilterDefinition`.
42 filters : `~collections.abc.Sequence`
43 The filters in this collection.
47 """Whether these filters have been defined via
48 `~lsst.afw.image.utils.defineFilter`. If so, set to ``self`` to identify
49 the filter collection that defined them.
53 """A mapping from physical filter name to band name.
54 This is a convenience feature to allow file readers to create a FilterLabel
55 when reading a raw file that only has a physical filter name, without
56 iterating over the entire collection.
60 self.
_filters_filters = list(filters)
70 return "FilterDefinitions(" +
', '.join(str(f)
for f
in self.
_filters_filters) +
')'
73 """Define all the filters to `lsst.afw.image.Filter`.
75 `~lsst.afw.image.Filter` objects are singletons, so we protect against
76 filters being defined multiple times.
81 Raised if any other `FilterDefinitionCollection` has already called
85 with warnings.catch_warnings():
87 warnings.simplefilter(
'ignore', category=FutureWarning)
91 FilterDefinitionCollection._defined = self
96 msg = f
"afw Filters were already defined on: {self._defined}"
97 raise RuntimeError(msg)
101 """Reset the afw Filter definitions and clear the `defined` singleton.
102 Use this in unittests that define different filters.
104 with warnings.catch_warnings():
106 warnings.simplefilter(
'ignore', category=FutureWarning)
107 lsst.afw.image.utils.resetFilters()
111 """Return the FilterDefinitions that match a particular name.
113 This method makes no attempt to prioritize, e.g., band names over
114 physical filter names; any definition that makes *any* reference
115 to the name is returned.
120 The name to search for. May be any band, physical, or alias name.
124 matches : `set` [`FilterDefinition`]
125 All FilterDefinitions containing ``name`` as one of their
129 for filter
in self.
_filters_filters:
130 if name == filter.physical_filter
or name == filter.band
or name == filter.afw_name \
131 or name
in filter.alias:
136 @dataclasses.dataclass(frozen=True)
138 """The definition of an instrument's filter bandpass.
140 This class is used to interface between the `~lsst.afw.image.Filter` class
141 and the Gen2 `~lsst.daf.persistence.CameraMapper` and Gen3
142 `~lsst.obs.base.Instruments` and ``physical_filter``/``band``
143 `~lsst.daf.butler.Dimension`.
145 This class is likely temporary, until we have a better versioned filter
146 definition system that includes complete transmission information.
150 """The name of a filter associated with a particular instrument: unique for
151 each piece of glass. This should match the exact filter name used in the
152 observatory's metadata.
154 This name is used to define the ``physical_filter`` gen3 Butler Dimension.
156 If neither ``band`` or ``afw_name`` is defined, this is used
157 as the `~lsst.afw.image.Filter` ``name``, otherwise it is added to the
158 list of `~lsst.afw.image.Filter` aliases.
162 """The effective wavelength of this filter (nm)."""
165 """The generic name of a filter not associated with a particular instrument
166 (e.g. `r` for the SDSS Gunn r-band, which could be on SDSS, LSST, or HSC).
168 Not all filters have an abstract filter: engineering or test filters may
169 not have a genericly-termed filter name.
171 If specified and if `afw_name` is None, this is used as the
172 `~lsst.afw.image.Filter` ``name`` field, otherwise it is added to the list
173 of `~lsst.afw.image.Filter` aliases.
177 """A short description of this filter, possibly with a link to more
182 """If not None, the name of the `~lsst.afw.image.Filter` object.
184 This is distinct from physical_filter and band to maintain
185 backwards compatibility in some obs packages.
186 For example, for HSC there are two distinct ``r`` and ``i`` filters, named
187 ``r/r2`` and ``i/i2``.
190 lambdaMin: float = np.nan
191 """The minimum wavelength of this filter (nm; defined as 1% throughput)"""
192 lambdaMax: float = np.nan
193 """The maximum wavelength of this filter (nm; defined as 1% throughput)"""
195 alias: set = frozenset()
196 """Alternate names for this filter. These are added to the
197 `~lsst.afw.image.Filter` alias list.
202 if not isinstance(self.alias, frozenset):
203 object.__setattr__(self,
'alias', frozenset(self.alias))
206 txt = f
"FilterDefinition(physical_filter='{self.physical_filter}', lambdaEff='{self.lambdaEff}'"
207 if self.band
is not None:
208 txt += f
", band='{self.band}'"
209 if self.afw_name
is not None:
210 txt += f
", afw_name='{self.afw_name}'"
211 if not np.isnan(self.lambdaMin):
212 txt += f
", lambdaMin='{self.lambdaMin}'"
213 if not np.isnan(self.lambdaMax):
214 txt += f
", lambdaMax='{self.lambdaMax}'"
215 if len(self.alias) != 0:
216 txt += f
", alias='{self.alias}'"
220 """Declare the filters via afw.image.Filter.
222 aliases =
set(self.alias)
223 name = self.physical_filter
224 if self.band
is not None:
226 aliases.add(self.physical_filter)
227 if self.afw_name
is not None:
229 aliases.add(self.physical_filter)
231 if self.afw_name
is not None:
232 if self.band
is not None:
233 aliases.add(self.band)
234 with warnings.catch_warnings():
236 warnings.simplefilter(
'ignore', category=FutureWarning)
237 lsst.afw.image.utils.defineFilter(name,
238 lambdaEff=self.lambdaEff,
239 lambdaMin=self.lambdaMin,
240 lambdaMax=self.lambdaMax,
241 alias=sorted(aliases))
244 """Create a complete FilterLabel for this filter.
246 return lsst.afw.image.FilterLabel(band=self.band, physical=self.physical_filter)
def __init__(self, *filters)
dictionary physical_to_band
def __getitem__(self, key)
def makeFilterLabel(self)