skutils package

skutils.FemtoDAQController module

exception skutils.FemtoDAQController.BusyError[source]

Bases: Exception

An error representing that the FemtoDAQ device is busy.

class skutils.FemtoDAQController.FemtoDAQController(url: str, verbose: bool = False, skip_version_check: bool = False)[source]

Bases: object

A controller for FemtoDAQ devices, such as the FemtoDAQ Kingfisher or FemtoDAQ Vireo device. For full functionality, use the FemtoDAQController with a v6 DDC_APPs version for your FemtoDAQ device.

getTriggerXPosition()[source]

Get the position of where the event trigger fired in the waveform buffer

setTriggerXPosition(x_position: int, force: bool = False)[source]

Set the position of where the event trigger in the waveform buffer

Parameters:
  • x_position – The position of the trigger in the N-sample window.

  • force – apply change even if data collection is ongoing.

getTriggerActiveWindow()[source]

Gets the trigger active window in samples/clock cycles. AKA coincidence Window - the window in which triggers across multiple channels will be considered part of the same event.

setTriggerActiveWindow(window_width: int, force: bool = False)[source]

sets the trigger active window. AKA coincidence Window - the window in which triggers across multiple channels will be considered part of the same event. The window starts at the first trigger in an event and stays active for the number of samples specified

Parameters:
  • window_width – number of samples to keep the trigger active.

  • force – apply change even if data collection is ongoing.

getCoincidenceWindow()[source]

alias for getTriggerActiveWindow()

setCoincidenceWindow(*args: Any, **kwargs: Any)[source]

alias for setTriggerActiveWindow()

getPulseHeightWindow() int[source]

Gets the pulse height window / filter window in samples (ie clock cycles)

setPulseHeightWindow(window_width: int, force: bool = False)[source]

Set the number of samples after a trigger in which the firmware will calculate the DSP quantities: pulse height, trigger height, qdc_triangular, and qdc_rectangular

Note

Historical Naming

The “Pulse Height Window” also defines size of the window for DSP quantities such as pulse height, trigger height, qdc_triangular, and qdc_rectangular are calculated. This includes all histogram quantities.

Note

Window for all Channels Starts at first trigger in event

This window starts at the first trigger in the event regardless of where an individual channel triggers. SkuTek recommends setting the Pulse Height Window to the same value as the Trigger/Coincidence Window for most applications.

Parameters:
  • window_width – Width of DSP calculation window following event trigger

  • force – apply change even if data collection is ongoing.

getEnableBaselineRestoration() bool[source]

Gets current active status of the automatic Baseline Restoration. Baseline Restoration is not supported on all products. Check with has_baseline_restoration

setEnableBaselineRestoration(enable: bool, force: bool = False)[source]

Enable (or disable) Baseline Restoration. Baseline Restoration is not supported on all products. Check with has_baseline_restoration

Parameters:
  • enable – True to enable baseline restoration. False to disable

  • force – apply change even if data collection is ongoing.

getBaselineRestorationExclusion()[source]

Get the area used in baseline restoration exclusion to excluse your triggered pulse.

setBaselineRestorationExclusion(window_width: int, force: bool = False)[source]

Sets the number of samples after an event trigger to exclude from the baseline calculation algorithm. This prevents pulsse data from corrupting the baseline calculation

Note

SkuTek recommends that the Baseline Restoration Window be greater than your (trigger_window + decay_period) of your signal pulse.

Warning

Baseline Restoration calculates the baseline on the fly so the calculated baseline can vary between events. If this poses a problem for your experiment, we recommend manually setting the baseline using a setDigitialOffset().

Parameters:
  • window_width – Number of samples to exclude after an event trigger.

  • force – apply change even if data collection is ongoing.

getPulseHeightAveragingWindow() int[source]

Gets the size of the pulse height / DSP filter averaging window.

setPulseHeightAveragingWindow(window_width: int, force: bool = False)[source]

Sets the width of the Pulse Height / DSP quantitiy smoothing filter. Must be a power of 2. See filter_window_width_values for a list of valid sizes.

Note

Historical Naming

The “Pulse Height Averaging Window” also defines size of the averaging window for DSP quantities such as pulse height, qdc_triangular, and qdc_rectangular. This includes all histogram quantities. However the trigger_height quantity averaging is set with setTriggerAveragingWindow

Parameters:
  • window_width – Number of filter quantity samples to average

  • force – apply change even if data collection is ongoing.

getQuadQDCWindows() Tuple[int, int, int, int][source]

Get the quad QDC integration windows. Returns a tuple where the tuple values are: (base_width, fast_width, slow_width, tail_width)

Returns Zeros

setQuadQDCWindows(qdc_base_integration_window: int, qdc_fast_integration_window: int, qdc_slow_integration_window: int, qdc_tail_integration_window: int, force: bool = False)[source]

Set the windows for FGPA-based 4-part integration of an event.

QuadQDC Integration is composed of 4 integration windows on different sections of your pulse. There are windows for integrating BASELINE (pre-trigger),FAST (peak), SLOW (mid decay), TAIL (late decay). There is also a constant 8 sample gap between the FAST from the baseline in order to avoid contaminating the baseline with the pulse.

The values of the sums are latched when the FAST sum is at maximum.

Refer to the manual for figures describing this process

Warning

Set Pulse Height Accordingly

The Pulse Height Window should liberally encompass the duration of the FAST+SLOW+TAIL in order allow the maximum to be latched. Set Pulse Height Window with setPulseHeightWindow()

Note

Note available on all models

Check has_quadqdc_integration to see if this feature is supported on your unit

