diff --git a/doc/changelog.rst b/doc/changelog.rst index 16ab02c306b8000eebd2dd64bbb268f0da6d6e93..43f8f4bc5d69ff6228dc5bcd550269ab627e9bdc 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -21,6 +21,7 @@ unreleased - adds Chem diagnostics and Gotthard II mnemonics :mr:`292` - make hRIXS centroid threshold configurable :mr:`298` - drop MaranaX non-existing mnemonics and add attributes on dataset :mr:`300` + - streamline digitizer functions :mr:`304` - **New Features** diff --git a/src/toolbox_scs/constants.py b/src/toolbox_scs/constants.py index 41ab20c3b58b3db628315d5c7308e3208d45de5e..ba1dd3d7a7954435f3716a4487295049175c4e91 100644 --- a/src/toolbox_scs/constants.py +++ b/src/toolbox_scs/constants.py @@ -799,28 +799,32 @@ mnemonics = { # TIM "MCP1apd": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_D.apd.pulseIntegral', - 'dim': ['apdId']},), + 'dim': ['apdId'], + 'extract': 'peaks'},), "MCP1raw": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_D.raw.samples', 'dim': ['samplesId'], 'extract': 'peaks'},), "MCP2apd": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_C.apd.pulseIntegral', - 'dim': ['apdId']},), + 'dim': ['apdId'], + 'extract': 'peaks'},), "MCP2raw": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_C.raw.samples', 'dim': ['samplesId'], 'extract': 'peaks'},), "MCP3apd": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_B.apd.pulseIntegral', - 'dim': ['apdId']},), + 'dim': ['apdId'], + 'extract': 'peaks'},), "MCP3raw": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_B.raw.samples', 'dim': ['samplesId'], 'extract': 'peaks'},), "MCP4apd": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_A.apd.pulseIntegral', - 'dim': ['apdId']},), + 'dim': ['apdId'], + 'extract': 'peaks'},), "MCP4raw": ({'source': 'SCS_UTC1_ADQ/ADC/1:network', 'key': 'digitizers.channel_1_A.raw.samples', 'dim': ['samplesId'], @@ -829,70 +833,80 @@ mnemonics = { # FastADC "FastADC0peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_0.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC0raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_0.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC1peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_1.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC1raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_1.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC2peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_2.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_2.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC3peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_3.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC3raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_3.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC4peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_4.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC4raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_4.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC5peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_5.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC5raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_5.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC6peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_6.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC6raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_6.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC7peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_7.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC7raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_7.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC8peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_8.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC8raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_8.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], 'extract': 'peaks'},), "FastADC9peaks": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_9.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC9raw": ({'source': 'SCS_UTC1_MCP/ADC/1:channel_9.output', 'key': 'data.rawData', 'dim': ['fadc_samplesId'], @@ -901,70 +915,80 @@ mnemonics = { # FastADC 2 "FastADC2_0peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_0.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_0raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_0.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_1peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_1.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_1raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_1.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_2peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_2.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_2raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_2.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_3peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_3.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_3raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_3.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_4peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_4.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_4raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_4.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_5peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_5.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_5raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_5.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_6peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_6.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_6raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_6.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_7peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_7.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_7raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_7.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_8peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_8.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_8raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_8.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], 'extract': 'peaks'},), "FastADC2_9peaks": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_9.output', 'key': 'data.peaks', - 'dim': ['peakId']},), + 'dim': ['peakId'], + 'extract': 'peaks'},), "FastADC2_9raw": ({'source': 'SCS_UTC2_FADC/ADC/1:channel_9.output', 'key': 'data.rawData', 'dim': ['fadc2_samplesId'], diff --git a/src/toolbox_scs/detectors/digitizers.py b/src/toolbox_scs/detectors/digitizers.py index d69efd42d7ff39b0f740ca057f25489cc31cfbf0..83672429db6a1d9897962733b8aa96fce38d9d13 100644 --- a/src/toolbox_scs/detectors/digitizers.py +++ b/src/toolbox_scs/detectors/digitizers.py @@ -143,8 +143,8 @@ def peaks_from_apd(array, params, digitizer, bpt, bunchPattern): f'but the array length is only {array.sizes[arr_dim]}.') npulses_apd = array.sizes[arr_dim] mask = is_pulse_at(bpt, bunchPattern).rename({'pulse_slot': pulse_dim}) - mask = mask.sel(trainId=array.trainId) - mask = mask.assign_coords({pulse_dim: np.arange(2700)}) + mask = mask.where(mask.trainId.isin(array.trainId), drop=True) + mask = mask.assign_coords({pulse_dim: np.arange(bpt.sizes['pulse_slot'])}) pid = np.sort(np.unique(np.where(mask)[1])) npulses_bpt = len(pid) apd_coords = np.arange(pid[0], pid[0] + stride*npulses_apd, stride) @@ -152,7 +152,8 @@ def peaks_from_apd(array, params, digitizer, bpt, bunchPattern): if len(np.intersect1d(apd_coords, pid, assume_unique=True)) < npulses_bpt: log.warning('Not all pulses were recorded. The digitizer ' 'was set to record pulse ids ' - f'{apd_coords[apd_coords<2700]} but the bunch pattern for' + f'{apd_coords[apd_coords<bpt.sizes["pulse_slot"]]} but the' + 'bunch pattern for' f' {bunchPattern} is {pid}. Skipping pulse ID alignment.') noalign = True array = array.isel({arr_dim: slice(0, npulses_apd)}) @@ -167,10 +168,8 @@ def peaks_from_apd(array, params, digitizer, bpt, bunchPattern): def get_peaks(run, - data=None, - source=None, - key=None, - digitizer='ADQ412', + data, + mnemonic, useRaw=True, autoFind=True, integParams=None, @@ -190,15 +189,10 @@ def get_peaks(run, array containing the raw traces or peak-integrated values from the digitizer. If str, must be one of the ToolBox mnemonics. If None, the data is loaded via the source and key arguments. - source: str - Name of digitizer source, e.g. 'SCS_UTC1_ADQ/ADC/1:network'. Only - required if data is a DataArray or None. - key: str - Key for digitizer data, e.g. 'digitizers.channel_1_A.raw.samples'. - Only required if data is a DataArray or is None. - digitizer: string - name of digitizer, e.g. 'FastADC' or 'ADQ412'. Used to determine - the sampling rate. + mnemonic: str or dict + ToolBox mnemonic or dict with source and key as in + {'source': 'SCS_UTC1_ADQ/ADC/1:network', + 'key': 'digitizers.channel_1_A.raw.samples'} useRaw: bool If True, extract peaks from raw traces. If False, uses the APD (or peaks) data from the digitizer. @@ -210,12 +204,10 @@ def get_peaks(run, integration: 'pulseStart', 'pulseStop', 'baseStart', 'baseStop', 'period', 'npulses'. Not used if autoFind is True. All keys are required when bunch pattern is missing. - bunchPattern: string or dict + bunchPattern: str match the peaks to the bunch pattern: 'sase1', 'sase3', 'scs_ppl'. This will dictate the name of the pulse ID coordinates: 'sa1_pId', - 'sa3_pId' or 'scs_ppl'. Alternatively, a dict with source, key and - pattern can be provided, e.g. {'source':'SCS_RR_UTC/TSYS/TIMESERVER', - 'key':'bunchPatternTable.value', 'pattern':'sase3'} + 'sa3_pId' or 'scs_ppl'. bpt: xarray DataArray bunch pattern table extra_dim: str @@ -229,43 +221,25 @@ def get_peaks(run, ------- xarray.DataArray containing digitizer peaks with pulse coordinates """ - if data is None and (source is None or key is None): - raise ValueError('At least data or source + key arguments ' - 'are required.') - # Load data - arr = None - run_mnemonics = mnemonics_for_run(run) - if data is None: - log.debug(f'Loading array from DataCollection with {source}, {key}') - arr = run.get_array(source, key) - if isinstance(data, str): - log.debug(f'Loading array from mnemonic {data}') - m = run_mnemonics[data] - source = m['source'] - key = m['key'] - arr = run.get_array(source, key, m['dim']) - if arr is None: - log.debug('Using array provided in data argument.') - if source is None or key is None: - raise ValueError('source and/or key arguments missing.') - arr = data + arr = data dim = [d for d in arr.dims if d != 'trainId'][0] # Load bunch pattern table + run_mnemonics = mnemonics_for_run(run) if bpt is None and bunchPattern != 'None': - if isinstance(bunchPattern, dict): - bpt = run.get_array(bunchPattern['source'], bunchPattern['key'], - extra_dims=['pulse_slot']) - pattern = bunchPattern['pattern'] if 'bunchPatternTable' in run_mnemonics: m = run_mnemonics['bunchPatternTable'] bpt = run.get_array(m['source'], m['key'], m['dim']) - pattern = bunchPattern + pattern = bunchPattern else: pattern = bunchPattern if bunchPattern == 'None': bpt = None + # Find digitizer type + m = mnemonic if isinstance(mnemonic, dict) else run_mnemonics[mnemonic] + digitizer = digitizer_type(run, m.get('source')) + # 1. Peak-integrated data from digitizer if useRaw is False: # 1.1 No bunch pattern provided @@ -279,13 +253,16 @@ def get_peaks(run, return arr.isel({dim: indices}).rename({dim: extra_dim}) # 1.2 Bunch pattern is provided - peak_params = channel_peak_params(run, source, key) + if isinstance(mnemonic, dict): + peak_params = channel_peak_params(run, mnemonic.get('source'), + mnemonic.get('key')) + else: + peak_params = channel_peak_params(run, mnemonic) log.debug(f'Digitizer peak integration parameters: {peak_params}') return peaks_from_apd(arr, peak_params, digitizer, bpt, bunchPattern) # 2. Use raw data from digitizer # minimum pulse period @ 4.5MHz, according to digitizer type - digitizer = digitizer_type(source=source) min_distance = 1 if digitizer == 'FastADC': min_distance = 24 @@ -338,7 +315,7 @@ def get_peaks(run, else: mask = is_pulse_at(bpt.sel(trainId=valid_tid), pattern) mask = mask.rename({'pulse_slot': extra_dim}) - mask = mask.assign_coords({extra_dim: np.arange(2700)}) + mask = mask.assign_coords({extra_dim: np.arange(bpt.sizes['pulse_slot'])}) mask_on = mask.where(mask, drop=True).fillna(False).astype(bool) log.info(f'Bunch pattern of {pattern} changed during the run.') pid = mask_on.coords[extra_dim] @@ -727,7 +704,7 @@ def check_peak_params(run, mnemonic, raw_trace=None, ntrains=200, params=None, log.warning('The digitizer did not record peak-integrated data.') if not plot: return params - digitizer = digitizer_type(mnemonic, run_mnemonics) + digitizer = digitizer_type(run, run_mnemonics[mnemonic]['source']) min_distance = 24 if digitizer == "FastADC" else 440 if 'bunchPatternTable' in run_mnemonics and bunchPattern != 'None': sel = run.select_trains(np.s_[:ntrains]) @@ -829,27 +806,35 @@ def plotPeakIntegrationWindow(raw_trace, params, bp_params, show_all=False): return fig, ax -def digitizer_type(mnemonic=None, mnemo_dict=None, source=None): - if mnemonic is not None: - source = mnemo_dict[mnemonic]['source'] - if ':channel' in source: - return 'FastADC' - if ':output' in source: - return 'FastADC' - if ':network' in source: - return 'ADQ412' - dic = {'XTD10_MCP': 'FastADC', - 'FastADC': 'FastADC', - 'PES': 'ADQ412', - 'MCP': 'ADQ412'} - for k, v in dic.items(): - if k in mnemonic: - return v - log.warning(f'Could not find digitizer type from mnemonic {mnemonic}.') - return 'ADQ412' - - -def get_tim_peaks(run, mnemonics=None, merge_with=None, +def digitizer_type(run, source): + """ + Finds the digitizer type based on the class Id / name of the source. + Example source: 'SCS_UTC1_MCP/ADC/1'. Defaults to ADQ412 if not found. + """ + ret = None + if '_MCP/ADC/1' in source: + ret = 'FastADC' + if '_ADQ/ADC/1' in source: + ret = 'ADQ412' + if ret is None: + digi_dict = {'FastAdc': 'FastADC', + 'FastAdcLegacy': 'FastADC', + 'AdqDigitizer': 'ADQ412', + 'PyADCChannel': 'FastADC', + 'PyADCChannelLegacy': 'FastADC' + } + try: + source = source.split(':')[0] + classId = run.get_run_value(source, 'classId.value') + ret = digi_dict.get(classId) + except Exception as e: + log.warning(str(e)) + log.warning(f'Could not find digitizer type from source {source}.') + ret = 'ADQ412' + return ret + + +def get_tim_peaks(run, mnemonic=None, merge_with=None, bunchPattern='sase3', integParams=None, keepAllSase=False): """ @@ -862,10 +847,8 @@ def get_tim_peaks(run, mnemonics=None, merge_with=None, ---------- run: extra_data.DataCollection DataCollection containing the digitizer data. - mnemonics: str or list of str - mnemonics for TIM, e.g. "MCP2apd" or ["MCP2apd", "MCP3raw"]. - If None, defaults to "MCP2apd" in case no merge_with dataset - is provided. + mnemonic: str + mnemonics for TIM, e.g. "MCP2apd". merge_with: xarray Dataset If provided, the resulting Dataset will be merged with this one. The TIM variables of merge_with (if any) will also be @@ -885,16 +868,16 @@ def get_tim_peaks(run, mnemonics=None, merge_with=None, Returns ------- - xarray Dataset with all TIM variables substituted by + xarray Dataset with TIM variables substituted by the peak caclulated values (e.g. "MCP2raw" becomes "MCP2peaks"), merged with Dataset *merge_with* if provided. """ - return get_digitizer_peaks(run, mnemonics, merge_with, + return get_digitizer_peaks(run, mnemonic, merge_with, bunchPattern, integParams, keepAllSase) -def get_laser_peaks(run, mnemonics=None, merge_with=None, +def get_laser_peaks(run, mnemonic=None, merge_with=None, bunchPattern='scs_ppl', integParams=None): """ Extracts laser photodiode signal (peak intensity) from Fast ADC @@ -906,10 +889,9 @@ def get_laser_peaks(run, mnemonics=None, merge_with=None, ---------- run: extra_data.DataCollection DataCollection containing the digitizer data. - mnemonics: str or list of str - mnemonics for FastADC corresponding to laser signal, e.g. - "FastADC2peaks" or ["FastADC2raw", "FastADC3peaks"]. If None, - defaults to "MCP2apd" in case no merge_with dataset is provided. + mnemonic: str + mnemonic for FastADC corresponding to laser signal, e.g. + "FastADC2peaks" or 'I0_ILHraw'. merge_with: xarray Dataset If provided, the resulting Dataset will be merged with this one. The FastADC variables of merge_with (if any) will also be @@ -930,16 +912,16 @@ def get_laser_peaks(run, mnemonics=None, merge_with=None, the peak caclulated values (e.g. "FastADC2raw" becomes "FastADC2peaks"). """ - return get_digitizer_peaks(run, mnemonics, merge_with, + return get_digitizer_peaks(run, mnemonic, merge_with, bunchPattern, integParams, False) -def get_digitizer_peaks(run, mnemonics=None, merge_with=None, - bunchPattern='None', integParams=None, - digitizer=None, keepAllSase=False): +def get_digitizer_peaks(run, mnemonic, merge_with=None, + bunchPattern='sase3', integParams=None, + keepAllSase=False): """ - Automatically computes digitizer peaks. Sources can be loaded on the - fly via the mnemonics argument, or processed from an existing data set + Automatically computes digitizer peaks. A source can be loaded on the + fly via the mnemonic argument, or processed from an existing data set (merge_with). The bunch pattern table is used to assign the pulse id coordinates. @@ -947,18 +929,14 @@ def get_digitizer_peaks(run, mnemonics=None, merge_with=None, ---------- run: extra_data.DataCollection DataCollection containing the digitizer data. - mnemonics: str or list of str - mnemonics for FastADC or TIM, e.g. "FastADC2raw" or ["MCP2raw", - "MCP3apd"]. If None and no merge_with dataset is provided, - defaults to "MCP2apd" if digitizer is ADQ412 or - "FastADC5raw" if digitizer is FastADC. + mnemonic: str + mnemonic for FastADC or ADQ412, e.g. "I0_ILHraw" or "MCP3apd". + The data is either loaded from the DataCollection or taken from + merge_with. merge_with: xarray Dataset - If provided, the resulting Dataset will be merged with this - one. The FastADC variables of merge_with (if any) will also be - computed and merged. - bunchPattern: str + If provided, the resulting Dataset will be merged with this one. + bunchPattern: str or dict 'sase1' or 'sase3' or 'scs_ppl', 'None': bunch pattern - used to extract peaks. integParams: dict dictionnary for raw trace integration, e.g. {'pulseStart':100, 'pulsestop':200, 'baseStart':50, @@ -970,48 +948,22 @@ def get_digitizer_peaks(run, mnemonics=None, merge_with=None, Returns ------- - xarray Dataset with all Fast ADC variables substituted by - the peak caclulated values (e.g. "FastADC2raw" becomes + xarray Dataset with digitizer peak variables. Raw variables are + substituted by the peak caclulated values (e.g. "FastADC2raw" becomes "FastADC2peaks"). """ - if mnemonics is None and merge_with is None: - raise ValueError("at least one of mnemonics or merge_with " - "arguments is expected.") - run_mnemonics = mnemonics_for_run(run) - # find digitizer type and get the list of mnemonics to process - def to_processed_name(name): - return name.replace('raw', 'peaks').replace('apd', 'peaks') - if mnemonics is None: - if digitizer is None: - for v in merge_with: - if 'FastADC2_' in v: - digitizer = 'FastADC2' - break - if 'FastADC' in v: - digitizer = 'FastADC' - break - if 'MCP' in v: - digitizer = 'ADQ412' - break - if digitizer is None: - log.warning(f'No array with digitizer data ' - 'to extract. Skipping.') - return merge_with - mnemonics = mnemonics_to_process(mnemonics, merge_with, - digitizer, to_processed_name) - else: - mnemonics = [mnemonics] if isinstance(mnemonics, str) else mnemonics - digitizer = digitizer_type(mnemonics[0], run_mnemonics) - - if len(mnemonics) == 0: - log.info(f'No array with unaligned {digitizer} peaks to extract. ' - 'Skipping.') + if mnemonic not in run_mnemonics: + log.warning('Mnemonic not found in run. Skipping.') return merge_with - else: - log.info(f'Extracting {digitizer} peaks from {mnemonics}.') - + if bool(merge_with) and mnemonic in merge_with: + for d in merge_with[mnemonic].dims: + if d in ['sa3_pId', 'ol_pId']: + log.warning(f'{mnemonic} already extracted. ' + 'Skipping.') + return merge_with # check if bunch pattern table exists + bpt = None if bool(merge_with) and 'bunchPatternTable' in merge_with: bpt = merge_with['bunchPatternTable'] log.debug('Using bpt from merge_with dataset.') @@ -1024,39 +976,29 @@ def get_digitizer_peaks(run, mnemonics=None, merge_with=None, bpt = run.get_array(m['source'], m['key'], m['dim']) log.debug('Loaded bpt from DataCollection.') else: - bpt = None - - # iterate over mnemonics and merge arrays in dataset + log.warning('Could not load bunch pattern table.') + # prepare resulting dataset if bool(merge_with): - mw_ds = merge_with.drop(mnemonics, errors='ignore') + mw_ds = merge_with.drop(mnemonic, errors='ignore') else: mw_ds = xr.Dataset() + # iterate over mnemonics and merge arrays in dataset autoFind = True if integParams is None else False - names = [] - vals = [] - for k in mnemonics: - useRaw = True if 'raw' in k else False - m = run_mnemonics[k] - if bool(merge_with) and k in merge_with: - data = merge_with[k] - else: - data = None - peaks = get_peaks(run, data, - source=m['source'], - key=m['key'], - digitizer=digitizer, - useRaw=useRaw, - autoFind=autoFind, - integParams=integParams, - bunchPattern=bunchPattern, - bpt=bpt) - name = to_processed_name(k) - names.append(name) - vals.append(peaks) + m = run_mnemonics[mnemonic] + useRaw = True if 'raw' in mnemonic else False + if bool(merge_with) and mnemonic in merge_with: + data = merge_with[mnemonic] + else: + data = run.get_array(m['source'], m['key'], m['dim']) + peaks = get_peaks(run, data, mnemonic, + useRaw=useRaw, + autoFind=autoFind, + integParams=integParams, + bunchPattern=bunchPattern, + bpt=bpt) + name = mnemonic.replace('raw', 'peaks').replace('apd', 'peaks') join = 'outer' if keepAllSase else 'inner' - aligned_vals = xr.align(*vals, join=join) - ds = xr.Dataset(dict(zip(names, aligned_vals))) - ds = mw_ds.merge(ds, join=join) + ds = mw_ds.merge(peaks.rename(name), join=join) return ds diff --git a/src/toolbox_scs/load.py b/src/toolbox_scs/load.py index 268dc9fff81e50c51c12f4270bd363bb7168f6d7..275e555a12a1fcceae21c3983974014957370aa6 100644 --- a/src/toolbox_scs/load.py +++ b/src/toolbox_scs/load.py @@ -238,7 +238,7 @@ def load(proposalNB=None, runNB=None, if bp is None: continue ds = tbdet.get_digitizer_peaks( - run, mnemonics=k, merge_with=ds, bunchPattern=bp) + run, mnemonic=k, merge_with=ds, bunchPattern=bp) if extract_xgm: for k, v in run_mnemonics.items(): if k not in ds or v.get('extract') != 'XGM':