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))
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
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))
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))
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))
## 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)
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)
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")
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)