def generate_energy_spectrum(self):
        if self.input_beam is None: return

        try:
            if self.input_beam.getOEHistory(oe_number=0)._shadow_source_end.src.FSOURCE_DEPTH == 1:
                raise Exception("Source has no depth, calcution could be inconsistent")

            if self.kind_of_calculation == 1:
                congruence.checkFile(self.user_file)
            else:
                congruence.checkStrictlyPositiveNumber(self.factor, "Proportionality factor (k) [to eV/Å]")
                congruence.checkStrictlyPositiveNumber(self.central_value, "Central Energy/Wavelength Value [eV/Å]")

            beam_out = self.input_beam.duplicate()

            if self.kind_of_calculation == 0:
                for index in range(0, len(beam_out._beam.rays)):
                    if self.units == 0:
                        beam_out._beam.rays[index, 10] =  ShadowPhysics.getShadowKFromEnergy(self.central_value + self.factor*beam_out._beam.rays[index, 1])
                    else:
                        beam_out._beam.rays[index, 10] =  ShadowPhysics.getShadowKFromWavelength(self.central_value + self.factor*beam_out._beam.rays[index, 1])
            else:
                self.load_energy_distribution()

                for index in range(0, len(beam_out._beam.rays)):
                    if self.units == 0:
                        beam_out._beam.rays[index, 10] = ShadowPhysics.getShadowKFromEnergy(self.get_value_from_y(beam_out._beam.rays[index, 1]))
                    else:
                        beam_out._beam.rays[index, 10] =  ShadowPhysics.getShadowKFromWavelength(self.get_value_from_y(beam_out._beam.rays[index, 1]))

            self.send("Beam", beam_out)
        except Exception as exception:
                QtGui.QMessageBox.critical(self, "Error", str(exception), QtGui.QMessageBox.Ok)
Exemple #2
0
    def plot_efficiency(self):
        if self.type_of_zp == PHASE_ZP:
            if self.energy_plot == 1:
                if self.plot_canvas[5] is None:
                    self.plot_canvas[5] = oasysgui.plotWindow(roi=False, control=False, position=True, logScale=False)
                    self.tab[5].layout().addWidget(self.plot_canvas[5] )

                self.plot_canvas[5].clear()

                self.plot_canvas[5].setDefaultPlotLines(True)
                self.plot_canvas[5].setActiveCurveColor(color='blue')
    
                self.plot_canvas[5].setGraphTitle('Thickness: ' + str(self.zone_plate_thickness) + " nm")
                self.plot_canvas[5].getXAxis().setLabel('Energy [eV]')
                self.plot_canvas[5].getYAxis().setLabel('Efficiency [%]')
    
                x_values = numpy.linspace(self.energy_from, self.energy_to, 100)
                y_values = numpy.zeros(100)
    
                for index in range(len(x_values)):
                    y_values[index], _, _ = ZonePlate.calculate_efficiency(ShadowPhysics.getWavelengthFromEnergy(x_values[index])/10,
                                                                           self.zone_plate_material,
                                                                           self.zone_plate_thickness)
                y_values = numpy.round(100.0*y_values, 3)
    
                self.plot_canvas[5].addCurve(x_values, y_values, "Efficiency vs Energy", symbol='', color='blue', replace=True)
            else:
                if not self.plot_canvas[5] is None: self.plot_canvas[5].clear()

            if self.thickness_plot == 1:
                if self.plot_canvas[6] is None:
                    self.plot_canvas[6] = oasysgui.plotWindow(roi=False, control=False, position=True, logScale=False)
                    self.tab[6].layout().addWidget(self.plot_canvas[6] )
    
                self.plot_canvas[6].setDefaultPlotLines(True)
                self.plot_canvas[6].setActiveCurveColor(color='blue')
    
                self.plot_canvas[6].setGraphTitle('Energy: ' + str(round(ShadowPhysics.getEnergyFromWavelength(self.avg_wavelength*10), 3)) + " eV")
                self.plot_canvas[6].getXAxis().setLabel('Thickness [nm]')
                self.plot_canvas[6].getYAxis().setLabel('Efficiency [%]')
    
                x_values = numpy.linspace(self.thickness_from, self.thickness_to, 100)
                y_values = numpy.zeros(100)
    
                for index in range(len(x_values)):
                    y_values[index], _, _ = ZonePlate.calculate_efficiency(self.avg_wavelength,
                                                                           self.zone_plate_material,
                                                                           x_values[index])
                y_values = numpy.round(100*y_values, 3)
    
                self.plot_canvas[6].addCurve(x_values, y_values, "Efficiency vs Thickness", symbol='', color='blue', replace=True)
            else:
                if not self.plot_canvas[6] is None: self.plot_canvas[6].clear()

        else:
            if not self.plot_canvas[5] is None: self.plot_canvas[5].clear()
            if not self.plot_canvas[6] is None: self.plot_canvas[6].clear()
Exemple #3
0
def get_delta(input_parameters, calculation_parameters):
    density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(input_parameters.crl_material))

    energy_in_KeV = ShadowPhysics.getEnergyFromWavelength(calculation_parameters.gwavelength*input_parameters.widget.workspace_units_to_m*1e10)/1000
    delta = 1-xraylib.Refractive_Index_Re(input_parameters.crl_material, energy_in_KeV, density)

    return delta
Exemple #4
0
 def checkFields(self):
     self.SYMBOL = ShadowPhysics.checkCompoundName(self.SYMBOL)
     self.DENSITY = congruence.checkStrictlyPositiveNumber(self.DENSITY, "Density")
     self.E_MIN  = congruence.checkPositiveNumber(self.E_MIN , "Minimum Energy")
     self.E_MAX  = congruence.checkStrictlyPositiveNumber(self.E_MAX , "Maximum Energy")
     self.E_STEP = congruence.checkStrictlyPositiveNumber(self.E_STEP, "Energy step")
     if self.E_MIN > self.E_MAX: raise Exception("Minimum Energy cannot be bigger than Maximum Energy")
     congruence.checkDir(self.SHADOW_FILE)
Exemple #5
0
 def checkFields(self):
     self.SYMBOL = ShadowPhysics.checkCompoundName(self.SYMBOL)
     self.DENSITY = congruence.checkStrictlyPositiveNumber(self.DENSITY, "Density")
     self.E_MIN  = congruence.checkPositiveNumber(self.E_MIN , "Minimum Energy")
     self.E_MAX  = congruence.checkStrictlyPositiveNumber(self.E_MAX , "Maximum Energy")
     self.E_STEP = congruence.checkStrictlyPositiveNumber(self.E_STEP, "Energy step")
     congruence.checkLessOrEqualThan(self.E_MIN, self.E_MAX, "Minimum Energy", "Maximum Energy")
     congruence.checkDir(self.SHADOW_FILE)
Exemple #6
0
 def get_material_weight_factor(cls, shadow_rays, material, thickness):
     mu = numpy.zeros(len(shadow_rays))
     
     for i in range(0, len(mu)):
         mu[i] = xraylib.CS_Total_CP(material, ShadowPhysics.getEnergyFromShadowK(shadow_rays[i, 10])/1000) # energy in KeV
     
     rho = ZonePlate.get_material_density(material)
                 
     return numpy.sqrt(numpy.exp(-mu*rho*thickness*1e-7)) # thickness in CM
