lsst.meas.astrom gaf95d0f0f9+e66c719481
Loading...
Searching...
No Matches
verifyWcs.py
Go to the documentation of this file.
2# LSST Data Management System
3# Copyright 2008, 2009, 2010 LSST Corporation.
4#
5# This product includes software developed by the
6# LSST Project (http://www.lsst.org/).
7#
8# This program is free software: you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation, either version 3 of the License, or
11# (at your option) any later version.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the LSST License Statement and
19# the GNU General Public License along with this program. If not,
20# see <http://www.lsstcorp.org/LegalNotices/>.
21#
22
23__all__ = ["checkMatches"]
24
25
26import numpy as np
27
28import lsst.geom
29import lsst.afw.detection as afwDetection
30import lsst.afw.math as afwMath
31import lsst.meas.algorithms as measAlg
32from lsst.log import Log
33
34
35def checkMatches(srcMatchSet, exposure, log=None):
36 """Check astrometric matches and assess Wcs quality by computing statics
37 over spacial cells in the image.
38
39 Parameters
40 ----------
41 srcMatchSet : `list` of `lsst.afw.table.ReferenceMatch`
42 List of matched sources to a reference catalog.
43 exposure : `lsst.afw.image.Exposure`
44 Image the sources in srcMatchSet were detected/measured in.
45 log : `lsst.log.Log`
46 Logger object.
47
48 Returns
49 -------
50 values : `dict`
51 Result dictionary with fields:
52
53 - ``minObjectsPerCell`` : (`int`)
54 - ``maxObjectsPerCell`` : (`int`)
55 - ``meanObjectsPerCell`` : (`float`)
56 - ``stdObjectsPerCell`` : (`float`)
57 """
58 if not exposure:
59 return {}
60
61 if log is None:
62 log = Log.getLogger("meas.astrom.verifyWcs.checkMatches")
63
64 im = exposure.getMaskedImage().getImage()
65 width, height = im.getWidth(), im.getHeight()
66 nx, ny = 3, 3
67 w, h = width//nx, height//ny
68
69 if w == 0:
70 w = 1
71 while nx*w < width:
72 w += 1
73
74 if h == 0:
75 h = 1
76 while ny*h < height:
77 h += 1
78
79 cellSet = afwMath.SpatialCellSet(
80 lsst.geom.Box2I(lsst.geom.Point2I(0, 0), lsst.geom.Extent2I(width, height)), w, h)
81 #
82 # Populate cellSet
83 #
84 i = -1
85 for m in srcMatchSet:
86 i += 1
87
88 src = m.second
89 csrc = afwDetection.Source()
90 csrc.setId(i)
91 csrc.setXAstrom(src.getXAstrom())
92 csrc.setYAstrom(src.getYAstrom())
93
94 try:
95 cellSet.insertCandidate(measAlg.PsfCandidateF(csrc, exposure.getMaskedImage()))
96 except Exception as e:
97 log.warn(str(e))
98
99 ncell = len(cellSet.getCellList())
100 nobj = np.ndarray(ncell, dtype='i')
101
102 for i in range(ncell):
103 cell = cellSet.getCellList()[i]
104
105 nobj[i] = cell.size()
106
107 dx = np.ndarray(cell.size())
108 dy = np.ndarray(cell.size())
109
110 j = 0
111 for cand in cell:
112 #
113 # Swig doesn't know that we're a SpatialCellImageCandidate; all it knows is that we have
114 # a SpatialCellCandidate so we need an explicit (dynamic) cast
115 #
116 mid = cand.getSource().getId()
117 dx[j] = srcMatchSet[mid].first.getXAstrom() - srcMatchSet[mid].second.getXAstrom()
118 dy[j] = srcMatchSet[mid].first.getYAstrom() - srcMatchSet[mid].second.getYAstrom()
119
120 j += 1
121
122 log.debug("%s %-30s %8s dx,dy = %5.2f,%5.2f rms_x,y = %5.2f,%5.2f",
123 cell.getLabel(), cell.getBBox(), ("nobj=%d" % cell.size()),
124 dx.mean(), dy.mean(), dx.std(), dy.std())
125
126 nobj.sort()
127
128 values = {}
129 values["minObjectsPerCell"] = int(nobj[0]) # otherwise it's a numpy integral type
130 values["maxObjectsPerCell"] = int(nobj[-1])
131 values["meanObjectsPerCell"] = nobj.mean()
132 values["stdObjectsPerCell"] = nobj.std()
133
134 return values
def checkMatches(srcMatchSet, exposure, log=None)
Definition: verifyWcs.py:35