Welcome to PyElegantSDDS’s documentation!

PyElegantSDDS

PyElegantSDDS is a Python wrapper around a Singularity container with SDDS and Parallel Elegant installed in it. It uses this container to build and run templates for common task in particle tracking for accelerators.

Features

  • SDDS commands

  • Elegant commands (twiss, track, FMA, DA, …)

  • Run simulations in just a few lines of Python code.

  • Generate Hyper-cubical and Hyper-Spherical distributions for tracking

  • Quick plotting using SDDS tools

Installation

Stable release

To install PyElegantSDDS, run this command in your terminal:

$ pip install pyelegantsdds

This is the preferred method to install PyElegantSDDS, as it will always install the most recent stable release.

If you don’t have pip installed, this Python installation guide can guide you through the process.

From sources

The sources for PyElegantSDDS can be downloaded from the Github repo.

You can either clone the public repository:

$ git clone git://github.com/tomerten/pyelegantsdds

Or download the tarball:

$ curl  -OL https://github.com/tomerten/pyelegantsdds/tarball/master

Once you have a copy of the source, you can install it with:

$ python setup.py install

API

Package pyelegantsdds

Top-level package for pyelegantsdds.

Module pyelegantsdds.tools

A module containing basic SDDS commands.

Module pyelegantsdds.elegant_command

A module containing the ElegantCommandFile class.

Development

History

v0.0.0 (2021-05-09)

This package was created with package et-micc,

Tutorial : SDDSCommand

This is a very short tutorial on the SDDSCommand class.

[1]:
from pyelegantsdds.sdds import SDDSCommand
[2]:
%load_ext autoreload
%autoreload 2
[3]:
# Path to Pelegant singularity container
sif = "PATH_TO_SIF_PELEGANT"
[4]:
sddscommand = SDDSCommand(sif)
sddscommand.command
[4]:
{}

The getCommand method returns the command string that can be executed and updates the command property.

[5]:
sddscommand.getCommand('sddsquery',columnList=None,file='temp.sdds')
[5]:
'/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds'
[6]:
sddscommand.command
[6]:
{'NAME': 'sddsquery', 'columnList': None, 'file': 'temp.sdds'}

The runCommand allows to execute the command.

[7]:
sddscommand.runCommand()
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds

The class contains a special method to generate the command to convert a data table in plain format to sdds format.

[8]:
sddscommand.get_particles_plain_2_SDDS_command()
[8]:
'/home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.txt -inputMode=ascii -outputMode=ascii "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount'

Tutorial : SDDS

This tutorial shows some basic functionality of the SDDS class.

[1]:
import pandas as pd
import numpy as np
import inspect

from pyelegantsdds.sdds import SDDS
[2]:
%load_ext autoreload
%autoreload 2
[3]:
# Path to Pelegant singularity container
sif = "PATH_TO_SIF_PELEGANT:"
[4]:
# filetype is either 0 for binary or 1 for ascii
sdds = SDDS(sif,'temp.sdds',0)

Overview - Properties

[5]:
sdds.__dict__
[5]:
{'sif': '/home/mti/gitlab-hzb/containers/bin/pelegant.sif',
 '_filetype': 0,
 '_filename': 'temp.sdds',
 'columnlist': None,
 'parameterlist': None,
 'commandlist': [],
 'command_history': {},
 '_count_iter': count(0)}

Overview - Methods

[6]:
from types import FunctionType
[x for x, y in SDDS.__dict__.items() if (type(y) == FunctionType) and not x.startswith('_')]
[6]:
['addCommand',
 'clearCommandList',
 'clearHistory',
 'runCommand',
 'printHistory',
 'reload_from_history',
 'rerun_from_history',
 'load_raw_data',
 'convert',
 'getColumnList',
 'getColumnValues',
 'getParameterList',
 'getParameterValues',
 'readParticleData',
 'process_scan',
 'sddsplot_tunediagram',
 'sddsplot_base',
 'sddsplot',
 'sddsplot_fma',
 'generate_scan_dataset']

Commands

Print the command history.

[7]:
sdds.printHistory()
History is empty.

Add a command.

[8]:
sdds.addCommand('sddsquery',columnList=None,file=sdds.filename)

Check if the command has been added.

[9]:
sdds.commandlist
[9]:
['/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds']

Note that this command has not been added to the history yet, this is to allow the removal of the current commandlist without clogging the history.

[10]:
sdds.printHistory()
History is empty.

Clear the command list. The option save allows to select if the current command list has to be written to the history.

[11]:
sdds.clearCommandList(save=True)
sdds.printHistory()
History key: 0

---------------

/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds



The command list has now been cleared.

[12]:
sdds.commandlist
[12]:
[]

One can reload commands from history.

[13]:
sdds.reload_from_history(history_idx=0)
[14]:
sdds.commandlist
[14]:
['/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds']

There is a related command that allows to directly rerun a command from history.

[15]:
sdds.rerun_from_history(history_idx=0)
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds

Running all the command in the current command list.

[16]:
sdds.runCommand()
No commands entered - nothing to do!

After running the command list is cleared and the command list has been written to the history.

[17]:
sdds.printHistory()
History key: 0

---------------

/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds



History key: 1

---------------

/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds



History key: 2

---------------

/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds



History key: 3

---------------

/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsquery -columnList temp.sdds



To load the raw content of the file into the class (raw_content) use:

[18]:
sdds.load_raw_data()
sdds.raw_content
[18]:
b'SDDS1\n!# little-endian\n&column name=Q1, type=double,  &end\n&column name=Q2, type=double,  &end\n&data mode=binary, &end\n\x02\x00\x00\x00V\x88\xbc\x83\x96j\xfc?\x86\xba\xd7\x14\x8eI\x02@\xa8@\xdb\x08\x82\xbc\xfc?\xae\x16g\xd7\x83r\x02@'

The command history can be cleared with:

[19]:
sdds.clearHistory()
[20]:
sdds.printHistory()
History is empty.

Template commands - files and data in files

Generic files

[21]:
sdds.convert(outfile=None)
Warning - auto filename set
Changed from temp.sdds to temp.sdds.txt
Warning - auto filetype set
Changed from 0 to 1

Notice that the filename and filetype have changed.

[22]:
sdds.filename, sdds.filetype
[22]:
('temp.sdds.txt', 1)

Get the column names available in the file (auto writes them to the columnlist property).

[23]:
sdds.getColumnList(), sdds.columnlist
[23]:
(['Q1', 'Q2'], ['Q1', 'Q2'])

Next one can get the column values. The method has a memory_threshold argument to deal with very large datasets. If the data is larger than the threshold the data is written to a file that can be loaded using dask in a lazy fashion and the filename is returned. If the dataset is small enough a pandas dataframe is returned.

[24]:
sdds.getColumnValues()
[24]:
Q1 Q2
0 1.776022 2.285916
1 1.796022 2.305916

Similar to column data one can get the parameter data.

[25]:
sdds = SDDS(sif,'temp.aper',0)
[26]:
sdds.getParameterList()
[26]:
['Step', 'SVNVersion', 'Area']
[27]:
sdds.getParameterValues()
[27]:
ParameterName
Step    1.00000
Area    0.00052
Name: ParameterValue, dtype: float64

Generating datasets

The class includes a method to create a dataset from a dictionary to allow for the generation of input data for using the vary_element command in combination with a table of manually created input data.

[28]:
datasetdc = {
    "Q1" : [1.786022448154-0.01,1.786022448154+0.01],
    "Q2" : [2.295915530046-0.01,2.295915530046+0.01],

}

sdds = SDDS(sif,'temp.sdds',0)
sdds.generate_scan_dataset(datasetdc)

Check if the data is in the file.

[29]:
sdds.getColumnValues()
[29]:
Q1 Q2
0 1.776022 2.285916
1 1.796022 2.305916

Explicit check of the dataset file.

[30]:
# convert to ascii to read easily using Python
sdds.convert()
Warning - auto filename set
Changed from temp.sdds to temp.sdds.txt
Warning - auto filetype set
Changed from 0 to 1
[31]:
with open(sdds.filename,'r') as f:
    dat = f.read()

print(dat)
SDDS1
&column name=Q1, type=double,  &end
&column name=Q2, type=double,  &end
&data mode=ascii, &end
! page number 1
                   2
 1.776022448154000e+00  2.285915530046000e+00
 1.796022448154000e+00  2.305915530046000e+00

Particle Tracking data

The readParticleData method allow to select the processing methods for datasets that are generated using the vary_element command and the datasets generated without it. The method uses also the process_scan method internally, but this last method can also be used manually for more flexible file manipulation.

[32]:
# wihtout vary_element
sdds = SDDS(sif,'temp-001.w1',0)
sdds.readParticleData()
Warning - auto filename set
Changed from temp-001.w1 to temp-001.w1.txt
Warning - auto filetype set
Changed from 0 to 1
[32]:
x xp y yp t p dt particleID Turn
0 1.000000e-05 0.000000e+00 0.0 0.0 0.000000e+00 3326.816862 0.000000e+00 1 1
1 8.955780e-07 -7.105001e-07 0.0 0.0 2.839631e-08 3326.816862 1.723844e-21 1 2
2 -9.839588e-06 -1.272616e-07 0.0 0.0 5.679263e-08 3326.816862 4.149138e-21 1 3
3 -2.658002e-06 6.877055e-07 0.0 0.0 8.518894e-08 3326.816862 5.201312e-21 1 4
4 9.363498e-06 2.504404e-07 0.0 0.0 1.135853e-07 3326.816862 8.218867e-21 1 5
... ... ... ... ... ... ... ... ... ...
95 -7.866553e-06 -4.404272e-07 0.0 0.0 2.697650e-06 3326.816862 1.825356e-19 1 96
96 -6.853626e-06 5.194750e-07 0.0 0.0 2.726046e-06 3326.816862 1.825356e-19 1 97
97 6.638962e-06 5.334732e-07 0.0 0.0 2.754442e-06 3326.816862 1.859237e-19 1 98
98 8.042768e-06 -4.239216e-07 0.0 0.0 2.782839e-06 3326.816862 1.863472e-19 1 99
99 -5.198377e-06 -6.094042e-07 0.0 0.0 2.811235e-06 3326.816862 1.901589e-19 1 100