Exemple #7
0
    def checkFields(self):
        congruence.checkDir(self.FILE)
        self.E_MIN = congruence.checkPositiveNumber(self.E_MIN, "Min Energy")
        self.E_MAX = congruence.checkStrictlyPositiveNumber(
            self.E_MAX, "Max Energy")
        congruence.checkLessOrEqualThan(self.E_MIN, self.E_MAX,
                                        "Minimum Energy", "Maximum Energy")
        self.S_MATERIAL = ShadowPhysics.checkCompoundName(self.S_MATERIAL)
        self.S_DENSITY = congruence.checkStrictlyPositiveNumber(
            float(self.S_DENSITY), "Density (substrate)")
        self.E_MATERIAL = ShadowPhysics.checkCompoundName(self.E_MATERIAL)
        self.E_DENSITY = congruence.checkStrictlyPositiveNumber(
            float(self.E_DENSITY), "Density (even sublayer)")
        self.O_MATERIAL = ShadowPhysics.checkCompoundName(self.O_MATERIAL)
        self.O_DENSITY = congruence.checkStrictlyPositiveNumber(
            float(self.O_DENSITY), "Density (odd sublayer)")

        if self.GRADE_DEPTH == 0:
            self.N_PAIRS = congruence.checkStrictlyPositiveNumber(
                int(self.N_PAIRS), "Number of bilayers")
            self.THICKNESS = congruence.checkStrictlyPositiveNumber(
                float(self.THICKNESS), "bilayer thickness t")
            self.GAMMA = congruence.checkStrictlyPositiveNumber(
                float(self.GAMMA), "gamma ratio")
            self.ROUGHNESS_EVEN = congruence.checkPositiveNumber(
                float(self.ROUGHNESS_EVEN), "Roughness even layer")
            self.ROUGHNESS_ODD = congruence.checkPositiveNumber(
                float(self.ROUGHNESS_ODD), "Roughness odd layer")
        else:
            congruence.checkDir(self.FILE_DEPTH)

        if self.GRADE_SURFACE == 1:
            congruence.checkDir(self.FILE_SHADOW)
            congruence.checkDir(self.FILE_THICKNESS)
            congruence.checkDir(self.FILE_GAMMA)
        elif self.GRADE_SURFACE == 2:
            self.AA0 = congruence.checkNumber(float(self.AA0),
                                              "zero-order coefficient")
            self.AA1 = congruence.checkNumber(float(self.AA1),
                                              "linear coefficient")
            self.AA2 = congruence.checkNumber(float(self.AA2),
                                              "2nd degree coefficient")
            self.AA3 = congruence.checkNumber(float(self.AA3),
                                              "3rd degree coefficient")
Exemple #8
0
 def get_delta_beta(cls, shadow_rays, material):
     beta = numpy.zeros(len(shadow_rays))
     delta = numpy.zeros(len(shadow_rays))
     density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(material))
 
     for i in range(0, len(shadow_rays)):
         energy_in_KeV = ShadowPhysics.getEnergyFromShadowK(shadow_rays[i, 10])/1000
         delta[i] = (1-xraylib.Refractive_Index_Re(material, energy_in_KeV, density))
         beta[i]  = xraylib.Refractive_Index_Im(material, energy_in_KeV, density)
 
     return delta, beta 
Exemple #9
0
    def calculate_efficiency(cls, wavelength, zone_plate_material, zone_plate_thickness):
        energy_in_KeV = ShadowPhysics.getEnergyFromWavelength(wavelength*10)/1000

        density = xraylib.ElementDensity(xraylib.SymbolToAtomicNumber(zone_plate_material))
        delta   = (1-xraylib.Refractive_Index_Re(zone_plate_material, energy_in_KeV, density))
        beta    = xraylib.Refractive_Index_Im(zone_plate_material, energy_in_KeV, density)
        phi     = 2*numpy.pi*zone_plate_thickness*delta/wavelength
        rho     = beta/delta

        efficiency     = (1/(numpy.pi**2))*(1 + numpy.exp(-2*rho*phi)      - (2*numpy.exp(-rho*phi)*numpy.cos(phi)))
        max_efficiency = (1/(numpy.pi**2))*(1 + numpy.exp(-2*rho*numpy.pi) + (2*numpy.exp(-rho*numpy.pi)))
        thickness_max_efficiency = numpy.round(wavelength/(2*delta), 2)

        return efficiency, max_efficiency, thickness_max_efficiency
    def plot_results(self):
        self.plotted_beam = None

        if super().plot_results():
            if self.spectro_plot_canvas is None:
                self.spectro_plot_canvas = PlotWindow.PlotWindow(roi=False, control=False, position=False, plugins=False, logx=False, logy=False)
                self.spectro_plot_canvas.setDefaultPlotLines(True)
                self.spectro_plot_canvas.setDefaultPlotPoints(False)
                self.spectro_plot_canvas.setZoomModeEnabled(True)
                self.spectro_plot_canvas.setMinimumWidth(673)
                self.spectro_plot_canvas.setMaximumWidth(673)
                pos = self.spectro_plot_canvas._plot.graph.ax.get_position()
                self.spectro_plot_canvas._plot.graph.ax.set_position([pos.x0, pos.y0 , pos.width*0.86, pos.height])
                pos = self.spectro_plot_canvas._plot.graph.ax2.get_position()
                self.spectro_plot_canvas._plot.graph.ax2.set_position([pos.x0, pos.y0 , pos.width*0.86, pos.height])
                ax3 = self.spectro_plot_canvas._plot.graph.fig.add_axes([.82, .15, .05, .75])

                self.spectro_image_box.layout().addWidget(self.spectro_plot_canvas)
            else:
                self.spectro_plot_canvas.clear()
                ax3 = self.spectro_plot_canvas._plot.graph.fig.axes[-1]
                ax3.cla()

            number_of_bins = self.spectro_number_of_bins + 1

            x, auto_title, xum = self.get_titles()

            if self.plotted_beam is None: self.plotted_beam = self.input_beam

            xrange  = self.get_range(self.plotted_beam._beam, x)

            min_k = numpy.min(self.plotted_beam._beam.rays[:, 10])
            max_k = numpy.max(self.plotted_beam._beam.rays[:, 10])

            if self.spectro_variable == 0: #Energy
                energy_min = ShadowPhysics.getEnergyFromShadowK(min_k)
                energy_max = ShadowPhysics.getEnergyFromShadowK(max_k)

                bins = energy_min + numpy.arange(0, number_of_bins + 1)*((energy_max-energy_min)/number_of_bins)
                normalization = colors.Normalize(vmin=energy_min, vmax=energy_max)
            else: #wavelength
                wavelength_min = ShadowPhysics.getWavelengthfromShadowK(max_k)
                wavelength_max = ShadowPhysics.getWavelengthfromShadowK(min_k)

                bins = wavelength_min + numpy.arange(0, number_of_bins + 1)*((wavelength_max-wavelength_min)/number_of_bins)
                normalization = colors.Normalize(vmin=wavelength_min, vmax=wavelength_max)

            scalarMap = cmx.ScalarMappable(norm=normalization, cmap=self.color_map)

            cb1 = colorbar.ColorbarBase(ax3,
                                        cmap=self.color_map,
                                        norm=normalization,
                                        orientation='vertical')

            if self.spectro_variable == 0: #Energy
                cb1.set_label('Energy [eV]')
            else:
                cb1.set_label('Wavelength [Å]')

            go = numpy.where(self.plotted_beam._beam.rays[:, 9] == 1)
            lo = numpy.where(self.plotted_beam._beam.rays[:, 9] != 1)

            rays_to_plot = self.plotted_beam._beam.rays

            if self.rays == 1:
                rays_to_plot = self.plotted_beam._beam.rays[go]
            elif self.rays == 2:
                rays_to_plot = self.plotted_beam._beam.rays[lo]

            factor_x = ShadowPlot.get_factor(x, self.workspace_units_to_cm)

            for index in range (0, number_of_bins):
                min_value = bins[index]
                max_value = bins[index+1]

                if index < number_of_bins-1:
                    if self.spectro_variable == 0: #Energy
                        cursor = numpy.where((numpy.round(ShadowPhysics.getEnergyFromShadowK(rays_to_plot[:, 10]), 4) >= numpy.round(min_value, 4)) &
                                             (numpy.round(ShadowPhysics.getEnergyFromShadowK(rays_to_plot[:, 10]), 4) < numpy.round(max_value, 4)))
                    else:
                        cursor = numpy.where((numpy.round(ShadowPhysics.getWavelengthfromShadowK(rays_to_plot[:, 10]), 4) >= numpy.round(min_value, 4)) &
                                             (numpy.round(ShadowPhysics.getWavelengthfromShadowK(rays_to_plot[:, 10]), 4) < numpy.round(max_value, 4)))
                else:
                    if self.spectro_variable == 0: #Energy
                        cursor = numpy.where((numpy.round(ShadowPhysics.getEnergyFromShadowK(rays_to_plot[:, 10]), 4) >= numpy.round(min_value, 4)) &
                                             (numpy.round(ShadowPhysics.getEnergyFromShadowK(rays_to_plot[:, 10]), 4) <= numpy.round(max_value, 4)))
                    else:
                        cursor = numpy.where((numpy.round(ShadowPhysics.getWavelengthfromShadowK(rays_to_plot[:, 10]), 4) >= numpy.round(min_value, 4)) &
                                             (numpy.round(ShadowPhysics.getWavelengthfromShadowK(rays_to_plot[:, 10]), 4) <= numpy.round(max_value, 4)))

                color = scalarMap.to_rgba((bins[index] + bins[index+1])/2)

                if index == 0: self.spectro_plot_canvas.setActiveCurveColor(color=color)

                self.replace_spectro_fig(rays_to_plot[cursor], x, factor_x, xrange,
                                         title=self.title + str(index), color=color)

            self.spectro_plot_canvas.setDrawModeEnabled(True, 'rectangle')
            self.spectro_plot_canvas.setGraphXLimits(xrange[0]*factor_x, xrange[1]*factor_x)
            self.spectro_plot_canvas.setGraphXLabel(auto_title)
            self.spectro_plot_canvas.replot()
