Exemple #1
0
    def test_setters_and_getters(self):

        print("# ")
        print("# setters and getters ")
        print("# ")
        a = Beam.initialize_as_pencil(200)
        b= a.duplicate()
        assert_equal (a.get_number_of_rays() - b.get_number_of_rays(), 0)
        assert_equal (a.get_column(1).mean() - b.get_column(1).mean(), 0)

        a.set_photon_energy_eV(1.0)
        assert_equal(a.get_photon_energy_eV(),1.0)

        a.set_photon_wavelength(1.51e-10)
        assert_equal(a.get_photon_wavelength(),1.51e-10)

        for i in range(18):
            a.set_column(i,numpy.pi)
            assert_equal (a.get_column(i).mean(),numpy.pi)

        a = Beam.initialize_as_pencil(200)
        assert_equal (a.get_intensity(nolost=1),200)
        assert_equal (a.get_intensity(nolost=2),0)
        flag = a.get_column(10)
        flag[50:100] = -1 # remember flag[100] is NOT changed!!
        a.set_column(10,flag)
        assert_equal (a.get_intensity(nolost=1),150)
Exemple #2
0
def example_branch_3(surface_shape_file, do_plot=True):
    #
    # source
    #
    # beam0 = Beam.initialize_as_pencil(N=500)
    source = SourceGaussian.initialize_from_keywords(
        number_of_rays=100000,
        sigmaX=0.0,
        sigmaY=0.0,
        sigmaZ=0.0,
        sigmaXprime=1e-4,
        sigmaZprime=1e-4,
    )
    beam0 = Beam()
    beam0.genSource(source)
    print(beam0.info())

    if do_plot:
        plotxy(beam0, 4, 6, title="Image 0", nbins=201)

    #
    # syned definitopns
    #

    # boundaries
    rlen1 = 0.6
    rlen2 = 0.6
    rwidx1 = 0.05
    rwidx2 = 0.05

    #
    # shadow definitions
    #
    mirror1 = S4SurfaceDataMirrorElement(optical_element=S4SurfaceDataMirror(
        name="M1",
        surface_data_file=surface_shape_file,
        boundary_shape=Rectangle(x_left=-rwidx2,
                                 x_right=rwidx1,
                                 y_bottom=-rlen2,
                                 y_top=rlen1)),
                                         coordinates=ElementCoordinates(
                                             p=100.0,
                                             q=1000.0,
                                             angle_radial=numpy.radians(88.8)))
    print(mirror1.info())

    #
    # run
    #
    beam1, mirr1 = mirror1.trace_beam(beam0)
    print(mirr1.info())

    #
    # check
    #

    if do_plot:
        plotxy(beam1, 1, 3, title="Image 1", nbins=101, nolost=1)
        plotxy(mirr1, 2, 1, title="Footprint 1", nbins=101, nolost=1)
Exemple #3
0
    def duplicate(self, copy_rays=True, history=True):
        beam = Beam()
        if copy_rays: beam.rays = copy.deepcopy(self._beam.rays)

        new_shadow_beam = ShadowBeam(self._oe_number, beam)
        new_shadow_beam.setScanningData(self.scanned_variable_data)

        if history:
            for historyItem in self.history:
                new_shadow_beam.history.append(historyItem)

        return new_shadow_beam
Exemple #4
0
def example_branch_2(do_plot=True):
    source = SourceGaussian.initialize_from_keywords(
        number_of_rays=100000,
        sigmaX=0.0,
        sigmaY=0.0,
        sigmaZ=0.0,
        sigmaXprime=1e-6,
        sigmaZprime=1e-6,
    )
    beam0 = Beam()
    beam0.genSource(source)
    print(beam0.info())

    if do_plot:
        plotxy(beam0, 4, 6, title="Image 0", nbins=201)

    #
    # syned definitopns
    #

    # boundaries
    boundary_shape = None  #Rectangle(x_left=-rwidx2,x_right=rwidx1,y_bottom=-rlen2,y_top=rlen1)

    #
    # shadow definitions
    #
    mirror1 = S4ToroidalMirrorElement(optical_element=S4ToroidalMirror(
        name="M1",
        surface_calculation=SurfaceCalculation.EXTERNAL,
        min_radius=0.157068,
        maj_radius=358.124803 - 0.157068,
        boundary_shape=boundary_shape),
                                      coordinates=ElementCoordinates(
                                          p=10.0,
                                          q=6.0,
                                          angle_radial=numpy.radians(88.8)))

    print(mirror1.info())

    #
    # run
    #
    beam1, mirr1 = mirror1.trace_beam(beam0)
    print(mirr1.info())

    #
    # check
    #

    if do_plot:
        plotxy(beam1, 1, 3, title="Image 1", nbins=101, nolost=1)
        plotxy(mirr1, 2, 1, title="Footprint 1", nbins=101, nolost=1)
Exemple #5
0
    def __new__(cls, oe_number=0, beam=None, number_of_rays=0):
        self = super().__new__(cls)
        self._oe_number = oe_number
        if (beam is None):
            if number_of_rays > 0:
                self._beam = Beam(number_of_rays)
            else:
                self._beam = Beam()
        else:
            self._beam = beam

        self.history = []
        self.scanned_variable_data = None

        return self
Exemple #6
0
    def traceFromSource(cls,
                        shadow_src,
                        write_begin_file=0,
                        write_start_file=0,
                        write_end_file=0,
                        history=True,
                        widget_class_name=None):
        self = cls.__new__(ShadowBeam, beam=Beam())

        shadow_src.self_repair()

        shadow_source_start = shadow_src.duplicate()

        if write_start_file == 1:
            shadow_src.src.write("start.00")

        self._beam.genSource(shadow_src.src)

        shadow_src.self_repair()

        if write_begin_file:
            self.writeToFile("begin.dat")

        if write_end_file == 1:
            shadow_src.src.write("end.00")

        shadow_source_end = shadow_src.duplicate()

        if history:
            self.history.append(
                ShadowOEHistoryItem(shadow_source_start=shadow_source_start,
                                    shadow_source_end=shadow_source_end,
                                    widget_class_name=widget_class_name))

        return self
Exemple #7
0
    def get_beam(self, N=5000, POL_DEG=1.0, POL_ANGLE=0.0, F_COHER=False):

        rays = self.calculate_rays(N=N,
                                   POL_DEG=POL_DEG,
                                   POL_ANGLE=POL_ANGLE,
                                   F_COHER=F_COHER)
        return Beam.initialize_from_array(rays)
Exemple #8
0
    def load_h5(cls, filename, simulation_name="run001", beam_name="begin"):
        b4 = Beam_shadow4.load_h5(filename,
                                  simulation_name=simulation_name,
                                  beam_name=beam_name)
        b3 = Beam3(N=b4.rays.shape[0])
        b3.rays = b4.rays.copy()

        return b3
