Ejemplo n.º 1
0
def getSimpleBl():
    
    bl = Beamline()    
    
    bl.append(Drift(10), propagation_parameters(1, 1, 1, 1, mode = 'quadratic'))
    
    return bl
Ejemplo n.º 2
0
def scale(wfr, nx=512, ny=512):
    """
    narrow functionality for scaling a wavefront (ie the number of pixels)
    in the source plane

    :param wfr: wpg wfr strucutre
    :param isc: ideal scale
    :param ifov: ideal field of view

    :returns wfr: scaled wpg wfr structure
    """

    ix, iy = wfr.params.Mesh.nx, wfr.params.Mesh.ny
    dx, dy = wfr.params.Mesh.xMax - wfr.params.Mesh.xMin, wfr.params.Mesh.yMax - wfr.params.Mesh.yMin

    print(dx, dy)
    print(nx / ix)

    scbl = Beamline()
    scbl.append(
        Aperture('r', 'a', 800e-06, 800e-06),
        propagation_parameters(800e-06 / dx, nx / ix, 800e-06 / dx, ny / iy))

    scbl.propagate(wfr)

    return wfr
Ejemplo n.º 3
0
def sliceFocus(wfr,
               ekev,
               focus='nano',
               nslices=500,
               axisName='x',
               outdir=None):

    spb = get_beamline_object(apertures=False, surface=False)

    el_n = len(spb.propagation_options[0]['optical_elements']) - 1

    spb.propagation_options[0]['optical_elements'][el_n].L *= 0.98
    slice_interval = 2.2 - copy(
        spb.propagation_options[0]['optical_elements'][el_n].L / nslices)

    spb.propagation_options[0]['propagation_parameters'][
        el_n] = propagation_parameters(5, 1, 5, 1, mode='fresnel')

    spb.propagate(wfr)
    plotIntensity(wfr)

    if axisName == 'x':
        data_focslice = np.zeros([nslices, np.shape(wfr.data.arrEhor)[0]])
    elif axisName == 'y':
        data_focslice = np.zeros([nslices, np.shape(wfr.data.arrEhor)[1]])

    for n in range(nslices):
        print("Slice {}/{}".format(n + 1, nslices))

        bl = Beamline()
        bl.append(SRWLOptD(slice_interval),
                  propagation_parameters(1, 1, 1, 1, mode='quadratic'))
        bl.propagate(wfr)
        plotIntensity(wfr)
        data_focslice[-n - 1, :] = wfr.get_intensity()[:, :, 0].sum(-1)
        #plt.plot(data_focslice[-n-1, :])
        plt.show()

    y = np.linspace(
        spb.bl.propagation_options[0]['optical_elements'][el_n].L,
        spb.bl.propagation_options[0]['optical_elements'][el_n].L +
        nslices * slice_interval, nslices)

    # =============================================================================
    #     ax1 =     colorbar_plot(data_focslice,
    #               get_mesh(data_focslice,
    #                                wfr.get_spatial_resolution()[0]*1e6,
    #                                y[1]-y[0]),
    #               aspect = 'auto',
    #               scale = 1,
    #               #norm=mpl.colors.LogNorm(),
    #               xlabel = "x($\mu m$)",
    #               ylabel = "z(m)",
    #               return_axes = True)
    #
    # =============================================================================
    return data_focslice
Ejemplo n.º 4
0
def propagate_NVE():
            
    wfr_directory = sys.argv[1].replace("*", "/")
 
    job_name = "NKB_4980eV_250pC_NVE_to_EHC"
    python_command = propagate_NVE
    input_directory = dCache + "/NanoKB-Pulse/NVE/"
    
    save_directory = input_directory.replace("/NVE/", "/EHC/")
    mkdir_p(save_directory)
    
    log_directory = logs
    
    focus = "nano"
    analysis = False
    
    filename = __file__
    dt = datetime.now().__str__()
    function = python_command.__name__
    
    description = "Propagate NanoKB Pulses 4.98 keV, 250 pC from Undulator NVE mirror to the EHC Screen"
    
    append = None
    
    print("info")
    print("wavefront directory: {}".format(wfr_directory))
    print("save directory: {}".format(save_directory))
    print("focus (i.e. beamline option): {}".format(focus))
    print("analysis: {}".format(analysis))
    print("datetime: {}".format(dt))
    print("filename: {}".format(filename))
    print("function: {}".format(function))
    print("description: {}".format(description))
    
  
    wfr = Wavefront()
    wfr.load_hdf5(wfr_directory)
     
    bl = Beamline()
    bl.append(Drift(2.2+3.5), propagation_parameters(1/3,1,1/3,1,'quadratic'))
    bl.propagate(wfr)
    
    wfr.custom_fields['focus'] = focus
    wfr.custom_fields['job name'] = job_name
    wfr.custom_fields['input directory'] = wfr_directory
    wfr.custom_fields['datetime'] = dt
    wfr.custom_fields['function'] = function
    wfr.custom_fields['filename'] = filename
    wfr.custom_fields['description'] = description
    #wfr.custom_fields['bl'] = bl.__str__
                
    if analysis: 
        wfr.analysis()
        
    wfr.store_hdf5(wfr_directory.replace("/NVE/", "/EHC/"))
Ejemplo n.º 5
0
def modify_beam_divergence(wfr, sig, dtheta):
    """
    Construct a thin-lens with a focal length defined by a desired divergence,
    see: thin_lens_mod, and then propagate to 2f

    :param wfr: WPG wfr structure
    :params sig: beam fwhm [m]
    :params dtheta: pulse divergence [rad]
    """
    f = sig/(np.tan(dtheta))

    tl = thinLens(f,f)
    bl = Beamline()
    bl.append(tl, [0,0,0,0,0,1,1,1,1,0,0,0])
    bl.append(Drift(2*f), [0,0,0,0,0,1,1,1,1,0,0,0])
    bl.propagate(wfr)

    wfr.params.Mesh.zCoord = 0
Ejemplo n.º 6
0
def simpleProp(wfr):
    
    print(calculate_fwhm(wfr))
    bl = Beamline()
    #bl.append(Aperture('c','a', 500e-06),propagation_parameters(1,1,1,1,mode = 'normal'))
    bl.append(Drift(100), propagation_parameters(1,1,1,1,mode = 'quadratic'))
    
    #bl.append(Drift(100), propagation_parameters(1,1,1,1,mode = 'quadratic'))
    bl.propagate(wfr)
    plotIntensity(wfr)
    print(calculate_fwhm(wfr))
Ejemplo n.º 7
0
 def detect(self, wfr):
     
     xMin, xMax, yMax, yMin = wfr.get_limits()
     
     idx, idy = xMax-xMin, yMax-yMin
     inx, iny = wfr.params.Mesh.nx, wfr.params.Mesh.ny
     print(idx,idy)
     print((self.dy*self.ny)/idy)
     bl = Beamline()
     bl.append(Drift(0),
               propagation_parameters((self.dx*self.nx)/idx, self.nx/inx, (self.dy*self.ny)/idy, self.ny/iny))
 
     bl.propagate(wfr)
Ejemplo n.º 8
0
    def detect(self, wfr):
        """
        return the detected intensity distribution
        """

        bl = Beamline()
        bl.append(
            Drift(0),
            propagation_parameters(self.mesh.dx / wfr.dx, 1,
                                   self.mesh.dy / wfr.dy, 1))
        bl.propagate(wfr)

        ii = wfr.get_intensity().sum(-1)
        ii = compress_and_average(ii, (self.mesh.nx, self.mesh.ny))

        return ii
Ejemplo n.º 9
0
def propThruMaskLite(wfr, _x=0, _y=0):
    """
    propagate through the speckle generator
    """
    s = Sample("/opt/FELpy/felpy/data/samples/speckle.tif",
               rx=100e-06 / 1000,
               ry=100e-06 / 1000,
               thickness=60e-06,
               delta=3.35e-03,
               atten_len=20e-06,
               xc=0,
               yc=0,
               shift_x=_y,
               shift_y=_x)

    bl = Beamline()
    bl.append(s, propagation_parameters(1, 1, 1, 1, mode='fresnel'))
    bl.propagate(wfr)

    return wfr