100 rows × 9 columns

[33]:
# with vary_element
sdds = SDDS(sif,'temp-001.wq',0)
sdds.readParticleData(vary=True)
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsprocess -define=column,step,Step temp-001.wq temp-001_processed.wq
Warning - auto filename set
Changed from temp-001.wq to temp-001_processed.wq
Warning - auto filename set
Changed from temp-001_processed.wq to temp-001_processed.wq.txt
Warning - auto filetype set
Changed from 0 to 1
[33]:
x xp y yp t p dt particleID step Turn
0 0.000000 0.000000 0.000000 0.000000 0.000000 1722.116751 0.000000e+00 1 1.0 1
1 0.000000 0.000000 0.000000 0.000000 0.000050 1722.116751 5.000000e-05 2 1.0 1
2 0.000000 0.000000 0.000000 0.000000 0.000100 1722.116751 1.000000e-04 3 1.0 1
3 0.000000 0.000000 0.000000 0.000050 0.000000 1722.116751 0.000000e+00 4 1.0 1
4 0.000000 0.000000 0.000000 0.000050 0.000050 1722.116751 5.000000e-05 5 1.0 1
... ... ... ... ... ... ... ... ... ... ...
7771 -0.000213 -0.000033 0.000214 0.000047 0.000052 1722.116751 5.000000e-05 239 2.0 16
7772 -0.000213 -0.000033 0.000214 0.000047 0.000102 1722.116751 1.000000e-04 240 2.0 16
7773 -0.000214 -0.000033 0.000335 0.000095 0.000002 1722.116751 8.013319e-14 241 2.0 16
7774 -0.000214 -0.000033 0.000335 0.000095 0.000052 1722.116751 5.000000e-05 242 2.0 16
7775 -0.000214 -0.000033 0.000335 0.000095 0.000102 1722.116751 1.000000e-04 243 2.0 16

7776 rows × 10 columns

Plotting commands

For more details on the tracking simulations see the tutorial on tracking.

[34]:
from pyelegantsdds.elegantrun import ElegantRun

# set lattice for the rest of the tutorial
lattice = "FODO.lte"

# run single particle tracking
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)
er.simple_single_particle_track(n_passes=100, coord=np.array([1e-5,0,0,0,0]))
Shape: (1, 6) - Number of paritcles: 1
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount

The command below can be used to make a quick plot using the sddsplot_base command. If the device and output argument are not provided the output will be the standard sddsplot figure, otherwise the plot is saved to file and can be used further.

[35]:
# quick plot
sdds = SDDS(sif,"temp-001.w1",0)

sdds.sddsplot_base(
    columnNames="x,xp",
    graph="symb,vary=subtype,fill",
    device='png',
    output="FODO_single_particle.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.w1 -columnNames=x,xp -graph=symb,vary=subtype,fill -device=png -output=FODO_single_particle.png

title

More advanced sddsplot methods are available - for more details see the tracking tutorial.

Tutorial : ElegantCommand class

This tutorial shows basic usage of the ElegantCommand class, which is used by the ElegantRun class to construct the Elegant command file.

[2]:
from pyelegantsdds.elegant_command import ElegantCommandFile
[3]:
# filetype is either 0 for binary or 1 for ascii
ec = ElegantCommandFile('test.ele')

Properties

[4]:
ec.__dict__
[4]:
{'commandlist': [],
 'filename': 'test.ele',
 'history': {},
 '_count_iter': count(0)}

Methods

[5]:
from types import FunctionType
[x for x, y in ElegantCommandFile.__dict__.items() if (type(y) == FunctionType) and not x.startswith('_')]
[5]:
['checkCommand',
 'addCommand',
 'modifyCommand',
 'repeatCommand',
 'clearHistory',
 'clear',
 'remove_command',
 'write']

Examples

[6]:
ec.filename, ec.commandlist
[6]:
('test.ele', [])

Adding a command.

[7]:
ec.addCommand(
    "run_setup",
    lattice='FODO.lte',
    use_beamline='FODO',
    p_central_mev=1700.00,
    default_order= 1,
    concat_order= 3,
    rootname="temp",
    parameters="%s.params",
    semaphore_file="%s.done",
    magnets="%s.mag",  # for plotting profile
)

ec.commandlist
[7]:
[{'NAME': 'run_setup',
  'NOTE': '',
  'lattice': 'FODO.lte',
  'use_beamline': 'FODO',
  'p_central_mev': 1700.0,
  'default_order': 1,
  'concat_order': 3,
  'rootname': 'temp',
  'parameters': '%s.params',
  'semaphore_file': '%s.done',
  'magnets': '%s.mag'}]

The modifyCommand method allows to modify command in the command list. The mode argument allows to select which command to modify based on the command name (‘last’,’first’, index as int).

[8]:
ec.modifyCommand('run_setup', mode='last',lattice='partrack.lte')
[9]:
ec.commandlist
[9]:
[{'NAME': 'run_setup',
  'NOTE': '',
  'lattice': 'partrack.lte',
  'use_beamline': 'FODO',
  'p_central_mev': 1700.0,
  'default_order': 1,
  'concat_order': 3,
  'rootname': 'temp',
  'parameters': '%s.params',
  'semaphore_file': '%s.done',
  'magnets': '%s.mag'}]

Commands can be repeated.

[10]:
ec.repeatCommand('run_setup',mode='last')
[11]:
ec.commandlist
[11]:
[{'NAME': 'run_setup',
  'NOTE': '',
  'lattice': 'partrack.lte',
  'use_beamline': 'FODO',
  'p_central_mev': 1700.0,
  'default_order': 1,
  'concat_order': 3,
  'rootname': 'temp',
  'parameters': '%s.params',
  'semaphore_file': '%s.done',
  'magnets': '%s.mag'},
 {'NAME': 'run_setup',
  'NOTE': '',
  'lattice': 'partrack.lte',
  'use_beamline': 'FODO',
  'p_central_mev': 1700.0,
  'default_order': 1,
  'concat_order': 3,
  'rootname': 'temp',
  'parameters': '%s.params',
  'semaphore_file': '%s.done',
  'magnets': '%s.mag'}]

Or removed.

[12]:
ec.remove_command('run_setup',mode='last')
[13]:
ec.commandlist
[13]:
[{'NAME': 'run_setup',
  'NOTE': '',
  'lattice': 'partrack.lte',
  'use_beamline': 'FODO',
  'p_central_mev': 1700.0,
  'default_order': 1,
  'concat_order': 3,
  'rootname': 'temp',
  'parameters': '%s.params',
  'semaphore_file': '%s.done',
  'magnets': '%s.mag'}]

The write method is used to write the command file and update the history adn clear the command list.

[14]:
ec.write()
[15]:
with open(ec.filename,'r') as f:
    dat=f.read()

print(dat)
&run_setup
        lattice             = partrack.lte,
        use_beamline        = FODO,
        p_central_mev       = 1700.0,
        default_order       = 1,
        concat_order        = 3,
        rootname            = temp,
        parameters          = %s.params,
        semaphore_file      = %s.done,
        magnets             = %s.mag,
&end


[16]:
ec.history
[16]:
{0: [{'NAME': 'run_setup',
   'NOTE': '',
   'lattice': 'partrack.lte',
   'use_beamline': 'FODO',
   'p_central_mev': 1700.0,
   'default_order': 1,
   'concat_order': 3,
   'rootname': 'temp',
   'parameters': '%s.params',
   'semaphore_file': '%s.done',
   'magnets': '%s.mag'}],
 1: [{'NAME': 'run_setup',
   'NOTE': '',
   'lattice': 'partrack.lte',
   'use_beamline': 'FODO',
   'p_central_mev': 1700.0,
   'default_order': 1,
   'concat_order': 3,
   'rootname': 'temp',
   'parameters': '%s.params',
   'semaphore_file': '%s.done',
   'magnets': '%s.mag'}]}
[17]:
ec.commandlist
[17]:
[]

Tutorial : ElegantRun class - Basic

[1]:
import pandas as pd
import numpy as np

from pyelegantsdds.elegantrun import ElegantRun
from pyelegantsdds.sdds import SDDS

from matplotlib import pyplot as plt

%matplotlib notebook
[2]:
# path to singularity container with parallel elegant installed
sif = "PATH_TO_SIF_ELEGANT"

Generate FODO lattice to use in examples

[3]:
# lattice element definitions
elements ={
    "QF": {"type" : "KQUAD", "L": 0.342, "K1":  0.4900, "N_KICKS": 16},
    "QD": {"type" : "KQUAD", "L": 0.668, "K1": -0.4999, "N_KICKS": 16},
    "D":  {"type" : "DRIF" , "L": 3.5805},
    "W1": {"type" : "WATCH", "filename":"\"%s-%03ld.w1\"","mode": "coordinates"}
}

FODOstr = "! FODO cell.\n\n"
stringlist = ["{:6}: {}".format(k,", ".join(["{}={:15.12f}".format(kk,vv)
                if not isinstance(vv,str)
                else "{}={}".format(kk,vv)
                if kk!="type" else "{}".format(vv) for kk,vv in v.items()]))
              for k,v in elements.items()]

line     = ["W1","QF","D","QD","D","QF"]
linestr  = "{:6}: LINE=({})".format("FODO",",".join(line))
FODOstr += "\n".join(stringlist)
FODOstr += "\n\n"
FODOstr += linestr

print(FODOstr)

with open("FODO.lte","w") as f:
    f.write(FODOstr)

# set lattice for the rest of the tutorial
lattice = "FODO.lte"
! FODO cell.

QF    : KQUAD, L= 0.342000000000, K1= 0.490000000000, N_KICKS=16.000000000000
QD    : KQUAD, L= 0.668000000000, K1=-0.499900000000, N_KICKS=16.000000000000
D     : DRIF, L= 3.580500000000
W1    : WATCH, filename="%s-%03ld.w1", mode=coordinates

FODO  : LINE=(W1,QF,D,QD,D,QF)

ElegantRun

The ElegantRun class is used to setup, control and run the Elegant simulations.

[4]:
# load Elegant similator
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)

The kwargs argument is used to extract the settings for the simulations and building of the Elegant command file (temp.ele) - minimum required arguments are: * use_beamline * energy

