Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QADC Update: Background Subtraction, CFD Edge Detection #1294

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
1190 Remove duplicate QADC code, update QADC PVs for new IOC
#################

API Breaks
----------
- digitizers: Various QADC classes removed in favor of replacements in qadc.py module.

Library Features
----------------
- N/A

Device Features
---------------
- Qadc134: Adds new waveform analysis features like background correction and CFD analysis.
- Qadc134Lcls2: Adds new waveform analysis features like background correction and CFD analysis.

New Devices
-----------
- N/A

Bugfixes
--------
- N/A

Maintenance
-----------
- N/A

Contributors
------------
- slactjohnson
111 changes: 0 additions & 111 deletions pcdsdevices/digitizers.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,114 +605,3 @@ class Wave8V2(Wave8V2Simple):
xpm_mini = Cpt(Wave8V2XpmMini, ':XpmMini')

xpm_msg = Cpt(Wave8V2XpmMsg, ':TrEvent')


class QadcBase(BaseInterface, Device):
"""
Base class common to all qadc digitizers.
"""
ch0 = Cpt(EpicsSignalRO, ":CH0", kind="normal")
ch1 = Cpt(EpicsSignalRO, ":CH1", kind="normal")
ch2 = Cpt(EpicsSignalRO, ":CH2", kind="normal")
ch3 = Cpt(EpicsSignalRO, ":CH3", kind="normal")

config = Cpt(EpicsSignal, ":CONFIG", kind="config")
set_metadata(config, dict(variety='command-proc', value=1))


class Qadc(QadcBase):
"""
Class for older qadc, based on Abaco FMC126.
"""
gain0_i = Cpt(EpicsSignal, ":GAIN0_I", kind="omitted")
gain0_ni = Cpt(EpicsSignal, ":GAIN0_NI", kind="omitted")
gain1_i = Cpt(EpicsSignal, ":GAIN1_I", kind="omitted")
gain1_ni = Cpt(EpicsSignal, ":GAIN1_NI", kind="omitted")
gain2_i = Cpt(EpicsSignal, ":GAIN2_I", kind="omitted")
gain2_ni = Cpt(EpicsSignal, ":GAIN2_NI", kind="omitted")
gain3_i = Cpt(EpicsSignal, ":GAIN3_I", kind="omitted")
gain3_ni = Cpt(EpicsSignal, ":GAIN3_NI", kind="omitted")

ichan = Cpt(EpicsSignal, ":ICHAN", kind="config")
interleave = Cpt(EpicsSignal, ":INTERLEAVE", kind="config")

length = Cpt(EpicsSignal, ":LENGTH", kind="config")

off0_i = Cpt(EpicsSignal, ":OFF0_I", kind="omitted")
off0_ni = Cpt(EpicsSignal, ":OFF0_NI", kind="omitted")
off1_i = Cpt(EpicsSignal, ":OFF1_I", kind="omitted")
off1_ni = Cpt(EpicsSignal, ":OFF1_NI", kind="omitted")
off2_i = Cpt(EpicsSignal, ":OFF2_I", kind="omitted")
off2_ni = Cpt(EpicsSignal, ":OFF2_NI", kind="omitted")
off3_i = Cpt(EpicsSignal, ":OFF3_I", kind="omitted")
off3_ni = Cpt(EpicsSignal, ":OFF3_NI", kind="omitted")

out = Cpt(EpicsSignalRO, ":OUT", kind="normal")

rawdata = Cpt(EpicsSignalRO, ":RAWDATA", kind="normal")

start = Cpt(EpicsSignal, ":START", kind="normal")

train = Cpt(EpicsSignal, ":TRAIN", kind="omitted")

trig_delay = Cpt(EpicsSignal, ":TRIG_DELAY", kind="config")
trig_event = Cpt(EpicsSignal, ":TRIG_EVENT", kind="config")


class Qadc134Sparsification(BaseInterface, Device):
"""
Class for Abaco FMC134, which supports sparsification.
"""
hi_thresh = Cpt(EpicsSignal, ":HI_THRESH_RBV", write_pv=":HI_THRESH",
kind="config")
lo_thresh = Cpt(EpicsSignal, ":LO_THRESH_RBV", write_pv=":LO_THRESH",
kind="config")

sparse_en = Cpt(EpicsSignal, ":SPARSE_EN_RBV", write_pv=":SPARSE_EN",
kind="config", doc="Enable sparse output arrays")

