Skip to content

Commit

Permalink
Add properties, patch and cell wcs access, and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
erykoff committed Oct 30, 2021
1 parent 738047e commit c80cdd5
Show file tree
Hide file tree
Showing 10 changed files with 443 additions and 39 deletions.
1 change: 1 addition & 0 deletions python/lsst/skymap/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
from .discreteSkyMap import *
from .skyMapRegistry import *
from .version import *
from .detail import makeSkyPolygonFromBBox
52 changes: 45 additions & 7 deletions python/lsst/skymap/cellInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ class CellInfo():
Inner bounding box.
outerBBox : `lsst.geom.Box2I`
Outer bounding box.
sequentialIndex : `int`
Cell sequential index.
tractWcs : `lsst.afw.geom.SkyWcs`
Tract WCS object.
"""
def __init__(self, index, innerBBox, outerBBox):
def __init__(self, index, innerBBox, outerBBox, sequentialIndex, tractWcs):
self._index = index
self._sequentialIndex = sequentialIndex
self._innerBBox = innerBBox
self._outerBBox = outerBBox
self._wcs = tractWcs
if not outerBBox.contains(innerBBox):
raise RuntimeError("outerBBox=%s does not contain innerBBox=%s" % (outerBBox, innerBBox))

Expand All @@ -56,6 +62,32 @@ def getIndex(self):
"""
return self._index

index = property(getIndex, None)

def getSequentialIndex(self):
"""Return cell sequential index.
Returns
-------
result : `int`
Sequential cell index.
"""
return self._sequentialIndex

sequentialIndex = property(getSequentialIndex, None)

def getWcs(self):
"""Return the associated tract wcs
Returns
-------
wcs : `lsst.afw.geom.SkyWcs`
Tract WCS.
"""
return self._wcs

wcs = property(getWcs, None)

def getInnerBBox(self):
"""Get inner bounding box.
Expand All @@ -66,6 +98,8 @@ def getInnerBBox(self):
"""
return self._innerBBox

innerBBox = property(getInnerBBox, None)

def getOuterBBox(self):
"""Get outer bounding box.
Expand All @@ -76,35 +110,39 @@ def getOuterBBox(self):
"""
return self._outerBBox

def getInnerSkyPolygon(self, tractWcs):
outerBBox = property(getOuterBBox, None)

def getInnerSkyPolygon(self, tractWcs=None):
"""Get the inner on-sky region.
Parameters
----------
tractWcs : `lsst.afw.image.SkyWcs`
tractWcs : `lsst.afw.image.SkyWcs`, optional
WCS for the associated tract.
Returns
-------
result : `lsst.sphgeom.ConvexPolygon`
The inner sky region.
"""
return makeSkyPolygonFromBBox(bbox=self.getInnerBBox(), wcs=tractWcs)
_tractWcs = tractWcs if tractWcs is not None else self._wcs
return makeSkyPolygonFromBBox(bbox=self.getInnerBBox(), wcs=_tractWcs)

def getOuterSkyPolygon(self, tractWcs):
def getOuterSkyPolygon(self, tractWcs=None):
"""Get the outer on-sky region.
Parameters
----------
tractWcs : `lsst.afw.image.SkyWcs`
tractWcs : `lsst.afw.image.SkyWcs`, optional
WCS for the associated tract.
Returns
-------
result : `lsst.sphgeom.ConvexPolygon`
The outer sky region.
"""
return makeSkyPolygonFromBBox(bbox=self.getOuterBBox(), wcs=tractWcs)
_tractWcs = tractWcs if tractWcs is not None else self._wcs
return makeSkyPolygonFromBBox(bbox=self.getOuterBBox(), wcs=_tractWcs)

def __eq__(self, rhs):
return (self.getIndex() == rhs.getIndex()) \
Expand Down
2 changes: 1 addition & 1 deletion python/lsst/skymap/detail/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ def makeSkyPolygonFromBBox(bbox, wcs):
"""
pixelPoints = geom.Box2D(bbox).getCorners()
skyPoints = wcs.pixelToSky(pixelPoints)
return lsst.sphgeom.ConvexPolygon.convexHull([sp.getVector() for sp in skyPoints])
return lsst.sphgeom.ConvexPolygon([sp.getVector() for sp in skyPoints])
122 changes: 109 additions & 13 deletions python/lsst/skymap/patchInfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
__all__ = ["PatchInfo", "makeSkyPolygonFromBBox"]

import numbers
from collections.abc import Iterable

from lsst.geom import Extent2I, Point2I, Box2I
from .detail import makeSkyPolygonFromBBox
Expand All @@ -45,6 +46,10 @@ class PatchInfo:
inner bounding box
outerBBox : `lsst.geom.Box2I`
inner bounding box
sequentialIndex : `int`
Patch sequential index
tractWcs : `lsst.afw.geom.SkyWcs`
Tract WCS object.
cellInnerDimensions : `lsst.geom.Extent2I`, optional
Inner dimensions of each cell (x,y pixels).
cellBorder : `int`, optional
Expand All @@ -55,12 +60,15 @@ class PatchInfo:
Number of cells in the patch border.
"""

