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
#!/usr/bin/env python # # LSST Data Management System # Copyright 2008-2016 AURA/LSST. # # This product includes software developed by the # LSST Project (http://www.lsst.org/). # # 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 LSST License Statement and # the GNU General Public License along with this program. If not, # see <http://www.lsstcorp.org/LegalNotices/>. #
""" Configuration for Sample Plugin with a FlagHandler. """
""" This is a sample Python plugin which shows how to create a plugin which has a log provided to it by the measurement task which is running it. Note that the hasLogName attribute must be a member of the Plugin class, and must be True """
def getExecutionOrder(cls): return cls.FLUX_ORDER
# The initializer for the class requires an optional logName 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")
""" The measure method is called by the measurement framework when task.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)
""" This routine responds to the standard failure call in baseMeasurement If the exception is a MeasurementError, the error will be passed to the fail method by the MeasurementFramework. If 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 no file is specified""" 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 the registered Plugins to see if their logName is set as expected. Those which have the hasLogName=True attribute will have a LogName parameter in their __init__, and should set the internal BasePlugin._logName attribute. If they are wrapped C++ Algorithms, the cpp.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 are known to 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)
"""Check that plugin log can be set to ERROR level, where Measurement Error doesn't show.""" """Check that we recover the correct location of the centroid.""" 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)
"""Check that plugin log can be set to ERROR level, where Measurement Error doesn't show.""" """Check that we recover the correct location of the centroid.""" 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() |