Layout Plotting¶
In [1]:
Copied!
import os
import numpy as np
from impact import Impact
from impact.parsers import parse_impact_input
from impact.plotting import layout_plot
from impact.fieldmaps import ele_field, lattice_field
from bokeh.plotting import output_notebook
from bokeh.plotting import show
output_notebook(hide_banner=True)
import matplotlib.pyplot as plt
from ipywidgets import interact
%config InlineBackend.figure_format = 'retina'
import os
import numpy as np
from impact import Impact
from impact.parsers import parse_impact_input
from impact.plotting import layout_plot
from impact.fieldmaps import ele_field, lattice_field
from bokeh.plotting import output_notebook
from bokeh.plotting import show
output_notebook(hide_banner=True)
import matplotlib.pyplot as plt
from ipywidgets import interact
%config InlineBackend.figure_format = 'retina'
In [2]:
Copied!
infile = 'templates/lcls_injector/ImpactT.in'
infile = 'templates/lcls_injector/ImpactT.in'
matplotlib plotting from the Impact object¶
In [3]:
Copied!
I = Impact(infile)
I.plot(figsize=(12,4))
I = Impact(infile)
I.plot(figsize=(12,4))
In [4]:
Copied!
# Track 1 particle
I.track1()
# These are the fields seen by the bunch centroid
I.plot('Ez', y2='Bz')
# Track 1 particle
I.track1()
# These are the fields seen by the bunch centroid
I.plot('Ez', y2='Bz')
In [5]:
Copied!
# Fieldmaps can be added to existing axes
from impact.plot import add_fieldmaps_to_axes
fig, ax = plt.subplots()
add_fieldmaps_to_axes(I, t=1, ax=ax, bounds=(0, 10))
# Fieldmaps can be added to existing axes
from impact.plot import add_fieldmaps_to_axes
fig, ax = plt.subplots()
add_fieldmaps_to_axes(I, t=1, ax=ax, bounds=(0, 10))
Low-level get field¶
In [6]:
Copied!
# Get fieldmaps
fmaps = I.fieldmaps
# This shows the field from a single element
ele_field(I.ele['GUN'], z=.1, fmaps=fmaps)
# Get fieldmaps
fmaps = I.fieldmaps
# This shows the field from a single element
ele_field(I.ele['GUN'], z=.1, fmaps=fmaps)
Out[6]:
1738690.5187003822
In [7]:
Copied!
# this gets the total field from all elements in the lattice
lattice_field(I.lattice, z=.3, fmaps=fmaps)
# this gets the total field from all elements in the lattice
lattice_field(I.lattice, z=.3, fmaps=fmaps)
Out[7]:
0.0
In [8]:
Copied!
I.input['fieldmaps'].keys()
I.input['fieldmaps'].keys()
Out[8]:
dict_keys(['rfdata201', 'rfdata102', 'rfdata4', 'rfdata5', 'rfdata6', 'rfdata7'])
In [9]:
Copied!
# Period in ps
T = 1 / 2856000000.0
T / 1e-12 # ps
# Period in ps
T = 1 / 2856000000.0
T / 1e-12 # ps
Out[9]:
350.140056022409
In [10]:
Copied!
I = Impact(infile)
I.plot(figsize=(12,4), field_t=0)
I = Impact(infile)
I.plot(figsize=(12,4), field_t=0)
In [11]:
Copied!
# Make a function to get a field array at a given phase/2pi
zz = np.linspace(0, I.stop, 1000)
def field_at(phi0):
Ez_at = np.array([I.field(z=z, t=phi0/2856000000.0,
component='Ez') for z in zz])
plt.plot(zz, Ez_at/1e6)
plt.ylim(-100, 100)
#plt.xlim(2, 2.2)
#def field_at(phi0):
# t=phi0/2856000000.0
# fig = I.plot(figsize=(12,4), field_t=t, return_figure=True)
# fig.axes[0].set_ylim(-100,100)
# fig.axes[1].set_ylim(-0, 0.3)
field_at(0)
# Make a function to get a field array at a given phase/2pi
zz = np.linspace(0, I.stop, 1000)
def field_at(phi0):
Ez_at = np.array([I.field(z=z, t=phi0/2856000000.0,
component='Ez') for z in zz])
plt.plot(zz, Ez_at/1e6)
plt.ylim(-100, 100)
#plt.xlim(2, 2.2)
#def field_at(phi0):
# t=phi0/2856000000.0
# fig = I.plot(figsize=(12,4), field_t=t, return_figure=True)
# fig.axes[0].set_ylim(-100,100)
# fig.axes[1].set_ylim(-0, 0.3)
field_at(0)
In [12]:
Copied!
# Visualize the oscillating fields
interact(field_at, phi0=(0, 2, .01))
# Visualize the oscillating fields
interact(field_at, phi0=(0, 2, .01))
Out[12]:
<function __main__.field_at(phi0)>
In [13]:
Copied!
# These are the fields seen by the bunch
I.track1()
zz = I.stat('mean_z')
tt = I.stat('t')
Ez_seen = np.array([lattice_field(I.lattice, z=z, t=t, fmaps=fmaps,
component='Ez') for z, t in zip(zz, tt)])
zz = zz[:len(tt)]
plt.plot(zz, Ez_seen)
# These are the fields seen by the bunch
I.track1()
zz = I.stat('mean_z')
tt = I.stat('t')
Ez_seen = np.array([lattice_field(I.lattice, z=z, t=t, fmaps=fmaps,
component='Ez') for z, t in zip(zz, tt)])
zz = zz[:len(tt)]
plt.plot(zz, Ez_seen)
Out[13]:
[<matplotlib.lines.Line2D at 0x1427b1550>]
In [14]:
Copied!
# MeV energy gain
-np.trapz(Ez_seen, zz) / 1e6
# MeV energy gain
-np.trapz(Ez_seen, zz) / 1e6
Out[14]:
34.272824268974844
In [15]:
Copied!
# This is pretty close to the tracked kinetic energy
I.stat('mean_kinetic_energy')[-1]/1e6
# This is pretty close to the tracked kinetic energy
I.stat('mean_kinetic_energy')[-1]/1e6
Out[15]:
34.269711
Bokeh plotting from the input file¶
In [16]:
Copied!
infile = 'templates/lcls_injector/ImpactT.in'
os.path.exists(infile)
dat= parse_impact_input(infile)
header = dat['header']
lattice = dat['lattice']
infile = 'templates/lcls_injector/ImpactT.in'
os.path.exists(infile)
dat= parse_impact_input(infile)
header = dat['header']
lattice = dat['lattice']
In [17]:
Copied!
layout = layout_plot(lattice)
show(layout)
layout = layout_plot(lattice)
show(layout)
Output Plotting¶
In [18]:
Copied!
from bokeh.plotting import figure
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Range1d
from impact.parsers import load_many_fort
from impact.parsers import UNITS
from bokeh.plotting import figure
from bokeh.layouts import column, row
from bokeh.models import ColumnDataSource, Range1d
from impact.parsers import load_many_fort
from impact.parsers import UNITS
In [19]:
Copied!
opath = 'templates/lcls_injector/output/'
data = load_many_fort(opath, verbose=True)
ds = ColumnDataSource(data)
opath = 'templates/lcls_injector/output/'
data = load_many_fort(opath, verbose=True)
ds = ColumnDataSource(data)
Loaded fort 18 : Time and energy Loaded fort 24 : RMS X information Loaded fort 25 : RMS Y information Loaded fort 26 : RMS Z information Loaded fort 27 : Max amplitude information Loaded fort 28 : Load balance and loss diagnostics Loaded fort 29 : Cube root of third moments of the beam distribution Loaded fort 30 : Fourth root of the fourth moments of the beam distribution
In [20]:
Copied!
def plot1(y_axis, x_axis='mean_z', source=ds):
yunit = UNITS[y_axis]
ylabel = y_axis+' ('+yunit+')'
xunit = UNITS[x_axis]
xlabel = x_axis+' ('+xunit+')'
p = figure(width=600, height=200, x_axis_label=xlabel, y_axis_label=ylabel)
p.line( x_axis, y_axis, source=source, color='red')
return p
show(plot1('norm_emit_x'))
def plot1(y_axis, x_axis='mean_z', source=ds):
yunit = UNITS[y_axis]
ylabel = y_axis+' ('+yunit+')'
xunit = UNITS[x_axis]
xlabel = x_axis+' ('+xunit+')'
p = figure(width=600, height=200, x_axis_label=xlabel, y_axis_label=ylabel)
p.line( x_axis, y_axis, source=source, color='red')
return p
show(plot1('norm_emit_x'))
Stacking plots¶
This also links the panning, zooming
In [21]:
Copied!
p1 = plot1('sigma_x')
p2 = plot1('norm_emit_x')
zmax = 2
layout.x_range = Range1d(0,zmax)
p1.x_range = Range1d(0,zmax)
layout.width = p1.width
# Link panning, zooming
layout.x_range = p1.x_range
p2.x_range = p1.x_range
show(
column(
p1,
p2,
layout))
p1 = plot1('sigma_x')
p2 = plot1('norm_emit_x')
zmax = 2
layout.x_range = Range1d(0,zmax)
p1.x_range = Range1d(0,zmax)
layout.width = p1.width
# Link panning, zooming
layout.x_range = p1.x_range
p2.x_range = p1.x_range
show(
column(
p1,
p2,
layout))