Ejemplo n.º 1
0
def inspect_pupil(cfg):
    from mpl_toolkits.axes_grid1 import make_axes_locatable

    fig, axes = plt.subplots(1, 2)
    center = 15
    image_size = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    aberrations = [1E-6, 0]
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    pupil = fpmm.aberrated_pupil(image_size=cfg.patch_size,
                                 pupil_radius=pupil_radius,
                                 aberrations=aberrations,
                                 pixel_size=ps,
                                 wavelength=wlen)
    CTF = fpmm.generate_CTF(fx=0,
                            fy=0,
                            image_size=cfg.patch_size,
                            pupil_radius=pupil_radius)

    def put_colorbar(ax, im):
        divider = make_axes_locatable(ax)
        cax = divider.append_axes('right', size='5%', pad=0.05)
        fig.colorbar(im, cax=cax, orientation='vertical')

    im = axes[0].imshow(np.abs(pupil * CTF), cmap='Blues')
    put_colorbar(axes[0], im)
    im = axes[1].imshow(np.imag(pupil * CTF), cmap='RdBu')
    put_colorbar(axes[1], im)
    plt.show()
    return ct.set_iterator(cfg)
Ejemplo n.º 2
0
def fpm_reconstruct_classic(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).
    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation

    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    # k relative to absolute k factor
    npx = fpmm.get_image_size(cfg)
    ps_req = fpmm.get_pixel_size_required(cfg)
    wlen = fpmm.get_wavelength(cfg)
    led_gap = float(cfg.led_gap)
    height = float(cfg.sample_height)

    objectRecover_mag = (samples[(0, -1)]) / np.amax(samples[(0, -1)])
    objectRecover_phase = (samples[(0, -1)] - samples[(-1, 0)]) / (samples[
        (0, -1)] + samples[(-1, 0)])
    objectRecover_phase = np.pi * (
        objectRecover_phase) / np.amax(objectRecover_phase)
    objectRecover = objectRecover_mag * np.exp(1j * objectRecover_phase)
    objectRecover = np.ones(hrshape)
    # plt.imshow(objectRecover_phase)
    # plt.show()
    center = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(image_size=[lrsize, lrsize],
                            pupil_radius=pupil_radius) * .1
    # pupil = fpmm.aberrated_pupil(image_size=[lrsize, lrsize], pupil_radius=pupil_radius,
    #                             aberrations=[0,], pixel_size=ps, wavelength=wlen)
    objectRecoverFT = fftshift(fft2(objectRecover))  # shifted transform
    # Steps 2-5
    factor = (lrsize / hrshape[0])**2
    # For the convergence index
    # Steps 2-5
    for iteration in range(10):
        iterator = ct.set_iterator(cfg)
        # print('Iteration n. %d' % iteration)
        for it in iterator:
            # indexes, kx_rel, ky_rel = ct.n_to_krels(it=it, cfg=cfg, xoff=0, yoff=0)
            indexes = it['indexes']
            lr_sample = np.copy(samples[it['indexes']])
            led_number = np.array([it['ny'], it['nx']])
            # Convert indexes to pupil center coordinates kx, ky
            mc = np.array(cfg.mat_center)  #  Matrix center
            k_rel = np.sin(np.arctan((led_number - mc) * led_gap / height))
            k_abs = k_rel * ps_req * npx / wlen
            pup_center = k_abs + center
            # Pupil borders
            lp = np.round(pup_center - (lrsize + 1) / 2).astype(
                int)  # Extreme left low point
            hp = lp + lrsize  # Extreme right high point
            pupil_square = [slice(lp[0], hp[0]), slice(lp[1], hp[1])]

            lowResFT = factor * objectRecoverFT[pupil_square] * CTF
            im_lowRes = ifft2(ifftshift(lowResFT))
            im_lowRes = (1 / factor) * lr_sample * np.exp(
                1j * np.angle(im_lowRes))
            lowResFT = fftshift(fft2(im_lowRes)) * CTF

            objectRecoverFT[pupil_square] = (
                1 - CTF) * objectRecoverFT[pupil_square] + lowResFT
    im_out = ifft2(fftshift(objectRecoverFT))
    return im_out
