23 """Load a full reference catalog in numpy/table/dataframe format. 
   25 This task will load multi-band reference objects, apply a reference selector, 
   26 and apply color terms. 
   29 from astropy 
import units
 
   41 __all__ = [
'LoadReferenceCatalogConfig', 
'LoadReferenceCatalogTask']
 
   45     """Config for LoadReferenceCatalogTask""" 
   46     refObjLoader = pexConfig.ConfigurableField(
 
   47         target=LoadIndexedReferenceObjectsTask,
 
   48         doc=
"Reference object loader for photometry",
 
   50     doApplyColorTerms = pexConfig.Field(
 
   51         doc=(
"Apply photometric color terms to reference stars? " 
   52              "Requires that colorterms be set to a ColorTermLibrary"),
 
   56     colorterms = pexConfig.ConfigField(
 
   57         doc=
"Library of photometric reference catalog name to color term dict.",
 
   58         dtype=ColortermLibrary,
 
   60     referenceSelector = pexConfig.ConfigurableField(
 
   61         target=ReferenceSourceSelectorTask,
 
   62         doc=
"Selection of reference sources",
 
   64     doReferenceSelection = pexConfig.Field(
 
   65         doc=
"Run the reference selector on the reference catalog?",
 
   73             msg = 
"applyColorTerms=True requires the `colorterms` field be set to a ColortermLibrary." 
   74             raise pexConfig.FieldValidationError(LoadReferenceCatalogConfig.colorterms, self, msg)
 
   78     """Load multi-band reference objects from a reference catalog. 
   82     dataIds : iterable of `lsst.daf.butler.dataId`, optional 
   83         An iterable object of dataIds which point to reference catalogs 
   84         in a Gen3 repository.  Required for Gen3. 
   85     refCats : iterable of `lsst.daf.butler.DeferredDatasetHandle`, optional 
   86         An iterable object of dataset refs for reference catalogs in 
   87         a Gen3 repository.  Required for Gen3. 
   88     butler : `lsst.daf.persistence.Butler`, optional 
   89         A Gen2 butler.  Required for Gen2. 
   91     ConfigClass = LoadReferenceCatalogConfig
 
   92     _DefaultName = 
"loadReferenceCatalog" 
   94     def __init__(self, dataIds=None, refCats=None, butler=None, **kwargs):
 
   95         if dataIds 
is not None and refCats 
is not None:
 
   96             pipeBase.Task.__init__(self, **kwargs)
 
   97             refConfig = self.config.refObjLoader
 
  102         elif butler 
