diff --git a/hkl.c b/hkl.c index d00d7553..f93fec5f 100644 --- a/hkl.c +++ b/hkl.c @@ -628,7 +628,7 @@ static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon, { if(iRetry > 1) { - psi = i*10.; + psi = i*.5; } else { @@ -725,7 +725,7 @@ static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon, { if(iRetry > 1) { - psi = 10. *i; + psi = i*.5; } else { @@ -846,7 +846,7 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self, } else { - iRetry = 35; + iRetry = 699; } @@ -861,6 +861,9 @@ static int calculateNormalBeamOmega(MATRIX z1, pHKL self, if(self->iOMPHI > 0) { if(ABS(fSet[2] - .0) < .1 || ABS(fSet[2] - 180.) < .1){ fSet[1] -= fSet[3]; + /* + fSet[1] = 360. - fSet[3]; + */ fSet[3] = .0; if(fSet[1] < 0.){ fSet[1] += 360.; diff --git a/hklscan.c b/hklscan.c index 883fc6de..de9bf0c9 100644 --- a/hklscan.c +++ b/hklscan.c @@ -155,7 +155,8 @@ /* make the data header */ sprintf(pLine,"%-5s","NP"); - strcpy(pInfo,"Scanning Variables: H, K, L"); + sprintf(pInfo,"Scanning Variables: H, K, L STEP: %8.3f %8.3f %8.3f", + pHaSca->fStep[0],pHaSca->fStep[1], pHaSca->fStep[2]); strcat(pLine,"H K L "); for(i = 0; i < self->iScanVar;i++) { diff --git a/mccontrol.c b/mccontrol.c index 46b2ebaa..1927259e 100644 --- a/mccontrol.c +++ b/mccontrol.c @@ -1,4 +1,4 @@ - /*---------------------------------------------------------------------------- +/*---------------------------------------------------------------------------- McStas simulation to SICS controller module implementation file. For more details see mcstas.tex. @@ -296,25 +296,16 @@ int McStasStart(pMcStasController self, CounterMode mode, float fPreset){ static long readMonFile(pMcStasController self){ char pResult[256]; FILE *fd = NULL; - struct flock fl; long monValue = -1; int i; if(!StringDictGet(self->scripts,"mcmonfile",pResult,255)){ return -1; } - fl.l_type = F_RDLCK; - fl.l_whence = SEEK_SET; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); - + fd = fopen(pResult,"r"); if(fd != NULL){ - fcntl(fileno(fd),F_SETLKW,&fl); fscanf(fd,"%ld", &monValue); - fl.l_type = F_UNLCK; - fcntl(fileno(fd),F_SETLK,&fl); fclose(fd); } return monValue; diff --git a/mcreader.c b/mcreader.c index 082e1ffa..4470ac59 100644 --- a/mcreader.c +++ b/mcreader.c @@ -7,6 +7,7 @@ Mark Koennecke, June 2005 -----------------------------------------------------------------------------*/ #include +#include #include "mcreader.h" #include "counter.h" #include "HistMem.h" @@ -283,12 +284,12 @@ static int insertHM(pMcStasReader self, SConnection *pCon, return 0; } - pData = (char *)malloc(iDim[0]*sizeof(char)); + pData = (char *)malloc((iDim[0]+1)*sizeof(char)); if(pData == NULL){ SCWrite(pCon,"ERROR: out of memory in mcreader inserthm",eError); return 0; } - memset(pData,0,iDim[0]*sizeof(char)); + memset(pData,0,(iDim[0]+1)*sizeof(char)); status = NXgetdata(self->handle,pData); if(status != NX_OK){ @@ -322,6 +323,57 @@ static int insertHM(pMcStasReader self, SConnection *pCon, return 1; } /*--------------------------------------------------------------------------*/ +static int getField(pMcStasReader self, SConnection *pCon, + SicsInterp *pSics, int argc, char *argv[]){ + char pBueffel[512], *pPtr, pNumber[80], *pData = NULL; + int status, type, rank, iDim[NX_MAXRANK]; + + if(argc < 2){ + SCWrite(pCon,\ + "ERROR: insufficient number of arguments to mcreader getfield", + eError); + return 0; + } + if(self->handle == NULL){ + SCWrite(pCon,"ERROR: no file open to read data from",eError); + return 0; + } + + status = NXopenpath(self->handle,argv[2]); + if(status != NX_OK){ + snprintf(pBueffel,511,"ERROR: Nexus error %s while opening %s", + self->nexusError, argv[2]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + + status = NXgetinfo(self->handle,&rank,iDim,&type); + if(status != NX_OK){ + snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s", + self->nexusError, argv[2]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + + pData = (char *)malloc((iDim[0]+1)*sizeof(char)); + if(pData == NULL){ + SCWrite(pCon,"ERROR: out of memory in mcreader getfield",eError); + return 0; + } + memset(pData,0,(iDim[0]+1)*sizeof(char)); + + status = NXgetdata(self->handle,pData); + if(status != NX_OK){ + snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s", + self->nexusError, argv[2]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + SCWrite(pCon,pData,eValue); + free(pData); + return 1; +} +/*--------------------------------------------------------------------------*/ static int insertHMFromData(pMcStasReader self, SConnection *pCon, SicsInterp *pSics, int argc, char *argv[]){ char pBueffel[512]; @@ -403,6 +455,8 @@ int McStasReaderWrapper(SConnection *pCon, SicsInterp *pSics, return insertHM(self,pCon, pSics,argc,argv); } else if(strcmp(argv[1],"inserthmfromdata") == 0){ return insertHMFromData(self,pCon, pSics,argc,argv); + } else if(strcmp(argv[1],"getfield") == 0){ + return getField(self,pCon, pSics,argc,argv); } else { snprintf(pBueffel,511,"ERROR: invalid subcommand %s to %s", argv[1],argv[0]); diff --git a/mcstas/dmc/DataNumber b/mcstas/dmc/DataNumber index 37109d54..68a86760 100644 --- a/mcstas/dmc/DataNumber +++ b/mcstas/dmc/DataNumber @@ -1,3 +1,3 @@ - 89 + 98 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/mcstas/dmc/MKMonitor.comp b/mcstas/dmc/MKMonitor.comp index d21d3c55..79eb2803 100644 --- a/mcstas/dmc/MKMonitor.comp +++ b/mcstas/dmc/MKMonitor.comp @@ -47,24 +47,18 @@ OUTPUT PARAMETERS (Nsum, psum, p2sum,currentCount) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) SHARE %{ -#include void dumpTotal(char *ffilename, long totalCounts){ FILE *fd = NULL; - struct flock fl; - - fl.l_type = F_WRLCK; - fl.l_whence = 0; - fl.l_start = 0; - fl.l_len = 0; - fl.l_pid = getpid(); - - fd = fopen(ffilename,"w"); + char tmp[1024]; + + strncpy(tmp,ffilename, 1000); + strcat(tmp,"tmp"); + fd = fopen(tmp,"w"); if(fd != NULL){ - fcntl(fileno(fd),F_SETLKW,&fl); fprintf(fd,"%ld\n",totalCounts); - fl.l_type = F_UNLCK; - fcntl(fileno(fd),F_SETLK,&fl); fclose(fd); + rename(tmp,ffilename); + unlink(tmp); } } %} diff --git a/mcstas/dmc/vdmccom.tcl b/mcstas/dmc/vdmccom.tcl index 6c763549..2dce4196 100644 --- a/mcstas/dmc/vdmccom.tcl +++ b/mcstas/dmc/vdmccom.tcl @@ -156,14 +156,14 @@ proc rundmcoptsim {mode preset } { } } #------------------------------------------------------------------------ -proc copydmcdata { } { +proc copydmcdataold { } { global home set mcversion "McStas 1.8 - Mar. 05, 2004" washsimfile $home/dmc.xml mcreader open $home/dmc.xml mcreader insertmon \ "/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \ - counter 1 [expr 1./700] + counter 1 [expr 1./350] mcreader insertmon \ "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \ counter 5 @@ -171,7 +171,36 @@ proc copydmcdata { } { if { $hmScale <= 0} { set hmScale 1e9 } else { - set hmScale [expr $hmScale * 1e5] + set hmScale [expr $hmScale * 5e4] + } + clientput "HM scale = $hmScale" + mcreader inserthm \ + "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/data" banana $hmScale + mcreader close +} +#------------------------------------------------------------------------ +proc copydmcdata { } { + global home + set mcversion "McStas 1.8 - Mar. 05, 2004" + washsimfile $home/dmc.xml + mcreader open $home/dmc.xml + mcreader insertmon \ + "/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \ + counter 1 [expr 1./350] + mcreader insertmon \ + "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \ + counter 5 + set hmScale [SplitReply [counter getmonitor 5]] + set val [mcreader getfield\ + "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values"] + set l [split $val] + set a [lindex $l 0] + set b [lindex $val 2] + if {$b > .0} { + set hmScale [expr $b / $a] + set hmScale [expr $hmScale / 6.] + } else { + set hmScale 1e9 } clientput "HM scale = $hmScale" mcreader inserthm \ @@ -186,9 +215,9 @@ proc dmcdump {pid} { #mccontrol configure mcstart rundmcsim mccontrol configure mcstart rundmcoptsim mccontrol configure mccopydata copydmcdata -mccontrol configure update 60 +mccontrol configure update 30 mccontrol configure mcmonfile $home/monfile -mccontrol configure monitorscale [expr 1. /700] +mccontrol configure monitorscale [expr 1. /350] mccontrol configure mcdump mcstasdump #-------------------------------------------------------------------------- # A count command for VDMC diff --git a/mcstas/dmc/vdmcstatus.tcl b/mcstas/dmc/vdmcstatus.tcl index d5c4b54d..b13c25c8 100644 --- a/mcstas/dmc/vdmcstatus.tcl +++ b/mcstas/dmc/vdmcstatus.tcl @@ -14,7 +14,7 @@ sicsdatapostfix .hdf sicsdatapostfix setAccess 0 sicsdataprefix powder sicsdataprefix setAccess 0 -starttime 2005-07-19 17:15:54 +starttime 2005-08-16 16:46:50 starttime setAccess 2 comment3 UNKNOWN comment3 setAccess 2 @@ -121,9 +121,9 @@ a1 precision 0.010000 a1 AccessCode 2.000000 a1 movecount 10.000000 banana CountMode monitor -banana preset 4000.000000 +banana preset 60.000000 # Counter counter -counter SetPreset 40000000.000000 +counter SetPreset 60000.000000 counter SetMode Monitor # Motor twothetad twothetad sign 1.000000 diff --git a/mesure.c b/mesure.c index 49e03992..1ef700ea 100644 --- a/mesure.c +++ b/mesure.c @@ -625,7 +625,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon) fStart -= (np/2)*stepWidth; /* - spcial case: psd mode + special case: psd mode */ if(self->psd == 1) { diff --git a/motor.c b/motor.c index 1b876a4b..85a34ede 100644 --- a/motor.c +++ b/motor.c @@ -216,6 +216,9 @@ static int statusRunTo(pMotor self, SConnection *pCon) SCWrite(pCon,pBueffel,eError); return HWFault; } + if(SCGetInterrupt(pCon) != eContinue){ + return HWFault; + } self->retryCount++; snprintf(pBueffel,255,"WARNING: restarting %s, %d time", self->name,self->retryCount); diff --git a/napi.c b/napi.c index 60673de8..4f7cb501 100644 --- a/napi.c +++ b/napi.c @@ -23,12 +23,13 @@ ----------------------------------------------------------------------------*/ -static const char* rscid = "$Id: napi.c,v 1.11 2005/06/22 07:10:00 koennecke Exp $"; /* Revision interted by CVS */ +static const char* rscid = "$Id: napi.c,v 1.12 2005/09/07 13:51:12 koennecke Exp $"; /* Revision interted by CVS */ #include #include #include #include +#include #include #include #include "napi.h" @@ -157,13 +158,27 @@ static int determineFileType(CONSTCHAR *filename) iFortifyScope = Fortify_EnterScope(); Fortify_CheckAllMemory(); */ - *gHandle = NULL; + + /* + allocate data + */ + *gHandle = NULL; fHandle = (pNexusFunction)malloc(sizeof(NexusFunction)); if (fHandle == NULL) { NXIReportError (NXpData,"ERROR: no memory to create Function structure"); return NX_ERROR; } memset(fHandle, 0, sizeof(NexusFunction)); /* so any functions we miss are NULL */ + + /* + test the strip flag. Elimnate it for the rest of the tests to work + */ + fHandle->stripFlag = 1; + if(am & NXACC_NOSTRIP){ + fHandle->stripFlag = 0; + am -= NXACC_NOSTRIP; + } + if (am==NXACC_CREATE) { /* HDF4 will be used ! */ hdf_type=1; @@ -306,7 +321,16 @@ static int determineFileType(CONSTCHAR *filename) int rank, int dimensions[]) { pNexusFunction pFunc = (pNexusFunction)fid; - return pFunc->nxmakedata(pFunc->pNexusData, name, datatype, rank, dimensions); + if ( (datatype == NX_CHAR) && (rank > 1) ) + { + NXIReportError (NXpData, + "ERROR: multi-dimensional NX_CHAR arrays are not supported by the NeXus library"); + return NX_ERROR; + } + else + { + return pFunc->nxmakedata(pFunc->pNexusData, name, datatype, rank, dimensions); + } } @@ -316,7 +340,16 @@ static int determineFileType(CONSTCHAR *filename) int rank, int dimensions[],int compress_type, int chunk_size[]) { pNexusFunction pFunc = (pNexusFunction)fid; - return pFunc->nxcompmakedata (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size); + if ( (datatype == NX_CHAR) && (rank > 1) ) + { + NXIReportError (NXpData, + "ERROR: multi-dimensional NX_CHAR arrays are not supported by the NeXus library"); + return NX_ERROR; + } + else + { + return pFunc->nxcompmakedata (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size); + } } @@ -419,27 +452,32 @@ static int determineFileType(CONSTCHAR *filename) /*-------------------------------------------------------------------------*/ - NXstatus CALLING_STYLE 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; *data = NULL; for(i=0; inxgetnextentry(pFunc->pNexusData, name, nxclass, datatype); } +/*----------------------------------------------------------------------*/ +/* +** TRIM.C - Remove leading, trailing, & excess embedded spaces +** +** public domain by Bob Stout +*/ +#define NUL '\0' +static char *nxitrim(char *str) +{ + char *ibuf = str, *obuf = str; + int i = 0, cnt = 0; + /* + ** Trap NULL + */ + + if (str) + { + /* + ** Remove leading spaces (from RMLEAD.C) + */ + + for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf) + ; + str = ibuf; + + /* + ** Remove trailing spaces (from RMTRAIL.C) + */ + i = strlen(str); + while (--i >= 0) + { + if (!isspace(str[i])) + break; + } + str[++i] = NUL; + } + return str; +} /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetdata (NXhandle fid, void *data) { + int status, type, rank, iDim[NX_MAXRANK]; + char *pPtr, *pPtr2; + pNexusFunction pFunc = (pNexusFunction)fid; - return pFunc->nxgetdata(pFunc->pNexusData, data); + status = pFunc->nxgetinfo(pFunc->pNexusData, &rank, iDim, &type); /* unstripped size if string */ + if ( (type == NX_CHAR) && (pFunc->stripFlag == 1) ) + { + pPtr = (char*)malloc(iDim[0]+1); + memset(pPtr, 0, iDim[0]+1); + status = pFunc->nxgetdata(pFunc->pNexusData, pPtr); + pPtr2 = nxitrim(pPtr); + strncpy((char*)data, pPtr2, strlen(pPtr2)); /* not NULL terminated by default */ + free(pPtr); + } + else + { + status = pFunc->nxgetdata(pFunc->pNexusData, data); + } + return status; } - /*-------------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NXgetinfo (NXhandle fid, int *rank, int dimension[], int *iType) + NXstatus CALLING_STYLE NXgetinfo (NXhandle fid, int *rank, + int dimension[], int *iType) { + int status; + char *pPtr = NULL; + pNexusFunction pFunc = (pNexusFunction)fid; - return pFunc->nxgetinfo(pFunc->pNexusData, rank, dimension, iType); + status = pFunc->nxgetinfo(pFunc->pNexusData, rank, dimension, iType); + /* + the length of a string may be trimmed.... + */ + if(*iType == NX_CHAR && pFunc->stripFlag == 1){ + pPtr = (char *)malloc((dimension[0]+1)*sizeof(char)); + if(pPtr != NULL){ + memset(pPtr,0,(dimension[0]+1)*sizeof(char)); + pFunc->nxgetdata(pFunc->pNexusData, pPtr); + dimension[0] = strlen(nxitrim(pPtr)); + free(pPtr); + } + } + if ( (*iType == NX_CHAR) && (*rank > 1) ) + { + NXIReportError(NXpData, + "WARNING: multi-dimensional character arrays are not really supported"); + } + return status; } /*-------------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NXgetslab (NXhandle fid, void *data, int iStart[], int iSize[]) + NXstatus CALLING_STYLE NXgetslab (NXhandle fid, void *data, + int iStart[], int iSize[]) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetslab(pFunc->pNexusData, data, iStart, iSize); @@ -754,7 +869,6 @@ static NXstatus stepOneUp(NXhandle hfil, char *name) { return NX_OK; } - NXinitgroupdir(hfil); while(NXgetnextentry(hfil,name2,xclass,&datatype) != NX_EOD) diff --git a/napi.h b/napi.h index edf04a2d..26543077 100644 --- a/napi.h +++ b/napi.h @@ -3,7 +3,7 @@ Application Program Interface Header File - Copyright (C) 2000-2003 Mark Koennecke, Uwe Filges + Copyright (C) 2000-2005 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 @@ -21,7 +21,7 @@ For further information, see - $Id: napi.h,v 1.8 2005/05/27 11:58:05 koennecke Exp $ + $Id: napi.h,v 1.9 2005/09/07 13:51:12 koennecke Exp $ ----------------------------------------------------------------------------*/ @@ -45,16 +45,30 @@ #ifdef _WIN32 #define snprintf nxisnprintf - extern int nxisnprintf(char* buffer, int len, const char* format, ... ); - -#endif +#endif /* _WIN32 */ typedef void* NXhandle; /* really a pointer to a NexusFile structure */ typedef int NXstatus; typedef char NXname[128]; -typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE4=4, NXACC_CREATE5=5, NXACC_CREATEXML=6} NXaccess; +/* + * Any new NXaccess options should be numbered in 2^n format + * (8, 16, 32, etc) so that they can be bit masked and tested easily. + * + * To test older non bit masked options (values below 8) use e.g. + * + * if ( (mode & NXACCMASK_REMOVEFLAGS) == NXACC_CREATE ) + * + * To test new (>=8) options just use normal bit masking e.g. + * + * if ( mode & NXACC_NOSTRIP ) + * + */ +#define NXACCMASK_REMOVEFLAGS (0x7) /* bit mask to remove higher flag options */ + +typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE4=4, + NXACC_CREATE5=5, NXACC_CREATEXML=6, NXACC_NOSTRIP=128} NXaccess; typedef struct { char *iname; @@ -70,10 +84,6 @@ typedef struct { #define NX_MAXRANK 32 #define NX_MAXNAMELEN 64 - - - - /*------------------------------------------------------------------------- HDF Datatype values for datatype parameters in the Nexus API @@ -91,7 +101,6 @@ typedef struct { --------------------------------------------------------------------------*/ - /* Map NeXus to HDF types */ #define NX_FLOAT32 5 #define NX_FLOAT64 6 @@ -111,37 +120,20 @@ typedef struct { #define NX_COMP_RLE 300 #define NX_COMP_HUF 400 - -#ifdef HDF4 -#include -#endif - -#ifdef HDF5 -#include -#endif - -#ifndef HDF4 -typedef int int32; -#endif - typedef struct { - int32 iTag; /* HDF4 variable */ - int32 iRef; /* HDF4 variable */ -#ifdef HDF5 + long iTag; /* HDF4 variable */ + long iRef; /* HDF4 variable */ char iTag5[1024]; /* HDF5 variable */ char iRef5[1024]; /* HDF5 variable */ char iRefd[1024]; /* HDF5 variable */ -#endif char targetPath[1024]; /* XML path */ } NXlink; - - #define NXMAXSTACK 50 #define CONCAT(__a,__b) __a##__b /* token concatenation */ -#if defined(__unix) || defined(__unix__) || defined (__VMS) +#if defined(__unix) || defined(__unix__) || defined (__VMS) || defined(__APPLE__) # ifdef __VMS # define MANGLE(__arg) __arg @@ -331,6 +323,7 @@ NX_EXTERNAL NXstatus CALLING_STYLE NXfree(void** data); NX_EXTERNAL void CALLING_STYLE NXMSetError(void *pData, void (*ErrFunc)(void *pD, char *text)); extern void (*NXIReportError)(void *pData,char *text); extern void *NXpData; +extern char *NXIformatNeXusTime(); /* @@ -344,6 +337,7 @@ NX_EXTERNAL NXstatus CALLING_STYLE NXsetcache(long newVal); */ typedef struct { NXhandle *pNexusData; + int stripFlag; NXstatus (CALLING_STYLE *nxclose)(NXhandle* pHandle); NXstatus (CALLING_STYLE *nxflush)(NXhandle* pHandle); NXstatus (CALLING_STYLE *nxmakegroup) (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); diff --git a/napi4.c b/napi4.c index 45974ee1..6838ce60 100644 --- a/napi4.c +++ b/napi4.c @@ -21,7 +21,7 @@ For further information, see - $Id: napi4.c,v 1.4 2005/05/27 11:58:06 koennecke Exp $ + $Id: napi4.c,v 1.5 2005/09/07 13:51:12 koennecke Exp $ ----------------------------------------------------------------------------*/ #include @@ -324,18 +324,12 @@ extern void *NXpData; NXhandle* pHandle) { pNexusFile pNew = NULL; - char pBuffer[512], time_buffer[64]; + char pBuffer[512]; + char *time_puffer; char HDF_VERSION[64]; uint32 lmajor, lminor, lrelease; int32 am1=0; int32 file_id=0, an_id=0, ann_id=0; - time_t timer; - struct tm *time_info; - const char* time_format; - long gmt_offset; -#ifdef USE_FTIME - struct timeb timeb_struct; -#endif /* USE_FTIME */ *pHandle = NULL; /* map Nexus NXaccess types to HDF4 types */ @@ -355,53 +349,9 @@ extern void *NXpData; return NX_ERROR; } memset (pNew, 0, sizeof (NexusFile)); -/* - * get time in ISO 8601 format - */ -/* -#ifdef NEED_TZSET - tzset(); -#endif - time(&timer); -#ifdef USE_FTIME - ftime(&timeb_struct); - gmt_offset = -timeb_struct.timezone * 60; - if (timeb_struct.dstflag != 0) { - gmt_offset += 3600; - } -#else - time_info = gmtime(&timer); - if (time_info != NULL) { - gmt_offset = (long)difftime(timer, mktime(time_info)); - } else { - NXIReportError(NXpData, "Your gmtime() function does not work ... timezone information will be incorrect\n"); - gmt_offset = 0; - } -#endif - time_info = localtime(&timer); -*/ - time_info = NULL; - if (time_info != NULL) { - if (gmt_offset < 0) { - time_format = "%04d-%02d-%02d %02d:%02d:%02d-%02d%02d"; - } else { - time_format = "%04d-%02d-%02d %02d:%02d:%02d+%02d%02d"; - } - sprintf(time_buffer, time_format, - 1900 + time_info->tm_year, - 1 + time_info->tm_mon, - time_info->tm_mday, - time_info->tm_hour, - time_info->tm_min, - time_info->tm_sec, - abs(gmt_offset / 3600), - abs((gmt_offset % 3600) / 60) - ); - } else { - strcpy(time_buffer, "1970-01-01 00:00:00+0000"); - } - + time_puffer = NXIformatNeXusTime(); + #if WRITE_OLD_IDENT /* not used at moment */ /* * write something that can be used by OLE @@ -457,9 +407,15 @@ extern void *NXpData; NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); return NX_ERROR; } - if (SDsetattr(pNew->iSID, "file_time", DFNT_CHAR8, strlen(time_buffer), time_buffer) < 0) { - NXIReportError (NXpData, "ERROR: HDF failed to store file_time attribute "); - return NX_ERROR; + if(time_puffer != NULL){ + if (SDsetattr(pNew->iSID, "file_time", DFNT_CHAR8, + strlen(time_puffer), time_puffer) < 0) { + NXIReportError (NXpData, + "ERROR: HDF failed to store file_time attribute "); + free(time_puffer); + return NX_ERROR; + } + free(time_puffer); } } @@ -1465,7 +1421,8 @@ extern void *NXpData; /*-------------------------------------------------------------------------*/ NXstatus - CALLING_STYLE NX4getinfo (NXhandle fid, int *rank, int dimension[], int *iType) + CALLING_STYLE NX4getinfo (NXhandle fid, int *rank, int dimension[], + int *iType) { pNexusFile pFile; NXname pBuffer; diff --git a/napi4.h b/napi4.h index 927d58a8..05a9e70f 100644 --- a/napi4.h +++ b/napi4.h @@ -1,6 +1,6 @@ #define NXSIGNATURE 959697 -#include "napi.h" +#include "mfhdf.h" /* #include "napi4.c" */ /* diff --git a/napi5.c b/napi5.c index b4f9e983..aca1767f 100644 --- a/napi5.c +++ b/napi5.c @@ -117,13 +117,10 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); { hid_t attr1,aid1, aid2; pNexusFile5 pNew = NULL; - char pBuffer[512], time_buffer[64]; + char pBuffer[512]; + char *time_buffer; char version_nr[10]; int iRet; - time_t timer; - struct tm *time_info; - const char* time_format; - long gmt_offset; unsigned int vers_major, vers_minor, vers_release, am1 ; hid_t fapl; int mdc_nelmts; @@ -132,7 +129,6 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); #else size_t rdcc_nelmts; #endif - size_t rdcc_nbytes; double rdcc_w0; @@ -151,56 +147,8 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); } memset (pNew, 0, sizeof (NexusFile5)); -#ifdef NEED_TZSET - tzset(); -#endif - time(&timer); -#ifdef USE_FTIME - ftime(&timeb_struct); - gmt_offset = -timeb_struct.timezone * 60; - if (timeb_struct.dstflag != 0) - { - gmt_offset += 3600; - } -#else - time_info = gmtime(&timer); - if (time_info != NULL) - { - gmt_offset = (long)difftime(timer, mktime(time_info)); - } - else - { - NXIReportError (NXpData, - "Your gmtime() function does not work ... timezone information will be incorrect\n"); - gmt_offset = 0; - } -#endif - time_info = localtime(&timer); - if (time_info != NULL) - { - if (gmt_offset < 0) - { - time_format = "%04d-%02d-%02d %02d:%02d:%02d-%02d%02d"; - } - else - { - time_format = "%04d-%02d-%02d %02d:%02d:%02d+%02d%02d"; - } - sprintf(time_buffer, time_format, - 1900 + time_info->tm_year, - 1 + time_info->tm_mon, - time_info->tm_mday, - time_info->tm_hour, - time_info->tm_min, - time_info->tm_sec, - abs(gmt_offset / 3600), - abs((gmt_offset % 3600) / 60) - ); - } - else - { - strcpy(time_buffer, "1970-01-01 00:00:00+0000"); - } + time_buffer = NXIformatNeXusTime(); + /* start HDF5 interface */ if (am == NXACC_CREATE5) { fapl = H5Pcreate(H5P_FILE_ACCESS); @@ -311,28 +259,33 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); iRet = H5Sclose(aid2); iRet = H5Aclose(attr1); /*----------- file time */ - aid2=H5Screate(H5S_SCALAR); - aid1 = H5Tcopy(H5T_C_S1); - H5Tset_size(aid1, strlen(time_buffer)); - attr1=H5Acreate(pNew->iVID, "file_time", aid1, aid2, H5P_DEFAULT); - if (attr1 < 0) - { - NXIReportError (NXpData, + if(time_buffer != NULL){ + aid2=H5Screate(H5S_SCALAR); + aid1 = H5Tcopy(H5T_C_S1); + H5Tset_size(aid1, strlen(time_buffer)); + attr1=H5Acreate(pNew->iVID, "file_time", aid1, aid2, H5P_DEFAULT); + if (attr1 < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_time attribute "); - return NX_ERROR; - } - if (H5Awrite(attr1, aid1, time_buffer) < 0) - { - NXIReportError (NXpData, + free(time_buffer); + return NX_ERROR; + } + if (H5Awrite(attr1, aid1, time_buffer) < 0) + { + NXIReportError (NXpData, "ERROR: HDF failed to store file_time attribute "); - return NX_ERROR; - } - /* Close attribute dataspace */ - iRet = H5Tclose(aid1); - iRet = H5Sclose(aid2); - /* Close attribute */ - iRet = H5Aclose(attr1); - H5Gclose(pNew->iVID); + free(time_buffer); + return NX_ERROR; + } + /* Close attribute dataspace */ + iRet = H5Tclose(aid1); + iRet = H5Sclose(aid2); + /* Close attribute */ + iRet = H5Aclose(attr1); + free(time_buffer); + } + H5Gclose(pNew->iVID); } /* Set HDFgroup access mode */ if (am1 == H5F_ACC_RDONLY) { @@ -610,8 +563,10 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); /* --------------------------------------------------------------------- */ - NXstatus CALLING_STYLE NX5compmakedata (NXhandle fid, CONSTCHAR *name, int datatype, - int rank, int dimensions[],int compress_type, int chunk_size[]) + NXstatus CALLING_STYLE NX5compmakedata (NXhandle fid, CONSTCHAR *name, + int datatype, + int rank, int dimensions[], + int compress_type, int chunk_size[]) { hid_t datatype1, dataspace, iNew, iRet; hid_t type,cparms; @@ -692,6 +647,7 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); { mydim1[i] = dimensions[i]; } + dimensions[0] = byte_zahl; dataspace=H5Screate_simple(rank,mydim1,NULL); } else { if (dimensions[0] == NX_UNLIMITED) diff --git a/nxio.c b/nxio.c index 4f156422..d06230ca 100644 --- a/nxio.c +++ b/nxio.c @@ -342,7 +342,7 @@ mxml_type_t nexusTypeCallback(mxml_node_t *parent){ if(typeString == NULL){ /* MXML_TEXT seems more appropriate here. But mxml hacks text into - single words which is not what NeXus want. + single words which is not what NeXus wants. */ return MXML_OPAQUE; } else{ @@ -498,6 +498,41 @@ char *nexusWriteCallback(mxml_node_t *node){ myxml_add_char('\0',&bufPtr,&buffer,&bufsize); return (char *)buffer; } +/*------------------------------------------------------------------*/ +int isDataNode(mxml_node_t *node){ + if(mxmlElementGetAttr(node,"name") != NULL){ + return 0; + } + if(strcmp(node->value.element.name,"NXroot") == 0){ + return 0; + } + if(strcmp(node->value.element.name,"NAPIlink") == 0){ + return 0; + } + return 1; +} +/*--------------------------------------------------------------------*/ +static int isTextData(mxml_node_t *node){ + const char *attr = NULL; + int rank, type, iDim[NX_MAXRANK]; + + if(!isDataNode(node)){ + return 0; + } + /* + test datasets + */ + attr = mxmlElementGetAttr(node,TYPENAME); + if(attr == NULL){ + return 1; + } + analyzeDim(attr,&rank,iDim,&type); + if(type == NX_CHAR){ + return 1; + } else { + return 0; + } +} /*---------------------------------------------------------------------*/ const char *NXwhitespaceCallback(mxml_node_t *node, int where){ char *indent; @@ -507,6 +542,20 @@ const char *NXwhitespaceCallback(mxml_node_t *node, int where){ return NULL; } + if(isTextData(node)){ + if(where == MXML_WS_BEFORE_OPEN){ + len = countDepth(node)*2 + 2; + indent = (char *)malloc(len*sizeof(char)); + if(indent != NULL){ + memset(indent,' ',len); + indent[0]= '\n'; + indent[len-1] = '\0'; + return (const char*)indent; + } + } + return NULL; + } + if(where == MXML_WS_BEFORE_OPEN || where == MXML_WS_BEFORE_CLOSE){ len = countDepth(node)*2 + 2; indent = (char *)malloc(len*sizeof(char)); diff --git a/nxio.h b/nxio.h index f0f5bc64..98283779 100644 --- a/nxio.h +++ b/nxio.h @@ -39,7 +39,7 @@ void initializeNumberFormats(); void getNumberText(int nx_type, char *typestring, int typeLen); void destroyDataset(void *data); int translateTypeCode(char *code); - +int isDataNode(mxml_node_t *node); #endif diff --git a/nxxml.c b/nxxml.c index 524c6dca..6da95720 100644 --- a/nxxml.c +++ b/nxxml.c @@ -30,7 +30,6 @@ extern void *NXpData; -extern char *NXIformatNeXusTime(); /*----------------------- our data structures -------------------------- @@ -59,21 +58,8 @@ typedef struct { xmlStack stack[NXMAXSTACK]; /* stack */ }XMLNexus, *pXMLNexus; /*===================== support functions ===============================*/ -static int isDataNode(mxml_node_t *node){ - if(mxmlElementGetAttr(node,"name") != NULL){ - return 0; - } - if(strcmp(node->value.element.name,"NXroot") == 0){ - return 0; - } - if(strcmp(node->value.element.name,"NAPIlink") == 0){ - return 0; - } - return 1; -} -/*----------------------------------------------------------------------*/ extern char *stptok(char *s, char *tok, size_t toklen, char *brk); - +/*----------------------------------------------------------------------*/ static mxml_node_t *getLinkTarget(pXMLNexus xmlHandle, const char *target){ mxml_node_t *node = NULL; mxml_node_t *testNode = NULL; @@ -160,7 +146,7 @@ NXstatus CALLING_STYLE NXXopen(CONSTCHAR *filename, NXaccess am, "?xml version=\"1.0\" encoding=\"UTF-8\"?"); current = mxmlNewElement(xmlHandle->root,"NXroot"); mxmlElementSetAttr(current,"NeXus_version",NEXUS_VERSION); - mxmlElementSetAttr(current,"XML_version","mxml-2.0"); + mxmlElementSetAttr(current,"XML_version","mxml"); mxmlElementSetAttr(current,"file_name",filename); time_buffer = NXIformatNeXusTime(); if(time_buffer != NULL){ @@ -448,6 +434,24 @@ static mxml_node_t *searchSDSLinks(pXMLNexus xmlHandle, CONSTCHAR *name){ } return NULL; } +/*-------------------------------------------------------------------*/ +static int strtrimcr(char *szStr, char *szSet) +{ + int i, j; /* Locale counters */ + + /*-------------------------------------------------*/ + + j = i = strlen(szStr) - 1; /* Find length of string */ + + while (strrchr(szSet, szStr[ i ]) + && (0 <= i)) + { + /* While string is terminated by one of the specified characters */ + szStr[ i-- ] = '\0'; /*- Replace character with '\0' */ + } + + return(j - i); /* Return the difference between old and new length */ +} /*-----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXXopendata (NXhandle fid, CONSTCHAR *name){ pXMLNexus xmlHandle = NULL; @@ -603,7 +607,7 @@ NXstatus CALLING_STYLE NXXgetinfo (NXhandle fid, int *rank, */ *rank = 1; *iType = NX_CHAR; - dimension[0]= strlen(userData->value.opaque) +1; + dimension[0]= strlen(userData->value.opaque); } else { dataset = (pNXDS)userData->value.custom.data; assert(dataset); @@ -1015,8 +1019,13 @@ NXstatus CALLING_STYLE NXXgetnextentry (NXhandle fid,NXname name, assert(xmlHandle); if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXIReportError(NXpData,"Cannot search datasets"); - return NX_ERROR; + /* + be nice to users: close the open dataset even as this is + a usage error + */ + NXIReportError(NXpData, + "WARNING: fixing bad NAPI usage: dataset still open"); + NXXclosedata(fid); } stackPtr = xmlHandle->stackPointer; diff --git a/nxxml.h b/nxxml.h index 3df4dda8..f8ec57a9 100644 --- a/nxxml.h +++ b/nxxml.h @@ -22,7 +22,9 @@ #ifndef NEXUSXML #define NEXUSXML -NX_EXTERNAL NXstatus CALLING_STYLE NXXopen(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle); +NX_EXTERNAL NXstatus CALLING_STYLE NXXopen(CONSTCHAR *filename, + NXaccess access_method, + NXhandle* pHandle); NX_EXTERNAL NXstatus CALLING_STYLE NXXclose(NXhandle* pHandle); NX_EXTERNAL NXstatus CALLING_STYLE NXXflush(NXhandle* pHandle); diff --git a/scan.c b/scan.c index ddcabd49..730bedec 100644 --- a/scan.c +++ b/scan.c @@ -1648,6 +1648,40 @@ static int InterpretScanFunctions(pScanData self, SConnection *pCon, } return 0; } +/*--------------------------------------------------------------------------*/ +static int DumpScan(pScanData self, SConnection *pCon) +{ + int i; + SConnection *oldCon; + char pFile[1024]; + + if(self->iActive) + { + SCWrite(pCon,"ERROR: cannot dump scan while running",eError); + return 0; + } + if(!self->pSics) + { + self->pSics = pServ->pSics; + } + /* + * save old file etc status + */ + oldCon = self->pCon; + pFile[0] = '\0'; + strncpy(pFile,self->pFile,1023); + prepareDataFile(self); + self->pCon = pCon; + self->WriteHeader(self); + for(i = 0; i < self->iNP; i++) + { + self->WriteScanPoints(self,i); + } + SCWrite(pCon,"Scan dumped", eValue); + self->pCon = oldCon; + strncpy(self->pFile,pFile,1023); + return 1; +} /*---------------------------------------------------------------------------*/ int ScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) @@ -1970,7 +2004,12 @@ static int InterpretScanFunctions(pScanData self, SConnection *pCon, return 0; } return 1; - } + } +/*------------ dump */ + else if(strcmp(argv[1],"dump") == 0) + { + return DumpScan(self,pCon); + } /* --------callback */ else if(strcmp(argv[1],"callback") == 0) { diff --git a/scan.tex b/scan.tex index 1d99cb0e..4f5f46e4 100644 --- a/scan.tex +++ b/scan.tex @@ -466,6 +466,10 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ */@\\ \mbox{}\verb@ int PrepareScan(pScanData self);@\\ \mbox{}\verb@ /**@\\ +\mbox{}\verb@ * allocate a new data file@\\ +\mbox{}\verb@ */@\\ +\mbox{}\verb@ int prepareDataFile(pScanData self);@\\ +\mbox{}\verb@ /**@\\ \mbox{}\verb@ * second version of PrepareScan which does not check scan limits@\\ \mbox{}\verb@ */ @\\ \mbox{}\verb@ int NonCheckPrepare(pScanData self);@\\ diff --git a/scan.w b/scan.w index 53135d5f..545394a4 100644 --- a/scan.w +++ b/scan.w @@ -411,6 +411,10 @@ documentation. * counter. */ int PrepareScan(pScanData self); + /** + * allocate a new data file + */ + int prepareDataFile(pScanData self); /** * second version of PrepareScan which does not check scan limits */ diff --git a/stdscan.c b/stdscan.c index 71601976..2da901bf 100644 --- a/stdscan.c +++ b/stdscan.c @@ -267,7 +267,7 @@ static char *fixExtension(char *filename) int WriteScanPoints(pScanData self, int iPoint) { int i, i2; - char pLine[512], pItem[30], pInfo[512]; + char pLine[512], pItem[30], pInfo[1024], pSteps[256]; pVarEntry pVar = NULL; pCountEntry pData = NULL; void *pPtr = NULL; @@ -296,6 +296,7 @@ static char *fixExtension(char *filename) /* make the data header */ sprintf(pLine,"%-4s ","NP"); strcpy(pInfo,"Scanning Variables: "); + strcpy(pSteps,"Steps: "); for(i = 0; i < self->iScanVar;i++) { DynarGet(self->pScanVar,i,&pPtr); @@ -306,6 +307,8 @@ static char *fixExtension(char *filename) strcat(pLine,pItem); sprintf(pItem,"%s, ",ScanVarName(pVar)); strcat(pInfo,pItem); + sprintf(pItem,"%f ",ScanVarStep(pVar)); + strcat(pSteps,pItem); } } strcat(pLine," Counts "); @@ -313,6 +316,7 @@ static char *fixExtension(char *filename) strcat(pLine,"Monitor2 "); strcat(pLine,"Monitor3 "); strcat(pLine,"Time "); + strcat(pInfo,pSteps); sprintf(pItem,"\n%d Points,",self->iNP); strcat(pInfo,pItem); if(self->iMode == eTimer) @@ -369,7 +373,7 @@ static char *fixExtension(char *filename) return 1; } /*------------------------------------------------------------------------*/ -static int prepareDataFile(pScanData self){ +int prepareDataFile(pScanData self){ char *pPtr = NULL; char pBueffel[512]; @@ -704,6 +708,16 @@ static int prepareDataFile(pScanData self){ long lTask; int status; + /* + * drive the first point normally, otherwise there is to much intensity + * in the first data point from the long time driving to the start + * position. + */ + if(iPoint == 0) + { + return ScanDrive(self,iPoint); + } + iRet = StartToDrive(self,iPoint); if(!iRet) { diff --git a/stdscan.h b/stdscan.h index 85780f66..5ad5c223 100644 --- a/stdscan.h +++ b/stdscan.h @@ -28,6 +28,10 @@ * counter. */ int PrepareScan(pScanData self); + /** + * allocate a new data file + */ + int prepareDataFile(pScanData self); /** * second version of PrepareScan which does not check scan limits */ diff --git a/synchronize.c b/synchronize.c index 5b451f9c..dd21137c 100644 --- a/synchronize.c +++ b/synchronize.c @@ -258,6 +258,15 @@ tryagain: eWarning); } + /* + * relase the connection, this may be more stable + */ + NETClosePort(connection); + free(connection); + connection = NULL; + + + /* now read the backup file and we are done */ diff --git a/ubfour.c b/ubfour.c index 948f3be0..eeebed68 100644 --- a/ubfour.c +++ b/ubfour.c @@ -20,15 +20,21 @@ /*--------------------------------------------------------------------------------------*/ static MATRIX calcUVectorFromAngles(reflection r){ MATRIX u; + double om; u = makeVector(); if(u == NULL){ return NULL; } - vectorSet(u,0,Cosd(r.om)*Cosd(r.chi)*Cosd(r.phi) - Sind(r.om)*Sind(r.phi)); - vectorSet(u,1,Cosd(r.om)*Cosd(r.chi)*Sind(r.phi) + Sind(r.om)*Cosd(r.phi)); - vectorSet(u,2,Cosd(r.om)*Sind(r.chi)); - + /* + * the tricky bit is set again: Busing and Levy's omega is 0 in bisecting + * position. This is why we have to correct for two_theta/2 here in order + * to arrive at the proper rotation around the omega axis. + */ + om = r.om - r.s2t/2.; + vectorSet(u,0,Cosd(om)*Cosd(r.chi)*Cosd(r.phi) - Sind(om)*Sind(r.phi)); + vectorSet(u,1,Cosd(om)*Cosd(r.chi)*Sind(r.phi) + Sind(om)*Cosd(r.phi)); + vectorSet(u,2,Cosd(om)*Sind(r.chi)); return u; } /*--------------------------------------------------------------------------------------*/