Ejemplo n.º 10
0
        src.store_hdf5("../data/tmp/source.h5")
    except (KeyError):
        os.remove("../data/tmp/source.h5")
        src.store_hdf5("../data/tmp/source.h5")

    src = Source()
    src.load_hdf5("../data/tmp/source.h5")
    from felpy.model.wavefront import Wavefront
    from wpg.wpg_uti_wf import plot_intensity_map
    wfr = Wavefront()

    from felpy.model.beamline import Beamline
    from wpg.optical_elements import Drift
    from felpy.model.tools import propagation_parameters
    from matplotlib import pyplot as plt

    bl = Beamline()
    bl.append(Drift(50), propagation_parameters(1, 1, 1, 1, mode='fresnel'))

    for w in src.pulses:

        wfr.load_hdf5(w)
        bl.propagate(wfr)
        plt.plot(wfr.x_axis,
                 wfr.get_x_profile(),
                 label="{} $\mu$ rad".format(wfr.source_properties['theta_x'] *
                                             1e6))
        #plot_intensity_map(wfr)
        print(wfr.com)

    plt.legend()
Ejemplo n.º 11
0
ny = 25

plt.imshow(create_mask(nx, ny))
wfr = construct_SA1_wavefront(512, 512, 5, .8, mx=0, xoff=0, tiltX=0)

period = nx * wfr.get_spatial_resolution()[0] * (512 / (nx))
print(period)
wav = wfr.get_wavelength()

d = (2 * period**2) / wav

arr = create_mask(nx, ny)
np.save("/opt/arr", arr)
im = Image.fromarray(arr)
im = im.convert('RGB')
im.save("/opt/arr.png")

obj = srwloptT("/opt/arr.png",
               wfr.get_spatial_resolution()[0] * (512 / 75),
               wfr.get_spatial_resolution()[1] * (512 / 75),
               1e-06,
               1e-8,
               atten_len=1e-08)

bl = Beamline()
bl.append(Drift(50), propagation_parameters(1, 1, 1, 1, mode='quadratic'))
bl.append(obj, propagation_parameters(1, 1, 1, 1))
bl.append(Drift(d),
          propagation_parameters(1 / 3, 4, 1 / 3, 4, mode='fraunhofer'))
bl.propagate(wfr)
plot_intensity_map(wfr)
Ejemplo n.º 12
0
ekev = 25
wav = ekev2wav(ekev)

k = (np.pi * 2) / wav

x = np.linspace(-r1 / 2, r1 / 2, 100)

y = np.ones([100, 100])

phase_shift = phase(x, r1, r2, k, delta)
mask = y * phase_shift

z1 = 2
z2 = .01

bl = Beamline()

from felpy.model.src.coherent import construct_SA1_wavefront

# =============================================================================
# src = construct_gaussian(1024, 1024, ekev, extent = [-25e-04, 25e-04, -25e-04, 25e-04],
#                      sigX = .5e-04, sigY = .5e-04, divergence = np.arctan(13.5e-03/8))
#
# =============================================================================
q = 0.50
src = construct_SA1_wavefront(1024, 1024, 25.0, q)

plot_ii(src)