Exemple #9
0
    def test_write_and_load(self):
        print("# ")
        print("# file write/load ")
        print("# ")
        a = Beam.initialize_as_pencil(200)
        a.rays[:, 0] = numpy.random.rand(200)
        a.rays[:, 2] = numpy.random.rand(200)

        a.write_h5("tmp.h5", simulation_name="run1", beam_name="begin", overwrite=True)
        a.write_h5("tmp.h5", simulation_name="run1", beam_name="star01", overwrite=False)
        a.write_h5("tmp.h5", simulation_name="run2", beam_name="begin", overwrite=False)

        b = Beam.load_h5("tmp.h5",simulation_name="run2", beam_name="begin")

        print("a is equal to b ? ", a.identical(b))
        assert(a.identical(b))

        a.difference(b)
Exemple #10
0
def minishadow_run_mesh_mirror():

    # ;
    # ; ray tracing of a surface defined with a mesh using minishadow
    # ; results are compared with shadow3
    # ;

    # ;
    # ; Runs shadow3
    # ;
    shadow3_beam_source,shadow3_beam,oe0,oe1 = run_shadow3_from_start_files(iwrite=1)


    # copy source to new Beam object
    newbeam = Beam.initialize_from_array(shadow3_beam_source.rays.copy())


    # ;
    # ; INPUTS
    # ;

    p             = oe1.T_SOURCE # 1000.0       # source-mirror
    q             = oe1.T_IMAGE  # 300.0        # mirror-image
    alpha         = oe1.ALPHA    # 0.0      # mirror orientation angle
    theta_grazing = (90.0-oe1.T_INCIDENCE) * numpy.pi / 180  # 5e-3     # grazing angle, rad

    print("p=%f, q=%f, alpha=%f, theta_grazing=%f rad"%(p,q,alpha,theta_grazing))

    mm = S4Mesh()
    mm.load_file("bump.dat")

    newbeam.rotate(alpha,axis=2)
    newbeam.rotate(theta_grazing,axis=1)
    newbeam.translation([0.0,-p*numpy.cos(theta_grazing),p*numpy.sin(theta_grazing)])


    #
    # reflect beam in the mirror surface and dump mirr.01
    #

    newbeam, normal, t, x1, v1, x2, v2 = mm.apply_specular_reflection_on_beam(newbeam)

    from shadow4tests.compatibility.beam3 import Beam3
    Beam3.initialize_from_shadow4_beam(newbeam).write('minimirr.01')

    #
    # put beam in lab frame and compute image
    #
    newbeam.rotate(theta_grazing,axis=1)
    # TODO what about alpha?
    newbeam.retrace(q,resetY=True)
    Beam3.initialize_from_shadow4_beam(newbeam).write('ministar.01')
Exemple #11
0
    def get_beam(self, F_COHER=0, NRAYS=5000, SEED=123456,
                       EPSI_DX=0.0, EPSI_DZ=0.0,
                       psi_interval_in_units_one_over_gamma=None,
                       psi_interval_number_of_points=1001,
                       verbose=False):

        return Beam.initialize_from_array(self.__calculate_rays(F_COHER=F_COHER,
                                                                NRAYS=NRAYS,
                                                                SEED=SEED,
                                                                EPSI_DX=EPSI_DX,
                                                                EPSI_DZ=EPSI_DZ,
                                                                psi_interval_in_units_one_over_gamma=psi_interval_in_units_one_over_gamma,
                                                                psi_interval_number_of_points=psi_interval_number_of_points,
                                                                verbose=verbose))
Exemple #12
0
    def get_beam(self, NRAYS=5000, SEED=123456):
        user_unit_to_m = 1.0
        F_COHER = 0
        # use_gaussian_approximation = False

        if self.get_magnetic_structure().use_gaussian_approximation():
            return self.get_beam_in_gaussian_approximation(NRAYS=NRAYS,
                                                           SEED=SEED)
        else:
            return Beam.initialize_from_array(
                self.__calculate_rays(user_unit_to_m=user_unit_to_m,
                                      F_COHER=F_COHER,
                                      NRAYS=NRAYS,
                                      SEED=SEED))
Exemple #13
0
    def get_beam(self,wavelength=1e-10):
        """
        Returns a Beam
        :param wavelength: the photon wavelength in m
        :return:
        """

        rays = numpy.zeros((self.get_number_of_points(),18))
        rays[:,0:6] = self.get_volume()
        rays[:,6] = 1.0 # Es
        rays[:,9] = 1   # flag
        rays[:,10] = 2 * numpy.pi / (wavelength * 1e2) # wavenumber
        rays[:,11] = numpy.arange(self.get_number_of_points(),dtype=float) # index
        return Beam.initialize_from_array(rays)
Exemple #14
0
    def get_beam(self, NRAYS=5000, SEED=123456):

        user_unit_to_m = 1.0
        F_COHER = 0
        EPSI_DX = 0.0
        EPSI_DZ = 0.0
        psi_interval_in_units_one_over_gamma = None
        psi_interval_number_of_points = 1001
        verbose = True

        return Beam.initialize_from_array(
            self.__calculate_rays(
                user_unit_to_m=user_unit_to_m,
                F_COHER=F_COHER,
                NRAYS=NRAYS,
                SEED=SEED,
                EPSI_DX=EPSI_DX,
                EPSI_DZ=EPSI_DZ,
                psi_interval_in_units_one_over_gamma=
                psi_interval_in_units_one_over_gamma,
                psi_interval_number_of_points=psi_interval_number_of_points,
                verbose=verbose))
Exemple #15
0
    def test_rotations_and_translations(self):


        print("# ")
        print("# rotations and translations ")
        print("# ")
        a = Beam.initialize_as_pencil(200)
        a.translation([10,100.0,20])
        assert_equal (a.get_column(1).mean(),10)
        assert_equal (a.get_column(2).mean(),100)
        assert_equal (a.get_column(3).mean(),20)

        a = Beam.initialize_as_pencil(200)
        a.rotate(-45.*numpy.pi/180,axis=1)
        assert_equal(a.get_column(4).mean(),0)
        assert_almost_equal(a.get_column(5).mean(),numpy.sqrt(2)/2)
        assert_almost_equal(a.get_column(6).mean(),numpy.sqrt(2)/2)

        a = Beam.initialize_as_pencil(200)
        a.rotate(-45.*numpy.pi/180,axis=2)
        assert_equal(a.get_column(4).mean(),0.0)
        assert_equal(a.get_column(5).mean(),1.0)
        assert_equal(a.get_column(6).mean(),0.0)

        a = Beam.initialize_as_pencil(200)
        a.rotate(45.*numpy.pi/180,axis=3)
        # print(a.get_column(4).mean(),a.get_column(5).mean(),a.get_column(6).mean(),)
        assert_almost_equal(a.get_column(4).mean(),numpy.sqrt(2)/2)
        assert_almost_equal(a.get_column(5).mean(),numpy.sqrt(2)/2)
        assert_equal(a.get_column(6).mean(),0)

        a = Beam.initialize_as_pencil(200)
        a.rotate(-45.*numpy.pi/180,axis=1)
        a.retrace(5.0)
        assert_equal(a.get_column(1).mean(),0)
        assert_almost_equal(a.get_column(2).mean(),5.0)
        assert_almost_equal(a.get_column(3).mean(),5.0)
        #
        a = Beam.initialize_as_pencil(200)
        a.rotate(-45.*numpy.pi/180,axis=1)
        a.retrace(15.0,resetY=True)
        assert_equal(a.get_column(1).mean(),0)
        assert_almost_equal(a.get_column(2).mean(),0.0)
        assert_almost_equal(a.get_column(3).mean(),15.0)
