diff --git a/HistDriv.i b/HistDriv.i index 174045f1..aba84ffa 100644 --- a/HistDriv.i +++ b/HistDriv.i @@ -1,5 +1,5 @@ -#line 477 "histogram.w" +#line 478 "histogram.w" /*--------------------------------------------------------------------------- H I S T D R I V @@ -13,7 +13,7 @@ #define MAXCHAN 16834 -#line 82 "histogram.w" +#line 83 "histogram.w" typedef struct __HistDriver { /* configuration data */ @@ -77,17 +77,17 @@ void *pPriv; } HistDriver; -#line 489 "histogram.w" +#line 490 "histogram.w" -#line 239 "histogram.w" +#line 240 "histogram.w" pHistDriver CreateHistDriver(pStringDict pDict); void DeleteHistDriver(pHistDriver self); int HistDriverConfig(pHistDriver self, pStringDict pOpt, SConnection *pCon); -#line 490 "histogram.w" +#line 491 "histogram.w" #endif diff --git a/HistMem.h b/HistMem.h index 579b63e9..3463f60e 100644 --- a/HistMem.h +++ b/HistMem.h @@ -1,5 +1,5 @@ -#line 450 "histogram.w" +#line 451 "histogram.w" /*-------------------------------------------------------------------------- H I S T M E M @@ -29,10 +29,11 @@ eHTOF, eHStrobo, eHRPT, - ePSD + ePSD, + eSANSTOF } HistMode; -#line 34 "histogram.w" +#line 35 "histogram.w" typedef enum { eOIgnore, @@ -41,22 +42,22 @@ eReflect } OverFlowMode; -#line 470 "histogram.w" +#line 471 "histogram.w" /*--------------------------------------------------------------------------*/ -#line 303 "histogram.w" +#line 304 "histogram.w" pHistMem CreateHistMemory(char *drivername); void DeleteHistMemory(void *self); -#line 319 "histogram.w" +#line 320 "histogram.w" int HistGetOption(pHistMem self, char *name, char *result, int iResultLen); int HistSetOption(pHistMem self, char *name, char *value); int HistConfigure(pHistMem self, SConnection *pCon, SicsInterp *pSics); -#line 347 "histogram.w" +#line 348 "histogram.w" float GetHistPreset(pHistMem self); int SetHistPreset(pHistMem self, float fVal); @@ -71,7 +72,7 @@ int HistBlockCount(pHistMem self, SConnection *pCon); -#line 376 "histogram.w" +#line 377 "histogram.w" int SetHistogram(pHistMem self, SConnection *pCon, int i,int iStart, int iEnd, HistInt *lData); @@ -83,7 +84,7 @@ HistInt *lData, int iDataLen); int PresetHistogram(pHistMem self, SConnection *pCon, HistInt lVal); -#line 419 "histogram.w" +#line 420 "histogram.w" int MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); @@ -92,7 +93,7 @@ int argc, char *argv[]); -#line 472 "histogram.w" +#line 473 "histogram.w" #endif diff --git a/HistMem.i b/HistMem.i index 67d47a75..27781143 100644 --- a/HistMem.i +++ b/HistMem.i @@ -1,5 +1,5 @@ -#line 495 "histogram.w" +#line 496 "histogram.w" /*--------------------------------------------------------------------------- H I S T M E M -- Internal @@ -11,7 +11,7 @@ #ifndef SICSHISTMEMINT #define SICSHISTMEMINT -#line 261 "histogram.w" +#line 262 "histogram.w" typedef struct __HistMem { pObjectDescriptor pDes; @@ -29,7 +29,7 @@ int iUpdateIntervall; } HistMem; -#line 505 "histogram.w" +#line 506 "histogram.w" #endif diff --git a/anticollider.i b/anticollider.i new file mode 100644 index 00000000..74307cc5 --- /dev/null +++ b/anticollider.i @@ -0,0 +1,28 @@ + +/*------------------------------------------------------------------------- + Anticollider internal data structure definition. Generated from + anticollider.w. Do not edit. +-------------------------------------------------------------------------*/ + + typedef struct __ANTICOLLIDER{ + pObjectDescriptor pDes; + pIDrivable pDriv; + int motorList; + int sequenceList; + char *colliderScript; + int isDirty; + int level; + }AntiCollider, *pAntiCollider; + + + typedef struct { + int level; + char pMotor[80]; + float target; + }Sequence; + + int StartLevel(int level, int sequenceList, int motorList, + SConnection *pCon); + + + diff --git a/countdriv.c b/countdriv.c index 4c8a9634..bdd6b8d4 100644 --- a/countdriv.c +++ b/countdriv.c @@ -102,6 +102,7 @@ int iPort; int iChannel; void *pData; + int finishCount; } EL737st; /*------------------------------------------------------------------------*/ static int EL737GetStatus(struct __COUNTER *self, float *fControl) @@ -143,18 +144,29 @@ self->lCounts[7] = iC4; if(iRS == 0) { - return HWIdle; + pEL737->finishCount++; + if(pEL737->finishCount >= 2) + { + return HWIdle; + } + else + { + return HWBusy; + } } else if((iRS == 1) || (iRS == 2)) { + pEL737->finishCount = 0; return HWBusy; } else if( (iRS == 5) || (iRS == 6)) { + pEL737->finishCount = 0; return HWNoBeam; } else { + pEL737->finishCount = 0; return HWPause; } } @@ -179,6 +191,7 @@ iRet = EL737_StartCnt(&pEL737->pData,(int)nintf(self->fPreset),&iRS); if(iRet == 1) { + pEL737->finishCount = 0; return OKOK; } else @@ -191,6 +204,7 @@ iRet = EL737_StartTime(&pEL737->pData,self->fPreset,&iRS); if(iRet == 1) { + pEL737->finishCount = 0; return OKOK; } else diff --git a/histdriv.c b/histdriv.c index f1510275..7252dde1 100644 --- a/histdriv.c +++ b/histdriv.c @@ -108,6 +108,7 @@ "strobo", "hrpt", "psd", + "sanstof", NULL }; diff --git a/histmem.c b/histmem.c index 9e6ecf94..1bdefc9e 100644 --- a/histmem.c +++ b/histmem.c @@ -654,7 +654,9 @@ myDim++; } } - if(self->pDriv->eHistMode == eHTOF || self->pDriv->eHistMode == ePSD) + if(self->pDriv->eHistMode == eHTOF + || self->pDriv->eHistMode == ePSD + || self->pDriv->eHistMode == eSANSTOF) { iDim[myDim] = self->pDriv->iTimeChan; myDim++; diff --git a/histogram.tex b/histogram.tex index 276878b2..507b292d 100644 --- a/histogram.tex +++ b/histogram.tex @@ -18,7 +18,8 @@ $\langle$Modes {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ eHTOF,@\\ \mbox{}\verb@ eHStrobo,@\\ \mbox{}\verb@ eHRPT,@\\ -\mbox{}\verb@ ePSD@\\ +\mbox{}\verb@ ePSD,@\\ +\mbox{}\verb@ eSANSTOF@\\ \mbox{}\verb@ } HistMode;@\\ \mbox{}\verb@@$\diamond$ \end{list} diff --git a/histogram.w b/histogram.w index 8bf27d35..8b45399b 100644 --- a/histogram.w +++ b/histogram.w @@ -13,7 +13,8 @@ histograms. Let's discuss these different modes first. eHTOF, eHStrobo, eHRPT, - ePSD + ePSD, + eSANSTOF } HistMode; @} A histogram memory can be operated in transparent mode. It has not yet been diff --git a/napi4.c b/napi4.c new file mode 100644 index 00000000..e4d3a64a --- /dev/null +++ b/napi4.c @@ -0,0 +1,1727 @@ +#include +#include +#include +#include + + typedef struct __NexusFile { + struct iStack { + int32 *iRefDir; + int32 *iTagDir; + int32 iVref; + int32 __iStack_pad; + int iNDir; + int iCurDir; + } iStack[NXMAXSTACK]; + struct iStack iAtt; + int32 iVID; + int32 iSID; + int32 iCurrentVG; + int32 iCurrentSDS; + int iNXID; + int iStackPtr; + char iAccess[2]; + } NexusFile, *pNexusFile; + + + /*--------------------------------------------------------------------*/ + + static pNexusFile NXIassert(NXhandle fid) + { + pNexusFile pRes; + + assert(fid != NULL); + pRes = (pNexusFile)fid; + assert(pRes->iNXID == NXSIGNATURE); + return pRes; + } + + /* --------------------------------------------------------------------- */ + + static int32 NXIFindVgroup (pNexusFile pFile, char *name, char *nxclass) + { + int32 iNew, iRef, iTag; + int iN, i; + int32 *pArray = NULL; + NXname pText; + + assert (pFile != NULL); + + if (pFile->iCurrentVG == 0) { /* root level */ + /* get the number and ID's of all lone Vgroups in the file */ + iN = Vlone (pFile->iVID, NULL, 0); + if(iN == 0) { + return NX_EOD; + } + pArray = (int32 *) malloc (iN * sizeof (int32)); + if (!pArray) { + NXIReportError (NXpData, "ERROR: out of memory in NXIFindVgroup"); + return NX_EOD; + } + Vlone (pFile->iVID, pArray, iN); + + /* loop and check */ + for (i = 0; i < iN; i++) { + iNew = Vattach (pFile->iVID, pArray[i], "r"); + Vgetname (iNew, pText); + if (strcmp (pText, name) == 0) { + Vgetclass (iNew, pText); + if (strcmp (pText, nxclass) == 0) { + /* found ! */ + Vdetach (iNew); + iNew = pArray[i]; + free (pArray); + return iNew; + } + } + Vdetach (iNew); + } + /* nothing found */ + free (pArray); + return NX_EOD; + } else { /* case in Vgroup */ + iN = Vntagrefs (pFile->iCurrentVG); + for (i = 0; i < iN; i++) { + Vgettagref (pFile->iCurrentVG, i, &iTag, &iRef); + if (iTag == DFTAG_VG) { + iNew = Vattach (pFile->iVID, iRef, "r"); + Vgetname (iNew, pText); + if (strcmp (pText, name) == 0) { + Vgetclass (iNew, pText); + if (strcmp (pText, nxclass) == 0) { + /* found ! */ + Vdetach (iNew); + return iRef; + } + } + Vdetach (iNew); + } + } /* end for */ + } /* end else */ + /* not found */ + return NX_EOD; + } + + /*----------------------------------------------------------------------*/ + + static int32 NXIFindSDS (NXhandle fid, CONSTCHAR *name) + { + pNexusFile self; + int32 iNew, iRet, iTag, iRef; + int32 i, iN, iA, iD1, iD2; + NXname pNam; + int32 iDim[MAX_VAR_DIMS]; + + self = NXIassert (fid); + + /* root level search */ + if (self->iCurrentVG == 0) { + i = SDfileinfo (self->iSID, &iN, &iA); + if (i < 0) { + NXIReportError (NXpData, "ERROR: failure to read file information"); + return NX_EOD; + } + for (i = 0; i < iN; i++) { + iNew = SDselect (self->iSID, i); + SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2); + if (strcmp (pNam, name) == 0) { + iRet = SDidtoref (iNew); + SDendaccess (iNew); + return iRet; + } else { + SDendaccess (iNew); + } + } + /* not found */ + return NX_EOD; + } + /* end root level */ + else { /* search in a Vgroup */ + iN = Vntagrefs (self->iCurrentVG); + for (i = 0; i < iN; i++) { + Vgettagref (self->iCurrentVG, i, &iTag, &iRef); + /* we are now writing using DFTAG_NDG, but need others for backward compatability */ + if ((iTag == DFTAG_SDG) || (iTag == DFTAG_NDG) || (iTag == DFTAG_SDS)) { + iNew = SDreftoindex (self->iSID, iRef); + iNew = SDselect (self->iSID, iNew); + SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2); + if (strcmp (pNam, name) == 0) { + SDendaccess (iNew); + return iRef; + } + SDendaccess (iNew); + } + } /* end for */ + } /* end Vgroup */ + /* we get here, only if nothing found */ + return NX_EOD; + } + + /*----------------------------------------------------------------------*/ + + static int NXIInitDir (pNexusFile self) + { + int i; + int32 iTag, iRef; + int iStackPtr; + + /* + * Note: the +1 to various malloc() operations is to avoid a + * malloc(0), which is an error on some operating systems + */ + iStackPtr = self->iStackPtr; + if (self->iCurrentVG == 0 && + self->iStack[iStackPtr].iRefDir == NULL) { /* root level */ + /* get the number and ID's of all lone Vgroups in the file */ + self->iStack[iStackPtr].iNDir = Vlone (self->iVID, NULL, 0); + self->iStack[iStackPtr].iRefDir = + (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1); + if (!self->iStack[iStackPtr].iRefDir) { + NXIReportError (NXpData, "ERROR: out of memory in NXIInitDir"); + return NX_EOD; + } + Vlone (self->iVID, + self->iStack[self->iStackPtr].iRefDir, + self->iStack[self->iStackPtr].iNDir); + } else { + /* Vgroup level */ + self->iStack[iStackPtr].iNDir = Vntagrefs (self->iCurrentVG); + self->iStack[iStackPtr].iRefDir = + (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1); + self->iStack[iStackPtr].iTagDir = + (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1); + if ((!self->iStack[iStackPtr].iRefDir) || + (!self->iStack[iStackPtr].iTagDir)) { + NXIReportError (NXpData, "ERROR: out of memory in NXIInitDir"); + return NX_EOD; + } + for (i = 0; i < self->iStack[self->iStackPtr].iNDir; i++) { + Vgettagref (self->iCurrentVG, i, &iTag, &iRef); + self->iStack[iStackPtr].iRefDir[i] = iRef; + self->iStack[iStackPtr].iTagDir[i] = iTag; + } + } + self->iStack[iStackPtr].iCurDir = 0; + return 1; + } + + /*----------------------------------------------------------------------*/ + + static void NXIKillDir (pNexusFile self) + { + if (self->iStack[self->iStackPtr].iRefDir) { + free (self->iStack[self->iStackPtr].iRefDir); + self->iStack[self->iStackPtr].iRefDir = NULL; + } + if (self->iStack[self->iStackPtr].iTagDir) { + free (self->iStack[self->iStackPtr].iTagDir); + self->iStack[self->iStackPtr].iTagDir = NULL; + } + self->iStack[self->iStackPtr].iCurDir = 0; + self->iStack[self->iStackPtr].iNDir = 0; + } + + + /*-------------------------------------------------------------------------*/ + + static int NXIInitAttDir (pNexusFile pFile) + { + int iRet; + int32 iData, iAtt, iRank, iType; + int32 iDim[MAX_VAR_DIMS]; + NXname pNam; + + pFile->iAtt.iCurDir = 0; + if (pFile->iCurrentSDS != 0) { /* SDS level */ + iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType, + &iAtt); + } else { /* global level */ + iRet = SDfileinfo (pFile->iSID, &iData, &iAtt); + } + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot read attribute numbers"); + pFile->iAtt.iNDir = 0; + return NX_ERROR; + } + pFile->iAtt.iNDir = iAtt; + return NX_OK; + } + + /* --------------------------------------------------------------------- */ + + static void NXIKillAttDir (pNexusFile self) + { + if (self->iAtt.iRefDir) { + free (self->iAtt.iRefDir); + self->iAtt.iRefDir = NULL; + } + if (self->iAtt.iTagDir) { + free (self->iAtt.iTagDir); + self->iAtt.iTagDir = NULL; + } + self->iAtt.iCurDir = 0; + self->iAtt.iNDir = 0; + } + + + /* ---------------------------------------------------------------------- + + Definition of NeXus API + + ---------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4open(CONSTCHAR *filename, NXaccess am, NXhandle* pHandle) + { + pNexusFile pNew = NULL; + char pBuffer[512], time_buffer[64]; + char HDF_VERSION[64]; + uint32 lmajor, lminor, lrelease; + int32 am1=0; + int32 file_id=0, an_id=0, ann_id=0; + time_t timer; + struct tm *time_info; + const char* time_format; + long gmt_offset; +#ifdef USE_FTIME + struct timeb timeb_struct; +#endif /* USE_FTIME */ + + *pHandle = NULL; + /* map Nexus NXaccess types to HDF4 types */ + if (am == NXACC_CREATE) { + am1 = DFACC_CREATE; + } else if (am == NXACC_READ) { + am1 = DFACC_READ; + } else if (am == NXACC_RDWR) { + am1 = DFACC_RDWR; + } + /* get memory */ + pNew = (pNexusFile) malloc (sizeof (NexusFile)); + if (!pNew) { + NXIReportError (NXpData, "ERROR: no memory to create File datastructure"); + return NX_ERROR; + } + memset (pNew, 0, sizeof (NexusFile)); +/* + * get time in ISO 8601 format + */ +#ifdef NEED_TZSET + tzset(); +#endif /* NEED_TZSET */ + time(&timer); +#ifdef USE_FTIME + ftime(&timeb_struct); + gmt_offset = -timeb_struct.timezone * 60; + if (timeb_struct.dstflag != 0) { + gmt_offset += 3600; + } +#else + time_info = gmtime(&timer); + if (time_info != NULL) { + gmt_offset = difftime(timer, mktime(time_info)); + } else { + NXIReportError(NXpData, "Your gmtime() function does not work ... timezone information will be incorrect\n"); + gmt_offset = 0; + } +#endif /* USE_FTIME */ + time_info = localtime(&timer); + if (time_info != NULL) { + if (gmt_offset < 0) { + time_format = "%04d-%02d-%02d %02d:%02d:%02d-%02d%02d"; + } else { + time_format = "%04d-%02d-%02d %02d:%02d:%02d+%02d%02d"; + } + sprintf(time_buffer, time_format, + 1900 + time_info->tm_year, + 1 + time_info->tm_mon, + time_info->tm_mday, + time_info->tm_hour, + time_info->tm_min, + time_info->tm_sec, + abs(gmt_offset / 3600), + abs((gmt_offset % 3600) / 60) + ); + } else { + strcpy(time_buffer, "1970-01-01 00:00:00+0000"); + } + +#if WRITE_OLD_IDENT /* not used at moment */ +/* + * write something that can be used by OLE + */ + + if (am == NXACC_CREATE) { + if ( (file_id = Hopen(filename, am1, 0)) == -1 ) { + sprintf (pBuffer, "ERROR: cannot open file_a: %s", filename); + NXIReportError (NXpData, pBuffer); + free (pNew); + return NX_ERROR; + } + an_id = ANstart(file_id); + ann_id = ANcreatef(an_id, AN_FILE_LABEL); /* AN_FILE_DESC */ + ANwriteann(ann_id, "NeXus", 5); + ANendaccess(ann_id); + ANend(an_id); + if (Hclose(file_id) == -1) { + sprintf (pBuffer, "ERROR: cannot close file: %s", filename); + NXIReportError (NXpData, pBuffer); + free (pNew); + return NX_ERROR; + } + am = NXACC_RDWR; + } +#endif /* WRITE_OLD_IDENT */ + + /* start SDS interface */ + pNew->iSID = SDstart (filename, am1); + if (pNew->iSID <= 0) { + sprintf (pBuffer, "ERROR: cannot open file_b: %s", filename); + NXIReportError (NXpData, pBuffer); + free (pNew); + return NX_ERROR; + } +/* + * need to create global attributes file_name file_time NeXus_version + * at some point for new files + */ + if (am != NXACC_READ) { + if (SDsetattr(pNew->iSID, "NeXus_version", DFNT_CHAR8, strlen(NEXUS_VERSION), NEXUS_VERSION) < 0) { + NXIReportError (NXpData, "ERROR: HDF failed to store NeXus_version attribute "); + return NX_ERROR; + } + Hgetlibversion(&lmajor, &lminor, &lrelease, HDF_VERSION); + if (SDsetattr(pNew->iSID, "HDF_version", DFNT_CHAR8, strlen(HDF_VERSION), HDF_VERSION) < 0) { + NXIReportError (NXpData, "ERROR: HDF failed to store HDF_version attribute "); + return NX_ERROR; + } + } + if (am == NXACC_CREATE) { + if (SDsetattr(pNew->iSID, "file_name", DFNT_CHAR8, strlen(filename), (char*)filename) < 0) { + NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); + return NX_ERROR; + } + if (SDsetattr(pNew->iSID, "file_time", DFNT_CHAR8, strlen(time_buffer), time_buffer) < 0) { + NXIReportError (NXpData, "ERROR: HDF failed to store file_time attribute "); + return NX_ERROR; + } + } + + /* + * Otherwise we try to create the file two times which makes HDF + * Throw up on us. + */ + if (am == NXACC_CREATE) { + am = NXACC_RDWR; + am1 = DFACC_RDWR; + } + + /* Set Vgroup access mode */ + if (am == NXACC_READ) { + strcpy(pNew->iAccess,"r"); + } else { + strcpy(pNew->iAccess,"w"); + } + + /* start Vgroup API */ + + pNew->iVID = Hopen (filename, am1, 100); + if (pNew->iVID <= 0) { + sprintf (pBuffer, "ERROR: cannot open file_c: %s", filename); + NXIReportError (NXpData, pBuffer); + free (pNew); + return NX_ERROR; + } + Vstart (pNew->iVID); + pNew->iNXID = NXSIGNATURE; + pNew->iStack[0].iVref = 0; /* root! */ + + *pHandle = (NXhandle)pNew; + return NX_OK; + } + +/*-----------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX4close (NXhandle* fid) + { + pNexusFile pFile = NULL; + int iRet; + + pFile = NXIassert(*fid); + iRet = 0; + /* close links into vGroups or SDS */ + if (pFile->iCurrentVG != 0) { + Vdetach (pFile->iCurrentVG); + } + if (pFile->iCurrentSDS != 0) { + iRet = SDendaccess (pFile->iCurrentSDS); + } + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: ending access to SDS"); + } + /* close the SDS and Vgroup API's */ + Vend (pFile->iVID); + iRet = SDend (pFile->iSID); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot close SDS interface"); + } + iRet = Hclose (pFile->iVID); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot close HDF file"); + } + /* release memory */ + NXIKillDir (pFile); + free (pFile); + *fid = NULL; + return NX_OK; + } + + +/*-----------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4makegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + { + pNexusFile pFile; + int32 iNew, iRet; + char pBuffer[256]; + + pFile = NXIassert (fid); + /* + * Make sure that a group with the same name and nxclass does not + * already exist. + */ + if ((iRet = NXIFindVgroup (pFile, (char*)name, nxclass)) >= 0) { + sprintf (pBuffer, "ERROR: Vgroup %s, class %s already exists", + name, nxclass); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + + /* create and configure the group */ + iNew = Vattach (pFile->iVID, -1, "w"); + if (iNew < 0) { + NXIReportError (NXpData, "ERROR: HDF could not create Vgroup"); + return NX_ERROR; + } + Vsetname (iNew, name); + Vsetclass (iNew, nxclass); + + /* Insert it into the hierarchy, when appropriate */ + iRet = 0; + if (pFile->iCurrentVG != 0) { + iRet = Vinsert (pFile->iCurrentVG, iNew); + } + Vdetach (iNew); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF failed to insert Vgroup"); + return NX_ERROR; + } + return NX_OK; + } + + + /*------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4opengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + { + pNexusFile pFile; + int32 iRef; + char pBuffer[256]; + + pFile = NXIassert (fid); + + iRef = NXIFindVgroup (pFile, (char*)name, nxclass); + if (iRef < 0) { + sprintf (pBuffer, "ERROR: Vgroup %s, class %s NOT found", name, nxclass); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + /* are we at root level ? */ + if (pFile->iCurrentVG == 0) { + pFile->iCurrentVG = Vattach (pFile->iVID, iRef,pFile->iAccess); + pFile->iStackPtr++; + pFile->iStack[pFile->iStackPtr].iVref = iRef; + } else { + Vdetach (pFile->iCurrentVG); + pFile->iStackPtr++; + pFile->iStack[pFile->iStackPtr].iVref = iRef; + pFile->iCurrentVG = Vattach (pFile->iVID, + pFile->iStack[pFile->iStackPtr].iVref, + pFile->iAccess); + } + NXIKillDir (pFile); + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + + NXstatus CALLING_STYLE NX4closegroup (NXhandle fid) + { + pNexusFile pFile; + + pFile = NXIassert (fid); + + /* first catch the trivial case: we are at root and cannot get + deeper into a negative directory hierarchy (anti-directory) + */ + if (pFile->iCurrentVG == 0) { + NXIKillDir (pFile); + return NX_OK; + } else { /* Sighhh. Some work to do */ + /* close the current VG and decrement stack */ + Vdetach (pFile->iCurrentVG); + NXIKillDir (pFile); + pFile->iStackPtr--; + if (pFile->iStackPtr <= 0) { /* we hit root */ + pFile->iStackPtr = 0; + pFile->iCurrentVG = 0; + } else { + /* attach to the lower Vgroup */ + pFile->iCurrentVG = Vattach (pFile->iVID, + pFile->iStack[pFile->iStackPtr].iVref, + pFile->iAccess); + } + } + return NX_OK; + } + + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX4makedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, + int dimensions[]) + { + pNexusFile pFile; + int32 iNew; + char pBuffer[256]; + int i, iRet, type; + int32 myDim[MAX_VAR_DIMS]; + + pFile = NXIassert (fid); + + if (dimensions[0] == NX_UNLIMITED) + { + dimensions[0] = SD_UNLIMITED; + } + + if ((iNew = NXIFindSDS (fid, name))>=0) { + sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + + if (datatype == NX_CHAR) + { + type=DFNT_CHAR8; + } + else if (datatype == NX_INT8) + { + type=DFNT_INT8; + } + else if (datatype == NX_UINT8) + { + type=DFNT_UINT8; + } + else if (datatype == NX_INT16) + { + type=DFNT_INT16; + } + else if (datatype == NX_UINT16) + { + type=DFNT_UINT16; + } + else if (datatype == NX_INT32) + { + type=DFNT_INT32; + } + else if (datatype == NX_UINT32) + { + type=DFNT_UINT32; + } + else if (datatype == NX_FLOAT32) + { + type=DFNT_FLOAT32; + } + else if (datatype == NX_FLOAT64) + { + type=DFNT_FLOAT64; + } + + if (rank <= 0) { + sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s", + name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + + /* + Check dimensions for consistency. The first dimension may be 0 + thus denoting an unlimited dimension. + */ + for (i = 1; i < rank; i++) { + if (dimensions[i] <= 0) { + sprintf (pBuffer, + "ERROR: invalid dimension %d, value %d given for SDS %s", + i, dimensions[i], name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + } + + /* cast the dimensions array properly for non 32-bit ints */ + for(i = 0; i < rank; i++) + { + myDim[i] = (int32)dimensions[i]; + } + + + /* behave nicely, if there is still an SDS open */ + if (pFile->iCurrentSDS != 0) { + SDendaccess (pFile->iCurrentSDS); + pFile->iCurrentSDS = 0; + } + + /* Do not allow creation of SDS's at the root level */ + if (pFile->iCurrentVG == 0) { + sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted"); + NXIReportError(NXpData, pBuffer); + return NX_ERROR; + } + + /* dataset creation */ + iNew = SDcreate (pFile->iSID, (char*)name, (int32)type, + (int32)rank, myDim); + if (iNew < 0) { + sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments", + name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + /* link into Vgroup, if in one */ + if (pFile->iCurrentVG != 0) { + iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew)); + } + iRet = SDendaccess (iNew); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot end access to SDS"); + return NX_ERROR; + } + return NX_OK; + } + + + /* --------------------------------------------------------------------- */ + + + NXstatus CALLING_STYLE NX4compmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, + int dimensions[],int compress_type, int chunk_size[]) + { + pNexusFile pFile; + int32 iNew, iRet, type; + char pBuffer[256]; + int i; + int32 myDim[MAX_VAR_DIMS]; + comp_info compstruct; + + pFile = NXIassert (fid); + + if (dimensions[0] == NX_UNLIMITED) + { + dimensions[0] = SD_UNLIMITED; + } + + if ((iNew = NXIFindSDS (fid, name))>=0) { + sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + + if (datatype == NX_CHAR) + { + type=DFNT_CHAR8; + } + else if (datatype == NX_INT8) + { + type=DFNT_INT8; + } + else if (datatype == NX_UINT8) + { + type=DFNT_UINT8; + } + else if (datatype == NX_INT16) + { + type=DFNT_INT16; + } + else if (datatype == NX_UINT16) + { + type=DFNT_UINT16; + } + else if (datatype == NX_INT32) + { + type=DFNT_INT32; + } + else if (datatype == NX_UINT32) + { + type=DFNT_UINT32; + } + else if (datatype == NX_FLOAT32) + { + type=DFNT_FLOAT32; + } + else if (datatype == NX_FLOAT64) + { + type=DFNT_FLOAT64; + } + + if (rank <= 0) { + sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s", + name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + + /* + Check dimensions for consistency. The first dimension may be 0 + thus denoting an unlimited dimension. + */ + for (i = 1; i < rank; i++) { + if (dimensions[i] <= 0) { + sprintf (pBuffer, + "ERROR: invalid dimension %d, value %d given for SDS %s", + i, dimensions[i], name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + } + + /* cast the dimensions array properly for non 32-bit ints */ + for(i = 0; i < rank; i++) + { + myDim[i] = (int32)dimensions[i]; + } + + + /* behave nicely, if there is still an SDS open */ + if (pFile->iCurrentSDS != 0) { + SDendaccess (pFile->iCurrentSDS); + pFile->iCurrentSDS = 0; + } + + /* Do not allow creation of SDS's at the root level */ + if (pFile->iCurrentVG == 0) { + sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted"); + NXIReportError(NXpData, pBuffer); + return NX_ERROR; + } + + /* dataset creation */ + iNew = SDcreate (pFile->iSID, (char*)name, (int32)type, + (int32)rank, myDim); + if (iNew < 0) { + sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments", + name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + + /* compress SD data set */ + + if(compress_type == NX_COMP_LZW) + { + compstruct.deflate.level = 6; + iRet = SDsetcompress(iNew, COMP_CODE_DEFLATE, &compstruct); + if (iRet < 0) + { + NXIReportError (NXpData, "LZW-Compression failure!"); + return NX_ERROR; + } + } + else if (compress_type == NX_COMP_RLE) + { + iRet = SDsetcompress(iNew, COMP_CODE_RLE, &compstruct); + if (iRet < 0) + { + NXIReportError (NXpData, "RLE-Compression failure!"); + return NX_ERROR; + } + } + else if (compress_type == NX_COMP_HUF) + { + compstruct.skphuff.skp_size = DFKNTsize(type); + iRet = SDsetcompress(iNew, COMP_CODE_SKPHUFF, &compstruct); + if (iRet < 0) + { + NXIReportError (NXpData, "HUF-Compression failure!"); + return NX_ERROR; + } + } + else if (compress_type == NX_COMP_NONE) + { + /* */ + } + else + { + NXIReportError (NXpData, "Unknown compression method!"); + NX_ERROR; + } + /* link into Vgroup, if in one */ + if (pFile->iCurrentVG != 0) { + iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew)); + } + iRet = SDendaccess (iNew); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot end access to SDS"); + return NX_ERROR; + } + + return NX_OK; + } + + /* --------------------------------------------------------------------- */ + + + NXstatus CALLING_STYLE NX4compress (NXhandle fid, int compress_type) + { + pNexusFile pFile; + int32 iRank, iAtt, iType, iRet; + int32 iSize[MAX_VAR_DIMS]; + int compress_typei; + NXname pBuffer; + char pError[512]; + comp_info compstruct; + + pFile = NXIassert (fid); + + /* check if there is an SDS open */ + if (pFile->iCurrentSDS == 0) { + NXIReportError (NXpData, "ERROR: no SDS open"); + return NX_ERROR; + } + + if (compress_type == NX_COMP_NONE) + { + compress_typei = COMP_CODE_NONE; + } + else if (compress_type == NX_COMP_LZW) + { + compress_typei = COMP_CODE_DEFLATE; + } + else if (compress_type == NX_COMP_RLE) + { + compress_typei = COMP_CODE_RLE; + } + else if + (compress_type == NX_COMP_HUF) + { + compress_typei = COMP_CODE_SKPHUFF; + } + + /* first read dimension information */ + SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt); + + /* + according to compression type initialize compression + information + */ + if(compress_type == NX_COMP_LZW) + { + compstruct.deflate.level = 6; + } + else if(compress_type == NX_COMP_HUF) + { + compstruct.skphuff.skp_size = DFKNTsize(iType); + } + + iRet = SDsetcompress(pFile->iCurrentSDS, compress_typei, &compstruct); + if (iRet < 0) { + sprintf (pError, "ERROR: failure to compress data to %s", pBuffer); + NXIReportError (NXpData, pError); + return NX_ERROR; + } + return NX_OK; + } + + /* --------------------------------------------------------------------- */ + + + NXstatus CALLING_STYLE NX4opendata (NXhandle fid, CONSTCHAR *name) + { + pNexusFile pFile; + int32 iNew; + char pBuffer[256]; + int iRet; + + pFile = NXIassert (fid); + + /* First find the reference number of the SDS */ + iNew = NXIFindSDS (fid, name); + if (iNew < 0) { + sprintf (pBuffer, "ERROR: SDS %s not found at this level", name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + /* Be nice: properly close the old open SDS silently if there is + * still an SDS open. + */ + if (pFile->iCurrentSDS) { + iRet = SDendaccess (pFile->iCurrentSDS); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot end access to SDS"); + } + } + /* clear pending attribute directories first */ + NXIKillAttDir (pFile); + + /* open the SDS */ + iNew = SDreftoindex (pFile->iSID, iNew); + pFile->iCurrentSDS = SDselect (pFile->iSID, iNew); + if (pFile->iCurrentSDS < 0) { + NXIReportError (NXpData, "ERROR: HDF error opening SDS"); + pFile->iCurrentSDS = 0; + return NX_ERROR; + } + return NX_OK; + } + + /* ----------------------------------------------------------------- */ + + + NXstatus CALLING_STYLE NX4closedata (NXhandle fid) + { + pNexusFile pFile; + int iRet; + + pFile = NXIassert (fid); + + if (pFile->iCurrentSDS != 0) { + iRet = SDendaccess (pFile->iCurrentSDS); + pFile->iCurrentSDS = 0; + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot end access to SDS"); + return NX_ERROR; + } + } else { + NXIReportError (NXpData, "ERROR: no SDS open --> nothing to do"); + return NX_ERROR; + } + NXIKillAttDir (pFile); /* for attribute data */ + return NX_OK; + } + + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX4putdata (NXhandle fid, void *data) + { + pNexusFile pFile; + int32 iStart[MAX_VAR_DIMS], iSize[MAX_VAR_DIMS], iStride[MAX_VAR_DIMS]; + NXname pBuffer; + int32 iRank, iAtt, iType, iRet, i; + char pError[512]; + + pFile = NXIassert (fid); + + /* check if there is an SDS open */ + if (pFile->iCurrentSDS == 0) { + NXIReportError (NXpData, "ERROR: no SDS open"); + return NX_ERROR; + } + /* first read dimension information */ + memset (iStart, 0, MAX_VAR_DIMS * sizeof (int32)); + SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt); + + /* initialise stride to 1 */ + for (i = 0; i < iRank; i++) { + iStride[i] = 1; + } + + /* actually write */ + iRet = SDwritedata (pFile->iCurrentSDS, iStart, iStride, iSize, data); + if (iRet < 0) { + sprintf (pError, "ERROR: failure to write data to %s", pBuffer); + NXIReportError (NXpData, pError); + return NX_ERROR; + } + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + NXstatus + CALLING_STYLE NX4putattr (NXhandle fid, CONSTCHAR *name, void *data, int datalen, int iType) + { + pNexusFile pFile; + int iRet, type; + + pFile = NXIassert (fid); + if (iType == NX_CHAR) + { + type=DFNT_CHAR8; + } + else if (iType == NX_INT8) + { + type=DFNT_INT8; + } + else if (iType == NX_UINT8) + { + type=DFNT_UINT8; + } + else if (iType == NX_INT16) + { + type=DFNT_INT16; + } + else if (iType == NX_UINT16) + { + type=DFNT_UINT16; + } + else if (iType == NX_INT32) + { + type=DFNT_INT32; + } + else if (iType == NX_UINT32) + { + type=DFNT_UINT32; + } + else if (iType == NX_FLOAT32) + { + type=DFNT_FLOAT32; + } + else if (iType == NX_FLOAT64) + { + type=DFNT_FLOAT64; + } + if (pFile->iCurrentSDS != 0) { + /* SDS attribute */ + iRet = SDsetattr (pFile->iCurrentSDS, (char*)name, (int32)type, + (int32)datalen, data); + } else { + /* global attribute */ + iRet = SDsetattr (pFile->iSID, (char*)name, (int32)type, + (int32)datalen, data); + + } + iType = type; + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDf failed to store attribute "); + return NX_ERROR; + } + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + + NXstatus CALLING_STYLE NX4putslab (NXhandle fid, void *data, int iStart[], int iSize[]) + { + pNexusFile pFile; + int iRet; + int32 iStride[MAX_VAR_DIMS]; + int32 myStart[MAX_VAR_DIMS], mySize[MAX_VAR_DIMS]; + int32 i, iRank, iType, iAtt; + NXname pBuffer; + + + pFile = NXIassert (fid); + + /* check if there is an SDS open */ + if (pFile->iCurrentSDS == 0) { + NXIReportError (NXpData, "ERROR: no SDS open"); + return NX_ERROR; + } + /* initialise stride to 1 */ + for (i = 0; i < MAX_VAR_DIMS; i++) { + iStride[i] = 1; + } + + /* if an int is not 32-bit we have to cast them properly in order + to kill a bug. + */ + if(sizeof(int) != 4) + { + SDgetinfo (pFile->iCurrentSDS, pBuffer, + &iRank, myStart, &iType, &iAtt); + for(i = 0; i < iRank; i++) + { + myStart[i] = (int32)iStart[i]; + mySize[i] = (int32)iSize[i]; + } + /* finally write */ + iRet = SDwritedata (pFile->iCurrentSDS, myStart, + iStride, mySize, data); + + } + else + { + /* write directly */ + + iRet = SDwritedata (pFile->iCurrentSDS,(int32*)iStart, iStride, (int32*)iSize, data); + } + + /* deal with HDF errors */ + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: writing slab failed"); + return NX_ERROR; + } + return NX_OK; + } + + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX4getdataID (NXhandle fid, NXlink* sRes) + { + pNexusFile pFile; + + pFile = NXIassert (fid); + + if (pFile->iCurrentSDS == 0) { + sRes->iTag = NX_ERROR; + return NX_ERROR; + } else { + sRes->iTag = DFTAG_NDG; + sRes->iRef = SDidtoref (pFile->iCurrentSDS); + return NX_OK; + } + sRes->iTag = NX_ERROR; + return NX_ERROR; /* not reached */ + } + + + /* ------------------------------------------------------------------- */ + + + NXstatus CALLING_STYLE NX4makelink (NXhandle fid, NXlink* sLink) + { + pNexusFile pFile; + int32 iVG, iRet; + + pFile = NXIassert (fid); + + if (pFile->iCurrentVG == 0) { /* root level, can not link here */ + return NX_ERROR; + } + Vaddtagref (pFile->iCurrentVG, sLink->iTag, sLink->iRef); + return NX_OK; + } + + + /*----------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX4flush(NXhandle *pHandle) + { + char *pFileName, *pCopy = NULL; + int access, dummy, iRet, i, iStack; + pNexusFile pFile = NULL; + NXaccess ac; + int *iRefs = NULL; + + pFile = NXIassert(*pHandle); + + /* + The HDF4-API does not support a flush. We help ourselves with + inquiring the name and access type of the file, closing it and + opening it again. This is also the reason why this needs a pointer + to the handle structure as the handle changes. The other thing we + do is to store the refs of all open vGroups in a temporary array + in order to recover the position in the vGroup hierarchy before the + flush. + */ + iRet = Hfidinquire(pFile->iVID,&pFileName,&access,&dummy); + if (iRet < 0) { + NXIReportError (NXpData, + "ERROR: Failed to inquire file name for HDF file"); + return NX_ERROR; + } + if(pFile->iAccess[0] == 'r') { + ac = NXACC_READ; + }else if(pFile->iAccess[0] == 'w') { + ac = NXACC_RDWR; + } + pCopy = (char *)malloc((strlen(pFileName)+10)*sizeof(char)); + if(!pCopy) { + NXIReportError (NXpData, + "ERROR: Failed to allocate data for filename copy"); + return NX_ERROR; + } + memset(pCopy,0,strlen(pFileName)+10); + strcpy(pCopy,pFileName); + + /* get refs for recovering vGroup position */ + iStack = 0; + if(pFile->iStackPtr > 0) { + iStack = pFile->iStackPtr + 1; + iRefs = (int *)malloc(iStack*sizeof(int)); + if(!iRefs){ + NXIReportError (NXpData, + "ERROR: Failed to allocate data for hierarchy copy"); + return NX_ERROR; + } + for(i = 0; i < iStack; i++){ + iRefs[i] = pFile->iStack[i].iVref; + } + } + + iRet = NX4close(pHandle); + if(iRet != NX_OK) { + return iRet; + } + + iRet = NX4open(pCopy, ac, pHandle); + free(pCopy); + + /* return to position in vGroup hierarchy */ + pFile = NXIassert(*pHandle); + if(iStack > 0){ + pFile->iStackPtr = iStack - 1; + for(i = 0; i < iStack; i++){ + pFile->iStack[i].iVref = iRefs[i]; + } + free(iRefs); + pFile->iCurrentVG = Vattach(pFile->iVID, + pFile->iStack[pFile->iStackPtr].iVref, + pFile->iAccess); + } + + return iRet; + } + + /*-------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4getnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype) + { + pNexusFile pFile; + int iRet, iStackPtr, iCurDir; + int32 iTemp, iD1, iD2, iA; + int32 iDim[MAX_VAR_DIMS]; + + pFile = NXIassert (fid); + + iStackPtr = pFile->iStackPtr; + iCurDir = pFile->iStack[pFile->iStackPtr].iCurDir; + + /* first case to check for: no directory entry */ + if (pFile->iStack[pFile->iStackPtr].iRefDir == NULL) { + iRet = NXIInitDir (pFile); + if (iRet < 0) { + NXIReportError (NXpData, + "ERROR: no memory to store directory info"); + return NX_EOD; + } + } + /* Next case: end of directory */ + if (iCurDir >= pFile->iStack[pFile->iStackPtr].iNDir) { + NXIKillDir (pFile); + return NX_EOD; + } + /* Next case: we have data! supply it and increment counter */ + if (pFile->iCurrentVG == 0) { /* root level */ + iTemp = Vattach (pFile->iVID, + pFile->iStack[iStackPtr].iRefDir[iCurDir], "r"); + if (iTemp < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot attach to Vgroup"); + return NX_ERROR; + } + Vgetname (iTemp, name); + Vgetclass (iTemp, nxclass); + *datatype = DFTAG_VG; + pFile->iStack[pFile->iStackPtr].iCurDir++; + Vdetach (iTemp); + return NX_OK; + } else { /* in Vgroup */ + if (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_VG) {/* Vgroup */ + iTemp = Vattach (pFile->iVID, + pFile->iStack[iStackPtr].iRefDir[iCurDir], "r"); + if (iTemp < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot attach to Vgroup"); + return NX_ERROR; + } + Vgetname (iTemp, name); + Vgetclass (iTemp, nxclass); + *datatype = DFTAG_VG; + pFile->iStack[pFile->iStackPtr].iCurDir++; + Vdetach (iTemp); + return NX_OK; + /* we are now writing using DFTAG_NDG, but need others for backward compatability */ + } else if ((pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDG) || + (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_NDG) || + (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDS)) { + iTemp = SDreftoindex (pFile->iSID, + pFile->iStack[iStackPtr].iRefDir[iCurDir]); + iTemp = SDselect (pFile->iSID, iTemp); + SDgetinfo (iTemp, name, &iA, iDim, &iD1, &iD2); + strcpy (nxclass, "SDS"); + *datatype = iD1; + SDendaccess (iTemp); + pFile->iStack[pFile->iStackPtr].iCurDir++; + return NX_OK; + } else { /* unidentified */ + strcpy (name, "UNKNOWN"); + strcpy (nxclass, "UNKNOWN"); + *datatype = pFile->iStack[iStackPtr].iTagDir[iCurDir]; + pFile->iStack[pFile->iStackPtr].iCurDir++; + return NX_OK; + } + } + return NX_ERROR; /* not reached */ + } + + + /*-------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4getdata (NXhandle fid, void *data) + { + pNexusFile pFile; + int32 iStart[MAX_VAR_DIMS], iSize[MAX_VAR_DIMS]; + NXname pBuffer; + int32 iRank, iAtt, iType; + + pFile = NXIassert (fid); + + /* check if there is an SDS open */ + if (pFile->iCurrentSDS == 0) { + NXIReportError (NXpData, "ERROR: no SDS open"); + return NX_ERROR; + } + /* first read dimension information */ + memset (iStart, 0, MAX_VAR_DIMS * sizeof (int32)); + SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt); + /* actually read */ + SDreaddata (pFile->iCurrentSDS, iStart, NULL, iSize, data); + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus + CALLING_STYLE NX4getinfo (NXhandle fid, int *rank, int dimension[], int *iType) + { + pNexusFile pFile; + NXname pBuffer; + int32 iAtt, myDim[MAX_VAR_DIMS], i, iRank, mType; + + pFile = NXIassert (fid); + + /* check if there is an SDS open */ + if (pFile->iCurrentSDS == 0) { + NXIReportError (NXpData, "ERROR: no SDS open"); + return NX_ERROR; + } + /* read information */ + SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, myDim, + &mType, &iAtt); + + /* conversion to proper ints for the platform */ + *iType = (int)mType; + *rank = (int)iRank; + for(i = 0; i < iRank; i++) + { + dimension[i] = (int)myDim[i]; + } + return NX_OK; + } + + + /*-------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4getslab (NXhandle fid, void *data, int iStart[], int iSize[]) + { + pNexusFile pFile; + int32 myStart[MAX_VAR_DIMS], mySize[MAX_VAR_DIMS]; + int32 i, iRank, iType, iAtt; + NXname pBuffer; + + pFile = NXIassert (fid); + + /* check if there is an SDS open */ + if (pFile->iCurrentSDS == 0) { + NXIReportError (NXpData, "ERROR: no SDS open"); + return NX_ERROR; + } + + /* if an int is not 32-bit we have to cast them properly in order + to kill a bug. + */ + if(sizeof(int) != 4) + { + SDgetinfo (pFile->iCurrentSDS, pBuffer, + &iRank, myStart, &iType, &iAtt); + for(i = 0; i < iRank; i++) + { + myStart[i] = (int32)iStart[i]; + mySize[i] = (int32)iSize[i]; + } + /* finally read */ + SDreaddata (pFile->iCurrentSDS, myStart, NULL, + mySize, data); + return NX_OK; + } + else + { + /* read directly */ + SDreaddata (pFile->iCurrentSDS, (int32*)iStart, NULL, + (int32*)iSize, data); + return NX_OK; + } + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX4getnextattr (NXhandle fileid, NXname pName, + int *iLength, int *iType) + { + pNexusFile pFile; + int iRet; + int32 iPType, iCount; + + pFile = NXIassert (fileid); + + /* first check if we have to start a new attribute search */ + if (pFile->iAtt.iNDir == 0) { + iRet = NXIInitAttDir (pFile); + if (iRet == NX_ERROR) { + return NX_ERROR; + } + } + /* are we done ? */ + if (pFile->iAtt.iCurDir >= pFile->iAtt.iNDir) { + NXIKillAttDir (pFile); + return NX_EOD; + } + /* well, there must be data to copy */ + if (pFile->iCurrentSDS == 0) { /* global attribute */ + iRet = SDattrinfo (pFile->iSID, pFile->iAtt.iCurDir, + pName, &iPType, &iCount); + } else { + iRet = SDattrinfo (pFile->iCurrentSDS, pFile->iAtt.iCurDir, + pName, &iPType, &iCount); + } + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot read attribute info"); + return NX_ERROR; + } + *iLength = iCount; + *iType = iPType; + pFile->iAtt.iCurDir++; + return NX_OK; + } + + + /*-------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4getattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) + { + pNexusFile pFile; + int32 iNew, iType32; + void *pData = NULL; + int32 iLen, iRet; + int type; + char pBuffer[256]; + NXname pNam; + + type = *iType; + if (type == NX_CHAR) + { + type=DFNT_CHAR8; + } + else if (type == NX_INT8) + { + type=DFNT_INT8; + } + else if (type == NX_UINT8) + { + type=DFNT_UINT8; + } + else if (type == NX_INT16) + { + type=DFNT_INT16; + } + else if (type == NX_UINT16) + { + type=DFNT_UINT16; + } + else if (type == NX_INT32) + { + type=DFNT_INT32; + } + else if (type == NX_UINT32) + { + type=DFNT_UINT32; + } + else if (type == NX_FLOAT32) + { + type=DFNT_FLOAT32; + } + else if (type == NX_FLOAT64) + { + type=DFNT_FLOAT64; + } + *datalen = (*datalen) * DFKNTsize(type); + pFile = NXIassert (fid); + + /* find attribute */ + if (pFile->iCurrentSDS != 0) { + /* SDS attribute */ + iNew = SDfindattr (pFile->iCurrentSDS, name); + } else { + /* global attribute */ + iNew = SDfindattr (pFile->iSID, name); + } + if (iNew < 0) { + sprintf (pBuffer, "ERROR: attribute %s not found", name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + /* get more info, allocate temporary data space */ + iType32 = (int32)type; + if (pFile->iCurrentSDS != 0) { + iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, &iType32, &iLen); + } else { + iRet = SDattrinfo (pFile->iSID, iNew, pNam, &iType32, &iLen); + } + if (iRet < 0) { + sprintf (pBuffer, "ERROR: HDF could not read attribute info"); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + *iType = (int)iType32; + iLen = iLen * DFKNTsize (*iType); + pData = (void *) malloc (iLen); + if (!pData) { + NXIReportError (NXpData, "ERROR: allocating memory in NXgetattr"); + return NX_ERROR; + } + memset (pData, 0, iLen); + + /* finally read the data */ + if (pFile->iCurrentSDS != 0) { + iRet = SDreadattr (pFile->iCurrentSDS, iNew, pData); + } else { + iRet = SDreadattr (pFile->iSID, iNew, pData); + } + if (iRet < 0) { + sprintf (pBuffer, "ERROR: HDF could not read attribute data"); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + /* copy data to caller */ + memset (data, 0, *datalen); + if ((*datalen <= iLen) && (*iType == DFNT_UINT8 || *iType == DFNT_CHAR8 || *iType == DFNT_UCHAR8)) { + iLen = *datalen - 1; + } + memcpy (data, pData, iLen); + *datalen = iLen / DFKNTsize(*iType); + free (pData); + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4getattrinfo (NXhandle fid, int *iN) + { + pNexusFile pFile; + int iRet; + int32 iData, iAtt, iRank, iType; + int32 iDim[MAX_VAR_DIMS]; + NXname pNam; + + pFile = NXIassert (fid); + if (pFile->iCurrentSDS != 0) { /* SDS level */ + iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType, + &iAtt); + } else { /* global level */ + iRet = SDfileinfo (pFile->iSID, &iData, &iAtt); + } + if (iRet < 0) { + NXIReportError (NXpData, "NX_ERROR: HDF cannot read attribute numbers"); + *iN = 0; + return NX_ERROR; + } + *iN = iAtt; + return iRet; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX4getgroupID (NXhandle fileid, NXlink* sRes) + { + pNexusFile pFile; + + pFile = NXIassert (fileid); + + if (pFile->iCurrentVG == 0) { + sRes->iTag = NX_ERROR; + return NX_ERROR; + } else { + sRes->iTag = DFTAG_VG; + sRes->iRef = VQueryref(pFile->iCurrentVG); + return NX_OK; + } + /* not reached */ + sRes->iTag = NX_ERROR; + return NX_ERROR; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus + CALLING_STYLE NX4getgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) + { + pNexusFile pFile; + + pFile = NXIassert (fid); + /* check if there is a group open */ + if (pFile->iCurrentVG == 0) { + *iN = Vlone (pFile->iVID, NULL, 0); + strcpy (pName, "root"); + strcpy (pClass, "NXroot"); + } + else { + *iN = Vntagrefs (pFile->iCurrentVG); + Vgetname (pFile->iCurrentVG, pName); + Vgetclass (pFile->iCurrentVG, pClass); + } + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4initattrdir (NXhandle fid) + { + pNexusFile pFile; + int iRet; + + pFile = NXIassert (fid); + NXIKillAttDir (fid); + iRet = NXIInitAttDir (pFile); + if (iRet == NX_ERROR) + return NX_ERROR; + return NX_OK; + } + + + /*-------------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NX4initgroupdir (NXhandle fid) + { + pNexusFile pFile; + int iRet; + + pFile = NXIassert (fid); + NXIKillDir (fid); + iRet = NXIInitDir (pFile); + if (iRet < 0) { + NXIReportError (NXpData,"NX_ERROR: no memory to store directory info"); + return NX_EOD; + } + return NX_OK; + } + diff --git a/napi4.h b/napi4.h new file mode 100644 index 00000000..733544d4 --- /dev/null +++ b/napi4.h @@ -0,0 +1,43 @@ +#define NXSIGNATURE 959697 + +#include "napi4.c" + +/* + * HDF4 interface + */ + +NX_EXTERNAL NXstatus CALLING_STYLE NX4open(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle); +NX_EXTERNAL NXstatus CALLING_STYLE NX4close(NXhandle* pHandle); +NX_EXTERNAL NXstatus CALLING_STYLE NX4flush(NXhandle* pHandle); + +NX_EXTERNAL NXstatus CALLING_STYLE NX4makegroup (NXhandle handle, CONSTCHAR* Vgroup, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX4opengroup (NXhandle handle, CONSTCHAR* Vgroup, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX4closegroup(NXhandle handle); + +NX_EXTERNAL NXstatus CALLING_STYLE NX4makedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); +NX_EXTERNAL NXstatus CALLING_STYLE NX4compmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]); +NX_EXTERNAL NXstatus CALLING_STYLE NX4compress (NXhandle handle, int compr_type); +NX_EXTERNAL NXstatus CALLING_STYLE NX4opendata (NXhandle handle, CONSTCHAR* label); + +NX_EXTERNAL NXstatus CALLING_STYLE NX4closedata(NXhandle handle); + +NX_EXTERNAL NXstatus CALLING_STYLE NX4getdata(NXhandle handle, void* data); +NX_EXTERNAL NXstatus CALLING_STYLE NX4getslab(NXhandle handle, void* data, int start[], int size[]); +NX_EXTERNAL NXstatus CALLING_STYLE NX4getattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); + +NX_EXTERNAL NXstatus CALLING_STYLE NX4putdata(NXhandle handle, void* data); +NX_EXTERNAL NXstatus CALLING_STYLE NX4putslab(NXhandle handle, void* data, int start[], int size[]); +NX_EXTERNAL NXstatus CALLING_STYLE NX4putattr(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType); + +NX_EXTERNAL NXstatus CALLING_STYLE NX4getinfo(NXhandle handle, int* rank, int dimension[], int* datatype); +NX_EXTERNAL NXstatus CALLING_STYLE NX4getgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX4initgroupdir(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NX4getnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype); +NX_EXTERNAL NXstatus CALLING_STYLE NX4getattrinfo(NXhandle handle, int* no_items); +NX_EXTERNAL NXstatus CALLING_STYLE NX4initattrdir(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NX4getnextattr(NXhandle handle, NXname pName, int *iLength, int *iType); + +NX_EXTERNAL NXstatus CALLING_STYLE NX4getgroupID(NXhandle handle, NXlink* pLink); +NX_EXTERNAL NXstatus CALLING_STYLE NX4getdataID(NXhandle handle, NXlink* pLink); +NX_EXTERNAL NXstatus CALLING_STYLE NX4makelink(NXhandle handle, NXlink* pLink); + diff --git a/napi45.c b/napi45.c new file mode 100644 index 00000000..8061dd9e --- /dev/null +++ b/napi45.c @@ -0,0 +1,629 @@ +#include +#include +#include +#include +#include "napi.h" + + typedef struct { + NXhandle *pNexusData; + NXstatus (*nxclose)(NXhandle* pHandle); + NXstatus (*nxflush)(NXhandle* pHandle); + NXstatus (*nxmakegroup) (NXhandle handle, CONSTCHAR *name, char* NXclass); + NXstatus (*nxopengroup) (NXhandle handle, CONSTCHAR *name, char* NXclass); + NXstatus (*nxclosegroup)(NXhandle handle); + NXstatus (*nxmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); + NXstatus (*nxcompmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]); + NXstatus (*nxcompress) (NXhandle handle, int compr_type); + NXstatus (*nxopendata) (NXhandle handle, CONSTCHAR* label); + NXstatus (*nxclosedata)(NXhandle handle); + NXstatus (*nxputdata)(NXhandle handle, void* data); + NXstatus (*nxputattr)(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType); + NXstatus (*nxputslab)(NXhandle handle, void* data, int start[], int size[]); + NXstatus (*nxgetdataID)(NXhandle handle, NXlink* pLink); + NXstatus (*nxmakelink)(NXhandle handle, NXlink* pLink); + NXstatus (*nxgetdata)(NXhandle handle, void* data); + NXstatus (*nxgetinfo)(NXhandle handle, int* rank, int dimension[], int* datatype); + NXstatus (*nxgetnextentry)(NXhandle handle, NXname name, NXname nxclass, int* datatype); + NXstatus (*nxgetslab)(NXhandle handle, void* data, int start[], int size[]); + NXstatus (*nxgetnextattr)(NXhandle handle, NXname pName, int *iLength, int *iType); + NXstatus (*nxgetattr)(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); + NXstatus (*nxgetattrinfo)(NXhandle handle, int* no_items); + NXstatus (*nxgetgroupID)(NXhandle handle, NXlink* pLink); + NXstatus (*nxgetgroupinfo)(NXhandle handle, int* no_items, NXname name, NXname nxclass); + NXstatus (*nxinitgroupdir)(NXhandle handle); + NXstatus (*nxinitattrdir)(NXhandle handle); + } NexusFunction, *pNexusFunction; + + static int iFortifyScope; +/*------------------------------------------------------------------------ + HDF-5 cache size special stuff + -------------------------------------------------------------------------*/ +static long cacheSize = 1024000; /* 1MB, HDF-5 default */ + +NXstatus CALLING_STYLE NXsetcache(long newVal) +{ + if(newVal > 0) + { + cacheSize = newVal; + return NX_OK; + } + return NX_ERROR; +} + + + /*---------------------------------------------------------------------*/ + + static void NXNXNXReportError(void *pData, char *string) + { + printf("%s \n",string); + } + + /*---------------------------------------------------------------------*/ + + void *NXpData = NULL; + void (*NXIReportError)(void *pData, char *string) = NXNXNXReportError; + + /*---------------------------------------------------------------------*/ + + void CALLING_STYLE NXMSetError(void *pData, void (*NewError)(void *pD, char *text)) + { + NXpData = pData; + NXIReportError = NewError; + } + +#ifdef HDF5 +#include "napi5.h" +#endif +#ifdef HDF4 +#include "napi4.h" +#endif + + + /* ---------------------------------------------------------------------- + + Definition of NeXus API + + ---------------------------------------------------------------------*/ + + + NXstatus CALLING_STYLE NXopen(CONSTCHAR *filename, NXaccess am, NXhandle *gHandle) + { + int hdf_type=0; + int iRet=0; + NXhandle hdf5_handle; + NXhandle hdf4_handle; + pNexusFunction fHandle; + + /* configure fortify + iFortifyScope = Fortify_EnterScope(); + Fortify_CheckAllMemory(); + */ + + fHandle = (pNexusFunction)malloc(sizeof(NexusFunction)); + if (fHandle == NULL) { + NXIReportError (NXpData,"ERROR: no memory to create Function structure"); + return NX_ERROR; + } + if (am==NXACC_CREATE) { + /* HDF4 will be used ! */ + hdf_type=1; + } else if (am==NXACC_CREATE5) { + /* HDF5 will be used ! */ + hdf_type=2; + } else { + /* check file type hdf4/hdf5 for reading */ +#ifdef HDF5 + iRet=H5Fis_hdf5((const char*)filename); +#endif + if (iRet>0) { + hdf_type=2; + } else { +#ifdef HDF4 + iRet=Hishdf(filename); +#endif + if (iRet>0) { + hdf_type=1; + } + } + } + if (hdf_type==1) { + /* HDF4 type */ +#ifdef HDF4 + iRet = NX4open(filename,am,&hdf4_handle); + fHandle->pNexusData=hdf4_handle; + fHandle->nxclose=NX4close; + fHandle->nxflush=NX4flush; + fHandle->nxmakegroup=NX4makegroup; + fHandle->nxopengroup=NX4opengroup; + fHandle->nxclosegroup=NX4closegroup; + fHandle->nxmakedata=NX4makedata; + fHandle->nxcompmakedata=NX4compmakedata; + fHandle->nxcompress=NX4compress; + fHandle->nxopendata=NX4opendata; + fHandle->nxclosedata=NX4closedata; + fHandle->nxputdata=NX4putdata; + fHandle->nxputattr=NX4putattr; + fHandle->nxputslab=NX4putslab; + fHandle->nxgetdataID=NX4getdataID; + fHandle->nxmakelink=NX4makelink; + fHandle->nxgetdata=NX4getdata; + fHandle->nxgetinfo=NX4getinfo; + fHandle->nxgetnextentry=NX4getnextentry; + fHandle->nxgetslab=NX4getslab; + fHandle->nxgetnextattr=NX4getnextattr; + fHandle->nxgetattr=NX4getattr; + fHandle->nxgetattrinfo=NX4getattrinfo; + fHandle->nxgetgroupID=NX4getgroupID; + fHandle->nxgetgroupinfo=NX4getgroupinfo; + fHandle->nxinitgroupdir=NX4initgroupdir; + fHandle->nxinitattrdir=NX4initattrdir; +#endif + } else if (hdf_type==2) { + /* HDF5 type */ +#ifdef HDF5 + iRet = NX5open(filename,am,&hdf5_handle); + fHandle->pNexusData=hdf5_handle; + fHandle->nxclose=NX5close; + fHandle->nxflush=NX5flush; + fHandle->nxmakegroup=NX5makegroup; + fHandle->nxopengroup=NX5opengroup; + fHandle->nxclosegroup=NX5closegroup; + fHandle->nxmakedata=NX5makedata; + fHandle->nxcompmakedata=NX5compmakedata; + fHandle->nxcompress=NX5compress; + fHandle->nxopendata=NX5opendata; + fHandle->nxclosedata=NX5closedata; + fHandle->nxputdata=NX5putdata; + fHandle->nxputattr=NX5putattr; + fHandle->nxputslab=NX5putslab; + fHandle->nxgetdataID=NX5getdataID; + fHandle->nxmakelink=NX5makelink; + fHandle->nxgetdata=NX5getdata; + fHandle->nxgetinfo=NX5getinfo; + fHandle->nxgetnextentry=NX5getnextentry; + fHandle->nxgetslab=NX5getslab; + fHandle->nxgetnextattr=NX5getnextattr; + fHandle->nxgetattr=NX5getattr; + fHandle->nxgetattrinfo=NX5getattrinfo; + fHandle->nxgetgroupID=NX5getgroupID; + fHandle->nxgetgroupinfo=NX5getgroupinfo; + fHandle->nxinitgroupdir=NX5initgroupdir; + fHandle->nxinitattrdir=NX5initattrdir; +#endif + } else { + NXIReportError (NXpData,"ERROR: Format couldn't be handled!"); + *gHandle = NULL; + return NX_ERROR; + } + if(iRet == NX_OK) + { + *gHandle = fHandle; + return NX_OK; + } + else + { + free(fHandle); + return iRet; + } + } + +/* ------------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXclose (NXhandle *fid) + { + NXhandle hfil; + int status; + + pNexusFunction pFunc=NULL; + pFunc = (pNexusFunction)*fid; + hfil = pFunc->pNexusData; + status = pFunc->nxclose(&hfil); + pFunc->pNexusData = hfil; + free(pFunc); + /* + Fortify_CheckAllMemory(); + */ + return status; + } + + /*-----------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXmakegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxmakegroup(pFunc->pNexusData, name, nxclass); + } + + /*------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXopengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxopengroup(pFunc->pNexusData, name, nxclass); + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXclosegroup (NXhandle fid) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxclosegroup(pFunc->pNexusData); + } + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype, + int rank, int dimensions[]) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxmakedata(pFunc->pNexusData, name, datatype, rank, dimensions); + } + + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXcompmakedata (NXhandle fid, CONSTCHAR *name, int datatype, + int rank, int dimensions[],int compress_type, int chunk_size[]) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxcompmakedata (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size); + } + + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXcompress (NXhandle fid, int compress_type) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxcompress (pFunc->pNexusData, compress_type); + } + + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXopendata (NXhandle fid, CONSTCHAR *name) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxopendata(pFunc->pNexusData, name); + } + + + /* ----------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXclosedata (NXhandle fid) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxclosedata(pFunc->pNexusData); + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXputdata (NXhandle fid, void *data) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxputdata(pFunc->pNexusData, data); + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXputattr (NXhandle fid, CONSTCHAR *name, void *data, + int datalen, int iType) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxputattr(pFunc->pNexusData, name, data, datalen, iType); + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXputslab (NXhandle fid, void *data, int iStart[], int iSize[]) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxputslab(pFunc->pNexusData, data, iStart, iSize); + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXgetdataID (NXhandle fid, NXlink* sRes) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxgetdataID(pFunc->pNexusData, sRes); + } + + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NXmakelink (NXhandle fid, NXlink* sLink) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxmakelink(pFunc->pNexusData, sLink); + } + + + /*----------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXflush(NXhandle *pHandle) + { + NXhandle hfil; + int status; + + pNexusFunction pFunc=NULL; + pFunc = (pNexusFunction)*pHandle; + hfil = pFunc->pNexusData; + status = pFunc->nxflush(&hfil); + pFunc->pNexusData = hfil; + return status; + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXmalloc (void** data, int rank, int dimensions[], int datatype) + { + int i; + size_t size = 1; + *data = NULL; + for(i=0; inxgetnextentry(pFunc->pNexusData, name, nxclass, datatype); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetdata (NXhandle fid, void *data) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxgetdata(pFunc->pNexusData, data); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetinfo (NXhandle fid, int *rank, int dimension[], int *iType) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxgetinfo(pFunc->pNexusData, rank, dimension, iType); + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetslab (NXhandle fid, void *data, int iStart[], int iSize[]) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxgetslab(pFunc->pNexusData, data, iStart, iSize); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetnextattr (NXhandle fileid, NXname pName, + int *iLength, int *iType) + { + pNexusFunction pFunc = (pNexusFunction)fileid; + return pFunc->nxgetnextattr(pFunc->pNexusData, pName, iLength, iType); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxgetattr(pFunc->pNexusData, name, data, datalen, iType); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetattrinfo (NXhandle fid, int *iN) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxgetattrinfo(pFunc->pNexusData, iN); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetgroupID (NXhandle fileid, NXlink* sRes) + { + pNexusFunction pFunc = (pNexusFunction)fileid; + return pFunc->nxgetgroupID(pFunc->pNexusData, sRes); + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXgetgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxgetgroupinfo(pFunc->pNexusData, iN, pName, pClass); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXinitattrdir (NXhandle fid) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxinitattrdir(pFunc->pNexusData); + } + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXinitgroupdir (NXhandle fid) + { + pNexusFunction pFunc = (pNexusFunction)fid; + return pFunc->nxinitgroupdir(pFunc->pNexusData); + } +/*---------------------------------------------------------------------- + F77 - API - Support - Routines + ----------------------------------------------------------------------*/ + /* + * We store the whole of the NeXus file in the array - that way + * we can just pass the array name to C as it will be a valid + * NXhandle. We could store the NXhandle value in the FORTRAN array + * instead, but that would mean writing far more wrappers + */ + NXstatus CALLING_STYLE NXfopen(char * filename, NXaccess* am, + NexusFunction* pHandle) + { + NXstatus ret; + NXhandle fileid = NULL; + ret = NXopen(filename, *am, &fileid); + if (ret == NX_OK) + { + memcpy(pHandle, fileid, sizeof(NexusFunction)); + } + else + { + memset(pHandle, 0, sizeof(NexusFunction)); + } + if (fileid != NULL) + { + free(fileid); + } + return ret; + } +/* + * The pHandle from FORTRAN is a pointer to a static FORTRAN + * array holding the NexusFunction structure. We need to malloc() + * a temporary copy as NXclose will try to free() this + */ + NXstatus CALLING_STYLE NXfclose (NexusFunction* pHandle) + { + NXhandle h; + NXstatus ret; + h = (NXhandle)malloc(sizeof(NexusFunction)); + memcpy(h, pHandle, sizeof(NexusFunction)); + ret = NXclose(&h); /* does free(h) */ + memset(pHandle, 0, sizeof(NexusFunction)); + return ret; + } + +/*---------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXfflush(NexusFunction* pHandle) + { + NXhandle h; + NXstatus ret; + h = (NXhandle)malloc(sizeof(NexusFunction)); + memcpy(h, pHandle, sizeof(NexusFunction)); + ret = NXflush(&h); /* modifies and reallocates h */ + memcpy(pHandle, h, sizeof(NexusFunction)); + return ret; + } +/*----------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXfmakedata(NXhandle fid, char *name, int *pDatatype, + int *pRank, int dimensions[]) + { + NXstatus ret; + static char buffer[256]; + int i, *reversed_dimensions; + reversed_dimensions = (int*)malloc(*pRank * sizeof(int)); + if (reversed_dimensions == NULL) + { + sprintf (buffer, + "ERROR: Cannot allocate space for array rank of %d in NXfmakedata", + *pRank); + NXIReportError (NXpData, buffer); + return NX_ERROR; + } +/* + * Reverse dimensions array as FORTRAN is column major, C row major + */ + for(i=0; i < *pRank; i++) + { + reversed_dimensions[i] = dimensions[*pRank - i - 1]; + } + ret = NXmakedata(fid, name, *pDatatype, *pRank, reversed_dimensions); + free(reversed_dimensions); + return ret; + } + + + NXstatus CALLING_STYLE NXfcompmakedata(NXhandle fid, char *name, + int *pDatatype, + int *pRank, int dimensions[], + int *compression_type, int chunk[]) + { + NXstatus ret; + static char buffer[256]; + int i, *reversed_dimensions, *reversed_chunk; + reversed_dimensions = (int*)malloc(*pRank * sizeof(int)); + reversed_chunk = (int*)malloc(*pRank * sizeof(int)); + if (reversed_dimensions == NULL || reversed_chunk == NULL) + { + sprintf (buffer, + "ERROR: Cannot allocate space for array rank of %d in NXfcompmakedata", + *pRank); + NXIReportError (NXpData, buffer); + return NX_ERROR; + } +/* + * Reverse dimensions array as FORTRAN is column major, C row major + */ + for(i=0; i < *pRank; i++) + { + reversed_dimensions[i] = dimensions[*pRank - i - 1]; + reversed_chunk[i] = chunk[*pRank - i - 1]; + } + ret = NXcompmakedata(fid, name, *pDatatype, *pRank, + reversed_dimensions,*compression_type, reversed_chunk); + free(reversed_dimensions); + free(reversed_chunk); + return ret; + } +/*-----------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXfcompress(NXhandle fid, int *compr_type) + { + return NXcompress(fid,*compr_type); + } +/*-----------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXfputattr(NXhandle fid, char *name, void *data, + int *pDatalen, int *pIType) + { + return NXputattr(fid, name, data, *pDatalen, *pIType); + } diff --git a/napi5.c b/napi5.c new file mode 100644 index 00000000..85365191 --- /dev/null +++ b/napi5.c @@ -0,0 +1,1837 @@ +#include +#include +#include +#include + + typedef struct __NexusFile5 { + struct iStack5 { + int *iRefDir; + int *iTagDir; + char irefn[1024]; + int iVref; + } iStack5[NXMAXSTACK]; + struct iStack5 iAtt5; + int iVID; + int iFID; + int fapl; + int iCurrentG; + int iCurrentD; + int iCurrentS; + int iCurrentT; + int iCurrentIDX; + unsigned int iCurrentA_IDX; + int iCurrentA; + int iNX; + int iNXID; + int iStackPtr; + char *iCurrentLGG; + char *iCurrentLD; + char name_ref[1024]; + char name_tmp[1024]; + char iAccess[2]; + } NexusFile5, *pNexusFile5; + + + /*--------------------------------------------------------------------*/ + + static pNexusFile5 NXI5assert(NXhandle fid) + { + pNexusFile5 pRes; + + assert(fid != NULL); + pRes = (pNexusFile5)fid; + assert(pRes->iNXID == NX5SIGNATURE); + return pRes; + } + + /*--------------------------------------------------------------------*/ + + static void NXI5KillDir (pNexusFile5 self) + { + if (self->iStack5[self->iStackPtr].iRefDir) { + free (self->iStack5[self->iStackPtr].iRefDir); + self->iStack5[self->iStackPtr].iRefDir = NULL; + } + if (self->iStack5[self->iStackPtr].iTagDir) { + free (self->iStack5[self->iStackPtr].iTagDir); + self->iStack5[self->iStackPtr].iTagDir = NULL; + } + } + + /*--------------------------------------------------------------------*/ + + static void NXI5KillAttDir (pNexusFile5 self) + { + if (self->iAtt5.iRefDir) { + free (self->iAtt5.iRefDir); + self->iAtt5.iRefDir = NULL; + } + if (self->iAtt5.iTagDir) { + free (self->iAtt5.iTagDir); + self->iAtt5.iTagDir = NULL; + } + } + + /* ---------------------------------------------------------------------- + + Definition of NeXus API + + ---------------------------------------------------------------------*/ + + NXstatus NX5open(CONSTCHAR *filename, NXaccess am, NXhandle* pHandle) + { + hid_t attr1,aid1, aid2; + pNexusFile5 pNew = NULL; + char pBuffer[512], time_buffer[64]; + char version_nr[10]; + int iRet; + time_t timer; + struct tm *time_info; + const char* time_format; + long gmt_offset; + unsigned int vers_major, vers_minor, vers_release, am1 ; + int mdc_nelmts, rdcc_nelmts; + size_t rdcc_nbytes; + double rdcc_w0; + + /* turn off the automatic HDF error handling */ + + H5Eset_auto(NULL,NULL); + +#ifdef USE_FTIME + struct timeb timeb_struct; +#endif + + *pHandle = NULL; + + pNew = (pNexusFile5) malloc (sizeof (NexusFile5)); + if (!pNew) { + NXIReportError (NXpData,"ERROR: no memory to create File datastructure"); + return NX_ERROR; + } + memset (pNew, 0, sizeof (NexusFile5)); + +#ifdef NEED_TZSET + tzset(); +#endif + time(&timer); +#ifdef USE_FTIME + ftime(&timeb_struct); + gmt_offset = -timeb_struct.timezone * 60; + if (timeb_struct.dstflag != 0) + { + gmt_offset += 3600; + } +#else + time_info = gmtime(&timer); + if (time_info != NULL) + { + gmt_offset = difftime(timer, mktime(time_info)); + } + else + { + NXIReportError (NXpData, + "Your gmtime() function does not work ... timezone information will be incorrect\n"); + gmt_offset = 0; + } +#endif + time_info = localtime(&timer); + if (time_info != NULL) + { + if (gmt_offset < 0) + { + time_format = "%04d-%02d-%02d %02d:%02d:%02d-%02d%02d"; + } + else + { + time_format = "%04d-%02d-%02d %02d:%02d:%02d+%02d%02d"; + } + sprintf(time_buffer, time_format, + 1900 + time_info->tm_year, + 1 + time_info->tm_mon, + time_info->tm_mday, + time_info->tm_hour, + time_info->tm_min, + time_info->tm_sec, + abs(gmt_offset / 3600), + abs((gmt_offset % 3600) / 60) + ); + } + else + { + strcpy(time_buffer, "1970-01-01 00:00:00+0000"); + } + /* start HDF5 interface */ + if (am == NXACC_CREATE5) { + pNew->fapl = H5Pcreate(H5P_FILE_ACCESS); + iRet=H5Pget_cache(pNew->fapl,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0); + rdcc_nbytes=(size_t)cacheSize; + iRet = H5Pset_cache(pNew->fapl,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0); + am1 = H5F_ACC_TRUNC; + pNew->iFID = H5Fcreate (filename, am1, H5P_DEFAULT, pNew->fapl); + } else { + if (am == NXACC_READ) { + am1 = H5F_ACC_RDONLY; + } else { + am1 = H5F_ACC_RDWR; + } + pNew->iFID = H5Fopen (filename, am1, H5P_DEFAULT); + } + if (pNew->iFID <= 0) { + sprintf (pBuffer, "ERROR: cannot open file: %s", filename); + NXIReportError (NXpData, pBuffer); + free (pNew); + return NX_ERROR; + } + +/* + * need to create global attributes file_name file_time NeXus_version + * at some point for new files + */ + if (am1 != H5F_ACC_RDONLY) + { + pNew->iVID=H5Gopen(pNew->iFID,"/"); + aid2 = H5Screate(H5S_SCALAR); + aid1 = H5Tcopy(H5T_C_S1); + H5Tset_size(aid1, strlen(NEXUS_VERSION)); + if (am1 == H5F_ACC_RDWR) + { + H5Adelete(pNew->iVID, "NeXus_version"); + } + attr1= H5Acreate(pNew->iVID, "NeXus_version", aid1, aid2, H5P_DEFAULT); + if (attr1<0) + { + NXIReportError (NXpData, + "ERROR: HDF failed to store NeXus_version attribute "); + return NX_ERROR; + } + if (H5Awrite(attr1, aid1,NEXUS_VERSION)<0) + { + NXIReportError (NXpData, + "ERROR: HDF failed to store NeXus_version attribute "); + return NX_ERROR; + } + /* Close attribute dataspace */ + iRet = H5Tclose(aid1); + iRet = H5Sclose(aid2); + /* Close attribute */ + iRet = H5Aclose(attr1); + H5Gclose(pNew->iVID); + } + if (am1 == H5F_ACC_TRUNC) + { + pNew->iVID=H5Gopen(pNew->iFID,"/"); + aid2=H5Screate(H5S_SCALAR); + aid1 = H5Tcopy(H5T_C_S1); + H5Tset_size(aid1, strlen(filename)); + attr1= H5Acreate(pNew->iVID, "file_name", aid1, aid2, H5P_DEFAULT); + if (attr1 < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); + return NX_ERROR; + } + if (H5Awrite(attr1, aid1, (char*)filename) < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); + return NX_ERROR; + } + H5get_libversion(&vers_major, &vers_minor, &vers_release); + sprintf (version_nr, "%d.%d.%d", vers_major,vers_minor,vers_release); + aid2=H5Screate(H5S_SCALAR); + aid1 = H5Tcopy(H5T_C_S1); + H5Tset_size(aid1, strlen(version_nr)); + attr1= H5Acreate(pNew->iVID, "HDF5_Version", aid1, aid2, H5P_DEFAULT); + if (attr1 < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); + return NX_ERROR; + } + if (H5Awrite(attr1, aid1, (char*)version_nr) < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); + return NX_ERROR; + } + H5Tset_size(aid1, strlen(time_buffer)); + attr1=H5Acreate(pNew->iVID, "file_time", aid1, aid2, H5P_DEFAULT); + if (attr1 < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_time attribute "); + return NX_ERROR; + } + if (H5Awrite(attr1, aid1, time_buffer) < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_time attribute "); + return NX_ERROR; + } + /* Close attribute dataspace */ + iRet = H5Tclose(aid1); + iRet = H5Sclose(aid2); + /* Close attribute */ + iRet = H5Aclose(attr1); + H5Gclose(pNew->iVID); + } + /* Set HDFgroup access mode */ + if (am1 == H5F_ACC_RDONLY) { + strcpy(pNew->iAccess,"r"); + } else { + strcpy(pNew->iAccess,"w"); + } + pNew->iNXID = NX5SIGNATURE; + pNew->iStack5[0].iVref = 0; /* root! */ + *pHandle = (NXhandle)pNew; + return NX_OK; + } + + /* ------------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5close (NXhandle* fid) + { + pNexusFile5 pFile = NULL; + int iRet; + + pFile = NXI5assert(*fid); + if (pFile->fapl != NULL) { + iRet = H5Pclose(pFile->fapl); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot close plist."); + } + } + iRet = 0; + iRet = H5Fclose(pFile->iFID); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot close HDF file"); + } + /* release memory */ + NXI5KillDir (pFile); + free (pFile); + *fid = NULL; + iRet = 0; + iRet = H5close(); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot close HDF library"); + } + return NX_OK; + } + + /*-----------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5makegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + { + pNexusFile5 pFile; + hid_t iRet; + hid_t attr1,aid1, aid2; + char pBuffer[1024]; + + pFile = NXI5assert (fid); + /* create and configure the group */ + if (pFile->iCurrentG==0) + { + iRet = H5Gcreate(pFile->iFID,(const char*)name, 0); + } else + { + sprintf(pBuffer,"/%s/%s",pFile->name_ref,name); + iRet = H5Gcreate(pFile->iFID,(const char*)pBuffer, 0); + } + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF could not create Group"); + return NX_ERROR; + } + pFile->iVID = iRet; + strcpy(pFile->name_ref,pBuffer); + aid2 = H5Screate(H5S_SCALAR); + aid1 = H5Tcopy(H5T_C_S1); + H5Tset_size(aid1, strlen(nxclass)); + attr1= H5Acreate(pFile->iVID, "NX_class", aid1, aid2, H5P_DEFAULT); + if (attr1 < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store class name!"); + return NX_ERROR; + } + if (H5Awrite(attr1, aid1, (char*)nxclass) < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store class name!"); + return NX_ERROR; + } + /* close group */ + iRet=H5Sclose(aid2); + iRet=H5Tclose(aid1); + iRet=H5Aclose(attr1); + iRet=H5Gclose(pFile->iVID); + return NX_OK; + } + + /*------------------------------------------------------------------------*/ + + herr_t attr_check (hid_t loc_id, const char *member_name, void *opdata) + { + char attr_name[8]; + + strcpy(attr_name,"NX_class"); + return strstr(member_name, attr_name) ? 1 : 0; + } + + NXstatus CALLING_STYLE NX5opengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + { + + pNexusFile5 pFile; + hid_t iRet, attr1, atype; + char pBuffer[1024]; + char data[128]; + + pFile = NXI5assert (fid); + if (pFile->iCurrentG == 0) + { + iRet = H5Gopen (pFile->iFID, (const char *)name); + if (iRet < 0) { + sprintf (pBuffer, "ERROR: Group %s does not exist!", name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + pFile->iCurrentG = iRet; + /* check group attribute */ + iRet = H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR iterating thourgh group!"); + return NX_ERROR; + } else if (iRet == 1) { + /* group attribute was found */ + } else { + /* no group attribute available */ + NXIReportError (NXpData, "No group attribute available"); + return NX_ERROR; + } + /* check contains of group attribute */ + attr1 = H5Aopen_name(pFile->iCurrentG, "NX_class"); + atype=H5Tcopy(H5T_C_S1); + H5Tset_size(atype,128); + iRet = H5Aread(attr1, atype, data); + if (strcmp(data, nxclass) == 0) { + /* test OK */ + } else { + NXIReportError (NXpData, "Group class is not identical!"); + iRet = H5Tclose(atype); + iRet = H5Aclose(attr1); + return NX_ERROR; + } + iRet = H5Tclose(atype); + iRet = H5Aclose(attr1); + pFile->iStack5[pFile->iStackPtr].iVref=0; + strcpy(pFile->iStack5[pFile->iStackPtr].irefn,""); + strcpy(pFile->name_ref,name); + strcpy(pFile->name_tmp,name); + } else { + sprintf(pBuffer,"%s/%s",pFile->name_tmp,name); + iRet = H5Gopen (pFile->iFID,(const char *)pBuffer); + if (iRet < 0) { + sprintf (pBuffer, "ERROR: Group %s does not exist!", pFile->name_tmp); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + pFile->iCurrentG = iRet; + strcpy(pFile->name_tmp,pBuffer); + strcpy(pFile->name_ref,pBuffer); + /* check group attribute */ + iRet=H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR iterating thourgh group!"); + return NX_ERROR; + } else if (iRet == 1) { + /* group attribute was found */ + } else { + /* no group attribute available */ + NXIReportError (NXpData, "No group attribute available"); + return NX_ERROR; + } + /* check contains of group attribute */ + attr1 = H5Aopen_name(pFile->iCurrentG, "NX_class"); + atype=H5Tcopy(H5T_C_S1); + H5Tset_size(atype,128); + iRet = H5Aread(attr1, atype, data); + if (strcmp(data, nxclass) == 0) { + /* test OK */ + } else { + NXIReportError (NXpData, "Group class is not identical!"); + iRet = H5Tclose(atype); + iRet = H5Aclose(attr1); + return NX_ERROR; + } + iRet = H5Tclose(atype); + iRet = H5Aclose(attr1); + } + pFile->iStackPtr++; + pFile->iStack5[pFile->iStackPtr].iVref=pFile->iCurrentG; + strcpy(pFile->iStack5[pFile->iStackPtr].irefn,name); + pFile->iCurrentIDX=0; + pFile->iCurrentA_IDX=0; + pFile->iCurrentLGG = strdup(name); + NXI5KillDir (pFile); + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5closegroup (NXhandle fid) + { + pNexusFile5 pFile; + int i,ii; + char *uname = NULL; + char *u1name = NULL; + + pFile = NXI5assert (fid); + /* first catch the trivial case: we are at root and cannot get + deeper into a negative directory hierarchy (anti-directory) + */ + if (pFile->iCurrentG == 0) { + NXI5KillDir (pFile); + return NX_OK; + } else { + /* close the current group and decrement name_ref */ + H5Gclose (pFile->iCurrentG); + i = 0; + i = strlen(pFile->iStack5[pFile->iStackPtr].irefn); + ii = strlen(pFile->name_ref); + if (pFile->iStackPtr>1) { + ii=ii-i-1; + } else { + ii=ii-i; + } + if (ii>0) { + uname = strdup(pFile->name_ref); + u1name = (char*) malloc((ii+1)*sizeof(char)); + memset(u1name,0,ii); + for (i=0; iname_ref,u1name); + strcpy(pFile->name_tmp,u1name); + free(uname); + free(u1name); + } else { + strcpy(pFile->name_ref,""); + strcpy(pFile->name_tmp,""); + } + pFile->iStackPtr--; + if (pFile->iStackPtr>0) { + pFile->iCurrentG=pFile->iStack5[pFile->iStackPtr].iVref; + } else { + pFile->iCurrentG=0; + } + NXI5KillDir (pFile); + } + pFile->iCurrentIDX=0; + pFile->iCurrentA_IDX=0; + return NX_OK; + } + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5makedata (NXhandle fid, CONSTCHAR *name, int datatype, + int rank, int dimensions[]) + { + pNexusFile5 pFile; + int chunk_size[H5S_MAX_RANK]; + int i; + + pFile = NXI5assert (fid); + memset(chunk_size,0,H5S_MAX_RANK*sizeof(int)); + if (dimensions[0] == NX_UNLIMITED) + { + for (i = 0; i < H5S_MAX_RANK; i++) + { + chunk_size[i]= 1; + } + } + return NX5compmakedata (fid, name, datatype, rank, dimensions, NX_COMP_NONE, chunk_size); + + return NX_OK; + } + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5compmakedata (NXhandle fid, CONSTCHAR *name, int datatype, + int rank, int dimensions[],int compress_type, int chunk_size[]) + { + hid_t datatype1, dataspace, iNew, iRet; + hid_t type,cparms; + pNexusFile5 pFile; + char pBuffer[256]; + int i, byte_zahl; + hsize_t chunkdims[H5S_MAX_RANK]; + hsize_t mydim[H5S_MAX_RANK], mydim1[H5S_MAX_RANK]; + hsize_t size[2]; + hsize_t maxdims[1] = {H5S_UNLIMITED}; + + pFile = NXI5assert (fid); + + for (i = 0; i < rank; i++) + { + chunkdims[i]=chunk_size[i]; + } + if (datatype == NX_CHAR) + { + type=H5T_C_S1; + } + else if (datatype == NX_INT8) + { + type=H5T_NATIVE_CHAR; + } + else if (datatype == NX_UINT8) + { + type=H5T_NATIVE_UCHAR; + } + else if (datatype == NX_INT16) + { + type=H5T_NATIVE_SHORT; + } + else if (datatype == NX_UINT16) + { + type=H5T_NATIVE_USHORT; + } + else if (datatype == NX_INT32) + { + type=H5T_NATIVE_INT; + } + else if (datatype == NX_UINT32) + { + type=H5T_NATIVE_UINT; + } + else if (datatype == NX_FLOAT32) + { + type=H5T_NATIVE_FLOAT; + } + else if (datatype == NX_FLOAT64) + { + type=H5T_NATIVE_DOUBLE; + } + if (rank <= 0) { + sprintf (pBuffer, "ERROR: invalid rank specified %s", + name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + /* + Check dimensions for consistency. The first dimension may be 0 + thus denoting an unlimited dimension. + */ + for (i = 1; i < rank; i++) { + if (dimensions[i] <= 0) { + sprintf (pBuffer, + "ERROR: invalid dimension %d, value %d given for Dataset %s", + i, dimensions[i], name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + } + if (datatype == NX_CHAR) + { + byte_zahl=dimensions[0]; + dimensions[0]=rank; + for(i = 0; i < rank; i++) + { + mydim1[i] = dimensions[i]; + } + dataspace=H5Screate_simple(rank,mydim1,NULL); + } else { + if (dimensions[0] == NX_UNLIMITED) + { + mydim[0]=0; + dataspace=H5Screate_simple(rank, mydim, maxdims); + } else { + for(i = 0; i < rank; i++) + { + mydim[i] = dimensions[i]; + } + /* dataset creation */ + dataspace=H5Screate_simple(rank, mydim, NULL); + } + } + datatype1=H5Tcopy(type); + if (datatype == NX_CHAR) + { + H5Tset_size(datatype1, byte_zahl); + } + if(compress_type == NX_COMP_LZW) + { + cparms = H5Pcreate(H5P_DATASET_CREATE); + iNew = H5Pset_chunk(cparms,rank,chunkdims); + if (iNew < 0) { + NXIReportError (NXpData, "ERROR: Size of chuncks could not be set!"); + return NX_ERROR; + } + H5Pset_deflate(cparms,6); + iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, cparms); + } else if (compress_type == NX_COMP_NONE) { + if (dimensions[0] == NX_UNLIMITED) { + cparms = H5Pcreate(H5P_DATASET_CREATE); + iNew = H5Pset_chunk(cparms,rank,chunkdims); + if (iNew < 0) { + NXIReportError (NXpData, "ERROR: Size1 of chuncks could not be set!"); + return NX_ERROR; + } + iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, cparms); + } else { + iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT); + } + } else { + NXIReportError (NXpData, "HDF5 don't support selected compression method! Dataset was saved without compression"); + iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT); + } + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: Creating chuncked Dataset failed!"); + return NX_ERROR; + } else { + pFile->iCurrentD = iRet; + } + if (dimensions[0] == NX_UNLIMITED) + { + size[0] = 1; + size[1] = 1; + iNew = H5Dextend (pFile->iCurrentD, size); + if (iNew < 0) { + sprintf (pBuffer, "ERROR: cannot create Dataset %s, check arguments", + name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + } + iRet = H5Sclose(dataspace); + iRet = H5Tclose(datatype1); + iRet = H5Dclose(pFile->iCurrentD); + pFile->iCurrentD = 0; + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot close Dataset"); + return NX_ERROR; + } + return NX_OK; + } + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5compress (NXhandle fid, int compress_type) + { + printf(" NXcompress ERROR: NeXus API based on HDF5 don't supports\n"); + printf(" NXcompress function! Using HDF5 library\n"); + printf(" the NXcompmakedata function can be applied\n"); + printf(" for compression of data!\n"); + return NX_ERROR; + } + + /* --------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5opendata (NXhandle fid, CONSTCHAR *name) + { + pNexusFile5 pFile; + char pBuffer[256]; + + pFile = NXI5assert (fid); + /* clear pending attribute directories first */ + NXI5KillAttDir (pFile); + + + /* find the ID number and open the dataset */ + pFile->iCurrentD = H5Dopen(pFile->iCurrentG, name); + if (pFile->iCurrentD < 0) { + sprintf (pBuffer, "ERROR: Dataset %s not found at this level", name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + /* find the ID number of datatype */ + pFile->iCurrentT = H5Dget_type(pFile->iCurrentD); + if (pFile->iCurrentT < 0) { + NXIReportError (NXpData, "ERROR:HDF error opening Dataset"); + pFile->iCurrentT=0; + return NX_ERROR; + } + /* find the ID number of dataspace */ + pFile->iCurrentS = H5Dget_space(pFile->iCurrentD); + if (pFile->iCurrentS < 0) { + NXIReportError (NXpData, "ERROR:HDF error opening Dataset"); + pFile->iCurrentS=0; + return NX_ERROR; + } + pFile->iCurrentLD = strdup(name); + return NX_OK; + } + + /* ----------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5closedata (NXhandle fid) + { + pNexusFile5 pFile; + int iRet; + + pFile = NXI5assert (fid); + iRet = H5Sclose(pFile->iCurrentS); + iRet = H5Tclose(pFile->iCurrentT); + iRet = H5Dclose(pFile->iCurrentD); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: HDF cannot end access to Dataset"); + return NX_ERROR; + } + pFile->iCurrentD=0; + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5putdata (NXhandle fid, void *data) + { + pNexusFile5 pFile; + NXname pBuffer; + hid_t iRet, xfer_plist; + size_t size; + + char pError[512]; + + pFile = NXI5assert (fid); + + /* set buffer size to 16 MB */ + + xfer_plist = H5Pcreate(H5P_DATASET_XFER); + size = 16000000; + iRet = H5Pset_buffer(xfer_plist, size, NULL, NULL); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: Buffer size can not be set to 16 MB"); + return NX_ERROR; + } + + /* actually write */ + iRet = H5Dwrite (pFile->iCurrentD, pFile->iCurrentT, H5S_ALL, H5S_ALL, + xfer_plist, data); + H5Pclose(xfer_plist); + if (iRet < 0) { + sprintf (pError, "ERROR: failure to write data to %s", pBuffer); + NXIReportError (NXpData, pError); + return NX_ERROR; + } + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5putattr (NXhandle fid, CONSTCHAR *name, void *data, + int datalen, int iType) + { + pNexusFile5 pFile; + hid_t attr1, aid1, aid2; + hid_t type; + int iRet; + + pFile = NXI5assert (fid); + if (iType == NX_CHAR) + { + type=H5T_C_S1; + } + else if (iType == NX_INT8) + { + type=H5T_NATIVE_CHAR; + } + else if (iType == NX_UINT8) + { + type=H5T_NATIVE_UCHAR; + } + else if (iType == NX_INT16) + { + type=H5T_NATIVE_SHORT; + } + else if (iType == NX_UINT16) + { + type=H5T_NATIVE_USHORT; + } + else if (iType == NX_INT32) + { + type=H5T_NATIVE_INT; + } + else if (iType == NX_UINT32) + { + type=H5T_NATIVE_UINT; + } + else if (iType == NX_FLOAT32) + { + type=H5T_NATIVE_FLOAT; + } + else if (iType == NX_FLOAT64) + { + type=H5T_NATIVE_DOUBLE; + } + if (pFile->iCurrentD != 0) { + /* Dataset attribute */ + aid2=H5Screate(H5S_SCALAR); + aid1=H5Tcopy(type); + if (iType == NX_CHAR) + { + H5Tset_size(aid1,datalen); + } + iRet = H5Aopen_name(pFile->iCurrentD, name); + if (iRet>0) { + H5Aclose(iRet); + iRet=H5Adelete(pFile->iCurrentD,name); + if (iRet<0) { + NXIReportError (NXpData, "ERROR: Old attribute cannot removed! "); + return NX_ERROR; + } + } + attr1 = H5Acreate(pFile->iCurrentD, name, aid1, aid2, H5P_DEFAULT); + if (attr1 < 0) { + NXIReportError (NXpData, "ERROR: Attribute cannot created! "); + return NX_ERROR; + } + if (H5Awrite(attr1,aid1,data) < 0) + { + NXIReportError (NXpData, "ERROR: HDf failed to store attribute "); + return NX_ERROR; + } + /* Close attribute dataspace */ + iRet=H5Tclose(aid1); + iRet=H5Sclose(aid2); + /* Close attribute */ + iRet=H5Aclose(attr1); + } else { + /* global attribute */ + pFile->iVID=H5Gopen(pFile->iFID,"/"); + aid2=H5Screate(H5S_SCALAR); + aid1=H5Tcopy(type); + if (iType == NX_CHAR) + { + H5Tset_size(aid1,datalen); + } + iRet = H5Aopen_name(pFile->iVID, name); + if (iRet>0) { + H5Aclose(iRet); + iRet=H5Adelete(pFile->iVID,name); + if (iRet<0) { + NXIReportError (NXpData, "ERROR: Old attribute cannot removed! "); + return NX_ERROR; + } + } + attr1 = H5Acreate(pFile->iVID, name, aid1, aid2, H5P_DEFAULT); + if (attr1 < 0) { + NXIReportError (NXpData, "ERROR: Attribute cannot created! "); + return NX_ERROR; + } + if (H5Awrite(attr1,aid1,data) < 0) + { + NXIReportError (NXpData, "ERROR: HDf failed to store attribute "); + return NX_ERROR; + } + /* Close attribute dataspace */ + iRet=H5Tclose(aid1); + iRet=H5Sclose(aid2); + /* Close attribute */ + iRet=H5Aclose(attr1); + H5Gclose(pFile->iVID); + } + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5putslab (NXhandle fid, void *data, int iStart[], int iSize[]) + { + pNexusFile5 pFile; + int iRet, i; + int rank, size_id; + hssize_t myStart[H5S_MAX_RANK]; + hsize_t mySize[H5S_MAX_RANK]; + hsize_t size[1],maxdims[H5S_MAX_RANK]; + size_t buff_size; + hid_t filespace, dataspace, xfer_plist; + + pFile = NXI5assert (fid); + /* check if there is an Dataset open */ + if (pFile->iCurrentD == 0) { + NXIReportError (NXpData, "ERROR: no Dataset open"); + return NX_ERROR; + } + /* set buffer size to 16 MB */ + buff_size = 16000000; + + /* + size_id = H5Tget_size(pFile->iCurrentT); + buff_size = 1; + for(i = 0; i < rank;i++){ + buff_size *= iSize[i]; + } + buff_size *= size_id; + */ + + xfer_plist = H5Pcreate(H5P_DATASET_XFER); + iRet = H5Pset_buffer(xfer_plist, buff_size, NULL, NULL); + if (iRet < 0) { + NXIReportError (NXpData, "ERROR: Buffer size can not be set to 16 MB"); + return NX_ERROR; + } + + rank = H5Sget_simple_extent_ndims(pFile->iCurrentS); + for(i = 0; i < rank; i++) + { + myStart[i] = iStart[i]; + mySize[i] = iSize[i]; + } + iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, NULL, maxdims); + dataspace = H5Screate_simple (rank, mySize, NULL); + if (maxdims[0] == NX_UNLIMITED) + { + size[0]=iStart[0] + iSize[0]; + iRet = H5Dextend(pFile->iCurrentD, size); + filespace = H5Dget_space(pFile->iCurrentD); + + /* define slab */ + iRet = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, myStart, + NULL, mySize, NULL); + /* deal with HDF errors */ + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: selecting slab failed"); + return NX_ERROR; + } + /* write slab */ + iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, + filespace, xfer_plist, data); + iRet = H5Sclose(filespace); + } else { + /* define slab */ + iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, myStart, + NULL, mySize, NULL); + /* deal with HDF errors */ + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: selecting slab failed"); + return NX_ERROR; + } + /* write slab */ + iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, + pFile->iCurrentS, xfer_plist, data); + } + /* deal with HDF errors */ + H5Pclose(xfer_plist); + iRet = H5Sclose(dataspace); + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: writing slab failed"); + return NX_ERROR; + } + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5getdataID (NXhandle fid, NXlink* sRes) + { + pNexusFile5 pFile; + + pFile = NXI5assert (fid); + strcpy(sRes->iRef5,pFile->name_ref); + strcpy(sRes->iRefd,pFile->iCurrentLD); + return NX_OK; + } + + /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5makelink (NXhandle fid, NXlink* sLink) + { + pNexusFile5 pFile; + int iRet; + herr_t status; + int size_type; + + pFile = NXI5assert (fid); + if (pFile->iCurrentG == 0) { /* root level, can not link here */ + return NX_ERROR; + } + size_type = strlen(sLink->iRefd); + if (size_type > 0) + { + /* dataset link */ + strcpy(sLink->iTag5,pFile->name_ref); + } else { + /* group link */ + strcat(pFile->iCurrentLGG, sLink->iTag5); + strcpy(sLink->iTag5,"/"); + strcat(sLink->iTag5,pFile->iCurrentLGG); + } + if (size_type>0) + { + strcat(sLink->iRef5,"/"); + strcat(sLink->iRef5,sLink->iRefd); + } + if (size_type>0) + { + strcat(sLink->iTag5,"/"); + strcat(sLink->iTag5,sLink->iRefd); + } + status = H5Glink(pFile->iFID, H5G_LINK_HARD, sLink->iRef5, sLink->iTag5); + return NX_OK; + } + + /*----------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5flush(NXhandle *pHandle) + { + pNexusFile5 pFile = NULL; + int iRet; + + pFile = NXI5assert (*pHandle); + if (pFile->iCurrentD != 0) + { + iRet=H5Fflush(pFile->iCurrentD,H5F_SCOPE_LOCAL); + } + else if (pFile->iCurrentG != 0) + { + iRet=H5Fflush(pFile->iCurrentG,H5F_SCOPE_LOCAL); + } + else + { + iRet=H5Fflush(pFile->iFID,H5F_SCOPE_LOCAL); + } + if (iRet < 0){ + NXIReportError (NXpData, "ERROR: The object cannot be flushed"); + return NX_ERROR; + } + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + /* Operator function. */ + + herr_t nxgroup_info(hid_t loc_id, const char *name, void *op_data) + { + H5G_stat_t statbuf; + pinfo self; + + self = (pinfo)op_data; + H5Gget_objinfo(loc_id, name, 0, &statbuf); + switch (statbuf.type) + { + case H5G_GROUP: + self->iname = strdup(name); + self->type = H5G_GROUP; + break; + case H5G_DATASET: + self->iname = strdup(name); + self->type = H5G_DATASET; + break; + default: + self->type=0; + break; + } + return 1; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getnextentry (NXhandle fid,NXname name, NXname nxclass, int *datatype) + { + pNexusFile5 pFile; + hid_t grp, attr1,type,atype; + int iRet,iPtype, i; + int idx,data_id,size_id, sign_id; + char data[128]; + char ph_name[1024]; + info_type op_data; + + pFile = NXI5assert (fid); + op_data.iname = NULL; + idx=pFile->iCurrentIDX; + if (strlen(pFile->name_ref) == 0) { + /* root group */ + strcpy(pFile->name_ref,"/"); + } + iRet=H5Giterate(pFile->iFID,pFile->name_ref,&idx,nxgroup_info,&op_data); + strcpy(nxclass,""); + if (iRet > 0) + { + pFile->iCurrentIDX++; + strcpy(name,op_data.iname); + if (op_data.iname != NULL) { + free(op_data.iname); + } + if (op_data.type == H5G_GROUP) + { + strcpy(ph_name,""); + for(i = 1; i < (pFile->iStackPtr + 1); i++) + { + strcat(ph_name,pFile->iStack5[i].irefn); + strcat(ph_name,"/"); + } + strcat(ph_name,name); + grp=H5Gopen(pFile->iFID,ph_name); + attr1 = H5Aopen_name(grp, "NX_class"); + type=H5T_C_S1; + atype=H5Tcopy(type); + H5Tset_size(atype,128); + iRet = H5Aread(attr1, atype, data); + strcpy(nxclass,data); + H5Tclose(atype); + H5Gclose(grp); + } else if (op_data.type==H5G_DATASET) + { + grp=H5Dopen(pFile->iCurrentG,name); + type=H5Dget_type(grp); + atype=H5Tcopy(type); + data_id = H5Tget_class(atype); + if (data_id==H5T_STRING) + { + iPtype=NX_CHAR; + } + if (data_id==H5T_INTEGER) + { + size_id=H5Tget_size(atype); + sign_id=H5Tget_sign(atype); + if (size_id==1) + { + if (sign_id==H5T_SGN_2) + { + iPtype=NX_INT8; + } else { + iPtype=NX_UINT8; + } + } + else if (size_id==2) + { + if (sign_id==H5T_SGN_2) + { + iPtype=NX_INT16; + } else { + iPtype=NX_UINT16; + } + } + else if (size_id==4) + { + if (sign_id==H5T_SGN_2) + { + iPtype=NX_INT32; + } else { + iPtype=NX_UINT32; + } + } + } else if (data_id==H5T_FLOAT) + { + size_id=H5Tget_size(atype); + if (size_id==4) + { + iPtype=NX_FLOAT32; + } + else if (size_id==8) + { + iPtype=NX_FLOAT64; + } + } + *datatype=iPtype; + strcpy(nxclass, "SDS"); + H5Tclose(atype); + H5Dclose(grp); + } + return NX_OK; + } + else if (iRet==0) + { + if (op_data.iname != NULL) { + free(op_data.iname); + } + return NX_EOD; + } + else + { + if (op_data.iname != NULL) { + free(op_data.iname); + } + NXIReportError (NXpData, + "ERROR: Iteration was not successful"); + return NX_ERROR; + } + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getdata (NXhandle fid, void *data) + { + pNexusFile5 pFile; + int iStart[H5S_MAX_RANK]; + + pFile = NXI5assert (fid); + /* check if there is an Dataset open */ + if (pFile->iCurrentD == 0) + { + NXIReportError (NXpData, "ERROR: no Dataset open"); + return NX_ERROR; + } + memset (iStart, 0, H5S_MAX_RANK * sizeof(int)); + /* actually read */ + + H5Dread (pFile->iCurrentD, pFile->iCurrentT, H5S_ALL, H5S_ALL,H5P_DEFAULT, data); + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getinfo (NXhandle fid, int *rank, int dimension[], int *iType) + { + pNexusFile5 pFile; + int i, iRank, mType, iRet; + hsize_t myDim[H5S_MAX_RANK]; + hid_t data_id,size_id,sign_id; + + pFile = NXI5assert (fid); + /* check if there is an Dataset open */ + if (pFile->iCurrentD == 0) { + NXIReportError (NXpData, "ERROR: no Dataset open"); + return NX_ERROR; + } + + /* read information */ + data_id = H5Tget_class(pFile->iCurrentT); + if (data_id==H5T_STRING) + { + mType=NX_CHAR; + } + if (data_id==H5T_INTEGER) + { + size_id=H5Tget_size(pFile->iCurrentT); + sign_id=H5Tget_sign(pFile->iCurrentT); + if (size_id==1) + { + if (sign_id==H5T_SGN_2) + { + mType=NX_INT8; + } else { + mType=NX_UINT8; + } + } + else if (size_id==2) + { + if (sign_id==H5T_SGN_2) + { + mType=NX_INT16; + } else { + mType=NX_UINT16; + } + } + else if (size_id==4) + { + if (sign_id==H5T_SGN_2) + { + mType=NX_INT32; + } else { + mType=NX_UINT32; + } + } + } else if (data_id==H5T_FLOAT) + { + size_id=H5Tget_size(pFile->iCurrentT); + if (size_id==4) + { + mType=NX_FLOAT32; + } + else if (size_id==8) + { + mType=NX_FLOAT64; + } + } + iRank = H5Sget_simple_extent_ndims(pFile->iCurrentS); + iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, myDim, NULL); + /* conversion to proper ints for the platform */ + *iType = (int)mType; + if (data_id==H5T_STRING) { + for (i = 0; i < iRank; i++) + { + myDim[i] = H5Tget_size(pFile->iCurrentT); + } + } + *rank = (int)iRank; + for (i = 0; i < iRank; i++) + { + dimension[i] = (int)myDim[i]; + } + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getslab (NXhandle fid, void *data, int iStart[], int iSize[]) + { + pNexusFile5 pFile; + hssize_t myStart[H5S_MAX_RANK]; + hsize_t mySize[H5S_MAX_RANK]; + hssize_t mStart[H5S_MAX_RANK]; + hid_t memspace, iRet, data_id; + char *tmp_data; + char *data1; + int i, iRank, mtype = 0; + + pFile = NXI5assert (fid); + /* check if there is an Dataset open */ + if (pFile->iCurrentD == 0) + { + NXIReportError (NXpData, "ERROR: no Dataset open"); + return NX_ERROR; + } + iRank = H5Sget_simple_extent_ndims(pFile->iCurrentS); + for (i = 0; i < iRank; i++) + { + myStart[i] = (hssize_t)iStart[i]; + mySize[i] = (hsize_t)iSize[i]; + mStart[i] = (hsize_t)0; + } + data_id = H5Tget_class(pFile->iCurrentT); + if (data_id == H5T_STRING) { + mtype = NX_CHAR; + if (mySize[0] == 1) { + mySize[0] = H5Tget_size(pFile->iCurrentT); + } + tmp_data = (char*) malloc(mySize[0]); + memset(tmp_data,0,sizeof(mySize[0])); + iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, mStart, + NULL, mySize, NULL); + } else { + iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, myStart, + NULL, mySize, NULL); + } + /* define slab */ + /* deal with HDF errors */ + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: selecting slab failed"); + return NX_ERROR; + } + + memspace=H5Screate_simple(iRank, mySize, NULL); + iRet = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, mStart, + NULL, mySize, NULL); + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: Select memspace failed"); + return NX_ERROR; + } + + /* read slab */ + if (mtype == NX_CHAR) { + iRet = H5Dread(pFile->iCurrentD, pFile->iCurrentT, H5S_ALL, + H5S_ALL, H5P_DEFAULT,tmp_data); + data1 = tmp_data + myStart[0]; + strncpy(data,data1,(hsize_t)iSize[0]); + free(tmp_data); + } else { + iRet = H5Dread(pFile->iCurrentD, pFile->iCurrentT, memspace, + pFile->iCurrentS, H5P_DEFAULT,data); + } + + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: Reading slab failed"); + return NX_ERROR; + } + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + /* Operator function. */ + + herr_t attr_info(hid_t loc_id, const char *name, void *opdata) + { + *((char**)opdata)=strdup(name); + return 1; + } + + NXstatus CALLING_STYLE NX5getnextattr (NXhandle fileid, NXname pName, + int *iLength, int *iType) + { + pNexusFile5 pFile; + hid_t attr_id,size_id,sign_id; + hid_t iRet, atype, aspace; + int iPType,rank; + char *iname = NULL; + unsigned int idx; + + pFile = NXI5assert (fileid); + idx=pFile->iCurrentA_IDX; + if ((pFile->iCurrentD == 0) && (pFile->iCurrentG==0)) + { + /* global attribute */ + pFile->iVID=H5Gopen(pFile->iFID,"/"); + iRet=H5Aiterate(pFile->iVID,&idx,attr_info,&iname); + } else { + iRet=H5Aiterate(pFile->iCurrentD,&idx,attr_info,&iname); + } + if (iRet>0) + { + pFile->iCurrentA_IDX++; + strcpy(pName, iname); + if (iname != NULL) { + free(iname); + } + if ((pFile->iCurrentD == 0) && (pFile->iCurrentG==0)) { + /* global attribute */ + pFile->iCurrentA = H5Aopen_name(pFile->iVID, pName); + } else { + pFile->iCurrentA = H5Aopen_name(pFile->iCurrentD, pName); + } + atype = H5Aget_type(pFile->iCurrentA); + aspace = H5Aget_space(pFile->iCurrentA); + rank = H5Sget_simple_extent_ndims(aspace); + attr_id = H5Tget_class(atype); + if (attr_id==H5T_STRING) { + iPType=NX_CHAR; + rank = H5Tget_size(atype); + } + if (rank == 0) { + rank++; + } + if (attr_id==H5T_INTEGER) + { + size_id=H5Tget_size(atype); + sign_id=H5Tget_sign(atype); + if (size_id==1) + { + if (sign_id==H5T_SGN_2) + { + iPType=NX_INT8; + } else { + iPType=NX_UINT8; + } + } + else if (size_id==2) + { + if (sign_id==H5T_SGN_2) + { + iPType=NX_INT16; + } else { + iPType=NX_UINT16; + } + } + else if (size_id==4) + { + if (sign_id==H5T_SGN_2) + { + iPType=NX_INT32; + } else { + iPType=NX_UINT32; + } + } + } else if (attr_id==H5T_FLOAT) + { + size_id=H5Tget_size(atype); + if (size_id==4) + { + iPType=NX_FLOAT32; + } + else if (size_id==8) + { + iPType=NX_FLOAT64; + } + } + *iType=iPType; + *iLength=rank; + H5Tclose(atype); + H5Sclose(aspace); + H5Aclose(pFile->iCurrentA); + if ((pFile->iCurrentD == 0) && (pFile->iCurrentG==0)) + { + /* close group for global attribute */ + H5Gclose(pFile->iVID); + } + return NX_OK; + } + else if (iRet==0) + { + if (iname != NULL) { + free(iname); + } + if (idx == 0) + { + NXIReportError (NXpData, "Dataset has no attributes!"); + return NX_EOD; + } + + return NX_EOD; + } + else + { + if (iname != NULL) { + free(iname); + } + NXIReportError (NXpData, + "ERROR: Iteration was not successful"); + return NX_ERROR; + } + } + + + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) + { + pNexusFile5 pFile; + int iNew, iRet; + hid_t type, atype, glob; + char pBuffer[256]; + + pFile = NXI5assert (fid); + type = *iType; + glob = 0; + if (type == NX_CHAR) + { + type=H5T_C_S1; + } + else if (type == NX_INT8) + { + type=H5T_NATIVE_CHAR; + } + else if (type == NX_UINT8) + { + type=H5T_NATIVE_UCHAR; + } + else if (type == NX_INT16) + { + type=H5T_NATIVE_SHORT; + } + else if (type == NX_UINT16) + { + type=H5T_NATIVE_USHORT; + } + else if (type == NX_INT32) + { + type=H5T_NATIVE_INT; + } + else if (type == NX_UINT32) + { + type=H5T_NATIVE_UINT; + } + else if (type == NX_FLOAT32) + { + type=H5T_NATIVE_FLOAT; + } + else if (type == NX_FLOAT64) + { + type=H5T_NATIVE_DOUBLE; + } + /* find attribute */ + if (pFile->iCurrentD != 0) + { + /* Dataset attribute */ + iNew = H5Aopen_name(pFile->iCurrentD, name); + } + else + { + /* globale and group attributes */ + if (pFile->iCurrentG != 0) { + /* group attribute */ + iNew = H5Aopen_name(pFile->iCurrentG, name); + } else { + /* global attributes */ + glob=H5Gopen(pFile->iFID,"/"); + iNew = H5Aopen_name(glob, name); + } + } + if (iNew < 0) { + sprintf (pBuffer, "ERROR: attribute %s not found", name); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + pFile->iCurrentA = iNew; + /* finally read the data */ + if (type==H5T_C_S1) + { + atype=H5Tcopy(type); + H5Tset_size(atype,*datalen); + iRet = H5Aread(pFile->iCurrentA, atype, data); + *datalen=strlen(data); + } else { + iRet = H5Aread(pFile->iCurrentA, type, data); + *datalen=1; + } + + if (iRet < 0) { + sprintf (pBuffer, "ERROR: HDF could not read attribute data"); + NXIReportError (NXpData, pBuffer); + return NX_ERROR; + } + + iRet = H5Aclose(pFile->iCurrentA); + if (glob > 0) + { + H5Gclose(glob); + } + if (type==H5T_C_S1) + { + H5Tclose(atype); + } + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getattrinfo (NXhandle fid, int *iN) + { + pNexusFile5 pFile; + char *iname = NULL; + unsigned int idx; + int iRet; + + pFile = NXI5assert (fid); + idx=0; + if (pFile->iCurrentD == 0 && pFile->iCurrentG == 0) { + /* + global attribute + */ + pFile->iVID=H5Gopen(pFile->iFID,"/"); + iRet = H5Aiterate(pFile->iVID,&idx,attr_info,&iname); + iRet = 1; + while (iRet != 0) { + iRet = H5Aiterate(pFile->iVID,&idx,attr_info,&iname); + } + if (idx > 0) { + *iN = idx; + } else { + *iN = 1; + } + if (iname != NULL) { + free(iname); + } + return NX_OK; + } + else + { + iRet=H5Aiterate(pFile->iCurrentD,&idx,attr_info,&iname); + } + if (iRet<0) { + NXIReportError (NXpData, "Attribute number cannot be fixed!"); + return NX_ERROR; + } + if ((idx==0) && (iRet==0)) { + *iN=idx; + return NX_OK; + } + iRet = 1; + while (iRet != 0) { + iRet = H5Aiterate(pFile->iCurrentD,&idx,attr_info,&iname); + } + if (idx > 0) { + *iN = idx; + } else { + *iN = 1; + } + if (iname != NULL) { + free(iname); + } + return NX_OK; + + } + + /* --------------------------------------------------------------------- */ + + /* Operator function. */ + + herr_t group_info1(hid_t loc_id, const char *name, void *opdata) + { + NexusFile5 self; + H5G_stat_t statbuf; + self.iNX = *((int*)opdata); + H5Gget_objinfo(loc_id, name, 0, &statbuf); + + switch (statbuf.type) + { + case H5G_GROUP: + self.iNX++; + *((int*)opdata)=self.iNX; + break; + case H5G_DATASET: + self.iNX++; + *((int*)opdata)=self.iNX; + break; + } + return 0; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) + { + pNexusFile5 pFile; + hid_t atype,attr_id; + char data[64]; + int iRet; + + pFile = NXI5assert (fid); + /* check if there is a group open */ + if (pFile->iCurrentG == 0) { + strcpy (pName, "root"); + strcpy (pClass, "NXroot"); + pFile->iNX=0; + iRet=H5Giterate(pFile->iFID,"/",0,group_info1,&pFile->iNX); + *iN=pFile->iNX; + } + else { + strcpy (pName,pFile->name_ref); + attr_id = H5Aopen_name(pFile->iCurrentG,"NX_class"); + if (attr_id<0) { + strcpy(pClass,"non"); + } else { + atype=H5Tcopy(H5T_C_S1); + H5Tset_size(atype,64); + H5Aread(attr_id, atype, data); + strcpy(pClass,data); + pFile->iNX=0; + iRet=H5Giterate(pFile->iFID,pFile->name_ref,0,group_info1, &pFile->iNX); + *iN=pFile->iNX; + H5Aclose(attr_id); + } + } + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5getgroupID (NXhandle fileid, NXlink* sRes) + { + pNexusFile5 pFile; + int u; + char group_name[64], class_name[64]; + + pFile = NXI5assert (fileid); + if (pFile->iCurrentG == 0) { + return NX_ERROR; + } + else { + strcpy(sRes->iRef5,"/"); + NX5getgroupinfo(fileid, &u, group_name,class_name); + strcat(sRes->iRef5,group_name); + strcpy(sRes->iTag5,"/"); + strcat(sRes->iTag5, pFile->iCurrentLGG); + strcpy(sRes->iRefd,""); + return NX_OK; + } + /* not reached */ + return NX_ERROR; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5initattrdir (NXhandle fid) + { + pNexusFile5 pFile; + + pFile = NXI5assert (fid); + NXI5KillAttDir (fid); + pFile->iCurrentA_IDX=0; + return NX_OK; + } + + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NX5initgroupdir (NXhandle fid) + { + pNexusFile5 pFile; + + pFile = NXI5assert (fid); + NXI5KillDir (fid); + pFile->iCurrentIDX=0; + return NX_OK; + } diff --git a/napi5.h b/napi5.h new file mode 100644 index 00000000..69a39ea7 --- /dev/null +++ b/napi5.h @@ -0,0 +1,47 @@ +#define NX5SIGNATURE 959695 + +#include +#include "napi5.c" + +/* HDF5 interface */ + +NX_EXTERNAL NXstatus CALLING_STYLE NX5open(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle); +NX_EXTERNAL NXstatus CALLING_STYLE NX5close(NXhandle* pHandle); +NX_EXTERNAL NXstatus CALLING_STYLE NX5flush(NXhandle* pHandle); + +NX_EXTERNAL NXstatus CALLING_STYLE NX5makegroup (NXhandle handle, CONSTCHAR *name, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX5opengroup (NXhandle handle, CONSTCHAR *name, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX5closegroup(NXhandle handle); + +NX_EXTERNAL NXstatus CALLING_STYLE NX5makedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); +NX_EXTERNAL NXstatus CALLING_STYLE NX5compmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]); +NX_EXTERNAL NXstatus CALLING_STYLE NX5compress (NXhandle handle, int compr_type); +NX_EXTERNAL NXstatus CALLING_STYLE NX5opendata (NXhandle handle, CONSTCHAR* label); +NX_EXTERNAL NXstatus CALLING_STYLE NX5closedata(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NX5putdata(NXhandle handle, void* data); + +NX_EXTERNAL NXstatus CALLING_STYLE NX5putattr(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType); +NX_EXTERNAL NXstatus CALLING_STYLE NX5putslab(NXhandle handle, void* data, int start[], int size[]); + +NX_EXTERNAL NXstatus CALLING_STYLE NX5getdataID(NXhandle handle, NXlink* pLink); +NX_EXTERNAL NXstatus CALLING_STYLE NX5makelink(NXhandle handle, NXlink* pLink); + +NX_EXTERNAL NXstatus CALLING_STYLE NX5getdata(NXhandle handle, void* data); +NX_EXTERNAL NXstatus CALLING_STYLE NX5getinfo(NXhandle handle, int* rank, int dimension[], int* datatype); +NX_EXTERNAL NXstatus CALLING_STYLE NX5getnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype); + +NX_EXTERNAL NXstatus CALLING_STYLE NX5getslab(NXhandle handle, void* data, int start[], int size[]); +NX_EXTERNAL NXstatus CALLING_STYLE NX5getnextattr(NXhandle handle, NXname pName, int *iLength, int *iType); +NX_EXTERNAL NXstatus CALLING_STYLE NX5getattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); +NX_EXTERNAL NXstatus CALLING_STYLE NX5getattrinfo(NXhandle handle, int* no_items); +NX_EXTERNAL NXstatus CALLING_STYLE NX5getgroupID(NXhandle handle, NXlink* pLink); +NX_EXTERNAL NXstatus CALLING_STYLE NX5getgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass); + +NX_EXTERNAL NXstatus CALLING_STYLE NX5initgroupdir(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NX5initattrdir(NXhandle handle); + + +herr_t nxgroup_info(hid_t loc_id, const char *name, void *op_data); +herr_t attr_info(hid_t loc_id, const char *name, void *opdata); +herr_t group_info(hid_t loc_id, const char *name, void *opdata); + diff --git a/sansdict.dic b/sansdict.dic index cec0eeb4..e2e1ef5e 100644 --- a/sansdict.dic +++ b/sansdict.dic @@ -92,10 +92,10 @@ gummimon1 = /entry1,NXentry/SANS,NXinstrument/detector,NXdetector/SDS \ gummi_monitor1 -rank 1 -dim {$(timedim)} \ -attr {units,counts} gummimon2 = /entry1,NXentry/SANS,NXinstrument/detector,NXdetector/SDS \ - gummi_monitor1 -rank 1 -dim {$(timedim)} \ + gummi_monitor2 -rank 1 -dim {$(timedim)} \ -attr {units,counts} gummimon3 = /entry1,NXentry/SANS,NXinstrument/detector,NXdetector/SDS \ - gummi_monitor1 -rank 1 -dim {$(timedim)} \ + gummi_monitor3 -rank 1 -dim {$(timedim)} \ -attr {units,counts} #--------Sample san = /entry1,NXentry/sample,NXsample/SDS name -type DFNT_CHAR -rank 1 \ diff --git a/sicsstatus.tcl b/sicsstatus.tcl index e484f928..4246f616 100644 --- a/sicsstatus.tcl +++ b/sicsstatus.tcl @@ -78,7 +78,7 @@ det1zerox 128.000000 det1zerox setAccess 1 mono2theta 36.77 mono2theta setAccess 1 -monodescription unknownit crystal +monodescription unknownit crystal monodescription setAccess 1 # Motor om om sign 1.000000 @@ -176,7 +176,7 @@ twotheta SoftUpperLim 113.000000 twotheta Fixed -1.000000 twotheta InterruptMode 0.000000 twotheta AccessCode 2.000000 -lastscancommand cscan a4 10. .1 10 5 +lastscancommand cscan a4 10. .1 10 5 lastscancommand setAccess 2 sample_mur 0.000000 sample_mur setAccess 2 @@ -455,11 +455,11 @@ a1 SoftUpperLim 120.000000 a1 Fixed -1.000000 a1 InterruptMode 0.000000 a1 AccessCode 2.000000 -user Uwe Filges +user Uwe Filges user setAccess 2 -sample D20 30K SNP Okt 2001 GS +sample D20 30K SNP Okt 2001 GS sample setAccess 2 -title endtest called with 23.000000 :Driving: +title endtest called with 23.000000 :Driving: title setAccess 2 -starttime 2002-08-07 08:09:45 +starttime 2002-08-07 08:09:45 starttime setAccess 2 diff --git a/sinqhm/Makefile b/sinqhm/Makefile index ddb3e470..a3982373 100644 --- a/sinqhm/Makefile +++ b/sinqhm/Makefile @@ -14,7 +14,7 @@ FF = f90 CC = cc CFLAGS = -std -g -I. -I../hardsup -I$(PGPLOT_DIR) -I/data/koenneck/include BIN = ../bin -LFLAGS = -L../hardsup -L$PGPLOT_DIR +LFLAGS = -L../hardsup -L$PGPLOT_DIR -L/data/lnslib/lib #------------ for Linux ## FF = g77 ## CC = gcc diff --git a/sinqhm/SinqHM_srv_filler.c b/sinqhm/SinqHM_srv_filler.c index 71c92f6a..fbbbf46d 100755 --- a/sinqhm/SinqHM_srv_filler.c +++ b/sinqhm/SinqHM_srv_filler.c @@ -841,13 +841,13 @@ yPos = (yPos - 2048)/psdYFactor; - if(xPos < 0 || xPos > psdXSize) + if(xPos < 0 || xPos >= psdXSize) { printf("X position out of range: %d, alllowed 0 - %d\n", xPos, psdXSize); continue; } - if(yPos < 0 || yPos > psdYSize) + if(yPos < 0 || yPos >= psdYSize) { printf("Y position out of range: %d, alllowed 0 - %d\n", yPos, psdYSize); @@ -893,6 +893,11 @@ printf("Matched time stamp %d into bin %d\n", iTime,middl); } + if(middl >= Tof_edges[0]->n_bins){ + middl = Tof_edges[0]->n_bins-1; + printf("WARNING: Fixed bad time bin!\n"); + } + /* calculate histogram position to update */ @@ -959,12 +964,10 @@ counting at 1, and ANSI-C at 0 */ edNum = edData.ui2[1] - 1; - /* if(edNum < 0 || edNum >= MAX_PSD_ED){ - printf("Got invalid detector number %d\n",edNum); + printf("Got invalid single detector number %d\n",edNum); continue; } - */ /* Extract time stamp and match to the appropriate time bin. @@ -1005,6 +1008,11 @@ printf("Matched time stamp %d into bin %d\n", iTime,middl); } + if(middl >= Tof_edges[0]->n_bins){ + middl = Tof_edges[0]->n_bins-1; + printf("WARNING: Fixed bad time bin for single detector!\n"); + } + /* calculate histogram position to update */ diff --git a/sinqhm/SinqHM_srv_main.c b/sinqhm/SinqHM_srv_main.c index 722b6be8..63a6b3c9 100755 --- a/sinqhm/SinqHM_srv_main.c +++ b/sinqhm/SinqHM_srv_main.c @@ -151,7 +151,7 @@ Dbg_mask = 0; Dbg_lev0 = 0; - Dbg_lev1 = 1; + Dbg_lev1 = 0; Dbg_lev2 = 0; Dbg_lev3 = 0; Cfgn_done = 0; /* Force a configuration before we can do anything. */ @@ -272,10 +272,22 @@ printf ("%s: Instrument = \"%s\"\n", Tsk_name[0], "HRPT"); Lwl_hdr_daq_mask = LWL_HDR_SYNC0_MASK | LWL_HDR_SYNC2_MASK; Lwl_hdr_daq_soll = LWL_HDR_SYNC2_MASK; - }else if (strcmp (INST, "TRICS") == 0 || strcmp(INST,"AMOR") == 0) { + }else if (strcmp (INST, "TRICS") == 0) { printf ("%s: Instrument = \"%s\"\n", Tsk_name[0], "TriCS"); + /* Lwl_hdr_daq_mask = LWL_HDR_NRL_MASK | LWL_PSD_PWF; Lwl_hdr_daq_soll = 0; + */ + Lwl_hdr_daq_mask = 0x00f00000; + Lwl_hdr_daq_soll = 0x00e00000; + }else if (strcmp(INST,"AMOR") == 0) { + printf ("%s: Instrument = \"%s\"\n", Tsk_name[0], "TriCS"); + /* + Lwl_hdr_daq_mask = LWL_HDR_NRL_MASK | LWL_PSD_PWF; + Lwl_hdr_daq_soll = 0; + */ + Lwl_hdr_daq_mask = 0x00f00000; + Lwl_hdr_daq_soll = 0x00600000; }else if (strcmp (INST, "POLDI") == 0) { printf ("%s: Instrument = \"%s\"\n", Tsk_name[0], "POLDI"); Lwl_hdr_daq_mask = LWL_HDR_NRL_MASK; diff --git a/sinqhm/SinqHM_srv_routines.c b/sinqhm/SinqHM_srv_routines.c index 5f40307b..c62ddc0e 100755 --- a/sinqhm/SinqHM_srv_routines.c +++ b/sinqhm/SinqHM_srv_routines.c @@ -1721,7 +1721,7 @@ rply_status_setup_and_send (skt, reply, KER__BAD_CREATE, is, /* No */ "Filler creation failed"); printf ("\n%s -- creation of FILLER failed: %d.\n", - Tsk_name[index], status); + Tsk_name[index], is); free_HM_memory (NULL); Cfgn_done = 0; return ERROR; @@ -3447,7 +3447,7 @@ return -1; /* Yes. */ }else { /* No */ Filler_pid = created_pid; - tmo = 1000; /* Normally give FILLER 1000 ticks to .. + tmo = 10000; /* Normally give FILLER 1000 ticks to .. ** .. get going */ if (suspendMode != 0) { tmo = WAIT_FOREVER; /* But in debug mode, wait forever! */ diff --git a/sinqhmdriv.c b/sinqhmdriv.c index d60a641e..bd36ec15 100644 --- a/sinqhmdriv.c +++ b/sinqhmdriv.c @@ -235,6 +235,14 @@ pCon); SINQHMDefineBank(pInternal->pMaster,0,0,self->iDims[0], self->fTime,self->iTimeChan); break; + case eSANSTOF: + iMode = SQHM__TOF; + self->iLength = self->iDims[0]*self->iDims[1]; + self->iLength *= self->iTimeChan; + SINQHMDefineBank(pInternal->pMaster,0,0, + (self->iDims[0]*self->iDims[1]) + 3, + self->fTime,self->iTimeChan); + break; case eHStrobo: iMode = SQHM__HM_PSD | SQHM__STROBO; break; diff --git a/splitter.c b/splitter.c index 39a6adde..43060d39 100644 --- a/splitter.c +++ b/splitter.c @@ -362,7 +362,7 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType; else { strcat(buf,argv[i]); - strcat(buf," "); + /* strcat(buf," "); */ } } return 1; @@ -419,4 +419,4 @@ typedef enum _CharType {eSpace, eNum,eeText,eQuote} CharType; } #endif - \ No newline at end of file + diff --git a/sps.c b/sps.c index b95c4e16..2859a404 100644 --- a/sps.c +++ b/sps.c @@ -192,18 +192,11 @@ return -1; } - /* if in simulation mode, return a random number */ + /* if in simulation mode, return 1 */ if(self->iMode) { - if(SimRandom() >= 50.) - { *iSet = 1; - } - else - { - *iSet = 0; - } - return 1; + return 1; } /* send an R command down to the SPS */ diff --git a/ttest.tcl b/ttest.tcl index 237f7800..278977e0 100644 --- a/ttest.tcl +++ b/ttest.tcl @@ -81,3 +81,6 @@ MakeDrive Publish scan User Publish otUnknown User MakeRuenBuffer + +MakeRS232Controller marcel psxtemp 3004 +