22 """Support utilities for Measuring sources""" 25 __all__ = [
"DipoleTestImage"]
37 import lsst.meas.algorithms
as measAlg
39 from .dipoleFitTask
import DipoleFitAlgorithm
40 from .
import diffimLib
41 from .
import diffimTools
46 def showSourceSet(sSet, xy0=(0, 0), frame=0, ctype=ds9.GREEN, symb=
"+", size=2):
47 """Draw the (XAstrom, YAstrom) positions of a set of Sources. Image has the given XY0""" 51 xc, yc = s.getXAstrom() - xy0[0], s.getYAstrom() - xy0[1]
54 ds9.dot(str(s.getId()), xc, yc, frame=frame, ctype=ctype, size=size)
56 ds9.dot(symb, xc, yc, frame=frame, ctype=ctype, size=size)
64 ctype=None, ctypeUnused=None, ctypeBad=None, size=3,
65 frame=None, title="Spatial Cells"):
66 """Show the SpatialCells. If symb is something that ds9.dot 67 understands (e.g. "o"), the top nMaxPerCell candidates will be 68 indicated with that symbol, using ctype and size""" 70 ds9.mtv(maskedIm, frame=frame, title=title)
72 origin = [-maskedIm.getX0(), -maskedIm.getY0()]
73 for cell
in kernelCellSet.getCellList():
74 displayUtils.drawBBox(cell.getBBox(), origin=origin, frame=frame)
76 goodies = ctypeBad
is None 77 for cand
in cell.begin(goodies):
78 xc, yc = cand.getXCenter() + origin[0], cand.getYCenter() + origin[1]
79 if cand.getStatus() == afwMath.SpatialCellCandidate.BAD:
81 elif cand.getStatus() == afwMath.SpatialCellCandidate.GOOD:
83 elif cand.getStatus() == afwMath.SpatialCellCandidate.UNKNOWN:
89 ds9.dot(symb, xc, yc, frame=frame, ctype=color, size=size)
92 rchi2 = cand.getChi2()
95 ds9.dot(
"%d %.1f" % (cand.getId(), rchi2),
96 xc - size, yc - size - 4, frame=frame, ctype=color, size=size)
100 """Display Dia Sources 106 for plane
in (
"BAD",
"CR",
"EDGE",
"INTERPOlATED",
"INTRP",
"SAT",
"SATURATED"):
107 ds9.setMaskPlaneVisibility(plane,
False)
109 mos = displayUtils.Mosaic()
110 for i
in range(len(sources)):
112 badFlag = isFlagged[i]
113 dipoleFlag = isDipole[i]
114 bbox = source.getFootprint().getBBox()
115 stamp = exposure.Factory(exposure, bbox,
True)
116 im = displayUtils.Mosaic(gutter=1, background=0, mode=
"x")
117 im.append(stamp.getMaskedImage())
118 lab =
"%.1f,%.1f:" % (source.getX(), source.getY())
125 if not badFlag
and not dipoleFlag:
128 mos.append(im.makeMosaic(), lab, ctype)
129 title =
"Dia Sources" 130 mosaicImage = mos.makeMosaic(frame=frame, title=title)
135 resids=False, kernels=False):
136 """Display the Kernel candidates. 137 If kernel is provided include spatial model and residuals; 138 If chi is True, generate a plot of residuals/sqrt(variance), i.e. chi 145 mos = displayUtils.Mosaic(gutter=5, background=0)
147 mos = displayUtils.Mosaic(gutter=5, background=-1)
149 candidateCenters = []
150 candidateCentersBad = []
152 for cell
in kernelCellSet.getCellList():
153 for cand
in cell.begin(
False):
156 resid = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
160 rchi2 = cand.getChi2()
164 if not showBadCandidates
and cand.isBad():
167 im_resid = displayUtils.Mosaic(gutter=1, background=-0.5, mode=
"x")
170 im = cand.getScienceMaskedImage()
171 im = im.Factory(im,
True)
172 im.setXY0(cand.getScienceMaskedImage().getXY0())
175 if (
not resids
and not kernels):
176 im_resid.append(im.Factory(im,
True))
178 im = cand.getTemplateMaskedImage()
179 im = im.Factory(im,
True)
180 im.setXY0(cand.getTemplateMaskedImage().getXY0())
183 if (
not resids
and not kernels):
184 im_resid.append(im.Factory(im,
True))
188 var = resid.getVariance()
189 var = var.Factory(var,
True)
190 np.sqrt(var.getArray(), var.getArray())
191 resid = resid.getImage()
193 bbox = kernel.shrinkBBox(resid.getBBox())
194 resid = resid.Factory(resid, bbox,
True)
196 kim = cand.getKernelImage(diffimLib.KernelCandidateF.ORIG).convertF()
197 resid = kim.Factory(kim,
True)
198 im_resid.append(resid)
201 ski = afwImage.ImageD(kernel.getDimensions())
202 kernel.computeImage(ski,
False, int(cand.getXCenter()), int(cand.getYCenter()))
206 sbg = background(int(cand.getXCenter()), int(cand.getYCenter()))
207 sresid = cand.getDifferenceImage(sk, sbg)
210 resid = sresid.getImage()
212 bbox = kernel.shrinkBBox(resid.getBBox())
213 resid = resid.Factory(resid, bbox,
True)
216 resid = kim.Factory(kim,
True)
217 im_resid.append(resid)
219 im = im_resid.makeMosaic()
221 lab =
"%d chi^2 %.1f" % (cand.getId(), rchi2)
222 ctype = ds9.RED
if cand.isBad()
else ds9.GREEN
224 mos.append(im, lab, ctype)
226 if False and np.isnan(rchi2):
227 ds9.mtv(cand.getScienceMaskedImage.getImage(), title=
"candidate", frame=1)
228 print(
"rating", cand.getCandidateRating())
230 im = cand.getScienceMaskedImage()
231 center = (candidateIndex, cand.getXCenter() - im.getX0(), cand.getYCenter() - im.getY0())
234 candidateCentersBad.append(center)
236 candidateCenters.append(center)
243 title =
"Candidates & residuals" 244 mosaicImage = mos.makeMosaic(frame=frame, title=title)
250 """Display a Kernel's basis images 252 mos = displayUtils.Mosaic()
254 for k
in kernel.getKernelList():
255 im = afwImage.ImageD(k.getDimensions())
256 k.computeImage(im,
False)
258 mos.makeMosaic(frame=frame, title=
"Kernel Basis Images")
266 numSample=128, keepPlots=True, maxCoeff=10):
267 """Plot the Kernel spatial model.""" 270 import matplotlib.pyplot
as plt
271 import matplotlib.colors
272 except ImportError
as e:
273 print(
"Unable to import numpy and matplotlib: %s" % e)
276 x0 = kernelCellSet.getBBox().getBeginX()
277 y0 = kernelCellSet.getBBox().getBeginY()
285 for cell
in kernelCellSet.getCellList():
286 for cand
in cell.begin(
False):
287 if not showBadCandidates
and cand.isBad():
289 candCenter = afwGeom.PointD(cand.getXCenter(), cand.getYCenter())
291 im = cand.getTemplateMaskedImage()
295 targetFits = badFits
if cand.isBad()
else candFits
296 targetPos = badPos
if cand.isBad()
else candPos
297 targetAmps = badAmps
if cand.isBad()
else candAmps
300 kp0 = np.array(cand.getKernel(diffimLib.KernelCandidateF.ORIG).getKernelParameters())
301 amp = cand.getCandidateRating()
303 targetFits = badFits
if cand.isBad()
else candFits
304 targetPos = badPos
if cand.isBad()
else candPos
305 targetAmps = badAmps
if cand.isBad()
else candAmps
307 targetFits.append(kp0)
308 targetPos.append(candCenter)
309 targetAmps.append(amp)
311 xGood = np.array([pos.getX()
for pos
in candPos]) - x0
312 yGood = np.array([pos.getY()
for pos
in candPos]) - y0
313 zGood = np.array(candFits)
315 xBad = np.array([pos.getX()
for pos
in badPos]) - x0
316 yBad = np.array([pos.getY()
for pos
in badPos]) - y0
317 zBad = np.array(badFits)
320 xRange = np.linspace(0, kernelCellSet.getBBox().getWidth(), num=numSample)
321 yRange = np.linspace(0, kernelCellSet.getBBox().getHeight(), num=numSample)
324 maxCoeff = min(maxCoeff, kernel.getNKernelParameters())
326 maxCoeff = kernel.getNKernelParameters()
328 for k
in range(maxCoeff):
329 func = kernel.getSpatialFunction(k)
330 dfGood = zGood[:, k] - np.array([func(pos.getX(), pos.getY())
for pos
in candPos])
334 dfBad = zBad[:, k] - np.array([func(pos.getX(), pos.getY())
for pos
in badPos])
336 yMin = min([yMin, dfBad.min()])
337 yMax = max([yMax, dfBad.max()])
338 yMin -= 0.05 * (yMax - yMin)
339 yMax += 0.05 * (yMax - yMin)
341 fRange = np.ndarray((len(xRange), len(yRange)))
342 for j, yVal
in enumerate(yRange):
343 for i, xVal
in enumerate(xRange):
344 fRange[j][i] = func(xVal, yVal)
350 fig.canvas._tkcanvas._root().lift()
354 fig.suptitle(
'Kernel component %d' % k)
357 ax = fig.add_axes((0.1, 0.05, 0.35, 0.35))
360 norm = matplotlib.colors.Normalize(vmin=vmin, vmax=vmax)
361 im = ax.imshow(fRange, aspect=
'auto', norm=norm,
362 extent=[0, kernelCellSet.getBBox().getWidth()-1,
363 0, kernelCellSet.getBBox().getHeight()-1])
364 ax.set_title(
'Spatial polynomial')
365 plt.colorbar(im, orientation=
'horizontal', ticks=[vmin, vmax])
368 ax = fig.add_axes((0.1, 0.55, 0.35, 0.35))
369 ax.plot(-2.5*np.log10(candAmps), zGood[:, k],
'b+')
371 ax.plot(-2.5*np.log10(badAmps), zBad[:, k],
'r+')
372 ax.set_title(
"Basis Coefficients")
373 ax.set_xlabel(
"Instr mag")
374 ax.set_ylabel(
"Coeff")
377 ax = fig.add_axes((0.55, 0.05, 0.35, 0.35))
378 ax.set_autoscale_on(
False)
379 ax.set_xbound(lower=0, upper=kernelCellSet.getBBox().getHeight())
380 ax.set_ybound(lower=yMin, upper=yMax)
381 ax.plot(yGood, dfGood,
'b+')
383 ax.plot(yBad, dfBad,
'r+')
385 ax.set_title(
'dCoeff (indiv-spatial) vs. y')
388 ax = fig.add_axes((0.55, 0.55, 0.35, 0.35))
389 ax.set_autoscale_on(
False)
390 ax.set_xbound(lower=0, upper=kernelCellSet.getBBox().getWidth())
391 ax.set_ybound(lower=yMin, upper=yMax)
392 ax.plot(xGood, dfGood,
'b+')
394 ax.plot(xBad, dfBad,
'r+')
396 ax.set_title(
'dCoeff (indiv-spatial) vs. x')
401 if keepPlots
and not keptPlots:
404 print(
"%s: Please close plots when done." % __name__)
409 print(
"Plots closed, exiting...")
411 atexit.register(show)
416 showCenter=True, showEllipticity=True):
417 """Show a mosaic of Kernel images. 419 mos = displayUtils.Mosaic()
421 x0 = bbox.getBeginX()
422 y0 = bbox.getBeginY()
423 width = bbox.getWidth()
424 height = bbox.getHeight()
427 ny = int(nx*float(height)/width + 0.5)
431 schema = afwTable.SourceTable.makeMinimalSchema()
432 centroidName =
"base_SdssCentroid" 433 shapeName =
"base_SdssShape" 434 control = measBase.SdssCentroidControl()
435 schema.getAliasMap().set(
"slot_Centroid", centroidName)
436 schema.getAliasMap().set(
"slot_Centroid_flag", centroidName+
"_flag")
437 centroider = measBase.SdssCentroidAlgorithm(control, centroidName, schema)
438 sdssShape = measBase.SdssShapeControl()
439 shaper = measBase.SdssShapeAlgorithm(sdssShape, shapeName, schema)
440 table = afwTable.SourceTable.make(schema)
441 table.defineCentroid(centroidName)
442 table.defineShape(shapeName)
448 x = int(ix*(width-1)/(nx-1)) + x0
449 y = int(iy*(height-1)/(ny-1)) + y0
451 im = afwImage.ImageD(kernel.getDimensions())
452 ksum = kernel.computeImage(im,
False, x, y)
453 lab =
"Kernel(%d,%d)=%.2f" % (x, y, ksum)
if False else "" 458 w, h = im.getWidth(), im.getHeight()
459 centerX = im.getX0() + w//2
460 centerY = im.getY0() + h//2
461 src = table.makeRecord()
463 foot.addPeak(centerX, centerY, 1)
464 src.setFootprint(foot)
466 centroider.measure(src, exp)
467 centers.append((src.getX(), src.getY()))
469 shaper.measure(src, exp)
470 shapes.append((src.getIxx(), src.getIxy(), src.getIyy()))
472 mos.makeMosaic(frame=frame, title=title
if title
else "Model Kernel", mode=nx)
474 if centers
and frame
is not None:
476 with ds9.Buffering():
477 for cen, shape
in zip(centers, shapes):
478 bbox = mos.getBBox(i)
480 xc, yc = cen[0] + bbox.getMinX(), cen[1] + bbox.getMinY()
482 ds9.dot(
"+", xc, yc, ctype=ds9.BLUE, frame=frame)
485 ixx, ixy, iyy = shape
486 ds9.dot(
"@:%g,%g,%g" % (ixx, ixy, iyy), xc, yc, frame=frame, ctype=ds9.RED)
492 kernel, background, testSources, config,
493 origVariance=False, nptsFull=1e6, keepPlots=True, titleFs=14):
494 """Plot diffim residuals for LOCAL and SPATIAL models""" 499 for cell
in kernelCellSet.getCellList():
500 for cand
in cell.begin(
True):
502 if not (cand.getStatus() == afwMath.SpatialCellCandidate.GOOD):
505 diffim = cand.getDifferenceImage(diffimLib.KernelCandidateF.ORIG)
506 orig = cand.getScienceMaskedImage()
508 ski = afwImage.ImageD(kernel.getDimensions())
509 kernel.computeImage(ski,
False, int(cand.getXCenter()), int(cand.getYCenter()))
511 sbg = background(int(cand.getXCenter()), int(cand.getYCenter()))
512 sdiffim = cand.getDifferenceImage(sk, sbg)
515 bbox = kernel.shrinkBBox(diffim.getBBox())
516 tdiffim = diffim.Factory(diffim, bbox)
517 torig = orig.Factory(orig, bbox)
518 tsdiffim = sdiffim.Factory(sdiffim, bbox)
521 candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
522 np.sqrt(torig.getVariance().getArray())))
523 spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
524 np.sqrt(torig.getVariance().getArray())))
526 candidateResids.append(np.ravel(tdiffim.getImage().getArray() /
527 np.sqrt(tdiffim.getVariance().getArray())))
528 spatialResids.append(np.ravel(tsdiffim.getImage().getArray() /
529 np.sqrt(tsdiffim.getVariance().getArray())))
531 fullIm = diffExposure.getMaskedImage().getImage().getArray()
532 fullMask = diffExposure.getMaskedImage().getMask().getArray()
534 fullVar = exposure.getMaskedImage().getVariance().getArray()
536 fullVar = diffExposure.getMaskedImage().getVariance().getArray()
539 bitmaskBad |= afwImage.Mask.getPlaneBitMask(
'NO_DATA')
540 bitmaskBad |= afwImage.Mask.getPlaneBitMask(
'SAT')
541 idx = np.where((fullMask & bitmaskBad) == 0)
542 stride = int(len(idx[0]) // nptsFull)
543 sidx = idx[0][::stride], idx[1][::stride]
544 allResids = fullIm[sidx] / np.sqrt(fullVar[sidx])
546 testFootprints = diffimTools.sourceToFootprintList(testSources, warpedTemplateExposure,
547 exposure, config, Log.getDefaultLogger())
548 for fp
in testFootprints:
549 subexp = diffExposure.Factory(diffExposure, fp[
"footprint"].getBBox())
550 subim = subexp.getMaskedImage().getImage()
552 subvar = afwImage.ExposureF(exposure, fp[
"footprint"].getBBox()).getMaskedImage().getVariance()
554 subvar = subexp.getMaskedImage().getVariance()
555 nonfitResids.append(np.ravel(subim.getArray() / np.sqrt(subvar.getArray())))
557 candidateResids = np.ravel(np.array(candidateResids))
558 spatialResids = np.ravel(np.array(spatialResids))
559 nonfitResids = np.ravel(np.array(nonfitResids))
563 from matplotlib.font_manager
import FontProperties
564 except ImportError
as e:
565 print(
"Unable to import pylab: %s" % e)
571 fig.canvas._tkcanvas._root().lift()
575 fig.suptitle(
"Diffim residuals: Normalized by sqrt(input variance)", fontsize=titleFs)
577 fig.suptitle(
"Diffim residuals: Normalized by sqrt(diffim variance)", fontsize=titleFs)
579 sp1 = pylab.subplot(221)
580 sp2 = pylab.subplot(222, sharex=sp1, sharey=sp1)
581 sp3 = pylab.subplot(223, sharex=sp1, sharey=sp1)
582 sp4 = pylab.subplot(224, sharex=sp1, sharey=sp1)
583 xs = np.arange(-5, 5.05, 0.1)
584 ys = 1. / np.sqrt(2*np.pi)*np.exp(-0.5*xs**2)
586 sp1.hist(candidateResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 587 % (np.mean(candidateResids), np.var(candidateResids)))
588 sp1.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
589 sp1.set_title(
"Candidates: basis fit", fontsize=titleFs-2)
590 sp1.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs-6))
592 sp2.hist(spatialResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 593 % (np.mean(spatialResids), np.var(spatialResids)))
594 sp2.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
595 sp2.set_title(
"Candidates: spatial fit", fontsize=titleFs-2)
596 sp2.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs-6))
598 sp3.hist(nonfitResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 599 % (np.mean(nonfitResids), np.var(nonfitResids)))
600 sp3.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
601 sp3.set_title(
"Control sample: spatial fit", fontsize=titleFs-2)
602 sp3.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs-6))
604 sp4.hist(allResids, bins=xs, normed=
True, alpha=0.5, label=
"N(%.2f, %.2f)" 605 % (np.mean(allResids), np.var(allResids)))
606 sp4.plot(xs, ys,
"r-", lw=2, label=
"N(0,1)")
607 sp4.set_title(
"Full image (subsampled)", fontsize=titleFs-2)
608 sp4.legend(loc=1, fancybox=
True, shadow=
True, prop=FontProperties(size=titleFs-6))
610 pylab.setp(sp1.get_xticklabels()+sp1.get_yticklabels(), fontsize=titleFs-4)
611 pylab.setp(sp2.get_xticklabels()+sp2.get_yticklabels(), fontsize=titleFs-4)
612 pylab.setp(sp3.get_xticklabels()+sp3.get_yticklabels(), fontsize=titleFs-4)
613 pylab.setp(sp4.get_xticklabels()+sp4.get_yticklabels(), fontsize=titleFs-4)
620 if keepPlots
and not keptPlots:
623 print(
"%s: Please close plots when done." % __name__)
628 print(
"Plots closed, exiting...")
630 atexit.register(show)
635 """Calculate first moment of a (kernel) image""" 638 xarr = np.asarray([[el
for el
in range(x)]
for el2
in range(y)])
639 yarr = np.asarray([[el2
for el
in range(x)]
for el2
in range(y)])
642 centx = narr.sum()/sarrSum
644 centy = narr.sum()/sarrSum
649 """Calculate second moment of a (kernel) image""" 653 xarr = np.asarray([[el
for el
in range(x)]
for el2
in range(y)])
654 yarr = np.asarray([[el2
for el
in range(x)]
for el2
in range(y)])
655 narr = sarr*np.power((xarr - centx), 2.)
657 xstd = np.sqrt(narr.sum()/sarrSum)
658 narr = sarr*np.power((yarr - centy), 2.)
659 ystd = np.sqrt(narr.sum()/sarrSum)
664 """Print differences in sky coordinates between source Position and its Centroid mapped through Wcs""" 666 sCentroid = s.getCentroid()
667 sPosition = s.getCoord().getPosition(afwGeom.degrees)
668 dra = 3600*(sPosition.getX() - wcs.pixelToSky(sCentroid).getPosition(afwGeom.degrees).getX())/0.2
669 ddec = 3600*(sPosition.getY() - wcs.pixelToSky(sCentroid).getPosition(afwGeom.degrees).getY())/0.2
670 if np.isfinite(dra)
and np.isfinite(ddec):
675 """Create regions file for ds9 from input source list""" 676 fh = open(outfilename,
"w")
677 fh.write(
"global color=red font=\"helvetica 10 normal\" " 678 "select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 source\nfk5\n")
681 (ra, dec) = wcs.pixelToSky(s.getCentroid()).getPosition(afwGeom.degrees)
683 (ra, dec) = s.getCoord().getPosition(afwGeom.degrees)
684 if np.isfinite(ra)
and np.isfinite(dec):
685 fh.write(
"circle(%f,%f,2\")\n"%(ra, dec))
691 """Draw the (RA, Dec) positions of a set of Sources. Image has the XY0.""" 692 with ds9.Buffering():
694 (xc, yc) = wcs.skyToPixel(s.getCoord().getRa(), s.getCoord().getDec())
697 ds9.dot(symb, xc, yc, frame=frame, ctype=ctype, size=size)
701 """Plot whisker diagram of astromeric offsets between results.matches""" 702 refCoordKey = results.matches[0].first.getTable().getCoordKey()
703 inCentroidKey = results.matches[0].second.getTable().getCentroidKey()
704 positions = [m.first.get(refCoordKey)
for m
in results.matches]
705 residuals = [m.first.get(refCoordKey).getOffsetFrom(
706 newWcs.pixelToSky(m.second.get(inCentroidKey)))
for 707 m
in results.matches]
708 import matplotlib.pyplot
as plt
710 sp = fig.add_subplot(1, 1, 0)
711 xpos = [x[0].asDegrees()
for x
in positions]
712 ypos = [x[1].asDegrees()
for x
in positions]
713 xpos.append(0.02*(max(xpos) - min(xpos)) + min(xpos))
714 ypos.append(0.98*(max(ypos) - min(ypos)) + min(ypos))
715 xidxs = np.isfinite(xpos)
716 yidxs = np.isfinite(ypos)
717 X = np.asarray(xpos)[xidxs]
718 Y = np.asarray(ypos)[yidxs]
719 distance = [x[1].asArcseconds()
for x
in residuals]
721 distance = np.asarray(distance)[xidxs]
724 bearing = [x[0].asRadians()
for x
in residuals]
726 bearing = np.asarray(bearing)[xidxs]
727 U = (distance*np.cos(bearing))
728 V = (distance*np.sin(bearing))
729 sp.quiver(X, Y, U, V)
730 sp.set_title(
"WCS Residual")
736 """!Utility class for dipole measurement testing 738 Generate an image with simulated dipoles and noise; store the original "pre-subtraction" images 739 and catalogs as well. 740 Used to generate test data for DMTN-007 (http://dmtn-007.lsst.io). 743 def __init__(self, w=101, h=101, xcenPos=[27.], ycenPos=[25.], xcenNeg=[23.], ycenNeg=[25.],
744 psfSigma=2., flux=[30000.], fluxNeg=None, noise=10., gradientParams=None):
760 def _makeDipoleImage(self):
761 """!Generate an exposure and catalog with the given dipole source(s)""" 770 dipole = posImage.clone()
771 di = dipole.getMaskedImage()
772 di -= negImage.getMaskedImage()
776 posDetectedBits = posImage.getMaskedImage().getMask().getArray() == dm.getPlaneBitMask(
"DETECTED")
777 negDetectedBits = negImage.getMaskedImage().getMask().getArray() == dm.getPlaneBitMask(
"DETECTED")
778 pos_det = dm.addMaskPlane(
"DETECTED_POS")
779 neg_det = dm.addMaskPlane(
"DETECTED_NEG")
782 dma[:, :] = posDetectedBits*pos_det + negDetectedBits*neg_det
783 self.diffim, self.posImage, self.posCatalog, self.negImage, self.negCatalog \
784 = dipole, posImage, posCatalog, negImage, negCatalog
786 def _makeStarImage(self, xc=[15.3], yc=[18.6], flux=[2500], schema=None, randomSeed=None):
787 """!Generate an exposure and catalog with the given stellar source(s)""" 790 bbox = afwGeom.Box2I(afwGeom.Point2I(0, 0), afwGeom.Point2I(self.
w-1, self.
h-1))
791 dataset = TestDataset(bbox, psfSigma=self.
psfSigma, threshold=1.)
793 for i
in range(len(xc)):
794 dataset.addSource(instFlux=flux[i], centroid=afwGeom.Point2D(xc[i], yc[i]))
797 schema = TestDataset.makeMinimalSchema()
798 exposure, catalog = dataset.realize(noise=self.
noise, schema=schema, randomSeed=randomSeed)
801 y, x = np.mgrid[:self.
w, :self.
h]
803 gradient = gp[0] + gp[1] * x + gp[2] * y
805 gradient += gp[3] * x*y + gp[4] * x*x + gp[5] * y*y
806 imgArr = exposure.getMaskedImage().getArrays()[0]
809 return exposure, catalog
813 fitResult = alg.fitDipole(source, **kwds)
817 """!Utility function for detecting dipoles. 819 Detect pos/neg sources in the diffim, then merge them. A 820 bigger "grow" parameter leads to a larger footprint which 821 helps with dipole measurement for faint dipoles. 826 Whether to merge the positive and negagive detections into a single source table 827 diffim : `lsst.afw.image.exposure.exposure.ExposureF` 828 Difference image on which to perform detection 829 detectSigma : `float` 830 Threshold for object detection 832 Number of pixels to grow the footprints before merging 834 Minimum bin size for the background (re)estimation (only applies if the default leads to 835 min(nBinX, nBinY) < fit order so the default config parameter needs to be decreased, but not 836 to a value smaller than minBinSize, in which case the fitting algorithm will take over and 837 decrease the fit order appropriately.) 841 sources : `lsst.afw.table.SourceCatalog` 842 If doMerge=True, the merged source catalog is returned OR 843 detectTask : `lsst.meas.algorithms.SourceDetectionTask` 844 schema : `lsst.afw.table.Schema` 845 If doMerge=False, the source detection task and its schema are returned 851 schema = afwTable.SourceTable.makeMinimalSchema()
854 detectConfig = measAlg.SourceDetectionConfig()
855 detectConfig.returnOriginalFootprints =
False 857 psfSigma = diffim.getPsf().computeShape().getDeterminantRadius()
860 detectConfig.thresholdPolarity =
"both" 861 detectConfig.thresholdValue = detectSigma
863 detectConfig.reEstimateBackground =
True 864 detectConfig.thresholdType =
"pixel_stdev" 866 while ((min(diffim.getWidth(), diffim.getHeight()))//detectConfig.background.binSize <
867 detectConfig.background.approxOrderX
and detectConfig.background.binSize > minBinSize):
868 detectConfig.background.binSize = max(minBinSize, detectConfig.background.binSize//2)
871 detectTask = measAlg.SourceDetectionTask(schema, config=detectConfig)
873 table = afwTable.SourceTable.make(schema)
874 catalog = detectTask.makeSourceCatalog(table, diffim, sigma=psfSigma)
878 fpSet = catalog.fpSets.positive
879 fpSet.merge(catalog.fpSets.negative, grow, grow,
False)
880 sources = afwTable.SourceCatalog(table)
881 fpSet.makeSources(sources)
886 return detectTask, schema
def _makeDipoleImage(self)
Generate an exposure and catalog with the given dipole source(s)
def showDiaSources(sources, exposure, isFlagged, isDipole, frame=None)
Lightweight class containing methods for fitting a dipole model in a diffim, used by DipoleFitPlugin...
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)
Utility class for dipole measurement testing.
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)
Generate an exposure and catalog with the given stellar source(s)
def plotKernelSpatialModel(kernel, kernelCellSet, showBadCandidates=True, numSample=128, keepPlots=True, maxCoeff=10)
def showSourceSetSky(sSet, wcs, xy0, frame=0, ctype=ds9.GREEN, symb="+", size=2)
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 showSourceSet(sSet, xy0=(0, 0), frame=0, ctype=ds9.GREEN, symb="+", size=2)
def detectDipoleSources(self, doMerge=True, diffim=None, detectSigma=5.5, grow=3, minBinSize=32)
Utility function for detecting dipoles.
def calcWidth(arr, centx, centy)
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)