Skip to content
Snippets Groups Projects
Commit 36c68fc4 authored by Philipp Niedermayer's avatar Philipp Niedermayer
Browse files

Documentation

parent 6316adea
No related branches found
No related tags found
No related merge requests found
......@@ -12,7 +12,61 @@ git submodule init
git -c http.sslVerify=false submodule update bdiolib
```
### Examples
**Tip**: In jupyter notbooks press SHIFT+TAB to show method signature and docstrings
- https://git.gsi.de/p.niedermayer/data-analysis-2022-05-06-exciter/-/blob/main/analysis.ipynb
- https://git.gsi.de/p.niedermayer/data-analysis-2022-05-08-btf/-/blob/main/analysis.ipynb
```python
from analysis_utils.data import *
from analysis_utils.fitting import *
from analysis_utils.plotting import *
fig, ax = plt.subplots(constrained_layout=True)
# Libera bunch-by-bunch data
data = LiberaBBBData.from_file('libera_ireg_dump.bin').to_tbt_data(h=2)
plot_tbt(ax, data, 'fxys',
turn_range=(0, 1900000),
over_time=True,
)
plot_tune_spectrogram(ax, data, 'x',
over_time=True,
)
plot_tune_spectrum(ax, data, 'x',
tune_range=(0.315,0.335)
smoothing=500,
fit=fit_lorenzian,
)
# Data from old SIS18 IPM
data = IPMData.from_file(d['ipm'],
from_event=EVT_MB_TRIGGER,
)
ax.imshow(data.x.T, extent=(data.t[0], data.t[-1], data.w[-1], data.w[0]),
aspect='auto', rasterized=True, cmap='gist_heat_r', vmin=0, vmax=100
)
plot_beam_size(ax, data, 'x',
time_range=(2, 4),
smoothing=10
)
# Data from SIS18 BTF Network analyser
data = NWAData.from_file('magnitude.csv', 'phase.csv'],
isdeg=True, unwrap=True)
data.m_unit = 'dB'
plot_btf(ax1, ax2, data,
frev=854e3
)
```
......
......@@ -54,7 +54,8 @@ class LassieSpillData(Trace):
"""Read in time series data from a *.tdf file saved with lassiespill or DCCT application
:param fname: path to filename
:param from_event: return data from this event, time will also be relative to this event
:param from_event: return data from this event, time will also be relative to this event
:param time_offset: adds a given time offset (in s) to the timestamps
References: https://git.acc.gsi.de/bi/bdiolib.python
"""
......@@ -170,8 +171,9 @@ class IPMData(Trace):
:param fname: path to filename
:param clean: if True, use calibrated data from adc_clean.dat instead of raw data from adc.dat
:param from_event: return data from this event on, time will also be relative to this event
:param subtract_background: if True, subtract background level prior to injection
:param from_event: return data from this event on, time will also be relative to this event
:param time_offset: adds a given time offset (in s) to the timestamps
References:
Giacomini, Tino <T.Giacomini@gsi.de>
......@@ -291,6 +293,8 @@ class LiberaBBBData(LiberaData):
"""Read in bunch-by-bunch data from a *.bin file saved with libera-ireg
:param fname: path to filename
:param time_offset: adds a given time offset (in s) to the timestamps
References: Libera_Hadron_User_Manual_1.04.pdf
"""
bunch = np.memmap(fname, dtype=np.dtype([
......@@ -341,7 +345,7 @@ class NWAData(Trace):
def from_file(cls, magfile, phasefile=None, *, isdeg=True, unwrap=False, verbose=0):
"""Read in data from CSV file for magnitude and phase
:param magfile: path to filename with magnitude trace data
:param magfile: path to filename with magnitude trace data (and optional phase data, see phasefile)
:param phasefile: path to filename with phase trace data. If None, phase data is assumed to be the second column in magfile.
:param unwrap: if true, relative phase is unwraped to absolute phase centered around zero
:param isdeg: if phase data is in degree (True) or radians (False)
......
......@@ -64,7 +64,7 @@ def add_resonance_vlines(axes, max_order, color='r'):
alpha=1/max(1, m-2), text_vertical=True, text_top=True)
def subplot_shared_labels(axes, xlabel=None, ylabel=None, clear='auto'):
"""Adds labels to shared axes as needed
"""Adds and removes labels to shared axes as needed
:param axes: 2D array of axes from subplots (pass squeeze=False to plt.subplots if required)
:param xlabel: the shared xlabel
......@@ -88,6 +88,11 @@ def subplot_shared_labels(axes, xlabel=None, ylabel=None, clear='auto'):
axes[r,c].set(ylabel=ylabel)
def grid_diagonal(ax, **kwargs):
"""Adds a diagonal grid to the given axes
:param ax: the axes
:param kwargs: optional arguments passed to ax.axline
"""
for k, v in dict(color='lightgray',lw=1,zorder=-100).items():
kwargs.setdefault(k, v)
xlim, ylim = ax.get_xlim(), ax.get_ylim()
......@@ -102,8 +107,14 @@ def grid_diagonal(ax, **kwargs):
def fiberplot(ax, datasets, *, labels=[None, None], vertical=True):
"""Create a
:param datasets: 2D array of datasets (position, x, y) or dict with two levels
"""Create a fiberplot with multiple datasets of x and y data
x is plotted on the horizontal (vertical) axis
y determines the height (width) of the fiberplot
position of each dataset determines the fiberplot position on the vertical (horizontal) axis
label can be used to compare 2 categories where the fiberplot is split into two
:param datasets: 2D array of datasets [(position, x, y), ...] or dict with two levels {label: {position: (x,y), ...}, ...}
"""
if type(datasets) is dict:
labels = list(datasets.keys())
......@@ -163,7 +174,11 @@ def turn_or_time_range(time, turn_range=None, time_range=None):
def plot_tbt(ax, libera_data, what='fsxy', *, over_time=True, turn_range=None, time_range=None):
"""Plot turn-by-turn data
:param what: list of signals to plot: f, s, x, y
:param libera_data: instance of LiberaTBTData
:param what: signals to plot, any combination of 'f' (revolution frequency), 's' (sum signal), 'x' and/or 'y' (position)
:param over_time: if True, plot data as function of time rather than turn
:param turn_range: (start, stop) tuple of turns to plot
:param time_range: (start, stop) tuple of time in s to plot
"""
assert isinstance(libera_data, LiberaTBTData), f'Expected LiberaTBTData but got {type(libera_data)}'
......@@ -196,6 +211,14 @@ def plot_tbt(ax, libera_data, what='fsxy', *, over_time=True, turn_range=None, t
def plot_btf(axf, axp, data, *, frev=None, **kwargs):
"""Plot beam transfer function
:param axf: axis for magnitude response
:param axp: axis for phase response
:param data: instance of NWAData
:param frev: if not None, plot fraction of revolution frequency (tune) on x axis
:param kwargs: arguments passed to plot function
"""
f = data.f*(1/frev if frev else 1)
axf.plot(f, data.m, **kwargs)
......@@ -212,7 +235,10 @@ def plot_tune_spectrum(ax, libera_data, xy, turn_range=None, time_range=None, tu
:param libera_data: Instance of LiberaTBTData class
:param xy: either 'x' or 'y'
:param turn_range: tuple of (start_turn, stop_turn) for range to plot
:param turn_range: tuple of (start_time, stop_time) in seconds for range to plot
:param time_range: tuple of (start_time, stop_time) in seconds for range to plot
:param tune_range: tuple of (start_tune, stop_tune) for range to plot
:param fit: if True or any of (fit_lorenzian, fit_gaussian), determine the tune from a fit on the spectrum
:param smoothing: if specified, apply a moving average smoothing filter of this width to the data
"""
assert isinstance(libera_data, LiberaTBTData), f'Expected LiberaTBTData but got {type(libera_data)}'
......@@ -417,6 +443,13 @@ def plot_tune_spectrogram(ax, libera_data, xy, *, nperseg=2**12, noverlap=None,
###########
def plot_beam_size(ax, ipm_data, xy, time_range=None, smoothing=None, **kwargs):
"""Plot beam size as function of time from fitted IPM data
:param ipm_data: instance of IPMData
:param xy: plane to consider, either 'x' or 'y'
:param time_range: range of (start, stop) time in s to plot
:param smoothing: if specified, apply a moving average smoothing filter of this width to the data
"""
mask = irng(ipm_data.t, *time_range)
data = getattr(ipm_data, xy)[mask]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment