- TDC histogram memory driver sort of working

- New class for scripting datafiles
- SANS-II almost complete initialization file
This commit is contained in:
cvs
2003-02-07 15:20:19 +00:00
parent f51588e2a7
commit ac10723d74
25 changed files with 2965 additions and 1711 deletions

View File

@ -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 \ hmcontrol.o userscan.o slsmagnet.o rs232controller.o lomax.o \
polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o \ polterwrite.o fourlib.o motreg.o motreglist.o anticollider.o \
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) ecb.o ecbdriv.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 MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
COUNTEROBJ = countdriv.o simcter.o counter.o COUNTEROBJ = countdriv.o simcter.o counter.o

View File

@ -10,6 +10,7 @@
#ifndef SICSINTERPRETER #ifndef SICSINTERPRETER
#define SICSINTERPRETER #define SICSINTERPRETER
#include "Scommon.h" #include "Scommon.h"
#include <tcl.h>
/* M.Z. */ /* M.Z. */
#include "definealias.i" #include "definealias.i"
@ -141,5 +142,10 @@ typedef struct __SINTER
------------------------------------------------------------------------*/ ------------------------------------------------------------------------*/
void *FindDrivable(SicsInterp *pics, char *name); void *FindDrivable(SicsInterp *pics, char *name);
/*-----------------------------------------------------------------------
Get a copy of the Tcl interpreter
------------------------------------------------------------------------*/
Tcl_Interp *InterpGetTcl(SicsInterp *pSics);
#endif #endif

View File

@ -1276,9 +1276,8 @@ extern pServer pServ;
strtolower(argv[1]); strtolower(argv[1]);
if(strcmp(argv[1],"list") == 0) if(strcmp(argv[1],"list") == 0)
{ {
sprintf(pBueffel,"OutCode = %s",pCode[pCon->iOutput]); sprintf(pBueffel,"OutCode = %s\nUserRights = %d",
SCWrite(pCon,pBueffel,eStatus); pCode[pCon->iOutput], SCGetRights(pCon));
sprintf(pBueffel,"UserRights = %d",SCGetRights(pCon));
SCWrite(pCon,pBueffel,eStatus); SCWrite(pCon,pBueffel,eStatus);
return 1; return 1;
} }

131
doc/manager/nxscript.htm Normal file
View File

@ -0,0 +1,131 @@
<HTML>
<HEAD>
<TITLE>Scripting NeXus Files</TITLE>
</HEAD>
<BODY>
<H1>Scripting NeXus Files</H1>
<P>
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:
<ul>
<li>The interface needs two filenames: the
NeXus filename and the dictionary filename when opening files.
<li>Writing commands have the general form: alias object. This means
that object is written to the NeXus file using the specified alias.
<li>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.
<li>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.
<li>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.
</ul>
</P>
<h2>Usage</h2>
<p>
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:
<dl>
<dt>MakeNXScript ?name?
<dd>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.
</dl>
In the following sections it is assumed that an object <b>nxscript</b>
had been configured into SICS.
</p>
<h3>File Opening and Closing</h3>
<p>
<dl>
<dt>nxscript create5 nexusFile dictFile
<dd>Creates a new NeXus file based on HDF-5 with the name
nexusFile. The dictionary file dictFile is used.
<dt>nxscript create4 nexusFile dictFile
<dd>Creates a new NeXus file based on HDF-4 with the name
nexusFile. The dictionary file dictFile is used.
<dt>nxscript reopen nexusFile dictFile
<dd>Reopens an existing NeXus with the name
nexusFile for modification or appending.
The dictionary file dictFile is used.
<dt>nxscript close
<dd>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.
</dl>
</p>
<h3>Writing Things</h3>
<p>
<dl>
<dt>nxscript puttext alias bla bla bla ....
<dd>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.
<dt>nxscript putfloat alias value
<dd>Writes a single floating point value to alias alias.
<dt>nscript putmot aliasName motorName
<dd>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.
<dt>nxscript putcounter aliasBase counterName
<dd>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:
<dl>
<dt>aliasBase_preset
<dd>The preset value.
<dt>aliasBase_mode
<dd>The counter mode
<dt>aliasBase_time
<dd>The actual time counted, without breaks due to insufficient beam.
<dt>aliasbase_00 ... aliasBase_09
<dd>The monitor readings for monitors 0 to 9. Please note that 00
would denote the normal counting tube at a scanning type of
experiment.
</dl>
<dt>nxscript puthm hmAlias hmName ?start? ?length?
<dd>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.
<dt>nxscript puttimebinning aliasName hmName
<dd>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.
<dt>nxscript putarray aliasName arrayName length
<dd>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.
<dt>nxsript putglobal attName bla bla bla
<dd>This writes an global attribute attName. Everything after attName
is concatenated to a string which then respresents the value of the
attribute.
<dt>nxscript makelink targetAlias victimAlias
<dd>This creates a symbolic link for victimAlias in the group
designated by targetAlias.
</dl>
</p>
</BODY>
</HTML>

2
ecb.c
View File

@ -344,7 +344,7 @@ int ECBAction(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon,pError,eError); SCWrite(pCon,pError,eError);
return 0; return 0;
} }
sprintf(pBuffer,"%x %x %x %x", sprintf(pBuffer,"%d %d %d %d",
out.d, out.e, out.b, out.c); out.d, out.e, out.b, out.c);
SCWrite(pCon,pBuffer,eValue); SCWrite(pCon,pBuffer,eValue);
return 1; return 1;

View File