Most command have default argument that can be changed by use of the kwargs, in this way simple simulations can be set up quickly and in just a few lines of python code. More complicated examples, using kwargs can be found in the advanced tutorials.

[5]:
er.kwargs
[5]:
{'use_beamline': 'FODO', 'energy': 1700.0}

The parallel argument allows to choose between running serial or parallel Elegant.

[6]:
er.parallel
[6]:
True

The latticefile used in the simulations is saved in the lattice property.

[7]:
er.lattice
[7]:
'FODO.lte'

Properties

[8]:
er.__dict__
[8]:
{'sif': '/home/mti/gitlab-hzb/containers/bin/pelegant.sif',
 'lattice': 'FODO.lte',
 'parallel': True,
 'kwargs': {'use_beamline': 'FODO', 'energy': 1700.0},
 'commandfile': <pyelegantsdds.elegant_command.ElegantCommandFile at 0x7f640117f9d0>,
 'pelegant': 'run_pelegant.sh',
 'exec': 'bash run_pelegant.sh'}

The class contains a property commandfile that is an instance of the ElegantCommandFile class (see the specific tutorial for more details on this class).

Methods

[9]:
from types import FunctionType
[x for x, y in ElegantRun.__dict__.items() if (type(y) == FunctionType) and not x.startswith('_')]
[9]:
['check',
 'clearCommands',
 'clearCommandHistory',
 'clearAll',
 'run',
 'add_basic_setup',
 'add_basic_twiss',
 'add_vary_element',
 'add_vary_element_from_file',
 'add_basic_controls',
 'add_watch',
 'add_watch_at_start',
 'add_fma_command',
 'add_DA_command',
 'findtwiss',
 'find_matrices',
 'generate_sdds_particle_inputfile',
 'simple_single_particle_track',
 'track_simple',
 'track_vary',
 'fma',
 'dynap',
 'dynapmom',
 'table_scan']

Commands - Basic

Most commands are designed to generate template command files that can be used by a single simulation command by providing a minimal of arguments through the kwargs argument.

[10]:
# should always be used first
er.add_basic_setup()
er.commandfile.commandlist, er.commandfile.history
[10]:
([{'NAME': 'run_setup',
   'NOTE': '',
   'lattice': 'FODO.lte',
   'use_beamline': 'FODO',
   'p_central_mev': 1700.0,
   'default_order': 1,
   'concat_order': 3,
   'rootname': 'temp',
   'parameters': '%s.params',
   'semaphore_file': '%s.done',
   'magnets': '%s.mag'}],
 {})

Let us add now some basic twiss.

[11]:
er.add_basic_twiss()
er.commandfile.commandlist, er.commandfile.history
[11]:
([{'NAME': 'run_setup',
   'NOTE': '',
   'lattice': 'FODO.lte',
   'use_beamline': 'FODO',
   'p_central_mev': 1700.0,
   'default_order': 1,
   'concat_order': 3,
   'rootname': 'temp',
   'parameters': '%s.params',
   'semaphore_file': '%s.done',
   'magnets': '%s.mag'},
  {'NAME': 'twiss_output',
   'NOTE': '',
   'filename': '%s.twi',
   'matched': 1,
   'radiation_integrals': 1}],
 {})

And a watchpoint at the start.

[12]:
er.add_watch_at_start()
er.commandfile.commandlist, er.commandfile.history
[12]:
([{'NAME': 'run_setup',
   'NOTE': '',
   'lattice': 'FODO.lte',
   'use_beamline': 'FODO',
   'p_central_mev': 1700.0,
   'default_order': 1,
   'concat_order': 3,
   'rootname': 'temp',
   'parameters': '%s.params',
   'semaphore_file': '%s.done',
   'magnets': '%s.mag'},
  {'NAME': 'twiss_output',
   'NOTE': '',
   'filename': '%s.twi',
   'matched': 1,
   'radiation_integrals': 1},
  {'NAME': 'insert_elements',
   'NOTE': '',
   'name': 'W',
   's_start': -1,
   's_end': -1,
   'skip': 1,
   'insert_before': 0,
   'add_at_end': 0,
   'add_at_start': 1,
   'element_def': '"W: WATCH, FILENAME=\\"%s-%03ld.wq\\", mode=\\"coordinates\\""'}],
 {})

And finish of by adding basic controls.

[13]:
er.add_basic_controls()
er.commandfile.commandlist ,er.commandfile.history
[13]:
([{'NAME': 'run_setup',
   'NOTE': '',
   'lattice': 'FODO.lte',
   'use_beamline': 'FODO',
   'p_central_mev': 1700.0,
   'default_order': 1,
   'concat_order': 3,
   'rootname': 'temp',
   'parameters': '%s.params',
   'semaphore_file': '%s.done',
   'magnets': '%s.mag'},
  {'NAME': 'twiss_output',
   'NOTE': '',
   'filename': '%s.twi',
   'matched': 1,
   'radiation_integrals': 1},
  {'NAME': 'insert_elements',
   'NOTE': '',
   'name': 'W',
   's_start': -1,
   's_end': -1,
   'skip': 1,
   'insert_before': 0,
   'add_at_end': 0,
   'add_at_start': 1,
   'element_def': '"W: WATCH, FILENAME=\\"%s-%03ld.wq\\", mode=\\"coordinates\\""'},
  {'NAME': 'run_control', 'NOTE': ''},
  {'NAME': 'bunched_beam', 'NOTE': ''},
  {'NAME': 'track', 'NOTE': ''}],
 {})
[14]:
# as example write to ele file and print
er.commandfile.write('basic.ele')

with open('basic.ele', 'r') as f:
    cmd = f.read()

print(cmd)
&run_setup
        lattice             = FODO.lte,
        use_beamline        = FODO,
        p_central_mev       = 1700.0,
        default_order       = 1,
        concat_order        = 3,
        rootname            = temp,
        parameters          = %s.params,
        semaphore_file      = %s.done,
        magnets             = %s.mag,
&end

&twiss_output
        filename            = %s.twi,
        matched             = 1,
        radiation_integrals = 1,
&end

&insert_elements
        name                = W,
        s_start             = -1,
        s_end               = -1,
        skip                = 1,
        insert_before       = 0,
        add_at_end          = 0,
        add_at_start        = 1,
        element_def         = "W: WATCH, FILENAME=\"%s-%03ld.wq\", mode=\"coordinates\"",
&end

&run_control
&end

&bunched_beam
&end

&track
&end


Clearing

[15]:
er.clearAll()
er.commandfile.commandlist ,er.commandfile.history
[15]:
([], {})

Below are a few more examples of basic commands that can be used as building blocks for generating composite templates.

[16]:
er.add_watch(type='KQUAD',insert_before=1,
             element_def = '"WQ: WATCH, FILENAME=\\"%s-%03ld.wq\\", mode=\\"coordinates\\""')
er.commandfile.commandlist
[16]:
[{'NAME': 'insert_elements',
  'NOTE': '',
  'type': 'KQUAD',
  's_start': -1,
  's_end': -1,
  'skip': 1,
  'insert_before': 1,
  'add_at_end': 0,
  'add_at_start': 0,
  'element_def': '"WQ: WATCH, FILENAME=\\"%s-%03ld.wq\\", mode=\\"coordinates\\""'}]
[17]:
er.clearAll()
er.add_vary_element_from_file(enumeration_file='scan.sdds')
er.commandfile.commandlist
[17]:
[{'NAME': 'vary_element',
  'NOTE': '',
  'name': '*',
  'item': 'L',
  'index_number': 0,
  'index_limit': 1,
  'enumeration_file': 'scan.sdds',
  'enumeration_column': None}]
[18]:
er.clearAll()

Templates - Basic

Twiss

[19]:
# load Elegant similator
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)

# twiss
twidata, twipar = er.findtwiss()

# for example
print("Nux       : {:12.6f}".format(twipar.nux))
print("Nuy       : {:12.6f}".format(twipar.nuy))
print("dNux / dp : {:12.6f}".format(twipar['dnux/dp']))
print("dNuy / dp : {:12.6f}".format(twipar['dnuy/dp']))
Nux       :     0.235726
Nuy       :     0.234332
dNux / dp :    -0.000000
dNuy / dp :    -0.000000
[20]:
# twiss data is returned as dataframe
twidata.head()
[20]:
s betax alphax psix etax etaxp xAperture betay alphay psiy ... pCentral0 ElementName ElementOccurence ElementType ChamberShape dI1 dI2 dI3 dI4 dI5
0 0.0000 14.018177 0.000000 0.000000 0.0 0.0 10.0 2.856023 9.761713e-17 0.000000 ... 3326.816296 _BEG_ 1 MARK NaN 0.0 0.0 0.0 0.0 0.0
1 0.0000 14.018177 0.000000 0.000000 0.0 0.0 10.0 2.856023 9.761713e-17 0.000000 ... 3326.816296 W1 1 WATCH ? 0.0 0.0 0.0 0.0 0.0
2 0.3420 13.238180 2.236957 0.024869 0.0 0.0 10.0 3.064602 -6.214851e-01 0.116974 ... 3326.816296 QF 1 KQUAD ? 0.0 0.0 0.0 0.0 0.0
3 3.9225 3.033641 0.613075 0.625301 0.0 0.0 10.0 13.314053 -2.241090e+00 0.712004 ... 3326.816296 D 1 DRIF ? 0.0 0.0 0.0 0.0 0.0
4 4.5905 3.033641 -0.613075 0.855812 0.0 0.0 10.0 13.314053 2.241090e+00 0.760351 ... 3326.816296 QD 1 KQUAD ? 0.0 0.0 0.0 0.0 0.0

5 rows × 23 columns

