#=================================================================#
# Template file: NDProcess.template
# Database for ND PluginProcess
# Mark Rivers
# March 14, 2010

include "NDPluginBase.template"

###################################################################
#  These records control the data type of the array data          # 
#  The last entry is "Automatic" meaning preserve the data type   #
#  of the input array.                                            # 
###################################################################

record(mbbo, "$(P)$(R)DataTypeOut")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))PROCESS_DATA_TYPE")
    field(ZRST, "Int8")
    field(ZRVL, "0")
    field(ONST, "UInt8")
    field(ONVL, "1")
    field(TWST, "Int16")
    field(TWVL, "2")
    field(THST, "UInt16")
    field(THVL, "3")
    field(FRST, "Int32")
    field(FRVL, "4")
    field(FVST, "UInt32")
    field(FVVL, "5")
    field(SXST, "Int64")
    field(SXVL, "6")
    field(SVST, "UInt64")
    field(SVVL, "7")
    field(EIST, "Float32")
    field(EIVL, "8")
    field(NIST, "Float64")
    field(NIVL, "9")
    field(TEST, "Automatic")
    field(TEVL, "-1")
    field(VAL,  "10")
    info(autosaveFields, "VAL")
}

record(mbbi, "$(P)$(R)DataTypeOut_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))PROCESS_DATA_TYPE")
    field(ZRST, "Int8")
    field(ZRVL, "0")
    field(ONST, "UInt8")
    field(ONVL, "1")
    field(TWST, "Int16")
    field(TWVL, "2")
    field(THST, "UInt16")
    field(THVL, "3")
    field(FRST, "Int32")
    field(FRVL, "4")
    field(FVST, "UInt32")
    field(FVVL, "5")
    field(SXST, "Int64")
    field(SXVL, "6")
    field(SVST, "UInt64")
    field(SVVL, "7")
    field(EIST, "Float32")
    field(EIVL, "8")
    field(NIST, "Float64")
    field(NIVL, "9")
    field(TEST, "Automatic")
    field(TEVL, "-1")
    field(SCAN, "I/O Intr")
}

###################################################################
# These records control the background array processing           #
###################################################################
record(bo, "$(P)$(R)SaveBackground")
{
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SAVE_BACKGROUND")
    field(VAL,  "1")
    field(ZNAM, "No")
    field(ONAM, "Yes")
}

record(bi, "$(P)$(R)SaveBackground_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SAVE_BACKGROUND")
    field(ZNAM, "No")
    field(ONAM, "Yes")
    field(SCAN, "I/O Intr")
}

record(bo, "$(P)$(R)EnableBackground")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_BACKGROUND")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    info(autosaveFields, "VAL")
}

record(bi, "$(P)$(R)EnableBackground_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_BACKGROUND")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    field(ZSV,  "NO_ALARM")
    field(OSV,  "MINOR")
    field(SCAN, "I/O Intr")
}

record(bi, "$(P)$(R)ValidBackground_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))VALID_BACKGROUND")
    field(ZNAM, "Invalid")
    field(ONAM, "Valid")
    field(SCAN, "I/O Intr")
}

record(sseq, "$(P)$(R)ReadBackgroundTIFFSeq")
{
    # Make a backup copy of the NDArrayPort field
    field(DOL1, "$(P)$(R)NDArrayPort")
    field(LNK1, "$(P)$(R)PortBackup PP MS")
    # Set the NDArrayPort field to the TIFF plugin
    field(DOL2, "$(P)$(R)TIFF:PortName_RBV")
    field(LNK2, "$(P)$(R)NDArrayPort PP MS")
    # Enable array callbacks in the TIFF plugin
    field(STR3, "Enable")
    field(LNK3, "$(P)$(R)TIFF:ArrayCallbacks PP MS")
    # Read the TIFF file
    field(DLY4, "0.1")
    field(DO4, "1")
    field(LNK4, "$(P)$(R)TIFF:ReadFile PP MS")
    # Save background TIFF
    field(DLY5, "0.5")
    field(DO5, "1")
    field(LNK5, "$(P)$(R)SaveBackground PP MS")
    # Restore the NDArrayPort field
    field(DOL6, "$(P)$(R)PortBackup")
    field(LNK6, "$(P)$(R)NDArrayPort PP MS")
}

record(stringout, "$(P)$(R)PortBackup")
{
}

