Coverage for python/lsst/ap/verify/testPipeline.py: 48%

139 statements  

« prev     ^ index     » next       coverage.py v7.5.0, created at 2024-05-03 04:25 -0700

1# 

2# This file is part of ap_verify. 

3# 

4# Developed for the LSST Data Management System. 

5# This product includes software developed by the LSST Project 

6# (http://www.lsst.org). 

7# See the COPYRIGHT file at the top-level directory of this distribution 

8# for details of code ownership. 

9# 

10# This program is free software: you can redistribute it and/or modify 

11# it under the terms of the GNU General Public License as published by 

12# the Free Software Foundation, either version 3 of the License, or 

13# (at your option) any later version. 

14# 

15# This program is distributed in the hope that it will be useful, 

16# but WITHOUT ANY WARRANTY; without even the implied warranty of 

17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

18# GNU General Public License for more details. 

19# 

20# You should have received a copy of the GNU General Public License 

21# along with this program. If not, see <http://www.gnu.org/licenses/>. 

22# 

23 

24 

25# These classes exist only to be included in a mock pipeline, and don't need 

26# to be public for that. 

27__all__ = [] 

28 

29import astropy.table 

30import numpy as np 

31import pandas 

32 

33import lsst.geom as geom 

34import lsst.afw.image as afwImage 

35import lsst.afw.math as afwMath 

36import lsst.afw.table as afwTable 

37from lsst.ap.association import (TransformDiaSourceCatalogConfig, 

38 DiaPipelineConfig, FilterDiaSourceCatalogConfig) 

39from lsst.pipe.base import PipelineTask, Struct 

40from lsst.ip.isr import IsrTaskConfig 

41from lsst.ip.diffim import (GetTemplateConfig, AlardLuptonSubtractConfig, 

42 DetectAndMeasureConfig, SpatiallySampledMetricsConfig) 

43from lsst.pipe.tasks.characterizeImage import CharacterizeImageConfig 

44from lsst.pipe.tasks.calibrate import CalibrateConfig 

45from lsst.meas.transiNet import RBTransiNetConfig 

46 

47 

48class MockIsrTask(PipelineTask): 

49 """A do-nothing substitute for IsrTask. 

50 """ 

51 ConfigClass = IsrTaskConfig 

52 _DefaultName = "notIsr" 

53 

54 def run(self, ccdExposure, *, camera=None, bias=None, linearizer=None, 

55 crosstalk=None, crosstalkSources=None, 

56 dark=None, flat=None, ptc=None, bfKernel=None, bfGains=None, defects=None, 

57 fringes=Struct(fringes=None), opticsTransmission=None, filterTransmission=None, 

58 sensorTransmission=None, atmosphereTransmission=None, 

59 detectorNum=None, strayLightData=None, illumMaskedImage=None, 

60 deferredCharge=None, 

61 ): 

