def fromName(name: str, registry: Registry, collection_prefix: Optional[str] = None) -> Instrument: """Given an instrument name and a butler registry, retrieve a corresponding instantiated instrument object. Parameters ---------- name : `str` Name of the instrument (must match the return value of `getName`). registry : `lsst.daf.butler.Registry` Butler registry to query to find the information. collection_prefix : `str`, optional Prefix for collection names to use instead of the intrument's own name. This is primarily for use in simulated-data repositories, where the instrument name may not be necessary and/or sufficient to distinguish between collections. 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 or the imported symbol is not an `Instrument` subclass. """ try: records = list( registry.queryDimensionRecords("instrument", instrument=name)) except DataIdError: records = None if not records: raise LookupError(f"No registered instrument with name '{name}'.") cls_name = records[0].class_name if not isinstance(cls_name, str): raise TypeError( f"Unexpected class name retrieved from {name} instrument dimension (got {cls_name})" ) instrument_cls: type = doImportType(cls_name) if not issubclass(instrument_cls, Instrument): raise TypeError( f"{instrument_cls!r}, obtained from importing {cls_name}, is not an Instrument subclass." ) return instrument_cls(collection_prefix=collection_prefix)
def _fillRelationships(dimension: Dimension, dimensionInfo: Mapping[str, Any], existing: Registry) -> Mapping[str, Any]: """Create arbitrary mappings from one dimension to all dimensions it depends on. Parameters ---------- dimension : `lsst.daf.butler.Dimension` The dimension for which to generate relationships. dimensionInfo : `dict` [`str`] A mapping of dimension keys to values. existing : `lsst.daf.butler.Registry` The registry with all previously registered dimensions. Returns ------- filledInfo : `dict` [`str`] A version of ``dimensionInfo`` with extra mappings for any relationships required by ``dimension``. Any relationships already defined in ``dimensionInfo`` are preserved. Raises ------ ValueError Raised if ``dimension`` depends on a dimension for which no values exist yet. """ filledInfo = dimensionInfo.copy() for other in dimension.required: if other != dimension and other.name not in filledInfo: _matchAnyDataId(filledInfo, existing, other) # Do not recurse, to keep the user from having to provide # irrelevant dimensions. for other in dimension.implied: toUpdate = other != dimension and other.name not in filledInfo updatable = other.viewOf is None # Do not run query if either toUpdate or updatable is false if toUpdate and updatable and list( existing.queryDimensionRecords(other)): _matchAnyDataId(filledInfo, existing, other) return filledInfo
def importAll(registry: Registry) -> None: """Import all the instruments known to this registry. This will ensure that all metadata translators have been registered. Parameters ---------- registry : `lsst.daf.butler.Registry` Butler registry to query to find the information. Notes ----- It is allowed for a particular instrument class to fail on import. This might simply indicate that a particular obs package has not been setup. """ records = list(registry.queryDimensionRecords("instrument")) for record in records: cls = record.class_name try: doImportType(cls) except Exception: pass
def _matchAnyDataId(record: Mapping[str, Any], registry: Registry, dimension: Dimension): """Matches a partial dimension record to an existing record along a specific dimension. Parameters ---------- record : `dict` [`str`] A mapping representing the record to be matched. registry : `lsst.daf.butler.Registry` The registry with all known dimension records. dimension : `lsst.daf.butler.Dimension` The dimension on which to find a match for ``record``. Raises ------ RuntimeError Raised if there are no existing records for ``dimension``. """ matches = list(registry.queryDimensionRecords(dimension.name)) if matches: record[dimension.name] = matches[0].dataId[dimension.name] else: raise RuntimeError(f"No matching values for {dimension.name} found.")