22__all__ = [
"displayAstrometry",
"plotAstrometry"]
33def displayAstrometry(refCat=None, sourceCat=None, distortedCentroidKey=None, bbox=None, exposure=None,
34 matches=None, frame=1, title="", pause=True):
35 """Show an astrometry debug image.
40 reference object catalog; must have fields "centroid_x" an
42 sourceCat : `lsst.afw.table.SourceCatalg`
43 source catalog; must have field
"slot_Centroid_x" and "slot_Centroid_y"
45 key
for sourceCat
with field to use
for distorted positions
49 bounding box of exposure; Used
if the exposure
is `
None`
51 List of matched objects
53 frame number
for display
57 pause
for inspection of display? This
is done by dropping into pdb.
62 - reference objects
in refCat are shown
as red X
63 - sources
in sourceCat are shown
as green +
64 - distorted sources
in sourceCat (position given by distortedCentroidKey)
66 - matches are shown
as a yellow circle around the source
and a yellow line
67 connecting the reference object
and source
68 -
if both exposure
and bbox are `
None`, no image
is displayed
71 disp = afwDisplay.getDisplay(frame=frame)
73 if exposure
is not None:
74 disp.mtv(exposure, title=title)
75 elif bbox
is not None:
76 disp.mtv(exposure=ExposureF(bbox), title=title)
78 with disp.Buffering():
79 if refCat
is not None:
80 refCentroidKey = Point2DKey(refCat.schema[
"centroid"])
82 rx, ry = refObj.get(refCentroidKey)
83 disp.dot(
"x", rx, ry, size=10, ctype=afwDisplay.RED)
85 if sourceCat
is not None:
86 sourceCentroidKey = Point2DKey(sourceCat.schema[
"slot_Centroid"])
87 for source
in sourceCat:
88 sx, sy = source.get(sourceCentroidKey)
89 disp.dot(
"+", sx, sy, size=10, ctype=afwDisplay.GREEN)
90 if distortedCentroidKey
is not None:
91 dx, dy = source.get(distortedCentroidKey)
92 disp.dot(
"o", dx, dy, size=10, ctype=afwDisplay.GREEN)
93 disp.line([(sx, sy), (dx, dy)], ctype=afwDisplay.GREEN)
95 if matches
is not None:
96 refCentroidKey = Point2DKey(matches[0].first.schema[
"centroid"])
97 sourceCentroidKey = Point2DKey(matches[0].second.schema[
"slot_Centroid"])
98 radArr = np.ndarray(len(matches))
100 for i, m
in enumerate(matches):
101 refCentroid = m.first.get(refCentroidKey)
102 sourceCentroid = m.second.get(sourceCentroidKey)
103 radArr[i] = math.hypot(*(refCentroid - sourceCentroid))
104 sx, sy = sourceCentroid
105 disp.dot(
"o", sx, sy, size=10, ctype=afwDisplay.YELLOW)
106 disp.line([refCentroid, sourceCentroid], ctype=afwDisplay.YELLOW)
108 print(
"<match radius> = %.4g +- %.4g [%d matches]" %
109 (radArr.mean(), radArr.std(), len(matches)))
112 print(
"Dropping into debugger to allow inspection of display. Type 'continue' when done.")
127 """Plot reference objects, sources and matches
134 reference object catalog, or None to
not plot reference objects
136 source catalog,
or None to
not plot sources
138 pyplot marker
for reference objects
140 pyplot color
for reference objects
142 pyplot marker
for sources
144 pyplot color
for sources
146 color
for matches; can be a constant
147 or a function taking one match
and returning a string
153 - reference objects
in refCat are shown
as red X
154 - sources
in sourceCat are shown
as green +
155 - matches are shown
as a yellow circle around the source
and a line
156 connecting the reference object to the source
159 import matplotlib.pyplot
as plt
160 refSchema = matches[0][0].schema
161 refCentroidKey = Point2DKey(refSchema[
"centroid"])
162 srcSchema = matches[0][1].schema
163 srcCentroidKey = Point2DKey(srcSchema[
"slot_Centroid"])
165 if refCat
is not None:
166 refXArr, refYArr =
list(zip(*[ref.get(refCentroidKey)
for ref
in refCat]))
167 plt.plot(refXArr, refYArr, marker=refMarker, color=refColor, linestyle=
"")
169 if sourceCat
is not None:
170 srcXArr, srcYArr =
list(zip(*[src.get(srcCentroidKey)
for src
in sourceCat]))
171 plt.plot(srcXArr, srcYArr, marker=sourceMarker, color=sourceColor, linestyle=
"")
173 def makeLineSegmentData(refXYArr, srcXYArr, colorArr):
174 """Make a list of line segement data
176 This is used to draw line segements between ref
and src positions
in the specified color
180 The returned data has the format:
181 [(refX0, srcX0), (refY0, srcY0), color0, (refX1, srcX1), (refY1, srcY1), color1,...]
183 if len(refXYArr) != len(srcXYArr):
184 raise RuntimeError(
"len(refXYArr) = %d != %d = len(srcXYArr)" %
185 (len(refXYArr), len(srcXYArr)))
186 if len(refXYArr) != len(colorArr):
187 raise RuntimeError(
"len(refXYArr) = %d != %d = len(colorArr)" %
188 (len(refXYArr), len(colorArr)))
190 refXArr, refYArr =
list(zip(*refXYArr))
191 srcXArr, srcYArr =
list(zip(*srcXYArr))
192 refSrcXArr =
list(zip(refXArr, srcXArr))
193 refSrcYArr =
list(zip(refYArr, srcYArr))
195 for xycolor
in zip(refSrcXArr, refSrcYArr, colorArr):
200 refXYArr, srcXYArr = \
201 list(zip(*[(match[0].get(refCentroidKey), match[1].get(srcCentroidKey))
for match
in matches]))
203 def plotSourceCircles(matches, color):
204 srcXYArr = [match[1].get(srcCentroidKey)
for match
in matches]
205 srcXArr, srcYArr =
list(zip(*srcXYArr))
206 plt.plot(srcXArr, srcYArr,
"o", mec=color, mfc=
"none", ms=10,)
208 if callable(matchColor):
210 matchColorArr = [matchColor(match)
for match
in matches]
213 matchColorSet =
set(matchColorArr)
214 for color
in matchColorSet:
215 subMatches = [match
for match
in matches
if matchColor(match) == color]
216 plotSourceCircles(subMatches, color=color)
218 matchColorArr = [matchColor]*len(refXYArr)
219 plotSourceCircles(matches, color=matchColor)
221 lineSegData = makeLineSegmentData(refXYArr, srcXYArr, matchColorArr)
222 plt.plot(*lineSegData)
A class to contain the data, WCS, and other information needed to describe an image of the sky.
A class used as a handle to a particular field in a table.
Custom catalog class for record/table subclasses that are guaranteed to have an ID,...
An integer coordinate rectangle.
daf::base::PropertyList * list
daf::base::PropertySet * set
plotAstrometry(matches, refCat=None, sourceCat=None, refMarker="x", refColor="r", sourceMarker="+", sourceColor="g", matchColor="y")
Lightweight representation of a geometric match between two records.