62 """Accept ISR inputs, and produce ISR outputs with no processing. 

63 

64 Parameters 

65 ---------- 

66 ccdExposure : `lsst.afw.image.Exposure` 

67 The raw exposure that is to be run through ISR. The 

68 exposure is modified by this method. 

69 camera : `lsst.afw.cameraGeom.Camera`, optional 

70 The camera geometry for this exposure. Required if 

71 one or more of ``ccdExposure``, ``bias``, ``dark``, or 

72 ``flat`` does not have an associated detector. 

73 bias : `lsst.afw.image.Exposure`, optional 

74 Bias calibration frame. 

75 linearizer : `lsst.ip.isr.linearize.LinearizeBase`, optional 

76 Functor for linearization. 

77 crosstalk : `lsst.ip.isr.crosstalk.CrosstalkCalib`, optional 

78 Calibration for crosstalk. 

79 crosstalkSources : `list`, optional 

80 List of possible crosstalk sources. 

81 dark : `lsst.afw.image.Exposure`, optional 

82 Dark calibration frame. 

83 flat : `lsst.afw.image.Exposure`, optional 

84 Flat calibration frame. 

85 ptc : `lsst.ip.isr.PhotonTransferCurveDataset`, optional 

86 Photon transfer curve dataset, with, e.g., gains 

87 and read noise. 

88 bfKernel : `numpy.ndarray`, optional 

89 Brighter-fatter kernel. 

90 bfGains : `dict` of `float`, optional 

91 Gains used to override the detector's nominal gains for the 

92 brighter-fatter correction. A dict keyed by amplifier name for 

93 the detector in question. 

94 defects : `lsst.ip.isr.Defects`, optional 

95 List of defects. 

96 fringes : `lsst.pipe.base.Struct`, optional 

97 Struct containing the fringe correction data, with 

98 elements: 

99 - ``fringes``: fringe calibration frame (`afw.image.Exposure`) 

100 - ``seed``: random seed derived from the ccdExposureId for random 

101 number generator (`uint32`) 

102 opticsTransmission: `lsst.afw.image.TransmissionCurve`, optional 

103 A ``TransmissionCurve`` that represents the throughput of the 

104 optics, to be evaluated in focal-plane coordinates. 

105 filterTransmission : `lsst.afw.image.TransmissionCurve` 

106 A ``TransmissionCurve`` that represents the throughput of the 

107 filter itself, to be evaluated in focal-plane coordinates. 

108 sensorTransmission : `lsst.afw.image.TransmissionCurve` 

109 A ``TransmissionCurve`` that represents the throughput of the 

110 sensor itself, to be evaluated in post-assembly trimmed detector 

111 coordinates. 

112 atmosphereTransmission : `lsst.afw.image.TransmissionCurve` 

113 A ``TransmissionCurve`` that represents the throughput of the 

114 atmosphere, assumed to be spatially constant. 

115 detectorNum : `int`, optional 

116 The integer number for the detector to process. 

117 isGen3 : bool, optional 

118 Flag this call to run() as using the Gen3 butler environment. 

119 strayLightData : `object`, optional 

120 Opaque object containing calibration information for stray-light 

121 correction. If `None`, no correction will be performed. 

122 illumMaskedImage : `lsst.afw.image.MaskedImage`, optional 

123 Illumination correction image. 

124 

125 Returns 

126 ------- 

127 result : `lsst.pipe.base.Struct` 

128 Result struct with components: 

129 

130 ``exposure`` 

131 The fully ISR corrected exposure (`afw.image.Exposure`). 

132 ``outputExposure`` 

133 An alias for ``exposure`` (`afw.image.Exposure`). 

134 ``ossThumb`` 

135 Thumbnail image of the exposure after overscan subtraction 

136 (`numpy.ndarray`). 

137 ``flattenedThumb`` 

138 Thumbnail image of the exposure after flat-field correction 

139 (`numpy.ndarray`). 

140 - ``outputStatistics`` : mapping [`str`] 

141 Values of the additional statistics calculated. 

142 """ 

143 return Struct(exposure=afwImage.ExposureF(), 

144 outputExposure=afwImage.ExposureF(), 

145 ossThumb=np.empty((1, 1)), 

146 flattenedThumb=np.empty((1, 1)), 

147 preInterpExposure=afwImage.ExposureF(), 

148 outputOssThumbnail=np.empty((1, 1)), 

149 outputFlattenedThumbnail=np.empty((1, 1)), 

150 outputStatistics={}, 

151 ) 

152 

153 

154class MockCharacterizeImageTask(PipelineTask): 

155 """A do-nothing substitute for CharacterizeImageTask. 

156 """ 

157 ConfigClass = CharacterizeImageConfig 

158 _DefaultName = "notCharacterizeImage" 

159 

160 def __init__(self, refObjLoader=None, schema=None, **kwargs): 

161 super().__init__(**kwargs) 

162 self.outputSchema = afwTable.SourceCatalog() 

163 

164 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

165 inputs = butlerQC.get(inputRefs) 

166 if 'idGenerator' not in inputs.keys(): 

167 inputs['idGenerator'] = self.config.idGenerator.apply(butlerQC.quantum.dataId) 

