270 Fill the visit catalog with visit metadata
274 visitCat : `afw.table.BaseCatalog`
275 Visit catalog. See _makeFgcmVisitSchema() for schema definition.
276 groupedHandles : `dict` [`list` [`lsst.daf.butler.DeferredDatasetHandle`]]
277 Dataset handles, grouped by visit.
281 for i, visit
in enumerate(sorted(groupedHandles)):
282 if (i % self.config.nVisitsPerCheckpoint) == 0:
283 self.log.info(
"Retrieving metadata for visit %d (%d/%d)", visit, i, len(groupedHandles))
285 handle = groupedHandles[visit][0]
286 summary = handle.get()
288 summaryRow = summary.find(self.config.referenceCCD)
289 if summaryRow
is None:
291 summaryRow = summary[0]
293 visitInfo = summaryRow.getVisitInfo()
294 physicalFilter = summaryRow[
'physical_filter']
296 goodSigma, = np.where(summary[
'psfSigma'] > 0)
297 if goodSigma.size > 2:
298 psfSigma = np.median(summary[
'psfSigma'][goodSigma])
299 elif goodSigma.size > 0:
300 psfSigma = summary[
'psfSigma'][goodSigma[0]]
302 self.log.warning(
"Could not find any good summary psfSigma for visit %d", visit)
305 goodBackground, = np.where(np.nan_to_num(summary[
'skyBg']) > 0.0)
306 if goodBackground.size > 2:
307 skyBackground = np.median(summary[
'skyBg'][goodBackground])
308 elif goodBackground.size > 0:
309 skyBackground = summary[
'skyBg'][goodBackground[0]]
311 self.log.warning(
'Could not find any good summary skyBg for visit %d', visit)
316 rec[
'physicalFilter'] = physicalFilter
318 radec = visitInfo.getBoresightRaDec()
319 rec[
'telra'] = radec.getRa().asDegrees()
320 rec[
'teldec'] = radec.getDec().asDegrees()
321 rec[
'telha'] = visitInfo.getBoresightHourAngle().asDegrees()
322 rec[
'telrot'] = visitInfo.getBoresightRotAngle().asDegrees()
323 rec[
'mjd'] = visitInfo.getDate().get(system=DateTime.MJD)
324 rec[
'exptime'] = visitInfo.getExposureTime()
327 rec[
'pmb'] = visitInfo.getWeather().getAirPressure() / 100
331 rec[
'scaling'][:] = 1.0
333 rec[
'deltaAper'] = 0.0
334 rec[
'psfSigma'] = psfSigma
335 rec[
'skyBackground'] = skyBackground
340 Make a schema mapper for fgcm sources
344 sourceSchema: `afwTable.Schema`
345 Default source schema from the butler
349 sourceMapper: `afwTable.schemaMapper`
350 Mapper to the FGCM source schema
357 sourceMapper.addMapping(sourceSchema[
'coord_ra'].asKey(),
'ra')
358 sourceMapper.addMapping(sourceSchema[
'coord_dec'].asKey(),
'dec')
359 sourceMapper.addMapping(sourceSchema[
'slot_Centroid_x'].asKey(),
'x')
360 sourceMapper.addMapping(sourceSchema[
'slot_Centroid_y'].asKey(),
'y')
366 sourceMapper.addMapping(sourceSchema[self.config.psfCandidateName].asKey(),
369 sourceMapper.editOutputSchema().addField(
370 "psf_candidate", type=
'Flag',
371 doc=(
"Flag set if the source was a candidate for PSF determination, "
372 "as determined by the star selector."))
375 sourceMapper.editOutputSchema().addField(
376 "visit", type=np.int64, doc=
"Visit number")
377 sourceMapper.editOutputSchema().addField(
378 "ccd", type=np.int32, doc=
"CCD number")
379 sourceMapper.editOutputSchema().addField(
380 "instMag", type=np.float32, doc=
"Instrumental magnitude")
381 sourceMapper.editOutputSchema().addField(
382 "instMagErr", type=np.float32, doc=
"Instrumental magnitude error")
383 sourceMapper.editOutputSchema().addField(
384 "jacobian", type=np.float32, doc=
"Relative pixel scale from wcs jacobian")
385 sourceMapper.editOutputSchema().addField(
386 "deltaMagBkg", type=np.float32, doc=
"Change in magnitude due to local background offset")
387 sourceMapper.editOutputSchema().addField(
388 "deltaMagAper", type=np.float32, doc=
"Change in magnitude from larger to smaller aperture")
394 Use FGCM code to match observations into unique stars.
398 visitCat: `afw.table.BaseCatalog`
399 Catalog with visit data for fgcm
400 obsCat: `afw.table.BaseCatalog`
401 Full catalog of star observations for fgcm
402 lutHandle: `lsst.daf.butler.DeferredDatasetHandle`, optional
403 Data reference to fgcm look-up table (used if matching reference stars).
407 fgcmStarIdCat: `afw.table.BaseCatalog`
408 Catalog of unique star identifiers and index keys
409 fgcmStarIndicesCat: `afwTable.BaseCatalog`
410 Catalog of unique star indices
411 fgcmRefCat: `afw.table.BaseCatalog`
412 Catalog of matched reference stars.
413 Will be None if `config.doReferenceMatches` is False.
417 visitFilterNames = np.zeros(len(visitCat), dtype=
'a30')
418 for i
in range(len(visitCat)):
419 visitFilterNames[i] = visitCat[i][
'physicalFilter']
422 visitIndex = np.searchsorted(visitCat[
'visit'],
425 obsFilterNames = visitFilterNames[visitIndex]
427 if self.config.doReferenceMatches:
429 lutCat = lutHandle.get()
431 stdFilterDict = {filterName: stdFilter
for (filterName, stdFilter)
in
432 zip(lutCat[0][
'physicalFilters'].split(
','),
433 lutCat[0][
'stdPhysicalFilters'].split(
','))}
434 stdLambdaDict = {stdFilter: stdLambda
for (stdFilter, stdLambda)
in
435 zip(lutCat[0][
'stdPhysicalFilters'].split(
','),
436 lutCat[0][
'lambdaStdFilter'])}
443 self.log.info(
"Using the following reference filters: %s" %
444 (
', '.join(referenceFilterNames)))
448 referenceFilterNames = []
451 starConfig = {
'logger': self.log,
453 'filterToBand': self.config.physicalFilterMap,
454 'requiredBands': self.config.requiredBands,
455 'minPerBand': self.config.minPerBand,
456 'matchRadius': self.config.matchRadius,
457 'isolationRadius': self.config.isolationRadius,
458 'matchNSide': self.config.matchNside,
459 'coarseNSide': self.config.coarseNside,
460 'densNSide': self.config.densityCutNside,
461 'densMaxPerPixel': self.config.densityCutMaxPerPixel,
462 'randomSeed': self.config.randomSeed,
463 'primaryBands': self.config.primaryBands,
464 'referenceFilterNames': referenceFilterNames}
467 fgcmMakeStars = fgcm.FgcmMakeStars(starConfig)
475 conv = obsCat[0][
'ra'].asDegrees() / float(obsCat[0][
'ra'])
476 fgcmMakeStars.makePrimaryStars(obsCat[
'ra'] * conv,
477 obsCat[
'dec'] * conv,
478 filterNameArray=obsFilterNames,
482 fgcmMakeStars.makeMatchedStars(obsCat[
'ra'] * conv,
483 obsCat[
'dec'] * conv,
486 if self.config.doReferenceMatches:
495 fgcmStarIdCat.reserve(fgcmMakeStars.objIndexCat.size)
496 for i
in range(fgcmMakeStars.objIndexCat.size):
497 fgcmStarIdCat.addNew()
500 fgcmStarIdCat[
'fgcm_id'][:] = fgcmMakeStars.objIndexCat[
'fgcm_id']
501 fgcmStarIdCat[
'ra'][:] = fgcmMakeStars.objIndexCat[
'ra']
502 fgcmStarIdCat[
'dec'][:] = fgcmMakeStars.objIndexCat[
'dec']
503 fgcmStarIdCat[
'obsArrIndex'][:] = fgcmMakeStars.objIndexCat[
'obsarrindex']
504 fgcmStarIdCat[
'nObs'][:] = fgcmMakeStars.objIndexCat[
'nobs']
509 fgcmStarIndicesCat.reserve(fgcmMakeStars.obsIndexCat.size)
510 for i
in range(fgcmMakeStars.obsIndexCat.size):
511 fgcmStarIndicesCat.addNew()
513 fgcmStarIndicesCat[
'obsIndex'][:] = fgcmMakeStars.obsIndexCat[
'obsindex']
515 if self.config.doReferenceMatches:
519 fgcmRefCat.reserve(fgcmMakeStars.referenceCat.size)
521 for i
in range(fgcmMakeStars.referenceCat.size):
524 fgcmRefCat[
'fgcm_id'][:] = fgcmMakeStars.referenceCat[
'fgcm_id']
525 fgcmRefCat[
'refMag'][:, :] = fgcmMakeStars.referenceCat[
'refMag']
526 fgcmRefCat[
'refMagErr'][:, :] = fgcmMakeStars.referenceCat[
'refMagErr']
529 md.set(
"REFSTARS_FORMAT_VERSION", REFSTARS_FORMAT_VERSION)
530 md.set(
"FILTERNAMES", referenceFilterNames)
531 fgcmRefCat.setMetadata(md)
536 return fgcmStarIdCat, fgcmStarIndicesCat, fgcmRefCat