Source code for simba.Modules.Fields.sdds

import numpy as np

from ..units import UnitValue
from ..constants import speed_of_light

from .FieldParameter import FieldParameter
from warnings import warn
from ..SDDSFile import SDDSFile, SDDS_Types


[docs] def write_SDDS_field_file(self, sddsindex: int = 0, ascii: bool = False) -> str: """ Generate the field data in a format that is suitable for SDDS, based on the :class:`~simba.Modules.Fields.field` object provided. This is then written to an SDDS file. The `field_type` parameter determines the format of the file. A warning is raised if the field type is not supported (perhaps elevate to a `NotImplementedError`? Parameters ---------- self: :class:`~simba.Modules.Fields.field` The field object sddsindex: int Must be provided for :class:`~simba.Modules.SDDSFile.SddsFile` class ascii: bool, optional Convert to ascii? Returns ------- str: The name of the SDDS field file. """ sdds_filename = self._output_filename(extension=".sdds") sddsfile = SDDSFile(index=sddsindex, ascii=ascii) zdata = self.z_values tdata = self.t_values if self.field_type == "LongitudinalWake": wzdata = self.Wz.value.val cnames = ["z", "t", "Wz"] cunits = ["m", "s", "V/C"] ccolumns = [ zdata, tdata, wzdata, ] elif self.field_type == "TransverseWake": wxdata = self.Wx.value.val wydata = self.Wy.value.val ccolumns = np.array( [ zdata, tdata, wxdata, wydata, ] ) cnames = ["z", "t", "Wx", "Wy"] cunits = ["m", "s", "V/C/m", "V/C/m"] elif self.field_type == "3DWake": wxdata = self.Wx.value.val wydata = self.Wy.value.val wzdata = self.Wz.value.val ccolumns = np.array( [ zdata, tdata, wxdata, wydata, wzdata, ] ) cnames = ["z", "t", "Wx", "Wy", "Wz"] cunits = ["m", "s", "V/C/m", "V/C/m", "V/C"] elif self.field_type == "1DElectroDynamic": ezdata = self.Ez.value.val cnames = ["z", "Ez"] cunits = ["m", "V"] ccolumns = [ zdata, ezdata, ] else: warn(f"Field type {self.field_type} not supported for SDDS") return if ccolumns is not None: ctypes = [SDDS_Types.SDDS_DOUBLE for _ in ccolumns] csymbols = ["" for _ in ccolumns] sddsfile.add_columns(cnames, ccolumns, ctypes, cunits, csymbols) sddsfile.write_file(sdds_filename) return sdds_filename
[docs] def read_SDDS_field_file(self, filename: str, field_type: str): """ Read an SDDS field file and convert it into a :class:`simba.Modules.Fields.field` object. Only works for wakefield files. Parameters ---------- self: :class:`~simba.Modules.Fields.field` The field object to be updated. filename: str The path to the SDDS field file field_type: str The name of the field, see :attr:`~simba.Modules.Fields.allowed_fields` Returns ------- None Raises ------ NotImplementedError: if a given `field_type` is not implemented """ self.reset_dicts() setattr(self, "field_type", field_type) try: elegantObject = SDDSFile(index=1, ascii=True) except Exception: elegantObject = SDDSFile(index=1, ascii=False) elegantObject.read_file(filename, page=-1) if field_type in ["LongitudinalWake", "3DWake", "TransverseWake"]: for key, val in elegantObject._columns.items(): data = np.array(val.data) if val.unit == "m": setattr( self, "z", FieldParameter(name="z", value=UnitValue(data, units=val.unit)), ) elif val.unit == "s": setattr( self, "t", FieldParameter( name="t", value=UnitValue(data, units="m") ), ) elif val.unit == "V/C": setattr( self, "Wz", FieldParameter(name="Wz", value=UnitValue(data, units="V/C")), ) elif val.unit == "V/C/m": setattr( self, "Wx", FieldParameter(name="Wx", value=UnitValue(data, units="V/C/m")), ) setattr( self, "Wy", FieldParameter(name="Wy", value=UnitValue(data, units="V/C/m")), ) else: raise ValueError(f"Unit {val.unit} not recognised in {filename}") else: raise NotImplementedError( f"{field_type} loading not implemented for SDDS files" )