35 """Config for MakeDiscreteSkyMapTask
37 coaddName = pexConfig.Field(
38 doc=
"coadd name, e.g. deep, goodSeeing, chiSquared",
42 skyMap = pexConfig.ConfigField(
43 dtype=BaseSkyMap.ConfigClass,
44 doc=
"SkyMap configuration parameters, excluding position and radius"
46 borderSize = pexConfig.Field(
47 doc=
"additional border added to the bounding box of the calexps, in degrees",
51 doAppend = pexConfig.Field(
52 doc=
"append another tract to an existing DiscreteSkyMap on disk, if present?",
56 doWrite = pexConfig.Field(
57 doc=
"persist the skyMap?",
63 self.skyMap.tractOverlap = 0.0
67 """Run a task with all dataRefs at once, rather than one dataRef at a time.
69 Call the run method of the task using two positional arguments:
71 - dataRefList: list of all dataRefs,
75 return [(parsedCmd.butler, parsedCmd.id.refList)]
79 @param args Arguments for Task.run()
82 - None if self.doReturnResults false
83 - A pipe_base Struct containing these fields if self.doReturnResults true:
84 - dataRef: the provided data reference
85 - metadata: task metadata after execution of run
86 - result: result returned by task run, or None if the task fails
88 butler, dataRefList = args
89 task = self.TaskClass(config=self.config, log=self.log)
92 result = task.run(butler, dataRefList)
95 result = task.run(butler, dataRefList)
96 except Exception
as e:
97 task.log.fatal(
"Failed: %s" % e)
98 if not isinstance(e, pipeBase.TaskError):
99 traceback.print_exc(file=sys.stderr)
100 for dataRef
in dataRefList:
101 task.writeMetadata(dataRef)
103 if self.doReturnResults:
104 return pipeBase.Struct(
105 dataRefList=dataRefList,
106 metadata=task.metadata,
112 """!Make a DiscreteSkyMap in a repository, using the bounding box of a set of calexps.
114 The command-line and run signatures and config are sufficiently different from MakeSkyMapTask
115 that we don't inherit from it, but it is a replacement, so we use the same config/metadata names.
117 ConfigClass = MakeDiscreteSkyMapConfig
118 _DefaultName =
"makeDiscreteSkyMap"
119 RunnerClass = MakeDiscreteSkyMapRunner
122 pipeBase.CmdLineTask.__init__(self, **kwargs)
125 def run(self, butler, dataRefList):
126 """!Make a skymap from the bounds of the given set of calexps.
128 @param[in] butler data butler used to save the SkyMap
129 @param[in] dataRefList dataRefs of calexps used to determine the size and pointing of the SkyMap
130 @return a pipeBase Struct containing:
131 - skyMap: the constructed SkyMap
133 self.log.info(
"Extracting bounding boxes of %d images" % len(dataRefList))
135 for dataRef
in dataRefList:
136 if not dataRef.datasetExists(
"calexp"):
137 self.log.warn(
"CalExp for %s does not exist: ignoring" % (dataRef.dataId,))
139 md = dataRef.get(
"calexp_md", immediate=
True)
144 points.extend(tuple(wcs.pixelToSky(corner).getVector())
for corner
in boxD.getCorners())
146 raise RuntimeError(
"No data found from which to compute convex hull")
147 self.log.info(
"Computing spherical convex hull")
148 polygon = lsst.geom.convexHull(points)
151 "Failed to compute convex hull of the vertices of all calexp bounding boxes; "
152 "they may not be hemispherical."
154 circle = polygon.getBoundingCircle()
156 datasetName = self.config.coaddName +
"Coadd_skyMap"
158 skyMapConfig = DiscreteSkyMap.ConfigClass()
159 if self.config.doAppend
and butler.datasetExists(datasetName):
160 oldSkyMap = butler.get(datasetName, immediate=
True)
161 if not isinstance(oldSkyMap.config, DiscreteSkyMap.ConfigClass):
162 raise TypeError(
"Cannot append to existing non-discrete skymap")
164 if not self.config.skyMap.compare(oldSkyMap.config, output=compareLog.append):
165 raise ValueError(
"Cannot append to existing skymap - configurations differ:", *compareLog)
166 skyMapConfig.raList.extend(oldSkyMap.config.raList)
167 skyMapConfig.decList.extend(oldSkyMap.config.decList)
168 skyMapConfig.radiusList.extend(oldSkyMap.config.radiusList)
169 skyMapConfig.update(**self.config.skyMap.toDict())
170 skyMapConfig.raList.append(circle.center[0])
171 skyMapConfig.decList.append(circle.center[1])
172 skyMapConfig.radiusList.append(circle.radius + self.config.borderSize)
173 skyMap = DiscreteSkyMap(skyMapConfig)
175 for tractInfo
in skyMap:
176 wcs = tractInfo.getWcs()
184 skyPosList = [wcs.pixelToSky(pos).getPosition(afwGeom.degrees)
for pos
in pixelPosList]
185 posStrList = [
"(%0.3f, %0.3f)" % tuple(skyPos)
for skyPos
in skyPosList]
186 self.log.info(
"tract %s has corners %s (RA, Dec deg) and %s x %s patches" %
187 (tractInfo.getId(),
", ".join(posStrList),
188 tractInfo.getNumPatches()[0], tractInfo.getNumPatches()[1]))
189 if self.config.doWrite:
190 butler.put(skyMap, datasetName)
191 return pipeBase.Struct(
196 """Return None to disable saving config
198 There's only one SkyMap per repository, so the config is redundant, and checking it means we can't
199 easily overwrite or append to an existing repository.
204 """Return None to disable saving metadata
206 The metadata is not interesting, and by not saving it we can eliminate a dataset type.
212 parser = ArgumentParser(name=cls._DefaultName)
213 parser.add_id_argument(name=
"--id", datasetType=
"calexp", help=
"data ID, e.g. --id visit=123 ccd=1,2")
An integer coordinate rectangle.
boost::shared_ptr< Wcs > makeWcs(coord::Coord const &crval, geom::Point2D const &crpix, double CD11, double CD12, double CD21, double CD22)
Create a Wcs object from crval, crpix, CD, using CD elements (useful from python) ...
def run
Make a skymap from the bounds of the given set of calexps.
A floating-point coordinate rectangle geometry.
Make a DiscreteSkyMap in a repository, using the bounding box of a set of calexps.