623 def _generateGrid(self, exposure, forceEvenSized=False, **kwargs):
624 """Generate two lists of bounding boxes that evenly grid `exposure`
625
626 Unless the config was provided with `cellCentroidsX` and
627 `cellCentroidsY`, grid (subimage) centers are spaced evenly
628 by gridStepX/Y. Then the grid is adjusted as little as
629 possible to evenly cover the input exposure (if
630 adjustGridOption is not 'none'). Then the second set of
631 bounding boxes is expanded by borderSizeX/Y. The expanded
632 bounding boxes are adjusted to ensure that they intersect the
633 exposure's bounding box. The resulting lists of bounding boxes
634 and corresponding expanded bounding boxes are set to
635 `self.boxes0`, `self.boxes1`.
636
637 Parameters
638 ----------
639 exposure : `lsst.afw.image.Exposure`
640 input exposure whose full bounding box is to be evenly gridded.
641 forceEvenSized : `bool`
642 force grid elements to have even-valued x- and y- dimensions?
643 (Potentially useful if doing Fourier transform of subExposures.)
644 """
645
646
647 bbox = exposure.getBBox()
648
649
650 cellCentroidsX = self.config.cellCentroidsX
651 cellCentroidsY = self.config.cellCentroidsY
652 cellSizeX = self.config.cellSizeX
653 cellSizeY = self.config.cellSizeY
654 gridStepX = self.config.gridStepX
655 gridStepY = self.config.gridStepY
656 borderSizeX = self.config.borderSizeX
657 borderSizeY = self.config.borderSizeY
658 adjustGridOption = self.config.adjustGridOption
659 scaleByFwhm = self.config.scaleByFwhm
660
661 if cellCentroidsX is None or len(cellCentroidsX) <= 0:
662
663 psf = exposure.getPsf()
664 psfFwhm = (psf.computeShape(psf.getAveragePosition()).getDeterminantRadius()
665 * 2.*np.sqrt(2.*np.log(2.)))
666 if scaleByFwhm:
667 self.log.info("Scaling grid parameters by %f", psfFwhm)
668
669 def rescaleValue(val):
670 if scaleByFwhm:
671 return np.rint(val*psfFwhm).astype(int)
672 else:
673 return np.rint(val).astype(int)
674
675 cellSizeX = rescaleValue(cellSizeX)
676 cellSizeY = rescaleValue(cellSizeY)
677 gridStepX = rescaleValue(gridStepX)
678 gridStepY = rescaleValue(gridStepY)
679 borderSizeX = rescaleValue(borderSizeX)
680 borderSizeY = rescaleValue(borderSizeY)
681
682 nGridX = bbox.getWidth()//gridStepX
683 nGridY = bbox.getHeight()//gridStepY
684
685 if adjustGridOption == 'spacing':
686
687 nGridX = bbox.getWidth()//cellSizeX + 1
688 nGridY = bbox.getHeight()//cellSizeY + 1
689 xLinSpace = np.linspace(cellSizeX//2, bbox.getWidth() - cellSizeX//2, nGridX)
690 yLinSpace = np.linspace(cellSizeY//2, bbox.getHeight() - cellSizeY//2, nGridY)
691
692 elif adjustGridOption == 'size':
693 cellSizeX = gridStepX
694 cellSizeY = gridStepY
695 xLinSpace = np.arange(cellSizeX//2, bbox.getWidth() + cellSizeX//2, cellSizeX)
696 yLinSpace = np.arange(cellSizeY//2, bbox.getHeight() + cellSizeY//2, cellSizeY)
697 cellSizeX += 1
698 cellSizeY += 1
699
700 else:
701 xLinSpace = np.arange(cellSizeX//2, bbox.getWidth() + cellSizeX//2, gridStepX)
702 yLinSpace = np.arange(cellSizeY//2, bbox.getHeight() + cellSizeY//2, gridStepY)
703
704 cellCentroids = [(x, y) for x in xLinSpace for y in yLinSpace]
705
706 else:
707
708 cellCentroids = [(cellCentroidsX[i], cellCentroidsY[i]) for i in range(len(cellCentroidsX))]
709
710
712
715
716 self.boxes0 = []
717 self.boxes1 = []
718
719 def _makeBoxEvenSized(bb):
720 """Force a bounding-box to have dimensions that are modulo 2."""
721
722 if bb.getWidth() % 2 == 1:
724 bb.clip(bbox)
725 if bb.getWidth() % 2 == 1:
727 bb.clip(bbox)
728 if bb.getHeight() % 2 == 1:
730 bb.clip(bbox)
731 if bb.getHeight() % 2 == 1:
733 bb.clip(bbox)
734 if bb.getWidth() % 2 == 1 or bb.getHeight() % 2 == 1:
735 raise RuntimeError('Cannot make bounding box even-sized. Probably too big.')
736
737 return bb
738
739
740 if cellCentroids is not None and len(cellCentroids) > 0:
741 for x, y in cellCentroids:
744 xoff = int(np.floor(centroid.getX())) - bb0.getWidth()//2
745 yoff = int(np.floor(centroid.getY())) - bb0.getHeight()//2
747 bb0.clip(bbox)
748 if forceEvenSized:
749 bb0 = _makeBoxEvenSized(bb0)
752 bb1.clip(bbox)
753 if forceEvenSized:
754 bb1 = _makeBoxEvenSized(bb1)
755
756 if bb0.getArea() > 1 and bb1.getArea() > 1:
757 self.boxes0.append(bb0)
758 self.boxes1.append(bb1)
759
760 return self.boxes0, self.boxes1
761
An integer coordinate rectangle.