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
2026-07-04 00:13:50,076 | 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.000143663801972771,
'yrms': 0.00040974781186741376,
'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()
2026-07-04 00:13:50,198 | INFO : Initializing observer
2026-07-04 00:13:50,200 | INFO : Running online!
2026-07-04 00:13:50,201 | INFO : EPICS put QUAD:HTR:120:BCTRL = -6
2026-07-04 00:13:50,201 | INFO : Settling for 0.1 s...
2026-07-04 00:13:50,708 | INFO : 2026-07-04_00-13-50-708486
2026-07-04 00:13:50,789 | INFO : EPICS put QUAD:HTR:120:BCTRL = -4
2026-07-04 00:13:50,790 | INFO : Settling for 0.1 s...
2026-07-04 00:13:51,124 | INFO : 2026-07-04_00-13-51-124779
2026-07-04 00:13:51,208 | INFO : EPICS put QUAD:HTR:120:BCTRL = -2
2026-07-04 00:13:51,209 | INFO : Settling for 0.1 s...
2026-07-04 00:13:51,540 | INFO : 2026-07-04_00-13-51-539967
2026-07-04 00:13:51,619 | INFO : EPICS put QUAD:HTR:120:BCTRL = 0
2026-07-04 00:13:51,620 | INFO : Settling for 0.1 s...
2026-07-04 00:13:51,949 | INFO : 2026-07-04_00-13-51-949714
2026-07-04 00:13:52,037 | INFO : Adapting ranges
2026-07-04 00:13:52,040 | INFO : Adapting ranges for x beam size measurement: [np.float64(-0.7232447690759222), np.float64(-0.18603730756326842), np.float64(0.35117015394938533), np.float64(0.888377615462039), np.float64(1.4255850769746927), np.float64(1.9627925384873466), np.float64(2.5)]
2026-07-04 00:13:52,040 | INFO : EPICS put QUAD:HTR:120:BCTRL = -0.7232447690759222
2026-07-04 00:13:52,041 | INFO : Settling for 0.1 s...
2026-07-04 00:13:52,428 | INFO : 2026-07-04_00-13-52-428180
2026-07-04 00:13:52,510 | INFO : EPICS put QUAD:HTR:120:BCTRL = -0.18603730756326842
2026-07-04 00:13:52,512 | INFO : Settling for 0.1 s...
2026-07-04 00:13:52,846 | INFO : 2026-07-04_00-13-52-846290
2026-07-04 00:13:52,926 | INFO : EPICS put QUAD:HTR:120:BCTRL = 0.35117015394938533
2026-07-04 00:13:52,927 | INFO : Settling for 0.1 s...
2026-07-04 00:13:53,244 | INFO : 2026-07-04_00-13-53-244276
2026-07-04 00:13:53,328 | INFO : EPICS put QUAD:HTR:120:BCTRL = 0.888377615462039
2026-07-04 00:13:53,329 | INFO : Settling for 0.1 s...
2026-07-04 00:13:53,636 | INFO : 2026-07-04_00-13-53-636005
2026-07-04 00:13:53,712 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.4255850769746927
2026-07-04 00:13:53,713 | INFO : Settling for 0.1 s...
2026-07-04 00:13:54,021 | INFO : 2026-07-04_00-13-54-021727
2026-07-04 00:13:54,194 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.9627925384873466
2026-07-04 00:13:54,195 | INFO : Settling for 0.1 s...
2026-07-04 00:13:54,505 | INFO : 2026-07-04_00-13-54-505580
2026-07-04 00:13:54,585 | INFO : EPICS put QUAD:HTR:120:BCTRL = 2.5
2026-07-04 00:13:54,586 | INFO : Settling for 0.1 s...
2026-07-04 00:13:54,894 | INFO : 2026-07-04_00-13-54-894445
2026-07-04 00:13:54,971 | INFO : Adapting ranges for y beam size measurement: [np.float64(-1.8193414082752075), np.float64(-1.0994511735626729), np.float64(-0.3795609388501384), np.float64(0.340329295862396), np.float64(1.0602195305749307), np.float64(1.7801097652874653), np.float64(2.5)]
2026-07-04 00:13:54,972 | INFO : EPICS put QUAD:HTR:120:BCTRL = -1.8193414082752075
2026-07-04 00:13:54,973 | INFO : Settling for 0.1 s...
2026-07-04 00:13:55,300 | INFO : 2026-07-04_00-13-55-300758
2026-07-04 00:13:55,378 | INFO : EPICS put QUAD:HTR:120:BCTRL = -1.0994511735626729
2026-07-04 00:13:55,380 | INFO : Settling for 0.1 s...
2026-07-04 00:13:55,695 | INFO : 2026-07-04_00-13-55-695392
2026-07-04 00:13:55,777 | INFO : EPICS put QUAD:HTR:120:BCTRL = -0.3795609388501384
2026-07-04 00:13:55,778 | INFO : Settling for 0.1 s...
2026-07-04 00:13:56,206 | INFO : 2026-07-04_00-13-56-206606
2026-07-04 00:13:56,286 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.0602195305749307
2026-07-04 00:13:56,287 | INFO : Settling for 0.1 s...
2026-07-04 00:13:56,604 | INFO : 2026-07-04_00-13-56-604004
2026-07-04 00:13:56,680 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.7801097652874653
2026-07-04 00:13:56,682 | INFO : Settling for 0.1 s...
2026-07-04 00:13:56,995 | INFO : 2026-07-04_00-13-56-995111
2026-07-04 00:13:56,995 | INFO : Beam params out of bounds in image 0 out of 1 samples
2026-07-04 00:13:57,078 | INFO : Resampled 0 times (max_samples = 1, beam still out of bounds
2026-07-04 00:13:57,079 | INFO : xrms 57.82 um, yrms 707.62 um (threshold: min_rms 60.60 um, max_rms 14140.00 um)
2026-07-04 00:13:57,079 | INFO : xamp 697452.99, yamp 56988.37 (amp_thresh: 150, in json)
2026-07-04 00:13:57,079 | INFO : area_x 104617947.9, area_y 8548255.0 (threshold: 1500, hardcoded)
2026-07-04 00:13:57,080 | INFO : Returning NaNs
2026-07-04 00:13:57,080 | INFO : Checking symmetry
2026-07-04 00:13:57,081 | INFO : EPICS put QUAD:HTR:120:BCTRL = 2.9604635384394173
2026-07-04 00:13:57,082 | INFO : Settling for 0.1 s...
2026-07-04 00:13:57,410 | INFO : 2026-07-04_00-13-57-410963
2026-07-04 00:13:57,493 | INFO : EPICS put QUAD:HTR:120:BCTRL = 3.5744149230253073
2026-07-04 00:13:57,494 | INFO : Settling for 0.1 s...
2026-07-04 00:13:57,819 | INFO : 2026-07-04_00-13-57-819165
2026-07-04 00:13:57,897 | INFO : EPICS put QUAD:HTR:120:BCTRL = 4.188366307611197
2026-07-04 00:13:57,898 | INFO : Settling for 0.1 s...
2026-07-04 00:13:58,219 | INFO : 2026-07-04_00-13-58-219392
2026-07-04 00:13:58,296 | INFO : EPICS put QUAD:HTR:120:BCTRL = 4.802317692197088
2026-07-04 00:13:58,297 | INFO : Settling for 0.1 s...
2026-07-04 00:13:58,765 | INFO : 2026-07-04_00-13-58-764966
2026-07-04 00:13:58,849 | INFO : EPICS put QUAD:HTR:120:BCTRL = 3.117048772610744
2026-07-04 00:13:58,850 | INFO : Settling for 0.1 s...
2026-07-04 00:13:59,169 | INFO : 2026-07-04_00-13-59-169054
2026-07-04 00:13:59,251 | INFO : EPICS put QUAD:HTR:120:BCTRL = 3.939780469425069
2026-07-04 00:13:59,252 | INFO : Settling for 0.1 s...
2026-07-04 00:13:59,563 | INFO : 2026-07-04_00-13-59-563812
2026-07-04 00:13:59,643 | INFO : EPICS put QUAD:HTR:120:BCTRL = 5.585243863053719
2026-07-04 00:13:59,644 | INFO : Settling for 0.1 s...
2026-07-04 00:13:59,958 | INFO : 2026-07-04_00-13-59-958634
2026-07-04 00:14:00,035 | INFO : Checking inflection
2026-07-04 00:14:00,036 | 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.72324477, -0.18603731, 0.35117015, 0.88837762, 1.42558508,
1.96279254, 2.5 , 2.96046354, 3.57441492, 4.18836631,
4.80231769]),
'beamsizesx': array([5.33260702e-04, 4.15971171e-04, 2.99923812e-04, 1.88860487e-04,
8.61090562e-05, 7.52340967e-05, 1.70472681e-04, 2.63713474e-04,
3.86824108e-04, 5.12112156e-04, 6.37280472e-04]),
'beamsizeserrx': array([6.21853130e-07, 5.10692389e-07, 2.46032491e-07, 1.08739826e-07,
3.89476356e-08, 2.94820609e-08, 9.44353798e-08, 2.20338375e-07,
3.76212681e-07, 6.19684093e-07, 8.53500324e-07]),
'error_x': False,
'emit_x': np.float64(6.457885947220003e-09),
'norm_emit_x': np.float64(1.0110007774097442e-06),
'beta_x': np.float64(9.88893084649848),
'alpha_x': np.float64(-1.9771686591702444),
'emit_x_err': np.float64(3.750665074768893e-12),
'norm_emit_x_err': np.float64(5.871774969991966e-10),
'beta_x_rel_err': np.float64(0.0005807883733814598),
'alpha_x_rel_err': np.float64(-3.701367451274716e-20),
'sigma_11': np.float64(6.386158754663294e-08),
'sigma_12': np.float64(1.2768329699339337e-08),
'sigma_22': np.float64(3.2059105024414173e-09),
'screen_sigma_11': array([2.82291041e-07, 1.72113243e-07, 9.00232900e-08, 3.53533920e-08,
7.44448345e-09, 5.64614782e-09, 2.93165407e-08, 6.93961601e-08,
1.50538539e-07, 2.62497676e-07, 4.04366410e-07]),
'screen_sigma_12': array([ 6.50495700e-08, 2.96082474e-08, 6.47937852e-09, -4.63390597e-09,
-4.02457214e-09, 8.01828271e-09, 3.12093956e-08, 5.97471400e-08,
1.09914311e-07, 1.73554435e-07, 2.50264475e-07]),
'screen_sigma_22': array([1.51373945e-08, 5.33574634e-09, 9.29610958e-10, 1.78702444e-09,
7.77776890e-09, 1.87733570e-08, 3.46470164e-08, 5.20407040e-08,
8.05299438e-08, 1.14907098e-07, 1.54993120e-07]),
'quadvalsy': array([-1.81934141, -1.09945117, -0.37956094, 0.3403293 , 1.06021953,
2.5 , 3.11704877, 3.93978047, 4.76251217, 5.58524386]),
'beamsizesy': array([0.00170402, 0.00151884, 0.00131597, 0.00111439, 0.00091513,
0.00049673, 0.00031826, 0.00010627, 0.00021874, 0.00044649]),
'beamsizeserry': array([4.65995821e-06, 3.77826930e-06, 2.91747116e-06, 2.41618635e-06,
1.68569319e-06, 6.54168749e-07, 3.22952446e-07, 5.37117857e-08,
1.62023649e-07, 6.12369815e-07]),
'error_y': False,
'emit_y': np.float64(1.3608959098343318e-08),
'norm_emit_y': np.float64(2.130522022316816e-06),
'beta_y': np.float64(10.492569462416359),
'alpha_y': np.float64(18.995341192474754),
'emit_y_err': np.float64(1.3602061746848477e-11),
'norm_emit_y_err': np.float64(2.12944222193317e-09),
'beta_y_rel_err': np.float64(0.0009994931756677483),
'alpha_y_rel_err': np.float64(2.735086143616672e-19),
'sigma_33': np.float64(1.4279294865055036e-07),
'sigma_34': np.float64(-2.585068213474649e-07),
'sigma_44': np.float64(4.692877420362188e-07),
'screen_sigma_33': array([2.97311315e-06, 2.32423852e-06, 1.74910719e-06, 1.25058605e-06,
8.31596249e-07, 2.44170665e-07, 9.94978778e-08, 1.13106786e-08,
4.71741798e-08, 2.11962512e-07]),
'screen_sigma_34': array([ 1.56895236e-06, 1.25273280e-06, 9.68685240e-07, 7.18082971e-07,
5.02223562e-07, 1.80046749e-07, 8.88210553e-08, 1.30322374e-08,
-8.41400575e-09, 2.66489795e-08]),
'screen_sigma_44': array([8.28019850e-07, 6.75285547e-07, 5.36580208e-07, 4.12469304e-07,
3.03529159e-07, 1.33521510e-07, 8.11513151e-08, 3.13900689e-08,
5.42668175e-09, 4.22419922e-09]),
'sqrt_norm_emit_4d': np.float64(1.4676373601305199e-06),
'sqrt_norm_emit_4d_err': np.float64(1.6965670420503978e-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 0x7f29bcac4c40>]
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 0x7f29bc91e590>]
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]:
[np.float64(0.0017250140189747276), np.float64(0.001271292105050032), np.float64(0.0008134551493821093), np.float64(0.0007686877047519976), np.float64(0.0006175411348857564), np.float64(0.0005332607018341535), np.float64(0.00045752728454358466), np.float64(0.0004159711706901915), np.float64(0.0003750547515657457), np.float64(0.0002999238119602337), np.float64(0.00018886048720329982), np.float64(0.00015378331546266248), np.float64(8.610905623978902e-05), nan, np.float64(7.52340967108487e-05), np.float64(0.0001704726810445484), np.float64(0.00026371347360741257), np.float64(0.0002948869651276345), np.float64(0.0003868241081107097), np.float64(0.0004637338717222228), np.float64(0.0005121121556323335), np.float64(0.0006372804721640243), np.float64(0.0007970697193868257)]
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]:
np.int64(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': np.float64(2.862437989475247),
'yrms': np.float64(35.03070925825606),
'xrms_err': np.float64(0.0008127192868587119),
'yrms_err': np.float64(0.05558532805863923),
'xamp': np.float64(697452.986218199),
'yamp': np.float64(56988.3664091905)}
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
2026-07-04 00:14:00,757 | INFO : EPICS put QUAD:HTR:120:BCTRL = 1.2345
2026-07-04 00:14:00,758 | INFO : Settling for 0.1 s...
2026-07-04 00:14:01,073 | INFO : 2026-07-04_00-14-01-073045
Out[17]:
{'xrms': np.float64(0.00011962636653257673),
'yrms': np.float64(0.0008539082496760955),
'xrms_err': np.float64(6.114942460212805e-08),
'yrms_err': np.float64(1.5701596782123082e-06),
'extra': <pyemittance.image.Image at 0x7f29bc9de0e0>}
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 0x7f29bc9de0e0>
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': np.float64(5.9220973530978585),
'yrms': np.float64(42.27268562752948),
'xrms_err': np.float64(0.0030271992377291115),
'yrms_err': np.float64(0.07773067713922319),
'xamp': np.float64(336769.3049554571),
'yamp': np.float64(47122.83719484807)}
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.00037486171256434335