6__all__ = [
'CalexpCutoutTaskConfig',
'CalexpCutoutTask']
7DETECTOR_DIMENSIONS = (
'instrument',
'visit',
'detector')
11 dimensions=DETECTOR_DIMENSIONS,
13 """Connections class for CalexpCutoutTask
15 in_table = pipeBase.connectionTypes.Input(
16 doc="Locations for cutouts",
17 name=
"cutout_positions",
18 storageClass=
"AstropyQTable",
19 dimensions=DETECTOR_DIMENSIONS,
21 calexp = pipeBase.connectionTypes.Input(
24 storageClass=
"ExposureF",
25 dimensions=DETECTOR_DIMENSIONS,
27 cutouts = pipeBase.connectionTypes.Output(
29 name=
"calexp_cutouts",
30 storageClass=
"Stamps",
31 dimensions=DETECTOR_DIMENSIONS,
36 pipelineConnections=CalexpCutoutTaskConnections):
37 """Configuration for CalexpCutoutTask
39 max_cutouts = Field(dtype=int, default=100, doc='Maximum number of entries to process. '
40 'The result will be the first N in the input table.')
41 skip_bad = Field(dtype=bool, default=
True, doc=
'Skip cutouts that do not fall completely within'
42 ' the calexp bounding box? If set to False a ValueError'
43 ' is raised instead.')
47 """Task for computing cutouts on a specific calexp given
48 positions, xspans, and yspans of the stamps.
50 ConfigClass = CalexpCutoutTaskConfig
51 _DefaultName = "calexpCutoutTask"
53 def run(self, in_table, calexp):
54 """Compute and return the cutouts.
58 in_table : `astropy.QTable`
59 A table containing at least the following columns: position, xspan
60 and yspan. The position should be an `astropy.SkyCoord`. The
61 xspan
and yspan are the extent of the cutout
in x
and y
in pixels.
62 calexp : `lsst.afw.image.ExposureF`
63 The calibrated exposure
from which to extract cutouts
67 output : `lsst.pipe.base.Struct`
70 * cutouts: an `lsst.meas.algorithms.Stamps` object
71 that wraps a list of masked images of the cutouts
and a
72 `PropertyList` containing the metadata to be persisted
73 with the cutouts. The exposure metadata
is preserved
and,
74 in addition, arrays holding the RA
and Dec of each stamp
75 in degrees are added to the metadata. Note: the origin
76 of the output stamps
is `lsst.afw.image.PARENT`.
78 stamps that were skiped
for being off the image
79 or partially off the image
84 If the input catalog doesn
't have the required columns,
85 a ValueError is raised
87 cols = in_table.colnames
88 if 'position' not in cols
or 'xspan' not in cols
or 'yspan' not in cols:
89 raise ValueError(
'Required column missing from the input table. '
90 'Required columns are "position", "xspan", and "yspan". '
91 f
'The column names are: {in_table.colnames}')
92 max_idx = self.config.max_cutouts
95 mim = calexp.getMaskedImage()
98 skipped_positions = []
99 for rec
in in_table[:max_idx]:
100 ra = rec[
'position'].ra.degree
101 dec = rec[
'position'].dec.degree
106 pix = wcs.skyToPixel(pt)
107 xspan = rec[
'xspan'].value
108 yspan = rec[
'yspan'].value
112 if not mim.getBBox().contains(box):
113 if not self.config.skip_bad:
114 raise ValueError(f
'Cutout bounding box is not completely contained in the image: {box}')
116 skipped_positions.append(pt)
118 sub = mim.Factory(mim, box)
119 stamp = Stamp(stamp_im=sub, position=pt)
120 cutout_list.append(stamp)
121 metadata = calexp.getMetadata()
122 metadata[
'RA_DEG'] = ras
123 metadata[
'DEC_DEG'] = decs
124 return pipeBase.Struct(cutouts=Stamps(cutout_list, metadata=metadata),
125 skipped_positions=skipped_positions)
def run(self, in_table, calexp)