def plotTotalPower(self, spectrum=False): """ Method to plot the total power. :param spectrum: Whether to plot the power density in energy domain (True) or time domain (False, default). :type spectrum: bool """ """ Adapted from github:Samoylv/WPG/wpg/wpg_uti_wf.integral_intensity() """ print("\n Plotting total power.") # Setup new figure. plt.figure() # Switch to frequency (energy) domain if requested. if spectrum: print("\n Switching to frequency domain.") wpg.srwlib.srwl.SetRepresElecField(self.wavefront._srwl_wf, 'f') self.intensity = self.wavefront.get_intensity() # Get dimensions. mesh = self.wavefront.params.Mesh dx = (mesh.xMax - mesh.xMin)/(mesh.nx - 1) dy = (mesh.yMax - mesh.yMin)/(mesh.ny - 1) # Get intensity by integrating over transverse dimensions. int0 = self.intensity.sum(axis=(0,1)) # Scale to get unit W/mm^2 int0 = int0*(dx*dy*1.e6) # amplitude units sqrt(W/mm^2) int0max = int0.max() # Get center pixel numbers. center_nx = int(mesh.nx/2) center_ny = int(mesh.ny/2) # Get meaningful slices. aw = [a[0] for a in numpy.argwhere(int0 > int0max*0.01)] int0_mean = int0[min(aw):max(aw)] # meaningful range of pulse dSlice = (mesh.sliceMax - mesh.sliceMin)/(mesh.nSlices - 1) xs = numpy.arange(mesh.nSlices)*dSlice+ mesh.sliceMin xs_mf = numpy.arange(min(aw), max(aw))*dSlice + mesh.sliceMin if(self.wavefront.params.wDomain=='time'): plt.plot(xs*1e15, int0) # time axis converted to fs. plt.plot(xs_mf*1e15, int0_mean, 'ro') plt.title('Power') plt.xlabel('time (fs)') plt.ylabel('Power (W)') dt = (mesh.sliceMax - mesh.sliceMin)/(mesh.nSlices - 1) print(('Pulse energy {:1.2g} J'.format(int0_mean.sum()*dt))) else: #frequency domain plt.plot(xs, int0) plt.plot(xs_mf, int0_mean, 'ro') plt.title('Spectral Energy') plt.xlabel('eV') plt.ylabel('J/eV') # Switch back to time domain. wpg.srwlib.srwl.SetRepresElecField(self.wavefront._srwl_wf, 't') self.intensity = self.wavefront.get_intensity()
def plotRadialProjection(pattern, parameters, logscale=True, offset=1.e-5, unit="q_nm^-1"): """ Perform integration over azimuthal angle and plot as function of radius. :param unit:can be "q_nm^-1", "q_A^-1", "2th_deg", "2th_rad", "r_mm". :type unit: str """ qs, intensities = azimuthalIntegration(pattern, parameters, unit=unit) if logscale: plt.semilogy(qs, intensities + offset) else: plt.plot(qs, intensities) if (unit == "q_nm^-1"): plt.xlabel("q (1/nm)") elif (unit == "q_A^-1"): plt.xlabel("q (1/A)") elif (unit == "2th_deg"): plt.xlabel("2theta (degrees)") elif (unit == "2th_rad"): plt.xlabel("2theta (radians)") elif (unit == "r_mm"): plt.xlabel("mm") plt.ylabel("Intensity (arb. units)") plt.tight_layout()
def photonStatistics(stack): """ """ number_of_images = stack.shape[0] photons = numpy.sum(stack, axis=(1, 2)) avg_photons = numpy.mean(photons) rms_photons = numpy.std(photons) print("*************************") print("avg = %6.5e" % (avg_photons)) print("std = %6.5e" % (rms_photons)) print("*************************") # Plot histogram. plt.figure() max_photon_number = int(numpy.max(photons)) min_photon_number = int(numpy.min(photons)) if max_photon_number == min_photon_number: max_photon_number += 1 binwidth = max_photon_number - min_photon_number number_of_bins = min(20, number_of_images) binwidth = int(binwidth / number_of_bins) plt.hist(photons, bins=range(min_photon_number, max_photon_number, binwidth), facecolor='red', alpha=0.75) plt.xlim([min_photon_number, max_photon_number]) plt.xlabel("Photons") plt.ylabel("Histogram") plt.title("Photon number histogram")
def plotImage(pattern, logscale=False, offset=1e-1): """ Workhorse function to plot an image :param logscale: Whether to show the data on logarithmic scale (z axis) (default False). :type logscale: bool :param offset: Offset to apply if logarithmic scaling is on. :type offset: float """ plt.figure() # Get limits. mn, mx = pattern.min(), pattern.max() x_range, y_range = pattern.shape if logscale: if mn <= 0.0: mn += pattern.min() + offset pattern = pattern.astype(float) + mn plt.imshow(pattern, norm=mpl.colors.LogNorm(vmin=mn, vmax=mx), cmap="viridis") else: plt.imshow(pattern, norm=Normalize(vmin=mn, vmax=mx), cmap='viridis') plt.xlabel(r'$x$ (pixel)') plt.ylabel(r'$y$ (pixel)') plt.xlim([0, x_range - 1]) plt.ylim([0, y_range - 1]) plt.tight_layout() plt.colorbar()
def plot_charge(self): """ Plot the average number of electrons per atom per atomic species as function of time. """ for d in self.__trajectory['charge'].T: plt.plot(d) ### TODO: time axis, labels, legend plt.xlabel('Time [fs]') plt.ylabel('Number of bound electrons per atom')
def plotImage(pattern, logscale=False, offset=1e-1, symlog=False, *argv, **kwargs): """ Workhorse function to plot an image :param logscale: Whether to show the data on logarithmic scale (z axis) (default False). :type logscale: bool :param offset: Offset to apply if logarithmic scaling is on. :type offset: float :param symlog: If logscale is True, to show the data on symlogarithmic scale (z axis) (default False). :type symlog: bool :return: the handles of figure and axis :rtype: figure,axis """ fig, ax = plt.subplots() # Get limits. mn, mx = pattern.min(), pattern.max() x_range, y_range = pattern.shape if logscale: if mn <= 0.0: mn = pattern.min() + offset mx = pattern.max() + offset pattern = pattern.astype(float) + offset # default plot setup kwargs['cmap'] = kwargs.pop('cmap', "viridis") if symlog: kwargs['norm'] = kwargs.pop( 'norm', mpl.colors.SymLogNorm(0.015, vmin=mn, vmax=mx)) else: kwargs['norm'] = kwargs.pop('norm', mpl.colors.LogNorm(vmin=mn, vmax=mx)) axes = kwargs.pop('axes', None) plt.imshow(pattern, *argv, **kwargs) else: kwargs['norm'] = kwargs.pop('norm', Normalize(vmin=mn, vmax=mx)) kwargs['cmap'] = kwargs.pop('cmap', "viridis") plt.imshow(pattern, *argv, **kwargs) plt.xlabel(r'$x$ (pixel)') plt.ylabel(r'$y$ (pixel)') plt.xlim([0, x_range - 1]) plt.ylim([0, y_range - 1]) plt.tight_layout() plt.colorbar() return fig, ax
def plot_displacement(self): """ Plot the average displacement per atomic species as function of time. """ #t = self.trajectory['time'] for d in self.__trajectory['displacement'].T: plt.plot( d ) # self.trajectory['disp'][ : , pylab.find( sel_Z == pylab.array( list(data['sample']['selZ'].keys()) ) ) ] , xcolor ) plt.xlabel('Time [fs]') plt.ylabel('Average displacement [$\AA$]')
def plotRadialProjection(pattern, parameters, logscale=True, offset=1.e-5): """ Perform integration over azimuthal angle and plot as function of radius. """ qs, intensities = azimuthalIntegration(pattern, parameters) if logscale: plt.semilogy(qs, intensities + offset) else: plt.plot(qs, intensities) plt.xlabel("q (1/nm)") plt.ylabel("Intensity (arb. units)") plt.tight_layout()
def plotImage(pattern, logscale=False, offset=None, symlog=False, *argv, **kwargs): """ Workhorse function to plot an image :param logscale: Whether to show the data on logarithmic scale (z axis) (default False). :type logscale: bool :param offset: Offset to apply to the pattern. :type offset: float :param symlog: To show the data on symlogarithmic scale (z axis) (default False). :type symlog: bool """ fig, ax = plt.subplots() # Get limits. mn, mx = pattern.min(), pattern.max() x_range, y_range = pattern.shape if offset: mn = pattern.min() + offset mx = pattern.max() + offset pattern = pattern.astype(float) + offset if (logscale and symlog): print('logscale and symlog are both true.\noverrided by logscale') # default plot setup if (logscale or symlog): kwargs['cmap'] = kwargs.pop('cmap', "viridis") if logscale: kwargs['norm'] = kwargs.pop('norm', mpl.colors.LogNorm()) elif symlog: kwargs['norm'] = kwargs.pop('norm', mpl.colors.SymLogNorm(0.015)) axes = kwargs.pop('axes', None) plt.imshow(pattern, *argv, **kwargs) else: kwargs['norm'] = kwargs.pop('norm', Normalize(vmin=mn, vmax=mx)) kwargs['cmap'] = kwargs.pop('cmap', "viridis") plt.imshow(pattern, *argv, **kwargs) plt.xlabel(r'$x$ (pixel)') plt.ylabel(r'$y$ (pixel)') plt.xlim([0, x_range - 1]) plt.ylim([0, y_range - 1]) plt.tight_layout() plt.colorbar()
def photonStatistics(stack): """ """ number_of_images = stack.shape[0] photons = numpy.sum(stack, axis=(1, 2)) avg_photons = numpy.mean(photons) rms_photons = numpy.std(photons) meanPerPattern = numpy.mean(stack, axis=(1, 2)) # average over the mean nphotons of each pattern in the stack avg_mean = numpy.mean(meanPerPattern) maxPerPattern = numpy.max(stack, axis=(1, 2)) # average over the max nphotons of each pattern in the stack avg_max = numpy.mean(maxPerPattern) minPerPattern = numpy.min(stack, axis=(1, 2)) # average over the min nphotons of each pattern in the stack avg_min = numpy.mean(minPerPattern) print("*************************") print("Photon number statistics per pattern") print("avg = %6.5e" % (avg_photons)) print("std = %6.5e" % (rms_photons)) print("Photon number statistics per pixel") print("avg_mean_pixel = %6.5e" % (avg_mean)) print("avg_max_pixel = %6.5e" % (avg_max)) print("avg_min_pixel = %6.5e" % (avg_min)) print("*************************") # Plot histogram. plt.figure() max_photon_number = int(numpy.max(photons)) min_photon_number = int(numpy.min(photons)) if max_photon_number == min_photon_number: max_photon_number += 1 binwidth = max_photon_number - min_photon_number number_of_bins = min(20, number_of_images) binwidth = int(binwidth / number_of_bins) plt.hist(photons, bins=range(min_photon_number, max_photon_number, binwidth), facecolor='red', alpha=0.75) plt.xlim([min_photon_number, max_photon_number]) plt.xlabel("Photons") plt.ylabel("Histogram") plt.title("Photon number histogram")
def plotOnAxisPowerDensity(self, spectrum=False): """ Method to plot the on-axis power density. :param spectrum: Whether to plot the power density in energy domain (True) or time domain (False, default). :type spectrum: bool """ """ Adapted from github:Samoylv/WPG/wpg/wpg_uti_wf.integral_intensity() """ print("\n Plotting on-axis power density.") # Setup new figure. plt.figure() # Switch to frequency (energy) domain if requested. if spectrum: wpg.srwlib.srwl.SetRepresElecField(self.wavefront._srwl_wf, 'f') self.intensity = self.wavefront.get_intensity() # Get dimensions. mesh = self.wavefront.params.Mesh dx = (mesh.xMax - mesh.xMin)/(mesh.nx - 1) dy = (mesh.yMax - mesh.yMin)/(mesh.ny - 1) # Get center pixel numbers. center_nx = int(mesh.nx/2) center_ny = int(mesh.ny/2) # Get time slices of intensity. intensity = self.intensity # Get on-axis intensity. int0_00 = intensity[center_ny, center_nx, :] int0 = intensity.sum(axis=(0,1))*(dx*dy*1.e6) # amplitude units sqrt(W/mm^2) int0max = int0.max() # Get meaningful slices. aw = [a[0] for a in numpy.argwhere(int0 > int0max*0.01)] if aw == []: raise RuntimeError("No significant intensities found.") dSlice = (mesh.sliceMax - mesh.sliceMin)/(mesh.nSlices - 1) xs = numpy.arange(mesh.nSlices)*dSlice+ mesh.sliceMin xs_mf = numpy.arange(min(aw), max(aw))*dSlice + mesh.sliceMin # Plot. if(self.wavefront.params.wDomain=='time'): plt.plot(xs*1e15,int0_00) plt.plot(xs_mf*1e15, int0_00[min(aw):max(aw)], 'ro') plt.title('On-Axis Power Density') plt.xlabel('time (fs)') plt.ylabel(r'Power density (W/mm${}^{2}$)') else: #frequency domain plt.plot(xs,int0_00) plt.plot(xs_mf, int0_00[min(aw):max(aw)], 'ro') plt.title('On-Axis Spectral Fluence') plt.xlabel('photon energy (eV)') plt.ylabel(r'fluence (J/eV/mm${}^{2}$)') # Switch back to time domain. wpg.srwlib.srwl.SetRepresElecField(self.wavefront._srwl_wf, 't') self.intensity = self.wavefront.get_intensity()