Drivers

The generated header file contains the string parameters, and defines the parameters to make the interface. In this example we have a header file pilatusDetectorParamSet.h:

#ifndef PilatusDetectorParamSet_H
#define PilatusDetectorParamSet_H

#include "ADDriverParamSet.h"

#define PilatusResetPowerString "RESET_POWER"
#define PilatusThresholdApplyString "THRESHOLD_APPLY"
#define PilatusImageFileTmotString "IMAGE_FILE_TMOT"
#define PilatusWavelengthString "WAVELENGTH"
#define PilatusEnergyLowString "ENERGY_LOW"
#define PilatusEnergyHighString "ENERGY_HIGH"
#define PilatusDetDistString "DET_DIST"
#define PilatusDetVOffsetString "DET_VOFFSET"
#define PilatusBeamXString "BEAM_X"
#define PilatusBeamYString "BEAM_Y"
#define PilatusFluxString "FLUX"
#define PilatusFilterTransmString "FILTER_TRANSM"
#define PilatusStartAngleString "START_ANGLE"
#define PilatusAngleIncrString "ANGLE_INCR"
#define PilatusDet2thetaString "DET_2THETA"
#define PilatusPolarizationString "POLARIZATION"
#define PilatusAlphaString "ALPHA"
#define PilatusKappaString "KAPPA"
#define PilatusPhiString "PHI"
#define PilatusPhiIncrString "PHI_INCR"
#define PilatusChiString "CHI"
#define PilatusChiIncrString "CHI_INCR"
#define PilatusOmegaString "OMEGA"
#define PilatusOmegaIncrString "OMEGA_INCR"
#define PilatusOscillAxisString "OSCILL_AXIS"
#define PilatusNumOscillString "NUM_OSCILL"
#define PilatusBadPixelFileString "BAD_PIXEL_FILE"
#define PilatusFlatFieldFileString "FLAT_FIELD_FILE"
#define PilatusCbfTemplateFileString "CBFTEMPLATEFILE"
#define PilatusHeaderStringString "HEADERSTRING"
#define PilatusArmedString "ARMED"
#define PilatusNumBadPixelsString "NUM_BAD_PIXELS"
#define PilatusFlatFieldValidString "FLAT_FIELD_VALID"
#define PilatusPixelCutOffString "PIXEL_CUTOFF"
#define PilatusThTemp0String "TH_TEMP_0"
#define PilatusThTemp1String "TH_TEMP_1"
#define PilatusThTemp2String "TH_TEMP_2"
#define PilatusThHumid0String "TH_HUMID_0"
#define PilatusThHumid1String "TH_HUMID_1"
#define PilatusThHumid2String "TH_HUMID_2"
#define PilatusTvxVersionString "TVXVERSION"
#define PilatusResetPowerTimeString "RESET_POWER_TIME"
#define PilatusDelayTimeString "DELAY_TIME"
#define PilatusThresholdString "THRESHOLD"
#define PilatusThresholdAutoApplyString "THRESHOLD_AUTO_APPLY"
#define PilatusEnergyString "ENERGY"
#define PilatusMinFlatFieldString "MIN_FLAT_FIELD"
#define PilatusGapFillString "GAP_FILL"
#define ProgressBarTestString "PROGRESS"

