diff --git a/documentation/records.dox b/documentation/records.dox
index 2166878..75c465e 100644
--- a/documentation/records.dox
+++ b/documentation/records.dox
@@ -14,6 +14,7 @@ Device support for these record types must be written in C++.
- statBin
- pvstructin
- tableAgg
+- ndaroi
All of these record types provide custom device support (dset)
struct definitions. eg. 'struct svectorindset'
@@ -233,4 +234,25 @@ record(tableAgg, "my:table") {
When processed, the default device support will read each INPx field and populate the corresponding
value with the obtained array.
-*/
\ No newline at end of file
+@section qsrv_ndaroi ndaroi record type
+
+The ndaroi record is the analog of the areaDetector plugin NDPluginROI. It performs
+a ROI in a NTNDArray PVstrucuture, typically stored inside a ndain record.
+
+Currently, it supports only Gray scale images, with the ROI dimensions specified
+by the fields:
+
+XMIN and XSIZE specifies the X offset and the horizontal size of the ROI, respectively
+
+YMIN and YSIZE specifies the Y offset and the vertical size of the ROI, respectively
+
+ZMIN and ZSIZE specifies the color offset and the color size of the ROI, respectively (unsupported for now)
+
+@subsection qsrv_ndaroi_softchannel ndaroi default device support
+
+During initialization, the default device support for ndaroi will read a Structure from
+the INP field and then proceed to read the PVStructure from the input record.
+
+Type changes after the first record processing are unsupported for now.
+
+*/
diff --git a/iocBoot/iocimagedemo/ndaroi.bob b/iocBoot/iocimagedemo/ndaroi.bob
new file mode 100644
index 0000000..72d84df
--- /dev/null
+++ b/iocBoot/iocimagedemo/ndaroi.bob
@@ -0,0 +1,157 @@
+
+
+ Display
+ 1000
+
+ Label
+ TITLE
+ NDAROI Example
+ 0
+ 0
+ 550
+ 31
+
+
+
+
+
+
+
+
+ true
+
+
+ Image
+ pva://TST:image3:Array
+ 20
+ 90
+
+ true
+ X
+ 0.0
+ 1024.0
+
+
+
+
+
+
+
+
+
+
+ true
+ Y
+ 768.0
+ 0.0
+
+
+
+
+
+
+
+
+
+ false
+
+
+ ROI 0
+
+
+
+
+ true
+ true
+ pva://TST:image3:ArrayROI.XMIN
+ pva://TST:image3:ArrayROI.YMIN
+ pva://TST:image3:ArrayROI.XSIZE
+ pva://TST:image3:ArrayROI.YSIZE
+
+
+
+
+
+ Image_1
+ pva://TST:image3:ArrayROI
+ 510
+ 90
+
+ true
+ X
+ 0.0
+ 1024.0
+
+
+
+
+
+
+
+
+
+
+ true
+ Y
+ 768.0
+ 0.0
+
+
+
+
+
+
+
+
+
+ false
+
+
+ Text Update_1
+ pva://TST:image3:ArrayROIStat/max
+ 690
+ 410
+
+
+ Label_3
+ Max
+ 590
+ 410
+
+
+ Text Update_2
+ pva://TST:image3:ArrayROIStat/min
+ 690
+ 430
+
+
+ Label_4
+ Min
+ 590
+ 430
+
+
+ Text Update_3
+ pva://TST:image3:ArrayROIStat/std
+ 690
+ 450
+
+
+ Label_5
+ Std
+ 590
+ 450
+
+
+ Text Update_4
+ pva://TST:image3:ArrayROIStat/mean
+ 690
+ 470
+
+
+ Label_6
+ Mean
+ 590
+ 470
+
+
diff --git a/iocBoot/iocimagedemo/ndaroi.db b/iocBoot/iocimagedemo/ndaroi.db
new file mode 100644
index 0000000..164975a
--- /dev/null
+++ b/iocBoot/iocimagedemo/ndaroi.db
@@ -0,0 +1,23 @@
+record(ndain, "$(N):Array") {
+ field(DTYP, "QSRV Demo")
+ field(W, "1024")
+ field(H, "768")
+ field(PINI, "YES")
+ field(SCAN, "1 second")
+ field(FLNK, "$(N):ArrayROI")
+}
+
+record(ndaroi, "$(N):ArrayROI") {
+ field(DTYP, "Soft Channel")
+ field(INP, "$(N):Array")
+ field(XMIN, "0")
+ field(XSIZE, "100")
+ field(YMIN, "0")
+ field(YSIZE, "100")
+ field(FLNK, "$(N):ArrayROIStat")
+}
+
+record(statBin, "$(N):ArrayROIStat") {
+ field(INP, "$(N):ArrayROI NPP")
+ field(TSEL, "$(N):ArrayROI.TIME NPP")
+}
diff --git a/iocBoot/iocimagedemo/st.cmd b/iocBoot/iocimagedemo/st.cmd
index d7323b8..b6b198c 100755
--- a/iocBoot/iocimagedemo/st.cmd
+++ b/iocBoot/iocimagedemo/st.cmd
@@ -1,7 +1,8 @@
-#!../../bin/linux-x86_64-debug/softIocPVA
+#!../../bin/linux-x86_64/softIocPVA
dbLoadRecords("image.db","N=TST:image1")
dbLoadRecords("ndain.db","N=TST:image2")
+dbLoadRecords("ndaroi.db","N=TST:image3")
dbLoadRecords("table.db","N=TST:table1")
iocInit()
diff --git a/pdbApp/Makefile b/pdbApp/Makefile
index f74d15f..eb08cf0 100644
--- a/pdbApp/Makefile
+++ b/pdbApp/Makefile
@@ -35,6 +35,7 @@ DBDINC += columnarinRecord
DBDINC += columnaroutRecord
DBDINC += statBinRecord
DBDINC += ndainRecord
+DBDINC += ndaroiRecord
DBDINC += tableAggRecord
DBDINC += multiArrayCommon
@@ -85,6 +86,7 @@ qsrv_SRCS += columnaroutRecord.cpp
qsrv_SRCS += statBinRecord.cpp
qsrv_SRCS += ndainRecord.cpp
+qsrv_SRCS += ndaroiRecord.cpp
qsrv_SRCS += tableAggRecord.cpp
qsrv_SRCS += multiArrayCommon.cpp
@@ -142,6 +144,7 @@ $(COMMON_DIR)/softIocPVA.dbd: ../columnarinRecord.dbd
$(COMMON_DIR)/softIocPVA.dbd: ../columnaroutRecord.dbd
$(COMMON_DIR)/softIocPVA.dbd: ../statBinRecord.dbd
$(COMMON_DIR)/softIocPVA.dbd: ../ndainRecord.dbd
+$(COMMON_DIR)/softIocPVA.dbd: ../ndaroiRecord.dbd
$(COMMON_DIR)/softIocPVA.dbd: ../tableAggRecord.dbd
$(COMMON_DIR)/softIocPVA.dbd: $(COMMON_DIR)/qsrv.dbd
diff --git a/pdbApp/ndaroiRecord.cpp b/pdbApp/ndaroiRecord.cpp
new file mode 100644
index 0000000..1e67b2b
--- /dev/null
+++ b/pdbApp/ndaroiRecord.cpp
@@ -0,0 +1,615 @@
+/*************************************************************************\
+* Copyright (c) 2020 Michael Davidsaver
+* EPICS BASE is distributed subject to a Software License Agreement found
+* in file LICENSE that is included with this distribution.
+\*************************************************************************/
+
+#ifndef USE_TYPED_RSET
+# define USE_TYPED_RSET
+#endif
+#ifndef USE_TYPED_DSET
+# define USE_TYPED_DSET
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+// include by ndaroiRecord.h
+#include "epicsTypes.h"
+#include "link.h"
+#include "epicsMutex.h"
+#include "ellLib.h"
+#include "devSup.h"
+#include "epicsTime.h"
+
+#include "helper.h"
+
+#include
+#include
+#include
+#include
+
+#define GEN_SIZE_OFFSET
+#include
+#undef GEN_SIZE_OFFSET
+#include
+
+#include