示例#1
0
def test_angle_offset():
    """
    Tests if things are still correct when there is a 2PI offset in the angles.
    """
    sino, angles = create_test_sino_2d()
    parameters = get_test_parameter_set(2)
    # reference
    r1 = []
    for p in parameters:
        f1 = odtbrain.backpropagate_2d(sino, angles, weight_angles=False, **p)
        r1.append(f1)
    # with offset
    angles[::2] += 2*np.pi*np.arange(angles[::2].shape[0])
    r2 = []
    for p in parameters:
        f2 = odtbrain.backpropagate_2d(sino, angles, weight_angles=False, **p)
        r2.append(f2)
    # with offset and weights
    r3 = []
    for p in parameters:
        f3 = odtbrain.backpropagate_2d(sino, angles, weight_angles=True, **p)
        r3.append(f3)
    assert np.allclose(np.array(r1).flatten().view(float),
                       np.array(r2).flatten().view(float))
    assert np.allclose(np.array(r2).flatten().view(float),
                       np.array(r3).flatten().view(float))
示例#2
0
def test_bpp_2d():
    sino, angles = create_test_sino_2d(N=10)
    p = get_test_parameter_set(1)[0]
    # complex
    jmc = mp.Value("i", 0)
    jmm = mp.Value("i", 0)

    odtbrain.backpropagate_2d(sino,
                              angles,
                              padval=0,
                              count=jmc,
                              max_count=jmm,
                              **p)
    assert jmc.value == jmm.value
    assert jmc.value != 0
示例#3
0
def test_2d_backprop_full():
    myframe = sys._getframe()
    sino, angles = create_test_sino_2d(ampl_range=(0.9, 1.1))
    parameters = get_test_parameter_set(2)
    r = list()
    for p in parameters:
        f = odtbrain.backpropagate_2d(sino, angles, **p)
        r.append(cutout(f))
    if WRITE_RES:
        write_results(myframe, r)
    assert np.allclose(np.array(r).flatten().view(float), get_results(myframe))
示例#4
0
def test_2d_backprop_real():
    """
    Check if the real reconstruction matches the real part
    of the complex reconstruction.
    """
    sino, angles = create_test_sino_2d()
    parameters = get_test_parameter_set(2)
    # complex
    r = list()
    for p in parameters:
        f = odtbrain.backpropagate_2d(sino, angles, padval=0, **p)
        r.append(f)
    # real
    r2 = list()
    for p in parameters:
        f = odtbrain.backpropagate_2d(sino,
                                      angles,
                                      padval=0,
                                      onlyreal=True,
                                      **p)
        r2.append(f)
    assert np.allclose(np.array(r).real, np.array(r2))
示例#5
0
def test_angle_swap():
    """
    Test if everything still works, when angles are swapped.
    """
    sino, angles = create_test_sino_2d()
    # remove elements so that we can see that weighting works
    angles = angles[:-2]
    sino = sino[:-2, :]
    parameters = get_test_parameter_set(2)
    # reference
    r1 = []
    for p in parameters:
        f1 = odtbrain.backpropagate_2d(sino, angles, weight_angles=True, **p)
        r1.append(f1)
    # change order of angles
    order = np.argsort(angles % .5)
    angles = angles[order]
    sino = sino[order, :]
    r2 = []
    for p in parameters:
        f2 = odtbrain.backpropagate_2d(sino, angles, weight_angles=True, **p)
        r2.append(f2)
    assert np.allclose(np.array(r1).flatten().view(float),
                       np.array(r2).flatten().view(float))
    
    lD = cfg["lD"] # measurement distance in wavelengths
    lC = cfg["lC"] # displacement from center of image
    size = cfg["size"]
    res = cfg["res"] # px/wavelengths
    A = cfg["A"] # number of projections

    #phantom = np.loadtxt(arc.open("mie_phantom.txt"))
    x = np.arange(size)-size/2.0
    X,Y = np.meshgrid(x,x)
    rad_px = radius*res
    phantom = np.array(((Y-lC*res)**2+X**2)<rad_px**2, dtype=np.float)*(ncyl-nmed)+nmed

    # Born
    u_sinB = (sino/u0*u0_single-u0_single) #fake born
    fB = odt.backpropagate_2d(u_sinB, angles, res, nmed, lD*res)
    nB = odt.odt_to_ri(fB, res, nmed)
    
    # Rytov
    u_sinR = odt.sinogram_as_rytov(sino/u0)
    fR = odt.backpropagate_2d(u_sinR, angles, res, nmed, lD*res)
    nR = odt.odt_to_ri(fR, res, nmed)
    
    # Rytov 50
    u_sinR50 = odt.sinogram_as_rytov((sino/u0)[::5,:])
    fR50 = odt.backpropagate_2d(u_sinR50, angles[::5], res, nmed, lD*res)
    nR50 = odt.odt_to_ri(fR50, res, nmed)
    
    
    # Plot sinogram phase and amplitude
    ph = unwrap.unwrap(np.angle(sino/u0))