const std::string pilatusParamTree = \
"{\"parameters\":[{\"type\": \"Group\", \"name\": \"ComponentGroupOne\", \"label\": \"\", \"layout\": {\"type\": \"Grid\", \"labelled\": true}, \"children\": [{\"type\": \"SignalW\", \"name\": \"WaitForPlugins\", \"label\": \"\", \"pv\": \"WaitForPlugins\", \"widget\": {\"type\": \"CheckBox\"}}, {\"type\": \"SignalW\", \"name\": \"EmptyFreeList\", \"label\": \"\", \"pv\": \"EmptyFreeList\", \"widget\": {\"type\": \"CheckBox\"}}, {\"type\": \"SignalW\", \"name\": \"NDAttributesMacros\", \"label\": \"\", \"pv\": \"NDAttributesMacros\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"NDAttributesFile\", \"label\": \"\", \"pv\": \"NDAttributesFile\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"ADCoreVersion\", \"label\": \"\", \"pv\": \"ADCoreVersion_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"DriverVersion\", \"label\": \"\", \"pv\": \"DriverVersion_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"PortName\", \"label\": \"\", \"pv\": \"PortName_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Manufacturer\", \"label\": \"\", \"pv\": \"Manufacturer_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Model\", \"label\": \"\", \"pv\": \"Model_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"SerialNumber\", \"label\": \"\", \"pv\": \"SerialNumber_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"SDKVersion\", \"label\": \"\", \"pv\": \"SDKVersion_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"FirmwareVersion\", \"label\": \"\", \"pv\": \"FirmwareVersion_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"AcquireBusyCB\", \"label\": \"\", \"pv\": \"AcquireBusyCB\", \"widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"BayerPattern\", \"label\": \"\", \"pv\": \"BayerPattern_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"ArraySizeX\", \"label\": \"\", \"pv\": \"ArraySizeX_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"ArraySizeY\", \"label\": \"\", \"pv\": \"ArraySizeY_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"ArraySizeZ\", \"label\": \"\", \"pv\": \"ArraySizeZ_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"ArraySize\", \"label\": \"\", \"pv\": \"ArraySize_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Codec\", \"label\": \"\", \"pv\": \"Codec_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"CompressedSize\", \"label\": \"\", \"pv\": \"CompressedSize_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"UniqueId\", \"label\": \"\", \"pv\": \"UniqueId_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"TimeStamp\", \"label\": \"\", \"pv\": \"TimeStamp_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"EpicsTSSec\", \"label\": \"\", \"pv\": \"EpicsTSSec_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"EpicsTSNsec\", \"label\": \"\", \"pv\": \"EpicsTSNsec_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"NDAttributesStatus\", \"label\": \"\", \"pv\": \"NDAttributesStatus\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"PoolMaxMem\", \"label\": \"\", \"pv\": \"PoolMaxMem\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"PoolUsedMem\", \"label\": \"\", \"pv\": \"PoolUsedMem\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"PoolAllocBuffers\", \"label\": \"\", \"pv\": \"PoolAllocBuffers\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"PoolFreeBuffers\", \"label\": \"\", \"pv\": \"PoolFreeBuffers\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"NumQueuedArrays\", \"label\": \"\", \"pv\": \"NumQueuedArrays\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"Acquire\", \"label\": \"\", \"pv\": \"Acquire\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"\", \"read_widget\": null}, {\"type\": \"SignalRW\", \"name\": \"NDimensions\", \"label\": \"\", \"pv\": \"NDimensions\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"NDimensions_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"Dimensions\", \"label\": \"\", \"pv\": \"Dimensions\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"Dimensions_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"DataType\", \"label\": \"\", \"pv\": \"DataType\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"DataType_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ColorMode\", \"label\": \"\", \"pv\": \"ColorMode\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"ColorMode_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ArrayCounter\", \"label\": \"\", \"pv\": \"ArrayCounter\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"ArrayCounter_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ArrayCallbacks\", \"label\": \"\", \"pv\": \"ArrayCallbacks\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"ArrayCallbacks_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"FilePathExists\", \"label\": \"\", \"pv\": \"FilePathExists_RBV\", \"widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"FullFileName\", \"label\": \"\", \"pv\": \"FullFileName_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"NumCaptured\", \"label\": \"\", \"pv\": \"NumCaptured_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"WriteStatus\", \"label\": \"\", \"pv\": \"WriteStatus\", \"widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"WriteMessage\", \"label\": \"\", \"pv\": \"WriteMessage\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"FilePath\", \"label\": \"\", \"pv\": \"FilePath\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"FilePath_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"CreateDirectory\", \"label\": \"\", \"pv\": \"CreateDirectory\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"CreateDirectory_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"FileName\", \"label\": \"\", \"pv\": \"FileName\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"FileName_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"FileNumber\", \"label\": \"\", \"pv\": \"FileNumber\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"\", \"read_widget\": null}, {\"type\": \"SignalRW\", \"name\": \"AutoIncrement\", \"label\": \"\", \"pv\": \"AutoIncrement\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"AutoIncrement_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"FileTemplate\", \"label\": \"\", \"pv\": \"FileTemplate\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"FileTemplate_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"AutoSave\", \"label\": \"\", \"pv\": \"AutoSave\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"AutoSave_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"WriteFile\", \"label\": \"\", \"pv\": \"WriteFile\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"WriteFile_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"ReadFile\", \"label\": \"\", \"pv\": \"ReadFile\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"ReadFile_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"FileFormat\", \"label\": \"\", \"pv\": \"FileFormat\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"FileFormat_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"FileWriteMode\", \"label\": \"\", \"pv\": \"FileWriteMode\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"FileWriteMode_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"Capture\", \"label\": \"\", \"pv\": \"Capture\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"Capture_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"NumCapture\", \"label\": \"\", \"pv\": \"NumCapture\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"NumCapture_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"DeleteDriverFile\", \"label\": \"\", \"pv\": \"DeleteDriverFile\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"DeleteDriverFile_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"LazyOpen\", \"label\": \"\", \"pv\": \"LazyOpen\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"LazyOpen_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"TempSuffix\", \"label\": \"\", \"pv\": \"TempSuffix\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"TempSuffix_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"ReadStatus\", \"label\": \"\", \"pv\": \"ReadStatus\", \"widget\": {\"type\": \"CheckBox\"}}, {\"type\": \"SignalR\", \"name\": \"MaxSizeX\", \"label\": \"\", \"pv\": \"MaxSizeX_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"MaxSizeY\", \"label\": \"\", \"pv\": \"MaxSizeY_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"TimeRemaining\", \"label\": \"\", \"pv\": \"TimeRemaining_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"NumExposuresCounter\", \"label\": \"\", \"pv\": \"NumExposuresCounter_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"NumImagesCounter\", \"label\": \"\", \"pv\": \"NumImagesCounter_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"DetectorState\", \"label\": \"\", \"pv\": \"DetectorState_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"StatusMessage\", \"label\": \"\", \"pv\": \"StatusMessage_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"StringToServer\", \"label\": \"\", \"pv\": \"StringToServer_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"StringFromServer\", \"label\": \"\", \"pv\": \"StringFromServer_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"ShutterStatus\", \"label\": \"\", \"pv\": \"ShutterStatus_RBV\", \"widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"ShutterControlEPICS\", \"label\": \"\", \"pv\": \"ShutterControlEPICS\", \"widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"TemperatureActual\", \"label\": \"\", \"pv\": \"TemperatureActual\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"BinX\", \"label\": \"\", \"pv\": \"BinX\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"BinX_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"BinY\", \"label\": \"\", \"pv\": \"BinY\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"BinY_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"MinX\", \"label\": \"\", \"pv\": \"MinX\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"MinX_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"MinY\", \"label\": \"\", \"pv\": \"MinY\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"MinY_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"SizeX\", \"label\": \"\", \"pv\": \"SizeX\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"SizeX_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"SizeY\", \"label\": \"\", \"pv\": \"SizeY\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"SizeY_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ReverseX\", \"label\": \"\", \"pv\": \"ReverseX\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"ReverseX_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"ReverseY\", \"label\": \"\", \"pv\": \"ReverseY\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"ReverseY_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"AcquireTime\", \"label\": \"\", \"pv\": \"AcquireTime\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"AcquireTime_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"AcquirePeriod\", \"label\": \"\", \"pv\": \"AcquirePeriod\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"AcquirePeriod_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"Gain\", \"label\": \"\", \"pv\": \"Gain\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"Gain_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"FrameType\", \"label\": \"\", \"pv\": \"FrameType\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"FrameType_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ImageMode\", \"label\": \"\", \"pv\": \"ImageMode\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"ImageMode_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"TriggerMode\", \"label\": \"\", \"pv\": \"TriggerMode\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"TriggerMode_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"NumExposures\", \"label\": \"\", \"pv\": \"NumExposures\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"NumExposures_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"NumImages\", \"label\": \"\", \"pv\": \"NumImages\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"NumImages_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ShutterMode\", \"label\": \"\", \"pv\": \"ShutterMode\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"ShutterMode_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ShutterControl\", \"label\": \"\", \"pv\": \"ShutterControl\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"ShutterControl_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"ShutterOpenDelay\", \"label\": \"\", \"pv\": \"ShutterOpenDelay\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"ShutterOpenDelay_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ShutterCloseDelay\", \"label\": \"\", \"pv\": \"ShutterCloseDelay\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"ShutterCloseDelay_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"Temperature\", \"label\": \"\", \"pv\": \"Temperature\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"Temperature_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"ResetPower\", \"label\": \"\", \"pv\": \"ResetPower\", \"widget\": {\"type\": \"CheckBox\"}}, {\"type\": \"SignalW\", \"name\": \"ThresholdApply\", \"label\": \"\", \"pv\": \"ThresholdApply\", \"widget\": {\"type\": \"CheckBox\"}}, {\"type\": \"SignalW\", \"name\": \"ImageFileTmot\", \"label\": \"\", \"pv\": \"ImageFileTmot\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Wavelength\", \"label\": \"\", \"pv\": \"Wavelength\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"EnergyLow\", \"label\": \"\", \"pv\": \"EnergyLow\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"EnergyHigh\", \"label\": \"\", \"pv\": \"EnergyHigh\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"DetDist\", \"label\": \"\", \"pv\": \"DetDist\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"DetVOffset\", \"label\": \"\", \"pv\": \"DetVOffset\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"BeamX\", \"label\": \"\", \"pv\": \"BeamX\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"BeamY\", \"label\": \"\", \"pv\": \"BeamY\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Flux\", \"label\": \"\", \"pv\": \"Flux\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"FilterTransm\", \"label\": \"\", \"pv\": \"FilterTransm\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"StartAngle\", \"label\": \"\", \"pv\": \"StartAngle\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"AngleIncr\", \"label\": \"\", \"pv\": \"AngleIncr\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Det2theta\", \"label\": \"\", \"pv\": \"Det2theta\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Polarization\", \"label\": \"\", \"pv\": \"Polarization\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Alpha\", \"label\": \"\", \"pv\": \"Alpha\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Kappa\", \"label\": \"\", \"pv\": \"Kappa\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Phi\", \"label\": \"\", \"pv\": \"Phi\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"PhiIncr\", \"label\": \"\", \"pv\": \"PhiIncr\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Chi\", \"label\": \"\", \"pv\": \"Chi\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"ChiIncr\", \"label\": \"\", \"pv\": \"ChiIncr\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"Omega\", \"label\": \"\", \"pv\": \"Omega\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"OmegaIncr\", \"label\": \"\", \"pv\": \"OmegaIncr\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"OscillAxis\", \"label\": \"\", \"pv\": \"OscillAxis\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"NumOscill\", \"label\": \"\", \"pv\": \"NumOscill\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"BadPixelFile\", \"label\": \"\", \"pv\": \"BadPixelFile\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"FlatFieldFile\", \"label\": \"\", \"pv\": \"FlatFieldFile\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"CbfTemplateFile\", \"label\": \"\", \"pv\": \"CbfTemplateFile\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalW\", \"name\": \"HeaderString\", \"label\": \"\", \"pv\": \"HeaderString\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Armed\", \"label\": \"\", \"pv\": \"Armed\", \"widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"NumBadPixels\", \"label\": \"\", \"pv\": \"NumBadPixels\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"FlatFieldValid\", \"label\": \"\", \"pv\": \"FlatFieldValid\", \"widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalR\", \"name\": \"PixelCutOff\", \"label\": \"\", \"pv\": \"PixelCutOff_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Temp0\", \"label\": \"\", \"pv\": \"Temp0_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Temp1\", \"label\": \"\", \"pv\": \"Temp1_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Temp2\", \"label\": \"\", \"pv\": \"Temp2_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Humid0\", \"label\": \"\", \"pv\": \"Humid0_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Humid1\", \"label\": \"\", \"pv\": \"Humid1_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"Humid2\", \"label\": \"\", \"pv\": \"Humid2_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"TVXVersion\", \"label\": \"\", \"pv\": \"TVXVersion_RBV\", \"widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ResetPowerTime\", \"label\": \"\", \"pv\": \"ResetPowerTime\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"ResetPowerTime_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"DelayTime\", \"label\": \"\", \"pv\": \"DelayTime\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"DelayTime_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ThresholdEnergy\", \"label\": \"\", \"pv\": \"ThresholdEnergy\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"ThresholdEnergy_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"ThresholdAutoApply\", \"label\": \"\", \"pv\": \"ThresholdAutoApply\", \"widget\": {\"type\": \"CheckBox\"}, \"read_pv\": \"ThresholdAutoApply_RBV\", \"read_widget\": {\"type\": \"LED\"}}, {\"type\": \"SignalRW\", \"name\": \"Energy\", \"label\": \"\", \"pv\": \"Energy\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"Energy_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"MinFlatField\", \"label\": \"\", \"pv\": \"MinFlatField\", \"widget\": {\"type\": \"TextWrite\", \"lines\": 1}, \"read_pv\": \"MinFlatField_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalRW\", \"name\": \"GapFill\", \"label\": \"\", \"pv\": \"GapFill\", \"widget\": {\"type\": \"ComboBox\", \"choices\": []}, \"read_pv\": \"GapFill_RBV\", \"read_widget\": {\"type\": \"TextRead\", \"lines\": 1}}, {\"type\": \"SignalR\", \"name\": \"ProgressBarTest\", \"label\": \"\", \"pv\": \"ProgressBarTest_RBV\", \"widget\": {\"type\": \"ProgressBar\"}}]}]}";

