Coverage for tests/test_PluginLogs.py : 18%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# This file is part of meas_base. # # Developed for the LSST Data Management System. # This product includes software developed by the LSST Project # (https://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 <https://www.gnu.org/licenses/>.
"""Configuration for sample plugin. """
"""Sample Python plugin which has an associated log name.
Notes ----- The log name is provided to the plugin by the measurement task which is running it. This requires that the `hasLogName` attribute must be a member of the plugin class, and it must be `True`. """
def getExecutionOrder(cls): return cls.FLUX_ORDER
# The initializer for the class must accept an optional logName parameter. SingleFramePlugin.__init__(self, config, name, schema, metadata, logName=logName) flagDefs = FlagDefinitionList() self.FAILURE = flagDefs.addFailureFlag() self.CONTAINS_NAN = flagDefs.add("flag_containsNan", "Measurement area contains a nan") self.flagHandler = FlagHandler.addFields(schema, name, flagDefs) self.instFluxKey = schema.addField(name + "_instFlux", "F", doc="flux")
"""Perform measurement.
Notes ----- The `measure` method is called by the measurement framework when `run` is called. If a `MeasurementError` is raised during this method, the `fail` method will be called to set the error flags. """ lsst.log.Log.getLogger(self.getLogName()).info("%s plugin measuring."%(self.name,)) # Sum the pixels inside the bounding box centerPoint = lsst.geom.Point2I(int(measRecord.getX()), int(measRecord.getY())) bbox = lsst.geom.Box2I(centerPoint, lsst.geom.Extent2I(1, 1)) instFlux = lsst.afw.image.ImageF(exposure.getMaskedImage().getImage(), bbox).getArray().sum() measRecord.set(self.instFluxKey, instFlux)
# If there was a NaN inside the bounding box, the instFlux will still # be NaN if numpy.isnan(instFlux): raise MeasurementError(self.CONTAINS_NAN.doc, self.CONTAINS_NAN.number)
"""Handle measurement failures.
Notes ----- If measurement raises a `MeasurementError`, the error will be passed to the fail method by the measurement framework. If the error is not `None`, ``error.cpp`` should correspond to a specific error and the appropriate error flag will be set. """ if error is None: self.flagHandler.handleFailure(measRecord) else: self.flagHandler.handleFailure(measRecord, error.cpp)
"""Direct the log given to a file or to the console if ``file`` is `None`. """ props = "log4j.rootLogger=INFO, FA\n" if file is None: props += "log4j.appender.FA=ConsoleAppender\n" else: props += "log4j.appender.FA=FileAppender\n" props += "log4j.appender.FA.Append=false\n" props += "log4j.appender.FA.file=%s\n"%(file,) props += "log4j.appender.FA.Append=false\n" props += "log4j.appender.FA.layout=PatternLayout\n" props += "log4j.appender.FA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %p %c %m %X%n\n" props += "log4j.logger.main.a=DEBUG\n" log.configure_prop(props)
"""Test all registered Plugins to see if their logName is set as expected.
Those which have the ``hasLogName=True`` attribute will have a ``logName`` parameter passed to their ``__init__``, and should set the internal ``_logName`` attribute. If they are wrapped C++ algorithms, the `getLogName` should also return same ``logName`` as the plugin. """ center = lsst.geom.Point2D(50, 50) bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(100, 100)) dataset = lsst.meas.base.tests.TestDataset(bbox) dataset.addSource(1000000.0, center) registry = SingleFramePlugin.registry dependencies = registry.keys() task = self.makeSingleFrameMeasurementTask("base_SdssCentroid", dependencies=dependencies) exposure, catalog = dataset.realize(noise=100.0, schema=task.schema, randomSeed=0) task.log.setLevel(lsst.log.ERROR) task.run(catalog, exposure) for pluginName in dependencies: plugin = task.plugins[pluginName] if hasattr(plugin, "hasLogName") and plugin.hasLogName: self.assertEqual(plugin.getLogName(), task.getPluginLogName(pluginName)) # if the plugin is cpp, check the cpp Algorithm as well if hasattr(plugin, "cpp"): self.assertEqual(plugin.cpp.getLogName(), plugin.getLogName()) else: self.assertEqual(plugin.getLogName(), None)
# Test all the ForcedPlugins registered to see if their logName is set # as expected. center = lsst.geom.Point2D(50, 50) bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(100, 100)) dataset = lsst.meas.base.tests.TestDataset(bbox) dataset.addSource(1000000.0, center) registry = ForcedPlugin.registry dependencies = registry.keys()
task = self.makeForcedMeasurementTask("base_SdssCentroid", dependencies=dependencies) measWcs = dataset.makePerturbedWcs(dataset.exposure.getWcs(), randomSeed=1) measDataset = dataset.transform(measWcs) exposure, truthCatalog = measDataset.realize(10.0, measDataset.makeMinimalSchema(), randomSeed=1) refCat = dataset.catalog refWcs = dataset.exposure.getWcs() measCat = task.generateMeasCat(exposure, refCat, refWcs) task.attachTransformedFootprints(measCat, refCat, exposure, refWcs)
task.log.setLevel(lsst.log.ERROR) task.run(measCat, exposure, refCat, refWcs) for pluginName in dependencies: plugin = task.plugins[pluginName] if hasattr(plugin, "hasLogName") and plugin.hasLogName: self.assertEqual(plugin.getLogName(), task.getPluginLogName(pluginName)) # if the plugin is cpp, check the cpp Algorithm as well if hasattr(plugin, "cpp"): self.assertEqual(plugin.cpp.getLogName(), task.log.getName() + "." + pluginName) else: self.assertEqual(plugin.getLogName(), None)
"""Test one C++ and one Python plugin which have hasLogName=True. """ bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Point2I(100, 100)) self.dataset = lsst.meas.base.tests.TestDataset(bbox) self.dataset.addSource(instFlux=1E5, centroid=lsst.geom.Point2D(25, 25)) config = lsst.meas.base.SingleFrameMeasurementConfig() config.slots.centroid = None config.slots.apFlux = None config.slots.calibFlux = None config.slots.gaussianFlux = None config.slots.modelFlux = None config.slots.psfFlux = None config.slots.shape = None config.slots.psfShape = None self.config = config
del self.config del self.dataset
algName = "test_LoggingPlugin" schema = self.dataset.makeMinimalSchema() self.config.plugins = [algName] task = lsst.meas.base.SingleFrameMeasurementTask(schema=schema, config=self.config) # test that the plugin's logName has been propagated to the plugin self.assertTrue(task.plugins[algName].getLogName(), task.getPluginLogName(algName)) log = lsst.log.Log.getLogger(task.getPluginLogName(algName)) with lsst.utils.tests.getTempFilePath(".log") as pluginLogName: directLog(log, pluginLogName) exposure, cat = self.dataset.realize(noise=0.0, schema=schema, randomSeed=2) task.run(cat, exposure) directLog(log, None) # direct back to console, closing log files with open(pluginLogName) as fin: lines = fin.read() # test that the sample plugin has correctly logged to where we # expected it to. self.assertTrue(lines.find("measuring") >= 0)
# PsfFlux is known to log an ``ERROR`` if a Psf is not attached algName = "base_PsfFlux" self.config.plugins = [algName]
schema = self.dataset.makeMinimalSchema() task = lsst.meas.base.SingleFrameMeasurementTask(schema=schema, config=self.config) log = lsst.log.Log.getLogger(task.getPluginLogName(algName)) log.setLevel(lsst.log.ERROR)
# test that the plugin's logName has been propagated to the plugin self.assertTrue(task.plugins[algName].getLogName(), task.getPluginLogName(algName)) self.assertTrue(task.plugins[algName].cpp.getLogName(), task.getPluginLogName(algName)) with lsst.utils.tests.getTempFilePath(".log") as pluginLogName: directLog(log, pluginLogName) exposure, cat = self.dataset.realize(noise=0.0, schema=schema, randomSeed=3) exposure.setPsf(None) # This call throws an error, so be prepared for it try: task.run(cat, exposure) except Exception: pass directLog(log, None) # direct back to console, closing log files with open(pluginLogName) as fin: lines = fin.read() # test that the sample plugin has correctly logged to where we # expected it to. self.assertTrue(lines.find("ERROR") >= 0)
# object in corner to trigger EDGE error self.center = lsst.geom.Point2D(5, 5) self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(100, 100)) self.dataset = lsst.meas.base.tests.TestDataset(self.bbox) self.dataset.addSource(1000000.0, self.center) self.task = self.makeSingleFrameMeasurementTask("base_SdssCentroid") self.log = lsst.log.Log.getLogger(self.task.getPluginLogName("base_SdssCentroid")) self.exposure, self.catalog = self.dataset.realize(10.0, self.task.schema, randomSeed=4)
del self.center del self.bbox del self.dataset del self.task del self.log del self.exposure del self.catalog
"""Check that the task log and the plugin log are truly separate. """ taskLogName = os.path.join(ROOT, 'testSeparatePluginLogs-task.log') directLog(self.task.log, taskLogName) self.task.log.info("Testing") with lsst.utils.tests.getTempFilePath(".log") as pluginLogName: directLog(self.log, pluginLogName) self.log.setLevel(lsst.log.DEBUG) self.task.run(self.catalog, self.exposure) # direct back to console, closing log files directLog(self.log, None) directLog(self.task.log, None) with open(taskLogName) as fin: lines = fin.read() os.unlink(taskLogName) self.assertTrue(lines.find("Testing") >= 0) with open(pluginLogName) as fin: lines = fin.read() self.assertTrue(lines.find("MeasurementError") >= 0)
"""Test setting the plugin log level.
Specifically, we set it to the ``ERROR`` level. """ with lsst.utils.tests.getTempFilePath(".log") as pluginLogName: directLog(self.log, pluginLogName) self.log.setLevel(lsst.log.ERROR) self.task.run(self.catalog, self.exposure) # direct back to console, closing log files directLog(self.log, None) with open(pluginLogName) as fin: lines = fin.read() self.assertTrue(lines.find("MeasurementError") < 0)
# object in corner to trigger EDGE error self.center = lsst.geom.Point2D(0, 0) self.bbox = lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(100, 100)) self.dataset = lsst.meas.base.tests.TestDataset(self.bbox) self.dataset.addSource(1000000.0, self.center) self.task = self.makeForcedMeasurementTask("base_SdssCentroid") self.log = lsst.log.Log.getLogger(self.task.getPluginLogName("base_SdssCentroid")) measWcs = self.dataset.makePerturbedWcs(self.dataset.exposure.getWcs(), randomSeed=5) measDataset = self.dataset.transform(measWcs) self.exposure, truthCatalog = measDataset.realize(10.0, measDataset.makeMinimalSchema(), randomSeed=5) self.refCat = self.dataset.catalog self.refWcs = self.dataset.exposure.getWcs() self.measCat = self.task.generateMeasCat(self.exposure, self.refCat, self.refWcs) self.task.attachTransformedFootprints(self.measCat, self.refCat, self.exposure, self.refWcs)
del self.center del self.bbox del self.dataset del self.task del self.log del self.exposure del self.measCat del self.refCat del self.refWcs
"""Check that the task log and the plugin log are truly separate. """ taskLogName = os.path.join(ROOT, 'testSeparatePluginLog-task.log') directLog(self.task.log, taskLogName) self.task.log.info("Testing") with lsst.utils.tests.getTempFilePath(".log") as pluginLogName: directLog(self.log, pluginLogName) self.log.setLevel(lsst.log.DEBUG) self.task.run(self.measCat, self.exposure, self.refCat, self.refWcs) # direct back to console, closing log files directLog(self.log, None) directLog(self.task.log, None) with open(taskLogName) as fin: lines = fin.read() os.unlink(taskLogName) self.assertTrue(lines.find("Testing") >= 0) with open(pluginLogName) as fin: lines = fin.read() self.assertTrue(lines.find("MeasurementError") >= 0)
"""Test setting the plugin log level.
Specifically, we set it to the ``ERROR`` level. """ with lsst.utils.tests.getTempFilePath(".log") as pluginLogName: directLog(self.log, pluginLogName) self.log.setLevel(lsst.log.ERROR) self.task.run(self.measCat, self.exposure, self.refCat, self.refWcs) # direct back to console, closing log files directLog(self.log, None) with open(pluginLogName) as fin: lines = fin.read() self.assertTrue(lines.find("MeasurementError") < 0)
lsst.utils.tests.init()
lsst.utils.tests.init() unittest.main() |