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)
示例#4
0
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