Parameters:
  • qdc_base_integration_window – Width of Baseline calculation window in samples prior to the pulse. Followed by an 8 sample gap

  • qdc_fast_integration_window – Width of the FAST window in samples. Starts 8 samples following the end of the BASELINE window.

  • qdc_slow_integration_window – Width of the SLOW window in samples. Starts immediately after end of the FAST window.

  • qdc_tail_integration_window – Width of the TAIL window in samples. Starts immediately after end of the SLOW window.

  • force – apply change even if data collection is ongoing.

getBiasVoltage() float[source]

Read back the bias voltage used to drive the High Voltage (HV) output. If available

setBiasVoltage(voltage: float, force: bool = False)[source]

Sets the bias voltage used to drive the High Voltage (HV) output.

Some models may require you to switch between High and Low voltage ranges using a physical switch on the back of the unit. Refer you unit’s manual for more information

See bias_voltage_min and bias_voltage_max for your digitizer’s available voltage range.

Parameters:
  • voltage – Voltage to drive the HV output

  • force – apply change even if data collection is ongoing.

getBiasVoltageRaw() int[source]

Get the raw DAC value used to bias a detector

setBiasVoltageRaw(voltage: int, force: bool = False)[source]

Set the raw DAC value used to bias output for a detector. Steps of 1. Use for higher precision configuration of HV bias voltage.

See bias_voltage_raw_min and bias_voltage_raw_max for your digitizer’s available DAC range.

Parameters:
  • voltage – DAC value to configure the HV voltage driver.

  • force – apply change even if data collection is ongoing.

getGlobalId() int[source]

Gets the assigned global ID of this device for this experimental run. This is also known as “Module Number” in some documentation.

setGlobalId(global_id: int, force: bool = False)[source]

Sets assigned global ID of this device for this experimental run. This is also known as “Module Number” in some documentation.

Parameters:
  • global_id – Identifier for this unit in an experimental run

  • force – apply change even if data collection is ongoing.

setAnalogOffsetPercent(channel: int, offset_percent: int, force: bool = False)[source]

Set the analog offset. 100% is maximum analog offset. -100% is minimum analog offset

Note

This value is unable to be read back.

Parameters:
  • channel – Target Channel

  • offset_percent – The percent offset for analog baseline offset ranging from -100% to 100% as an integer

  • force – apply change even if data collection is ongoing.

Raises:

ValueError – If the offset percentage is not in the valid range

setAnalogOffsetRaw(channel: int, offset_val: int, force: bool = False)[source]

Set the analog offset with the raw DAC value. Useful for precise non-linearity measurements. Use analog_offset_raw_min and analog_offset_raw_max to determine what values you can set.

Note

This value is unable to be read back.

Parameters:
  • channel – Target Channel

  • offset_percent – The analog offset in raw dac values.

  • force – apply change even if data collection is ongoing.

getDigitalOffset(channel: int) int[source]

Gets the digital offset applied to this channel’s waveform.

Parameters:

channel – Target Channel

setDigitalOffset(channel: int, offset: int)[source]

Sets the digital offset applied to this channel’s waveform. Offset occurs AFTER inversion if set.

Refer to adc_max_val and adc_min_val to check your unit’s

available offset range

Parameters:
  • channel – Target Channel

  • offset – Offset in ADC counts

getEnableTrigger(channel: int) bool[source]

Checks whether a channel’s trigger is enabled.

Parameters:

channel – Target Channel

setEnableTrigger(channel: int, enable: bool, force: bool = False)[source]

Enables or disables a channel’s trigger.

Parameters:
  • channel – Target Channel

  • enable – True to enable trigger. False to disable.

  • force – apply change even if data collection is ongoing.

getTriggerEdge(channel: int) str[source]

Get what edge a trigger happens for a specified channel. :param channel: channel to get the trigger edge data from.

setTriggerEdge(channel: int, direction: Literal['rising'] | Literal['falling'] | int, force: bool = False)[source]

Set a rising or falling edge trigger mode

Parameters:
  • channel – Target Channel

  • direction – “rising” for Rising Edge Trigger. “falling” for falling edge trigger

  • force – apply change even if data collection is ongoing.

getTriggerSensitivity(channel: int) int[source]

Gets the differential trigger threshold for the target channel.

Parameters:

channel – channel to obtain the trigger threshold of.

setTriggerSensitivity(channel: int, sensitivity: int, force: bool = False)[source]

Sets the differential trigger threshold. When the difference between samples exceeds this value, the channel will trigger will fire (if enabled)

Refer to trigger_sensitivity_min and trigger_sensitivity_max

your unit’s available range of trigger sensitivity values.

Note

Differential Trigger is subject to averaging.

see setTriggerAveragingWindow()

Parameters:
  • channel – Target Channel

  • sensitivity – Differential threshold of the trigger in ADC counts.

  • force – apply change even if data collection is ongoing.

getTriggerAveragingWindow(channel: int) int[source]

Get the duration of the leading and trailing summation windows in ADC samples. :param channel: channel to get the trigger averaging window of.

setTriggerAveragingWindow(channel: int, window_width: int, force: bool = False)[source]

Sets the width of the Differential Trigger’s smoothing filter. Must be a power of 2. See filter_window_width_values for a list of valid sizes.

Parameters:
  • channel – Target Channel

  • window_width – Number of trigger differentials (B-A) to average before checking against the trigger sensitivity.

  • force – apply change even if data collection is ongoing.

getHistogramScaling(channel: int) int[source]

Get the state of the histogram scaling for a specified channel

Parameters:

channel – Target Channel

setHistogramScaling(channel: int, state: int)[source]

Set the histogram scaling for a specified channel, if state is 1, this bins histogram quantities by 2 otherwise for 0, do not bin. To cover the whole positive ADC range state must 1

Parameters:
  • channel – Target Channel

  • state – 1 to scale histograms by factor of two, 0 for no scaling

getHistogramQuantity(channel: int) str[source]