@ -1177,3 +1177,15 @@ MotorDriver *CreateECBMotor(SConnection *pCon, int argc, char *argv[]){
self->errorCode = 0; self->errorCode = 0;
return (MotorDriver *)self; 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);
}

View File

@ -10,6 +10,9 @@
added getzip: Mark Koennecke, October 2000 added getzip: Mark Koennecke, October 2000
Refactored data handling into separater HMdata class.
Mark Koennecke, January 2003
Copyright: Copyright:
Labor fuer Neutronenstreuung Labor fuer Neutronenstreuung

View File

@ -70,11 +70,6 @@
#include "servlog.h" #include "servlog.h"
#define SICSERROR "005567SICS" #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. 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 The Tcl algorithm is to call a command called unknown when it cannot

View File

@ -57,6 +57,7 @@
#include "splitter.h" #include "splitter.h"
#include "status.h" #include "status.h"
#include "servlog.h" #include "servlog.h"
#include "ecbdriv.h"
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
some lokal defines some lokal defines
@ -468,7 +469,7 @@ extern void KillPiPiezo(void *pData);
} }
else if(strcmp(pM->drivername,"ECB") == 0) else if(strcmp(pM->drivername,"ECB") == 0)
{ {
free(pM->pDriver); KillECBMotor( (void *)pM->pDriver);
} }
free(pM->drivername); free(pM->drivername);
} }
@ -876,7 +877,6 @@ extern void KillPiPiezo(void *pData);
*/ */
extern MotorDriver *MakePiPiezo(Tcl_Interp *pTcl, char *pArray); 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 MotorCreate(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])

View File

@ -108,9 +108,11 @@ int StartRegMot(pMotReg self, SConnection *pCon, float fValue){
self->motorData, self->motorData,
pCon, pCon,
fValue); fValue);
/*
sprintf(pBueffel,"anticollision started %s to %f",self->motorName, sprintf(pBueffel,"anticollision started %s to %f",self->motorName,
fValue); fValue);
SCWrite(pCon,pBueffel,eValue); SCWrite(pCon,pBueffel,eValue);
*/
pDriv->SetValue = oldSet; pDriv->SetValue = oldSet;
self->iActive = 1; self->iActive = 1;
@ -121,9 +123,13 @@ int CheckRegMot(pMotReg self, SConnection *pCon){
int stat; int stat;
assert(self); assert(self);
stat = self->originalCheckStatus(self->motorData,pCon); if(self->iActive){
if(stat != HWBusy){ stat = self->originalCheckStatus(self->motorData,pCon);
self->iActive = 0; if(stat != HWBusy){
self->iActive = 0;
}
} else {
return HWIdle;
} }
return stat;
} }

2032
napi.c

File diff suppressed because it is too large Load Diff

207
napi.h
View File

