# areaDetector Plugin NDPluginROI

## March 7, 2010

## Mark Rivers

## University of Chicago

## Contents

- Overview
- Configuration
- Screen shots

## Overview

NDPluginROI selects one or more rectangular "Regions-Of-Interest" (ROIs) from the NDArray callback data. The maximum number of ROIs is defined when the plugin is created. Each ROI can be any size, from a single array element to the entire array. NDPluginROI optinally does the following operations with these ROIs, in this order:

1. Extracts of the selected region. When the ROI is extracted the following operations can be performed:
   - Binning in any dimension.
   - Orientation reversal (mirroring) in any dimension.
   - Conversion to a new data type.
2. Subtracts a background array which has been previously acquired.
3. Clips to minimum and maximum specified values.
4. Computes statistics, e.g. mean, maximum, minimum, total, net (background subtracted), and centroid values.
5. Computes a histogram of the values (e.g. number of pixels versus intensity per pixel)
6. Exports the ROI as a new NDArray object. In this regard NDPluginROI is different from the NDPluginStdArrays and NDPluginFile plugins because it is both a recipient of callbacks (as they are) and a source of NDArray callbacks, as a driver is. This means that the NDPluginStdArrays and NDPluginFile plugins can be connected to an NDPluginROI plugin, in which case they will save or display the selected ROI rather than the full detector driver data.

Each of these operations can be enabled or disabled independently.

Each NDPluginROI can handle any number of ROIs. Several ROI plugins could be created for a single detector driver to increase the number of threads running in parallel, maximizing the use of multiple CPU cores. Individual ROIs are addressed through the asyn interfaces by the asyn "addr" field in the asynUser structure. Note that while the NDPluginROI should be N-dimensional, the EPICS interface to the definition of the ROI is currently limited to a maximum of 3-D. This limitation may be removed in a future release.

NDPluginROI inherits from NDPluginDriver. The NDPluginROI class documentation describes this class in detail.

NDPluginROI.h defines the following parameters that are global to all ROIs for a plugin. It also implements all of the standard plugin parameters from NDPluginDriver. The EPICS database NDROI.template provide access to these parameters, listed in the following table.

Parameter Definitions in NDPluginROI.h and EPICS Record Definitions in NDROI.template
Enum name | asyn interface | Access | Description | drvUser string | EPICS record name | EPICS record type
--- | --- | --- | --- | --- | --- | ---

NDPluginROIHighlight

asynInt32

r/w

Flag to indicate if the borders of ROIs should be highlighted (0=No, 1=Yes). If set then the borders of all ROIs will be highlighted in all other ROIs where they overlap. One common use of this is to set the first ROI to be the entire detector, and then the location of all other ROIs will be visible when the first ROI is displayed. The highlighting is done by replacing the border pixels with the maximum value of the data in that ROI. Statistics are computed before the highlighting is done.

HIGHLIGHT

$(P)$(R)Highlight
$(P)$(R)Highlight_RBV

bo
bi

NDPluginROI.h defines the following parameters that are specific to each individual ROI in the plugin. The EPICS database NDROIN.template provide access to these parameters, listed in the following table. The pasynUser->addr is used to control which ROI is being addressed. Note that to reduce the width of this table the enum names have been split into 2 lines, but these are just a single name, for example `NDPluginROIName`.