###################################################################
# These records control the flat field array processing           #
###################################################################
record(bo, "$(P)$(R)SaveFlatField")
{
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SAVE_FLAT_FIELD")
    field(VAL,  "1")
    field(ZNAM, "No")
    field(ONAM, "Yes")
}

record(bi, "$(P)$(R)SaveFlatField_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SAVE_FLAT_FIELD")
    field(ZNAM, "No")
    field(ONAM, "Yes")
    field(SCAN, "I/O Intr")
}

record(bo, "$(P)$(R)EnableFlatField")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_FLAT_FIELD")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    info(autosaveFields, "VAL")
}

record(bi, "$(P)$(R)EnableFlatField_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_FLAT_FIELD")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    field(ZSV,  "NO_ALARM")
    field(OSV,  "MINOR")
    field(SCAN, "I/O Intr")
}

record(bi, "$(P)$(R)ValidFlatField_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))VALID_FLAT_FIELD")
    field(ZNAM, "Invalid")
    field(ONAM, "Valid")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)ScaleFlatField")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SCALE_FLAT_FIELD")
    field(VAL,  "255.")
    info(autosaveFields, "VAL")
}

record(ai, "$(P)$(R)ScaleFlatField_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SCALE_FLAT_FIELD")
    field(SCAN, "I/O Intr")
}

record(sseq, "$(P)$(R)ReadFlatFieldTIFFSeq")
{
    # Make a backup copy of the NDArrayPort field
    field(DOL1, "$(P)$(R)NDArrayPort")
    field(LNK1, "$(P)$(R)PortBackup PP MS")
    # Set the NDArrayPort field to the TIFF plugin
    field(DOL2, "$(P)$(R)TIFF:PortName_RBV")
    field(LNK2, "$(P)$(R)NDArrayPort PP MS")
    # Enable array callbacks in the TIFF plugin
    field(STR3, "Enable")
    field(LNK3, "$(P)$(R)TIFF:ArrayCallbacks PP MS")
    # Read the TIFF file
    field(DLY4, "0.1")
    field(DO4, "1")
    field(LNK4, "$(P)$(R)TIFF:ReadFile PP MS")
    # Save background TIFF
    field(DLY5, "0.5")
    field(DO5, "1")
    field(LNK5, "$(P)$(R)SaveFlatField PP MS")
    # Restore the NDArrayPort field
    field(DOL6, "$(P)$(R)PortBackup")
    field(LNK6, "$(P)$(R)NDArrayPort PP MS")
}

###################################################################
# These records control the offset and scale                      #
###################################################################
record(bo, "$(P)$(R)EnableOffsetScale")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_OFFSET_SCALE")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    info(autosaveFields, "VAL")
}

# Oneshot record for calculating scale and offset
record(busy, "$(P)$(R)AutoOffsetScale")
{
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))AUTO_OFFSET_SCALE")
    field(ZNAM, "Done")
    field(ONAM, "Calculating")
}

record(bi, "$(P)$(R)EnableOffsetScale_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_OFFSET_SCALE")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    field(ZSV,  "NO_ALARM")
    field(OSV,  "MINOR")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)Offset")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))OFFSET")
    field(PREC, "2")
    field(VAL,  "0.0")
    info(autosaveFields, "VAL")
}

record(ai, "$(P)$(R)Offset_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))OFFSET")
    field(PREC, "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)Scale")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SCALE")
    field(PREC, "2")
    field(VAL,  "1.0")
    info(autosaveFields, "VAL")
}

record(ai, "$(P)$(R)Scale_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))SCALE")
    field(PREC, "2")
    field(SCAN, "I/O Intr")
}

###################################################################
# These records control the high and low clipping                 #
###################################################################
record(bo, "$(P)$(R)EnableLowClip")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_LOW_CLIP")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    info(autosaveFields, "VAL")
}

record(bi, "$(P)$(R)EnableLowClip_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_LOW_CLIP")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    field(ZSV,  "NO_ALARM")
    field(OSV,  "MINOR")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)LowClipThresh")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))LOW_CLIP_THRESH")
    field(VAL,  "0.0")
    info(autosaveFields, "VAL")
}

record(ai, "$(P)$(R)LowClipThresh_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))LOW_CLIP_THRESH")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)LowClipValue")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))LOW_CLIP_VALUE")
    field(VAL,  "0.0")
    info(autosaveFields, "VAL")
}