rows_after = Cpt(EpicsSignal, ":ROWS_AFTER_RBV", write_pv=":ROWS_AFTER",
kind="config")
rows_before = Cpt(EpicsSignal, ":ROWS_BEFORE_RBV",
write_pv=":ROWS_BEFORE", kind="config")

sparse0 = Cpt(EpicsSignalRO, ":SPARSE0", kind="config")
sparse1 = Cpt(EpicsSignalRO, ":SPARSE1", kind="config")


class Qadc134(QadcBase):
"""
Class for the Abaco FMC134 digitizer card.
"""
sparsification = Cpt(Qadc134Sparsification, '', kind='omitted')

full_en = Cpt(EpicsSignal, ":FULL_EN_RBV", write_pv=":FULL_EN",
kind="config", doc="Enable full size output arrays")

ichan = Cpt(EpicsSignal, ":ICHAN_RBV", write_pv=":ICHAN", kind="config",
doc="Interleave channel")
interleave = Cpt(EpicsSignal, ":INTERLEAVE_RBV", write_pv=":INTERLEAVE",
kind="config", doc="Enable interleaving on ichan")

length = Cpt(EpicsSignal, ":LENGTH_RBV", write_pv=":LENGTH",
kind="config")
prescale = Cpt(EpicsSignal, ":PRESCALE_RBV", write_pv=":PRESCALE",
kind="config")

trig_delay = Cpt(EpicsSignal, ":TRIG_DELAY_RBV", write_pv=":TRIG_DELAY",
kind="config", doc="Delay in 156.17 MHz ticks")
trig_event = Cpt(EpicsSignal, ":TRIG_EVENT_RBV", write_pv=":TRIG_EVENT",
kind="config")

clear_config = Cpt(EpicsSignal, ":CLEAR_CONFIG", kind="config")
set_metadata(clear_config, dict(variety='command-proc', value=1))

out0 = Cpt(EpicsSignalRO, ":OUT0", kind="normal", doc="Signal in Volts")
out1 = Cpt(EpicsSignalRO, ":OUT1", kind="normal", doc="Signal in Volts")

rawdata0 = Cpt(EpicsSignalRO, ":RAWDATA0", kind="normal",
doc="Signal in ADU")
rawdata1 = Cpt(EpicsSignalRO, ":RAWDATA1", kind="normal",
doc="Signal in ADU")

start = Cpt(EpicsSignal, ":START", kind="normal")
100 changes: 89 additions & 11 deletions pcdsdevices/qadc.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
from ophyd import Component as Cpt
from ophyd import Device, EpicsSignal
from ophyd import FormattedComponent as FCpt

from .interface import BaseInterface
from .variety import set_metadata

# Qadc == Abaco FMC126 Digitzier
# Qadc134 == Abaco FMC134 Digitizer


class QadcCommon(BaseInterface, Device):
"""
Common class for Abaco FMC digitizers. Used in Qadc and Qadc134.
"""

ch0 = Cpt(EpicsSignal, ":CH0", kind="normal", doc="Input 0 of the ADC")
ch1 = Cpt(EpicsSignal, ":CH1", kind="normal", doc="Input 1 of the ADC")
ch2 = Cpt(EpicsSignal, ":CH2", kind="normal", doc="Input 2 of the ADC")
ch3 = Cpt(EpicsSignal, ":CH3", kind="normal", doc="Input 3 of the ADC")
config = Cpt(EpicsSignal, ":CONFIG", kind="config",
doc="Write the current config to the QADC")
set_metadata(config, dict(variety='command-proc', value=1))
Expand Down Expand Up @@ -51,10 +50,83 @@ class QadcLcls2Timing(BaseInterface, Device):
doc="Trigger partition number")


class Qadc134Waveform(BaseInterface, Device):
"""
Common class for Qadc134 waveforms. Includes common settings and controls
for these waveforms, like averaging and background correction.
"""
enable_averaging = FCpt(
EpicsSignal, "{self.prefix}:ENABLE_AVERAGE_{self.chan}",
kind="config", doc="Enable signal averaging"
)
n_average = FCpt(
EpicsSignal, "{self.prefix}:N_AVERAGE_{self.chan}", kind="config",
doc="Number of waveforms to average"
)
average = FCpt(
EpicsSignal, "{self.prefix}:AVERAGE_{self.chan}", kind="normal",
doc="Averaged waveform"
)