Parameter Definitions in NDPluginROI.h and EPICS Record Definitions in NDROIN.template
Enum name | asyn interface | Access | Description | drvUser string | EPICS record name | EPICS record type
--- | --- | --- | --- | --- | --- | ---
NDPluginROI Name | asynOctet | r/w | Name of this ROI | NAME | $(P)$(R)Name $(P)$(R)Name_RBV | stringout stringin
NDPluginROI Use | asynInt32 | r/w | Flag to control whether this ROI is used (0=No, 1=Yes). Not using an ROI reduces CPU load. | USE | $(P)$(R)Use $(P)$(R)Use_RBV | bo bi
ROI definition
NDPluginROI Dim0Bin | asynInt32 | r/w | Binning in the X direction | DIM0_BIN | $(P)$(R)BinX $(P)$(R)BinX_RBV | longout longin
NDPluginROI Dim1Bin | asynInt32 | r/w | Binning in the Y direction | DIM1_BIN | $(P)$(R)BinY $(P)$(R)BinY_RBV | longout longin
NDPluginROI Dim2Bin | asynInt32 | r/w | Binning in the Z direction | DIM2_BIN | $(P)$(R)BinZ $(P)$(R)BinZ_RBV | longout longin
NDPluginROI Dim0Min | asynInt32 | r/w | First pixel in the ROI in the X direction. 0 is the first pixel in the array. | DIM0_MIN | $(P)$(R)MinX $(P)$(R)MinX_RBV | longout longin
NDPluginROI Dim1Min | asynInt32 | r/w | First pixel in the ROI in the Y direction. 0 is the first pixel in the array. | DIM1_MIN | $(P)$(R)MinY $(P)$(R)MinY_RBV | longout longin
NDPluginROI Dim2Min | asynInt32 | r/w | First pixel in the ROI in the Z direction. 0 is the first pixel in the array. | DIM2_MIN | $(P)$(R)MinZ $(P)$(R)MinZ_RBV | longout longin
NDPluginROI Dim0Size | asynInt32 | r/w | Size of the ROI in the X direction | DIM0_SIZE | $(P)$(R)SizeX $(P)$(R)SizeX_RBV | longout longin
NDPluginROI Dim1Size | asynInt32 | r/w | Size of the ROI in the Y direction | DIM1_SIZE | $(P)$(R)SizeY $(P)$(R)SizeY_RBV | longout longin
NDPluginROI Dim2Size | asynInt32 | r/w | Size of the ROI in the Z direction | DIM2_SIZE | $(P)$(R)SizeZ $(P)$(R)SizeZ_RBV | longout longin
NDPluginROI Dim0MaxSize | asynInt32 | r/o | Maximum size of the ROI in the X direction | DIM0_MAX_SIZE | $(P)$(R)MaxSizeX_RBV | longin
NDPluginROI Dim1MaxSize | asynInt32 | r/o | Maximum size of the ROI in the Y direction | DIM1_MAX_SIZE | $(P)$(R)MaxSizeY_RBV | longin
NDPluginROI Dim2MaxSize | asynInt32 | r/o | Maximum size of the ROI in the Z direction | DIM2_MAX_SIZE | $(P)$(R)MaxSizeZ_RBV | longin
NDPluginROI Dim0Reverse | asynInt32 | r/w | Reverse ROI in the X direction (0=No, 1=Yes) | DIM0_REVERSE | $(P)$(R)ReverseX $(P)$(R)ReverseX_RBV | longout longin
NDPluginROI Dim1Reverse | asynInt32 | r/w | Reverse ROI in the Y direction (0=No, 1=Yes) | DIM1_REVERSE | $(P)$(R)ReverseY $(P)$(R)ReverseY_RBV | longout longin
NDPluginROI Dim2Reverse | asynInt32 | r/w | Reverse ROI in the Z direction (0=No, 1=Yes) | DIM2_REVERSE | $(P)$(R)ReverseZ $(P)$(R)ReverseZ_RBV | longout longin
NDPluginROI DataType | asynInt32 | r/w | Data type of the ROI (NDDataType_t). This can be different from the data type of the NDArray callback data. | ROI_DATA_TYPE | $(P)$(R)DataType $(P)$(R)DataType_RBV | mbbo mbbi
NDPluginROI BgdWidth | asynInt32 | r/w | Width of the background in pixels to use when computing net counts. 0=no background subtraction, so the net counts is the same as the total counts. | BGD_WIDTH | $(P)$(R)BgdWidth $(P)$(R)BgdWidth_RBV | longout longin
NDArraySizeX | asynInt32 | r/o | Size of the ROI data in the X direction | ARRAY_SIZE_X | $(P)$(R)ArraySizeX_RBV | longin
NDArraySizeY | asynInt32 | r/o | Size of the ROI data in the Y direction | ARRAY_SIZE_Y | $(P)$(R)ArraySizeY_RBV | longin
NDArraySizeZ | asynInt32 | r/o | Size of the ROI data in the Z direction | ARRAY_SIZE_Z | $(P)$(R)ArraySizeZ_RBV | longin
ROI clipping and background subtraction
NDPluginROI GrabBackground | asynInt32 | r/w | Command to use the most recently acquired ROI array as a background. Note that this recently acquired ROI should have been acquired with EnableBackground=0, or else that array will already have had the background subtracted, which is probably not what was intended! | GRAB_BACKGROUND | $(P)$(R)GrabBackground $(P)$(R)GrabBackground_RBV | bo bi
NDPluginROI ValidBackground | asynInt32 | r/o | Flag indicating whether there is a valid background array that has been acquired for this ROI using GrabBackground. This flag will be Invalid (0) if no background has been acquired, or of the size of the ROI has changed since the background was last acquired. | VALID_BACKGROUND | $(P)$(R)ValidBackground_RBV | bi

