From 82619a50bab5470f37c16c56c1e5f8ef4bcdb095 Mon Sep 17 00:00:00 2001 From: Nick Rees Date: Tue, 6 Jan 2015 10:55:46 +0000 Subject: [PATCH 1/5] Added feature to allow file plugins to create directories before writing A CREATE_DIR parameter can be set to 1 to enable this feature. The default is 0 (i.e. no directory creation). --- ADApp/ADSrc/asynNDArrayDriver.cpp | 2 + ADApp/ADSrc/asynNDArrayDriver.h | 3 +- ADApp/Db/NDFile.template | 16 +++++ ADApp/Db/NDFile_settings.req | 1 + ADApp/pluginSrc/NDPluginFile.cpp | 104 +++++++++++++++++++++++++++++- ADApp/pluginSrc/NDPluginFile.h | 1 + 6 files changed, 124 insertions(+), 3 deletions(-) diff --git a/ADApp/ADSrc/asynNDArrayDriver.cpp b/ADApp/ADSrc/asynNDArrayDriver.cpp index 76d26cf92..b282a6712 100644 --- a/ADApp/ADSrc/asynNDArrayDriver.cpp +++ b/ADApp/ADSrc/asynNDArrayDriver.cpp @@ -542,6 +542,7 @@ asynNDArrayDriver::asynNDArrayDriver(const char *portName, int maxAddr, int numP createParam(NDFileCaptureString, asynParamInt32, &NDFileCapture); createParam(NDFileDeleteDriverFileString, asynParamInt32, &NDFileDeleteDriverFile); createParam(NDFileLazyOpenString, asynParamInt32, &NDFileLazyOpen); + createParam(NDFileCreateDirString, asynParamInt32, &NDFileCreateDir); createParam(NDAttributesFileString, asynParamOctet, &NDAttributesFile); createParam(NDArrayDataString, asynParamGenericPointer, &NDArrayData); createParam(NDArrayCallbacksString, asynParamInt32, &NDArrayCallbacks); @@ -585,6 +586,7 @@ asynNDArrayDriver::asynNDArrayDriver(const char *portName, int maxAddr, int numP setIntegerParam(NDAutoIncrement, 0); setStringParam (NDFileTemplate, "%s%s_%3.3d.dat"); setIntegerParam(NDFileNumCaptured, 0); + setIntegerParam(NDFileCreateDir, 0); setIntegerParam(NDPoolMaxBuffers, this->pNDArrayPool->maxBuffers()); setIntegerParam(NDPoolAllocBuffers, this->pNDArrayPool->numBuffers()); diff --git a/ADApp/ADSrc/asynNDArrayDriver.h b/ADApp/ADSrc/asynNDArrayDriver.h index f54f9cfa7..c40d6f6b0 100755 --- a/ADApp/ADSrc/asynNDArrayDriver.h +++ b/ADApp/ADSrc/asynNDArrayDriver.h @@ -72,7 +72,7 @@ typedef enum { #define NDFileCaptureString "CAPTURE" /**< (asynInt32, r/w) Start or stop capturing arrays */ #define NDFileDeleteDriverFileString "DELETE_DRIVER_FILE" /**< (asynInt32, r/w) Delete driver file */ #define NDFileLazyOpenString "FILE_LAZY_OPEN" /**< (asynInt32, r/w) Don't open file until first frame arrives in Stream mode */ - +#define NDFileCreateDirString "CREATE_DIR" /**< (asynInt32, r/w) If set then create the target directory before writing file */ #define NDAttributesFileString "ND_ATTRIBUTES_FILE" /**< (asynOctet, r/w) Attributes file name */ @@ -150,6 +150,7 @@ class epicsShareFunc asynNDArrayDriver : public asynPortDriver { int NDFileCapture; int NDFileDeleteDriverFile; int NDFileLazyOpen; + int NDFileCreateDir; int NDAttributesFile; int NDArrayData; int NDArrayCallbacks; diff --git a/ADApp/Db/NDFile.template b/ADApp/Db/NDFile.template index e09464f30..69929129c 100644 --- a/ADApp/Db/NDFile.template +++ b/ADApp/Db/NDFile.template @@ -37,6 +37,22 @@ record(bi, "$(P)$(R)FilePathExists_RBV") field(SCAN, "I/O Intr") } +record(longout, "$(P)$(R)CreateDirectory") +{ + field(PINI, "YES") + field(DTYP, "asynInt32") + field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))CREATE_DIR") + field(VAL, "0" ) +} + +record(longin, "$(P)$(R)CreateDirectory_RBV") +{ + field(DTYP, "asynInt32") + field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))CREATE_DIR") + field(VAL, "") + field(SCAN, "I/O Intr") +} + # Filename record(waveform, "$(P)$(R)FileName") { diff --git a/ADApp/Db/NDFile_settings.req b/ADApp/Db/NDFile_settings.req index 52b05edc0..8587d44d0 100644 --- a/ADApp/Db/NDFile_settings.req +++ b/ADApp/Db/NDFile_settings.req @@ -8,3 +8,4 @@ $(P)$(R)FileFormat $(P)$(R)FileWriteMode $(P)$(R)NumCapture $(P)$(R)DeleteDriverFile +$(P)$(R)CreateDirectory diff --git a/ADApp/pluginSrc/NDPluginFile.cpp b/ADApp/pluginSrc/NDPluginFile.cpp index c46993a7f..1b67f3108 100644 --- a/ADApp/pluginSrc/NDPluginFile.cpp +++ b/ADApp/pluginSrc/NDPluginFile.cpp @@ -31,6 +31,100 @@ static const char *driverName="NDPluginFile"; + +/** + * Make sure all the directories in the create path exist. Returns asnySuccess + * or asynFail in the hope that this is propagated back to GDA. + */ +#define MAX_PATH_PARTS 32 + +#if defined(_WIN32) +#include +#define strtok_r(a,b,c) strtok(a,b) +#define mkdir(a,b) _mkdir(a) +#define delim "\\" +#else +#include +#include +#define delim "/" +#endif + +/** Function to create a directory path for a file. + \param[in] createPath Path to create. The final part is the file name and is not created. + \param[in] stem_size This determines how much file stem to assume exists before attempting + to create directories: + stem_size = 0 create no directories + stem_size = 1 create all directories needed (i.e. only assume root directory exists). + stem_size = 2 Assume 1 directory below the root directory exists + stem_size = -1 Assume all but one direcory exists + stem_size = -2 Assume all but two directories exist. +*/ +asynStatus NDPluginFile::createDirectoryPath( char *createPath, int stem_size ) +{ + asynStatus result = asynSuccess; + char * parts[MAX_PATH_PARTS]; + int num_parts; + char directory[MAX_FILENAME_LEN]; + + // Initialise the directory to create + char nextDir[MAX_FILENAME_LEN]; + + // Extract the next name from the directory + char* saveptr; + int i=0; + + // Check for trivial case. + if (stem_size == 0) return asynSuccess; + + // Check for Windows disk designator + if ( createPath[1] == ':' ) + { + nextDir[0]=createPath[0]; + nextDir[1]=':'; + i+=2; + } + + // Skip over any more delimiters + while ( (createPath[i] == '/' || createPath[i] == '\\') && i < MAX_FILENAME_LEN) + { + nextDir[i] = createPath[i]; + ++i; + } + nextDir[i] = 0; + + // Now, tokenise the path - first making a copy because strtok is destructive + strcpy( directory, &createPath[i] ); + num_parts = 0; + parts[num_parts] = strtok_r( directory, "\\/",&saveptr); + while ( parts[num_parts] != NULL ) { + parts[++num_parts] = strtok_r(NULL, "\\/",&saveptr); + } + + // Handle the case if the stem size is negative + if (stem_size < 0) + { + stem_size = num_parts + stem_size; + if (stem_size < 1) stem_size = 1; + } + + // Loop through parts creating dirctories + for ( i = 1; i < num_parts && result != asynError; i++ ) + { + strcat(nextDir, parts[i-1]); + + if ( i >= stem_size ) + { + if(mkdir(nextDir, 0777) != 0 && errno != EEXIST) + { + result = asynError; + } + } + strcat(nextDir, delim); + } + + return result; +} + /** Base method for opening a file * Creates the file name with NDPluginBase::createFileName, then calls the pure virtual function openFile * in the derived class. */ @@ -58,6 +152,11 @@ asynStatus NDPluginFile::openFileBase(NDFileOpenMode_t openMode, NDArray *pArray } setStringParam(NDFullFileName, fullFileName); + int createDirectory; + getIntegerParam( NDFileCreateDir, &createDirectory ); + if (createDirectory) + status = createDirectoryPath( fullFileName, createDirectory ); + /* Call the openFile method in the derived class */ epicsMutexLock(this->fileMutexId); this->registerInitFrameInfo(pArray); @@ -620,8 +719,9 @@ bool NDPluginFile::isFrameValid(NDArray *pArray) // Check frame size in X and Y dimensions if ((initInfo->xSize != info.xSize) || (initInfo->ySize != info.ySize)) { asynPrint(this->pasynUserSelf, ASYN_TRACE_ERROR, - "NDPluginFile::isFrameValid: WARNING: Frame dimensions have changed X:%ld,%ld Y:%ld,%ld]\n", - (long)initInfo->xSize, (long)info.xSize, (long)initInfo->ySize, (long)info.ySize); + "NDPluginFile::isFrameValid: WARNING: Frame dimensions have changed X:%lu,%lu Y:%lu,%lu]\n", + (unsigned long)initInfo->xSize, (unsigned long)info.xSize, + (unsigned long)initInfo->ySize, (unsigned long)info.ySize); valid = false; } diff --git a/ADApp/pluginSrc/NDPluginFile.h b/ADApp/pluginSrc/NDPluginFile.h index 6dcfc1ecf..c6fdf46a7 100755 --- a/ADApp/pluginSrc/NDPluginFile.h +++ b/ADApp/pluginSrc/NDPluginFile.h @@ -65,6 +65,7 @@ class epicsShareClass NDPluginFile : public NDPluginDriver { * multiple NDArrays to a single file. Used in capture and stream modes. */ private: + asynStatus createDirectoryPath( char * path, int create ); asynStatus openFileBase(NDFileOpenMode_t openMode, NDArray *pArray); asynStatus readFileBase(); asynStatus writeFileBase(); From c7d1125b4af663deaa0d8f09c0632badb86d06ac Mon Sep 17 00:00:00 2001 From: Nick Rees Date: Tue, 6 Jan 2015 11:05:39 +0000 Subject: [PATCH 2/5] Updated EDM screen HDF5 details Now with both TempSuffix and CreateDir PVs --- ADApp/op/edl/NDFileHDF5Details.edl | 406 +++++++++++++---------------- 1 file changed, 188 insertions(+), 218 deletions(-) diff --git a/ADApp/op/edl/NDFileHDF5Details.edl b/ADApp/op/edl/NDFileHDF5Details.edl index 8def83935..508684f21 100644 --- a/ADApp/op/edl/NDFileHDF5Details.edl +++ b/ADApp/op/edl/NDFileHDF5Details.edl @@ -3,10 +3,10 @@ beginScreenProperties major 4 minor 0 release 1 -x 426 -y 134 +x 566 +y 47 w 417 -h 906 +h 905 font "arial-bold-r-12.0" ctlFont "arial-bold-r-12.0" btnFont "arial-bold-r-12.0" @@ -32,9 +32,9 @@ major 4 minor 0 release 0 x 5 -y 55 +y 765 w 405 -h 115 +h 100 lineColor index 14 fill fillColor index 3 @@ -47,22 +47,7 @@ major 4 minor 0 release 0 x 5 -y 560 -w 405 -h 40 -lineColor index 14 -fill -fillColor index 3 -endObjectProperties - -# (Rectangle) -object activeRectangleClass -beginObjectProperties -major 4 -minor 0 -release 0 -x 5 -y 480 +y 395 w 405 h 65 lineColor index 14 @@ -77,7 +62,7 @@ major 4 minor 0 release 0 x 5 -y 615 +y 480 w 405 h 40 lineColor index 14 @@ -92,7 +77,7 @@ major 4 minor 0 release 0 x 5 -y 395 +y 305 w 405 h 70 lineColor index 14 @@ -105,11 +90,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 385 -w 118 -h 13 +y 295 +w 122 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -127,7 +112,7 @@ major 4 minor 0 release 0 x 205 -y 410 +y 320 w 75 h 20 fgColor index 25 @@ -145,9 +130,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 410 +y 320 w 165 h 20 font "arial-bold-r-12.0" @@ -166,7 +151,7 @@ major 4 minor 0 release 0 x 205 -y 435 +y 345 w 75 h 20 fgColor index 25 @@ -184,9 +169,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 435 +y 345 w 185 h 20 font "arial-bold-r-12.0" @@ -203,7 +188,7 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 0 y 0 w 415 @@ -224,11 +209,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 605 -w 134 -h 13 +y 470 +w 135 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -244,9 +229,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 625 +y 490 w 165 h 20 font "arial-bold-r-12.0" @@ -265,7 +250,7 @@ major 4 minor 0 release 0 x 245 -y 625 +y 490 w 75 h 20 fgColor index 25 @@ -285,7 +270,7 @@ major 10 minor 0 release 0 x 325 -y 625 +y 490 w 75 h 20 controlPv "$(P)$(R)Compression_RBV" @@ -321,11 +306,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 470 -w 118 -h 13 +y 385 +w 122 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -343,7 +328,7 @@ major 10 minor 0 release 0 x 205 -y 515 +y 430 w 195 h 20 controlPv "$(P)$(R)IOSpeed" @@ -362,7 +347,7 @@ major 10 minor 0 release 0 x 205 -y 490 +y 405 w 195 h 20 controlPv "$(P)$(R)RunTime" @@ -379,9 +364,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 490 +y 405 w 165 h 20 font "arial-bold-r-12.0" @@ -398,9 +383,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 515 +y 430 w 165 h 20 font "arial-bold-r-12.0" @@ -419,7 +404,7 @@ major 4 minor 0 release 0 x 5 -y 820 +y 700 w 405 h 45 lineColor index 14 @@ -432,11 +417,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 810 -w 105 -h 13 +y 690 +w 109 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -452,9 +437,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 835 +y 715 w 185 h 20 font "arial-bold-r-12.0" @@ -473,7 +458,7 @@ major 4 minor 0 release 0 x 245 -y 835 +y 715 w 155 h 20 @@ -486,7 +471,7 @@ major 10 minor 0 release 0 x 245 -y 835 +y 715 w 75 h 20 controlPv "$(P)$(R)ZLevel" @@ -504,7 +489,7 @@ major 10 minor 0 release 0 x 325 -y 835 +y 715 w 75 h 20 controlPv "$(P)$(R)ZLevel_RBV" @@ -530,7 +515,7 @@ major 4 minor 0 release 0 x 5 -y 760 +y 635 w 405 h 45 lineColor index 14 @@ -543,11 +528,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 750 -w 108 -h 13 +y 625 +w 112 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -563,9 +548,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 775 +y 650 w 185 h 20 font "arial-bold-r-12.0" @@ -584,7 +569,7 @@ major 4 minor 0 release 0 x 245 -y 775 +y 650 w 155 h 20 @@ -597,7 +582,7 @@ major 10 minor 0 release 0 x 245 -y 775 +y 650 w 75 h 20 controlPv "$(P)$(R)SZipNumPixels" @@ -615,7 +600,7 @@ major 10 minor 0 release 0 x 325 -y 775 +y 650 w 75 h 20 controlPv "$(P)$(R)SZipNumPixels_RBV" @@ -641,7 +626,7 @@ major 4 minor 0 release 0 x 5 -y 670 +y 540 w 405 h 75 lineColor index 14 @@ -654,11 +639,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 660 -w 112 -h 13 +y 530 +w 117 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -674,9 +659,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 690 +y 560 w 185 h 20 font "arial-bold-r-12.0" @@ -693,9 +678,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 715 +y 585 w 185 h 20 font "arial-bold-r-12.0" @@ -714,7 +699,7 @@ major 4 minor 0 release 0 x 245 -y 690 +y 560 w 155 h 45 @@ -727,7 +712,7 @@ major 10 minor 0 release 0 x 245 -y 690 +y 560 w 75 h 20 controlPv "$(P)$(R)NumDataBits" @@ -745,7 +730,7 @@ major 10 minor 0 release 0 x 325 -y 690 +y 560 w 75 h 20 controlPv "$(P)$(R)NumDataBits_RBV" @@ -764,7 +749,7 @@ major 10 minor 0 release 0 x 325 -y 715 +y 585 w 75 h 20 controlPv "$(P)$(R)DataBitsOffset_RBV" @@ -783,7 +768,7 @@ major 10 minor 0 release 0 x 245 -y 715 +y 585 w 75 h 20 controlPv "$(P)$(R)DataBitsOffset" @@ -808,7 +793,7 @@ major 4 minor 0 release 0 x 5 -y 185 +y 60 w 405 h 140 lineColor index 14 @@ -821,11 +806,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 175 -w 143 -h 13 +y 50 +w 145 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -843,7 +828,7 @@ major 10 minor 0 release 0 x 200 -y 220 +y 95 w 100 h 20 controlPv "$(P)$(R)NumColChunks" @@ -861,7 +846,7 @@ major 10 minor 0 release 0 x 300 -y 220 +y 95 w 100 h 20 controlPv "$(P)$(R)NumColChunks_RBV" @@ -880,7 +865,7 @@ major 10 minor 0 release 0 x 300 -y 245 +y 120 w 100 h 20 controlPv "$(P)$(R)NumFramesChunks_RBV" @@ -899,7 +884,7 @@ major 10 minor 0 release 0 x 200 -y 245 +y 120 w 100 h 20 controlPv "$(P)$(R)NumFramesChunks" @@ -917,7 +902,7 @@ major 10 minor 0 release 0 x 300 -y 195 +y 70 w 100 h 20 controlPv "$(P)$(R)NumRowChunks_RBV" @@ -936,7 +921,7 @@ major 10 minor 0 release 0 x 200 -y 195 +y 70 w 100 h 20 controlPv "$(P)$(R)NumRowChunks" @@ -952,9 +937,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 195 +y 70 w 165 h 20 font "arial-bold-r-12.0" @@ -971,9 +956,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 220 +y 95 w 165 h 20 font "arial-bold-r-12.0" @@ -990,9 +975,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 245 +y 120 w 175 h 20 font "arial-bold-r-12.0" @@ -1011,7 +996,7 @@ major 4 minor 0 release 0 x 5 -y 340 +y 240 w 405 h 40 lineColor index 14 @@ -1024,11 +1009,11 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 330 -w 118 -h 13 +y 230 +w 122 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -1046,7 +1031,7 @@ major 10 minor 0 release 0 x 300 -y 350 +y 250 w 100 h 20 controlPv "$(P)$(R)NumFramesFlush_RBV" @@ -1065,7 +1050,7 @@ major 10 minor 0 release 0 x 200 -y 350 +y 250 w 100 h 20 controlPv "$(P)$(R)NumFramesFlush" @@ -1081,9 +1066,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 350 +y 250 w 165 h 20 font "arial-bold-r-12.0" @@ -1102,7 +1087,7 @@ major 10 minor 0 release 0 x 300 -y 270 +y 145 w 100 h 20 controlPv "$(P)$(R)BoundaryAlign_RBV" @@ -1121,7 +1106,7 @@ major 10 minor 0 release 0 x 200 -y 270 +y 145 w 100 h 20 controlPv "$(P)$(R)BoundaryAlign" @@ -1137,9 +1122,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 270 +y 145 w 175 h 20 font "arial-bold-r-12.0" @@ -1158,7 +1143,7 @@ major 10 minor 0 release 0 x 325 -y 570 +y 775 w 75 h 20 controlPv "$(P)$(R)LazyOpen_RBV" @@ -1177,7 +1162,7 @@ major 4 minor 0 release 0 x 245 -y 570 +y 775 w 75 h 20 fgColor index 25 @@ -1195,9 +1180,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 20 -y 570 +y 775 w 220 h 20 font "arial-bold-r-12.0" @@ -1214,16 +1199,16 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 5 -y 550 -w 72 -h 13 +y 755 +w 132 +h 14 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 value { - " Lazy Open " + " File Creation Control " } autoSize border @@ -1236,7 +1221,7 @@ major 10 minor 0 release 0 x 300 -y 295 +y 170 w 100 h 20 controlPv "$(P)$(R)BoundaryThreshold_RBV" @@ -1255,7 +1240,7 @@ major 10 minor 0 release 0 x 200 -y 295 +y 170 w 100 h 20 controlPv "$(P)$(R)BoundaryThreshold" @@ -1271,9 +1256,9 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 +release 1 x 15 -y 295 +y 170 w 175 h 20 font "arial-bold-r-12.0" @@ -1290,125 +1275,110 @@ object activeXTextClass beginObjectProperties major 4 minor 1 -release 0 -x 5 -y 50 -w 101 -h 13 -font "arial-medium-r-12.0" +release 1 +x 20 +y 805 +w 185 +h 20 +font "arial-bold-r-12.0" fgColor index 14 -bgColor index 5 +bgColor index 3 +useDisplayBg value { - " XML Layout File " + "Temp. suffix while file is open:" } -autoSize -border endObjectProperties -# (Static Text) -object activeXTextClass +# (Textentry) +object TextentryClass beginObjectProperties -major 4 -minor 1 +major 10 +minor 0 release 0 -x 15 -y 65 -w 370 -h 15 -font "arial-bold-r-12.0" -fgColor index 14 +x 245 +y 805 +w 75 +h 20 +controlPv "$(P)$(R)TempSuffix" +fgColor index 25 +fgAlarm bgColor index 3 -useDisplayBg -value { - "Full path of filename" -} +fill +font "arial-medium-r-12.0" endObjectProperties -# (Text Control) -object activeXTextDspClass +# (Textupdate) +object TextupdateClass beginObjectProperties -major 4 -minor 5 +major 10 +minor 0 release 0 -x 15 -y 80 -w 385 +x 325 +y 805 +w 75 h 20 -controlPv "$(P)$(R)XMLFileName_RBV" -font "helvetica-medium-r-10.0" +controlPv "$(P)$(R)TempSuffix_RBV" fgColor index 16 +fgAlarm bgColor index 10 -limitsFromDb -nullColor index 0 -smartRefresh -useHexPrefix -newPos -objType "controls" +fill +font "arial-medium-r-12.0" +fontAlign "center" endObjectProperties -# (Text Control) -object activeXTextDspClass +# (Static Text) +object activeXTextClass beginObjectProperties major 4 -minor 5 -release 0 -x 15 -y 105 -w 385 +minor 1 +release 1 +x 20 +y 835 +w 185 h 20 -controlPv "$(P)$(R)XMLFileName" -font "helvetica-medium-r-10.0" -fgColor index 25 +font "arial-bold-r-12.0" +fgColor index 14 bgColor index 3 -editable -motifWidget -limitsFromDb -nullColor index 0 -useKp -file -useHexPrefix -newPos -inputFocusUpdates -objType "controls" +useDisplayBg +value { + "Create directories:" +} endObjectProperties -# (Text Control) -object activeXTextDspClass +# (Textentry) +object TextentryClass beginObjectProperties -major 4 -minor 5 +major 10 +minor 0 release 0 -x 15 -y 140 -w 355 +x 245 +y 835 +w 75 h 20 -controlPv "$(P)$(R)XMLErrorMsg_RBV" -font "helvetica-medium-r-10.0" -fgColor index 16 -bgColor index 10 -limitsFromDb -nullColor index 0 -smartRefresh -useHexPrefix -newPos -objType "controls" +controlPv "$(P)$(R)CreateDirectory" +fgColor index 25 +fgAlarm +bgColor index 3 +fill +font "arial-medium-r-12.0" endObjectProperties -# (Byte) -object ByteClass +# (Textupdate) +object TextupdateClass beginObjectProperties -major 4 +major 10 minor 0 release 0 -x 380 -y 140 -w 18 -h 18 -controlPv "$(P)$(R)XMLValid_RBV" -lineColor index 14 -onColor index 15 -offColor index 19 -lineWidth 2 -numBits 1 +x 325 +y 835 +w 75 +h 20 +controlPv "$(P)$(R)CreateDirectory_RBV" +fgColor index 16 +fgAlarm +bgColor index 10 +fill +font "arial-medium-r-12.0" +fontAlign "center" endObjectProperties From 33416652590289a0e4ce1a0c4633b4bf65b1c9b0 Mon Sep 17 00:00:00 2001 From: Ulrik Kofoed Pedersen Date: Tue, 6 Jan 2015 11:48:12 +0000 Subject: [PATCH 3/5] Modified the CreateDirectory PVs to be binary Was originally longout/in and are now bo/bi as per convention. EDM screen modified to reflect this. --- ADApp/Db/NDFile.template | 9 +++- ADApp/op/edl/NDFileHDF5Details.edl | 76 +++++++++++++++--------------- 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/ADApp/Db/NDFile.template b/ADApp/Db/NDFile.template index 69929129c..946e96622 100644 --- a/ADApp/Db/NDFile.template +++ b/ADApp/Db/NDFile.template @@ -37,20 +37,25 @@ record(bi, "$(P)$(R)FilePathExists_RBV") field(SCAN, "I/O Intr") } -record(longout, "$(P)$(R)CreateDirectory") +record(bo, "$(P)$(R)CreateDirectory") { field(PINI, "YES") field(DTYP, "asynInt32") field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))CREATE_DIR") field(VAL, "0" ) + field(ZNAM, "No") + field(ONAM, "Yes") + info(autosaveFields, "VAL") } -record(longin, "$(P)$(R)CreateDirectory_RBV") +record(bi, "$(P)$(R)CreateDirectory_RBV") { field(DTYP, "asynInt32") field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))CREATE_DIR") field(VAL, "") field(SCAN, "I/O Intr") + field(ZNAM, "No") + field(ONAM, "Yes") } # Filename diff --git a/ADApp/op/edl/NDFileHDF5Details.edl b/ADApp/op/edl/NDFileHDF5Details.edl index 508684f21..6006fda08 100644 --- a/ADApp/op/edl/NDFileHDF5Details.edl +++ b/ADApp/op/edl/NDFileHDF5Details.edl @@ -3,8 +3,8 @@ beginScreenProperties major 4 minor 0 release 1 -x 566 -y 47 +x 615 +y 52 w 417 h 905 font "arial-bold-r-12.0" @@ -93,8 +93,8 @@ minor 1 release 1 x 5 y 295 -w 122 -h 14 +w 118 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -212,8 +212,8 @@ minor 1 release 1 x 5 y 470 -w 135 -h 14 +w 134 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -309,8 +309,8 @@ minor 1 release 1 x 5 y 385 -w 122 -h 14 +w 118 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -420,8 +420,8 @@ minor 1 release 1 x 5 y 690 -w 109 -h 14 +w 105 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -531,8 +531,8 @@ minor 1 release 1 x 5 y 625 -w 112 -h 14 +w 108 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -642,8 +642,8 @@ minor 1 release 1 x 5 y 530 -w 117 -h 14 +w 112 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -809,8 +809,8 @@ minor 1 release 1 x 5 y 50 -w 145 -h 14 +w 143 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -1012,8 +1012,8 @@ minor 1 release 1 x 5 y 230 -w 122 -h 14 +w 118 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -1202,8 +1202,8 @@ minor 1 release 1 x 5 y 755 -w 132 -h 14 +w 126 +h 13 font "arial-medium-r-12.0" fgColor index 14 bgColor index 5 @@ -1345,40 +1345,42 @@ value { } endObjectProperties -# (Textentry) -object TextentryClass +# (Textupdate) +object TextupdateClass beginObjectProperties major 10 minor 0 release 0 -x 245 +x 325 y 835 w 75 h 20 -controlPv "$(P)$(R)CreateDirectory" -fgColor index 25 +controlPv "$(P)$(R)CreateDirectory_RBV" +fgColor index 16 fgAlarm -bgColor index 3 +bgColor index 10 fill font "arial-medium-r-12.0" +fontAlign "center" endObjectProperties -# (Textupdate) -object TextupdateClass +# (Menu Button) +object activeMenuButtonClass beginObjectProperties -major 10 +major 4 minor 0 release 0 -x 325 +x 245 y 835 w 75 h 20 -controlPv "$(P)$(R)CreateDirectory_RBV" -fgColor index 16 -fgAlarm -bgColor index 10 -fill -font "arial-medium-r-12.0" -fontAlign "center" +fgColor index 25 +bgColor index 3 +inconsistentColor index 0 +topShadowColor index 1 +botShadowColor index 11 +controlPv "$(P)$(R)CreateDirectory" +indicatorPv "$(P)$(R)CreateDirectory_RBV" +font "arial-bold-r-12.0" endObjectProperties From a3671d17137cd66956c2c1026e8e77d5b0c97bbf Mon Sep 17 00:00:00 2001 From: Ulrik Kofoed Pedersen Date: Tue, 6 Jan 2015 13:14:35 +0000 Subject: [PATCH 4/5] Fixed silly mistake Reverted the change of NDFile.template to use longin/out again as the Create Directory feature actually uses the value of the parameter rather than just enable/disable. Modified the EDM screen to match. --- ADApp/Db/NDFile.template | 8 ++------ ADApp/op/edl/NDFileHDF5Details.edl | 20 +++++++++----------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/ADApp/Db/NDFile.template b/ADApp/Db/NDFile.template index 946e96622..2f227b71c 100644 --- a/ADApp/Db/NDFile.template +++ b/ADApp/Db/NDFile.template @@ -37,25 +37,21 @@ record(bi, "$(P)$(R)FilePathExists_RBV") field(SCAN, "I/O Intr") } -record(bo, "$(P)$(R)CreateDirectory") +record(longout, "$(P)$(R)CreateDirectory") { field(PINI, "YES") field(DTYP, "asynInt32") field(OUT, "@asyn($(PORT),$(ADDR),$(TIMEOUT))CREATE_DIR") field(VAL, "0" ) - field(ZNAM, "No") - field(ONAM, "Yes") info(autosaveFields, "VAL") } -record(bi, "$(P)$(R)CreateDirectory_RBV") +record(longin, "$(P)$(R)CreateDirectory_RBV") { field(DTYP, "asynInt32") field(INP, "@asyn($(PORT),$(ADDR),$(TIMEOUT))CREATE_DIR") field(VAL, "") field(SCAN, "I/O Intr") - field(ZNAM, "No") - field(ONAM, "Yes") } # Filename diff --git a/ADApp/op/edl/NDFileHDF5Details.edl b/ADApp/op/edl/NDFileHDF5Details.edl index 6006fda08..099cd1b56 100644 --- a/ADApp/op/edl/NDFileHDF5Details.edl +++ b/ADApp/op/edl/NDFileHDF5Details.edl @@ -3,8 +3,8 @@ beginScreenProperties major 4 minor 0 release 1 -x 615 -y 52 +x 629 +y 142 w 417 h 905 font "arial-bold-r-12.0" @@ -1364,23 +1364,21 @@ font "arial-medium-r-12.0" fontAlign "center" endObjectProperties -# (Menu Button) -object activeMenuButtonClass +# (Textentry) +object TextentryClass beginObjectProperties -major 4 +major 10 minor 0 release 0 x 245 y 835 w 75 h 20 +controlPv "$(P)$(R)CreateDirectory" fgColor index 25 +fgAlarm bgColor index 3 -inconsistentColor index 0 -topShadowColor index 1 -botShadowColor index 11 -controlPv "$(P)$(R)CreateDirectory" -indicatorPv "$(P)$(R)CreateDirectory_RBV" -font "arial-bold-r-12.0" +fill +font "arial-medium-r-12.0" endObjectProperties From 2f1d6a712740df39ed50a67dd95144ecf3bdeef8 Mon Sep 17 00:00:00 2001 From: Ulrik Kofoed Pedersen Date: Tue, 6 Jan 2015 13:15:13 +0000 Subject: [PATCH 5/5] Updated documentation To include the File writer create directory feature. --- RELEASE.md | 4 ++++ documentation/areaDetectorDoc.html | 25 +++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/RELEASE.md b/RELEASE.md index e5c1885da..613174bb7 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -46,6 +46,10 @@ R2-2 (January XXX, 2015) * Remember the requested ROI size and offset. If the requested values cannot be satisfied due to constraints such as binning or the input array size, then use the requested values when the constraints no longer apply. + +### NDPluginFile +* Created the NDFileCreateDir parameter. This allows file writers to create a controlled number + of directories in the path of the output file. ### NDFileHDF5 * Created separated NDFileHDF5.h so class can be exported to other applications. diff --git a/documentation/areaDetectorDoc.html b/documentation/areaDetectorDoc.html index 9f16970a4..3041151ae 100755 --- a/documentation/areaDetectorDoc.html +++ b/documentation/areaDetectorDoc.html @@ -961,6 +961,31 @@

bo
bi + + + NDFileCreateDir + + asynInt32 + + r/w + + This parameter is used to automatically create directories if they don't exist. + If it is zero (default), no directories are created. If it is negative, then the + absolute value is the maximum of directories that will be created (i.e. -1 will + create a maximum of one directory to complete the path, -2 will create a maximum + of 2 directories). If it is positive, then at least that many directories in the + path must exist (i.e. a value of 1 will create all directories below the root + directory and 2 will not create a directory in the root directory). + + + CREATE_DIR + + $(P)$(R)CreateDirectory
+ $(P)$(R)CreateDirectory_RBV + + longout
+ longin + Array data