def _srw_electron_beam(x=0., y=0., z=0., xp=0., yp=0., e=6.04, Iavg=0.2, sigX=345e-6 * 1.e-20, sigY=23e-6 * 1.e-20, mixX=0.0, mixY=0.0, sigXp=4.e-9 * 1.e-20 / 345e-6, sigYp=4.e-11 * 1.e-20 / 23e-6, sigE=1.e-4): el_rest = 0.51099890221e-03 eBeam = sl.SRWLPartBeam() eBeam.Iavg = Iavg eBeam.partStatMom1.x = x eBeam.partStatMom1.y = y eBeam.partStatMom1.z = z eBeam.partStatMom1.xp = xp eBeam.partStatMom1.yp = yp eBeam.partStatMom1.gamma = e / el_rest eBeam.partStatMom1.relE0 = 1.0 eBeam.partStatMom1.nq = -1 eBeam.arStatMom2[ 0] = sigX**2 #from here it is not necessary for Single Electron calculation, obviously.... eBeam.arStatMom2[1] = mixX eBeam.arStatMom2[2] = sigXp**2 eBeam.arStatMom2[3] = sigY**2 eBeam.arStatMom2[4] = mixY eBeam.arStatMom2[5] = sigYp**2 eBeam.arStatMom2[10] = sigE**2 return eBeam
def srw_ebeam(ebeam_dict): import srwlib # ***********Electron Beam eBeam = srwlib.SRWLPartBeam() eBeam.Iavg = ebeam_dict["sr_cur"] # average current [A] eBeam.partStatMom1.x = 0.0 # initial transverse positions [m] eBeam.partStatMom1.y = 0.0 eBeam.partStatMom1.z = ( 0.0) # initial longitudinal positions (set in the middle of undulator) eBeam.partStatMom1.xp = 0 # initial relative transverse velocities eBeam.partStatMom1.yp = 0 eBeam.partStatMom1.gamma = (ebeam_dict["ebeam_energy"] / 0.51099890221e-03 ) # relative energy sigEperE = ebeam_dict["rms_energy_spread"] # relative RMS energy spread sigX = ebeam_dict["sh"] # horizontal RMS size of e-beam [m] sigXp = ebeam_dict["divh"] # horizontal RMS angular divergence [rad] sigY = ebeam_dict["sv"] # vertical RMS size of e-beam [m] sigYp = ebeam_dict["divv"] # vertical RMS angular divergence [rad] # 2nd order stat. moments: eBeam.arStatMom2[0] = sigX * sigX # <(x-<x>)^2> eBeam.arStatMom2[1] = 0 # <(x-<x>)(x'-<x'>)> eBeam.arStatMom2[2] = sigXp * sigXp # <(x'-<x'>)^2> eBeam.arStatMom2[3] = sigY * sigY # <(y-<y>)^2> eBeam.arStatMom2[4] = 0 # <(y-<y>)(y'-<y'>)> eBeam.arStatMom2[5] = sigYp * sigYp # <(y'-<y'>)^2> eBeam.arStatMom2[10] = sigEperE * sigEperE # <(E-<E>)^2>/<E>^2 return eBeam
def compute_wavefront_at_detector(self, coords, dipole_1_on=True, dipole_2_on=True): """ computes the wavefront on the detector's surface where the wavelength is given by 'self.detector_wavelength' """ # get magnetic field if dipole_1_on and dipole_2_on: magnetic_field = self.__magnetic_field_regular elif not dipole_1_on and dipole_2_on: magnetic_field = self.__magnetic_field_no_dipole_1 elif dipole_1_on and not dipole_2_on: magnetic_field = self.__magnetic_field_no_dipole_2 else: raise Exception('At least one dipole must be on to compute wavefront at detector') # ensure paricles won't be tracked past the detector if self.detector_z <= self.z_at_end: raise Exception('Particles tracked past detector, please decrease dipole 2 pad drift length or increase detector distance') # define initial beam beam = srwlib.SRWLPartBeam() beam.Iavg = self.average_current beam.partStatMom1 = srwlib.SRWLParticle(*self.transform_coordinates(coords, dipole_1_on)) # define wavefront wavefront = srwlib.SRWLWfr() wavefront.allocate(1, self.detector_points, self.detector_points) wavefront.mesh.eStart = 1239.8 / self.detector_wavelength wavefront.mesh.eFin = 1239.8 / self.detector_wavelength wavefront.mesh.xStart = -0.5 * self.detector_edge_length wavefront.mesh.xFin = 0.5 * self.detector_edge_length wavefront.mesh.yStart = -0.5 * self.detector_edge_length wavefront.mesh.yFin = 0.5 * self.detector_edge_length wavefront.mesh.zStart = self.detector_z wavefront.partBeam = beam # compute wavefront precision = [0, self.relative_precision, 0, self.z_at_end, self.trajectory_points, 1, -1] srwlib.srwl.CalcElecFieldSR(wavefront, 0, magnetic_field, precision) return wavefront
def calc2d_srw(self, photon_energy, photon_energy_step, scanning_data): Kv = scanning_data.get_additional_parameter("Kv") Kh = scanning_data.get_additional_parameter("Kh") period_id = scanning_data.get_additional_parameter("period_id") n_periods = scanning_data.get_additional_parameter("n_periods") B0v = Kv/period_id/(codata.e/(2*numpy.pi*codata.electron_mass*codata.c)) B0h = Kh/period_id/(codata.e/(2*numpy.pi*codata.electron_mass*codata.c)) eBeam = srwlib.SRWLPartBeam() eBeam.Iavg = scanning_data.get_additional_parameter("electron_current") eBeam.partStatMom1.gamma = scanning_data.get_additional_parameter("electron_energy") / (codata_mee * 1e-3) eBeam.partStatMom1.relE0 = 1.0 eBeam.partStatMom1.nq = -1 eBeam.partStatMom1.x = 0.0 eBeam.partStatMom1.y = 0.0 eBeam.partStatMom1.z = -0.5*period_id*n_periods + 4 eBeam.partStatMom1.xp = 0.0 eBeam.partStatMom1.yp = 0.0 eBeam.arStatMom2[ 0] = scanning_data.get_additional_parameter("electron_beam_size_h") ** 2 eBeam.arStatMom2[ 1] = 0.0 eBeam.arStatMom2[ 2] = scanning_data.get_additional_parameter("electron_beam_divergence_h") ** 2 eBeam.arStatMom2[ 3] = scanning_data.get_additional_parameter("electron_beam_size_v") ** 2 eBeam.arStatMom2[ 4] = 0.0 eBeam.arStatMom2[ 5] = scanning_data.get_additional_parameter("electron_beam_divergence_v") ** 2 eBeam.arStatMom2[10] = scanning_data.get_additional_parameter("electron_energy_spread") ** 2 gap_h = scanning_data.get_additional_parameter("gap_h") gap_v = scanning_data.get_additional_parameter("gap_v") mesh = srwlib.SRWLRadMesh(photon_energy, photon_energy, 1, -gap_h / 2, gap_h / 2, scanning_data.get_additional_parameter("h_slits_points"), -gap_v / 2, gap_v / 2, scanning_data.get_additional_parameter("v_slits_points"), scanning_data.get_additional_parameter("distance")) srw_magnetic_fields = [] if B0v > 0: srw_magnetic_fields.append(srwlib.SRWLMagFldH(1, "v", B0v)) if B0h > 0: srw_magnetic_fields.append(srwlib.SRWLMagFldH(1, "h", B0h)) magnetic_structure = srwlib.SRWLMagFldC([srwlib.SRWLMagFldU(srw_magnetic_fields, period_id, n_periods)], srwlib.array("d", [0]), srwlib.array("d", [0]), srwlib.array("d", [0])) wfr = srwlib.SRWLWfr() wfr.mesh = mesh wfr.partBeam = eBeam wfr.allocate(mesh.ne, mesh.nx, mesh.ny) srwlib.srwl.CalcElecFieldSR(wfr, 0, magnetic_structure, [1, 0.01, 0, 0, 50000, 1, 0]) mesh_out = wfr.mesh h_array=numpy.linspace(mesh_out.xStart, mesh_out.xFin, mesh_out.nx)*1e3 # in mm v_array=numpy.linspace(mesh_out.yStart, mesh_out.yFin, mesh_out.ny)*1e3 # in mm intensity_array = numpy.zeros((h_array.size, v_array.size)) arI0 = srwlib.array("f", [0]*mesh_out.nx*mesh_out.ny) #"flat" array to take 2D intensity data srwlib.srwl.CalcIntFromElecField(arI0, wfr, 6, 1, 3, photon_energy, 0, 0) data = numpy.ndarray(buffer=arI0, shape=(mesh_out.ny, mesh_out.nx),dtype=arI0.typecode) for ix in range(h_array.size): for iy in range(v_array.size): intensity_array[ix, iy] = data[iy,ix] return self.calculate_power(h_array, v_array, intensity_array, photon_energy_step)
def process_beam_parameters(ebeam): import srwlib import sirepo.sim_data sim_data = sirepo.sim_data.get_class('srw') def _convert_ebeam_units(field_name, value, to_si=True): """Convert values from the schema to SI units (m, rad) and back. Args: field_name: name of the field in _SCHEMA['model']['electronBeam']. value: value of the field. to_si: if set to True, convert to SI units, otherwise convert back to the units in the schema. Returns: value: converted value. """ def _invert_value(value): return value**-1 if to_si else value s = sim_data.schema() if field_name in s['model']['electronBeam'].keys(): label, field_type = s['model']['electronBeam'][field_name] if field_type == 'Float': if re.search(r'\[m(m|rad)\]', label): value *= _invert_value(1e3) elif re.search(r'\[\xb5(m|rad)\]', label): # mu value *= _invert_value(1e6) elif re.search(r'\[n(m|rad)\]', label): value *= _invert_value(1e9) return value # if the beamDefinition is "twiss", compute the moments fields and set on ebeam moments_fields = [ 'rmsSizeX', 'xxprX', 'rmsDivergX', 'rmsSizeY', 'xxprY', 'rmsDivergY' ] for k in moments_fields: if k not in ebeam: ebeam[k] = 0 if 'beamDefinition' not in ebeam: ebeam['beamDefinition'] = 't' if ebeam['beamDefinition'] == 't': # Twiss model = copy.deepcopy(ebeam) # Convert to SI units to perform SRW calculation: for k in model: model[k] = _convert_ebeam_units(k, ebeam[k]) beam = srwlib.SRWLPartBeam() beam.from_Twiss( _e=model['energy'], _sig_e=model['rmsSpread'], _emit_x=model['horizontalEmittance'], _beta_x=model['horizontalBeta'], _alpha_x=model['horizontalAlpha'], _eta_x=model['horizontalDispersion'], _eta_x_pr=model['horizontalDispersionDerivative'], _emit_y=model['verticalEmittance'], _beta_y=model['verticalBeta'], _alpha_y=model['verticalAlpha'], _eta_y=model['verticalDispersion'], _eta_y_pr=model['verticalDispersionDerivative'], ) # copy moments values into the ebeam for i, k in enumerate(moments_fields): v = beam.arStatMom2[i] if k in ['xxprX', 'xxprY' ] else beam.arStatMom2[i]**0.5 ebeam[k] = sim_data.srw_format_float( _convert_ebeam_units(k, v, to_si=False)) return ebeam