NDPluginROI
EnableBackground

asynInt32

r/w

Flag indicating whether the background array acquired with GrabBackground should be subtracted when computing this ROI. This background subtraction is done before the clipping operations, and before the statistics are computed. If ValidBackground=0 then no background subtraction is done. This background subtraction modifies the ROI data, so other plugins that use this ROI will receive the background subtracted data.

ENABLE_BACKGROUND

$(P)$(R)EnableBackground
$(P)$(R)EnableBackground_RBV

bo
bi

NDPluginROI EnableLowClip | asynInt32 | r/w | Flag to control whether to clip values to the LowClip value for this ROI (0=No, 1=Yes). | ENABLE_LOW_CLIP | $(P)$(R)EnableLowClip $(P)$(R)EnableLowClip_RBV | bo bi

NDPluginROI
LowClip

asynFloat64

r/w

The minimum allowed value for this ROI. If EnableLowClip=1, then all values in the array less than LowClip will be replaced by LowClip. This clipping operation is performed after the background is subtracted (if EnableBackground=1). This clipping modifies the ROI data, so other plugins that use this ROI will receive the clipped data.

LOW_CLIP

$(P)$(R)LowClip
$(P)$(R)LowClip_RBV

ao
ai

NDPluginROI EnableHighClip | asynInt32 | r/w | Flag to control whether to clip values to the HighClip value for this ROI (0=No, 1=Yes). | ENABLE_HIGH_CLIP | $(P)$(R)EnableHighClip $(P)$(R)EnableHighClip_RBV | bo bi

NDPluginROI
HighClip

asynFloat64

r/w

The maximum allowed value for this ROI. If EnableHighClip=1, then all values in the array greater than HighClip will be replaced by HighClip. This clipping operation is performed after the background is subtracted (if EnableBackground=1). This clipping modifies the ROI data, so other plugins that use this ROI will receive the clipped data.

HIGH_CLIP

$(P)$(R)HighClip
$(P)$(R)HighClip_RBV

ao
ai

ROI statistics
NDPluginROI ComputeStatistics | asynInt32 | r/w | Flag to control whether to compute statistics for this ROI (0=No, 1=Yes). Not computing statistics reduces CPU load. | COMPUTE_STATISTICS | $(P)$(R)ComputeStatistics $(P)$(R)ComputeStatistics_RBV | bo bi
NDPluginROI MinValue | asynFloat64 | r/o | Minimum value in any element in the ROI | MIN_VALUE | $(P)$(R)MinValue_RBV | ai
NDPluginROI MaxValue | asynFloat64 | r/o | Maximum value in any element in the ROI | MAX_VALUE | $(P)$(R)MaxValue_RBV | ai
NDPluginROI MeanValue | asynFloat64 | r/o | Mean value in the ROI | MEAN_VALUE | $(P)$(R)MeanValue_RBV | ai
NDPluginROI Total | asynFloat64 | r/o | Sum (total) of all elements in the ROI | TOTAL | $(P)$(R)Total_RBV | ai

NDPluginROI
Net

asynFloat64

r/o

Net (background subtracted) total of all elements in the ROI. The background is calculated by determining the average counts per array element in a border around the ROI of width NDPluginROIBgdWidth. This average background counts per element is then subtracted from all elements inside the ROI. If NDPluginROIBgdWidth is ≤ 0 then no background is computed. Note that this background subtraction is done after the "array" background is subtracted if EnableBackground=1, as described above.

NET

