Ejemplo n.º 1
0
def _CloudRep(psi, eps, *, code, step=1, vis=False):
    ## Initialize ##
    F = int(np.shape(psi)[0] / USER.KER_T)
    pos = [None] * F
    wgt = [None] * F

    tru = OP._LoadTruth(code)

    H_A, H_S = _IDFilters(np.shape(psi)[1:])

    ## Identify ##
    for f in np.arange(F, step=step):
        eps_f = eps[f, ...] / np.max(eps)
        psi_f = psi[f * USER.KER_T:(f + 1) * USER.KER_T, ...]
        Psi_f = npf.fftn(psi_f)
        psi_f = npf.ifftshift(psi_f)

        # Obtain the local blurring for each point found #
        psi_a = np.real_if_close(npf.ifftn(Psi_f * H_A))
        psi_s = np.real_if_close(npf.ifftn(Psi_f * H_S))

        # Determine where the smaller blur is bigger than the larger one #
        idx = np.nonzero(psi_a > psi_s + eps_f *
                         (np.mean(psi_f) + np.std(psi_f))
                         )  # + eps_f**2 *(np.mean(psi_f) + np.std(psi_f)))
        pos[f] = np.array([idx[3], idx[2], idx[1], idx[0] / USER.KER_T + f]).T
        wgt[f] = np.round(np.sqrt(psi_f**2 + ((psi_a + psi_s) / 2)**2)[idx], 3)

        if (vis):
            pts = np.zeros([0, 3])
            for p in range(len(tru)):
                if (f in tru[p].frm):
                    idx = np.nonzero(f == tru[p].frm)[0]
                    pts = np.concatenate((pts, tru[p].res[idx, :]), axis=0)

            plt.figure()
            plt.gca(position=[0, 0, 1, 1])
            plt.imshow(psi_f[0, 0, :, :], cmap='gray')
            plt.scatter(pos[f][:, 0], pos[f][:, 1], 100 * wgt[f], c='b')
            plt.plot(pts[:, 0],
                     pts[:, 1],
                     color='r',
                     marker='o',
                     linewidth=0,
                     fillstyle='none')
            plt.show()

    ## Output ##
    return pos, wgt
Ejemplo n.º 2
0
def _Identify(pos, wgt, img, *, code, vis=False):
	## Initialization ##
	F = len(wgt)
	clouds = list()

	# Progress #
	stpwch = time.time()
	timers = np.zeros((F))
	tru = OP._LoadTruth(code)			

	## Cluster points in each frame ##
	for f in range(F):
		if(len(wgt[f]) == 0): continue	# Check if there are any points in this frame #

		# Create a point cloud based on the points #
		pts = np.concatenate([pos[f], wgt[f][:,None]], axis=1)

		# Segment the point cloud to find clusters #
		cloud = PointCloud(pts, seg=True)

		# Why?? # vvv #
		# Weight threshold #
		clust = _CloudThr(cloud.clust, vis=vis)
		#		# ^^^ #
		clust = _Separate(clust)

		# Append new clusters to the batch #
		clouds.extend(clust)

		## Visualize ##
		"""
		if(vis):
			pts = np.zeros([0, 3]);
			for p in range(len(tru)):
				if(f in tru[p].frm):
					idx = np.nonzero(f == tru[p].frm)[0]
					pts = np.concatenate((pts, tru[p].res[idx,:]), axis=0)

			plt.figure()
			if(USER.KER_Z > 1):
				ax = plt.axes(position=[0,0,1,1], projection='3d')
				imclr = np.repeat((img/np.max(img))[f,0,:,:,None], 3, axis=2)
				xx, yy = np.meshgrid(range(np.shape(img)[2]), range(np.shape(img)[3]))
				ax.plot_surface(xx*USER.RES[0], yy*USER.RES[1], 0*xx, facecolors=imclr, rstride=8, cstride=8, zorder=-100000)
				for c in clust:
					ax.plot(c.abs[:,0], c.abs[:,1], c.abs[:,2], marker='o', linewidth=0, zorder=1000)
			else:
				ax = plt.axes(position=[0,0,1,1])
				ax.imshow(img[f,0,:,:], cmap='gray')
				for c in clust:
					ax.scatter(c.pos[:,0], c.pos[:,1], s=400*c.wgt, c='b')
				ax.plot(pts[:,0], pts[:,1], color='r', marker='o', linewidth=0, fillstyle='none')
			plt.show()
		"""

		# Progress Display #
		timers[f] = time.time() - stpwch
		if(f > 0):
			prefix = '(%s):\t%8.3f sec' % (code, timers[f])
			suffix = '(Remain: %5.0f sec)' % ((F-(f+1)) * np.mean(np.diff(timers[timers > 0])))
			VIS._ProgressBar(f+1, F, prefix=prefix, suffix=suffix)

	## Output ##
	return clouds