168 outputs = self.run(**inputs) 

169 butlerQC.put(outputs, outputRefs) 

170 

171 def run(self, exposure, background=None, idGenerator=None): 

172 """Produce characterization outputs with no processing. 

173 

174 Parameters 

175 ---------- 

176 exposure : `lsst.afw.image.Exposure` 

177 Exposure to characterize. 

178 background : `lsst.afw.math.BackgroundList`, optional 

179 Initial model of background already subtracted from exposure. 

180 idGenerator : `lsst.meas.base.IdGenerator`, optional 

181 Object that generates source IDs and provides random number 

182 generator seeds. 

183 

184 Returns 

185 ------- 

186 result : `lsst.pipe.base.Struct` 

187 Struct containing these fields: 

188 

189 ``characterized`` 

190 Characterized exposure (`lsst.afw.image.Exposure`). 

191 ``sourceCat`` 

192 Detected sources (`lsst.afw.table.SourceCatalog`). 

193 ``backgroundModel`` 

194 Model of background subtracted from exposure (`lsst.afw.math.BackgroundList`) 

195 ``psfCellSet`` 

196 Spatial cells of PSF candidates (`lsst.afw.math.SpatialCellSet`) 

197 """ 

198 # Can't persist empty BackgroundList; DM-33714 

199 bg = afwMath.BackgroundMI(geom.Box2I(geom.Point2I(0, 0), geom.Point2I(16, 16)), 

200 afwImage.MaskedImageF(16, 16)) 

201 return Struct(characterized=exposure, 

202 sourceCat=afwTable.SourceCatalog(), 

203 backgroundModel=afwMath.BackgroundList(bg), 

204 psfCellSet=afwMath.SpatialCellSet(exposure.getBBox(), 10), 

205 ) 

206 

207 

208class MockCalibrateTask(PipelineTask): 

209 """A do-nothing substitute for CalibrateTask. 

210 """ 

211 ConfigClass = CalibrateConfig 

212 _DefaultName = "notCalibrate" 

213 

214 def __init__(self, astromRefObjLoader=None, 

215 photoRefObjLoader=None, icSourceSchema=None, 

216 initInputs=None, **kwargs): 

217 super().__init__(**kwargs) 

218 self.outputSchema = afwTable.SourceCatalog() 

219 

220 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

221 inputs = butlerQC.get(inputRefs) 

222 inputs['idGenerator'] = self.config.idGenerator.apply(butlerQC.quantum.dataId) 

223 

224 if self.config.doAstrometry: 

225 inputs.pop('astromRefCat') 

226 if self.config.doPhotoCal: 

227 inputs.pop('photoRefCat') 

228 

229 outputs = self.run(**inputs) 

230 

231 if self.config.doWriteMatches and self.config.doAstrometry: 

232 normalizedMatches = afwTable.packMatches(outputs.astromMatches) 

233 if self.config.doWriteMatchesDenormalized: 

234 # Just need an empty BaseCatalog with a valid schema. 

235 outputs.matchesDenormalized = afwTable.BaseCatalog(outputs.outputCat.schema) 

236 outputs.matches = normalizedMatches 

237 butlerQC.put(outputs, outputRefs) 

238 

239 def run(self, exposure, background=None, 

240 icSourceCat=None, idGenerator=None): 

241 """Produce calibration outputs with no processing. 

242 

243 Parameters 

244 ---------- 

245 exposure : `lsst.afw.image.Exposure` 

246 Exposure to calibrate. 

247 background : `lsst.afw.math.BackgroundList`, optional 

248 Background model already subtracted from exposure. 

249 icSourceCat : `lsst.afw.table.SourceCatalog`, optional 

250 A SourceCatalog from CharacterizeImageTask from which we can copy some fields. 

251 idGenerator : `lsst.meas.base.IdGenerator`, optional 

252 Object that generates source IDs and provides random number 

253 generator seeds. 

254 

255 Returns 

256 ------- 

257 result : `lsst.pipe.base.Struct` 

258 Struct containing these fields: 

259 

260 ``outputExposure`` 

261 Calibrated science exposure with refined WCS and PhotoCalib 

262 (`lsst.afw.image.Exposure`). 

263 ``outputBackground`` 

264 Model of background subtracted from exposure 

265 (`lsst.afw.math.BackgroundList`). 

266 ``outputCat`` 

267 Catalog of measured sources (`lsst.afw.table.SourceCatalog`). 

268 ``astromMatches`` 

269 List of source/refObj matches from the astrometry solver 

270 (`list` [`lsst.afw.table.ReferenceMatch`]). 

271 """ 