bg_enable = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_BGCORR", kind="config",
doc="Enable bacground correction"
)
bg_start = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_BGSTART", kind="config",
doc="Background start (64 sample increments)"
)
bg_end = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_BGEND", kind="config",
doc="Background end (64 sample increments)"
)

cfd_enable = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_CFDEN", kind="config",
doc="Enable CFD edge finding algorithm"
)
cfd_delay = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_CFDEL", kind="config",
doc="CFD delay, in pixels"
)
cfd_threshold = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_CFDTH", kind="config",
doc="CFD threshold, in volts"
)
cfd_edges = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_CFD_EDGES", kind="normal",
doc="Array of up to 10 detected edges (in ns)"
)
cfd_edges = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_CFD_INDICES", kind="normal",
doc="Array of up to 10 detected edge indices (in pixel)"
)
cfd_edge_1 = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_EDGE1", kind="normal",
doc="First detected edge (cfd_edges[0])"
)
cfd_edge_2 = FCpt(
EpicsSignal, "{self.prefix}:{self.chan}_EDGE2", kind="normal",
doc="First detected edge (cfd_edges[1])"
)

def __init__(self, prefix, chan=None, **kwargs):
self.chan = chan
super().__init__(prefix, **kwargs)


class Qadc134Common(QadcCommon):
"""
Common class for FMC134 digitizers.
"""
ch0 = Cpt(Qadc134Waveform, '', chan="CH0", kind="normal",
doc="Input 0 of the ADC")
ch1 = Cpt(Qadc134Waveform, '', chan="CH1", kind="normal",
doc="Input 1 of the ADC")
ch2 = Cpt(Qadc134Waveform, '', chan="CH2", kind="normal",
doc="Input 2 of the ADC")
ch3 = Cpt(Qadc134Waveform, '', chan="CH3", kind="normal",
doc="Input 3 of the ADC")
trig_delay = Cpt(
EpicsSignal, ":TRIG_DELAY_RBV", write_pv=":TRIG_DELAY", kind="config",
doc="Trigger delay in EVR/TPR ticks"
Expand Down Expand Up @@ -93,16 +165,18 @@ class Qadc134Common(QadcCommon):
clear_config = Cpt(EpicsSignal, ":CLEAR_CONFIG", kind="config",
doc="Clear the current configuration")
set_metadata(clear_config, dict(variety='command-proc', value=1))
out0 = Cpt(EpicsSignal, ":OUT0", kind="normal", doc="Full output zero")
out1 = Cpt(EpicsSignal, ":OUT1", kind="normal", doc="Full output one")
out0 = Cpt(Qadc134Waveform, '', chan="OUT0", kind="normal",
doc="Interleaved waveform 0 of the ADC")
out1 = Cpt(Qadc134Waveform, '', chan="OUT1", kind="normal",
doc="Interleaved waveform 1 of the ADC")
rawdata0 = Cpt(EpicsSignal, ":RAWDATA0", kind="normal",
doc="Raw output zero")
rawdata1 = Cpt(EpicsSignal, ":RAWDATA1", kind="normal",
doc="Raw output one")
sparse0 = Cpt(EpicsSignal, ":SPARSE0", kind="normal",
doc="Sparsified output zero")
sparse1 = Cpt(EpicsSignal, ":SPARSE1", kind="normal",
doc="Sparsified output one")
sparse0 = Cpt(Qadc134Waveform, '', chan="SPARSE0", kind="normal",
doc="Sparsified waveform 0 of the ADC")
sparse1 = Cpt(Qadc134Waveform, '', chan="SPARSE1", kind="normal",
doc="Sparsified waveform 1 of the ADC")


class Qadc134(Qadc134Common, QadcLcls1Timing):
Expand All @@ -121,6 +195,10 @@ class Qadc(QadcCommon):
"""
Class for an older Abaco FMC PCIe digitzer, used in the LCLS-I hutches.
"""
ch0 = Cpt(EpicsSignal, ":CH0", kind="normal", doc="Input 0 of the ADC")
ch1 = Cpt(EpicsSignal, ":CH1", kind="normal", doc="Input 1 of the ADC")
ch2 = Cpt(EpicsSignal, ":CH2", kind="normal", doc="Input 2 of the ADC")
ch3 = Cpt(EpicsSignal, ":CH3", kind="normal", doc="Input 3 of the ADC")

gain0_i = Cpt(EpicsSignal, ":GAIN0_I", kind="config")
gain0_ni = Cpt(EpicsSignal, ":GAIN0_NI", kind="config")
Expand Down