示例#7
0
    ## Setup background
    t_RealBack = float('-1.60175172169E-02')
    t_ImagBack = float('-1.85142597885E-02')
    t_ComplexBack = t_RealBack + 1j*t_ImagBack
    # t_SinoBack = np.tile(t_ComplexBack, t_SudutProj*t_SensorInterp).reshape(t_SudutProj, t_SensorInterp)
    t_SinoBack = np.tile(t_ComplexBack, t_SudutInterp*t_SensorInterp).reshape(t_SudutInterp, t_SensorInterp)
    # print(t_SinoBack)

    ## Prep for Reconstruksi Citra
    t_Theta = np.linspace(0., 360., t_SudutInterp, endpoint=False)

    ## Do Fasa background corrected
    t_SinoCorrected = t_SinoSudutInterp/t_SinoBack

    ## Do backpropagate 2D
    u_sinR  = odt.sinogram_as_rytov(t_SinoCorrected)
    angles  = np.linspace(0, 2*np.pi, t_SudutInterp, endpoint=False)
    res     = 9.0
    nmed    = 2.4
    lD      = 1.0
    fR      = odt.backpropagate_2d(u_sinR, angles, res, nmed, lD * res)
    nR      = odt.odt_to_ri(fR, res, nmed)

    ## plot data
    fig, (ax1) = plt.subplots(1, 1)
    ax1.imshow(ndimage.median_filter(nR.real*-1, size=7))
    ax1.set_xlabel('pixel')
    ax1.set_ylabel('pixel')
    plt.show()
X, Y = np.meshgrid(x, x)
rad_px = radius * res
phantom = np.array(((Y - lC * res)**2 + X**2) < rad_px**2,
                   dtype=np.float) * (ncyl - nmed) + nmed

u_sinR = odt.sinogram_as_rytov(sino / u0)

# Rytov 200 projections
# remove 50 projections from total of 250 projections
remove200 = np.argsort(angles % .0002)[:50]
angles200 = np.delete(angles, remove200, axis=0)
u_sinR200 = np.delete(u_sinR, remove200, axis=0)
ph200 = unwrap.unwrap(np.angle(sino / u0))
ph200[remove200] = 0

fR200 = odt.backpropagate_2d(u_sinR200, angles200, res, nmed, lD * res)
nR200 = odt.odt_to_ri(fR200, res, nmed)
fR200nw = odt.backpropagate_2d(u_sinR200,
                               angles200,
                               res,
                               nmed,
                               lD * res,
                               weight_angles=False)
nR200nw = odt.odt_to_ri(fR200nw, res, nmed)

# Rytov 50 projections
remove50 = np.argsort(angles % .0002)[:200]
angles50 = np.delete(angles, remove50, axis=0)
u_sinR50 = np.delete(u_sinR, remove50, axis=0)
ph50 = unwrap.unwrap(np.angle(sino / u0))
ph50[remove50] = 0
lD = cfg["lD"]  # measurement distance in wavelengths
lC = cfg["lC"]  # displacement from center of image
size = cfg["size"]
res = cfg["res"]  # px/wavelengths
A = cfg["A"]  # number of projections

x = np.arange(size) - size / 2
X, Y = np.meshgrid(x, x)
rad_px = radius * res
phantom = np.array(((Y - lC * res)**2 + X**2) < rad_px**2,
                   dtype=np.float) * (ncyl - nmed) + nmed

# Born
u_sinB = (sino / u0 * u0_single - u0_single)  # fake born
fB = odt.backpropagate_2d(u_sinB, angles, res, nmed, lD * res)
nB = odt.odt_to_ri(fB, res, nmed)

# Rytov
u_sinR = odt.sinogram_as_rytov(sino / u0)
fR = odt.backpropagate_2d(u_sinR, angles, res, nmed, lD * res)
nR = odt.odt_to_ri(fR, res, nmed)

# Rytov 50
u_sinR50 = odt.sinogram_as_rytov((sino / u0)[::5, :])
fR50 = odt.backpropagate_2d(u_sinR50, angles[::5], res, nmed, lD * res)
nR50 = odt.odt_to_ri(fR50, res, nmed)

