a

# areaDetector Plugin NDPluginFile

## November 24, 2008

## Mark Rivers

## University of Chicago

## Contents

- Overview
- Configuration
- Screen shots
- netCDF file contents
- IDL file reading function
- Future plans

## Overview

NDPluginFile saves the NDArray data from a callback to a disk file.

NDPluginFile inherits from NDPluginDriver. This plugin currently saves data in the netCDF file format, which is a portable self-describing binary file format supported by UniData at UCAR (University Corporation for Atmospheric Research).

The NDArray callback data can be written to disk in 1 of 3 modes:

1. Single mode. In this mode each NDArray callback results in a separate disk file.
2. Capture mode. In this mode a memory buffer is allocated before saving begins. Callback arrays are placed into this buffer, and when capture stops the file is written to disk. This mode limits the number of frames that can be saved, because they all must fit in a memory buffer. It is the fastest mode, with the least probability of dropping arrays, because no disk I/O is required while capture is in progress.
3. Stream mode. In this mode the data are written to a single disk file, with each frame being appended to the file without closing it. It is intermediate in speed between single mode and capture mode, but unlike capture mode it is not limited by available memory in the number of arrays that can be saved.

The NDPluginFile public interface is defined in NDPluginFile.h as follows:

    /* Note that the file format enum must agree with the mbbo/mbbi records in the NDFile.template file */
    typedef enum {
        NDFileFormatNetCDF,
    } NDPluginFileFormat_t;

    ...
    class NDPluginFile : public NDPluginDriver {
    public:
        NDPluginFile(const char *portName, int queueSize, int blockingCallbacks,
                     const char *NDArrayPort, int NDArrayAddr);

        /* These methods override those in the base class */
        void processCallbacks(NDArray *pArray);
        asynStatus writeInt32(asynUser *pasynUser, epicsInt32 value);
        asynStatus writeNDArray(asynUser *pasynUser, void *genericPointer);
        asynStatus drvUserCreate(asynUser *pasynUser, const char *drvInfo,
                                 const char **pptypeName, size_t *psize);

    ...
    }

NDPluginFile supports all of the file saving parameters defined in ADStdDriverParams.h, e.g. ADFilePath, ADFileName, etc. Thus, the same interface that is used for saving files directly in a driver is used for this plugin.

## Configuration

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

    drvNDFileConfigure(const char *portName, int queueSize, int blockingCallbacks,
                       const char *NDArrayPort, int NDArrayAddr)

Argument | Description
--- | ---
`portName` | The name of the asyn port for this plugin.
`queueSize` | The maximum number of NDArray objects that can be queued for processing. Passed to the NDPluginDriver base class constructor.
`blockingCallbacks` | Flag controlling whether callbacks block. Passed to the NDPluginDriver base class constructor.
`NDArrayPort` | The name of the asyn port of the driver that will provide the NDArray data. Passed to the NDPluginDriver base class constructor.
`NDArrayAddr` | The asyn addr of the asyn port of the driver that will provide the NDArray data. Passed to the NDPluginDriver base class constructor.

## Screen shots

The following is the MEDM screen that provides access to the parameters in NDPluginDriver.h and NDPluginFile.h through records in NDPluginBase.template and NDFile.template. This is the MEDM screen that is used to control the saving of images to disk.

### NDPluginFile.adl

## netCDF file contents

The following is the header contents of a netCDF file produced by this plugin. This information was produced with the following command:

    ncdump -h test_A_2.nc

    netcdf test_A_2 {
    dimensions:
    	numArrays = 200 ;
    	dim0 = 480 ;
    	dim1 = 640 ;
    variables:
    	int uniqueId(numArrays) ;
    	double timeStamp(numArrays) ;
    	byte array_data(numArrays, dim0, dim1) ;

    // global attributes:
    		:dataType = 0 ;
    		:numArrayDims = 2 ;
    		:dimSize = 640, 480 ;
    		:dimOffset = 0, 0 ;
    		:dimBinning = 1, 1 ;
    		:dimReverse = 0, 0 ;
    }

This is an explanation of this output:

- dimensions: numArrays is the number of arrays in the file. It will be 1 for files collected in Single mode, and is normally > 1 for files collected in Capture or Stream mode. For each array dim0 is the slowest varying dimension, dim1 the next slowest, etc.
- variables: There are 3 variables in the netCDF file. uniqueId is the unique ID number of each array. timeStamp is the timestamp in seconds for each array. array_data is the array data. Its data type depends on the data type of the NDArray data passed in the callbacks. It dimensions are [numArrays, dim0, dim1, ...dimN]. This notation is in the Fortran syntax where the slowest varying dimension comes first in the list.
- global attributes. dataType is the NDDataType_t enum value for the array data type. numArrayDims is the number of dimensions in each array. array_data has 1 more dimension than this, numArrays, because it contains all of the array callback data. dimSize is an array[numArrayDims] containing the size of each dimension, with the fastest varying dimension first. dimOffset, dimBinning, and dimReverse are the values of the offset, binning and reverse fields in the NDDimension_t structure for each dimension.

## IDL file reading function

There is an IDL function, read_nd_netcdf that can be used to read the netCDF files created by this plugin. This routine is contained in the CARS IDL detector package. This function is currently limited to reading the entire file at once, so it may fail for very large files on machines with insufficient virtual memory. This will be fixed in a future release.

## Future plans

Additional file formats, such as TIFF and HDF may be supported in the future.

The IDL function described above will be enhanced to allow reading only a subset of the file at a time.