Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0d33ba9806+3d1aa5cd78,g0fba68d861+6c07529581,g1e78f5e6d3+aa4d1c21f1,g1ec0fe41b4+f536777771,g1fd858c14a+c6963eae98,g35bb328faa+fcb1d3bbc8,g4af146b050+58cb980876,g4d2262a081+bfae794ebc,g53246c7159+fcb1d3bbc8,g5a012ec0e7+b20b785ecb,g60b5630c4e+3d1aa5cd78,g67b6fd64d1+4086c0989b,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g7b71ed6315+fcb1d3bbc8,g87b7deb4dc+a8b896a16a,g8852436030+75f93ca278,g89139ef638+4086c0989b,g9125e01d80+fcb1d3bbc8,g94187f82dc+3d1aa5cd78,g989de1cb63+4086c0989b,g9f33ca652e+94dd9a85be,g9f7030ddb1+3f50642ad9,ga2b97cdc51+3d1aa5cd78,ga44b1db4f6+7d2d5e68ea,gabe3b4be73+1e0a283bba,gabf8522325+fa80ff7197,gb1101e3267+96cb2ddcf2,gb58c049af0+f03b321e39,gb89ab40317+4086c0989b,gcf25f946ba+75f93ca278,gd6cbbdb0b4+af3c3595f5,gd9a9a58781+fcb1d3bbc8,gde0f65d7ad+ed90e8109d,ge278dab8ac+d65b3c2b70,ge410e46f29+4086c0989b,gf67bdafdda+4086c0989b,gfe06eef73a+e2ab3e8e4f,v29.0.0.rc5
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
footprints.py
Go to the documentation of this file.
1# This file is part of {{ cookiecutter.package_name }}.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (https://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <https://www.gnu.org/licenses/>.
21
22
23import numpy as np
24from astropy.io.votable.tree import Info
25from astropy.io.votable import from_table
26from astropy.table import Column
27
28import lsst.geom as geom
29import lsst.afw.table as afwTable
30
31
32def recordSelector(record, selection):
33 """Select records from source catalog
34
35 Parameters:
36 -----------
37 record : `lsst.afw.detect.SourceRecord`
38 record to select
39 selection : `str`
40 'all' to select all records. 'blended parents' to select records with
41 more than zero children. 'deblended children' to select records with
42 non-zero parents. 'isolated' to select records that are not blended,
43 meaning zero parents and zero children.
44 Values to check for sel
45 """
46 nChildren = record.get('deblend_nChild')
47 parentId = record.getParent()
48 if selection == 'all':
49 return True
50 elif selection == 'blended parents':
51 return (nChildren > 0)
52 elif selection == 'deblended children':
53 return (parentId > 0)
54 elif selection == 'isolated':
55 return ((parentId == 0) and (nChildren == 0))
56 else:
57 raise RuntimeError(
58 f'invalid selection: {selection}\n'
59 'Must be one of "all", "blended parents", "deblended children", "isolated"'
60 )
61
62
63def createFootprintsTable(catalog, xy0=None, insertColumn=4):
64 """make a VOTable of SourceData table and footprints
65
66 Parameters:
67 -----------
68 catalog : `lsst.afw.table.SourceCatalog`
69 Source catalog from which to display footprints.
70 xy0 : tuple or list or None
71 Pixel origin to subtract off from the footprint coordinates.
72 If None, the value used is (0,0)
73 insertColumn : `int`
74 Column at which to insert the "family_id" and "category" columns
75
76 Returns:
77 --------
78 `astropy.io.votable.voTableFile`
79 VOTable object to upload to Firefly
80 """
81 if xy0 is None:
82 xy0 = geom.Point2I(0, 0)
83
84 _catalog = afwTable.SourceCatalog(catalog.table.clone())
85 _catalog.extend(catalog, deep=True)
86 sourceTable = _catalog.asAstropy()
87
88 # Change int64 dtypes so they convert to VOTable
89 for colName in sourceTable.colnames:
90 if sourceTable[colName].dtype.num == 9:
91 sourceTable[colName].dtype = np.dtype('long')
92
93 inputColumnNames = sourceTable.colnames
94
95 x0, y0 = xy0
96 spanList = []
97 peakList = []
98 familyList = []
99 categoryList = []
100 fpxll = []
101 fpyll = []
102 fpxur = []
103 fpyur = []
104 for record in catalog:
105 footprint = record.getFootprint()
106 recordId = record.getId()
107 spans = footprint.getSpans()
108 scoords = [(s.getY()-y0, s.getX0()-x0, s.getX1()-x0) for s in spans]
109 scoords = np.array(scoords).flatten()
110 scoords = np.ma.MaskedArray(scoords, mask=np.zeros(len(scoords),
111 dtype=np.bool))
112 fpbbox = footprint.getBBox()
113 corners = [(c.getX()-x0, c.getY()-y0) for c in fpbbox.getCorners()]
114 fpxll.append(corners[0][0])
115 fpyll.append(corners[0][1])
116 fpxur.append(corners[2][0])
117 fpyur.append(corners[2][1])
118 peaks = footprint.getPeaks()
119 pcoords = [(p.getFx()-x0, p.getFy()-y0) for p in peaks]
120 pcoords = np.array(pcoords).flatten()
121 pcoords = np.ma.MaskedArray(pcoords, mask=np.zeros(len(pcoords),
122 dtype=np.bool))
123 fpbbox = footprint.getBBox()
124 parentId = record.getParent()
125 nChild = record.get('deblend_nChild')
126 if parentId == 0:
127 familyList.append(recordId)
128 if nChild > 0:
129 # blended parent
130 categoryList.append('blended parent')
131 else:
132 # isolated
133 categoryList.append('isolated')
134 else:
135 # deblended child
136 familyList.append(parentId)
137 categoryList.append('deblended child')
138 spanList.append(scoords)
139 peakList.append(pcoords)
140
141 sourceTable.add_column(Column(np.array(familyList)),
142 name='family_id',
143 index=insertColumn)
144 sourceTable.add_column(Column(np.array(categoryList)),
145 name='category',
146 index=insertColumn+1)
147 sourceTable.add_column(Column(np.array(spanList)), name='spans')
148 sourceTable.add_column(Column(np.array(peakList)), name='peaks')
149 sourceTable.add_column(Column(np.array(fpxll)), name='footprint_corner1_x')
150 sourceTable.add_column(Column(np.array(fpyll)), name='footprint_corner1_y')
151 sourceTable.add_column(Column(np.array(fpxur)), name='footprint_corner2_x')
152 sourceTable.add_column(Column(np.array(fpyur)), name='footprint_corner2_y')
153
154 outputVO = from_table(sourceTable)
155 outTable = outputVO.get_first_table()
156
157 outTable.infos.append(Info(name='contains_lsst_footprints', value='true'))
158 outTable.infos.append(Info(name='contains_lsst_measurements', value='true'))
159 outTable.infos.append(Info(name='FootPrintColumnNames',
160 value='id;footprint_corner1_x;footprint_corner1_y;' +
161 'footprint_corner2_x;footprint_corner2_y;spans;peaks'))
162 outTable.infos.append(Info(name='pixelsys', value='zero-based'))
163 # Check whether the coordinates are included and are valid
164 if (('slot_Centroid_x' in inputColumnNames) and
165 ('slot_Centroid_y' in inputColumnNames) and
166 np.isfinite(outTable.array['slot_Centroid_x']).any() and
167 np.isfinite(outTable.array['slot_Centroid_y']).any()):
168 coord_column_string = 'slot_Centroid_x;slot_Centroid_y;ZERO_BASED'
169 elif (('coord_ra' in inputColumnNames) and
170 ('coord_dec' in inputColumnNames) and
171 np.isfinite(outTable.array['coord_ra']).any() and
172 np.isfinite(outTable.array['coord_dec']).any()):
173 coord_column_string = 'coord_ra;coord_dec;EQ_J2000'
174 elif (('base_SdssCentroid_x' in inputColumnNames) and
175 ('base_SdssCentroid_y' in inputColumnNames) and
176 np.isfinite(outTable.array['base_SdssCentroid_x']).any() and
177 np.isfinite(outTable.array['base_SdssCentroid_y']).any()):
178 coord_column_string = 'base_SdssCentroid_x;base_SdssCentroid_y;ZERO_BASED'
179 else:
180 raise RuntimeError('No valid coordinate columns in catalog')
181 outTable.infos.append(Info(name='CatalogCoordColumns',
182 value=coord_column_string))
183
184 for f in outTable.fields:
185 if f.datatype == 'bit':
186 f.datatype = 'boolean'
187
188 outTable._config['version_1_3_or_later'] = True
189 outputVO.set_all_tables_format('binary2')
190
191 return outputVO
createFootprintsTable(catalog, xy0=None, insertColumn=4)
Definition footprints.py:63
recordSelector(record, selection)
Definition footprints.py:32