Ejemplo n.º 3
0
def RUN(scope, *, code='', update=False, visual=False):
    ## Update query ##
    if (update or not OP._CheckFile('%s\\%s_prep.tif' % (code, code))):
        # Pre-process the movie and the kernel, obtaining the local threshold #
        img_, ker_, eps_ = _Preprocess2(code, scope.img, scope.ker)

        # Ensure that all values are non-negative #
        if (USER.KER_T > 1):
            img_ = np.maximum(img_, 0)
            ker_ = np.maximum(ker_, 0)
            eps_ = np.maximum(eps_, 0)

        # Save the processed image, kernel, and local threshold #
        OP._SaveMov(img_, '%s\\%s_prep' % (code, code))  # Processed Movie	#
        OP._SaveKer(ker_, '%s\\%s_ker' % (code, code))  # Processed Kernel	#
        OP._SaveMov(eps_, '%s\\%s_eps' % (code, code))  # Local Threshold	#
    else:
        # Check if the movies exist #
        if (OP._CheckFile('%s\\%s_prep.tif' % (code, code))):
            # Load the processed image, kernel, and local threshold #
            img_ = OP._LoadMov('%s\\%s_prep' %
                               (code, code))  # Processed Movie	#
            ker_ = OP._LoadKer('%s\\%s_ker' %
                               (code, code))  # Processed Kernel	#
            eps_ = OP._LoadMov('%s\\%s_eps' %
                               (code, code))  # Local Threshold	#
        else:
            # Just stuff some zeros in there for now #
            img_ = np.zeros_like(scope.img)
            ker_ = np.zeros_like(scope.ker)
            eps_ = np.zeros_like(scope.img)

    ## Visualization query ##
    if (visual):
        f = 0
        tru = OP._LoadTruth(code)
        pts = np.zeros([0, 3])
        for p in range(len(tru)):
            if (f in tru[p].frm):
                idx = np.nonzero(f == tru[p].frm)[0]
                pts = np.concatenate((pts, tru[p].res[idx, :]), axis=0)

        # Movie #
        VIS._VisImg(img_[f, 0, :, :], 550, 50, pts)

        # Kernel #
        if ((USER.KER_Z > 1) and (USER.KER_T == 1)):
            VIS._VisImg(ker_[0, 0, :, :], 100, 50)
            VIS._VisImg(ker_[0, (USER.KER_Z) // 4, :, :], 100, 550)
            VIS._VisImg(ker_[0, (2 * USER.KER_Z) // 4, :, :], 550, 550)
            VIS._VisImg(ker_[0, (3 * USER.KER_Z) // 4, :, :], 1000, 550)
            VIS._VisImg(ker_[0, -1, :, :], 1000, 50)
        elif ((USER.KER_Z == 1) and (USER.KER_T > 1)):
            VIS._VisImg(ker_[0, 0, :, :], 100, 50)
            VIS._VisImg(ker_[(USER.KER_T) // 4, 0, :, :], 100, 550)
            VIS._VisImg(ker_[(2 * USER.KER_T) // 4, 0, :, :], 550, 550)
            VIS._VisImg(ker_[(3 * USER.KER_T) // 4, 0, :, :], 1000, 550)
            VIS._VisImg(ker_[-1, 0, :, :], 1000, 50)

        # Local Threshold #
        VIS._VisImg(eps_[f, 0, :, :], 1450, 50)
        VIS._VisImg(((img_ - eps_) * (img_ > eps_))[f, 0, :, :], 1450, 550,
                    pts)

        plt.show()

    ## Output ##
    return img_, ker_, eps_
Ejemplo n.º 4
0
def TEST_LIMITS(img, ker, eps, *, code='', visual=False):
    # Test runs for limitations only - 64x64! #
    ## Initialize ##
    F = np.shape(img)[0]
    Z = np.shape(img)[1]
    Y = np.shape(img)[2]
    X = np.shape(img)[3]

    pos = [None] * F
    wgt = [None] * F
    H_A, H_S = _IDFilters([Z * np.shape(ker)[1], Y, X])

    tru = OP._LoadTruth(code)
    error = np.full([int(USER.REC_ITER // 3), F, 3], np.nan)

    # Progress #
    stpwch = time.time()
    timers = np.zeros((F))
    t_remain = np.nan

    ## Recover Emitter Positions ##
    admm = ADMM(ker)
    for f in np.arange(F):
        psi_f = np.zeros((np.shape(ker)[0], Z * np.shape(ker)[1], Y, X))
        for z in range(Z):
            pb = (code, f, F, z, Z, 0, 1, 0, 1,
                  timers[f - (1 if (f > 0) else 0)], t_remain)
            zrng = [z * USER.KER_Z, (z + 1) * USER.KER_Z]

            # Split the image into each plane #
            img_ = img[f, z, :, :] / eps[f, z, :, :]
            eps_ = eps[f, z, :, :] / np.max(eps)

            # Obtain the point clouds per frame #
            psi_f[:, zrng[0]:zrng[1], ...], error = admm.Recover(img_,
                                                                 code=code,
                                                                 pb=pb,
                                                                 vis=visual,
                                                                 error=error)

        # Identify points in the cloud #
        Psi_f = npf.fftn(psi_f)
        psi_a = np.real_if_close(
            npf.ifftshift(npf.ifftn(Psi_f * H_A), axes=(-2, -1)))
        psi_s = np.real_if_close(
            npf.ifftshift(npf.ifftn(Psi_f * H_S), axes=(-2, -1)))

        # Determine where the smaller blur is bigger than the larger one #
        lhs = psi_a
        rhs = psi_s * (1 + 1 / eps_) + np.mean(psi_f)
        idx = np.nonzero(lhs > rhs)
        pos[f] = np.array([idx[3], idx[2], idx[1], idx[0] / USER.KER_T + f]).T
        wgt[f] = np.round(np.sqrt(psi_f**2 + ((psi_a + psi_s) / 2)**2)[idx], 3)

        # Progress Display #
        timers[f] = time.time() - stpwch
        if (sum(timers > 0) > 1):
            t_remain = (F - (f + 1)) * np.mean(np.diff(timers[timers > 0]))
            prefix = '(%s):\t%8.3f sec' % (code, timers[f])
            suffix = '(Remain: %5.0f sec)' % (t_remain)
            VIS._ProgressBar(f + 1, F, prefix=prefix, suffix=suffix)

    #if(error is not None):
    spi.savemat(OP.FOLD_MAT + code + ' error.mat', {'error': error})
    print(code + ' done!')
Ejemplo n.º 5
0
    def Recover(self,
                xi,
                *,
                code='',
                pb=('', 0, 1, 0, 0, 0, 0, 0, 0, 0, 0),
                vis=False,
                error=None,
                err=None):
        ## Initialization ##
        # Hard-code the random seed to make it reproducible #
        np.random.seed(0)

        # Pass xi into the goal image `y`, but pass it through the selection matrix `sig` first #
        y = np.zeros((np.shape(self.sig)[0], np.size(xi)))
        y[0, ...] = xi.reshape(np.size(xi), order="F")
        self.y[:] = np.reshape(self.sig @ y, self.sz, order="F")
        self.y_ = self.y.copy()

        # Reinitialize psi and the slack variables #
        self.Psi[:] = fftw.zeros_aligned(self.sz, dtype='complex64')
        self.S_0[:] = fftw.zeros_aligned(self.sz, dtype='complex64')
        self.S_1[:] = fftw.zeros_aligned(self.sz, dtype='complex64')
        self.S_2[:] = fftw.zeros_aligned(self.sz, dtype='complex64')

        # Localization error #
        if (vis or (error is not None)):
            pts = np.zeros([0, 3])
            if (error is not None):
                tru = OP._LoadMot(code)
                pts = tru[tru[:, :, 3] == pb[1], :]
                temp = []
                temp[:] = pts[:, 0]
                pts[:, 0] = pts[:, 1]  # Swap X & Y #
                pts[:, 1] = temp[:]
                H_A, H_S = _IDFilters(self.sz[1:])
            else:
                tru = OP._LoadTruth(code)
                for p in range(len(tru)):
                    if (pb[1] in tru[p].frm):
                        f = np.nonzero(pb[1] == tru[p].frm)[0]
                        pts = np.concatenate((pts, tru[p].res[f, :]), axis=0)

        ## Iterate Through ADMM ##
        stpwch = time.time()
        timers = np.zeros((USER.REC_ITER))
        for i in range(USER.REC_ITER):
            # Separate the result of this iteration from the previous solution `self.Psi`.  This allows us to build Psi incrementally, modularizing the regularization.
            Psi = fftw.zeros_aligned(self.sz, dtype='complex64')

            # Perform Regularizations #
            Psi = self.Reg_Accuracy(Psi, i)
            Psi = self.Reg_Sparcity(
                Psi, 1)  #np.minimum(np.maximum(2*i/USER.REC_ITER, 1/2), 3/2))
            Psi = self.Reg_Temporal(Psi)

            # Copy in the new result #
            self.Psi[:] = Psi.copy()

            # Alert us if we have an issue! #
            if (np.any(np.isnan(Psi))): raise ValueError("Psi has NaN values!")

            # Visualization #
            if (vis and (np.mod(i, USER.REC_ITER // 20) == 0)):
                self.BT_Psi()
                plt.clf()
                plt.gca(position=[0, 0, 1, 1])
                plt.imshow(np.log10(
                    npf.fftshift(np.sum(np.abs(self.psi), axis=(0, 1)))),
                           cmap='gray')
                plt.plot(pts[:, 0],
                         pts[:, 1],
                         color='r',
                         marker='o',
                         linewidth=0,
                         fillstyle='none')
                plt.clim(-3, 0)
                plt.draw()
                plt.pause(0.1)
            if ((error is not None) and (np.mod(i, 3) == 0) and (i > 60)):
                # Get psi #
                self.BT_Psi()

                # Find where psi is important #
                psi_f = npf.fftshift(np.abs(self.psi), axes=(-2, -1))

                # Identify points in the cloud #
                Psi_f = npf.fftn(psi_f)
                psi_a = np.real_if_close(
                    npf.ifftshift(npf.ifftn(Psi_f * H_A), axes=(-2, -1)))
                psi_s = np.real_if_close(
                    npf.ifftshift(npf.ifftn(Psi_f * H_S), axes=(-2, -1)))
                lhs = psi_a
                rhs = psi_s * (1 + 1) + np.mean(psi_f)
                idx = np.nonzero(lhs > rhs)
                pos = np.array([idx[3], idx[2], idx[1], idx[0] / USER.KER_T]).T
                wgt = np.round(
                    np.sqrt(psi_f**2 + ((psi_a + psi_s) / 2)**2)[idx], 3)

                if (0 < len(wgt) < 10000):
                    # Attempt a triangulation #
                    # Create a point cloud based on the points #
                    pnts = np.concatenate([pos, wgt[:, None]], axis=1)

                    # Segment the point cloud to find clusters #
                    cloud = PointCloud(pnts, seg=True)

                    # Why?? # vvv #
                    # Weight threshold #
                    clust = _CloudThr(cloud.clust)
                    #		# ^^^ #

                    clust = _Separate(clust)

                    if (len(clust) == 0): continue

                    # Evaluate the average minimum error per particle #
                    dist_x = np.zeros([np.shape(pts)[0], len(clust)])
                    dist_y = np.zeros([np.shape(pts)[0], len(clust)])
                    dist_z = np.zeros([np.shape(pts)[0], len(clust)])

                    # Evaluate the distance between each point and all clusters #
                    for c in range(len(clust)):
                        diff = (pts[:, :3] - clust[c].res) * [
                            *USER.RES, USER.DOF[0] / USER.KER_Z
                        ]
                        dist_x[:, c] = np.abs(diff[:, 0])
                        dist_y[:, c] = np.abs(diff[:, 1])
                        dist_z[:, c] = np.abs(diff[:, 2])

                    # Get the minimum error per cluster, average over all particles #
                    error[int(i // 3), pb[1], 0] = np.mean(np.min(dist_x,
                                                                  1))  # X
                    error[int(i // 3), pb[1], 1] = np.mean(np.min(dist_y,
                                                                  1))  # Y
                    error[int(i // 3), pb[1], 2] = np.mean(np.min(dist_z,
                                                                  1))  # Z
            #if((err is not None) and (np.mod(i, 3) == 0)):
            #	err[pb(1),i,:] = ComputeError(xi)

            # Progress Bar #
            timers[i] = time.time() - stpwch
            if (i > 0):
                prefix = '(%s):\t%8.3f sec' % (pb[0], pb[-2] + timers[i])
                #suffix = '(Remain: %5.0f sec)' % (pb[-1])
                suffix = '(Remain: %3.0f:%2.0f:%2.0f)  ' % (pb[-1] // 3600,
                                                            (pb[-1] % 3600) //
                                                            60, pb[-1] % 60)
                if (pb[4] > 1):  # Show Z progress #
                    VIS._ProgressBar(pb[1] + 1,
                                     pb[2],
                                     sub_i=pb[3] + 1,
                                     sub_I=pb[4],
                                     prefix=prefix,
                                     suffix=suffix)
                elif (pb[6] > 1
                      or pb[8] > 1):  # Show chunked iteration progress #
                    i_ = i + 1 + (pb[5] * pb[8] + pb[7]) * USER.REC_ITER
                    I_ = pb[6] * pb[8] * USER.REC_ITER
                    VIS._ProgressBar(pb[1] + 1,
                                     pb[2],
                                     sub_i=i_,
                                     sub_I=I_,
                                     prefix=prefix,
                                     suffix=suffix)
                else:
                    VIS._ProgressBar(pb[1] + 1,
                                     pb[2],
                                     sub_i=i,
                                     sub_I=USER.REC_ITER,
                                     prefix=prefix,
                                     suffix=suffix)
        if (vis):
            plt.ioff()
            plt.show()

        ## Output ##
        self.BT_Psi()
        return np.abs(self.psi), error
Ejemplo n.º 6
0
def _Recover(img, ker, eps, *, code='', step=1, vis=False):
    ## Initialize ##
    f0 = 0
    F = np.shape(img)[0]
    Z = np.shape(img)[1]
    Y = np.shape(img)[2]
    X = np.shape(img)[3]
    C = np.minimum(X, Y) if ((not USER.REC_CHUNK) or ((X <= 128) and
                                                      (Y <= 128))) else 64

    pos = [None] * F
    wgt = [None] * F
    H_A, H_S = _IDFilters([np.shape(ker)[0], Z * np.shape(ker)[1], Y, X])

    tru = OP._LoadTruth(code)

    # Progress #
    stpwch = time.time()
    timers = np.zeros((F))
    t_remain = np.nan

    # Truth #
    #error = np.full([int(USER.REC_ITER//3), F], np.nan)

    ## Recover Emitter Positions ##
    ker_ = ker[..., (Y - C) // 2:(Y + C) // 2, :][...,
                                                  (X - C) // 2:(X + C) // 2]
    admm = ADMM(ker_)
    for f in np.arange(F, step=step):
        psi_f = np.zeros((np.shape(ker)[0], Z * np.shape(ker)[1], Y, X))
        for z in range(Z):
            zrng = [z * USER.KER_Z, (z + 1) * USER.KER_Z]

            # Split the image into each plane #
            img_ = img[f + f0, z, :, :] / eps[
                f + f0,
                z, :, :]  # << ------------------------------------------------------------ #
            eps_ = eps[f + f0, z, :, :] / np.max(eps)

            # Chunk the image and obtain point clouds per frame #
            img_chunks, xrng, yrng, overlay = _Chunk(img_, C=C)
            M = np.shape(xrng)[0]
            N = np.shape(yrng)[0]
            for m in range(M):
                for n in range(N):
                    pb = (code, f, F, z, Z, m, M, n, N,
                          timers[f -
                                 (1 if (M == 1 and N == 1 and f > 0) else 0)],
                          t_remain)
                    if (np.ptp(img_chunks[n, m, ...]) > 2 * np.std(img_)):
                        psi, _ = admm.Recover(img_chunks[n, m, ...],
                                              code=code,
                                              pb=pb,
                                              vis=False)
                        psi = np.fft.fftshift(psi, axes=(-2, -1))
                        psi_f[:, zrng[0]:zrng[1],
                              ...][...,
                                   yrng[n,
                                        0]:yrng[n,
                                                1], :][...,
                                                       xrng[m,
                                                            0]:xrng[m,
                                                                    1]] += psi
                    timers[f] = time.time() - stpwch
            psi_f[:, zrng[0]:zrng[1], ...] /= np.maximum(overlay, 1)

        # Identify points in the cloud #
        Psi_f = npf.fftn(psi_f)
        psi_a = np.real_if_close(
            npf.ifftshift(npf.ifftn(Psi_f * H_A), axes=(-2, -1)))
        psi_s = np.real_if_close(
            npf.ifftshift(npf.ifftn(Psi_f * H_S), axes=(-2, -1)))

        # Determine where the smaller blur is bigger than the larger one #
        lhs = psi_a
        rhs = psi_s * (1 + 1 / eps_) + np.mean(psi_f) * (
            1 + (USER.KER_T > 1))  #eps_ * np.std(psi_f)/np.mean(psi_f)
        idx = np.nonzero(lhs > rhs)
        pos[f] = np.array([idx[3], idx[2], idx[1], idx[0] / USER.KER_T + f]).T
        wgt[f] = np.round(np.sqrt(psi_f**2 + ((psi_a + psi_s) / 2)**2)[idx], 3)

        # Visualization #
        if (vis):
            plt.figure(figsize=(15, 5))
            ax = plt.axes(position=[0, 0, 1 / 3, 0.9])
            ax.imshow(img_, cmap='gray')
            ax.set_title('Input image #%i/%i' % (f + 1, F + 1))

            ax = plt.axes(position=[1 / 3, 0, 1 / 3, 0.9])
            ax.imshow(np.sum(psi_f, axis=(0, 1)), cmap='gray')
            ax.set_title('Deconvolution')

            ax = plt.axes(position=[2 / 3, 0, 1 / 3, 0.9])
            ax.imshow(img_, cmap='gray')
            if (len(wgt[f]) > 0):
                ax.scatter(pos[f][:, 0],
                           pos[f][:, 1],
                           s=100 * (wgt[f] / np.max(wgt[f])),
                           c='r')
            ax.set_title('Point Cloud')

            if (USER.KER_Z > 1):
                plt.figure(figsize=(6, 6))
                ax = plt.axes(projection='3d',
                              position=[-0.05, -0.07, 1.1, 1.1])
                if (len(wgt[f]) > 0):
                    ax.scatter(pos[f][:, 0],
                               pos[f][:, 1],
                               pos[f][:, 2],
                               s=100 * (wgt[f] / np.max(wgt[f])))
                ax.view_init(azim=30, elev=10)
                ax.set_xlim(0, np.shape(img)[3])
                ax.set_ylim(0, np.shape(img)[2])
                ax.set_zlim(0, USER.KER_Z)
            plt.show()

        # Progress Display #
        timers[f] = time.time() - stpwch
        if (sum(timers > 0) > 1):
            t_remain = (F - (f + 1)) * np.mean(np.diff(timers[timers > 0]))
            prefix = '(%s):\t%8.3f sec' % (code, timers[f])
            #suffix = '(Remain: %5.0f sec)' % (t_remain)
            suffix = '(Remain: %3.0f:%2.0f:%2.0f)' % (t_remain // 3600,
                                                      (t_remain % 3600) // 60,
                                                      t_remain % 60)
            VIS._ProgressBar(f + 1, F, prefix=prefix, suffix=suffix)

    #import scipy.io as spi
    #spi.savemat(OP.FOLD_MAT + code + ' error.mat', {'error': error})

    ## Output ##
    return pos, wgt