class pilatusDetectorParamSet : public virtual ADDriverParamSet {
public:
    pilatusDetectorParamSet() {
        this->add(PilatusResetPowerString, asynParamInt32, &PilatusResetPower);
        this->add(PilatusThresholdApplyString, asynParamInt32, &PilatusThresholdApply);
        this->add(PilatusImageFileTmotString, asynParamFloat64, &PilatusImageFileTmot);
        this->add(PilatusWavelengthString, asynParamFloat64, &PilatusWavelength);
        this->add(PilatusEnergyLowString, asynParamFloat64, &PilatusEnergyLow);
        this->add(PilatusEnergyHighString, asynParamFloat64, &PilatusEnergyHigh);
        this->add(PilatusDetDistString, asynParamFloat64, &PilatusDetDist);
        this->add(PilatusDetVOffsetString, asynParamFloat64, &PilatusDetVOffset);
        this->add(PilatusBeamXString, asynParamFloat64, &PilatusBeamX);
        this->add(PilatusBeamYString, asynParamFloat64, &PilatusBeamY);
        this->add(PilatusFluxString, asynParamFloat64, &PilatusFlux);
        this->add(PilatusFilterTransmString, asynParamFloat64, &PilatusFilterTransm);
        this->add(PilatusStartAngleString, asynParamFloat64, &PilatusStartAngle);
        this->add(PilatusAngleIncrString, asynParamFloat64, &PilatusAngleIncr);
        this->add(PilatusDet2thetaString, asynParamFloat64, &PilatusDet2theta);
        this->add(PilatusPolarizationString, asynParamFloat64, &PilatusPolarization);
        this->add(PilatusAlphaString, asynParamFloat64, &PilatusAlpha);
        this->add(PilatusKappaString, asynParamFloat64, &PilatusKappa);
        this->add(PilatusPhiString, asynParamFloat64, &PilatusPhi);
        this->add(PilatusPhiIncrString, asynParamFloat64, &PilatusPhiIncr);
        this->add(PilatusChiString, asynParamFloat64, &PilatusChi);
        this->add(PilatusChiIncrString, asynParamFloat64, &PilatusChiIncr);
        this->add(PilatusOmegaString, asynParamFloat64, &PilatusOmega);
        this->add(PilatusOmegaIncrString, asynParamFloat64, &PilatusOmegaIncr);
        this->add(PilatusOscillAxisString, asynParamOctet, &PilatusOscillAxis);
        this->add(PilatusNumOscillString, asynParamInt32, &PilatusNumOscill);
        this->add(PilatusBadPixelFileString, asynParamOctet, &PilatusBadPixelFile);
        this->add(PilatusFlatFieldFileString, asynParamOctet, &PilatusFlatFieldFile);
        this->add(PilatusCbfTemplateFileString, asynParamOctet, &PilatusCbfTemplateFile);
        this->add(PilatusHeaderStringString, asynParamOctet, &PilatusHeaderString);
        this->add(PilatusArmedString, asynParamInt32, &PilatusArmed);
        this->add(PilatusNumBadPixelsString, asynParamInt32, &PilatusNumBadPixels);
        this->add(PilatusFlatFieldValidString, asynParamInt32, &PilatusFlatFieldValid);
        this->add(PilatusPixelCutOffString, asynParamInt32, &PilatusPixelCutOff);
        this->add(PilatusThTemp0String, asynParamFloat64, &PilatusThTemp0);
        this->add(PilatusThTemp1String, asynParamFloat64, &PilatusThTemp1);
        this->add(PilatusThTemp2String, asynParamFloat64, &PilatusThTemp2);
        this->add(PilatusThHumid0String, asynParamFloat64, &PilatusThHumid0);
        this->add(PilatusThHumid1String, asynParamFloat64, &PilatusThHumid1);
        this->add(PilatusThHumid2String, asynParamFloat64, &PilatusThHumid2);
        this->add(PilatusTvxVersionString, asynParamOctet, &PilatusTvxVersion);
        this->add(PilatusResetPowerTimeString, asynParamInt32, &PilatusResetPowerTime);
        this->add(PilatusDelayTimeString, asynParamFloat64, &PilatusDelayTime);
        this->add(PilatusThresholdString, asynParamFloat64, &PilatusThreshold);
        this->add(PilatusThresholdAutoApplyString, asynParamInt32, &PilatusThresholdAutoApply);
        this->add(PilatusEnergyString, asynParamFloat64, &PilatusEnergy);
        this->add(PilatusMinFlatFieldString, asynParamInt32, &PilatusMinFlatField);
        this->add(PilatusGapFillString, asynParamInt32, &PilatusGapFill);
        this->add(ProgressBarTestString, asynParamFloat64, &ProgressBarTest);

        this->paramTree = pilatusParamTree;
    }