Get the quantity histogrammed at each event, check setHistogramQuantity for the meanings of values

Note

Histogram Quantities must be greater than 0.

Quantities less than or equal to zero will be placed in the underflow bin (bin0).

Parameters:

channel – Target Channel

setHistogramQuantity(channel: int, quantity: Literal['pulse_height', 'qdc_rect', 'qdc_tri', 'trigger_height'])[source]

Set the quantity histogrammed at each event. See the FemtoDAQ Operations manual for in depth information about quantity calculation

Possibile quantities are:
  • “pulse_height”: The maximum pulse height as found in the pulse height window after averaging

  • “trigger_height”: the maximum value of the trigger after averaging

  • “qdc_rect”: Running sum over PH window without averaging.

  • “qdc_tri”: Running average of PH window sum (average of qdc_rect).

Parameters:
  • channel – Target Channel

  • quantity – desired quantity to histogram

getHistogramValueRange(channel: int) Tuple[int, int][source]

Returns a tuple of the minimum/maximum quantity values that can be histogrammed for this channel

Parameters:

channel – Target Channel

Returns:

a tuple (min_val, max_val) of quantity values that can be histogrammed with the current scaling configuration. Quantity values outside of this range will be either be placed into the underflow bin (0) or overflow bin (the final bin)

setInvertADCSignal(channel: int, invert: bool, force: bool = False)[source]

Enable or disable ADC signal inversion. This occurs before all other offsets or averaging

Parameters:
  • channel – Target Channel

  • invert – A boolean representing whether to invert or not invert the ADC channel

  • force – apply change even if data collection is ongoing.

getInvertADCSignal(channel: int) bool[source]

Get the ADC inversion status of a channel

Parameters:

channel – Target Channel

zeroHistogram(channel: int)[source]

Reset the histogram for a given channel

configureCoincidence(coincidence_mode: Literal['hit_pattern', 'multiplicity'], trigger_multiplicity: int | None = None, trigger_hit_pattern: Dict[str, str] | None = None, force: bool = False)[source]

Configures coincidence prior to an experimental run.

Parameters:
  • mode – the coincidence mode for triggering. Must be one of two options. - “multiplicity” : global trigger requires at least the specified number of individual channels to trigger - “hit_pattern” : global trigger requires specific channels to trigger or not trigger. AKA coincidence/anti-coincidence/ignore hit pattern

  • multiplicity – Required if mode = “multiplicity”. The minimum number of individual channel triggers required to define an Event. This arugment is ignored if mode is “hit_pattern”

  • hit_pattern

    Required if mode = “hit_pattern”. This argument must be a dictionary. Keys are “channel_{channel}_trigger_hit_pattern”, and value is one of:

    • ’COINCIDENCE’ : If a trigger is required on this channel

    • ’ANTICOINCIDENCE’ : If a trigger is not allowed on this channel

    • ’IGNORE’ : If triggers on this channel have no impact on Event

    All channels must be present when presented to configureCoincidence. A simple builder for configureCoincidence is helpers.HitPatternCoincidenceBuilder which will fill in unspecified items with “IGNORE” exists. This arugment is ignored if mode is “multiplicity”

  • force – apply change even if data collection is ongoing.

Hit Pattern Example

1hit_pattern = {"channel_0_trigger_hit_pattern" : "COINCIDENCE", "channel_1_trigger_hit_pattern" : "ANTICOINCIDENCE"}
2digitizer.configureCoincidence("hit_pattern", hit_pattern=hit_pattern)

Multiplicity Example

1multiplicity = 3
2digitizer.configureCoincidence("multiplicity", multiplicity=multiplicity)
getCoincidenceSettings() Dict[str, Any][source]

Obtain the current Coincidence settings.

configureRecording(channels_to_record: Sequence[int], number_of_samples_to_capture: int = 512, file_recording_name_prefix: str = 'API_Recording', file_recording_format: str = 'gretina', file_recording_data_output: Literal['waveforms', 'both', 'pulse_summaries', 'all_possible'] = 'all_possible', recording_directory: str | None = None, seq_file_size_MB: int = 100, only_record_triggered: bool = False, file_recording_enabled: bool = True, waveform_display_enabled: bool = False, display_channels: Sequence[int] = [], events_to_capture: int = 1000)[source]

Configures file recording prior to an experimental run.

Parameters:
  • channels_to_record – channels to record

  • number_of_samples_to_capture – The number of samples each channel will record. Must be a multiple of 64.

  • file_recording_name_prefix – The prefix for files being generated by the FemtoDAQ device

  • file_recording_format – The format the file is stored in, check getRecordingFormatInfo() for available formats.

  • file_recording_data_output – The data products to record. “waveforms” for just waveforms, “pulse_summaries” for just pulse summaries, “both” for both, “all_possible” to automatically save all possible data products,

  • recording_directory – The directory to record the files to on the target device, either /data/ or /mnt/ or derived paths

  • seq_file_size_MB – Size of the sequence file in megabytes

  • only_record_triggered – Set to True to only record triggered channels, not all formats support this.

  • file_recording_enabled – Enable recording to file, presumably you want this.

  • waveform_display_enabled – Enable or disable waveform display, faster to not have this, but required to use waitUntil.

  • display_channels – Enable channels for GUI display, performance hit to have on, do not use this unless required.

  • events_to_capture – Optional - primarily used for making configuration files. Number of events to capture by default for the next run. Overwritten by the “how_many” argument in the start function

Raises:

ValueError – if an invalid file format is specified

getRecordingSettings() Dict[str, Any][source]

Get the current recording settings, this will return a dictionary of values exactly the same as the parameters used for configureRecording.

configureSoftwareStreaming(channels: Sequence[int], format: str, target_ip: str, target_port: int | str, only_stream_triggered_channels: bool = False, enabled: bool = False, force: bool = False)[source]