is not None:
 
  103             raise RuntimeError(
"LoadReferenceCatalogTask does not support Gen2 Butlers.")
 
  105             raise RuntimeError(
"Must instantiate LoadReferenceCatalogTask with " 
  106                                "dataIds and refCats (Gen3)")
 
  108         if self.config.doReferenceSelection:
 
  109             self.makeSubtask(
'referenceSelector')
 
  115                            bboxToSpherePadding=None):
 
  116         """Get a multi-band reference catalog by specifying a bounding box and WCS. 
  118         The catalog will be in `numpy.ndarray`, with positions proper-motion 
  119         corrected to "epoch" (if specified, and if the reference catalog has 
  120         proper motions); sources cut on a reference selector (if 
  121         "config.doReferenceSelection = True"); and color-terms applied (if 
  122         "config.doApplyColorTerms = True"). 
  124         The format of the reference catalog will be of the format: 
  126         dtype = [('ra', 'np.float64'), 
  127                  ('dec', 'np.float64'), 
  128                  ('refMag', 'np.float32', (len(filterList), )), 
  129                  ('refMagErr', 'np.float32', (len(filterList), ))] 
  131         Reference magnitudes (AB) and errors will be 99 for non-detections 
  136         bbox : `lsst.geom.Box2I` 
  137             Box which bounds a region in pixel space. 
  138         wcs : `lsst.afw.geom.SkyWcs` 
  139             Wcs object defining the pixel to sky (and reverse) transform for 
  141         filterList : `List` [ `str` ] 
  142             List of camera physicalFilter names to retrieve magnitudes. 
  143         epoch : `astropy.time.Time`, optional 
  144             Epoch to which to correct proper motion and parallax 
  145             (if available), or `None` to not apply such corrections. 
  146         bboxToSpherePadding : `int`, optional 
  147             Padding to account for translating a set of corners into a 
  148             spherical (convex) boundary that is certain to encompass the 
  149             entire area covered by the bbox. 
  153         refCat : `numpy.ndarray` 
  158             center = wcs.pixelToSky(bbox.getCenter())
 
  163                                                 bboxToSpherePadding=bboxToSpherePadding)
 
  165         if not skyBox.refCat.isContiguous():
 
  166             refCat = skyBox.refCat.copy(deep=
True)
 
  168             refCat = skyBox.refCat
 
  173                             catalogFormat='numpy'):
 
  174         """Get a multi-band reference catalog by specifying a center and radius. 
  176         The catalog will be in `numpy.ndarray`, with positions proper-motion 
  177         corrected to "epoch" (if specified, and if the reference catalog has 
  178         proper motions); sources cut on a reference selector (if 
  179         "config.doReferenceSelection = True"); and color-terms applied (if 
  180         "config.doApplyColorTerms = True"). 
  182         The format of the reference catalog will be of the format: 
  184         dtype = [('ra', 'np.float64'), 
  185                  ('dec', 'np.float64'), 
  186                  ('refMag', 'np.float32', (len(filterList), )), 
  187                  ('refMagErr', 'np.float32', (len(filterList), ))] 
  189         Reference magnitudes (AB) and errors will be 99 for non-detections 
  194         center : `lsst.geom.SpherePoint` 
  195             Point defining the center of the circular region. 
  196         radius : `lsst.geom.Angle` 
  197             Defines the angular radius of the circular region. 
  198         filterList : `List` [ `str` ] 
  199             List of camera physicalFilter names to retrieve magnitudes. 
  200         epoch : `astropy.time.Time`, optional 
  201             Epoch to which to correct proper motion and parallax 
  202             (if available), or `None` to not apply such corrections. 
  206         refCat : `numpy.ndarray` 
  213         skyCircle = self.
