- Fixed a normalisation problem in diffscan when the first value

did not have enough counts
- Reduced polling frequency in emon
- Fixed a scriptcontext bug which would cause it to dump core in SctTransact
  on interrupts
- Fixed an issue with missing <nl> at the end of batch files
- Added a feature which does not call halt when counting stops in hmcontrol.c
  This is necessary for the BOA CCD
- Initalized doNotFree properly in hipadaba.c
- Added the travelling salesman reflection measurement algorithm
- Added another component to amorset
- Removed old SicsWait from nserver.c
- Added a means to nxscript to write 16 bit data for BOA
- Modified tasub to accept a drivabel as a motor and not only a motor.
  This became necessary to make EIGER work as A2 on EIGER is a virtual
  motor


SKIPPED:
	psi/amorcomp.h
	psi/amordrive.h
	psi/amorset.c
	psi/amorset.h
	psi/amorset.tex
	psi/amorset.w
	psi/el734hp.c
	psi/el737hpdriv.c
	psi/make_gen
	psi/pardef.c
	psi/polterwrite.c
	psi/psi.c
	psi/sinqhttpopt.c
This commit is contained in:
koennecke
2011-09-23 07:55:49 +00:00
parent 2dd46f0968
commit ce565b4d50
29 changed files with 676 additions and 145 deletions

View File

