diff --git a/config/spectrum_config.yaml b/config/spectrum_config.yaml new file mode 100644 index 0000000000000000000000000000000000000000..433f84e7eafc7a3a45b36d8f5da8993885f2dcae --- /dev/null +++ b/config/spectrum_config.yaml @@ -0,0 +1,80 @@ +# Dict with uid's as key and a nested dict with configuration variables +general: + runtime: 600 # desired runtime in seconds + runevents: &number_of_events 100000 + number_of_samples: &number_of_samples 2048 + analogue_offset: &analogue_offset 0 + sample_time_ns: &sample_time_ns 32 + + trigger_level: &trigger_level 50 + trigger_channel: &trigger_channel '1' + trigger_direction: &trigger_direction 'rising' + pre_trigger_samples: &pre_trigger_samples 103 # 5% + +find_peaks: + sample_time_ns: *sample_time_ns + analogue_offset: *analogue_offset + number_of_samples: *number_of_samples + pre_trigger_samples: *pre_trigger_samples + peak_minimal_prominence: 50 # has to be positive and higher than avg. noise peaks to not cause havoc! + trigger_channel: *trigger_channel + peak_minimal_distance: 10 # minimal distance between two peaks in number of samples + peak_minimal_width: 7 # in number of samples + trigger_channel: *trigger_channel + trigger_position_tolerance: 7 # in number of samples + +# dict for RedPitaya redPoscidaq +redP_to_rb: + ip_address: '192.168.0.103' + eventcount: *number_of_events + sample_time_ns: *sample_time_ns + number_of_samples: *number_of_samples + pre_trigger_samples: *pre_trigger_samples + trigger_channel: *trigger_channel + trigger_level: *trigger_level + trigger_mode: 'norm' + +# Dict for simul_source.py +simul_source: + sample_time_ns: *sample_time_ns + number_of_samples: *number_of_samples + pre_trigger_samples: *pre_trigger_samples + analogue_offset: *analogue_offset + eventcount: *number_of_events + sleeptime: 0.03 + random: true + +# Dict for push_simul +push_simul: + sample_time_ns: *sample_time_ns + number_of_samples: *number_of_samples + pre_trigger_samples: *pre_trigger_samples + analogue_offset: *analogue_offset + eventcount: *number_of_events + sleeptime: 0.03 + random: true + +save_to_txt: + filename: "spectrum" + +save_parquet: + filename: "spectrum" + +plot_waveform: + title: "Muon waveform" + min_sleeptime: 0.5 # time to wait between graphics updates + number_of_samples: *number_of_samples + sample_time_ns: *sample_time_ns + analogue_offset: *analogue_offset # analogue offset in V + pre_trigger_samples: *pre_trigger_samples + channel_range: 4096 # channel range in mV + trigger_channel: *trigger_channel # Channel name in the PicoScope. Valid values are 'A', 'B', 'C' or 'D' + trigger_level: *trigger_level # value in mV, take account of analogue_offset, which is added to input voltage ! + +plot_histograms: + title: "on-line histograms" + # define histograms + histograms: + # name min max nbins ymax name lin/log + chA_height: [50., 3000., 250, 5.9, "ph 1A", 0] + chB_height: [50., 3000., 250, 5.9, "ph 1B", 0] diff --git a/modules/#redPitaya_source.py# b/modules/#redPitaya_source.py# new file mode 100644 index 0000000000000000000000000000000000000000..423ea6f6eec0cb87650aea3b7c5b96f638388e63 --- /dev/null +++ b/modules/#redPitaya_source.py# @@ -0,0 +1,64 @@ +""" +**redPitaya_source**: mimoCoRB source compatible to redPoscdaq + +Input data is provided as numpy-arry of shape (number_of_channels, number_of_samples). +""" + +from mimocorb.buffer_control import rbImport +import numpy as np +import sys, time +from mutiprocessing import Event + +def simul_source(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + """ + Generate simulated data and pass data to buffer + + The class mimocorb.buffer_control/rbImport is used to interface to the + newBuffer and Writer classes of the package mimoCoRB.mimo_buffer + + This example may serve as a template for other data sources + + :param config_dict: configuration dictionary + + - events_required: number of events to be simulated or 0 for infinite + - sleeptime: (mean) time between events + - random: random time between events according to a Poission process + - number_of_samples, sample_time_ns, pretrigger_samples and analogue_offset + describe the waveform data to be generated (as for oscilloscope setup) + + Internal parameters of the simulated physics process (the decay of a muon) + are (presently) not exposed to user. + """ + + global databuffer + data_ready = Event() + data_ready.clear() + + run_rpControl(callback=rp_data) + + def rp_data(data): + while data_ready.is_set(): + time.sleep(0.01) + databuffer = data + data_ready.set() + + events_required = 1000 if "eventcount" not in config_dict else config_dict["eventcount"] + + def yield_data(): + """generate simulated data, called by instance of class mimoCoRB.rbImport""" + + event_count = 0 + while events_required == 0 or event_count < events_required: + data_ready.wait() + # deliver pulse data and no metadata + yield (databuffer, None) + data_ready.clear() + event_count += 1 + + datasource = rbImport(config_dict=config_dict, sink_list=sink_list, ufunc=yield_data, **rb_info) + # possibly check consistency of provided dtype with simulation ! + + # TODO: Change to logger! + # print("** simul_source ** started, config_dict: \n", config_dict) + # print("?> sample interval: {:02.1f}ns".format(osci.time_interval_ns.value)) + datasource() diff --git a/modules/__pycache__/filters.cpython-310.pyc b/modules/__pycache__/filters.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9aef4eb7f1388cf9ab8704995f557ad269652889 Binary files /dev/null and b/modules/__pycache__/filters.cpython-310.pyc differ diff --git a/modules/__pycache__/filters.cpython-311.pyc b/modules/__pycache__/filters.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb6d48f582732eccf3eeb668b632970fc3d21180 Binary files /dev/null and b/modules/__pycache__/filters.cpython-311.pyc differ diff --git a/modules/__pycache__/plot_histograms.cpython-310.pyc b/modules/__pycache__/plot_histograms.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cf4bec83dff02352931ad37bd2a6f2832be03571 Binary files /dev/null and b/modules/__pycache__/plot_histograms.cpython-310.pyc differ diff --git a/modules/__pycache__/plot_histograms.cpython-311.pyc b/modules/__pycache__/plot_histograms.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..888023e5d33dc72af599714231aa19140b3b82eb Binary files /dev/null and b/modules/__pycache__/plot_histograms.cpython-311.pyc differ diff --git a/modules/__pycache__/plot_waveform.cpython-310.pyc b/modules/__pycache__/plot_waveform.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4803edcf405c5ab825674ee3fc3f085ebe0cf1e Binary files /dev/null and b/modules/__pycache__/plot_waveform.cpython-310.pyc differ diff --git a/modules/__pycache__/plot_waveform.cpython-311.pyc b/modules/__pycache__/plot_waveform.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..13b544f98c384cbdc54a7eff10c19b584be60ad5 Binary files /dev/null and b/modules/__pycache__/plot_waveform.cpython-311.pyc differ diff --git a/modules/__pycache__/save_files.cpython-310.pyc b/modules/__pycache__/save_files.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..d2288e065bf1d008f36656f6533fcbd3773e07f4 Binary files /dev/null and b/modules/__pycache__/save_files.cpython-310.pyc differ diff --git a/modules/__pycache__/save_files.cpython-311.pyc b/modules/__pycache__/save_files.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8438319ec401b1a914fec694630618c82f38c344 Binary files /dev/null and b/modules/__pycache__/save_files.cpython-311.pyc differ diff --git a/modules/__pycache__/spectrum_filter.cpython-310.pyc b/modules/__pycache__/spectrum_filter.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2654ba2c30ba1ff2f15a2e882c28db1786368ca7 Binary files /dev/null and b/modules/__pycache__/spectrum_filter.cpython-310.pyc differ diff --git a/modules/__pycache__/spectrum_filter.cpython-311.pyc b/modules/__pycache__/spectrum_filter.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..cb8923dcc4ebbf21c4b01e74dd7460d7a7ed07df Binary files /dev/null and b/modules/__pycache__/spectrum_filter.cpython-311.pyc differ diff --git a/modules/filters.py b/modules/filters.py new file mode 100644 index 0000000000000000000000000000000000000000..7158cc661b40f5a14d37270f9957aa3b21079aaf --- /dev/null +++ b/modules/filters.py @@ -0,0 +1,94 @@ +from mimocorb import mimo_buffer as bm +from scipy import signal +import numpy as np +from numpy.lib import recfunctions as rfn +import sys +import os + + +def normed_pulse(ch_input, position, prominence, analogue_offset): + # > Compensate for analogue offset + ch_data = ch_input - analogue_offset + # > Find pulse area + # rel_height is not good because of the quantized nature of the picoscope data + # so we have to "hack" a little bit to always cut 10mV above the analogue offset + width_data = signal.peak_widths(ch_data, [int(position)], rel_height=(ch_data[int(position)] - 10) / prominence) + left_ips, right_ips = width_data[2], width_data[3] + # Crop pulse area and normalize + pulse_data = ch_data[int(np.floor(left_ips)) : int(np.ceil(right_ips))] + pulse_int = sum(pulse_data) + pulse_data *= 1 / pulse_int + return pulse_data, int(np.floor(left_ips)), pulse_int + + +def correlate_pulses(data_pulse, reference_pulse): + correlation = signal.correlate(data_pulse, reference_pulse, mode="same") + shift_array = signal.correlation_lags(data_pulse.size, reference_pulse.size, mode="same") + shift = shift_array[np.argmax(correlation)] + return shift + + +def tag_peaks(input_data, prominence, distance, width): + peaks = {} + peaks_prop = {} + for key in input_data.dtype.names: + peaks[key], peaks_prop[key] = signal.find_peaks( + input_data[key], prominence=prominence, distance=distance, width=width + ) + return peaks, peaks_prop + + +def correlate_peaks(peaks, tolerance): + m_dtype = [] + for key in peaks.keys(): + m_dtype.append((key, np.int32)) + next_peak = {} + for key, data in peaks.items(): + if len(data) > 0: + next_peak[key] = data[0] + correlation_list = [] + while len(next_peak) > 0: + minimum = min(next_peak.values()) + line = [] + for key, data in peaks.items(): + if key in next_peak: + if abs(next_peak[key] - minimum) < tolerance: + idx = data.tolist().index(next_peak[key]) + line.append(idx) + if len(data) > idx + 1: + next_peak[key] = data[idx + 1] + else: + del next_peak[key] + else: + line.append(-1) + else: + line.append(-1) + correlation_list.append(line) + array = np.zeros(len(correlation_list), dtype=m_dtype) + for idx, line in enumerate(correlation_list): + array[idx] = tuple(line) + return array + + +def match_signature(peak_matrix, signature): + if len(signature) > len(peak_matrix): + return False + # Boolean array with found peaks + input_peaks = rfn.structured_to_unstructured(peak_matrix) >= 0 + must_have_peak = np.array(signature, dtype=np.str0) == "+" + must_not_have_peak = np.array(signature, dtype=np.str0) == "-" + match = True + # Check the signature for each peak (1st peak with 1st signature, 2nd peak with 2nd signature, ...) + for idx in range(len(signature)): + # Is everywhere a peak, where the signature expects one -> Material_conditial(A, B): (not A) OR B + first = (~must_have_peak[idx]) | input_peaks[idx] + # Is everywhere no peak, where the signature expects no peak -> NAND(A, B): not (A and B) + second = ~(must_not_have_peak[idx] & input_peaks[idx]) + match = match & (np.all(first) & np.all(second)) + return match + + +if __name__ == "__main__": + print("Script: " + os.path.basename(sys.argv[0])) + print("Python: ", sys.version, "\n".ljust(22, "-")) + print("THIS IS A MODULE AND NOT MEANT FOR STANDALONE EXECUTION") diff --git a/modules/plot_histograms.py b/modules/plot_histograms.py new file mode 100644 index 0000000000000000000000000000000000000000..fce24083a9721625b0c7aa07dfedcce46c61913d --- /dev/null +++ b/modules/plot_histograms.py @@ -0,0 +1,27 @@ +""" +**plot_histograms**: histogram variable(s) from buffer using mimoCoRB.histogram_buffer +""" +import sys +import os +from mimocorb.histogram_buffer import histogram_buffer +import matplotlib + +# select matplotlib frontend if needed +matplotlib.use("TkAgg") + + +def plot_histograms(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + """ + Online display of histogram(s) of variable(s) from mimiCoRB buffer + + :param input: configuration dictionary + + """ + histbuf = histogram_buffer(source_list, sink_list, observe_list, config_dict, **rb_info) + histbuf() + + +if __name__ == "__main__": + print("Script: " + os.path.basename(sys.argv[0])) + print("Python: ", sys.version, "\n".ljust(22, "-")) + print("THIS IS A MODULE AND NOT MEANT FOR STANDALONE EXECUTION") diff --git a/modules/plot_waveform.py b/modules/plot_waveform.py new file mode 100644 index 0000000000000000000000000000000000000000..66d0c1285844f59b16078bbce6aa6a68e7fd96f0 --- /dev/null +++ b/modules/plot_waveform.py @@ -0,0 +1,33 @@ +""" +**plot**: plotting waveforms from buffer using mimoCoRB.buffer_control.OberserverData +""" + +import sys +import os +from mimocorb.plot_buffer import plot_buffer +import matplotlib + +# select matplotlib frontend if needed +matplotlib.use("TkAgg") + + +def plot_waveform(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + """ + Plot waveform data from mimiCoRB buffer + + :param input: configuration dictionary + + - plot_title: graphics title to be shown on graph + - min_sleeptime: time between updates + - sample_time_ns, channel_range, pretrigger_samples and analogue_offset + describe the waveform data as for oscilloscope setup + """ + + pltbuf = plot_buffer(source_list, sink_list, observe_list, config_dict, **rb_info) + pltbuf() + + +if __name__ == "__main__": + print("Script: " + os.path.basename(sys.argv[0])) + print("Python: ", sys.version, "\n".ljust(22, "-")) + print("THIS IS A MODULE AND NOT MEANT FOR STANDALONE EXECUTION") diff --git a/modules/redPitaya_source.py b/modules/redPitaya_source.py new file mode 100644 index 0000000000000000000000000000000000000000..adabc04e3d9c19d87c520fc2f9f4fe7e67d37366 --- /dev/null +++ b/modules/redPitaya_source.py @@ -0,0 +1,54 @@ +""" +**simul_source**: a simple template for a mimoCoRB source to +enter simulated wave form data in a mimoCoRB buffer. + +Input data is provided as numpy-arry of shape (number_of_channels, number_of_samples). +""" + +from mimocorb.buffer_control import rbImport +import numpy as np +import sys, time +from pulseSimulator import pulseSimulator + +def simul_source(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + """ + Generate simulated data and pass data to buffer + + The class mimocorb.buffer_control/rbImport is used to interface to the + newBuffer and Writer classes of the package mimoCoRB.mimo_buffer + + This example may serve as a template for other data sources + + :param config_dict: configuration dictionary + + - events_required: number of events to be simulated or 0 for infinite + - sleeptime: (mean) time between events + - random: random time between events according to a Poission process + - number_of_samples, sample_time_ns, pretrigger_samples and analogue_offset + describe the waveform data to be generated (as for oscilloscope setup) + + Internal parameters of the simulated physics process (the decay of a muon) + are (presently) not exposed to user. + """ + + events_required = 1000 if "eventcount" not in config_dict else config_dict["eventcount"] + + def yield_data(): + """generate simulated data, called by instance of class mimoCoRB.rbImport""" + + event_count = 0 + while events_required == 0 or event_count < events_required: + pulse = dataSource(number_of_channels) + # deliver pulse data and no metadata + yield (pulse, None) + event_count += 1 + + dataSource = pulseSimulator(config_dict) + simulsource = rbImport(config_dict=config_dict, sink_list=sink_list, ufunc=yield_data, **rb_info) + number_of_channels = len(simulsource.sink.dtype) + # possibly check consistency of provided dtype with simulation ! + + # TODO: Change to logger! + # print("** simul_source ** started, config_dict: \n", config_dict) + # print("?> sample interval: {:02.1f}ns".format(osci.time_interval_ns.value)) + simulsource() diff --git a/modules/save_files.py b/modules/save_files.py new file mode 100644 index 0000000000000000000000000000000000000000..00074474b6df256672f533db358c2095f8f53bd3 --- /dev/null +++ b/modules/save_files.py @@ -0,0 +1,26 @@ +"""Module save_files to handle file I/O for data in txt and parquet format + + This module relies on classes in mimocorb.buffer_control +""" + +import sys +import os +from mimocorb.buffer_control import rb_toTxtfile, rb_toParquetfile + + +# def save_to_txt(source_dict): +def save_to_txt(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + sv = rb_toTxtfile(source_list=source_list, config_dict=config_dict, **rb_info) + sv() + # print("\n ** save_to_txt: end seen") + + +def save_parquet(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + sv = rb_toParquetfile(source_list=source_list, config_dict=config_dict, **rb_info) + sv() + + +if __name__ == "__main__": + print("Script: " + os.path.basename(sys.argv[0])) + print("Python: ", sys.version, "\n".ljust(22, "-")) + print("THIS IS A MODULE AND NOT MEANT FOR STANDALONE EXECUTION") diff --git a/modules/spectrum_filter.py b/modules/spectrum_filter.py new file mode 100644 index 0000000000000000000000000000000000000000..fc8022812bbb879437cff68176f26b0e89f64d83 --- /dev/null +++ b/modules/spectrum_filter.py @@ -0,0 +1,106 @@ +"""Module **pulse_filter** + +This (rather complex) module filters waveform data to search for valid signal pulses. +The code first validates the trigger pulse, identifies coincidences of signals in +different layers (indiating the passage of a cosmic ray particle, a muon) and finally +searches for double-pulse signatures indicating that a muon was stopped in or near +a detection layer where the resulting decay-electron produced a delayed pulse. +The time difference between the initial and the delayed pulses is the individual +lifetime of the muon. + +The decay time and the properties of the signal pulses (height, integral and +postition in time) are written to a buffer; the raw wave forms are optionally +also written to another buffer. + +The callable functions *find_peaks()* and *calulate_decay_time()* depend on the +buffer manager *mimoCoRB* and provide the filter functionality described above. +These functions support multiple sinks to be configured for output. + +The relevant configuration parameters can be found in the section *find_peaks:* +and *calculate_decay_time:* in the configuration file. + +""" + +from mimocorb.buffer_control import rbTransfer +import numpy as np +import pandas as pd +import os, sys + +from filters import * + +def find_peaks(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + """filter client for mimoCoRB: Find valid signal pulses in waveform data + + Input: + + - wave form data from source buffer defined in source_list + + Returns: + + - None if filter not passed + - list of list(s) of pulse parameters, written to sinks defined in sink_list + + """ + + if config_dict is None: + raise ValueError("ERROR! Wrong configuration passed (in lifetime_modules: calculate_decay_time)!!") + + # Load configuration + sample_time_ns = config_dict["sample_time_ns"] + analogue_offset = config_dict["analogue_offset"]*1000 + peak_minimal_prominence = config_dict["peak_minimal_prominence"] + peak_minimal_distance = config_dict["peak_minimal_distance"] + peak_minimal_width = config_dict["peak_minimal_width"] + pre_trigger_samples = config_dict["pre_trigger_samples"] + trigger_channel = config_dict["trigger_channel"] + if trigger_channel not in ['A','B','C','D']: + trigger_channel = None + trigger_position_tolerance = config_dict["trigger_position_tolerance"] + + pulse_par_dtype = sink_list[-1]['dtype'] + + + def tag_pulses(input_data): + """find all valid pulses + + This function to be called by instance of class mimoCoRB.rbTransfer + + Args: input data as structured ndarray + + Returns: list of parameterized pulses + """ + + # Find all the peaks and store them in a dictionary + peaks, peaks_prop = tag_peaks(input_data, peak_minimal_prominence, peak_minimal_distance, peak_minimal_width) + + # identify trigger channel, validate trigger pulse and get time of trigger pulse + if trigger_channel is not None: + trigger_peaks = peaks['ch' + trigger_channel] + if len(trigger_peaks) == 0: + return None + reference_position = trigger_peaks[np.argmin(np.abs(trigger_peaks - pre_trigger_samples))] + else: # external or no trigger: set to nominal position + reference_position = pre_trigger_samples + + peak_data= np.zeros( (1,), dtype=pulse_par_dtype) + for key in peaks.keys(): + for position, height, left_ips, right_ips in zip( + peaks[key], peaks_prop[key]['prominences'], + peaks_prop[key]['left_ips'], peaks_prop[key]['right_ips']): + if np.abs(reference_position - position) < trigger_position_tolerance: + peak_data[0][key+'_position'] = position + peak_data[0][key+'_height'] = input_data[key][position] - analogue_offset #height + left = int(np.floor(left_ips)) + right = int(np.ceil(right_ips)) + peak_data[0][key+'_integral'] = \ + sum(input_data[key][left:right] - analogue_offset) * sample_time_ns * 1e-9/50/5 + return [peak_data] + + p_filter = rbTransfer(source_list=source_list, sink_list=sink_list, config_dict=config_dict, + ufunc=tag_pulses, **rb_info) + p_filter() + +if __name__ == "__main__": + print("Script: " + os.path.basename(sys.argv[0])) + print("Python: ", sys.version, "\n".ljust(22, '-')) + print("THIS IS A MODULE AND NOT MEANT FOR STANDALONE EXECUTION") diff --git a/redP_mimoCoRB.py b/redP_mimoCoRB.py new file mode 100644 index 0000000000000000000000000000000000000000..6882767f2a340dccb40d68dd523440f229bafed1 --- /dev/null +++ b/redP_mimoCoRB.py @@ -0,0 +1,51 @@ +""" +**redP_mimoCoRB**: a simple template to use mimoCoRB with the RedPitaya and redPoscdaq.py + +Input data is provided as numpy-arry of shape (number_of_channels, number_of_samples). +""" + +import time +import sys + +import redPoscdaq as rp + + +def redP_to_rb(source_list=None, sink_list=None, observe_list=None, config_dict=None, **rb_info): + """ + Get data from RedPitaya and pass data to buffer + + The class mimocorb.buffer_control/rbImport is used to interface to the + newBuffer and Writer classes of the package mimoCoRB.mimo_buffer + + This example may serve as a template for other data sources + + :param config_dict: configuration dictionary + + - events_required: number of events to be simulated or 0 for infinite + - sleeptime: (mean) time between events + - random: random time between events according to a Poission process + - number_of_samples, sample_time_ns, pretrigger_samples and analogue_offset + describe the waveform data to be generated (as for oscilloscope setup) + + Internal parameters of the simulated physics process (the decay of a muon) + are (presently) not exposed to user. + """ + + # initialize mimocorb class inside redPoscidaq + datasource= rp.redP_mimocorb(config_dict=config_dict, sink_list=sink_list, **rb_info) + #print("data source initialized") + + # start oscilloscope + #print("starting osci") + rp.run_rpControl(callback=datasource.data_sink, conf_dict=config_dict) + + +#daq = run_mimoDAQ('redP_mimoCoRB.yaml') +#daq.setup() +#RB_1 = daq.ringbuffers['RB_1'] +#sink_dict = RB_1.new_writer() +#datasource= rp.redP_mimocorb(config_dict={}, sink_list=[sink_dict], RB_1='write') +#print("data source initialized") +#rp.run_rpControl(callback=datasource.data_sink) +#print("starting DAQ") +#daq.run() diff --git a/setup.yaml b/setup.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a079387b2fd0a0832f58e4186859e3f1268c60f8 --- /dev/null +++ b/setup.yaml @@ -0,0 +1,86 @@ +# Configuration for recording two channels with mimoCoRB +# ----------------------------------------------------- +# +# configure two buffers: +# - RB_1 for raw waveforms +# - RB_2 for derived pulse parameters +# data from RB_2, the result buffer, are saved to a file in csv (text) format. +# +# - data from RB_1 are also passed to an obsever process driving a real-time display +# - data from RB_2 are passed to a Reader process driving a real-time histogram display +# +# Notes: +# +# 1. additional config files controlling the user functions are +# located in the subdirectory config/ +# 2. necessary application-specific user code is located +# in the subdirectory modules/ +# +# ---------------------------------------------------------------------------- +# + +RingBuffer: + # define ring buffers + - RB_1: + # raw input data buffer (from picoScope, file or simulation) + number_of_slots: 16 + channel_per_slot: 2048 + data_type: + 1: ['chA', "float32"] + 2: ['chB', "float32"] + - RB_2: + # buffer with correct signature double pulse parameters + number_of_slots: 16 + channel_per_slot: 1 + data_type: + data_type: + 1: ['chA_height', "float32"] + 2: ['chA_position', "int32"] + 3: ['chA_integral', "float32"] + 4: ['chB_height', "float32"] + 5: ['chB_position', "int32"] + 6: ['chB_integral', "float32"] + +Functions: + # define functions and ringbuffer assignment + + - Fkt_main: + config_file: "config/spectrum_config.yaml" + + - Fkt_1: + ## for simulation with rbPut + file_name: "redP_mimoCoRB" + fkt_name: "redP_to_rb" + num_process: 1 + RB_assign: + RB_1: "write" + + - Fkt_2: + file_name: "modules/spectrum_filter" + fkt_name: "find_peaks" + num_process: 2 + RB_assign: + RB_1: "read" + RB_2: "write" + + - Fkt_3: + file_name: "modules/save_files" + fkt_name: "save_to_txt" + num_process: 1 + RB_assign: + RB_2: "read" + +# --- the following functions are optioal + + - Fkt_4: + file_name: "modules/plot_waveform" + fkt_name: "plot_waveform" + num_process: 1 + RB_assign: + RB_1: "observe" + - Fkt_5: + file_name: "modules/plot_histograms" + fkt_name: "plot_histograms" + num_process: 1 + RB_assign: + RB_2: "read" # pulse parameters