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 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 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 shannonPixelPhoton(self, resolution): """ Get the average number of photons per shannon pixel :param resolution: The full periodic resolution (A) for shannon pixels :type resolution: float """ # Extract parameters. beam = self.parameters['beam'] geom = self.parameters['geom'] # Photon energy and wavelength E0 = beam['photonEnergy'] lmd = 1239.8 / E0 # Pixel dimension apix = geom['pixelWidth'] # Sample-detector distance Ddet = geom['detectorDist'] # Number of pixels in each dimension Npix = geom['mask'].shape[0] # Find center. center = 0.5 * (Npix - 1) # Max. scattering angle. theta_max = math.atan(center * apix / Ddet) # Min resolution. d_min = 0.5 * lmd / math.sin(theta_max / 2.0) # Next integer resolution. d0 = 0.1 * math.ceil(d_min * 10.0) # 10 powers to get Angstrom ds = resolution / 10 # nm # Pixel numbers corresponding to resolution rings. N = Ddet / apix * numpy.tan(numpy.arcsin(lmd / 2. / ds) * 2) pi = self.patterns_iterator stack = numpy.array([p for p in pi]) y, x = numpy.indices(stack[0].shape) r = numpy.sqrt((x - center)**2 + (y - center)**2) mask = (abs(r - N) <= 0.5) for i in range(len(stack)): stack[i] *= mask plt.figure() plt.imshow(stack[0]) plt.title('Frame 0') a = mask[mask == True] nShannonPixel = len(a) # Mean number of expected photons per Shannon pixel photons = numpy.sum(stack, axis=(1, 2)) / nShannonPixel avg_photons = numpy.mean(photons) rms_photons = numpy.std(photons) print("*************************") print("nShannonPixel = %i" % (nShannonPixel)) print("avg = %6.5e" % (avg_photons)) print("std = %6.5e" % (rms_photons)) print("*************************")
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()