Ejemplo n.º 3
0
def fpm_reconstruct_wrappable(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).

    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    kdsc = fpmm.get_k_discrete(cfg)

    objectRecover = np.ones(hrshape)
    xc, yc = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], pupil_radius)
    objectRecoverFT = fftshift(fft2(objectRecover))  # shifted transform
    # Steps 2-5
    factor = (lrsize / hrshape[0])**2
    # For the convergence index
    N = len(samples)

    for iteration in range(1):
        iterator = ct.set_iterator(cfg)
        # Patching for testing
        for it in iterator:
            # Coordinates manipulation
            acqpars = it['acqpars']
            indexes, kx_rel, ky_rel = ct.n_to_krels(it=it,
                                                    cfg=cfg,
                                                    xoff=0,
                                                    yoff=0)
            lr_sample = np.copy(samples[it['indexes']])
            [kx, ky] = kdsc * kx_rel, kdsc * ky_rel
            # Iteration step
            kyl = int(np.round(yc + ky - (lrsize + 1) / 2))
            kyh = kyl + lrsize
            kxl = int(np.round(xc + kx - (lrsize + 1) / 2))
            kxh = kxl + lrsize
            lowResFT = factor * objectRecoverFT[kyl:kyh, kxl:kxh] * CTF
            # Step 2: lr of the estimated image using the known pupil
            im_lowRes = ifft2(
                ifftshift(lowResFT))  # space pupil * fourier image
            im_lowRes = 1 / factor * lr_sample * np.exp(
                1j * np.angle(im_lowRes))
            ## pupil correction update
            lowResFT2 = fftshift(fft2(im_lowRes)) * CTF * 1. / pupil
            ORFT = objectRecoverFT[kyl:kyh, kxl:kxh].ravel()
            objectRecoverFT[kyl:kyh,
                            kxl:kxh] += (lowResFT2 - lowResFT) * np.conjugate(
                                pupil) / np.max(np.abs(pupil.ravel())**2)
            pupil += (lowResFT2 - lowResFT) * np.conjugate(
                objectRecoverFT[kyl:kyh, kxl:kxh]) / np.max(np.abs(ORFT)**2)
            ####################################################################
    im_out = ifft2(ifftshift(objectRecoverFT))
    return im_out
Ejemplo n.º 4
0
def fpm_reconstruct_epry(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).

    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    kdsc = fpmm.get_k_discrete(cfg)

    objectRecover = np.ones(hrshape)
    xc, yc = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], 1. * pupil_radius)
    # print(lrsize,hrshape)
    # plt.imshow(CTF)
    # plt.show()
    # pupil = np.ones_like(CTF, dtype='complex')
    pupil = 1
    # pupil = fpmm.aberrated_pupil(image_size=[lrsize, lrsize], pupil_radius=pupil_radius, aberrations=[-.1E-6,], pixel_size=ps, wavelength=wlen)*CTF
    # pupil = (rand(lrsize, lrsize)*(1+0*1j)+1)*0.5
    # gfk = exp(1j*rand(hrshape[0], hrshape[1])*pi)*fpmm.generate_CTF(0, 0, [hrshape[0], hrshape[1]], pupil_radius*.1)
    # gfk = np.zeros(hrshape, dtype='complex')
    gfk = fftshift(fft2(objectRecover))
    # gfk += rand(hrshape[0], hrshape[1])+1
    # gfk[yc-lrsize//2:yc+lrsize//2, xc-lrsize//2:xc+lrsize//2] = 1+rand(lrsize, lrsize)
    # gfk[yc, xc] = 1
    # Steps 2-5
    factor = (float(lrsize) / hrshape[0])**2
    # For convergence index
    e_gk = 0
    gk_prev = np.zeros_like(gfk)
    gk = np.ones_like(gfk) * (1 + 1j)
    gpk_prev = np.zeros_like(gfk)
    gpk = np.ones_like(gfk)
    ek = 1
    gm = 0
    a = 1
    b = 1
    sum_lr = 0
    for it in ct.set_iterator(cfg):
        indexes, kx_rel, ky_rel = ct.n_to_krels(it=it, cfg=cfg)
        sum_lr += np.sum(samples[it['indexes']])
    for iteration in range(15):

        iterator = ct.set_iterator(cfg)
        print('Iteration n. %d' % iteration)
        # Patching for testing
        e_gk = np.sum((abs(gk) - abs(gk_prev))**2) / (np.sum(abs(gk)**2))
        e_gpk = np.sum(
            (angle(gk) - angle(gk_prev))**2) / (np.sum(angle(gk)**2))
        gk_prev = gk
        print('Iteration %d | gk error %.2e | gpk error %.4f | ek %.2e |' %
              (iteration, e_gk, e_gpk, ek))
        # if (ek < 0.00001):
        #     break
        ek = 0
        gm = gm * e_gk
        for it in iterator:
            acqpars = it['acqpars']
            indexes, kx_rel, ky_rel = ct.n_to_krels(it=it,
                                                    cfg=cfg,
                                                    xoff=0.,
                                                    yoff=0.)
            lr_sample = np.copy(
                np.sqrt(samples[it['indexes']][:lrsize, :lrsize]))
            # From generate_il
            # Calculating coordinates
            [kx, ky] = kdsc * kx_rel, kdsc * ky_rel  # k_rel is sin(phi)
            # print(kdsc)
            kyl = int(np.round(yc + ky - (lrsize + 1) / 2))
            kyh = kyl + lrsize
            kxl = int(np.round(xc + kx - (lrsize + 1) / 2))
            kxh = kxl + lrsize
            delta_gfk1 = gfk[kyl:kyh, kxl:kxh] * pupil * CTF
            # print(kyl, kyh, kxl, kxh, yc+kx, yc+ky)
            # Step 2: lr of the estimated image using the known pupil
            delta_gk = ifft2(ifftshift(delta_gfk1))
            gk_prime = 1 / factor * lr_sample * delta_gk / abs(delta_gk)
            delta_gfk2 = fftshift(fft2(gk_prime))
            # update of the pupil and the fourier transform of the sample.
            delta_phi = delta_gfk2 - delta_gfk1
            sampled_gfk = gfk[kyl:kyh, kxl:kxh]
            sampled_gfk += a * delta_phi * conj(CTF * pupil) / amax(
                abs(CTF * pupil))**2
            if iteration > -1:
                pupil += b * delta_phi * conj(sampled_gfk) / amax(
                    abs(sampled_gfk))**2
            gfk[kyl:kyh, kxl:kxh] = sampled_gfk
            # test_img = delta_phi
            # plt.plot(abs(delta_phi[25,:]))
            # plt.show()
            ek += np.sum(abs(delta_gfk2 - delta_gfk1)**2) / sum_lr**2
        gk = ifft2(fftshift(gfk))
        # plt.imshow(np.log(abs(gfk)))
        # plt.show()
    return gk, pupil
