Skip to content

Commit

Permalink
Add Instrument.fromName to read instrument class from registry
Browse files Browse the repository at this point in the history
  • Loading branch information
timj committed Apr 7, 2020
1 parent 6accb33 commit 1387dec
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 1 deletion.
41 changes: 40 additions & 1 deletion python/lsst/obs/base/instrument.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
import astropy.time

from lsst.daf.butler import TIMESPAN_MIN, TIMESPAN_MAX, DatasetType, DataCoordinate
from lsst.utils import getPackageDir
from lsst.utils import getPackageDir, doImport

# To be a standard text curated calibration means that we use a
# standard definition for the corresponding DatasetType.
Expand Down Expand Up @@ -115,6 +115,45 @@ def obsDataPackageDir(self):
self._obsDataPackageDir = getPackageDir(self.obsDataPackage)
return self._obsDataPackageDir

@classmethod
def fromName(cls, name, registry):
"""Given an instrument name and a butler, retrieve a corresponding
instantiated instrument object.
Parameters
----------
name : `str`
Name of the instrument (must match the name property of
an instrument class).
registry : `lsst.daf.butler.Registry`
Butler registry to query to find the information.
Returns
-------
instrument : `Instrument`
An instance of the relevant `Instrument`.
Notes
-----
The instrument must be registered in the corresponding butler.
Raises
------
LookupError
Raised if the instrument is not known to the supplied registry.
ModuleNotFoundError
Raised if the class could not be imported. This could mean
that the relevant obs package has not been setup.
TypeError
Raised if the class name retrieved is not a string.
"""
dimensions = list(registry.queryDimensions("instrument", dataId={"instrument": name}))
cls = dimensions[0].records["instrument"].class_name
if not isinstance(cls, str):
raise TypeError(f"Unexpected class name retrieved from {name} instrument dimension (got {cls})")
instrument = doImport(cls)
return instrument()

def _registerFilters(self, registry):
"""Register the physical and abstract filter Dimension relationships.
This should be called in the ``register`` implementation.
Expand Down
5 changes: 5 additions & 0 deletions python/lsst/obs/base/instrument_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import abc
import dataclasses

from lsst.obs.base import Instrument
from lsst.daf.butler import Registry
from lsst.daf.butler import ButlerConfig

Expand Down Expand Up @@ -96,3 +97,7 @@ def test_register(self):
physicalFilterDataIds = list(registry.queryDimensions(["physical_filter"]))
filterNames = {dataId['physical_filter'] for dataId in physicalFilterDataIds}
self.assertGreaterEqual(filterNames, self.data.physical_filters)

# Check that the instrument class can be retrieved
registeredInstrument = Instrument.fromName(self.instrument.getName(), registry)
self.assertEqual(type(registeredInstrument), type(self.instrument))

0 comments on commit 1387dec

Please sign in to comment.