Exemple #11
0
empty_element._oe.set_screens(n_screen, i_screen, i_abs, sl_dis, i_slit,
                              i_stop, k_slit, thick, file_abs, rx_slit,
                              rz_slit, cx_slit, cz_slit, file_scr_ext)

zone_plate_beam = ShadowBeam.traceFromOE(input_beam,
                                         empty_element,
                                         history=False)

go = numpy.where(zone_plate_beam._beam.rays[:, 9] == 1)

go_input_beam = ShadowBeam()
go_input_beam._beam.rays = copy.deepcopy(zone_plate_beam._beam.rays[go])

###################################################

avg_wavelength = ShadowPhysics.getWavelengthFromShadowK(
    numpy.average(go_input_beam._beam.rays[:, 10])) * 1e-1  #ANGSTROM->nm

print("W", avg_wavelength, "nm")

focal_distance = (delta_rn * (1000 * diameter) / avg_wavelength) * 1e-7  # cm
image_position = focal_distance * source_distance / (source_distance -
                                                     focal_distance)
magnification = numpy.abs(image_position / source_distance)

print("FD", focal_distance, "cm")
print("Q", image_position, "cm")
print("M", magnification)

out_beam = apply_fresnel_zone_plate(go_input_beam, type_of_zp, diameter,
                                    delta_rn, image_position,
                                    substrate_material, substrate_thickness,
Exemple #12
0
def apply_fresnel_zone_plate(input_beam, type_of_zp, diameter, delta_rn,
                             image_position, substrate_material,
                             substrate_thickness, zone_plate_material,
                             zone_plate_thickness):

    max_zones_number = int(diameter * 1000 / (4 * delta_rn))

    print("MZN", max_zones_number)

    focused_beam = input_beam.duplicate(history=False)

    if type_of_zp == PHASE_ZP:
        substrate_weight_factor = get_material_weight_factor(
            focused_beam, substrate_material, substrate_thickness)

        focused_beam._beam.rays[:,
                                6] = focused_beam._beam.rays[:,
                                                             6] * substrate_weight_factor[:]
        focused_beam._beam.rays[:,
                                7] = focused_beam._beam.rays[:,
                                                             7] * substrate_weight_factor[:]
        focused_beam._beam.rays[:,
                                8] = focused_beam._beam.rays[:,
                                                             8] * substrate_weight_factor[:]
        focused_beam._beam.rays[:,
                                15] = focused_beam._beam.rays[:,
                                                              15] * substrate_weight_factor[:]
        focused_beam._beam.rays[:,
                                16] = focused_beam._beam.rays[:,
                                                              16] * substrate_weight_factor[:]
        focused_beam._beam.rays[:,
                                17] = focused_beam._beam.rays[:,
                                                              17] * substrate_weight_factor[:]

    good_zones = []
    dark_zones = []
    r_zone_i_previous = 0.0
    for i in range(1, max_zones_number + 1):
        r_zone_i = numpy.sqrt(i * diameter * 1000 * delta_rn) * 1e-7
        if i % 2 == 0: good_zones.append([r_zone_i_previous, r_zone_i])
        else: dark_zones.append([r_zone_i_previous, r_zone_i])
        r_zone_i_previous = r_zone_i

    x = input_beam._beam.rays[:, 0]
    z = input_beam._beam.rays[:, 2]
    r = numpy.sqrt(x**2 + z**2)

    focused_beam._beam.rays[:, 9] = -100

    for zone in good_zones:
        t = numpy.where(numpy.logical_and(r >= zone[0], r <= zone[1]))

        intercepted_rays = focused_beam._beam.rays[t]

        # (see formulas in A.G. Michette, "X-ray science and technology"
        #  Institute of Physics Publishing (1993))

        x_int = intercepted_rays[:, 0]
        z_int = intercepted_rays[:, 2]
        xp_int = intercepted_rays[:, 3]
        zp_int = intercepted_rays[:, 5]
        k_mod_int = intercepted_rays[:, 10]

        r_int = numpy.sqrt(x_int**2 + z_int**2)

        k_x_int = k_mod_int * xp_int
        k_z_int = k_mod_int * zp_int
        d = zone[1] - zone[0]

        # computing G (the "grating" wavevector in Angstrom^-1)
        gx = -numpy.pi / d * (x_int / r_int)
        gz = -numpy.pi / d * (z_int / r_int)

        k_x_out = k_x_int + gx
        k_z_out = k_z_int + gz
        xp_out = k_x_out / k_mod_int
        zp_out = k_z_out / k_mod_int

        intercepted_rays[:, 3] = xp_out  # XP
        intercepted_rays[:, 5] = zp_out  # ZP
        intercepted_rays[:, 9] = 1

        focused_beam._beam.rays[t, 3] = intercepted_rays[:, 3]
        focused_beam._beam.rays[t, 4] = intercepted_rays[:, 4]
        focused_beam._beam.rays[t, 5] = intercepted_rays[:, 5]
        focused_beam._beam.rays[t, 9] = intercepted_rays[:, 9]

    if type_of_zp == PHASE_ZP:
        for zone in dark_zones:
            t = numpy.where(numpy.logical_and(r >= zone[0], r <= zone[1]))

            intercepted_rays = focused_beam._beam.rays[t]

            # (see formulas in A.G. Michette, "X-ray science and technology"
            #  Institute of Physics Publishing (1993))

            x_int = intercepted_rays[:, 0]
            z_int = intercepted_rays[:, 2]
            xp_int = intercepted_rays[:, 3]
            zp_int = intercepted_rays[:, 5]
            k_mod_int = intercepted_rays[:, 10]

            r_int = numpy.sqrt(x_int**2 + z_int**2)

            k_x_int = k_mod_int * xp_int
            k_z_int = k_mod_int * zp_int
            d = zone[1] - zone[0]

            # computing G (the "grating" wavevector in Angstrom^-1)
            gx = -numpy.pi / d * (x_int / r_int)
            gz = -numpy.pi / d * (z_int / r_int)

            k_x_out = k_x_int + gx
            k_z_out = k_z_int + gz
            xp_out = k_x_out / k_mod_int
            zp_out = k_z_out / k_mod_int

            intercepted_rays[:, 3] = xp_out  # XP
            intercepted_rays[:, 5] = zp_out  # ZP
            intercepted_rays[:, 9] = 1

            focused_beam._beam.rays[t, 3] = intercepted_rays[:, 3]
            focused_beam._beam.rays[t, 4] = intercepted_rays[:, 4]
            focused_beam._beam.rays[t, 5] = intercepted_rays[:, 5]
            focused_beam._beam.rays[t, 9] = intercepted_rays[:, 9]

    go = numpy.where(focused_beam._beam.rays[:, 9] == 1)
    lo = numpy.where(focused_beam._beam.rays[:, 9] != 1)

    intensity_go = numpy.sum(focused_beam._beam.rays[go, 6] ** 2 + focused_beam._beam.rays[go, 7] ** 2 + focused_beam._beam.rays[go, 8] ** 2 + \
                             focused_beam._beam.rays[go, 15] ** 2 + focused_beam._beam.rays[go, 16] ** 2 + focused_beam._beam.rays[go, 17] ** 2)

    intensity_lo = numpy.sum(focused_beam._beam.rays[lo, 6] ** 2 + focused_beam._beam.rays[lo, 7] ** 2 + focused_beam._beam.rays[lo, 8] ** 2 + \
                             focused_beam._beam.rays[lo, 15] ** 2 + focused_beam._beam.rays[lo, 16] ** 2 + focused_beam._beam.rays[lo, 17] ** 2)

    if type_of_zp == PHASE_ZP:
        wavelength = ShadowPhysics.getWavelengthFromShadowK(
            focused_beam._beam.rays[go, 10]) * 1e-8  #cm
        delta, beta = get_delta_beta(focused_beam._beam.rays[go],
                                     zone_plate_material)

        phi = 2 * numpy.pi * (zone_plate_thickness * 1e-7) * delta / wavelength
        r = beta / delta

        efficiency_zp = ((1 + numpy.exp(-2 * r * phi) -
                          (2 * numpy.exp(-r * phi) * numpy.cos(phi))) /
                         numpy.pi)**2

        efficiency_weight_factor = numpy.sqrt(efficiency_zp)
    elif type_of_zp == AMPLITUDE_ZP:
        efficiency_zp = numpy.ones(len(
            focused_beam._beam.rays[go])) / (numpy.pi**2)
        efficiency_weight_factor = numpy.sqrt(
            efficiency_zp * (1 + (intensity_lo / intensity_go)))

    print("EFF", efficiency_weight_factor**2,
          numpy.max(efficiency_weight_factor**2),
          numpy.min(efficiency_weight_factor**2))

    focused_beam._beam.rays[
        go, 6] = focused_beam._beam.rays[go, 6] * efficiency_weight_factor[:]
    focused_beam._beam.rays[
        go, 7] = focused_beam._beam.rays[go, 7] * efficiency_weight_factor[:]
    focused_beam._beam.rays[
        go, 8] = focused_beam._beam.rays[go, 8] * efficiency_weight_factor[:]
    focused_beam._beam.rays[
        go, 15] = focused_beam._beam.rays[go, 15] * efficiency_weight_factor[:]
    focused_beam._beam.rays[
        go, 16] = focused_beam._beam.rays[go, 16] * efficiency_weight_factor[:]
    focused_beam._beam.rays[
        go, 17] = focused_beam._beam.rays[go, 17] * efficiency_weight_factor[:]

    return focused_beam
    def compute(self):
        try:
            self.shadow_output.setText("")

            sys.stdout = EmittingStream(textWritten=self.writeStdOut)

            self.checkFields()

            m = -self.grating_diffraction_order

            if self.units_in_use == 0:
                _lambda = ShadowPhysics.getWavelengthFromEnergy(self.photon_energy) / self.workspace_units_to_m * 1e-10
            elif self.units_in_use == 1:
                _lambda = self.photon_wavelength / self.workspace_units_to_m * 1e-10

            sin_alpha = (-m * self.k * _lambda / (self.c ** 2 - 1)) + numpy.sqrt(
                1 + (m * m * self.c * self.c * self.k * self.k * _lambda * _lambda) / ((self.c ** 2 - 1) ** 2)
            )
            alpha = numpy.arcsin(sin_alpha)

            beta = numpy.arcsin(sin_alpha - m * self.k * _lambda)
            _beta = numpy.arccos(self.c * numpy.cos(alpha))

            print("Lambda:", _lambda, self.workspace_units_label)
            print("ALPHA:", numpy.degrees(alpha), "deg")
            print("BETA:", numpy.degrees(beta), numpy.degrees(_beta), "deg")

            b2 = (((numpy.cos(alpha) ** 2) / self.r_a) + ((numpy.cos(beta) ** 2) / self.r_b)) / (
                -2 * m * self.k * _lambda
            )
            b3 = (
                (numpy.sin(alpha) * numpy.cos(alpha) ** 2) / self.r_a ** 2
                - (numpy.sin(beta) * numpy.cos(beta) ** 2) / self.r_b ** 2
            ) / (-2 * m * self.k * _lambda)
            b4 = (
                ((4 * numpy.sin(alpha) ** 2 - numpy.cos(alpha) ** 2) * numpy.cos(alpha) ** 2) / self.r_a ** 3
                + ((4 * numpy.sin(beta) ** 2 - numpy.cos(beta) ** 2) * numpy.cos(beta) ** 2) / self.r_b ** 3
            ) / (-8 * m * self.k * _lambda)

            print("\nb2", b2)
            print("b3", b3)
            print("b4", b4)

            shadow_coeff_0 = self.k
            shadow_coeff_1 = -2 * self.k * b2
            shadow_coeff_2 = 3 * self.k * b3
            shadow_coeff_3 = -4 * self.k * b4

            print("\nshadow_coeff_0", shadow_coeff_0)
            print("shadow_coeff_1", shadow_coeff_1)
            print("shadow_coeff_2", shadow_coeff_2)
            print("shadow_coeff_3", shadow_coeff_3)

            ############################################
            #
            # 1 - in case of mirror recalculate real ray tracing distance (r_a') from initial r_a and vertical distance
            #     between grating and mirror (h)
            #

            gamma = (alpha + beta) / 2

            d_source_to_mirror = self.r_a - (self.h / numpy.abs(numpy.tan(numpy.pi - 2 * gamma)))
            d_mirror_to_grating = self.h / numpy.abs(numpy.sin(numpy.pi - 2 * gamma))

            r_a_first = d_source_to_mirror + d_mirror_to_grating

            print("\ngamma", numpy.degrees(gamma))
            print("d_source_to_mirror", d_source_to_mirror, self.workspace_units_label)
            print("d_mirror_to_grating", d_mirror_to_grating, self.workspace_units_label)
            print("r_a_first", r_a_first, self.workspace_units_label)

            ############################################

            if self.new_units_in_use == 0:
                new_lambda = (
                    ShadowPhysics.getWavelengthFromEnergy(self.new_photon_energy) / self.workspace_units_to_m * 1e-10
                )
            elif self.new_units_in_use == 1:
                new_lambda = self.new_photon_wavelength / self.workspace_units_to_m * 1e-10

            r = self.r_b / r_a_first

            A0 = self.k * new_lambda
            A2 = self.k * new_lambda * self.r_b * b2

            new_c_num = (
                2 * A2
                + 4 * (A2 / A0) ** 2
                + (4 + 2 * A2 - A0 ** 2) * r
                - 4 * (A2 / A0) * numpy.sqrt((1 + r) ** 2 + 2 * A2 * (1 + r) - r * A0 ** 2)
            )

            new_c_den = -4 + A0 ** 2 - 4 * A2 + 4 * (A2 / A0) ** 2

            new_c = numpy.sqrt(new_c_num / new_c_den)

            new_sin_alpha = (-m * self.k * new_lambda / (new_c ** 2 - 1)) + numpy.sqrt(
                1 + (m * m * new_c * new_c * self.k * self.k * new_lambda * new_lambda) / ((new_c ** 2 - 1) ** 2)
            )

            new_alpha = numpy.arcsin(new_sin_alpha)
            new_beta = numpy.arcsin(new_sin_alpha - m * self.k * new_lambda)
            _new_beta = numpy.arccos(new_c * numpy.cos(new_alpha))

            print("New Lambda:", new_lambda, self.workspace_units_label)
            print("New C:", new_c)
            print("NEW ALPHA:", numpy.degrees(new_alpha), "deg")
            print("NEW BETA:", numpy.degrees(new_beta), numpy.degrees(_new_beta), "deg")

            gamma = (new_alpha + new_beta) / 2

            d_source_to_mirror = self.r_a - (self.h / numpy.abs(numpy.tan(numpy.pi - 2 * gamma)))
            d_mirror_to_grating = self.h / numpy.abs(numpy.sin(numpy.pi - 2 * gamma))

            r_a_first = d_source_to_mirror + d_mirror_to_grating

            print("\ngamma", numpy.degrees(gamma))
            print("d_source_to_mirror", d_source_to_mirror, self.workspace_units_label)
            print("d_mirror_to_grating", d_mirror_to_grating, self.workspace_units_label)
            print("r_a_first", r_a_first, self.workspace_units_label)

            self.send("PreProcessor_Data", ShadowPreProcessorData())
        except Exception as exception:
            QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)
