def setUp(self): random.seed(0) self.ImageSet = afwImage.ImagePcaF()
def imagePca(mosaics, visits=None, nComponent=3, log=False, rng=30, showEigen=True, showResiduals=False, showOriginal=True, showRecon=False, normalizeEimages=True, scale=False, frame0=0, verbose=False): if showOriginal and showRecon: raise RuntimeError( "You may not specify both showOriginal and showRecon") try: rng[0] except TypeError: rng = [rng, rng] if not visits: visits = sorted(mosaics.keys()) mosaics = mosaics.copy() for v in visits: mosaics[v] = mosaics[v].clone() pca = afwImage.ImagePcaF() mask = None for v in visits: im = mosaics[v] if not mask: mask = im.Factory(im.getDimensions()) maska = mask.getArray() X, Y = np.meshgrid(np.arange(mask.getWidth()), np.arange(mask.getHeight())) maska[np.where(np.hypot(X - 571, Y - 552) > 531)] = np.nan del maska mask[168:184, 701:838] = np.nan mask[667:733, 420:556] = np.nan mask[653:677, 548:570] = np.nan mask[1031:1047, 274:414] = np.nan if False: mask[866:931, 697:828] = np.nan mask[267:334, 145:276] = np.nan im += mask pca.addImage(im, afwMath.makeStatistics(im, afwMath.SUM).getValue()) pca.analyze() eValues = np.array(pca.getEigenValues()) eValues /= eValues[0] eImages = pca.getEigenImages() # # Fiddle eigen images (we don't care about orthogonality) # if False: f10 = 0.1 f20 = -0.3 f30 = 0.55 eImages[1].getArray()[:] += f10 * eImages[0].getArray() eImages[2].getArray()[:] += f20 * eImages[0].getArray() eImages[3].getArray()[:] += f30 * eImages[0].getArray() if nComponent: eImages = eImages[:nComponent] else: nComponent = len(eImages) # # Normalize # good = np.where(np.isfinite(eImages[0].getArray())) if normalizeEimages: for eim in eImages: eima = eim.getArray() eima /= 1e-3 * np.sqrt(np.sum(eima[good]**2)) # # Plot/display eigen values/images # frame = frame0 if showEigen: for i in range(len(eImages)): ds9.mtv(eImages[i], frame=frame, title="%d %.2g" % (i, eValues[i])) ds9.ds9Cmd("scale linear; scale mode zscale") frame += 1 pyplot.clf() if log: eValues = np.log10(eValues) pyplot.plot(eValues) pyplot.plot(eValues, marker='o') pyplot.xlim(-0.5, len(eValues)) pyplot.ylim(max(-5, pyplot.ylim()[0]), 0.05 if log else 1.05) pyplot.xlabel("n") pyplot.ylabel(r"$lg(\lambda)$" if log else r"$\lambda$") pyplot.show() if showOriginal or showRecon or showResiduals: # # Expand input images in the (modified) eImages # A = np.empty(nComponent * nComponent).reshape((nComponent, nComponent)) b = np.empty(nComponent) for v in visits: im = mosaics[v] if scale: im /= afwMath.makeStatistics(im, afwMath.MEANCLIP).getValue() for i in range(nComponent): b[i] = np.dot(eImages[i].getArray()[good], im.getArray()[good]) for j in range(i, nComponent): A[i, j] = np.dot(eImages[i].getArray()[good], eImages[j].getArray()[good]) A[j, i] = A[i, j] x = np.linalg.solve(A, b) #print v, A, b, x print "%d [%s] %s" % (v, ", ".join(["%9.2e" % _ for _ in x / x[0] ]), labels.get(v, "")) recon = eImages[0].clone() recon *= x[0] recona = recon.getArray() for i in range(1, nComponent): recona += x[i] * eImages[i].getArray() mtv = True if showOriginal or showRecon: if mtv: ds9.mtv(im if showOriginal else recon, frame=frame, title=v) else: ds9.erase(frame=frame) s0 = afwMath.makeStatistics(recon, afwMath.MEDIAN).getValue() s0 -= 0.5 * rng[0] ds9.ds9Cmd("scale linear; scale limits %g %g" % (s0, s0 + rng[0]), frame=frame) ds9.dot("%s %d" % ("orig" if showOriginal else "resid", v), int(0.5 * im.getWidth()), int(0.15 * im.getHeight()), frame=frame, ctype=ds9.RED) if labels.has_key(v): ds9.dot(labels[v], int(0.5 * im.getWidth()), int(0.85 * im.getHeight()), frame=frame, ctype=ds9.RED) frame += 1 if showResiduals: recon -= im if mtv: ds9.mtv(recon, frame=frame) else: ds9.erase(frame=frame) s0 = 0 s0 -= 0.5 * rng[1] ds9.ds9Cmd("scale linear; scale limits %g %g" % (s0, s0 + rng[1]), frame=frame) frame += 1 return eImages