    int PilatusResetPower;
    #define FIRST_PILATUSDETECTORPARAMSET_PARAM PilatusResetPower
    int PilatusThresholdApply;
    int PilatusImageFileTmot;
    int PilatusWavelength;
    int PilatusEnergyLow;
    int PilatusEnergyHigh;
    int PilatusDetDist;
    int PilatusDetVOffset;
    int PilatusBeamX;
    int PilatusBeamY;
    int PilatusFlux;
    int PilatusFilterTransm;
    int PilatusStartAngle;
    int PilatusAngleIncr;
    int PilatusDet2theta;
    int PilatusPolarization;
    int PilatusAlpha;
    int PilatusKappa;
    int PilatusPhi;
    int PilatusPhiIncr;
    int PilatusChi;
    int PilatusChiIncr;
    int PilatusOmega;
    int PilatusOmegaIncr;
    int PilatusOscillAxis;
    int PilatusNumOscill;
    int PilatusBadPixelFile;
    int PilatusFlatFieldFile;
    int PilatusCbfTemplateFile;
    int PilatusHeaderString;
    int PilatusArmed;
    int PilatusNumBadPixels;
    int PilatusFlatFieldValid;
    int PilatusPixelCutOff;
    int PilatusThTemp0;
    int PilatusThTemp1;
    int PilatusThTemp2;
    int PilatusThHumid0;
    int PilatusThHumid1;
    int PilatusThHumid2;
    int PilatusTvxVersion;
    int PilatusResetPowerTime;
    int PilatusDelayTime;
    int PilatusThreshold;
    int PilatusThresholdAutoApply;
    int PilatusEnergy;
    int PilatusMinFlatField;
    int PilatusGapFill;
    int ProgressBarTest;
};

#endif // PilatusDetectorParamSet_H

The existing pilatus.cpp is then modified to remove these parameters definitions and use the param set API.

Database Template File

According to the demand and readback properties of the component, the following records are created:

# This file was automatically generated
# *** Please do not edit this file: edit the source file instead. ***

# Group: ComponentGroupOne
record(bo, "$(P)$(R)ResetPower")
{
    field(DESC, "ResetPower")
    field(DTYP, "asynInt32")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))RESET_POWER")
    field(ZNAM, "Done")
    field(ONAM, "Reset")
}

record(busy, "$(P)$(R)ThresholdApply")
{
    field(DESC, "ThresholdApply")
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))THRESHOLD_APPLY")
    field(ONAM, "Apply")
}

record(ao, "$(P)$(R)ImageFileTmot")
{
    field(DESC, "Timeout for image file")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "20")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))IMAGE_FILE_TMOT")
    field(PREC, "3")
    field(EGU,  "s")
}

record(ao, "$(P)$(R)Wavelength")
{
    field(DESC, "Wavelength")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "1.54")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))WAVELENGTH")
    field(PREC, "4")
    field(EGU,  "Angstroms")
}

record(ao, "$(P)$(R)EnergyLow")
{
    field(DESC, "EnergyLow")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))ENERGY_LOW")
    field(PREC, "3")
    field(EGU,  "eV")
}

record(ao, "$(P)$(R)EnergyHigh")
{
    field(DESC, "EnergyHigh")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))ENERGY_HIGH")
    field(PREC, "3")
    field(EGU,  "eV")
}

record(ao, "$(P)$(R)DetDist")
{
    field(DESC, "DetDist")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "1000")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))DET_DIST")
    field(PREC, "3")
    field(EGU,  "mm")
}

record(ao, "$(P)$(R)DetVOffset")
{
    field(DESC, "DetVOffset")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))DET_VOFFSET")
    field(PREC, "3")
    field(EGU,  "mm")
}

record(ao, "$(P)$(R)BeamX")
{
    field(DESC, "BeamX")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))BEAM_X")
    field(PREC, "3")
    field(EGU,  "pixels")
}

record(ao, "$(P)$(R)BeamY")
{
    field(DESC, "BeamY")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))BEAM_Y")
    field(PREC, "3")
    field(EGU,  "pixels")
}

record(ao, "$(P)$(R)Flux")
{
    field(DESC, "Flux")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLUX")
    field(PREC, "4")
    field(EGU,  "ph/s")
}

record(ao, "$(P)$(R)FilterTransm")
{
    field(DESC, "FilterTransm")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "1.0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))FILTER_TRANSM")
    field(PREC, "4")
}

record(ao, "$(P)$(R)StartAngle")
{
    field(DESC, "StartAngle")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))START_ANGLE")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)AngleIncr")
{
    field(DESC, "AngleIncr")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0.1")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))ANGLE_INCR")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)Det2theta")
{
    field(DESC, "Det2theta")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))DET_2THETA")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)Polarization")
{
    field(DESC, "Polarization")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0.99")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))POLARIZATION")
    field(PREC, "4")
}

record(ao, "$(P)$(R)Alpha")
{
    field(DESC, "Alpha")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))ALPHA")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)Kappa")
{
    field(DESC, "Kappa")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))KAPPA")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)Phi")
{
    field(DESC, "Phi")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))PHI")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)PhiIncr")
{
    field(DESC, "PhiIncr")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0.1")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))PHI_INCR")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)Chi")
{
    field(DESC, "Chi")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))CHI")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)ChiIncr")
{
    field(DESC, "ChiIncr")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0.1")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))CHI_INCR")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)Omega")
{
    field(DESC, "Omega")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))OMEGA")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(ao, "$(P)$(R)OmegaIncr")
{
    field(DESC, "OmegaIncr")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0.1")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))OMEGA_INCR")
    field(PREC, "4")
    field(EGU,  "deg")
}

record(stringout, "$(P)$(R)OscillAxis")
{
    field(DESC, "OscillAxis")
    field(PINI, "YES")
    field(DTYP, "asynOctetWrite")
    field(VAL,  "X, CW")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))OSCILL_AXIS")
}

record(longout, "$(P)$(R)NumOscill")
{
    field(DESC, "NumOscill")
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(VAL,  "1")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))NUM_OSCILL")
}

record(waveform, "$(P)$(R)BadPixelFile")
{
    field(DESC, "BadPixelFile")
    field(DTYP, "asynOctetWrite")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))BAD_PIXEL_FILE")
    field(NELM, "256")
    field(FTVL, "CHAR")
}

record(waveform, "$(P)$(R)FlatFieldFile")
{
    field(DESC, "FlatFieldFile")
    field(DTYP, "asynOctetWrite")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLAT_FIELD_FILE")
    field(NELM, "256")
    field(FTVL, "CHAR")
}

record(waveform, "$(P)$(R)CbfTemplateFile")
{
    field(DESC, "CbfTemplateFile")
    field(DTYP, "asynOctetWrite")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))CBFTEMPLATEFILE")
    field(NELM, "256")
    field(FTVL, "CHAR")
}

record(waveform, "$(P)$(R)HeaderString")
{
    field(DESC, "HeaderString")
    field(DTYP, "asynOctetWrite")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))HEADERSTRING")
    field(NELM, "68")
    field(FTVL, "CHAR")
}

record(bi, "$(P)$(R)Armed")
{
    field(DESC, "Armed")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))ARMED")
    field(ZNAM, "Unarmed")
    field(ONAM, "Armed")
}

record(longin, "$(P)$(R)NumBadPixels")
{
    field(DESC, "Number of bad pixels")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))NUM_BAD_PIXELS")
}

record(bi, "$(P)$(R)FlatFieldValid")
{
    field(DESC, "Flat field valid")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))FLAT_FIELD_VALID")
    field(ZNAM, "No")
    field(ONAM, "Yes")
}

record(ai, "$(P)$(R)PixelCutOff_RBV")
{
    field(DESC, "PixelCutOff_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))PIXEL_CUTOFF")
    field(EGU,  "counts")
}

record(ai, "$(P)$(R)Temp0_RBV")
{
    field(DESC, "Temp0_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))TH_TEMP_0")
    field(PREC, "1")
    field(EGU,  "C")
}

record(ai, "$(P)$(R)Temp1_RBV")
{
    field(DESC, "Temp1_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))TH_TEMP_1")
    field(PREC, "1")
    field(EGU,  "C")
}

record(ai, "$(P)$(R)Temp2_RBV")
{
    field(DESC, "Temp2_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))TH_TEMP_2")
    field(PREC, "1")
    field(EGU,  "C")
}

record(ai, "$(P)$(R)Humid0_RBV")
{
    field(DESC, "Humid0_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))TH_HUMID_0")
    field(PREC, "1")
    field(EGU,  "%")
}

record(ai, "$(P)$(R)Humid1_RBV")
{
    field(DESC, "Humid1_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))TH_HUMID_1")
    field(PREC, "1")
    field(EGU,  "%")
}

record(ai, "$(P)$(R)Humid2_RBV")
{
    field(DESC, "Humid2_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))TH_HUMID_2")
    field(PREC, "1")
    field(EGU,  "%")
}

record(stringin, "$(P)$(R)TVXVersion_RBV")
{
    field(DESC, "TVXVersion_RBV")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynOctetRead")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))TVXVERSION")
}

record(longin, "$(P)$(R)ResetPowerTime_RBV")
{
    field(DESC, "Reset module power wait time")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))RESET_POWER_TIME")
    field(EGU,  "Seconds")
}

record(longout, "$(P)$(R)ResetPowerTime")
{
    field(DESC, "Reset module power wait time")
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(VAL,  "1")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))RESET_POWER_TIME")
    field(EGU,  "Seconds")
}

record(ai, "$(P)$(R)DelayTime_RBV")
{
    field(DESC, "DelayTime")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))DELAY_TIME")
    field(PREC, "6")
    field(EGU,  "s")
}

record(ao, "$(P)$(R)DelayTime")
{
    field(DESC, "DelayTime")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))DELAY_TIME")
    field(PREC, "6")
    field(EGU,  "s")
}

record(ai, "$(P)$(R)ThresholdEnergy_RBV")
{
    field(DESC, "Energy threshold")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))THRESHOLD")
    field(PREC, "3")
    field(EGU,  "keV")
}

record(ao, "$(P)$(R)ThresholdEnergy")
{
    field(DESC, "Energy threshold")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "10.000")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))THRESHOLD")
    field(PREC, "3")
    field(EGU,  "keV")
}

record(bi, "$(P)$(R)ThresholdAutoApply_RBV")
{
    field(DESC, "ThresholdAutoApply")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))THRESHOLD_AUTO_APPLY")
    field(ZNAM, "No")
    field(ONAM, "Yes")
}

record(bo, "$(P)$(R)ThresholdAutoApply")
{
    field(DESC, "ThresholdAutoApply")
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(VAL,  "1")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))THRESHOLD_AUTO_APPLY")
    field(ZNAM, "No")
    field(ONAM, "Yes")
}

record(ai, "$(P)$(R)Energy_RBV")
{
    field(DESC, "X-ray Energy")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))ENERGY")
    field(PREC, "3")
    field(EGU,  "keV")
}

record(ao, "$(P)$(R)Energy")
{
    field(DESC, "X-ray Energy")
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(VAL,  "20.000")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))ENERGY")
    field(PREC, "3")
    field(EGU,  "keV")
}

record(longin, "$(P)$(R)MinFlatField_RBV")
{
    field(DESC, "Minimum flat field value")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))MIN_FLAT_FIELD")
    field(EGU,  "Counts")
}

record(longout, "$(P)$(R)MinFlatField")
{
    field(DESC, "Minimum flat field value")
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(VAL,  "100")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))MIN_FLAT_FIELD")
    field(EGU,  "Counts")
}

record(mbbi, "$(P)$(R)GapFill_RBV")
{
    field(DESC, "GapFill")
    field(SCAN, "I/O Intr")
    field(DTYP, "asynInt32")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))GAP_FILL")
    field(ZRVL, "2")
    field(ONVL, "0")
    field(TWVL, "-1")
    field(ZRST, "N.A.")
    field(ONST, "0")
    field(TWST, "-1")
}

record(mbbo, "$(P)$(R)GapFill")
{
    field(DESC, "GapFill")
    field(PINI, "YES")
    field(DTYP, "asynInt32")
    field(VAL,  "0")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))GAP_FILL")
    field(ZRVL, "2")
    field(ONVL, "0")
    field(TWVL, "-1")
    field(ZRST, "N.A.")
    field(ONST, "0")
    field(TWST, "-1")
}

record(ai, "$(P)$(R)ProgressBarTest_RBV")
{
    field(DESC, "ProgressBar")
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))PROGRESS")
    field(PREC, "4")
    field(EGU,  "deg")
}

The top level pilatus.template includes this file, as well as records that provide logic (for things like the arrayRate and EPICSShutter in areaDetector).

UI

Finally, UI elements can be generated for each component for multiple graphical applications. For example, the following EDM screen is generated:

../_images/pilatus_edl.png

This can serve as a low level overview of the entire system, as well as a convenient pallette for constructing higher level, more structured screens.

Ongoing Development

Once a module is working with PVI (either an existing module after the YAML is created from the templates using the one time generation script, or a newly written module) it will then be necessary to update the YAML file in future development. Here is an example of necessary changes to add a new parameter, with and without PVI:

With PVI

Update YAML file:

- type: AsynFloat64
  name: DelayTime
  description: Delay in seconds between the external trigger and the start of image acquisition
  role: Setting
  initial: 0
  record_fields:
    PREC: 3
    EGU: s

And then run pvi (or possibly just make, if it is integrated into a Makefile). It can then be shared with other sites who can generate their own required files.

Without PVI

Update template:

# Delay time in External Trigger mode.
record(ao, "$(P)$(R)DelayTime")
{
    field(PINI, "YES")
    field(DTYP, "asynFloat64")
    field(OUT,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))DELAY_TIME")
    field(EGU,  "s")
    field(VAL,  "0")
    field(PREC, "6")
}

record(ai, "$(P)$(R)DelayTime_RBV")
{
    field(DTYP, "asynFloat64")
    field(INP,  "@asyn($(PORT),$(ADDR),$(TIMEOUT))DELAY_TIME")
    field(EGU,  "s")
    field(PREC, "6")
    field(SCAN, "I/O Intr")
}

Update header file:

...
#define PilatusDelayTimeString "DELAY_TIME"
...
createParam(PilatusDelayTimeString, asynParamFloat64, &PilatusDelayTime);
...
int PilatusDelayTime;
...

Update docs:

* - Delay in seconds between the external trigger and the start of image acquisition
  - DELAY_TIME
  - $(P)$(R)DelayTime
  - ao

Update screens (of course, this will actually involve editing with a graphical interface):

"text update" {
    object {
        x=604
        y=146
        width=80
        height=18
    }
    monitor {
        chan="$(P)$(R)DelayTime_RBV"
        clr=54
        bclr=4
    }
    align="horiz. centered"
    limits {
    }
}
"text entry" {
    object {
        x=540
        y=145
        width=59
        height=20
    }
    control {
        chan="$(P)$(R)DelayTime"
        clr=14
        bclr=51
    }
    limits {
    }
}
text {
    object {
        x=435
        y=145
        width=100
        height=20
    }
    "basic attribute" {
        clr=14
    }
    textix="Delay time"
    align="horiz. right"
}

