This notebook also can be downloaded or executed at MS Azure cloud: https://notebooks.azure.com/library/fnal (press 'Clone and run' button).
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
from urllib.request import urlopen
from io import StringIO
from bokeh.plotting import figure, output_file, show
from bokeh.io import output_notebook
from bokeh.resources import INLINE
output_notebook(resources=INLINE)
%matplotlib inline
font = {'weight':'normal','size':14, 'family':'Times New Roman'}
matplotlib.rc('font', **font)
def readDATA(url):
# ORM file content as a string
txt = urlopen(url).read().decode()
# make stream out of string (it's easier to read then):
DATA=StringIO(txt)
print(DATA.readline().strip(' #\n'))
line = DATA.readline()
line = line.replace('Dipole current', 'Dipole_current')
line = line.replace('Cycle time', 'Cycle_time')
line = line.replace('B:HP', 'H')
line = line.replace('B:VP', 'V')
line = line.replace('03LU', 'U3L')
line = line.replace('06LU', 'U6L')
line = line.replace('07LU', 'U7L')
cols = []
for col in line.split():
if col.startswith('H') or col.startswith('V'):
# converting H03S to HS03 and H03L to HL03
cols.append(col[0] + col[-1] + col[1:-1])
else:
cols.append(col)
# converting B:HL1 to HL01
df = pd.read_table(DATA, names=cols, delim_whitespace=True)
df['Dipole'] = df['Dipole'].str.replace('B:', '')
Dipoles = df['Dipole'].values
df['Dipole'] = [
Dipole[:2] + '{:02.0f}'.format(int(Dipole[2:])) for Dipole in Dipoles
]
df['Dipole_base_name'] = df['Dipole'].str[1:]
return df
#df_DATA = readDATA('https://apetrenko.blob.core.windows.net/fnal-booster-orm/test.txt')
#df_DATA = readDATA('https://apetrenko.blob.core.windows.net/fnal-booster-orm/2011-12-20_ORM_3.txt')
df1 = readDATA('https://apetrenko.blob.core.windows.net/fnal-booster-orm/2016-11-22_ORM_H.txt')
df2 = readDATA('https://apetrenko.blob.core.windows.net/fnal-booster-orm/2016-11-22_ORM_V.txt')
df_DATA = pd.concat([df1, df2], ignore_index=True)
df_DATA.head(3)
df_DATA.tail(3)
This table contains different cycle times:
Cycle_times = df_DATA.Cycle_time.drop_duplicates().values
print('t = ', end=""); print(Cycle_times)
Dipole_current = list(df_DATA.Dipole_current.drop_duplicates().values)
print('I = ', end=""); print(Dipole_current)
Let's select one time point:
t = Cycle_times[3]
#t = Cycle_times[6]
df_DATA_t = df_DATA[df_DATA.Cycle_time == t]
df_DATA_t.head(5)
url = 'https://apetrenko.blob.core.windows.net/misc/BoosterBPMs.txt'
txt = urlopen(url).read().decode()
df_BPMs = pd.read_table(StringIO(txt), names=['BPM', 's'], delim_whitespace=True)
BPMs = list(df_BPMs.BPM.values)
s_BPM = list(df_BPMs.s.values)
xBPMs = ['H'+col for col in BPMs]
yBPMs = ['V'+col for col in BPMs]
df_I0 = df_DATA_t[df_DATA_t.Dipole_current == 0]
dfx = pd.DataFrame(df_I0, columns=xBPMs)
dfy = pd.DataFrame(df_I0, columns=yBPMs)
x_ticks = range(len(BPMs))
plt.rcParams["figure.figsize"] = [12,7]
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.set_title('Central orbit')
ax1.set_ylabel('x (mm)')
ax2.set_ylabel('y (mm)')
ax2.set_xlabel('BPM name')
for i, row in dfx.iterrows():
ax1.scatter(x_ticks, row.values, color='red',
alpha=0.3, s=20, edgecolor = 'none')
ax1.set_xticks(x_ticks)
for i, row in dfy.iterrows():
ax2.scatter(x_ticks, row.values, color='blue',
alpha=0.3, s=20, edgecolor = 'none')
ax2.set_xticks(x_ticks)
ax2.set_xticklabels(BPMs, rotation='vertical') #, fontsize=16
ax1.set_ylim(-17,+17)
ax2.set_ylim(-17,+17)
ax1.grid()
ax2.grid()
plt.tight_layout()
plt.show(fig)
#for row in dfx.rows:
# print row['c1'], row['c2']
#dfx.head()
#BPM = 'S24'
#BPM = 'L24'
#BPM = 'L07'
#BPM = 'LU3'
#BPM = 'L16'
BPM = 'S16'
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.set_title('Central orbit at '+BPM)
ax1.set_ylabel('H'+BPM+' (mm)')
ax2.set_ylabel('V'+BPM+' (mm)')
ax2.set_xlabel('Measurement index')
x = df_I0['H'+BPM].values
y = df_I0['V'+BPM].values
ax1.scatter(range(len(x)), x, color='red',
alpha=0.7, s=20, edgecolor = 'none')
ax2.scatter(range(len(y)), y, color='blue',
alpha=0.7, s=20, edgecolor = 'none')
ax1.set_ylim([-15,+15])
ax2.set_ylim([-15,+15])
ax1.grid()
ax2.grid()
plt.tight_layout()
plt.show(fig)
Since the central orbit is measured many times we can mark the outlier points for the central orbit easily:
df = df_I0.copy()
outlier_cols = []
for bpm in xBPMs+yBPMs:
mean = df[bpm].mean()
std = df[bpm].std()
df[bpm+'outlier'] = ((df[bpm]-mean < -1.5*std) | (df[bpm]-mean > 1.5*std))
outlier_cols.append(bpm+'outlier')
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True)
ax1.set_title('Central orbit at '+BPM)
ax1.set_ylabel('H'+BPM+' (mm)')
ax2.set_ylabel('V'+BPM+' (mm)')
ax2.set_xlabel('Measurement index')
df['meas_idx'] = range(len(df))
df_xout = df[ df['H'+BPM+'outlier']==True ]
df_yout = df[ df['V'+BPM+'outlier']==True ]
ax1.scatter(df.meas_idx, df['H'+BPM], color='red',
alpha=0.7, s=20, edgecolor = 'none')
ax1.scatter(df_xout.meas_idx,
df_xout['H'+BPM], facecolors='none',
alpha=1.0, s=80, edgecolor = 'black')
ax2.scatter(df.meas_idx, df['V'+BPM], color='blue',
alpha=0.7, s=20, edgecolor = 'none')
ax2.scatter(df_yout.meas_idx,
df_yout['V'+BPM], facecolors='none',
alpha=1.0, s=80, edgecolor = 'black')
#ax1.set_ylim([-15,+15])
#ax2.set_ylim([-15,+15])
ax1.grid()
ax2.grid()
plt.tight_layout()
plt.show(fig)
Now let's copy the outlier markers to the main dataframe (df_DATA_t) for later use:
df.head()
df_DATA_t = df_DATA_t.drop(outlier_cols, axis=1, errors='ignore') # to avoid duplicates
df_DATA_t = pd.concat( [ df_DATA_t, df[outlier_cols] ], axis=1)
df_DATA_t = df_DATA_t.fillna(False)
df_DATA_t.head(6)
from scipy import stats
def get_ORMfromDATA(df_data, bpm_names):
# defining new DataFrame for slopes and errors
cols = ['Dipole', 'Dipole_base_name', 's']
for bpm in bpm_names:
cols.extend([bpm+'slope', bpm+'intercept', bpm+'std_err'])
df_out = pd.DataFrame(columns=cols)
# using stats.linregress to find slopes and errors
i = 0
grouped = df_data.groupby('Dipole')
for Dipole, df in grouped:
i = i + 1
print('\rWorking on ' + Dipole +
' ({:.0f}%)'.format(100*i/len(grouped)), end='')
s = df_BPMs[df_BPMs['BPM'] == Dipole[1:]].s.values[0]
vals = [Dipole, Dipole[1:], s]
for bpm in bpm_names:
df_no_outliers = df[df[bpm+'outlier'] == False]
cur = df_no_outliers['Dipole_current'].values
v = df_no_outliers[bpm].values
slope, intercept, r_value, p_value, std_err = stats.linregress(cur, v)
vals.extend([slope, intercept, std_err])
df_out.loc[len(df_out)] = vals
df_H = df_out[df_out['Dipole'].str.startswith('H')].sort_values(by='s')
df_V = df_out[df_out['Dipole'].str.startswith('V')].sort_values(by='s')
df_out = pd.concat([df_H, df_V])
print('\nDone')
return df_out
def mark_outliers(df_data, df_orm, bpm_names):
df_out = df_data.copy()
i = 0
grouped = df_out.groupby('Dipole')
for Dipole, df in grouped:
i = i + 1
print('\rWorking on ' + Dipole +
' ({:.0f}%)'.format(100*i/len(grouped)), end='')
n = float(len(df))
t = 4.0; # appropriate t value
#conf = [] # confidence level
# residuals:
for bpm in bpm_names:
slope = df_orm[df_orm.Dipole == Dipole][bpm + 'slope'].values[0]
v0 = df_orm[df_orm.Dipole == Dipole][bpm + 'intercept'].values[0]
I = df['Dipole_current'].values
fit = v0 + slope*I
residual = df[bpm] - fit
s_err = (residual*residual).sum()
conf = t * np.sqrt((s_err/(n-2.0))*(1.0/n + I*I/(I*I).sum()))
df_out.loc[df_out.Dipole == Dipole, bpm+'outlier'] = abs(residual) - conf > 0
print('\nDone.')
return df_out
df_ORM = get_ORMfromDATA(df_DATA_t, xBPMs + yBPMs)
xDipoles = [itm for itm in df_ORM.Dipole.values if itm.startswith('H')]
yDipoles = [itm for itm in df_ORM.Dipole.values if itm.startswith('V')]
Dipoles = list(df_ORM.Dipole_base_name.drop_duplicates().values)
df_ORM.head()
df_DATA_t = mark_outliers(df_DATA_t, df_ORM, xBPMs + yBPMs)
df_ORM = get_ORMfromDATA(df_DATA_t, xBPMs + yBPMs)
df_ORM.head()
from bokeh.models import (HoverTool, ColumnDataSource,
LinearColorMapper, TapTool,
CustomJS, RadioGroup)
import bokeh.palettes as palettes
#cmap = matplotlib.cm.get_cmap('bwr')
#cnorm = matplotlib.colors.Normalize(-2.0, +2.0)
#rgba = cmap(cnorm(-3))
#hex_color = matplotlib.colors.rgb2hex(rgba)
#print(hex_color)
import decimal
def get_SlopeDataSource(bpm_names, dipole_names):
bpm_list = []
dipole_list = []
bpm_type_list = []
dipole_type_list = []
slope_list = []
std_err_list = []
# raw measurements (these will be big lists):
measured_vals_list = []
I_points_list = []
# outliers:
outliers_idx_list = []
i = 0
for dipole in dipole_names:
df = df_ORM[df_ORM.Dipole == dipole]
df_measured = df_DATA_t[df_DATA_t.Dipole == dipole].sort_values(by='Dipole_current')
for bpm in bpm_names:
slope = df[bpm + 'slope'].values[0]
slope_list.append('{:+.3f}'.format(slope))
std_err = df[bpm + 'std_err'].values[0]
std_err_list.append('{:+.3f}'.format(std_err))
# axis ticks will be without H or V:
bpm_list.append(bpm[1:])
bpm_type_list.append(bpm[0])
dipole_list.append(dipole[1:])
dipole_type_list.append(dipole[0])
# raw measured data points:
I_vals = list(df_measured['Dipole_current'].values)
I_vals = [float(val) for val in I_vals]
v0 = df[bpm + 'intercept'].values[0]
m_vals = df_measured[bpm].values
m_vals = [float(np.round(val-v0, 2)) for val in m_vals]
measured_vals_list.append(m_vals)
I_points_list.append(I_vals)
# outliers
df_out = df_measured.reset_index(drop=True)
df_out = df_out[ df_out[bpm + 'outlier']==True ]
outliers_idx_list.append(list(df_out.index))
return ColumnDataSource(data=dict(
bpm=bpm_list,
dipole=dipole_list,
bpm_type=bpm_type_list,
dipole_type=dipole_type_list,
slope=slope_list,
std_err=std_err_list,
measured_vals=measured_vals_list,
I_points=I_points_list,
outliers_idx = outliers_idx_list,
))
def plot_ORM_cmap(source, cmap_field, cmapper,
x_range, y_range, measured_points_src,
selected_response_src, hover_callback):
p = figure(x_axis_location="below", tools="crosshair,save,box_zoom,reset",
x_range=x_range, y_range=y_range)
p.xaxis.axis_label='BPM'
p.yaxis.axis_label='Dipole'
p.grid.grid_line_color = None
p.axis.axis_line_color = None
p.axis.major_tick_line_color = None
p.axis.major_label_text_font_size = "7pt"
p.axis.major_label_standoff = 0
p.xaxis.major_label_orientation = np.pi/3
r = p.rect('bpm', 'dipole', 0.9, 0.9, source=source,
fill_color={'field': cmap_field, 'transform': cmapper},
hover_color={'field': cmap_field, 'transform': cmapper},
line_color=None, hover_line_color='black')
#tips = [
# ('BPM', '@bpm_type-@bpm'),
# ('Dipole', '@dipole_type-@dipole'),
# ('dBPM/dI', '@slope mm/A'),
# ('Error dBPM/dI', '@std_err mm/A'),
# #('I_points', '@I_points (A)'),
# #('values', '@measured_vals (mm)'),
#]
#p.select_one(HoverTool).tooltips = tips
#p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[r]))
#p.add_tools(HoverTool(tooltips=tips, callback=hover_callback))
p.add_tools(HoverTool(tooltips=None, callback=hover_callback))
return p
# this is the data source the color map:
slope_source = get_SlopeDataSource(xBPMs, xDipoles)
# different data sources attached to radio-buttons:
dx_dx = get_SlopeDataSource(xBPMs, xDipoles)
dx_dy = get_SlopeDataSource(xBPMs, yDipoles)
dy_dx = get_SlopeDataSource(yBPMs, xDipoles)
dy_dy = get_SlopeDataSource(yBPMs, yDipoles)
# this is the sources of data from selected response:
measured_points_src = ColumnDataSource(data=dict(
measured_vals=[0,0],
outlier_vals=[0,0],
I_points=[-4,4],
meas_idx=[0,1],
))
selected_response_src = ColumnDataSource(data=dict(
slope_index=[],
bpm=[],
dipole=[],
))
Imin = df_DATA_t.Dipole_current.min()
Imax = df_DATA_t.Dipole_current.max()
cur = np.linspace(Imin-0.5, Imax+0.5, 10)
selected_response_fit_src = ColumnDataSource(data=dict(
I=list(cur),
vmin=list(cur*0),
vmax=list(cur*0),
v=list(cur*0),
))
#selected_response_fit_src.data
p0 = figure(tools="save,box_zoom,reset", toolbar_location="right")
p0.title.text = "Move the mouse over the map to see the results"
p0.yaxis.axis_label='dBPM (mm)'
p0.xaxis.axis_label='dI (A)'
p0.line('I', 'vmax', source=selected_response_fit_src, color='blue',
line_width=2, line_alpha=0.3, line_dash = [10, 5])
p0.line('I', 'vmin', source=selected_response_fit_src, color='blue',
line_width=2, line_alpha=0.3, line_dash = [10, 5], legend='Fit error')
p0.line('I', 'v', source=selected_response_fit_src, color='blue',
line_width=3, line_alpha=0.8)
p0.legend.background_fill_alpha = 0.4
p0.circle('I_points', 'measured_vals', size=4, source=measured_points_src,
alpha=0.6, fill_color=None, line_color="black")
p0.circle('I_points', 'outlier_vals', size=8, source=measured_points_src,
alpha=0.8, fill_color=None, line_color="red", line_width=1.5)
p0.plot_width = 360
p0.plot_height = 250
# plot x-y range:
p0.x_range.start=-5; p0.x_range.end = 5
p0.y_range.start=-25; p0.y_range.end = 25
p1 = figure(tools="save,box_zoom,reset", y_range=p0.y_range,
x_axis_type=None, toolbar_location="right")
p1.circle('meas_idx', 'measured_vals', size=4, source=measured_points_src,
alpha=0.6, fill_color=None, line_color="black")
p1.circle('meas_idx', 'outlier_vals', size=8, source=measured_points_src,
alpha=0.8, fill_color=None, line_color="red", line_width=1.5,
legend='Excluded')
p1.legend.background_fill_alpha = 0.4
p1.plot_height = p0.plot_height
p1.plot_width = p0.plot_width
#p1.xaxis.axis_label='Measurement index'
hover_callback = CustomJS(args={
'src': slope_source,
'm_src': measured_points_src,
's_src': selected_response_src,
'fit_src': selected_response_fit_src,
'pvsI': p0,
},
code='''
var indices = cb_data.index['1d'].indices;
if(indices.length > 0){
i = indices[0];
if(i != s_src.data.slope_index[0]){
data = src.data;
bpm = data.bpm[i];
bpm_type = data.bpm_type[i];
dipole = data.dipole[i];
dipole_type = data.dipole_type[i];
I_points = data.I_points[i];
measured_vals = data.measured_vals[i];
slope = Number(data.slope[i]);
std_err = Number(data.std_err[i]);
outliers_idx=data.outliers_idx[i];
//console.log(outliers_idx);
pvsI.title.text =
bpm_type+bpm+' BPM vs '+dipole_type+dipole+' dipole:';
s_src.data.slope_index[0] = i;
s_src.data.bpm[0] = bpm;
s_src.data.dipole[0] = dipole;
m_src.data.I_points = I_points;
m_src.data.outlier_vals = I_points.slice();
m_src.data.meas_idx = I_points.slice();
for (k = 0; k < I_points.length; k++) {
m_src.data.meas_idx[k] = k;
m_src.data.outlier_vals[k] = NaN;
}
for (k = 0; k < outliers_idx.length; k++) {
idx = outliers_idx[k];
m_src.data.outlier_vals[idx] = measured_vals[idx];
}
m_src.data.measured_vals = measured_vals;
I_fit = fit_src.data.I;
//t = 2.31; // appropriate t value (where n=9, two tailed 95%)
t = 2.31;
conf = I_fit.slice(); // confidence level
// residuals:
n = 0;
s_err = 0; // sum of the squares of the residuals
for (k = 0; k < I_points.length; k++) {
v = measured_vals[k];
if (m_src.data.outlier_vals[k]!=v) {
n = n + 1;
I = I_points[k];
v_predicted = I*slope;
v_err = v - v_predicted;
s_err = s_err + v_err*v_err;
}
}
console.log(n);
I2_sum = 0;
for (k = 0; k < I_fit.length; k++) {
I = I_fit[k];
I2_sum = I2_sum + I*I;
}
for (k = 0; k < I_fit.length; k++) {
I = I_fit[k];
fit = I*slope;
fit_src.data.v[k] = fit;
conf[k] = t * Math.sqrt((s_err/(n-2.0))*(1.0/n + I*I/I2_sum));
fit_src.data.vmax[k] = I*slope + conf[k];
fit_src.data.vmin[k] = I*slope - conf[k];
}
s_src.trigger('change');
fit_src.trigger('change');
m_src.trigger('change');
//console.log(bpm);
}
}
''')
slope_mapper = LinearColorMapper(palette=palettes.RdBu11, low=-2.0, high=2.0)
p2 = plot_ORM_cmap(slope_source, 'slope',
slope_mapper, x_range=BPMs, y_range=Dipoles,
measured_points_src=measured_points_src,
selected_response_src=selected_response_src,
hover_callback=hover_callback)
p2.plot_width = 710
p2.plot_height = 400
std_err_mapper = LinearColorMapper(palette=palettes.RdBu11, low=-0.15, high=0.15)
p3 = plot_ORM_cmap(slope_source, 'std_err',
std_err_mapper, x_range=p2.x_range, y_range=p2.y_range,
measured_points_src=measured_points_src,
selected_response_src=selected_response_src,
hover_callback=hover_callback)
p3.plot_width = p2.plot_width
p3.plot_height = p2.plot_height
from bokeh.models.widgets import Panel, Tabs, RadioGroup
from bokeh.layouts import gridplot, row, column, layout
radio_group = RadioGroup(labels=['dx/dx', 'dx/dy', 'dy/dx', 'dy/dy'],
active=0, inline=True)
callback_args = {
'src': slope_source,
'dx_dx': dx_dx,
'dx_dy': dx_dy,
'dy_dx': dy_dx,
'dy_dy': dy_dy,
'radio_group': radio_group,
}
radio_group.callback = CustomJS(
args=callback_args,
code="""
switch (radio_group.active) {
case 0:
src.data = dx_dx.data;
break;
case 1:
src.data = dx_dy.data;
break;
case 2:
src.data = dy_dx.data;
break;
case 3:
src.data = dy_dy.data;
break;
}
src.trigger('change');
// alert('It worked!');
""")
tab1 = Panel(child=p2, title="Slopes")
tab2 = Panel(child=p3, title="Slope errors")
tabs = Tabs(tabs=[ tab1, tab2 ]) #, width=730
plots = row([p0, p1])
tabs_and_plots=gridplot([[row([tabs, radio_group])],
[plots]], toolbar_location='right')
lay = tabs_and_plots
#layout = radio_group
show(lay)
from bokeh.models import LabelSet
def plot_responses(dipole_names, ylabel):
dipole_s_list = []
dipole_list = []
text_y_list = []
x_resp_list = []
x_err_list = []
y_resp_list = []
y_err_list = []
x_slope_cols = [bpm+'slope' for bpm in xBPMs]
x_err_cols = [bpm+'std_err' for bpm in xBPMs]
y_slope_cols = [bpm+'slope' for bpm in yBPMs]
y_err_cols = [bpm+'std_err' for bpm in yBPMs]
for dipole in dipole_names:
df = df_ORM[df_ORM.Dipole == dipole]
dipole_list.append(dipole[1:])
dipole_s_list.append(df.s.values[0])
if dipole[1] =='S':
text_y_list.append(+1.9)
else:
text_y_list.append(-1.9)
x_slopes = list(df[x_slope_cols].values[0])
x_slopes = [float(np.round(val, 2)) for val in x_slopes]
x_resp_list.append(x_slopes)
x_errs = list(df[x_err_cols].values[0])
x_errs = [float(np.round(val*4, 3)) for val in x_errs]
x_err_list.append(x_errs)
y_slopes = list(df[y_slope_cols].values[0])
y_slopes = [float(np.round(val, 2)) for val in y_slopes]
y_resp_list.append(y_slopes)
y_errs = list(df[y_err_cols].values[0])
y_errs = [float(np.round(val*4, 3)) for val in y_errs]
y_err_list.append(y_errs)
v = np.array(dipole_s_list)*0
orbit_responses_src = ColumnDataSource(data=dict(
dipole=dipole_list,
dipole_s=dipole_s_list,
text_y=text_y_list,
x_resp=x_resp_list,
x_err=x_err_list,
y_resp=y_resp_list,
y_err=y_err_list,
))
#print(orbit_responses_src.data)
selected_dipole_src = ColumnDataSource(data=dict(
dipole_index = [0],
dipole_s = [float('nan')],
text_y = [float('nan')],
))
s = np.array(df_BPMs.s.values)
v = s*0
selected_orbit_response_src = ColumnDataSource(data=dict(
bpm_s = list(s),
bpm_name = list(df_BPMs.BPM.values),
x_response = x_slopes,
x_response_err = x_errs,
y_response = y_slopes,
y_response_err = y_errs,
))
p = figure(tools="xbox_zoom,pan,reset", toolbar_location="above", y_axis_type=None, #x_axis_type=None,
logo="grey", plot_width=800, plot_height=100, active_drag="xbox_zoom")
p.grid.grid_line_color = None
p.axis.axis_line_color = None
#p.axis.major_tick_line_color = None
#p.yaxis.major_tick_line_color = None
p.x_range.start=-15; p.x_range.end = max(s)+15
p.y_range.start=-5; p.y_range.end = 5
p.rect("dipole_s", 'text_y', width=18, height=3, source=selected_dipole_src,
line_color="black", line_alpha=1.0, fill_alpha=0.4)
r = p.rect("dipole_s", 'text_y', width=18, height=3, source=orbit_responses_src,
#hover_color='red', hover_alpha=0.4,
line_color="black", line_alpha=0.2, fill_alpha=0.2)
#p.line([p.x_range.start, p.x_range.end], 0, line_color="black", line_alpha=0.3)
labels = LabelSet(x="dipole_s", y='text_y', text="dipole", x_offset=0, y_offset=0,
text_font_size="9pt", text_color="black",
source=orbit_responses_src, text_align='center', text_baseline='middle')
p.add_layout(labels)
hover_callback = CustomJS(args={
'src': orbit_responses_src,
'dipole_src': selected_dipole_src,
's_src': selected_orbit_response_src,
},
code='''
var indices = cb_data.index['1d'].indices;
if(indices.length > 0){
i = indices[0];
if(i != dipole_src.data.dipole_index[0]){
dipole_src.data.dipole_index[0] = i;
data = src.data;
dipole = data.dipole[i];
s = data.dipole_s[i];
y = data.text_y[i];
dipole_src.data.dipole_s[0] = s;
dipole_src.data.text_y[0] = y;
s_src.data.x_response = src.data.x_resp[i];
s_src.data.x_response_err = src.data.x_err[i];
s_src.data.y_response = src.data.y_resp[i];
s_src.data.y_response_err = src.data.y_err[i];
//console.log(dipole);
s_src.trigger('change');
dipole_src.trigger('change');
}
}
''')
p.add_tools(HoverTool(tooltips=None, callback=hover_callback, renderers=[r]))
p_dipoles = p
p = figure(tools="save,box_zoom,pan,reset,hover", toolbar_location="above",
logo="grey", plot_width=800, plot_height=400, active_drag="box_zoom")
p.x_range.start=-15; p.x_range.end = max(s)+15
p.y_range.start=-5.0; p.y_range.end = +5.0
p.xaxis.axis_label='s (m)'
p.yaxis.axis_label=ylabel
p.line('bpm_s', 'x_response', source=selected_orbit_response_src, color='red',
line_width=2, line_alpha=0.2, line_dash = [5, 2], legend='dx/dI')
c1 = p.circle('bpm_s', 'x_response', source=selected_orbit_response_src, color='red',
legend='dx/dI')
r1 = p.rect("bpm_s", 'x_response', width=1.5, height='x_response_err', source=selected_orbit_response_src,
line_color=None, fill_color='red', fill_alpha=0.3)
p.line('bpm_s', 'y_response', source=selected_orbit_response_src, color='blue',
line_width=2, line_alpha=0.2, line_dash = [5, 2], legend='dy/dI')
c2 = p.circle('bpm_s', 'y_response', source=selected_orbit_response_src, color='blue',
legend='dy/dI')
r2 = p.rect("bpm_s", 'y_response', width=1.5, height='y_response_err', source=selected_orbit_response_src,
line_color=None, fill_color='blue', fill_alpha=0.3)
tips = [
('BPM', '@bpm_name'),
]
hover = p.select_one(HoverTool)
hover.tooltips = tips
hover.renderers=[c1,c2,r1,r2]
#p.add_tools(HoverTool(tooltips=tips, renderers=[c1,c2]))
p.legend.background_fill_alpha = 0.4
lay=gridplot([
[p_dipoles],
[p]
], toolbar_location='right')
return lay
lay_x = plot_responses(xDipoles, 'BPM response to x-kick (mm/A)')
lay_y = plot_responses(yDipoles, 'BPM response to y-kick (mm/A)')
tab1 = Panel(child=lay_x, title="H-dipoles")
tab2 = Panel(child=lay_y, title="V-dipoles")
tabs = Tabs(tabs=[ tab1, tab2 ]) #, width=730
show(gridplot([[tabs]], sizing_mode='scale_width', merge_tools=False))
Saving processed data for later use:
#df_ORM.to_csv('2016-11-22_ORM_nb.txt', sep = ' ', float_format='%.4e')
#df_DATA_t.to_csv('2016-11-22_ORBITS_nb.txt', sep = ' ', float_format='%.4e')