# Plot sinogram phase and amplitude
ph = odt.sinogram_as_radon(sino / u0)
示例#10
0
x = np.arange(size) - size / 2.0
X, Y = np.meshgrid(x, x)
rad_px = radius * res
phantom = np.array(((Y - lC * res)**2 + X**2) < rad_px**2,
                   dtype=np.float) * (ncyl - nmed) + nmed

u_sinR = odt.sinogram_as_rytov(sino / u0)

# Rytov 100 projections evenly distributed
removeeven = np.argsort(angles % .002)[:150]
angleseven = np.delete(angles, removeeven, axis=0)
u_sinReven = np.delete(u_sinR, removeeven, axis=0)
pheven = odt.sinogram_as_radon(sino / u0)
pheven[removeeven] = 0

fReven = odt.backpropagate_2d(u_sinReven, angleseven, res, nmed, lD * res)
nReven = odt.odt_to_ri(fReven, res, nmed)
fRevennw = odt.backpropagate_2d(u_sinReven,
                                angleseven,
                                res,
                                nmed,
                                lD * res,
                                weight_angles=False)
nRevennw = odt.odt_to_ri(fRevennw, res, nmed)

# Rytov 100 projections more than 180
removemiss = 249 - \
    np.concatenate((np.arange(100), 100 + np.arange(150)[::3]))
anglesmiss = np.delete(angles, removemiss, axis=0)
u_sinRmiss = np.delete(u_sinR, removemiss, axis=0)
phmiss = odt.sinogram_as_radon(sino / u0)
    x = np.arange(size)-size/2.0
    X,Y = np.meshgrid(x,x)
    rad_px = radius*res
    phantom = np.array(((Y-lC*res)**2+X**2)<rad_px**2, dtype=np.float)*(ncyl-nmed)+nmed

    u_sinR = odt.sinogram_as_rytov(sino/u0)
    
    # Rytov 200 projections    
    # remove 50 projections from total of 250 projections
    remove200 = np.argsort(angles % .002)[:50]
    angles200 = np.delete(angles, remove200, axis=0)
    u_sinR200 = np.delete(u_sinR, remove200, axis=0)
    ph200 = unwrap.unwrap(np.angle(sino/u0))
    ph200[remove200] = 0
    
    fR200 = odt.backpropagate_2d(u_sinR200, angles200, res, nmed, lD*res)
    nR200 = odt.odt_to_ri(fR200, res, nmed)
    fR200nw = odt.backpropagate_2d(u_sinR200, angles200, res, nmed, lD*res, weight_angles=False)
    nR200nw = odt.odt_to_ri(fR200nw, res, nmed)
    
    
    # Rytov 50 projections
    remove50 = np.argsort(angles % .002)[:200]
    angles50 = np.delete(angles, remove50, axis=0)
    u_sinR50 = np.delete(u_sinR, remove50, axis=0)
    ph50 = unwrap.unwrap(np.angle(sino/u0))
    ph50[remove50] = 0
    
    fR50 = odt.backpropagate_2d(u_sinR50, angles50, res, nmed, lD*res)
    nR50 = odt.odt_to_ri(fR50, res, nmed)    
    fR50nw = odt.backpropagate_2d(u_sinR50, angles50, res, nmed, lD*res, weight_angles=False)