refObjLoaderrefObjLoader.loadSkyCircle(center, radius,
 
  217         if not skyCircle.refCat.isContiguous():
 
  218             refCat = skyCircle.refCat.copy(deep=
True)
 
  220             refCat = skyCircle.refCat
 
  224     def _formatCatalog(self, refCat, filterList):
 
  225         """Format a reference afw table into the final format. 
  227         This method applies reference selections and color terms as specified 
  232         refCat : `lsst.afw.table.SourceCatalog` 
  233             Reference catalog in afw format. 
  234         filterList : `list` [`str`] 
  235             List of camera physicalFilter names to apply color terms. 
  239         refCat : `numpy.ndarray` 
  242         if self.config.doReferenceSelection:
 
  243             goodSources = self.referenceSelector.selectSources(refCat)
 
  244             selected = goodSources.selected
 
  246             selected = np.ones(len(refCat), dtype=bool)
 
  248         npRefCat = np.zeros(np.sum(selected), dtype=[(
'ra', 
'f8'),
 
  250                                                      (
'refMag', 
'f4', (len(filterList), )),
 
  251                                                      (
'refMagErr', 
'f4', (len(filterList), ))])
 
  253         if npRefCat.size == 0:
 
  260         npRefCat[
'ra'] = np.rad2deg(refCat[
'coord_ra'][selected])
 
  261         npRefCat[
'dec'] = np.rad2deg(refCat[
'coord_dec'][selected])
 
  264         npRefCat[
'refMag'][:, :] = 99.0
 
  265         npRefCat[
'refMagErr'][:, :] = 99.0
 
  267         if self.config.doApplyColorTerms:
 
  268             if isinstance(self.
refObjLoaderrefObjLoader, ReferenceObjectLoader):
 
  270                 refCatName = self.
refObjLoaderrefObjLoader.config.value.ref_dataset_name
 
  273                 refCatName = self.
refObjLoaderrefObjLoader.ref_dataset_name
 
  276                 if fluxField 
is None:
 
  280                 self.log.
debug(
"Applying color terms for filterName='%s'", filterName)
 
  282                 colorterm = self.config.colorterms.getColorterm(filterName, refCatName, doRaise=
True)
 
  284                 refMag, refMagErr = colorterm.getCorrectedMagnitudes(refCat)
 
  290                 good, = np.where((np.nan_to_num(refMag[selected], nan=99.0) < 90.0)
 
  291                                  & (np.nan_to_num(refMagErr[selected], nan=99.0) < 90.0)
 
  292                                  & (np.nan_to_num(refMagErr[selected]) > 0.0))
 
  294                 npRefCat[
'refMag'][good, i] = refMag[selected][good]
 
  295                 npRefCat[
'refMagErr'][good, i] = refMagErr[selected][good]
 
  301                 good, = np.where((np.nan_to_num(refCat[fluxField][selected]) > 0.0)
 
  302                                  & (np.nan_to_num(refCat[fluxField+
'Err'][selected]) > 0.0))
 
  303                 refMag = (refCat[fluxField][selected][good]*units.nJy).to_value(units.ABmag)
 
  305                                                 refCat[fluxField][selected][good])
 
  306                 npRefCat[
'refMag'][good, i] = refMag
 
  307                 npRefCat[
'refMagErr'][good, i] = refMagErr
 
  311     def _determineFluxFields(self, center, filterList):
 
  312         """Determine the flux field names for a reference catalog. 
  314         This method sets self._fluxFields, self._referenceFilter. 
  318         center : `lsst.geom.SpherePoint` 
  319             The center around which to load test sources. 
  320         filterList : `list` [`str`] 
  321             List of camera physicalFilter names. 
  325         foundReferenceFilter = 
False 
  331         configIntersection = {k: getattr(self.
refObjLoaderrefObjLoader.config, k)
 
  333                               if (k 
in configTemp.keys() 
and k != 
"connections")}
 
  335         configIntersection[
'requireProperMotion'] = 
False 
  336         configTemp.update(**configIntersection)
 
  340         for filterName 
in filterList:
 
  341             if self.config.refObjLoader.anyFilterMapsToThis 
is not None:
 
  342                 refFilterName = self.config.refObjLoader.anyFilterMapsToThis
 
  344                 refFilterName = self.config.refObjLoader.filterMap.get(filterName)
 
  345             if refFilterName 
is None:
 
  348                 results = self.
refObjLoaderrefObjLoader.loadSkyCircle(center,
 
  349                                                           0.05*lsst.geom.degrees,
 
  351                 foundReferenceFilter = 
True 
  354             except RuntimeError 
as err:
 
  357                 if 'not find flux' in err.args[0]:
 
  366         if not foundReferenceFilter:
 
  367             raise RuntimeError(
"Could not find any valid flux field(s) %s" %
 
  368                                (
", ".join(filterList)))
 
  375         for filterName 
in filterList:
 
  378             if self.config.refObjLoader.anyFilterMapsToThis 
is not None:
 
  379                 refFilterName = self.config.refObjLoader.anyFilterMapsToThis
 
  381                 refFilterName = self.config.refObjLoader.filterMap.get(filterName)
 
  383             if refFilterName 
is not None:
 
  385                     fluxField = 
getRefFluxField(results.refCat.schema, filterName=refFilterName)
 
  390             if fluxField 
is None:
 
  391                 self.log.
warning(
'No reference flux field for camera filter %s', filterName)
 
std::vector< SchemaItem< Flag > > * items
def getPixelBoxCatalog(self, bbox, wcs, filterList, epoch=None, bboxToSpherePadding=None)
def __init__(self, dataIds=None, refCats=None, butler=None, **kwargs)
def _determineFluxFields(self, center, filterList)
def _formatCatalog(self, refCat, filterList)
def getSkyCircleCatalog(self, center, radius, filterList, epoch=None, catalogFormat='numpy')
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
Backwards-compatibility support for depersisting the old Calib (FluxMag0/FluxMag0Err) objects.
double abMagErrFromFluxErr(double fluxErr, double flux)
Compute AB magnitude error from flux and flux error in Janskys.
def getRefFluxField(schema, filterName=None)
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations.