diff --git a/Makefile b/Makefile index a1870b52..8cd90ede 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ macro.o ofac.o obpar.o obdes.o drive.o status.o intserv.o \ devexec.o mumo.o mumoconf.o selector.o selvar.o fupa.o lld.o \ lld_blob.o buffer.o strrepl.o ruli.o lin2ang.o fomerge.o\ - script.o o2t.o alias.o napi.o nxdata.o stringdict.o sdynar.o\ + script.o o2t.o alias.o napi45.o nxdata.o stringdict.o sdynar.o\ histmem.o histdriv.o histsim.o sinqhmdriv.o interface.o callback.o \ event.o emon.o evcontroller.o evdriver.o simev.o perfmon.o \ danu.o itc4driv.o itc4.o nxdict.o nxsans.o varlog.o stptok.o nread.o \ @@ -48,7 +48,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ circular.o el755driv.o maximize.o sicscron.o tecsdriv.o sanscook.o \ tasinit.o tasutil.o t_rlp.o t_conv.o d_sign.o d_mod.o \ tasdrive.o tasscan.o synchronize.o definealias.o swmotor.o t_update.o \ - hmcontrol.o userscan.o + hmcontrol.o userscan.o slsmagnet.o rs232controller.o MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o COUNTEROBJ = countdriv.o simcter.o counter.o @@ -62,14 +62,16 @@ VELOOBJ = velo.o velosim.o velodorn.o velodornier.o #------------- for Digital Unix BINTARGET=bin -HDFROOT=/data/koenneck +HDFROOT=/data/lnslib CC=cc EXTRA= -CFLAGS = -I$(HDFROOT)/include -Ihardsup -I. -std1 -g -warnprotos -c -#CFLAGS = -I$(HDFROOT)/include -DFORTIFY -Ihardsup -g -std1 -warnprotos -c +CFLAGS = -I$(HDFROOT)/include -Ihardsup -DHDF4 -DHDF5 -I. -std1 \ + -g -warnprotos -c +#CFLAGS = -I$(HDFROOT)/include -DFORTIFY -DHDF4 -DHDF5 -Ihardsup -g \ +# -std1 -warnprotos -c LIBS = -L$(HDFROOT)/lib -Lhardsup -lhlib -Lmatrix -lmatrix -Ltecs \ - -ltecsl -ltcl8.0 -lfor -lmfhdf -ldf $(HDFROOT)/lib/libjpeg.a \ - -lz -lm -ll -lc + -ltecsl -ltcl8.0 -lfor $(HDFROOT)/lib/libhdf5.a \ + -lmfhdf -ldf $(HDFROOT)/lib/libjpeg.a -lz -lm -ll -lc #------- for cygnus #HDFROOT=../HDF411 diff --git a/amor.dic b/amor.dic index e2a0c37d..4ca96224 100644 --- a/amor.dic +++ b/amor.dic @@ -15,6 +15,7 @@ timebin=512 detxsize=255 detysize=255 scanlength = 10 +chunk = #---------- NXentry level etitle=/entry1,NXentry/SDS title -type DFNT_CHAR -rank 1 -dim {132} estart=/entry1,NXentry/SDS start_time -type DFNT_CHAR -rank 1 -dim {132} @@ -181,10 +182,12 @@ dettime=/entry1,NXentry/reflectometer,NXinstrument/TOF,NXdetector/SDS time_binni -attr {units,ms} spinup=/entry1,NXentry/reflectometer,NXinstrument/TOF,NXdetector/SDS spinup \ -type DFNT_INT32 -rank 3 -dim {$(detxsize),$(detysize),$(timebin)} \ - -LZW -attr {signal,1} + -LZW $(chunk) -attr {signal,1} +detchunk=/entry1,NXentry/reflectometer,NXinstrument/TOF,NXdetector/SDS \ + chunksize -type DFNT_INT32 -rank 1 -dim {3} spinup2d=/entry1,NXentry/reflectometer,NXinstrument/TOF,NXdetector/SDS spinup \ -type DFNT_INT32 -rank 2 -dim {$(detxsize),$(detysize)} \ - -LZW -attr {signal,1} + -LZW $(chunk) -attr {signal,1} spindown=/entry1,NXentry/reflectometer,NXinstrument/TOF,NXdetector/SDS spindown \ -type DFNT_INT32 -rank 3 -dim {$(detxsize),$(detysize),$(timebin)} \ -LZW -attr {signal,1} diff --git a/amortest.tcl b/amortest.tcl index 82785625..d233208e 100644 --- a/amortest.tcl +++ b/amortest.tcl @@ -185,7 +185,8 @@ Motor COX SIM -100. 100. .1 2. # counter x ClientPut "Motors initialized" #======================== histogram memory -MakeHM hm SinqHM +#MakeHM hm SinqHM +MakeHM hm SIM hm configure HistMode PSD hm configure OverFlowMode Ceil hm configure Rank 1 @@ -203,7 +204,7 @@ hm configure HMComputer psds03.psi.ch hm configure HMPort 2400 hm configure Counter counter hm configure init 0 -hm genbin 0. 33 5 +hm genbin 0. 33 1024 hm init ClientPut "Histogram Memory Initialized" diff --git a/danu.dat b/danu.dat index dbd081e4..265dcb48 100644 --- a/danu.dat +++ b/danu.dat @@ -1,3 +1,3 @@ - 24 + 103 NEVER, EVER modify or delete this file You'll risk eternal damnation and a reincarnation as a cockroach!|n \ No newline at end of file diff --git a/doc/manager/hwini.htm b/doc/manager/hwini.htm index cb950bd0..08010e30 100644 --- a/doc/manager/hwini.htm +++ b/doc/manager/hwini.htm @@ -213,10 +213,31 @@ After this, the parameter can be modified by a command like:
 drive vname newvalue
 
-

+

+

RS232 Controller Direct Access

+

+RS232 controllers connected to a terminal server can be directly accessed +by SICS through the TCP/IP network, bypassing the SerPortServer +program. See the description of this facility +for more details. Such a controller can be configured into the system +through the command: +

+MakeRS232Controller name terminalserver port
+
+For example: +
+MakeRS232Controller hugo psts213 3004
+
+name is the SICS name for the controller, terminalserver is the name +of the terminal server the device is connected to and port is the port +number at which the terminal server publishes the RS232 channel to +which the device is connected. This is usally the port number plus 3000. +

+

To be expanded. Please note, that environment devices such as temperature controllers are dynamically configured into the system at run time. Therefore the necessary commands are described in the user documentation. +

