Skip to content

Commit d861bb8

Browse files
committed
Replace coadd/visitContext with pexConfig.ChoiceField
1 parent abc10b6 commit d861bb8

File tree

12 files changed

+214
-173
lines changed

12 files changed

+214
-173
lines changed

pipelines/coaddColumnValidate.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ tasks:
77
connections.outputName: objectTableColumnValidate
88
metrics.validPsfFluxMetric: ValidFracColumnMetric
99
metrics.validPsfFluxMetric.vectorKey: 'psfFlux'
10-
metrics.validPsfFluxMetric.applyContext: CoaddContext
10+
metrics.validPsfFluxMetric.context: "coadd"
1111
metrics.validCmodelFluxMetric: ValidFracColumnMetric
1212
metrics.validCmodelFluxMetric.vectorKey: 'cModelFlux'
13-
metrics.validCmodelFluxMetric.applyContext: CoaddContext
13+
metrics.validCmodelFluxMetric.context: "coadd"
1414
python: |
1515
from lsst.analysis.tools.analysisMetrics import *
16-
from lsst.analysis.tools.contexts import *

pipelines/coaddQualityCore.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ tasks:
1212
plots.e2DiffScatterPlot: E2DiffScatterPlot
1313
metrics.e2DiffScatterMetric: E2DiffMetric
1414
metrics.skyFluxStatisticMetric: SkyFluxStatisticMetric
15-
metrics.skyFluxStatisticMetric.applyContext: CoaddContext
15+
metrics.skyFluxStatisticMetric.context: "coadd"
1616
plots.wPerpPSFPlot: WPerpPSFPlot
1717
metrics.wPerpPSFMetric: WPerpPSFMetric
1818
plots.wPerpCModelPlot: WPerpCModelPlot
@@ -30,7 +30,6 @@ tasks:
3030
python: |
3131
from lsst.analysis.tools.analysisPlots import *
3232
from lsst.analysis.tools.analysisMetrics import *
33-
from lsst.analysis.tools.contexts import *
3433
analyzeObjectTableSurveyCore:
3534
class: lsst.analysis.tools.tasks.ObjectTableSurveyAnalysisTask
3635
config:

pipelines/visitColumnValidate.yaml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,40 @@ tasks:
77
connections.outputName: visitTableColumnValidate
88
metrics.validPsfFluxMetric: ValidFracColumnMetric
99
metrics.validPsfFluxMetric.vectorKey: 'psfFlux'
10-
metrics.validPsfFluxMetric.applyContext: VisitContext
10+
metrics.validPsfFluxMetric.context: 'visit'
1111
metrics.validAp03FluxMetric: ValidFracColumnMetric
1212
metrics.validAp03FluxMetric.vectorKey: 'ap03Flux'
13-
metrics.validAp03FluxMetric.applyContext: VisitContext
13+
metrics.validAp03FluxMetric.context: 'visit'
1414
metrics.validAp06FluxMetric: ValidFracColumnMetric
1515
metrics.validAp06FluxMetric.vectorKey: 'ap06Flux'
16-
metrics.validAp06FluxMetric.applyContext: VisitContext
16+
metrics.validAp06FluxMetric.context: 'visit'
1717
metrics.validAp09FluxMetric: ValidFracColumnMetric
1818
metrics.validAp09FluxMetric.vectorKey: 'ap09Flux'
19-
metrics.validAp09FluxMetric.applyContext: VisitContext
19+
metrics.validAp09FluxMetric.context: 'visit'
2020
metrics.validAp12FluxMetric: ValidFracColumnMetric
2121
metrics.validAp12FluxMetric.vectorKey: 'ap12Flux'
22-
metrics.validAp12FluxMetric.applyContext: VisitContext
22+
metrics.validAp12FluxMetric.context: 'visit'
2323
metrics.validAp17FluxMetric: ValidFracColumnMetric
2424
metrics.validAp17FluxMetric.vectorKey: 'ap17Flux'
25-
metrics.validAp17FluxMetric.applyContext: VisitContext
25+
metrics.validAp17FluxMetric.context: 'visit'
2626
metrics.validAp25FluxMetric: ValidFracColumnMetric
2727
metrics.validAp25FluxMetric.vectorKey: 'ap25Flux'
28-
metrics.validAp25FluxMetric.applyContext: VisitContext
28+
metrics.validAp25FluxMetric.context: 'visit'
2929
metrics.validAp35FluxMetric: ValidFracColumnMetric
3030
metrics.validAp35FluxMetric.vectorKey: 'ap35Flux'
31-
metrics.validAp35FluxMetric.applyContext: VisitContext
31+
metrics.validAp35FluxMetric.context: 'visit'
3232
metrics.validAp50FluxMetric: ValidFracColumnMetric
3333
metrics.validAp50FluxMetric.vectorKey: 'ap50Flux'
34-
metrics.validAp50FluxMetric.applyContext: VisitContext
34+
metrics.validAp50FluxMetric.context: 'visit'
3535
metrics.validAp70FluxMetric: ValidFracColumnMetric
3636
metrics.validAp70FluxMetric.vectorKey: 'ap70Flux'
37-
metrics.validAp70FluxMetric.applyContext: VisitContext
37+
metrics.validAp70FluxMetric.context: 'visit'
3838
metrics.validCalibFluxMetric: ValidFracColumnMetric
3939
metrics.validCalibFluxMetric.vectorKey: 'calibFlux'
40-
metrics.validCalibFluxMetric.applyContext: VisitContext
40+
metrics.validCalibFluxMetric.context: 'visit'
4141
metrics.validGaussianFluxMetric: ValidFracColumnMetric
4242
metrics.validGaussianFluxMetric.vectorKey: 'gaussianFlux'
43-
metrics.validGaussianFluxMetric.applyContext: VisitContext
43+
metrics.validGaussianFluxMetric.context: 'visit'
4444
python: |
4545
from lsst.analysis.tools.analysisMetrics import *
4646
from lsst.analysis.tools.contexts import *

