4141from . import measurePsf , repair , photoCal , computeExposureSummaryStats , snapCombine
4242
4343
44+ class _EmptyTargetTask (pipeBase .PipelineTask ):
45+ """
46+ This is a placeholder target for create_summary_metrics and must be retargeted at
47+ runtime. create_summary_metrics should target an analysis tool task, but that
48+ would, at the time of writing, result in a circular import.
49+
50+ As a result, this class should not be used for anything else.
51+ """
52+ ConfigClass = pipeBase .PipelineTaskConfig
53+
54+ def __init__ (self , ** kwargs ) -> None :
55+ raise NotImplementedError (
56+ "do_create_summary_metrics is set to True, in which "
57+ "case create_summary_metrics must be retargeted."
58+ )
59+
60+
4461class CalibrateImageConnections (pipeBase .PipelineTaskConnections ,
4562 dimensions = ("instrument" , "visit" , "detector" )):
4663
@@ -136,6 +153,11 @@ class CalibrateImageConnections(pipeBase.PipelineTaskConnections,
136153 storageClass = "Catalog" ,
137154 dimensions = ("instrument" , "visit" , "detector" ),
138155 )
156+ summary_metrics = connectionTypes .Output (
157+ name = "initial_summary_metrics" ,
158+ storageClass = "MetricMeasurementBundle" ,
159+ dimensions = ("instrument" , "visit" , "detector" ),
160+ )
139161
140162 def __init__ (self , * , config = None ):
141163 super ().__init__ (config = config )
@@ -147,6 +169,8 @@ def __init__(self, *, config=None):
147169 del self .astrometry_matches
148170 if config .optional_outputs is None or "photometry_matches" not in config .optional_outputs :
149171 del self .photometry_matches
172+ if not config .do_create_summary_metrics :
173+ del self .summary_metrics
150174
151175
152176class CalibrateImageConfig (pipeBase .PipelineTaskConfig , pipelineConnections = CalibrateImageConnections ):
@@ -259,6 +283,16 @@ class CalibrateImageConfig(pipeBase.PipelineTaskConfig, pipelineConnections=Cali
259283 target = computeExposureSummaryStats .ComputeExposureSummaryStatsTask ,
260284 doc = "Task to to compute summary statistics on the calibrated exposure."
261285 )
286+ do_create_summary_metrics = pexConfig .Field (
287+ dtype = bool ,
288+ default = False ,
289+ doc = "Run the subtask to create summary metrics, and then write those metrics."
290+ )
291+ create_summary_metrics = pexConfig .ConfigurableField (
292+ target = _EmptyTargetTask ,
293+ doc = "Subtask to create metrics from the summary stats. This must be retargeted, likely to an"
294+ "analysis_tools task such as CalexpSummaryMetrics."
295+ )
262296
263297 def setDefaults (self ):
264298 super ().setDefaults ()
@@ -411,6 +445,9 @@ def __init__(self, initial_stars_schema=None, **kwargs):
411445
412446 self .makeSubtask ("compute_summary_stats" )
413447
448+ if self .config .do_create_summary_metrics :
449+ self .makeSubtask ("create_summary_metrics" )
450+
414451 # For the butler to persist it.
415452 self .initial_stars_schema = afwTable .SourceCatalog (initial_stars_schema )
416453
@@ -543,7 +580,9 @@ def run(self, *, exposures, id_generator=None, result=None):
543580 result .photometry_matches = lsst .meas .astrom .denormalizeMatches (photometry_matches ,
544581 photometry_meta )
545582
546- self ._summarize (result .exposure , result .stars_footprints , result .background )
583+ result .summary_metrics = self ._summarize (result .exposure ,
584+ result .stars_footprints ,
585+ result .background )
547586
548587 return result
549588
@@ -856,3 +895,8 @@ def _summarize(self, exposure, stars, background):
856895 # applied calibration). This needs to be checked.
857896 summary = self .compute_summary_stats .run (exposure , stars , background )
858897 exposure .info .setSummaryStats (summary )
898+
899+ summaryMetrics = None
900+ if self .config .do_create_summary_metrics :
901+ summaryMetrics = self .create_summary_metrics .run (data = summary .__dict__ ).metrics
902+ return summaryMetrics
0 commit comments