Exemple #14
0
 def set_Density(self):
     if not self.SYMBOL is None:
         if not self.SYMBOL.strip() == "":
             self.SYMBOL = self.SYMBOL.strip()
             self.DENSITY = ShadowPhysics.getMaterialDensity(self.SYMBOL)
Exemple #15
0
 def set_Density(self):
     if not self.SYMBOL is None:
         if not self.SYMBOL.strip() == "":
             self.SYMBOL = self.SYMBOL.strip()
             self.DENSITY = ShadowPhysics.getMaterialDensity(self.SYMBOL)
Exemple #16
0
    def traceOpticalElement(self):
        try:
            self.setStatusMessage("")
            self.progressBarInit()

            if ShadowCongruence.checkEmptyBeam(self.input_beam):
                if ShadowCongruence.checkGoodBeam(self.input_beam):
                    self.checkFields()

                    sys.stdout = EmittingStream(textWritten=self.writeStdOut)

                    if self.trace_shadow:
                        grabber = TTYGrabber()
                        grabber.start()

                    ###########################################
                    # TODO: TO BE ADDED JUST IN CASE OF BROKEN
                    #       ENVIRONMENT: MUST BE FOUND A PROPER WAY
                    #       TO TEST SHADOW
                    self.fixWeirdShadowBug()
                    ###########################################

                    self.progressBarSet(10)

                    if self.source_distance_flag == 0:
                        self.source_distance = self.source_plane_distance

                    zone_plate_beam = self.get_zone_plate_beam()

                    go = numpy.where(zone_plate_beam._beam.rays[:, 9] == GOOD)

                    self.avg_wavelength = ShadowPhysics.getWavelengthFromShadowK(numpy.average(zone_plate_beam._beam.rays[go, 10]))*1e-1 #ANGSTROM->nm

                    self.focal_distance = (self.delta_rn*(self.diameter*1000)/self.avg_wavelength)* (1e-9/self.workspace_units_to_m)       # WS Units
                    self.image_position = self.focal_distance*self.source_distance/(self.source_distance-self.focal_distance)              # WS Units
                    self.magnification = numpy.abs(self.image_position/self.source_distance)

                    self.avg_wavelength = numpy.round(self.avg_wavelength, 6)      # nm
                    self.focal_distance = numpy.round(self.focal_distance, 6)
                    self.image_position = numpy.round(self.image_position, 6)
                    self.magnification = numpy.round(self.magnification, 6)

                    if self.automatically_set_image_plane == 1:
                        self.image_plane_distance = self.image_position

                    self.progressBarSet(30)

                    if self.type_of_zp == PHASE_ZP:
                        efficiency, max_efficiency, thickness_max_efficiency = ZonePlate.calculate_efficiency(self.avg_wavelength, # Angstrom
                                                                                                              self.zone_plate_material,
                                                                                                              self.zone_plate_thickness)

                        self.efficiency = numpy.round(100*efficiency, 3)
                        self.max_efficiency = numpy.round(100*max_efficiency, 3)
                        self.thickness_max_efficiency =  thickness_max_efficiency
                    else:
                        self.efficiency = numpy.round(100/(numpy.pi**2), 3)
                        self.max_efficiency = numpy.nan
                        self.thickness_max_efficiency =  numpy.nan

                    focused_beam, \
                    self.number_of_zones = ZonePlate.apply_fresnel_zone_plate(zone_plate_beam,  # WS Units
                                                                              self.type_of_zp,
                                                                              self.diameter,  # micron
                                                                              self.delta_rn, # nm
                                                                              self.substrate_material,
                                                                              self.substrate_thickness,
                                                                              self.zone_plate_material,
                                                                              self.zone_plate_thickness,
                                                                              self.source_distance, # WS Units
                                                                              self.workspace_units_to_m)

                    self.progressBarSet(60)

                    beam_out = self.get_output_beam(focused_beam)

                    self.progressBarSet(80)

                    if self.trace_shadow:
                        grabber.stop()

                        for row in grabber.ttyData:
                           self.writeStdOut(row)

                    self.setStatusMessage("Plotting Results")

                    self.plot_results(beam_out)
                    self.plot_efficiency()

                    self.setStatusMessage("")

                    beam_out.setScanningData(self.input_beam.scanned_variable_data)

                    self.send("Beam", beam_out)
                    self.send("Trigger", TriggerIn(new_object=True))
                else:
                    if self.not_interactive: self.sendEmptyBeam()
                    else: raise Exception("Input Beam with no good rays")
            else:
                if self.not_interactive: self.sendEmptyBeam()
                else: raise Exception("Empty Input Beam")

        except Exception as exception:
            QMessageBox.critical(self, "Error",
                                       str(exception), QMessageBox.Ok)

            if self.IS_DEVELOP: raise exception

        self.progressBarFinished()