@ -1,7 +1,7 @@
/*--------------------------------------------------------------------------- /*---------------------------------------------------------------------------
NeXus - Neutron & X-ray Common Data Format NeXus - Neutron & X-ray Common Data Format
NeXus API header file Application Program Interface Header File
Copyright (C) 2000-2003 Mark Koennecke, Uwe Filges Copyright (C) 2000-2003 Mark Koennecke, Uwe Filges
@ -19,14 +19,6 @@
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact : Mark Koennecke <Mark.Koennecke@psi.ch>
Uwe Filges <Uwe.Filges@psi.ch>
Labor fuer Neutronenstreuung
Paul Scherrer Institut
CH-5232 Villigen-PSI
Switzerland
For further information, see <http://www.neutron.anl.gov/NeXus/> For further information, see <http://www.neutron.anl.gov/NeXus/>
----------------------------------------------------------------------------*/ ----------------------------------------------------------------------------*/
@ -35,22 +27,30 @@
#define NEXUSAPI #define NEXUSAPI
/* NeXus HDF45 */ /* 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 int NXstatus;
typedef char NXname[128]; 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 { typedef struct {
char *iname; char *iname;
int type; int type;
}info_type, *pinfo; }info_type, *pinfo;
#define NX_OK 1 #define NX_OK 1
#define NX_ERROR 0 #define NX_ERROR 0
@ -79,22 +79,19 @@ typedef struct {
NX_UINT32 32 bit unsigned integer NX_UINT32 32 bit unsigned integer
NX_CHAR 8 bit character 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 */ /* Map NeXus to HDF types */
#define NX_FLOAT32 5 #define NX_FLOAT32 5
#define NX_FLOAT64 6 #define NX_FLOAT64 6
#define NX_INT8 20 #define NX_INT8 20
#define NX_UINT8 21 #define NX_UINT8 21
#define NX_INT16 22 #define NX_INT16 22
#define NX_UINT16 23 #define NX_UINT16 23
#define NX_INT32 24 #define NX_INT32 24
#define NX_UINT32 25 #define NX_UINT32 25
#define NX_CHAR 4 #define NX_CHAR 4
/* Map NeXus compression methods to HDF compression methods */ /* Map NeXus compression methods to HDF compression methods */
#define NX_COMP_NONE 100 #define NX_COMP_NONE 100
@ -107,6 +104,10 @@ typedef struct {
#include <mfhdf.h> #include <mfhdf.h>
#endif #endif
#ifdef HDF5
#include <hdf5.h>
#endif
typedef struct { typedef struct {
#ifdef HDF4 #ifdef HDF4
int32 iTag; /* HDF4 variable */ int32 iTag; /* HDF4 variable */
@ -124,57 +125,138 @@ typedef struct {
#define NXMAXSTACK 50 #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 CALLING_STYLE /* blank */
# define NXclose MANGLE(nxiclose)
# define NXmakegroup MANGLE(nximakegroup) # define NXopen MANGLE(nxiopen)
# define NXopengroup MANGLE(nxiopengroup) # define NXclose MANGLE(nxiclose)
# define NXclosegroup MANGLE(nxiclosegroup) # define NXmakegroup MANGLE(nximakegroup)
# define NXmakedata MANGLE(nximakedata) # define NXopengroup MANGLE(nxiopengroup)
# define NXcompmakedata MANGLE(nxicompmakedata) # define NXclosegroup MANGLE(nxiclosegroup)
# define NXcompress MANGLE(nxicompress) # define NXmakedata MANGLE(nximakedata)
# define NXopendata MANGLE(nxiopendata) # define NXcompmakedata MANGLE(nxicompmakedata)
# define NXclosedata MANGLE(nxiclosedata) # define NXcompress MANGLE(nxicompress)
# define NXputdata MANGLE(nxiputdata) # define NXopendata MANGLE(nxiopendata)
# define NXputslab MANGLE(nxiputslab) # define NXclosedata MANGLE(nxiclosedata)
# define NXputattr MANGLE(nxiputattr) # define NXputdata MANGLE(nxiputdata)
# define NXgetdataID MANGLE(nxigetdataid) # define NXputslab MANGLE(nxiputslab)
# define NXmakelink MANGLE(nximakelink) # define NXputattr MANGLE(nxiputattr)
# define NXmalloc MANGLE(nximalloc) # define NXgetdataID MANGLE(nxigetdataid)
# define NXfree MANGLE(nxifree) # define NXmakelink MANGLE(nximakelink)
# define NXmalloc MANGLE(nximalloc)
# define NXfree MANGLE(nxifree)
# define NXflush MANGLE(nxiflush) # define NXflush MANGLE(nxiflush)
# define NXgetinfo MANGLE(nxigetinfo) # define NXgetinfo MANGLE(nxigetinfo)
# define NXgetnextentry MANGLE(nxigetnextentry) # define NXgetnextentry MANGLE(nxigetnextentry)
# define NXgetdata MANGLE(nxigetdata) # define NXgetdata MANGLE(nxigetdata)
# define NXgetslab MANGLE(nxigetslab) # define NXgetslab MANGLE(nxigetslab)
# define NXgetnextattr MANGLE(nxigetnextattr) # define NXgetnextattr MANGLE(nxigetnextattr)
# define NXgetattr MANGLE(nxigetattr) # define NXgetattr MANGLE(nxigetattr)
# define NXgetattrinfo MANGLE(nxigetattrinfo) # define NXgetattrinfo MANGLE(nxigetattrinfo)
# define NXgetgroupID MANGLE(nxigetgroupid) # define NXgetgroupID MANGLE(nxigetgroupid)
# define NXgetgroupinfo MANGLE(nxigetgroupinfo) # define NXgetgroupinfo MANGLE(nxigetgroupinfo)
# define NXinitgroupdir MANGLE(nxiinitgroupdir) # define NXsameID MANGLE(nxisameid)
# define NXinitattrdir MANGLE(nxiinitattrdir) # define NXinitgroupdir MANGLE(nxiinitgroupdir)
# define NXsetcache MANGLE(nxisetcache) # define NXinitattrdir MANGLE(nxiinitattrdir)
# define NXsetcache MANGLE(nxisetcache)
/* FORTRAN helpers - for NeXus internal use only */ /* FORTRAN helpers - for NeXus internal use only */
# define NXfopen MANGLE(nxifopen) # define NXfopen MANGLE(nxifopen)
# define NXfclose MANGLE(nxifclose) # define NXfclose MANGLE(nxifclose)
# define NXfflush MANGLE(nxifflush) # define NXfflush MANGLE(nxifflush)
# define NXfmakedata MANGLE(nxifmakedata) # define NXfmakedata MANGLE(nxifmakedata)
# define NXfcompmakedata MANGLE(nxifcompmakedata) # define NXfcompmakedata MANGLE(nxifcompmakedata)
# define NXfcompress MANGLE(nxifcompress) # define NXfcompress MANGLE(nxifcompress)
# define NXfputattr MANGLE(nxifputattr) # 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 * 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 NXopen(CONSTCHAR * filename, NXaccess access_method, NXhandle* pHandle);
NX_EXTERNAL NXstatus CALLING_STYLE NXclose(NXhandle* pHandle); NX_EXTERNAL NXstatus CALLING_STYLE NXclose(NXhandle* pHandle);
NX_EXTERNAL NXstatus CALLING_STYLE NXflush(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 NXgetattrinfo(NXhandle handle, int* no_items);
NX_EXTERNAL NXstatus CALLING_STYLE NXgetgroupID(NXhandle handle, NXlink* pLink); 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 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 NXinitgroupdir(NXhandle handle);
NX_EXTERNAL NXstatus CALLING_STYLE NXinitattrdir(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); NX_EXTERNAL NXstatus CALLING_STYLE NXsetcache(long newVal);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /*NEXUSAPI*/ #endif /*NEXUSAPI*/

52
napi4.c
View File

@ -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 <http://www.neutron.anl.gov/NeXus/>
----------------------------------------------------------------------------*/
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -290,6 +314,8 @@
/* map Nexus NXaccess types to HDF4 types */ /* map Nexus NXaccess types to HDF4 types */
if (am == NXACC_CREATE) { if (am == NXACC_CREATE) {
am1 = DFACC_CREATE; am1 = DFACC_CREATE;
} else if (am == NXACC_CREATE4) {
am1 = DFACC_CREATE;
} else if (am == NXACC_READ) { } else if (am == NXACC_READ) {
am1 = DFACC_READ; am1 = DFACC_READ;
} else if (am == NXACC_RDWR) { } else if (am == NXACC_RDWR) {
@ -318,7 +344,7 @@
#else #else
time_info = gmtime(&timer); time_info = gmtime(&timer);
if (time_info != NULL) { if (time_info != NULL) {
gmt_offset = difftime(timer, mktime(time_info)); gmt_offset = (long)difftime(timer, mktime(time_info));
} else { } else {
NXIReportError(NXpData, "Your gmtime() function does not work ... timezone information will be incorrect\n"); NXIReportError(NXpData, "Your gmtime() function does not work ... timezone information will be incorrect\n");
gmt_offset = 0; gmt_offset = 0;
@ -350,7 +376,7 @@
* write something that can be used by OLE * 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 ) { if ( (file_id = Hopen(filename, am1, 0)) == -1 ) {
sprintf (pBuffer, "ERROR: cannot open file_a: %s", filename); sprintf (pBuffer, "ERROR: cannot open file_a: %s", filename);
NXIReportError (NXpData, pBuffer); NXIReportError (NXpData, pBuffer);
@ -395,7 +421,7 @@
return NX_ERROR; 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) { if (SDsetattr(pNew->iSID, "file_name", DFNT_CHAR8, strlen(filename), (char*)filename) < 0) {
NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute ");
return NX_ERROR; return NX_ERROR;
@ -410,7 +436,7 @@
* Otherwise we try to create the file two times which makes HDF * Otherwise we try to create the file two times which makes HDF
* Throw up on us. * Throw up on us.
*/ */
if (am == NXACC_CREATE) { if (am == NXACC_CREATE || am == NXACC_CREATE4) {
am = NXACC_RDWR; am = NXACC_RDWR;
am1 = DFACC_RDWR; am1 = DFACC_RDWR;
} }
@ -424,7 +450,7 @@
/* start Vgroup API */ /* start Vgroup API */
pNew->iVID = Hopen (filename, am1, 100); pNew->iVID = Hopen(filename, am1, 100);
if (pNew->iVID <= 0) { if (pNew->iVID <= 0) {
sprintf (pBuffer, "ERROR: cannot open file_c: %s", filename); sprintf (pBuffer, "ERROR: cannot open file_c: %s", filename);
NXIReportError (NXpData, pBuffer); NXIReportError (NXpData, pBuffer);
@ -1644,7 +1670,7 @@
return NX_ERROR; return NX_ERROR;
} }
*iN = iAtt; *iN = iAtt;
return iRet; return NX_OK;
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
@ -1690,6 +1716,20 @@
return NX_OK; 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;
}
}
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/

341
napi5.c
View File

@ -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 <http://www.neutron.anl.gov/NeXus/>
----------------------------------------------------------------------------*/
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -9,17 +33,15 @@
int *iTagDir; int *iTagDir;
char irefn[1024]; char irefn[1024];
int iVref; int iVref;
int iCurrentIDX;
} iStack5[NXMAXSTACK]; } iStack5[NXMAXSTACK];
struct iStack5 iAtt5; struct iStack5 iAtt5;
int iVID; int iVID;
int iFID; int iFID;
int fapl;
int iCurrentG; int iCurrentG;
int iCurrentD; int iCurrentD;
int iCurrentS; int iCurrentS;
int iCurrentT; int iCurrentT;
int iCurrentIDX;
unsigned int iCurrentA_IDX;
int iCurrentA; int iCurrentA;
int iNX; int iNX;
int iNXID; int iNXID;
@ -56,6 +78,7 @@
free (self->iStack5[self->iStackPtr].iTagDir); free (self->iStack5[self->iStackPtr].iTagDir);
self->iStack5[self->iStackPtr].iTagDir = NULL; self->iStack5[self->iStackPtr].iTagDir = NULL;
} }
self->iStack5[self->iStackPtr].iCurrentIDX = 0;
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
@ -70,6 +93,7 @@
free (self->iAtt5.iTagDir); free (self->iAtt5.iTagDir);
self->iAtt5.iTagDir = NULL; 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; hid_t attr1,aid1, aid2;
pNexusFile5 pNew = NULL; pNexusFile5 pNew = NULL;
@ -90,6 +114,7 @@
const char* time_format; const char* time_format;
long gmt_offset; long gmt_offset;
unsigned int vers_major, vers_minor, vers_release, am1 ; unsigned int vers_major, vers_minor, vers_release, am1 ;
hid_t fapl;
int mdc_nelmts, rdcc_nelmts; int mdc_nelmts, rdcc_nelmts;
size_t rdcc_nbytes; size_t rdcc_nbytes;
double rdcc_w0; double rdcc_w0;
@ -126,7 +151,7 @@
time_info = gmtime(&timer); time_info = gmtime(&timer);
if (time_info != NULL) if (time_info != NULL)
{ {
gmt_offset = difftime(timer, mktime(time_info)); gmt_offset = (long)difftime(timer, mktime(time_info));
} }
else else
{ {
@ -163,12 +188,12 @@
} }
/* start HDF5 interface */ /* start HDF5 interface */
if (am == NXACC_CREATE5) { if (am == NXACC_CREATE5) {
pNew->fapl = H5Pcreate(H5P_FILE_ACCESS); fapl = H5Pcreate(H5P_FILE_ACCESS);
iRet=H5Pget_cache(pNew->fapl,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0); iRet=H5Pget_cache(fapl,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0);
rdcc_nbytes=(size_t)cacheSize; 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; am1 = H5F_ACC_TRUNC;
pNew->iFID = H5Fcreate (filename, am1, H5P_DEFAULT, pNew->fapl); pNew->iFID = H5Fcreate (filename, am1, H5P_DEFAULT, fapl);
} else { } else {
if (am == NXACC_READ) { if (am == NXACC_READ) {
am1 = H5F_ACC_RDONLY; am1 = H5F_ACC_RDONLY;
@ -289,14 +314,8 @@
pNexusFile5 pFile = NULL; pNexusFile5 pFile = NULL;
int iRet; int iRet;
pFile = NXI5assert(*fid); pFile=NXI5assert(*fid);
if (pFile->fapl != NULL) { iRet=0;
iRet = H5Pclose(pFile->fapl);
if (iRet < 0) {
NXIReportError (NXpData, "ERROR: HDF cannot close plist.");
}
}
iRet = 0;
iRet = H5Fclose(pFile->iFID); iRet = H5Fclose(pFile->iFID);
if (iRet < 0) { if (iRet < 0) {
NXIReportError (NXpData, "ERROR: HDF cannot close HDF file"); NXIReportError (NXpData, "ERROR: HDF cannot close HDF file");
@ -305,11 +324,6 @@
NXI5KillDir (pFile); NXI5KillDir (pFile);
free (pFile); free (pFile);
*fid = NULL; *fid = NULL;
iRet = 0;
iRet = H5close();
if (iRet < 0) {
NXIReportError (NXpData, "ERROR: HDF cannot close HDF library");
}
return NX_OK; return NX_OK;
} }
@ -364,7 +378,7 @@
herr_t attr_check (hid_t loc_id, const char *member_name, void *opdata) 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"); strcpy(attr_name,"NX_class");
return strstr(member_name, attr_name) ? 1 : 0; return strstr(member_name, attr_name) ? 1 : 0;
@ -391,7 +405,7 @@
/* check group attribute */ /* check group attribute */
iRet = H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL); iRet = H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL);
if (iRet < 0) { if (iRet < 0) {
NXIReportError (NXpData, "ERROR iterating thourgh group!"); NXIReportError (NXpData, "ERROR iterating through group!");
return NX_ERROR; return NX_ERROR;
} else if (iRet == 1) { } else if (iRet == 1) {
/* group attribute was found */ /* group attribute was found */
@ -400,7 +414,7 @@
NXIReportError (NXpData, "No group attribute available"); NXIReportError (NXpData, "No group attribute available");
return NX_ERROR; return NX_ERROR;
} }
/* check contains of group attribute */ /* check contents of group attribute */
attr1 = H5Aopen_name(pFile->iCurrentG, "NX_class"); attr1 = H5Aopen_name(pFile->iCurrentG, "NX_class");
atype=H5Tcopy(H5T_C_S1); atype=H5Tcopy(H5T_C_S1);
H5Tset_size(atype,128); H5Tset_size(atype,128);
@ -433,7 +447,7 @@
/* check group attribute */ /* check group attribute */
iRet=H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL); iRet=H5Aiterate(pFile->iCurrentG,NULL,attr_check,NULL);
if (iRet < 0) { if (iRet < 0) {
NXIReportError (NXpData, "ERROR iterating thourgh group!"); NXIReportError (NXpData, "ERROR iterating through group!");
return NX_ERROR; return NX_ERROR;
} else if (iRet == 1) { } else if (iRet == 1) {
/* group attribute was found */ /* group attribute was found */
@ -461,8 +475,7 @@
pFile->iStackPtr++; pFile->iStackPtr++;
pFile->iStack5[pFile->iStackPtr].iVref=pFile->iCurrentG; pFile->iStack5[pFile->iStackPtr].iVref=pFile->iCurrentG;
strcpy(pFile->iStack5[pFile->iStackPtr].irefn,name); strcpy(pFile->iStack5[pFile->iStackPtr].irefn,name);
pFile->iCurrentIDX=0; pFile->iAtt5.iCurrentIDX=0;
pFile->iCurrentA_IDX=0;
pFile->iCurrentLGG = strdup(name); pFile->iCurrentLGG = strdup(name);
NXI5KillDir (pFile); NXI5KillDir (pFile);
return NX_OK; return NX_OK;
@ -502,7 +515,7 @@
for (i=0; i<ii; i++) { for (i=0; i<ii; i++) {
*(u1name + i) = *(uname + i); *(u1name + i) = *(uname + i);
} }
*(u1name + i) = NULL; *(u1name + i) = '\0';
/* /*
strncpy(u1name, uname, ii); strncpy(u1name, uname, ii);
*/ */
@ -514,42 +527,17 @@
strcpy(pFile->name_ref,""); strcpy(pFile->name_ref,"");
strcpy(pFile->name_tmp,""); strcpy(pFile->name_tmp,"");
} }
NXI5KillDir (pFile);
pFile->iStackPtr--; pFile->iStackPtr--;
if (pFile->iStackPtr>0) { if (pFile->iStackPtr>0) {
pFile->iCurrentG=pFile->iStack5[pFile->iStackPtr].iVref; pFile->iCurrentG=pFile->iStack5[pFile->iStackPtr].iVref;
} else { } else {
pFile->iCurrentG=0; pFile->iCurrentG=0;
} }
NXI5KillDir (pFile);
} }
pFile->iCurrentIDX=0;
pFile->iCurrentA_IDX=0;
return NX_OK; 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, NXstatus CALLING_STYLE NX5compmakedata (NXhandle fid, CONSTCHAR *name, int datatype,
@ -659,7 +647,7 @@
cparms = H5Pcreate(H5P_DATASET_CREATE); cparms = H5Pcreate(H5P_DATASET_CREATE);
iNew = H5Pset_chunk(cparms,rank,chunkdims); iNew = H5Pset_chunk(cparms,rank,chunkdims);
if (iNew < 0) { 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; return NX_ERROR;
} }
H5Pset_deflate(cparms,6); H5Pset_deflate(cparms,6);
@ -669,7 +657,7 @@
cparms = H5Pcreate(H5P_DATASET_CREATE); cparms = H5Pcreate(H5P_DATASET_CREATE);
iNew = H5Pset_chunk(cparms,rank,chunkdims); iNew = H5Pset_chunk(cparms,rank,chunkdims);
if (iNew < 0) { 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; return NX_ERROR;
} }
iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, cparms); iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, cparms);
@ -677,11 +665,11 @@
iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT); iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT);
} }
} else { } 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); iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT);
} }
if (iRet < 0) { if (iRet < 0) {
NXIReportError (NXpData, "ERROR: Creating chuncked Dataset failed!"); NXIReportError (NXpData, "ERROR: Creating chunked dataset failed!");
return NX_ERROR; return NX_ERROR;
} else { } else {
pFile->iCurrentD = iRet; pFile->iCurrentD = iRet;
@ -709,12 +697,37 @@
return NX_OK; 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) NXstatus CALLING_STYLE NX5compress (NXhandle fid, int compress_type)
{ {
printf(" NXcompress ERROR: NeXus API based on HDF5 don't supports\n"); printf(" NXcompress ERROR: NeXus API based on HDF5 doesn't support\n");
printf(" NXcompress function! Using HDF5 library\n"); printf(" NXcompress function! Using HDF5 library,\n");
printf(" the NXcompmakedata function can be applied\n"); printf(" the NXcompmakedata function can be applied\n");
printf(" for compression of data!\n"); printf(" for compression of data!\n");
return NX_ERROR; return NX_ERROR;
@ -782,27 +795,15 @@
{ {
pNexusFile5 pFile; pNexusFile5 pFile;
NXname pBuffer; NXname pBuffer;
hid_t iRet, xfer_plist; hid_t iRet;
size_t size;
char pError[512]; char pError[512];
pFile = NXI5assert (fid); 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 */ /* actually write */
iRet = H5Dwrite (pFile->iCurrentD, pFile->iCurrentT, H5S_ALL, H5S_ALL, iRet = H5Dwrite (pFile->iCurrentD, pFile->iCurrentT, H5S_ALL, H5S_ALL,
xfer_plist, data); H5P_DEFAULT, data);
H5Pclose(xfer_plist);
if (iRet < 0) { if (iRet < 0) {
sprintf (pError, "ERROR: failure to write data to %s", pBuffer); sprintf (pError, "ERROR: failure to write data to %s", pBuffer);
NXIReportError (NXpData, pError); NXIReportError (NXpData, pError);
@ -882,7 +883,7 @@
} }
if (H5Awrite(attr1,aid1,data) < 0) 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; return NX_ERROR;
} }
/* Close attribute dataspace */ /* Close attribute dataspace */
@ -934,38 +935,18 @@
{ {
pNexusFile5 pFile; pNexusFile5 pFile;
int iRet, i; int iRet, i;
int rank, size_id; int rank;
hssize_t myStart[H5S_MAX_RANK]; hssize_t myStart[H5S_MAX_RANK];
hsize_t mySize[H5S_MAX_RANK]; hsize_t mySize[H5S_MAX_RANK];
hsize_t size[1],maxdims[H5S_MAX_RANK]; hsize_t size[1],maxdims[H5S_MAX_RANK];
size_t buff_size; hid_t filespace,dataspace;
hid_t filespace, dataspace, xfer_plist;
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
/* check if there is an Dataset open */ /* check if there is an Dataset open */
if (pFile->iCurrentD == 0) { if (pFile->iCurrentD == 0) {
NXIReportError (NXpData, "ERROR: no Dataset open"); NXIReportError (NXpData, "ERROR: no dataset open");
return NX_ERROR; 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); rank = H5Sget_simple_extent_ndims(pFile->iCurrentS);
for(i = 0; i < rank; i++) for(i = 0; i < rank; i++)
{ {
@ -991,7 +972,7 @@
} }
/* write slab */ /* write slab */
iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace,
filespace, xfer_plist, data); filespace, H5P_DEFAULT,data);
iRet = H5Sclose(filespace); iRet = H5Sclose(filespace);
} else { } else {
/* define slab */ /* define slab */
@ -1005,10 +986,9 @@
} }
/* write slab */ /* write slab */
iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace,
pFile->iCurrentS, xfer_plist, data); pFile->iCurrentS, H5P_DEFAULT,data);
} }
/* deal with HDF errors */ /* deal with HDF errors */
H5Pclose(xfer_plist);
iRet = H5Sclose(dataspace); iRet = H5Sclose(dataspace);
if (iRet < 0) if (iRet < 0)
{ {
@ -1035,7 +1015,7 @@
NXstatus CALLING_STYLE NX5makelink (NXhandle fid, NXlink* sLink) NXstatus CALLING_STYLE NX5makelink (NXhandle fid, NXlink* sLink)
{ {
pNexusFile5 pFile; pNexusFile5 pFile;
int iRet; /* int iRet; */
herr_t status; herr_t status;
int size_type; int size_type;
@ -1137,7 +1117,7 @@
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
op_data.iname = NULL; op_data.iname = NULL;
idx=pFile->iCurrentIDX; idx=pFile->iStack5[pFile->iStackPtr].iCurrentIDX;
if (strlen(pFile->name_ref) == 0) { if (strlen(pFile->name_ref) == 0) {
/* root group */ /* root group */
strcpy(pFile->name_ref,"/"); strcpy(pFile->name_ref,"/");
@ -1146,7 +1126,7 @@
strcpy(nxclass,""); strcpy(nxclass,"");
if (iRet > 0) if (iRet > 0)
{ {
pFile->iCurrentIDX++; pFile->iStack5[pFile->iStackPtr].iCurrentIDX++;
strcpy(name,op_data.iname); strcpy(name,op_data.iname);
if (op_data.iname != NULL) { if (op_data.iname != NULL) {
free(op_data.iname); free(op_data.iname);
@ -1234,6 +1214,7 @@
if (op_data.iname != NULL) { if (op_data.iname != NULL) {
free(op_data.iname); free(op_data.iname);
} }
pFile->iStack5[pFile->iStackPtr].iCurrentIDX = 0;
return NX_EOD; return NX_EOD;
} }
else else
@ -1253,18 +1234,69 @@
{ {
pNexusFile5 pFile; pNexusFile5 pFile;
int iStart[H5S_MAX_RANK]; int iStart[H5S_MAX_RANK];
hid_t data_id, memtype_id, size_id, sign_id;
int dims;
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
/* check if there is an Dataset open */ /* check if there is an Dataset open */
if (pFile->iCurrentD == 0) if (pFile->iCurrentD == 0)
{ {
NXIReportError (NXpData, "ERROR: no Dataset open"); NXIReportError (NXpData, "ERROR: no Dataset open");
return NX_ERROR; return NX_ERROR;
} }
memset (iStart, 0, H5S_MAX_RANK * sizeof(int)); memset (iStart, 0, H5S_MAX_RANK * sizeof(int));
/* actually read */ /* 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;
}
}
H5Dread (pFile->iCurrentD, pFile->iCurrentT, H5S_ALL, H5S_ALL,H5P_DEFAULT, data); /* actually read */
H5Dread (pFile->iCurrentD, memtype_id, H5S_ALL, H5S_ALL,H5P_DEFAULT, data);
return NX_OK; return NX_OK;
} }
@ -1360,9 +1392,10 @@
hsize_t mySize[H5S_MAX_RANK]; hsize_t mySize[H5S_MAX_RANK];
hssize_t mStart[H5S_MAX_RANK]; hssize_t mStart[H5S_MAX_RANK];
hid_t memspace, iRet, data_id; hid_t memspace, iRet, data_id;
hid_t memtype_id, size_id, sign_id;
char *tmp_data; char *tmp_data;
char *data1; char *data1;
int i, iRank, mtype = 0; int i, dims, iRank, mtype = 0;
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
/* check if there is an Dataset open */ /* check if there is an Dataset open */
@ -1408,16 +1441,64 @@
NXIReportError (NXpData, "ERROR: Select memspace failed"); NXIReportError (NXpData, "ERROR: Select memspace failed");
return NX_ERROR; 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 */ /* read slab */
if (mtype == NX_CHAR) { 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); H5S_ALL, H5P_DEFAULT,tmp_data);
data1 = tmp_data + myStart[0]; data1 = tmp_data + myStart[0];
strncpy(data,data1,(hsize_t)iSize[0]); strncpy(data,data1,(hsize_t)iSize[0]);
free(tmp_data); free(tmp_data);
} else { } else {
iRet = H5Dread(pFile->iCurrentD, pFile->iCurrentT, memspace, iRet = H5Dread(pFile->iCurrentD, memtype_id, memspace,
pFile->iCurrentS, H5P_DEFAULT,data); pFile->iCurrentS, H5P_DEFAULT,data);
} }
@ -1450,18 +1531,18 @@
unsigned int idx; unsigned int idx;
pFile = NXI5assert (fileid); pFile = NXI5assert (fileid);
idx=pFile->iCurrentA_IDX; idx=pFile->iAtt5.iCurrentIDX;
if ((pFile->iCurrentD == 0) && (pFile->iCurrentG==0)) if ((pFile->iCurrentD == 0) && (pFile->iCurrentG==0))
{ {
/* global attribute */ /* global attribute */
pFile->iVID=H5Gopen(pFile->iFID,"/"); pFile->iVID=H5Gopen(pFile->iFID,"/");
iRet=H5Aiterate(pFile->iVID,&idx,attr_info,&iname); iRet=H5Aiterate(pFile->iVID,&idx,attr_info,&iname);
} else { } else {
iRet=H5Aiterate(pFile->iCurrentD,&idx,attr_info,&iname); iRet=H5Aiterate(pFile->iCurrentD,&idx,attr_info,&iname);
} }
if (iRet>0) if (iRet>0)
{ {
pFile->iCurrentA_IDX++; pFile->iAtt5.iCurrentIDX++;
strcpy(pName, iname); strcpy(pName, iname);
if (iname != NULL) { if (iname != NULL) {
free(iname); free(iname);
@ -1545,10 +1626,10 @@
} }
if (idx == 0) if (idx == 0)
{ {
NXIReportError (NXpData, "Dataset has no attributes!"); pFile->iAtt5.iCurrentIDX = 0;
return NX_EOD; return NX_EOD;
} }
pFile->iAtt5.iCurrentIDX = 0;
return NX_EOD; return NX_EOD;
} }
else else
@ -1812,7 +1893,23 @@
return NX_ERROR; 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) NXstatus CALLING_STYLE NX5initattrdir (NXhandle fid)
{ {
@ -1820,7 +1917,6 @@
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
NXI5KillAttDir (fid); NXI5KillAttDir (fid);
pFile->iCurrentA_IDX=0;
return NX_OK; return NX_OK;
} }
@ -1832,6 +1928,5 @@
pFile = NXI5assert (fid); pFile = NXI5assert (fid);
NXI5KillDir (fid); NXI5KillDir (fid);
pFile->iCurrentIDX=0;
return NX_OK; return NX_OK;
} }

View File

@ -34,8 +34,9 @@
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <mfhdf.h>
#include "lld.h" #include "lld.h"
#include "napi.h" #include "../napi.h"
#include "stringdict.h" #include "stringdict.h"
#include "dynstring.h" #include "dynstring.h"
#include "nxdict.h" #include "nxdict.h"

716
nxscript.c Normal file
View File

@ -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 <stdlib.h>
#include <assert.h>
#include <errno.h>
#include <tcl.h>
#include <unistd.h>
#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;
}

20
nxscript.h Normal file
View File

@ -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

48
nxscript.w Normal file
View File

@ -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
@}