$(P)$(R)Net_RBV

ai

NDPluginROI CentroidX | asynFloat64 | r/o | X centroid of the ROI. | CENTROIDX_VALUE | $(P)$(R)CentroidX_RBV | ai
NDPluginROI CentroidY | asynFloat64 | r/o | Y centroid of the ROI. | CENTROIDY_VALUE | $(P)$(R)CentroidY_RBV | ai
ROI histogram
NDPluginROI ComputeHistogram | asynInt32 | r/w | Flag to control whether to compute the histogram for this ROI (0=No, 1=Yes). Not computing the histogram reduces CPU load. | COMPUTE_HISTOGRAM | $(P)$(R)ComputeHistogram $(P)$(R)ComputeHistogram_RBV | bo bi
NDPluginROI HistSize | asynInt32 | r/w | Number of elements (bins) in the histogram | HIST_SIZE | $(P)$(R)HistSize $(P)$(R)HistSize_RBV | longout longin
NDPluginROI HistMin | asynFloat64 | r/w | Minimum value for the histogram. All values less than or equal to this will be in the first bin of the histogram. | HIST_MIN | $(P)$(R)HistMin $(P)$(R)HistMin_RBV | ao ai
NDPluginROI HistMax | asynFloat64 | r/w | Maximum value for the histogram. All values greater than or equal to this will be in the last bin of the histogram. | HIST_MAX | $(P)$(R)HistMax $(P)$(R)HistMax_RBV | ao ai
NDPluginROI HistEntropy | asynFloat64 | r/o | Entropy of the image. This is a measure of the sharpness of the histogram, and is often a useful figure of merit for determining sharpness of focus, etc. It is defined as -SUM(BIN[i]*log(BIN[i]), where the sum is over the number of bins in the histogram and BIN[i] is the number of elements in bin i. | HIST_ENTROPY | $(P)$(R)HistEntropy_RBV | ai
NDPluginROI HistArray | asynFloat64Array | r/o | Histogram array, i.e. counts in each histogram bin. | HIST_ARRAY | $(P)$(R)Histogram_RBV | waveform

A special case is made when the NDArray data has colorMode=NDColorModeRGB1 or NDColorModeRGB2. In these cases the user interface to the array dimensions is changed so that the Z PVs always refer to the color dimension (as for NDColorModeRGB3), the X dimension refers to the horizontal direction, and the Y direction refers to the vertical direction. This is very convenient, because it means that the ROI does not need to redefined if, for example, the color mode is changed from Mono to RGB1, which would be required if the X, Y and Z directions were not automatically switched.

## Configuration

The NDPluginROI plugin is created with the NDROIConfigure command, either from C/C++ or from the EPICS IOC shell.

    NDROIConfigure(const char *portName, int queueSize, int blockingCallbacks,
                   const char *NDArrayPort, int NDArrayAddr, int maxROIs,
                   int maxBuffers, size_t maxMemory,
                   int priority, int stackSize)

For details on the meaning of the parameters to this function refer to the detailed documentation on the NDROIConfigure function in the NDPluginROI.cpp documentation and in the documentation for the constructor for the NDPluginROI class.

## Screen shots

The following is the MEDM screen that provides access to the parameters in NDPluginDriver.h and NDPluginROI.h through records in NDPluginBase.template and NDROI.template. This is the MEDM screen that is used to control the behavior of the ROI plugin, but not the individual ROIs.

### NDROI.adl

The following is the MEDM screen that provides access to the parameters in NDPluginROI.h for an individual ROI through records in NDROIN.template. This is the MEDM screen that is used to control the behavior of a specific ROI.

### NDROIN.adl

The following is another MEDM screen that provides access to the parameters in NDPluginROI.h through records in NDROIN.template. This is the MEDM screen that is used to control the most commonly used properties of 8 ROIs.

### NDROI8.adl

The following is an IDL epics_ad_display screen illustrating the highlighting of ROIs. In this example the ROIs defined are those in the 8 ROI display above. The NDPluginStdArrays driver has been configured to be receiving its NDArray callbacks from the first ROI (which is defined to be the entire detector array), and the NDPluginROIHighlight flag is set to Yes.

### Highlighted Regions-of-Interest