Exemple #17
0
    def plot_power_density_BM(self,
                              shadow_beam,
                              initial_energy,
                              initial_flux,
                              nbins_interpolation,
                              var_x,
                              var_y,
                              nbins_h=100,
                              nbins_v=100,
                              xrange=None,
                              yrange=None,
                              nolost=1,
                              to_mm=1.0,
                              show_image=True):
        n_rays = len(shadow_beam._beam.rays[:, 0])  # lost and good!

        if n_rays == 0:
            ticket, _ = self.manage_empty_beam(None, nbins_h, nbins_v, xrange,
                                               yrange, var_x, var_y, 0.0, 0.0,
                                               0.0, 0.0, show_image, to_mm)
            return ticket

        source_beam = shadow_beam.getOEHistory(
            oe_number=1)._input_beam.duplicate(history=False)
        history_item = shadow_beam.getOEHistory(
            oe_number=shadow_beam._oe_number)

        if history_item is None or history_item._input_beam is None:
            previous_beam = shadow_beam
        else:
            previous_beam = history_item._input_beam.duplicate(history=False)

        rays_energy = ShadowPhysics.getEnergyFromShadowK(
            shadow_beam._beam.rays[:, 10])
        energy_range = [numpy.min(rays_energy), numpy.max(rays_energy)]

        ticket_initial = source_beam._beam.histo1(11,
                                                  xrange=energy_range,
                                                  nbins=nbins_interpolation,
                                                  nolost=1,
                                                  ref=23)

        energy_bins = ticket_initial["bin_center"]

        energy_min = energy_bins[0]
        energy_max = energy_bins[-1]
        energy_step = energy_bins[1] - energy_bins[0]

        initial_flux_shadow = numpy.interp(energy_bins,
                                           initial_energy,
                                           initial_flux,
                                           left=initial_flux[0],
                                           right=initial_flux[-1])
        initial_power_shadow = initial_flux_shadow * 1e3 * codata.e * energy_step

        total_initial_power_shadow = initial_power_shadow.sum()

        print("Total Initial Power from Shadow", total_initial_power_shadow)

        if nolost > 1:  # must be calculating only the rays the become lost in the last object
            current_beam = shadow_beam

            if history_item is None or history_item._input_beam is None:
                beam = shadow_beam._beam
            else:
                if nolost == 2:
                    current_lost_rays_cursor = numpy.where(
                        current_beam._beam.rays[:, 9] != 1)

                    current_lost_rays = current_beam._beam.rays[
                        current_lost_rays_cursor]
                    lost_rays_in_previous_beam = previous_beam._beam.rays[
                        current_lost_rays_cursor]

                    lost_that_were_good_rays_cursor = numpy.where(
                        lost_rays_in_previous_beam[:, 9] == 1)

                    beam = Beam()
                    beam.rays = current_lost_rays[
                        lost_that_were_good_rays_cursor]  # lost rays that were good after the previous OE

                    # in case of filters, Shadow computes the absorption for lost rays. This cause an imbalance on the total power.
                    # the lost rays that were good must have the same intensity they had before the optical element.

                    beam.rays[:, 6] = lost_rays_in_previous_beam[
                        lost_that_were_good_rays_cursor][:, 6]
                    beam.rays[:, 7] = lost_rays_in_previous_beam[
                        lost_that_were_good_rays_cursor][:, 7]
                    beam.rays[:, 8] = lost_rays_in_previous_beam[
                        lost_that_were_good_rays_cursor][:, 8]
                    beam.rays[:, 15] = lost_rays_in_previous_beam[
                        lost_that_were_good_rays_cursor][:, 15]
                    beam.rays[:, 16] = lost_rays_in_previous_beam[
                        lost_that_were_good_rays_cursor][:, 16]
                    beam.rays[:, 17] = lost_rays_in_previous_beam[
                        lost_that_were_good_rays_cursor][:, 17]
                else:
                    incident_rays = previous_beam._beam.rays
                    transmitted_rays = current_beam._beam.rays

                    incident_intensity = incident_rays[:, 6]**2  + incident_rays[:, 7]**2  + incident_rays[:, 8]**2 +\
                                         incident_rays[:, 15]**2 + incident_rays[:, 16]**2 + incident_rays[:, 17]**2
                    transmitted_intensity = transmitted_rays[:, 6]**2  + transmitted_rays[:, 7]**2  + transmitted_rays[:, 8]**2 +\
                                            transmitted_rays[:, 15]**2 + transmitted_rays[:, 16]**2 + transmitted_rays[:, 17]**2

                    electric_field = numpy.sqrt(incident_intensity -
                                                transmitted_intensity)
                    electric_field[numpy.where(
                        electric_field == numpy.nan)] = 0.0

                    beam = Beam()
                    beam.rays = copy.deepcopy(shadow_beam._beam.rays)

                    beam.rays[:, 6] = electric_field
                    beam.rays[:, 7] = 0.0
                    beam.rays[:, 8] = 0.0
                    beam.rays[:, 15] = 0.0
                    beam.rays[:, 16] = 0.0
                    beam.rays[:, 17] = 0.0
        else:
            beam = shadow_beam._beam

        if len(beam.rays) == 0:
            ticket, _ = self.manage_empty_beam(None, nbins_h, nbins_v, xrange,
                                               yrange, var_x, var_y, 0.0,
                                               energy_min, energy_max,
                                               energy_step, show_image, to_mm)
            return ticket

        ticket_incident = previous_beam._beam.histo1(
            11,
            xrange=energy_range,
            nbins=nbins_interpolation,
            nolost=1,
            ref=23)  # intensity of good rays per bin incident
        ticket_final = beam.histo1(11,
                                   xrange=energy_range,
                                   nbins=nbins_interpolation,
                                   nolost=1,
                                   ref=23)  # intensity of good rays per bin

        good = numpy.where(ticket_initial["histogram"] > 0)

        efficiency_incident = numpy.zeros(len(ticket_incident["histogram"]))
        efficiency_incident[good] = ticket_incident["histogram"][
            good] / ticket_initial["histogram"][good]

        incident_power_shadow = initial_power_shadow * efficiency_incident

        total_incident_power_shadow = incident_power_shadow.sum()
        print("Total Incident Power from Shadow", total_incident_power_shadow)

        efficiency_final = numpy.zeros(len(ticket_final["histogram"]))
        efficiency_final[good] = ticket_final["histogram"][
            good] / ticket_initial["histogram"][good]

        final_power_shadow = initial_power_shadow * efficiency_final

        total_final_power_shadow = final_power_shadow.sum()
        print("Total Final Power from Shadow", total_final_power_shadow)

        # CALCULATE POWER DENSITY PER EACH RAY -------------------------------------------------------

        ticket = beam.histo1(11,
                             xrange=energy_range,
                             nbins=nbins_interpolation,
                             nolost=1,
                             ref=0)  # number of rays per bin
        good = numpy.where(ticket["histogram"] > 0)

        final_power_per_ray = numpy.zeros(len(final_power_shadow))
        final_power_per_ray[
            good] = final_power_shadow[good] / ticket["histogram"][good]

        go = numpy.where(shadow_beam._beam.rays[:, 9] == 1)

        rays_energy = ShadowPhysics.getEnergyFromShadowK(
            shadow_beam._beam.rays[go, 10])

        ticket = beam.histo2(var_x,
                             var_y,
                             nbins_h=nbins_h,
                             nbins_v=nbins_v,
                             xrange=xrange,
                             yrange=yrange,
                             nolost=1,
                             ref=0)

        ticket['bin_h_center'] *= to_mm
        ticket['bin_v_center'] *= to_mm
        pixel_area = (ticket['bin_h_center'][1] -
                      ticket['bin_h_center'][0]) * (ticket['bin_v_center'][1] -
                                                    ticket['bin_v_center'][0])

        power_density = numpy.interp(
            rays_energy, energy_bins, final_power_per_ray, left=0,
            right=0) / pixel_area

        final_beam = Beam()
        final_beam.rays = copy.deepcopy(beam.rays)

        final_beam.rays[go, 6] = numpy.sqrt(power_density)
        final_beam.rays[go, 7] = 0.0
        final_beam.rays[go, 8] = 0.0
        final_beam.rays[go, 15] = 0.0
        final_beam.rays[go, 16] = 0.0
        final_beam.rays[go, 17] = 0.0

        ticket = final_beam.histo2(var_x,
                                   var_y,
                                   nbins_h=nbins_h,
                                   nbins_v=nbins_v,
                                   xrange=xrange,
                                   yrange=yrange,
                                   nolost=1,
                                   ref=23)

        ticket['histogram'][numpy.where(ticket['histogram'] < 1e-7)] = 0.0

        self.cumulated_previous_power_plot = total_incident_power_shadow
        self.cumulated_power_plot = total_final_power_shadow

        self.plot_power_density_ticket(ticket, var_x, var_y,
                                       total_initial_power_shadow, energy_min,
                                       energy_max, energy_step, show_image)

        return ticket