示例#12
0
def backpropagate_sinogram(
    sinogram,
    angles,
    approx,
    res,
    nm,
    ld=0,
):
    """Backpropagate a 2D or 3D sinogram

    Parameters
    ----------
    sinogram: complex ndarray
        The scattered field data
    angles: 1d ndarray
        The angles at which the sinogram data were recorded
    approx: str
        Approximation to use, one of ["radon", "born", "rytov"]
    res: float
        Size of vacuum wavelength in pixels
    nm: float
        Refractive index of surrounding medium
    ld: float
        Reconstruction distance. Values !=0 only make sense for the
        Born approximation (which itself is not very usable).
        See the ODTbrain documentation for more information.

    Returns
    -------
    ri: ndarray
        The 2D or 3D reconstructed refractive index
    """
    sshape = len(sinogram.shape)
    assert sshape in [2, 3], "sinogram must have dimension 2 or 3"

    uSin = sinogram
    assert approx in ["radon", "born", "rytov"]

    if approx == "rytov":
        uSin = odt.sinogram_as_rytov(uSin)
    elif approx == "radon":
        uSin = odt.sinogram_as_radon(uSin)

    if approx in ["born", "rytov"]:
        # Perform reconstruction with ODT
        if sshape == 2:
            f = odt.backpropagate_2d(uSin,
                                     angles=angles,
                                     res=res,
                                     nm=nm,
                                     lD=ld)
        else:
            f = odt.backpropagate_3d(uSin,
                                     angles=angles,
                                     res=res,
                                     nm=nm,
                                     lD=ld)

        ri = odt.odt_to_ri(f, res, nm)
    else:
        # Perform reconstruction with OPT
        # works in 2d and 3d
        f = rt.backproject(uSin, angles=angles)
        ri = odt.opt_to_ri(f, res, nm)

    return ri
    print("Example: Backpropagation from 2d FDTD simulations")
    print("Refractive index of medium:", cfg["nm"])
    print("Measurement position from object center:", cfg["lD"])
    print("Wavelength sampling:", cfg["res"])
    print("Performing backpropagation.")


    ## Apply the Rytov approximation
    sinoRytov = odt.sinogram_as_rytov(sino)


    ## perform backpropagation to obtain object function f
    f = odt.backpropagate_2d( uSin=sinoRytov,
                              angles=angles,
                              res=cfg["res"],
                              nm=cfg["nm"],
                              lD=cfg["lD"]*cfg["res"]
                              )


    ## compute refractive index n from object function
    n = odt.odt_to_ri(f, res=cfg["res"], nm=cfg["nm"])


    ## compare phantom and reconstruction in plot
    fig, axes = plt.subplots(1, 3, figsize=(12,4), dpi=300)
    
    axes[0].set_title("FDTD phantom")
    axes[0].imshow(phantom, vmin=phantom.min(), vmax=phantom.max())
    sino_phase = np.unwrap(np.angle(sino), axis=1)
    axes[0].set_xlabel("x")
示例#14
0
    f_phantom="fdtd_phantom.txt",
)

print("Example: Backpropagation from 2D FDTD simulations")
print("Refractive index of medium:", cfg["nm"])
print("Measurement position from object center:", cfg["lD"])
print("Wavelength sampling:", cfg["res"])
print("Performing backpropagation.")

# Apply the Rytov approximation
sino_rytov = odt.sinogram_as_rytov(sino)

# perform backpropagation to obtain object function f
f = odt.backpropagate_2d(uSin=sino_rytov,
                         angles=angles,
                         res=cfg["res"],
                         nm=cfg["nm"],
                         lD=cfg["lD"] * cfg["res"])

# compute refractive index n from object function
n = odt.odt_to_ri(f, res=cfg["res"], nm=cfg["nm"])

# compare phantom and reconstruction in plot
fig, axes = plt.subplots(1, 3, figsize=(8, 2.8))

axes[0].set_title("FDTD phantom")
axes[0].imshow(phantom, vmin=phantom.min(), vmax=phantom.max())
sino_phase = np.unwrap(np.angle(sino), axis=1)

axes[1].set_title("phase sinogram")
axes[1].imshow(sino_phase,
    #phantom = np.loadtxt(arc.open("mie_phantom.txt"))
    x = np.arange(size)-size/2.0
    X,Y = np.meshgrid(x,x)
    rad_px = radius*res
    phantom = np.array(((Y-lC*res)**2+X**2)<rad_px**2, dtype=np.float)*(ncyl-nmed)+nmed

    u_sinR = odt.sinogram_as_rytov(sino/u0)
    
    # Rytov 100 projections evenly distributed    
    removeeven = np.argsort(angles % .002)[:150]
    angleseven = np.delete(angles, removeeven, axis=0)
    u_sinReven = np.delete(u_sinR, removeeven, axis=0)
    pheven = unwrap.unwrap(np.angle(sino/u0))
    pheven[removeeven] = 0
    
    fReven = odt.backpropagate_2d(u_sinReven, angleseven, res, nmed, lD*res)
    nReven = odt.odt_to_ri(fReven, res, nmed)
    fRevennw = odt.backpropagate_2d(u_sinReven, angleseven, res, nmed, lD*res, weight_angles=False)
    nRevennw = odt.odt_to_ri(fRevennw, res, nmed)
    
    
    # Rytov 100 projections more than 180
    removemiss = 249 - np.concatenate((np.arange(100), 100+np.arange(150)[::3]))
    anglesmiss = np.delete(angles, removemiss, axis=0)
    u_sinRmiss = np.delete(u_sinR, removemiss, axis=0)
    phmiss = unwrap.unwrap(np.angle(sino/u0))
    phmiss[removemiss] = 0
    
    fRmiss = odt.backpropagate_2d(u_sinRmiss, anglesmiss, res, nmed, lD*res)
    nRmiss = odt.odt_to_ri(fRmiss, res, nmed)    
    fRmissnw = odt.backpropagate_2d(u_sinRmiss, anglesmiss, res, nmed, lD*res, weight_angles=False)