Skip to content

Commit

Permalink
Add Instrument interface and minimal implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
Pim Schellart authored and Pim Schellart committed Apr 18, 2018
1 parent ffe70f8 commit e2dee12
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 4 deletions.
70 changes: 70 additions & 0 deletions python/lsst/daf/butler/instrument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# This file is part of daf_butler.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
# (http://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.


__all__ = ("Instrument", )


class Instrument:
"""A template method class that can register itself with a
`Registry.
This class should be subclassed by various implementations.
Subclasses should provide all relevant attributes, as documented
below.
Attributes
----------
camera : `str`
Name of the camera. Must be provided by subclass.
physicalFilters : `list`
List of PhysicalFilter entries (each entry being a dict).
sensors : `list`
List of Sensor entries (each entry being a dict).
"""
camera = None
physicalFilters = []
sensors = []

def register(self, registry):
"""Register an instance of this `Instrument` with a `Registry`.
Creates all relevant `DataUnit` entries.
"""
assert self.camera is not None
self._addCamera(registry)
self._addPhysicalFilters(registry)
self._addSensors(registry)

def _addCamera(self, registry):
registry.addDataUnitEntry('Camera', {'camera': self.camera})

def _addPhysicalFilters(self, registry):
for entry in self.physicalFilters:
if 'camera' not in entry:
entry['camera'] = self.camera
registry.addDataUnitEntry('PhysicalFilter', entry)

def _addSensors(self, registry):
for entry in self.sensors:
if 'camera' not in entry:
entry['camera'] = self.camera
registry.addDataUnitEntry('Sensor', entry)
9 changes: 5 additions & 4 deletions python/lsst/daf/butler/registries/sqlRegistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,23 +673,24 @@ def markInputUsed(self, quantum, ref):
raise KeyError("{} is not a predicted consumer for {}".format(ref, quantum))
quantum._markInputUsed(ref)

def addDataUnitEntry(self, dataUnitName, value):
def addDataUnitEntry(self, dataUnitName, values):
"""Add a new `DataUnit` entry.
dataUnitName : `str`
Name of the `DataUnit` (e.g. ``"Camera"``).
values : `dict`
Dictionary of ``columnName, value`` pairs.
Dictionary of ``columnName, columnValue`` pairs.
Raises
------
ValueError
If an entry for this value is already present.
If an entry with the primary-key defined in `values` is already
present.
"""
dataUnitTable = self._schema.metadata.tables[dataUnitName]
with self._engine.begin() as connection:
try:
connection.execute(dataUnitTable.insert().values(**value))
connection.execute(dataUnitTable.insert().values(**values))
except IntegrityError as err:
raise ValueError(str(err)) # TODO this should do an explicit validity check instead

Expand Down
69 changes: 69 additions & 0 deletions tests/test_instrument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# This file is part of daf_butler.
#
# Developed for the LSST Data Management System.
# This product includes software developed by the LSST Project
# (http://www.lsst.org).
# See the COPYRIGHT file at the top-level directory of this distribution
# for details of code ownership.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import os
import unittest

import lsst.utils.tests

from lsst.daf.butler.core import Registry

from lsst.daf.butler.instrument import Instrument

"""Tests for Instrument.
"""


class DummyCam(Instrument):
camera = 'DummyCam'

physicalFilters = [{'physical_filter': 'dummy_g'},
{'physical_filter': 'dummy_u'}]

sensors = [{'sensor': 'one'},
{'sensor': 'two'}]


class InstrumentTestCase(lsst.utils.tests.TestCase):
"""Test for Instrument.
"""

def setUp(self):
self.testDir = os.path.dirname(__file__)
self.configFile = os.path.join(self.testDir, "config/basic/butler.yaml")

def testRegister(self):
registry = Registry.fromConfig(self.configFile)
dummyCam = DummyCam()
dummyCam.register(registry)


class MemoryTester(lsst.utils.tests.MemoryTestCase):
pass


def setup_module(module):
lsst.utils.tests.init()


if __name__ == "__main__":
lsst.utils.tests.init()
unittest.main()

0 comments on commit e2dee12

Please sign in to comment.