|
1 | 1 |
|
2 | | -__all__ = ["DynamicDetectionConfig", "DynamicDetectionTask"] |
| 2 | +__all__ = ["DynamicDetectionConfig", "DynamicDetectionTask", "InsufficientSourcesError"] |
3 | 3 |
|
4 | 4 | import numpy as np |
5 | 5 |
|
6 | 6 | from lsst.pex.config import Field, ConfigurableField |
7 | | -from lsst.pipe.base import Struct, NoWorkFound |
| 7 | +from lsst.pipe.base import Struct |
8 | 8 |
|
9 | 9 | from .detection import SourceDetectionConfig, SourceDetectionTask |
10 | 10 | from .skyObjects import SkyObjectsTask |
|
19 | 19 | import lsst.geom as geom |
20 | 20 |
|
21 | 21 |
|
| 22 | +class InsufficientSourcesError(Exception): |
| 23 | + """Raised if an insufficient number of sky sources are found for |
| 24 | + dynamic detection. |
| 25 | +
|
| 26 | + Parameters |
| 27 | + ---------- |
| 28 | + msg : `str` |
| 29 | + Error message. |
| 30 | + nGoodPix : `int` |
| 31 | + Number of good pixels (i.e. not NO_DATA or BAD). |
| 32 | + nPix : `int` |
| 33 | + Total number of pixels. |
| 34 | + **kwargs : `dict`, optional |
| 35 | + Additional keyword arguments to initialize the Exception base class. |
| 36 | + """ |
| 37 | + def __init__(self, msg, nGoodPix, nPix, **kwargs): |
| 38 | + self.msg = msg |
| 39 | + self._metadata = kwargs |
| 40 | + super().__init__(msg, **kwargs) |
| 41 | + self._metadata["nGoodPix"] = int(nGoodPix) |
| 42 | + self._metadata["nPix"] = int(nPix) |
| 43 | + |
| 44 | + def __str__(self): |
| 45 | + # Exception doesn't handle **kwargs, so we need a custom str. |
| 46 | + return f"{self.msg}: {self.metadata}" |
| 47 | + |
| 48 | + @property |
| 49 | + def metadata(self): |
| 50 | + for key, value in self._metadata.items(): |
| 51 | + if not (isinstance(value, int) or isinstance(value, float) or isinstance(value, str)): |
| 52 | + raise TypeError(f"{key} is of type {type(value)}, but only (int, float, str) are allowed.") |
| 53 | + return self._metadata |
| 54 | + |
| 55 | + |
22 | 56 | class DynamicDetectionConfig(SourceDetectionConfig): |
23 | 57 | """Configuration for DynamicDetectionTask |
24 | 58 | """ |
@@ -259,8 +293,8 @@ def calculateThreshold(self, exposure, seed, sigma=None, minFractionSourcesFacto |
259 | 293 | "so there should be sufficient area to locate suitable sky sources. " |
260 | 294 | f"Note that {nDetectedPix} of {nGoodPix} \"good\" pixels were marked " |
261 | 295 | "as DETECTED or DETECTED_NEGATIVE.") |
262 | | - raise RuntimeError(msg) |
263 | | - raise NoWorkFound(msg) |
| 296 | + raise InsufficientSourcesError(msg, nGoodPix, nPix) |
| 297 | + raise InsufficientSourcesError(msg, nGoodPix, nPix) |
264 | 298 |
|
265 | 299 | if not isBgTweak: |
266 | 300 | self.log.info("Number of good sky sources used for dynamic detection: %d (of %d requested).", |
|
0 commit comments