Configures streaming readout from software prior to an experimental run.

Parameters:
  • channels – list of channels to stream during this experimental run

  • target_ip – The IP address to stream to.

  • target_port – The network port at the specified IP address to stream to.

  • only_stream_triggered_channels – If True, then only record the channels in the channels list that triggered in the event. This is more efficient and reduces the liklihood of noise waveforms ending up in your data files. If left as False, the default, then all specified channels will be written to disk even if no trigger was detected. This is less efficient, but ensures that the same channels will be in each event.

  • force – apply change even if data collection is ongoing.

getSoftwareStreamSettings() Dict[str, Any][source]

Retrieve the stream settings currently made for the FemtoDAQ device. :returns: Dict of a json packet The JSON packet should look like this:

{
    "soft_stream_channels": channels,
    "soft_stream_dest_ip": target_ip,
    "soft_stream_dest_port": int | str,
    "soft_stream_format": string,
    "only_stream_triggered": bool
}
getRunStatistics() Dict[str, Any][source]

returns a dictionary which contains at least the following keys

{
    "fpga_events" : int,
    "fpga_run_time" : float,
    "fpga_active_time" : float,
    "fpga_dead_time" : float,
    "recorded_events" : int,
    "recorded_bytes" : int,
    "recording_files" : int,
    "recording_duration_sec" : float,
    "is_currently_recording" : bool,
}
getHistogramDuration() int[source]

Gets the number of seconds the histogram is configured to run for

setHistogramDuration(histogram_duration: int, force: bool = False)[source]

Set the duration that a histogram run will run for

Parameters:
  • histogram_duration – Time in seconds to histogram

  • force – apply change even if data collection is ongoing.

isReserved() bool[source]

Determine if the FemtoDAQ is reserved

getReservedInfo() Dict[str, str | bool][source]

Get the reservation information of a FemtoDAQ device

reserve(reserver_name: str, reserve_contact: str | None = None, reserve_message: str | None = None)[source]

Set the reservation status of a FemtoDAQ device. Note: This is not strictly enforced

unreserve()[source]

Release reservation of a FemtoDAQ device Note: This technically does not do anything other than say “Hey, please don’t use this while I am!”

start(how_many: int | Literal['continuous', 'single'] | None = None) None[source]

Starts data collection for the specified number of events

Parameters:

how_many – number of events to capture for this run. Use’continuous’ to capture until told to stop separately.or ‘single’ for a single event (equivalent to 1). Leave as None to use the number of events defined previously in a configuration file or the configureRecording function

waitUntil(nevents: int | None = None, timeout_time: float | None = None, print_status: bool | None = False) bool[source]

Wait until either the number of events as received by the Digitizer has been received, or wait timeout_time seconds for a timeout. If both are specified, whichever completes first will be performed. If the recording is stopped both either condition is fulfilled or both are None, returns.

Return a boolean indicating if waiting timed out.

Parameters:
  • timeout_time – A float representing a time (in seconds) to wait for until completion until return.

  • nevents – The minimum number of samples/events to wait for.

  • print_status – Whether or not to print the status at the end of a wait cycle

Returns:

True if waiting timed out. False if the number of events was successfully reached before timeout

stop() None[source]

Stop waveform capture

zeroTimestamp(force: bool = False)[source]

Zero the FPGA timestamp. Future timestamps will start incrementing at 0.

Parameters:

force – apply change even if data collection is ongoing.

getLastEventTimestamp() int[source]

Get the timestamp for last FPGA event.

Attention

This timestamp is calculated in firmware and does not account for coincidence conditions. It is not guarenteed to match the most recent timestamp saved to disk.

forceTrigger() None[source]

Forces a trigger regardless of coincidence conditions

inspectNextEvent(max_timeout: float | None = 10) EventInfo[source]

Returns the next event that meets coincidence conditions as specified by the configureCoincidence and configureRecording functions

Data Collection must ongoing (ie. start() has been run), or this operation will hang until timeout.

Attention

This function is intended for debugging or inspection work, it is NOT intended to readout during data collection. Readout via this method will be orders of magnitude slower than using your FemtoDAQ’s recording or streaming systems

See configureRecording for information about configuring recording See configureSoftwareStreaming for information about configuring streaming

Parameters:

max_timeout – Timeout for receiving the inspected waveform in seconds.

getHistogramData(channel_or_all: int | Literal['all']) ndarray[source]
getListOfDataFiles(last_run_only: bool = False) Sequence[str][source]

Get the list of all remote data files.

Parameters:

last_run_only – If true, only gets the data files recorded in the last run.

downloadFile(filename: str, save_to: str | None = None, silent: bool = False) str[source]

Download a file from a given path, save to a location on disk, and optionally print out values

Parameters:
  • filename – Remote file to download

  • save_to – location to save that file to, or the local destionation

  • silent – Don’t print values out

Returns:

The full path of the downloaded file

deleteDataFile(filename: str) None[source]

Delete a file with a specified name from the /data/ directory. :param filename: A filename to delete from /data/ on the FemtoDAQ device

downloadLastRunDataFiles(save_to: str | None = None) List[str][source]

Iterate through all data files from the last run and download them.

Parameters:

save_to – an optional parameter specifying where to save the data.

downloadCurrentConfig() Dict[str, Any][source]

Download the current configuration as a json dictionary suitable for loading in with applyConfig

applyConfig(config_dict: Dict[str, Any])[source]

Apply a configuration from the dictionary! This is a companion function to downloadConfig, allowing you to replay a downloaded configuration on-top of a file. Not every item will be configured by this function! Notably items for which there are not get functions for will not be applied by this function!

Parameters:

config_dict – A dictionary representing the configuration

saveCurrentConfig(setting_name: str)[source]

pulls settings dictionary and then saves it to a JSON file in /var/www/data –> Identical to Save Configuration Button in GUI

loadandApplyExistingConfig(setting_name: str)[source]

loads a JSON file from /var/www/data loads and apply settings dictionary from JSON –> Identical to Load Configuration Button in GUI

loadDefaultConfig()[source]

Load and apply the default configuration (default.json) of the digitizer

getSoftwareVersion()[source]

Returns the FemtoDAQ device Software version

getFirmwareVersion()[source]

Returns the FemtoDAQ device Firmware version

getImageVersion()[source]

Returns the image version of the FemtoDAQ device

getStreamFormatInfo()[source]

Returns the supported software streaming formats and their capabilities

getRecordingFormatInfo() Dict[str, Any][source]

Returns the supported recording formats and their capabilities

summary() str[source]

Obtain a string summary of the FemtoDAQ device

property product_name: str

Get the short name of the FemtoDAQ product

property serial_number: str

Get the serial name of the product

property clk_period_ns: int

period of each clock cycle in nanoseconds

property frequency

The ADC sampling rate in MHz

property bitdepth: int

The number of bits in the ADC

property name: str

Get the whole name of the product, being product-serial number

property num_channels: int

The number of channels in the product

property channels: Sequence[int]

A list of all channels in the product

property num_wave_samples: int

Number of samples in a max-size waveform

property wave_duration_us: float

Returns the maximum duration of a waveform in microseconds

property wave_max_val: int

Maximum value in the wave

property wave_min_val: int

Minimum value in the wave

property num_hist_bins: int

Number of bins in a histogram

property quadqdc_window_min: int
property quadqdc_window_max: int
property adc_max_val: int

Maximum ADC value of the product

property adc_min_val: int

Minimum ADC value of the product

property bias_voltage_raw_max: int

Maximum raw DAC value allowed by the Bias Voltage system

property bias_voltage_raw_min: int

Minimum raw DAC value allowed by the Bias Voltage system

property bias_voltage_max: int

Maximum voltage that can be generated by the Bias Voltage system

property bias_voltage_min: int

Minimum raw DAC value allowed by the Bias Voltage system

property global_id_min: int

Minimum allows global ID value

property global_id_max: int

Maximum allows global ID value

property filter_window_width_values: Sequence[int]

a list of allowed values for the Pulse Height Averaging and Trigger Averaging window width

property trigger_sensitivity_max: int

Maximum trigger sensitivity

property trigger_sensitivity_min: int

Minimum trigger sensitivity

property analog_offset_raw_min: int

Minimum analog offset DAC value for each channel

property analog_offset_raw_max: int

Maximum analog offset DAC value for each channel

property has_baseline_restoration

Whether or not this unit has the automatic baseline resoration feature

property has_histogram

Whether or not this unit has in firmware histogramming

property has_high_voltage_output

Whether or not this unit has a high voltage bias output

property has_quadqdc_integration

Whether or not this unit has the QuadQDC firmware module

property has_spy_output

Whether or not this unit has the SPY filter inspection module

property has_waveforms

Whether or not this unit has waveform readout

property has_channel_timestamps

Whether or not this unit has per-channel timestamping

skutils.Loader module

class skutils.Loader.ChannelData(channel: int, timestamp: int, pulse_summary: Dict[str, Any] | None, wave: ndarray | None)[source]

All data related to a single channel, could be as part of an event or not as part of an event, and may or may not have a pulse summary or wave

Check self.has_wave and self.has_summary to see if either are present

channel: int

channel ID

timestamp: int

FPGA Event Timestamp

has_wave: bool

Boolean indicating whether this channel contains waveform data

has_summary: bool

Boolean indicating whether this channel contains DSP summary data

wave: ndarray | None

Numpy Waveform for digitizer signal

pulse_summary: Dict[str, Any]

Dictionary of Pulse Summary (DSP) Information

pulse_height: int | None

Maximum height of pulse in the pulse height window. Subject to averaging

trigger_height: int | None

Maximum height of trigger in the trigger active window. Subject to averaging

quadqdc_base: int | None

QuadQDC BASE Integration. Not supported on all digitizer models

quadqdc_fast: int | None

QuadQDC FAST Integration. Not supported on all digitizer models

quadqdc_slow: int | None

QuadQDC SLOW Integration. Not supported on all digitizer models

quadqdc_tail: int | None

QuadQDC TAIL Integration. Not supported on all digitizer models

triggered: bool | None

Boolean indicating whether this channel triggered

trigger_multiplicity: int | None

The number of times the trigger for this channel fired in the trigger window Also known as pileup count

property pileup: bool

Returns true if there have been multiple triggers in this channel

property num_wave_samples: int

Returns the number of samples in the wave, 0 if this has no wave

class skutils.Loader.EventInfo(channel_data: Sequence[ChannelData])[source]

Information related to a group of channels collated as an “Event” as defined by either the file format or a rebuilt coincidence window.

num_channels

number of channels in this event

property has_waves

True if this Event contains waveform data for ALL of it’s channels

property has_summary

True if this Event contains pulse summary data for ALL of it’s channels

wavedata() ndarray[source]

An np.ndarray of waves in the event. Rows are samples, columns are the channels in this event. see channels for the list of channel numbers

property num_wave_samples: int | None

Returns the number of samples in each channel’s waveform or None if no waveforms exist

shape()[source]