Exemple #16
0
    #
    # shadow3
    #
    from shadow4tests.oasys_workspaces.mirrors_branch3_mesh import define_source, run_source, define_beamline, run_beamline

    oe0 = define_source()
    beam3_source = run_source(oe0)

    #
    # shadow4
    #

    oe = define_beamline()[0]

    beam4_source = Beam.initialize_from_array(beam3_source.rays)
    beam4 = beam4_source

    check_congruence(oe)

    #
    # shadow definitions
    #

    name = "SurfaceDataMirror"
    mirror1 = S4SurfaceDataMirrorElement(
        optical_element=S4SurfaceDataMirror(
            name=name,
            surface_data_file="../oasys_workspaces/mirrors_branch3_mesh.hdf5",
            boundary_shape=Rectangle(
                x_left=-oe.RWIDX2,
Exemple #17
0
def minishadow_run_conic_mirror(shadow3_beam_source, shadow3_beam, oe0, oe1):

    # ;
    # ; ray tracing of a single conic mirror using minishadow
    # ; results are compared with shadow3
    # ;
    #

    # copy source to new Beam object
    newbeam = Beam.initialize_from_array(shadow3_beam_source.rays.copy())

    # ;
    # ; INPUTS
    # ;
    #
    fmirr = oe1.FMIRR  # 1
    p = oe1.T_SOURCE  # 1000.0       # source-mirror
    q = oe1.T_IMAGE  # 300.0        # mirror-image
    alpha = oe1.ALPHA  # 0.0      # mirror orientation angle
    theta_grazing = (90.0 - oe1.T_INCIDENCE
                     ) * numpy.pi / 180  # 5e-3     # grazing angle, rad
    fcyl = oe1.FCYL
    f_convex = oe1.F_CONVEX

    print("fmirr = %s, p=%f, q=%f, alpha=%f, theta_grazing=%f rad, fcyl=%d"%\
              (fmirr,p,q,alpha,theta_grazing,fcyl))

    # ccc = SurfaceConic()
    # ccc.set_sphere_from_focal_distances(p,q,theta_grazing,itype=fmirr,cylindrical=fcyl)

    if fmirr == 1:  # sphere
        ccc = S4Conic.initialize_as_sphere_from_focal_distances(
            p, q, theta_grazing, cylindrical=fcyl, switch_convexity=f_convex)
    elif fmirr == 2:  # Ellipsoid
        ccc = S4Conic.initialize_as_ellipsoid_from_focal_distances(
            p, q, theta_grazing, cylindrical=fcyl, switch_convexity=f_convex)
    elif fmirr == 3:  # Toroidal
        raise Exception("fmirr=3 (toroidal) is NOT A CONIC surface")
    elif fmirr == 4:  # Paraboloid
        ccc = S4Conic.initialize_as_paraboloid_from_focal_distances(
            p, q, theta_grazing, cylindrical=fcyl, switch_convexity=f_convex)
    elif fmirr == 5:
        ccc = S4Conic.initialize_as_plane()
    elif fmirr == 6:  # Codling slit
        raise Exception("fmirr=6 (Codling slit) is NOT A CONIC surface")
    elif fmirr == 7:  # Hyperboloid
        ccc = S4Conic.initialize_as_hyperboloid_from_focal_distances(
            p, q, theta_grazing, cylindrical=fcyl, switch_convexity=f_convex)
    elif fmirr == 8:  # Cone
        raise Exception("fmirr=8 (Cone) is NOT A CONIC surface")
    else:
        raise Exception("fmirr invalid")

    print(ccc.info())
    #
    # put beam in mirror reference system
    #
    # TODO: calculate rotation matrices? Invert them for putting back to the lab system?

    newbeam.rotate(alpha, axis=2)
    newbeam.rotate(theta_grazing, axis=1)
    newbeam.translation(
        [0.0, -p * numpy.cos(theta_grazing), p * numpy.sin(theta_grazing)])
    #
    # # newbeam.rotate(alpha,axis=2)
    # # newbeam.rotate(theta_grazing,axis=1)
    # # newbeam.translation([0.0,-p*numpy.cos(theta_grazing),p*numpy.sin(theta_grazing)])
    #
    #
    #
    # reflect beam in the mirror surface and dump mirr.01
    #
    newbeam, tmp = ccc.apply_specular_reflection_on_beam(newbeam)
    Beam3.initialize_from_shadow4_beam(newbeam).write('minimirr.01')

    #
    # put beam in lab frame and compute image
    #
    newbeam.rotate(theta_grazing, axis=1)
    # TODO what about alpha?
    newbeam.retrace(q, resetY=True)
    Beam3.initialize_from_shadow4_beam(newbeam).write('ministar.01')
Exemple #18
0
    # patches = MultiplePatch()
    # patches.append_polygon([-1,-1,1,1],[-1,1,1,-1])

    source3, beam3 = run_shadow3()

    #
    if do_plot:
        plotxy(beam3,
               1,
               3,
               nbins=100,
               title="SHADOW3 BEAMSTOPPER",
               nolost=True)

    beam = Beam.initialize_from_array(source3.rays)

    scr = S4Screen(
        name="Undefined",
        boundary_shape=patches,
        i_abs=False,  # include absorption
        i_stop=True,  # aperture/stop
        thick=0.0,  # thickness of the absorber (in SI)
        file_abs="",  # if i_abs=True, the material file (from prerefl)
    )

    coordinates = ElementCoordinates(p=322.971 * 1e-2, q=5.0 * 1e-2)

    slit1 = S4ScreenElement(optical_element=scr, coordinates=coordinates)

    print(slit1.info())
Exemple #19
0
    from shadow4.beamline.optical_elements.mirrors.s4_surface_data_mirror import S4SurfaceDataMirror, \
        S4SurfaceDataMirrorElement

    from shadow4.syned.shape import Rectangle, Direction, Side  # TODO from syned.beamline.shape
    from srxraylib.plot.gol import set_qt

    set_qt()
    do_plot = True

    source = SourceGaussian.initialize_from_keywords(number_of_rays=10000,
                                                     sigmaX=0.0,
                                                     sigmaY=0.0,
                                                     sigmaZ=0.0,
                                                     sigmaXprime=1e-6,
                                                     sigmaZprime=1e-6, )
    beam0 = Beam()
    beam0.genSource(source)
    print(beam0.info())

    if do_plot:
        plotxy(beam0, 4, 6, title="Image 0", nbins=201)

    rlen1 = 0.6
    rlen2 = 0.6
    rwidx1 = 0.05
    rwidx2 = 0.05

    base_element = S4ToroidalMirror(name="M1b",
                                    surface_calculation=SurfaceCalculation.EXTERNAL,
                                    min_radius=0.157068,
                                    maj_radius=358.124803 - 0.157068,
Exemple #20
0
def example_branch_5(surface_type, do_plot=True):
    #
    # source
    #
    source = SourceGaussian.initialize_from_keywords(
        number_of_rays=100000,
        sigmaX=0.0,
        sigmaY=0.0,
        sigmaZ=0.0,
        sigmaXprime=1e-6,
        sigmaZprime=1e-6,
    )
    beam0 = Beam()
    beam0.genSource(source)
    # print(beam0.info())

    #
    # syned definitopns
    #
    # boundaries
    boundary_shape = None

    coordinates_syned = ElementCoordinates(p=10.0,
                                           q=10.0,
                                           angle_radial=numpy.radians(88.8))

    # surface shape

    if surface_type == "plane":
        mirror1 = S4PlaneMirrorElement(optical_element=S4PlaneMirror(
            name="M1", boundary_shape=boundary_shape),
                                       coordinates=coordinates_syned)
    elif surface_type == "sphere":
        mirror1 = S4SphereMirrorElement(optical_element=S4SphereMirror(
            name="M1",
            boundary_shape=boundary_shape,
            is_cylinder=False,
            surface_calculation=SurfaceCalculation.INTERNAL,
            p_focus=10.0,
            q_focus=10.0,
            grazing_angle=numpy.radians(90.0 - 88.8)),
                                        coordinates=coordinates_syned)
    elif surface_type == "spherical_cylinder_tangential":
        mirror1 = S4SphereMirrorElement(optical_element=S4SphereMirror(
            name="M1",
            boundary_shape=boundary_shape,
            is_cylinder=True,
            cylinder_direction=Direction.TANGENTIAL,
            surface_calculation=SurfaceCalculation.INTERNAL,
            p_focus=10.0,
            q_focus=10.0,
            grazing_angle=numpy.radians(90.0 - 88.8)),
                                        coordinates=coordinates_syned)
    elif surface_type == "spherical_cylinder_sagittal":
        mirror1 = S4SphereMirrorElement(optical_element=S4SphereMirror(
            name="M1",
            boundary_shape=boundary_shape,
            is_cylinder=True,
            cylinder_direction=Direction.SAGITTAL,
            surface_calculation=SurfaceCalculation.INTERNAL,
            p_focus=10.0,
            q_focus=10.0,
            grazing_angle=numpy.radians(90.0 - 88.8)),
                                        coordinates=coordinates_syned)
    elif surface_type == "ellipsoid":
        mirror1 = S4EllipsoidMirrorElement(optical_element=S4EllipsoidMirror(
            name="M1",
            boundary_shape=boundary_shape,
            is_cylinder=False,
            surface_calculation=SurfaceCalculation.INTERNAL,
            p_focus=20.0,
            q_focus=10.0,
            grazing_angle=0.003),
                                           coordinates=coordinates_syned)
    elif surface_type == "elliptical_cylinder":
        mirror1 = S4EllipsoidMirrorElement(optical_element=S4EllipsoidMirror(
            name="M1",
            boundary_shape=boundary_shape,
            is_cylinder=True,
            cylinder_direction=Direction.TANGENTIAL,
            surface_calculation=SurfaceCalculation.INTERNAL,
            p_focus=20.0,
            q_focus=10.0,
            grazing_angle=0.003),
                                           coordinates=coordinates_syned)
    elif surface_type == "hyperboloid":
        mirror1 = S4HyperboloidMirrorElement(
            optical_element=S4HyperboloidMirror(
                name="M1",
                boundary_shape=boundary_shape,
                is_cylinder=False,
                surface_calculation=SurfaceCalculation.INTERNAL,
                p_focus=20.0,
                q_focus=10.0,
                grazing_angle=0.003),
            coordinates=coordinates_syned)
    elif surface_type == "hyperbolic_cylinder":
        mirror1 = S4HyperboloidMirrorElement(
            optical_element=S4HyperboloidMirror(
                name="M1",
                boundary_shape=boundary_shape,
                is_cylinder=True,
                cylinder_direction=Direction.TANGENTIAL,
                surface_calculation=SurfaceCalculation.INTERNAL,
                p_focus=20.0,
                q_focus=10.0,
                grazing_angle=0.003),
            coordinates=coordinates_syned)
    elif surface_type == "paraboloid":
        mirror1 = S4ParaboloidMirrorElement(optical_element=S4ParaboloidMirror(
            name="M1",
            boundary_shape=boundary_shape,
            is_cylinder=False,
            surface_calculation=SurfaceCalculation.INTERNAL,
            at_infinity=Side.SOURCE,
            p_focus=20.0,
            q_focus=10.0,
            grazing_angle=0.003),
                                            coordinates=coordinates_syned)
    elif surface_type == "parabolic_cylinder":
        mirror1 = S4ParaboloidMirrorElement(optical_element=S4ParaboloidMirror(
            name="M1",
            boundary_shape=boundary_shape,
            is_cylinder=True,
            cylinder_direction=Direction.TANGENTIAL,
            surface_calculation=SurfaceCalculation.INTERNAL,
            at_infinity=Side.SOURCE,
            p_focus=20.0,
            q_focus=10.0,
            grazing_angle=0.003),
                                            coordinates=coordinates_syned)
    elif surface_type == "conic":
        mirror1 = S4ConicMirrorElement(optical_element=S4ConicMirror(
            name="M1",
            boundary_shape=boundary_shape,
            conic_coefficients=[
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0
            ]),
                                       coordinates=coordinates_syned)
    else:
        raise Exception("undefined surface shape")

    #
    # run
    #
    print(mirror1.info())
    beam1, mirr1 = mirror1.trace_beam(beam0)

    #
    # check
    #

    if do_plot:
        plotxy(beam1, 1, 3, nbins=101, nolost=1, title=surface_type)
Exemple #21
0
def example_branch_4(do_plot=True, f_refl=0):

    #
    # source
    #
    # beam0 = Beam.initialize_as_pencil(N=500)
    source = SourceGaussian.initialize_from_keywords(
        number_of_rays=100000,
        sigmaX=0.0,
        sigmaY=0.0,
        sigmaZ=0.0,
        sigmaXprime=1e-6,
        sigmaZprime=1e-6,
    )
    beam0 = Beam()
    numpy.random.seed(123456)
    beam0.genSource(source)
    beam0.set_photon_wavelength(5e-10)
    print(beam0.info())

    if do_plot:
        plotxy(beam0, 4, 6, title="Image 0", nbins=201)

    #
    # syned definitopns
    #

    # surface shape
    # boundaries
    rlen1 = 5e-05
    rlen2 = 5e-05
    rwidx1 = 2e-05
    rwidx2 = 2e-05

    boundary_shape = Rectangle(x_left=-rwidx2,
                               x_right=rwidx1,
                               y_bottom=-rlen2,
                               y_top=rlen1)

    coordinates_syned = ElementCoordinates(p=10.0,
                                           q=6.0,
                                           angle_radial=numpy.radians(88.8))

    #
    # shadow definitions
    #
    if f_refl == 0:  # prerefl

        PreRefl.prerefl(interactive=False,
                        SYMBOL="SiC",
                        DENSITY=3.217,
                        FILE="SiC.dat",
                        E_MIN=100.0,
                        E_MAX=20000.0,
                        E_STEP=100.0)
        mirror1 = S4ConicMirrorElement(optical_element=S4ConicMirror(
            name="M1",
            conic_coefficients=[
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0
            ],
            boundary_shape=boundary_shape,
            f_reflec=1,
            f_refl=f_refl,
            file_refl="SiC.dat"),
                                       coordinates=coordinates_syned)
    elif f_refl == 1:  # refraction index
        import xraylib
        refraction_index = xraylib.Refractive_Index("SiC", 2.4797, 3.217)
        mirror1 = S4ConicMirrorElement(optical_element=S4ConicMirror(
            name="M1",
            conic_coefficients=[
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0
            ],
            boundary_shape=boundary_shape,
            f_reflec=1,
            f_refl=f_refl,
            file_refl="",
            refraction_index=refraction_index),
                                       coordinates=coordinates_syned)
    elif f_refl == 2:  # user file: 1D  vs angle
        mirror1 = S4ConicMirrorElement(optical_element=S4ConicMirror(
            name="M1",
            conic_coefficients=[
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0
            ],
            boundary_shape=boundary_shape,
            f_reflec=1,
            f_refl=f_refl,
            file_refl="../../oasys_workspaces/xoppy_f1f2_139980555361648.dat"),
                                       coordinates=coordinates_syned)
    elif f_refl == 3:  # user file 1D vs energy
        mirror1 = S4ConicMirrorElement(optical_element=S4ConicMirror(
            name="M1",
            conic_coefficients=[
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0
            ],
            boundary_shape=boundary_shape,
            f_reflec=1,
            f_refl=f_refl,
            file_refl="../../oasys_workspaces/xoppy_f1f2_139981943656272.dat"),
                                       coordinates=coordinates_syned)
    elif f_refl == 4:  # user file
        mirror1 = S4ConicMirrorElement(optical_element=S4ConicMirror(
            name="M1",
            conic_coefficients=[
                0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0
            ],
            boundary_shape=boundary_shape,
            f_reflec=1,
            f_refl=f_refl,
            file_refl="../../oasys_workspaces/xoppy_f1f2_139980938100080.dat"),
                                       coordinates=coordinates_syned)

    print(mirror1.info())

    #
    # run
    #
    beam1, mirr1 = mirror1.trace_beam(beam0)
    print(mirr1.info())

    #
    # check
    #

    if do_plot:
        plotxy(beam1, 1, 3, title="Image 1", nbins=101, nolost=1)
        plotxy(mirr1, 2, 1, title="Footprint 1", nbins=101, nolost=1)
Exemple #22
0
 def initialize_from_array(cls, array):
     return Beam3.initialize_from_shadow4_beam(
         Beam_shadow4.initialize_from_array(array))
Exemple #23
0
def run_conic(kind="conic"):
    #
    # shadow3
    #
    if kind == "conic":
        from shadow4tests.oasys_workspaces.mirrors_branch5_conic import define_source, run_source, define_beamline, run_beamline
    else:
        raise Exception("Bad input")

    oe0 = define_source()
    beam3_source = run_source(oe0)



    #
    # shadow4
    #

    from shadow4.syned.element_coordinates import ElementCoordinates

    oe = define_beamline()[0]

    beam4_source = Beam.initialize_from_array(beam3_source.rays)
    beam4 = beam4_source


    check_congruence(oe)


    #
    # shadow definitions
    #



    name = "Conic Mirror (%s) " % kind
    mirror1 = S4ConicMirrorElement(
        optical_element=S4ConicMirror(
                name=name,
                boundary_shape=None,
                conic_coefficients=oe.CCC.tolist(),
            # inputs related to mirror reflectivity
                f_reflec=oe.F_REFLEC,  # reflectivity of surface: 0=no reflectivity, 1=full polarization
                # f_refl=0,  # 0=prerefl file, 1=electric susceptibility, 2=user defined file (1D reflectivity vs angle)
                #             # 3=user defined file (1D reflectivity vs energy), # 4=user defined file (2D reflectivity vs energy and angle)
                # file_refl="",  # preprocessor file fir f_refl=0,2,3,4
                # refraction_index=1.0  # refraction index (complex) for f_refl=1
                ),
        coordinates=ElementCoordinates(
                p=oe.T_SOURCE,
                q=oe.T_IMAGE,
                angle_radial=numpy.radians(oe.T_INCIDENCE),
                ),
    )

    print(mirror1.info())

    #
    # run
    #

    beam4, mirr4 = mirror1.trace_beam(beam_in=beam4, flag_lost_value=-11000)



    #
    # compare
    #
    oe_list = define_beamline()
    beam3 = run_beamline(beam3_source, oe_list)

    plotxy(beam3, 1, 3, nbins=201, nolost=1, title="%s shadow3" % name)
    plotxy(beam4, 1, 3, nbins=201, nolost=1, title="%s shadow4" % name)

    from shadow4tests.compatibility.compare_beams import check_six_columns_mean_and_std, check_almost_equal

    check_six_columns_mean_and_std(beam3, beam4, do_assert=True, do_plot=False, assert_value=1e-6)
    check_almost_equal(beam3, beam4, do_assert = True, level=3)
Exemple #24
0
    from shadow4.beam.beam import Beam
    from shadow4.tools.graphics import plotxy

    #
    # source
    #
    src = SourceGaussian.initialize_from_keywords(
        number_of_rays=10000,
        sigmaX=1.0e-6,
        sigmaY=0.0,
        sigmaZ=1.0e-6,
        sigmaXprime=0.0002,
        sigmaZprime=0.0002,
        real_space_center=[0.0, 0.0, 0.0],
        direction_space_center=[0.0, 0.0])
    beam = Beam()

    beam.genSource(src)
    beam.set_photon_energy_eV(1000.0)

    print(beam.info())

    # plotxy(Beam3.initialize_from_shadow4_beam(beam),1,3,nbins=100,title="SOURCE")

    #
    # grating
    #
    g = S4PlaneGrating(
        name="my_grating",
        boundary_shape=None,  # BoundaryShape(),
        ruling=600000.0,
Exemple #25
0
    def tests_initializars(self):
        print("# ")
        print("# initializers ")
        print("# ")
        a = Beam(N=100)
        self.assertEqual(100,a.get_number_of_rays())

        a = Beam(array=numpy.zeros( (1000,18) ))
        print(a.info())
        print(a.info())
        self.assertEqual(1000,a.get_number_of_rays())

        a = Beam.initialize_from_array(numpy.zeros( (500,18) ))
        print(a.info())
        print(a.info())
        self.assertEqual(500,a.get_number_of_rays())

        a = Beam.initialize_as_pencil(200)
        print(a.info())
        self.assertEqual(200,a.get_number_of_rays())
Exemple #26
0
def run_hyperboloid(kind="hyperboloid"):
    #
    # shadow3
    #
    if kind == "hyperboloid":
        from shadow4tests.oasys_workspaces.mirrors_branch5_hyperboloid import define_source, run_source, define_beamline, run_beamline
    else:
        raise Exception("Bad input")

    oe0 = define_source()
    beam3_source = run_source(oe0)

    #
    # shadow4
    #

    from shadow4.syned.element_coordinates import ElementCoordinates

    oe = define_beamline()[0]

    beam4_source = Beam.initialize_from_array(beam3_source.rays)
    beam4 = beam4_source

    check_congruence(oe)

    #
    # shadow definitions
    #

    if oe.F_DEFAULT == 0:
        p_focus = oe.SSOUR
        q_focus = oe.SIMAG
        grazing_angle = numpy.radians(90 - oe.THETA)
    elif oe.F_DEFAULT == 1:
        p_focus = oe.T_SOURCE
        q_focus = oe.T_IMAGE
        grazing_angle = numpy.radians(90 - oe.T_INCIDENCE)

    is_cylinder = oe.FCYL

    if oe.CIL_ANG == 0:
        cylinder_direction = Direction.TANGENTIAL
    else:
        cylinder_direction = Direction.SAGITTAL

    if oe.F_CONVEX == 0:
        convexity = Convexity.UPWARD
    elif oe.F_CONVEX == 1:
        convexity = Convexity.DOWNWARD

    name = "Hyperboloid Mirror (%s) " % kind
    mirror1 = S4HyperboloidMirrorElement(
        optical_element=S4HyperboloidMirror(
            name=name,
            boundary_shape=None,
            surface_calculation=SurfaceCalculation.INTERNAL,
            is_cylinder=is_cylinder,
            cylinder_direction=cylinder_direction,
            convexity=convexity,
            p_focus=p_focus,
            q_focus=q_focus,
            grazing_angle=grazing_angle,

            # inputs related to mirror reflectivity
            f_reflec=oe.
            F_REFLEC,  # reflectivity of surface: 0=no reflectivity, 1=full polarization
            # f_refl=0,  # 0=prerefl file, 1=electric susceptibility, 2=user defined file (1D reflectivity vs angle)
            #             # 3=user defined file (1D reflectivity vs energy), # 4=user defined file (2D reflectivity vs energy and angle)
            # file_refl="",  # preprocessor file fir f_refl=0,2,3,4
            # refraction_index=1.0  # refraction index (complex) for f_refl=1
        ),
        coordinates=ElementCoordinates(
            p=oe.T_SOURCE,
            q=oe.T_IMAGE,
            angle_radial=numpy.radians(oe.T_INCIDENCE),
        ),
    )

    print(mirror1.info())

    #
    # run
    #

    beam4, mirr4 = mirror1.trace_beam(beam_in=beam4, flag_lost_value=-11000)

    #
    # compare
    #
    oe_list = define_beamline()
    beam3 = run_beamline(beam3_source, oe_list)

    plotxy(beam3, 1, 3, nbins=201, nolost=1, title="%s shadow3" % name)
    plotxy(beam4, 1, 3, nbins=201, nolost=1, title="%s shadow4" % name)

    from shadow4tests.compatibility.compare_beams import check_six_columns_mean_and_std, check_almost_equal

    check_six_columns_mean_and_std(beam3,
                                   beam4,
                                   do_assert=True,
                                   do_plot=False,
                                   assert_value=1e-6)
    check_almost_equal(beam3, beam4, do_assert=False, level=3)
Exemple #27
0
def example_branch_1(do_plot=True):
    #
    # source
    #
    source = SourceGaussian.initialize_from_keywords(
        number_of_rays=100000,
        sigmaX=0.0,
        sigmaY=0.0,
        sigmaZ=0.0,
        sigmaXprime=1e-6,
        sigmaZprime=1e-6,
    )
    beam0 = Beam()
    beam0.genSource(source)
    print(beam0.info())

    if do_plot:
        plotxy(beam0, 4, 6, title="Image 0", nbins=201)

    #
    # syned definitopns
    #

    # surface shape

    # boundaries
    # boundary_shape = None
    rlen1 = 5e-05
    rlen2 = 5e-05
    rwidx1 = 2e-05
    rwidx2 = 2e-05
    boundary_shape = Rectangle(x_left=-rwidx2,
                               x_right=rwidx1,
                               y_bottom=-rlen2,
                               y_top=rlen1)
    # boundary_shape = Rectangle(x_left=-1e-05, x_right=2e-05, y_bottom=-5e-04, y_top=7e-04)
    # boundary_shape = Ellipse(a_axis_min=-rwidx2/2, a_axis_max=rwidx2/2, b_axis_min=-rlen2/2, b_axis_max=rlen2/2)
    # boundary_shape = Ellipse(a_axis_min=-0e-05, a_axis_max=1e-05, b_axis_min=-1.5e-05, b_axis_max=2.5e-05)
    # boundary_shape = Ellipse(a_axis_min=0, a_axis_max=1e-05, b_axis_min=-0.0005, b_axis_max=0)

    # rlen1 = -2.5e-05
    # rlen2 = 5e-05
    # rwidx1 = 1e-05
    # rwidx2 = 2e-05
    #
    # boundary_shape = TwoEllipses(
    #     a1_axis_min=-rwidx1 / 2, a1_axis_max=rwidx1 / 2, b1_axis_min=-rlen1 / 2, b1_axis_max=rlen1 / 2,
    #     a2_axis_min=-rwidx2 / 2, a2_axis_max=rwidx2 / 2, b2_axis_min=-rlen2 / 2, b2_axis_max=rlen2 / 2)

    coordinates_syned = ElementCoordinates(p=10.0,
                                           q=6.0,
                                           angle_radial=numpy.radians(88.8))

    #
    # shadow definitions
    #
    mirror1 = S4ConicMirrorElement(optical_element=S4ConicMirror(
        name="M1",
        conic_coefficients=[0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0],
        boundary_shape=boundary_shape),
                                   coordinates=coordinates_syned)

    print(mirror1.info())

    #
    # run
    #
    beam1, mirr1 = mirror1.trace_beam(beam_in=beam0)
    print(mirr1.info())

    #
    # check
    #

    if do_plot:
        plotxy(beam1, 1, 3, title="Image 1", nbins=101, nolost=1)
        plotxy(mirr1, 2, 1, title="Footprint 1", nbins=101, nolost=1)

    #
    # M2
    #

    mirror2 = S4ConicMirrorElement(optical_element=S4ConicMirror(
        conic_coefficients=[0, 0, 0, 0, 0, 0, 0, 0, -1, 0],
        boundary_shape=Rectangle(-100e-6, 100e-6, -150e-6, 150e-6)),
                                   coordinates=ElementCoordinates(
                                       p=10.0,
                                       q=100.0,
                                       angle_radial=(0.5 * numpy.pi - 0.003)))

    print(mirror2.info())
    #
    #
    if do_plot:
        beam2, mirr2 = mirror2.trace_beam(beam1)
        plotxy(beam2, 1, 3, title="Image 2", nbins=101, nolost=1)
        plotxy(mirr2, 2, 1, title="Footprint 2", nbins=101, nolost=1)
Exemple #28
0
def minishadow_run_toroid_mirror():

    # ;
    # ; ray tracing of a single conic mirror using minishadow
    # ; results are compared with shadow3
    # ;
    #

    # ;
    # ; Runs shadow3
    #
    shadow3_beam_source,shadow3_beam,oe0,oe1 = run_shadow3_from_start_files(iwrite=1)


    # copy source to new Beam object
    newbeam = Beam.initialize_from_array(shadow3_beam_source.rays.copy())

    # ;
    # ; INPUTS
    # ;
    #
    fmirr         = oe1.FMIRR    # 1
    p             = oe1.T_SOURCE # 1000.0       # source-mirror
    q             = oe1.T_IMAGE  # 300.0        # mirror-image
    alpha         = oe1.ALPHA    # 0.0      # mirror orientation angle
    theta_grazing = (90.0-oe1.T_INCIDENCE) * numpy.pi / 180  # 5e-3     # grazing angle, rad
    fcyl          = oe1.FCYL
    f_convex      = oe1.F_CONVEX

    print("fmirr = %s, p=%f, q=%f, alpha=%f, theta_grazing=%f rad, fcyl=%d"%\
              (fmirr,p,q,alpha,theta_grazing,fcyl))

    t = S4Toroid()

    t.set_from_focal_distances(p, q, theta_grazing)

    print(t.info())

    #
    # put beam in mirror reference system
    #
    # TODO: calculate rotation matrices? Invert them for putting back to the lab system?
    #

    # THIS PART IS NOT DONE FOR TOROIDS!!!!!!!!

    newbeam.rotate(alpha,axis=2)
    newbeam.rotate(theta_grazing,axis=1)
    newbeam.translation([0.0,-p*numpy.cos(theta_grazing),p*numpy.sin(theta_grazing)])

    #
    # #
    # # reflect beam in the mirror surface and dump mirr.01
    # #
    newbeam, tmp = t.apply_specular_reflection_on_beam(newbeam)
    # newbeam.dump_shadow3_file('minimirr.01')
    Beam3.initialize_from_shadow4_beam(newbeam).write('minimirr.01')
    #
    # #
    # # put beam in lab frame and compute image
    # #
    newbeam.rotate(theta_grazing,axis=1)
    # TODO what about alpha?
    newbeam.retrace(q,resetY=True)
    # newbeam.dump_shadow3_file('ministar.01')
    Beam3.initialize_from_shadow4_beam(newbeam).write('ministar.01')
Exemple #29
0
class ShadowBeam:
    class ScanningData(object):
        def __init__(self,
                     scanned_variable_name,
                     scanned_variable_value,
                     scanned_variable_display_name,
                     scanned_variable_um,
                     additional_parameters={}):
            self.__scanned_variable_name = scanned_variable_name
            self.__scanned_variable_value = scanned_variable_value
            self.__scanned_variable_display_name = scanned_variable_display_name
            self.__scanned_variable_um = scanned_variable_um

            self.__additional_parameters = additional_parameters

        def get_scanned_variable_name(self):
            return self.__scanned_variable_name

        def get_scanned_variable_value(self):
            return self.__scanned_variable_value

        def get_scanned_variable_display_name(self):
            return self.__scanned_variable_display_name

        def get_scanned_variable_um(self):
            return self.__scanned_variable_um

        def has_additional_parameter(self, name):
            return name in self.__additional_parameters.keys()

        def get_additional_parameter(self, name):
            return self.__additional_parameters[name]

    def __new__(cls, oe_number=0, beam=None, number_of_rays=0):
        self = super().__new__(cls)
        self._oe_number = oe_number
        if (beam is None):
            if number_of_rays > 0:
                self._beam = Beam(number_of_rays)
            else:
                self._beam = Beam()
        else:
            self._beam = beam

        self.history = []
        self.scanned_variable_data = None

        return self

    def get_number_of_rays(self):
        return self._beam.rays.shape[0]

    def setBeam(self, beam):
        self._beam = beam

    def setScanningData(self,
                        scanned_variable_data=ScanningData(
                            None, None, None, None)):
        self.scanned_variable_data = scanned_variable_data

    def loadFromFile(self, file_name):
        if not self._beam is None:
            if os.path.exists(file_name):
                self._beam.load(file_name)
            else:
                raise Exception("File " + file_name + " not existing")

    def writeToFile(self, file_name):
        if not self._beam is None:
            self._beam.write(file_name)

    def duplicate(self, copy_rays=True, history=True):
        beam = Beam()
        if copy_rays: beam.rays = copy.deepcopy(self._beam.rays)

        new_shadow_beam = ShadowBeam(self._oe_number, beam)
        new_shadow_beam.setScanningData(self.scanned_variable_data)

        if history:
            for historyItem in self.history:
                new_shadow_beam.history.append(historyItem)

        return new_shadow_beam

    @classmethod
    def mergeBeams(cls, beam_1, beam_2):
        if beam_1 and beam_2:
            rays_1 = None
            rays_2 = None

            if len(getattr(beam_1._beam, "rays", numpy.zeros(0))) > 0:
                rays_1 = copy.deepcopy(beam_1._beam.rays)
            if len(getattr(beam_2._beam, "rays", numpy.zeros(0))) > 0:
                rays_2 = copy.deepcopy(beam_2._beam.rays)

            merged_beam = beam_1.duplicate(copy_rays=False, history=True)

            if not rays_1 is None and not rays_2 is None:
                merged_beam._oe_number = beam_1._oe_number
                merged_beam._beam.rays = numpy.append(rays_1, rays_2, axis=0)
            elif not rays_1 is None:
                merged_beam._beam.rays = rays_1
                merged_beam._oe_number = beam_1._oe_number
            elif not rays_2 is None:
                merged_beam._beam.rays = rays_2
                merged_beam._oe_number = beam_2._oe_number

            merged_beam._beam.rays[:, 11] = numpy.arange(
                1,
                len(merged_beam._beam.rays) + 1, 1)  # ray_index

            return merged_beam

    @classmethod
    def traceFromSource(cls,
                        shadow_src,
                        write_begin_file=0,
                        write_start_file=0,
                        write_end_file=0,
                        history=True,
                        widget_class_name=None):
        self = cls.__new__(ShadowBeam, beam=Beam())

        shadow_src.self_repair()

        shadow_source_start = shadow_src.duplicate()

        if write_start_file == 1:
            shadow_src.src.write("start.00")

        self._beam.genSource(shadow_src.src)

        shadow_src.self_repair()

        if write_begin_file:
            self.writeToFile("begin.dat")

        if write_end_file == 1:
            shadow_src.src.write("end.00")

        shadow_source_end = shadow_src.duplicate()

        if history:
            self.history.append(
                ShadowOEHistoryItem(shadow_source_start=shadow_source_start,
                                    shadow_source_end=shadow_source_end,
                                    widget_class_name=widget_class_name))

        return self

    @classmethod
    def traceFromOE(cls,
                    input_beam,
                    shadow_oe,
                    write_start_file=0,
                    write_end_file=0,
                    history=True,
                    widget_class_name=None):

        self = cls.initializeFromPreviousBeam(input_beam)

        shadow_oe.self_repair()

        if history:
            history_shadow_oe_start = shadow_oe.duplicate()

        if write_start_file == 1:
            shadow_oe._oe.write("start.%02d" % self._oe_number)

        self._beam.traceOE(shadow_oe._oe, self._oe_number)

        shadow_oe.self_repair()

        if write_end_file == 1:
            shadow_oe._oe.write("end.%02d" % self._oe_number)

        if history:
            history_shadow_oe_end = shadow_oe.duplicate()

            #N.B. history[0] = Source
            if not self._oe_number == 0:
                if len(self.history) - 1 < self._oe_number:
                    self.history.append(
                        ShadowOEHistoryItem(
                            oe_number=self._oe_number,
                            input_beam=input_beam.duplicate(),
                            shadow_oe_start=history_shadow_oe_start,
                            shadow_oe_end=history_shadow_oe_end,
                            widget_class_name=widget_class_name))
                else:
                    self.history[self._oe_number] = ShadowOEHistoryItem(
                        oe_number=self._oe_number,
                        input_beam=input_beam.duplicate(),
                        shadow_oe_start=history_shadow_oe_start,
                        shadow_oe_end=history_shadow_oe_end,
                        widget_class_name=widget_class_name)

        return self

    @classmethod
    def traceIdealLensOE(cls,
                         input_beam,
                         shadow_oe,
                         history=True,
                         widget_class_name=None):

        self = cls.initializeFromPreviousBeam(input_beam)

        shadow_oe.self_repair()

        if history:
            history_shadow_oe_start = shadow_oe.duplicate()

        self._beam.traceIdealLensOE(shadow_oe._oe, self._oe_number)

        shadow_oe.self_repair()

        if history:
            history_shadow_oe_end = shadow_oe.duplicate()

            #N.B. history[0] = Source
            if not self._oe_number == 0:
                if len(self.history) - 1 < self._oe_number:
                    self.history.append(
                        ShadowOEHistoryItem(
                            oe_number=self._oe_number,
                            input_beam=input_beam.duplicate(),
                            shadow_oe_start=history_shadow_oe_start,
                            shadow_oe_end=history_shadow_oe_end,
                            widget_class_name=widget_class_name))
                else:
                    self.history[self._oe_number] = ShadowOEHistoryItem(
                        oe_number=self._oe_number,
                        input_beam=input_beam.duplicate(),
                        shadow_oe_start=history_shadow_oe_start,
                        shadow_oe_end=history_shadow_oe_end,
                        widget_class_name=widget_class_name)

        return self

    @classmethod
    def traceFromCompoundOE(cls,
                            input_beam,
                            shadow_oe,
                            write_start_files=0,
                            write_end_files=0,
                            write_star_files=0,
                            write_mirr_files=0,
                            history=True,
                            widget_class_name=None):
        self = cls.initializeFromPreviousBeam(input_beam)

        shadow_oe.self_repair()

        if history:
            history_shadow_oe_start = shadow_oe.duplicate()

        self._beam.traceCompoundOE(shadow_oe._oe,
                                   from_oe=self._oe_number,
                                   write_start_files=write_start_files,
                                   write_end_files=write_end_files,
                                   write_star_files=write_star_files,
                                   write_mirr_files=write_mirr_files)

        shadow_oe.self_repair()

        if history:
            history_shadow_oe_end = shadow_oe.duplicate()

            # N.B. history[0] = Source
            if not self._oe_number == 0:
                if len(self.history) - 1 < self._oe_number:
                    self.history.append(
                        ShadowOEHistoryItem(
                            oe_number=self._oe_number,
                            input_beam=input_beam.duplicate(),
                            shadow_oe_start=history_shadow_oe_start,
                            shadow_oe_end=history_shadow_oe_end,
                            widget_class_name=widget_class_name))
                else:
                    self.history[self._oe_number] = ShadowOEHistoryItem(
                        oe_number=self._oe_number,
                        input_beam=input_beam.duplicate(),
                        shadow_oe_start=history_shadow_oe_start,
                        shadow_oe_end=history_shadow_oe_end,
                        widget_class_name=widget_class_name)

        return self

    @classmethod
    def initializeFromPreviousBeam(cls, input_beam):
        self = input_beam.duplicate()
        self._oe_number = input_beam._oe_number + 1

        return self

    def getOEHistory(self, oe_number=None):
        if oe_number is None:
            return self.history
        else:
            return self.history[oe_number]

    def historySize(self):
        return len(self.history)