[21]:
from pprint import pprint
[22]:
print(twipar.to_dict())
{'Step': 0.0, 'nux': 0.2357264, 'dnux/dp': -0.0, 'dnux/dp2': 0.0, 'dnux/dp3': 0.0, 'Ax': 0.0, 'AxLocation': -1.797693e+308, 'nuy': 0.2343325, 'dnuy/dp': -0.0, 'dnuy/dp2': 0.0, 'dnuy/dp3': 0.0, 'Ay': 0.0, 'AyLocation': -1.797693e+308, 'deltaHalfRange': 0.0, 'nuxChromUpper': 0.2357264, 'nuxChromLower': 0.2357264, 'nuyChromUpper': 0.2343325, 'nuyChromLower': 0.2343325, 'pCentral': 3326.816, 'dbetax/dp': 0.0, 'dbetay/dp': 0.0, 'dalphax/dp': 0.0, 'dalphay/dp': 0.0, 'etax2': 0.0, 'etay2': 0.0, 'etax3': 0.0, 'etay3': 0.0, 'etaxp2': 0.0, 'etayp2': 0.0, 'etaxp3': 0.0, 'etayp3': 0.0, 'betaxMin': 3.033641, 'betaxAve': 8.176835, 'betaxMax': 14.01818, 'betayMin': 2.856023, 'betayAve': 8.171316, 'betayMax': 13.31405, 'etaxMax': 0.0, 'etayMax': 0.0, 'waistsx': 0.0, 'waistsy': 2.0, 'dnux/dAx': 0.0, 'dnux/dAy': 0.0, 'dnuy/dAx': 0.0, 'dnuy/dAy': 0.0, 'dnux/dAx2': 0.0, 'dnux/dAy2': 0.0, 'dnux/dAxAy': 0.0, 'dnuy/dAx2': 0.0, 'dnuy/dAy2': 0.0, 'dnuy/dAxAy': 0.0, 'nuxTswaLower': 0.0, 'nuxTswaUpper': 0.0, 'nuyTswaLower': 0.0, 'nuyTswaUpper': 0.0, 'couplingIntegral': 0.0, 'couplingDelta': 0.001393925, 'emittanceRatio': 0.0, 'alphac2': 0.0, 'alphac': 0.0, 'I1': 0.0, 'I2': 0.0, 'I3': 0.0, 'I4': 0.0, 'I5': 0.0, 'ex0': nan, 'enx0': nan, 'taux': nan, 'Jx': nan, 'tauy': inf, 'Jy': 1.0, 'Sdelta0': nan, 'taudelta': nan, 'Jdelta': nan, 'U0': 0.0, 'length': 8.513}

Find Matrices

[23]:
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)
tup = er.find_matrices(SDDS_output_order=3)
[24]:
print(tup[0])
[[0.   ]
 [0.   ]
 [0.   ]
 [0.   ]
 [8.513]
 [0.   ]]
[25]:
print(tup[1])
[[ 0.97148042  0.33874254  0.          0.          0.          0.        ]
 [-0.16598385  0.97148042  0.          0.          0.          0.        ]
 [ 0.          0.          1.0287933   0.34527618  0.          0.        ]
 [ 0.          0.          0.16918533  1.0287933   0.          0.        ]
 [ 0.          0.          0.          0.          1.          0.        ]
 [ 0.          0.          0.          0.          0.          1.        ]]
[26]:
tup[2].head()
[26]:
s ElementName ElementOccurence ElementType C1 C2 C3 C4 C5 C6 ... U6652 U6653 U6654 U6655 U6661 U6662 U6663 U6664 U6665 U6666
0 0.0000 _BEG_ 1 MARK 0.0 0.0 0.0 0.0 0.0000 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
1 0.0000 W1 1 WATCH 0.0 0.0 0.0 0.0 0.0000 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
2 0.3420 QF 1 KQUAD 0.0 0.0 0.0 0.0 0.3420 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
3 3.9225 D 1 DRIF 0.0 0.0 0.0 0.0 3.5805 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
4 4.5905 QD 1 KQUAD 0.0 0.0 0.0 0.0 0.6680 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0

5 rows × 508 columns

[27]:
print(tup[3])
{'T111': 0.0, 'T121': 0.0, 'T122': 0.0, 'T131': 0.0, 'T132': 0.0, 'T133': 0.0, 'T141': 0.0, 'T142': 0.0, 'T143': 0.0, 'T144': 0.0, 'T151': 0.0, 'T152': 0.0, 'T153': 0.0, 'T154': 0.0, 'T155': 0.0, 'T161': 0.0, 'T162': 0.0, 'T163': 0.0, 'T164': 0.0, 'T165': 0.0, 'T166': 0.0, 'T211': 0.0, 'T221': 0.0, 'T222': 0.0, 'T231': 0.0, 'T232': 0.0, 'T233': 0.0, 'T241': 0.0, 'T242': 0.0, 'T243': 0.0, 'T244': 0.0, 'T251': 0.0, 'T252': 0.0, 'T253': 0.0, 'T254': 0.0, 'T255': 0.0, 'T261': 0.0, 'T262': 0.0, 'T263': 0.0, 'T264': 0.0, 'T265': 0.0, 'T266': 0.0, 'T311': 0.0, 'T321': 0.0, 'T322': 0.0, 'T331': 0.0, 'T332': 0.0, 'T333': 0.0, 'T341': 0.0, 'T342': 0.0, 'T343': 0.0, 'T344': 0.0, 'T351': 0.0, 'T352': 0.0, 'T353': 0.0, 'T354': 0.0, 'T355': 0.0, 'T361': 0.0, 'T362': 0.0, 'T363': 0.0, 'T364': 0.0, 'T365': 0.0, 'T366': 0.0, 'T411': 0.0, 'T421': 0.0, 'T422': 0.0, 'T431': 0.0, 'T432': 0.0, 'T433': 0.0, 'T441': 0.0, 'T442': 0.0, 'T443': 0.0, 'T444': 0.0, 'T451': 0.0, 'T452': 0.0, 'T453': 0.0, 'T454': 0.0, 'T455': 0.0, 'T461': 0.0, 'T462': 0.0, 'T463': 0.0, 'T464': 0.0, 'T465': 0.0, 'T466': 0.0, 'T511': 0.0, 'T521': 0.0, 'T522': 0.0, 'T531': 0.0, 'T532': 0.0, 'T533': 0.0, 'T541': 0.0, 'T542': 0.0, 'T543': 0.0, 'T544': 0.0, 'T551': 0.0, 'T552': 0.0, 'T553': 0.0, 'T554': 0.0, 'T555': 0.0, 'T561': 0.0, 'T562': 0.0, 'T563': 0.0, 'T564': 0.0, 'T565': 0.0, 'T566': 0.0, 'T611': 0.0, 'T621': 0.0, 'T622': 0.0, 'T631': 0.0, 'T632': 0.0, 'T633': 0.0, 'T641': 0.0, 'T642': 0.0, 'T643': 0.0, 'T644': 0.0, 'T651': 0.0, 'T652': 0.0, 'T653': 0.0, 'T654': 0.0, 'T655': 0.0, 'T661': 0.0, 'T662': 0.0, 'T663': 0.0, 'T664': 0.0, 'T665': 0.0, 'T666': 0.0}
[28]:
print(tup[4])
{'Q1111': 0.0, 'Q1211': 0.0, 'Q1221': 0.0, 'Q1222': 0.0, 'Q1311': 0.0, 'Q1321': 0.0, 'Q1322': 0.0, 'Q1331': 0.0, 'Q1332': 0.0, 'Q1333': 0.0, 'Q1411': 0.0, 'Q1421': 0.0, 'Q1422': 0.0, 'Q1431': 0.0, 'Q1432': 0.0, 'Q1433': 0.0, 'Q1441': 0.0, 'Q1442': 0.0, 'Q1443': 0.0, 'Q1444': 0.0, 'Q1511': 0.0, 'Q1521': 0.0, 'Q1522': 0.0, 'Q1531': 0.0, 'Q1532': 0.0, 'Q1533': 0.0, 'Q1541': 0.0, 'Q1542': 0.0, 'Q1543': 0.0, 'Q1544': 0.0, 'Q1551': 0.0, 'Q1552': 0.0, 'Q1553': 0.0, 'Q1554': 0.0, 'Q1555': 0.0, 'Q1611': 0.0, 'Q1621': 0.0, 'Q1622': 0.0, 'Q1631': 0.0, 'Q1632': 0.0, 'Q1633': 0.0, 'Q1641': 0.0, 'Q1642': 0.0, 'Q1643': 0.0, 'Q1644': 0.0, 'Q1651': 0.0, 'Q1652': 0.0, 'Q1653': 0.0, 'Q1654': 0.0, 'Q1655': 0.0, 'Q1661': 0.0, 'Q1662': 0.0, 'Q1663': 0.0, 'Q1664': 0.0, 'Q1665': 0.0, 'Q1666': 0.0, 'Q2111': 0.0, 'Q2211': 0.0, 'Q2221': 0.0, 'Q2222': 0.0, 'Q2311': 0.0, 'Q2321': 0.0, 'Q2322': 0.0, 'Q2331': 0.0, 'Q2332': 0.0, 'Q2333': 0.0, 'Q2411': 0.0, 'Q2421': 0.0, 'Q2422': 0.0, 'Q2431': 0.0, 'Q2432': 0.0, 'Q2433': 0.0, 'Q2441': 0.0, 'Q2442': 0.0, 'Q2443': 0.0, 'Q2444': 0.0, 'Q2511': 0.0, 'Q2521': 0.0, 'Q2522': 0.0, 'Q2531': 0.0, 'Q2532': 0.0, 'Q2533': 0.0, 'Q2541': 0.0, 'Q2542': 0.0, 'Q2543': 0.0, 'Q2544': 0.0, 'Q2551': 0.0, 'Q2552': 0.0, 'Q2553': 0.0, 'Q2554': 0.0, 'Q2555': 0.0, 'Q2611': 0.0, 'Q2621': 0.0, 'Q2622': 0.0, 'Q2631': 0.0, 'Q2632': 0.0, 'Q2633': 0.0, 'Q2641': 0.0, 'Q2642': 0.0, 'Q2643': 0.0, 'Q2644': 0.0, 'Q2651': 0.0, 'Q2652': 0.0, 'Q2653': 0.0, 'Q2654': 0.0, 'Q2655': 0.0, 'Q2661': 0.0, 'Q2662': 0.0, 'Q2663': 0.0, 'Q2664': 0.0, 'Q2665': 0.0, 'Q2666': 0.0, 'Q3111': 0.0, 'Q3211': 0.0, 'Q3221': 0.0, 'Q3222': 0.0, 'Q3311': 0.0, 'Q3321': 0.0, 'Q3322': 0.0, 'Q3331': 0.0, 'Q3332': 0.0, 'Q3333': 0.0, 'Q3411': 0.0, 'Q3421': 0.0, 'Q3422': 0.0, 'Q3431': 0.0, 'Q3432': 0.0, 'Q3433': 0.0, 'Q3441': 0.0, 'Q3442': 0.0, 'Q3443': 0.0, 'Q3444': 0.0, 'Q3511': 0.0, 'Q3521': 0.0, 'Q3522': 0.0, 'Q3531': 0.0, 'Q3532': 0.0, 'Q3533': 0.0, 'Q3541': 0.0, 'Q3542': 0.0, 'Q3543': 0.0, 'Q3544': 0.0, 'Q3551': 0.0, 'Q3552': 0.0, 'Q3553': 0.0, 'Q3554': 0.0, 'Q3555': 0.0, 'Q3611': 0.0, 'Q3621': 0.0, 'Q3622': 0.0, 'Q3631': 0.0, 'Q3632': 0.0, 'Q3633': 0.0, 'Q3641': 0.0, 'Q3642': 0.0, 'Q3643': 0.0, 'Q3644': 0.0, 'Q3651': 0.0, 'Q3652': 0.0, 'Q3653': 0.0, 'Q3654': 0.0, 'Q3655': 0.0, 'Q3661': 0.0, 'Q3662': 0.0, 'Q3663': 0.0, 'Q3664': 0.0, 'Q3665': 0.0, 'Q3666': 0.0, 'Q4111': 0.0, 'Q4211': 0.0, 'Q4221': 0.0, 'Q4222': 0.0, 'Q4311': 0.0, 'Q4321': 0.0, 'Q4322': 0.0, 'Q4331': 0.0, 'Q4332': 0.0, 'Q4333': 0.0, 'Q4411': 0.0, 'Q4421': 0.0, 'Q4422': 0.0, 'Q4431': 0.0, 'Q4432': 0.0, 'Q4433': 0.0, 'Q4441': 0.0, 'Q4442': 0.0, 'Q4443': 0.0, 'Q4444': 0.0, 'Q4511': 0.0, 'Q4521': 0.0, 'Q4522': 0.0, 'Q4531': 0.0, 'Q4532': 0.0, 'Q4533': 0.0, 'Q4541': 0.0, 'Q4542': 0.0, 'Q4543': 0.0, 'Q4544': 0.0, 'Q4551': 0.0, 'Q4552': 0.0, 'Q4553': 0.0, 'Q4554': 0.0, 'Q4555': 0.0, 'Q4611': 0.0, 'Q4621': 0.0, 'Q4622': 0.0, 'Q4631': 0.0, 'Q4632': 0.0, 'Q4633': 0.0, 'Q4641': 0.0, 'Q4642': 0.0, 'Q4643': 0.0, 'Q4644': 0.0, 'Q4651': 0.0, 'Q4652': 0.0, 'Q4653': 0.0, 'Q4654': 0.0, 'Q4655': 0.0, 'Q4661': 0.0, 'Q4662': 0.0, 'Q4663': 0.0, 'Q4664': 0.0, 'Q4665': 0.0, 'Q4666': 0.0, 'Q5111': 0.0, 'Q5211': 0.0, 'Q5221': 0.0, 'Q5222': 0.0, 'Q5311': 0.0, 'Q5321': 0.0, 'Q5322': 0.0, 'Q5331': 0.0, 'Q5332': 0.0, 'Q5333': 0.0, 'Q5411': 0.0, 'Q5421': 0.0, 'Q5422': 0.0, 'Q5431': 0.0, 'Q5432': 0.0, 'Q5433': 0.0, 'Q5441': 0.0, 'Q5442': 0.0, 'Q5443': 0.0, 'Q5444': 0.0, 'Q5511': 0.0, 'Q5521': 0.0, 'Q5522': 0.0, 'Q5531': 0.0, 'Q5532': 0.0, 'Q5533': 0.0, 'Q5541': 0.0, 'Q5542': 0.0, 'Q5543': 0.0, 'Q5544': 0.0, 'Q5551': 0.0, 'Q5552': 0.0, 'Q5553': 0.0, 'Q5554': 0.0, 'Q5555': 0.0, 'Q5611': 0.0, 'Q5621': 0.0, 'Q5622': 0.0, 'Q5631': 0.0, 'Q5632': 0.0, 'Q5633': 0.0, 'Q5641': 0.0, 'Q5642': 0.0, 'Q5643': 0.0, 'Q5644': 0.0, 'Q5651': 0.0, 'Q5652': 0.0, 'Q5653': 0.0, 'Q5654': 0.0, 'Q5655': 0.0, 'Q5661': 0.0, 'Q5662': 0.0, 'Q5663': 0.0, 'Q5664': 0.0, 'Q5665': 0.0, 'Q5666': 0.0, 'Q6111': 0.0, 'Q6211': 0.0, 'Q6221': 0.0, 'Q6222': 0.0, 'Q6311': 0.0, 'Q6321': 0.0, 'Q6322': 0.0, 'Q6331': 0.0, 'Q6332': 0.0, 'Q6333': 0.0, 'Q6411': 0.0, 'Q6421': 0.0, 'Q6422': 0.0, 'Q6431': 0.0, 'Q6432': 0.0, 'Q6433': 0.0, 'Q6441': 0.0, 'Q6442': 0.0, 'Q6443': 0.0, 'Q6444': 0.0, 'Q6511': 0.0, 'Q6521': 0.0, 'Q6522': 0.0, 'Q6531': 0.0, 'Q6532': 0.0, 'Q6533': 0.0, 'Q6541': 0.0, 'Q6542': 0.0, 'Q6543': 0.0, 'Q6544': 0.0, 'Q6551': 0.0, 'Q6552': 0.0, 'Q6553': 0.0, 'Q6554': 0.0, 'Q6555': 0.0, 'Q6611': 0.0, 'Q6621': 0.0, 'Q6622': 0.0, 'Q6631': 0.0, 'Q6632': 0.0, 'Q6633': 0.0, 'Q6641': 0.0, 'Q6642': 0.0, 'Q6643': 0.0, 'Q6644': 0.0, 'Q6651': 0.0, 'Q6652': 0.0, 'Q6653': 0.0, 'Q6654': 0.0, 'Q6655': 0.0, 'Q6661': 0.0, 'Q6662': 0.0, 'Q6663': 0.0, 'Q6664': 0.0, 'Q6665': 0.0, 'Q6666': 0.0}

