Skip to content

Commit

Permalink
Add basic INPUT dataset provenance
Browse files Browse the repository at this point in the history
  • Loading branch information
timj committed Jan 24, 2025
1 parent 774be8e commit 108fdc6
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 9 deletions.
8 changes: 5 additions & 3 deletions python/lsst/obs/base/exposureAssembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
# Need to enable PSFs to be instantiated
import lsst.afw.detection
from lsst.afw.image import Exposure, makeExposure, makeMaskedImage
from lsst.daf.butler import DatasetComponent, DatasetRef, StorageClassDelegate
from lsst.daf.butler import DatasetComponent, DatasetProvenance, DatasetRef, StorageClassDelegate

from .formatters.fitsExposure import add_provenance_to_fits_header

Expand Down Expand Up @@ -322,7 +322,9 @@ def selectResponsibleComponent(cls, readComponent: str, fromComponents: set[str
return c
raise ValueError(f"Can not calculate read component {readComponent} from {fromComponents}")

def add_provenance(self, inMemoryDataset: Any, ref: DatasetRef) -> Any:
def add_provenance(
self, inMemoryDataset: Any, ref: DatasetRef, provenance: DatasetProvenance | None = None
) -> Any:
# Add provenance via FITS headers.
add_provenance_to_fits_header(inMemoryDataset.metadata, ref)
add_provenance_to_fits_header(inMemoryDataset.metadata, ref, provenance)
return inMemoryDataset
24 changes: 19 additions & 5 deletions python/lsst/obs/base/formatters/fitsExposure.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@
# Needed for ApCorrMap to resolve properly
from lsst.afw.math import BoundedField # noqa: F401
from lsst.daf.base import PropertyList, PropertySet
from lsst.daf.butler import DatasetRef, FormatterV2
from lsst.daf.butler import DatasetProvenance, DatasetRef, FormatterV2
from lsst.resources import ResourcePath
from lsst.utils.classes import cached_getter
from lsst.utils.introspection import find_outside_stacklevel


def add_provenance_to_fits_header(hdr: PropertyList | MutableMapping, ref: DatasetRef) -> None:
def add_provenance_to_fits_header(
hdr: PropertyList | MutableMapping, ref: DatasetRef, provenance: DatasetProvenance | None = None
) -> None:
"""Modify the given header to include provenance headers.
Parameters
Expand All @@ -65,14 +67,26 @@ def add_provenance_to_fits_header(hdr: PropertyList | MutableMapping, ref: Datas
# Use property list here so that we have the option of including comments.
extras = PropertyList()
hierarch = "LSST BUTLER"

# Add the information about this dataset.
extras.set(f"{hierarch} ID", str(ref.id), comment="Dataset ID")
extras.set(f"{hierarch} RUN", ref.run, comment="Run collection")
extras.set(f"{hierarch} DATASETTYPE", ref.datasetType.name, comment="Dataset type")
for k, v in sorted(ref.dataId.required.items()):
extras.set(f"{hierarch} DATAID {k.upper()}", v, comment="Data identifier")

# Purge old headers from metadata (important for data ID headers and to
# prevent headers accumulating in a PropertyList).
# Add information about any inputs to the quantum that generated
# this dataset.
if provenance is not None:
for i, input in enumerate(provenance.inputs):
input_key = f"{hierarch} INPUT {i}"
# Comments can make the strings too long and need CONTINUE.
extras.set(f"{input_key} ID", str(input.id))
extras.set(f"{input_key} RUN", input.run)
extras.set(f"{input_key} DATASETTYPE", input.datasetType.name)

# Purge old headers from metadata (important for data ID and input headers
# and to prevent headers accumulating in a PropertyList).
for k in hdr:
if k.startswith(hierarch):
del hdr[k]
Expand Down Expand Up @@ -548,7 +562,7 @@ class FitsExposureFormatter(FitsMaskedImageFormatter):

def add_provenance(self, in_memory_dataset: Any) -> Any:
# Add provenance via FITS headers.
add_provenance_to_fits_header(in_memory_dataset.metadata, self.dataset_ref)
add_provenance_to_fits_header(in_memory_dataset.metadata, self.dataset_ref, self._provenance)
return in_memory_dataset

def readComponent(self, component):
Expand Down
2 changes: 1 addition & 1 deletion python/lsst/obs/base/formatters/fitsGeneric.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ def add_provenance(self, in_memory_dataset: Any) -> Any:
else:
# Unable to find compliant metadata attribute.
return in_memory_dataset
add_provenance_to_fits_header(metadata, self.dataset_ref)
add_provenance_to_fits_header(metadata, self.dataset_ref, self._provenance)
return in_memory_dataset

0 comments on commit 108fdc6

Please sign in to comment.