From ac10723d74b560ae6a4654d4943438a295a93453 Mon Sep 17 00:00:00 2001
From: cvs
Date: Fri, 7 Feb 2003 15:20:19 +0000
Subject: [PATCH] - TDC histogram memory driver sort of working - New class for
scripting datafiles - SANS-II almost complete initialization file
---
Makefile | 2 +-
SCinter.h | 6 +
conman.c | 5 +-
doc/manager/nxscript.htm | 131 +++
ecb.c | 2 +-
ecbdriv.c | 12 +
histmem.c | 3 +
macro.c | 5 -
motor.c | 4 +-
motreg.c | 14 +-
napi.c | 2022 ++++++++++----------------------------
napi.h | 209 ++--
napi4.c | 52 +-
napi5.c | 351 ++++---
nxdict.c | 3 +-
nxscript.c | 716 ++++++++++++++
nxscript.h | 20 +
nxscript.w | 48 +
ofac.c | 3 +
sans.tcl | 1 +
sans2.dic | 139 +++
sans2.tcl | 599 +++++++++++
sans2com.tcl | 261 +++++
sicsstat.tcl | 37 +
tdchm.c | 31 +-
25 files changed, 2965 insertions(+), 1711 deletions(-)
create mode 100644 doc/manager/nxscript.htm
create mode 100644 nxscript.c
create mode 100644 nxscript.h
create mode 100644 nxscript.w
create mode 100644 sans2.dic
create mode 100644 sans2.tcl
create mode 100644 sans2com.tcl
diff --git a/Makefile b/Makefile
index 80e124c7..3b44d34c 100644
--- a/Makefile
+++ b/Makefile
@@ -59,7 +59,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o \
polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o \
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) ecb.o ecbdriv.o \
- ecbcounter.o hmdata.o tdchm.o
+ ecbcounter.o hmdata.o tdchm.o nxscript.o
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
COUNTEROBJ = countdriv.o simcter.o counter.o
diff --git a/SCinter.h b/SCinter.h
index e5ae3dce..34e96501 100644
--- a/SCinter.h
+++ b/SCinter.h
@@ -10,6 +10,7 @@
#ifndef SICSINTERPRETER
#define SICSINTERPRETER
#include "Scommon.h"
+#include
/* M.Z. */
#include "definealias.i"
@@ -141,5 +142,10 @@ typedef struct __SINTER
------------------------------------------------------------------------*/
void *FindDrivable(SicsInterp *pics, char *name);
+
+/*-----------------------------------------------------------------------
+ Get a copy of the Tcl interpreter
+ ------------------------------------------------------------------------*/
+Tcl_Interp *InterpGetTcl(SicsInterp *pSics);
#endif
diff --git a/conman.c b/conman.c
index 4e8a188b..a2a542b0 100644
--- a/conman.c
+++ b/conman.c
@@ -1276,9 +1276,8 @@ extern pServer pServ;
strtolower(argv[1]);
if(strcmp(argv[1],"list") == 0)
{
- sprintf(pBueffel,"OutCode = %s",pCode[pCon->iOutput]);
- SCWrite(pCon,pBueffel,eStatus);
- sprintf(pBueffel,"UserRights = %d",SCGetRights(pCon));
+ sprintf(pBueffel,"OutCode = %s\nUserRights = %d",
+ pCode[pCon->iOutput], SCGetRights(pCon));
SCWrite(pCon,pBueffel,eStatus);
return 1;
}
diff --git a/doc/manager/nxscript.htm b/doc/manager/nxscript.htm
new file mode 100644
index 00000000..91a99e7e
--- /dev/null
+++ b/doc/manager/nxscript.htm
@@ -0,0 +1,131 @@
+
+
+Scripting NeXus Files
+
+
+Scripting NeXus Files
+
+This section describes the scripting interface to NeXus
+files, called nxscript. Scripting the generation of NeXus files has
+the advantage that
+it can be customised very quickly to special needs. Moreover it might
+help to reduce the amount of instrument specific code required for an
+instrument. This scripting interface uses the NeXus dictionary API for
+the actual writing process. This has the following consequences:
+
+- The interface needs two filenames: the
+NeXus filename and the dictionary filename when opening files.
+
- Writing commands have the general form: alias object. This means
+that object is written to the NeXus file using the specified alias.
+
- Another property is that some writing commands write several bits
+of information in one go. In such cases the aliases for the additional
+bits are derived from the base alias by appending specific
+strings. Thus dictionary files need to have a special form for this
+scripting interface to work.
+
- Nxscript also tries to figure out the dimensions of
+multidimensional datasets such as histogram memories by itself. In
+such cases the dimension attribute in the dictionary file must be
+omitted.
+
- Nxscript assumes the following policy for data writing:
+irrespective of errors write everything you can. Thus this interface
+will complain bitterly and verbosely if something does not work, but
+never return an error.
+
+
+Usage
+
+Before this facility can be used nxscript has to be installed into the
+SICServer from the instrument configuration file. This is done through
+the command:
+
+- MakeNXScript ?name?
+
- This creates a NeXus scripting object. If the name is omitted, an
+object named nxscript is created. If a name is given, this name is
+used for the scripting object. Having scripting objects with different
+names is also the only possibility to have more then one NeXus file
+writing operation going at a given time.
+
+In the following sections it is assumed that an object nxscript
+had been configured into SICS.
+
+File Opening and Closing
+
+
+- nxscript create5 nexusFile dictFile
+
- Creates a new NeXus file based on HDF-5 with the name
+nexusFile. The dictionary file dictFile is used.
+
- nxscript create4 nexusFile dictFile
+
- Creates a new NeXus file based on HDF-4 with the name
+nexusFile. The dictionary file dictFile is used.
+
- nxscript reopen nexusFile dictFile
+
- Reopens an existing NeXus with the name
+nexusFile for modification or appending.
+The dictionary file dictFile is used.
+
- nxscript close
+
- Closes the current NeXus file. This command MUST be given at the
+end of each script in order to make sure that all data is written
+properly to disk.
+
+
+Writing Things
+
+
+- nxscript puttext alias bla bla bla ....
+
- Writes everything after alias as text data to the alias. The
+definition string for the alias should not contain a dimension
+description, this is automatically appended.
+
- nxscript putfloat alias value
+
- Writes a single floating point value to alias alias.
+
- nscript putmot aliasName motorName
+
- Writes the position of the motor motorName into the NeXus file as
+described by aliasName. Theposition is a zero point corrected position. If
+another alias aliasname_null exists in the dictionary, the zero
+point of the motor is also written to file.
+
- nxscript putcounter aliasBase counterName
+
- Writes counter data to a NeXus file. Data is taken from the single
+counter counterName. What is written depends on the aliases present in
+the dictionary file:
+
+- aliasBase_preset
+
- The preset value.
+
- aliasBase_mode
+
- The counter mode
+
- aliasBase_time
+
- The actual time counted, without breaks due to insufficient beam.
+
- aliasbase_00 ... aliasBase_09
+
- The monitor readings for monitors 0 to 9. Please note that 00
+would denote the normal counting tube at a scanning type of
+experiment.
+
+ - nxscript puthm hmAlias hmName ?start? ?length?
+
- Writes data from the histogram memory hmName to a NeXus file using
+the alias hmAlias. The definition string for the alias should not
+contain neither -rank nor -dim information as this will be appended by
+nxscript. If the optional parameters start and end are given, a
+subset of the data is written. It is the users responsability that the
+values requested make sense to the histogram memory. In the case of
+subset writing, the dimensions have to be specified in the definition
+string belonging to the alias. Nxscript sets a variable timedim in the
+dictionary though which contains the length of a time binning if
+appropriate. This is a special help for writing extra detectors at
+SANS and AMOR.
+
- nxscript puttimebinning aliasName hmName
+
- Writes the time binning at histogram memory hmName to file using
+the alias aliasName. The length of the time binning data is
+automatically appended to the definition string for the alias.
+
- nxscript putarray aliasName arrayName length
+
- Writes the Tcl array arrayName to file using the aliasName. The
+definiton string belonging to aliasName does not need to contain a
+-dim argument as this is set by this routine. The parameter length is
+the length of the array. Only rank 1 arrays are supported.
+
- nxsript putglobal attName bla bla bla
+
- This writes an global attribute attName. Everything after attName
+is concatenated to a string which then respresents the value of the
+attribute.
+
- nxscript makelink targetAlias victimAlias
+
- This creates a symbolic link for victimAlias in the group
+designated by targetAlias.
+
+
+
+
diff --git a/ecb.c b/ecb.c
index 4173d560..cc5ed1e5 100644
--- a/ecb.c
+++ b/ecb.c
@@ -344,7 +344,7 @@ int ECBAction(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon,pError,eError);
return 0;
}
- sprintf(pBuffer,"%x %x %x %x",
+ sprintf(pBuffer,"%d %d %d %d",
out.d, out.e, out.b, out.c);
SCWrite(pCon,pBuffer,eValue);
return 1;
diff --git a/ecbdriv.c b/ecbdriv.c
index 0d3c53ed..c1be5d8c 100644
--- a/ecbdriv.c
+++ b/ecbdriv.c
@@ -1177,3 +1177,15 @@ MotorDriver *CreateECBMotor(SConnection *pCon, int argc, char *argv[]){
self->errorCode = 0;
return (MotorDriver *)self;
}
+/*=======================================================================*/
+void KillECBMotor(void *pDriver){
+ int i;
+ pECBMotDriv self = (pECBMotDriv)pDriver;
+
+ for(i = 0; i < MAXPAR; i++){
+ if(self->driverPar[i].name != NULL){
+ free(self->driverPar[i].name);
+ }
+ }
+ free(self);
+}
diff --git a/histmem.c b/histmem.c
index 8d7bd5b5..5ccad538 100644
--- a/histmem.c
+++ b/histmem.c
@@ -10,6 +10,9 @@
added getzip: Mark Koennecke, October 2000
+ Refactored data handling into separater HMdata class.
+ Mark Koennecke, January 2003
+
Copyright:
Labor fuer Neutronenstreuung
diff --git a/macro.c b/macro.c
index bb1a9c3b..1119e05e 100644
--- a/macro.c
+++ b/macro.c
@@ -70,11 +70,6 @@
#include "servlog.h"
#define SICSERROR "005567SICS"
-
-/* in SCinter.c, but only used here */
-
-extern Tcl_Interp *InterpGetTcl(SicsInterp *pSics);
-
/*----------------------------------------------------------------------------
SICS Macro uses the Tcl "unknown" mechanism to access the Sics-objects.
The Tcl algorithm is to call a command called unknown when it cannot
diff --git a/motor.c b/motor.c
index f6a7ad6e..e1ea8f1f 100644
--- a/motor.c
+++ b/motor.c
@@ -57,6 +57,7 @@
#include "splitter.h"
#include "status.h"
#include "servlog.h"
+#include "ecbdriv.h"
/*-------------------------------------------------------------------------
some lokal defines
@@ -468,7 +469,7 @@ extern void KillPiPiezo(void *pData);
}
else if(strcmp(pM->drivername,"ECB") == 0)
{
- free(pM->pDriver);
+ KillECBMotor( (void *)pM->pDriver);
}
free(pM->drivername);
}
@@ -876,7 +877,6 @@ extern void KillPiPiezo(void *pData);
*/
extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray);
-extern MotorDriver *CreateECBMotor(SConnection *pCon, int argc, char *argv[]);
int MotorCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
diff --git a/motreg.c b/motreg.c
index c6c93214..348f833b 100644
--- a/motreg.c
+++ b/motreg.c
@@ -108,9 +108,11 @@ int StartRegMot(pMotReg self, SConnection *pCon, float fValue){
self->motorData,
pCon,
fValue);
+ /*
sprintf(pBueffel,"anticollision started %s to %f",self->motorName,
fValue);
SCWrite(pCon,pBueffel,eValue);
+ */
pDriv->SetValue = oldSet;
self->iActive = 1;
@@ -121,9 +123,13 @@ int CheckRegMot(pMotReg self, SConnection *pCon){
int stat;
assert(self);
- stat = self->originalCheckStatus(self->motorData,pCon);
- if(stat != HWBusy){
- self->iActive = 0;
+ if(self->iActive){
+ stat = self->originalCheckStatus(self->motorData,pCon);
+ if(stat != HWBusy){
+ self->iActive = 0;
+ }
+ } else {
+ return HWIdle;
}
- return stat;
}
+
diff --git a/napi.c b/napi.c
index 97310d98..e75f665c 100644
--- a/napi.c
+++ b/napi.c
@@ -19,331 +19,547 @@
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- Contact : Mark Koennecke
- Labor fuer Neutronenstreuung
- Paul Scherrer Institut
- CH-5232 Villigen-PSI
- Switzerland
-
- Przemek Klosowski
- NIST Center for Neutron Research
- 100 Bureau Drive, Stop 8562
- Gaithersburg, MD 20899-8562
- USA
-
For further information, see
----------------------------------------------------------------------------*/
-static const char* rscid = "$Id: napi.c,v 1.5 2001/10/25 13:58:00 cvs Exp $"; /* Revision interted by CVS */
+static const char* rscid = "$Id: napi.c,v 1.6 2003/02/07 15:20:20 cvs Exp $"; /* Revision interted by CVS */
#include
#include
#include
#include
-#include
#include "napi.h"
-#define NXMAXSTACK 50
-#define NXSIGNATURE 959697
-
- typedef struct __NexusFile {
- struct iStack {
- int32 *iRefDir;
- int32 *iTagDir;
- int32 iVref;
- int32 __iStack_pad; /* for 64 bit alignment */
- 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 void NXNXNXReportError(void *pData, char *string)
- {
-#if defined(_WIN32) && ( defined(_DLL) || defined(_HDFDLL_) ) && !defined(_CONSOLE) && !defined(JNEXUS)
/*
- * printf() output may get lost in Windows applications without a console ... this code
- * makes them appear in Dialog boxes. To use printf(), you would probably have to create
- * a console window with AllocConsole(), or get hold of "stdout" from the main program
- * and then use fprintf(main_program_stdout, ... ) rather then printf(...)
+ * We need to include CALLING_STYLE in the function pointer definition
+ * or else we get a type mismatch on Win32
*/
- MessageBeep(MB_ICONEXCLAMATION);
- MessageBox(NULL, string, "NeXus Error", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND);
-#else
- printf("%s \n",string);
-#endif /* _WIN32 */
- }
- /*---------------------------------------------------------------------*/
- 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;
- }
+ typedef struct {
+ NXhandle *pNexusData;
+ NXstatus (CALLING_STYLE *nxclose)(NXhandle* pHandle);
+ NXstatus (CALLING_STYLE *nxflush)(NXhandle* pHandle);
+ NXstatus (CALLING_STYLE *nxmakegroup) (NXhandle handle, CONSTCHAR *name, char* NXclass);
+ NXstatus (CALLING_STYLE *nxopengroup) (NXhandle handle, CONSTCHAR *name, char* NXclass);
+ NXstatus (CALLING_STYLE *nxclosegroup)(NXhandle handle);
+ NXstatus (CALLING_STYLE *nxmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]);
+ NXstatus (CALLING_STYLE *nxcompmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]);
+ NXstatus (CALLING_STYLE *nxcompress) (NXhandle handle, int compr_type);
+ NXstatus (CALLING_STYLE *nxopendata) (NXhandle handle, CONSTCHAR* label);
+ NXstatus (CALLING_STYLE *nxclosedata)(NXhandle handle);
+ NXstatus (CALLING_STYLE *nxputdata)(NXhandle handle, void* data);
+ NXstatus (CALLING_STYLE *nxputattr)(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType);
+ NXstatus (CALLING_STYLE *nxputslab)(NXhandle handle, void* data, int start[], int size[]);
+ NXstatus (CALLING_STYLE *nxgetdataID)(NXhandle handle, NXlink* pLink);
+ NXstatus (CALLING_STYLE *nxmakelink)(NXhandle handle, NXlink* pLink);
+ NXstatus (CALLING_STYLE *nxgetdata)(NXhandle handle, void* data);
+ NXstatus (CALLING_STYLE *nxgetinfo)(NXhandle handle, int* rank, int dimension[], int* datatype);
+ NXstatus (CALLING_STYLE *nxgetnextentry)(NXhandle handle, NXname name, NXname nxclass, int* datatype);
+ NXstatus (CALLING_STYLE *nxgetslab)(NXhandle handle, void* data, int start[], int size[]);
+ NXstatus (CALLING_STYLE *nxgetnextattr)(NXhandle handle, NXname pName, int *iLength, int *iType);
+ NXstatus (CALLING_STYLE *nxgetattr)(NXhandle handle, char* name, void* data, int* iDataLen, int* iType);
+ NXstatus (CALLING_STYLE *nxgetattrinfo)(NXhandle handle, int* no_items);
+ NXstatus (CALLING_STYLE *nxgetgroupID)(NXhandle handle, NXlink* pLink);
+ NXstatus (CALLING_STYLE *nxgetgroupinfo)(NXhandle handle, int* no_items, NXname name, NXname nxclass);
+ NXstatus (CALLING_STYLE *nxsameID)(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID);
+ NXstatus (CALLING_STYLE *nxinitgroupdir)(NXhandle handle);
+ NXstatus (CALLING_STYLE *nxinitattrdir)(NXhandle handle);
+ } NexusFunction, *pNexusFunction;
- /*--------------------------------------------------------------------*/
- static pNexusFile NXIassert(NXhandle fid)
- {
- pNexusFile pRes;
+ 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;
+ }
- assert(fid != NULL);
- pRes = (pNexusFile)fid;
- assert(pRes->iNXID == NXSIGNATURE);
- return pRes;
- }
+#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_CREATE4) {
+ /* 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((const char*)filename);
+#endif
+ if (iRet>0) {
+ hdf_type=1;
+ }
+ }
+ }
+ if (hdf_type==1) {
+ /* HDF4 type */
+#ifdef HDF4
+ NX4open((const char *)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->nxsameID=NX4sameID;
+ fHandle->nxinitgroupdir=NX4initgroupdir;
+ fHandle->nxinitattrdir=NX4initattrdir;
+#endif
+ *gHandle = fHandle;
+ return NX_OK;
+ } else if (hdf_type==2) {
+ /* HDF5 type */
+#ifdef HDF5
+ 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->nxsameID=NX5sameID;
+ fHandle->nxinitgroupdir=NX5initgroupdir;
+ fHandle->nxinitattrdir=NX5initattrdir;
+#endif
+ *gHandle = fHandle;
+ return NX_OK;
+ } else {
+ NXIReportError (NXpData,"ERROR: Format not readable by this NeXus library");
+ *gHandle = NULL;
+ return NX_ERROR;
+ }
+ }
+
+/* ------------------------------------------------------------------------- */
+
+ 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);
+ }
+
/*----------------------------------------------------------------------*/
- static int32
- NXIFindVgroup (pNexusFile pFile, char *name, char *nxclass)
+
+ NXstatus CALLING_STYLE NXflush(NXhandle *pHandle)
{
- 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;
+ NXhandle hfil;
+ int status;
+
+ pNexusFunction pFunc=NULL;
+ pFunc = (pNexusFunction)*pHandle;
+ hfil = pFunc->pNexusData;
+ status = pFunc->nxflush(&hfil);
+ pFunc->pNexusData = hfil;
+ return status;
}
+
+
+ /*-------------------------------------------------------------------------*/
- 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, &iD2, &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, &iD2, &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)
+ NXstatus CALLING_STYLE NXmalloc (void** data, int rank, int dimensions[], int datatype)
{
int i;
- int32 iTag, iRef;
- int iStackPtr, iCurDir;
-
-/*
- * 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;
+ size_t size = 1;
+ *data = NULL;
+ for(i=0; iiVID,
- 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;
+ else if ((datatype == NX_INT16) || (datatype == NX_UINT16)) {
+ size *= 2;
+ }
+ else if ((datatype == NX_INT32) || (datatype == NX_UINT32) || (datatype == NX_FLOAT32)) {
+ size *= 4;
+ }
+ else if (datatype == NX_FLOAT64) {
+ size *= 8;
}
+ else {
+ NXIReportError (NXpData, "ERROR: NXmalloc - unknown data type in array");
+ return NX_ERROR;
}
- self->iStack[iStackPtr].iCurDir = 0;
- return 1;
+ *data = (void*)malloc(size);
+ memset(*data,0,size);
+ return NX_OK;
+ }
+
+ /*-------------------------------------------------------------------------*/
+
+ NXstatus CALLING_STYLE NXfree (void** data)
+ {
+ if (data == NULL) {
+ NXIReportError (NXpData, "ERROR: passing NULL to NXfree");
+ return NX_ERROR;
+ }
+ if (*data == NULL) {
+ NXIReportError (NXpData,"ERROR: passing already freed pointer to NXfree");
+ return NX_ERROR;
+ }
+ free(*data);
+ *data = NULL;
+ return NX_OK;
+ }
+
+ /* --------------------------------------------------------------------- */
+
+
+ NXstatus CALLING_STYLE NXgetnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype)
+ {
+ pNexusFunction pFunc = (pNexusFunction)fid;
+ return pFunc->nxgetnextentry(pFunc->pNexusData, name, nxclass, datatype);
+ }
+
+
+ /*-------------------------------------------------------------------------*/
+
+ NXstatus CALLING_STYLE NXgetdata (NXhandle fid, void *data)
+ {
+ pNexusFunction pFunc = (pNexusFunction)fid;
+ return pFunc->nxgetdata(pFunc->pNexusData, data);
}
- static void
- NXIKillDir (pNexusFile self)
+
+ /*-------------------------------------------------------------------------*/
+
+ NXstatus CALLING_STYLE NXgetinfo (NXhandle fid, int *rank, int dimension[], int *iType)
{
- 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;
+ pNexusFunction pFunc = (pNexusFunction)fid;
+ return pFunc->nxgetinfo(pFunc->pNexusData, rank, dimension, iType);
}
/*-------------------------------------------------------------------------*/
- static int
- NXIInitAttDir (pNexusFile pFile)
+
+ NXstatus CALLING_STYLE NXgetslab (NXhandle fid, void *data, int iStart[], int iSize[])
{
- 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;
+ pNexusFunction pFunc = (pNexusFunction)fid;
+ return pFunc->nxgetslab(pFunc->pNexusData, data, iStart, iSize);
}
- static void
- NXIKillAttDir (pNexusFile self)
+
+ /*-------------------------------------------------------------------------*/
+
+ NXstatus CALLING_STYLE NXgetnextattr (NXhandle fileid, NXname pName,
+ int *iLength, int *iType)
{
- 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;
+ 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 NXsameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID)
+ {
+ pNexusFunction pFunc = (pNexusFunction)fileid;
+ return pFunc->nxsameID(pFunc->pNexusData, pFirstID, pSecondID);
+ }
+
+ /*-------------------------------------------------------------------------*/
+
+ 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, NexusFile* pHandle)
+ 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(NexusFile));
+ memcpy(pHandle, fileid, sizeof(NexusFunction));
}
else
{
- memset(pHandle, 0, sizeof(NexusFile));
+ memset(pHandle, 0, sizeof(NexusFunction));
}
if (fileid != NULL)
{
@@ -351,434 +567,34 @@ static const char* rscid = "$Id: napi.c,v 1.5 2001/10/25 13:58:00 cvs Exp $"; /*
}
return ret;
}
-
-/*
- * On Open VMS prior to version 7.0 timezone support wasn't complete and gmtime() always returned NULL
- */
-#if (defined(__VMS) && (__VMS_VER < 70000000))
-# define USE_FTIME /* use ftime() function */
-# include
-#endif /* __VMS && __VMS_VER < 70000000 */
-
-/* #define NEED_TZSET /* probably not needed now as we do not use the "timezone" external variable */
-
- NXstatus CALLING_STYLE NXopen(CONSTCHAR * filename, NXaccess am, NXhandle* pHandle)
- {
- pNexusFile pNew = NULL;
- char pBuffer[512], time_buffer[64];
- int iRet;
- int32 file_id, an_id, ann_id;
- 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;
- /* 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, am, 0)) == -1 )
- {
- sprintf (pBuffer, "ERROR: cannot open file: %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, am);
- if (pNew->iSID <= 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 (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;
- }
- }
- 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;
- }
-
- /* Set Vgroup access mode */
- if (am == NXACC_READ) {
- strcpy(pNew->iAccess,"r");
- } else {
- strcpy(pNew->iAccess,"w");
- }
-
- /* start Vgroup API */
- pNew->iVID = Hopen (filename, am, 100);
- if (pNew->iVID <= 0) {
- sprintf (pBuffer, "ERROR: cannot open file: %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;
- }
-
-
/*
* The pHandle from FORTRAN is a pointer to a static FORTRAN
- * array holding the NexusFile structure. We need to malloc()
+ * array holding the NexusFunction structure. We need to malloc()
* a temporary copy as NXclose will try to free() this
*/
- NXstatus CALLING_STYLE NXfclose (NexusFile* pHandle)
+ NXstatus CALLING_STYLE NXfclose (NexusFunction* pHandle)
{
NXhandle h;
NXstatus ret;
- h = (NXhandle)malloc(sizeof(NexusFile));
- memcpy(h, pHandle, sizeof(NexusFile));
+ h = (NXhandle)malloc(sizeof(NexusFunction));
+ memcpy(h, pHandle, sizeof(NexusFunction));
ret = NXclose(&h); /* does free(h) */
- memset(pHandle, 0, sizeof(NexusFile));
+ memset(pHandle, 0, sizeof(NexusFunction));
return ret;
}
-
- NXstatus CALLING_STYLE NXclose (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;
- }
-/*---------------------------------------------------------------------------
- For the same reasons as stated above we need a wrapper for the fortran
- version of NXFlush
- ---------------------------------------------------------------------------*/
- NXstatus CALLING_STYLE NXfflush(NexusFile* pHandle)
+/*---------------------------------------------------------------------*/
+ NXstatus CALLING_STYLE NXfflush(NexusFunction* pHandle)
{
NXhandle h;
NXstatus ret;
- h = (NXhandle)malloc(sizeof(NexusFile));
- memcpy(h, pHandle, sizeof(NexusFile));
+ h = (NXhandle)malloc(sizeof(NexusFunction));
+ memcpy(h, pHandle, sizeof(NexusFunction));
ret = NXflush(&h); /* modifies and reallocates h */
- memcpy(pHandle, h, sizeof(NexusFile));
+ memcpy(pHandle, h, sizeof(NexusFunction));
return ret;
}
-
/*----------------------------------------------------------------------*/
- NXstatus CALLING_STYLE NXflush(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 = NXclose(pHandle);
- if(iRet != NX_OK) {
- return iRet;
- }
-
- iRet = NXopen(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 NXmakegroup (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 NXopengroup (NXhandle fid, CONSTCHAR *name, char *nxclass)
- {
- pNexusFile pFile;
- int32 iNew, 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 NXclosegroup (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 NXfmakedata(NXhandle fid, char *name, int *pDatatype,
int *pRank, int dimensions[])
{
@@ -788,7 +604,9 @@ static const char* rscid = "$Id: napi.c,v 1.5 2001/10/25 13:58:00 cvs Exp $"; /*
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);
+ sprintf (buffer,
+ "ERROR: Cannot allocate space for array rank of %d in NXfmakedata",
+ *pRank);
NXIReportError (NXpData, buffer);
return NX_ERROR;
}
@@ -804,819 +622,47 @@ static const char* rscid = "$Id: napi.c,v 1.5 2001/10/25 13:58:00 cvs Exp $"; /*
return ret;
}
- NXstatus CALLING_STYLE NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank,
- int dimensions[])
+
+ NXstatus CALLING_STYLE NXfcompmakedata(NXhandle fid, char *name,
+ int *pDatatype,
+ int *pRank, int dimensions[],
+ int *compression_type, int chunk[])
{
- pNexusFile pFile;
- int32 iNew;
- char pBuffer[256];
- int i, iRet;
- int32 myDim[MAX_VAR_DIMS];
-
- pFile = NXIassert (fid);
-
-
- if ((iNew = NXIFindSDS (fid, name))>=0) {
- sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name);
- NXIReportError (NXpData, pBuffer);
- return NX_ERROR;
- }
-
-
- /* Do some argument checking */
- switch (datatype) {
- case DFNT_FLOAT32: break;
- case DFNT_FLOAT64: break;
- case DFNT_INT8: break;
- case DFNT_UINT8: break;
- case DFNT_CHAR8: break;
- case DFNT_UCHAR8: break;
- case DFNT_INT16: break;
- case DFNT_UINT16: break;
- case DFNT_INT32: break;
- case DFNT_UINT32: break;
- default:
- sprintf (pBuffer, "ERROR: unknown datatype specified for SDS %s",
- name);
- NXIReportError (NXpData, pBuffer);
- return NX_ERROR;
- }
-
- 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++)
+ 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)
{
- myDim[i] = (int32)dimensions[i];
+ sprintf (buffer,
+ "ERROR: Cannot allocate space for array rank of %d in NXfcompmakedata",
+ *pRank);
+ NXIReportError (NXpData, buffer);
+ return NX_ERROR;
}
-
-
- /* behave nicely, if there is still an SDS open */
- if (pFile->iCurrentSDS != 0) {
- SDendaccess (pFile->iCurrentSDS);
- pFile->iCurrentSDS = 0;
+/*
+ * 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];
}
-
- /* 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)datatype,
- (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;
+ ret = NXcompmakedata(fid, name, *pDatatype, *pRank,
+ reversed_dimensions,*compression_type, reversed_chunk);
+ free(reversed_dimensions);
+ free(reversed_chunk);
+ return ret;
}
-
-
- NXstatus CALLING_STYLE NXopendata (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 NXfcompress(NXhandle fid, int *compr_type)
{
return NXcompress(fid,*compr_type);
}
-
- NXstatus CALLING_STYLE NXcompress (NXhandle fid, int compress_type)
- {
- pNexusFile pFile;
- int32 iRank, iAtt, iType, iRet, i, e;
- int32 iSize[MAX_VAR_DIMS];
- NXname pBuffer;
- char pError[512];
- comp_info compstruct;
- char *str;
-
- 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 */
- 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_type, &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 NXclosedata (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 NXgetdata (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 NXgetslab (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 NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType)
- {
- pNexusFile pFile;
- int32 iNew, iType32;
- void *pData = NULL;
- int32 iLen, iRet;
- char pBuffer[256];
- NXname pNam;
-
- *datalen = (*datalen) * DFKNTsize(*iType);
- 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)*iType;
- if (pFile->iCurrentSDS != 0) {
- iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, &iType32, &iLen);
- } else {
- iRet = SDattrinfo (pFile->iSID, iNew, pNam, &iType32, &iLen);
- }
- *iType = (int)iType32;
- if (iRet < 0) {
- sprintf (pBuffer, "ERROR: HDF could not read attribute info");
- NXIReportError (NXpData, pBuffer);
- return NX_ERROR;
- }
- 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 NXputdata (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, e;
- char pError[512];
- char *str;
-
- 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 NXputslab (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 NXfputattr(NXhandle fid, char *name, void *data, int *pDatalen, int *pIType)
+/*-----------------------------------------------------------------------*/
+ NXstatus CALLING_STYLE NXfputattr(NXhandle fid, char *name, void *data,
+ int *pDatalen, int *pIType)
{
return NXputattr(fid, name, data, *pDatalen, *pIType);
}
-
- NXstatus
- CALLING_STYLE NXputattr (NXhandle fid, CONSTCHAR *name, void *data, int datalen, int iType)
- {
- pNexusFile pFile;
- int iRet;
-
- pFile = NXIassert (fid);
-
- if (pFile->iCurrentSDS != 0) {
- /* SDS attribute */
- iRet = SDsetattr (pFile->iCurrentSDS, (char*)name, (int32)iType,
- (int32)datalen, data);
- } else {
- /* global attribute */
- iRet = SDsetattr (pFile->iSID, (char*)name, (int32)iType,
- (int32)datalen, data);
-
- }
- if (iRet < 0) {
- NXIReportError (NXpData, "ERROR: HDf failed to store attribute ");
- return NX_ERROR;
- }
- return NX_OK;
- }
-
-
- NXstatus
- CALLING_STYLE NXgetinfo (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 NXgetgroupinfo (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 NXgetattrinfo (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 NXinitgroupdir (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;
- }
-
- /*-------------------------------------------------------------------------*/
- NXstatus
- CALLING_STYLE NXgetnextentry (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 NXinitattrdir (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 NXgetnextattr (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 NXgetgroupID (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 = pFile->iStack[pFile->iStackPtr].iVref;
- return NX_OK;
- }
- /* not reached */
- sRes->iTag = NX_ERROR;
- return NX_ERROR;
- }
-
-
- NXstatus
- CALLING_STYLE NXgetdataID (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 NXmakelink (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;
- }
- if(sLink->iTag == DFTAG_VG)
- {
- iVG = Vattach (pFile->iVID, sLink->iRef,pFile->iAccess);
- iRet = Vinsert(pFile->iCurrentVG,iVG);
- iRet = Vdetach(iVG);
- }
- else
- {
- Vaddtagref (pFile->iCurrentVG, sLink->iTag, sLink->iRef);
- }
- return NX_OK;
- }
-
-/* allocate space for an array of given dimensions and type */
- NXstatus CALLING_STYLE NXmalloc (void** data, int rank, int dimensions[], int datatype)
- {
- int i;
- size_t size = 1;
- *data = NULL;
- for(i=0; i
- Uwe Filges
- Labor fuer Neutronenstreuung
- Paul Scherrer Institut
- CH-5232 Villigen-PSI
- Switzerland
-
-
For further information, see
----------------------------------------------------------------------------*/
@@ -35,22 +27,30 @@
#define NEXUSAPI
/* NeXus HDF45 */
-#define NEXUS_VERSION "2.1.0." /* major.minor.patch */
+#define NEXUS_VERSION "2.0.0." /* major.minor.patch */
-#define CONSTCHAR char
+#define CONSTCHAR const char
-#define NX_EXTERNAL
+#if defined(_WIN32) && defined(_DLL)
+# ifdef NX45DLL_EXPORTS
+# define NX_EXTERNAL __declspec(dllexport)
+# else
+# define NX_EXTERNAL __declspec(dllimport)
+# endif
+#else
+# define NX_EXTERNAL
+#endif
-typedef void* NXhandle; /* really a pointer to a NexusFile structure */
+typedef void* NXhandle; /* really a pointer to a NexusFile structure */
typedef int NXstatus;
typedef char NXname[128];
-typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE5=4} NXaccess;
+typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE4=4, NXACC_CREATE5=5} NXaccess;
typedef struct {
- char *iname;
- int type;
- }info_type, *pinfo;
+ char *iname;
+ int type;
+ }info_type, *pinfo;
#define NX_OK 1
#define NX_ERROR 0
@@ -79,22 +79,19 @@ typedef struct {
NX_UINT32 32 bit unsigned integer
NX_CHAR 8 bit character
- This list is a edited version of the one found in the HDF header file
- htndefs.h. That source will always be the real reference, this is
- documented here for your convenience.
--------------------------------------------------------------------------*/
/* Map NeXus to HDF types */
#define NX_FLOAT32 5
#define NX_FLOAT64 6
-#define NX_INT8 20
+#define NX_INT8 20
#define NX_UINT8 21
-#define NX_INT16 22
+#define NX_INT16 22
#define NX_UINT16 23
#define NX_INT32 24
#define NX_UINT32 25
-#define NX_CHAR 4
+#define NX_CHAR 4
/* Map NeXus compression methods to HDF compression methods */
#define NX_COMP_NONE 100
@@ -107,6 +104,10 @@ typedef struct {
#include
#endif
+#ifdef HDF5
+#include
+#endif
+
typedef struct {
#ifdef HDF4
int32 iTag; /* HDF4 variable */
@@ -124,57 +125,138 @@ typedef struct {
#define NXMAXSTACK 50
-#define CONCAT(__a,__b) __a##__b /* token concatenation */
+#define CONCAT(__a,__b) __a##__b /* token concatenation */
-#define MANGLE(__arg) CONCAT(__arg,_)
+#if defined(__unix) || defined(__unix__) || defined (__VMS)
-#define CALLING_STYLE /* blank */
+# ifdef __VMS
+# define MANGLE(__arg) __arg
+# else
+# define MANGLE(__arg) CONCAT(__arg,_)
+# endif
-# define NXopen MANGLE(nxiopen)
-# define NXclose MANGLE(nxiclose)
-# define NXmakegroup MANGLE(nximakegroup)
-# define NXopengroup MANGLE(nxiopengroup)
-# define NXclosegroup MANGLE(nxiclosegroup)
-# define NXmakedata MANGLE(nximakedata)
-# define NXcompmakedata MANGLE(nxicompmakedata)
-# define NXcompress MANGLE(nxicompress)
-# define NXopendata MANGLE(nxiopendata)
-# define NXclosedata MANGLE(nxiclosedata)
-# define NXputdata MANGLE(nxiputdata)
-# define NXputslab MANGLE(nxiputslab)
-# define NXputattr MANGLE(nxiputattr)
-# define NXgetdataID MANGLE(nxigetdataid)
-# define NXmakelink MANGLE(nximakelink)
-# define NXmalloc MANGLE(nximalloc)
-# define NXfree MANGLE(nxifree)
+# define CALLING_STYLE /* blank */
+
+# define NXopen MANGLE(nxiopen)
+# define NXclose MANGLE(nxiclose)
+# define NXmakegroup MANGLE(nximakegroup)
+# define NXopengroup MANGLE(nxiopengroup)
+# define NXclosegroup MANGLE(nxiclosegroup)
+# define NXmakedata MANGLE(nximakedata)
+# define NXcompmakedata MANGLE(nxicompmakedata)
+# define NXcompress MANGLE(nxicompress)
+# define NXopendata MANGLE(nxiopendata)
+# define NXclosedata MANGLE(nxiclosedata)
+# define NXputdata MANGLE(nxiputdata)
+# define NXputslab MANGLE(nxiputslab)
+# define NXputattr MANGLE(nxiputattr)
+# define NXgetdataID MANGLE(nxigetdataid)
+# define NXmakelink MANGLE(nximakelink)
+# define NXmalloc MANGLE(nximalloc)
+# define NXfree MANGLE(nxifree)
# define NXflush MANGLE(nxiflush)
-# define NXgetinfo MANGLE(nxigetinfo)
-# define NXgetnextentry MANGLE(nxigetnextentry)
-# define NXgetdata MANGLE(nxigetdata)
+# define NXgetinfo MANGLE(nxigetinfo)
+# define NXgetnextentry MANGLE(nxigetnextentry)
+# define NXgetdata MANGLE(nxigetdata)
-# define NXgetslab MANGLE(nxigetslab)
-# define NXgetnextattr MANGLE(nxigetnextattr)
-# define NXgetattr MANGLE(nxigetattr)
-# define NXgetattrinfo MANGLE(nxigetattrinfo)
-# define NXgetgroupID MANGLE(nxigetgroupid)
-# define NXgetgroupinfo MANGLE(nxigetgroupinfo)
-# define NXinitgroupdir MANGLE(nxiinitgroupdir)
-# define NXinitattrdir MANGLE(nxiinitattrdir)
-# define NXsetcache MANGLE(nxisetcache)
+# define NXgetslab MANGLE(nxigetslab)
+# define NXgetnextattr MANGLE(nxigetnextattr)
+# define NXgetattr MANGLE(nxigetattr)
+# define NXgetattrinfo MANGLE(nxigetattrinfo)
+# define NXgetgroupID MANGLE(nxigetgroupid)
+# define NXgetgroupinfo MANGLE(nxigetgroupinfo)
+# define NXsameID MANGLE(nxisameid)
+# define NXinitgroupdir MANGLE(nxiinitgroupdir)
+# define NXinitattrdir MANGLE(nxiinitattrdir)
+# define NXsetcache MANGLE(nxisetcache)
/* FORTRAN helpers - for NeXus internal use only */
-# define NXfopen MANGLE(nxifopen)
-# define NXfclose MANGLE(nxifclose)
+# define NXfopen MANGLE(nxifopen)
+# define NXfclose MANGLE(nxifclose)
# define NXfflush MANGLE(nxifflush)
-# define NXfmakedata MANGLE(nxifmakedata)
-# define NXfcompmakedata MANGLE(nxifcompmakedata)
-# define NXfcompress MANGLE(nxifcompress)
-# define NXfputattr MANGLE(nxifputattr)
+# define NXfmakedata MANGLE(nxifmakedata)
+# define NXfcompmakedata MANGLE(nxifcompmakedata)
+# define NXfcompress MANGLE(nxifcompress)
+# define NXfputattr MANGLE(nxifputattr)
+
+#elif defined(_WIN32)
+/*
+ * START OF WINDOWS SPECIFIC CONFIGURATION
+ *
+ * Added by Freddie Akeroyd 9/8/2002
+ *
+ * Various PC calling conventions - you need only uncomment one of the following definitions of MANGLE()
+ * anlong with the appropriate CALLING_STYLE
+ * The choice arises because under Windows the default way FORTRAN calls FORTRAN is different
+ * from the dafault way C calls C, and so when you need to have FORTRAN calling C you must
+ * force them to use the same convention. Notice the use of "default way" above ... by choice
+ * of compiler options (or compiler vendor) you may actually have FORTRAN calling in the C way
+ * etc., so you might need to experiment with the options below until you get no "unresolved symbols"
+ *
+ * Choice 1: Should allow both FORTRAN and C NeXus interfaces to work in a "default" setup
+ * Choice 2: For when choice 1: gives problems and you only require the C interface
+ * Choice 3: An alternative to 1: which may allow both FORTRAN and C in a non-default setup
+ */
+# define MANGLE(__arg) __arg /* Choice 1 */
+# define CALLING_STYLE __stdcall /* Choice 1 */
+/* # define MANGLE(__arg) __arg /* Choice 2 */
+/* # define CALLING_STYLE /* Choice 2 */
+/* # define MANGLE(__arg) CONCAT(__arg,_) /* Choice 3 */
+/* # define CALLING_STYLE __stdcall /* Choice 3 */
+/*
+ * END OF WINDOWS SPECIFIC CONFIGURATION
+ */
+# define NXopen MANGLE(NXIOPEN)
+# define NXclose MANGLE(NXICLOSE)
+# define NXflush MANGLE(NXIFLUSH)
+# define NXmakegroup MANGLE(NXIMAKEGROUP)
+# define NXopengroup MANGLE(NXIOPENGROUP)
+# define NXclosegroup MANGLE(NXICLOSEGROUP)
+# define NXmakedata MANGLE(NXIMAKEDATA)
+# define NXcompress MANGLE(NXICOMPRESS)
+# define NXopendata MANGLE(NXIOPENDATA)
+# define NXclosedata MANGLE(NXICLOSEDATA)
+# define NXgetdata MANGLE(NXIGETDATA)
+# define NXgetslab MANGLE(NXIGETSLAB)
+# define NXgetattr MANGLE(NXIGETATTR)
+# define NXgetdim MANGLE(NXIGETDIM)
+# define NXputdata MANGLE(NXIPUTDATA)
+# define NXputslab MANGLE(NXIPUTSLAB)
+# define NXputattr MANGLE(NXIPUTATTR)
+# define NXputdim MANGLE(NXIPUTDIM)
+# define NXgetinfo MANGLE(NXIGETINFO)
+# define NXgetgroupinfo MANGLE(NXIGETGROUPINFO)
+# define NXsameID MANGLE(NXISAMEID)
+# define NXinitgroupdir MANGLE(NXIINITGROUPDIR)
+# define NXgetnextentry MANGLE(NXIGETNEXTENTRY)
+# define NXgetattrinfo MANGLE(NXIGETATTRINFO)
+# define NXinitattrdir MANGLE(NXIINITATTRDIR)
+# define NXgetnextattr MANGLE(NXIGETNEXTATTR)
+# define NXgetgroupID MANGLE(NXIGETGROUPID)
+# define NXgetdataID MANGLE(NXIGETDATAID)
+# define NXmakelink MANGLE(NXIMAKELINK)
+# define NXmalloc MANGLE(NXIMALLOC)
+# define NXfree MANGLE(NXIFREE)
+/* FORTRAN helpers - for NeXus internal use only */
+# define NXfopen MANGLE(NXIFOPEN)
+# define NXfclose MANGLE(NXIFCLOSE)
+# define NXfflush MANGLE(NXIFFLUSH)
+# define NXfmakedata MANGLE(NXIFMAKEDATA)
+# define NXfcompmakedata MANGLE(NXIFCOMPMAKEDATA)
+# define NXfcompress MANGLE(NXIFCOMPRESS)
+# define NXfputattr MANGLE(NXIFPUTATTR)
+#else
+# error Cannot compile - unknown operating system
+#endif
+
/*
* Standard interface
*/
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
NX_EXTERNAL NXstatus CALLING_STYLE NXopen(CONSTCHAR * filename, NXaccess access_method, NXhandle* pHandle);
NX_EXTERNAL NXstatus CALLING_STYLE NXclose(NXhandle* pHandle);
NX_EXTERNAL NXstatus CALLING_STYLE NXflush(NXhandle* pHandle);
@@ -206,6 +288,7 @@ NX_EXTERNAL NXstatus CALLING_STYLE NXgetattr(NXhandle handle, char* name, void*
NX_EXTERNAL NXstatus CALLING_STYLE NXgetattrinfo(NXhandle handle, int* no_items);
NX_EXTERNAL NXstatus CALLING_STYLE NXgetgroupID(NXhandle handle, NXlink* pLink);
NX_EXTERNAL NXstatus CALLING_STYLE NXgetgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass);
+NX_EXTERNAL NXstatus CALLING_STYLE NXsameID(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID);
NX_EXTERNAL NXstatus CALLING_STYLE NXinitgroupdir(NXhandle handle);
NX_EXTERNAL NXstatus CALLING_STYLE NXinitattrdir(NXhandle handle);
@@ -224,5 +307,9 @@ NX_EXTERNAL void CALLING_STYLE NXMSetError(void *pData, void (*ErrFunc)(void *p
*/
NX_EXTERNAL NXstatus CALLING_STYLE NXsetcache(long newVal);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
#endif /*NEXUSAPI*/
diff --git a/napi4.c b/napi4.c
index e4d3a64a..4da84b52 100644
--- a/napi4.c
+++ b/napi4.c
@@ -1,3 +1,27 @@
+/*---------------------------------------------------------------------------
+ NeXus - Neutron & X-ray Common Data Format
+
+ Application Program Interface (HDF4) Routines
+
+ Copyright (C) 1997-2002 Mark Koennecke, Przemek Klosowski
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ For further information, see
+
+----------------------------------------------------------------------------*/
#include
#include
#include
@@ -290,6 +314,8 @@
/* map Nexus NXaccess types to HDF4 types */
if (am == NXACC_CREATE) {
am1 = DFACC_CREATE;
+ } else if (am == NXACC_CREATE4) {
+ am1 = DFACC_CREATE;
} else if (am == NXACC_READ) {
am1 = DFACC_READ;
} else if (am == NXACC_RDWR) {
@@ -318,7 +344,7 @@
#else
time_info = gmtime(&timer);
if (time_info != NULL) {
- gmt_offset = difftime(timer, mktime(time_info));
+ gmt_offset = (long)difftime(timer, mktime(time_info));
} else {
NXIReportError(NXpData, "Your gmtime() function does not work ... timezone information will be incorrect\n");
gmt_offset = 0;
@@ -350,7 +376,7 @@
* write something that can be used by OLE
*/
- if (am == NXACC_CREATE) {
+ if (am == NXACC_CREATE || am == NXACC_CREATE4) {
if ( (file_id = Hopen(filename, am1, 0)) == -1 ) {
sprintf (pBuffer, "ERROR: cannot open file_a: %s", filename);
NXIReportError (NXpData, pBuffer);
@@ -395,7 +421,7 @@
return NX_ERROR;
}
}
- if (am == NXACC_CREATE) {
+ if (am == NXACC_CREATE || am == NXACC_CREATE4) {
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;
@@ -410,7 +436,7 @@
* Otherwise we try to create the file two times which makes HDF
* Throw up on us.
*/
- if (am == NXACC_CREATE) {
+ if (am == NXACC_CREATE || am == NXACC_CREATE4) {
am = NXACC_RDWR;
am1 = DFACC_RDWR;
}
@@ -424,7 +450,7 @@
/* start Vgroup API */
- pNew->iVID = Hopen (filename, am1, 100);
+ pNew->iVID = Hopen(filename, am1, 100);
if (pNew->iVID <= 0) {
sprintf (pBuffer, "ERROR: cannot open file_c: %s", filename);
NXIReportError (NXpData, pBuffer);
@@ -1644,7 +1670,7 @@
return NX_ERROR;
}
*iN = iAtt;
- return iRet;
+ return NX_OK;
}
/*-------------------------------------------------------------------------*/
@@ -1690,6 +1716,20 @@
return NX_OK;
}
+ /* ------------------------------------------------------------------- */
+
+ NXstatus CALLING_STYLE NX4sameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID)
+ {
+ pNexusFile pFile;
+
+ pFile = NXIassert (fileid);
+ if ((pFirstID->iTag == pSecondID->iTag) & (pFirstID->iRef == pSecondID->iRef)) {
+ return NX_OK;
+ } else {
+ return NX_ERROR;
+ }
+ }
+
/*-------------------------------------------------------------------------*/
diff --git a/napi5.c b/napi5.c
index 85365191..56144a42 100644
--- a/napi5.c
+++ b/napi5.c
@@ -1,3 +1,27 @@
+/*---------------------------------------------------------------------------
+ NeXus - Neutron & X-ray Common Data Format
+
+ Application Program Interface (HDF5) Routines
+
+ Copyright (C) 1997-2002 Mark Koennecke, Przemek Klosowski
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ For further information, see
+
+----------------------------------------------------------------------------*/
#include
#include
#include
@@ -9,17 +33,15 @@
int *iTagDir;
char irefn[1024];
int iVref;
+ int iCurrentIDX;
} 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;
@@ -56,6 +78,7 @@
free (self->iStack5[self->iStackPtr].iTagDir);
self->iStack5[self->iStackPtr].iTagDir = NULL;
}
+ self->iStack5[self->iStackPtr].iCurrentIDX = 0;
}
/*--------------------------------------------------------------------*/
@@ -70,6 +93,7 @@
free (self->iAtt5.iTagDir);
self->iAtt5.iTagDir = NULL;
}
+ self->iAtt5.iCurrentIDX = 0;
}
/* ----------------------------------------------------------------------
@@ -78,7 +102,7 @@
---------------------------------------------------------------------*/
- NXstatus NX5open(CONSTCHAR *filename, NXaccess am, NXhandle* pHandle)
+ NXstatus CALLING_STYLE NX5open(CONSTCHAR *filename, NXaccess am, NXhandle* pHandle)
{
hid_t attr1,aid1, aid2;
pNexusFile5 pNew = NULL;
@@ -90,6 +114,7 @@
const char* time_format;
long gmt_offset;
unsigned int vers_major, vers_minor, vers_release, am1 ;
+ hid_t fapl;
int mdc_nelmts, rdcc_nelmts;
size_t rdcc_nbytes;
double rdcc_w0;
@@ -126,7 +151,7 @@
time_info = gmtime(&timer);
if (time_info != NULL)
{
- gmt_offset = difftime(timer, mktime(time_info));
+ gmt_offset = (long)difftime(timer, mktime(time_info));
}
else
{
@@ -163,12 +188,12 @@
}
/* 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);
+ fapl = H5Pcreate(H5P_FILE_ACCESS);
+ iRet=H5Pget_cache(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);
+ iRet = H5Pset_cache(fapl,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0);
am1 = H5F_ACC_TRUNC;
- pNew->iFID = H5Fcreate (filename, am1, H5P_DEFAULT, pNew->fapl);
+ pNew->iFID = H5Fcreate (filename, am1, H5P_DEFAULT, fapl);
} else {
if (am == NXACC_READ) {
am1 = H5F_ACC_RDONLY;
@@ -289,14 +314,8 @@
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;
+ pFile=NXI5assert(*fid);
+ iRet=0;
iRet = H5Fclose(pFile->iFID);
if (iRet < 0) {
NXIReportError (NXpData, "ERROR: HDF cannot close HDF file");
@@ -305,11 +324,6 @@
NXI5KillDir (pFile);
free (pFile);
*fid = NULL;
- iRet = 0;
- iRet = H5close();
- if (iRet < 0) {
- NXIReportError (NXpData, "ERROR: HDF cannot close HDF library");
- }
return NX_OK;
}
@@ -364,7 +378,7 @@
herr_t attr_check (hid_t loc_id, const char *member_name, void *opdata)
{
- char attr_name[8];
+ char attr_name[8+1]; /* need to leave space for \0 as well */
strcpy(attr_name,"NX_class");
return strstr(member_name, attr_name) ? 1 : 0;
@@ -391,7 +405,7 @@
/* check group attribute */
iRet = H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL);
if (iRet < 0) {
- NXIReportError (NXpData, "ERROR iterating thourgh group!");
+ NXIReportError (NXpData, "ERROR iterating through group!");
return NX_ERROR;
} else if (iRet == 1) {
/* group attribute was found */
@@ -400,7 +414,7 @@
NXIReportError (NXpData, "No group attribute available");
return NX_ERROR;
}
- /* check contains of group attribute */
+ /* check contents of group attribute */
attr1 = H5Aopen_name(pFile->iCurrentG, "NX_class");
atype=H5Tcopy(H5T_C_S1);
H5Tset_size(atype,128);
@@ -433,7 +447,7 @@
/* check group attribute */
iRet=H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL);
if (iRet < 0) {
- NXIReportError (NXpData, "ERROR iterating thourgh group!");
+ NXIReportError (NXpData, "ERROR iterating through group!");
return NX_ERROR;
} else if (iRet == 1) {
/* group attribute was found */
@@ -461,8 +475,7 @@
pFile->iStackPtr++;
pFile->iStack5[pFile->iStackPtr].iVref=pFile->iCurrentG;
strcpy(pFile->iStack5[pFile->iStackPtr].irefn,name);
- pFile->iCurrentIDX=0;
- pFile->iCurrentA_IDX=0;
+ pFile->iAtt5.iCurrentIDX=0;
pFile->iCurrentLGG = strdup(name);
NXI5KillDir (pFile);
return NX_OK;
@@ -502,7 +515,7 @@
for (i=0; iname_ref,"");
strcpy(pFile->name_tmp,"");
}
+ NXI5KillDir (pFile);
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,
@@ -659,7 +647,7 @@
cparms = H5Pcreate(H5P_DATASET_CREATE);
iNew = H5Pset_chunk(cparms,rank,chunkdims);
if (iNew < 0) {
- NXIReportError (NXpData, "ERROR: Size of chuncks could not be set!");
+ NXIReportError (NXpData, "ERROR: Size of chunks could not be set!");
return NX_ERROR;
}
H5Pset_deflate(cparms,6);
@@ -669,7 +657,7 @@
cparms = H5Pcreate(H5P_DATASET_CREATE);
iNew = H5Pset_chunk(cparms,rank,chunkdims);
if (iNew < 0) {
- NXIReportError (NXpData, "ERROR: Size1 of chuncks could not be set!");
+ NXIReportError (NXpData, "ERROR: Size of chunks could not be set!");
return NX_ERROR;
}
iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, cparms);
@@ -677,11 +665,11 @@
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");
+ NXIReportError (NXpData, "HDF5 doesn'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!");
+ NXIReportError (NXpData, "ERROR: Creating chunked dataset failed!");
return NX_ERROR;
} else {
pFile->iCurrentD = iRet;
@@ -709,12 +697,37 @@
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 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(" NXcompress ERROR: NeXus API based on HDF5 doesn't support\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;
@@ -782,27 +795,15 @@
{
pNexusFile5 pFile;
NXname pBuffer;
- hid_t iRet, xfer_plist;
- size_t size;
+ hid_t iRet;
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);
+ H5P_DEFAULT, data);
if (iRet < 0) {
sprintf (pError, "ERROR: failure to write data to %s", pBuffer);
NXIReportError (NXpData, pError);
@@ -882,7 +883,7 @@
}
if (H5Awrite(attr1,aid1,data) < 0)
{
- NXIReportError (NXpData, "ERROR: HDf failed to store attribute ");
+ NXIReportError (NXpData, "ERROR: HDF failed to store attribute ");
return NX_ERROR;
}
/* Close attribute dataspace */
@@ -934,38 +935,18 @@
{
pNexusFile5 pFile;
int iRet, i;
- int rank, size_id;
+ int rank;
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;
+ hid_t filespace,dataspace;
pFile = NXI5assert (fid);
/* check if there is an Dataset open */
if (pFile->iCurrentD == 0) {
- NXIReportError (NXpData, "ERROR: no Dataset open");
+ 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++)
{
@@ -991,7 +972,7 @@
}
/* write slab */
iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace,
- filespace, xfer_plist, data);
+ filespace, H5P_DEFAULT,data);
iRet = H5Sclose(filespace);
} else {
/* define slab */
@@ -1005,10 +986,9 @@
}
/* write slab */
iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace,
- pFile->iCurrentS, xfer_plist, data);
+ pFile->iCurrentS, H5P_DEFAULT,data);
}
/* deal with HDF errors */
- H5Pclose(xfer_plist);
iRet = H5Sclose(dataspace);
if (iRet < 0)
{
@@ -1035,7 +1015,7 @@
NXstatus CALLING_STYLE NX5makelink (NXhandle fid, NXlink* sLink)
{
pNexusFile5 pFile;
- int iRet;
+/* int iRet; */
herr_t status;
int size_type;
@@ -1137,7 +1117,7 @@
pFile = NXI5assert (fid);
op_data.iname = NULL;
- idx=pFile->iCurrentIDX;
+ idx=pFile->iStack5[pFile->iStackPtr].iCurrentIDX;
if (strlen(pFile->name_ref) == 0) {
/* root group */
strcpy(pFile->name_ref,"/");
@@ -1146,7 +1126,7 @@
strcpy(nxclass,"");
if (iRet > 0)
{
- pFile->iCurrentIDX++;
+ pFile->iStack5[pFile->iStackPtr].iCurrentIDX++;
strcpy(name,op_data.iname);
if (op_data.iname != NULL) {
free(op_data.iname);
@@ -1233,7 +1213,8 @@
{
if (op_data.iname != NULL) {
free(op_data.iname);
- }
+ }
+ pFile->iStack5[pFile->iStackPtr].iCurrentIDX = 0;
return NX_EOD;
}
else
@@ -1253,18 +1234,69 @@
{
pNexusFile5 pFile;
int iStart[H5S_MAX_RANK];
-
+ hid_t data_id, memtype_id, size_id, sign_id;
+ int dims;
+
pFile = NXI5assert (fid);
/* check if there is an Dataset open */
if (pFile->iCurrentD == 0)
- {
- NXIReportError (NXpData, "ERROR: no Dataset open");
- return NX_ERROR;
- }
+ {
+ 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);
+ /* map datatypes of other plateforms */
+ data_id = H5Tget_class(pFile->iCurrentT);
+ if (data_id==H5T_STRING)
+ {
+ dims = H5Tget_size(pFile->iCurrentT);
+ memtype_id = H5Tcopy(H5T_C_S1);
+ H5Tset_size(memtype_id, dims);
+ }
+ 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)
+ {
+ memtype_id = H5T_NATIVE_INT8;
+ } else {
+ memtype_id = H5T_NATIVE_UINT8;
+ }
+ }
+ else if (size_id==2)
+ {
+ if (sign_id==H5T_SGN_2)
+ {
+ memtype_id = H5T_NATIVE_INT16;
+ } else {
+ memtype_id = H5T_NATIVE_UINT16;
+ }
+ }
+ else if (size_id==4)
+ {
+ if (sign_id==H5T_SGN_2)
+ {
+ memtype_id = H5T_NATIVE_INT32;
+ } else {
+ memtype_id = H5T_NATIVE_UINT32;
+ }
+ }
+ } else if (data_id==H5T_FLOAT)
+ {
+ size_id=H5Tget_size(pFile->iCurrentT);
+ if (size_id==4)
+ {
+ memtype_id = H5T_NATIVE_FLOAT;
+ } else if (size_id==8) {
+ memtype_id = H5T_NATIVE_DOUBLE;
+ }
+ }
+
+ /* actually read */
+ H5Dread (pFile->iCurrentD, memtype_id, H5S_ALL, H5S_ALL,H5P_DEFAULT, data);
return NX_OK;
}
@@ -1360,9 +1392,10 @@
hsize_t mySize[H5S_MAX_RANK];
hssize_t mStart[H5S_MAX_RANK];
hid_t memspace, iRet, data_id;
+ hid_t memtype_id, size_id, sign_id;
char *tmp_data;
char *data1;
- int i, iRank, mtype = 0;
+ int i, dims, iRank, mtype = 0;
pFile = NXI5assert (fid);
/* check if there is an Dataset open */
@@ -1408,16 +1441,64 @@
NXIReportError (NXpData, "ERROR: Select memspace failed");
return NX_ERROR;
}
-
+ /* map datatypes of other plateforms */
+ if (data_id==H5T_STRING)
+ {
+ dims = H5Tget_size(pFile->iCurrentT);
+ memtype_id = H5Tcopy(H5T_C_S1);
+ H5Tset_size(memtype_id, dims);
+ }
+ 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)
+ {
+ memtype_id = H5T_NATIVE_INT8;
+ } else {
+ memtype_id = H5T_NATIVE_UINT8;
+ }
+ }
+ else if (size_id==2)
+ {
+ if (sign_id==H5T_SGN_2)
+ {
+ memtype_id = H5T_NATIVE_INT16;
+ } else {
+ memtype_id = H5T_NATIVE_UINT16;
+ }
+ }
+ else if (size_id==4)
+ {
+ if (sign_id==H5T_SGN_2)
+ {
+ memtype_id = H5T_NATIVE_INT32;
+ } else {
+ memtype_id = H5T_NATIVE_UINT32;
+ }
+ }
+ } else if (data_id==H5T_FLOAT)
+ {
+ size_id=H5Tget_size(pFile->iCurrentT);
+ if (size_id==4)
+ {
+ memtype_id = H5T_NATIVE_FLOAT;
+ } else if (size_id==8) {
+ memtype_id = H5T_NATIVE_DOUBLE;
+ }
+ }
+
/* read slab */
if (mtype == NX_CHAR) {
- iRet = H5Dread(pFile->iCurrentD, pFile->iCurrentT, H5S_ALL,
+ iRet = H5Dread(pFile->iCurrentD, memtype_id, 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,
+ iRet = H5Dread(pFile->iCurrentD, memtype_id, memspace,
pFile->iCurrentS, H5P_DEFAULT,data);
}
@@ -1450,18 +1531,18 @@
unsigned int idx;
pFile = NXI5assert (fileid);
- idx=pFile->iCurrentA_IDX;
+ idx=pFile->iAtt5.iCurrentIDX;
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);
+ iRet=H5Aiterate(pFile->iCurrentD,&idx,attr_info,&iname);
}
if (iRet>0)
{
- pFile->iCurrentA_IDX++;
+ pFile->iAtt5.iCurrentIDX++;
strcpy(pName, iname);
if (iname != NULL) {
free(iname);
@@ -1545,10 +1626,10 @@
}
if (idx == 0)
{
- NXIReportError (NXpData, "Dataset has no attributes!");
- return NX_EOD;
+ pFile->iAtt5.iCurrentIDX = 0;
+ return NX_EOD;
}
-
+ pFile->iAtt5.iCurrentIDX = 0;
return NX_EOD;
}
else
@@ -1812,7 +1893,23 @@
return NX_ERROR;
}
- /*-------------------------------------------------------------------------*/
+ /* ------------------------------------------------------------------- */
+
+ NXstatus CALLING_STYLE NX5sameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID)
+ {
+ pNexusFile5 pFile;
+
+ pFile = NXI5assert (fileid);
+ if ((strcmp(pFirstID->iTag5,pSecondID->iTag5) == 0) &
+ (strcmp(pFirstID->iRef5,pSecondID->iRef5) == 0) &
+ (strcmp(pFirstID->iRefd,pSecondID->iRefd) == 0)) {
+ return NX_OK;
+ } else {
+ return NX_ERROR;
+ }
+ }
+
+ /*-------------------------------------------------------------------------*/
NXstatus CALLING_STYLE NX5initattrdir (NXhandle fid)
{
@@ -1820,10 +1917,9 @@
pFile = NXI5assert (fid);
NXI5KillAttDir (fid);
- pFile->iCurrentA_IDX=0;
return NX_OK;
}
-
+
/*-------------------------------------------------------------------------*/
NXstatus CALLING_STYLE NX5initgroupdir (NXhandle fid)
@@ -1832,6 +1928,5 @@
pFile = NXI5assert (fid);
NXI5KillDir (fid);
- pFile->iCurrentIDX=0;
return NX_OK;
}
diff --git a/nxdict.c b/nxdict.c
index 64a2efd3..2ebea057 100644
--- a/nxdict.c
+++ b/nxdict.c
@@ -34,8 +34,9 @@
#include
#include
#include
+#include
#include "lld.h"
-#include "napi.h"
+#include "../napi.h"
#include "stringdict.h"
#include "dynstring.h"
#include "nxdict.h"
diff --git a/nxscript.c b/nxscript.c
new file mode 100644
index 00000000..76c3a633
--- /dev/null
+++ b/nxscript.c
@@ -0,0 +1,716 @@
+/*-----------------------------------------------------------------------
+ N X S C R I P T
+
+ This is a class for scripting the contents of NeXus files from
+ SICS.
+
+ copyright: see file COPYRIGHT
+
+ Mark Koennecke, February 2003
+------------------------------------------------------------------------*/
+#include
+#include
+#include
+#include
+#include
+#include "fortify.h"
+#include "sics.h"
+#include "splitter.h"
+#include "HistMem.h"
+#include "motor.h"
+#include "counter.h"
+#include "nxdict.h"
+#include "nxscript.h"
+/*============== a personal data structure ============================*/
+typedef struct {
+ pObjectDescriptor pDes;
+ NXhandle fileHandle;
+ NXdict dictHandle;
+} NXScript, *pNXScript;
+/*======================== Action =======================================*/
+static int handleFileOperations(SConnection *pCon, pNXScript self,
+ int argc, char *argv[]){
+ int status;
+ NXaccess access;
+ char buffer[512];
+
+ if(strcmp(argv[1],"close") == 0){
+ NXclose(&self->fileHandle);
+ NXDclose(self->dictHandle,NULL);
+ self->fileHandle = NULL;
+ self->dictHandle = NULL;
+ SCSendOK(pCon);
+ return 1;
+ } else if(strcmp(argv[1],"reopen") == 0){
+ access = NXACC_RDWR;
+ } else if(strcmp(argv[1],"create4") == 0){
+ access = NXACC_CREATE4;
+ } else if(strcmp(argv[1],"create5") == 0){
+ access = NXACC_CREATE5;
+ } else {
+ return 0;
+ }
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments for file operation",
+ eError);
+ return 1;
+ }
+ /*
+ be considerate: close files left open
+ */
+ if(self->fileHandle != NULL){
+ NXclose(&self->fileHandle);
+ self->fileHandle = NULL;
+ }
+ if(self->dictHandle != NULL){
+ NXDclose(self->dictHandle, NULL);
+ self->dictHandle = NULL;
+ }
+ /*
+ now initialize ourselves
+ */
+ unlink(argv[2]); /* kill file for overwrite */
+ status = NXopen(argv[2],access,&self->fileHandle);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to open %s",argv[2]);
+ SCWrite(pCon,buffer,eError);
+ }
+ status = NXDinitfromfile(argv[3],&self->dictHandle);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to open dictionary %s",argv[3]);
+ SCWrite(pCon,buffer,eError);
+ }
+ SCSendOK(pCon);
+ return 1;
+}
+/*----------------------------------------------------------------------*/
+static void putMotor(SConnection *pCon, SicsInterp *pSics, pNXScript self,
+ int argc, char *argv[]){
+ int status;
+ pMotor brumm = NULL;
+ float fVal;
+ char buffer[132], dummy[256];
+
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to putmotor",
+ eError);
+ return;
+ }
+
+ /*
+ find motor
+ */
+ brumm = (pMotor)FindCommandData(pSics,argv[3],"Motor");
+ if(!brumm){
+ sprintf(buffer,"ERROR: motor %s not found!", argv[3]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+
+ /*
+ do position
+ */
+ status = MotorGetSoftPosition(brumm, pCon,&fVal);
+ if(!status){
+ sprintf(buffer,"ERROR: failed to read position of %s", argv[3]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+ status = NXDputalias(self->fileHandle,self->dictHandle,argv[2],&fVal);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write %s with alias %s",
+ argv[3],argv[2]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+
+ /*
+ if alias_null is available: write zero point
+ */
+ strcpy(buffer,argv[2]);
+ strcat(buffer,"_null");
+ if(NXDget(self->dictHandle,buffer,dummy,255)){
+ MotorGetPar(brumm,"softzero",&fVal);
+ status = NXDputalias(self->fileHandle,self->dictHandle,buffer, &fVal);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write %s zero with alias %s",
+ argv[3],argv[2]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+ }
+}
+/*---------------------------------------------------------------------*/
+static void putCounter(SConnection *pCon, SicsInterp *pSics, pNXScript self,
+ int argc, char *argv[]){
+ pCounter cter = NULL;
+ float fVal;
+ long counts;
+ char buffer[256], newAlias[256], dummy[80];
+ int status, i, icounts;
+ CounterMode eMode;
+
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to putcounter",
+ eError);
+ return;
+ }
+
+ /*
+ find counter
+ */
+ cter = (pCounter)FindCommandData(pSics,argv[3],"SingleCounter");
+ if(!cter){
+ sprintf(buffer,"ERROR: counter %s not found!", argv[3]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+
+ /*
+ do preset
+ */
+ fVal = GetCounterPreset(cter);
+ strcpy(newAlias,argv[2]);
+ strcat(newAlias,"_preset");
+ status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,&fVal);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write preset to %s", newAlias);
+ SCWrite(pCon,buffer,eError);
+ }
+
+ /*
+ do countmode
+ */
+ eMode = GetCounterMode(cter);
+ strcpy(newAlias,argv[2]);
+ strcat(newAlias,"_mode");
+ if(eMode == eTimer){
+ strcpy(dummy,"timer");
+ } else {
+ strcpy(dummy,"monitor");
+ }
+ status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,dummy);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write counter mode to %s", newAlias);
+ SCWrite(pCon,buffer,eError);
+ }
+
+ /*
+ do time
+ */
+ fVal = GetCountTime(cter,pCon);
+ strcpy(newAlias,argv[2]);
+ strcat(newAlias,"_time");
+ if(NXDget(self->dictHandle,newAlias,dummy,79)){
+ status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,&fVal);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write count time to %s", newAlias);
+ SCWrite(pCon,buffer,eError);
+ }
+ }
+
+
+ /*
+ do counter and monitors
+ */
+ for(i = 0; i < 10; i++){
+ sprintf(newAlias,"%s_%2.2d",argv[2],i);
+ if(NXDget(self->dictHandle,newAlias,dummy,79)){
+ counts = GetMonitor(cter,i,pCon);
+ icounts = (int)counts;
+ status = NXDputalias(self->fileHandle,self->dictHandle,newAlias,
+ &icounts);
+ }
+ }
+
+ return;
+}
+/*----------------------------------------------------------------------*/
+static void putHistogramMemory(SConnection *pCon, SicsInterp *pSics,
+ pNXScript self,
+ int argc, char *argv[]){
+ pHistMem mem = NULL;
+ int status, start, length, iDim[MAXDIM], rank, i, subset = 0;
+ HistInt *iData = NULL;
+ char buffer[256], defString[512], dummy[40];
+ const float *timeBin;
+ int timeLength;
+
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to puthm",
+ eError);
+ return;
+ }
+
+ /*
+ find Histogram Memory
+ */
+ mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
+ if(!mem){
+ sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+
+ /*
+ default: everything
+ */
+ start = 0;
+ length = GetHistLength(mem);
+
+ /*
+ check for further arguments specifying a subset
+ */
+ if(argc > 5){
+ subset = 1;
+ status = Tcl_GetInt(InterpGetTcl(pSics),argv[4],&start);
+ if(status != TCL_OK){
+ sprintf(buffer,"ERROR: failed to convert %s to integer",
+ argv[4]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+ status = Tcl_GetInt(InterpGetTcl(pSics),argv[5],&length);
+ if(status != TCL_OK){
+ sprintf(buffer,"ERROR: failed to convert %s to integer",
+ argv[5]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+ }
+
+ /*
+ now get some memory
+ */
+ iData = (HistInt *)malloc(length*sizeof(HistInt));
+ if(!iData){
+ SCWrite(pCon,"ERROR: out of memory for reading histogram memory",
+ eError);
+ return;
+ }
+
+ /*
+ build the definition string
+ */
+ status = NXDget(self->dictHandle,argv[2],buffer,254);
+ if(!status){
+ sprintf(buffer,"ERROR: alias %s for histogram memory not found",
+ argv[2]);
+ SCWrite(pCon,buffer,eError);
+ free(iData);
+ return;
+ }
+ if(subset){
+ strcpy(defString,buffer);
+ timeBin = GetHistTimeBin(mem,&timeLength);
+ if(timeLength > 2){
+ sprintf(dummy,"%d",timeLength);
+ NXDupdate(self->dictHandle,"timedim",dummy);
+ }
+ } else {
+ strcpy(defString,buffer);
+ GetHistDim(mem,iDim,&rank);
+ sprintf(dummy," -rank %d", rank);
+ strcat(defString,dummy);
+ strcat(defString," -dim { ");
+ sprintf(dummy,"%d",iDim[0]);
+ strcat(defString,dummy);
+ for(i = 1; i < rank; i++){
+ sprintf(dummy,", %d",iDim[i]);
+ strcat(defString,dummy);
+ }
+ strcat(defString," } ");
+ }
+
+ /*
+ read HM
+ */
+ if(subset){
+ status = GetHistogramDirect(mem,pCon,0,start,length,iData,
+ length*sizeof(HistInt));
+ }else{
+ status = GetHistogram(mem,pCon,0,start,length,iData,
+ length*sizeof(HistInt));
+ }
+ if(!status){
+ SCWrite(pCon,"ERROR: failed to read histogram memory",eError);
+ free(iData);
+ return;
+ }
+
+ /*
+ finally: write
+ */
+ status = NXDputdef(self->fileHandle, self->dictHandle,defString,iData);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write histogram memory data");
+ SCWrite(pCon,buffer,eError);
+ }
+
+ free(iData);
+ SCSendOK(pCon);
+
+ return;
+}
+/*-------------------------------------------------------------------*/
+static void putTimeBinning(SConnection *pCon, SicsInterp *pSics,
+ pNXScript self,
+ int argc, char *argv[]){
+ pHistMem mem = NULL;
+ int status, timeLength;
+ char buffer[256], defString[512], dummy[40];
+ const float *timeBin;
+
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to puttimebinning",
+ eError);
+ return;
+ }
+
+ /*
+ find Histogram Memory
+ */
+ mem = (pHistMem)FindCommandData(pSics,argv[3],"HistMem");
+ if(!mem){
+ sprintf(buffer,"ERROR: HistMem %s not found!", argv[3]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+
+
+ /*
+ build definition string
+ */
+ status = NXDget(self->dictHandle,argv[2],buffer,254);
+ if(!status){
+ sprintf(buffer,"ERROR: alias %s for time binning not found",
+ argv[2]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+ timeBin = GetHistTimeBin(mem,&timeLength);
+ sprintf(defString,"%s -dim {%d} ",buffer,timeLength);
+
+ /*
+ write
+ */
+ status = NXDputdef(self->fileHandle, self->dictHandle,
+ defString,(void *)timeBin);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write time binning");
+ SCWrite(pCon,buffer,eError);
+ }
+ SCSendOK(pCon);
+ return;
+}
+/*----------------------------------------------------------------------*/
+static void putArray(SConnection *pCon, SicsInterp *pSics,
+ pNXScript self,
+ int argc, char *argv[]){
+ float *data = NULL;
+ int length, i, status;
+ char num[20];
+ char buffer[256], defString[512], *varData;
+ Tcl_Interp *tcl = NULL;
+ double dVal;
+
+ if(argc < 5){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to array",
+ eError);
+ return;
+ }
+ tcl = InterpGetTcl(pSics);
+ assert(tcl != NULL);
+
+ /*
+ get array length
+ */
+ status = Tcl_GetInt(tcl,argv[4],&length);
+ if(status = TCL_OK){
+ sprintf(buffer,"ERROR: failed to convert %s to integer",argv[4]);
+ SCWrite(pCon,buffer,eError);
+ return;
+ }
+
+ /*
+ allocate
+ */
+ if(length > 0){
+ data = (float *)malloc(length*sizeof(float));
+ }
+ if(data == NULL){
+ SCWrite(pCon,"ERROR: out of memory or invalid length",eError);
+ return;
+ }
+ memset(data,0,length*sizeof(float));
+
+ /*
+ try getting data
+ */
+ for(i = 0; i < length; i++){
+ sprintf(num,"%d",i);
+ varData = Tcl_GetVar2(tcl,argv[3],num,0);
+ if(varData != NULL){
+ status = Tcl_GetDouble(tcl,varData,&dVal);
+ if(status = TCL_OK){
+ sprintf(buffer,"ERROR: failed to convert %s to double",
+ varData);
+ SCWrite(pCon,buffer,eError);
+ }
+ data[i] = (float)dVal;
+ } else {
+ sprintf(buffer,"WARNING: failed to find array element %d", i);
+ SCWrite(pCon,buffer,eError);
+ }
+ }
+
+ /*
+ build definition string
+ */
+ status = NXDget(self->dictHandle,argv[2],buffer,254);
+ if(!status){
+ sprintf(buffer,"ERROR: alias %s for array not found",
+ argv[2]);
+ SCWrite(pCon,buffer,eError);
+ free(data);
+ return;
+ }
+ sprintf(defString,"%s -dim {%d} ",buffer,length);
+
+ /*
+ write it!
+ */
+ status = NXDputdef(self->fileHandle,self->dictHandle,defString,data);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write array");
+ SCWrite(pCon,buffer,eError);
+ }
+ free(data);
+ SCSendOK(pCon);
+}
+/*----------------------------------------------------------------------*/
+static void putGlobal(SConnection *pCon, SicsInterp *pSics,
+ pNXScript self,
+ int argc, char *argv[]){
+ char value[1024];
+ int status;
+
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to putglobal",
+ eError);
+ return;
+ }
+
+ Arg2Text(argc-3,&argv[3],value,1023);
+ status = NXputattr(self->fileHandle,argv[2],value,strlen(value),
+ NX_CHAR);
+ if(status != NX_OK){
+ SCWrite(pCon,"ERROR: failed to write attribute",eError);
+ }
+ SCSendOK(pCon);
+}
+/*-----------------------------------------------------------------------*/
+static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self,
+ int argc, char *argv[]){
+ int status;
+ char buffer[1024], defString[1024], numBuf[25];
+ double dVal;
+ float fVal;
+
+ /*============ */
+ if(strcmp(argv[1],"putfloat") == 0){
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to putfloat",
+ eError);
+ return 1;
+ }
+ status = Tcl_GetDouble(InterpGetTcl(pSics),argv[3],&dVal);
+ if(status != TCL_OK){
+ sprintf(buffer,"ERROR: failed to convert %s to float",
+ argv[3]);
+ SCWrite(pCon,buffer,eError);
+ return 1;
+ }
+ fVal = (float)dVal;
+ status = NXDputalias(self->fileHandle, self->dictHandle,
+ argv[2],&fVal);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write %f to alias %s",
+ fVal, argv[2]);
+ SCWrite(pCon,buffer,eError);
+ }
+ return 1;
+ } else if (strcmp(argv[1],"puttext") == 0){
+ /*====================*/
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to putfloat",
+ eError);
+ return 1;
+ }
+ Arg2Text(argc-3,&argv[3],buffer,1023);
+ status = NXDget(self->dictHandle,argv[2],defString,1023);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: alias %s not found in puttext",
+ argv[2]);
+ SCWrite(pCon,buffer,eError);
+ return 1;
+ }
+ if(strlen(defString) < 900){
+ strcat(defString," -dim {");
+ sprintf(numBuf,"%d",strlen(buffer)+1);
+ strcat(defString,numBuf);
+ strcat(defString," }");
+ } else {
+ SCWrite(pCon,"ERROR: out of definition string space in puttext",
+ eError);
+ return 1;
+ }
+ status = NXDputdef(self->fileHandle,self->dictHandle,
+ defString,buffer);
+ if(status != NX_OK){
+ sprintf(buffer,"ERROR: failed to write alias %s",
+ fVal, argv[2]);
+ SCWrite(pCon,buffer,eError);
+ }
+ return 1;
+ } else if(strcmp(argv[1],"putmot") == 0){
+ /*=========== */
+ putMotor(pCon,pSics,self,argc,argv);
+ return 1;
+ } else if(strcmp(argv[1],"putcounter") == 0){
+ /* ================*/
+ putCounter(pCon,pSics,self, argc,argv);
+ return 1;
+ }else if(strcmp(argv[1],"puthm") == 0){
+ /*=================*/
+ putHistogramMemory(pCon,pSics,self,argc, argv);
+ return 1;
+ }else if(strcmp(argv[1],"puttimebinning") == 0){
+ /*=================*/
+ putTimeBinning(pCon,pSics,self,argc,argv);
+ }else if(strcmp(argv[1],"putarray") == 0){
+ /*================*/
+ putArray(pCon,pSics,self,argc,argv);
+ }else if(strcmp(argv[1],"putglobal") == 0){
+ /*===============*/
+ putGlobal(pCon,pSics,self,argc,argv);
+ } else {
+ SCWrite(pCon,"ERROR: put command not recognised",eError);
+ }
+ return 0;
+}
+/*----------------------------------------------------------------------*/
+static void makeLink(SConnection *pCon, SicsInterp *pSics,
+ pNXScript self,
+ int argc, char *argv[]){
+ int status;
+
+ if(argc < 4){
+ SCWrite(pCon,"ERROR: insufficient number of arguments to makelink",
+ eError);
+ return;
+ }
+
+ status = NXDaliaslink(self->fileHandle, self->dictHandle,
+ argv[2],argv[3]);
+ if(status != NX_OK){
+ SCWrite(pCon,"ERROR: linking failed",eError);
+ return;
+ }
+
+ SCSendOK(pCon);
+}
+
+/*-----------------------------------------------------------------------*/
+int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]){
+ pNXScript self = (pNXScript)pData;
+
+ /*
+ preliminary checks
+ */
+ assert(self);
+ if(!SCMatchRights(pCon,usUser)){
+ return 1;
+ }
+ if(argc < 2){
+ SCWrite(pCon,"ERROR: no keyword found",eError);
+ return 1;
+ }
+ strtolower(argv[1]);
+
+ if(handleFileOperations(pCon,self,argc,argv)){
+ return 1;
+ }
+
+ /*
+ if we are here, we can only continue if files are open
+ */
+ if(self->fileHandle == NULL || self->dictHandle == NULL){
+ SCWrite(pCon,"ERROR: cannot write, files not open",eError);
+ return 1;
+ }
+
+ if(strstr(argv[1],"put") != NULL){
+ handlePut(pCon,pSics,self,argc,argv);
+ return 1;
+ }
+
+ if(strcmp(argv[1],"makelink") == 0){
+ makeLink(pCon,pSics,self,argc,argv);
+ return 1;
+ }
+ return 1;
+}
+/*=============== make it ==============================================*/
+static void KillNXScript(void *pData){
+ pNXScript self = (pNXScript)pData;
+ if(self == NULL){
+ return;
+ }
+ if(self->pDes){
+ DeleteDescriptor(self->pDes);
+ }
+ if(self->fileHandle){
+ NXclose(&self->fileHandle);
+ }
+ if(self->dictHandle){
+ NXDclose(self->dictHandle, NULL);
+ }
+ free(self);
+}
+/*----------------------------------------------------------------------*/
+int MakeNXScript(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]){
+ pNXScript self = NULL;
+ int status;
+
+ self = (pNXScript)malloc(sizeof(NXScript));
+ if(self == NULL){
+ SCWrite(pCon,"ERROR: no memory for NXscript creation",eError);
+ return 0;
+ }
+ memset(self,0,sizeof(NXScript));
+ self->pDes = CreateDescriptor("NXScript");
+ if(self->pDes == NULL){
+ SCWrite(pCon,"ERROR: no memory for NXscript creation",eError);
+ free(self);
+ return 0;
+ }
+
+ /*
+ create with with a default name if none specified
+ */
+ if(argc > 1){
+ status = AddCommand(pSics,argv[1],NXScriptAction,KillNXScript,self);
+ } else {
+ status = AddCommand(pSics,"nxscript",NXScriptAction,KillNXScript,self);
+ }
+ if(!status){
+ SCWrite(pCon,"ERROR: duplicate NXScript object not created",eError);
+ KillNXScript(self);
+ return 0;
+ }
+ return 1;
+}
+
diff --git a/nxscript.h b/nxscript.h
new file mode 100644
index 00000000..860a67c0
--- /dev/null
+++ b/nxscript.h
@@ -0,0 +1,20 @@
+
+/*-----------------------------------------------------------------------
+ N X S C R I P T
+
+ This is a class for scripting the contents of NeXus files from
+ SICS.
+
+ copyright: see file COPYRIGHT
+
+ Mark Koennecke, February 2003
+------------------------------------------------------------------------*/
+#ifndef NXSCRIPT
+#define NXSCRIPT
+
+int MakeNXScript(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]);
+int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]);
+
+#endif
diff --git a/nxscript.w b/nxscript.w
new file mode 100644
index 00000000..d539ce3a
--- /dev/null
+++ b/nxscript.w
@@ -0,0 +1,48 @@
+\subsection{nxscript}
+Nxscript is a facility for scripting the contents of SICS NeXus
+files. For the actual writing bit the NXdict library is used. This
+means that nxscript needs both a filename and a dictionary filename
+when opening a new file. Then functions are provided for writing
+values, motors, histogram memories etc. This module should serve two
+purposes:
+\begin{itemize}
+\item Replace the instrument specific codes for NeXus file writing.
+\item Enable the user to quickly modify the contents of data files by
+defining an new dictionary entry and adding another line to the
+instrument script.
+\end{itemize}
+
+The general policy with errors while writing data files is to ignore
+them and to write as much as possible. Thus this module will moan and
+complain but always return success.
+
+The module is designed for writing one NeXus file at a time. However
+it will be possible to create several instances of this class in order
+to support the unlikely event that several files have to be written at
+the same time.
+
+As this is mostly a scripting facility the only interface exposed is
+the interface to the interpreter.
+
+@o nxscript.h @{
+/*-----------------------------------------------------------------------
+ N X S C R I P T
+
+ This is a class for scripting the contents of NeXus files from
+ SICS.
+
+ copyright: see file COPYRIGHT
+
+ Mark Koennecke, February 2003
+------------------------------------------------------------------------*/
+#ifndef NXSCRIPT
+#define NXSCRIPT
+
+int MakeNXScript(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]);
+int NXScriptAction(SConnection *pCon, SicsInterp *pSics, void *pData,
+ int argc, char *argv[]);
+
+#endif
+@}
+
diff --git a/ofac.c b/ofac.c
index 25168d3e..1deb7b9b 100644
--- a/ofac.c
+++ b/ofac.c
@@ -110,6 +110,7 @@
#include "anticollider.h"
#include "gpibcontroller.h"
#include "ecb.h"
+#include "nxscript.h"
/*----------------------- Server options creation -------------------------*/
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@@ -295,6 +296,7 @@
AddCommand(pInter,"AntiCollisionInstall",AntiColliderFactory,NULL,NULL);
AddCommand(pInter,"MakeGPIB",MakeGPIB,NULL,NULL);
AddCommand(pInter,"MakeECB",MakeECB,NULL,NULL);
+ AddCommand(pInter,"MakeNXScript",MakeNXScript,NULL,NULL);
}
/*---------------------------------------------------------------------------*/
static void KillIniCommands(SicsInterp *pSics)
@@ -357,6 +359,7 @@
RemoveCommand(pSics,"AntiColliderInstall");
RemoveCommand(pSics,"MakeGPIB");
RemoveCommand(pSics,"MakeECB");
+ RemoveCommand(pSics,"MakeNXScript");
}
diff --git a/sans.tcl b/sans.tcl
index b4a856f6..41bf129a 100644
--- a/sans.tcl
+++ b/sans.tcl
@@ -206,3 +206,4 @@ Publish LogBook User
source $root/bin/count.tcl
Publish count User
Publish Repeat User
+
diff --git a/sans2.dic b/sans2.dic
new file mode 100644
index 00000000..09d1f9cc
--- /dev/null
+++ b/sans2.dic
@@ -0,0 +1,139 @@
+##NXDICT-1.0
+#----------------------------------------------------------------------------
+# NeXus dictionary file for SANS-II at SINQ, PSI
+#
+# DO NOT MODIFY OR YOUR DATA MAY NEVER BE RECOVERED AGAIN!
+# DO NOT MODIFY! YOU RISK ETERNAL DAMNATION!
+#
+# Mark Koennecke, February 2003
+#---------------------------------------------------------------------------
+#--------- NXentry
+etitle = /entry1,NXentry/SDS title -type DFNT_CHAR -rank 1
+etime = /entry1,NXentry/SDS start_time -type DFNT_CHAR -rank 1
+endtime = /entry1,NXentry/SDS end_time -type DFNT_CHAR -rank 1
+#----------- NXinstrument
+iname = /entry1,NXentry/SANS-II,NXinstrument/SDS name -type DFNT_CHAR \
+ -rank 1
+#----------------------NXSource
+sname = /entry1,NXentry/SANS-II,NXinstrument/SINQ,NXsource/SDS name \
+ -type DFNT_CHAR -rank 1
+stype = /entry1,NXentry/SANS-II,NXinstrument/SINQ,NXsource/SDS type \
+ -type DFNT_CHAR -rank 1
+#---------------------Selector
+vname = /entry1,NXentry/SANS-II,NXinstrument/Dornier-VS,NXchopper/SDS type \
+ -type DFNT_CHAR -rank 1
+vrot = /entry1,NXentry/SANS-II,NXinstrument/Dornier-VS,NXchopper/SDS \
+ rotation_speed -attr {units,RPM}
+vtilt = /entry1,NXentry/SANS-II,NXinstrument/Dornier-VS,NXchopper/SDS \
+ tilt_angle -attr {units,degree}
+vlambda = /entry1,NXentry/SANS-II,NXinstrument/Dornier-VS,NXchopper/SDS \
+ lambda -attr {units,nm}
+#-------------------- monitor 1
+cter_01 = /entry1,NXentry/SANS-II,NXinstrument/monitor1,NXmonitor/SDS \
+ counts -type DFNT_INT32
+#-------------------- proton monitor
+cter_04 = /entry1,NXentry/SANS-II,NXinstrument/integrated_beam,NXmonitor/SDS \
+ counts -type DFNT_INT32
+#--------------------- collimator
+colli = /entry1,NXentry/SANS-II,NXinstrument/collimator,NXcollimator/SDS \
+ length -attr {units,m}
+#--------------------- attenuator
+atti = /entry1,NXentry/SANS-II,NXinstrument/attenuator,NXattenuator/SDS \
+ selection
+#-------------------- BeamStop
+bspos= /entry1,NXentry/SANS-II,NXinstrument/beam_stop,NXstop/SDS out_flag
+vsx = /entry1,NXentry/SANS-II,NXinstrument/beam_stop,NXstop/SDS x_position \
+ -attr {units,mm}
+vsx_null = /entry1,NXentry/SANS-II,NXinstrument/beam_stop,NXstop/SDS x_null \
+ -attr {units,mm}
+vsy = /entry1,NXentry/SANS-II,NXinstrument/beam_stop,NXstop/SDS y_position \
+ -attr {units,mm}
+vsy_null = /entry1,NXentry/SANS-II,NXinstrument/beam_stop,NXstop/SDS y_null \
+ -attr {units,mm}
+#--------------------- Detector
+ddx = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS x_position \
+ -attr {units,mm}
+ddx_null = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS \
+ x_null -attr {units,mm}
+cter_mode = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS \
+ count_mode -type DFNT_CHAR -rank 1 -dim {30}
+cter_preset = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS \
+ preset -attr {units,secORcounts}
+cter_01 = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS \
+ monitor_counts -type DFNT_UINT32 -rank 1 -dim {1}
+cter_time = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS \
+ counting_time -attr {units,seconds}
+ddcounts = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS counts -type DFNT_UINT32 -LZW -attr {signal,1}
+ddcx = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS \
+ detector_x -type DFNT_FLOAT32 -rank 1 -attr {axis,1}
+ddcy = /entry1,NXentry/SANS-II,NXinstrument/detector,NXdetector/SDS \
+ detector_y -type DFNT_INT32 -rank 1 -attr {axis,2}
+#--------Sample
+san = /entry1,NXentry/sample,NXsample/SDS name -type DFNT_CHAR -rank 1
+stable = /entry1,NXentry/sample,NXsample/SDS active_sample_table\
+ -type DFNT_CHAR -rank 1
+charo = /entry1,NXentry/sample,NXsample/SDS chamber_rotation \
+ -attr {units,degree}
+charo_null = /entry1,NXentry/sample,NXsample/SDS chamber_rotation_null \
+ -attr {units,degree}
+chax = /entry1,NXentry/sample,NXsample/SDS chamber_x \
+ -attr {units,mm}
+chax_null = /entry1,NXentry/sample,NXsample/SDS chamber_x_null \
+ -attr {units,mm}
+chaz = /entry1,NXentry/sample,NXsample/SDS chamber_z \
+ -attr {units,mm}
+chaz_null = /entry1,NXentry/sample,NXsample/SDS chamber_z_null \
+ -attr {units,mm}
+chac = /entry1,NXentry/sample,NXsample/SDS chamber_changer \
+ -attr {units,mm}
+chac_null = /entry1,NXentry/sample,NXsample/SDS chamber_changer_null \
+ -attr {units,mm}
+goniox = /entry1,NXentry/sample,NXsample/SDS goniometer_x \
+ -attr {units,mm}
+goniox_null = /entry1,NXentry/sample,NXsample/SDS goniometer_x_null \
+ -attr {units,mm}
+gonioy = /entry1,NXentry/sample,NXsample/SDS goniometer_y \
+ -attr {units,mm}
+gonioy_null = /entry1,NXentry/sample,NXsample/SDS goniometer_y_null \
+ -attr {units,mm}
+goniochi = /entry1,NXentry/sample,NXsample/SDS goniometer_chi \
+ -attr {units,degree}
+goniochi_null = /entry1,NXentry/sample,NXsample/SDS goniometer_chi_null \
+ -attr {units,degree}
+goniophi = /entry1,NXentry/sample,NXsample/SDS goniometer_phi \
+ -attr {units,degree}
+goniophi_null = /entry1,NXentry/sample,NXsample/SDS goniometer_phi_null \
+ -attr {units,degree}
+tablex = /entry1,NXentry/sample,NXsample/SDS table_x \
+ -attr {units,mm}
+tabley = /entry1,NXentry/sample,NXsample/SDS table_y \
+ -attr {units,mm}
+tablez = /entry1,NXentry/sample,NXsample/SDS table_z \
+ -attr {units,mm}
+tableom = /entry1,NXentry/sample,NXsample/SDS table_omega \
+ -attr {units,degree}
+tablex_null = /entry1,NXentry/sample,NXsample/SDS table_x_null \
+ -attr {units,mm}
+tabley_null = /entry1,NXentry/sample,NXsample/SDS table_null \
+ -attr {units,mm}
+tablez_null = /entry1,NXentry/sample,NXsample/SDS table_z_null \
+ -attr {units,mm}
+sans1om = /entry1,NXentry/sample,NXsample/SDS sans1_omega \
+ -attr {units,degree}
+sans1om_null = /entry1,NXentry/sample,NXsample/SDS sans1_omega_null \
+ -attr {units,degree}
+sans1chi = /entry1,NXentry/sample,NXsample/SDS sans1_chi \
+ -attr {units,degree}
+sans1chi_null = /entry1,NXentry/sample,NXsample/SDS sans1_chi_null \
+ -attr {units,degree}
+satemp = /entry1,NXentry/sample,NXsample/SDS temperature -attr {units,Kelvin}
+samag = /entry1,NXentry/sample,NXsample/SDS magnetic_field \
+ -attr {units,A}
+saenv = /entry1,NXentry/sample,NXsample/SDS environment \
+ -type DFNT_CHAR -rank 1 -dim {256}
+#-------data
+dan = /entry1,NXentry/data1,NXdata/NXVGROUP
+
+
+
+
diff --git a/sans2.tcl b/sans2.tcl
new file mode 100644
index 00000000..db92e962
--- /dev/null
+++ b/sans2.tcl
@@ -0,0 +1,599 @@
+# --------------------------------------------------------------------------
+# Initialization script for the instrument SANSII at SINQ
+#
+# Dr. Mark Koennecke, January - ???? 2003
+#---------------------------------------------------------------------------
+# O P T I O N S
+set root "/afs/psi.ch/user/k/koennecke/src/sics"
+# first all the server options are set
+
+ServerOption SaveFile $root/tmp/sans2stat.tcl
+# File to save the status of the instrument too
+
+ServerOption ReadTimeOut 10
+# timeout when checking for commands. In the main loop SICS checks for
+# pending commands on each connection with the above timeout, has
+# PERFORMANCE impact!
+
+ServerOption AcceptTimeOut 10
+# timeout when checking for connection req.
+# Similar to above, but for connections
+
+ServerOption ReadUserPasswdTimeout 500000
+# time to wiat for a user/passwd to be sent from a client. Increase this
+# if there is a problem connecting to a server due to network overload\
+
+ServerOption LogFileBaseName $root/tmp/sans2log
+# the path and base name of the internal server logfile to which all
+# activity will be logged.
+
+ServerOption ServerPort 2915
+# the port number the server is going to listen at. The client MUST know
+# this number in order to connect. It is in client.ini
+
+ServerOption InterruptPort 2917
+# The UDP port where the server will wait for Interrupts from clients.
+# Obviously, clients wishing to interrupt need to know this number.
+# Telnet Options
+ServerOption TelnetPort 1301
+ServerOption TelWord sicslogin
+
+# The token system
+TokenInit connan
+
+#---------------------------------------------------------------------------
+# U S E R S
+
+# than the SICS users are specified
+# Syntax: SicsUser name password userRightsCode
+SicsUser Manager Joachim 1
+SicsUser User Kohl 2
+SicsUser Spy 007 1
+
+#--------------------------------------------------------------------------
+# S I M P L E V A R I A B L E S
+
+# now a few general variables are created
+# Syntax: VarMake name type access
+# type can be one of: Text, Int, Float
+#access can be one of: Internal, Mugger, user, Spy
+
+VarMake Instrument Text Internal
+Instrument "SANS-II at SINQ,PSI"
+#initialisation
+Instrument lock
+
+VarMake title Text User
+VarMake User Text User
+VarMake SubTitle Text User
+VarMake environment Text User
+VarMake comment Text User
+VarMake samplename Text User
+VarMake email Text User
+VarMake fax Text User
+VarMake phone Text User
+VarMake adress Text User
+VarMake sample Text User
+VarMake BatchRoot Text User
+VarMake starttime Text User
+BatchRoot $root
+
+VarMake sampletable Text User
+
+#----------- Initialize data storage stuff
+VarMake SicsDataPath Text Mugger
+SicsDataPath $root/tmp/
+SicsDataPath lock
+VarMake SicsDataPrefix Text Mugger
+SicsDataPrefix sansII
+SicsDataPrefix lock
+VarMake SicsDataPostFix Text Mugger
+SicsDataPostFix ".hdf"
+SicsDataPostFix lock
+MakeDataNumber SicsDataNumber $root/tmp/DataNumber
+
+#=========================================================================
+# Initialize ECB system
+#========================================================================
+
+#--------- GPIB Controller with National Instruments driver
+MakeGPIB gpib ni
+
+#-------- MakeECB name gpib-controller board-number gpib-address
+MakeECB ecb1 gpib 0 5
+
+#--------- Function to switch ecb to automatic control
+proc ecbauto {} {
+ ecb1 func 162 1 0 0 0
+}
+Publish ecbauto User
+
+ecbauto
+
+#-------------- ECB Motors
+# Motor name ecb ecb-controller ecb-motor-index hardlowerlimit hardupperlimit
+
+Motor sr ecb ecb1 1 -10000. 10000.
+sr encoder 0
+sr control 0
+sr range 1
+sr multi 0
+sr multchan 0
+sr acceleration 1000
+sr rotation_dir -1
+sr startspeed 330
+sr maxspeed 1000
+sr auto 330
+sr manuell 50
+sr delay 50
+sr offset 0
+sr dtolerance .01
+sr step2deg 1
+sr step2dig 0
+sr backlash .15
+
+Motor stx ecb ecb1 2 -16000. 16000.
+stx encoder 0
+stx control 0
+stx range 1
+stx multi 0
+stx multchan 0
+stx acceleration 500
+stx rotation_dir -1
+stx startspeed 330
+stx maxspeed 1000
+stx auto 500
+stx manuell 50
+stx delay 50
+stx offset 0
+stx dtolerance .01
+stx step2deg 1
+stx step2dig 0
+stx backlash .15
+
+Motor stz ecb ecb1 3 6500. 20000.
+stz encoder 0
+stz control 0
+stz range 1
+stz multi 0
+stz multchan 0
+stz acceleration 500
+stz rotation_dir -1
+stz startspeed 330
+stz maxspeed 1000
+stz auto 500
+stz manuell 50
+stz delay 50
+stz offset 0
+stz dtolerance .01
+stz step2deg 1
+stz step2dig 0
+stz backlash .15
+
+Motor sc ecb ecb1 4 -2000. 70000.
+sc encoder 0
+sc control 0
+sc range 1
+sc multi 0
+sc multchan 0
+sc acceleration 500
+sc rotation_dir -1
+sc startspeed 330
+sc maxspeed 1000
+sc auto 500
+sc manuell 50
+sc delay 50
+sc offset 0
+sc dtolerance .01
+sc step2deg 1
+sc step2dig 0
+sc backlash .15
+
+Motor gu ecb ecb1 5 -10000. 10000.
+gu encoder 0
+gu control 0
+gu range 1
+gu multi 0
+gu multchan 0
+gu acceleration 500
+gu rotation_dir -1
+gu startspeed 330
+gu maxspeed 1000
+gu auto 500
+gu manuell 40
+gu delay 50
+gu offset 0
+gu dtolerance .02
+gu step2deg 1
+gu step2dig 0
+gu backlash .15
+
+Motor gl ecb ecb1 6 -10000. 10000.
+gl encoder 0
+gl control 0
+gl range 1
+gl multi 0
+gl multchan 0
+gl acceleration 500
+gl rotation_dir -1
+gl startspeed 330
+gl maxspeed 1000
+gl auto 500
+gl manuell 40
+gl delay 50
+gl offset 0
+gl dtolerance .02
+gl step2deg 1
+gl step2dig 0
+gl backlash .15
+
+
+Motor tu ecb ecb1 7 -10000. 10000.
+tu encoder 0
+tu control 0
+tu range 1
+tu multi 0
+tu multchan 0
+tu acceleration 500
+tu rotation_dir 1
+tu startspeed 330
+tu maxspeed 1000
+tu auto 330
+tu manuell 40
+tu delay 50
+tu offset 0
+tu dtolerance .01
+tu step2deg 1
+tu step2dig 0
+tu backlash .15
+
+
+Motor tl ecb ecb1 8 -10000. 10000.
+tl encoder 0
+tl control 0
+tl range 1
+tl multi 0
+tl multchan 0
+tl acceleration 500
+tl rotation_dir 1
+tl startspeed 330
+tl maxspeed 1000
+tl auto 330
+tl manuell 40
+tl delay 50
+tl offset 0
+tl dtolerance .01
+tl step2deg 1
+tl step2dig 0
+tl backlash .15
+
+Motor om ecb ecb1 9 -10000. 10000.
+om encoder 1
+om control 1
+om range 1
+om multi 0
+om multchan 0
+om acceleration 500
+om rotation_dir 1
+om startspeed 330
+om maxspeed 1000
+om auto 100
+om manuell 40
+om delay 50
+om offset 0
+om dtolerance .01
+om step2deg 1
+om step2dig 10
+om backlash .15
+
+Motor sz ecb ecb1 10 -10000. 10000.
+sz encoder 0
+sz control 0
+sz range 1
+sz multi 0
+sz multchan 0
+sz acceleration 500
+sz rotation_dir 1
+sz startspeed 330
+sz maxspeed 1000
+sz auto 500
+sz manuell 40
+sz delay 50
+sz offset 0
+sz dtolerance .001
+sz step2deg 1
+sz step2dig 0
+sz backlash .15
+
+Motor sx ecb ecb1 11 -10000. 10000.
+sx encoder 0
+sx control 0
+sx range 1
+sx multi 0
+sx multchan 0
+sx acceleration 500
+sx rotation_dir 1
+sx startspeed 330
+sx maxspeed 1000
+sx auto 500
+sx manuell 40
+sx delay 50
+sx offset 0
+sx dtolerance .01
+sx step2deg 1
+sx step2dig 0
+sx backlash .15
+
+Motor sy ecb ecb1 12 -10000. 10000.
+sy encoder 0
+sy control 0
+sy range 1
+sy multi 0
+sy multchan 0
+sy acceleration 500
+sy rotation_dir 1
+sy startspeed 330
+sy maxspeed 1000
+sy auto 500
+sy manuell 50
+sy delay 50
+sy offset 0
+sy dtolerance .001
+sy step2deg 1
+sy step2dig 0
+sy backlash .15
+
+Motor dz ecb ecb1 13 1.05 6.0
+dz encoder 0
+dz control 0
+dz range 1
+dz multi 0
+dz multchan 0
+dz acceleration 2000
+dz rotation_dir -1
+dz startspeed 330
+dz maxspeed 1000
+dz auto 500
+dz manuell 40
+dz delay 1000
+dz offset 0
+dz dtolerance .001
+dz step2deg 53076
+dz step2dig 0
+dz backlash .15
+
+Motor dh ecb ecb1 14 -14000. 16000.
+dh encoder 0
+dh control 0
+dh range 1
+dh multi 0
+dh multchan 0
+dh acceleration 1000
+dh rotation_dir -1
+dh startspeed 330
+dh maxspeed 1000
+dh auto 500
+dh manuell 40
+dh delay 50
+dh offset 0
+dh dtolerance .001
+dh step2deg 1
+dh step2dig 0
+dh backlash .15
+
+Motor dv ecb ecb1 15 -14000. 25000.
+dv encoder 0
+dv control 0
+dv range 1
+dv multi 0
+dv multchan 0
+dv acceleration 2000
+dv rotation_dir -1
+dv startspeed 330
+dv maxspeed 1000
+dv auto 500
+dv manuell 40
+dv delay 50
+dv offset 0
+dv dtolerance .001
+dv step2deg 1
+dv step2dig 0
+dv backlash .15
+
+Motor az1 ecb ecb1 16 -3900. 0.
+az1 encoder 0
+az1 control 0
+az1 range 1
+az1 multi 0
+az1 multchan 0
+az1 acceleration 1000
+az1 rotation_dir -1
+az1 startspeed 330
+az1 maxspeed 1000
+az1 auto 330
+az1 manuell 40
+az1 delay 50
+az1 offset 0
+az1 dtolerance .001
+az1 step2deg 1
+az1 step2dig 0
+az1 backlash .15
+
+Motor atz ecb ecb1 17 -3900. 0.
+atz encoder 0
+atz control 0
+atz range 1
+atz multi 0
+atz multchan 0
+atz acceleration 1000
+atz rotation_dir -1
+atz startspeed 330
+atz maxspeed 1000
+atz auto 330
+atz manuell 40
+atz delay 50
+atz offset 0
+atz dtolerance .001
+atz step2deg 1
+atz step2dig 0
+atz backlash .15
+
+#===========================================================================
+# The ECB system has the drawback that only one out of 8 motors in a rack
+# can run at any given time. Access to such motors has to be serialized.
+# This is done through the anticollision system originally developed for
+# TRICS. This system registers requests from motors to run and then calls
+# a script which serializes the running of motors. This system is used at
+# SANS to deal with the rack logic. This section installs the necessary
+# scripts and configures the system.
+#===========================================================================
+AntiCollisionInstall
+anticollision register sr
+anticollision register stx
+anticollision register stz
+anticollision register sc
+anticollision register gu
+anticollision register gl
+anticollision register tu
+anticollision register tl
+anticollision register om
+anticollision register sz
+anticollision register sx
+anticollision register sy
+anticollision register dz
+anticollision register dh
+anticollision register dv
+anticollision register az1
+anticollision register atz
+
+#------------ assignment which motors belong into which rack
+set rack1 [list sr stx sty sc gu gl tu tl]
+set rack2 [list om sz sx dz dh dv az1 atz]
+set rack3 [list sy]
+
+proc sans2rack args {
+ global rack1 rack2 rack3
+ set length [ expr [llength $args]/2.]
+#-------- make list which motors have to be run in each rack
+ for { set i 0} { $i < $length} {incr i} {
+ set mot [lindex $args [expr $i * 2]]
+ set target [lindex $args [expr ($i *2) + 1]]
+ if { [lsearch $rack1 $mot] >= 0} {
+ lappend rack1mot $mot
+ lappend rack1target $target
+ }
+ if { [lsearch $rack2 $mot] >= 0} {
+ lappend rack2mot $mot
+ lappend rack2target $target
+ }
+ if { [lsearch $rack3 $mot] >= 0} {
+ lappend rack3mot $mot
+ lappend rack3target $target
+ }
+ }
+#------- append a dummy to each in order to ensure existence
+ lappend rack1mot dummy
+ lappend rack1target 0.0
+ lappend rack2mot dummy
+ lappend rack2target 0.0
+ lappend rack3mot dummy
+ lappend rack3target 0.0
+#-------- how many levels do we have?
+ set level -1
+ if { [llength $rack1mot] > $level} {
+ set level [llength $rack1mot]
+ }
+ if { [llength $rack2mot] > $level} {
+ set level [llength $rack2mot]
+ }
+ if { [llength $rack3mot] > $level} {
+ set level [llength $rack3mot]
+ }
+ if { $level <= 1} {
+ error "Nothing to do"
+ }
+#------------ we are set to serialize
+ anticollision clear
+ for {set i 0} {$i < $level} {incr i} {
+ set tst [expr $i + 1]
+ if { [llength $rack1mot] > $tst} {
+ anticollision add $i [lindex $rack1mot $i] \
+ [lindex $rack1target $i]
+ }
+ if { [llength $rack2mot] > $tst } {
+ anticollision add $i [lindex $rack2mot $i] \
+ [lindex $rack2target $i]
+ }
+ if { [llength $rack3mot] > $tst } {
+ anticollision add $i [lindex $rack3mot $i] \
+ [lindex $rack3target $i]
+ }
+ }
+ return
+}
+Publish sans2rack User #---------for testing purposes
+anticollision script sans2rack
+#====================== PSI Motoren ===================================
+Motor ome SIM -180. 180. .1 -.1
+Motor chi SIM -20. 20. .1 -.1
+#====================== Multi Motor Setup ==============================
+MakeMulti detector
+detector alias dz x
+detector endconfig
+SicsAlias detector dt
+
+MakeMulti bs
+bs alias dh x
+bs alias dv y
+bs endconfig
+
+MakeMulti chamber
+chamber alias sr omega
+chamber alias stx x
+chamber alias sty y
+chamber alias sc c
+chamber endconfig
+
+MakeMulti gonio
+gonio alias gu chi
+gonio alias gl phi
+gonio alias tu xu
+gonio alias tl yu
+gonio endconfig
+
+MakeMulti table
+table alias om om
+table alias sz z
+table alias sx x
+table alias sy y
+table endconfig
+#====================== HISTOGRAM MEMORY ================================
+MakeCounter counter ecb ecb1
+MakeECB tdc gpib 0 7
+MakeHM banana tdc
+banana configure dim0 128
+banana configure dim1 128
+banana configure rank 2
+banana configure Counter counter
+banana configure bank 0
+banana configure map 9
+banana configure range 0
+banana configure n 0
+banana configure ecb tdc
+banana configure fill 0
+banana configure mode HMXY
+banana init
+banana exponent 6
+banana CountMode timer
+banana preset 100
+#===================================== data file writing ================
+MakeNXScript
+#===================================== install commands ==================
+MakeDrive
+MakeRuenBuffer
+commandlog auto
+#=================================== load specific command file ===========
+source $root/sans2com.tcl
+
+
+
diff --git a/sans2com.tcl b/sans2com.tcl
new file mode 100644
index 00000000..5558f928
--- /dev/null
+++ b/sans2com.tcl
@@ -0,0 +1,261 @@
+#-----------------------------------------------------------------------
+# Scripts for the SANS-II Risoe instrument as installed at PSI.
+#
+# Initial version: Mark Koennecke, Febrary 2003
+#----------------------------------------------------------------------
+#source $root/log.tcl
+#source $root/batch.tcl
+source $root/nxsupport.tcl
+
+if { [info exists sansinit] == 0 } {
+ set sansinit 1
+ Publish beamstop Spy
+ Publish stopmot User
+# Publish collRead Spy #-----for debugging
+# Publish collSet Spy #-----for debugging
+ Publish collimator Spy
+ Publish coll Spy
+# Publis att Spy
+ Publish batchrun User
+ Publish LogBook User
+ Publish count User
+ Publish Repeat User
+ Publish storedata User
+}
+#======================== general useful stuff ======================
+proc SplitReply { text } {
+ set l [split $text =]
+ return [lindex $l 1]
+}
+#======================== Collimator stuff ===========================
+proc collRead args {
+ set res [ecb1 func 164 0 0 0 0]
+ set l [split $res]
+ return [expr ([lindex $l 1] << 8) + [lindex $l 0]]
+}
+#--------------------------------------------------------------------
+proc collSet {val} {
+ switch $val {
+ 1 { set d 0}
+ 2 { set d 01}
+ 3 { set d 03}
+ 4 { set d 07}
+ 5 { set d 017}
+ 6 { set d 037}
+ default {
+ error "Invalid collimation length requested"
+ }
+ }
+ ecb1 func 148 $d 0 0 0
+ return OK
+}
+#--------------------------------------------------------------------
+proc collimator args {
+ if { [llength $args ] < 1} {
+#------------- read case
+ set res [collRead]
+ set res [expr $res & 255]
+ set length -1
+ switch $res {
+ 0 { set length 1}
+ 1 { set length 2}
+ 3 { set length 3}
+ 7 { set length 4}
+ 15 { set length 5}
+ 31 { set length 6}
+ default {
+ error "Unknown reply $res from colRead"
+ }
+ }
+ return [format "collimator = %f" $length]
+ } else {
+#------------- set case
+ set rights [SplitReply [config myrights]]
+ if {$rights > 2} {
+ error "Insufficient rights to drive collimator"
+ }
+ return [collSet [lindex $args 0]]
+ }
+}
+#----------------------------------------------------------------------
+proc coll args {
+ return coliimator $args
+}
+#======================== Beamstop stuff ==============================
+proc beamstop args {
+#----- without arguments: request
+ if { [llength $args] < 1} {
+ set res [collRead 0]
+ if { ($res & 256) > 0 } {
+ return "0 in"
+ } else {
+ return "1 out"
+ }
+ }
+#---- with arguments: change, but only with at least user privilege
+ set rights [SplitReply [config myrights]]
+ if {$rights > 2} {
+ error "Insufficient rights to drive beamstop"
+ }
+ switch [lindex $args 0] {
+ 0 { set d 1}
+ in {set d 1}
+ 1 {set d 0}
+ out {set d 0}
+ default{
+ error "Invalid beamstop requested"
+ }
+ }
+ ecb1 func 160 $d 0 0 0
+ return OK
+}
+#================================ stopmot ================================
+proc stopmot args {
+ ecb1 func 132 0 0 0 0
+}
+#=============================== counting ===============================
+proc count { {mode NULL } { preset NULL } } {
+#----- deal with mode
+ set mode2 [string toupper $mode]
+ set mode3 [string trim $mode2]
+ set mc [string index $mode2 0]
+ if { [string compare $mc T] == 0 } {
+ banana CountMode Timer
+ } elseif { [string compare $mc M] == 0 } {
+ banana CountMode Monitor
+ }
+#------ deal with preset
+ if { [string compare $preset NULL] != 0 } {
+ banana preset $preset
+ }
+#------ prepare a count message
+ set ret [catch {Success} msg]
+ set a [banana preset]
+ set aa [SplitReply $a]
+ set b [banana CountMode]
+ set bb [SplitReply $b]
+ set tt [sicstime]
+ set sn [sample]
+ starttime [sicstime]
+ ClientPut [format " Starting counting in %s mode with a preset of %s" \
+ $bb $aa ]
+ ClientPut [format "Count started at %s" $tt]
+ ClientPut [format " sample name: %s" $sn]
+#------- count
+ banana InitVal 0
+ wait 1
+ set ret [catch {Success} msg]
+ banana count
+ set ret [catch {Success} msg]
+#------- StoreData
+ storedata
+ set ttt [sicstime]
+ if { $ret != 0 } {
+ ClientPut [format "Counting ended at %s" $ttt]
+ error [format "Counting ended with error: %s" $msg]
+ }
+ ClientPut [format "Counting ended at %s" $ttt]
+ ClientPut "Total Counts: [SplitReply [banana sum 0 128 0 128]]"
+}
+#---------------- Repeat -----------------------------------------------
+proc repeat { num {mode NULL} {preset NULL} } {
+ for { set i 0 } { $i < $num } { incr i } {
+ count $mode $preset
+ }
+}
+#=================== Data File Writing =================================
+proc writeBeforeSample args {
+ writeTextVar etitle title
+ writeTextVar etime starttime
+ nxscript puttext endtime [sicstime]
+ writeTextVar iname instrument
+ nxscript puttext sname SINQ, Paul Scherrer Institut
+ nxscript puttext stype Continuous flux spallation source
+ nxscript puttext vname Dornier velocity selector
+# writeFloatVar vrot velo
+# writeFloatVar vtilt tilt
+# writeFloatvar vlambda lambda
+ writeFloatVar colli collimator
+# writeFloatVar atti attenuator
+}
+#--------------------------------------------------------------------
+proc writeSample args {
+ writeTextVar san sample
+ writeTextVar stable sampletable
+#------------- sample chamber
+ nxscript putmot charo sr
+ nxscript putmot chax stx
+ nxscript putmot chaz stz
+ nxscript putmot chac sc
+#------------- goniometer
+ nxscript putmot goniox tu
+ nxscript putmot gonioy tl
+ nxscript putmot goniochi gu
+ nxscript putmot goniophi gl
+#------------- xyz-table
+ nxscript putmot tablex sx
+ nxscript putmot tabley sy
+ nxscript putmot tablez sz
+ nxscript putmot tableom om
+#------------ sans1table
+ nxscript putmot sans1chi chi
+ nxscript putmot sans1om ome
+#---------- environment
+ if { [catch {set tmp [SplitReply [temperature]]} tmp] == 0} {
+ nxscript putfloat satemp $tmp
+ }
+ if { [catch {set tmp [SplitReply [magnet]]} tmp] == 0} {
+ nxscript putfloat samag $tmp
+ }
+ writeTextVar saenv environment
+}
+#----------------------------------------------------------------------
+proc writeAfterSample args {
+#-------- beamstop
+ nxscript putmot vsx dh
+ nxscript putmot vsy dv
+ set tst [beamstop]
+ if { [string first in $tst] >= 0} {
+ nxscript putfloat bspos 0
+ } else {
+ nxscript putfloat bspos 1.
+ }
+#------- counter
+ nxscript putcounter cter counter
+#------- detector
+ nxscript putmot ddx dz
+ nxscript puthm ddcounts banana
+ for { set i 0} { $i < 128} {incr i} {
+ set detar($i) [expr -64. + $i]
+ }
+ nxscript putarray ddcx detar 128
+ nxscript putarray ddcy detar 128
+}
+#----------------------------------------------------------------------
+proc makeLinks args {
+ nxscript makelink dan ddcounts
+ nxscript makelink dan ddcx
+ nxscript makelink dan ddcy
+}
+#-----------------------------------------------------------------------
+proc storedata args {
+ global root
+ set filnam [makeFileName]
+ clientput [format "Writing %s" $filnam]
+ nxscript create5 $filnam $root/sans2.dic
+ writeStandardAttributes $filnam
+
+ writeBeforeSample
+
+ writeSample
+
+ writeAfterSample
+
+ makeLinks
+
+ nxscript close
+}
+
+
+
+
diff --git a/sicsstat.tcl b/sicsstat.tcl
index 060930d9..008c022f 100644
--- a/sicsstat.tcl
+++ b/sicsstat.tcl
@@ -1,3 +1,24 @@
+banana CountMode timer
+banana preset 100.000000
+# Counter counter
+counter SetPreset 12.000000
+counter SetMode Timer
+# Motor chi
+chi sign 1.000000
+chi SoftZero 0.000000
+chi SoftLowerLim -20.000000
+chi SoftUpperLim 20.000000
+chi Fixed -1.000000
+chi InterruptMode 0.000000
+chi AccessCode 2.000000
+# Motor ome
+ome sign 1.000000
+ome SoftZero 0.000000
+ome SoftLowerLim -180.000000
+ome SoftUpperLim 180.000000
+ome Fixed -1.000000
+ome InterruptMode 0.000000
+ome AccessCode 2.000000
# Motor atz
atz sign 1.000000
atz SoftZero 0.000000
@@ -134,6 +155,22 @@ sr SoftUpperLim 10000.000000
sr Fixed -1.000000
sr InterruptMode 0.000000
sr AccessCode 2.000000
+sampletable UNKNOWN
+sampletable setAccess 2
+starttime UNKNOWN
+starttime setAccess 2
+batchroot /afs/psi.ch/user/k/koennecke/src/sics
+batchroot setAccess 2
+sample Wurstbroetchen
+sample setAccess 2
+adress UNKNOWN
+adress setAccess 2
+phone UNKNOWN
+phone setAccess 2
+fax UNKNOWN
+fax setAccess 2
+email UNKNOWN
+email setAccess 2
samplename KohlSulfid
samplename setAccess 2
comment UNKNOWN
diff --git a/tdchm.c b/tdchm.c
index b7f874a0..15768905 100644
--- a/tdchm.c
+++ b/tdchm.c
@@ -73,7 +73,7 @@ static int downloadConfiguration(pTdc self){
case HMY:
function = 130;
break;
- caseHMXY:
+ case HMXY:
function = 128;
break;
default:
@@ -154,12 +154,6 @@ static int TDCConfigure(pHistDriver self, SConnection *pCon,
tdc->fillByte = 0;
- status = downloadConfiguration(tdc);
- if(!status){
- tdc->errorCode = status;
- return 0;
- }
-
status = StringDictGet(pOpt,"ecb",pValue,79);
assert(status);
tdc->tdc = FindCommandData(pSics,pValue,"ECB");
@@ -168,6 +162,13 @@ static int TDCConfigure(pHistDriver self, SConnection *pCon,
return 0;
}
+ status = downloadConfiguration(tdc);
+ if(!status){
+ tdc->errorCode = status;
+ return 0;
+ }
+
+
self->iReconfig = 0;
return 1;
@@ -265,13 +266,21 @@ static int TDCCountStatus(pHistDriver self, SConnection *pCon){
assert(tdc);
if(tdc->counter != NULL){
- return tdc->counter->pDriv->GetStatus(tdc->counter->pDriv,&fControl);
+ status = tdc->counter->pDriv->GetStatus(tdc->counter->pDriv,&fControl);
}
/*
The TDC does not seem to have a means to figure if it is counting or not
- or to do some sort of progress report.
+ or to do some sort of progress report. So it has to have an associated
+ counter in order to stop it at the end.
*/
- return HWIdle;
+ if(status != HWBusy){
+ status = disableTdc(tdc);
+ if(status != 1){
+ tdc->errorCode = COMMERROR;
+ return HWFault;
+ }
+ }
+ return status;
}
/*=====================================================================*/
static int TDCGetError(pHistDriver self, int *iCode, char *perror,
@@ -472,7 +481,7 @@ static int TDCGetHistogram(pHistDriver self, SConnection *pCon,
tdc = (pTdc)self->pPriv;
assert(tdc);
- if(length >= MAXTDCCHANNELS){
+ if(length > MAXTDCCHANNELS){
tdc->errorCode = MAXEXCEEDED;
return HWFault;
}