Returns the shape of :meth:`.wavedata’ or None if no waveforms exist

property channels: Sequence[int]

List of all channels in the event in the order they appear

property timestamps: Sequence[int]

All timestamps found throughout all of the channels we have

property timestamp: int

Alias for min_timestamp

property min_timestamp: int

The smallest timestamp found in the list of timestamps

property max_timestamp: int

The largest timestamp found in the list of timestamps

property timestamp_range: int

Range of timestamps from the maximum and minimum

property pulse_heights: Sequence[int] | Sequence[None]

Returns the pulse heights on each channel.

property trigger_heights: Sequence[int] | Sequence[None]

Returns the trigger heights trigger on each channel.

property channel_multiplicity: int

Returns the number of channels that triggered at least once in this event

property pileup_count: Sequence[int] | Sequence[None]

Returns a list of the number of triggers fired for each channel

property total_triggers: int

Returns the total number of triggers that fired across all channels. AKA Hit Multiplicity

class skutils.Loader.ChannelData(channel: int, timestamp: int, pulse_summary: Dict[str, Any] | None, wave: ndarray | None)[source]

Bases: object

All data related to a single channel, could be as part of an event or not as part of an event, and may or may not have a pulse summary or wave

Check self.has_wave and self.has_summary to see if either are present

channel: int

channel ID

timestamp: int

FPGA Event Timestamp

has_wave: bool

Boolean indicating whether this channel contains waveform data

has_summary: bool

Boolean indicating whether this channel contains DSP summary data

wave: ndarray | None

Numpy Waveform for digitizer signal

pulse_summary: Dict[str, Any]

Dictionary of Pulse Summary (DSP) Information

pulse_height: int | None

Maximum height of pulse in the pulse height window. Subject to averaging

trigger_height: int | None

Maximum height of trigger in the trigger active window. Subject to averaging

quadqdc_base: int | None

QuadQDC BASE Integration. Not supported on all digitizer models

quadqdc_fast: int | None

QuadQDC FAST Integration. Not supported on all digitizer models

quadqdc_slow: int | None

QuadQDC SLOW Integration. Not supported on all digitizer models

quadqdc_tail: int | None

QuadQDC TAIL Integration. Not supported on all digitizer models

triggered: bool | None

Boolean indicating whether this channel triggered

trigger_multiplicity: int | None

The number of times the trigger for this channel fired in the trigger window Also known as pileup count

property pileup: bool

Returns true if there have been multiple triggers in this channel

property num_wave_samples: int

Returns the number of samples in the wave, 0 if this has no wave

class skutils.Loader.EventInfo(channel_data: Sequence[ChannelData])[source]

Bases: object

Information related to a group of channels collated as an “Event” as defined by either the file format or a rebuilt coincidence window.

num_channels

number of channels in this event

property has_waves

True if this Event contains waveform data for ALL of it’s channels

property has_summary

True if this Event contains pulse summary data for ALL of it’s channels

wavedata() ndarray[source]

An np.ndarray of waves in the event. Rows are samples, columns are the channels in this event. see channels for the list of channel numbers

property num_wave_samples: int | None

Returns the number of samples in each channel’s waveform or None if no waveforms exist

shape()[source]

Returns the shape of :meth:`.wavedata’ or None if no waveforms exist

property channels: Sequence[int]

List of all channels in the event in the order they appear

property timestamps: Sequence[int]

All timestamps found throughout all of the channels we have

property timestamp: int

Alias for min_timestamp

property min_timestamp: int

The smallest timestamp found in the list of timestamps

property max_timestamp: int

The largest timestamp found in the list of timestamps

property timestamp_range: int

Range of timestamps from the maximum and minimum

property pulse_heights: Sequence[int] | Sequence[None]

Returns the pulse heights on each channel.

property trigger_heights: Sequence[int] | Sequence[None]

Returns the trigger heights trigger on each channel.

property channel_multiplicity: int

Returns the number of channels that triggered at least once in this event

property pileup_count: Sequence[int] | Sequence[None]

Returns a list of the number of triggers fired for each channel

property total_triggers: int

Returns the total number of triggers that fired across all channels. AKA Hit Multiplicity

class skutils.Loader.BaseLoader(fpath: str, rebuild_events_with_window: int | None = None)[source]

Bases: object

The base class that all Loader types are an extension of, Loaders extending this subclass this class and then implement load_channel_batch

All BaseLoader derived classes can be used as a context manager, i.e.:

with <loader>(file) as loader:

# Do whatever

NOTE:

An individual BaseLoader instance is able to run exactly once before needing to -reopen the file, please keep this in mind.

loadChannelBatch() Sequence[ChannelData] | None[source]

The base method for loading channels, this loads a sequence of channels (events) or individual channels.

This is specialized for all loader types.

channelByChannel() Generator[ChannelData, Any, None][source]

Get the individual channels, loaded one at a time

nextEvent() EventInfo | None[source]

Obtain the next event by loading the next batch.

lazyLoad() Generator[EventInfo, Any, None][source]

Lazily yield events, returns the next event in a generator fashion for iterating

class skutils.Loader.EventCSVLoader(fpath: str, rebuild_events_with_window: int | None = None)[source]

Bases: BaseLoader

Loader for the TSV-type format for the Vireo EventCSV Format

loadChannelBatch() Sequence[ChannelData] | None[source]

The base method for loading channels, this loads a sequence of channels (events) or individual channels.

This is specialized for all loader types.

class skutils.Loader.IGORPulseHeightLoader(fpath: str, rebuild_events_with_window: int | None = None)[source]

Bases: BaseLoader

IGOR pulse height loader, this type of loader does not actually have waveforms, but only the height and timestamp of a summary

Only the pulse_height section of ChannelData and the timestamp will be filled

loadChannelBatch() Sequence[ChannelData] | None[source]

The base method for loading channels, this loads a sequence of channels (events) or individual channels.

This is specialized for all loader types.

class skutils.Loader.GretinaLoader(fpath: str, rebuild_events_with_window: int | None = None)[source]

Bases: BaseLoader

Different from the original GretinaLoader, this wraps that to the standard BaseLoader interface for consistency purposes.