Then either add equivalent changes to other screen types or use autoconvert, if available, and add any site specific details to any of these files (such as autosave and archiver tags).

Class Hierarchy

Drivers will access their parameters via a param set, either using inheritance or composition. The class hierarchy for param sets mirrors the drivers. Each of the ‘base’ classes (classes not instantiated directly) has-a paramSet containing its parameters in addition to its parent class(es). The most derived classes inherit their param sets so that they have direct access to all parameter indexes (and so that the source code does not have to change to insert paramSet-> to access them).

There is a new method asynPortDriver::createParams that iterates the member vector of asynParamSet storing parameter definitions and calls asynPortDriver::createParam (no ‘s’) on each of them. If the vector is empty (i.e. if it only has the default asynParamSet and not a specific implementation) it has no effect. This means asynPortDriver can be inherited from as before with no change.

Virtual inheritance is required for two reasons. Primarily, it ensures only a single instance of asynParamSet is created and it is shared throughout the class hierarchy to ensure asynPortDriver can find the child parameters. It also means that the most derived class must call the constructors for all virtual base classes before the non-virtual base classes. This means the constructors are called in the correct order such that when the asynPortDriver constructor the asynParamSet parameterDefinitions is fully populated when createParams is called.

Change Summary

  • asyn - https://github.com/dls-controls/asyn/tree/pvi
    • Created asynParamSet

    • New overloaded asynPortDriver constructor that takes an asynParamSet* and calls createParams()

  • ADCore - https://github.com/dls-controls/ADCore/tree/pvi
    • asynNDArrayDriver parameters split into asynNDArrayDriverParamSet

      Constructor updated to take an asynNDArrayDriverParamSet*. Updated to access parameters via paramSet->

    • ADDriver parameters split into ADDriverParamSet

      Constructor updated to take an ADDriverParamSet*. Updated to access parameters via paramSet->

    • NDPluginDriver inherits asynNDArrayDriverParamSet in addition to asynNDArrayDriver

      Updated to access parameters via paramSet->. Child classes work with no changes

    • Some trivial updates to the tests

  • ADSimDetector - https://github.com/dls-controls/ADSimDetector/tree/pvi
    • simDetector parameters split into simDetectorParamSet

    • simDetector inherits from simDetectorParamSet in addition to ADDriver

    • Can access parameters as before

  • ADPilatus - https://github.com/dls-controls/ADPilatus/tree/pvi
    • Equivalent to ADSimDetector changes

  • motor - https://github.com/dls-controls/motor/tree/pvi
    • asynMotorController parameters split into asynMotorControllerParamSet

    • Updated to access parameters via paramSet->

  • pmac - https://github.com/dls-controls/pmac/tree/pvi
    • pmacController parameters split into pmacControllerParamSet

    • pmacCSController same

    • Each inherit from their own param set (which inherits asynMotorControllerParamSet) in addition to asynMotorController

    • Can access parameters as before

Caveats

There are some changes that are unavoidable without inserting edge cases into the generation logic and making the YAML schema more complicated. Some examples are:

  1. The first param index used for calling base class methods is inconsistently named, so we will have to agree a consistent way to generate them and make them the same.

  2. Any readback parameters will have an _RBV suffix added. Some existing readbacks do not have this, e.g. Armed in pilatusDetector.

  3. FIRST_DRIVER_PARAM needs to be defined in the main header file based on the FIRST_DRIVER_PARAM_INDEX defined in the param set header file, appending paramSet-> or not depending on whether it inherits the param set or not. (This could possibly be handled in a better way by adding more logic to the asynParamSet - see Possible Further Work)

  4. Asyn parameter names will be the same as the name of the index variable. The value can be overridden to define drvInfo for drvUserCreate dynamic parameters.

Next Steps

A script is in development to perform the generation of an initial YAML file from a template. The idea being that after this point, everything is generated from the YAML file and any changes are made there and everything regenerated. New drivers can use a YAML file from the start.

The current hierarchy (base classes have-a param set while the most derived class is-a param set) is inconsistent and confusing, but it has the benefit that people are not forced to change drivers inheriting from these base classes to access parameters via paramSet->, they just need to inherit the parent param set. It also means that the most derived classes cannot be inherited from alongside an extended param set (this is not necessarily a problem, but it seems like an unnecessary restriction). It would be clearer to remove this and require all child classes to use the param set explicitly, removing the need for virtual inheritance. This would just need an addition to the extern C calls to create the param set and pass it into the constructor of the driver. Another option is to create a class that inherits from the driver and the param set, with no additional logic. This could then instantiate the param set and pass it to the driver constructor. Either solution would resolve caveat 3, because all classes will access FIRST_DRIVER_PARAM via paramSet->.

Possible Further Work

Adopting this framework could make it easier to make other improvements to the C++ code, such as:

  • Move some asynPortDriver functionality into asynParamSet / asynParam (See ADEiger eigerParam)
    • Reduce the size of asynPortDriver

    • Possibility of typed subclasses of asynParam to reduce if statements for handling the many asynParamType values in slightly different ways

  • Simplify the sharing of file writing functionality between some drivers
    • ADPilatus and NDPluginFile-derived classes - Parameters could be split out of asynNDArrayDriver into a FileWriterParamSet, which could then be included via composition only where required, rather than every driver and plugin under asynNDArrayDriver having these parameters.