record(ai, "$(P)$(R)LowClipValue_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))LOW_CLIP_VALUE")
    field(SCAN, "I/O Intr")
}

record(bo, "$(P)$(R)EnableHighClip")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_HIGH_CLIP")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    info(autosaveFields, "VAL")
}

record(bi, "$(P)$(R)EnableHighClip_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_HIGH_CLIP")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    field(ZSV,  "NO_ALARM")
    field(OSV,  "MINOR")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)HighClipThresh")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))HIGH_CLIP_THRESH")
    field(VAL,  "100.0")
    info(autosaveFields, "VAL")
}

record(ai, "$(P)$(R)HighClipThresh_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))HIGH_CLIP_THRESH")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)HighClipValue")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))HIGH_CLIP_VALUE")
    field(VAL,  "100.0")
    info(autosaveFields, "VAL")
}

record(ai, "$(P)$(R)HighClipValue_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))HIGH_CLIP_VALUE")
    field(SCAN, "I/O Intr")
}

###################################################################
# These records control frame filtering                           #
###################################################################
record(bo, "$(P)$(R)EnableFilter")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_FILTER")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    info(autosaveFields, "VAL")
}

record(bi, "$(P)$(R)EnableFilter_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))ENABLE_FILTER")
    field(ZNAM, "Disable")
    field(ONAM, "Enable")
    field(ZSV,  "NO_ALARM")
    field(OSV,  "MINOR")
    field(SCAN, "I/O Intr")
}

record(bo, "$(P)$(R)ResetFilter")
{
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))RESET_FILTER")
    field(VAL,  "1")
    field(ZNAM, "No")
    field(ONAM, "Yes")
}

record(bi, "$(P)$(R)ResetFilter_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))RESET_FILTER")
    field(ZNAM, "No")
    field(ONAM, "Yes")
    field(SCAN, "I/O Intr")
}

record(bo, "$(P)$(R)AutoResetFilter")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))AUTO_RESET_FILTER")
    field(ZNAM, "No")
    field(ONAM, "Yes")
    info(autosaveFields, "VAL")
}

record(bi, "$(P)$(R)AutoResetFilter_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))AUTO_RESET_FILTER")
    field(ZNAM, "No")
    field(ONAM, "Yes")
    field(SCAN, "I/O Intr")
}

record(bo, "$(P)$(R)FilterCallbacks")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_CALLBACKS")
    field(ZNAM, "Every array")
    field(ONAM, "Array N only")
    info(autosaveFields, "VAL")
}

record(bi, "$(P)$(R)FilterCallbacks_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_CALLBACKS")
    field(ZNAM, "Every array")
    field(ONAM, "Array N only")
    field(SCAN, "I/O Intr")
}

record(longout, "$(P)$(R)NumFilter")
{
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))NUM_FILTER")
    field(VAL,  "1")
    field(FLNK, "$(P)$(R)NumFilterRecip.PROC PP")
    info(autosaveFields, "VAL")
}

record(longin, "$(P)$(R)NumFilter_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))NUM_FILTER")
    field(SCAN, "I/O Intr")
}

# This is 1/NumFilter, used in RecursiveSum filter
# If this value changes we need to process FilterType to make it update filter coefficients
record(calc, "$(P)$(R)NumFilterRecip")
{
    field(INPA, "$(P)$(R)NumFilter.VAL NPP")
    field(CALC, "1./A")
    field(FLNK, "$(P)$(R)FilterType.PROC PP")
}

record(longin, "$(P)$(R)NumFiltered_RBV")
{
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))NUM_FILTERED")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)OOffset")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OOFFSET")
    field(VAL,  "0.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)OOffset_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OOFFSET")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)OScale")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OSCALE")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)OScale_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OSCALE")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)OC1")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC1")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)OC1_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC1")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)OC2")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC2")
    field(VAL,  "-1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)OC2_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC2")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)OC3")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC3")
    field(VAL,  "0.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)OC3_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC3")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)OC4")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC4")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)OC4_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_OC4")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)FOffset")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FOFFSET")
    field(VAL,  "0.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)FOffset_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FOFFSET")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)FScale")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FSCALE")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)FScale_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FSCALE")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)FC1")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC1")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)FC1_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC1")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)FC2")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC2")
    field(VAL,  "-1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)FC2_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC2")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}
