LSST Applications  21.0.0-147-g0e635eb1+1acddb5be5,22.0.0+052faf71bd,22.0.0+1ea9a8b2b2,22.0.0+6312710a6c,22.0.0+729191ecac,22.0.0+7589c3a021,22.0.0+9f079a9461,22.0.1-1-g7d6de66+b8044ec9de,22.0.1-1-g87000a6+536b1ee016,22.0.1-1-g8e32f31+6312710a6c,22.0.1-10-gd060f87+016f7cdc03,22.0.1-12-g9c3108e+df145f6f68,22.0.1-16-g314fa6d+c825727ab8,22.0.1-19-g93a5c75+d23f2fb6d8,22.0.1-19-gb93eaa13+aab3ef7709,22.0.1-2-g8ef0a89+b8044ec9de,22.0.1-2-g92698f7+9f079a9461,22.0.1-2-ga9b0f51+052faf71bd,22.0.1-2-gac51dbf+052faf71bd,22.0.1-2-gb66926d+6312710a6c,22.0.1-2-gcb770ba+09e3807989,22.0.1-20-g32debb5+b8044ec9de,22.0.1-23-gc2439a9a+fb0756638e,22.0.1-3-g496fd5d+09117f784f,22.0.1-3-g59f966b+1e6ba2c031,22.0.1-3-g849a1b8+f8b568069f,22.0.1-3-gaaec9c0+c5c846a8b1,22.0.1-32-g5ddfab5d3+60ce4897b0,22.0.1-4-g037fbe1+64e601228d,22.0.1-4-g8623105+b8044ec9de,22.0.1-5-g096abc9+d18c45d440,22.0.1-5-g15c806e+57f5c03693,22.0.1-7-gba73697+57f5c03693,master-g6e05de7fdc+c1283a92b8,master-g72cdda8301+729191ecac,w.2021.39
LSST Data Management Base Package
verifyWcs.py
Go to the documentation of this file.
1 #
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 
26 import numpy as np
27 
28 import lsst.geom
29 import lsst.afw.detection as afwDetection
30 import lsst.afw.math as afwMath
31 import lsst.meas.algorithms as measAlg
32 from lsst.log import Log
33 
34 
35 def 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
A collection of SpatialCells covering an entire image.
Definition: SpatialCell.h:383
An integer coordinate rectangle.
Definition: Box.h:55
Definition: Log.h:717
Fit spatial kernel using approximate fluxes for candidates, and solving a linear system of equations.
def checkMatches(srcMatchSet, exposure, log=None)
Definition: verifyWcs.py:35