272 # Can't persist empty BackgroundList; DM-33714 

273 bg = afwMath.BackgroundMI(geom.Box2I(geom.Point2I(0, 0), geom.Point2I(16, 16)), 

274 afwImage.MaskedImageF(16, 16)) 

275 return Struct(outputExposure=exposure, 

276 outputBackground=afwMath.BackgroundList(bg), 

277 outputCat=afwTable.SourceCatalog(), 

278 astromMatches=[], 

279 ) 

280 

281 

282class MockGetTemplateTask(PipelineTask): 

283 """A do-nothing substitute for GetTemplateTask. 

284 """ 

285 ConfigClass = GetTemplateConfig 

286 _DefaultName = "notGetTemplate" 

287 

288 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

289 inputs = butlerQC.get(inputRefs) 

290 # Mock GetTemplateTask.getOverlappingExposures 

291 results = Struct(coaddExposures=[], 

292 dataIds=[], 

293 ) 

294 inputs["coaddExposures"] = results.coaddExposures 

295 inputs["dataIds"] = results.dataIds 

296 outputs = self.run(**inputs) 

297 butlerQC.put(outputs, outputRefs) 

298 

299 def run(self, coaddExposures, bbox, wcs, dataIds, **kwargs): 

300 """Warp coadds from multiple tracts to form a template for image diff. 

301 

302 Where the tracts overlap, the resulting template image is averaged. 

303 The PSF on the template is created by combining the CoaddPsf on each 

304 template image into a meta-CoaddPsf. 

305 

306 Parameters 

307 ---------- 

308 coaddExposures : `list` of `lsst.afw.image.Exposure` 

309 Coadds to be mosaicked 

310 bbox : `lsst.geom.Box2I` 

311 Template Bounding box of the detector geometry onto which to 

312 resample the coaddExposures 

313 wcs : `lsst.afw.geom.SkyWcs` 

314 Template WCS onto which to resample the coaddExposures 

315 dataIds : `list` of `lsst.daf.butler.DataCoordinate` 

316 Record of the tract and patch of each coaddExposure. 

317 **kwargs 

318 Any additional keyword parameters. 

319 

320 Returns 

321 ------- 

322 result : `lsst.pipe.base.Struct` containing 

323 - ``template`` : a template coadd exposure assembled out of patches 

324 """ 

325 return Struct(template=afwImage.ExposureF(), 

326 ) 

327 

328 

329class MockAlardLuptonSubtractTask(PipelineTask): 

330 """A do-nothing substitute for AlardLuptonSubtractTask. 

331 """ 

332 ConfigClass = AlardLuptonSubtractConfig 

333 _DefaultName = "notAlardLuptonSubtract" 

334 

335 def run(self, template, science, sources, finalizedPsfApCorrCatalog=None, visitSummary=None): 

