LSSTApplications  16.0-10-g0ee56ad+5,16.0-11-ga33d1f2+5,16.0-12-g3ef5c14+3,16.0-12-g71e5ef5+18,16.0-12-gbdf3636+3,16.0-13-g118c103+3,16.0-13-g8f68b0a+3,16.0-15-gbf5c1cb+4,16.0-16-gfd17674+3,16.0-17-g7c01f5c+3,16.0-18-g0a50484+1,16.0-20-ga20f992+8,16.0-21-g0e05fd4+6,16.0-21-g15e2d33+4,16.0-22-g62d8060+4,16.0-22-g847a80f+4,16.0-25-gf00d9b8+1,16.0-28-g3990c221+4,16.0-3-gf928089+3,16.0-32-g88a4f23+5,16.0-34-gd7987ad+3,16.0-37-gc7333cb+2,16.0-4-g10fc685+2,16.0-4-g18f3627+26,16.0-4-g5f3a788+26,16.0-5-gaf5c3d7+4,16.0-5-gcc1f4bb+1,16.0-6-g3b92700+4,16.0-6-g4412fcd+3,16.0-6-g7235603+4,16.0-69-g2562ce1b+2,16.0-8-g14ebd58+4,16.0-8-g2df868b+1,16.0-8-g4cec79c+6,16.0-8-gadf6c7a+1,16.0-8-gfc7ad86,16.0-82-g59ec2a54a+1,16.0-9-g5400cdc+2,16.0-9-ge6233d7+5,master-g2880f2d8cf+3,v17.0.rc1
LSSTDataManagementBasePackage
display.py
Go to the documentation of this file.
1 #
2 # LSST Data Management System
3 # Copyright 2008-2016 AURA/LSST.
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__ = ["displayAstrometry", "plotAstrometry"]
24 
25 import math
26 
27 import numpy as np
28 
29 import lsst.afw.display as afwDisplay
30 from lsst.afw.image import ExposureF
31 from lsst.afw.table import Point2DKey
32 
33 
34 def displayAstrometry(refCat=None, sourceCat=None, distortedCentroidKey=None, bbox=None, exposure=None,
35  matches=None, frame=1, title="", pause=True):
36  """Show an astrometry debug image.
37 
38  Parameters
39  ----------
40  refCat : `lsst.afw.table.SimpleCatalog`
41  reference object catalog; must have fields "centroid_x" an
42  "centroid_y"
43  sourceCat : `lsst.afw.table.SourceCatalg`
44  source catalog; must have field "slot_Centroid_x" and "slot_Centroid_y"
45  distortedCentroidKey : `lsst.afw.table.Key`
46  key for sourceCat with field to use for distorted positions
47  exposure : `lsst.afw.image.Exposure`
48  exposure to display
49  bbox : `lsst.geom.Box2I`
50  bounding box of exposure; Used if the exposure is `None`
51  matches : `list` of `lsst.afw.table.ReferenceMatch`
52  List of matched objects
53  frame : `int`
54  frame number for ds9 display
55  title : `str`
56  title for ds9 display
57  pause : `bool`
58  pause for inspection of display? This is done by dropping into pdb.
59 
60  Notes
61  -----
62 
63  - reference objects in refCat are shown as red X
64  - sources in sourceCat are shown as green +
65  - distorted sources in sourceCat (position given by distortedCentroidKey)
66  are shown as green o
67  - matches are shown as a yellow circle around the source and a yellow line
68  connecting the reference object and source
69  - if both exposure and bbox are `None`, no image is displayed
70 
71  """
72  disp = afwDisplay.getDisplay(frame)
73 
74  if exposure is not None:
75  disp.mtv(exposure, title=title)
76  elif bbox is not None:
77  disp.mtv(exposure=ExposureF(bbox), title=title)
78 
79  with disp.Buffering():
80  if refCat is not None:
81  refCentroidKey = Point2DKey(refCat.schema["centroid"])
82  for refObj in refCat:
83  rx, ry = refObj.get(refCentroidKey)
84  disp.dot("x", rx, ry, size=10, ctype=afwDisplay.RED)
85 
86  if sourceCat is not None:
87  sourceCentroidKey = Point2DKey(sourceCat.schema["slot_Centroid"])
88  for source in sourceCat:
89  sx, sy = source.get(sourceCentroidKey)
90  disp.dot("+", sx, sy, size=10, ctype=afwDisplay.GREEN)
91  if distortedCentroidKey is not None:
92  dx, dy = source.get(distortedCentroidKey)
93  disp.dot("o", dx, dy, size=10, ctype=afwDisplay.GREEN)
94  disp.line([(sx, sy), (dx, dy)], ctype=afwDisplay.GREEN)
95 
96  if matches is not None:
97  refCentroidKey = Point2DKey(matches[0].first.schema["centroid"])
98  sourceCentroidKey = Point2DKey(matches[0].second.schema["slot_Centroid"])
99  radArr = np.ndarray(len(matches))
100 
101  for i, m in enumerate(matches):
102  refCentroid = m.first.get(refCentroidKey)
103  sourceCentroid = m.second.get(sourceCentroidKey)
104  radArr[i] = math.hypot(*(refCentroid - sourceCentroid))
105  sx, sy = sourceCentroid
106  disp.dot("o", sx, sy, size=10, ctype=afwDisplay.YELLOW)
107  disp.line([refCentroid, sourceCentroid], ctype=afwDisplay.YELLOW)
108 
109  print("<match radius> = %.4g +- %.4g [%d matches]" %
110  (radArr.mean(), radArr.std(), len(matches)))
111 
112  if pause:
113  print("Dropping into debugger to allow inspection of display. Type 'continue' when done.")
114  import pdb
115  pdb.set_trace()
116 
117 
118 def plotAstrometry(
119  matches,
120  refCat=None,
121  sourceCat=None,
122  refMarker="x",
123  refColor="r",
124  sourceMarker="+",
125  sourceColor="g",
126  matchColor="y"
127 ):
128  """Plot reference objects, sources and matches
129 
130  Parameters
131  ----------
132  matches : `list` of `lsst.afw.table.ReferenceMatch`
133  list of matches
134  refCat : `lsst.afw.table.SimpleCatalog`
135  reference object catalog, or None to not plot reference objects
136  sourceCat : `lsst.afw.table.SourceCatalog`
137  source catalog, or None to not plot sources
138  refMarker : `str`
139  pyplot marker for reference objects
140  refColor : `str`
141  pyplot color for reference objects
142  sourceMarker : `str`
143  pyplot marker for sources
144  sourceColor : `str`
145  pyplot color for sources
146  matchColor : `str`
147  color for matches; can be a constant
148  or a function taking one match and returning a string
149 
150  Notes
151  -----
152  By default:
153 
154  - reference objects in refCat are shown as red X
155  - sources in sourceCat are shown as green +
156  - matches are shown as a yellow circle around the source and a line
157  connecting the reference object to the source
158  """
159  # delay importing plt to give users a chance to set the backend before calling this function
160  import matplotlib.pyplot as plt
161  refSchema = matches[0][0].schema
162  refCentroidKey = Point2DKey(refSchema["centroid"])
163  srcSchema = matches[0][1].schema
164  srcCentroidKey = Point2DKey(srcSchema["slot_Centroid"])
165 
166  if refCat is not None:
167  refXArr, refYArr = list(zip(*[ref.get(refCentroidKey) for ref in refCat]))
168  plt.plot(refXArr, refYArr, marker=refMarker, color=refColor, linestyle="")
169 
170  if sourceCat is not None:
171  srcXArr, srcYArr = list(zip(*[src.get(srcCentroidKey) for src in sourceCat]))
172  plt.plot(srcXArr, srcYArr, marker=sourceMarker, color=sourceColor, linestyle="")
173 
174  def makeLineSegmentData(refXYArr, srcXYArr, colorArr):
175  """Make a list of line segement data
176 
177  This is used to draw line segements between ref and src positions in the specified color
178 
179  Notes
180  -----
181  The returned data has the format:
182  [(refX0, srcX0), (refY0, srcY0), color0, (refX1, srcX1), (refY1, srcY1), color1,...]
183  """
184  if len(refXYArr) != len(srcXYArr):
185  raise RuntimeError("len(refXYArr) = %d != %d = len(srcXYArr)" %
186  (len(refXYArr), len(srcXYArr)))
187  if len(refXYArr) != len(colorArr):
188  raise RuntimeError("len(refXYArr) = %d != %d = len(colorArr)" %
189  (len(refXYArr), len(colorArr)))
190 
191  refXArr, refYArr = list(zip(*refXYArr))
192  srcXArr, srcYArr = list(zip(*srcXYArr))
193  refSrcXArr = list(zip(refXArr, srcXArr))
194  refSrcYArr = list(zip(refYArr, srcYArr))
195  dataList = []
196  for xycolor in zip(refSrcXArr, refSrcYArr, colorArr):
197  for val in xycolor:
198  dataList.append(val)
199  return dataList
200 
201  refXYArr, srcXYArr = \
202  list(zip(*[(match[0].get(refCentroidKey), match[1].get(srcCentroidKey)) for match in matches]))
203 
204  def plotSourceCircles(matches, color):
205  srcXYArr = [match[1].get(srcCentroidKey) for match in matches]
206  srcXArr, srcYArr = list(zip(*srcXYArr))
207  plt.plot(srcXArr, srcYArr, "o", mec=color, mfc="none", ms=10,)
208 
209  if callable(matchColor):
210  # different matches have different colors
211  matchColorArr = [matchColor(match) for match in matches]
212 
213  # plot circles for each color separately
214  matchColorSet = set(matchColorArr)
215  for color in matchColorSet:
216  subMatches = [match for match in matches if matchColor(match) == color]
217  plotSourceCircles(subMatches, color=color)
218  else:
219  matchColorArr = [matchColor]*len(refXYArr)
220  plotSourceCircles(matches, color=matchColor)
221 
222  lineSegData = makeLineSegmentData(refXYArr, srcXYArr, matchColorArr)
223  plt.plot(*lineSegData)
224 
225  plt.show()
def plotAstrometry(matches, refCat=None, sourceCat=None, refMarker="x", refColor="r", sourceMarker="+", sourceColor="g", matchColor="y")
Definition: display.py:127
PointKey< double > Point2DKey
Definition: aggregates.h:118
daf::base::PropertySet * set
Definition: fits.cc:832
def displayAstrometry(refCat=None, sourceCat=None, distortedCentroidKey=None, bbox=None, exposure=None, matches=None, frame=1, title="", pause=True)
Definition: display.py:35
daf::base::PropertyList * list
Definition: fits.cc:833