loadChannelBatch() Sequence[ChannelData] | None[source]

The base method for loading channels, this loads a sequence of channels (events) or individual channels.

This is specialized for all loader types.

class skutils.Loader.IGORWaveLoader(fpath: str, rebuild_events_with_window: int | None = None)[source]

Bases: BaseLoader

A loader for the IGOR wave format type, this is an event type format and will consistently have events correctly built so long as the orignial event was made.

loadChannelBatch() Sequence[ChannelData] | None[source]

The base method for loading channels, this loads a sequence of channels (events) or individual channels.

This is specialized for all loader types.

skutils.Loader.quickLoad(file_list: Sequence[str]) Generator[EventInfo, Any, None][source]

generator which loads events from the list of files provided. This function determines which Loader object to use for each file depending on the file extension and content. If you need to rebuild events or utilize other loader features, you will need to use Loader Objects directly.

Parameters:

file_list – a list of files to load events from. Files will be loaded in the order they are passed in

Yields:

EventInfo object for each event in all files.

skutils.SolidagoController module

class skutils.SolidagoController.Stream(board_id: int, sfp_id: int, default_words_per_packet: int = 1100, total_packet_count: int = 281474976710655, seed: int = -1)[source]

Bases: object

This Class will represent a single 10G port on Solidago and by the sub-boards

reset() None[source]

Reset the settings to default, notably inter-event-pause is set to 32, inter-packet-pause is set to 32, and packets per event is set to 1. All port information, mac information, and ip information is also wiped. Words per packet is also set to just the GRETA_HEADER_SIZE

apply_existing(sfp: int, words_per_packet: int, random_seed: int, total_number_packets: int, packets_per_event: int, packets_per_event_range: int, inter_event_pause: int, inter_event_pause_range: int, inter_packet_pause: int, inter_packet_pause_range: int, greta_version: int, greta_type: int, greta_subtype: int, greta_subtype_range: int, greta_flags: int, dst_port: int, dst_mac: str, dst_ip: str, src_ip: str, src_port: int, src_mac: str, **kwargs: Any)[source]

Apply an existing config, intended usage is to take in each kwarg from a json expansion

set_packet_size_words(nwords: int)[source]

Set the packet size in number of 64 bit words.

Parameters:

nwords

The number of 64 bit words to set the packet size to.

NOTE: nwords is the number of 64 bit words, that means to get the number of bytes being sent you multiply this number by 8!!!! MUST be greater than the minimum for the GRETA header

set_packet_size_bytes(nbytes: int)[source]

Set the packet size by an approxmiate number of bytes, it is rounded up to the nearest multiple of 8 :param nbytes: Number of bytes to set the payload size to (the input is rounded up to the nearest multiple of 8)

NOTE: nbytes is rounded up to the nearest multiple of 8(!)

set_source(src_ip: str, src_mac: int | str, src_port: int | str)[source]

The source of the packets being streamed out, Solidago does not do DHCP discovery, so it cannot automatically assign itself these parameters. :param src_ip: The ip that the stream will say it’s sending from. :param src_mac: the mac address the stream will say it’s sending from. :param src_port: the port the stream will say it’s sending from.

set_destination(dst_ip: str, dst_mac: str | int, dst_port: int | str)[source]

Set the target information’s packet information, as the Solidago is designed to be “dumb”, it cannot do MAC address discovery. :param dst_ip: The destination IP the stream will send to. :param dst_mac: The MAC address associated with the target IP. :param dst_port: The port designated to receive the UDP stream.

set_greta_format(version: int, flags: int, type: int, subtype: int, subtype_range: int)[source]

Set various information about the GRETA packet being sent by Solidago, this API may change as the product updates

Parameters:
  • version – The GRETA version

  • flags – The GRETA flags

  • type – The GRETA type, the Solidago will not actually change the packet format based on the type

  • subtype – The default subtype to set, Solidago will not change the packet based on the subtype other than simply setting the subtype

  • subtype_range – The maximum range of the subtype, calculated as subtype + rand(1, subtype_range)

configure_by_pulse_rate(pulse_freq_hz: float, pulse_width_us: float, inter_packet_pause: int = 32) float[source]

This configures this stream to have specific packets per event and inter event pause ranges based on the frequency of pulses and pulse widths as well as the distance between packets The minimum inter event pause is 32 clk cycles :param pulse_freq_hz: The pulse frequency in terms of number of pulses per second :param pulse_width_us: The width of the pulses in microseconds :param inter_packet_pause: Length of a pause in FPGA clock ticks.

Returns:

The estimated speed in gbps of the settings

configure_by_constant_speed(speed_gbps: float) float[source]

Configure speed, in GIGABITS per packet, close approximation

Parameters:

speed_gbps

wanted speed in gigabits per second

NOTE: KNOWN TO CURRENTLY NOT WORK PROPERLY

Returns:

The estimated speed in gbps of the settings

configure_raw(packets_per_event: int | None = None, packets_per_event_range: int | None = None, inter_event_pause: int | None = None, inter_event_pause_range: int | None = None, inter_packet_pause: int | None = None, inter_packet_pause_range: int | None = None, words_per_packet: int | None = None)[source]

Set various internal variables of the same name, all variables are optional so if None is passed in no change happens on that variable

Parameters:
  • packets_per_event – The number of packets in a specific event to send as a baseline

  • packets_per_event_range – An extra range of packets sent as part of the event, allows for a random number of packets to be sent from a particular stream

  • inter_event_pause – The length of a pause (in FPGA ticks) between events

  • inter_event_pause_range – A number indicating an extra “range” of ticks that are used in the length of a pause in packets

  • inter_packet_pause – The pause (in FPGA ticks) between packets in an event

  • inter_packet_pause_range – The range of the length of the pause (in ticks) of an event

  • words_per_packet – The number of FPGA words in a packet, this is multiplied by 8 to get the number of bytes in the packet.

