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