Ejemplo n.º 5
0
def fpm_reconstruct(samples=None, it=None, cfg=None, debug=False):
    """ FPM reconstructon using the alternating projections algorithm. Here
    the complete samples and (optional) background images are loaded and Then
    cropped according to the patch size set in the configuration tuple (cfg).

    Args:
    -----
        samples: the acquired samples as a dictionary with angles as keys.
        backgrounds: the acquired background as a dictionary with angles as
                     keys. They must be acquired right after or before taking
                     the samples.
        it: iterator with additional sampling information for each sample.
        init_point: [xoff, yoff] center of the patch to be reconstructed.
        cfg: configuration (named tuple)
        debug: set it to 'True' if you want to see the reconstruction proccess
               (it slows down the reconstruction).

    Returns:
    --------
        (ndarray) The reconstructed modulus and phase of the sampled image.
    """
    # Getting the maximum angle by the given configuration
    # Step 1: initial estimation
    # objectRecover = initialize(hrshape, cfg, 'zero')
    lrsize = fpmm.get_image_size(cfg)
    pupil_radius = fpmm.get_pupil_radius(cfg)
    ps = fpmm.get_pixel_size(cfg)
    wlen = fpmm.get_wavelength(cfg)
    hrshape = fpmm.get_reconstructed_shape(cfg)
    kdsc = fpmm.get_k_discrete(cfg)

    # Initialization
    xc, yc = fpmm.image_center(hrshape)
    CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], pupil_radius)
    # gk_prime = np.ones(hrshape)*exp(1j*rand(hrshape)*pi)
    # gfk = np.ones(hrshape)*exp(1j*rand(hrshape[0], hrshape[1])*pi)
    objectRecover = np.ones(hrshape)
    gfk = fftshift(fft2(objectRecover))  # shifted transform

    factor = (lrsize / hrshape[0])**2
    # For the convergence index
    N = len(samples)
    beta = 0.
    gm = 0
    # lrarray = np.zeros((lrsize, lrsize, N))
    e_gk = 0
    gk_prev = np.zeros_like(gfk)
    gk = np.ones_like(gfk)
    gpk_prev = np.zeros_like(gfk)
    gpk = np.ones_like(gfk)
    for iteration in range(5):
        iterator = ct.set_iterator(cfg)
        # Patching for testing
        e_gk = np.sum((abs(gk) - abs(gk_prev))**2) / (np.sum(abs(gk)**2))
        e_gpk = np.sum(
            (angle(gk) - angle(gk_prev))**2) / (np.sum(angle(gk)**2))
        gk_prev = gk
        print('Iteration %d | gk error %.4f' % (iteration, e_gk))
        print(e_gpk)
        if (e_gk < 5E-5):
            break
        for it in iterator:
            gm = gm * e_gk
            CTF = fpmm.generate_CTF(0, 0, [lrsize, lrsize], pupil_radius)
            acqpars = it['acqpars']
            # indexes, theta, phi = it['indexes'], it['theta'], it['phi']
            indexes, kx_rel, ky_rel = ct.n_to_krels(it, cfg=cfg)
            lr_sample = np.copy(samples[it['indexes']][:lrsize, :lrsize])
            # Calculating coordinates
            [ky, kx] = kdsc * ky_rel, kdsc * kx_rel
            kyl = int(np.round(yc + ky - (lrsize + 1) / 2))
            kyh = kyl + lrsize
            kxl = int(np.round(xc + kx - (lrsize + 1) / 2))
            kxh = kxl + lrsize
            # Fourier-space update
            delta_gfk = factor * gfk[kyl:kyh, kxl:kxh] * CTF
            # Step 2: lr of the estimated image using the known pupil
            delta_gk = ifft2(ifftshift(delta_gfk)) + gm * rand(lrsize, lrsize)
            # phase = arctan(real(delta_gk)/(imag(delta_gk)+0.))
            phase = angle(delta_gk)
            gk_prime = lr_sample * exp(1j * phase) / factor
            delta_gfk = fftshift(fft2(gk_prime)) * CTF
            gfk[kyl:kyh,
                kxl:kxh] = (1 - CTF) * gfk[kyl:kyh, kxl:kxh] + delta_gfk
        gk = ifft2(fftshift(gfk))
    return gk, gk