From 10a475f0206b990e1d1112725d905fd8484ca7c2 Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 9 Mar 2009 08:28:08 +0000 Subject: [PATCH] - Fixed conflicts in ascon.c - Supressed superfluous message from fmess - Expanded multicounter to deal with threshold commands nicely - Fixed an an issue with an uninitialized dummy connection in nserver - Many changes to simidex to make it work in a more reliable way. - Added hdbfactory path alias targetpath - Extended frame to deal with sinqhttp HM --- ascon.c | 1 + fourmess.c | 54 ++++++++++++++++++++++- frame.c | 49 +++++++++++++++------ hipadaba.c | 14 +++--- lld.c | 1 - macro.c | 36 ++++++++++++++++ macro.h | 2 + make_gen | 2 +- motorsec.c | 1 + multicounter.c | 62 ++++++++++++++++++++++----- nserver.c | 2 + ofac.c | 1 + sicshdbfactory.c | 102 +++++++++++++++++++++++++++++++++++++++++++- sicshipadaba.c | 2 +- simidx.c | 86 ++++++++++++++++++++++++++++--------- simidx.h | 9 +++- simindex.c | 109 +++++++++++++++++++++++++++++++---------------- singlenb.c | 9 ++-- singlex.c | 21 +++++++-- stdscan.c | 2 + velosim.c | 6 +-- 21 files changed, 469 insertions(+), 102 deletions(-) diff --git a/ascon.c b/ascon.c index 2f6a51c2..6de1c333 100644 --- a/ascon.c +++ b/ascon.c @@ -172,6 +172,7 @@ static void AsconConnect(Ascon * a) return; } + int AsconReadGarbage(int fd) { fd_set rmask; diff --git a/fourmess.c b/fourmess.c index 98363264..78c8bf8a 100644 --- a/fourmess.c +++ b/fourmess.c @@ -30,6 +30,10 @@ #include "matrix/matrix.h" #include "cell.h" #include "fourlib.h" +#include "counter.h" +#include "scanvar.h" +#include "scan.i" +#include "sdynar.h" extern void SNXFormatTime(char *pBueffel, int iLen); @@ -226,7 +230,6 @@ static int FourMessStart(pSICSOBJ self, SConnection * pCon, priv->count = 0; return 1; } - /*----------------------------------------------------------------------------*/ static int FourMessScanPar(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) @@ -255,7 +258,52 @@ static int FourMessScanPar(pSICSOBJ self, SConnection * pCon, } return 1; } +/*--------------------------------------------------------------------------*/ +static int FourMessPrepareScan(pScanData self) +{ + pVarEntry pVar = NULL; + void *pDings; + int i, iRet; + float fVal; + char pBueffel[512]; + char pMessage[1024]; + assert(self); + assert(self->pCon); + + /* check boundaries of scan variables and allocate storage */ + for (i = 0; i < self->iScanVar; i++) { + DynarGet(self->pScanVar, i, &pDings); + pVar = (pVarEntry) pDings; + if (pVar) { + iRet = CheckScanVar(pVar, self->pCon, self->iNP - 1); + if (!iRet) { + return 0; + } + InitScanVar(pVar); + } else { + SCWrite(self->pCon, + "WARNING: Internal error, no scan variable, I try to continue", + eLog); + } + pVar = NULL; + } /* end for */ + + /* configure counter */ + SetCounterMode((pCounter) self->pCounterData, self->iMode); + SetCounterPreset((pCounter) self->pCounterData, self->fPreset); + self->iCounts = 0; + + return 1; +} +/*-----------------------------------------------------------------------------*/ +static int FourMessPrepareCmd(pSICSOBJ self, SConnection * pCon, + pHdb commandNode, pHdb par[], int nPar) +{ + pFourMess priv = self->pPrivate; + + return FourMessPrepareScan(priv->pScanner); +} /*----------------------------------------------------------------------------*/ static hdbCallbackReturn SetScannerCB(pHdb node, void *userData, pHdbMessage mm) @@ -780,6 +828,10 @@ void InstallFourMess(SConnection * pCon, SicsInterp * pSics) AddSICSHdbPar(pNew->objectNode, "close", usUser, MakeSICSFunc(FourMessClose)); + cmd = + AddSICSHdbPar(pNew->objectNode, "prepare", usUser, + MakeSICSFunc(FourMessPrepareCmd)); + cmd = AddSICSHdbPar(pNew->objectNode, "scanpar", usUser, MakeSICSFunc(FourMessScanPar)); diff --git a/frame.c b/frame.c index 094edf33..d9fa9a6b 100644 --- a/frame.c +++ b/frame.c @@ -19,19 +19,23 @@ #include "HistMem.h" #include "HistMem.i" #include "HistDriv.i" -#include "hardsup/sinqhm.h" -#include "sinqhmdriv.i" +#include "psi/hardsup/sinqhm.h" +#include "psi/sinqhmdriv.i" #include "nxdict.h" #include "frame.h" + +extern int isSINQHTTP(pHistDriver self); /*======================================================================*/ -static int readHMFrame(SConnection * pCon, pHistMem pHM, int nFrame) +static int readHMFrame(SConnection * pCon, pHistMem pHM, + int nFrame, int sansflag) { - HistInt *buffer = NULL; + HistInt *buffer = NULL, *subbuf = NULL; int iDim[MAXDIM], rank, length, status, i, noTimeBins; pSINQHM pHist; SinqHMDriv *pTata; const float *timeBin; - + char histCommand[132]; + /* find dimensions and allocate data */ @@ -56,17 +60,17 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM, int nFrame) buffer[0] = htonl(iDim[0]); buffer[1] = htonl(iDim[1]); + if (nFrame < 0) { + nFrame = 0; + } + if (nFrame >= noTimeBins) { + nFrame = noTimeBins - 1; + } if (isSINQHMDriv(pHM->pDriv) && noTimeBins > 2) { /* read from HM. The 5 is PROJECT__FRAME in Sinqhm_def.h Again: be friendly: fix out of range frames */ - if (nFrame < 0) { - nFrame = 0; - } - if (nFrame >= noTimeBins) { - nFrame = noTimeBins - 1; - } pTata = (SinqHMDriv *) pHM->pDriv->pPriv; pHist = (pSINQHM) pTata->pMaster; status = SINQHMProject(pHist, 0x0005, 0, nFrame, @@ -77,6 +81,21 @@ static int readHMFrame(SConnection * pCon, pHistMem pHM, int nFrame) free(buffer); return 0; } + } else if(isSINQHTTP(pHM->pDriv) && noTimeBins > 2){ + if(sansflag){ + snprintf(histCommand,132,"sample:0:%d:%d:%d", iDim[0]*iDim[1], nFrame, nFrame+1); + } else { + snprintf(histCommand,132,"sample:0:%d:0:%d:%d:%d", iDim[0], iDim[1], nFrame, nFrame+1); + } + if(pHM->pDriv->SubSample != NULL){ + subbuf = pHM->pDriv->SubSample(pHM->pDriv, pCon,0,histCommand); + if(subbuf == NULL){ + SCWrite(pCon,"ERROR: subsampling failed ", eError); + return 0; + } + memcpy(buffer+2,subbuf, length *sizeof(HistInt)); + free(subbuf); + } } else { /* be friendly, just read the 2D data which is there @@ -210,6 +229,7 @@ int PSDFrameAction(SConnection * pCon, SicsInterp * pSics, void *pData, { pHistMem pHM; int nFrame; + int sansflag; /* this is unique and special for the SANS at PSI */ if (argc < 2) { SCWrite(pCon, "ERROR: Insufficient number of arguments to PSDFrame", @@ -230,7 +250,12 @@ int PSDFrameAction(SConnection * pCon, SicsInterp * pSics, void *pData, return 0; } nFrame = atoi(argv[3]); - return readHMFrame(pCon, pHM, nFrame); + if(argc > 3 && (strcmp(argv[4],"sans") == 0) ){ + sansflag = 1; + } else { + sansflag = 0; + } + return readHMFrame(pCon, pHM, nFrame, sansflag); } else if (strcmp(argv[1], "file") == 0) { if (argc < 6) { SCWrite(pCon, diff --git a/hipadaba.c b/hipadaba.c index 786940b3..bff09f7c 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -931,13 +931,13 @@ int copyHdbValue(hdbValue * source, hdbValue * target) /*---------------------------------------------------------------------------*/ static int SendDataMessage(pHdb node, char *type, - hdbValue v, void *callData) + hdbValue *v, void *callData) { hdbDataMessage dataMes; assert(type == set || type == get || type == update); dataMes.type = type; - dataMes.v = &v; + dataMes.v = v; dataMes.callData = callData; return InvokeCallbackChain(node, (pHdbMessage) & dataMes); } @@ -945,7 +945,7 @@ static int SendDataMessage(pHdb node, char *type, /*----------------------------------------------------------------------------*/ int SetHipadabaPar(pHdb node, hdbValue v, void *callData) { - return SendDataMessage(node, set, v, callData); + return SendDataMessage(node, set, &v, callData); } /*-----------------------------------------------------------------------------*/ @@ -953,7 +953,7 @@ int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData) { int status; - status = SendDataMessage(node, update, v, callData); + status = SendDataMessage(node, update, &v, callData); if (status == 1) { copyHdbValue(&v, &node->value); } @@ -963,12 +963,12 @@ int UpdateHipadabaPar(pHdb node, hdbValue v, void *callData) /*-----------------------------------------------------------------------------*/ int NotifyHipadabaPar(pHdb node, void *callData) { - SendDataMessage(node, update, node->value, callData); + SendDataMessage(node, update, &node->value, callData); return 1; } /*-----------------------------------------------------------------------------*/ -int GetHipadabaPar(pHdb node, hdbValue * v, void *callData) +int GetHipadabaPar(pHdb node, hdbValue *v, void *callData) { int status; @@ -976,7 +976,7 @@ int GetHipadabaPar(pHdb node, hdbValue * v, void *callData) v->doNotFree = 0; v->v.text = NULL; /* this sets all pointers in the union to NULL */ - status = SendDataMessage(node, get, *v, callData); + status = SendDataMessage(node, get, v, callData); copyHdbValue(&node->value, v); if (status != 1) { return status; diff --git a/lld.c b/lld.c index 30f74d7b..82cf1c3e 100644 --- a/lld.c +++ b/lld.c @@ -69,7 +69,6 @@ static int ListInit(int List, int ItemSize) if (0 != ItemSize) { /* create dummy head node */ - (void)Fortify_CheckAllMemory(); Tmp = NODE_MALLOC(List); if (NULL == Tmp) { return ERR_MEMORY; diff --git a/macro.c b/macro.c index 17e30e40..310abc53 100644 --- a/macro.c +++ b/macro.c @@ -1062,3 +1062,39 @@ int TransactAction(SConnection * pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, "TRANSACTIONFINISHED", eLog); return iRet; } +/*-----------------------------------------------------------------------------*/ +int CaptureAction(SConnection *pCon, SicsInterp * pSics, void *pData, + int argc, char *argv[]) +{ + SConnection *comCon = NULL; + char buffer[1024]; + char *command; + int status; + pDynString reply = NULL; + + if (argc < 2) { + SCWrite(pCon, "ERROR: insufficient arguments to capture", eError); + return 0; + } + + comCon = SCCopyConnection(pCon); + if (comCon == NULL) { + SCWrite(pCon, "EROOR: out of memory in capture", eError); + return 0; + } + memset(buffer, 0, sizeof(buffer)); + command = Arg2Tcl(argc - 1, &argv[1], buffer, sizeof buffer); + if (!command) { + SCWrite(pCon, "ERROR: no more memory", eError); + return 0; + } + SCStartBuffering(comCon); + status = InterpExecute(pSics, comCon, command); + if (command != buffer) + free(command); + reply = SCEndBuffering(comCon); + SCWrite(pCon,GetCharArray(reply), eValue); + SCDeleteConnection(comCon); + return status; + +} diff --git a/macro.h b/macro.h index 6ddf752d..f39c5346 100644 --- a/macro.h +++ b/macro.h @@ -37,6 +37,8 @@ int Broadcast(SConnection * pCon, SicsInterp * pInter, void *pData, int argc, char *argv[]); int TransactAction(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); +int CaptureAction(SConnection * pCon, SicsInterp * pSics, void *pData, + int argc, char *argv[]); int TclPublish(SConnection * pCon, SicsInterp * pInter, void *pData, int argc, char *argv[]); diff --git a/make_gen b/make_gen index 05ed0dd0..ab87e66f 100644 --- a/make_gen +++ b/make_gen @@ -35,7 +35,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ savehdb.o statusfile.o sicshdbfactory.o proxy.o devser.o \ moregress.o multicounter.o regresscter.o histregress.o \ sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \ - nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o \ + nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o frame.o\ nxcopy.o nxinterhelper.o nxinter_wrap.o genericcontroller.o nxstack.o \ sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.o \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \ diff --git a/motorsec.c b/motorsec.c index 3064480c..448d6468 100644 --- a/motorsec.c +++ b/motorsec.c @@ -608,6 +608,7 @@ pMotor SecMotorInit(char *name) free(pM); return NULL; } + /* TODO: give it a sicsdev here */ node = pM->pDescriptor->parNode; pM->objectNode = node; AppendHipadabaCallback(pM->pDescriptor->parNode, diff --git a/multicounter.c b/multicounter.c index ac71b29b..f68463de 100644 --- a/multicounter.c +++ b/multicounter.c @@ -14,6 +14,10 @@ * copyright: see file COPYRIGHT * * Mark Koennecke, September 2006 + * + * extended to forward parameter setting requests to the single counter driver + * + * Mark Koennecke, February 2009 */ #include #include @@ -290,30 +294,68 @@ static void MMCCParameter(void *pData, float fPreset, CounterMode eMode) } /*======================= Driver Interface ==============================*/ -static int MultiCounterSet(struct __COUNTER *self, char *name, +static int MultiCounterSet(struct __COUNTER *pCount, char *name, int iCter, float fVal) { + pDummy pDum; + int i; + pMultiCounter self = NULL; + pCounter pCter; + + self = (pMultiCounter) pCount->pData; + assert(self); - return 0; + for (i = 0; i < self->nSlaves; i++) { + pDum = (pDummy)self->slaveData[i]; + if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ + pCter = (pCounter)self->slaveData[i]; + return pCter->pDriv->Set(pCter->pDriv, name, iCter, fVal); + } + } + return 0; } - /*-----------------------------------------------------------------------*/ -static int MultiCounterGet(struct __COUNTER *self, char *name, +static int MultiCounterGet(struct __COUNTER *pCount, char *name, int iCter, float *fVal) { + pDummy pDum; + int i; + pMultiCounter self = NULL; + pCounter pCter; + + self = (pMultiCounter) pCount->pData; + assert(self); - return 0; + for (i = 0; i < self->nSlaves; i++) { + pDum = (pDummy)self->slaveData[i]; + if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ + pCter = (pCounter)self->slaveData[i]; + return pCter->pDriv->Get(pCter->pDriv, name, iCter, fVal); + } + } + return 0; } - /*-----------------------------------------------------------------------*/ -static int MultiCounterSend(struct __COUNTER *self, char *pText, +static int MultiCounterSend(struct __COUNTER *pCount, char *pText, char *reply, int replylen) { + pDummy pDum; + int i; + pMultiCounter self = NULL; + pCounter pCter; + + self = (pMultiCounter) pCount->pData; + assert(self); - strncpy(reply, "NOT Implemented", replylen); - return 0; + for (i = 0; i < self->nSlaves; i++) { + pDum = (pDummy)self->slaveData[i]; + if(strcmp(pDum->pDescriptor->name, "SingleCounter") == 0){ + pCter = (pCounter)self->slaveData[i]; + return pCter->pDriv->Send(pCter->pDriv,pText, reply, replylen); + } + } + return 0; } - /*---------------------------------------------------------------------*/ static int MultiCounterError(struct __COUNTER *pDriv, int *iCode, char *error, int errlen) diff --git a/nserver.c b/nserver.c index 9553c655..6cdfab40 100644 --- a/nserver.c +++ b/nserver.c @@ -107,6 +107,8 @@ int InitServer(char *file, pServer * pServ) /* interpreter */ self->pSics = InitInterp(); + self->dummyCon = SCCreateDummyConnection(self->pSics); + assert(self->dummyCon != NULL); assert(self->pSics); /* initialise tasker */ diff --git a/ofac.c b/ofac.c index 7c1791cc..8436e0b1 100644 --- a/ofac.c +++ b/ofac.c @@ -217,6 +217,7 @@ static void InitIniCommands(SicsInterp * pInter, pTaskMan pTask) AddCommand(pInter, "InternEval", InternalFileEval, NULL, NULL); AddCommand(pInter, "ClientPut", ClientPut, NULL, NULL); + AddCommand(pInter, "Capture", CaptureAction, NULL, NULL); AddCommand(pInter, "GumPut", GumPut, NULL, NULL); AddCommand(pInter, "broadcast", Broadcast, NULL, NULL); AddCommand(pInter, "transact", TransactAction, NULL, NULL); diff --git a/sicshdbfactory.c b/sicshdbfactory.c index d921f455..cc721066 100644 --- a/sicshdbfactory.c +++ b/sicshdbfactory.c @@ -305,7 +305,6 @@ static hdbCallbackReturn CommandSetCallback(pHdb node, void *userData, } return hdbContinue; } - /*---------------------------------------------------------------------------*/ static hdbCallbackReturn CommandGetCallback(pHdb node, void *userData, pHdbMessage message) @@ -361,7 +360,106 @@ static int MakeCommandNode(pHdb parent, char *name, SConnection * pCon, SCSendOK(pCon); return 1; } +/*---------------------------------------------------------------------------*/ +static hdbCallbackReturn AliasSourceCallback(pHdb node, void *userData, + pHdbMessage message) +{ + SConnection *pCon = NULL; + pHdb targetNode = NULL; + pHdbDataMessage mm; + + if((mm = GetHdbSetMessage(message)) != NULL){ + pCon = mm->callData; + targetNode = FindHdbNode(NULL,(char *)userData, pCon); + if(targetNode == NULL){ + if(pCon != NULL){ + SCPrintf(pCon,eError,"ERROR: link target %s not found, deleting link callbacks", + (char *)userData); + } + return hdbKill; + } + SetHipadabaPar(targetNode,*mm->v,pCon); + return hdbContinue; + } + + if((mm = GetHdbGetMessage(message)) != NULL){ + pCon = mm->callData; + targetNode = FindHdbNode(NULL,(char *)userData, pCon); + if(targetNode == NULL){ + if(pCon != NULL){ + SCPrintf(pCon,eError,"ERROR: link target %s not found, deleting link callbacks", + (char *)userData); + } + return hdbKill; + } + GetHipadabaPar(targetNode,mm->v,pCon); + copyHdbValue(mm->v,&node->value); + return hdbContinue; + } + + return hdbContinue; +} +/*---------------------------------------------------------------------------*/ +static hdbCallbackReturn AliasTargetCallback(pHdb node, void *userData, + pHdbMessage message) +{ + SConnection *pCon = NULL; + pHdb targetNode = NULL; + pHdbDataMessage mm; + + if((mm = GetHdbUpdateMessage(message)) != NULL){ + pCon = mm->callData; + targetNode = FindHdbNode(NULL,(char *)userData, pCon); + if(targetNode == NULL){ + if(pCon != NULL){ + SCPrintf(pCon,eError,"ERROR: link source %s not found, deleting link callbacks", + (char *)userData); + } + return hdbKill; + } + UpdateHipadabaPar(targetNode,*mm->v,pCon); + return hdbContinue; + } + return hdbContinue; +} +/*--------------------------------------------------------------------------*/ +static int MakeAliasNode(pHdb parent, char *name, SConnection *pCon, + int argc, char *argv[]) +{ + hdbValue v; + pHdb targetNode = NULL, child = NULL; + + if(argc < 4){ + SCWrite(pCon,"ERROR: hdbfactory alias needs 4 arguments, not enough supplied", + eError); + return 0; + } + + targetNode = FindHdbNode(NULL,argv[3], pCon); + if(targetNode == NULL){ + SCPrintf(pCon,eError,"ERROR: alias target %s not found", + argv[3]); + return 0; + } + + child = MakeHipadabaNode(name,targetNode->value.dataType, + targetNode->value.arrayLength); + if(child == NULL){ + SCWrite(pCon,"ERROR: out of memory in hdbfactory alias", eError); + return 0; + } + AppendHipadabaCallback(child, + MakeHipadabaCallback(AliasSourceCallback, + strdup(argv[3]),free)); + AddHipadabaChild(parent,child, pCon); + AppendHipadabaCallback(targetNode, + MakeHipadabaCallback(AliasTargetCallback, + strdup(argv[1]),free)); + + SCSendOK(pCon); + return 1; +} /*--------------------------------------------------------------------------*/ int HdbNodeFactory(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -390,6 +488,8 @@ int HdbNodeFactory(SConnection * pCon, SicsInterp * pSics, void *pData, return MakeScriptNode(parent, name, pCon, argc, argv); } else if (strcmp(argv[2], "link") == 0) { return MakeLinkNode(parent, name, pCon, argc, argv); + } else if (strcmp(argv[2], "alias") == 0) { + return MakeAliasNode(parent, name, pCon, argc, argv); } else if (strcmp(argv[2], "command") == 0) { return MakeCommandNode(parent, name, pCon, argc, argv); } else { diff --git a/sicshipadaba.c b/sicshipadaba.c index 2c1f84d6..cb7661e7 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -198,7 +198,7 @@ static hdbCallbackReturn SICSSetUpdateCallback(pHdb node, void *userData, return hdbContinue; } status = UpdateHipadabaPar(node, *(mm->v), mm->callData); - if (status) { + if (status && mm->callData != NULL) { SCSendOK(mm->callData); } return hdbContinue; diff --git a/simidx.c b/simidx.c index 430b3f6f..3a231db7 100644 --- a/simidx.c +++ b/simidx.c @@ -30,7 +30,7 @@ #define MAXCANDIDATES 20 #define MAXREF 20 #define MAXIDX 20 -#define MAXSOLUTION 20 +#define MAXSOLUTION 50 #define ABS(x) (x < 0 ? -(x) : (x)) /*======================== types =============================*/ typedef struct { @@ -250,7 +250,10 @@ static int calcIndexes() mink = -MAXIDX; minl = -MAXIDX; SetListMin_hkl(spgrp, MAXIDX, MAXIDX, &minh, &mink, &minl); - + for(i = 0; i < nReflections; i++){ + reflections[i].nHKL = 0; + } + for (h = MAXIDX; h > -MAXIDX; h--) { for (k = MAXIDX; k > -MAXIDX; k--) { for (l = MAXIDX; l > -MAXIDX; l--) { @@ -269,7 +272,14 @@ static int calcIndexes() } } mat_free(B); - return 1; + status = 1; + for(i = 0; i < nReflections; i++){ + if(reflections[i].nHKL < 1) { + SimIdxPrint(10,"Failed to find candidate indices for %4d", reflections[i].originalID); + status = 0; + } + } + return status; } /*-------------------------------------------------------------*/ @@ -346,13 +356,27 @@ static int areCoplanar(MATRIX v1, MATRIX v2, MATRIX v3) } else { dot = .0; } - if (ABS(dot) > .00001) { + if (ABS(dot) > .01) { return 0; } else { return 1; } } +/*-------------------------------------------------------------*/ +static double calcCoplanar(MATRIX v1, MATRIX v2, MATRIX v3) +{ + MATRIX norm; + double dot; + norm = vectorCrossProduct(v1, v2); + if (norm != NULL) { + dot = vectorDotProduct(norm, v3); + mat_free(norm); + } else { + dot = .0; + } + return ABS(dot); +} /*-------------------------------------------------------------- * - We want the shortest vectors * - We do not want vectors at 180 to each other @@ -361,15 +385,17 @@ static int areCoplanar(MATRIX v1, MATRIX v2, MATRIX v3) static int chooseTriplet(int triplet[3]) { double angle, vol; - int idx = 1; - + int idx = 1, coIdx = 0; + double coplanarVector[MAXREF], coMax = -9999999.99; + + memset(coplanarVector,0,MAXREF*sizeof(double)); triplet[0] = 0; /* * test for 180 */ while (idx < nReflections) { angle = angleBetweenScatVec(reflections[0].UVW, reflections[idx].UVW); - if (angle < 160 && angle > -160) { + if (angle < 140 && angle > -140) { triplet[1] = idx; break; } @@ -380,16 +406,28 @@ static int chooseTriplet(int triplet[3]) return 0; } + /* + * Try to find a reflection which is most out of the plane build by the first + * two. A good angular separation will give a better UB + */ for (idx = 1; idx < nReflections; idx++) { if (idx != triplet[1]) { - if (!areCoplanar(reflections[triplet[0]].UVW, + coplanarVector[idx] = calcCoplanar(reflections[triplet[0]].UVW, reflections[triplet[1]].UVW, - reflections[idx].UVW)) { - triplet[2] = idx; - return 1; - } + reflections[idx].UVW); } } + for(idx = 0; idx < nReflections; idx++){ + if(coplanarVector[idx] > coMax){ + coMax = coplanarVector[idx]; + coIdx = idx; + } + } + if(coMax > .01){ + triplet[2] = coIdx; + return 1; + } + SimIdxPrint(1, "ERROR: no three non coplanar reflections found"); return 0; } @@ -464,10 +502,9 @@ static int testRightHandedness(int r1, int r1idx, vol = mat_det(T); mat_free(T); if (vol > .0) { - return 1; - } else { return 0; - } + } + return 1; } /*-------------------------------------------------------------*/ @@ -502,8 +539,12 @@ static void storeSolution(int r1, int r1idx, } is.diff += diff; - solutions[nSolutions] = is; - nSolutions++; + if(nSolutions < MAXSOLUTION){ + solutions[nSolutions] = is; + nSolutions++; + } else { + SimIdxPrint(10,"WARNING: more solutions then solution space"); + } } /*----------------------------------------------------------------------*/ @@ -685,6 +726,7 @@ int SimIdxRun() calcRefTheta(); if (!calcIndexes()) { + SimIdxPrint(10,"ERROR: Problems finding candidate indices for reflections\nCannot continue\nCheck limits, cell and spacegroup"); return 0; } @@ -720,12 +762,18 @@ int SimIdxRun() return status; } -/*=========================== solution retrieval ===================*/ +/*=========================== solution management ===================*/ int SimIdxGetNSolutions() { return nSolutions; } - +/*------------------------------------------------------------------*/ +void SimIdxRemoveSolution(int id){ + if(id >= 0 && id < nSolutions){ + solutions[id] = solutions[nSolutions-1]; + nSolutions--; + } +} /*------------------------------------------------------------------*/ IndexSolution SimIdxGetSolution(int id) { diff --git a/simidx.h b/simidx.h index 1c24a01e..17668ecc 100644 --- a/simidx.h +++ b/simidx.h @@ -4,7 +4,7 @@ * - Candidate indices are calculated from the lattice constants * - Permutations of the generated indices are changed for a couple * of conditions: - * -- Does the angle between the reflections matches the expectaions + * -- Does the angle between the reflections matches the expectations * -- Do the reflections form a right handed set * UB matrics matching these conditions are calculated and stored * for later retrieval. @@ -98,5 +98,12 @@ int SimIdxGetNSolutions(); * \return A IndexSolution structure */ IndexSolution SimIdxGetSolution(int id); +/** + * Remove the solution with the id given. This allows + * for solution filtering though upper level code. Please + * note that this changes the number of available solutions + * @param id The solution to remove + */ +void SimIdxRemoveSolution(int id); #endif diff --git a/simindex.c b/simindex.c index 38276877..f4e1648f 100644 --- a/simindex.c +++ b/simindex.c @@ -21,10 +21,9 @@ static void SicsOutFunc(void *data, char *text) { SConnection *pCon = (SConnection *) data; if (pCon != NULL) { - SCWrite(pCon, text, eWarning); + SCWrite(pCon, text, eLog); } } - /*-----------------------------------------------------------------------*/ static hdbCallbackReturn SetSttLim(pHdb node, void *userData, pHdbMessage mm) @@ -54,16 +53,68 @@ static hdbCallbackReturn SetAngLim(pHdb node, void *userData, } return hdbContinue; } +/*-----------------------------------------------------------------------*/ +MATRIX calcUBForSolution(IndexSolution is, int *err) +{ + pSingleDiff diffi; + pSICSOBJ reflist; + int i; + MATRIX UB; + double hkl[3]; + + diffi = SXGetDiffractometer(); + reflist = SXGetReflectionList(); + assert(reflist != NULL && diffi != NULL); + for (i = 0; i < 3; i++) { + if (is.originalID[i] != 999) { + hkl[0] = (double) is.h[i]; + hkl[1] = (double) is.k[i]; + hkl[2] = (double) is.l[i]; + SetRefIndex(reflist, is.originalID[i], hkl); + } + } + if (is.originalID[2] == 999) { + UB = diffi->calcUBFromTwo(diffi, GetRefName(reflist, is.originalID[0]), + GetRefName(reflist, is.originalID[1]), err); + } else { + UB = diffi->calcUBFromThree(diffi, + GetRefName(reflist, is.originalID[0]), + GetRefName(reflist, is.originalID[1]), + GetRefName(reflist, is.originalID[2]), + err); + } + return UB; +} +/*-----------------------------------------------------------------------*/ +static void filterSolutions(){ + int i, err; + IndexSolution is; + MATRIX UB; + + for(i = 0; i < SimIdxGetNSolutions(); i++){ + is = SimIdxGetSolution(i); + if(is.originalID[0] != -999){ + UB = calcUBForSolution(is,&err); + if(UB != NULL){ + mat_free(UB); + } else { + SimIdxRemoveSolution(i); + i--; + } + } + } +} /*-------------------------------------------------------------------------*/ static int RunIndexCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { - int i, j, status; + int i, j, status, err; pSingleDiff diffi; pSICSOBJ reflist; double ang[4], z1[3]; IndexSolution is; + MATRIX ub; SimIdxSetLambda(SXGetLambda()); SimIdxSetCell((double *) SXGetCell()); @@ -78,29 +129,37 @@ static int RunIndexCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, diffi->calcZ1(diffi, GetRefName(reflist, i), z1); SimIdxAddReflection(z1); } - + status = SimIdxRun(); + filterSolutions(); if (status == 1) { if (SimIdxGetNSolutions() < 1) { - SCWrite(pCon, "No solutions were found", eWarning); + SCWrite(pCon, "No solutions were found", eLog); return 0; } - SCWrite(pCon, "Indexing Suggestions:", eWarning); + SCWrite(pCon, "Indexing Suggestions:", eLog); for (i = 0; i < SimIdxGetNSolutions(); i++) { is = SimIdxGetSolution(i); - SCPrintf(pCon, eWarning, "Solution No : %d, GOF = %6.3f", i, + SCPrintf(pCon, eLog, "Solution No : %d, GOF = %6.3f", i, is.diff * 100); for (j = 0; j < 3; j++) { if (is.originalID[j] != 999) { - SCPrintf(pCon, eWarning, " Ref = %2d, HKL = %4d %4d %4d ", + SCPrintf(pCon, eLog, " Ref = %2d, HKL = %4d %4d %4d ", is.originalID[j], is.h[j], is.k[j], is.l[j]); } } + SCPrintf(pCon,eLog," UB:"); + ub = calcUBForSolution(is,&err); + if(ub != NULL) { /* should never happen, as filtered */ + for(j = 0; j < 3; j++){ + SCPrintf(pCon, eLog," %8.5f %8.5f %8.5f", + ub[j][0], ub[j][1], ub[j][2]); + } + } } } return status; } - /*-----------------------------------------------------------------------*/ static int ChooseCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) @@ -108,9 +167,7 @@ static int ChooseCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, MATRIX UB; int err, solution, i; IndexSolution is; - double hkl[3], ub[9]; - pSICSOBJ reflist; - pSingleDiff diffi; + double ub[9]; if (nPar < 1) { SCWrite(pCon, "ERROR: need the solution number as argument", eError); @@ -123,30 +180,9 @@ static int ChooseCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, return 0; } - is = SimIdxGetSolution(i); - reflist = SXGetReflectionList(); - diffi = SXGetDiffractometer(); - assert(reflist != NULL); - assert(diffi != NULL); - for (i = 0; i < 3; i++) { - if (is.originalID[i] != 999) { - hkl[0] = (double) is.h[i]; - hkl[1] = (double) is.k[i]; - hkl[2] = (double) is.l[i]; - SetRefIndex(reflist, is.originalID[i], hkl); - } - } - - if (is.originalID[2] == 999) { - UB = diffi->calcUBFromTwo(diffi, GetRefName(reflist, is.originalID[0]), - GetRefName(reflist, is.originalID[1]), &err); - } else { - UB = diffi->calcUBFromThree(diffi, - GetRefName(reflist, is.originalID[0]), - GetRefName(reflist, is.originalID[1]), - GetRefName(reflist, is.originalID[2]), - &err); - } + is = SimIdxGetSolution(solution); + UB = calcUBForSolution(is,&err); + if (UB == NULL) { switch (err) { case REFERR: @@ -181,7 +217,6 @@ static int ChooseCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, SCSendOK(pCon); return 1; } - /*-----------------------------------------------------------------------*/ static int DiraxCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) diff --git a/singlenb.c b/singlenb.c index 936851c1..454aedfc 100644 --- a/singlenb.c +++ b/singlenb.c @@ -85,14 +85,15 @@ static int calculateNBSettings(pSingleDiff self, if (status != 1) { return 0; } + if(om > 180.){ + om -= 360; + } else if (om < -180.){ + om += 360.; + } if (checkNormalBeam(om, &gamma, nu, settings, self)) { return 1; } else { - if (checkNormalBeam(om + 360., &gamma, nu, settings, self)) { - return 1; - } else { return 0; - } } return 0; } diff --git a/singlex.c b/singlex.c index 2d5ac844..e6f5bc79 100644 --- a/singlex.c +++ b/singlex.c @@ -710,8 +710,11 @@ const double *SXGetUB() void SXSetUB(double ub[9]) { pHdb node = NULL; - pSingleX priv = (pSingleX) singlex->pPrivate; + if(singlex == NULL){ + return; + } + pSingleX priv = (pSingleX) singlex->pPrivate; node = GetHipadabaNode(singlex->objectNode, "ub"); assert(node != NULL); SetHipadabaPar(node, MakeHdbFloatArray(9, ub), NULL); @@ -777,12 +780,15 @@ void SXSetCell(double cell[6]) /*---------------------------------------------------------------------------*/ double SXGetLambda() { - pSingleX priv = (pSingleX) singlex->pPrivate; pSicsVariable lam = NULL; float val; hdbValue v; pHdb node = NULL; + if(singlex == NULL){ + return -99.9; + } + pSingleX priv = (pSingleX) singlex->pPrivate; if (priv->lambdaDriv != NULL) { return priv->lambdaDriv->GetValue(priv->lambdaVar, pServ->dummyCon); } else if (priv->lambdaVar != NULL) { @@ -792,7 +798,7 @@ double SXGetLambda() } node = GetHipadabaNode(singlex->objectNode, "lambda"); assert(node != NULL); - GetHipadabaPar(node, &v, NULL); + GetHipadabaPar(node, &v, pServ->dummyCon); return v.v.doubleValue; } @@ -820,16 +826,20 @@ T_SgInfo *SXGetSpaceGroup() /*---------------------------------------------------------------------------*/ pSingleDiff SXGetDiffractometer() { - pSingleX priv = (pSingleX) singlex->pPrivate; const double *cell, *ub; double lambda; int i; + /* Not initialized. * Trouble is motors need to be configured first, the we can set a diffractometer. * If this is ever triggered, the most likely cause is that no mode was selected in the * initialisation file. */ + if(singlex == NULL){ + return NULL; + } + pSingleX priv = (pSingleX) singlex->pPrivate; if (priv->diffractometer->calculateSettings == NULL) { return NULL; } @@ -851,6 +861,9 @@ void SXSetMode(SingleXModes m) { pHdb node = NULL; + if(singlex == NULL){ + return; + } node = GetHipadabaNode(singlex->objectNode, "mode"); assert(node != NULL); diff --git a/stdscan.c b/stdscan.c index d56538ab..12c0c910 100644 --- a/stdscan.c +++ b/stdscan.c @@ -1083,6 +1083,8 @@ int StandardScanWrapper(SConnection * pCon, SicsInterp * pSics, return WriteHeader(self); } else if (strcmp(argv[1], "prepare") == 0) { return PrepareScan(self); + } else if (strcmp(argv[1], "noncheckprepare") == 0) { + return NonCheckPrepare(self); } else if (strcmp(argv[1], "finish") == 0) { return 1; } diff --git a/velosim.c b/velosim.c index 6e7012f7..118223c9 100644 --- a/velosim.c +++ b/velosim.c @@ -114,7 +114,7 @@ static int GetSimPos(pVelSelDriv self, float *fPos) assert(self); if (SimRandom() < FAILURE) { *fPos = SimRandom(); - return HWFault; + return VELOFAIL; } pDriv = (pSimi) self->pPrivate; @@ -127,9 +127,9 @@ static int GetSimPos(pVelSelDriv self, float *fPos) } else { *fPos = pDriv->fPos; } - return OKOK; + return VELOOK; } - return OKOK; + return VELOOK; } /*----------------------------------------------------------------------------*/