22 """Support utilities for Measuring sources""" 25 __all__ = [
"DipoleTestImage"]
36 import lsst.meas.algorithms
as measAlg
38 from .dipoleFitTask
import DipoleFitAlgorithm
39 from .
import diffimLib
40 from .
import diffimTools
42 afwDisplay.setDefaultMaskTransparency(75)
46 def showSourceSet(sSet, xy0=(0, 0), frame=0, ctype=afwDisplay.GREEN, symb=
"+", size=2):
47 """Draw the (XAstrom, YAstrom) positions of a set of Sources. 49 Image has the given XY0. 51 disp = afwDisplay.afwDisplay(frame=frame)
52 with disp.Buffering():
54 xc, yc = s.getXAstrom() - xy0[0], s.getYAstrom() - xy0[1]
57 disp.dot(str(s.getId()), xc, yc, ctype=ctype, size=size)
59 disp.dot(symb, xc, yc, ctype=ctype, size=size)
67 ctype=None, ctypeUnused=None, ctypeBad=None, size=3,
68 frame=None, title="Spatial Cells"):
69 """Show the SpatialCells. 71 If symb is something that display.dot understands (e.g. "o"), the top 72 nMaxPerCell candidates will be indicated with that symbol, using ctype 75 disp = afwDisplay.Display(frame=frame)
76 disp.mtv(maskedIm, title=title)
77 with disp.Buffering():
78 origin = [-maskedIm.getX0(), -maskedIm.getY0()]
79 for cell
in kernelCellSet.getCellList():
80 afwDisplay.utils.drawBBox(cell.getBBox(), origin=origin, display=disp)
82 goodies = ctypeBad
is None 83 for cand
in cell.begin(goodies):
84 xc, yc = cand.getXCenter() + origin[0], cand.getYCenter() + origin[1]
85 if cand.getStatus() == afwMath.SpatialCellCandidate.BAD:
87 elif cand.getStatus() == afwMath.SpatialCellCandidate.GOOD:
89 elif cand.getStatus() == afwMath.SpatialCellCandidate.UNKNOWN:
95 disp.dot(symb, xc, yc, ctype=color, size=size)
98 rchi2 = cand.getChi2()
101 disp.dot(
"%d %.1f" % (cand.getId(), rchi2),
102 xc - size, yc - size - 4, ctype=color, size=size)
106 """Display Dia Sources. 112 disp = afwDisplay.Display(frame=frame)
113 for plane
in (
"BAD",
"CR",
"EDGE",
"INTERPOlATED",
"INTRP",
"SAT",
"SATURATED"):
114 disp.setMaskPlaneColor(plane, color=
"ignore")
116 mos = afwDisplay.utils.Mosaic()
117 for i
in range(len(sources)):
119 badFlag = isFlagged[i]
120 dipoleFlag = isDipole[i]
121 bbox = source.getFootprint().getBBox()
122 stamp = exposure.Factory(exposure, bbox,
True)
123 im = afwDisplay.utils.Mosaic(gutter=1, background=0, mode=
"x")
124 im.append(stamp.getMaskedImage())
125 lab =
"%.1f,%.1f:" % (source.getX(), source.getY())
127 ctype = afwDisplay.RED
130 ctype = afwDisplay.YELLOW
132 if not badFlag
and not dipoleFlag:
133 ctype = afwDisplay.GREEN
135 mos.append(im.makeMosaic(), lab, ctype)
136 title =
"Dia Sources" 137 mosaicImage = mos.makeMosaic(frame=frame, title=title)
142 resids=False, kernels=False):
143 """Display the Kernel candidates. 145 If kernel is provided include spatial model and residuals; 146 If chi is True, generate a plot of residuals/sqrt(variance), i.e. chi. 152 mos = afwDisplay.utils.Mosaic(gutter=5, background=0)
154 mos = afwDisplay.utils.Mosaic(gutter=5, background=-1)
156 candidateCenters = []
157 candidateCentersBad = []
159 for cell
in kernelCellSet.getCellList():
160 for cand
in cell.begin(
False):
163 resid = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
167 rchi2 = cand.getChi2()
171 if not showBadCandidates
and cand.isBad():
174 im_resid = afwDisplay.utils.Mosaic(gutter=1, background=-0.5, mode=
"x")
177 im = cand.getScienceMaskedImage()
178 im = im.Factory(im,
True)
179 im.setXY0(cand.getScienceMaskedImage().getXY0())
182 if (
not resids
and not kernels):
183 im_resid.append(im.Factory(im,
True))
185 im = cand.getTemplateMaskedImage()
186 im = im.Factory(im,
True)
187 im.setXY0(cand.getTemplateMaskedImage().getXY0())
190 if (
not resids
and not kernels):
191 im_resid.append(im.Factory(im,
True))
195 var = resid.getVariance()
196 var = var.Factory(var,
True)
197 np.sqrt(var.getArray(), var.getArray())
198 resid = resid.getImage()
200 bbox = kernel.shrinkBBox(resid.getBBox())
201 resid = resid.Factory(resid, bbox, deep=
True)
203 kim = cand.getKernelImage(diffimLib.KernelCandidateF.ORIG).convertF()
204 resid = kim.Factory(kim,
True)
205 im_resid.append(resid)
208 ski = afwImage.ImageD(kernel.getDimensions())
209 kernel.computeImage(ski,
False, int(cand.getXCenter()), int(cand.getYCenter()))
213 sbg = background(int(cand.getXCenter()), int(cand.getYCenter()))
214 sresid = cand.getDifferenceImage(sk, sbg)
217 resid = sresid.getImage()
219 bbox = kernel.shrinkBBox(resid.getBBox())
220 resid = resid.Factory(resid, bbox, deep=
True)
223 resid = kim.Factory(kim,
True)
224 im_resid.append(resid)
226 im = im_resid.makeMosaic()
228 lab =
"%d chi^2 %.1f" % (cand.getId(), rchi2)
229 ctype = afwDisplay.RED
if cand.isBad()
else afwDisplay.GREEN
231 mos.append(im, lab, ctype)
233 if False and np.isnan(rchi2):
234 disp = afwDisplay.Display(frame=1)
235 disp.mtv(cand.getScienceMaskedImage.getImage(), title=
"candidate")
236 print(
"rating", cand.getCandidateRating())
238 im = cand.getScienceMaskedImage()
239 center = (candidateIndex, cand.getXCenter() - im.getX0(), cand.getYCenter() - im.getY0())
242 candidateCentersBad.append(center)
244 candidateCenters.append(center)
251 title =
"Candidates & residuals" 252 mosaicImage = mos.makeMosaic(frame=frame, title=title)
258 """Display a Kernel's basis images. 260 mos = afwDisplay.utils.Mosaic()
262 for k
in kernel.getKernelList():
263 im = afwImage.ImageD(k.getDimensions())
264 k.computeImage(im,
False)
266 mos.makeMosaic(frame=frame, title=
"Kernel Basis Images")
274 numSample=128, keepPlots=True, maxCoeff=10):
275 """Plot the Kernel spatial model. 278 import matplotlib.pyplot
as plt
279 import matplotlib.colors
280 except ImportError
as e:
281 print(
"Unable to import numpy and matplotlib: %s" % e)
284 x0 = kernelCellSet.getBBox().getBeginX()
285 y0 = kernelCellSet.getBBox().getBeginY()
293 for cell
in kernelCellSet.getCellList():
294 for cand
in cell.begin(
False):
295 if not showBadCandidates
and cand.isBad():
297 candCenter = afwGeom.PointD(cand.getXCenter(), cand.getYCenter())
299 im = cand.getTemplateMaskedImage()
303 targetFits = badFits
if cand.isBad()
else candFits
304 targetPos = badPos
if cand.isBad()
else candPos
305 targetAmps = badAmps
if cand.isBad()
else candAmps
308 kp0 = np.array(cand.getKernel(diffimLib.KernelCandidateF.ORIG).getKernelParameters())
309 amp = cand.getCandidateRating()
311 targetFits = badFits
if cand.isBad()
else candFits
312 targetPos = badPos
if cand.isBad()
else candPos
313 targetAmps = badAmps
if cand.isBad()
else candAmps
315 targetFits.append(kp0)
316 targetPos.append(candCenter)
317 targetAmps.append(amp)
319 xGood = np.array([pos.getX()
for pos
in candPos]) - x0
320 yGood = np.array([pos.getY()
for pos
in candPos]) - y0
321 zGood = np.array(candFits)
323 xBad = np.array([pos.getX()
for pos
in badPos]) - x0
324 yBad = np.array([pos.getY()
for pos
in badPos]) - y0
325 zBad = np.array(badFits)
328 xRange = np.linspace(0, kernelCellSet.getBBox().getWidth(), num=numSample)
329 yRange = np.linspace(0, kernelCellSet.getBBox().getHeight(), num=numSample)
332 maxCoeff = min(maxCoeff, kernel.getNKernelParameters())
334 maxCoeff = kernel.getNKernelParameters()
336 for k
in range(maxCoeff):
337 func = kernel.getSpatialFunction(k)
338 dfGood = zGood[:, k] - np.array([func(pos.getX(), pos.getY())
for pos
in candPos])
342 dfBad = zBad[:, k] - np.array([func(pos.getX(), pos.getY())
for pos
in badPos])
344 yMin = min([yMin, dfBad.min()])
345 yMax = max([yMax, dfBad.max()])
346 yMin -= 0.05*(yMax - yMin)
347 yMax += 0.05*(yMax - yMin)
349 fRange = np.ndarray((len(xRange), len(yRange)))
350 for j, yVal
in enumerate(yRange):
351 for i, xVal
in enumerate(xRange):
352 fRange[j][i] = func(xVal, yVal)
358 fig.canvas._tkcanvas._root().lift()
362 fig.suptitle(
'Kernel component %d' % k)
365 ax = fig.add_axes((0.1, 0.05, 0.35, 0.35))
368 norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
369 im = ax.imshow(fRange, aspect=
'auto', norm=norm,
370 extent=[0, kernelCellSet.getBBox().getWidth() - 1,
371 0, kernelCellSet.getBBox().getHeight() - 1])
372 ax.set_title(
'Spatial polynomial')
373 plt.colorbar(im, orientation=
'horizontal', ticks=[vmin, vmax])
376 ax = fig.add_axes((0.1, 0.55, 0.35, 0.35))
377 ax.plot(-2.5*np.log10(candAmps), zGood[:, k],
'b+')
379 ax.plot(-2.5*np.log10(badAmps), zBad[:, k],
'r+')
380 ax.set_title(
"Basis Coefficients")
381 ax.set_xlabel(
"Instr mag")
382 ax.set_ylabel(
"Coeff")
385 ax = fig.add_axes((0.55, 0.05, 0.35, 0.35))
386 ax.set_autoscale_on(
False)
387 ax.set_xbound(lower=0, upper=kernelCellSet.getBBox().getHeight())
388 ax.set_ybound(lower=yMin, upper=yMax)
389 ax.plot(yGood, dfGood,
'b+')
391 ax.plot(yBad, dfBad,
'r+')
393 ax.set_title(
'dCoeff (indiv-spatial) vs. y')
396 ax = fig.add_axes((0.55, 0.55, 0.35, 0.35))
397 ax.set_autoscale_on(
False)
398 ax.set_xbound(lower=0, upper=kernelCellSet.getBBox().getWidth())
399 ax.set_ybound(lower=yMin, upper=yMax)
400 ax.plot(xGood, dfGood,
'b+')
402 ax.plot(xBad, dfBad,
'r+')
404 ax.set_title(
'dCoeff (indiv-spatial) vs. x')
409 if keepPlots
and not keptPlots:
412 print(
"%s: Please close plots when done." % __name__)
417 print(
"Plots closed, exiting...")
419 atexit.register(show)
424 showCenter=True, showEllipticity=True):
425 """Show a mosaic of Kernel images. 427 mos = afwDisplay.utils.Mosaic()
429 x0 = bbox.getBeginX()
430 y0 = bbox.getBeginY()
431 width = bbox.getWidth()
432 height = bbox.getHeight()
435 ny = int(nx*float(height)/width + 0.5)
439 schema = afwTable.SourceTable.makeMinimalSchema()
440 centroidName =
"base_SdssCentroid" 441 shapeName =
"base_SdssShape" 442 control = measBase.SdssCentroidControl()
443 schema.getAliasMap().set(
"slot_Centroid", centroidName)
444 schema.getAliasMap().set(
"slot_Centroid_flag", centroidName +
"_flag")
445 centroider = measBase.SdssCentroidAlgorithm(control, centroidName, schema)
446 sdssShape = measBase.SdssShapeControl()
447 shaper = measBase.SdssShapeAlgorithm(sdssShape, shapeName, schema)
448 table = afwTable.SourceTable.make(schema)
449 table.defineCentroid(centroidName)
450 table.defineShape(shapeName)
456 x = int(ix*(width - 1)/(nx - 1)) + x0
457 y = int(iy*(height - 1)/(ny - 1)) + y0
459 im = afwImage.ImageD(kernel.getDimensions())
460 ksum = kernel.computeImage(im,
False, x, y)
461 lab =
"Kernel(%d,%d)=%.2f" % (x, y, ksum)
if False else "" 467 w, h = im.getWidth(), im.getHeight()
468 centerX = im.getX0() + w//2
469 centerY = im.getY0() + h//2
470 src = table.makeRecord()
473 foot.addPeak(centerX, centerY, 1)
474 src.setFootprint(foot)
477 centroider.measure(src, exp)
478 centers.append((src.getX(), src.getY()))
480 shaper.measure(src, exp)
481 shapes.append((src.getIxx(), src.getIxy(), src.getIyy()))
485 mos.makeMosaic(frame=frame, title=title
if title
else "Model Kernel", mode=nx)
487 if centers
and frame
is not None:
488 disp = afwDisplay.Display(frame=frame)
490 with disp.Buffering():
491 for cen, shape
in zip(centers, shapes):
492 bbox = mos.getBBox(i)
494 xc, yc = cen[0] + bbox.getMinX(), cen[1] + bbox.getMinY()
496 disp.dot(
"+", xc, yc, ctype=afwDisplay.BLUE)
499 ixx, ixy, iyy = shape
500 disp.dot(
"@:%g,%g,%g" % (ixx, ixy, iyy), xc, yc, ctype=afwDisplay.RED)
506 kernel, background, testSources, config,
507 origVariance=False, nptsFull=1e6, keepPlots=True, titleFs=14):
508 """Plot diffim residuals for LOCAL and SPATIAL models. 514 for cell
in kernelCellSet.getCellList():
515 for cand
in cell.begin(
True):
517 if not (cand.getStatus() == afwMath.SpatialCellCandidate.GOOD):
520 diffim = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
521 orig = cand.getScienceMaskedImage()
523 ski = afwImage.ImageD(kernel.getDimensions())
524 kernel.computeImage(ski,
False, int(cand.getXCenter()), int(cand.getYCenter()))
526 sbg = background(int(cand.getXCenter()), int(cand.getYCenter()))
527 sdiffim = cand.getDifferenceImage(sk, sbg)
530 bbox = kernel.shrinkBBox(diffim.getBBox())
531 tdiffim = diffim.Factory(diffim, bbox)
532 torig = orig.Factory(orig, bbox)
533 tsdiffim = sdiffim.Factory(sdiffim, bbox)
536 candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
537 np.sqrt(torig.getVariance().getArray())))
538 spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
539 np.sqrt(torig.getVariance().getArray())))
541 candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
542 np.sqrt(tdiffim.getVariance().getArray())))
543 spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
544 np.sqrt(tsdiffim.getVariance().getArray())))
546 fullIm = diffExposure.getMaskedImage().getImage().getArray()
547 fullMask = diffExposure.getMaskedImage().getMask().getArray()
549 fullVar = exposure.getMaskedImage().getVariance().getArray()
551 fullVar = diffExposure.getMaskedImage().getVariance().getArray()
554 bitmaskBad |= afwImage.Mask.getPlaneBitMask(
'NO_DATA')
555 bitmaskBad |= afwImage.Mask.getPlaneBitMask(
'SAT')
556 idx = np.where((fullMask & bitmaskBad) == 0)
557 stride = int(len(idx[0])//nptsFull)
558 sidx = idx[0][::stride], idx[1][::stride]
559 allResids = fullIm[sidx]/np.sqrt(fullVar[sidx])
561 testFootprints = diffimTools.sourceToFootprintList(testSources, warpedTemplateExposure,
562 exposure, config, Log.getDefaultLogger())
563 for fp
in testFootprints:
564 subexp = diffExposure.Factory(diffExposure, fp[
"footprint"].getBBox())
565 subim = subexp.getMaskedImage().getImage()
567 subvar = afwImage.ExposureF(exposure, fp[
"footprint"].getBBox()).getMaskedImage().getVariance()
569 subvar = subexp.getMaskedImage().getVariance()
570 nonfitResids.append(np.ravel(subim.getArray()/np.sqrt(subvar.getArray())))
572 candidateResids = np.ravel(np.array(candidateResids))
573 spatialResids = np.ravel(np.array(spatialResids))
574 nonfitResids = np.ravel(np.array(nonfitResids))
578 from matplotlib.font_manager
import FontProperties
579 except ImportError
as e:
580 print(
"Unable to import pylab: %s" % e)
586 fig.canvas._tkcanvas._root().lift()
590 fig.suptitle(
"Diffim residuals: Normalized by sqrt(input variance)", fontsize=titleFs)
592 fig.suptitle(
"Diffim residuals: Normalized by sqrt(diffim variance)", fontsize=titleFs)
594 sp1 = pylab.subplot(221)
595 sp2 = pylab.subplot(222, sharex=sp1, sharey=sp1)
596 sp3 = pylab.subplot(223, sharex=sp1, sharey=sp1)
597 sp4 = pylab.subplot(224, sharex=sp1, sharey=sp1)
598 xs = np.arange(-5, 5.05, 0.1)
599 ys = 1./np.sqrt(2*np.pi)*np.exp(-0.5*xs**2)
601 sp1.hist(candidateResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 602 % (np.mean(candidateResids), np.var(candidateResids)))
603 sp1.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
604 sp1.set_title(
"Candidates: basis fit", fontsize=titleFs - 2)
605 sp1.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs - 6))
607 sp2.hist(spatialResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 608 % (np.mean(spatialResids), np.var(spatialResids)))
609 sp2.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
610 sp2.set_title(
"Candidates: spatial fit", fontsize=titleFs - 2)
611 sp2.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs - 6))
613 sp3.hist(nonfitResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 614 % (np.mean(nonfitResids), np.var(nonfitResids)))
615 sp3.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
616 sp3.set_title(
"Control sample: spatial fit", fontsize=titleFs - 2)
617 sp3.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs - 6))
619 sp4.hist(allResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 620 % (np.mean(allResids), np.var(allResids)))
621 sp4.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
622 sp4.set_title(
"Full image (subsampled)", fontsize=titleFs - 2)
623 sp4.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs - 6))
625 pylab.setp(sp1.get_xticklabels() + sp1.get_yticklabels(), fontsize=titleFs - 4)
626 pylab.setp(sp2.get_xticklabels() + sp2.get_yticklabels(), fontsize=titleFs - 4)
627 pylab.setp(sp3.get_xticklabels() + sp3.get_yticklabels(), fontsize=titleFs - 4)
628 pylab.setp(sp4.get_xticklabels() + sp4.get_yticklabels(), fontsize=titleFs - 4)
635 if keepPlots
and not keptPlots:
638 print(
"%s: Please close plots when done." % __name__)
643 print(
"Plots closed, exiting...")
645 atexit.register(show)
650 """Calculate first moment of a (kernel) image. 654 xarr = np.asarray([[el
for el
in range(x)]
for el2
in range(y)])
655 yarr = np.asarray([[el2
for el
in range(x)]
for el2
in range(y)])
658 centx = narr.sum()/sarrSum
660 centy = narr.sum()/sarrSum
665 """Calculate second moment of a (kernel) image. 670 xarr = np.asarray([[el
for el
in range(x)]
for el2
in range(y)])
671 yarr = np.asarray([[el2
for el
in range(x)]
for el2
in range(y)])
672 narr = sarr*np.power((xarr - centx), 2.)
674 xstd = np.sqrt(narr.sum()/sarrSum)
675 narr = sarr*np.power((yarr - centy), 2.)
676 ystd = np.sqrt(narr.sum()/sarrSum)
681 """Print differences in sky coordinates. 683 The difference is that between the source Position and its Centroid mapped 687 sCentroid = s.getCentroid()
688 sPosition = s.getCoord().getPosition(afwGeom.degrees)
689 dra = 3600*(sPosition.getX() - wcs.pixelToSky(sCentroid).getPosition(afwGeom.degrees).getX())/0.2
690 ddec = 3600*(sPosition.getY() - wcs.pixelToSky(sCentroid).getPosition(afwGeom.degrees).getY())/0.2
691 if np.isfinite(dra)
and np.isfinite(ddec):
696 """Create regions file for display from input source list. 698 fh = open(outfilename,
"w")
699 fh.write(
"global color=red font=\"helvetica 10 normal\" " 700 "select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source\nfk5\n")
703 (ra, dec) = wcs.pixelToSky(s.getCentroid()).getPosition(afwGeom.degrees)
705 (ra, dec) = s.getCoord().getPosition(afwGeom.degrees)
706 if np.isfinite(ra)
and np.isfinite(dec):
707 fh.write(
"circle(%f,%f,2\")\n"%(ra, dec))
713 """Draw the (RA, Dec) positions of a set of Sources. Image has the XY0. 715 disp = afwDisplay.Display(frame=frame)
716 with disp.Buffering():
718 (xc, yc) = wcs.skyToPixel(s.getCoord().getRa(), s.getCoord().getDec())
721 disp.dot(symb, xc, yc, ctype=ctype, size=size)
725 """Plot whisker diagram of astromeric offsets between results.matches. 727 refCoordKey = results.matches[0].first.getTable().getCoordKey()
728 inCentroidKey = results.matches[0].second.getTable().getCentroidKey()
729 positions = [m.first.get(refCoordKey)
for m
in results.matches]
730 residuals = [m.first.get(refCoordKey).getOffsetFrom(
731 newWcs.pixelToSky(m.second.get(inCentroidKey)))
for 732 m
in results.matches]
733 import matplotlib.pyplot
as plt
735 sp = fig.add_subplot(1, 1, 0)
736 xpos = [x[0].asDegrees()
for x
in positions]
737 ypos = [x[1].asDegrees()
for x
in positions]
738 xpos.append(0.02*(max(xpos) - min(xpos)) + min(xpos))
739 ypos.append(0.98*(max(ypos) - min(ypos)) + min(ypos))
740 xidxs = np.isfinite(xpos)
741 yidxs = np.isfinite(ypos)
742 X = np.asarray(xpos)[xidxs]
743 Y = np.asarray(ypos)[yidxs]
744 distance = [x[1].asArcseconds()
for x
in residuals]
746 distance = np.asarray(distance)[xidxs]
749 bearing = [x[0].asRadians()
for x
in residuals]
751 bearing = np.asarray(bearing)[xidxs]
752 U = (distance*np.cos(bearing))
753 V = (distance*np.sin(bearing))
754 sp.quiver(X, Y, U, V)
755 sp.set_title(
"WCS Residual")
760 """Utility class for dipole measurement testing. 762 Generate an image with simulated dipoles and noise; store the original 763 "pre-subtraction" images and catalogs as well. 764 Used to generate test data for DMTN-007 (http://dmtn-007.lsst.io). 767 def __init__(self, w=101, h=101, xcenPos=[27.], ycenPos=[25.], xcenNeg=[23.], ycenNeg=[25.],
768 psfSigma=2., flux=[30000.], fluxNeg=None, noise=10., gradientParams=None):
784 def _makeDipoleImage(self):
785 """Generate an exposure and catalog with the given dipole source(s). 794 dipole = posImage.clone()
795 di = dipole.getMaskedImage()
796 di -= negImage.getMaskedImage()
800 posDetectedBits = posImage.getMaskedImage().getMask().getArray() == dm.getPlaneBitMask(
"DETECTED")
801 negDetectedBits = negImage.getMaskedImage().getMask().getArray() == dm.getPlaneBitMask(
"DETECTED")
802 pos_det = dm.addMaskPlane(
"DETECTED_POS")
803 neg_det = dm.addMaskPlane(
"DETECTED_NEG")
806 dma[:, :] = posDetectedBits*pos_det + negDetectedBits*neg_det
807 self.diffim, self.posImage, self.posCatalog, self.negImage, self.negCatalog \
808 = dipole, posImage, posCatalog, negImage, negCatalog
810 def _makeStarImage(self, xc=[15.3], yc=[18.6], flux=[2500], schema=None, randomSeed=None):
811 """Generate an exposure and catalog with the given stellar source(s). 814 bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Point2I(self.
w - 1, self.
h - 1))
815 dataset = TestDataset(bbox, psfSigma=self.
psfSigma, threshold=1.)
817 for i
in range(len(xc)):
818 dataset.addSource(instFlux=flux[i], centroid=afwGeom.Point2D(xc[i], yc[i]))
821 schema = TestDataset.makeMinimalSchema()
822 exposure, catalog = dataset.realize(noise=self.
noise, schema=schema, randomSeed=randomSeed)
825 y, x = np.mgrid[:self.
w, :self.
h]
827 gradient = gp[0] + gp[1]*x + gp[2]*y
829 gradient += gp[3]*x*y + gp[4]*x*x + gp[5]*y*y
830 imgArr = exposure.getMaskedImage().getArrays()[0]
833 return exposure, catalog
837 fitResult = alg.fitDipole(source, **kwds)
841 """Utility function for detecting dipoles. 843 Detect pos/neg sources in the diffim, then merge them. A 844 bigger "grow" parameter leads to a larger footprint which 845 helps with dipole measurement for faint dipoles. 850 Whether to merge the positive and negagive detections into a single 852 diffim : `lsst.afw.image.exposure.exposure.ExposureF` 853 Difference image on which to perform detection. 854 detectSigma : `float` 855 Threshold for object detection. 857 Number of pixels to grow the footprints before merging. 859 Minimum bin size for the background (re)estimation (only applies if 860 the default leads to min(nBinX, nBinY) < fit order so the default 861 config parameter needs to be decreased, but not to a value smaller 862 than ``minBinSize``, in which case the fitting algorithm will take 863 over and decrease the fit order appropriately.) 867 sources : `lsst.afw.table.SourceCatalog` 868 If doMerge=True, the merged source catalog is returned OR 869 detectTask : `lsst.meas.algorithms.SourceDetectionTask` 870 schema : `lsst.afw.table.Schema` 871 If doMerge=False, the source detection task and its schema are 878 schema = afwTable.SourceTable.makeMinimalSchema()
881 detectConfig = measAlg.SourceDetectionConfig()
882 detectConfig.returnOriginalFootprints =
False 884 psfSigma = diffim.getPsf().computeShape().getDeterminantRadius()
887 detectConfig.thresholdPolarity =
"both" 888 detectConfig.thresholdValue = detectSigma
890 detectConfig.reEstimateBackground =
True 891 detectConfig.thresholdType =
"pixel_stdev" 893 while ((min(diffim.getWidth(), diffim.getHeight()))//detectConfig.background.binSize <
894 detectConfig.background.approxOrderX
and detectConfig.background.binSize > minBinSize):
895 detectConfig.background.binSize = max(minBinSize, detectConfig.background.binSize//2)
898 detectTask = measAlg.SourceDetectionTask(schema, config=detectConfig)
900 table = afwTable.SourceTable.make(schema)
901 catalog = detectTask.makeSourceCatalog(table, diffim, sigma=psfSigma)
905 fpSet = catalog.fpSets.positive
906 fpSet.merge(catalog.fpSets.negative, grow, grow,
False)
907 sources = afwTable.SourceCatalog(table)
908 fpSet.makeSources(sources)
913 return detectTask, schema
def _makeDipoleImage(self)
def showDiaSources(sources, exposure, isFlagged, isDipole, frame=None)
def makeRegions(sources, outfilename, wcs=None)
def __init__(self, w=101, h=101, xcenPos=[27.], ycenPos=[25.], xcenNeg=[23.], ycenNeg=[25.], psfSigma=2., flux=[30000.], fluxNeg=None, noise=10., gradientParams=None)
MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > * makeMaskedImage(typename std::shared_ptr< Image< ImagePixelT >> image, typename std::shared_ptr< Mask< MaskPixelT >> mask=Mask< MaskPixelT >(), typename std::shared_ptr< Image< VariancePixelT >> variance=Image< VariancePixelT >())
def showKernelSpatialCells(maskedIm, kernelCellSet, showChi2=False, symb="o", ctype=None, ctypeUnused=None, ctypeBad=None, size=3, frame=None, title="Spatial Cells")
std::shared_ptr< Exposure< ImagePixelT, MaskPixelT, VariancePixelT > > makeExposure(MaskedImage< ImagePixelT, MaskPixelT, VariancePixelT > &mimage, std::shared_ptr< geom::SkyWcs const > wcs=std::shared_ptr< geom::SkyWcs const >())
def _makeStarImage(self, xc=[15.3], yc=[18.6], flux=[2500], schema=None, randomSeed=None)
def plotKernelSpatialModel(kernel, kernelCellSet, showBadCandidates=True, numSample=128, keepPlots=True, maxCoeff=10)
def plotPixelResiduals(exposure, warpedTemplateExposure, diffExposure, kernelCellSet, kernel, background, testSources, config, origVariance=False, nptsFull=1e6, keepPlots=True, titleFs=14)
def printSkyDiffs(sources, wcs)
def showKernelCandidates(kernelCellSet, kernel, background, frame=None, showBadCandidates=True, resids=False, kernels=False)
def detectDipoleSources(self, doMerge=True, diffim=None, detectSigma=5.5, grow=3, minBinSize=32)
def calcWidth(arr, centx, centy)
def showSourceSet(sSet, xy0=(0, 0), frame=0, ctype=afwDisplay.GREEN, symb="+", size=2)
def plotWhisker(results, newWcs)
def showKernelMosaic(bbox, kernel, nx=7, ny=None, frame=None, title=None, showCenter=True, showEllipticity=True)
def showKernelBasis(kernel, frame=None)
def fitDipoleSource(self, source, kwds)
def showSourceSetSky(sSet, wcs, xy0, frame=0, ctype=afwDisplay.GREEN, symb="+", size=2)