Generate initial coordinates

Hypercube

[29]:
# generate rectangular coordinate input file - auto
# if pcentralmev is not given the energy value in er.kwargs will be used
er.generate_sdds_particle_inputfile(grid_type='rectangular', p_min=1e-6, p_max=1e-2,
                                    pcentralmev=er.kwargs.get('energy'),
                                    NPOINTS=7
                                   )
Shape: (16807, 6) - Number of paritcles: 16807
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[30]:
# read the data using SDDS class - see specific tutorial for more details
sddsp = SDDS(sif,"temp_particles_input.bin",0)
df = sddsp.readParticleData()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(df.x,df.xp,df.y,s=1)

# labels
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$p_x$')
ax.set_zlabel(r'$y$')

# padding
ax.xaxis.labelpad=15
ax.yaxis.labelpad=15
ax.zaxis.labelpad=15

plt.tight_layout()
plt.show()
Warning - auto filename set
Changed from temp_particles_input.bin to temp_particles_input.bin.txt
Warning - auto filetype set
Changed from 0 to 1

Hyperspheres

[31]:
# generate rectangular coordinate input file - auto
# if pcentralmev is not given the energy value in er.kwargs will be used
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)
er.generate_sdds_particle_inputfile(grid_type='spherical',
                                    dim=6,
                                    rmin=1e-6,
                                    rmax=1e-4,
                                    rsteps=5,
                                    phisteps=10,
                                    half=True, # False gives full spheres
                                    pcentralmev=er.kwargs.get('energy'),
                                   )

sddsp = SDDS(sif,"temp_particles_input.bin",0)
df = sddsp.readParticleData()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.xaxis.labelpad=15
ax.yaxis.labelpad=15
ax.zaxis.labelpad=15

ax.scatter(df.x,df.xp,df.y,s=1)
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$p_x$')
ax.set_zlabel(r'$y$')
plt.tight_layout()
plt.show()
Shape: (5000, 6) - Number of paritcles: 5000
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
Warning - auto filename set
Changed from temp_particles_input.bin to temp_particles_input.bin.txt
Warning - auto filetype set
Changed from 0 to 1
[32]:
# generate rectangular coordinate input file - auto
# if pcentralmev is not given the energy value in er.kwargs will be used
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)
er.generate_sdds_particle_inputfile(grid_type='spherical',
                                    dim=6,
                                    rmin=1e-6,
                                    rmax=1e-4,
                                    rsteps=5,
                                    phisteps=10,
                                    half=False, # False gives full spheres
                                    pcentralmev=er.kwargs.get('energy'),
                                   )

sddsp = SDDS(sif,"temp_particles_input.bin",0)
df = sddsp.readParticleData()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.xaxis.labelpad=15
ax.yaxis.labelpad=15
ax.zaxis.labelpad=15

ax.scatter(df.x,df.xp,df.y,s=1)
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$p_x$')
ax.set_zlabel(r'$y$')
plt.tight_layout()
plt.show()
Shape: (5000, 6) - Number of paritcles: 5000
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
Warning - auto filename set
Changed from temp_particles_input.bin to temp_particles_input.bin.txt
Warning - auto filetype set
Changed from 0 to 1

Tutorial : ElegantRun - Tracking

[1]:
import pandas as pd
import numpy as np

from pyelegantsdds.elegantrun import ElegantRun
from pyelegantsdds.sdds import SDDS

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
%matplotlib notebook

from IPython.display import Image
[2]:
# path to singularity container with parallel elegant installed
sif = "PATH_TO_SIF"

Lattices used in the tutorial

FODO

[3]:
### lattice element definitions
elements ={
    "QF": {"type" : "KQUAD", "L": 0.342, "K1":  0.4900, "N_KICKS": 16},
    "QD": {"type" : "KQUAD", "L": 0.668, "K1": -0.4999, "N_KICKS": 16},
    "D":  {"type" : "DRIF" , "L": 3.5805},
    "W1": {"type" : "WATCH", "filename":"\"%s-%03ld.w1\"","mode": "coordinates"}
}

