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)
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()
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
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)
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)
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
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")
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
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()
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,
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)
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)
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()
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
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)
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
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()
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)