Online PyEmittance¶
The following will work either on a production system, or with a simulated EPICS server.
For local development, start a simulated EPICS server using the simulated_epics.ipynb
notebook, or run in a separate process:
from pyemittance.simulation_server import start_server
start_server()
In [1]:
Copied!
%load_ext autoreload
%autoreload 2
%load_ext autoreload
%autoreload 2
In [2]:
Copied!
from pyemittance import PyEmittance, print_logging
import numpy as np
print_logging() # Print log messages here
from pyemittance import PyEmittance, print_logging
import numpy as np
print_logging() # Print log messages here
In [3]:
Copied!
meas = PyEmittance(config_name='LCLS2_OTR0H04')
meas.online = True
# Set some other options
meas.add_pnts = False
meas.num_points = 7 # only matters if adapt_ranges is used.
meas.adapt_ranges = True # If helping, will ensure there are at least 7 total points
meas.check_sym = True
meas.infl_check = True
meas.show_plots = True
# Change quad bounds
meas.config_dict['meas_pv_info']['meas_device']['bounds'] = [-6, 8]
# Change settle time
meas.config_dict['meas_pv_info']['meas_device']['settle_time'] = 0.1
meas.config_dict
meas = PyEmittance(config_name='LCLS2_OTR0H04')
meas.online = True
# Set some other options
meas.add_pnts = False
meas.num_points = 7 # only matters if adapt_ranges is used.
meas.adapt_ranges = True # If helping, will ensure there are at least 7 total points
meas.check_sym = True
meas.infl_check = True
meas.show_plots = True
# Change quad bounds
meas.config_dict['meas_pv_info']['meas_device']['bounds'] = [-6, 8]
# Change settle time
meas.config_dict['meas_pv_info']['meas_device']['settle_time'] = 0.1
meas.config_dict
2023-09-02 16:00:09,852 | INFO : Initializing observer
Out[3]:
{'beamline_info': {'name': 'LCLS2', 'species': 'electron', 'Lquad': 0.1244, 'energy': 80000000.0, 'Twiss0': [1e-06, 1e-06, 5.01, 5.01, 0.049, 0.049], 'rMatx': [1, 2.2, 0, 1], 'rMaty': [1, 2.2, 0, 1]}, 'img_proc': {'subtract_bg': False, 'use_roi': False, 'avg_ims': True, 'n_to_acquire': 1, 'background_im': '/home/physics3/ml_tuning/20220805_LCLS2_inj/example_images/bg_8_6_22.npy', 'amp_threshold': 150, 'min_sigma': 3, 'max_sigma': 700, 'max_samples': 1, 'roi': {'xmin': 0, 'xmax': 100, 'ymin': 0, 'ymax': 100}}, 'meas_pv_info': {'diagnostic': {'pv': {'name': 'OTRS:HTR:330', 'image': 'OTRS:HTR:330:Image:ArrayData', 'nrow': 'OTRS:HTR:330:Image:ArraySize1_RBV', 'ncol': 'OTRS:HTR:330:Image:ArraySize0_RBV', 'resolution': 'OTRS:HTR:330:RESOLUTION', 'xsize': 'OTRS:HTR:330:XRMS', 'ysize': 'OTRS:HTR:330:YRMS'}}, 'meas_device': {'settle_time': 0.1, 'bounds': [-6, 8], 'pv': {'name': 'QUAD:HTR:120', 'cntrl': 'QUAD:HTR:120:BCTRL', 'read': 'QUAD:HTR:120:BACT'}}, 'beam_info': {'energy': ''}}, 'savepaths': {'fits': '/home/physics3/ml_tuning/20220805_LCLS2_inj/data_saving/saved_fits/', 'images': None, 'monitoring': '/home/physics3/ml_tuning/20220805_LCLS2_inj/data_saving/monitoring/', 'summaries': '/home/physics3/ml_tuning/20220805_LCLS2_inj/data_saving/summaries/', 'raw_saves': '/home/physics3/ml_tuning/20220805_LCLS2_inj/data_saving/raw_saves/', 'emit_saves': '/home/physics3/ml_tuning/20220805_LCLS2_inj/data_saving/emit_saves/', 'mon_saves': '/home/physics3/ml_tuning/20220805_LCLS2_inj/data_saving/mon_saves/', 'xopt_saves': '/home/physics3/ml_tuning/20220805_LCLS2_inj/data_saving/xopt_saves/'}}
In [4]:
Copied!
meas.observer.get_beamsizes(1.2345)
meas.observer.get_beamsizes(1.2345)
Out[4]:
{'xrms': 0.0002856050839798949, 'yrms': 0.0002720644153953202, 'xrms_err': 0, 'yrms_err': 0}
In [5]:
Copied!
# Convenience methods.
meas.quad_init, meas.quad_bounds
# Convenience methods.
meas.quad_init, meas.quad_bounds
Out[5]:
([-6, -4, -2, 0], [-6, 8])
In [6]:
Copied!
meas.config_dict.keys()
meas.config_dict.keys()
Out[6]:
dict_keys(['beamline_info', 'img_proc', 'meas_pv_info', 'savepaths'])
In [7]:
Copied!
meas.config_dict['meas_pv_info']['meas_device']
meas.config_dict['meas_pv_info']['meas_device']
Out[7]:
{'settle_time': 0.1, 'bounds': [-6, 8], 'pv': {'name': 'QUAD:HTR:120', 'cntrl': 'QUAD:HTR:120:BCTRL', 'read': 'QUAD:HTR:120:BACT'}}
In [8]:
Copied!
meas.config_dict['img_proc']
meas.config_dict['img_proc']
Out[8]:
{'subtract_bg': False, 'use_roi': False, 'avg_ims': True, 'n_to_acquire': 1, 'background_im': '/home/physics3/ml_tuning/20220805_LCLS2_inj/example_images/bg_8_6_22.npy', 'amp_threshold': 150, 'min_sigma': 3, 'max_sigma': 700, 'max_samples': 1, 'roi': {'xmin': 0, 'xmax': 100, 'ymin': 0, 'ymax': 100}}
In [9]:
Copied!
result = meas.measure_emittance()
result = meas.measure_emittance()
2023-09-02 16:00:10,019 | INFO : Initializing observer 2023-09-02 16:00:10,021 | INFO : Running online! 2023-09-02 16:00:10,022 | INFO : EPICS put QUAD:HTR:120:BCTRL = -6 2023-09-02 16:00:10,023 | INFO : Settling for 0.1 s... 2023-09-02 16:00:11,046 | INFO : 2023-09-02_16-00-11-046232 [<pyemittance.image.Image object at 0x7f1087433790>] 2023-09-02 16:00:11,276 | INFO : EPICS put QUAD:HTR:120:BCTRL = -4 2023-09-02 16:00:11,278 | INFO : Settling for 0.1 s... 2023-09-02 16:00:11,773 | INFO : 2023-09-02_16-00-11-773604 [<pyemittance.image.Image object at 0x7f1087433790>, <pyemittance.image.Image object at 0x7f108634daf0>] 2023-09-02 16:00:11,941 | INFO : EPICS put QUAD:HTR:120:BCTRL = -2 2023-09-02 16:00:11,943 | INFO : Settling for 0.1 s... 2023-09-02 16:00:12,441 | INFO : 2023-09-02_16-00-12-441863 [<pyemittance.image.Image object at 0x7f1087433790>, <pyemittance.image.Image object at 0x7f108634daf0>, <pyemittance.image.Image object at 0x7f10bc491af0>] 2023-09-02 16:00:12,596 | INFO : EPICS put QUAD:HTR:120:BCTRL = 0 2023-09-02 16:00:12,598 | INFO : Settling for 0.1 s... 2023-09-02 16:00:13,067 | INFO : 2023-09-02_16-00-13-067086 [<pyemittance.image.Image object at 0x7f1087433790>, <pyemittance.image.Image object at 0x7f108634daf0>, <pyemittance.image.Image object at 0x7f10bc491af0>, <pyemittance.image.Image object at 0x7f1085f6d130>] 2023-09-02 16:00:13,230 | INFO : Adapting ranges 2023-09-02 16:00:13,234 | INFO : Adapting ranges for x beam size measurement: [-0.725921460376747, -0.1882678836472892, 0.3493856930821686, 0.8870392698116265, 1.4246928465410842, 1.9623464232705419, 2.5] 2023-09-02 16:00:13,235 | INFO : EPICS put QUAD:HTR:120:BCTRL = -0.725921460376747 2023-09-02 16:00:13,236 | INFO : Settling for 0.1 s... 2023-09-02 16:00:13,722 | INFO : 2023-09-02_16-00-13-722030 2023-09-02 16:00:13,890 | INFO : EPICS put QUAD:HTR:120:BCTRL = -0.1882678836472892 2023-09-02 16:00:13,892 | INFO : Settling for 0.1 s... 2023-09-02 16:00:14,416 | INFO : 2023-09-02_16-00-14-416095 2023-09-02 16:00:14,577 | INFO : EPICS put QUAD:HTR:120:BCTRL = 0.3493856930821686 2023-09-02 16:00:14,580 | INFO : Settling for 0.1 s... 2023-09-02 16:00:15,049 | INFO : 2023-09-02_16-00-15-049367 2023-09-02 16:00:15,212 | INFO : EPICS put QUAD:HTR:120:BCTRL = 0.8870392698116265 2023-09-02 16:00:15,215 | INFO : Settling for 0.1 s... 2023-09-02 16:00:15,748 | INFO : 2023-09-02_16-00-15-748219 2023-09-02 16:00:15,903 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.4246928465410842 2023-09-02 16:00:15,905 | INFO : Settling for 0.1 s... 2023-09-02 16:00:16,369 | INFO : 2023-09-02_16-00-16-369151 2023-09-02 16:00:16,525 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.9623464232705419 2023-09-02 16:00:16,527 | INFO : Settling for 0.1 s... 2023-09-02 16:00:16,990 | INFO : 2023-09-02_16-00-16-990638 2023-09-02 16:00:17,151 | INFO : EPICS put QUAD:HTR:120:BCTRL = 2.5 2023-09-02 16:00:17,154 | INFO : Settling for 0.1 s... 2023-09-02 16:00:17,731 | INFO : 2023-09-02_16-00-17-731145 2023-09-02 16:00:17,898 | INFO : Adapting ranges for y beam size measurement: [-1.811576315025631, -1.0929802625213592, -0.3743842100170873, 0.3442118424871845, 1.0628078949914563, 1.7814039474957282, 2.5] 2023-09-02 16:00:17,900 | INFO : EPICS put QUAD:HTR:120:BCTRL = -1.811576315025631 2023-09-02 16:00:17,901 | INFO : Settling for 0.1 s... 2023-09-02 16:00:18,383 | INFO : 2023-09-02_16-00-18-383328 2023-09-02 16:00:18,537 | INFO : EPICS put QUAD:HTR:120:BCTRL = -1.0929802625213592 2023-09-02 16:00:18,540 | INFO : Settling for 0.1 s... 2023-09-02 16:00:19,021 | INFO : 2023-09-02_16-00-19-021105 2023-09-02 16:00:19,182 | INFO : EPICS put QUAD:HTR:120:BCTRL = -0.3743842100170873 2023-09-02 16:00:19,183 | INFO : Settling for 0.1 s... 2023-09-02 16:00:19,666 | INFO : 2023-09-02_16-00-19-666574 2023-09-02 16:00:19,835 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.0628078949914563 2023-09-02 16:00:19,837 | INFO : Settling for 0.1 s... 2023-09-02 16:00:20,302 | INFO : 2023-09-02_16-00-20-302784 2023-09-02 16:00:20,588 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.7814039474957282 2023-09-02 16:00:20,591 | INFO : Settling for 0.1 s... 2023-09-02 16:00:21,069 | INFO : 2023-09-02_16-00-21-069003 2023-09-02 16:00:21,071 | INFO : Beam params out of bounds in image 0 out of 1 samples 2023-09-02 16:00:21,234 | INFO : Resampled 0 times (max_samples = 1, beam still out of bounds 2023-09-02 16:00:21,238 | INFO : xrms 57.62 um, yrms 708.39 um (threshold: min_rms 60.60 um, max_rms 14140.00 um) 2023-09-02 16:00:21,240 | INFO : xamp 699418.11, yamp 56932.53 (amp_thresh: 150, in json) 2023-09-02 16:00:21,241 | INFO : area_x 104912717.2, area_y 8539879.0 (threshold: 1500, hardcoded) 2023-09-02 16:00:21,243 | INFO : Returning NaNs 2023-09-02 16:00:21,245 | INFO : Checking symmetry 2023-09-02 16:00:21,247 | INFO : EPICS put QUAD:HTR:120:BCTRL = 2.960845922910964 2023-09-02 16:00:21,254 | INFO : Settling for 0.1 s... 2023-09-02 16:00:21,739 | INFO : 2023-09-02_16-00-21-738973 2023-09-02 16:00:21,918 | INFO : EPICS put QUAD:HTR:120:BCTRL = 3.575307153458916 2023-09-02 16:00:21,920 | INFO : Settling for 0.1 s... 2023-09-02 16:00:22,377 | INFO : 2023-09-02_16-00-22-377582 2023-09-02 16:00:22,535 | INFO : EPICS put QUAD:HTR:120:BCTRL = 4.189768384006868 2023-09-02 16:00:22,539 | INFO : Settling for 0.1 s... 2023-09-02 16:00:23,001 | INFO : 2023-09-02_16-00-23-001832 2023-09-02 16:00:23,170 | INFO : EPICS put QUAD:HTR:120:BCTRL = 4.80422961455482 2023-09-02 16:00:23,174 | INFO : Settling for 0.1 s... 2023-09-02 16:00:23,642 | INFO : 2023-09-02_16-00-23-642348 2023-09-02 16:00:23,804 | INFO : EPICS put QUAD:HTR:120:BCTRL = 3.1159394735750903 2023-09-02 16:00:23,806 | INFO : Settling for 0.1 s... 2023-09-02 16:00:24,280 | INFO : 2023-09-02_16-00-24-280537 2023-09-02 16:00:24,600 | INFO : EPICS put QUAD:HTR:120:BCTRL = 3.9371921050085437 2023-09-02 16:00:24,603 | INFO : Settling for 0.1 s... 2023-09-02 16:00:25,075 | INFO : 2023-09-02_16-00-25-075346 2023-09-02 16:00:25,231 | INFO : EPICS put QUAD:HTR:120:BCTRL = 5.5796973678754505 2023-09-02 16:00:25,233 | INFO : Settling for 0.1 s... 2023-09-02 16:00:25,734 | INFO : 2023-09-02_16-00-25-734743 2023-09-02 16:00:25,893 | INFO : Checking inflection 2023-09-02 16:00:25,895 | INFO : Emmitance calc for 11 x points, 11 y points
Examine results¶
In [10]:
Copied!
import matplotlib.pyplot as plt
import matplotlib.pyplot as plt
In [11]:
Copied!
result
result
Out[11]:
{'quadvalsx': array([-0.72592146, -0.18826788, 0.34938569, 0.88703927, 1.42469285, 1.96234642, 2.5 , 2.96084592, 3.57530715, 4.18976838, 4.80422961]), 'beamsizesx': array([5.31078936e-04, 4.16967250e-04, 3.00199679e-04, 1.87642596e-04, 8.65015138e-05, 7.40842698e-05, 1.71003369e-04, 2.62990146e-04, 3.89370174e-04, 5.15351284e-04, 6.37011245e-04]), 'beamsizeserrx': array([6.23146215e-07, 3.90894651e-07, 2.63595986e-07, 1.18694232e-07, 2.89670715e-08, 3.39773933e-08, 9.45749799e-08, 1.97634824e-07, 3.77245628e-07, 5.77603650e-07, 8.91494299e-07]), 'error_x': False, 'emit_x': 6.380225302143409e-09, 'norm_emit_x': 9.988427795017674e-07, 'beta_x': 10.028119862136135, 'alpha_x': -2.0149667431522307, 'emit_x_err': 3.584955433519756e-12, 'norm_emit_x_err': 5.612351727459969e-10, 'beta_x_rel_err': 0.000561885398046273, 'alpha_x_rel_err': -3.2106833809592616e-20, 'sigma_11': 6.398166407732784e-08, 'sigma_12': 1.2855941797637363e-08, 'sigma_22': 3.219399141625969e-09, 'screen_sigma_11': array([2.83971546e-07, 1.73221599e-07, 9.06662915e-08, 3.56348101e-08, 7.46511500e-09, 5.50386039e-09, 2.91063180e-08, 6.92011534e-08, 1.50466086e-07, 2.62660888e-07, 4.04874363e-07]), 'screen_sigma_12': array([ 6.55439337e-08, 2.98877193e-08, 6.59080634e-09, -4.64501801e-09, -4.11404248e-09, 7.89333347e-09, 3.10905651e-08, 5.96657053e-08, 1.09927484e-07, 1.73711680e-07, 2.50613466e-07]), 'screen_sigma_22': array([1.52716516e-08, 5.39183937e-09, 9.28084757e-10, 1.74782655e-09, 7.72025889e-09, 1.87163156e-08, 3.46086547e-08, 5.20324227e-08, 8.05813407e-08, 1.15039797e-07, 1.55227948e-07]), 'quadvalsy': array([-1.81157632, -1.09298026, -0.37438421, 0.34421184, 1.06280789, 2.5 , 3.11593947, 3.93719211, 4.75844474, 5.57969737]), 'beamsizesy': array([0.00171271, 0.00151594, 0.0013238 , 0.00110886, 0.00091245, 0.0004951 , 0.00031929, 0.00010643, 0.00022087, 0.00044845]), 'beamsizeserry': array([4.42851438e-06, 3.80479429e-06, 3.08277465e-06, 2.46012153e-06, 1.61680594e-06, 7.53839455e-07, 3.65935103e-07, 4.77619333e-08, 1.74149531e-07, 4.92537533e-07]), 'error_y': False, 'emit_y': 1.3751948236228059e-08, 'norm_emit_y': 2.152907389528063e-06, 'beta_y': 10.397064147488576, 'alpha_y': 18.80069944220473, 'emit_y_err': 1.344717956408853e-11, 'norm_emit_y_err': 2.105194969798521e-09, 'beta_y_rel_err': 0.000977838145772363, 'alpha_y_rel_err': 2.804075932518792e-19, 'sigma_33': 1.4297988796500551e-07, 'sigma_34': -2.585462455340812e-07, 'sigma_44': 4.688441018814357e-07, 'screen_sigma_33': array([2.96366364e-06, 2.31644175e-06, 1.74285170e-06, 1.24574977e-06, 8.28046203e-07, 2.42748957e-07, 9.87886497e-08, 1.13466513e-08, 4.77042107e-08, 2.12716246e-07]), 'screen_sigma_34': array([ 1.56456893e-06, 1.24908096e-06, 9.65716734e-07, 7.15744832e-07, 5.00457982e-07, 1.79232797e-07, 8.83277978e-08, 1.28770548e-08, -8.34102735e-09, 2.68316655e-08]), 'screen_sigma_44': array([8.26026617e-07, 6.73616062e-07, 5.35213596e-07, 4.11382601e-07, 3.02697249e-07, 1.33114935e-07, 8.08890087e-08, 3.12810019e-08, 5.42276696e-09, 4.27355394e-09]), 'sqrt_norm_emit_4d': 1.4664296781523841e-06, 'sqrt_norm_emit_4d_err': 1.6538067541652102e-09}
In [12]:
Copied!
plt.plot(result['quadvalsx'], np.sqrt(result['screen_sigma_11']))
plt.plot(result['quadvalsx'], result['beamsizesx'], marker='x')
plt.plot(result['quadvalsx'], np.sqrt(result['screen_sigma_11']))
plt.plot(result['quadvalsx'], result['beamsizesx'], marker='x')
Out[12]:
[<matplotlib.lines.Line2D at 0x7f105b7ef1c0>]
In [13]:
Copied!
plt.plot(result['quadvalsy'], np.sqrt(result['screen_sigma_33']))
plt.plot(result['quadvalsy'], result['beamsizesy'], marker='x')
plt.plot(result['quadvalsy'], np.sqrt(result['screen_sigma_33']))
plt.plot(result['quadvalsy'], result['beamsizesy'], marker='x')
Out[13]:
[<matplotlib.lines.Line2D at 0x7f105b8b12b0>]
Observer¶
The observer keeps all measurements made, as well as extra information such as images.
In [14]:
Copied!
o = meas.observer
o.beam_meas['x']
o = meas.observer
o.beam_meas['x']
Out[14]:
[0.0017319965094041647, 0.0012677116067485394, 0.0008156152128438839, 0.0007717229143932074, 0.0006109280395657084, 0.0005310789363652958, 0.0004565024520392191, 0.00041696725034169694, 0.00037389685405919346, 0.0003001996785587896, 0.00018764259633947025, 0.0001527761765133468, 8.650151376800355e-05, nan, 7.408426981944035e-05, 0.0001710033694494241, 0.0002629901458582531, 0.00029583871423323097, 0.0003893701741397189, 0.0004609075071683442, 0.0005153512835542348, 0.0006370112451163578, 0.0007952563299734706]
In [15]:
Copied!
# Note that this was a problematic image
ix_nan = np.where(np.isnan(o.beam_meas['x']))[0][0]
ix_nan
# Note that this was a problematic image
ix_nan = np.where(np.isnan(o.beam_meas['x']))[0][0]
ix_nan
Out[15]:
13
In [16]:
Copied!
# This is the image
o.extra[ix_nan].get_sizes()
# This is the image
o.extra[ix_nan].get_sizes()
Out[16]:
{'xrms': 2.8522865575268885, 'yrms': 35.06890802299145, 'xrms_err': 0.0010253071845839176, 'yrms_err': 0.05845542290783643, 'xamp': 699418.1145178082, 'yamp': 56932.52655505132}
In [17]:
Copied!
# The observer can also set the quad and return sizes (and extra image).
dat = o.get_beamsizes(1.2345)
dat
# The observer can also set the quad and return sizes (and extra image).
dat = o.get_beamsizes(1.2345)
dat
2023-09-02 16:00:27,428 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.2345 2023-09-02 16:00:27,430 | INFO : Settling for 0.1 s... 2023-09-02 16:00:27,895 | INFO : 2023-09-02_16-00-27-895549
Out[17]:
{'xrms': 0.00012047477546215778, 'yrms': 0.0008570228573263447, 'xrms_err': 5.86217973346717e-08, 'yrms_err': 1.528657218869215e-06, 'extra': <pyemittance.image.Image at 0x7f105b696400>}
In [18]:
Copied!
# This is the image
im = dat['extra']
im
# This is the image
im = dat['extra']
im
Out[18]:
<pyemittance.image.Image at 0x7f105b696400>
In [19]:
Copied!
# This plots. TODO: make a .plot() instead
im.get_sizes()
# This plots. TODO: make a .plot() instead
im.get_sizes()
Out[19]:
{'xrms': 5.964097795156326, 'yrms': 42.42687412506657, 'xrms_err': 0.0029020691749837477, 'yrms_err': 0.07567609994402054, 'xamp': 334856.0390775527, 'yamp': 46946.04587345442}
Interactively change the quad and acquire the screen image¶
In [20]:
Copied!
import epics
import matplotlib.pyplot as plt
from ipywidgets import interact
def f(quad_value):
epics.caput('QUAD:HTR:120:BCTRL', quad_value)
a = epics.caget('OTRS:HTR:330:Image:ArrayData').reshape(1040, 1392)
sigma_x = epics.caget('sim_screen_sigma_x')
sigma_y = epics.caget('sim_screen_sigma_y')
print(sigma_x)
plt.imshow(a, vmax=128)
plt.title(f'sim sigma_x, y = {sigma_x*1e3:0.3f} {sigma_y*1e3:0.3f} mm')
# interact(f, quad_value=(-4, 4, .1))
f(0)
import epics
import matplotlib.pyplot as plt
from ipywidgets import interact
def f(quad_value):
epics.caput('QUAD:HTR:120:BCTRL', quad_value)
a = epics.caget('OTRS:HTR:330:Image:ArrayData').reshape(1040, 1392)
sigma_x = epics.caget('sim_screen_sigma_x')
sigma_y = epics.caget('sim_screen_sigma_y')
print(sigma_x)
plt.imshow(a, vmax=128)
plt.title(f'sim sigma_x, y = {sigma_x*1e3:0.3f} {sigma_y*1e3:0.3f} mm')
# interact(f, quad_value=(-4, 4, .1))
f(0)
0.00037486171231124573