speckle = define_speckle_mask("../../data/samples/checkerboard-pattern.jpg",
                              rx=1e-8,
Ejemplo n.º 13
0
@author: twguest

test to see if backpropagation works (it does)
"""

import sys

sys.path.append("../")
sys.path.append("/opt/WPG/")

from model.tools import constructPulse
from model.beamline.structure import propagation_parameters
from felpy.model.beamline import Beamline
from wpg.optical_elements import Drift
from wpg.wpg_uti_wf import plot_intensity_map as plotIntensity



if __name__ == "__main__":
    
    wfr = constructPulse(nz = 2)
    plotIntensity(wfr)
    
    bl = Beamline()
    bl.append(Drift(-10), propagation_parameters(1,1,1,1))
    
    bl.propagate(wfr)
    
    plotIntensity(wfr)
    
Ejemplo n.º 14
0
    def build_beamline(self, focus="nano", screens="false"):
        """
        Construct the beamline object
        
        :param focus: what beamline configuration (micron or nano)
        """

        self.bl = Beamline()

        if focus == "micron":

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="fraunhofer"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))

            self.bl.append(
                self.MKB_pslit,
                propagation_parameters(1 / 5, 1, 1 / 5, 1, mode='fresnel'))
            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MHE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d6, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MVE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MVE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d8, propagation_parameters(1, 1, 1, 1, mode='quadratic'))

            self.bl.append(self.MVP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.df,
                           propagation_parameters(5, 1, 5, 1, mode='converge'))

        elif focus == "nano":

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="fraunhofer"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))

            self.bl.append(
                self.NKB_pslit,
                propagation_parameters(1 / 10, 1, 1 / 10, 1, mode='fresnel'))
            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.NHE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.NHE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))

            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.NVE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.NVE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))

            self.bl.append(
                self.df,
                propagation_parameters(1 / 20, 1, 1 / 20, 1, mode='converge'))

        self.bl.params = self.params
Ejemplo n.º 15
0
class Instrument:
    """
    A container for loading and modifying beamline data
    """
    def __init__(self, VERBOSE=True):

        self.VERBOSE = VERBOSE

        if VERBOSE:
            print("Initialising Single Particle Beamline")

        self.load_params()
        self.fpath = felpy_path()  ### felpy path (for dev. purposes)

        add_path()

    def load_params(self, fromFile=False):
        """
        load beamline parameters from /data/spb/
        """

        if fromFile:
            with open("../../data/params/exfel_spb.json", "r") as read_file:
                self.params = json.load(read_file)
        else:
            self.params = get_params()

    def export_params(self, sdir=None):
        """
        save the current set of beamline parameters in json format
        
        :param sdir: save directory
        """
        if sdir is None:
            with open('../../data/spb/parameters.json', 'w') as f:
                json.dump(self.params, f)
        else:
            with open(sdir + 'parameters.json', 'w') as f:
                json.dump(self.params, f)

    def adjust_mirror(self, mirror_name, ekev, new_ang, mirror_refl=None):

        if mirror_refl == None:
            if ekev >= 7.5:
                material = "B4C"
            else:
                material = "Ru"

            refl = get_refl(load_refl(material), ekev, new_ang)

        else:
            refl = mirror_refl

        new_ang = new_ang + np.tan(
            self.params[mirror_name]["xc"] /
            self.params[self.params[mirror_name]['next_drift']]['distance'])
        self.params[mirror_name]["incidence angle"] = new_ang
        self.params[mirror_name]['reflectivity'] = refl

    def define_mirror_profiles(self,
                               overwrite=False,
                               surface='flat',
                               plot=False,
                               aperture=True):
        """
        Define the plane mirror profiles by loading from /data/. 
        If mirror profiles not defined (unlikely), generate profiles via genMirrorSurface
        
        :param overwrite: bool to overwrite current file.
        :param surface: surface type (flat, random or real)
        """

        if surface == 'real':

            mm = 'random'  ### fix for no 'real' surface MHE, MVE, MVP surfaces etc.

            if overwrite == True:

                if aperture == True:
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MHP"]['dx'], self.params["MHP"]['dy']],
                        "../../data/spb/mirror_surface/mhp_",
                        mode=mm,
                        plot=plot,
                        mirrorName="MHP")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MVP"]['dx'], self.params["MVP"]['dy']],
                        "../../data/spb/mirror_surface/mvp_",
                        mode=mm,
                        plot=plot,
                        mirrorName="MVP")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MHE"]['dx'], self.params["MHE"]['dy']],
                        "../../data/spb/mirror_surface/mhe_",
                        mode=mm,
                        plot=plot,
                        mirrorName="MHE")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MVE"]['dx'], self.params["MVE"]['dy']],
                        "../../data/spb/mirror_surface/mve_",
                        mode=mm,
                        plot=plot,
                        mirrorName="MVE")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["NHE"]['dx'], self.params["NHE"]['dy']],
                        "../../data/spb/mirror_surface/nhe_",
                        mode=surface,
                        plot=plot,
                        mirrorName="NHE")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["NVE"]['dx'], self.params["NVE"]['dy']],
                        "../../data/spb/mirror_surface/nve_",
                        mode=surface,
                        plot=plot,
                        mirrorName="NVE")

                elif aperture == False:
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "data/spb/mirror_surface/hom1_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="HOM1")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "data/spb/mirror_surface/hom2_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="HOM2")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "data/spb/mirror_surface/mhp_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="MHP")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "data/spb/mirror_surface/mvp_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="MVP")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "data/spb/mirror_surface/mhe_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="MHE")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/mve_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="MVE")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/nhe_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="NHE")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/nve_",
                                     mode=mm,
                                     plot=plot,
                                     mirrorName="NVE")

        elif surface == 'flat':

            mm = 'flat'

            if overwrite == True:

                if aperture == True:
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MHP"]['dx'], self.params["MHP"]['dy']],
                        "../../data/spb/mirror_surface/mhp_",
                        mode=surface,
                        plot=plot,
                        mirrorName="MHP")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MVP"]['dx'], self.params["MVP"]['dy']],
                        "../../data/spb/mirror_surface/mvp_",
                        mode=surface,
                        plot=plot,
                        mirrorName="MVP")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MHE"]['dx'], self.params["MHE"]['dy']],
                        "../../data/spb/mirror_surface/mhe_",
                        mode=surface,
                        plot=plot,
                        mirrorName="MHE")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["MVE"]['dx'], self.params["MVE"]['dy']],
                        "../../data/spb/mirror_surface/mve_",
                        mode=surface,
                        plot=plot,
                        mirrorName="MVE")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["NHE"]['dx'], self.params["NHE"]['dy']],
                        "../../data/spb/mirror_surface/nhe_",
                        mode=surface,
                        plot=plot,
                        mirrorName="NHE")
                    genMirrorSurface(
                        500,
                        500,
                        [self.params["NVE"]['dx'], self.params["NVE"]['dy']],
                        "../../data/spb/mirror_surface/nve_",
                        mode=surface,
                        plot=plot,
                        mirrorName="NVE")

                if aperture == False:
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/hom1_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="HOM1")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/hom2_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="HOM2")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/mhp_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="MHP")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/mvp_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="MVP")
                    genMirrorSurface(500,
                                     500, [1000, 1000],
                                     "../../data/spb/mirror_surface/mhe_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="MHE")
                    genMirrorSurface(500,
                                     500, [1000, 1000],
                                     "../../data/spb/mirror_surface/mve_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="MVE")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/nhe_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="NHE")
                    genMirrorSurface(500,
                                     500, [100, 100],
                                     "../../data/spb/mirror_surface/nve_",
                                     mode=surface,
                                     plot=plot,
                                     mirrorName="NVE")

        if aperture == True:
            self.params['HOM1'][
                'mirror profile'] = "../../data/spb/mirror_surface/hom1_mir_{}.dat".format(
                    surface)
            self.params['HOM2'][
                'mirror profile'] = "../../data/spb/mirror_surface/hom2_mir_{}.dat".format(
                    surface)
        else:
            self.params['HOM1'][
                'mirror profile'] = "../../data/spb/mirror_surface/hom1_mir_{}.dat".format(
                    mm)
            self.params['HOM2'][
                'mirror profile'] = "../../data/spb/mirror_surface/hom2_mir_{}.dat".format(
                    mm)
            self.params['MHE']["length"] = 10
            self.params['MVE']["length"] = 10

        self.params['MHP'][
            'mirror profile'] = "../../data/spb/mirror_surface/mhp_mir_{}.dat".format(
                mm)
        self.params['MVP'][
            'mirror profile'] = "../../data/spb/mirror_surface/mvp_mir_{}.dat".format(
                mm)
        self.params['MHE_error'][
            'mirror profile'] = "../../data/spb/mirror_surface/mhe_mir_{}.dat".format(
                mm)
        self.params['MVE_error'][
            'mirror profile'] = "../../data/spb/mirror_surface/mve_mir_{}.dat".format(
                mm)
        self.params['NHE_error'][
            'mirror profile'] = "../../data/spb/mirror_surface/nhe_mir_{}.dat".format(
                mm)
        self.params['NVE_error'][
            'mirror profile'] = "../../data/spb/mirror_surface/nve_mir_{}.dat".format(
                mm)

    def build_elements(self, focus="nano"):

        self.d1 = Drift(self.params["HOM1"]['distance from source'])
        self.d1.name = self.params["d1"]['name']

        self.HOM1 = MirPl(np.loadtxt(
            self.fpath +
            self.params['HOM1']['mirror profile'].replace("../../", "")),
                          _dim=self.params['HOM1']['orientation'],
                          _ang=self.params['HOM1']['incidence angle'],
                          _amp_coef=1,
                          _x=self.params['HOM1']['xc'],
                          _y=self.params['HOM1']['yc'],
                          _refl=self.params['HOM1']['transmission'])

        self.HOM1.name = self.params['HOM1']['name']

        self.d2 = Drift(self.params["HOM2"]['distance from source'] -
                        self.params["HOM1"]['distance from source'])
        self.d2.name = self.params["d2"]['name']

        self.HOM2 = MirPl(np.loadtxt(
            self.fpath +
            self.params['HOM2']['mirror profile'].replace("../../", "")),
                          _dim=self.params['HOM2']['orientation'],
                          _ang=self.params['HOM2']['incidence angle'],
                          _amp_coef=1,
                          _x=self.params['HOM2']['xc'],
                          _y=self.params['HOM2']['yc'],
                          _refl=self.params['HOM2']['transmission'])

        self.HOM2.name = self.params['HOM2']['name']

        if focus == "micron":
            self.d3 = Drift(self.params["d3"]['distance'])
            self.d3.name = self.params["d3"]['name']

            self.MKB_pslit = Aperture(
                _shape=self.params["MKB_pslit"]['shape'],
                _ap_or_ob=self.params["MKB_pslit"]['type'],
                _Dx=self.params["MKB_pslit"]['dx'],
                _Dy=self.params["MKB_pslit"]['dy'],
                _x=self.params["MKB_pslit"]['xc'],
                _y=self.params["MKB_pslit"]['yc'])
            self.MKB_pslit.name = self.params["MKB_pslit"]['name']

            self.d4 = Drift(self.params["d4"]['distance'])
            self.d4.name = self.params["d4"]['name']

            self.MHP = MirPl(np.loadtxt(self.fpath +
                                        self.params['MHP']['mirror profile']),
                             _dim=self.params['MHP']['orientation'],
                             _ang=self.params['MHP']['incidence angle'],
                             _refl=self.params['MHP']['transmission'],
                             _x=self.params['MHP']['xc'],
                             _y=self.params['MHP']['yc'])
            self.MHP.name = self.params['MHP']['name']

            self.d5 = Drift(self.params["d5"]['distance'])
            self.d5.name = self.params["d5"]['name']

            self.MHE_error = MirPl(
                np.loadtxt(self.fpath +
                           self.params['MHE_error']['mirror profile']),
                _dim=self.params['MHE_error']['orientation'],
                _ang=self.params['MHE_error']['incidence angle'],
                _refl=self.params['MHE_error']['transmission'],
                _x=self.params['MHE_error']['xc'],
                _y=self.params['MHE_error']['yc'])

            self.MHE_error.name = self.params['MHE_error']['name']

            self.MVE_error = MirPl(
                np.loadtxt(self.fpath +
                           self.params['MVE_error']['mirror profile']),
                _dim=self.params['MVE_error']['orientation'],
                _ang=self.params['MVE_error']['incidence angle'],
                _refl=self.params['MVE_error']['transmission'],
                _x=self.params['MVE_error']['xc'],
                _y=self.params['MVE_error']['yc'])

            self.MVE_error.name = self.params['MVE_error']['name']

            self.MHE = MirEl(orient=self.params['MHE']["orientation"],
                             p=self.params['MHE']["distance from source"],
                             q=self.params['MHE']["distance to focus"],
                             thetaE=self.params['MHE']["design angle"],
                             theta0=self.params['MHE']["incidence angle"],
                             _x=self.params["MHE"]["xc"],
                             _y=self.params["MHE"]["yc"],
                             length=self.params['MHE']["length"],
                             roll=self.params['MHE']["roll"],
                             yaw=self.params['MHE']["yaw"],
                             _refl=self.params['MHE']["reflectivity"],
                             _ext_in=self.params['MHE']["_ext_in"],
                             _ext_out=self.params['MHE']["_ext_out"])

            self.MHE.name = self.params['MHE']['name']

            self.d6 = Drift(self.params["d7"]['distance'])
            self.d6.name = self.params["d7"]['name']

            self.MVE = MirEl(orient=self.params['MVE']["orientation"],
                             p=self.params['MVE']["distance from source"],
                             q=self.params['MVE']["distance to focus"],
                             thetaE=self.params['MVE']["design angle"],
                             theta0=self.params['MVE']["incidence angle"],
                             _x=self.params["MVE"]["xc"],
                             _y=self.params["MVE"]["yc"],
                             length=self.params['MVE']["length"],
                             roll=self.params['MVE']["roll"],
                             yaw=self.params['MVE']["yaw"],
                             _refl=self.params['MVE']["reflectivity"],
                             _ext_in=self.params['MVE']["_ext_in"],
                             _ext_out=self.params['MVE']["_ext_out"])

            self.MVE.name = self.params['MVE']['name']

            self.d8 = Drift(self.params["d8"]['distance'])
            self.d8.name = self.params["d8"]['name']

            self.MVP = MirPl(np.loadtxt(self.fpath +
                                        self.params['MVP']['mirror profile']),
                             _dim=self.params['MVP']['orientation'],
                             _ang=self.params['MVP']['incidence angle'],
                             _refl=self.params['MVP']['transmission'],
                             _x=self.params['MVP']['xc'],
                             _y=self.params['MVP']['yc'])
            self.MVP.name = self.params['MVP']['name']

            self.df = Drift(self.params["df"]['distance'])
            self.df.name = self.params["df"]['name']

        elif focus == "nano":

            self.NKB_pslit = Aperture(
                _shape=self.params["NKB_pslit"]['shape'],
                _ap_or_ob=self.params["NKB_pslit"]['type'],
                _Dx=self.params["NKB_pslit"]['dx'],
                _Dy=self.params["NKB_pslit"]['dy'],
                _x=self.params["NKB_pslit"]['xc'],
                _y=self.params["NKB_pslit"]['yc'])
            self.NKB_pslit.name = self.params["NKB_pslit"]['name']

            self.NHE = MirEl(orient=self.params['NHE']["orientation"],
                             p=self.params['NHE']["distance from source"],
                             q=self.params['NHE']["distance to focus"],
                             thetaE=self.params['NHE']["design angle"],
                             theta0=self.params['NHE']["incidence angle"],
                             _x=self.params["NHE"]["xc"],
                             _y=self.params["NHE"]["yc"],
                             length=self.params['NHE']["length"],
                             roll=self.params['NHE']["roll"],
                             yaw=self.params['NHE']["yaw"],
                             _refl=self.params['NHE']["reflectivity"],
                             _ext_in=self.params['NHE']["_ext_in"],
                             _ext_out=self.params['NHE']["_ext_out"])

            self.NHE.name = self.params["NHE"]["name"]

            self.NVE = MirEl(orient=self.params['NVE']["orientation"],
                             p=self.params['NVE']["distance from source"],
                             q=self.params['NVE']["distance to focus"],
                             thetaE=self.params['NVE']["design angle"],
                             theta0=self.params['NVE']["incidence angle"],
                             _x=self.params["NVE"]["xc"],
                             _y=self.params["NVE"]["yc"],
                             length=self.params['NVE']["length"],
                             roll=self.params['NVE']["roll"],
                             yaw=self.params['NVE']["yaw"],
                             _refl=self.params['NVE']["reflectivity"],
                             _ext_in=self.params['NVE']["_ext_in"],
                             _ext_out=self.params['NVE']["_ext_out"])

            self.NVE.name = self.params["NVE"]["name"]

            self.NVE_error = MirPl(
                np.loadtxt(self.fpath + self.params['NVE_error']
                           ['mirror profile'].replace("../../", "")),
                _dim=self.params['NVE_error']['orientation'],
                _ang=self.params['NVE_error']['incidence angle'] +
                self.params['NVE']['incidence angle'],
                _refl=self.params['NVE_error']['transmission'],
                _x=self.params['NVE_error']['xc'],
                _y=self.params['NVE_error']['yc'])

            self.NVE_error.name = self.params['NVE_error']['name']

            self.NHE_error = MirPl(
                np.loadtxt(self.fpath + self.params['NHE_error']
                           ['mirror profile'].replace("../../", "")),
                _dim=self.params['NHE_error']['orientation'],
                _ang=self.params['NHE_error']['incidence angle'] +
                self.params['NHE']['incidence angle'],
                _refl=self.params['NHE_error']['transmission'],
                _x=self.params['NHE_error']['xc'],
                _y=self.params['NHE_error']['yc'])

            self.NHE_error.name = self.params['NHE_error']['name']

            self.params["d3"]["distance"] = 656.424
            self.params["d4"]["distance"] = 1.20
            self.params["d5"]["distance"] = 1.00
            self.params["df"]["distance"] = 2.2

            self.d3 = Drift(self.params["d3"]['distance'])
            self.d3.name = self.params["d3"]['name']

            self.d4 = Drift(self.params["d4"]['distance'])
            self.d4.name = self.params["d4"]['name']

            self.d5 = Drift(self.params["d5"]['distance'])
            self.d5.name = self.params["d5"]['name']

            self.df = Drift(self.params["df"]['distance'])
            self.df.name = self.params["df"]['name']

    def build_beamline(self, focus="nano", screens="false"):
        """
        Construct the beamline object
        
        :param focus: what beamline configuration (micron or nano)
        """

        self.bl = Beamline()

        if focus == "micron":

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="fraunhofer"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))

            self.bl.append(
                self.MKB_pslit,
                propagation_parameters(1 / 5, 1, 1 / 5, 1, mode='fresnel'))
            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MHE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d6, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MVE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MVE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d8, propagation_parameters(1, 1, 1, 1, mode='quadratic'))

            self.bl.append(self.MVP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.df,
                           propagation_parameters(5, 1, 5, 1, mode='converge'))

        elif focus == "nano":

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="fraunhofer"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))

            self.bl.append(
                self.NKB_pslit,
                propagation_parameters(1 / 10, 1, 1 / 10, 1, mode='fresnel'))
            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.NHE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.NHE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))

            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.NVE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.NVE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))

            self.bl.append(
                self.df,
                propagation_parameters(1 / 20, 1, 1 / 20, 1, mode='converge'))

        self.bl.params = self.params

    def get_beamline(self):
        return self.bl

    def crop_beamline(self, element1=None, element2=None):
        """
        crop the beamline to some position as defined by the name of the optical element
        
        :param bl: beamline object
        :param position: position to be cropped to
        """

        if element1 is not None:
            names = [
                el.name
                for el in self.bl.propagation_options[0]['optical_elements']
            ]
            idx1 = names.index(element1)

        if element2 is not None:
            names = [
                el.name
                for el in self.bl.propagation_options[0]['optical_elements']
            ]
            idx2 = names.index(element2)

        if element1 not in names:
            pass
        elif element2 is not None:
            self.bl.propagation_options[0][
                'optical_elements'] = self.bl.propagation_options[0][
                    'optical_elements'][idx1:idx2 + 1]
            self.bl.propagation_options[0][
                'propagation_parameters'] = self.bl.propagation_options[0][
                    'propagation_parameters'][idx1:idx2 + 1]
        else:
            self.bl.propagation_options[0][
                'optical_elements'] = self.bl.propagation_options[0][
                    'optical_elements'][:idx1 + 1]
            self.bl.propagation_options[0][
                'propagation_parameters'] = self.bl.propagation_options[0][
                    'propagation_parameters'][:idx1 + 1]

    def add_screen(self, position, distance, screenName=None):
        """
        add a screening plane at drift beyond some element position
        
        :param position: last optical element before screen
        :param distance: position from last optical element to screen
        :param screenName: name of the screen element (ie., MKB-scr etc) [str]
        """
        self.crop_beamline(element1=position)

        drift2screen = Drift(distance)
        if screenName is not None:
            drift2screen.name = "screen"
        else:
            drift2screen.name = screenName
        self.bl.append(Drift(distance),
                       propagation_parameters(1, 1, 1, 1, m='quadratic'))

    def mirror_profiles(self, toggle="on", aperture=True, overwrite=False):
        """
        toggle for mirror surfaces
        """
        if toggle == "on":
            self.define_mirror_profiles(overwrite=overwrite,
                                        aperture=aperture,
                                        surface='real')
        if toggle == "off":
            self.define_mirror_profiles(overwrite=overwrite,
                                        aperture=aperture,
                                        surface='flat')

    def get_mirror_profiles(self, mirror_name, context='talk', sdir=None):

        sns.set()

        surface = np.loadtxt(self.params[mirror_name]['mirror profile'])

        x = surface[1:, 0]
        y = surface[0, 1:]

        surface = surface[1:, 1:]

        mesh = get_mesh(surface, abs(x[1] - x[0]), abs(y[1] - y[0]))

        return surface, mesh

    @property
    def list_elements(self):
        return [el.name for el in self.optical_elements]

    @property
    def optical_elements(self):
        """
        returns an ordered list of optical elements
        """
        if hasattr(self, "bl"):
            optical_elements = self.bl.propagation_options[0][
                'optical_elements']
        else:
            assert ("instrument class has no beamline attribute")

        return optical_elements

    def element_index(self, element_name):
        """
        get the index of an element in a beamline by name
        """
        ### get index
        names = self.list_elements

        if element_name in names:
            index = names.index(element_name)
        else:
            assert ("Beamline does not contain optical element: {}".format(
                element_name))

        return index

    def remove_element(self, element_name):
        """
        remove an element from the beamline by name
        """

        index = self.element_index(element_name)

        del self.bl.propagation_options[0]['optical_elements'][index]
        del self.bl.propagation_options[0]['propagation_parameters'][index]

    def edit_propagation_parameters(self, element_name, new_parameters):
        """
        edit the propagation parameters of an element by name
        """
        self.bl.propagation_options[0]['propagation_parameters'][
            self.element_index(element_name)] = new_parameters
Ejemplo n.º 16
0
    
    
    val = nx//4
    
    for i in range(N):
   
        wfr = construct_SA1_wavefront(nx,ny,4.96,0.25)
        pm = np.random.rand(nx,ny)*1e-2
        print(pm[val,val])
        srwlib.srwl.SetRepresElecField(wfr._srwl_wf, 'f')    
        ps = phaseMask(pm, [ get_axis(wfr, axis = 'x').max()-
                                                get_axis(wfr, axis = 'x').min(),
                                                get_axis(wfr, axis = 'y').max()-
                                                get_axis(wfr, axis = 'y').min()], wav) ##speckle
            
        bl = Beamline()
        bl.append(sp, propagation_parameters(1,1,1,1))
        bl.propagate(wfr)
        
        
        bl = Beamline()
        bl.append(ps, propagation_parameters(1,1,1,1))
        bl.propagate(wfr)
        
        
        PH[:,:,i] = wfr.get_phase()[:,:,0] #% np.pi*2
        ## PH = (PH + np.pi) % (2 * np.pi) - np.pi


        
        bl = Beamline()
Ejemplo n.º 17
0
class Instrument(base_class):
    """
    A container for loading and modifying beamline data
    """
    def __init__(self, parameter_file=None, VERBOSE=True, **kwargs):

        self.VERBOSE = VERBOSE
        self.load_params(file=parameter_file)
        self.fpath = felpy_path()  ### felpy path (for dev. purposes)

        self.mirrors = [
            "HOM1", "HOM2", "MHE", "MVE", "MHP", "MVP", "NVE", "NHE"
        ]
        self.nano = ["HOM1", "HOM2", "NVE", "NHE"]
        self.focus = ["MHE", "MVE", "NVE", "NHE"]
        add_path()

        super().__init__(VERBOSE, **kwargs)

    def load_params(self, file=None):
        """
        load beamline parameters from /data/spb/
        """

        if file is not None:
            with open(file, "r") as read_file:
                self.params = json.load(read_file)
        else:
            self.params = get_params()

    def export_params(self, sdir=None):
        """
        save the current set of beamline parameters in json format

        :param sdir: save directory
        """
        if sdir is None:
            with open(self.fpath + '/data/spb/parameters.json', 'w') as f:
                json.dump(self.params, f)
        else:
            with open(sdir + 'parameters.json', 'w') as f:
                json.dump(self.params, f)

    def adjust_mirror(self, mirror_name, ekev, new_ang, mirror_refl=None):

        if mirror_refl is None:
            if ekev <= 7.5:
                material = "B4C"
            else:
                material = "Ru"

            refl = get_refl(load_refl(material), ekev, new_ang)

        new_ang = new_ang + np.tan(
            self.params[mirror_name]["xc"] /
            self.params[self.params[mirror_name]['next_drift']]['distance'])

        self.params[mirror_name]["design angle"] = new_ang
        self.params[mirror_name]["incidence angle"] = new_ang
        self.params[mirror_name]['reflectivity'] = (
            refl
        )  #**2 ### note, this maps to an absorption parameter (hence 1-refl)

    def load_mirror_profiles(self, surface="flat", aperture=True):

        for mirror in self.nano:

            if mirror in ["MHE", "MVP", "MVE", "MHP"]:
                fdir = self.fpath + "/data/spb/mirror_surface/{}_mir_{}.dat".format(
                    mirror, surface)
            else:
                fdir = self.fpath + "/data/spb/mirror_surface/{}_mir_real.dat".format(
                    mirror)

            if aperture:

                if os.path.exists(fdir):
                    if mirror in self.focus:
                        self.params[mirror + "_error"]['mirror profile'] = fdir

                    else:
                        self.params[mirror]['mirror profile'] = fdir

                else:
                    print("The mirror path could not be found")
                    print("Generating Random Mirror File")
                    generate_mirror_surface(
                        512,
                        512,
                        dx=self.params[mirror]['dx'],
                        dy=self.params[mirror]['dy'],
                        savedir="../../data/spb/mirror_surface/",
                        mode=surface,
                        mirror_name=mirror)

                    self.params[mirror]['mirror profile'] = fdir

            elif aperture == False:

                ## ask liuba "RuntimeError: Failed to determine optical axis after reflection from mirror." for large el-mirror lengths

                if os.path.exists(fdir):
                    if mirror in self.focus:
                        self.params[mirror + "_error"]['mirror profile'] = fdir
                    else:
                        self.params[mirror]['mirror profile'] = fdir
                else:
                    generate_mirror_surface(
                        512,
                        512,
                        dx=100,
                        dy=100,
                        savedir="../../data/spb/mirror_surface/",
                        mode=surface,
                        mirror_name=mirror)

                    self.params[mirror]['mirror profile'] = fdir

    def build_elements(self, focus="nano"):

        self.d1 = Drift(self.params["HOM1"]['distance from source'])
        self.d1.name = self.params["d1"]['name']

        self.HOM1 = MirPl(np.loadtxt(
            self.params['HOM1']['mirror profile'].replace("../../", "")),
                          _dim=self.params['HOM1']['orientation'],
                          _ang=self.params['HOM1']['incidence angle'],
                          _amp_coef=1,
                          _x=self.params['HOM1']['xc'],
                          _y=self.params['HOM1']['yc'],
                          _refl=self.params['HOM1']['reflectivity'])

        self.HOM1.name = self.params['HOM1']['name']

        self.d2 = Drift(self.params["HOM2"]['distance from source'] -
                        self.params["HOM1"]['distance from source'])
        self.d2.name = self.params["d2"]['name']

        self.HOM2 = MirPl(np.loadtxt(
            self.params['HOM2']['mirror profile'].replace("../../", "")),
                          _dim=self.params['HOM2']['orientation'],
                          _ang=self.params['HOM2']['incidence angle'],
                          _amp_coef=1,
                          _x=self.params['HOM2']['xc'],
                          _y=self.params['HOM2']['yc'],
                          _refl=self.params['HOM2']['reflectivity'])

        self.HOM2.name = self.params['HOM2']['name']

        if focus == "direct":

            self.params["d3"]["distance"] = 656.424
            self.params["d4"]["distance"] = 1.20
            self.params["d5"]["distance"] = 1.00
            self.params["df"]["distance"] = 2.2

            self.d3 = Drift(self.params["d3"]['distance'])
            self.d3.name = self.params["d3"]['name']

            self.d4 = Drift(self.params["d4"]['distance'])
            self.d4.name = self.params["d4"]['name']

            self.d5 = Drift(self.params["d5"]['distance'])
            self.d5.name = self.params["d5"]['name']

            self.df = Drift(self.params["df"]['distance'])
            self.df.name = 'df'

            self.NKB_PSlit = Aperture(
                _shape=self.params["NKB_PSlit"]['shape'],
                _ap_or_ob=self.params["NKB_PSlit"]['type'],
                _Dx=self.params["NKB_PSlit"]['dx'],
                _Dy=self.params["NKB_PSlit"]['dy'],
                _x=self.params["NKB_PSlit"]['xc'],
                _y=self.params["NKB_PSlit"]['yc'])
            self.NKB_PSlit.name = self.params["NKB_PSlit"]['name']

        if focus == "micron":
            self.d3 = Drift(self.params["d3"]['distance'])
            self.d3.name = self.params["d3"]['name']

            self.MKB_pslit = Aperture(
                _shape=self.params["MKB_pslit"]['shape'],
                _ap_or_ob=self.params["MKB_pslit"]['type'],
                _Dx=self.params["MKB_pslit"]['dx'],
                _Dy=self.params["MKB_pslit"]['dy'],
                _x=self.params["MKB_pslit"]['xc'],
                _y=self.params["MKB_pslit"]['yc'])
            self.MKB_pslit.name = self.params["MKB_pslit"]['name']

            self.d4 = Drift(self.params["d4"]['distance'])
            self.d4.name = self.params["d4"]['name']

            self.MHP = MirPl(np.loadtxt(
                self.params['MHP']['mirror profile'].replace("../../", "")),
                             _dim=self.params['MHP']['orientation'],
                             _ang=self.params['MHP']['incidence angle'],
                             _refl=self.params['MHP']['transmission'],
                             _x=self.params['MHP']['xc'],
                             _y=self.params['MHP']['yc'])
            self.MHP.name = self.params['MHP']['name']

            self.d5 = Drift(self.params["d5"]['distance'])
            self.d5.name = self.params["d5"]['name']

            self.MHE_error = MirPl(
                np.loadtxt(self.params['MHE_error']['mirror profile'].replace(
                    "../../", "")),
                _dim=self.params['MHE_error']['orientation'],
                _ang=self.params['MHE_error']['incidence angle'],
                _refl=self.params['MHE_error']['transmission'],
                _x=self.params['MHE_error']['xc'],
                _y=self.params['MHE_error']['yc'])

            self.MHE_error.name = self.params['MHE_error']['name']

            self.MVE_error = MirPl(
                np.loadtxt(self.params['MVE_error']['mirror profile'].replace(
                    "../../", "")),
                _dim=self.params['MVE_error']['orientation'],
                _ang=self.params['MVE_error']['incidence angle'],
                _refl=self.params['MVE_error']['transmission'],
                _x=self.params['MVE_error']['xc'],
                _y=self.params['MVE_error']['yc'])

            self.MVE_error.name = self.params['MVE_error']['name']

            self.MHE = MirEl(orient=self.params['MHE']["orientation"],
                             p=self.params['MHE']["distance from source"],
                             q=self.params['MHE']["distance to focus"],
                             thetaE=self.params['MHE']["design angle"],
                             theta0=self.params['MHE']["incidence angle"],
                             _x=self.params["MHE"]["xc"],
                             _y=self.params["MHE"]["yc"],
                             length=self.params['MHE']["length"],
                             roll=self.params['MHE']["roll"],
                             yaw=self.params['MHE']["yaw"],
                             _refl=self.params['MHE']["reflectivity"],
                             _ext_in=self.params['MHE']["_ext_in"],
                             _ext_out=self.params['MHE']["_ext_out"])

            self.MHE.name = self.params['MHE']['name']

            self.d6 = Drift(self.params["d7"]['distance'])
            self.d6.name = self.params["d7"]['name']

            self.MVE = MirEl(orient=self.params['MVE']["orientation"],
                             p=self.params['MVE']["distance from source"],
                             q=self.params['MVE']["distance to focus"],
                             thetaE=self.params['MVE']["design angle"],
                             theta0=self.params['MVE']["incidence angle"],
                             _x=self.params["MVE"]["xc"],
                             _y=self.params["MVE"]["yc"],
                             length=self.params['MVE']["length"],
                             roll=self.params['MVE']["roll"],
                             yaw=self.params['MVE']["yaw"],
                             _refl=self.params['MVE']["reflectivity"],
                             _ext_in=self.params['MVE']["_ext_in"],
                             _ext_out=self.params['MVE']["_ext_out"])

            self.MVE.name = self.params['MVE']['name']

            self.d8 = Drift(self.params["d8"]['distance'])
            self.d8.name = self.params["d8"]['name']

            self.MVP = MirPl(np.loadtxt(
                self.params['MVP']['mirror profile'].replace("../../", "")),
                             _dim=self.params['MVP']['orientation'],
                             _ang=self.params['MVP']['incidence angle'],
                             _refl=self.params['MVP']['transmission'],
                             _x=self.params['MVP']['xc'],
                             _y=self.params['MVP']['yc'])
            self.MVP.name = self.params['MVP']['name']

            self.df = Drift(self.params["df"]['distance'])
            self.df.name = self.params["df"]['name']

        elif focus == "nano":

            self.NKB_PSlit = Aperture(
                _shape=self.params["NKB_PSlit"]['shape'],
                _ap_or_ob=self.params["NKB_PSlit"]['type'],
                _Dx=self.params["NKB_PSlit"]['dx'],
                _Dy=self.params["NKB_PSlit"]['dy'],
                _x=self.params["NKB_PSlit"]['xc'],
                _y=self.params["NKB_PSlit"]['yc'])
            self.NKB_PSlit.name = self.params["NKB_PSlit"]['name']

            self.NHE = MirEl(orient=self.params['NHE']["orientation"],
                             p=self.params['NHE']["distance from source"],
                             q=self.params['NHE']["distance to focus"],
                             thetaE=self.params['NHE']["design angle"],
                             theta0=self.params['NHE']["incidence angle"],
                             _x=self.params["NHE"]["xc"],
                             _y=self.params["NHE"]["yc"],
                             length=self.params['NHE']["length"],
                             roll=self.params['NHE']["roll"],
                             yaw=self.params['NHE']["yaw"],
                             _refl=self.params['NHE']["reflectivity"],
                             _ext_in=self.params['NHE']["_ext_in"],
                             _ext_out=self.params['NHE']["_ext_out"])

            self.NHE.name = self.params["NHE"]["name"]

            self.NVE = MirEl(orient=self.params['NVE']["orientation"],
                             p=self.params['NVE']["distance from source"],
                             q=self.params['NVE']["distance to focus"],
                             thetaE=self.params['NVE']["design angle"],
                             theta0=self.params['NVE']["incidence angle"],
                             _x=self.params["NVE"]["xc"],
                             _y=self.params["NVE"]["yc"],
                             length=self.params['NVE']["length"],
                             roll=self.params['NVE']["roll"],
                             yaw=self.params['NVE']["yaw"],
                             _refl=self.params['NVE']["reflectivity"],
                             _ext_in=self.params['NVE']["_ext_in"],
                             _ext_out=self.params['NVE']["_ext_out"])

            self.NVE.name = self.params["NVE"]["name"]

            NVE_error = np.loadtxt(
                self.params['NVE_error']['mirror profile'].replace(
                    "../../", ""))
            NVE_error[1:, 1:] = gaussian_filter1d(NVE_error[1:, 1:], 20)

            self.NVE_error = MirPl(
                NVE_error,
                _dim=self.params['NVE_error']['orientation'],
                _ang=self.params['NVE_error']
                ['incidence angle'],  ### + self.params['NVE']['incidence angle'],
                _refl=self.params['NVE_error']['transmission'],
                _x=self.params['NVE_error']['xc'],
                _y=self.params['NVE_error']['yc'],
                _amp_coef=1e-10)

            self.NVE_error.name = self.params['NVE_error']['name']

            self.NHE_error = MirPl(
                np.loadtxt(self.params['NHE_error']['mirror profile'].replace(
                    "../../", "")),
                _dim=self.params['NHE_error']['orientation'],
                _ang=self.params['NHE_error']
                ['incidence angle'],  ###+self.params['NHE']['incidence angle'],
                _refl=self.params['NHE_error']['transmission'],
                _x=self.params['NHE_error']['xc'],
                _y=self.params['NHE_error']['yc'],
                _amp_coef=1e-10)

            self.NHE_error.name = self.params['NHE_error']['name']

            self.params["d3"]["distance"] = 656.424
            self.params["d4"]["distance"] = 1.20
            self.params["d5"]["distance"] = 1.00
            self.params["df"]["distance"] = 2.2

            self.d3 = Drift(self.params["d3"]['distance'])
            self.d3.name = self.params["d3"]['name']

            self.d4 = Drift(self.params["d4"]['distance'])
            self.d4.name = self.params["d4"]['name']

            self.d5 = Drift(self.params["d5"]['distance'])
            self.d5.name = self.params["d5"]['name']

            self.df = Drift(self.params["df"]['distance'])
            self.df.name = 'df'

    def build_beamline(self, focus="nano", screens="false"):
        """
        Construct the beamline object

        :param focus: what beamline configuration (micron or nano)
        """

        self.bl = Beamline()

        if focus == 'direct':

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="quadratic"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(2, 1, 2, 1, mode='fraunhofer'))

            self.bl.append(
                self.NKB_PSlit,
                propagation_parameters(1 / 10, 1, 1 / 10, 1, mode='fresnel'))
            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))
            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(
                self.df, propagation_parameters(1, 1, 1, 1, mode='quadratic'))

        if focus == "micron":

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="fraunhofer"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))

            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MHE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d6, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MVE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MVE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d8, propagation_parameters(1, 1, 1, 1, mode='quadratic'))

            self.bl.append(self.MVP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.df,
                           propagation_parameters(5, 1, 5, 1, mode='converge'))

        elif focus == "nano":

            self.bl.append(self.d1,
                           propagation_parameters(*self.params['d1']['pp']))

            self.bl.append(self.HOM1,
                           propagation_parameters(*self.params['HOM1']['pp']))
            self.bl.append(self.d2,
                           propagation_parameters(*self.params['d2']['pp']))
            self.bl.append(self.HOM2,
                           propagation_parameters(*self.params['HOM2']['pp']))
            self.bl.append(self.d3,
                           propagation_parameters(*self.params['d3']['pp']))

            self.bl.append(
                self.NKB_PSlit,
                propagation_parameters(*self.params['NKB_PSlit']['pp']))
            self.bl.append(self.d4,
                           propagation_parameters(*self.params['d4']['pp']))
            self.bl.append(
                self.NHE_error,
                propagation_parameters(*self.params['NHE_error']['pp']))
            self.bl.append(self.NHE,
                           propagation_parameters(*self.params['NHE']['pp']))

            self.bl.append(self.d5,
                           propagation_parameters(*self.params['d5']['pp']))
            self.bl.append(
                self.NVE_error,
                propagation_parameters(*self.params['NVE_error']['pp']))
            self.bl.append(self.NVE,
                           propagation_parameters(*self.params['NVE']['pp']))

            #self.bl.append(self.df, propagation_parameters(1,1,1,1, mode = 'converge'))
            #self.bl.append(self.df, propagation_parameters(15,1,15,1, mode = 'converge')) ### perfect mirrors

        self.bl.params = self.params

    def get_beamline(self):
        return self.bl

    def crop_beamline(self, element1=None, element2=None):
        """
        crop the beamline to some position as defined by the name of the optical element

        :param bl: beamline object
        :param position: position to be cropped to
        """

        if element1 is not None:
            names = [
                el.name
                for el in self.bl.propagation_options[0]['optical_elements']
            ]
            idx1 = names.index(element1)
        else:
            idx1 = 0

        if element2 is not None:
            names = [
                el.name
                for el in self.bl.propagation_options[0]['optical_elements']
            ]
            idx2 = names.index(element2)

        elif element2 is not None:
            self.bl.propagation_options[0][
                'optical_elements'] = self.bl.propagation_options[0][
                    'optical_elements'][idx1:idx2 + 1]
            self.bl.propagation_options[0][
                'propagation_parameters'] = self.bl.propagation_options[0][
                    'propagation_parameters'][idx1:idx2 + 1]
        else:
            self.bl.propagation_options[0][
                'optical_elements'] = self.bl.propagation_options[0][
                    'optical_elements'][:idx1 + 1]
            self.bl.propagation_options[0][
                'propagation_parameters'] = self.bl.propagation_options[0][
                    'propagation_parameters'][:idx1 + 1]

    def add_screen(self, position, distance, screenName=None):
        """
        add a screening plane at drift beyond some element posiFalsetion

        :param position: last optical element before screen
        :param distance: position from last optical element to screen
        :param screenName: name of the screen element (ie., MKB-scr etc) [str]
        """
        self.crop_beamline(element1=position)

        drift2screen = Drift(distance)
        if screenName is not None:
            drift2screen.name = "screen"
        else:
            drift2screen.name = screenName
        self.bl.append(Drift(distance),
                       propagation_parameters(1, 1, 1, 1, m='quadratic'))

    def mirror_profiles(self, surface, aperture, overwrite=True):
        """
        toggle for mirror surfaces
        """
        self.load_mirror_profiles(aperture=aperture, surface=surface)

    def get_mirror_profile(self, mirror_name, sdir=None):

        surface = np.loadtxt(self.params[mirror_name]['mirror profile'])

        x = surface[1:, 0] * 1e3
        y = surface[0, 1:] * 1e3

        surface = surface[1:, 1:]

        return surface, x, y

    def rebuild(self, focus='nano'):
        self.build_elements(focus)
        self.build_beamline(focus)
Ejemplo n.º 18
0
    def build_beamline(self, focus="nano", screens="false"):
        """
        Construct the beamline object

        :param focus: what beamline configuration (micron or nano)
        """

        self.bl = Beamline()

        if focus == 'direct':

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="quadratic"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(2, 1, 2, 1, mode='fraunhofer'))

            self.bl.append(
                self.NKB_PSlit,
                propagation_parameters(1 / 10, 1, 1 / 10, 1, mode='fresnel'))
            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))
            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(
                self.df, propagation_parameters(1, 1, 1, 1, mode='quadratic'))

        if focus == "micron":

            self.bl.append(
                self.d1, propagation_parameters(1, 1, 1, 1, mode="fraunhofer"))

            self.bl.append(self.HOM1,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d2, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.HOM2,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d3, propagation_parameters(1, 1, 1, 1, mode='fraunhofer'))

            self.bl.append(
                self.d4, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d5, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MHE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MHE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d6, propagation_parameters(1, 1, 1, 1, mode='quadratic'))
            self.bl.append(self.MVE,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.MVE_error,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(
                self.d8, propagation_parameters(1, 1, 1, 1, mode='quadratic'))

            self.bl.append(self.MVP,
                           propagation_parameters(1, 1, 1, 1, mode='fresnel'))
            self.bl.append(self.df,
                           propagation_parameters(5, 1, 5, 1, mode='converge'))

        elif focus == "nano":

            self.bl.append(self.d1,
                           propagation_parameters(*self.params['d1']['pp']))

            self.bl.append(self.HOM1,
                           propagation_parameters(*self.params['HOM1']['pp']))
            self.bl.append(self.d2,
                           propagation_parameters(*self.params['d2']['pp']))
            self.bl.append(self.HOM2,
                           propagation_parameters(*self.params['HOM2']['pp']))
            self.bl.append(self.d3,
                           propagation_parameters(*self.params['d3']['pp']))

            self.bl.append(
                self.NKB_PSlit,
                propagation_parameters(*self.params['NKB_PSlit']['pp']))
            self.bl.append(self.d4,
                           propagation_parameters(*self.params['d4']['pp']))
            self.bl.append(
                self.NHE_error,
                propagation_parameters(*self.params['NHE_error']['pp']))
            self.bl.append(self.NHE,
                           propagation_parameters(*self.params['NHE']['pp']))

            self.bl.append(self.d5,
                           propagation_parameters(*self.params['d5']['pp']))
            self.bl.append(
                self.NVE_error,
                propagation_parameters(*self.params['NVE_error']['pp']))
            self.bl.append(self.NVE,
                           propagation_parameters(*self.params['NVE']['pp']))

            #self.bl.append(self.df, propagation_parameters(1,1,1,1, mode = 'converge'))
            #self.bl.append(self.df, propagation_parameters(15,1,15,1, mode = 'converge')) ### perfect mirrors

        self.bl.params = self.params
Ejemplo n.º 19
0
def sliceFocus(wfr,
               ekev,
               focus='micron',
               nslices=500,
               axisName='x',
               outdir=None):

    spb = Instrument(overwrite_mirrors=False)
    spb.setupHOMs(ekev)
    spb.build_elements(focus=focus)
    spb.buildBeamline(focus=focus)

    el_n = len(spb.bl.propagation_options[0]['optical_elements']) - 1

    slice_interval = copy(
        spb.bl.propagation_options[0]['optical_elements'][el_n].L / 1000)
    spb.bl.propagation_options[0]['optical_elements'][el_n].L *= 0.75
    spb.bl.propagation_options[0]['propagation_parameters'][
        el_n] = propagation_parameters(1 / 5, 5, 1 / 5, 5, mode='quadratic')
    bl = spb.get_beamline()
    bl.propagate(wfr)

    if axisName == 'x':
        data_focslice = np.zeros([nslices, np.shape(wfr.data.arrEhor)[0]])
    elif axisName == 'y':
        data_focslice = np.zeros([nslices, np.shape(wfr.data.arrEhor)[1]])

    fig = plt.figure()
    ax = fig.add_subplot(111)

    for n in range(nslices):
        print("Slice {}/{}".format(n + 1, nslices))

        bl = Beamline()
        bl.append(SRWLOptD(slice_interval),
                  propagation_parameters(1, 1, 1, 1, mode='normal'))
        bl.propagate(wfr)

        data_focslice[-n - 1, :] = wfr.get_profile_1d()[0]

    y = np.linspace(
        spb.bl.propagation_options[0]['optical_elements'][el_n].L,
        spb.bl.propagation_options[0]['optical_elements'][el_n].L +
        nslices * slice_interval, nslices)

    if axisName == 'x':
        extent = [
            wfr.params.Mesh.xMin * 1e6, wfr.params.Mesh.xMax * 1e6,
            y.min(),
            y.max()
        ]
    elif axisName == 'y':
        extent = [
            wfr.params.Mesh.yMin * 1e6, wfr.params.Mesh.yMax * 1e6,
            y.min(),
            y.max()
        ]
    ax.imshow(data_focslice,
              extent=extent,
              aspect='auto',
              norm=mpl.colors.LogNorm())

    if focus == "micron":
        ax.set_title("Micron Focus Location")
        ax.set_ylabel("Longitudinal Distance from MKB (m)")

        if axisName == 'x':
            x = np.linspace(wfr.params.Mesh.xMin * 1e6,
                            wfr.params.Mesh.xMax * 1e6, wfr.params.Mesh.nx)
            ax.set_xlabel("x ($\mu$m)")
        elif axisName == 'y':
            x = np.linspace(wfr.params.Mesh.yMin * 1e6,
                            wfr.params.Mesh.yMax * 1e6, wfr.params.Mesh.ny)
            ax.set_xlabel("y ($\mu$m)")

    if focus == "nano":
        ax.set_title("Nano Focus Location")
        ax.set_ylabel("Longitudinal Distance from NKB (m)")

        if axisName == 'x':
            x = np.linspace(wfr.params.Mesh.xMin * 1e6,
                            wfr.params.Mesh.xMax * 1e6, wfr.params.Mesh.nx)
            ax.set_xlabel("x ($\mu$m)")
        elif axisName == 'y':
            x = np.linspace(wfr.params.Mesh.yMin * 1e6,
                            wfr.params.Mesh.yMax * 1e6, wfr.params.Mesh.ny)
            ax.set_xlabel("y ($\mu$m)")

    ax.plot(x, np.ones(x.shape) * spb.bl.params["df"]["distance"], 'r--')
    plt.legend(["Design Focal Plane"])

    plt.show()

    estr = str(ekev).replace(".", "-")

    if outdir is not None:
        fig.savefig(outdir +
                    "{}_focus_slice_{}_{}".format(focus, estr, axisName))
Ejemplo n.º 20
0
    A = np.zeros((N, N), 'float32')
    B = np.zeros((N, 1), 'float32')

    wfr = construct_SA1_wavefront(nx, ny, 4.96, 0.25)
    wfr.store_hdf5("coherentSrc.h5")

    wav = (h * c) / (wfr.params.photonEnergy * e)
    pm = gaussian_filter(np.random.rand(5, 5) / 1000, sigma=20)
    plt.imshow(pm)

    sp = phaseMask(pm, [
        get_axis(wfr, axis='x').max() - get_axis(wfr, axis='x').min(),
        get_axis(wfr, axis='y').max() - get_axis(wfr, axis='y').min()
    ], wav)  ##speckle

    bl = Beamline()
    #bl.append(sp, propagation_parameters(1,1,1,1))
    bl.append(Drift(1), propagation_parameters(1, 1, 1, 1, mode='normal'))
    bl.propagate(wfr)

    Ps = wfr.get_phase(slice_number=0)  #
    Is = wfr.get_intensity(slice_number=0)

    ekev = wfr.params.photonEnergy
    z1 = 1
    z2 = 1
    pix_size = wfr.get_spatial_resolution()[0]
    delta = 1
    beta = 1
    bg_val = 1
    scale = 1
Ejemplo n.º 21
0
# -*- coding: utf-8 -*-

import sys

from felpy.model.wavefront import Wavefront
from felpy.model.beamline import Beamline
from wpg.optical_elements import Drift
from felpy.model.tools import propagation_parameters
from felpy.utils.os_utils import mkdir_p

if __name__ == '__main__':
    print("working")
    in_directory = sys.argv[1]
    print("in: ", in_directory)
    out_directory = sys.argv[2]
    print("out: ", out_directory)
    wfr = Wavefront()
    wfr.load_hdf5(in_directory)
    print("wfr loaded")
    bl = Beamline()
    bl.append(Drift(3.644 - 2.2),
              propagation_parameters(1, 1, 1, 1, 'quadratic'))
    bl.propagate(wfr)
    print("wfr propagated")
    wfr.store_hdf5(out_directory)
    print("wfr stored")
    wfr.analysis(VERBOSE=True, DEBUG=True)
    #print(wfr.custom_fields) ## good debug