def show_diagnostics(FELsource_out_number): FELsource_out_file = FELsource_out_number if not os.path.exists(FELsource_out_file): print('Input file {} not found.'.format(FELsource_out_file)) return wf = Wavefront() wf.load_hdf5(FELsource_out_file) plot_t_wf(wf) look_at_q_space(wf) # show two figures window 1: image of I(x,y) integral intensity, with real # x and y axis and title with file name J2eV = 6.24150934e18; mesh = wf.params.Mesh tmin = mesh.sliceMin; tmax = mesh.sliceMax; dt = (tmax - tmin) / (mesh.nSlices - 1); dx = (mesh.xMax - mesh.xMin) / (mesh.nx - 1); dy = (mesh.yMax - mesh.yMin) / (mesh.ny - 1); wf_intensity = wf.get_intensity(polarization='horizontal'); total_intensity = wf_intensity.sum(axis=-1); data = total_intensity * dt plt.figure() plt.imshow(data*dx*dy*1e6*J2eV/wf.params.photonEnergy,extent=[mesh.xMin*1e6,mesh.xMax*1e6,mesh.yMin*1e6,mesh.yMax * 1e6], cmap="YlGnBu_r") title = 'Number of photons per %.2f x %.2f $\mu m ^2$ pixel' % (dx*1e6, dx*1e6) plt.title(title) plt.colorbar(); plt.xlabel('[$\mu m$]'); # window 2: plot of 2 curves: #(1) history/parent/temporal_struct - FAST post-processing temporal_struct = wf.custom_fields['history']['parent']['misc']['temporal_struct'] t0 = (temporal_struct[:, 0].max() + temporal_struct[:, 0].min()) / 2 plt.figure() plt.plot(temporal_struct[:, 0] - t0, temporal_struct[:, 1] * 1e-9, 'b',label = 'output FAST-pp') plt.hold(True) #(2) integral intensity I(t) calculated for wavefront written in h5 t = np.linspace(tmin, tmax, wf.params.Mesh.nSlices) pulse_energy = wf.get_intensity().sum(axis=0).sum(axis=0) #check it plt.plot(t * 1e15, pulse_energy*dx*dy*1e6*1e-9,'ro', label = 'wavefront data') title = 'FEL pulse energy %.2f %s ' % (pulse_energy.sum(axis=0) * dx * dy * 1e6 * dt * 1e3, 'mJ') plt.title(title) plt.xlabel('time [fs]'); plt.ylabel('Instantaneous power [GW]'); plt.legend() plt.grid(True) plt.show()
def testGaussianReference(self, debug=False): """ Check that propagation of a Gaussian pulse (in t,x,y) through vacuum reproduces reference data. """ # Central photon energy. ekev = 8.4 # Energy [keV] # Pulse parameters. qnC = 0.5 # e-bunch charge, [nC] pulse_duration = 9.0e-15 # [s] pulseEnergy = 1.5e-3 # total pulse energy, J # Coherence time coh_time = 0.25e-15 # [s] # Distance in free space. z0 = 10. # (m), position where to build the wavefront. z1 = 10. # (m), distance to travel in free space. # Beam divergence. theta_fwhm = 2.5e-6 # rad wlambda = 12.4*1e-10/ekev # wavelength, m w0 = wlambda/(numpy.pi*theta_fwhm) # beam waist, m zR = (math.pi*w0**2)/wlambda #Rayleigh range, m fwhm_at_zR = theta_fwhm*zR #FWHM at Rayleigh range, m sigmaAmp = w0/(2.0*math.sqrt(math.log(2.0))) #sigma of amplitude, m if debug: print (" *** Pulse properties ***") print (" lambda = %4.3e m" % (wlambda) ) print (" w0 = %4.3e m" % (w0) ) print (" zR = %4.3e m" % (zR) ) print (" fwhm at zR = %4.3e m" % (fwhm_at_zR) ) print (" sigma = %4.3e m" % (sigmaAmp) ) # expected beam radius after free space drift. expected_beam_radius = w0*math.sqrt(1.0+(z0/zR)**2) # Number of points in each x and y dimension. np=400 # Sampling window = 6 sigma of initial beam. range_xy = 6.*expected_beam_radius dx = range_xy / (np-1) nslices = 20 if debug: print (" Expected beam waist at z=%4.3f m : %4.3e m." % (z0, expected_beam_radius) ) print ("Setting up mesh of %d points per dimension on a %4.3e x %4.3e m^2 grid with grid spacing %4.3e m." % (np, range_xy, range_xy, dx) ) # Construct srw wavefront. srwl_wf = build_gauss_wavefront(np, np, nslices, ekev, -range_xy/2., range_xy/2., -range_xy/2., range_xy/2., coh_time/math.sqrt(2.), sigmaAmp, sigmaAmp, z0, pulseEn=pulseEnergy, pulseRange=8.) # Convert to wpg. wf = Wavefront(srwl_wf) if debug: print('*** z=%4.3e m ***' % (z0)) fwhm = calculate_fwhm(wf) print('fwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) look_at_q_space(wf) # Construct the beamline. beamline = Beamline() # Add free space drift. drift = Drift(z1) beamline.append( drift, Use_PP(semi_analytical_treatment=1)) # Propagate srwl.SetRepresElecField(wf._srwl_wf, 'f') # <---- switch to frequency domain beamline.propagate(wf) srwl.SetRepresElecField(wf._srwl_wf, 't') if debug: print('*** z=%4.3e m ***' % (z0+z1)) fwhm = calculate_fwhm(wf) print('fwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) look_at_q_space(wf) # Get propagated wavefront data. wf_intensity = wf.get_intensity() # Project on t axis. wf_onaxis = wf_intensity.sum(axis=(0,1)) # Get hash of the data. wf_hash = hash( wf_intensity.tostring() ) # Load reference hash. with open(TestUtilities.generateTestFilePath("reference_wf_gauss_10m.hash.txt"), 'r') as hashfile: ref_hash = hashfile.readline() hashfile.close() ref_onaxis = numpy.loadtxt(TestUtilities.generateTestFilePath("reference_wf_gauss_onaxis_10m.txt")) # Weak test. for x,y in zip(wf_onaxis, ref_onaxis): self.assertAlmostEqual( x, y, 14 ) # Strong test. self.assertEqual( str(wf_hash), ref_hash)
def testGaussianVsAnalytic(self, debug=False): """ Check that propagation of a Gaussian pulse (in t,x,y) through vacuum gives the correct result, compare to analytic solution. """ # Central photon energy. ekev = 8.4 # Energy [keV] # Pulse parameters. qnC = 0.5 # e-bunch charge, [nC] pulse_duration = 9.0e-15 # [s] pulseEnergy = 1.5e-3 # total pulse energy, J # Coherence time coh_time = 0.25e-15 # [s] # Distance in free space. z0 = 10. # (m), position where to build the wavefront. z1 = 20. # (m), distance to travel in free space. z2 = z0 + z1 # distance where to build the reference wavefront. # Beam divergence. theta_fwhm = 2.5e-6 # rad wlambda = 12.4*1e-10/ekev # wavelength, m w0 = wlambda/(numpy.pi*theta_fwhm) # beam waist, m zR = (math.pi*w0**2)/wlambda #Rayleigh range, m fwhm_at_zR = theta_fwhm*zR #FWHM at Rayleigh range, m sigmaAmp = w0/(2.0*math.sqrt(math.log(2.0))) #sigma of amplitude, m if debug: print (" *** Pulse properties ***") print (" lambda = %4.3e m" % (wlambda) ) print (" w0 = %4.3e m" % (w0) ) print (" zR = %4.3e m" % (zR) ) print (" fwhm at zR = %4.3e m" % (fwhm_at_zR) ) print (" sigma = %4.3e m" % (sigmaAmp) ) # expected beam radius after free space drift. expected_beam_radius = w0*math.sqrt(1.0+(z0/zR)**2) # Number of points in each x and y dimension. np=600 # Sampling window = 6 sigma of initial beam. range_xy = 6.*expected_beam_radius dx = range_xy / (np-1) nslices = 20 #if debug: #print (" Expected beam waist at z=%4.3f m : %4.3e m." % (z0, expected_beam_radius) ) #print ("Setting up mesh of %d points per dimension on a %4.3e x %4.3e m^2 grid with grid spacing %4.3e m." % (np, range_xy, range_xy, dx) ) # Construct srw wavefront. srwl_wf = build_gauss_wavefront(np, np, nslices, ekev, -range_xy/2., range_xy/2., -range_xy/2., range_xy/2., coh_time/math.sqrt(2.), sigmaAmp, sigmaAmp, z0, pulseEn=pulseEnergy, pulseRange=8.) # Convert to wpg. wf = Wavefront(srwl_wf) # Construct reference srw wavefront. reference_srwl_wf = build_gauss_wavefront(np, np, nslices, ekev, -1.5*range_xy/2., 1.5*range_xy/2., -1.5*range_xy/2., 1.5*range_xy/2., coh_time/math.sqrt(2.), sigmaAmp, sigmaAmp, z2, pulseEn=pulseEnergy, pulseRange=8.) reference_wf = Wavefront(reference_srwl_wf) if debug: print('*** z=%4.3e m ***' % (z0)) fwhm = calculate_fwhm(wf) print('wf:\nfwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) #look_at_q_space(wf) # Construct the beamline. beamline = Beamline() # Add free space drift. drift = Drift(z1) beamline.append( drift, Use_PP(semi_analytical_treatment=0, zoom=2.0, sampling=0.5)) # Propagate srwl.SetRepresElecField(wf._srwl_wf, 'f') beamline.propagate(wf) srwl.SetRepresElecField(wf._srwl_wf, 't') fwhm = calculate_fwhm(wf) reference_fwhm = calculate_fwhm(reference_wf) if debug: print('*** z=%4.3e m ***' % (z0+z1)) print('wf :\nfwhm_x = %4.3e\nfwhm_y = %4.3e' % (fwhm['fwhm_x'], fwhm['fwhm_y']) ) plot_t_wf(wf) print('ref:\nfwhm_x = %4.3e\nfwhm_y = %4.3e' % (reference_fwhm['fwhm_x'], reference_fwhm['fwhm_y']) ) plot_t_wf(reference_wf) #look_at_q_space(wf) # Calculate difference reference_norm = numpy.linalg.norm(numpy.array([reference_fwhm['fwhm_x'], reference_fwhm['fwhm_y']])) difference_norm = numpy.linalg.norm(numpy.array([fwhm['fwhm_x'], fwhm['fwhm_y']]) - numpy.array([reference_fwhm['fwhm_x'], reference_fwhm['fwhm_y']])) if debug: print ("|ref_fwhm_xy| = %4.3e" % (reference_norm) ) print ("|ref_fwhm_xy - fhwm_xy| = %4.3e" % (difference_norm) ) self.assertLess(difference_norm / reference_norm, 0.01)