pipelines/visitQualityCore.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ tasks:
99
# metrics.name = AMetricsClass
1010
connections.outputName: sourceTableCore
1111
metrics.skyFluxVisitStatisticMetric: SkyFluxStatisticMetric
12-
metrics.skyFluxVisitStatisticMetric.applyContext: VisitContext
12+
metrics.skyFluxVisitStatisticMetric.context: "visit"
1313
plots.skySourceSkyPlot: SkySourceSkyPlot
1414
plots.skySourceHistPlot: SkySourceHistPlot
1515
python: |
1616
from lsst.analysis.tools.analysisPlots import *
1717
from lsst.analysis.tools.analysisMetrics import *
18-
from lsst.analysis.tools.contexts import *

python/lsst/analysis/tools/analysisMetrics/analysisMetrics.py

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
from ..actions.scalar import FracInRange, FracNan
3636
from ..actions.vector import LoadVector
37+
from ..analysisParts.coaddVisit import CoaddVisitConfig
3738
from ..analysisParts.stellarLocus import WPerpCModel, WPerpPSF, XPerpCModel, XPerpPSF, YPerpCModel, YPerpPSF
3839
from ..interfaces import AnalysisMetric
3940

@@ -102,33 +103,33 @@ def setDefaults(self):
102103
}
103104

104105

105-
class ValidFracColumnMetric(AnalysisMetric):
106+
class ValidFracColumnMetric(AnalysisMetric, CoaddVisitConfig):
106107
"""Calculate the fraction of values in a column that have valid
107108
numerical values (i.e., not NaN), and that fall within the specified
108109
"reasonable" range for the values.
109110
"""
110111

111112
vectorKey = Field[str](doc="Key of column to validate", default="psfFlux")
112113

113-
def visitContext(self) -> None:
114-
self.process.buildActions.loadVector = LoadVector()
115-
self.process.buildActions.loadVector.vectorKey = f"{self.vectorKey}"
116-
self._setActions(f"{self.vectorKey}")
117-
118-
def coaddContext(self) -> None:
119-
self.process.buildActions.loadVector = LoadVector()
120-
self.process.buildActions.loadVector.vectorKey = "{band}_" + f"{self.vectorKey}"
121-
self._setActions("{band}_" + f"{self.vectorKey}")
122-
123-
# Need to pass a mapping of new names so the default names get the
124-
# band prepended. Otherwise, each subsequent band's metric will
125-
# overwrite the current one.
126-
self.produce.newNames = {
127-
"validFracColumn": "{band}_validFracColumn",
128-
"nanFracColumn": "{band}_nanFracColumn",
129-
}
130-
131-
def _setActions(self, name: str) -> None:
114+
def _setActions(self) -> None:
115+
if self.context == "coadd":
116+
name = "{band}_" + f"{self.vectorKey}"
117+
self.process.buildActions.loadVector = LoadVector()
118+
self.process.buildActions.loadVector.vectorKey = "{band}_" + f"{self.vectorKey}"
119+
120+
# Need to pass a mapping of new names so the default names get the
121+
# band prepended. Otherwise, each subsequent band's metric will
122+
# overwrite the current one.
123+
self.produce.newNames = {
124+
"validFracColumn": "{band}_validFracColumn",
125+
"nanFracColumn": "{band}_nanFracColumn",
126+
}
127+
elif self.context == "visit":
128+
name = f"{self.vectorKey}"
129+
self.process.buildActions.loadVector = LoadVector()
130+
self.process.buildActions.loadVector.vectorKey = f"{self.vectorKey}"
131+
else:
132+
raise ValueError(f"Unsupported {self.context=}")
132133
# The default flux limits of 1e-1 < flux < 1e9 correspond to a
133134
# magnitude range of 34 < mag < 9 (i.e., reasonably well-measured)
134135
# objects should all be within this range).
@@ -150,3 +151,8 @@ def setDefaults(self):
150151
"validFracColumn": "percent",
151152
"nanFracColumn": "percent",
152153
}
154+
155+
def validate(self):
156+
super().validate()
157+
if not hasattr(self.process.buildActions, "loadVector"):
158+
self._setActions()