Exemple #18
0
    def compute(self):
        try:
            self.shadow_output.setText("")

            sys.stdout = EmittingStream(textWritten=self.writeStdOut)

            self.checkFields()

            m = -self.grating_diffraction_order

            if self.units_in_use == 0:
                wavelength = ShadowPhysics.getWavelengthFromEnergy(
                    self.photon_energy) / self.workspace_units_to_m * 1e-10
            elif self.units_in_use == 1:
                wavelength = self.photon_wavelength / self.workspace_units_to_m * 1e-10

            sin_alpha = (-m*self.k*wavelength/(self.c**2 - 1)) + \
                        numpy.sqrt(1 + (m*m*self.c*self.c*self.k*self.k*wavelength*wavelength)/((self.c**2 - 1)**2))

            alpha = numpy.arcsin(sin_alpha)
            beta = numpy.arcsin(sin_alpha - m * self.k * wavelength)

            self.design_alpha = round(numpy.degrees(alpha), 3)
            self.design_beta = round(numpy.degrees(beta), 3)
            #_beta = numpy.arccos(self.c*numpy.cos(alpha))

            print("####################################################")
            print("# DESIGN PHASE")
            print("####################################################\n")

            print("Photon Wavelength:", wavelength, self.workspace_units_label)
            print("Design ALPHA     :", self.design_alpha, "deg")
            print("Design BETA      :", self.design_beta, "deg")

            self.b2 = (((numpy.cos(alpha)**2) / self.r_a) +
                       ((numpy.cos(beta)**2) / self.r_b)) / (-2 * m * self.k *
                                                             wavelength)
            self.b3 = ((numpy.sin(alpha)*numpy.cos(alpha)**2)/self.r_a**2 - \
                      (numpy.sin(beta)*numpy.cos(beta)**2)/self.r_b**2)/(-2*m*self.k*wavelength)
            self.b4 = (((4*numpy.sin(alpha)**2 - numpy.cos(alpha)**2)*numpy.cos(alpha)**2)/self.r_a**3 + \
                      ((4*numpy.sin(beta)**2 - numpy.cos(beta)**2)*numpy.cos(beta)**2)/self.r_b**3)/(-8*m*self.k*wavelength)

            print("\nb2:", self.b2)
            print("b3:", self.b3)
            print("b4:", self.b4)

            self.shadow_coeff_0 = round(self.k, 8)
            self.shadow_coeff_1 = round(-2 * self.k * self.b2, 8)
            self.shadow_coeff_2 = round(3 * self.k * self.b3, 8)
            self.shadow_coeff_3 = round(-4 * self.k * self.b4, 8)

            print("\nshadow_coeff_0:", self.shadow_coeff_0)
            print("shadow_coeff_1:", self.shadow_coeff_1)
            print("shadow_coeff_2:", self.shadow_coeff_2)
            print("shadow_coeff_3:", self.shadow_coeff_3)

            ############################################
            #
            # 1 - in case of mirror recalculate real ray tracing distance (r_a') from initial r_a and vertical distance
            #     between grating and mirror (h)
            #

            gamma = (alpha + beta) / 2

            d_source_to_mirror = self.r_a - (
                self.h / numpy.abs(numpy.tan(numpy.pi - 2 * gamma)))
            d_mirror_to_grating = self.h / numpy.abs(
                numpy.sin(numpy.pi - 2 * gamma))

            r_a_first = d_source_to_mirror + d_mirror_to_grating

            print("\ngamma                   :", numpy.degrees(gamma), "deg")
            print("Source to Mirror distance :", d_source_to_mirror,
                  self.workspace_units_label)
            print("Mirror to Grating distance:", d_mirror_to_grating,
                  self.workspace_units_label)
            print("R_a'                      :", r_a_first,
                  self.workspace_units_label)

            ############################################

            if self.new_units_in_use == 0:
                newwavelength = ShadowPhysics.getWavelengthFromEnergy(
                    self.new_photon_energy) / self.workspace_units_to_m * 1e-10
            elif self.new_units_in_use == 1:
                newwavelength = self.new_photon_wavelength / self.workspace_units_to_m * 1e-10

            r = self.r_b / r_a_first

            A0 = self.k * newwavelength
            A2 = self.k * newwavelength * self.r_b * self.b2

            new_c_num = 2*A2 + 4*(A2/A0)**2 + \
                        (4 + 2*A2 - A0**2)*r - \
                        4*(A2/A0)*numpy.sqrt((1 + r)**2 + 2*A2*(1 + r) - r*A0**2)

            new_c_den = -4 + A0**2 - 4 * A2 + 4 * (A2 / A0)**2

            new_c = numpy.sqrt(new_c_num / new_c_den)

            new_sin_alpha = (-m*self.k*newwavelength/(new_c**2 - 1)) + \
                        numpy.sqrt(1 + (m*m*new_c*new_c*self.k*self.k*newwavelength*newwavelength)/((new_c**2 - 1)**2))

            new_alpha = numpy.arcsin(new_sin_alpha)
            new_beta = numpy.arcsin(new_sin_alpha - m * self.k * newwavelength)

            self.raytracing_alpha = round(numpy.degrees(new_alpha), 6)
            self.raytracing_beta = round(numpy.degrees(new_beta), 6)
            #_new_beta = numpy.arccos(new_c*numpy.cos(new_alpha))

            print("####################################################")
            print("# RAY-TRACING PHASE")
            print("####################################################\n")

            print("Ray-Tracing Wavelength:", newwavelength,
                  self.workspace_units_label)
            print("Ray-Tracing C         :", new_c)
            print("Ray-Tracing ALPHA     :", self.raytracing_alpha, "deg")
            print("Ray-Tracing BETA      :", self.raytracing_beta, "deg")

            gamma = (new_alpha + new_beta) / 2

            self.d_source_to_mirror = self.r_a - (
                self.h / numpy.abs(numpy.tan(numpy.pi - 2 * gamma)))
            self.d_mirror_to_grating = self.h / numpy.abs(
                numpy.sin(numpy.pi - 2 * gamma))

            r_a_first = self.d_source_to_mirror + self.d_mirror_to_grating

            self.d_source_to_mirror = round(self.d_source_to_mirror, 3)
            self.d_source_plane_to_mirror = round(
                self.d_source_to_mirror - self.last_element_distance, 3)
            self.d_mirror_to_grating = round(self.d_mirror_to_grating, 3)

            print("\ngamma                         :", numpy.degrees(gamma),
                  "deg")
            print("Source to Mirror distance       :", self.d_source_to_mirror,
                  self.workspace_units_label)
            print("Source Plane to Mirror distance :",
                  self.d_source_plane_to_mirror, self.workspace_units_label)
            print("Mirror to Grating distance      :",
                  self.d_mirror_to_grating, self.workspace_units_label)
            print("R_a'                            :", r_a_first,
                  self.workspace_units_label)

            self.send(
                "PreProcessor_Data",
                VlsPgmPreProcessorData(
                    shadow_coeff_0=self.shadow_coeff_0,
                    shadow_coeff_1=self.shadow_coeff_1,
                    shadow_coeff_2=self.shadow_coeff_2,
                    shadow_coeff_3=self.shadow_coeff_3,
                    d_source_plane_to_mirror=self.d_source_plane_to_mirror,
                    d_mirror_to_grating=self.d_mirror_to_grating,
                    d_grating_to_exit_slits=self.r_b,
                    alpha=self.raytracing_alpha,
                    beta=self.raytracing_beta))
        except Exception as exception:
            QMessageBox.critical(self, "Error", str(exception), QMessageBox.Ok)
