def fromParameters(pos, neg, fname_param, new_bs=False, old_prop=True, topo=None, auto_factor=False, experimental_setup = {'ccd_dist': 18e-2, 'energy': 779.5, 'px_size' : 20e-6}): ''' This function reconstructs a hologram using the latest parameters of the given hdf file. INPUT: fname_im: name of the h5 file where the images are stored entry_nr: list or array of the entry numbers [positive helicity image, negative helicity image], single helicity reconstruction: just the entry number you want to reconstruct fname_param: path and filename of the hdf file where the parameters are stored. new_bs: boolean variable to indicate if you want to use the stored beamstop (FALSE) or if you want to change it (TRUE), default is FALSE old_prop: boolean variable to indicate if you want to use the stored propagation distance (TRUE) or if you want to change it (FALSE), default is TRUE topo_nr: numbers of the topography entries for single helicity reconstruction, default is None, then the topography numbers of the hdf file are used if possible helpos: boolean variable to indicate the helicity of the single helicity reconstruction, default is None which indicates a double helicity reconstruction auto_factor: determine the factor by which neg is multiplied automatically, if FALSE: factor is set to 0.5, default is TRUE size: size of the hologram in pixels, default is the pixel dimensions of our greateyes camera. spe_prefix: default is NONE in which case it opens greateyes files, otherwise, it opens spe files with the given prefix holoN, factor, center, bs_diam, roi, prop_dist, phase OUTPUT: difference hologram that is centered and multiplied with the beamstop mask (if new_bs is FALSE) and propagated (if old_prop is TRUE), factor determined by the function center coordinates, beamstop diameter, ROI coordinates, propagation distance and phase from the hdf file ------- author: KG 2020 ''' #Load the parameters from the hdf file _, nref, _, center, bs_diam, prop_dist, phase, roi = fth.read_hdf(fname_param) #Load the images (spe or greateyes; single or double helicity) if pos is None: if topo is None: print('Please provide topology!') return else: holo, factor = fth.load_single(neg, topo, False, auto_factor=auto_factor) elif neg is None: if topo is None: print('Please provide topology!') return else: holo, factor = fth.load_single(pos, topo, True, auto_factor=auto_factor) else: holo, factor = fth.load_both(pos, neg, auto_factor=auto_factor) print("Start reconstructing the image using the center and beamstop mask from the Matlab reconstruction.") holoN = fth.set_center(holo, center) if not new_bs: print("Using beamstop diameter %i from config file and a sigma of 10."%bs_diam) holoN = fth.mask_beamstop(holoN, bs_diam, sigma=10) else: print("Please adapt the beamstop using the beamstop function and then propagate.") return(holoN, factor, center, bs_diam, roi, prop_dist, phase) if old_prop: print("Using propagation distance from config file.") holoN = fth.propagate(holoN, prop_dist*1e-6, experimental_setup = experimental_setup) print("Now determine the global phase shift by executing phase_shift.") else: print("Please use the propagation function to propagate.") return(holoN, factor, center, bs_diam, roi, prop_dist, phase)
def set_beamstop(holo, bs_diameter, sigma = 10): ''' Input center-shifted hologram and the diameter of the beamstop. You may change the sigma of the gauss filter (default is 10). Returns the hologram where the beamstop is masked. ------- author: KG 2019 ''' print("Masking beamstop with a diameter of %i pixels."%bs_diameter) holoB = fth.mask_beamstop(holo, bs_diameter, sigma=sigma) return holoB
def fromConfig(image_folder, image_numbers, folder_config, number_config, new_bs=False, old_prop=True, topo_nr=None, helpos=None, auto_factor=False, size=[2052,2046], spe_prefix=None): ''' old function that uses the config file, replaced by funtion FromParameters with hdf file opens the image files in image_numbers (either single helicity or double helicity) if a spe_prefix is given, it opens spe files, otherwise it opens greateyes files. opens the config file for the center, beamstop, the ROI and the propagation etc. shifts the center and masks the beamstop returns the reconstruction parameters as well as the hologram that was corrected as inidcated (with and without bs mask, propagation) ------- author: KG 2019 ''' #Load the config file nref, center, bs_diam, prop_dist, phase, roi = fth.read_config(folder_config + '%i_config.ini'%number_config) #Load the images (spe or greateyes; single or double helicity) if spe_prefix is None: #greateyes if helpos==None: print("Double Helicity Reconstruction") pos = cam.load_greateyes(image_folder + 'holo_%04d.dat'%image_numbers[0], size=size) neg = cam.load_greateyes(image_folder + 'holo_%04d.dat'%image_numbers[1], size=size) holo, factor = fth.load_both(pos, neg, auto_factor=auto_factor) else: print("Single Helicity Reconstruction") if topo_nr is None: if np.logical_or(np.isnan(nref[0]), np.isnan(nref[0])): print("Please put in the numbers for the topography.") return else: pos = cam.load_greateyes(image_folder + 'holo_%04d.dat'%nref[0], size=size) neg = cam.load_greateyes(image_folder + 'holo_%04d.dat'%nref[1], size=size) else: pos = cam.load_greateyes(image_folder + 'holo_%04d.dat'%topo_nr[0], size=size) neg = cam.load_greateyes(image_folder + 'holo_%04d.dat'%topo_nr[1], size=size) image = cam.load_greateyes(image_folder + 'holo_%04d.dat'%image_numbers, size=size) holo, factor = fth.load_single(image, pos+neg, helpos, auto_factor=auto_factor) else: #spe if helpos==None: print("Double Helicity Reconstruction") pos = cam.load_spe(image_folder + spe_prefix + '%04d.spe'%image_numbers[0], return_header=False) neg = cam.load_spe(image_folder + spe_prefix + '%04d.spe'%image_numbers[1], return_header=False) holo, factor = fth.load_both(pos, neg, auto_factor=auto_factor) else: print("Single Helicity Reconstruction") if topo_nr is None: if np.logical_or(np.isnan(nref[0]), np.isnan(nref[0])): print("Please put in the numbers for the topography.") return else: pos = cam.load_spe(image_folder + spe_prefix + '%04d.spe'%n_ref[0], return_header=False) neg = cam.load_spe(image_folder + spe_prefix + '%04d.spe'%n_ref[1], return_header=False) else: pos = cam.load_spe(image_folder + spe_prefix + '%04d.spe'%topo_nr[0], return_header=False) neg = cam.load_spe(image_folder + spe_prefix + '%04d.spe'%topo_nr[1], return_header=False) image = cam.load_spe(image_folder + spe_prefix + '%04d.spe'%image_numbers, return_header=False) holo, factor = fth.load_single(image, pos+neg, helpos, auto_factor=auto_factor) print("Start reconstructing the image using the center and beamstop mask from the Matlab reconstruction.") holoN = fth.set_center(holo, center) if not new_bs: print("Using beamstop diameter %i from config file and a sigma of 10."%bs_diam) holoN = fth.mask_beamstop(holoN, bs_diam, sigma=10) else: print("Please adapt the beamstop using the beamstop function and then propagate.") return(holoN, center, bs_diam, roi, prop_dist, phase) if old_prop: print("Using propagation distance from config file.") holoN = fth.propagate(holoN, prop_dist*1e-6) print("Now determine the global phase shift by executing phase_shift.") else: print("Please use the propagation function to propagate.") return(holoN, factor, center, bs_diam, roi, prop_dist, phase)
def simulHolo2(im_p_focused, im_n_focused, Cntrs_level=1, readout_noise_average=0, readout_noise_sigma=3, sigma_h_px=0, max_counts_per_image=64000, counts_per_photon=50, number_frames=100, bs_size=0, sigma=3): ''' Given two starting real space images (for the two helicities), the function simulates the holograms introducing drift, contrast levels, coherence effects and Poisson noise INPUT: im_p_focused,im_n_focused: positive and negative helicity images Cntrs_level: contrast of the image. Can make the contrast lower than the original for values <1 readout_noise_average, readout_noise_sigma: readout noise of the camera sigma_h_px: sigma of drift in pixles. Takes into account also the spatial incoherence, so that has to be be taken ito accout too max_counts_per_image: max number of counts the camera can take in one image counts_per_photon: number_of_frames: number of acquired frames. The more, the lower the noise ---------- Author: RB_2020 ''' sample_pos = Cntrs_level * (im_p_focused - im_n_focused) / 2 + ( im_p_focused + im_n_focused) / 2 sample_neg = Cntrs_level * (im_n_focused - im_p_focused) / 2 + ( im_p_focused + im_n_focused) / 2 npx, npy = sample_pos.shape # 1. the coherent hologram is given by |FFT(object+reference)|^2 pos = np.abs(np.fft.ifftshift(np.fft.fft2(np.fft.fftshift(sample_pos))))**2 neg = np.abs(np.fft.ifftshift(np.fft.fft2(np.fft.fftshift(sample_neg))))**2 # 4. simulate sample drift / vibrations AND SPATIAL INCOHERENCE if sigma_h_px > 0: kernel = np.outer(signal.gaussian(npx, sigma_h_px), signal.gaussian(npx, sigma_h_px)) if kernel.sum() > 0: kernel /= kernel.sum() pos = signal.fftconvolve(pos, kernel, mode='same') neg = signal.fftconvolve(neg, kernel, mode='same') #mask beamstop pos = fth.mask_beamstop(pos, bs_size, sigma, center=None) neg = fth.mask_beamstop(neg, bs_size, sigma, center=None) # 6. adjust the maximum count to 64000 for a single image pos *= (max_counts_per_image) / pos.max() neg *= (max_counts_per_image) / neg.max() # consider you will have more than one frame pos *= number_frames neg *= number_frames # 7. add Poisson noise to number of photons (sqrt(counts/counts_per_photon)) pos /= counts_per_photon neg /= counts_per_photon pos = np.random.poisson(pos).astype(np.float64) neg = np.random.poisson(neg).astype(np.float64) # 8. round to integer number of photons and convert back to counts pos = np.round(pos, 0) neg = np.round(neg, 0) pos *= counts_per_photon neg *= counts_per_photon # 9. add gaussian readout noise if (readout_noise_average > 0 or readout_noise_sigma > 0): pos += np.random.normal(readout_noise_average * number_frames, readout_noise_sigma * np.sqrt(number_frames), pos.shape) neg += np.random.normal(readout_noise_average * number_frames, readout_noise_sigma * np.sqrt(number_frames), neg.shape) pos /= number_frames neg /= number_frames pos = np.maximum(pos, np.zeros(pos.shape)) neg = np.maximum(neg, np.zeros(pos.shape)) #saturation pos = np.minimum(pos, np.ones(pos.shape) * max_counts_per_image) neg = np.minimum(neg, np.ones(pos.shape) * max_counts_per_image) #pos=pos.astype(complex) #neg=neg.astype(complex) return pos, neg