def test_2d_autofocus_stack_same_dist(): d = 5.5 nm = 1.5133 res = 6.25 method = "helmholtz" size = 10 metric = "average gradient" stack = 1 * np.exp(1j * np.linspace(.1, .5, size**3)).reshape( size, size, size) rfield = nrefocus.refocus_stack(fieldstack=stack, d=d, nm=nm, res=res, method=method, padding=True) ds, nfield = nrefocus.autofocus_stack(fieldstack=1 * rfield, nm=nm, res=res, ival=(-1.5 * d, -0.5 * d), roi=None, metric=metric, minimizer="legacy", padding=True, same_dist=False, num_cpus=1, copy=True) assert np.allclose(np.array(rfield).flatten().view(float), np.array(nfield).flatten().view(float), atol=.013) # reconstruction distance is same in above case ds_same, nfield_same = nrefocus.autofocus_stack(fieldstack=1 * rfield, nm=nm, res=res, ival=(-1.5 * d, -0.5 * d), roi=None, metric=metric, minimizer="legacy", padding=True, same_dist=True, num_cpus=1, copy=True) assert np.allclose(nfield[0][8][8], 0.9900406072155992 + 0.1341183159587472j) assert np.allclose(nfield[0][2][8], 0.9947454248517085 + 0.11020637810883656j) assert np.allclose(np.mean(ds), -4.8240740740740735) assert np.allclose(np.array(ds), np.mean(ds)) assert np.allclose(np.array(ds), ds_same) assert np.allclose(nfield, nfield_same)
def test_2d_autofocus_stack_same_dist(): d = 5.5 nm = 1.5133 res = 6.25 method = "helmholtz" size = 10 metric = "average gradient" stack = 1 * np.exp(1j * np.linspace(.1, .5, size**3)).reshape( size, size, size) rfield = nrefocus.refocus_stack(fieldstack=stack, d=d, nm=nm, res=res, method=method, padding=True) nfield = nrefocus.autofocus_stack(fieldstack=1 * rfield, nm=nm, res=res, ival=(-1.5 * d, -0.5 * d), roi=None, metric=metric, padding=True, same_dist=False, ret_ds=False, ret_grads=False, num_cpus=1, copy=True) assert np.allclose(np.array(rfield).flatten().view(float), np.array(nfield).flatten().view(float), atol=.013) # reconstruction distance is same in above case nfield_same = nrefocus.autofocus_stack(fieldstack=1 * rfield, nm=nm, res=res, ival=(-1.5 * d, -0.5 * d), roi=None, metric=metric, padding=True, same_dist=True, ret_ds=False, ret_grads=False, num_cpus=1, copy=True) assert np.allclose(nfield, nfield_same)
def test_2d_autofocus_stack_same_dist_nopadding(): d = 5.5 nm = 1.5133 res = 6.25 method = "helmholtz" size = 10 metric = "average gradient" stack = 1 * np.exp(1j * np.linspace(.1, .5, size**3)).reshape( size, size, size) rfield = nrefocus.refocus_stack(fieldstack=stack, d=d, nm=nm, res=res, method=method) ds, nfield = nrefocus.autofocus_stack(fieldstack=rfield.copy(), nm=nm, res=res, ival=(-1.5 * d, -0.5 * d), roi=None, metric=metric, minimizer="legacy", padding=False, same_dist=False, num_cpus=1, copy=True) # reconstruction distance is same in above case ds_same, nfield_same = nrefocus.autofocus_stack(fieldstack=rfield.copy(), nm=nm, res=res, ival=(-1.5 * d, -0.5 * d), roi=None, metric=metric, minimizer="legacy", padding=False, same_dist=True, num_cpus=1, copy=True) assert np.allclose(np.mean(ds), -4.867283950617284) assert np.all(np.array(ds) == ds_same) assert np.all(np.array(ds) == np.mean(ds)) assert np.allclose(nfield.flatten().view(float), nfield_same.flatten().view(float), atol=.000524)
def get_sinogram(tomo_path, ld_offset=1, autofocus=False, interpolate=False, force=False): """Obtain the sinogram of a MEEP tomographic simulation Parameters ---------- tomo_path: str Simulation directory ld_offset: float Number of wavelengths behind the phantom border at which to take the complex field from the simulation. This makes use of the "axial_object_size" info parameter. autofocus: bool If `True`, perform autofocusing. If `False` uses the exact focusing (the center of rotation in the simulation). interpolate: False or int If not `False`, interpolates the field data for faster reconstruction. force: bool If set to `True`, no cached data are used. Returns ------- sino: complex ndarray The 2D/3D complex field sinogam """ res_dir = get_results_dir(tomo_path) _bg, phs = extract.get_tomo_dirlist(tomo_path) info = extract.get_sim_info(phs[0]) res = info["wavelength"] nmed = info["medium_ri"] ld_guess = (ld_offset + info["axial_object_size [wavelengths]"] / 2) * res # raw sinogram rawname = "sinogram_raw_{}.npy".format(ld_guess) rawname = os.path.join(res_dir, rawname) if os.path.exists(rawname) and not force: print("...Loading extracted sinogram") sino_raw = np.load(rawname) else: print("...Extracting sinogram") sino_raw = extract.get_tomo_sinogram_at_ld(tomo_path, ld=ld_guess) np.save(rawname, sino_raw) # processed sinogram name = "sinogram_lmeas{}".format(ld_guess) if autofocus: name += "_af" if interpolate: name += "_intp{}".format(interpolate) name += "_{}.npy".format(os.path.basename(tomo_path)) name = os.path.join(res_dir, name) if os.path.exists(name) and not force: print("...Using preprocessed sinogram: {}".format(name)) u = np.load(name) else: print("...Processing raw sinogram: {}".format(name)) if interpolate: assert len(sino_raw.shape) == 3, "interpolation only for 3D data!" u = [] for ii in range(sino_raw.shape[0]): uii = postproc.interpolate_field(sino_raw[ii], interpolate) u.append(uii) u = np.array(u) else: u = sino_raw if autofocus: print("......Performing autofocusing") u, dopt, gradient = nrefocus.autofocus_stack( u, nmed, res, ival=(-1.5 * ld_guess, 0), same_dist=True, ret_ds=True, ret_grads=True, metric="average gradient", ) print("Autofocusing distance:", np.average(dopt)) # save gradient plt.figure(figsize=(4, 4), dpi=600) plt.plot(gradient[0][0][0], gradient[0][0][1], color="black") plt.plot(gradient[0][1][0], gradient[0][1][1], color="red") plt.xlabel("distance from original slice") plt.ylabel("average gradient metric") plt.tight_layout() plt.savefig(os.path.join(res_dir, "Refocus_Gradient.png")) plt.close() else: u = nrefocus.refocus_stack(u, d=-ld_guess, nm=nmed, res=res) # save sinogram np.save(name, u) angles = extract.get_tomo_angles(tomo_path) return u, angles