FODOstr    = "! FODO cell.\n\n"
stringlist = ["{:6}: {}".format(k,", ".join([
    "{}={:15.12f}".format(kk,vv)
    if not isinstance(vv,str)
    else "{}={}".format(kk,vv)
    if kk!="type"
    else "{}".format(vv)
    for kk,vv in v.items()]))
              for k,v in elements.items()]

line     = ["W1","QF","D","QD","D","QF"]
linestr  = "{:6}: LINE=({})".format("FODO",",".join(line))

FODOstr += "\n".join(stringlist)
FODOstr += "\n\n"
FODOstr += linestr

print(FODOstr)

with open("FODO.lte","w") as f:
    f.write(FODOstr)
! FODO cell.

QF    : KQUAD, L= 0.342000000000, K1= 0.490000000000, N_KICKS=16.000000000000
QD    : KQUAD, L= 0.668000000000, K1=-0.499900000000, N_KICKS=16.000000000000
D     : DRIF, L= 3.580500000000
W1    : WATCH, filename="%s-%03ld.w1", mode=coordinates

FODO  : LINE=(W1,QF,D,QD,D,QF)

parTrack from Elegant examples

[4]:
# Lattice parTrack from Elegant examples
latstr = """
l1a: DRIF, L=0.2
l1b: DRIF, L=1.531675
lqb: DRIF, L=0.24
l2:  DRIF, L=0.08
l3:  DRIF, L=1.47
l3a: DRIF, L=0.568095770758662
l3b: DRIF, L=0.551904229241338

! LHK is half the effective length of a kicker
lhk:  DRIF, L=0.175
l34a: DRIF, L=0.811087
l34b: DRIF, L=0.308913

l4: DRIF, L=0.08
l5: DRIF, L=0.325

b1: CSBEND, L=0.8, angle=-0.785398163397, e1=-0.445, e2=-0.445, k2=0.1375, k3=100, hgap=0.0225, fint=0.41, integration_order=4, n_kicks=20, nonlinear=1
b2: CSBEND, L=0.8, angle=-0.785398163397, e1=-0.445, e2=-0.445, k2=0.1375, k3=100, hgap=0.0225, fint=0.41, integration_order=4, n_kicks=20, nonlinear=1

q1: KQUAD, L=0.23, k1=1.786022448154, n_kicks=10
q2: KQUAD, L=0.23, k1=2.295915530046, n_kicks=10
q3: KQUAD, l=0.23, k1=0.0
q4: KQUAD, l=0.23, k1=2.270174600496, n_kicks=10

s1h: SEXT, l=0.1, k2=0.0

! vertical chromaticity sextupole plus vertical steering magnet
sdh: KSEXT, l=0.1, k2=5.95873739969822, n_kicks=4

! horizontal chromaticity sextupole plus horizontal steering magnet
sfh: ksextupole, l=0.1, k2=-1.65546424863732, n_kicks=4

s1: line=(s1h,s1h)
sd: line=(sdh,sdh)
sf: line=(sfh,sfh)

! markers for the septum center and the center of the RF straight
msept: marker
mrf:   marker

! quadrant 1, less half of SF
quadr1: line=(l1a,l1b,s1,l2,q1,lqb,b1,lqb,q2,l3a,lhk,lhk,l3b,sd,l4,q3,lqb,b2,lqb,q4,l5)

! quadrant 2, less half of SF
quadr2: line=(l1a,l1b,s1,l2,q1,lqb,b1,lqb,q2,l3a,lhk,lhk,l3b,sd,l4,q3,lqb,b2,lqb,q4,l5)

! quadrant 3, less half of SF
quadr3: line=(l1a,l1b,s1,l2,q1,lqb,b1,lqb,q2,l3,sd,l4,q3,lqb,b2,lqb,q4,l5)

! quadrant 4, less half of SF
quadr4: line=(l1a,l1b,s1,l2,q1,lqb,b1,lqb,q2,l34a,lhk,lhk,l34b,sd,l4,q3,lqb,b2,lqb,q4,l5)

half: line=(quadr2,sf,-quadr2)

ap: rcol,x_max=0.04,y_max=0.01
par: line=(2*half,ap)
return

""".upper()

with open('parTrack.lte','w') as f:
    f.write(latstr)

Tracking

Single particle tracking simple

[5]:
# set lattice for the rest of the tutorial
lattice = "FODO.lte"

# create instance of the class
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)

# run tracking of single particle with given init coord.
er.simple_single_particle_track(n_passes=2**8, coord=np.array([1e-5,0,0,0,0]))
1700.0
Shape: (1, 6) - Number of paritcles: 1
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[6]:
# quick plot
sddsp = SDDS(sif,"temp-001.w1",0)

sddsp.sddsplot_base(
    columnNames="x,xp",
    graph="symb,type=1,fill",
    device='png',
    output="FODO_single_particle.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.w1 -columnNames=x,xp -graph=symb,type=1,fill -device=png -output=FODO_single_particle.png
[7]:
Image(filename='FODO_single_particle.png')
[7]:
_images/notebook_Tutorial_ElegantRun_12_0.png

Multi-particle Tracking

Before tracking we need to decide on which initial distribution to track. The package offers several possibilities to generate initial distributions.

Hypercube
[8]:
# generate rectangular coordinate input file - auto
# if pcentralmev is not given the energy value in er.kwargs will be used
er.generate_sdds_particle_inputfile(grid_type='rectangular', p_min=1e-6, p_max=1e-2,
                                    pcentralmev=er.kwargs.get('energy'),
                                    NPOINTS=7
                                   )
1700.0
Shape: (16807, 6) - Number of paritcles: 16807
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount

Let us have a look at a 3D cut of the initial distribution.

[9]:
sddsp = SDDS(sif,"temp_particles_input.bin",0)
df    = sddsp.readParticleData()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(df.x,df.xp,df.y,s=1)

# labels
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$p_x$')
ax.set_zlabel(r'$y$')

# padding
ax.xaxis.labelpad=15
ax.yaxis.labelpad=15
ax.zaxis.labelpad=15

plt.tight_layout()
plt.show()
Warning - auto filename set
Changed from temp_particles_input.bin to temp_particles_input.bin.txt
Warning - auto filetype set
Changed from 0 to 1
[10]:
# track
er.track_simple(n_passes=2**6)
[11]:
# quick plot
sddsp = SDDS(sif,"temp-001.w1",0)

sddsp.sddsplot_base(
    columnNames="x,xp",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device='png',
    output="FODO_multi_particle_rectangular.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.w1 -columnNames=x,xp -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=FODO_multi_particle_rectangular.png
[12]:
Image(filename="FODO_multi_particle_rectangular.png")
[12]:
_images/notebook_Tutorial_ElegantRun_21_0.png
Higher dim ball
[13]:
# generate rectangular coordinate input file - auto
# if pcentralmev is not given the energy value in er.kwargs will be used
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)
er.generate_sdds_particle_inputfile(grid_type='spherical',
                                    dim=6,
                                    rmin=1e-6,
                                    rmax=1e-4,
                                    rsteps=5,
                                    phisteps=10,
                                    half=False, # True gives full first quadrant
                                    pcentralmev=er.kwargs.get('energy'),
                                   )
1700.0
Shape: (5000, 6) - Number of paritcles: 5000
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[14]:
sddsp = SDDS(sif,"temp_particles_input.bin",0)
df = sddsp.readParticleData()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.xaxis.labelpad=15
ax.yaxis.labelpad=15
ax.zaxis.labelpad=15

ax.scatter(df.x,df.xp,df.y,s=1)
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$p_x$')
ax.set_zlabel(r'$y$')
plt.tight_layout()
plt.show()
Warning - auto filename set
Changed from temp_particles_input.bin to temp_particles_input.bin.txt
Warning - auto filetype set
Changed from 0 to 1
[15]:
# generate rectangular coordinate input file - auto
# if pcentralmev is not given the energy value in er.kwargs will be used
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)
er.generate_sdds_particle_inputfile(grid_type='spherical',
                                    dim=6,
                                    rmin=1e-6,
                                    rmax=1e-4,
                                    rsteps=5,
                                    phisteps=10,
                                    half=True, # False gives full spheres
                                    pcentralmev=er.kwargs.get('energy'),
                                   )
1700.0
Shape: (5000, 6) - Number of paritcles: 5000
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[16]:
sddsp = SDDS(sif,"temp_particles_input.bin",0)
df = sddsp.readParticleData()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.xaxis.labelpad=15
ax.yaxis.labelpad=15
ax.zaxis.labelpad=15

ax.scatter(df.x,df.xp,df.y,s=1)
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$p_x$')
ax.set_zlabel(r'$y$')
plt.tight_layout()
plt.show()
Warning - auto filename set
Changed from temp_particles_input.bin to temp_particles_input.bin.txt
Warning - auto filetype set
Changed from 0 to 1
[17]:
# track
er.track_simple(n_passes=2)
[18]:
sddsp = SDDS(sif,"temp-001.w1",0)
df = sddsp.readParticleData()

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(df.loc[df.Turn==1].x,df.loc[df.Turn==1].xp,df.loc[df.Turn==1].y,s=1)
ax.scatter(df.loc[df.Turn==2].x,df.loc[df.Turn==2].xp,df.loc[df.Turn==2].y,s=1,c='red')

ax.xaxis.labelpad=15
ax.yaxis.labelpad=15
ax.zaxis.labelpad=15

ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$p_x$')
ax.set_zlabel(r'$y$')

plt.title('Sphere (half) after 1 turn')
plt.show()
Warning - auto filename set
Changed from temp-001.w1 to temp-001.w1.txt
Warning - auto filetype set
Changed from 0 to 1
Manual distribution
[19]:
# load elegant similator
er = ElegantRun(sif,lattice, parallel=True, use_beamline="FODO", energy=1700.00)

# twiss
twidata, twipar = er.findtwiss()
twipar.nux, twipar.nuy, twipar['dnux/dp'], twipar['dnuy/dp']
[19]:
(0.2357264, 0.2343325, -0.2898536, -0.2892501)
[20]:
# off - momentum
delta = 1.5e-3 * twipar.pCentral