3
ofac.c
View File

@ -110,6 +110,7 @@
#include "anticollider.h" #include "anticollider.h"
#include "gpibcontroller.h" #include "gpibcontroller.h"
#include "ecb.h" #include "ecb.h"
#include "nxscript.h"
/*----------------------- Server options creation -------------------------*/ /*----------------------- Server options creation -------------------------*/
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData, static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]) int argc, char *argv[])
@ -295,6 +296,7 @@
AddCommand(pInter,"AntiCollisionInstall",AntiColliderFactory,NULL,NULL); AddCommand(pInter,"AntiCollisionInstall",AntiColliderFactory,NULL,NULL);
AddCommand(pInter,"MakeGPIB",MakeGPIB,NULL,NULL); AddCommand(pInter,"MakeGPIB",MakeGPIB,NULL,NULL);
AddCommand(pInter,"MakeECB",MakeECB,NULL,NULL); AddCommand(pInter,"MakeECB",MakeECB,NULL,NULL);
AddCommand(pInter,"MakeNXScript",MakeNXScript,NULL,NULL);
} }
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
static void KillIniCommands(SicsInterp *pSics) static void KillIniCommands(SicsInterp *pSics)
@ -357,6 +359,7 @@
RemoveCommand(pSics,"AntiColliderInstall"); RemoveCommand(pSics,"AntiColliderInstall");
RemoveCommand(pSics,"MakeGPIB"); RemoveCommand(pSics,"MakeGPIB");
RemoveCommand(pSics,"MakeECB"); RemoveCommand(pSics,"MakeECB");
RemoveCommand(pSics,"MakeNXScript");
} }