record(ao, "$(P)$(R)FC3")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC3")
    field(VAL,  "0.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)FC3_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC3")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)FC4")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC4")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)FC4_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_FC4")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}
record(ao, "$(P)$(R)ROffset")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_ROFFSET")
    field(VAL,  "0.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)ROffset_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_ROFFSET")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)RC1")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_RC1")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)RC1_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_RC1")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

record(ao, "$(P)$(R)RC2")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_RC2")
    field(VAL,  "1.0")
    field(PREC, "2")
    info(autosaveFields, "VAL")
}
record(ai, "$(P)$(R)RC2_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))FILTER_RC2")
    field(PREC,  "2")
    field(SCAN, "I/O Intr")
}

# We don't see PINI=YES for FilterType because we want to restore the actual coefficients
# We do restore this record, but we don't process it
record(mbbo, "$(P)$(R)FilterType")
{
    field(ZRST, "RecursiveAve")
    field(ZRVL, "1")
    field(ONST, "Average")
    field(ONVL, "2")
    field(TWST, "Sum")
    field(TWVL, "3")
    field(THST, "Difference")
    field(THVL, "4")
    field(FRST, "RecursiveAveDiff")
    field(FRVL, "5")
    field(FVST, "CopyToFilter")
    field(FVVL, "6")
    field(FLNK, "$(P)$(R)FilterTypeSeq PP MS")
    info(autosaveFields, "VAL")
}

record(seq, "$(P)$(R)FilterTypeSeq")
{
    field(SELL, "$(P)$(R)FilterType.RVAL NPP")
    field(SELM, "Specified")
    field(DOL1, "1")
    field(LNK1, "$(P)$(R)RecursiveAveSeq.PROC PP MS")
    field(DOL2, "1")
    field(LNK2, "$(P)$(R)AverageSeq.PROC PP MS")
    field(DOL3, "1")
    field(LNK3, "$(P)$(R)SumSeq.PROC PP MS")
    field(DOL4, "1")
    field(LNK4, "$(P)$(R)DifferenceSeq.PROC PP MS")
    field(DOL5, "1")
    field(LNK5, "$(P)$(R)RecursiveAveDiffSeq.PROC PP MS")
    field(DOL6, "1")
    field(LNK6, "$(P)$(R)CopyToFilterSeq.PROC PP MS")
}

record(seq, "$(P)$(R)RecursiveAveSeq")
{
    field(DOL1, "1")
    field(LNK1, "$(P)$(R)OC1 PP MS")
    field(DOL2, "-1")
    field(LNK2, "$(P)$(R)OC2 PP MS")
    field(DOL3, "0")
    field(LNK3, "$(P)$(R)OC3 PP MS")
    field(DOL4, "1")
    field(LNK4, "$(P)$(R)OC4 PP MS")
    field(DOL5, "1")
    field(LNK5, "$(P)$(R)FC1 PP MS")
    field(DOL6, "-1")
    field(LNK6, "$(P)$(R)FC2 PP MS")
    field(DOL7, "0")
    field(LNK7, "$(P)$(R)FC3 PP MS")
    field(DOL8, "1")
    field(LNK8, "$(P)$(R)FC4 PP MS")
    field(DOL9, "0")
    field(LNK9, "$(P)$(R)RC1 PP MS")
    field(DOLA, "1")
    field(LNKA, "$(P)$(R)RC2 PP MS")
}

record(seq, "$(P)$(R)AverageSeq")
{
    field(DOL1, "1")
    field(LNK1, "$(P)$(R)OC1 PP MS")
    field(DOL2, "0")
    field(LNK2, "$(P)$(R)OC2 PP MS")
    field(DOL3, "$(P)$(R)NumFilterRecip NPP")
    field(LNK3, "$(P)$(R)OC3 PP MS")
    field(DOL4, "0")
    field(LNK4, "$(P)$(R)OC4 PP MS")
    field(DOL5, "1")
    field(LNK5, "$(P)$(R)FC1 PP MS")
    field(DOL6, "0")
    field(LNK6, "$(P)$(R)FC2 PP MS")
    field(DOL7, "$(P)$(R)NumFilterRecip NPP")
    field(LNK7, "$(P)$(R)FC3 PP MS")
    field(DOL8, "0")
    field(LNK8, "$(P)$(R)FC4 PP MS")
    field(DOL9, "0")
    field(LNK9, "$(P)$(R)RC1 PP MS")
    field(DOLA, "0")
    field(LNKA, "$(P)$(R)RC2 PP MS")
}