336 """PSF match, subtract, and decorrelate two images. 

337 

338 Parameters 

339 ---------- 

340 template : `lsst.afw.image.ExposureF` 

341 Template exposure, warped to match the science exposure. 

342 science : `lsst.afw.image.ExposureF` 

343 Science exposure to subtract from the template. 

344 sources : `lsst.afw.table.SourceCatalog` 

345 Identified sources on the science exposure. This catalog is used to 

346 select sources in order to perform the AL PSF matching on stamp 

347 images around them. 

348 finalizedPsfApCorrCatalog : `lsst.afw.table.ExposureCatalog`, optional 

349 Exposure catalog with finalized psf models and aperture correction 

350 maps to be applied if config.doApplyFinalizedPsf=True. Catalog 

351 uses the detector id for the catalog id, sorted on id for fast 

352 lookup. Deprecated in favor of ``visitSummary``, and will be 

353 removed after v26. 

354 visitSummary : `lsst.afw.table.ExposureCatalog`, optional 

355 Exposure catalog with external calibrations to be applied. Catalog 

356 uses the detector id for the catalog id, sorted on id for fast 

357 lookup. Ignored (for temporary backwards compatibility) if 

358 ``finalizedPsfApCorrCatalog`` is provided. 

359 

360 Returns 

361 ------- 

362 results : `lsst.pipe.base.Struct` 

363 ``difference`` : `lsst.afw.image.ExposureF` 

364 Result of subtracting template and science. 

365 ``matchedTemplate`` : `lsst.afw.image.ExposureF` 

366 Warped and PSF-matched template exposure. 

367 ``backgroundModel`` : `lsst.afw.math.Function2D` 

368 Background model that was fit while solving for the 

369 PSF-matching kernel 

370 ``psfMatchingKernel`` : `lsst.afw.math.Kernel` 

371 Kernel used to PSF-match the convolved image. 

372 """ 

373 return Struct(difference=afwImage.ExposureF(), 

374 matchedTemplate=afwImage.ExposureF(), 

375 backgroundModel=afwMath.NullFunction2D(), 

376 psfMatchingKernel=afwMath.FixedKernel(), 

377 ) 

378 

379 

380class MockDetectAndMeasureConfig(DetectAndMeasureConfig): 

381 

382 def setDefaults(self): 

383 super().setDefaults() 

384 # Avoid delegating to lsst.obs.base.Instrument specialization for the 

385 # data ID packing algorithm to use, since test code often does not use a 

386 # real Instrument in its data IDs. 

387 self.idGenerator.packer.name = "observation" 

388 

389 

390class MockDetectAndMeasureTask(PipelineTask): 

391 """A do-nothing substitute for DetectAndMeasureTask. 

392 """ 

393 ConfigClass = MockDetectAndMeasureConfig 

394 _DefaultName = "notDetectAndMeasure" 

395 

396 def __init__(self, **kwargs): 

397 super().__init__(**kwargs) 

398 self.outputSchema = afwTable.SourceCatalog() 

399 

400 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

401 inputs = butlerQC.get(inputRefs) 

402 idFactory = afwTable.IdFactory.makeSimple() 

403 

404 outputs = self.run(inputs['science'], 

405 inputs['matchedTemplate'], 

406 inputs['difference'], 

407 idFactory=idFactory) 

408 butlerQC.put(outputs, outputRefs) 

409 

410 def run(self, science, matchedTemplate, difference, 

411 idFactory=None): 

412 """Detect and measure sources on a difference image. 

413 

414 Parameters 

415 ---------- 

416 science : `lsst.afw.image.ExposureF` 

417 Science exposure that the template was subtracted from. 

418 matchedTemplate : `lsst.afw.image.ExposureF` 

419 Warped and PSF-matched template that was used produce the 

420 difference image. 

421 difference : `lsst.afw.image.ExposureF` 

422 Result of subtracting template from the science image. 

423 idFactory : `lsst.afw.table.IdFactory`, optional 

424 Generator object to assign ids to detected sources in the difference image. 

425 

426 Returns 

427 ------- 

428 results : `lsst.pipe.base.Struct` 

429 ``subtractedMeasuredExposure`` : `lsst.afw.image.ExposureF` 

430 Subtracted exposure with detection mask applied. 

431 ``diaSources`` : `lsst.afw.table.SourceCatalog` 

432 The catalog of detected sources. 

433 """ 

434 return Struct(subtractedMeasuredExposure=difference, 

435 diaSources=afwTable.SourceCatalog(), 

436 ) 

437 

438 

439class MockFilterDiaSourceCatalogTask(PipelineTask): 

