21 __all__ = [
"tractBuilderRegistry",
"BaseTractBuilder",
22 "LegacyTractBuilder",
"CellTractBuilder"]
31 from .patchInfo
import PatchInfo
32 from .detail
import Index2D
36 """Configuration that is to be shared amongst all tract builders."""
41 """Base class for algorithms that define patches within the tract.
45 config : `lsst.pexConfig.Config`
46 Input for configuring the algorithm
52 """Set up the patches of a particular size in a tract.
54 We grow the tract bounding box to hold an exact multiple of
55 the desired size (patchInnerDimensions or
56 numCellsPerPatchInner*cellInnerDimensions), while keeping
57 the center roughly the same. We return the final tract
58 bounding box, and the number of patches in each dimension
63 minBBox : `lsst.geom.Box2I`
64 Minimum bounding box for tract
65 wcs : `lsst.afw.geom.SkyWcs`
70 bbox : `lsst.geom.Box2I
71 final bounding box, number of patches
72 numPatches : `lsst.skymap.Index2D`
75 bboxMin = bbox.getMin()
76 bboxDim = bbox.getDimensions()
77 numPatchesList = [0, 0]
78 for i, innerDim
in enumerate(self._patchInnerDimensions):
79 num = (bboxDim[i] + innerDim - 1) // innerDim
80 deltaDim = (innerDim*num) - bboxDim[i]
82 bboxDim[i] = innerDim * num
83 bboxMin[i] -= deltaDim // 2
84 numPatchesList[i] = num
85 numPatches =
Index2D(*numPatchesList)
92 return bbox, numPatches
95 return self._patchBorder
99 """Return information for the specified patch.
103 index : `lsst.skymap.Index2D` or `Iterable` [`int`, `int`]
104 Index of patch, as Index2D or pair of ints;
105 or a sequential index as returned by getSequentialPatchIndex;
106 negative values are not supported.
107 tractWcs : `lsst.afw.geom.SkyWcs`
108 WCS associated with the tract.
112 result : `lsst.skymap.PatchInfo`
113 The patch info for that index.
118 If index is out of range.
120 raise NotImplementedError(
"Must be implemented by a subclass")
123 """Get dimensions of inner region of the patches (all are the same)
125 return self._patchInnerDimensions
128 """Return a single integer that uniquely identifies
129 the given patch within this tract.
133 patchInfo : `lsst.skymap.PatchInfo`
137 sequentialIndex : `int`
139 index = patchInfo.getIndex()
143 """Return a single integer that uniquely identifies
144 the patch index within the tract.
148 index : `lsst.skymap.Index2D` or `Iterable` [`int`, `int`]
152 sequentialIndex : `int`
154 if isinstance(index, Index2D):
157 if not isinstance(index, Iterable):
158 raise ValueError(
"Input index is not an iterable.")
160 raise ValueError(
"Input index does not have two values.")
163 return nx*_index.y + _index.x
166 """Convert sequential index into patch index (x,y) pair.
170 sequentialIndex : `int`
174 x, y : `lsst.skymap.Index2D`
177 x = sequentialIndex % nx
178 y = sequentialIndex // nx
183 """Get a packed config suitable for using in a sha1.
187 config : `lsst.skymap.BaseTractBuilderConfig`
191 configPacked : `bytes`
193 raise NotImplementedError(
"Must be implemented by a subclass")
197 patchInnerDimensions = pexConfig.ListField(
198 doc=
"dimensions of inner region of patches (x,y pixels)",
201 default=(4000, 4000),
203 patchBorder = pexConfig.Field(
204 doc=
"border between patch inner and outer bbox (pixels)",
211 ConfigClass = LegacyTractBuilderConfig
217 for val
in config.patchInnerDimensions))
224 raise RuntimeError(
"Programmer error; this should always be initialized.")
225 if isinstance(index, Index2D):
228 if isinstance(index, numbers.Number):
232 if (
not 0 <= _index.x < self.
_numPatches_numPatches.x) \
233 or (
not 0 <= _index.y < self.
_numPatches_numPatches.y):
234 raise IndexError(
"Patch index %s is not in range [0-%d, 0-%d]" %
240 "Bug: patch index %s valid but inner bbox=%s not contained in tract bbox=%s" %
241 (_index, innerBBox, self.
_tractBBox_tractBBox))
254 subConfig = config.tractBuilder[config.tractBuilder.name]
255 configPacked = struct.pack(
257 subConfig.patchInnerDimensions[0],
258 subConfig.patchInnerDimensions[1],
259 subConfig.patchBorder,
262 config.projection.encode(
'ascii'),
270 cellInnerDimensions = pexConfig.ListField(
271 doc=
"dimensions of inner region of cells (x,y pixels)",
276 cellBorder = pexConfig.Field(
277 doc=
"Border between cell inner and outer bbox (pixels)",
281 numCellsPerPatchInner = pexConfig.Field(
282 doc=
"Number of cells per inner patch.",
286 numCellsInPatchBorder = pexConfig.Field(
287 doc=
"Number of cells in the patch border (outside the inner patch region).",
294 raise ValueError(
"cellInnerDimensions must be 2 ints.")
297 raise ValueError(
"cellInnerDimensions must be equal (for square cells).")
301 ConfigClass = CellTractBuilderConfig
307 for val
in config.cellInnerDimensions))
312 for val
in config.cellInnerDimensions))
314 self.
_patchBorder_patchBorder = config.numCellsInPatchBorder*config.cellInnerDimensions[0] + self.
_cellBorder_cellBorder
320 raise RuntimeError(
"Programmer error; this should always be initialized.")
321 if isinstance(index, Index2D):
324 if isinstance(index, numbers.Number):
328 if (
not 0 <= _index.x < self.
_numPatches_numPatches.x) \
329 or (
not 0 <= _index.y < self.
_numPatches_numPatches.y):
330 raise IndexError(
"Patch index %s is not in range [0-%d, 0-%d]" %
336 "Bug: patch index %s valid but inner bbox=%s not contained in tract bbox=%s" %
337 (_index, innerBBox, self.
_tractBBox_tractBBox))
354 subConfig = config.tractBuilder[config.tractBuilder.name]
355 configPacked = struct.pack(
357 subConfig.cellInnerDimensions[0],
358 subConfig.cellInnerDimensions[1],
359 subConfig.cellBorder,
360 subConfig.numCellsPerPatchInner,
361 subConfig.numCellsInPatchBorder,
364 config.projection.encode(
'ascii'),
371 tractBuilderRegistry = pexConfig.makeRegistry(
372 doc=
"A registry of Tract Builders (subclasses of BaseTractBuilder)",
375 tractBuilderRegistry.register(
"legacy", LegacyTractBuilder)
376 tractBuilderRegistry.register(
"cells", CellTractBuilder)
An integer coordinate rectangle.
def getSequentialPatchIndexFromPair(self, index)
def getPatchIndexPair(self, sequentialIndex)
def getPatchInnerDimensions(self)
def getPackedConfig(self, config)
def __init__(self, config)
def getPatchInfo(self, index, tractWcs)
def setupPatches(self, minBBox, wcs)
def getSequentialPatchIndex(self, patchInfo)
def __init__(self, config)
def getPatchInfo(self, index, tractWcs)
def getPackedConfig(self, config)
def __init__(self, config)
def getPatchInfo(self, index, tractWcs)
def getPackedConfig(self, config)