Exemple #19
0
    def apply_fresnel_zone_plate(cls, 
                                 zone_plate_beam,
                                 type_of_zp, 
                                 diameter, 
                                 delta_rn,                              
                                 substrate_material, 
                                 substrate_thickness,
                                 zone_plate_material,
                                 zone_plate_thickness,
                                 source_distance,
                                 workspace_units_to_m):
        
        max_zones_number = int(diameter*1000/(4*delta_rn))

        focused_beam = zone_plate_beam.duplicate(history=True)

        go = numpy.where(focused_beam._beam.rays[:, 9] == GOOD)

        if type_of_zp == PHASE_ZP: 
            substrate_weight_factor = ZonePlate.get_material_weight_factor(focused_beam._beam.rays[go], substrate_material, substrate_thickness)
        
            focused_beam._beam.rays[go, 6] = focused_beam._beam.rays[go, 6]*substrate_weight_factor[:]
            focused_beam._beam.rays[go, 7] = focused_beam._beam.rays[go, 7]*substrate_weight_factor[:]
            focused_beam._beam.rays[go, 8] = focused_beam._beam.rays[go, 8]*substrate_weight_factor[:]
            focused_beam._beam.rays[go, 15] = focused_beam._beam.rays[go, 15]*substrate_weight_factor[:]
            focused_beam._beam.rays[go, 16] = focused_beam._beam.rays[go, 16]*substrate_weight_factor[:]
            focused_beam._beam.rays[go, 17] = focused_beam._beam.rays[go, 17]*substrate_weight_factor[:]
        
        clear_zones = []
        dark_zones = []
        r_zone_i_previous = 0.0
        for i in range(1, max_zones_number+1):
            r_zone_i = numpy.sqrt(i*diameter*1e-6*delta_rn*1e-9)/workspace_units_to_m # to workspace unit
            if i % 2 == 0: clear_zones.append([r_zone_i_previous, r_zone_i])
            else: dark_zones.append([r_zone_i_previous, r_zone_i])
            r_zone_i_previous = r_zone_i
               
        focused_beam._beam.rays[go, 9] = LOST_ZP
        
        ZonePlate.analyze_zone(clear_zones, focused_beam, source_distance, workspace_units_to_m)
        if type_of_zp == PHASE_ZP: ZonePlate.analyze_zone(dark_zones, focused_beam, source_distance, workspace_units_to_m)
    
        go_2 = numpy.where(focused_beam._beam.rays[:, 9] == GOOD_ZP)

        intensity_go_2 = numpy.sum(focused_beam._beam.rays[go_2, 6] ** 2 + focused_beam._beam.rays[go_2, 7] ** 2 + focused_beam._beam.rays[go_2, 8] ** 2 + \
                                   focused_beam._beam.rays[go_2, 15] ** 2 + focused_beam._beam.rays[go_2, 16] ** 2 + focused_beam._beam.rays[go_2, 17] ** 2)

        if type_of_zp == PHASE_ZP:
            wavelength = ShadowPhysics.getWavelengthFromShadowK(focused_beam._beam.rays[go_2, 10])*1e-1 # nm
            delta, beta = ZonePlate.get_delta_beta(focused_beam._beam.rays[go_2], zone_plate_material)
            
            phi = 2*numpy.pi*zone_plate_thickness*delta/wavelength
            rho = beta/delta
               
            efficiency_zp = (1/(numpy.pi**2))*(1 + numpy.exp(-2*rho*phi) - (2*numpy.exp(-rho*phi)*numpy.cos(phi)))
            efficiency_weight_factor = numpy.sqrt(efficiency_zp)

        elif type_of_zp == AMPLITUDE_ZP:
            lo_2 = numpy.where(focused_beam._beam.rays[:, 9] == LOST_ZP)

            intensity_lo_2 = numpy.sum(focused_beam._beam.rays[lo_2, 6] ** 2 + focused_beam._beam.rays[lo_2, 7] ** 2 + focused_beam._beam.rays[lo_2, 8] ** 2 + \
                                       focused_beam._beam.rays[lo_2, 15] ** 2 + focused_beam._beam.rays[lo_2, 16] ** 2 + focused_beam._beam.rays[lo_2, 17] ** 2)

            efficiency_zp = numpy.ones(len(focused_beam._beam.rays[go_2]))/(numpy.pi**2)
            efficiency_weight_factor = numpy.sqrt(efficiency_zp*(1 + (intensity_lo_2/intensity_go_2)))

        focused_beam._beam.rays[go_2, 6]  = focused_beam._beam.rays[go_2, 6]*efficiency_weight_factor[:]
        focused_beam._beam.rays[go_2, 7]  = focused_beam._beam.rays[go_2, 7]*efficiency_weight_factor[:]
        focused_beam._beam.rays[go_2, 8]  = focused_beam._beam.rays[go_2, 8]*efficiency_weight_factor[:]
        focused_beam._beam.rays[go_2, 15] = focused_beam._beam.rays[go_2, 15]*efficiency_weight_factor[:]
        focused_beam._beam.rays[go_2, 16] = focused_beam._beam.rays[go_2, 16]*efficiency_weight_factor[:]
        focused_beam._beam.rays[go_2, 17] = focused_beam._beam.rays[go_2, 17]*efficiency_weight_factor[:]
        focused_beam._beam.rays[go_2, 9] = GOOD

        return focused_beam, max_zones_number