python/lsst/analysis/tools/analysisMetrics/skyFluxStatisticMetrics.py

Lines changed: 34 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,43 @@
2424

2525
from ..actions.scalar.scalarActions import MeanAction, MedianAction, SigmaMadAction, StdevAction
2626
from ..actions.vector.selectors import SkyObjectSelector, SkySourceSelector
27+
from ..analysisParts.coaddVisit import CoaddVisitConfig
2728
from ..interfaces import AnalysisMetric
2829

2930

30-
class SkyFluxStatisticMetric(AnalysisMetric):
31-
"""Calculate sky flux statistics. This uses the 9-pixel aperture flux for
32-
sky sources/objects, and returns multiple statistics on the measured
33-
fluxes. Note that either visitContext (measurement on sourceTable) or
34-
coaddContext (measurement on objectTable) must be specified.
31+
class SkyFluxStatisticMetric(AnalysisMetric, CoaddVisitConfig):
32+
"""Calculate sky flux statistics.
33+
34+
This uses the 9-pixel aperture flux for sky sources/objects, and returns
35+
multiple statistics on the measured fluxes. Note that self.context must be
36+
set to "visit" (for measurement on sourceTables) or "coadd"
37+
(for measurement on objectTables).
3538
"""
3639

3740
fluxType: str = "ap09Flux"
3841

39-
def visitContext(self) -> None:
40-
self.prep.selectors.skySourceSelector = SkySourceSelector()
41-
self._setActions(f"{self.fluxType}")
42-
43-
def coaddContext(self) -> None:
44-
self.prep.selectors.skyObjectSelector = SkyObjectSelector()
45-
self.prep.selectors.skyObjectSelector.bands = []
46-
self._setActions(f"{{band}}_{self.fluxType}")
42+
def _setActions(self) -> None:
43+
if self.context == "coadd":
44+
name = f"{{band}}_{self.fluxType}"
45+
self.prep.selectors.skyObjectSelector = SkyObjectSelector()
46+
self.prep.selectors.skyObjectSelector.bands = []
4747

48-
# Need to pass a mapping of new names so the default names get the
49-
# band prepended. Otherwise, each subsequent band's metric will
50-
# overwrite the current one (e.g., running with g, r bands without
51-
# this, you would get "meanSky," "meanSky"; with it: "g_meanSky,"
52-
# "r_meanSky").
53-
self.produce.newNames = {
54-
"medianSky": "{band}_medianSky",
55-
"meanSky": "{band}_meanSky",
56-
"stdevSky": "{band}_stdevSky",
57-
"sigmaMADSky": "{band}_sigmaMADSky",
58-
}
59-
60-
def _setActions(self, name: str) -> None:
48+
# Need to pass a mapping of new names so the default names get the
49+
# band prepended. Otherwise, each subsequent band's metric will
50+
# overwrite the current one (e.g., running with g, r bands without
51+
# this, you would get "meanSky," "meanSky"; with it: "g_meanSky,"
52+
# "r_meanSky").
53+
self.produce.newNames = {
54+
"medianSky": "{band}_medianSky",
55+
"meanSky": "{band}_meanSky",
56+
"stdevSky": "{band}_stdevSky",
57+
"sigmaMADSky": "{band}_sigmaMADSky",
58+
}
59+
elif self.context == "visit":
60+
name = f"{self.fluxType}"
61+
self.prep.selectors.skySourceSelector = SkySourceSelector()
62+
else:
63+
raise ValueError(f"Unsupported {self.context=}")
6164
self.process.calculateActions.medianSky = MedianAction(vectorKey=name)
6265
self.process.calculateActions.meanSky = MeanAction(vectorKey=name)
6366
self.process.calculateActions.stdevSky = StdevAction(vectorKey=name)
@@ -72,3 +75,8 @@ def setDefaults(self):
7275
"stdevSky": "nJy",
7376
"sigmaMADSky": "nJy",
7477
}
78+
79+
def validate(self):
80+
super().validate()
81+
if not hasattr(self.process.calculateActions, "medianSky"):
82+
self._setActions()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# This file is part of analysis_tools.
2+
#
3+
# Developed for the LSST Data Management System.
4+
# This product includes software developed by the LSST Project
5+
# (https://www.lsst.org).
6+
# See the COPYRIGHT file at the top-level directory of this distribution
7+
# for details of code ownership.
8+
#
9+
# This program is free software: you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation, either version 3 of the License, or
12+
# (at your option) any later version.
13+
#
14+
# This program is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
22+
from lsst.pex.config import ChoiceField, Config
23+
24+
__all__ = ("CoaddVisitConfig",)
25+
26+
27+
class CoaddVisitConfig(Config):
28+
"""Config for tools that can be applied in coadd and visit contexts."""
29+
30+
context = ChoiceField(
31+
doc="The analysis context for this class",
32+
dtype=str,
33+
allowed={"coadd": "Coadded images", "visit": "Single visit images"},
34+
optional=False,
35+
)

0 commit comments

Comments
 (0)