def __init__(self, index, innerBBox, outerBBox,
def __init__(self, index, innerBBox, outerBBox, sequentialIndex,
tractWcs=None,
cellInnerDimensions=Extent2I(0, 0), cellBorder=0,
numCellsPerPatchInner=0, numCellsInPatchBorder=0):
self._index = index
self._sequentialIndex = sequentialIndex
self._innerBBox = innerBBox
self._outerBBox = outerBBox
self._wcs = tractWcs
if not outerBBox.contains(innerBBox):
raise RuntimeError("outerBBox=%s does not contain innerBBox=%s" % (outerBBox, innerBBox))
self._cellInnerDimensions = cellInnerDimensions
Expand All @@ -83,6 +91,32 @@ def getIndex(self):
"""
return self._index

index = property(getIndex, None)

def getSequentialIndex(self):
"""Return patch sequential index.
Returns
-------
result : `int`
Sequential patch index.
"""
return self._sequentialIndex

sequentialIndex = property(getSequentialIndex, None)

def getWcs(self):
"""Return the associated tract wcs
Returns
-------
wcs : `lsst.afw.geom.SkyWcs`
Tract WCS.
"""
return self._wcs

wcs = property(getWcs, None)

def getInnerBBox(self):
"""Get inner bounding box.
Expand All @@ -93,6 +127,8 @@ def getInnerBBox(self):
"""
return self._innerBBox

innerBBox = property(getInnerBBox, None)

def getOuterBBox(self):
"""Get outer bounding box.
Expand All @@ -103,35 +139,39 @@ def getOuterBBox(self):
"""
return self._outerBBox

def getInnerSkyPolygon(self, tractWcs):
outerBBox = property(getOuterBBox, None)

def getInnerSkyPolygon(self, tractWcs=None):
"""Get the inner on-sky region.
Parameters
----------
tractWcs : `lsst.afw.image.SkyWcs`
tractWcs : `lsst.afw.image.SkyWcs`, optional
WCS for the associated tract.
Returns
-------
result : `lsst.sphgeom.ConvexPolygon`
The inner sky region.
"""
return makeSkyPolygonFromBBox(bbox=self.getInnerBBox(), wcs=tractWcs)
_tractWcs = tractWcs if tractWcs is not None else self._wcs
return makeSkyPolygonFromBBox(bbox=self.getInnerBBox(), wcs=_tractWcs)

def getOuterSkyPolygon(self, tractWcs):
def getOuterSkyPolygon(self, tractWcs=None):
"""Get the outer on-sky region.
Parameters
----------
tractWcs : `lsst.afw.image.SkyWcs`
tractWcs : `lsst.afw.image.SkyWcs`, optional
WCS for the associated tract.
Returns
-------
result : `lsst.sphgeom.ConvexPolygon`
The outer sky region.
"""
return makeSkyPolygonFromBBox(bbox=self.getOuterBBox(), wcs=tractWcs)
_tractWcs = tractWcs if tractWcs is not None else self._wcs
return makeSkyPolygonFromBBox(bbox=self.getOuterBBox(), wcs=_tractWcs)

def getNumCells(self):
"""Get the number of cells in x, y.
Expand All @@ -145,9 +185,13 @@ def getNumCells(self):
"""
return self._numCells

numCells = property(getNumCells, None)

def getCellBorder(self):
return self._cellBorder

cellBorder = property(getCellBorder, None)

def getCellInfo(self, index):
"""Return information for the specified cell.
Expand All @@ -168,6 +212,8 @@ def getCellInfo(self, index):
IndexError
If index is out of range.
"""
if self._numCells[0] == 0 or self._numCells[1] == 0:
raise IndexError("Patch does not contain cells.")
if isinstance(index, numbers.Number):
index = self.getCellIndexPair(index)
if (not 0 <= index[0] < self._numCells[0]) \
Expand All @@ -176,7 +222,7 @@ def getCellInfo(self, index):
(index, self._numCells[0] - 1, self._numCells[1] - 1))
# We offset the index by numCellsInPatchBorder because the cells
# start outside the inner dimensions.
# The cells are defined relative to the patch bounding box.
# The cells are defined relative to the patch bounding box (within the tract).
patchInnerBBox = self.getInnerBBox()
innerMin = Point2I(*[(index[i] - self._numCellsInPatchBorder)*self._cellInnerDimensions[i]
+ patchInnerBBox.getBegin()[i]
Expand All @@ -189,23 +235,73 @@ def getCellInfo(self, index):
return CellInfo(
index=index,
innerBBox=innerBBox,
outerBBox=outerBBox
outerBBox=outerBBox,
sequentialIndex=self.getSequentialCellIndexFromPair(index),
tractWcs=self._wcs
)

def getCellInnerDimensions(self):
"""Get dimensions of inner region of the cells (all are the same)
"""
return self._cellInnerDimensions

cellInnerDimensions = property(getCellInnerDimensions, None)

def getSequentialCellIndex(self, cellInfo):
"""Return a single integer that uniquely identifies the given
cell within this patch.
"""Return a single integer that uniquely identifies
the given cell within this patch.
Parameters
----------
cellInfo : `lsst.skymap.CellInfo`
Returns
-------
sequentialIndex : `int`
Raises
------
IndexError
If index is out of range.
"""
index = cellInfo.getIndex()
return self.getSequentialCellIndexFromPair(index)

def getSequentialCellIndexFromPair(self, index):
"""Return a single integer that uniquely identifies
the given cell within this patch.
Parameters
----------
index : `tuple` [`int`, `int`]
Returns
-------
sequentialIndex : `int`
Raises
------
IndexError
If index is out of range.
"""
x, y = cellInfo.getIndex()
if not isinstance(index, Iterable):
raise ValueError("Input index is not an iterable.")
if len(index) != 2:
raise ValueError("Input index does not have two values.")
nx, ny = self.getNumCells()
return nx*y + x
return nx*index[1] + index[0]

def getCellIndexPair(self, sequentialIndex):
"""Convert a sequential index into an index pair.
Raises
------
IndexError
If index is out of range.
"""
if self._numCells[0] == 0 or self._numCells[1] == 0:
raise IndexError("Patch does not contain cells.")

nx, ny = self.getNumCells()
x = sequentialIndex % nx
y = (sequentialIndex - x) // nx
Expand Down

0 comments on commit c80cdd5

Please sign in to comment.