View File

@ -206,3 +206,4 @@ Publish LogBook User
source $root/bin/count.tcl source $root/bin/count.tcl
Publish count User Publish count User
Publish Repeat User Publish Repeat User

139
sans2.dic Normal file
View File

@ -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

599
sans2.tcl Normal file
View File

@ -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

261
sans2com.tcl Normal file
View File

@ -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
}

View File

@ -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 # Motor atz
atz sign 1.000000 atz sign 1.000000
atz SoftZero 0.000000 atz SoftZero 0.000000
@ -134,6 +155,22 @@ sr SoftUpperLim 10000.000000
sr Fixed -1.000000 sr Fixed -1.000000
sr InterruptMode 0.000000 sr InterruptMode 0.000000
sr AccessCode 2.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 KohlSulfid
samplename setAccess 2 samplename setAccess 2
comment UNKNOWN comment UNKNOWN

31
tdchm.c
View File

@ -73,7 +73,7 @@ static int downloadConfiguration(pTdc self){
case HMY: case HMY:
function = 130; function = 130;
break; break;
caseHMXY: case HMXY:
function = 128; function = 128;
break; break;
default: default:
@ -154,12 +154,6 @@ static int TDCConfigure(pHistDriver self, SConnection *pCon,
tdc->fillByte = 0; tdc->fillByte = 0;
status = downloadConfiguration(tdc);
if(!status){
tdc->errorCode = status;
return 0;
}
status = StringDictGet(pOpt,"ecb",pValue,79); status = StringDictGet(pOpt,"ecb",pValue,79);
assert(status); assert(status);
tdc->tdc = FindCommandData(pSics,pValue,"ECB"); tdc->tdc = FindCommandData(pSics,pValue,"ECB");
@ -168,6 +162,13 @@ static int TDCConfigure(pHistDriver self, SConnection *pCon,
return 0; return 0;
} }
status = downloadConfiguration(tdc);
if(!status){
tdc->errorCode = status;
return 0;
}
self->iReconfig = 0; self->iReconfig = 0;
return 1; return 1;
@ -265,13 +266,21 @@ static int TDCCountStatus(pHistDriver self, SConnection *pCon){
assert(tdc); assert(tdc);
if(tdc->counter != NULL){ 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 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, static int TDCGetError(pHistDriver self, int *iCode, char *perror,
@ -472,7 +481,7 @@ static int TDCGetHistogram(pHistDriver self, SConnection *pCon,
tdc = (pTdc)self->pPriv; tdc = (pTdc)self->pPriv;
assert(tdc); assert(tdc);
if(length >= MAXTDCCHANNELS){ if(length > MAXTDCCHANNELS){
tdc->errorCode = MAXEXCEEDED; tdc->errorCode = MAXEXCEEDED;
return HWFault; return HWFault;
} }