Skip to content

Commit

Permalink
Add loadSkyCircle abstract method to LoadReferenceObjectsTask
Browse files Browse the repository at this point in the history
LoadReferenceObjectsTask enhancements:
- Added a new abstract method loadSkyCircle
- Renamed loadObjectsInBBox to loadPixelBox (to focus on sky vs pixel space)
- Provided a default implementation of loadPixelBox that calls loadSkyCircle
Updated tests/testLoadReferenceObjects.py accordingly

Add a missing method to LoadReferenceObjectsTask
  • Loading branch information
r-owen committed Apr 16, 2015
1 parent 35b5ff9 commit 5ed6720
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 5 deletions.
69 changes: 66 additions & 3 deletions python/lsst/meas/algorithms/loadReferenceObjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import numpy

import lsst.afw.table as afwTable
import lsst.afw.geom as afwGeom
import lsst.pex.config as pexConfig
import lsst.pipe.base as pipeBase

Expand Down Expand Up @@ -96,7 +97,7 @@ class LoadReferenceObjectsTask(pipeBase.Task):
Abstract base class for tasks that load objects from a reference catalog
in a particular region of the sky.
Implementations must subclass this class, override the loadObjectsInBBox method,
Implementations must subclass this class, override the loadSkyCircle method,
and will typically override the value of ConfigClass with a task-specific config class.
@section meas_algorithms_loadReferenceObjects_Initialize Task initialisation
Expand Down Expand Up @@ -139,8 +140,8 @@ class LoadReferenceObjectsTask(pipeBase.Task):
ConfigClass = LoadReferenceObjectsConfig
_DefaultName = "LoadReferenceObjects"

@abc.abstractmethod
def loadObjectsInBBox(self, bbox, wcs, filterName=None, calib=None):
@pipeBase.timeMethod
def loadPixelBox(self, bbox, wcs, filterName=None, calib=None):
"""!Load reference objects that overlap a pixel-based rectangular region
The search algorith works by searching in a region in sky coordinates whose center is the center
Expand All @@ -154,8 +155,70 @@ def loadObjectsInBBox(self, bbox, wcs, filterName=None, calib=None):
@return a catalog of reference objects using the standard schema (see the class doc string)
"""
# compute on-sky center and radius of search region, for loadSkyCircle
bbox = afwGeom.Box2D(bbox) # make sure bbox is double and that we have a copy
bbox.grow(self.config.pixelMargin)
ctrCoord = wcs.pixelToSky(bbox.getCenter())
maxRadius = afwGeom.Angle(0)
for pixPt in bbox.getCorners():
coord = wcs.pixelToSky(pixPt)
rad = ctrCoord.angularSeparation(coord)
maxRadius = max(rad, maxRadius)
del rad

# find objects in circle
self.log.info("getting reference objects using center %s pix = %s sky and radius %s" %
(bbox.getCenter(), ctrCoord, maxRadius))
loadRes = self.loadSkyCircle(ctrCoord, maxRadius, filterName)
refCat = loadRes.refCat
numFound = len(refCat)

# trim objects outside bbox
refCat = self._trimToBBox(refCat=refCat, bbox=bbox, wcs=wcs)
numTrimmed = numFound - len(refCat)
self.log.info("trimmed %d out-of-bbox objects, leaving %d" % (numTrimmed, len(refCat)))

loadRes.refCat = refCat # should be a no-op, but just in case
return loadRes

@abc.abstractmethod
def loadSkyCircle(self, ctrCoord, radius, filterName=None):
"""!Load reference objects that overlap a circular sky region
@param[in] ctrCoord center of search region (an lsst.afw.geom.Coord)
@param[in] radius radius of search region (an lsst.afw.geom.Angle)
@param[in] filterName name of filter, or None for the default filter;
used for flux values in case we have flux limits (which are not yet implemented)
@return an lsst.pipe.base.Struct containing:
- refCat a catalog of reference objects with the
\link meas_algorithms_loadReferenceObjects_Schema standard schema \endlink
as documented in LoadReferenceObjects, including photometric, resolved and variable;
hasCentroid is False for all objects.
- fluxField = name of flux field for specified filterName
"""
return

@staticmethod
def _trimToBBox(refCat, bbox, wcs):
"""!Remove objects outside a given pixel-based bbox and set centroid and hasCentroid fields
@param[in] refCat a catalog of objects (an lsst.afw.table.SimpleCatalog,
or other table type that supports getCoord() on records)
@param[in] bbox pixel region (an afwImage.Box2D)
@param[in] wcs WCS used to convert sky position to pixel position (an lsst.afw.math.WCS)
@return a catalog of reference objects in bbox, with centroid and hasCentroid fields set
"""
retStarCat = type(refCat)(refCat.table)
for star in refCat:
point = wcs.skyToPixel(star.getCoord())
if bbox.contains(point):
star.set("centroid", point)
star.set("hasCentroid", True)
retStarCat.append(star)
return retStarCat

def _addFluxAliases(self, schema):
"""Add aliases for camera filter fluxes to the schema
Expand Down
4 changes: 2 additions & 2 deletions tests/testLoadReferenceObjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@
class TrivialLoader(LoadReferenceObjectsTask):
"""Minimal subclass of LoadReferenceObjectsTask to allow instantiation
"""
def loadObjectsInBBox(self, bbox, wcs, filterName=None, calib=None):
def loadSkyCircle(self, ctrCoord, radius, filterName):
pass

class TestLoadReferenceObjects(unittest.TestCase):
"""Test case for LoadReferenceObjectsTask abstract base class
Only methods with concrete implementations are tested (hence not loadObjectsInBBox)
Only methods with concrete implementations are tested (hence not loadSkyCircle)
"""
def testMakeMinimalSchema(self):
"""Make a schema and check it
Expand Down

0 comments on commit 5ed6720

Please sign in to comment.