440 """A do-nothing substitute for FilterDiaSourceCatalogTask. 

441 """ 

442 ConfigClass = FilterDiaSourceCatalogConfig 

443 _DefaultName = "notFilterDiaSourceCatalog" 

444 

445 def run(self, diaSourceCat): 

446 """Produce filtering outputs with no processing. 

447 

448 Parameters 

449 ---------- 

450 diaSourceCat : `lsst.afw.table.SourceCatalog` 

451 Catalog of sources measured on the difference image. 

452 

453 Returns 

454 ------- 

455 results : `lsst.pipe.base.Struct` 

456 Results struct with components. 

457 """ 

458 return Struct(filteredDiaSourceCat=afwTable.SourceCatalog(), 

459 rejectedDiaSources=afwTable.SourceCatalog(), 

460 ) 

461 

462 

463class MockSpatiallySampledMetricsTask(PipelineTask): 

464 """A do-nothing substitute for SpatiallySampledMetricsTask. 

465 """ 

466 ConfigClass = SpatiallySampledMetricsConfig 

467 _DefaultName = "notSpatiallySampledMetricsTask" 

468 

469 def run(self, science, matchedTemplate, template, difference, diaSources): 

470 """Produce spatially sampled metrics 

471 

472 Parameters 

473 ---------- 

474 science : `lsst.afw.image.ExposureF` 

475 Science exposure that the template was subtracted from. 

476 matchedTemplate : `lsst.afw.image.ExposureF` 

477 Warped and PSF-matched template that was used produce the 

478 difference image. 

479 template : `lsst.afw.image.ExposureF` 

480 Warped and non PSF-matched template that was used to produce 

481 the difference image. 

482 difference : `lsst.afw.image.ExposureF` 

483 Result of subtracting template from the science image. 

484 diaSources : `lsst.afw.table.SourceCatalog` 

485 The catalog of detected sources. 

486 

487 Returns 

488 ------- 

489 results : `lsst.pipe.base.Struct` 

490 Results struct with components. 

491 """ 

492 

493 return Struct(spatiallySampledMetrics=astropy.table.Table()) 

494 

495 

496class MockRBTransiNetTask(PipelineTask): 

497 """A do-nothing substitute for RBTransiNetTask. 

498 """ 

499 _DefaultName = "notRbTransiNet" 

500 ConfigClass = RBTransiNetConfig 

501 

502 def run(self, template, science, difference, diaSources, pretrainedModel=None): 

503 return Struct(classifications=afwTable.BaseCatalog(afwTable.Schema())) 

504 

505 

506class MockTransformDiaSourceCatalogTask(PipelineTask): 

507 """A do-nothing substitute for TransformDiaSourceCatalogTask. 

508 """ 

509 ConfigClass = TransformDiaSourceCatalogConfig 

510 _DefaultName = "notTransformDiaSourceCatalog" 

511 

512 def __init__(self, initInputs, **kwargs): 

513 super().__init__(**kwargs) 

514 

515 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

516 inputs = butlerQC.get(inputRefs) 

517 idGenerator = self.config.idGenerator.apply(butlerQC.quantum.dataId) 

518 inputs["ccdVisitId"] = idGenerator.catalog_id 

519 inputs["band"] = butlerQC.quantum.dataId["band"] 

520 

521 outputs = self.run(**inputs) 

522 

523 butlerQC.put(outputs, outputRefs) 

524 

525 def run(self, diaSourceCat, diffIm, band, ccdVisitId, funcs=None): 

526 """Produce transformation outputs with no processing. 

527 

528 Parameters 

529 ---------- 

530 diaSourceCat : `lsst.afw.table.SourceCatalog` 

531 The catalog to transform. 

532 diffIm : `lsst.afw.image.Exposure` 

533 An image, to provide supplementary information. 

534 band : `str` 

535 The band in which the sources were observed. 

536 ccdVisitId : `int` 

537 The exposure ID in which the sources were observed. 

538 funcs, optional 

539 Unused. 

540 

541 Returns 

542 ------- 

543 results : `lsst.pipe.base.Struct` 

544 Results struct with components: 

545 

546 ``diaSourceTable`` 

547 Catalog of DiaSources (`pandas.DataFrame`). 

548 """ 