diff --git a/doc/manager/managerman b/doc/manager/managerman index efe89d0c..4fc7c0ba 100644 --- a/doc/manager/managerman +++ b/doc/manager/managerman @@ -53,6 +53,7 @@ which is described elsewhere. %html iscan.htm 2 %html alias.htm 2 %html cron.htm 2 +%html rs232.htm 2 %html ../user/trouble.htm 1 %html move.htm 1 \end{document} diff --git a/doc/manager/special.htm b/doc/manager/special.htm index cf127b96..8be8e3f3 100644 --- a/doc/manager/special.htm +++ b/doc/manager/special.htm @@ -13,6 +13,8 @@ This section describes a few commands which need not be known to SICS users.
  • Accessing Siematic SPS controllers.
  • Aliases.
  • Reoccuring tasks. +
  • Direct access to RS232 controllers through + the terminal server.

    diff --git a/doc/user/samenv.htm b/doc/user/samenv.htm index 93d334c8..e4c7cca0 100644 --- a/doc/user/samenv.htm +++ b/doc/user/samenv.htm @@ -25,6 +25,8 @@ controller.
  • Eurotherm Temperature Controller.
  • Bruker Magnet Controller.
  • The PSI-EL755 Magnet Controller. +
  • The PSI-DSP Magnet Controller, also known as +SLS controller.

    @@ -651,6 +653,40 @@ connects to power supply 3 at the EL755-controller connected to lnsa09 at channel 5. The magnet is then available in the system as maggi. No special commands are supported for the EL755.

    + +

    PSI-DSP Magnet Controller

    +

    +The PSI-DSP magnet controller has been developed by the PSI +electronics group, most notably by Lukas Tanner, for the +SLS. However, these controllers are now being used at SINQ as +well. This controller has a binary command protocoll and thus the send +command does not work for it. In order to handle this protocoll SICS +has to bypass the usual SerPortServer mechanism for communicating with +serial devices +and to connect to the terminal server directly. This also implies one +gotcha: +The PSI-DSP works only at specially configured terminal server +ports.The terminal server +port to which the PSI-DSP is connected MUST be configured to: +115200 baud, 8 data bits, 1 stop bit, odd parity. In general a system +manager is required to do this. The PSI-DSP also requires a null-modem +connector between the box and the terminal server. Once these hurdles +have been mastered, the PSI-DSP can be configured into SICS with the +command: +

    +evfactory new name psi-dsp terminalservername port +
    +with name being the name of the magnet in SICS, terminalservername the +name of the terminal server, for example psts224 and port being the +address of the binary port on the terminal server. This is usually +the serial port number at the terminal server plus 3000. An example: +
    +evfactory new maggi psi-dsp psts224 3016 +
    +configures a magnet named maggi which is connectd to port 16 at the +terminal server psts224. maggi can now be read and driven like any +other environment device. +

    diff --git a/evcontroller.c b/evcontroller.c index 91867651..79608785 100644 --- a/evcontroller.c +++ b/evcontroller.c @@ -63,6 +63,12 @@ #include "tecsdriv.h" #include "chadapter.h" #include "status.h" + +/* + from slsmagnet.c +*/ +extern pEVDriver CreateSLSDriv(int argc, char *argv[]); + /*--------------------- Functions needed to implement interfaces -----------*/ static long EVIDrive(void *pData, SConnection *pCon, float fVal) { @@ -1434,6 +1440,17 @@ return 0; } } + else if(strcmp(argv[3],"psi-dsp") == 0) /* PSI-DSP magnet driver */ + { + /* Create a driver */ + pDriv = CreateSLSDriv(argc-4,&argv[4]); + if(!pDriv) + { + SCWrite(pCon, + "ERROR: failed to create PSI-DSP device driver",eError); + return 0; + } + } else if(strcmp(argv[3],"el755") == 0) /* EL755 magnet driver */ { /* Create a driver */ diff --git a/histsim.c b/histsim.c index 4dff8888..410e541f 100644 --- a/histsim.c +++ b/histsim.c @@ -181,16 +181,16 @@ #else if(iSet == 1) { - for(ii = iStart; ii < iEnd; ii++) + for(ii = iStart; ii < iStart + iEnd; ii++) { - lData[ii] = iSetVal; + lData[ii-iStart] = iSetVal; } } else { - for(ii = iStart; ii < iEnd; ii++) + for(ii = iStart; ii < iStart + iEnd; ii++) { - lData[ii] = random(); + lData[ii-iStart] = random(); } } #endif diff --git a/hkl.c b/hkl.c index 3d72ed62..4a5158fa 100644 --- a/hkl.c +++ b/hkl.c @@ -477,7 +477,7 @@ return -1; } theta = 2 * asin(v); - omega = .5 * theta - delomr; + omega = (.5 * theta) - delomr; sinchi = -z[2]/cos(delomr); if(ABS(sinchi) > 1.) @@ -777,6 +777,7 @@ fVal = fLower + 5.; /* same */ } fDelom = fSet[1] - fVal; + fDelom = -fDelom; } iTest += MotorCheckBoundary(self->pChi,fSet[2], &fHard,pError,131); iTest += MotorCheckBoundary(self->pPhi,fSet[3], &fHard,pError,131); diff --git a/napi.c b/napi.c index 1a5edaf3..97310d98 100644 --- a/napi.c +++ b/napi.c @@ -35,7 +35,7 @@ ----------------------------------------------------------------------------*/ -static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* Revision interted by CVS */ +static const char* rscid = "$Id: napi.c,v 1.5 2001/10/25 13:58:00 cvs Exp $"; /* Revision interted by CVS */ #include #include @@ -70,13 +70,24 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* /*---------------------------------------------------------------------*/ static void NXNXNXReportError(void *pData, char *string) { - printf("%s \n",string); +#if defined(_WIN32) && ( defined(_DLL) || defined(_HDFDLL_) ) && !defined(_CONSOLE) && !defined(JNEXUS) +/* + * printf() output may get lost in Windows applications without a console ... this code + * makes them appear in Dialog boxes. To use printf(), you would probably have to create + * a console window with AllocConsole(), or get hold of "stdout" from the main program + * and then use fprintf(main_program_stdout, ... ) rather then printf(...) + */ + MessageBeep(MB_ICONEXCLAMATION); + MessageBox(NULL, string, "NeXus Error", MB_ICONSTOP | MB_OK | MB_TASKMODAL | MB_SETFOREGROUND); +#else + printf("%s \n",string); +#endif /* _WIN32 */ } /*---------------------------------------------------------------------*/ void *NXpData = NULL; void (*NXIReportError)(void *pData, char *string) = NXNXNXReportError; /*---------------------------------------------------------------------*/ - void NXMSetError(void *pData, void (*NewError)(void *pD, char *text)) + void CALLING_STYLE NXMSetError(void *pData, void (*NewError)(void *pD, char *text)) { NXpData = pData; NXIReportError = NewError; @@ -321,7 +332,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* * NXhandle. We could store the NXhandle value in the FORTRAN array * instead, but that would mean writing far more wrappers */ - NXstatus NXfopen(char * filename, NXaccess* am, NexusFile* pHandle) + NXstatus CALLING_STYLE NXfopen(char * filename, NXaccess* am, NexusFile* pHandle) { NXstatus ret; NXhandle fileid = NULL; @@ -341,24 +352,17 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return ret; } -/* - * the following deals with how we do our timezone calculation. - * Not all systems have a timezone field as part of "struct tm" - * that is passed to localtime(), so we need to look elsewhere - * - * If you encounter problems, try defining USE_FTIME first, with - * NEED_TZSET is your system provides the tzset() function +/* + * On Open VMS prior to version 7.0 timezone support wasn't complete and gmtime() always returned NULL */ - -#if defined(_WIN32) -# define NEED_TZSET /* call tzset() to initialise time variables */ -# define USE_TIMEZONE /* use timezone and daylight variables */ -#elif (defined(__VMS) && (__VMS_VER < 70000000)) +#if (defined(__VMS) && (__VMS_VER < 70000000)) # define USE_FTIME /* use ftime() function */ # include #endif /* __VMS && __VMS_VER < 70000000 */ - NXstatus NXopen(CONSTCHAR * filename, NXaccess am, NXhandle* pHandle) +/* #define NEED_TZSET /* probably not needed now as we do not use the "timezone" external variable */ + + NXstatus CALLING_STYLE NXopen(CONSTCHAR * filename, NXaccess am, NXhandle* pHandle) { pNexusFile pNew = NULL; char pBuffer[512], time_buffer[64]; @@ -387,21 +391,26 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* tzset(); #endif /* NEED_TZSET */ time(&timer); - time_info = localtime(&timer); -#if defined(USE_TIMEZONE) - gmt_offset = -timezone + ( (daylight != 0) ? 3600 : 0 ); -#elif defined(USE_FTIME) +#ifdef USE_FTIME ftime(&timeb_struct); gmt_offset = -timeb_struct.timezone * 60; if (timeb_struct.dstflag != 0) { gmt_offset += 3600; } -#elif defined(__MWERKS__) - gmt_offset = difftime (timer, mktime(gmtime(&timer))); #else - gmt_offset = time_info->tm_gmtoff; -#endif + time_info = gmtime(&timer); + if (time_info != NULL) + { + gmt_offset = difftime(timer, mktime(time_info)); + } + else + { + NXIReportError(NXpData, "Your gmtime() function does not work ... timezone information will be incorrect\n"); + gmt_offset = 0; + } +#endif /* USE_FTIME */ + time_info = localtime(&timer); if (time_info != NULL) { if (gmt_offset < 0) @@ -507,7 +516,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } /* start Vgroup API */ - pNew->iVID = Hopen (filename, am, 5000); + pNew->iVID = Hopen (filename, am, 100); if (pNew->iVID <= 0) { sprintf (pBuffer, "ERROR: cannot open file: %s", filename); NXIReportError (NXpData, pBuffer); @@ -528,8 +537,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* * array holding the NexusFile structure. We need to malloc() * a temporary copy as NXclose will try to free() this */ - NXstatus - NXfclose (NexusFile* pHandle) + NXstatus CALLING_STYLE NXfclose (NexusFile* pHandle) { NXhandle h; NXstatus ret; @@ -540,8 +548,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return ret; } - NXstatus - NXclose (NXhandle* fid) + NXstatus CALLING_STYLE NXclose (NXhandle* fid) { pNexusFile pFile = NULL; int iRet; @@ -574,9 +581,102 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* *fid = NULL; return NX_OK; } - +/*--------------------------------------------------------------------------- + For the same reasons as stated above we need a wrapper for the fortran + version of NXFlush + ---------------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXfflush(NexusFile* pHandle) + { + NXhandle h; + NXstatus ret; + h = (NXhandle)malloc(sizeof(NexusFile)); + memcpy(h, pHandle, sizeof(NexusFile)); + ret = NXflush(&h); /* modifies and reallocates h */ + memcpy(pHandle, h, sizeof(NexusFile)); + return ret; + } + +/*----------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXflush(NXhandle *pHandle) + { + char *pFileName, *pCopy = NULL; + int access, dummy, iRet, i, iStack; + pNexusFile pFile = NULL; + NXaccess ac; + int *iRefs = NULL; + + pFile = NXIassert(*pHandle); + + /* + The HDF4-API does not support a flush. We help ourselves with + inquiring the name and access type of the file, closing it and + opening it again. This is also the reason why this needs a pointer + to the handle structure as the handle changes. The other thing we + do is to store the refs of all open vGroups in a temporary array + in order to recover the position in the vGroup hierarchy before the + flush. + */ + iRet = Hfidinquire(pFile->iVID,&pFileName,&access,&dummy); + if (iRet < 0) { + NXIReportError (NXpData, + "ERROR: Failed to inquire file name for HDF file"); + return NX_ERROR; + } + if(pFile->iAccess[0] == 'r') { + ac = NXACC_READ; + }else if(pFile->iAccess[0] == 'w') { + ac = NXACC_RDWR; + } + pCopy = (char *)malloc((strlen(pFileName)+10)*sizeof(char)); + if(!pCopy) { + NXIReportError (NXpData, + "ERROR: Failed to allocate data for filename copy"); + return NX_ERROR; + } + memset(pCopy,0,strlen(pFileName)+10); + strcpy(pCopy,pFileName); + + /* get refs for recovering vGroup position */ + iStack = 0; + if(pFile->iStackPtr > 0) { + iStack = pFile->iStackPtr + 1; + iRefs = (int *)malloc(iStack*sizeof(int)); + if(!iRefs){ + NXIReportError (NXpData, + "ERROR: Failed to allocate data for hierarchy copy"); + return NX_ERROR; + } + for(i = 0; i < iStack; i++){ + iRefs[i] = pFile->iStack[i].iVref; + } + } + + iRet = NXclose(pHandle); + if(iRet != NX_OK) { + return iRet; + } + + iRet = NXopen(pCopy, ac, pHandle); + free(pCopy); - NXstatus NXmakegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) { + /* return to position in vGroup hierarchy */ + pFile = NXIassert(*pHandle); + if(iStack > 0){ + pFile->iStackPtr = iStack - 1; + for(i = 0; i < iStack; i++){ + pFile->iStack[i].iVref = iRefs[i]; + } + free(iRefs); + pFile->iCurrentVG = Vattach(pFile->iVID, + pFile->iStack[pFile->iStackPtr].iVref, + pFile->iAccess); + } + + return iRet; + } +/*-----------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXmakegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + { pNexusFile pFile; int32 iNew, iRet; char pBuffer[256]; @@ -617,8 +717,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* /*------------------------------------------------------------------------*/ - NXstatus - NXopengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + NXstatus CALLING_STYLE NXopengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) { pNexusFile pFile; int32 iNew, iRef; @@ -650,8 +749,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } - NXstatus - NXclosegroup (NXhandle fid) + NXstatus CALLING_STYLE NXclosegroup (NXhandle fid) { pNexusFile pFile; @@ -681,7 +779,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_OK; } - NXstatus NXfmakedata(NXhandle fid, char *name, int *pDatatype, + NXstatus CALLING_STYLE NXfmakedata(NXhandle fid, char *name, int *pDatatype, int *pRank, int dimensions[]) { NXstatus ret; @@ -706,7 +804,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return ret; } - NXstatus NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, + NXstatus CALLING_STYLE NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, int dimensions[]) { pNexusFile pFile; @@ -750,7 +848,12 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* NXIReportError (NXpData, pBuffer); return NX_ERROR; } - for (i = 0; i < rank; i++) { + + /* + Check dimensions for consistency. The first dimension may be 0 + thus denoting an unlimited dimension. + */ + for (i = 1; i < rank; i++) { if (dimensions[i] <= 0) { sprintf (pBuffer, "ERROR: invalid dimension %d, value %d given for SDS %s", @@ -802,8 +905,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } - NXstatus - NXopendata (NXhandle fid, CONSTCHAR *name) + NXstatus CALLING_STYLE NXopendata (NXhandle fid, CONSTCHAR *name) { pNexusFile pFile; int32 iNew; @@ -843,13 +945,12 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } - NXstatus NXfcompress(NXhandle fid, int *compr_type) + NXstatus CALLING_STYLE NXfcompress(NXhandle fid, int *compr_type) { return NXcompress(fid,*compr_type); } - NXstatus - NXcompress (NXhandle fid, int compress_type) + NXstatus CALLING_STYLE NXcompress (NXhandle fid, int compress_type) { pNexusFile pFile; int32 iRank, iAtt, iType, iRet, i, e; @@ -892,8 +993,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_OK; } - NXstatus - NXclosedata (NXhandle fid) + NXstatus CALLING_STYLE NXclosedata (NXhandle fid) { pNexusFile pFile; int iRet; @@ -916,8 +1016,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } - NXstatus - NXgetdata (NXhandle fid, void *data) + NXstatus CALLING_STYLE NXgetdata (NXhandle fid, void *data) { pNexusFile pFile; int32 iStart[MAX_VAR_DIMS], iSize[MAX_VAR_DIMS]; @@ -940,8 +1039,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } - NXstatus - NXgetslab (NXhandle fid, void *data, int iStart[], int iSize[]) + NXstatus CALLING_STYLE NXgetslab (NXhandle fid, void *data, int iStart[], int iSize[]) { pNexusFile pFile; int32 myStart[MAX_VAR_DIMS], mySize[MAX_VAR_DIMS]; @@ -983,11 +1081,10 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } - NXstatus - NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) + NXstatus CALLING_STYLE NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) { pNexusFile pFile; - int32 iNew; + int32 iNew, iType32; void *pData = NULL; int32 iLen, iRet; char pBuffer[256]; @@ -1010,11 +1107,13 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_ERROR; } /* get more info, allocate temporary data space */ + iType32 = (int32)*iType; if (pFile->iCurrentSDS != 0) { - iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, (int32*)iType, &iLen); + iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, &iType32, &iLen); } else { - iRet = SDattrinfo (pFile->iSID, iNew, pNam, (int32*)iType, &iLen); + iRet = SDattrinfo (pFile->iSID, iNew, pNam, &iType32, &iLen); } + *iType = (int)iType32; if (iRet < 0) { sprintf (pBuffer, "ERROR: HDF could not read attribute info"); NXIReportError (NXpData, pBuffer); @@ -1050,46 +1149,8 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_OK; } - NXstatus - NXsetdimname(NXhandle fid, int iDim, CONSTCHAR *name) - { - pNexusFile pFile; - int32 dim_id, iRet; - - pFile = NXIassert (fid); - /* check if there is an SDS open */ - if (pFile->iCurrentSDS == 0) { - NXIReportError (NXpData, "ERROR: no SDS open"); - return NX_ERROR; - } - - /* - get dimension ID - */ - dim_id = SDgetdimid(pFile->iCurrentSDS,iDim); - if(dim_id < 0){ - NXIReportError(NXpData, - "ERROR: trying to set dimension name for non existent dimension"); - return NX_ERROR; - } - - /* - set name - */ - iRet = SDsetdimname(dim_id,name); - if(iRet < 0){ - NXIReportError(NXpData, - "ERROR: failed to set dimension name"); - return NX_ERROR; - } - - return NX_OK; - } - - - NXstatus - NXputdata (NXhandle fid, void *data) + NXstatus CALLING_STYLE NXputdata (NXhandle fid, void *data) { pNexusFile pFile; int32 iStart[MAX_VAR_DIMS], iSize[MAX_VAR_DIMS], iStride[MAX_VAR_DIMS]; @@ -1124,8 +1185,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_OK; } - NXstatus - NXputslab (NXhandle fid, void *data, int iStart[], int iSize[]) + NXstatus CALLING_STYLE NXputslab (NXhandle fid, void *data, int iStart[], int iSize[]) { pNexusFile pFile; int iRet; @@ -1167,8 +1227,8 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* else { /* write directly */ - iRet = SDwritedata (pFile->iCurrentSDS, (int32 *) iStart, - iStride, (int32 *) iSize, data); + iRet = SDwritedata (pFile->iCurrentSDS,(int32*)iStart, + iStride, (int32*)iSize, data); } /* deal with HDF errors */ @@ -1179,14 +1239,13 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_OK; } - NXstatus - NXfputattr(NXhandle fid, char *name, void *data, int *pDatalen, int *pIType) + NXstatus CALLING_STYLE NXfputattr(NXhandle fid, char *name, void *data, int *pDatalen, int *pIType) { return NXputattr(fid, name, data, *pDatalen, *pIType); } NXstatus - NXputattr (NXhandle fid, CONSTCHAR *name, void *data, int datalen, int iType) + CALLING_STYLE NXputattr (NXhandle fid, CONSTCHAR *name, void *data, int datalen, int iType) { pNexusFile pFile; int iRet; @@ -1212,7 +1271,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* NXstatus - NXgetinfo (NXhandle fid, int *rank, int dimension[], int *iType) + CALLING_STYLE NXgetinfo (NXhandle fid, int *rank, int dimension[], int *iType) { pNexusFile pFile; NXname pBuffer; @@ -1241,7 +1300,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* /*-------------------------------------------------------------------------*/ NXstatus - NXgetgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) + CALLING_STYLE NXgetgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) { pNexusFile pFile; @@ -1262,7 +1321,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* /*-------------------------------------------------------------------------*/ NXstatus - NXgetattrinfo (NXhandle fid, int *iN) + CALLING_STYLE NXgetattrinfo (NXhandle fid, int *iN) { pNexusFile pFile; int iRet; @@ -1287,7 +1346,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } NXstatus - NXinitgroupdir (NXhandle fid) + CALLING_STYLE NXinitgroupdir (NXhandle fid) { pNexusFile pFile; int iRet; @@ -1305,7 +1364,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* /*-------------------------------------------------------------------------*/ NXstatus - NXgetnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype) + CALLING_STYLE NXgetnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype) { pNexusFile pFile; int iRet, iStackPtr, iCurDir; @@ -1385,7 +1444,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* /*-------------------------------------------------------------------------*/ NXstatus - NXinitattrdir (NXhandle fid) + CALLING_STYLE NXinitattrdir (NXhandle fid) { pNexusFile pFile; int iRet; @@ -1400,7 +1459,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* /*-------------------------------------------------------------------------*/ NXstatus - NXgetnextattr (NXhandle fileid, NXname pName, + CALLING_STYLE NXgetnextattr (NXhandle fileid, NXname pName, int *iLength, int *iType) { pNexusFile pFile; @@ -1441,7 +1500,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* NXstatus - NXgetgroupID (NXhandle fileid, NXlink* sRes) + CALLING_STYLE NXgetgroupID (NXhandle fileid, NXlink* sRes) { pNexusFile pFile; @@ -1452,7 +1511,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_ERROR; } else { sRes->iTag = DFTAG_VG; - sRes->iRef = VQueryref(pFile->iCurrentVG); + sRes->iRef = pFile->iStack[pFile->iStackPtr].iVref; return NX_OK; } /* not reached */ @@ -1462,7 +1521,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* NXstatus - NXgetdataID (NXhandle fid, NXlink* sRes) + CALLING_STYLE NXgetdataID (NXhandle fid, NXlink* sRes) { pNexusFile pFile; @@ -1480,23 +1539,31 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* return NX_ERROR; /* not reached */ } - NXstatus - NXmakelink (NXhandle fid, NXlink* sLink) + NXstatus CALLING_STYLE NXmakelink (NXhandle fid, NXlink* sLink) { pNexusFile pFile; + int32 iVG, iRet; pFile = NXIassert (fid); if (pFile->iCurrentVG == 0) { /* root level, can not link here */ return NX_ERROR; } - Vaddtagref (pFile->iCurrentVG, sLink->iTag, sLink->iRef); + if(sLink->iTag == DFTAG_VG) + { + iVG = Vattach (pFile->iVID, sLink->iRef,pFile->iAccess); + iRet = Vinsert(pFile->iCurrentVG,iVG); + iRet = Vdetach(iVG); + } + else + { + Vaddtagref (pFile->iCurrentVG, sLink->iTag, sLink->iRef); + } return NX_OK; } /* allocate space for an array of given dimensions and type */ - NXstatus - NXmalloc (void** data, int rank, int dimensions[], int datatype) + NXstatus CALLING_STYLE NXmalloc (void** data, int rank, int dimensions[], int datatype) { int i; size_t size = 1; @@ -1536,8 +1603,7 @@ static const char* rscid = "$Id: napi.c,v 1.4 2001/06/08 15:18:37 cvs Exp $"; /* } /* free space allocated by NXmalloc */ - NXstatus - NXfree (void** data) + NXstatus CALLING_STYLE NXfree (void** data) { if (data == NULL) { diff --git a/napi.h b/napi.h index 23f57519..84d734c0 100644 --- a/napi.h +++ b/napi.h @@ -3,7 +3,7 @@ NeXus API header file - Copyright (C) 1997-2000 Mark Koennecke, Przemek Klosowski + Copyright (C) 2000-2003 Mark Koennecke, Uwe Filges This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -20,73 +20,52 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact : Mark Koennecke + Uwe Filges Labor fuer Neutronenstreuung Paul Scherrer Institut CH-5232 Villigen-PSI Switzerland - Przemek Klosowski - NIST Center for Neutron Research - 100 Bureau Drive, Stop 8562 - Gaithersburg, MD 20899-8562 - USA - + For further information, see - $Id: napi.h,v 1.3 2001/06/08 15:18:37 cvs Exp $ - -----------------------------------------------------------------------------*/ - + ----------------------------------------------------------------------------*/ + #ifndef NEXUSAPI #define NEXUSAPI -#define NEXUS_VERSION "1.3.1" /* major.minor.patch */ -#ifdef GENIE_IMPLEMENTATION__ /* OpenGENIE is fussy about consts */ -# define CONSTCHAR const char -#else -# define CONSTCHAR char -#endif /* GENIE_IMPLEMENTATION__ */ +/* NeXus HDF45 */ +#define NEXUS_VERSION "2.1.0." /* major.minor.patch */ -/* - * check for ints.h header on VMS - it defines conflicting types - */ -#if defined(__VMS) && defined(__INTS_LOADED) -# define int8 hdf_int8 -# define int16 hdf_int16 -# define uint16 hdf_uint16 -# define int32 hdf_int32 -# define uint32 hdf_uint32 -# include -# undef int8 -# undef int16 -# undef uint16 -# undef int32 -# undef uint32 -#else -# include -#endif /* defined(__VMS) && defined(__INTS_LOADED) */ +#define CONSTCHAR char -typedef enum {NXACC_READ = DFACC_READ, - NXACC_RDWR = DFACC_RDWR, - NXACC_CREATE = DFACC_CREATE } NXaccess; +#define NX_EXTERNAL typedef void* NXhandle; /* really a pointer to a NexusFile structure */ typedef int NXstatus; -typedef char NXname[VGNAMELENMAX]; +typedef char NXname[128]; - typedef struct { - int32 iTag; - int32 iRef; - } NXlink; +typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE5=4} NXaccess; +typedef struct { + char *iname; + int type; + }info_type, *pinfo; + #define NX_OK 1 #define NX_ERROR 0 #define NX_EOD -1 +#define NX_UNLIMITED -1 + #define NX_MAXRANK 32 #define NX_MAXNAMELEN 64 + + + + /*------------------------------------------------------------------------- HDF Datatype values for datatype parameters in the Nexus API @@ -108,46 +87,49 @@ typedef char NXname[VGNAMELENMAX]; /* Map NeXus to HDF types */ -#define NX_FLOAT32 DFNT_FLOAT32 -#define NX_FLOAT64 DFNT_FLOAT64 -#define NX_INT8 DFNT_INT8 -#define NX_UINT8 DFNT_UINT8 -#define NX_INT16 DFNT_INT16 -#define NX_UINT16 DFNT_UINT16 -#define NX_INT32 DFNT_INT32 -#define NX_UINT32 DFNT_UINT32 -#define NX_CHAR DFNT_CHAR8 +#define NX_FLOAT32 5 +#define NX_FLOAT64 6 +#define NX_INT8 20 +#define NX_UINT8 21 +#define NX_INT16 22 +#define NX_UINT16 23 +#define NX_INT32 24 +#define NX_UINT32 25 +#define NX_CHAR 4 /* Map NeXus compression methods to HDF compression methods */ -#define NX_COMP_NONE COMP_CODE_NONE -#define NX_COMP_LZW COMP_CODE_DEFLATE -#define NX_COMP_RLE COMP_CODE_RLE -#define NX_COMP_HUF COMP_CODE_SKPHUFF +#define NX_COMP_NONE 100 +#define NX_COMP_LZW 200 +#define NX_COMP_RLE 300 +#define NX_COMP_HUF 400 -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ -/* - * Now, we have the interface visible from FORTRAN and C. On UNIX system - * FORTRAN routines usually get an extra training - * Do not mangle using "_" as f2c mangles _ containing and non _ - * containing names differently - * We must also lowercase anything that is called from FORTRAN - * else we can't link - */ +#ifdef HDF4 +#include +#endif + +typedef struct { +#ifdef HDF4 + int32 iTag; /* HDF4 variable */ + int32 iRef; /* HDF4 variable */ +#endif + +#ifdef HDF5 + char iTag5[1024]; /* HDF5 variable */ + char iRef5[1024]; /* HDF5 variable */ + char iRefd[1024]; /* HDF5 variable */ +#endif + } NXlink; + + + +#define NXMAXSTACK 50 #define CONCAT(__a,__b) __a##__b /* token concatenation */ -/* - * Define a macro for FORTRAN name mangling _ pften we have to add an "_" - */ -#if defined(__VMS) || defined(__unix__) || defined(__MWERKS__) -# if defined(__VMS) || defined(__MWERKS__) || defined(__ABSOFT) -# define MANGLE(__arg) __arg -# else /* unix */ -# define MANGLE(__arg) CONCAT(__arg,_) -# endif +#define MANGLE(__arg) CONCAT(__arg,_) + +#define CALLING_STYLE /* blank */ # define NXopen MANGLE(nxiopen) # define NXclose MANGLE(nxiclose) @@ -155,132 +137,91 @@ extern "C" { # define NXopengroup MANGLE(nxiopengroup) # define NXclosegroup MANGLE(nxiclosegroup) # define NXmakedata MANGLE(nximakedata) +# define NXcompmakedata MANGLE(nxicompmakedata) # define NXcompress MANGLE(nxicompress) # define NXopendata MANGLE(nxiopendata) # define NXclosedata MANGLE(nxiclosedata) -# define 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 NXinitgroupdir MANGLE(nxiinitgroupdir) -# define NXgetnextentry MANGLE(nxigetnextentry) -# define NXgetattrinfo MANGLE(nxigetattrinfo) -# define NXinitattrdir MANGLE(nxiinitattrdir) -# define NXgetnextattr MANGLE(nxigetnextattr) -# define NXgetgroupID MANGLE(nxigetgroupid) +# define NXputdata MANGLE(nxiputdata) +# define NXputslab MANGLE(nxiputslab) +# define NXputattr MANGLE(nxiputattr) # define NXgetdataID MANGLE(nxigetdataid) # define NXmakelink MANGLE(nximakelink) # define NXmalloc MANGLE(nximalloc) # define NXfree MANGLE(nxifree) +# define NXflush MANGLE(nxiflush) + +# define NXgetinfo MANGLE(nxigetinfo) +# define NXgetnextentry MANGLE(nxigetnextentry) +# define NXgetdata MANGLE(nxigetdata) + +# define NXgetslab MANGLE(nxigetslab) +# define NXgetnextattr MANGLE(nxigetnextattr) +# define NXgetattr MANGLE(nxigetattr) +# define NXgetattrinfo MANGLE(nxigetattrinfo) +# define NXgetgroupID MANGLE(nxigetgroupid) +# define NXgetgroupinfo MANGLE(nxigetgroupinfo) +# define NXinitgroupdir MANGLE(nxiinitgroupdir) +# define NXinitattrdir MANGLE(nxiinitattrdir) /* 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) -#elif defined(_WIN32) -/* - * Various PC calling converntions - */ -/* # define MANGLE(__arg) __stdcall CONCAT(__arg,_) */ -/* # define MANGLE(__arg) CONCAT(__arg,_) */ -# define MANGLE(__arg) __stdcall __arg -# define NXopen NXIOPEN_ -# define NXclose NXICLOSE_ -# define NXmakegroup MANGLE(NXIMAKEGROUP) -# define NXopengroup MANGLE(NXIOPENGROUP) -# define NXclosegroup MANGLE(NXICLOSEGROUP) -# define NXmakedata 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 NXIPUTATTR_ -# define NXputdim MANGLE(NXIPUTDIM) -# define NXgetinfo MANGLE(NXIGETINFO) -# define NXgetgroupinfo MANGLE(NXIGETGROUPINFO) -# 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 NXfmakedata MANGLE(NXIFMAKEDATA) -# define NXfcompress MANGLE(NXIFCOMPRESS) -# define NXfputattr MANGLE(NXIFPUTATTR) -#else -# error Cannot compile - unknown operating system -#endif + /* * Standard interface */ - NXstatus NXopen(CONSTCHAR * filename, NXaccess access_method, NXhandle* pHandle); - NXstatus NXclose(NXhandle* pHandle); - - NXstatus NXmakegroup (NXhandle handle, CONSTCHAR* Vgroup, char* NXclass); - NXstatus NXopengroup (NXhandle handle, CONSTCHAR* Vgroup, char* NXclass); - NXstatus NXclosegroup(NXhandle handle); - - NXstatus NXmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); - NXstatus NXsetdimname(NXhandle handle, int iDim, CONSTCHAR *name); - NXstatus NXopendata (NXhandle handle, CONSTCHAR* label); - NXstatus NXcompress (NXhandle handle, int compr_type); - NXstatus NXclosedata(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NXopen(CONSTCHAR * filename, NXaccess access_method, NXhandle* pHandle); +NX_EXTERNAL NXstatus CALLING_STYLE NXclose(NXhandle* pHandle); +NX_EXTERNAL NXstatus CALLING_STYLE NXflush(NXhandle* pHandle); - NXstatus NXgetdata(NXhandle handle, void* data); - NXstatus NXgetslab(NXhandle handle, void* data, int start[], int size[]); - NXstatus NXgetattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); +NX_EXTERNAL NXstatus CALLING_STYLE NXmakegroup (NXhandle handle, CONSTCHAR *name, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NXopengroup (NXhandle handle, CONSTCHAR *name, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NXclosegroup(NXhandle handle); - NXstatus NXputdata(NXhandle handle, void* data); - NXstatus NXputslab(NXhandle handle, void* data, int start[], int size[]); - NXstatus NXputattr(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType); - - NXstatus NXgetinfo(NXhandle handle, int* rank, int dimension[], int* datatype); - NXstatus NXgetgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass); - NXstatus NXinitgroupdir(NXhandle handle); - NXstatus NXgetnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype); - NXstatus NXgetattrinfo(NXhandle handle, int* no_items); - NXstatus NXinitattrdir(NXhandle handle); - NXstatus NXgetnextattr(NXhandle handle, NXname pName, int *iLength, int *iType); - - NXstatus NXgetgroupID(NXhandle handle, NXlink* pLink); - NXstatus NXgetdataID(NXhandle handle, NXlink* pLink); - NXstatus NXmakelink(NXhandle handle, NXlink* pLink); - -/* - * Helper interface - */ +NX_EXTERNAL NXstatus CALLING_STYLE NXmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); +NX_EXTERNAL NXstatus CALLING_STYLE NXcompmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]); +NX_EXTERNAL NXstatus CALLING_STYLE NXcompress (NXhandle handle, int compr_type); +NX_EXTERNAL NXstatus CALLING_STYLE NXopendata (NXhandle handle, CONSTCHAR* label); +NX_EXTERNAL NXstatus CALLING_STYLE NXclosedata(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NXputdata(NXhandle handle, void* data); + +NX_EXTERNAL NXstatus CALLING_STYLE NXputattr(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType); +NX_EXTERNAL NXstatus CALLING_STYLE NXputslab(NXhandle handle, void* data, int start[], int size[]); + +NX_EXTERNAL NXstatus CALLING_STYLE NXgetdataID(NXhandle handle, NXlink* pLink); +NX_EXTERNAL NXstatus CALLING_STYLE NXmakelink(NXhandle handle, NXlink* pLink); + +NX_EXTERNAL NXstatus CALLING_STYLE NXgetdata(NXhandle handle, void* data); +NX_EXTERNAL NXstatus CALLING_STYLE NXgetinfo(NXhandle handle, int* rank, int dimension[], int* datatype); +NX_EXTERNAL NXstatus CALLING_STYLE NXgetnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype); + +NX_EXTERNAL NXstatus CALLING_STYLE NXgetslab(NXhandle handle, void* data, int start[], int size[]); +NX_EXTERNAL NXstatus CALLING_STYLE NXgetnextattr(NXhandle handle, NXname pName, int *iLength, int *iType); +NX_EXTERNAL NXstatus CALLING_STYLE NXgetattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); +NX_EXTERNAL NXstatus CALLING_STYLE NXgetattrinfo(NXhandle handle, int* no_items); +NX_EXTERNAL NXstatus CALLING_STYLE NXgetgroupID(NXhandle handle, NXlink* pLink); +NX_EXTERNAL NXstatus CALLING_STYLE NXgetgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass); + +NX_EXTERNAL NXstatus CALLING_STYLE NXinitgroupdir(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NXinitattrdir(NXhandle handle); + +NX_EXTERNAL NXstatus CALLING_STYLE NXmalloc(void** data, int rank, int dimensions[], int datatype); +NX_EXTERNAL NXstatus CALLING_STYLE NXfree(void** data); - NXstatus NXmalloc(void** data, int rank, int dimensions[], int datatype); - NXstatus NXfree(void** data); /*----------------------------------------------------------------------- A non Nexus standard function to set an error handler */ - void NXMSetError(void *pData, void (*ErrFunc)(void *pD, char *text)); +NX_EXTERNAL void CALLING_STYLE NXMSetError(void *pData, void (*ErrFunc)(void *pD, char *text)); + + +#endif /*NEXUSAPI*/ + -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* NEXUSAPI */ diff --git a/network.c b/network.c index 3688c10e..92f65761 100644 --- a/network.c +++ b/network.c @@ -402,7 +402,7 @@ CreateSocketAdress( } /* data or block for read, read */ - buffer[0] = '\0'; + memset(buffer,0,lLen); iRet = recv(self->sockid,buffer,lLen,0); if(iRet == 0) {/* eof */ @@ -414,10 +414,114 @@ CreateSocketAdress( } else { - buffer[iRet] = '\0'; return iRet; } } +/*---------------------------------------------------------------------*/ + int NETAvailable(mkChannel *self, int timeout) + { + fd_set lMask; + struct timeval tmo ={0,1}; + int iRet; + + if(!VerifyChannel(self)) + { + return 0; + } + + /* setup for select */ + tmo.tv_usec = timeout; + FD_ZERO(&lMask); + FD_SET(self->sockid,&lMask); + if((self->sockid >= FD_SETSIZE) || (self->sockid < 0) ) + /* invalid descriptor */ + { + return -1; /* eof */ + } + iRet = select( (self->sockid + 1),&lMask, NULL, NULL,&tmo); + if( iRet < 0) + { + return -1; + } + if(FD_ISSET(self->sockid,&lMask)) + { + return 1; + } + else + { + return 0; + } + } +/*--------------------------------------------------------------------------*/ + int NETReadTillTerm(mkChannel *self, int timeout, + char *pTerm, char *pBuffer, int iBufLen) + { + int iRet, termLen, i, j, nLoop; + int read = 0; + + + if(!VerifyChannel(self)) + { + return -1; + } + + /* + how may cycles to read in order to have a timeout + */ + nLoop = timeout/10; + if(nLoop <= 0) + { + nLoop = 1; + } + + for(i = 0; i < nLoop; i++) + { + iRet = NETAvailable(self,10); + if(iRet < 0) + { + return iRet; + } + else if(iRet == 0) + { + continue; + } + else + { + /* + data is pending, read it + */ + iRet = recv(self->sockid,pBuffer+read,iBufLen - read,0); + if(iRet < 0) + { + return iRet; + } + else + { + read += iRet; + } + if(read >= iBufLen) + { + pBuffer[iBufLen-1] = '\0'; + } + else + { + pBuffer[read+1] = '\0'; + } + /* + have we found a terminator ? + */ + for(j = 0; j < strlen(pTerm); j++) + { + if(strrchr(pBuffer,pTerm[j]) != NULL) + { + return 1; + } + } + } + } + return 0; /* timeout! */ + } + /*---------------------------------------------------------------------------*/ int NETClosePort(mkChannel *self) { diff --git a/network.h b/network.h index 2b4a11fa..2090e963 100644 --- a/network.h +++ b/network.h @@ -9,6 +9,13 @@ Mark Koennecke, October 1996 Free for non-commercial use, no warranties taken! + + Added functions: + NETavailable + NETReadTillTerm + in order to support RS-232 connection through a terminal server. + + Mark Koennecke, October 2001 ----------------------------------------------------------------------------*/ #ifndef NNNET @@ -17,7 +24,7 @@ #include #include - typedef struct { + typedef struct __MKCHANNEL{ int sockid; int iType; struct sockaddr_in adresse; @@ -68,7 +75,23 @@ data, and else the length of the data read. With a negative value or 0 for timeout this function blocks for the read. */ - + int NETAvailable(mkChannel *self, int timeout); + /* + returns 1 if data is pending on the port, 0 if none is + pending. + */ + int NETReadTillTerm(mkChannel *self, int timeout, + char *pTerm, char *pBuffer, int iBufLen); + /* + reads data until one of the terminators defined in pTerm has + been found. The data is copied into the buffer pBuffer. A + maximum length of iBufLen characters is observed. The timeout + parameter defines a maximum time to wait for a terminator to + appear. NETReadTillTerm returns 1 on success, 0 on a timeout, + and a negative value if a network error occurred. Beware that + this may not work correctly if the wrong terminator is given. + The last one is really needed. + */ /* ********************* KILLING FIELD ******************************** */ int NETClosePort(mkChannel *self); /* closes a port, do not forget to free the channel data- diff --git a/nextrics.c b/nextrics.c index 6677b386..43bcf286 100644 --- a/nextrics.c +++ b/nextrics.c @@ -60,6 +60,7 @@ */ #define HM2OFF "hm2off" #define HM3OFF "hm3off" +#define HM1OFF "hm1off" /* name of hkl object holding crystallographic information @@ -77,8 +78,10 @@ name of hkl object holding crystallographic information int iFirst; int iFrameNum; pICallBack pCall; - float hm2Off, hm3Off; + float hm2Off, hm3Off, hm1off; pHKL pCrystal; + int iHDF5; + pCounter pCount; } NexTrics; /* event type */ @@ -116,17 +119,24 @@ name of hkl object holding crystallographic information DeleteNexTrics(pNew); return NULL; } + if(strstr(pDict,"5") != NULL) + { + pNew->iHDF5 = 1; + } pNew->pFileRoot = strdup(pRoot); pNew->pDanu = pNum; /* find things in interpreter */ pCom = FindCommand(pSics,HM1); - if(!pCom) + if(pCom) { - DeleteNexTrics(pNew); - return NULL; + pNew->pHistogram1 = (pHistMem)pCom->pData; } - pNew->pHistogram1 = (pHistMem)pCom->pData; + else + { + pNew->pHistogram1 = NULL; + } + pCom = FindCommand(pSics,HM2); if(pCom) { @@ -154,9 +164,27 @@ name of hkl object holding crystallographic information { pNew->pCrystal = NULL; } + pCom = FindCommand(pSics,"counter"); + if(pCom) + { + pNew->pCount = (pCounter)pCom->pData; + } + else + { + pNew->pCrystal = NULL; + } pNew->iFirst = 1; pNew->iFrameNum = 0; + pVar = FindVariable(pSics,HM1OFF); + if(pVar) + { + pNew->hm1off = pVar->fVal; + } + else + { + pNew->hm1off = 0; + } pVar = FindVariable(pSics,HM2OFF); if(pVar) { @@ -164,7 +192,7 @@ name of hkl object holding crystallographic information } else { - pNew->hm2Off = -45.; + pNew->hm2Off = +45.; } pVar = FindVariable(pSics,HM3OFF); if(pVar) @@ -173,9 +201,10 @@ name of hkl object holding crystallographic information } else { - pNew->hm3Off = 45.; + pNew->hm3Off = 90.; } + return pNew; } /*-------------------------------------------------------------------------*/ @@ -313,7 +342,30 @@ name of hkl object holding crystallographic information } /* write counting parameters */ - eMode = GetHistCountMode(self->pHistogram1); + if(self->pHistogram1 != NULL) + { + eMode = GetHistCountMode(self->pHistogram1); + fVal = GetHistPreset(self->pHistogram1); + lVal = GetHistMonitor(self->pHistogram1,1,pCon); + } + if(self->pHistogram2 != NULL) + { + eMode = GetHistCountMode(self->pHistogram2); + fVal = GetHistPreset(self->pHistogram2); + lVal = GetHistMonitor(self->pHistogram2,1,pCon); + } + if(self->pHistogram3 != NULL) + { + eMode = GetHistCountMode(self->pHistogram3); + fVal = GetHistPreset(self->pHistogram3); + lVal = GetHistMonitor(self->pHistogram3,1,pCon); + } + if(self->pCount != NULL) + { + eMode = GetCounterMode(self->pCount); + fVal = GetCounterPreset(self->pCount); + lVal = GetMonitor(self->pCount,1,pCon); + } if(eMode == eTimer) { strcpy(pBueffel,"Timer"); @@ -323,36 +375,37 @@ name of hkl object holding crystallographic information strcpy(pBueffel,"Monitor"); } NXDputalias(hfil,self->pDict,"framemode",pBueffel); - fVal = GetHistPreset(self->pHistogram1); NXDputalias(hfil,self->pDict,"framepreset",&fVal); - lVal = GetHistMonitor(self->pHistogram1,1,pCon); iVal = (int32)lVal; NXDputalias(hfil,self->pDict,"framemonitor",&iVal); /* write detector1 histogram */ - strcpy(pBueffel,"detector1"); - NXDupdate(self->pDict,"dnumber",pBueffel); - SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict, - "frametilt","DG1"); - GetHistogram(self->pHistogram1,pCon,0,0,DET1X*DET1Y,lData, - DET1X*DET1Y*sizeof(HistInt)); - /* - NXDputalias(hfil,self->pDict,"framecounts",lData); - */ - NXDopenalias(hfil,self->pDict,"framecounts"); - NXputdata(hfil,lData); - NXsetdimname(hfil,0,"frame_x"); - NXsetdimname(hfil,1,"frame_y"); - NXclosedata(hfil); + if(self->pHistogram1 != NULL) + { + strcpy(pBueffel,"detector1"); + NXDupdate(self->pDict,"dnumber",pBueffel); + SNXSPutMotor(pServ->pSics,pCon,hfil,self->pDict, + "frametilt","DG1"); + GetHistogram(self->pHistogram1,pCon,0,0,DET1X*DET1Y,lData, + DET1X*DET1Y*sizeof(HistInt)); + NXDputalias(hfil,self->pDict,"framecounts",lData); - fVal = fTTheta; - NXDputalias(hfil,self->pDict,"frame2theta",&fVal); + /* + NXDopenalias(hfil,self->pDict,"framecounts"); + NXputdata(hfil,lData); + NXsetdimname(hfil,0,"frame_x"); + NXsetdimname(hfil,1,"frame_y"); + */ + NXclosedata(hfil); - /* the NXdata links */ - NXDaliaslink(hfil,self->pDict,"frame","detectorx"); - NXDaliaslink(hfil,self->pDict,"frame","detectory"); - NXDaliaslink(hfil,self->pDict,"frame","framecounts"); + fVal = fTTheta + self->hm1off; + NXDputalias(hfil,self->pDict,"frame2theta",&fVal); + /* the NXdata links */ + NXDaliaslink(hfil,self->pDict,"frame","detectorx"); + NXDaliaslink(hfil,self->pDict,"frame","detectory"); + NXDaliaslink(hfil,self->pDict,"frame","framecounts"); + } /* do detector 2 histogram */ @@ -364,13 +417,14 @@ name of hkl object holding crystallographic information "frametilt","DG2"); GetHistogram(self->pHistogram2,pCon,0,0,DET2X*DET2Y,lData, DET2X*DET2Y*sizeof(HistInt)); - /* NXDputalias(hfil,self->pDict,"framecounts",lData); - */ + + /* code for reducing object number in HDF-4 NXDopenalias(hfil,self->pDict,"framecounts"); NXputdata(hfil,lData); NXsetdimname(hfil,0,"frame_x"); NXsetdimname(hfil,1,"frame_y"); + */ NXclosedata(hfil); fVal = fTTheta + self->hm2Off; @@ -393,13 +447,15 @@ name of hkl object holding crystallographic information GetHistogram(self->pHistogram2,pCon,0,0,DET3X*DET3Y,lData, DET3X*DET3Y*sizeof(HistInt)); - /* NXDputalias(hfil,self->pDict,"framecounts",lData); - */ + + /* code for reducing object numbers in HDF-4 NXDopenalias(hfil,self->pDict,"framecounts"); NXputdata(hfil,lData); NXsetdimname(hfil,0,"frame_x"); NXsetdimname(hfil,1,"frame_y"); + */ + NXclosedata(hfil); fVal = fTTheta + self->hm3Off; @@ -555,91 +611,93 @@ name of hkl object holding crystallographic information first set detector variables in dictionary This is the first detector. */ - strcpy(pBueffel,"detector1"); - NXDupdate(self->pDict,"dnumber",pBueffel); - sprintf(pBueffel,"%d",DET1X); - NXDupdate(self->pDict,"framedim1",pBueffel); - sprintf(pBueffel,"%d",DET1Y); - NXDupdate(self->pDict,"framedim2",pBueffel); - strcpy(pBueffel,DET1DESC); - iRet = NXDputalias(hfil,self->pDict,"ddescription",pBueffel); - if(iRet != NX_OK) + if(self->pHistogram1 != NULL) { - SCWrite(pCon,"ERROR: failed to write detector1 description",eError); + strcpy(pBueffel,"detector1"); + NXDupdate(self->pDict,"dnumber",pBueffel); + sprintf(pBueffel,"%d",DET1X); + NXDupdate(self->pDict,"framedim1",pBueffel); + sprintf(pBueffel,"%d",DET1Y); + NXDupdate(self->pDict,"framedim2",pBueffel); + strcpy(pBueffel,DET1DESC); + iRet = NXDputalias(hfil,self->pDict,"ddescription",pBueffel); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write detector1 description",eError); + } + for(i = 0; i < DET1X; i++) + { + fPix[i] = i * DET1XS; + } + iRet = NXDputalias(hfil,self->pDict,"detectorx",fPix); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write detector1 x-axis description",eError); + } + for(i = 0; i < DET1Y; i++) + { + fPix[i] = i * DET1YS; + } + iRet = NXDputalias(hfil,self->pDict,"detectory",fPix); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write detector1 y-axis description",eError); + } + pVar = NULL; + pVar = FindVariable(pServ->pSics,"det1zerox"); + if(pVar) + { + fVal = pVar->fVal; + } + else + { + SCWrite(pCon,"ERROR: Variable detector x zero point not found ",eError); + fVal = -2188.99; + } + iRet = NXDputalias(hfil,self->pDict,"detzerox",&fVal); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write detecor x zero point",eError); + } + pVar = NULL; + pVar = FindVariable(pServ->pSics,"det1zeroy"); + if(pVar) + { + fVal = pVar->fVal; + } + else + { + SCWrite(pCon,"ERROR: Variable detector y zero point not found ",eError); + fVal = -2188.99; + } + iRet = NXDputalias(hfil,self->pDict,"detzeroy",&fVal); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write detecor y zero point",eError); + } + pVar = NULL; + pVar = FindVariable(pServ->pSics,"det1dist"); + if(pVar) + { + fVal = pVar->fVal; + } + else + { + SCWrite(pCon,"ERROR: Variable detector distance not found ",eError); + fVal = -2188.99; + } + iRet = NXDputalias(hfil,self->pDict,"detdist",&fVal); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write detecor y zero point",eError); + } + iRet = 1; + iRet = NXDputalias(hfil,self->pDict,"detvalid",&iRet); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write frame validity",eError); + } } - for(i = 0; i < DET1X; i++) - { - fPix[i] = i * DET1XS; - } - iRet = NXDputalias(hfil,self->pDict,"detectorx",fPix); - if(iRet != NX_OK) - { - SCWrite(pCon,"ERROR: failed to write detector1 x-axis description",eError); - } - for(i = 0; i < DET1Y; i++) - { - fPix[i] = i * DET1YS; - } - iRet = NXDputalias(hfil,self->pDict,"detectory",fPix); - if(iRet != NX_OK) - { - SCWrite(pCon,"ERROR: failed to write detector1 y-axis description",eError); - } - pVar = NULL; - pVar = FindVariable(pServ->pSics,"det1zerox"); - if(pVar) - { - fVal = pVar->fVal; - } - else - { - SCWrite(pCon,"ERROR: Variable detector x zero point not found ",eError); - fVal = -2188.99; - } - iRet = NXDputalias(hfil,self->pDict,"detzerox",&fVal); - if(iRet != NX_OK) - { - SCWrite(pCon,"ERROR: failed to write detecor x zero point",eError); - } - pVar = NULL; - pVar = FindVariable(pServ->pSics,"det1zeroy"); - if(pVar) - { - fVal = pVar->fVal; - } - else - { - SCWrite(pCon,"ERROR: Variable detector y zero point not found ",eError); - fVal = -2188.99; - } - iRet = NXDputalias(hfil,self->pDict,"detzeroy",&fVal); - if(iRet != NX_OK) - { - SCWrite(pCon,"ERROR: failed to write detecor y zero point",eError); - } - pVar = NULL; - pVar = FindVariable(pServ->pSics,"det1dist"); - if(pVar) - { - fVal = pVar->fVal; - } - else - { - SCWrite(pCon,"ERROR: Variable detector distance not found ",eError); - fVal = -2188.99; - } - iRet = NXDputalias(hfil,self->pDict,"detdist",&fVal); - if(iRet != NX_OK) - { - SCWrite(pCon,"ERROR: failed to write detecor y zero point",eError); - } - iRet = 1; - iRet = NXDputalias(hfil,self->pDict,"detvalid",&iRet); - if(iRet != NX_OK) - { - SCWrite(pCon,"ERROR: failed to write frame validity",eError); - } - /* second frame, but only if present */ @@ -969,45 +1027,48 @@ name of hkl object holding crystallographic information links in detector group detector 1 */ - strcpy(pBueffel,"detector1"); - NXDupdate(self->pDict,"dnumber",pBueffel); - iRet = NXDaliaslink(hfil,self->pDict,"det1","ddescription"); - if(iRet != NX_OK) + if(self->pHistogram1 != NULL) { - SCWrite(pCon,"WARNING: cannot link against detector description",eWarning); + strcpy(pBueffel,"detector1"); + NXDupdate(self->pDict,"dnumber",pBueffel); + iRet = NXDaliaslink(hfil,self->pDict,"det1","ddescription"); + if(iRet != NX_OK) + { + SCWrite(pCon,"WARNING: cannot link against detector description",eWarning); + } + iRet = NXDaliaslink(hfil,self->pDict,"det1","detectorx"); + if(iRet != NX_OK) + { + SCWrite(pCon,"WARNING: cannot link against detector x-axis",eWarning); + } + iRet = NXDaliaslink(hfil,self->pDict,"det1","detectory"); + if(iRet != NX_OK) + { + SCWrite(pCon,"WARNING: cannot link against detector y-axis",eWarning); + } + iRet = NXDaliaslink(hfil,self->pDict,"det1","detzerox"); + if(iRet != NX_OK) + { + SCWrite(pCon,"WARNING: cannot link against detector x zero ",eWarning); + } + iRet = NXDaliaslink(hfil,self->pDict,"det1","detzeroy"); + if(iRet != NX_OK) + { + SCWrite(pCon,"WARNING: cannot link against detector y zero",eWarning); + } + iRet = NXDaliaslink(hfil,self->pDict,"det1","detdist"); + if(iRet != NX_OK) + { + SCWrite(pCon,"WARNING: cannot link against detector distance", + eWarning); + } + iRet = 1; + iRet = NXDputalias(hfil,self->pDict,"detvalid",&iRet); + if(iRet != NX_OK) + { + SCWrite(pCon,"ERROR: failed to write frame validity",eError); + } } - iRet = NXDaliaslink(hfil,self->pDict,"det1","detectorx"); - if(iRet != NX_OK) - { - SCWrite(pCon,"WARNING: cannot link against detector x-axis",eWarning); - } - iRet = NXDaliaslink(hfil,self->pDict,"det1","detectory"); - if(iRet != NX_OK) - { - SCWrite(pCon,"WARNING: cannot link against detector y-axis",eWarning); - } - iRet = NXDaliaslink(hfil,self->pDict,"det1","detzerox"); - if(iRet != NX_OK) - { - SCWrite(pCon,"WARNING: cannot link against detector x zero ",eWarning); - } - iRet = NXDaliaslink(hfil,self->pDict,"det1","detzeroy"); - if(iRet != NX_OK) - { - SCWrite(pCon,"WARNING: cannot link against detector y zero",eWarning); - } - iRet = NXDaliaslink(hfil,self->pDict,"det1","detdist"); - if(iRet != NX_OK) - { - SCWrite(pCon,"WARNING: cannot link against detector distance",eWarning); - } - iRet = 1; - iRet = NXDputalias(hfil,self->pDict,"detvalid",&iRet); - if(iRet != NX_OK) - { - SCWrite(pCon,"ERROR: failed to write frame validity",eError); - } - /* links in detector group, detector 2 */ @@ -1158,7 +1219,14 @@ name of hkl object holding crystallographic information iRet = IncrementDataNumber(self->pDanu,&iYear); sprintf(pBueffel,"%s/trics%5.5d%4.4d.hdf",self->pFileRoot,iRet, iYear); self->pCurrentFile = strdup(pBueffel); - iRet = NXopen(self->pCurrentFile,NXACC_CREATE,&hfil); + if(self->iHDF5) + { + iRet = NXopen(self->pCurrentFile,NXACC_CREATE5,&hfil); + } + else + { + iRet = NXopen(self->pCurrentFile,NXACC_CREATE,&hfil); + } if(iRet != NX_OK) { sprintf(pBueffel,"ERROR: cannot open %s",self->pCurrentFile); diff --git a/nxamor.c b/nxamor.c index c4963e56..d9e68c24 100644 --- a/nxamor.c +++ b/nxamor.c @@ -10,6 +10,7 @@ Mark Koennecke, September 1999 Updated, Mark Koennecke, August 2001 --------------------------------------------------------------------------*/ + #include #include #include "fortify.h" @@ -35,6 +36,13 @@ #define SOURCETYPE "Continous flux spallation source" #define CHOPPERNAME "Dornier Chopper System" +/* + The rough size of each detector chunk to write in TOF mode + (currently 16MB) +#define TOFBLOCK 8192000 +*/ +#define TOFBLOCK 16384000 + /* a pointer to amor2t which we need for a couple of parameters */ @@ -68,7 +76,7 @@ pAmor2T pAmor = NULL; float fVal; /* open files */ - iRet = NXopen(file,NXACC_CREATE,&hfil); + iRet = NXopen(file,NXACC_CREATE5,&hfil); if(iRet != NX_OK) { sprintf(pBueffel,"ERROR: cannot open file %s for writing",file); @@ -326,6 +334,135 @@ pAmor2T pAmor = NULL; return 1; } +/*----------------------------------------------------------------------- + WriteTOFDetector writes the histogram memory data in TOF mode. As + the histogram memory can become quite large at AMOR, the data is + read and stored in chunks if it is to big. All this is handled + in this routine. + -------------------------------------------------------------------------*/ +static int WriteTOFDetector(char *name, pHistMem pHM, int *iDim, + NXhandle hfil, NXdict hdict, + SConnection *pCon) +{ + int iLength, nChunk, chunkSize, iChunk[3], i, iStart[3]; + HistInt *lData = NULL; + char pBueffel[132]; + + iLength = iDim[0]*iDim[1]*iDim[2]; + if( (iLength*4) < TOFBLOCK) + { + sprintf(pBueffel," -chunk {%d,%d,%d} ",iDim[0], iDim[1], iDim[2]); + NXDupdate(hdict,"chunk",pBueffel); + lData = (HistInt *)malloc(iLength*sizeof(HistInt)); + if(!lData) + { + SCWrite(pCon, + "ERROR: out of memory, failed to write histogram",eError); + return 0; + } + memset(lData,0,iLength*sizeof(HistInt)); + GetHistogramDirect(pHM,pCon, + 0,0,iLength,lData,iLength*sizeof(HistInt)); + NXDputalias(hfil,hdict,name,lData); + NXDputalias(hfil,hdict,"detchunk",iDim); + NXDaliaslink(hfil,hdict,"dana",name); + } + else + { + /* + implement chunked writing. We strive to write layers in Y. The + number of chunks needs to fulfill three conditions then: + - multiple of xSize* timeBin; + - close to TOFBLOCK in size + - divide Y without remainder. + */ + iChunk[0] = iDim[0]; + iChunk[2] = iDim[2]; + iChunk[1] = 1; + chunkSize = iDim[0]*iDim[2]; + for(i = 1; i < 64; i++) + { + if( (iDim[1] % i) == 0) + { + if(i*chunkSize*sizeof(HistInt) > TOFBLOCK) + { + iChunk[1] = i; + break; + } + } + } + sprintf(pBueffel,"Segmented TOF data in %d chunks",iDim[1]/iChunk[1]); + SCWrite(pCon,pBueffel,eWarning); + /* + now we have a chunkSize, lets go and write! + */ + NXDputalias(hfil,hdict,"detchunk",iChunk); + chunkSize = iChunk[1]*iChunk[0]*iChunk[2]; + sprintf(pBueffel," -chunk {%d,%d,%d} ",iChunk[0], iChunk[1], iChunk[2]); + NXDupdate(hdict,"chunk",pBueffel); + lData = (HistInt *)malloc(chunkSize*sizeof(HistInt)); + if(!lData) + { + SCWrite(pCon,"ERROR: out of memory while writing TOF data", + eError); + return 0; + } + NXDopenalias(hfil,hdict,name); + for(i = 0; i < iDim[1]/iChunk[1]; i++) + { + memset(lData,0,chunkSize*sizeof(HistInt)); + GetHistogramDirect(pHM,pCon, + 0,i*chunkSize,chunkSize,lData,chunkSize*sizeof(HistInt)); + /* + yield a little in order to allow other clients to receive a + response. Also allow for interrupting. + */ + SicsWait(2); + if(SCGetInterrupt(pCon) != eContinue) + { + SCWrite(pCon, + "ERROR: dataset writing interrupted, data probably corrupted", + eError); + return 0; + } + + iStart[0] = 0; + iStart[1] = i*iChunk[1]; + iStart[2] = 0; + NXputslab(hfil,lData,iStart, iChunk); + sprintf(pBueffel,"Wrote chunk %d", i); + SCWrite(pCon,pBueffel,eWarning); + /* + yield a little in order to allow other clients to receive a + response. Also allow for interrupting. + */ + SicsWait(2); + if(SCGetInterrupt(pCon) != eContinue) + { + SCWrite(pCon, + "ERROR: dataset writing interrupted, data probably corrupted", + eError); + return 0; + } + } + /* + close groups till root + */ + NXclosedata(hfil); + NXclosegroup(hfil); + NXclosegroup(hfil); + NXclosegroup(hfil); + + /* + make link + */ + NXDaliaslink(hfil,hdict,"dana",name); + NXDaliaslink(hfil,hdict,"dana","detchunk"); + + } + if(lData) + free(lData); +} /*-----------------------------------------------------------------------*/ int WriteAmorTOF(char *file, SConnection *pCon, pHistMem pHM) { @@ -473,33 +610,33 @@ pAmor2T pAmor = NULL; } else { - iLength = iDim[0]*iDim[1]*iDim[2]; - lData = (HistInt *)malloc(iLength*sizeof(HistInt)); - if(!lData) - { - SCWrite(pCon, - "ERROR: out of memory, failed to write histogram",eError); - return 0; - } - memset(lData,0,iLength*sizeof(HistInt)); - GetHistogramDirect(pHM,pCon, - 0,0,iLength,lData,iLength*sizeof(HistInt)); - NXDputalias(hfil,hdict,"spinup",lData); - NXDaliaslink(hfil,hdict,"dana","spinup"); + WriteTOFDetector("spinup",pHM, iDim,hfil,hdict,pCon); /* now get and write single detectors */ - GetHistogramDirect(pHM,pCon,0,iLength,2*iDim[2], - lData, iLength*sizeof(HistInt)); - NXDputalias(hfil,hdict,"singleup",lData); - NXDaliaslink(hfil,hdict,"singledana","singleup"); - NXDaliaslink(hfil,hdict,"singledana","singletime"); + iLength = iDim[0]*iDim[1]*iDim[2]; + lData = (HistInt *)malloc(2*iDim[2]*sizeof(HistInt)); + if(!lData) + { + SCWrite(pCon,"ERROR: out of memory while writing single detectors", + eError); + } + else + { + memset(lData,0,2*iDim[2]*sizeof(HistInt)); + GetHistogramDirect(pHM,pCon,0,iLength,2*iDim[2], + lData, 2*iDim[2]*sizeof(HistInt)); + NXDputalias(hfil,hdict,"singleup",lData); + NXDaliaslink(hfil,hdict,"singledana","singleup"); + NXDaliaslink(hfil,hdict,"singledana","singletime"); + } } /* to do: add polarizing code */ - free(lData); + if(lData) + free(lData); NXclose(&hfil); NXDclose(hdict,NULL); diff --git a/nxdict.c b/nxdict.c index 5c8a6303..a5d669ec 100644 --- a/nxdict.c +++ b/nxdict.c @@ -1,6 +1,4 @@ -#line 2264 "nxdict.w" - /*--------------------------------------------------------------------------- Nexus Dictionary API implementation file. @@ -20,8 +18,17 @@ August, 1997 Version: 1.0 + + Version 1.1 + + Updated to use the combined HDF4 HDF5 API. New keyword -chunk which + defines the chunk buffer size for a SDS. + + Mark Koennecke, August 2001 + -----------------------------------------------------------------------------*/ + #include #include #include @@ -41,14 +48,13 @@ extern void *NXpData; extern void (*NXIReportError)(void *pData, char *pBuffer); /*--------------------------------------------------------------------------*/ -/*#define DEFDEBUG 1*/ +/* #define DEFDEBUG 1 */ /* define DEFDEBUG when you wish to print your definition strings before action. This can help a lot to resolve mysteries when working with dictionaries. */ /*-------------------------------------------------------------------------*/ -#line 362 "nxdict.w" typedef struct __NXdict { @@ -58,7 +64,6 @@ /*------------------ verbosity level -------------------------------------*/ static int iVerbosity = 0 ; -#line 2311 "nxdict.w" /*-------------------------------------------------------------------------*/ static char *NXDIReadFile(FILE *fd) @@ -100,7 +105,6 @@ } /*--------------------------------------------------------------------------*/ -#line 490 "nxdict.w" #define FWORD 1 #define FHASH 2 @@ -173,11 +177,9 @@ } -#line 2351 "nxdict.w" /*------------------------------------------------------------------------*/ -#line 566 "nxdict.w" #define AMODE 0 #define DMODE 1 @@ -266,7 +268,6 @@ } } -#line 2353 "nxdict.w" /*--------------------------------------------------------------------------*/ NXstatus NXDinitfromfile(char *filename, NXdict *pData) @@ -277,7 +278,6 @@ char pError[512]; -#line 383 "nxdict.w" /* allocate a new NXdict structure */ if(iVerbosity == NXalot) @@ -302,10 +302,6 @@ } -#line 2362 "nxdict.w" - - -#line 410 "nxdict.w" /* is there a file name argument */ if(filename == NULL) @@ -318,10 +314,6 @@ return NX_OK; } -#line 2363 "nxdict.w" - - -#line 424 "nxdict.w" fd = fopen(filename,"rb"); if(!fd) @@ -334,12 +326,6 @@ } - -#line 2364 "nxdict.w" - - -#line 444 "nxdict.w" - /* read the file contents */ if(iVerbosity == NXalot) { @@ -363,8 +349,6 @@ } NXDIParse(pBuffer, pNew->pDictionary); -#line 2365 "nxdict.w" - if(iVerbosity == NXalot) { @@ -376,8 +360,6 @@ } /*--------------------------------------------------------------------------*/ -#line 660 "nxdict.w" - NXdict NXDIAssert(NXdict handle) { NXdict self = NULL; @@ -387,12 +369,9 @@ return self; } -#line 2376 "nxdict.w" /*-------------------------------------------------------------------------*/ -#line 671 "nxdict.w" - NXstatus NXDclose(NXdict handle, char *filename) { NXdict self; @@ -441,12 +420,8 @@ return NX_OK; } -#line 2378 "nxdict.w" - /*------------------------------------------------------------------------*/ -#line 724 "nxdict.w" - NXstatus NXDadd(NXdict handle, char *alias, char *pDef) { NXdict self; @@ -491,14 +466,7 @@ } return NX_OK; } - - -#line 2380 "nxdict.w" - /*-----------------------------------------------------------------------*/ - -#line 776 "nxdict.w" - #define NORMAL 1 #define ALIAS 2 pDynString NXDItextreplace(NXdict handle, char *pDefString) @@ -595,23 +563,12 @@ return NX_OK; } -#line 2382 "nxdict.w" - /*------------------- The Defintion String Parser -----------------------*/ /*------- Data structures */ - -#line 886 "nxdict.w" - typedef struct { char pText[20]; int iCode; } TokDat; - -#line 2385 "nxdict.w" - - -#line 896 "nxdict.w" - #define TERMSDS 100 #define TERMVG 200 #define TERMLINK 300 @@ -625,32 +582,15 @@ int iTerminal; } ParDat; -#line 2386 "nxdict.w" - - -#line 1101 "nxdict.w" - static void DummyError(void *pData, char *pError) { return; } - -#line 2387 "nxdict.w" - - -#line 1215 "nxdict.w" - typedef struct { char name[256]; char value[256]; }AttItem; -#line 2388 "nxdict.w" - -/*------------------------------------------------------------------------*/ - -#line 918 "nxdict.w" - /*---------------- Token name defines ---------------------------*/ #define DSLASH 0 #define DKOMMA 1 @@ -668,10 +608,11 @@ #define DLZW 14 #define DHUF 15 #define DRLE 16 +#define CHUNK 17 /*----------------- Keywords ----------------------------------------*/ - static TokDat TokenList[11] = { + static TokDat TokenList[12] = { {"SDS",DSDS}, {"NXLINK",DLINK}, {"NXVGROUP",DGROUP}, @@ -679,6 +620,7 @@ {"-type",DTYPE}, {"-rank",DRANK}, {"-attr",DATTR}, + {"-chunk",CHUNK}, {"-LZW",DLZW}, {"-HUF",DHUF}, {"-RLE",DRLE}, @@ -765,12 +707,8 @@ } -#line 2390 "nxdict.w" - /*------------------------------------------------------------------------*/ -#line 1114 "nxdict.w" - int NXDIParsePath(NXhandle hfil, ParDat *pParse) { int iRet, iToken; @@ -861,12 +799,8 @@ return NX_ERROR; } -#line 2392 "nxdict.w" - /*------------------------------------------------------------------------*/ -#line 1481 "nxdict.w" - static int NXDIParseAttr(ParDat *pParse, int iList) { char pError[256]; @@ -925,12 +859,7 @@ return NX_OK; } -#line 2394 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1428 "nxdict.w" - static int NXDIParseDim(ParDat *pParse, int *iDim) { char pError[256]; @@ -978,13 +907,7 @@ } return NX_OK; } - -#line 2396 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1379 "nxdict.w" - static TokDat tDatType[] = { {"DFNT_FLOAT32",DFNT_FLOAT32}, {"DFNT_FLOAT64",DFNT_FLOAT64}, @@ -1030,20 +953,15 @@ return NX_ERROR; } -#line 2398 "nxdict.w" - /*-------------------------------------------------------------------------*/ - -#line 1223 "nxdict.w" - static int NXDIParseSDS(NXhandle hfil, ParDat *pParse) { int iType = DFNT_FLOAT32; int iRank = 1; - int iCompress = 0; - int32 iDim[MAX_VAR_DIMS]; - int iList; - int iRet, iStat; + int iCompress = NX_COMP_NONE; + int32 iDim[MAX_VAR_DIMS], iChunk[MAX_VAR_DIMS]; + int iList, iChunkDefined = 0 ; + int iRet, iStat, i; char pError[256]; char pName[MAX_NC_NAME]; void (*ErrFunc)(void *pData, char *pErr); @@ -1087,6 +1005,15 @@ } iRank = atoi(pParse->pToken); break; + case CHUNK: /* chunk size for compression */ + iRet = NXDIParseDim(pParse, iChunk); + if(iRet == NX_ERROR) + { + LLDdelete(iList); + return iRet; + } + iChunkDefined = 1; + break; case DDIM: iRet = NXDIParseDim(pParse, iDim); if(iRet == NX_ERROR) @@ -1132,8 +1059,19 @@ } NXDIDefToken(pParse); } + + /* whew! got all information for doing the SDS + However, if the chunk sizes for compression have not + been set, default them to the dimensions of the data set + */ + if(iChunkDefined == 0) + { + for(i = 0; i < iRank; i++) + { + iChunk[i] = iDim[i]; + } + } - /* whew! got all information for doing the SDS */ /* first install dummy error handler, try open it, then deinstall again and create if allowed */ @@ -1153,7 +1091,8 @@ /* we need to create it, if we may */ if(pParse->iMayCreate) { - iRet = NXmakedata(hfil,pName,iType, iRank,iDim); + iRet = NXcompmakedata(hfil,pName,iType, iRank,iDim, + iCompress,iChunk); if(iRet != NX_OK) { /* a comment on this one has already been written! */ @@ -1167,23 +1106,7 @@ LLDdelete(iList); return iRet; } - /* - stop creation of superfluous dimension scales for single - numbers - */ - if(iRank == 1 && iDim[0] == 1) - { - NXsetdimname(hfil,0,"singleDim"); - } - /* deal with compression, if appropriate */ - if(iCompress != 0) - { - iRet = NXcompress(hfil,iCompress); - if(!iRet) - { - NXIReportError(NXpData,"Failed to compress data set"); - } - } + /* put attributes in */ iRet = LLDnodePtr2First(iList); while(iRet != 0) @@ -1213,13 +1136,7 @@ } return NX_OK; } - -#line 2400 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1544 "nxdict.w" - static int NXDIParseLink(NXhandle hfil, NXdict pDict,ParDat *pParse) { char pError[256]; @@ -1248,13 +1165,7 @@ return NXDopenalias(hfil, pDict, pParse->pToken); } - -#line 2402 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1034 "nxdict.w" - int NXDIDefParse(NXhandle hFil, NXdict pDict, ParDat *pParse) { int iRet; @@ -1305,13 +1216,7 @@ } return NX_OK; } - -#line 2404 "nxdict.w" - /*----------------------------------------------------------------------*/ - -#line 1576 "nxdict.w" - NXstatus NXDIUnwind(NXhandle hFil, int iDepth) { int i, iRet; @@ -1326,13 +1231,7 @@ } return NX_OK; } - -#line 2406 "nxdict.w" - /*-------------------- The Data Transfer Functions ----------------------*/ - -#line 1597 "nxdict.w" - NXstatus NXDopendef(NXhandle hfil, NXdict dict, char *pDef) { NXdict pDict; @@ -1366,24 +1265,18 @@ /* do not rewind on links */ return iRet; } - -#line 2408 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1637 "nxdict.w" - NXstatus NXDopenalias(NXhandle hfil, NXdict dict, char *pAlias) { NXdict pDict; int iRet; - char pDefinition[1024]; + char pDefinition[2048]; pDynString pReplaced = NULL; pDict = NXDIAssert(dict); /* get Definition String */ - iRet = NXDget(pDict,pAlias,pDefinition,1023); + iRet = NXDget(pDict,pAlias,pDefinition,2047); if(iRet != NX_OK) { sprintf(pDefinition,"ERROR: alias %s not recognized",pAlias); @@ -1403,13 +1296,7 @@ DeleteDynString(pReplaced); return iRet; } - -#line 2410 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1674 "nxdict.w" - NXstatus NXDputdef(NXhandle hFil, NXdict dict, char *pDef, void *pData) { NXdict pDict; @@ -1456,24 +1343,18 @@ } return iStat; } - -#line 2412 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1725 "nxdict.w" - NXstatus NXDputalias(NXhandle hFil, NXdict dict, char *pAlias, void *pData) { NXdict pDict; int iRet; - char pDefinition[1024]; + char pDefinition[2048]; pDynString pReplaced = NULL; pDict = NXDIAssert(dict); /* get Definition String */ - iRet = NXDget(pDict,pAlias,pDefinition,1023); + iRet = NXDget(pDict,pAlias,pDefinition,2047); if(iRet != NX_OK) { sprintf(pDefinition,"ERROR: alias %s not recognized",pAlias); @@ -1493,13 +1374,7 @@ DeleteDynString(pReplaced); return iRet; } - -#line 2414 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1760 "nxdict.w" - NXstatus NXDgetdef(NXhandle hFil, NXdict dict, char *pDef, void *pData) { NXdict pDict; @@ -1548,26 +1423,18 @@ return iStat; } - - - -#line 2416 "nxdict.w" - /*------------------------------------------------------------------------*/ - -#line 1812 "nxdict.w" - NXstatus NXDgetalias(NXhandle hFil, NXdict dict, char *pAlias, void *pData) { NXdict pDict; int iRet; - char pDefinition[1024]; + char pDefinition[2048]; pDynString pReplaced = NULL; pDict = NXDIAssert(dict); /* get Definition String */ - iRet = NXDget(pDict,pAlias,pDefinition,1023); + iRet = NXDget(pDict,pAlias,pDefinition,2047); if(iRet != NX_OK) { sprintf(pDefinition,"ERROR: alias %s not recognized",pAlias); @@ -1587,10 +1454,6 @@ DeleteDynString(pReplaced); return iRet; } - -#line 2418 "nxdict.w" - - /*------------------------------------------------------------------------*/ NXstatus NXDinfodef(NXhandle hFil, NXdict dict, char *pDef, int *rank, @@ -1649,13 +1512,13 @@ { NXdict pDict; int iRet; - char pDefinition[1024]; + char pDefinition[2048]; pDynString pReplaced = NULL; pDict = NXDIAssert(dict); /* get Definition String */ - iRet = NXDget(pDict,pAlias,pDefinition,1023); + iRet = NXDget(pDict,pAlias,pDefinition,2047); if(iRet != NX_OK) { sprintf(pDefinition,"ERROR: alias %s not recognized",pAlias); @@ -1677,10 +1540,6 @@ } /*------------------------------------------------------------------------*/ - - -#line 1849 "nxdict.w" - NXstatus NXDdeflink(NXhandle hFil, NXdict dict, char *pTarget, char *pVictim) { @@ -1769,7 +1628,7 @@ NXstatus NXDaliaslink(NXhandle hFil, NXdict dict, char *pTarget, char *pVictim) { - char pTargetDef[1024], pVictimDef[1024]; + char pTargetDef[2048], pVictimDef[2048]; int iRet; NXdict pDict; pDynString pRep1 = NULL, pRep2 = NULL; @@ -1777,7 +1636,7 @@ pDict = NXDIAssert(dict); /* get Target Definition String */ - iRet = NXDget(pDict,pTarget,pTargetDef,1023); + iRet = NXDget(pDict,pTarget,pTargetDef,2047); if(iRet != NX_OK) { sprintf(pTargetDef,"ERROR: alias %s not recognized",pTarget); @@ -1786,7 +1645,7 @@ } /* get Victim definition string */ - iRet = NXDget(pDict,pVictim,pVictimDef,1023); + iRet = NXDget(pDict,pVictim,pVictimDef,2047); if(iRet != NX_OK) { sprintf(pTargetDef,"ERROR: alias %s not recognized",pTarget); @@ -1812,14 +1671,6 @@ DeleteDynString(pRep2); return iRet; } - - -#line 2420 "nxdict.w" - -/*-----------------------------------------------------------------------*/ - -#line 1986 "nxdict.w" - /*-------------------------------------------------------------------------*/ static void SNXFormatTime(char *pBuffer, int iBufLen) { @@ -1845,15 +1696,16 @@ char pBueffel[512]; int iStat; - /* store global attributes */ + /* store global attributes, now done by NXopen iStat = NXputattr(pFile,"file_name",filename, strlen(filename)+1,NX_CHAR); if(iStat == NX_ERROR) { return NX_ERROR; } + */ - /* write creation time */ + /* write creation time, now done by NXopen SNXFormatTime(pBueffel,512); iStat = NXputattr(pFile,"file_time",pBueffel, strlen(pBueffel)+1,NX_CHAR); @@ -1861,6 +1713,7 @@ { return NX_ERROR; } + */ /* instrument name */ iStat = NXputattr(pFile,"instrument",instrument, @@ -1911,13 +1764,7 @@ } return NX_OK; } - -#line 2422 "nxdict.w" - /*-----------------------------------------------------------------------*/ - -#line 2082 "nxdict.w" - NXstatus NXUentergroup(NXhandle hFil, char *name, char *class) { void (*ErrFunc)(void *pData, char *pErr); @@ -1952,13 +1799,7 @@ } return NX_OK; } - -#line 2424 "nxdict.w" - /*-----------------------------------------------------------------------*/ - -#line 2119 "nxdict.w" - NXstatus NXUenterdata(NXhandle hFil, char *label, int datatype, int rank, int dim[], char *pUnits) { @@ -2001,13 +1842,7 @@ } return NX_OK; } - -#line 2426 "nxdict.w" - /*-----------------------------------------------------------------------*/ - -#line 2165 "nxdict.w" - NXstatus NXUallocSDS(NXhandle hFil, void **pData) { int iDIM[MAX_VAR_DIMS]; @@ -2072,13 +1907,7 @@ memset(*pData,0,lLength); return NX_OK; } - -#line 2428 "nxdict.w" - /*----------------------------------------------------------------------*/ - -#line 2229 "nxdict.w" - NXstatus NXUfreeSDS(void **pData) { free(*pData); @@ -2086,5 +1915,3 @@ return NX_OK; } -#line 2430 "nxdict.w" - diff --git a/ofac.c b/ofac.c index bef1e74b..968b47df 100644 --- a/ofac.c +++ b/ofac.c @@ -104,6 +104,7 @@ #include "definealias.h" #include "swmotor.h" #include "hmcontrol.h" +#include "rs232controller.h" /*----------------------- Server options creation -------------------------*/ static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) @@ -283,6 +284,7 @@ AddCommand(pInter,"MakeSync",MakeSync,NULL,NULL); AddCommand(pInter,"MakeSWMotor",MakeSWMotor,NULL,NULL); AddCommand(pInter,"MakeHMControl",MakeHMControl,NULL,NULL); + AddCommand(pInter,"MakeRS232Controller",RS232Factory,NULL,NULL); } /*---------------------------------------------------------------------------*/ static void KillIniCommands(SicsInterp *pSics) @@ -339,6 +341,7 @@ RemoveCommand(pSics,"MakeSync"); RemoveCommand(pSics,"MakeSWMotor"); RemoveCommand(pSics,"MakeHMControl"); + RemoveCommand(pSics,"MakeRS232Controller"); } diff --git a/rs232controller.c b/rs232controller.c new file mode 100644 index 00000000..1a8fc7ab --- /dev/null +++ b/rs232controller.c @@ -0,0 +1,619 @@ +/*--------------------------------------------------------------------- + R S 2 3 2 C o n t r o l l e r + + A general object which represents a controller connected to the network + via a terminal server. This bypasses David Maden's SerPortServer software. + Basic facilities are provided for writinga nd reading to and from the + device. For more information see the rs232controller.tex file. + + copyright: see copyright.h + + Mark Koennecke, October 2001 +-----------------------------------------------------------------------*/ +#include +#include +#include +#include "fortify.h" +#include "sics.h" +#include "splitter.h" +#include "rs232controller.h" + +/* + own error codes +*/ +#define NOTCONNECTED -2700 +#define BADMEMORY -2701 +#define TIMEOUT -2702 +#define FAILEDCONNECT -2703 + +/*--------------------------------------------------------------------*/ +void setRS232SendTerminator(prs232 self, char *term) +{ + assert(self); + + if(self->sendTerminator != NULL) + { + free(self->sendTerminator); + } + + if(term != NULL) + { + self->sendTerminator = strdup(term); + } + else + { + self->sendTerminator = NULL; + } +} +/*--------------------------------------------------------------------*/ +void setRS232ReplyTerminator(prs232 self, char *term) +{ + assert(self); + if(self->replyTerminator != NULL) + { + free(self->replyTerminator); + } + + if(term != NULL) + { + self->replyTerminator = strdup(term); + } + else + { + self->replyTerminator = NULL; + } + +} +/*---------------------------------------------------------------------*/ +void setRS232Timeout(prs232 self, int timeout) +{ + assert(self); + self->timeout = timeout; +} +/*--------------------------------------------------------------------*/ +int writeRS232(prs232 self, void *data, int dataLen) +{ + char *pPtr = NULL; + int iRet; + + + assert(self); + + /* + catch an unconnected socket + */ + if(!self->pSock) + { + return NOTCONNECTED; + } + + /* + do the terminator processing, if required. + If new data had to be allocated in order to add the terminator, + pPtr is not NULL. I any other case it is. + */ + if(self->sendTerminator != NULL) + { + pPtr = (char *)data; + if(strstr(pPtr,self->sendTerminator) == NULL) + { + /* + the terminator is missing. add it. + */ + pPtr = (char *)malloc((dataLen + strlen(self->sendTerminator) +2) + *sizeof(char)); + if(!pPtr) + { + return BADMEMORY; + } + strcpy(pPtr,(char *) data); + strcat(pPtr,self->sendTerminator); + dataLen += strlen(self->sendTerminator); + data = pPtr; + } + else + { + pPtr = NULL; + } + } + + /* + send + */ + iRet = NETWrite(self->pSock,data,dataLen); + + if(pPtr != NULL) + free(pPtr); + + return iRet; +} +/*----------------------------------------------------------------------*/ +int readRS232(prs232 self, void *data, int *dataLen) +{ + long lRead; + int iRet; + size_t rLength; + + assert(self); + /* + catch an unconnected socket + */ + if(!self->pSock) + { + return NOTCONNECTED; + } + + iRet = NETAvailable(self->pSock,self->timeout); + if(iRet < 0) + { + return iRet; + } + else if(iRet == 0) + { + *dataLen = 0; + return TIMEOUT; + } + else + { + rLength = *dataLen; + lRead = recv(self->pSock->sockid, data,rLength,0); + if(lRead >= 0) + { + *dataLen = lRead; + return 1; + } + else + { + return (int)lRead; + } + } + /* + not reached + */ + return 0; +} +/*-----------------------------------------------------------------------*/ +int availableRS232(prs232 self) +{ + assert(self); + + /* + catch an unconnected socket + */ + if(!self->pSock) + { + return NOTCONNECTED; + } + + return NETAvailable(self->pSock,self->timeout); +} +/*------------------------------------------------------------------------*/ +int transactRS232(prs232 self, void *send, int sendLen, + void *reply, int replyLen) +{ + int iRet; + + assert(self); + + /* + catch an unconnected socket + */ + if(!self->pSock) + { + return NOTCONNECTED; + } + + /* + write data + */ + iRet = writeRS232(self,send,sendLen); + if(iRet < 0) + { + return iRet; + } + + /* + read + */ + memset(reply,0,replyLen); + iRet = NETReadTillTerm(self->pSock,self->timeout,self->replyTerminator, + reply, replyLen); + if(iRet == 0) + { + return TIMEOUT; + } + else + { + return iRet; + } +} +/*------------------------------------------------------------------------*/ +void getRS232Error(int iCode, char *errorBuffer, + int errorBufferLen) +{ + /* + the error code is either one of our errors, or an errno code from + the system + */ + switch(iCode) + { + case BADMEMORY: + strncpy(errorBuffer, + "Out of memory for appending terminators", + errorBufferLen); + break; + case NOTCONNECTED: + strncpy(errorBuffer, + "Not connected!", + errorBufferLen); + break; + case TIMEOUT: + strncpy(errorBuffer, + "Timeout reading data", + errorBufferLen); + break; + case FAILEDCONNECT: + strncpy(errorBuffer, + "Failed to connect to terminal server", + errorBufferLen); + break; + default: + strncpy(errorBuffer,strerror(errno), + errorBufferLen); + break; + } +} +/*--------------------------------------------------------------------*/ +int initRS232(prs232 self) +{ + int iRet; + + assert(self); + + if(self->pSock != NULL) + { + NETClosePort(self->pSock); + self->pSock = NULL; + } + self->pSock = NETConnect(self->pHost, self->iPort); + if(!self->pSock) + return FAILEDCONNECT; + else + return 1; +} +/*-------------------------------------------------------------------*/ +static void KillRS232(void *pData) +{ + prs232 self = (prs232)pData; + if(!self) + { + return; + } + + if(self->pDes) + { + DeleteDescriptor(self->pDes); + } + if(self->sendTerminator != NULL) + { + free(self->sendTerminator); + } + if(self->replyTerminator != NULL) + { + free(self->replyTerminator); + } + if(self->pSock) + { + NETClosePort(self->pSock); + } + if(self->pHost) + { + free(self->pHost); + } +} +/*-------------------------------------------------------------------*/ +static int checkSet(SConnection *pCon, int argc, int rights) +{ + if(argc < 3) + { + return 0; + } + else + { + if(SCMatchRights(pCon,rights)) + { + return 1; + } + else + { + return 0; + } + } + /* + not reached + */ + return 0; +} +/*--------------------------------------------------------------------*/ +static void encodeTerminator(char *result, char *terminator) +{ + int i, len; + char pBuffer[10]; + + if(terminator == NULL) + { + result[0] = '\0'; + } + len = strlen(terminator); + sprintf(pBuffer,"0x%x",(int)terminator[0]); + strcpy(result,pBuffer); + for(i = 1; i < len; i++) + { + sprintf(pBuffer,"0x%x",(int)terminator[i]); + strcat(result,pBuffer); + } +} +extern char *stptok(char *pPtr, char *pToken, int tokenLen, char *term); +/*--------------------------------------------------------------------*/ +char *decodeTerminator(char *code) +{ + int count = 0, icode; + char *pResult; + char *pPtr, pToken[10]; + + /* + max 10 terminators! + */ + pResult = (char *)malloc(10*sizeof(char)); + if(!pResult) + { + return NULL; + } + memset(pResult,0,10); + + pToken[0] = '0'; + /* + I seem to get an empty token on the first call to stptok, this is why + I do 2 stptoks. Strange and wonderful. + */ + pPtr = stptok(code,pToken+1,9,"0"); + pPtr = stptok(pPtr,pToken+1,9,"0"); + while(pPtr != NULL) + { + sscanf(pToken,"%x",&icode); + pResult[count] = (char)icode; + count++; + pPtr = stptok(pPtr,pToken+1,9,"0"); + } + return pResult; +} +/*--------------------------------------------------------------------*/ +int RS232Action(SConnection *pCon, SicsInterp *pSics, + void *pData, int argc, char *argv[]) +{ + prs232 self = NULL; + char pError[256]; + char pBuffer[8192], pReply[8192]; + char *pPtr = NULL; + int iRet, iRead = 8191; + + self = (prs232)pData; + assert(self); + assert(pCon); + + /* + check for arguments + */ + if(argc < 2) + { + sprintf(pError,"ERROR: insufficient no of arguments to %s",argv[0]); + SCWrite(pCon,pError,eError); + return 0; + } + + strtolower(argv[1]); + if(strcmp(argv[1],"sendterminator") == 0) + { + if(checkSet(pCon,argc,usMugger)) + { + pPtr = decodeTerminator(argv[2]); + setRS232SendTerminator(self,pPtr); + if(pPtr) + free(pPtr); + SCSendOK(pCon); + return 1; + } + else + { + encodeTerminator(pBuffer,self->sendTerminator); + sprintf(pError,"%s.sendTerminator = \"%s\"",argv[0], + pBuffer); + SCWrite(pCon,pError,eValue); + return 1; + } + } + else if(strcmp(argv[1],"timeout") == 0) + { + if(checkSet(pCon,argc,usMugger)) + { + setRS232Timeout(self,atoi(argv[2])); + SCSendOK(pCon); + return 1; + } + else + { + sprintf(pError,"%s.Timeout = %d",argv[0],self->timeout); + SCWrite(pCon,pError,eValue); + return 1; + } + } + else if(strcmp(argv[1],"replyterminator") == 0) + { + if(checkSet(pCon,argc,usMugger)) + { + pPtr = decodeTerminator(argv[2]); + setRS232ReplyTerminator(self,pPtr); + if(pPtr) + free(pPtr); + SCSendOK(pCon); + return 1; + } + else + { + encodeTerminator(pBuffer,self->replyTerminator); + sprintf(pError,"%s.replyTerminator = \"%s\"",argv[0], + pBuffer); + SCWrite(pCon,pError,eValue); + return 1; + } + } + else if(strcmp(argv[1],"write") == 0) + { + Arg2Text(argc-2,argv+2,pBuffer,8191); + iRet = writeRS232(self,pBuffer,strlen(pBuffer)); + if(iRet < 0) + { + getRS232Error(iRet,pError,255); + SCWrite(pCon,pError,eError); + return 0; + } + SCSendOK(pCon); + return 1; + } + else if(strcmp(argv[1],"read") == 0) + { + if(!availableRS232(self)) + { + SCWrite(pCon,"Nothing to read!",eError); + return 1; + } + iRet = readRS232(self,pBuffer,&iRead); + if(iRet < 0) + { + getRS232Error(iRet,pError,255); + SCWrite(pCon,pError,eError); + return 0; + } + SCWrite(pCon,pBuffer,eValue); + return 1; + } + else if(strcmp(argv[1],"available") == 0) + { + iRet = availableRS232(self); + if(iRet < 0) + { + getRS232Error(iRet,pError,255); + SCWrite(pCon,pError,eError); + return 0; + } + else if(iRet == 0) + { + SCWrite(pCon,"No data pending",eValue); + return 1; + } + else + { + SCWrite(pCon,"Data available",eValue); + return 1; + } + } + else if(strcmp(argv[1],"send") == 0) + { + Arg2Text(argc-2,argv+2,pBuffer,8191); + iRet = transactRS232(self,pBuffer,strlen(pBuffer), + pReply,iRead); + if(iRet < 0) + { + getRS232Error(iRet,pError,255); + SCWrite(pCon,pError,eError); + return 0; + } + SCWrite(pCon,pReply,eValue); + return 1; + } + else if(strcmp(argv[1],"init") == 0) + { + iRet = initRS232(self); + if(iRet != 1) + { + sprintf(pError,"ERROR: reinitializing connection to %s at %d failed", + self->pHost, self->iPort); + SCWrite(pCon,pError,eError); + return 0; + } + else + { + SCSendOK(pCon); + return 1; + } + } + else + { + sprintf(pError,"ERROR: %s does not understand %s",argv[0], argv[1]); + SCWrite(pCon,pError,eError); + return 0; + } + + return 1; +} +/*-------------------------------------------------------------------*/ +int RS232Factory(SConnection *pCon, SicsInterp *pSics, + void *pData, int argc, char *argv[]) +{ + prs232 pNew = NULL; + int iRet; + char pError[256]; + + if(argc < 4) + { + SCWrite(pCon,"ERROR: insufficient no of arguments to RS232Factory", + eError); + return 0; + } + + /* + create data structure and open port + */ + pNew = (prs232)malloc(sizeof(rs232)); + if(!pNew) + { + SCWrite(pCon,"ERROR: out of memory in RS232Factory",eError); + return 0; + } + memset(pNew, 0, sizeof(rs232)); + + pNew->pHost = strdup(argv[2]); + pNew->iPort = atoi(argv[3]); + pNew->sendTerminator = strdup("\r"); + pNew->replyTerminator = strdup("\n"); + pNew->timeout = 1000; + pNew->pDes = CreateDescriptor("RS232 Controller"); + if(!pNew->pDes || !pNew->pHost || + !pNew->replyTerminator || !pNew->sendTerminator) + { + SCWrite(pCon,"ERROR: out of memory in RS232Factory",eError); + return 0; + } + pNew->pSock = NETConnect(pNew->pHost, pNew->iPort); + if(!pNew->pSock) + { + sprintf(pError,"ERROR: failed to connect to %s at port %d", + pNew->pHost, pNew->iPort); + SCWrite(pCon,pError,eError); + } + + /* + create the command + */ + iRet = AddCommand(pSics,argv[1],RS232Action, KillRS232, pNew); + if(!iRet) + { + sprintf(pError,"ERROR: duplicate command %s not created", argv[1]); + SCWrite(pCon,pError,eError); + KillRS232(pNew); + return 0; + } + return 1; +} + + diff --git a/rs232controller.h b/rs232controller.h new file mode 100644 index 00000000..3b5be048 --- /dev/null +++ b/rs232controller.h @@ -0,0 +1,52 @@ + +/*--------------------------------------------------------------------- + R S 2 3 2 C o n t r o l l e r + + A general object which represents a controller connected to the network + via a terminal server. This bypasses David Maden's SerPortServer software. + Basic facilities are provided for writinga nd reading to and from the + device. For more information see the rs232controller.tex file. + + copyright: see copyright.h + + Mark Koennecke, October 2001 +-----------------------------------------------------------------------*/ +#ifndef RS232CONTROLLER +#define RS232CONTROLLER +#include "network.h" + +/*----------------------- a data structure ----------------------------*/ + + typedef struct{ + pObjectDescriptor pDes; + char *sendTerminator; + char *replyTerminator; + int timeout; + mkChannel *pSock; + char *pHost; + int iPort; + } rs232, *prs232; + + + +/*----------------------- the interface functions --------------------*/ + + int RS232Action(SConnection *pCon, SicsInterp *pSics, + void *pData, int argc, char *argv[]); + int RS232Factory(SConnection *pCon, SicsInterp *pSics, + void *pData, int argc, char *argv[]); + + void setRS232SendTerminator(prs232 self, char *term); + void setRS232ReplyTerminator(prs232 self, char *term); + void setRS232Timeout(prs232 self, int timeout); + int writeRS232(prs232 self, void *data, int dataLen); + int readRS232(prs232 self, void *data, int *dataLen); + int availableRS232(prs232 self); + int transactRS232(prs232 self, void *send, int sendLen, + void *reply, int replylen); + void getRS232Error(int iCode, char *errorBuffer, + int errorBufferLen); + int initRS232(prs232 self); + + +#endif diff --git a/rs232controller.w b/rs232controller.w new file mode 100644 index 00000000..76f3f0f8 --- /dev/null +++ b/rs232controller.w @@ -0,0 +1,120 @@ +\subsection{RS232 Controller} +This class provides the basic communication facilities for an arbitrary + controller which is connected through a RS-232 cable to a terminal + server. This class bypasses David Maden's SerPortServer program. Also this + code may be useful for any other controller connected to a TCP/IP + network. Basic facilities are provided for writing data to such a device + and to read from + it. Morevoer there are utility functions for the common case when the + device is to send some data terminated with a specified terminator. + Timeouts are also observed on reading operations. It is required that this + controller accesses a binary port and not a port which uses some kind of + telnet negotiation. + + + This classes data structure: + +@d rs232dat @{ + typedef struct{ + pObjectDescriptor pDes; + char *sendTerminator; + char *replyTerminator; + int timeout; + mkChannel *pSock; + char *pHost; + int iPort; + } rs232, *prs232; + +@} +The fields are: +\begin{description} +\item[pDes] The standard object descriptor. +\item[sendTerminator] The terminator with which to terminate any command. +\item[replyTerminator] The terminator expected to end a transmission from the + device. +\item[timeout] A timeout for reading in microseconds. +\item[mkChannel] Our very own structure for a network connection. +\item[pHost]The host (mostly the terminal server) to connect to. +\item[iPort] The port at host to which to connect. +\end{description} + +The following interface functions are provided: + +@d rs232int @{ + int RS232Action(SConnection *pCon, SicsInterp *pSics, + void *pData, int argc, char *argv[]); + int RS232Factory(SConnection *pCon, SicsInterp *pSics, + void *pData, int argc, char *argv[]); + + void setRS232SendTerminator(prs232 self, char *term); + void setRS232ReplyTerminator(prs232 self, char *term); + void setRS232Timeout(prs232 self, int timeout); + int writeRS232(prs232 self, void *data, int dataLen); + int readRS232(prs232 self, void *data, int *dataLen); + int availableRS232(prs232 self); + int transactRS232(prs232 self, void *send, int sendLen, + void *reply, int replylen); + void getRS232Error(int iCode, char *errorBuffer, + int errorBufferLen); + int initRS232(prs232 self); +@} + +All functions take a pointer to their daat structure as a parameter. +When the functions return an integer, 1 measn successful completion, + anything else is an error code if not stated otherwise. +The functions have the following meanings: +\begin{description} +\item[RS232Action] The interpreter interface functon for the controller. +\item[RS232Factory] The factory function for configuring an interpreter. +\item[setRS232SendTerm] sets the terminator with which each command is + terminated. +\item[setRS232ReplyTerminator] sets the expected terminator in a reply from + the device. +\item[setRS232Timeout] sets the timeout for reading from the device. The value + is in microseconds. +\item[writeRS232] writes dataLen bytes from data to the device. +\item[readRS232] reads at max dataLen bytes from the device. dataLen is set + to the actual number of bytes read. +\item[transactRS232] sends sendLen bytes from send to the device and then + reads from the device until the reply terminator has been found. At max + replyLen bytes of reply are copied to reply. +\item[availableRS232] returns 1 if data is available, o if none is available + and a negative value if an error occurs. +\item[getRS232Error] gets a string representation for the error code + iCode. +\item[initRS232] tries to close and reopen the RS232 connection. This is + useful for the automatic fixing of communication problems encountered. +\end{description} + +@o rs232controller.h @{ +/*--------------------------------------------------------------------- + R S 2 3 2 C o n t r o l l e r + + A general object which represents a controller connected to the network + via a terminal server. This bypasses David Maden's SerPortServer software. + Basic facilities are provided for writinga nd reading to and from the + device. For more information see the rs232controller.tex file. + + copyright: see copyright.h + + Mark Koennecke, October 2001 +-----------------------------------------------------------------------*/ +#ifndef RS232CONTROLLER +#define RS232CONTROLLER +#include "network.h" + +/*----------------------- a data structure ----------------------------*/ +@ + +/*----------------------- the interface functions --------------------*/ +@ + +#endif +@} + + + + + + + diff --git a/scan.c b/scan.c index 6acc89a3..5a2de335 100644 --- a/scan.c +++ b/scan.c @@ -797,7 +797,7 @@ extern void SNXFormatTime(char *pBuffer, int iLen); return 0; } /* end value */ - fVal = pVar->fStart + self->iNP * pVar->fStep; + fVal = pVar->fStart + (self->iNP - 1) * pVar->fStep; iRet = pVar->pInter->CheckLimits(pVar->pObject, fVal,pBueffel,511); if(!iRet) diff --git a/sicsstatus.tcl b/sicsstatus.tcl index 1c948dfa..1e7e03bd 100644 --- a/sicsstatus.tcl +++ b/sicsstatus.tcl @@ -1,12 +1,33 @@ -hm3 CountMode timer -hm3 preset 10.000000 +a5l.length 80.000000 +flightpathlength 0.000000 +flightpathlength setAccess 1 +flightpath 0.000000 +flightpath setAccess 1 +delay 2500.000000 +delay setAccess 1 +hm CountMode timer +hm preset 100.000000 +hm genbin 120.000000 35.000000 512 +hm init +datafile focus-1001848.hdf +datafile setAccess 3 hm2 CountMode timer -hm2 preset 2.000000 +hm2 preset 5.000000 hm1 CountMode timer -hm1 preset 2.000000 +hm1 preset 5.000000 +dbfile UNKNOWN +dbfile setAccess 2 +# Motor th +th SoftZero 0.000000 +th SoftLowerLim -120.000000 +th SoftUpperLim 120.000000 +th Fixed -1.000000 +th sign 1.000000 +th InterruptMode 0.000000 +th AccessCode 2.000000 #Crystallographic Settings -hkl lambda 1.190000 -hkl setub 0.004793 0.001687 0.064144 -0.160885 -0.000806 0.001924 0.001646 -0.083791 0.001273 +hkl lambda 1.179000 +hkl setub 0.016169 0.011969 0.063195 -0.000545 0.083377 -0.009117 -0.162051 0.000945 0.006312 det3dist 300.000000 det3dist setAccess 1 det3zeroy 128.000000 @@ -32,7 +53,7 @@ monodescription setAccess 1 # Motor om om SoftZero 0.000000 om SoftLowerLim -73.000000 -om SoftUpperLim 134.000000 +om SoftUpperLim 39.000000 om Fixed -1.000000 om sign 1.000000 om InterruptMode 0.000000 @@ -112,7 +133,7 @@ chi AccessCode 1.000000 # Motor omega omega SoftZero 0.000000 omega SoftLowerLim -73.000000 -omega SoftUpperLim 134.000000 +omega SoftUpperLim 39.000000 omega Fixed -1.000000 omega sign 1.000000 omega InterruptMode 0.000000 @@ -127,6 +148,8 @@ twotheta InterruptMode 0.000000 twotheta AccessCode 2.000000 lastscancommand cscan a4 10. .1 10 5 lastscancommand setAccess 2 +banana CountMode timer +banana preset 100.000000 sample_mur 0.000000 sample_mur setAccess 2 email UNKNOWN @@ -410,5 +433,5 @@ sample test sample setAccess 2 title uwe_test1 title setAccess 2 -starttime 2001-07-19 15:11:21 +starttime 2001-09-21 16:55:53 starttime setAccess 2 diff --git a/sinqhm/SinqHM_srv_filler.c b/sinqhm/SinqHM_srv_filler.c index 5dea4451..8b7fd25c 100755 --- a/sinqhm/SinqHM_srv_filler.c +++ b/sinqhm/SinqHM_srv_filler.c @@ -733,7 +733,7 @@ uchar ui1[4]; } lwl_hdr, xData, yData, edData; - int xPos, yPos, iTime, dataPos, edNum; + int xPos, yPos, iTime, dataPos, edNum, xOff, yOff; signed int sPosx, sPosy; int i, j, is, ts, left, right, middl, not_finished; uint *edge_pntr; @@ -743,6 +743,13 @@ usint *histsPtr = (usint *)Hist_base_addr; uchar *histcPtr = (uchar *)Hist_base_addr; + + /* + precalculate some offsets + */ + xOff = psdXOffset*psdXFactor; + yOff = psdYOffset*psdYFactor; + /*----------------------------------------------- ** Make register copies of some items for speed. */ @@ -803,14 +810,28 @@ */ xPos = xData.ui2[1]; if(xPos > 32767) - xPos -= 65536 + psdXFactor; + xPos -= 65536; yPos = yData.ui2[1]; if(yPos > 32767) - yPos -= 65536 + psdYFactor; + yPos -= 65536; + + /* + if(xPos > 0) + xPos =(int)((float)xPos/(float)psdXFactor +.5 + psdXOffset); + else + xPos =(int)((float)xPos/(float)psdXFactor -.49999 + psdXOffset); + + if(yPos > 0) + yPos =(int)((float)yPos/(float)psdYFactor +.5 + psdYOffset); + else + yPos =(int)((float)yPos/(float)psdYFactor -.49999 + psdYOffset); + */ + + xPos = (int) ( (float)(xPos+xOff)/(float)psdXFactor); + yPos = (int)( (float)(yPos+yOff)/(float)psdYFactor); + - xPos = xPos/psdXFactor + psdXOffset; - yPos = yPos/psdYFactor + psdYOffset; if(xPos < 0 || xPos > psdXSize) { printf("X position out of range: %d, alllowed 0 - %d\n", diff --git a/sinqhm/SinqHM_srv_routines.c b/sinqhm/SinqHM_srv_routines.c index 138a7ba3..d5f9fbf7 100755 --- a/sinqhm/SinqHM_srv_routines.c +++ b/sinqhm/SinqHM_srv_routines.c @@ -2537,9 +2537,6 @@ break; case 4: my_pntr.i4[offs] += hm_pntr.i4[dataPtr + k]; - if(hm_pntr.i4[dataPtr +k] > 0 ) { - printf("Data found at %d, %d, %d\n",i,j,k); - } break; } } diff --git a/sinqhmdriv.c b/sinqhmdriv.c index 2ad69bf5..631122f0 100644 --- a/sinqhmdriv.c +++ b/sinqhmdriv.c @@ -137,17 +137,20 @@ pCom = FindCommand(pSics,pcCounter); if(!pCom) { - PrintHMError("EL737 counter for histogram memory not found", + PrintHMError("WARNING: no EL737 counter for HM found! ", pCon); - return 0; + pInternal->pCounter = NULL; } - pInternal->pCounter = (pCounter)pCom->pData; - if(!pInternal->pCounter->pDes->GetInterface(pInternal->pCounter, - COUNTID)) - { - PrintHMError("EL737 counter for histogram memory is invalid", - pCon); - return 0; + else + { + pInternal->pCounter = (pCounter)pCom->pData; + if(!pInternal->pCounter->pDes->GetInterface(pInternal->pCounter, + COUNTID)) + { + PrintHMError("EL737 counter for histogram memory is invalid", + pCon); + return 0; + } } } /* ok! put in HM */ @@ -336,9 +339,12 @@ } /* tell the counter box our current status */ - SetCounterMode(pInternal->pCounter,self->eCount); - SetCounterPreset(pInternal->pCounter,self->fCountPreset); - + if(pInternal->pCounter != NULL) + { + SetCounterMode(pInternal->pCounter,self->eCount); + SetCounterPreset(pInternal->pCounter,self->fCountPreset); + } + self->iReconfig = 0; return 1; } diff --git a/slsmagnet.c b/slsmagnet.c new file mode 100644 index 00000000..c1967a80 --- /dev/null +++ b/slsmagnet.c @@ -0,0 +1,388 @@ + /*-------------------------------------------------------------------------- + S L S M A G N E T + + This file contains the driver for the PSI-DSP magnet controller as + aquired from SLS. + + Mark Koennecke, October 2001 + + Copyright: see copyright.h +----------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include "fortify.h" +#include "conman.h" +#include "servlog.h" +#include "fortify.h" + + typedef struct __EVDriver *pEVDriver; + +#include "evdriver.i" +#include "hardsup/el734_def.h" +#include "hardsup/el734fix.h" +#include "network.h" +#include "rs232controller.h" + +/* + error codes +*/ +#define BADECHO -5100 +#define NOTCONNECTED -5200 +#define TIMEOUT -5300 + +/* + when waiting for results, the code loops at max MAXLOOP times + before doing a timeout. 100 corresponds to one second +*/ +#define MAXLOOP 100 + +/* + packet header codes +*/ +#define DSPWRITE 0x80 +#define DSPREAD 0x0 + +/*-----------------------------------------------------------------------*/ + typedef struct { + mkChannel *pSock; + char *pHost; + int iPort; + int iError; + } SLSDriv, *pSLSDriv; +/*------------------------------------------------------------------------- + Code for data conversion from Lukas Tanner. The ULONG is system dependent, + it MUST describe a 32 bit value. + -------------------------------------------------------------------------*/ +#define ULONG int +/***********************************************************************/ +static ULONG double2DSPfloat( double input ) +/***********************************************************************/ +/* Konvertiert eine normale double Variable in ein 32bit DSP Float Format. */ +{ + ULONG output; + double mantissa; + int exponent; + + if (input == 0) { + output = 0; + } else { + mantissa = 2 * (frexp(fabs(input), &exponent)); + mantissa = ldexp(mantissa, 23); + exponent =exponent - 1 + 127; + if (exponent < 0) { + exponent = 0; + } else if (exponent > 0xFE) { + exponent = 0xFE; + } + exponent = exponent << 23; + output = ((ULONG) mantissa) & 0x7FFFFF; + output = output | ((ULONG) (exponent)); + if (input < 0) { + output = output | 0x80000000; + } + } + return output; +} + +/***********************************************************************/ +static double DSPfloat2double( ULONG input ) +/***********************************************************************/ +/* Konvertiert eine Variable inder ein 32bit DSP Float Wert abgelegt ist, + in ein normales double Format + 32bit IEEE Float => SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM; S = Sign Bit + E = Exponent + M = Mantissa (23)*/ +{ + double output; + if ((input & 0x7FFFFF) == 0 && ((input >> 23) & 0xFF) == 0) { + output = 0; + } else { + output = ldexp(input & 0x7FFFFF,-23) + 1; + output = output * pow(-1, ((input >>31) & 1)); + output = output * ldexp(1, (((input >>23) & 0xFF) - 127)); + } + return output; +} +/*-------------------------------------------------------------------------*/ +static int communicateSLS(mkChannel *pSock, char msg[6], char reply[6]) +{ + long lVal = 0; + int iRet, i; + + if(!pSock) + return NOTCONNECTED; + + iRet = NETWrite(pSock,msg,6); + if(iRet < 0) + { + return iRet; + } + for(i = 0; i < MAXLOOP; i++) + { + iRet = NETAvailable(pSock,10); + if(iRet < 0) + { + return iRet; + } + else if(iRet == 1) + { + lVal += NETRead(pSock,reply+lVal,6-lVal,-10); + if(lVal >= 6) + { + return (int)lVal; + } + else + { + continue; + } + } + } + return TIMEOUT; +} +/*---------------------------------------------------------------------------*/ + static int GetSLSPos(pEVDriver self, float *fPos) + { + pSLSDriv pMe = NULL; + int iRet, ival; + double dval; + char msg[6], reply[6]; + long lVal; + + assert(self); + pMe = (pSLSDriv)self->pPrivate; + assert(pMe); + + msg[0] = DSPREAD; /* read request */ + msg[1] = 0x92; /* address of mag current */ + iRet = communicateSLS(pMe->pSock,msg,reply); + if(iRet < 0) + { + pMe->iError = iRet; + return iRet; + } + memcpy(&ival,reply+2,4); + dval = DSPfloat2double(ival); + *fPos = (float)dval; + pMe->iError = 0; + + return 1; + } +/*----------------------------------------------------------------------------*/ + static int SLSRun(pEVDriver self, float fVal) + { + pSLSDriv pMe = NULL; + int iRet, ival,i; + char msg[6], reply[6]; + + assert(self); + pMe = (pSLSDriv )self->pPrivate; + assert(pMe); + + msg[0] = DSPWRITE; + msg[1] = 0x90; + ival = double2DSPfloat((double)fVal); + memcpy(msg+2, &ival,4); + iRet = communicateSLS(pMe->pSock,msg,reply); + if(iRet <= 0) + { + pMe->iError = iRet; + return iRet; + } + for(i = 1; i < 6; i++) + { + if(msg[i] != reply[i]) + { + pMe->iError = BADECHO; + return BADECHO; + } + } + return 1; + } +/*--------------------------------------------------------------------------*/ + static int SLSError(pEVDriver self, int *iCode, char *error, int iErrLen) + { + pSLSDriv pMe = NULL; + char *pPtr = NULL; + int i1, i2; + char pBueffel[132]; + + assert(self); + pMe = (pSLSDriv)self->pPrivate; + assert(pMe); + + *iCode = pMe->iError; + switch(*iCode) + { + case BADECHO: + strncpy(error,"message sent and reply did not match", iErrLen); + break; + case NOTCONNECTED: + strncpy(error,"Not connected to device", iErrLen); + break; + case TIMEOUT: + strncpy(error,"Timeout waiting for response", iErrLen); + break; + default: + getRS232Error(*iCode,error,iErrLen); + break; + } + + return 1; + } +/*-------------------------------------------------------------------------*/ + static int SLSSend(pEVDriver self, char *pCommand, char *pReply, int iLen) + { + strncpy(pReply,"PSI-DSP understands only binary, send disabled",iLen); + return 0; + } +/*--------------------------------------------------------------------------*/ + static int SLSInit(pEVDriver self) + { + pSLSDriv pMe = NULL; + int iRet, ival, i; + char msg[6], reply[6]; + + assert(self); + pMe = (pSLSDriv )self->pPrivate; + assert(pMe); + + pMe->pSock = NULL; + pMe->pSock = NETConnect(pMe->pHost,pMe->iPort); + if(!pMe->pSock) + { + return 0; + } + + sleep(1); + + /* + try to switch device on + */ + msg[0] = DSPWRITE; + msg[1] = 0x31; + ival = 1; + memcpy(msg+2, &ival,4); + iRet = communicateSLS(pMe->pSock,msg,reply); + if(iRet <= 0) + { + pMe->iError = iRet; + return iRet; + } + for(i = 1; i < 6; i++) + { + if(msg[i] != reply[i]) + { + pMe->iError = BADECHO; + return BADECHO; + } + } + + return iRet; + } +/*--------------------------------------------------------------------------*/ + static int SLSClose(pEVDriver self) + { + pSLSDriv pMe = NULL; + int iRet; + + assert(self); + pMe = (pSLSDriv )self->pPrivate; + assert(pMe); + + NETClosePort(pMe->pSock); + pMe->pSock = NULL; + return 1; + } +/*---------------------------------------------------------------------------*/ + static int SLSFix(pEVDriver self, int iError) + { + pSLSDriv pMe = NULL; + int iRet; + + assert(self); + pMe = (pSLSDriv )self->pPrivate; + assert(pMe); + + switch(iError) + { + case BADECHO: + case TIMEOUT: + return DEVREDO; + default: + SLSClose(self); + iRet = SLSInit(self); + if(iRet) + { + return DEVREDO; + } + else + { + return DEVFAULT; + } + break; + } + } + +/*--------------------------------------------------------------------------*/ + static int SLSHalt(pEVDriver *self) + { + assert(self); + + return 1; + } +/*------------------------------------------------------------------------*/ + void KillSLS(void *pData) + { + pSLSDriv pMe = NULL; + + pMe = (pSLSDriv)pData; + assert(pMe); + + if(pMe->pHost) + { + free(pMe->pHost); + } + free(pMe); + } +/*------------------------------------------------------------------------*/ + pEVDriver CreateSLSDriv(int argc, char *argv[]) + { + pEVDriver pNew = NULL; + pSLSDriv pSim = NULL; + + /* check for arguments */ + if(argc < 2) + { + return NULL; + } + + pNew = CreateEVDriver(argc,argv); + pSim = (pSLSDriv)malloc(sizeof(SLSDriv)); + memset(pSim,0,sizeof(SLSDriv)); + if(!pNew || !pSim) + { + return NULL; + } + pNew->pPrivate = pSim; + pNew->KillPrivate = KillSLS; + + pSim->pHost = strdup(argv[0]); + pSim->iPort = atoi(argv[1]); + + /* initialise function pointers */ + pNew->SetValue = SLSRun; + pNew->GetValue = GetSLSPos; + pNew->Send = SLSSend; + pNew->GetError = SLSError; + pNew->TryFixIt = SLSFix; + pNew->Init = SLSInit; + pNew->Close = SLSClose; + + return pNew; + } + + + diff --git a/tasdrive.c b/tasdrive.c index d018bfbb..44a54f00 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -269,6 +269,7 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, } } + /* wait till we are finished */ @@ -299,3 +300,8 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, return rStatus; } + + + + + diff --git a/tasutil.c b/tasutil.c index 69487666..190fa11f 100644 --- a/tasutil.c +++ b/tasutil.c @@ -439,8 +439,8 @@ int TASStart(pTASdata self, SConnection *pCon, SicsInterp *pSics, tasMotorOrder[i], motorTargets[i]); if(status == 0) { - /* the error will have been reported */ - return 0; + /* the error will have been reported and must be ignored */ + SCSetInterrupt(pCon,eContinue); } } } @@ -453,8 +453,8 @@ int TASStart(pTASdata self, SConnection *pCon, SicsInterp *pSics, "MCV", motorTargets[6]); if(status == 0) { - /* the error will have been reported */ - return 0; + /* the error will have been reported but must be ignored*/ + SCSetInterrupt(pCon,eContinue); } } if(motorMask[8]) @@ -463,7 +463,8 @@ int TASStart(pTASdata self, SConnection *pCon, SicsInterp *pSics, "ACH", motorTargets[8]); if(status == 0) { - /* the error will have been reported */ + /* the error will have been reported but must be ignored*/ + SCSetInterrupt(pCon,eContinue); return 0; } } diff --git a/test.tcl b/test.tcl index bf84ba4b..97f65b51 100644 --- a/test.tcl +++ b/test.tcl @@ -473,3 +473,6 @@ MakeLin2Ang a5l a5 #source tmp/beam.tcl source tcl/wwwpar.tcl source bef.tcl + +#------- test of RS232Controller +#MakeRS232Controller hugo psts213 3004 diff --git a/trics.dic b/trics.dic index 0e5fe9b7..2d2a794b 100644 --- a/trics.dic +++ b/trics.dic @@ -72,7 +72,7 @@ frametilt = /$(framename),NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS -attr {units,degrees} framecounts = /$(framename),NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS counts \ -attr {signal,1} -attr {units,counts} -type DFNT_INT32 \ - -LZW -rank 2 -dim {$(framedim1),$(framedim2)} + -LZW -chunk {256,256} -rank 2 -dim {$(framedim1),$(framedim2)} detzerox = \ /frame0000,NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS x_zero_point \ -attr {units,pixel}