@ -34,6 +34,9 @@
#include "scanvar.h"
#include "scan.i"
#include "sdynar.h"
#include "lld.h"
extern char *trim(char *);
extern void SNXFormatTime(char *pBueffel, int iLen);
@ -797,12 +800,15 @@ static int hklCompare(const void *h1, const void *h2)
}
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
* This sorts on two theta only.
-----------------------------------------------------------------------------*/
static int SortRef(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar)
{
double *sortlist, d, lambda, om, hkl[4], ang[4];
const double *cell;
double *hklc;
int nRefl, i, j;
MATRIX B, H, Z1;
lattice direct;
@ -860,7 +866,195 @@ static int SortRef(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------------
* Sorting reflection is actually a variant of the traveling salesman
* problem. Optimal solutions for this are computationally expensive.
* Optimise for the shortest path between reflections. Not all motors
* are equal though. Om and phi move quick whereas stt and chi go slow.
* As a compromise, what I try here is sorting by a weighted addition of
* stt and chi.
----------------------------------------------------------------------------*/
static int SortRefNew(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar)
{
double *sortlist, d, lambda, om, hkl[4], ang[4];
const double *cell;
double *hklc;
int nRefl, i, j, status, count;
SingleXModes mode;
pFourMess priv = self->pPrivate;
pSingleDiff diffi = NULL;
diffi = SXGetDiffractometer();
mode = SXGetMode();
if(diffi == NULL){
SCWrite(pCon,"ERROR: not initialized, no diffractometer", eError);
return 0;
}
nRefl = ReflectionListCount(priv->messList);
sortlist = malloc(nRefl * 4 * sizeof(double));
if (sortlist == NULL) {
SCWrite(pCon, "ERROR: out of memory in SortRef", eError);
return 0;
}
/*
* I am using hkl[3] for storing the sort value to sort for! */
for (i = 0, count = 0; i < nRefl; i++) {
GetRefIndex(priv->messList, i, hkl);
status = diffi->calculateSettings(diffi,hkl,ang);
if(status == 1){
if(mode == Bisecting){
hkl[3] = ang[0] + 0.5* ang[2];
if(ang[2] < 0){
SCWrite(pCon,"WARNING: chi < 0!", eWarning);
}
} else if(mode == NB){
/*
* sort for nu in the first place. In order to cope with negativity, add
* 10.
*/
hkl[3] = ang[2]+10 + 0.1 * ang[0];
} else {
hkl[3] = ang[0];
}
memcpy(sortlist + count * 4, hkl, 4 * sizeof(double));
count++;
}
}
qsort(sortlist, count, 4 * sizeof(double), hklCompare);
ClearReflectionList(priv->messList);
for (i = 0; i < count; i++) {
hklc = sortlist+i*4;
hklc[3] = .0; /* otherwise this will be interpreted as psi! */
status = diffi->calculateSettings(diffi,hklc,ang);
AddRefIdxAng(priv->messList, sortlist+i*4,ang);
/* AddRefIdx(priv->messList, sortlist + i * 4); */
}
free(sortlist);
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------------
* Write a reflection list in the TSPLIB format for running a traveling
* salesman algorithm against it.
----------------------------------------------------------------------------- */
static int WriteTSP(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar)
{
double hkl[4], ang[4];
int nRefl, i, j, status, count;
SingleXModes mode;
pFourMess priv = self->pPrivate;
pSingleDiff diffi = NULL;
FILE *fd = NULL;
if(nPar < 1) {
SCWrite(pCon,"ERROR: need a filename parameter", eError);
return 0;
}
fd = fopen(trim(par[0]->value.v.text),"w");
if(fd == NULL){
SCPrintf(pCon,eError,"ERROR: failed to open %s for writing", par[0]->value.v.text);
return 0;
}
diffi = SXGetDiffractometer();
mode = SXGetMode();
if(diffi == NULL){
SCWrite(pCon,"ERROR: not initialized, no diffractometer", eError);
return 0;
}
nRefl = ReflectionListCount(priv->messList);
/*
* smear header...
*/
fprintf(fd,"NAME : %s\n", par[0]->value.v.text);
fprintf(fd,"TYPE : TSP\n");
fprintf(fd,"DIMENSION : %d\n", nRefl);
fprintf(fd,"EDGE_WEIGHT_TYPE : EUC_3D\n");
fprintf(fd,"NODE_COORD_SECTION\n");
for (i = 0, count = 0; i < nRefl; i++) {
GetRefIndex(priv->messList, i, hkl);
status = diffi->calculateSettings(diffi,hkl,ang);
if(status == 1){
if(mode == Bisecting){
fprintf(fd,"%d %e %e %e\n",i+1,ang[0]*3*100,ang[2]*2*100,ang[3]*100);
} else if(mode == NB){
fprintf(fd,"%d %e %e %e\n",i,ang[2]*4*100,ang[0]*3*100,ang[1]*100);
} else {
fprintf(fd,"%d %e %e %e\n",i,ang[0]*3*100,ang[2]*2*100,ang[3]*2*100);
}
}
}
fclose(fd);
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------------
* read a tour file as generated by LKH or other TSP solvers and
* reorder the reflection list accordingly.
-----------------------------------------------------------------------------*/
static int ReadTour(pSICSOBJ self, SConnection * pCon, pHdb commandNode,
pHdb par[], int nPar)
{
FILE *fd = NULL;
char buffer[132];
double hkl[4], ang[4];
int idx, tour;
pFourMess priv = self->pPrivate;
pSingleDiff diffi = NULL;
if(nPar < 1) {
SCWrite(pCon,"ERROR: need name of a tour file to read", eError);
return 0;
}
fd = fopen(par[0]->value.v.text,"r");
if(fd == NULL){
SCPrintf(pCon,eError,"ERROR: failed to open tour file %s for reading",
par[0]->value.v.text);
return 0;
}
tour = LLDcreate(sizeof(hkl));
diffi = SXGetDiffractometer();
assert(diffi != NULL);
/* skip header */
while(fgets(buffer,sizeof(buffer),fd) != NULL){
if(strstr(buffer,"TOUR_SECTION") != NULL){
break;
}
}
while(fscanf(fd,"%d",&idx) == 1){
if(idx < 0){
break;
}
GetRefIndex(priv->messList,idx-1,hkl);
LLDnodeAppendFrom(tour,hkl);
}
fclose(fd);
idx = LLDnodePtr2First(tour);
ClearReflectionList(priv->messList);
while(idx == 1){
LLDnodeDataTo(tour,hkl);
hkl[3] = 0;
diffi->calculateSettings(diffi,hkl,ang);
AddRefIdxAng(priv->messList, hkl,ang);
idx = LLDnodePtr2Next(tour);
}
LLDdelete(tour);
SCSendOK(pCon);
return 1;
}
/*----------------------------------------------------------------------------*/
static int FourMessSave(void *data, char *name, FILE * fd)
{
@ -982,7 +1176,15 @@ void InstallFourMess(SConnection * pCon, SicsInterp * pSics)
cmd =
AddSICSHdbPar(pNew->objectNode, "indsort", usUser,
MakeSICSFunc(SortRef));
cmd =
AddSICSHdbPar(pNew->objectNode, "writetsp", usUser,
MakeSICSFunc(WriteTSP));
AddSICSHdbPar(cmd, "filename", usUser, MakeHdbText("Unknown"));
cmd =
AddSICSHdbPar(pNew->objectNode, "readtour", usUser,
MakeSICSFunc(ReadTour));
AddSICSHdbPar(cmd, "filename", usUser, MakeHdbText("Unknown"));
cmd =
AddSICSHdbPar(pNew->objectNode, "template", usMugger,