diff --git a/SCinter.c b/SCinter.c index 52d10f11..50299ec9 100644 --- a/SCinter.c +++ b/SCinter.c @@ -134,6 +134,7 @@ static void freeList(int listID); SICSLogWrite(pBueffel,eInternal); return 0; } + memset(pNew,0,sizeof(CommandList)); /* if no data given, initialise with Dummy struct */ if(!pData) @@ -431,7 +432,7 @@ extern char *SkipSpace(char *pPtr); } if(fVal > -990.) { - fprintf(fd,"run %s %f\n",pCurrent->pName, fVal); + fprintf(fd,"drive %s %f\n",pCurrent->pName, fVal); } } } diff --git a/anticollider.c b/anticollider.c index f17fc583..6c58dbee 100644 --- a/anticollider.c +++ b/anticollider.c @@ -113,6 +113,7 @@ static long ColliderSetValue(void *pData, SConnection *pCon, float fTarget){ iRet = Tcl_Eval(pServ->pSics->pTcl,Tcl_DStringValue(&command)); if(iRet != TCL_OK){ SCWrite(pCon,"ERROR: Movement not possible or bad collider script",eError); + SCWrite(pCon,Tcl_DStringValue(&command),eError); /* SCWrite(pCon,pServ->pSics->pTcl->result,eError); */ diff --git a/conman.c b/conman.c index 3f4378b1..39d6827f 100644 --- a/conman.c +++ b/conman.c @@ -634,7 +634,7 @@ static int doSockWrite(SConnection *self, char *buffer) iRet = NETWrite(self->pSock,buffer,strlen(buffer)); if(!HasNL(buffer)) { - iRet = NETWrite(self->pSock,"\n",strlen("\n")); + iRet = NETWrite(self->pSock,"\r\n",strlen("\r\n")); } } if(!iRet) diff --git a/exe.w b/exe.w index 859ce1f8..58c62057 100644 --- a/exe.w +++ b/exe.w @@ -173,6 +173,7 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics, char *name); +pDynString findBatchFile(SicsInterp *pSics, char *name); @} @o exeman.i -d @{ diff --git a/exebuf.h b/exebuf.h index d32c05f3..026a9730 100644 --- a/exebuf.h +++ b/exebuf.h @@ -1,5 +1,5 @@ -#line 209 "exe.w" +#line 210 "exe.w" /** * Buffer handling code for the Exe Buffer batch file processing @@ -89,7 +89,7 @@ */ char *exeBufName(pExeBuf self); -#line 222 "exe.w" +#line 223 "exe.w" #endif diff --git a/exebuf.i b/exebuf.i index ffa5f5ee..62a15a24 100644 --- a/exebuf.i +++ b/exebuf.i @@ -1,5 +1,5 @@ -#line 200 "exe.w" +#line 201 "exe.w" /*-------------------------------------------------------------------- Internal header file for the exe buffer module. Do not edit. This is @@ -16,6 +16,6 @@ typedef struct __EXEBUF{ int lineno; } ExeBuf; -#line 205 "exe.w" +#line 206 "exe.w" diff --git a/exeman.c b/exeman.c index e0f01712..177c8c2f 100644 --- a/exeman.c +++ b/exeman.c @@ -175,6 +175,43 @@ static pDynString locateBatchBuffer(pExeMan self, char *name){ DeleteDynString(result); return NULL; } +/*------------------------------------------------------------------- + * Generate a full path name for the argument in the first + * directory of batch path + * -------------------------------------------------------------------*/ +static int makeExePath(pExeMan self, SConnection *pCon, int argc, char *argv[]){ + char buffer[512], *pPtr = NULL, pPath[132]; + + if(argc < 3) { + SCWrite(pCon,"ERROR: require a file name for makepath",eError); + return 0; + } + strcpy(buffer,"exe.makepath = "); + /* + * do nothing to absolute path + */ + if(argv[2][0] == '/'){ + strncat(buffer,argv[2],511-strlen(buffer)); + SCWrite(pCon,buffer,eValue); + return 1; + } + pPtr = self->batchPath; + pPtr = stptok(pPtr,pPath,131,":"); + strncat(buffer,pPath,511-strlen(buffer)); + strncat(buffer,"/",511-strlen(buffer)); + strncat(buffer,argv[2],511-strlen(buffer)); + SCWrite(pCon,buffer,eValue); + + return 1; +} +/*--------------------------------------------------------------------*/ +pDynString findBatchFile(SicsInterp *pSics, char *name){ + pExeMan self = (pExeMan)FindCommandData(pSics,"exe","ExeManager"); + if(self == NULL){ + return NULL; + } + return locateBatchBuffer(self,name); +} /*--------------------------------------------------------------------*/ static int runBatchBuffer(pExeMan self, SConnection *pCon, SicsInterp *pSics, char *name){ @@ -937,6 +974,7 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, char pBufferName[256]; int status; pDynString dirList = NULL; + pDynString fullPath = NULL; self = (pExeMan)pData; assert(self != NULL); @@ -1012,6 +1050,24 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, SCWrite(pCon,"Nothing found",eValue); } return 1; + }else if(strcmp(argv[1],"fullpath") == 0){ + if(argc < 2){ + SCWrite(pCon,"ERROR: not enough arguments to exe fullpath",eError); + return 0; + } + fullPath = locateBatchBuffer(self,argv[2]); + if(fullPath == NULL){ + SCWrite(pCon,"ERROR: buffer NOT found",eError); + return 0; + } else { + DynStringInsert(fullPath,"exe.fullpath=",0); + SCWrite(pCon,GetCharArray(fullPath),eValue); + DeleteDynString(fullPath); + return 1; + } + return 1; + }else if(strcmp(argv[1],"makepath") == 0){ + return makeExePath(self,pCon,argc,argv); }else if(strcmp(argv[1],"clear") == 0){ clearQueue(self); SCSendOK(pCon); diff --git a/exeman.h b/exeman.h index 0d5a08be..479c5087 100644 --- a/exeman.h +++ b/exeman.h @@ -15,5 +15,6 @@ int ExeManagerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); int runExeBatchBuffer(void *pData, SConnection *pCon, SicsInterp *pSics, char *name); +pDynString findBatchFile(SicsInterp *pSics, char *name); #endif diff --git a/exeman.i b/exeman.i index 2b441c74..c5436d01 100644 --- a/exeman.i +++ b/exeman.i @@ -1,5 +1,5 @@ -#line 178 "exe.w" +#line 179 "exe.w" /*------------------------------------------------------------------- Internal header file for the exe manager module. Do not edit. This @@ -20,5 +20,5 @@ typedef struct __EXEMAN{ int echo; }ExeMan, *pExeMan; -#line 183 "exe.w" +#line 184 "exe.w" diff --git a/histmem.c b/histmem.c index 07de915f..2eecdedb 100644 --- a/histmem.c +++ b/histmem.c @@ -1581,10 +1581,10 @@ static int checkHMEnd(pHistMem self, char *text){ else if(strcmp(argv[1],"timebin") == 0) { Tcl_DStringInit(&tResult); - Tcl_DStringAppend(&tResult,"histogram.timebins = ",-1); + Tcl_DStringAppend(&tResult,"histogram.timebins =",-1); for(i = 0; i < self->pDriv->data->nTimeChan; i++) { - sprintf(pBueffel," %8.2f", self->pDriv->data->timeBinning[i]); + sprintf(pBueffel,"%.2f ", self->pDriv->data->timeBinning[i]); Tcl_DStringAppend(&tResult,pBueffel,-1); } /* Write it */ diff --git a/hmcontrol.c b/hmcontrol.c index 198fbc72..758ed638 100644 --- a/hmcontrol.c +++ b/hmcontrol.c @@ -310,7 +310,7 @@ int HMControlAction(SConnection *pCon, SicsInterp *pSics, assert(self); if(argc < 4) { - sprintf("ERROR: Usage %s start preset mode", argv[0]); + snprintf(pBueffel,131,"ERROR: Usage %s start preset mode", argv[0]); SCWrite(pCon,pBueffel,eError); return 0; } diff --git a/hmdata.c b/hmdata.c index f491540b..e7945083 100644 --- a/hmdata.c +++ b/hmdata.c @@ -358,7 +358,7 @@ long sumHMDataRectangle(pHistMem hist, SConnection *pCon, int iStart[MAXDIM], int iEnd[MAXDIM]) { HistInt *iData; pHMdata self = hist->pDriv->data; - int i, iHistLength, status, iIndex; + int i, iHistLength, status, iIndex, myrank; char pBueffel[256]; unsigned long lSum, lRowSum; @@ -367,7 +367,12 @@ long sumHMDataRectangle(pHistMem hist, SConnection *pCon, /* error checking */ - for(i = 0; i < self->rank; i++){ + myrank = self->rank; + if(isInTOFMode(self)){ + self->iDim[self->rank] = getNoOfTimebins(self); + myrank++; + } + for(i = 0; i < myrank; i++){ if( (iStart[i] < 0) || (iStart[i] > self->iDim[i]) ) { sprintf(pBueffel,"ERROR: %d is out of data dimension range", iStart[i]); @@ -398,13 +403,14 @@ long sumHMDataRectangle(pHistMem hist, SConnection *pCon, iHistLength = getHMDataLength(self); /* actually sum */ - switch(self->rank) + switch(myrank) { case 1: lSum = SumRow(self->localBuffer, iHistLength, iStart[0], iEnd[0]); break; case 2: + /* lSum = 0; for(i = iStart[1]; i < iEnd[1]; i++){ iIndex = i*self->iDim[0]; @@ -412,11 +418,19 @@ long sumHMDataRectangle(pHistMem hist, SConnection *pCon, iIndex+iStart[0], iIndex+iEnd[0]); lSum += lRowSum; } + */ + lSum = 0; + for(i = iStart[0]; i < iEnd[0]; i++){ + iIndex = i*self->iDim[1]; + lRowSum = SumRow(self->localBuffer,iHistLength, + iIndex+iStart[1], iIndex+iEnd[1]); + lSum += lRowSum; + } break; default: sprintf(pBueffel, "ERROR: summing in %d dimensions not yet implemented", - self->rank); + myrank); SCWrite(pCon,pBueffel,eError); return -1; break; diff --git a/maximize.c b/maximize.c index be65ddf9..0afafcc3 100644 --- a/maximize.c +++ b/maximize.c @@ -47,6 +47,7 @@ #include "counter.h" #include "drive.h" #include "maximize.h" +#include "motor.h" #define MAXPTS 100 #define DEBUG 1 @@ -135,7 +136,25 @@ } return 1; } - + /*----------------------------------------------------------------------*/ + static float readMPDrivable(void *pVar, SConnection *pCon) + { + float value = -999.99; + pIDrivable pDriv = NULL; + pDummy pDum = (pDummy)pVar; + + pDriv = GetDrivableInterface(pVar); + assert(pDriv != NULL); + if(strcmp(pDum->pDescriptor->name,"Motor") == 0) + { + MotorGetSoftPosition((pMotor)pVar,pCon,&value); + } + else + { + value = pDriv->GetValue(pVar,pCon); + } + return value; + } /*-----------------------------------------------------------------------*/ int MaximizePeak(pMax self, void *pVar, char *pVarName, float fStep, CounterMode eMode, @@ -160,9 +179,9 @@ start: lMax = 0; lMin = 0x7fffffff; - fStart = pDriv->GetValue(pVar,pCon); + fStart = readMPDrivable(pVar,pCon); if(fStart < -999999.) - { + { return 0; } @@ -174,13 +193,13 @@ fPos = fStart - (self->maxpts/2 - i)*fStep; fPos = in360(self,fPos); if(maxDrive(pVar,pVarName,fPos,pCon) != 1) - { + { return 0; } - x[i] = pDriv->GetValue(pVar,pCon); + x[i] = readMPDrivable(pVar,pCon); /* count */ if(maxCount(self->pCount,eMode,fPreset, &lCts,pCon) != 1) - { + { return 0; } /* print a message */ @@ -256,7 +275,7 @@ { return 0; } - x[i] = pDriv->GetValue(pVar,pCon); + x[i] = readMPDrivable(pVar,pCon); /* count */ if(maxCount(self->pCount,eMode,fPreset, &lCts,pCon) != 1) { @@ -426,7 +445,9 @@ AddCommand(pSics,"max",MaximizeAction,MaxKill,pNew); return 1; } -/*------------------------------------------------------------------*/ +/*------------------------------------------------------------------ + * max motor step preset mode + * ---------------------------------------------------------------------*/ int MaximizeAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { diff --git a/mesure.c b/mesure.c index 83b0980c..7b436743 100644 --- a/mesure.c +++ b/mesure.c @@ -33,6 +33,7 @@ #include "fourtable.h" #include "lld.h" #include "stdscan.h" +#include "exeman.h" extern void SNXFormatTime(char *pBueffel, int iLen); extern float nintf(float f); @@ -993,7 +994,9 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon) static float fMax = 10.; int iRet, i,ii, iLF, iNP; char pBueffel[512], pNum[10], pTime[132]; - pEVControl pEva = NULL; + pEVControl pEva = NULL; + pDummy pPtr = NULL; + pIDrivable pDriv = NULL; assert(self); assert(pCon); @@ -1079,7 +1082,20 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon) fTemp = -777.77; pEva = (pEVControl)FindCommandData(pServ->pSics,"temperature", "Environment Controller"); - if(pEva) + if(pEva == NULL) + { + pPtr = (pDummy)FindCommandData(pServ->pSics,"temperature", + "RemObject"); + if(pPtr != NULL) + { + pDriv = pPtr->pDescriptor->GetInterface(pPtr,DRIVEID); + if(pDriv != NULL) + { + fTemp = pDriv->GetValue(pPtr,pCon); + } + } + } + else { iRet = EVCGetPos(pEva, pCon,&fTemp); } @@ -1141,6 +1157,19 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon) } return 1; } + /*---------------------------------------------------------------------*/ + static FILE *openListFile(char *pName){ + FILE *fd = NULL; + pDynString filename = NULL; + filename = findBatchFile(pServ->pSics,pName); + if(filename != NULL){ + fd = fopen(GetCharArray(filename),"r"); + DeleteDynString(filename); + } else { + fd = fopen(pName,"r"); + } + return fd; + } /*------------------------------------------------------------------------*/ int MesureFile(pMesure self, char *pFile, int iSkip, SConnection *pCon) { @@ -1153,7 +1182,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon) assert(pCon); /* well before doing a thing, open the list file */ - fd = fopen(pFile,"r"); + fd = openListFile(pFile); if(!fd) { sprintf(pBueffel,"ERROR: reflection file %s NOT found!",pFile); @@ -1242,7 +1271,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon) assert(pCon); /* well before doing a thing, open the list file */ - fd = fopen(pFile,"r"); + fd = openListFile(pFile); if(!fd) { sprintf(pBueffel,"ERROR: reflection file %s NOT found!",pFile); @@ -1301,7 +1330,7 @@ static int ScanReflection(pMesure self, float twoTheta, SConnection *pCon) assert(pCon); /* well before doing a thing, open the list file */ - fd = fopen(pFile,"r"); + fd = openListFile(pFile); if(!fd) { sprintf(pBueffel,"ERROR: reflection file %s NOT found!",pFile); diff --git a/mumoconf.c b/mumoconf.c index 00293496..305a7417 100644 --- a/mumoconf.c +++ b/mumoconf.c @@ -315,6 +315,7 @@ char pError[132]; int i, iToken, iRet; sParser PP; + CommandList *pCom = NULL; assert(pCon); assert(pSics); @@ -345,9 +346,10 @@ break; case ENDCONFIG: /* reconfigure command to final state */ - RemoveCommand(pSics,argv[0]); - AddCommand(pSics,argv[0],MultiWrapper,KillMultiMotor, - self); + pCom = FindCommand(pSics,argv[0]); + assert(pCom != NULL); + pCom->OFunc = MultiWrapper; + pCom->KFunc = KillMultiMotor; return 1; break; case ALIAS: diff --git a/network.c b/network.c index 4f3c37b3..3639cae9 100644 --- a/network.c +++ b/network.c @@ -424,9 +424,14 @@ CreateSocketAdress( return 0; } -#ifndef CYGNUS - /* setup for select first */ - tmo.tv_usec = 100; + /* + * Check if the we can write to the socket first.... + * Well, this how it should be. However, on linux I observe that + * there is a problem with Java clients not reliably receiving data when + * this is active. + */ +#ifndef CYGNUS + tmo.tv_usec = 10; FD_ZERO(&lMask); FD_SET(self->sockid,&lMask); if((self->sockid >= FD_SETSIZE) || (self->sockid < 0) ) @@ -445,7 +450,8 @@ CreateSocketAdress( { return -2; } -#endif +#endif + iRet = send(self->sockid,buffer,lLen,0); if(iRet != lLen) { diff --git a/nxscript.c b/nxscript.c index 3339acff..ddec8be1 100644 --- a/nxscript.c +++ b/nxscript.c @@ -750,7 +750,10 @@ static void putArray(SConnection *pCon, SicsInterp *pSics, data = (float *)malloc(length*sizeof(float)); } if(data == NULL){ - SCWrite(pCon,"ERROR: out of memory or invalid length",eError); + snprintf(buffer,255, + "ERROR: out of memory or invalid length at %s, length = %s", + argv[2],argv[4]); + SCWrite(pCon,buffer,eError); return; } memset(data,0,length*sizeof(float)); diff --git a/rs232controller.c b/rs232controller.c index 17fe6509..7b717502 100644 --- a/rs232controller.c +++ b/rs232controller.c @@ -434,6 +434,42 @@ void getRS232Error(int iCode, char *errorBuffer, } } /*--------------------------------------------------------------------*/ +int fixRS232Error(prs232 self, int iCode){ + int i, status, read; + char buffer[8192]; + + switch(iCode){ + case BADMEMORY: + case FAILEDCONNECT: + return 0; + break; + case INCOMPLETE: + case TIMEOUT: + /* + * try to clear possibly pending stuff + */ + for(i = 0; i < 3; i++){ + if(availableRS232(self)){ + read = 8192; + readRS232(self,buffer,&read); + } + } + return 1; + break; + case NOTCONNECTED: + case BADSEND: + closeRS232(self); + status = initRS232(self); + if(status){ + return 1; + } else { + return 0; + } + break; + } + return 0; +} +/*--------------------------------------------------------------------*/ int getRS232Timeout(prs232 self){ return self->timeout; } diff --git a/rs232controller.h b/rs232controller.h index beddb2d2..1628930c 100644 --- a/rs232controller.h +++ b/rs232controller.h @@ -65,6 +65,7 @@ void getRS232Error(int iCode, char *errorBuffer, int errorBufferLen); + int fixRS232Error(prs232 self, int iCode); int getRS232Timeout(prs232 self); int initRS232(prs232 self); int initRS232WithFlags(prs232 self, int flags); diff --git a/sans.tcl b/sans.tcl deleted file mode 100644 index 41bf129a..00000000 --- a/sans.tcl +++ /dev/null @@ -1,209 +0,0 @@ -# -------------------------------------------------------------------------- -# Initialization script the instrument SANS at SINQ -# -# Dr. Mark Koennecke, June 1997 -#--------------------------------------------------------------------------- -# O P T I O N S -set root "/data/koenneck/src/sics" -# first all the server options are set - -ServerOption SaveFile $root/bin/sansstat.tcl -# File to save the status of the instrument too - -ServerOption ReadTimeOut 10 -# timeout when checking for commands. In the main loop SICS checks for -# pending commands on each connection with the above timeout, has -# PERFORMANCE impact! - -ServerOption AcceptTimeOut 10 -# timeout when checking for connection req. -# Similar to above, but for connections - -ServerOption ReadUserPasswdTimeout 500000 -# time to wiat for a user/passwd to be sent from a client. Increase this -# if there is a problem connecting to a server due to network overload\ - -ServerOption LogFileBaseName $root/log/sanslog -# the path and base name of the internal server logfile to which all -# activity will be logged. - -ServerOption ServerPort 2915 -# the port number the server is going to listen at. The client MUST know -# this number in order to connect. It is in client.ini - -ServerOption InterruptPort 2917 -# The UDP port where the server will wait for Interrupts from clients. -# Obviously, clients wishing to interrupt need to know this number. - -# Telnet Options -ServerOption TelnetPort 1301 -ServerOption TelWord sicslogin - -# The token system -TokenInit connan - -#--------------------------------------------------------------------------- -# U S E R S - -# than the SICS users are specified -# Syntax: SicsUser name password userRightsCode -SicsUser Manager Joachim 1 -SicsUser User Kohl 2 -SicsUser Spy 007 3 - -#-------------------------------------------------------------------------- -# S I M P L E V A R I A B L E S - -# now a few general variables are created -# Syntax: VarMake name type access -# type can be one of: Text, Int, Float -#access can be one of: Internal, Mugger, user, Spy - -VarMake Instrument Text Internal -Instrument "SANS at SINQ,PSI" -#initialisation -Instrument lock - -VarMake title Text User -VarMake User Text User -User "Albert von Villigen" -VarMake SubTitle Text User -VarMake environment Text User -VarMake comment Text User -VarMake SampleName Text User -SampleName KohlSulfid -#----------- Initialize data storage stuff -VarMake SicsDataPath Text Mugger -SicsDataPath $root/data/ -SicsDataPath lock -VarMake SicsDataPrefix Text Mugger -SicsDataPrefix sans -SicsDataPrefix lock -VarMake SicsDataPostFix Text Mugger -SicsDataPostFix ".hdf" -SicsDataPostFix lock -MakeDataNumber SicsDataNumber $root/data/2001/DataNumber -InitSANS $root/sansdict.dic - - -#-------------------------------------------------------------------------- -# D E V I C E S : M O T O R S - -#Motor a4 EL734 LNSP22 4000 5 6 -# EL734 motor with parameters: hostname PortNumber Channel MotorID - -#Motor a4 EL734DC LNSP22 4000 5 6 -# EL734DC motor with parameters: hostname PortNumber Channel MotorID - -# Motor nam SIM -20. 20. 5. 1.0 -# Simulated motor with name nam, lower limit -20, upper limit +20, -# error ratio 5% and speed 1.0. Speed may be omitted - -# Motors for sample movement -Motor schi SIM -22.0 +22. 10. -Motor sphi SIM -22.0 +22.0 10. -Motor som EL734 lnsp25.psi.ch 4000 2 8 -Motor sax EL734 lnsp25.psi.ch 4000 2 6 -Motor say EL734 lnsp25.psi.ch 4000 2 7 -Motor saz EL734 lnsp25.psi.ch 4000 2 1 -Motor spos EL734 lnsp25.psi.ch 4000 2 5 - -#Motors for detector movement -Motor DetectorX EL734DC lnsp25.psi.ch 4000 3 1 -DetectorX Precision 0.5 -Motor DetectorY EL734DC lnsp25.psi.ch 4000 3 2 -DetectorY Precision 0.2 -Motor DetectorRotation EL734DC lnsp25.psi.ch 4000 3 3 -DetectorRotation Precision 0.1 - -#Motors for beamstop -Motor BeamStopX EL734 lnsp25.psi.ch 4000 2 3 -BeamStopX Precision 0.2 -Motor BeamStopY EL734 lnsp25.psi.ch 4000 2 4 -BeamStopY Precision 0.2 - - -#------------------------------------------------------------------------ -# Velocity selector -Motor tilt EL734 lnsp25.psi.ch 4000 2 2 -set dornen(Host) lnsp25.psi.ch -set dornen(Port) 4000 -set dornen(Channel) 6 -set dornen(Timeout) 3000 -VelocitySelector nvs tilt DORNIER dornen -nvs add -20 28800 -nvs add 3800 4500 -nvs add 5900 6700 -nvs add 8100 9600 -unset dornen - -#-------------------------------------------------------------------------- -# P R O C E D U R E S - -# create the drive command -MakeDrive -#-------------------------------------------------------------------------- -# MultiMotor is an object which groups several motors together. - -#--------------------------------- sample position -MakeMulti sample -# creates a MultiMotor with name sample -sample alias schi chi -# alias creates an internal name (chi) for motor schi -sample alias sphi phi -sample alias som omega -sample alias sax x -sample alias say y -sample alias saz z -sample pos Jo schi 0. sphi 0. som 45. sax 2. say 3. saz 10. -# define Jo as a named position. This means with sample Jo you'll reach -# the positions specified -sample pos Mo schi 0. sphi 0. som 180. sax 2. say 3. saz 10. -sample endconfig -# ends configuration of sample and install the command. This is REQUIRED - -#---------------------------------- detector position -MakeMulti detector -detector alias DetectorX X -detector alias DetectorY Y -detector alias DetectorRotation phi -detector endconfig - -#----------------------------------- beamstop -MakeMulti BeamStop -BeamStop alias BeamStopX X -BeamStop alias BeamStopY Y -BeamStop pos out BeamStopX 817. -BeamStop endconfig -#------------------------------------ Shortcuts -SicsAlias BeamStop bs -SicsAlias detector dt -#------------------------------------ Histogram Memory -MakeCounter counter EL737 lnsp25.psi.ch 4000 4 -counter SetExponent 6 - -MakeHM banana SINQHM -banana configure HistMode Normal -banana configure OverFlowMode Ceil -banana configure Rank 1 -banana configure Length 16384 -banana configure BinWidth 4 -banana preset 100. -banana CountMode Timer -banana configure HMComputer lnse02.psi.ch -banana configure HMPort 2400 -banana configure Counter counter -banana init -banana exponent 6 -#----------------------------------------------------------------------------- -# R U E N B U F F E R -MakeRuenBuffer - -#---------------------- some special Tcl commands -source $root/bin/log.tcl -Publish LogBook User - -source $root/bin/count.tcl -Publish count User -Publish Repeat User - diff --git a/statistics.c b/statistics.c index dce5bc62..711f00d6 100644 --- a/statistics.c +++ b/statistics.c @@ -13,9 +13,9 @@ struct Statistics { Statistics *next; }; -static Statistics *current; +static Statistics *current = NULL; static tv_t last, lastStat; -static Statistics *idle = NULL, *list; +static Statistics *idle = NULL, *list = NULL; static int init = 1; /*-----------------------------------------------------------------------*/ tv_t timeDif(tv_t t1, tv_t t2) { @@ -128,7 +128,9 @@ Statistics *StatisticsBegin(Statistics *stat) { res = current; gettimeofday(&now, 0); - timeAdd(¤t->tim, timeDif(last, now)); + if(current != NULL){ + timeAdd(¤t->tim, timeDif(last, now)); + } last = now; current = stat; stat->last = now; @@ -142,10 +144,12 @@ void StatisticsEnd(Statistics *stat) { gettimeofday(&now, 0); timeAdd(¤t->tim, timeDif(last, now)); last = now; - if (current->last.tv_sec >= 0) { - timeAdd(¤t->total, timeDif(current->last, now)); + if(current != NULL){ + if (current->last.tv_sec >= 0) { + timeAdd(¤t->total, timeDif(current->last, now)); + } + current->last.tv_sec = -1; } - current->last.tv_sec = -1; current = stat; } /*-----------------------------------------------------------------------*/ diff --git a/tasub.c b/tasub.c index 462e96f0..dc38ddf4 100644 --- a/tasub.c +++ b/tasub.c @@ -875,6 +875,80 @@ static void listDiagnostik(ptasUB self, SConnection *pCon){ status = LLDnodePtr2Next(self->reflectionList); } } +/*-----------------------------------------------------------------*/ +static int addAuxReflection(ptasUB self, SConnection *pCon, + SicsInterp *pSics, int argc, char *argv[]){ + int status; + tasReflection r1, r2; + float value = -999.99; + char pBueffel[256]; + MATRIX UB = NULL, B = NULL; + + if(argc < 5){ + SCWrite(pCon, + "ERROR: not enough arguments auxiliary reflection, need HKL", + eError); + return 0; + } + + if(!SCMatchRights(pCon,usUser)){ + return 0; + } + + status = Tcl_GetDouble(InterpGetTcl(pSics),argv[2],&r2.qe.qh); + if(status != TCL_OK){ + snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[2]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + status = Tcl_GetDouble(InterpGetTcl(pSics),argv[3],&r2.qe.qk); + if(status != TCL_OK){ + snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[3]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + status = Tcl_GetDouble(InterpGetTcl(pSics),argv[4],&r2.qe.ql); + if(status != TCL_OK){ + snprintf(pBueffel,255,"ERROR: failed to convert %s to number",argv[4]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + + B = mat_creat(3,3,ZERO_MATRIX); + if(B == NULL){ + SCWrite(pCon,"ERROR: out of memory creating B matrix",eError); + return 0; + } + status = calculateBMatrix(self->cell,B); + if(status < 0){ + SCWrite(pCon,"ERROR: bad cell constants, no volume",eError); + mat_free(B); + return 0; + } + + status = findReflection(self->reflectionList, 0,&r1); + if(status != 1){ + r2.qe.kf = self->current.kf; + r2.qe.ki = self->current.ki; + MotorGetSoftPosition(self->motors[A3],pCon,&value); + r2.angles.a3 = value + 180.; + r2.angles.sgu = .0; + r2.angles.sgl = .0; + calcTwoTheta(B,r2.qe,self->machine.ss_sample,&r2.angles.sample_two_theta); + r1 = r2; + } + + status = makeAuxReflection(B, r1, &r2,self->machine.ss_sample); + mat_free(B); + if(status < 0){ + SCWrite(pCon,"ERROR: out of memory in makeAuxUB or scattering angle not closed", + eError); + return 0; + } + LLDnodeAppend(self->reflectionList,&r2); + SCSendOK(pCon); + return 1; +} /*------------------------------------------------------------------*/ static int calcAuxUB(ptasUB self, SConnection *pCon, SicsInterp *pSics, int argc, char *argv[]){ @@ -885,8 +959,8 @@ static int calcAuxUB(ptasUB self, SConnection *pCon, SicsInterp *pSics, if(argc < 5){ SCWrite(pCon, - "ERROR: not enough arguments for UB calculation, need HKJL of second plane vector", - eError); + "ERROR: not enough arguments for UB calculation, need HKL of second plane vector", + eError); return 0; } @@ -1564,6 +1638,8 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData, return calcUB(self,pCon,pSics,argc,argv); } else if(strcmp(argv[1],"makeauxub") == 0){ return calcAuxUB(self,pCon,pSics,argc,argv); + } else if(strcmp(argv[1],"addauxref") == 0){ + return addAuxReflection(self,pCon,pSics,argc,argv); } else if(strcmp(argv[1],"makeubfromcell") == 0){ return calcUBFromCell(self,pCon); } else if(strcmp(argv[1],"calcang") == 0){ diff --git a/tasublib.c b/tasublib.c index 07af0d1b..eee5a650 100644 --- a/tasublib.c +++ b/tasublib.c @@ -246,6 +246,29 @@ int makeAuxReflection(MATRIX B, tasReflection r1, tasReflection *r2, return 1; } +/*------------------------------------------------------------------*/ +int calcTwoTheta(MATRIX B, tasQEPosition ref, int ss, double *value){ + MATRIX QC; + double cos2t, q; + + QC = tasReflectionToHC(ref,B); + if(QC == NULL){ + return UBNOMEMORY; + } + + q = vectorLength(QC); + q = 2.*PI*vectorLength(QC); + killVector(QC); + + cos2t = (ref.ki*ref.ki + ref.kf*ref.kf - q*q)/ + (2. * ABS(ref.ki) * ABS(ref.kf)); + if(ABS(cos2t) > 1.){ + return TRIANGLENOTCLOSED; + } + *value = ss*Acosd(cos2t); + + return 1; +} /*-------------------------------------------------------------------*/ MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2){ MATRIX u1 = NULL, u2 = NULL, planeNormal = NULL; diff --git a/tasublib.h b/tasublib.h index 35fb59ff..fa8ee5bf 100644 --- a/tasublib.h +++ b/tasublib.h @@ -137,6 +137,15 @@ double maCalcK(maCrystal data, double two_theta); */ int makeAuxReflection(MATRIX B, tasReflection r1, tasReflection *r2, int ss); +/** + * calculate two theta for the reflection ref + * @param B the metric matrix, or the UB + * @param ref The reflection for which to calculate two theta + * @param ss The scattering sense + * @param twoTheta The new two theta value (output) + * @return a negative error code on failure, 1 on success + */ +int calcTwoTheta(MATRIX B, tasQEPosition ref, int ss, double *twoTheta); /** * calculate a UB from two reflections and the cell. * @param cell The lattice constant of the crystal