record(seq, "$(P)$(R)SumSeq")
{
    field(DOL1, "1")
    field(LNK1, "$(P)$(R)OC1 PP MS")
    field(DOL2, "0")
    field(LNK2, "$(P)$(R)OC2 PP MS")
    field(DOL3, "1")
    field(LNK3, "$(P)$(R)OC3 PP MS")
    field(DOL4, "0")
    field(LNK4, "$(P)$(R)OC4 PP MS")
    field(DOL5, "1")
    field(LNK5, "$(P)$(R)FC1 PP MS")
    field(DOL6, "0")
    field(LNK6, "$(P)$(R)FC2 PP MS")
    field(DOL7, "1")
    field(LNK7, "$(P)$(R)FC3 PP MS")
    field(DOL8, "0")
    field(LNK8, "$(P)$(R)FC4 PP MS")
    field(DOL9, "0")
    field(LNK9, "$(P)$(R)RC1 PP MS")
    field(DOLA, "0")
    field(LNKA, "$(P)$(R)RC2 PP MS")
}

record(seq, "$(P)$(R)DifferenceSeq")
{
    field(DOL1, "-1")
    field(LNK1, "$(P)$(R)OC1 PP MS")
    field(DOL2, "0")
    field(LNK2, "$(P)$(R)OC2 PP MS")
    field(DOL3, "1")
    field(LNK3, "$(P)$(R)OC3 PP MS")
    field(DOL4, "0")
    field(LNK4, "$(P)$(R)OC4 PP MS")
    field(DOL5, "0")
    field(LNK5, "$(P)$(R)FC1 PP MS")
    field(DOL6, "0")
    field(LNK6, "$(P)$(R)FC2 PP MS")
    field(DOL7, "1")
    field(LNK7, "$(P)$(R)FC3 PP MS")
    field(DOL8, "0")
    field(LNK8, "$(P)$(R)FC4 PP MS")
    field(DOL9, "0")
    field(LNK9, "$(P)$(R)RC1 PP MS")
    field(DOLA, "1")
    field(LNKA, "$(P)$(R)RC2 PP MS")
}

record(seq, "$(P)$(R)RecursiveAveDiffSeq")
{
    field(DOL1, "-1")
    field(LNK1, "$(P)$(R)OC1 PP MS")
    field(DOL2, "0")
    field(LNK2, "$(P)$(R)OC2 PP MS")
    field(DOL3, "1")
    field(LNK3, "$(P)$(R)OC3 PP MS")
    field(DOL4, "0")
    field(LNK4, "$(P)$(R)OC4 PP MS")
    field(DOL5, "1")
    field(LNK5, "$(P)$(R)FC1 PP MS")
    field(DOL6, "-1")
    field(LNK6, "$(P)$(R)FC2 PP MS")
    field(DOL7, "0")
    field(LNK7, "$(P)$(R)FC3 PP MS")
    field(DOL8, "1")
    field(LNK8, "$(P)$(R)FC4 PP MS")
    field(DOL9, "0")
    field(LNK9, "$(P)$(R)RC1 PP MS")
    field(DOLA, "1")
    field(LNKA, "$(P)$(R)RC2 PP MS")
}

record(seq, "$(P)$(R)CopyToFilterSeq")
{
    field(DOL1, "0")
    field(LNK1, "$(P)$(R)OC1 PP MS")
    field(DOL2, "0")
    field(LNK2, "$(P)$(R)OC2 PP MS")
    field(DOL3, "1")
    field(LNK3, "$(P)$(R)OC3 PP MS")
    field(DOL4, "0")
    field(LNK4, "$(P)$(R)OC4 PP MS")
    field(DOL5, "0")
    field(LNK5, "$(P)$(R)FC1 PP MS")
    field(DOL6, "0")
    field(LNK6, "$(P)$(R)FC2 PP MS")
    field(DOL7, "1")
    field(LNK7, "$(P)$(R)FC3 PP MS")
    field(DOL8, "0")
    field(LNK8, "$(P)$(R)FC4 PP MS")
    field(DOL9, "0")
    field(LNK9, "$(P)$(R)RC1 PP MS")
    field(DOLA, "1")
    field(LNKA, "$(P)$(R)RC2 PP MS")
}