# initial coordinate grid for tracking
man_ranges= {
    0 : np.array([0,1e-6,1e-5,1e-4,1e-3,1e-2,1e-1,1,1.1,1.2,1.3,1.4,1.5,1.6,1.7,1.8,1.9,1.95,1.975,1.9875,2,2.1,2.2,2.3]),
    1 : [0.05],
    2 : 0,
    3 : 0,
    4 : 0,
    5 : twipar.pCentral + delta
}

# generate coordinate input file
er.generate_sdds_particle_inputfile(man_ranges=man_ranges)

# track
er.track_simple(n_passes=400)
1700.0
Shape: (24, 6) - Number of paritcles: 24
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[21]:
# quick plot
sddsp = SDDS(sif,"temp-001.w1",0)

# uncomment to save to file
sddsp.sddsplot_base(
    columnNames="x,xp",
#     file="temp-001.w1",
    scale="-2.5,2.5,0,0",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device="png",
    output="FODO_island.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.w1 -columnNames=x,xp -scale=-2.5,2.5,0,0 -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=FODO_island.png
[22]:
Image(filename="FODO_island.png")
[22]:
_images/notebook_Tutorial_ElegantRun_33_0.png

Advanced Tracking

FMA

[23]:
lattice = 'parTrack.lte'
er = ElegantRun(sif,lattice, parallel=True, use_beamline="par", energy=880.00)
er.fma(xmin=-0.05,xmax=0.05,ymin=0,ymax=0.02,nx=51,ny=51, n_passes=256)
[24]:
sddsp = SDDS(sif,'temp.fma',0)
sddsp.sddsplot_fma(
#     file2="temp.fma",
    device='png',
    output="partrack_fma_diffusionrate.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp.fma -col=x,y -graph=sym,vary=subtype,fill,scale=2,fill -order=spectral -split=column=diffusionRate -device=png -output=partrack_fma_diffusionrate.png
[25]:
Image(filename="partrack_fma_diffusionrate.png")
[25]:
_images/notebook_Tutorial_ElegantRun_38_0.png
[26]:
sddsp.sddsplot_tunediagram(scale="0,1,0,1", device='png',output="partrack_tune.png" )
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsresdiag resdiag.sdds
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot -columnNames=nux,nuy temp.fma -scale=0,1,0,1 -graph=sym,fill,vary=subtype -order=spect -split=col=x -col=nux,nuy resdiag.sdds -sever -device=png -output=partrack_tune.png
[27]:
Image(filename="partrack_tune.png")
[27]:
_images/notebook_Tutorial_ElegantRun_40_0.png

DA

[28]:
er = ElegantRun(sif,lattice, parallel=True, use_beamline="par", energy=880)
# parallel only supports n-line
er.dynap(n_lines=51)
[29]:
sddsp = SDDS(sif,"temp.aper",0)
sddsp.sddsplot_base(col="x,y",file1=sddsp.filename, device='png',output="partrack_aper.png")
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp.aper -col=x,y temp.aper -device=png -output=partrack_aper.png
[30]:
Image(filename="partrack_aper.png")
[30]:
_images/notebook_Tutorial_ElegantRun_44_0.png

Vary Element with input table

Mode: Row
[31]:
# create the input table for vary element
datasetdc = {
        "Q1" : [1.786022448154-0.01,1.786022448154+0.01],
        "Q2" : [2.295915530046-0.01,2.295915530046+0.01],

 }

# create simulation object
er = ElegantRun(sif,lattice, parallel=True, use_beamline="par", energy=880.00)

# generate particle grid for tracking
er.generate_sdds_particle_inputfile(grid_type='rectangular', p_min=1e-6, p_max=1e-2,
                                    pcentralmev=er.kwargs.get('energy'),
                                    NPOINTS=3
                                   )

# Track with vary - using mode row -> number of combinations is equal to the number of rows
er.track_vary(varydict=datasetdc,varyitemlist=['k1',"k1"],n_passes=2**8, add_watch_start=True, mode='row')

# laod the data
sdds = SDDS(sif, "temp-001.wq",0)
sdds.process_scan()
data = sdds.readParticleData()
data.head()
880.0
Shape: (243, 6) - Number of paritcles: 243
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsprocess -define=column,step,Step temp-001.wq temp-001_processed.wq
Warning - auto filename set
Changed from temp-001.wq to temp-001_processed.wq
Warning - auto filename set
Changed from temp-001_processed.wq to temp-001_processed.wq.txt
Warning - auto filetype set
Changed from 0 to 1
[31]:
x xp y yp t p dt particleID step Turn
0 0.0 0.0 0.0 0.00000 0.00000 1722.116751 0.00000 1 1.0 1
1 0.0 0.0 0.0 0.00000 0.00005 1722.116751 0.00005 2 1.0 1
2 0.0 0.0 0.0 0.00000 0.00010 1722.116751 0.00010 3 1.0 1
3 0.0 0.0 0.0 0.00005 0.00000 1722.116751 0.00000 4 1.0 1
4 0.0 0.0 0.0 0.00005 0.00005 1722.116751 0.00005 5 1.0 1
[32]:
# inspect input table file
sdds = SDDS(sif, "temp.sdds",0)
sdds.getColumnValues()
[32]:
Q1 Q2
0 1.776022 2.285916
1 1.796022 2.305916
[33]:
# quick plot
sddsp = SDDS(sif,"temp-001.wq",0)

sddsp.sddsplot_base(
    graph="dot,type=2",
    groupby='page',
    layout='2,1',
    split='parameterChange=Step,width=1,start=0',
    sep='page',
    columnNames="x,xp",
    legend='param=Step',
    device='png',
    output="partrack_vary_rect_mode_row.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -graph=dot,type=2 -groupby=page -layout=2,1 -split=parameterChange=Step,width=1,start=0 -sep=page -columnNames=x,xp -legend=param=Step -device=png -output=partrack_vary_rect_mode_row.png
[34]:
Image(filename='partrack_vary_rect_mode_row.png')
[34]:
_images/notebook_Tutorial_ElegantRun_50_0.png
[35]:
nsteps = int(data.step.max())

fig = plt.figure(constrained_layout=True)

gs= fig.add_gridspec(nsteps//2+nsteps%2, 2)

for i in [1.0*n for n in range(1,nsteps+1)]:
    ax = fig.add_subplot(gs[int(i-1)//2,int(i-1)%2])
    ax.xaxis.set_major_locator(plt.MaxNLocator(3))
    for name, group in data.loc[data.step==i].groupby("particleID"):
        ax.scatter(group["x"],group["xp"],s=1, label=name)

plt.show()
Mode: table
[36]:
# create the input table for vary element
datasetdc = {
        "Q1" : [1.786022448154-0.01,1.786022448154+0.01],
        "Q2" : [2.295915530046-0.01,2.295915530046+0.01],

 }

# create simulation object
er = ElegantRun(sif,lattice, parallel=True, use_beamline="par", energy=880.00)

# generate particle grid for tracking
er.generate_sdds_particle_inputfile(grid_type='rectangular', p_min=1e-6, p_max=1e-2,
                                    pcentralmev=er.kwargs.get('energy'),
                                    NPOINTS=3
                                   )

# Track with vary - using mode row -> number of combinations is equal to the number of rows
er.track_vary(varydict=datasetdc,varyitemlist=['k1',"k1"],n_passes=2**8, add_watch_start=True, mode='table')

# laod the data
sdds = SDDS(sif, "temp-001.wq",0)
sdds.process_scan()
data = sdds.readParticleData()
data.head()
880.0
Shape: (243, 6) - Number of paritcles: 243
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsprocess -define=column,step,Step temp-001.wq temp-001_processed.wq
Warning - auto filename set
Changed from temp-001.wq to temp-001_processed.wq
Warning - auto filename set
Changed from temp-001_processed.wq to temp-001_processed.wq.txt
Warning - auto filetype set
Changed from 0 to 1
[36]:
x xp y yp t p dt particleID step Turn
0 0.0 0.0 0.0 0.00000 0.00000 1722.116751 0.00000 1 1.0 1
1 0.0 0.0 0.0 0.00000 0.00005 1722.116751 0.00005 2 1.0 1
2 0.0 0.0 0.0 0.00000 0.00010 1722.116751 0.00010 3 1.0 1
3 0.0 0.0 0.0 0.00005 0.00000 1722.116751 0.00000 4 1.0 1
4 0.0 0.0 0.0 0.00005 0.00005 1722.116751 0.00005 5 1.0 1
[37]:
# inspect input table file
sdds = SDDS(sif, "temp.sdds",0)
sdds.getColumnValues()
[37]:
Q1 Q2
0 1.776022 2.285916
1 1.796022 2.305916
[38]:
# quick plot
sddsp = SDDS(sif,"temp-001.wq",0)

sddsp.sddsplot_base(
    graph="dot,type=2",
    groupby='page',
    layout='2,2',
    split='parameterChange=Step,width=1,start=0',
    sep='page',
    columnNames="x,xp",
    legend='param=Step',
    device='png',
    output="partrack_vary_rect_mode_table.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -graph=dot,type=2 -groupby=page -layout=2,2 -split=parameterChange=Step,width=1,start=0 -sep=page -columnNames=x,xp -legend=param=Step -device=png -output=partrack_vary_rect_mode_table.png
[39]:
Image(filename="partrack_vary_rect_mode_table.png")
[39]:
_images/notebook_Tutorial_ElegantRun_56_0.png
[40]:
nsteps = int(data.step.max())

fig = plt.figure(constrained_layout=True)

gs= fig.add_gridspec(nsteps//2+nsteps%2, 2)

for i in [1.0*n for n in range(1,nsteps+1)]:
    ax = fig.add_subplot(gs[int(i-1)//2,int(i-1)%2])
    ax.xaxis.set_major_locator(plt.MaxNLocator(3))
    for name, group in data.loc[data.step==i].groupby("particleID"):
        ax.scatter(group["x"],group["xp"],s=1, label=name)

plt.show()

Vary Elment with vary commands

Mode: row
[41]:
# create the input table for vary element
varyset = [
    {'name': "Q1", 'item':'K1', 'initial': 1.786022448154-0.01,'final':1.786022448154+0.01, 'index_limit': 2},
    {'name': "Q2", 'item':'K1', 'initial': 2.295915530046-0.01,'final':2.295915530046+0.01, 'index_limit': 2}
]


# create simulation object
er = ElegantRun(sif,lattice, parallel=True, use_beamline="par", energy=880.00)

# generate particle grid for tracking
er.generate_sdds_particle_inputfile(grid_type='rectangular', p_min=1e-6, p_max=1e-2,
                                    pcentralmev=er.kwargs.get('energy'),
                                    NPOINTS=3
                                   )
er.table_scan(varyset,mode='row',add_watch_start=True)


# laod the data
sdds = SDDS(sif, "temp-001.wq",0)
sdds.process_scan()
data = sdds.readParticleData()
data.head()
880.0
Shape: (243, 6) - Number of paritcles: 243
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsprocess -define=column,step,Step temp-001.wq temp-001_processed.wq
Warning - auto filename set
Changed from temp-001.wq to temp-001_processed.wq
Warning - auto filename set
Changed from temp-001_processed.wq to temp-001_processed.wq.txt
Warning - auto filetype set
Changed from 0 to 1
[41]:
x xp y yp t p dt particleID step Turn
0 0.0 0.0 0.0 0.00000 0.00000 1722.116751 0.00000 1 1.0 1
1 0.0 0.0 0.0 0.00000 0.00005 1722.116751 0.00005 2 1.0 1
2 0.0 0.0 0.0 0.00000 0.00010 1722.116751 0.00010 3 1.0 1
3 0.0 0.0 0.0 0.00005 0.00000 1722.116751 0.00000 4 1.0 1
4 0.0 0.0 0.0 0.00005 0.00005 1722.116751 0.00005 5 1.0 1
[42]:
# quick plot
sddsp = SDDS(sif,"temp-001.wq",0)

sddsp.sddsplot_base(
    graph="dot,type=2",
    groupby='page',
    layout='2,2',
    split='parameterChange=Step,width=1,start=0',
    sep='page',
    columnNames="x,xp",
    legend='param=Step',
    device='png',
    output="partrack_varycommand_rect_mode_row_.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -graph=dot,type=2 -groupby=page -layout=2,2 -split=parameterChange=Step,width=1,start=0 -sep=page -columnNames=x,xp -legend=param=Step -device=png -output=partrack_varycommand_rect_mode_row_.png
[43]:
Image(filename="partrack_varycommand_rect_mode_row_.png")
[43]:
_images/notebook_Tutorial_ElegantRun_62_0.png
[44]:
nsteps = int(data.step.max())

fig = plt.figure(constrained_layout=True)

gs= fig.add_gridspec(nsteps//2+nsteps%2, 2)

for i in [1.0*n for n in range(1,nsteps+1)]:
    ax = fig.add_subplot(gs[int(i-1)//2,int(i-1)%2])
    ax.xaxis.set_major_locator(plt.MaxNLocator(3))
    for name, group in data.loc[data.step==i].groupby("particleID"):
        ax.scatter(group["x"],group["xp"],s=1, label=name)

plt.show()
Mode: table
[45]:
# create the input table for vary element
varyset = [
    {'name': "Q1", 'item':'K1', 'initial': 1.786022448154-0.01,'final':1.786022448154+0.01, 'index_limit': 2},
    {'name': "Q2", 'item':'K1', 'initial': 2.295915530046-0.01,'final':2.295915530046+0.01, 'index_limit': 2}
]


# create simulation object
er = ElegantRun(sif,lattice, parallel=True, use_beamline="par", energy=880.00)

# generate particle grid for tracking
er.generate_sdds_particle_inputfile(grid_type='rectangular', p_min=1e-6, p_max=1e-2,
                                    pcentralmev=er.kwargs.get('energy'),
                                    NPOINTS=3
                                   )
er.table_scan(varyset,mode='table',add_watch_start=True)


# laod the data
sdds = SDDS(sif, "temp-001.wq",0)
sdds.process_scan()
data = sdds.readParticleData()
data.head()
880.0
Shape: (243, 6) - Number of paritcles: 243
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
Executing :
/home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsprocess -define=column,step,Step temp-001.wq temp-001_processed.wq
Warning - auto filename set
Changed from temp-001.wq to temp-001_processed.wq
Warning - auto filename set
Changed from temp-001_processed.wq to temp-001_processed.wq.txt
Warning - auto filetype set
Changed from 0 to 1
[45]:
x xp y yp t p dt particleID step Turn
0 0.0 0.0 0.0 0.00000 0.00000 1722.116751 0.00000 1 1.0 1
1 0.0 0.0 0.0 0.00000 0.00005 1722.116751 0.00005 2 1.0 1
2 0.0 0.0 0.0 0.00000 0.00010 1722.116751 0.00010 3 1.0 1
3 0.0 0.0 0.0 0.00005 0.00000 1722.116751 0.00000 4 1.0 1
4 0.0 0.0 0.0 0.00005 0.00005 1722.116751 0.00005 5 1.0 1
[46]:
# quick plot
sddsp = SDDS(sif,"temp-001.wq",0)

sddsp.sddsplot_base(
    graph="dot,type=2",
    groupby='page',
    layout='2,2',
    split='parameterChange=Step,width=1,start=0',
    sep='page',
    columnNames="x,xp",
    legend='param=Step',
    device='png',
    output="partrack_varycommand_rect_mode_table_.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -graph=dot,type=2 -groupby=page -layout=2,2 -split=parameterChange=Step,width=1,start=0 -sep=page -columnNames=x,xp -legend=param=Step -device=png -output=partrack_varycommand_rect_mode_table_.png
[47]:
Image(filename="partrack_varycommand_rect_mode_table_.png")
[47]:
_images/notebook_Tutorial_ElegantRun_67_0.png

Radiation and RF effects

[48]:
# use lattice from file
lattice = 'bii_simple.lte'

# run twiss to get gamma0 for generating particle input
er = ElegantRun(sif,lattice, parallel=True, use_beamline="ring", energy=1700.00)
twiss, twipar = er.findtwiss()

# on/off - momentum
gamma0 = twipar.pCentral

# initial coordinate grid for tracking
man_ranges= {
    0 : np.array([0,1e-6,1e-5,1e-4]),
    1 : [0],
    2 : 0,
    3 : 0,
    4 : 0,
    5 : gamma0
}

# generate coordinate input file
er = ElegantRun(sif,lattice, parallel=True, use_beamline="ring", energy=1700.00)
er.generate_sdds_particle_inputfile(man_ranges=man_ranges)
er.track_simple(rad=False, rf=False, add_watch_start=True, total_voltage=1.5e6)
1700.0
Shape: (4, 6) - Number of paritcles: 4
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[49]:
# quick plot
sddsp = SDDS(sif,"temp-001.wq",0)

sddsp.sddsplot_base(
    columnNames="dt,p",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device="png",
    output="bii_no_rad_no_rf_long.png"
)

sddsp.sddsplot_base(
    columnNames="x,xp",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device="png",
    output="bii_no_rad_no_rf_long_xpx.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -columnNames=dt,p -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=bii_no_rad_no_rf_long.png
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -columnNames=x,xp -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=bii_no_rad_no_rf_long_xpx.png
[50]:
# generate coordinate input file
er = ElegantRun(sif,lattice, parallel=True, use_beamline="ring", energy=1700.00)
er.generate_sdds_particle_inputfile(man_ranges=man_ranges)
er.track_simple(rad=True, rf=False, add_watch_start=True, total_voltage=1.5e6)
1700.0
Shape: (4, 6) - Number of paritcles: 4
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[51]:
# quick plot
sddsp = SDDS(sif,"temp-001.wq",0)

sddsp.sddsplot_base(
    columnNames="dt,p",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device="png",
    output="bii_rad_no_rf_long.png"
)

sddsp.sddsplot_base(
    columnNames="x,xp",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device="png",
    output="bii_rad_no_rf_long_xpx.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -columnNames=dt,p -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=bii_rad_no_rf_long.png
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -columnNames=x,xp -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=bii_rad_no_rf_long_xpx.png
[52]:
# generate coordinate input file
er = ElegantRun(sif,lattice, parallel=True, use_beamline="ring", energy=1700.00)
er.generate_sdds_particle_inputfile(man_ranges=man_ranges)
er.track_simple(rad=True, rf=True, add_watch_start=True, total_voltage=1.5e6)
1700.0
Shape: (4, 6) - Number of paritcles: 4
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif plaindata2sdds temp_plain_particles.dat temp_particles_input.bin -inputMode=ascii -outputMode=binary "-separator=  " -column=x,double,units=m -column=xp,double -column=y,double,units=m -column=yp,double -column=t,double,units=s -column=p,double,units="m$be$nc" -columns=particleID,long -noRowCount
[53]:
# quick plot
sddsp = SDDS(sif,"temp-001.wq",0)

sddsp.sddsplot_base(
    columnNames="dt,p",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device="png",
    output="bii_rad_rf_long.png"
)

sddsp.sddsplot_base(
    columnNames="x,xp",
    graph="symb,vary=subtype,fill",
    order="spectral",
    split="columnBin=particleID",
    device="png",
    output="bii_rad_rf_long_xpx.png"
)
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -columnNames=dt,p -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=bii_rad_rf_long.png
Running command /home/mti/gitlab-hzb/containers/bin/pelegant.sif sddsplot temp-001.wq -columnNames=x,xp -graph=symb,vary=subtype,fill -order=spectral -split=columnBin=particleID -device=png -output=bii_rad_rf_long_xpx.png
[54]:
Image('bii_no_rad_no_rf_long.png')
[54]:
_images/notebook_Tutorial_ElegantRun_75_0.png
[55]:
Image('bii_no_rad_no_rf_long_xpx.png')
[55]:
_images/notebook_Tutorial_ElegantRun_76_0.png
[56]:
Image('bii_rad_no_rf_long.png')
[56]:
_images/notebook_Tutorial_ElegantRun_77_0.png
[57]:
Image('bii_rad_no_rf_long_xpx.png')
[57]:
_images/notebook_Tutorial_ElegantRun_78_0.png
[58]:
Image(filename="bii_rad_rf_long.png")
[58]:
_images/notebook_Tutorial_ElegantRun_79_0.png
[59]:
Image(filename="bii_rad_rf_long_xpx.png")
[59]:
_images/notebook_Tutorial_ElegantRun_80_0.png

Indices and tables