get_rest_configuration() Dict[str, Any][source]

Get the total configuration for this sfp, as part of the board, as a json value. :returns: A dictionary usable as a packet for configuring this specific SFP via json

get_netifs() Dict[str, Any][source]

Get these network settings for a steram as a json value :returns: a packet usable for communication for updating an SFP

estimated_gbps() float[source]

Get the estimated gigabytes per second your settings will produce

Returns:

A float represented the expected SFP speed in GB/s

estimated_pps() float[source]

Get the estimated number of packets per second your settings will produces

Returns:

A float estimating the number of packets sent out per second, similar number to gbps, but also different.

property board_id_real: int

Board ID used for internal communication, boards are 1-indexed, but lists are 0-indexed, which is why this property even exists

property enabled: bool

Whether this stream is to be streaming when the board is set to a STREAMING state

property super_id: int

The ID of the Stream, this is the “total index” across everything

property dst_mac: str

The destination mac address for this stream

property src_mac: str

The source mac address for this stream

class skutils.SolidagoController.SolidagoController(ip: str, port: int | str = 80, num_boards: int = 4, sfps_per_board: int = 4)[source]

Bases: object

A controller to control the various functions of a given Solidago unit. A solidago Unit is made up of individual streams, the boards that send those streams, and the control unit. The boards themselves are almost irrelevant except for the modes in which they can be used.

Important note: Almost universally ALL boards are 1-indexed, and ALL streams are 0-indexed. Yes, this is annoying, yes this is confusing, and yes, we are aware that that is a problem.

autoincrement_stream_sources(starting_src_ip: int | str, starting_src_mac: int | str, starting_src_port: int)[source]

Automatically set every stream’s source ip, mac, and port, incrementing for every IP, mac, and port number

Parameters:
  • starting_src_ip – The starting ip to set the Streams to send from, increments for every SFP

  • starting_src_mac – The starting mac address to begin streaming from, increments for every SFP

  • starting_src_port – The starting port to stream from, increments for every SFP

autoincrement_stream_destinations(dst_ip: int | str, dst_mac: int | str, starting_dst_port: int)[source]

Automatically sets the dst and mac, and sets the destination port, but increments the port each time.

Parameters:
  • dst_ip – The IP to set all streams to send to

  • dst_mac – The MAC Address to set all streams to send to

  • starting_dst_port – The starting port to send to, increments for every stream

set_mode(mode: Literal['sync', 'independent', 'externallydriven'])[source]

Valid Modes: “Sync”, “Independent”, and “ExternallyDriven”

Terminology:

For the purposes of Solidago, “master” refers to a board that generates a clock sync signal, “slave” is a board that syncs to an external clock signal.

If mode is SYNC:

apply config for stream 1 to all streams (except for src/destination network config) set board 1 to MASTER. All other boards to slave

If mode is Independent

all boards set to master

if mode is ExternallyDriven

all boards set to slave

set_board_mode(board_id: int, mode: Literal['master', 'slave'])[source]

Set a given board (1-indexed) to be either a “master” (generates a clock signal) or a “slave” (responds to an external clock signal)

Parameters:
  • board_id1-indexed id of a board

  • mode – A choice between “master” and “slave” indicating whether it generates or accepts a clock-signal

configure(boards: int | Sequence[int] = [1, 2, 3, 4])[source]

This function bulk configures boards passed in.

Parameters:

boards – A 1-indexed list of boards to configure, each board that is wanted for configuration is configured as a group, then waiting for all boards to finish configuring happens, in Solidago, there are four (4) boards.

pull_configs()[source]

Get individually all board configurations and return them to the internal streams

enable_streams(streams: Sequence[int | Stream])[source]

enable streams to begin sending packets, for you to not get an error the listed streams must start from a CONFIGURED state

Parameters:

streams – A 0-indexed list of streams to begin streaming, or a Stream object to begin streaming

disable_streams(streams: Sequence[int | Stream])[source]

disable streams to end streaming packets, for you to not get an error the listed streams must be in a streaming state

Parameters:

streams – A 0-indexed list of streams to end streaming, or a Stream object to end streaming

start(streams: Sequence[int | Stream] = [])[source]

Enables all streams to begin streaming

stop(streams: Sequence[int | Stream] = [])[source]

Disables all streams to end streaming

status(board: int) Any[source]

Get the raw json status of a given board, 1-indexed NOTE: this returns a raw json response from the ‘data’ section of a return

Parameters:

board – The board to get the status of, 1-indexed

estimated_gbps() float[source]

returns: the estimated gbps of all enabled streams

estimated_pps() float[source]

Calculates the estimated packets per second of all enabled streams

skutils.helpers module

class skutils.helpers.HitPatternCoincidenceBuilder(num_channels: int)[source]

Bases: object

A utility class for easy building of hit pattern coincidences.

BUILDER_STRING = 'channel_{0}_trigger_hit_pattern'
addChannel(channel: int, pattern: Literal['A', 'C', 'I'] | str) None[source]

Add a channel to the coincidence pattern

Parameters:
  • channel – A zero-indexed integer representing a channel on a device

  • pattern – A string that starts with the letters A, C, or I (lower or upper case).

The letter each corresponds with Anticoincidence, Coincidence, or Ignore, respectively

reset() None[source]
buildForSend() Dict[str, str][source]
skutils.helpers.mac_to_num(mac: str) int[source]

Translate a MAC address string to a number

skutils.helpers.get_ip_address_of_interface(ifname: str) str[source]

Get the an ip address of the named interface, does not work on Windows.

skutils.helpers.get_mac_address_of_interface(ifname: str) str[source]

Get the MAC address of a named interface, does not work on windows.