Exemple #20
0
    def plot_results(self):
        self.plotted_beam = None

        if super().plot_results():
            if self.spectro_plot_canvas is None:
                self.spectro_plot_canvas = PlotWindow.PlotWindow(
                    roi=False,
                    control=False,
                    position=False,
                    plugins=False,
                    logx=False,
                    logy=False)
                self.spectro_plot_canvas.setDefaultPlotLines(False)
                self.spectro_plot_canvas.setDefaultPlotPoints(True)
                self.spectro_plot_canvas.setZoomModeEnabled(True)
                self.spectro_plot_canvas.setMinimumWidth(673)
                self.spectro_plot_canvas.setMaximumWidth(673)
                pos = self.spectro_plot_canvas._plot.graph.ax.get_position()
                self.spectro_plot_canvas._plot.graph.ax.set_position(
                    [pos.x0, pos.y0, pos.width * 0.86, pos.height])
                pos = self.spectro_plot_canvas._plot.graph.ax2.get_position()
                self.spectro_plot_canvas._plot.graph.ax2.set_position(
                    [pos.x0, pos.y0, pos.width * 0.86, pos.height])
                ax3 = self.spectro_plot_canvas._plot.graph.fig.add_axes(
                    [.82, .15, .05, .75])

                self.spectro_image_box.layout().addWidget(
                    self.spectro_plot_canvas)
            else:
                self.spectro_plot_canvas.clear()
                self.spectro_plot_canvas.setDefaultPlotLines(False)
                self.spectro_plot_canvas.setDefaultPlotPoints(True)
                ax3 = self.spectro_plot_canvas._plot.graph.fig.axes[-1]
                ax3.cla()

            number_of_bins = self.spectro_number_of_bins + 1

            x, y, auto_x_title, auto_y_title, xum, yum = self.get_titles()

            if self.plotted_beam is None: self.plotted_beam = self.input_beam

            xrange, yrange = self.get_ranges(self.plotted_beam._beam, x, y)

            min_k = numpy.min(self.plotted_beam._beam.rays[:, 10])
            max_k = numpy.max(self.plotted_beam._beam.rays[:, 10])

            if self.spectro_variable == 0:  #Energy
                energy_min = ShadowPhysics.getEnergyFromShadowK(min_k)
                energy_max = ShadowPhysics.getEnergyFromShadowK(max_k)

                bins = energy_min + numpy.arange(0, number_of_bins + 1) * (
                    (energy_max - energy_min) / number_of_bins)
                normalization = colors.Normalize(vmin=energy_min,
                                                 vmax=energy_max)
            else:  #wavelength
                wavelength_min = ShadowPhysics.getWavelengthfromShadowK(max_k)
                wavelength_max = ShadowPhysics.getWavelengthfromShadowK(min_k)

                bins = wavelength_min + numpy.arange(0, number_of_bins + 1) * (
                    (wavelength_max - wavelength_min) / number_of_bins)
                normalization = colors.Normalize(vmin=wavelength_min,
                                                 vmax=wavelength_max)

            scalarMap = cmx.ScalarMappable(norm=normalization,
                                           cmap=self.color_map)

            cb1 = colorbar.ColorbarBase(ax3,
                                        cmap=self.color_map,
                                        norm=normalization,
                                        orientation='vertical')

            if self.spectro_variable == 0:  #Energy
                cb1.set_label('Energy [eV]')
            else:
                cb1.set_label('Wavelength [Å]')

            go = numpy.where(self.plotted_beam._beam.rays[:, 9] == 1)
            lo = numpy.where(self.plotted_beam._beam.rays[:, 9] != 1)

            rays_to_plot = self.plotted_beam._beam.rays

            if self.rays == 1:
                rays_to_plot = self.plotted_beam._beam.rays[go]
            elif self.rays == 2:
                rays_to_plot = self.plotted_beam._beam.rays[lo]

            factor_x = ShadowPlot.get_factor(x, self.workspace_units_to_cm)
            factor_y = ShadowPlot.get_factor(y, self.workspace_units_to_cm)

            for index in range(0, number_of_bins):
                min_value = bins[index]
                max_value = bins[index + 1]

                if index < number_of_bins - 1:
                    if self.spectro_variable == 0:  #Energy
                        cursor = numpy.where((numpy.round(
                            ShadowPhysics.getEnergyFromShadowK(
                                rays_to_plot[:, 10]),
                            4) >= numpy.round(min_value, 4)) & (numpy.round(
                                ShadowPhysics.getEnergyFromShadowK(
                                    rays_to_plot[:, 10]), 4) < numpy.round(
                                        max_value, 4)))
                    else:
                        cursor = numpy.where((numpy.round(
                            ShadowPhysics.getWavelengthfromShadowK(
                                rays_to_plot[:, 10]),
                            4) >= numpy.round(min_value, 4)) & (numpy.round(
                                ShadowPhysics.getWavelengthfromShadowK(
                                    rays_to_plot[:, 10]), 4) < numpy.round(
                                        max_value, 4)))
                else:
                    if self.spectro_variable == 0:  #Energy
                        cursor = numpy.where((numpy.round(
                            ShadowPhysics.getEnergyFromShadowK(
                                rays_to_plot[:, 10]),
                            4) >= numpy.round(min_value, 4)) & (numpy.round(
                                ShadowPhysics.getEnergyFromShadowK(
                                    rays_to_plot[:, 10]), 4) <= numpy.round(
                                        max_value, 4)))
                    else:
                        cursor = numpy.where((numpy.round(
                            ShadowPhysics.getWavelengthfromShadowK(
                                rays_to_plot[:, 10]),
                            4) >= numpy.round(min_value, 4)) & (numpy.round(
                                ShadowPhysics.getWavelengthfromShadowK(
                                    rays_to_plot[:, 10]), 4) <= numpy.round(
                                        max_value, 4)))

                color = scalarMap.to_rgba((bins[index] + bins[index + 1]) / 2)

                if index == 0:
                    self.spectro_plot_canvas.setActiveCurveColor(color=color)

                self.replace_spectro_fig(rays_to_plot[cursor],
                                         x,
                                         y,
                                         factor_x,
                                         factor_y,
                                         title=self.title + str(index),
                                         color=color)

            self.spectro_plot_canvas.setGraphXLimits(xrange[0] * factor_x,
                                                     xrange[1] * factor_x)
            self.spectro_plot_canvas.setGraphYLimits(yrange[0] * factor_y,
                                                     yrange[1] * factor_y)
            self.spectro_plot_canvas.setGraphXLabel(auto_x_title)
            self.spectro_plot_canvas.setGraphYLabel(auto_y_title)
            self.spectro_plot_canvas.replot()
Exemple #21
0
 def set_ODensity(self):
     if not self.O_MATERIAL is None:
         if not self.O_MATERIAL.strip() == "":
             self.O_MATERIAL = self.O_MATERIAL.strip()
             self.O_DENSITY = ShadowPhysics.getMaterialDensity(
                 self.O_MATERIAL)