549 return Struct(diaSourceTable=pandas.DataFrame(), 

550 ) 

551 

552 

553class MockDiaPipelineConfig(DiaPipelineConfig): 

554 

555 def setDefaults(self): 

556 super().setDefaults() 

557 # Avoid delegating to lsst.obs.base.Instrument specialization for the 

558 # data ID packing algorithm to use, since test code often does not use a 

559 # real Instrument in its data IDs. 

560 self.idGenerator.packer.name = "observation" 

561 

562 

563class MockDiaPipelineTask(PipelineTask): 

564 """A do-nothing substitute for DiaPipelineTask. 

565 """ 

566 ConfigClass = MockDiaPipelineConfig 

567 _DefaultName = "notDiaPipe" 

568 

569 def runQuantum(self, butlerQC, inputRefs, outputRefs): 

570 inputs = butlerQC.get(inputRefs) 

571 inputs["idGenerator"] = self.config.idGenerator.apply(butlerQC.quantum.dataId) 

572 # Need to set ccdExposureIdBits (now deprecated) to None and pass it, 

573 # since there are non-optional positional arguments after it. 

574 inputs["ccdExposureIdBits"] = None 

575 inputs["band"] = butlerQC.quantum.dataId["band"] 

576 if not self.config.doSolarSystemAssociation: 

577 inputs["solarSystemObjectTable"] = None 

578 

579 outputs = self.run(**inputs) 

580 

581 butlerQC.put(outputs, outputRefs) 

582 

583 def run(self, 

584 diaSourceTable, 

585 solarSystemObjectTable, 

586 diffIm, 

587 exposure, 

588 template, 

589 ccdExposureIdBits, 

590 band, 

591 idGenerator=None): 

592 """Produce DiaSource and DiaObject outputs with no processing. 

593 

594 Parameters 

595 ---------- 

596 diaSourceTable : `pandas.DataFrame` 

597 Newly detected DiaSources. 

598 solarSystemObjectTable : `pandas.DataFrame` 

599 Expected solar system objects in the field of view. 

600 diffIm : `lsst.afw.image.ExposureF` 

601 Difference image exposure in which the sources in ``diaSourceCat`` 

602 were detected. 

603 exposure : `lsst.afw.image.ExposureF` 

604 Calibrated exposure differenced with a template to create 

605 ``diffIm``. 

606 template : `lsst.afw.image.ExposureF` 

607 Template exposure used to create diffIm. 

608 ccdExposureIdBits : `int` 

609 Number of bits used for a unique ``ccdVisitId``. Deprecated in 

610 favor of ``idGenerator``, and ignored if that is present. Pass 

611 `None` explicitly to avoid a deprecation warning (a default is 

612 impossible given that later positional arguments are not 

613 defaulted). 

614 band : `str` 

615 The band in which the new DiaSources were detected. 

616 idGenerator : `lsst.meas.base.IdGenerator`, optional 

617 Object that generates source IDs and random number generator seeds. 

618 Will be required after ``ccdExposureIdBits`` is removed. 

619 

620 Returns 

621 ------- 

622 results : `lsst.pipe.base.Struct` 

623 Results struct with components: 

624 

625 ``apdbMarker`` 

626 Marker dataset to store in the Butler indicating that this 

627 ccdVisit has completed successfully (`lsst.dax.apdb.ApdbConfig`). 

628 ``associatedDiaSources`` 

629 Catalog of newly associated DiaSources (`pandas.DataFrame`). 

630 """ 

631 return Struct(apdbMarker=self.config.apdb.value, 

632 associatedDiaSources=pandas.DataFrame(), 

633 diaForcedSources=pandas.DataFrame(), 

634 diaObjects=pandas.DataFrame(), 

635 longTrailedSources=pandas.DataFrame(), 

636 )