1 from builtins
import range
32 from .mockObject
import MockObjectTask
33 from .mockObservation
import MockObservationTask
34 from .mockSelect
import MockSelectImagesTask
38 makeSkyMap = lsst.pex.config.ConfigurableField(
39 doc=
"SkyMap builder subtask",
42 mockObject = lsst.pex.config.ConfigurableField(
43 doc=
"Subtask that generates and draws the objects/sources in the mock images",
46 mockObservation = lsst.pex.config.ConfigurableField(
47 doc=
"Subtask that generates the Wcs, Psf, Calib, etc. of mock images",
48 target=MockObservationTask
50 coaddName = lsst.pex.config.Field(
51 doc=
"Coadd name used as a prefix for other datasets",
56 nObservations = lsst.pex.config.Field(
57 doc=
"Number of mock observations to generate.",
62 edgeBuffer = lsst.pex.config.Field(
63 doc=(
"Number of pixels by which to grow object bounding boxes when determining whether they land "
64 " completely on a generated image"),
70 def setupSkyMapPatches(self, nPatches=2, patchSize=400, pixelScale=0.2*lsst.afw.geom.arcseconds):
72 Set the nested [discrete] skymap config parameters such that the full tract
73 has nPatches x nPatches patches of the given size and pixel scale.
75 self.makeSkyMap.skyMap[
'discrete'].patchInnerDimensions = [patchSize, patchSize]
76 self.makeSkyMap.skyMap[
'discrete'].pixelScale = pixelScale.asArcseconds()
79 radius = (0.5 * nPatches - 0.49) * patchSize * pixelScale.asDegrees()
80 self.makeSkyMap.skyMap[
'discrete'].radiusList = [radius]
83 self.makeSkyMap.skyMap.name =
'discrete'
84 self.makeSkyMap.skyMap[
'discrete'].raList = [90.0]
85 self.makeSkyMap.skyMap[
'discrete'].decList = [0.0]
86 self.makeSkyMap.skyMap[
'discrete'].patchBorder = 10
87 self.makeSkyMap.skyMap[
'discrete'].projection =
"TAN"
88 self.makeSkyMap.skyMap[
'discrete'].tractOverlap = 0.0
93 """MockCoaddTask is a driver task for creating mock coadds. As opposed to more realistic
94 simulations, MockCoadd generates and uses extremely simple "toy" data that can be used to more
95 rigorously test the behavior of high-level task code because the expected results are
96 more easily predicted. In particular, calexps are generated directly from the truth catalog,
97 and contain only zero-noise stars that are created using the same Psf, Calib, and Wcs that will
98 be attached to the mock calexp.
100 In addition to creating the mock calexps and truth catalogs, MockCoadd also contains driver
101 code to run the MakeSkyMap, MakeCoaddTempExp, and AssembleCoadd tasks on the mock calexps,
102 and code to directly create a mock coadd image using CoaddPsf, which can be compared to the
103 output of the regular coadd tasks to check that the coadd code and CoaddPsf are consistent.
105 Note that aside from MakeSkyMapTask, the coadd tasks are *not* subtasks of MockCoaddTasks,
106 and their configs are not part of MockCoaddConfig; these are created locally within
107 MockCoaddTask methods when needed, as not all coadd task config options are appropriate
108 for the mock data generated by MockCoadd.
111 ConfigClass = MockCoaddConfig
113 _DefaultName =
"MockCoadd"
116 """Construct a MockCoaddTask and the subtasks used for generating skymaps, objects,
117 and observations (i.e. calexp parameters).
119 lsst.pipe.base.CmdLineTask.__init__(self, **kwds)
120 self.makeSubtask(
"makeSkyMap")
121 self.makeSubtask(
"mockObject")
122 self.makeSubtask(
"mockObservation")
124 self.
objectIdKey = self.schema.addField(
"objectId", type=
"L", doc=
"foreign key to truth catalog")
126 doc=
"foreign key to observation catalog")
128 "centroidInBBox", type=
"Flag",
129 doc=
"set if this source's center position is inside the generated image's bbox"
132 "partialOverlap", type=
"Flag",
133 doc=
"set if this source was not completely inside the generated image"
137 """Build the skymap for the mock dataset."""
138 return self.makeSkyMap.run(butler.dataRef(self.config.coaddName +
"Coadd_skyMap")).skyMap
141 """Create and save (if butler is not None) a truth catalog containing all the mock objects.
143 Must be run after buildSkyMap.
145 Most of the work is delegated to the mockObject subtask.
148 skyMap = butler.get(self.config.coaddName +
"Coadd_skyMap")
149 catalog = self.mockObject.run(tractInfo=skyMap[tract])
150 if butler
is not None:
151 butler.put(catalog,
"truth", tract=tract)
155 """Create and save (if butler is not None) an ExposureCatalog of simulated observations,
156 containing the Psfs, Wcss, Calibs, etc. of the calexps to be simulated.
158 Must be run after buildSkyMap.
160 Most of the work is delegated to the mockObservation subtask.
163 skyMap = butler.get(self.config.coaddName +
"Coadd_skyMap")
165 camera = butler.get(
"camera")
166 catalog = self.mockObservation.run(butler=butler,
167 n=self.config.nObservations, camera=camera,
168 tractInfo=skyMap[tract])
169 if butler
is not None:
170 butler.put(catalog,
"observations", tract=tract)
174 """Use the truth catalog and observation catalog to create and save (if butler is not None)
175 mock calexps and an ExposureCatalog ('simsrc') that contains information about which objects
176 appear partially or fully in each exposure.
178 Must be run after buildTruthCatalog and buildObservationCatalog.
180 if obsCatalog
is None:
181 obsCatalog = butler.get(
"observations", tract=tract)
182 if truthCatalog
is None:
183 truthCatalog = butler.get(
"truth", tract=tract)
184 ccdKey = obsCatalog.getSchema().find(
"ccd").key
185 visitKey = obsCatalog.getSchema().find(
"visit").key
187 for obsRecord
in obsCatalog:
188 ccd = obsRecord.getI(ccdKey)
189 visit = obsRecord.getI(visitKey)
190 self.log.info(
"Generating image for visit={visit}, ccd={ccd}".
format(ccd=ccd, visit=visit))
191 exposure = lsst.afw.image.ExposureF(obsRecord.getBBox())
192 exposure.setCalib(obsRecord.getCalib())
193 exposure.setWcs(obsRecord.getWcs())
194 exposure.setPsf(obsRecord.getPsf())
195 exposure.getInfo().setApCorrMap(obsRecord.getApCorrMap())
196 for truthRecord
in truthCatalog:
197 status = self.mockObject.drawSource(truthRecord, exposure, buffer=self.config.edgeBuffer)
199 simSrcRecord = simSrcCatalog.addNew()
200 simSrcRecord.setCoord(truthRecord.getCoord())
201 simSrcRecord.setL(self.
objectIdKey, truthRecord.getId())
203 simSrcRecord.setFlag(self.
centroidInBBoxKey, obsRecord.contains(truthRecord.getCoord()))
205 self.log.info(
" added object {id}".
format(id=truthRecord.getId()))
206 exposure.getMaskedImage().getVariance().set(1.0)
207 if butler
is not None:
208 butler.put(exposure,
"calexp", ccd=ccd, visit=visit)
209 if butler
is not None:
210 butler.put(simSrcCatalog,
"simsrc", tract=tract)
214 """Convenience function that calls buildSkyMap, buildObservationCatalog, buildTruthCatalog,
215 and buildInputImages.
220 simSrcCatalog = self.
buildInputImages(butler, obsCatalog=observations, truthCatalog=truth)
223 """Helper function to create a Coadd task with configuration appropriate for the simulations.
225 MockCoaddTask does not include MakeCoaddTempExpTask or AssembleCoaddTask as subtasks, because
226 we want explicit control over their configs, rather than leaving this up to the user.
227 However, we have to install our own SelectImages task for both of these, so it made sense
228 to have a single method that would create one of these two tasks, set the config values we
229 want, and install the custom SelectImagesTask.
231 config = cls.ConfigClass()
232 config.coaddName = self.config.coaddName
233 config.select.retarget(MockSelectImagesTask)
234 if cls == MakeCoaddTempExpTask:
235 config.bgSubtracted =
True
236 config.doPsfMatch =
False
237 elif cls == AssembleCoaddTask:
238 config.doMatchBackgrounds =
False
242 """Generator that iterates over the patches in a tract, yielding dataRefs.
244 nPatchX, nPatchY = tractInfo.getNumPatches()
245 for iPatchX
in range(nPatchX):
246 for iPatchY
in range(nPatchY):
247 patchRef = butler.dataRef(self.config.coaddName +
"Coadd",
248 tract=tractInfo.getId(), patch=
"%d,%d" % (iPatchX, iPatchY),
253 """Run the coadd tasks (MakeCoaddTempExp and AssembleCoadd) on the mock data.
255 Must be run after buildInputImages.
258 skyMap = butler.get(self.config.coaddName +
"Coadd_skyMap")
259 tractInfo = skyMap[tract]
260 makeCoaddTempExpTask = self.
makeCoaddTask(MakeCoaddTempExpTask)
263 makeCoaddTempExpTask.run(patchRef)
265 assembleCoaddTask.run(patchRef)
268 """Directly create a simulation of the coadd, using the CoaddPsf of the coadd exposure
269 and the truth catalog.
271 Must be run after buildCoadd.
273 if truthCatalog
is None:
274 truthCatalog = butler.get(
"truth", tract=tract)
276 skyMap = butler.get(self.config.coaddName +
"Coadd_skyMap")
277 tractInfo = skyMap[tract]
278 tractWcs = tractInfo.getWcs()
280 exposure = patchRef.get(self.config.coaddName +
"Coadd")
281 exposure.getMaskedImage().getImage().set(0.0)
283 exposure.getInfo().getCoaddInputs().ccds, exposure.getWcs()
285 exposure.setPsf(coaddPsf)
286 for truthRecord
in truthCatalog:
287 self.mockObject.drawSource(truthRecord, exposure, buffer=0)
288 patchRef.put(exposure, self.config.coaddName +
"Coadd_mock")
292 """Convenience function to create and run MockCoaddTask with default settings.
294 from .simpleMapper
import makeDataRepo
297 task.buildAllInputs(butler)
298 task.buildCoadd(butler)
299 task.buildMockCoadd(butler)
static Schema makeMinimalSchema()
Return a minimal schema for Simple tables and records.
def buildObservationCatalog
Custom catalog class for record/table subclasses that are guaranteed to have an ID, and should generally be sorted by that ID.
CoaddPsf is the Psf derived to be used for non-PSF-matched Coadd images.