- Reworked the connection object and the IO system
- Reworked the support for TRICS - Added a second generation motor
This commit is contained in:
778
fourmess.c
Normal file
778
fourmess.c
Normal file
@ -0,0 +1,778 @@
|
||||
/**
|
||||
* This is a new version of the four circle reflection measurement module. Its task is
|
||||
* to provide functionality required for measuring a list of reflections. This is done
|
||||
* with the help of some scripts binding things together. This module provides:
|
||||
* - a table of scan parameters for measuring reflections at different angles.
|
||||
* - the functions required to produce the scan data files for single detector
|
||||
* mode.
|
||||
* - a list of reflections to measure.
|
||||
*
|
||||
* In contrast to the old mesure module, this only provides some help to
|
||||
* scripts. Thus, through scripts, a more flexible measurement is possible.
|
||||
*
|
||||
* copyright: see file COPYRIGHT
|
||||
*
|
||||
* Mark Koennecke, July 2008
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "singlex.h"
|
||||
#include "sicsobj.h"
|
||||
#include "fourtable.h"
|
||||
#include "sicshipadaba.h"
|
||||
#include "sicsvar.h"
|
||||
#include <sics.h>
|
||||
#include "scan.h"
|
||||
#include "stdscan.h"
|
||||
#include "evcontroller.h"
|
||||
#include "integrate.h"
|
||||
#include "sginfo.h"
|
||||
#include "matrix/matrix.h"
|
||||
#include "cell.h"
|
||||
#include "fourlib.h"
|
||||
|
||||
extern void SNXFormatTime(char *pBueffel, int iLen);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
FILE *profFile; /* file with reflection profiles, ccl */
|
||||
FILE *hklFile; /* file with integrated intensities */
|
||||
int stepTable; /* table with the scan parameters */
|
||||
char *currentFileRoot;
|
||||
pSICSOBJ messList;
|
||||
pHdb currentRefl; /* the current reflection being measured */
|
||||
int count;
|
||||
pScanData pScanner;
|
||||
int masterCount; /* the number of master reflection as craeted by indgen */
|
||||
}FourMess, *pFourMess;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void KillFourMess(void *data){
|
||||
pFourMess priv = (pFourMess)data;
|
||||
if(priv == NULL){
|
||||
return;
|
||||
}
|
||||
if(priv->profFile != NULL){
|
||||
fclose(priv->profFile);
|
||||
}
|
||||
if(priv->hklFile != NULL){
|
||||
fclose(priv->hklFile);
|
||||
}
|
||||
if(priv->currentFileRoot != NULL){
|
||||
free(priv->currentFileRoot);
|
||||
}
|
||||
if(priv->stepTable >= 0){
|
||||
DeleteFourCircleTable(priv->stepTable);
|
||||
}
|
||||
free(priv);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int FourMessAction(SConnection *pCon, SicsInterp *pSics,
|
||||
void *data, int argc, char *argv[]){
|
||||
pFourMess priv = NULL;
|
||||
pSICSOBJ self = (pSICSOBJ)data;
|
||||
int err, status;
|
||||
|
||||
assert(self != NULL);
|
||||
priv = self->pPrivate;
|
||||
assert(priv != NULL);
|
||||
|
||||
if(argc < 2){
|
||||
SCWrite(pCon,"ERROR: insufficient number of arguments to fmess",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(strcmp(argv[1],"table") == 0){
|
||||
return HandleFourCircleCommands(&priv->stepTable,pCon,
|
||||
argc,argv,&err);
|
||||
}
|
||||
|
||||
status = InvokeSICSOBJ(pCon,pSics,data,argc,argv);
|
||||
if(status < 0){
|
||||
SCPrintf(pCon,eError, "ERROR: %s no subcommand or parameter",
|
||||
argv[1]);
|
||||
return 0;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static int FourMessClose(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
pFourMess priv = NULL;
|
||||
|
||||
priv = self->pPrivate;
|
||||
if(priv->hklFile != NULL){
|
||||
fclose(priv->hklFile);
|
||||
priv->hklFile = NULL;
|
||||
}
|
||||
if(priv->profFile != NULL){
|
||||
fclose(priv->profFile);
|
||||
priv->profFile = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static int FourMessStart(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
pFourMess priv = NULL;
|
||||
char pFilename[512], pRoot[512];
|
||||
char pBueffel[1024];
|
||||
double lambda;
|
||||
const double *dUB;
|
||||
pSicsVariable pVar = NULL;
|
||||
char *pFile = NULL, *pPtr;
|
||||
FILE *temp = NULL;
|
||||
pHdb node;
|
||||
hdbValue v;
|
||||
|
||||
assert(self);
|
||||
assert(pCon);
|
||||
|
||||
priv = self->pPrivate;
|
||||
|
||||
if(nPar < 1){
|
||||
SCWrite(pCon,"ERROR: need file name parameter to start",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* close open files if so */
|
||||
if(priv->hklFile != NULL){
|
||||
FourMessClose(self,pCon,commandNode,par,nPar);
|
||||
}
|
||||
|
||||
/* create filename root */
|
||||
GetHipadabaPar(par[0],&v, pCon);
|
||||
pFile = strdup(v.v.text);
|
||||
pPtr = strrchr(pFile,(int)'.');
|
||||
pPtr++;
|
||||
*pPtr = '\0';
|
||||
if(priv->currentFileRoot != NULL){
|
||||
free(priv->currentFileRoot);
|
||||
}
|
||||
priv->currentFileRoot = strdup(pFile);
|
||||
free(pFile);
|
||||
strncpy(pRoot,priv->currentFileRoot,511);
|
||||
|
||||
|
||||
/* open the reflection file */
|
||||
sprintf(pBueffel,"Writing to %s.ccl, .rfl",pRoot);
|
||||
SCWrite(pCon,pBueffel,eValue);
|
||||
strcpy(pFilename,pRoot);
|
||||
strcat(pFilename,"ccl");
|
||||
priv->profFile = fopen(pFilename,"w");
|
||||
if(!priv->profFile){
|
||||
sprintf(pBueffel,"ERROR: SERIOUS TROUBLE: cannot open %s!",
|
||||
pFilename);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
node = GetHipadabaNode(self->objectNode,"template");
|
||||
assert(node != NULL);
|
||||
GetHipadabaPar(node,&v,pCon);
|
||||
temp = fopen(v.v.text,"r");
|
||||
if(temp == NULL)
|
||||
{
|
||||
SCWrite(pCon,"ERROR: failed to open header template",eError);
|
||||
}
|
||||
if(temp != NULL )
|
||||
{
|
||||
WriteTemplate(priv->profFile, temp, pFilename, NULL,
|
||||
pCon, pServ->pSics);
|
||||
fclose(temp);
|
||||
}
|
||||
|
||||
/* open hkl-data file */
|
||||
strcpy(pFilename,pRoot);
|
||||
strcat(pFilename,"rfl");
|
||||
priv->hklFile = fopen(pFilename,"w");
|
||||
if(!priv->hklFile){
|
||||
sprintf(pBueffel,"ERROR: SERIOUS TROUBLE: cannot open %s!",
|
||||
pFilename);
|
||||
SCWrite(pCon,pBueffel,eError);
|
||||
SCSetInterrupt(pCon,eAbortBatch);
|
||||
return 0;
|
||||
}
|
||||
fputs(pFilename,priv->hklFile);
|
||||
fputs("\n",priv->hklFile);
|
||||
|
||||
/* write some header data */
|
||||
SNXFormatTime(pBueffel,1024);
|
||||
fprintf(priv->hklFile,"filetime = %s\n",pBueffel);
|
||||
lambda = SXGetLambda();
|
||||
fprintf(priv->hklFile,"lambda = %f Angstroem\n",lambda);
|
||||
dUB = SXGetUB();
|
||||
fprintf(priv->hklFile,
|
||||
"UB = %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f\n",
|
||||
dUB[0], dUB[1],dUB[2],dUB[3],dUB[4],dUB[5],dUB[6],dUB[7],dUB[8]);
|
||||
|
||||
/* write sample & user info */
|
||||
strcpy(pBueffel,"CCL, Instr=TRICS, ");
|
||||
pVar = FindVariable(pServ->pSics,"sample");
|
||||
if(pVar){
|
||||
fprintf(priv->hklFile,"sample = %s\n",pVar->text);
|
||||
}
|
||||
pVar = FindVariable(pServ->pSics,"user");
|
||||
if(pVar){
|
||||
fprintf(priv->hklFile,"user = %s \n",pVar->text);
|
||||
}
|
||||
priv->count = 0;
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int FourMessScanPar(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
pFourMess priv = self->pPrivate;
|
||||
char *scanvar;
|
||||
double stt, dVal;
|
||||
int np, preset;
|
||||
pDynString data;
|
||||
|
||||
assert(priv != NULL);
|
||||
if(nPar < 1){
|
||||
SCWrite(pCon,"ERROR: need two theta parameter to scanpar", eError);
|
||||
return 0;
|
||||
}
|
||||
stt = par[0]->value.v.doubleValue;
|
||||
|
||||
scanvar = GetFourCircleScanVar(priv->stepTable,stt);
|
||||
dVal = GetFourCircleStep(priv->stepTable,stt);
|
||||
np = GetFourCircleScanNP(priv->stepTable,stt);
|
||||
preset = GetFourCirclePreset(priv->stepTable,stt);
|
||||
if(strcmp(scanvar,"NOT FOUND") == 0){
|
||||
SCPrintf(pCon,eValue,"%s,%f,%d,%d","om", dVal,np,preset);
|
||||
} else {
|
||||
SCPrintf(pCon,eValue,"%s,%f,%d,%d",scanvar,dVal,np,preset);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static hdbCallbackReturn SetScannerCB(pHdb node, void *userData,
|
||||
pHdbMessage mm){
|
||||
pHdbDataMessage set = NULL;
|
||||
pFourMess priv = (pFourMess)userData;
|
||||
SConnection *pCon = NULL;
|
||||
pScanData old;
|
||||
|
||||
if((set = GetHdbSetMessage(mm)) != NULL){
|
||||
old = priv->pScanner;
|
||||
priv->pScanner = FindCommandData(pServ->pSics,set->v->v.text,"ScanObject");
|
||||
if(priv->pScanner == NULL){
|
||||
priv->pScanner = old;
|
||||
pCon = set->callData;
|
||||
if(pCon != NULL){
|
||||
SCWrite(pCon,"ERROR: scan object not found", eError);
|
||||
}
|
||||
return hdbAbort;
|
||||
}
|
||||
}
|
||||
return hdbContinue;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static double getProtonAverage(pFourMess self){
|
||||
int np, i;
|
||||
long *lData = NULL, lSum = 0;
|
||||
|
||||
np = GetScanNP(self->pScanner);
|
||||
lData = (long *)malloc((np+1)*sizeof(long));
|
||||
if(lData == NULL || np == 0){
|
||||
return 0.;
|
||||
}
|
||||
memset(lData,0,(np+1)*sizeof(long));
|
||||
GetScanMonitor(self->pScanner,2,lData, np);
|
||||
for(i = 0; i < np; i++){
|
||||
lSum += lData[i];
|
||||
}
|
||||
free(lData);
|
||||
return (double)lSum/(double)np;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int FourMessStoreIntern(pSICSOBJ self, SConnection *pCon,
|
||||
double fHkl[3], double fPosition[4]){
|
||||
pFourMess priv = self->pPrivate;
|
||||
float fSum, fSigma, fTemp, fStep, fPreset;
|
||||
int i, iLF, iRet, iNP,ii;
|
||||
long *lCounts = NULL;
|
||||
pEVControl pEva = NULL;
|
||||
pDummy pPtr = NULL;
|
||||
pIDrivable pDriv = NULL;
|
||||
char pBueffel[512], pTime[512], pNum[10];
|
||||
double prot;
|
||||
|
||||
if(priv->pScanner == NULL){
|
||||
SCWrite(pCon,"ERROR: store: scan not configured", eLogError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(priv->hklFile == NULL){
|
||||
SCWrite(pCon,"ERROR: store: no files open", eLogError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* get necessary data */
|
||||
fSum = 0.;
|
||||
fSigma = 0.;
|
||||
iRet = ScanIntegrate(priv->pScanner,&fSum, &fSigma);
|
||||
if(iRet != 1){
|
||||
switch(iRet){
|
||||
case INTEGLEFT:
|
||||
sprintf(pBueffel,
|
||||
"WARNING: integration failed --> no left side to: %f %f %f",
|
||||
fHkl[0], fHkl[1],fHkl[2]);
|
||||
break;
|
||||
case INTEGRIGHT:
|
||||
sprintf(pBueffel,
|
||||
"WARNING: integration failed -->no right side to: %f %f %f",
|
||||
fHkl[0], fHkl[1],fHkl[2]);
|
||||
break;
|
||||
case INTEGNOPEAK:
|
||||
sprintf(pBueffel,
|
||||
"WARNING: integration failed -->no peak found: %f %f %f",
|
||||
fHkl[0], fHkl[1],fHkl[2]);
|
||||
break;
|
||||
case INTEGFUNNYBACK:
|
||||
sprintf(pBueffel,
|
||||
"WARNING: integration problem, asymmetric background: %f %f %f",
|
||||
fHkl[0], fHkl[1],fHkl[2]);
|
||||
break;
|
||||
}
|
||||
SCWrite(pCon,pBueffel,eLog);
|
||||
}
|
||||
iNP = GetScanNP(priv->pScanner);
|
||||
lCounts = malloc(iNP*sizeof(long));
|
||||
if(lCounts == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in store", eLogError);
|
||||
return 0;
|
||||
}
|
||||
GetScanCounts(priv->pScanner,lCounts,iNP);
|
||||
|
||||
/* write it */
|
||||
if(priv->profFile){
|
||||
fprintf(priv->profFile,"%4d %7.3f %7.3f %7.3f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
|
||||
priv->count, fHkl[0],fHkl[1],fHkl[2],
|
||||
fPosition[0], fPosition[1],
|
||||
fPosition[2], fPosition[3],
|
||||
fSum,fSigma);
|
||||
}
|
||||
if(priv->hklFile){
|
||||
fprintf(priv->hklFile,"%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
|
||||
priv->count, fHkl[0],fHkl[1],fHkl[2],
|
||||
fPosition[0], fPosition[1],
|
||||
fPosition[2],fPosition[3],
|
||||
fSum,fSigma);
|
||||
}
|
||||
sprintf(pBueffel,"%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n",
|
||||
priv->count, fHkl[0],fHkl[1],fHkl[2],
|
||||
fPosition[0], fPosition[1],
|
||||
fPosition[2], fPosition[3],
|
||||
fSum,fSigma);
|
||||
SCWrite(pCon,pBueffel,eLog);
|
||||
|
||||
/* get temperature */
|
||||
fTemp = -777.77;
|
||||
pEva = (pEVControl)FindCommandData(pServ->pSics,"temperature",
|
||||
"Environment Controller");
|
||||
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);
|
||||
}
|
||||
|
||||
/* write profile */
|
||||
if(priv->profFile){
|
||||
/* collect data */
|
||||
SNXFormatTime(pBueffel,512);
|
||||
GetScanVarStep(priv->pScanner,0,&fStep);
|
||||
fPreset = GetScanPreset(priv->pScanner);
|
||||
prot = getProtonAverage(priv);
|
||||
fprintf(priv->profFile,"%3d %7.4f %9.0f %7.3f %12f %s\n",iNP,fStep,
|
||||
fPreset,fTemp,prot, pBueffel);
|
||||
for(i = 0; i < iNP; i++){
|
||||
for(ii = 0; ii < 10 && i < iNP; ii++){
|
||||
fprintf(priv->profFile," %7ld",lCounts[i]);
|
||||
iLF = 1;
|
||||
i++;
|
||||
}
|
||||
fprintf(priv->profFile,"\n");
|
||||
i--;
|
||||
iLF = 0;
|
||||
}
|
||||
if(iLF){
|
||||
fprintf(priv->profFile,"\n");
|
||||
}
|
||||
fflush(priv->profFile);
|
||||
}
|
||||
|
||||
strcpy(pTime,pBueffel);
|
||||
sprintf(pBueffel,"%3d%8.4f%10.0f%8.3f %s\n",iNP,fStep,
|
||||
fPreset,fTemp,pTime);
|
||||
SCWrite(pCon,pBueffel,eLog);
|
||||
pBueffel[0] = '\0';
|
||||
for(i = 0; i < iNP; i++){
|
||||
for(ii = 0; ii < 10 && i < iNP; ii++){
|
||||
sprintf(pNum," %6ld",lCounts[i]);
|
||||
strcat(pBueffel,pNum);
|
||||
iLF = 1;
|
||||
i++;
|
||||
}
|
||||
SCWrite(pCon,pBueffel,eLog);
|
||||
pBueffel[0] = '\0';
|
||||
i--;
|
||||
iLF = 0;
|
||||
}
|
||||
if(iLF){
|
||||
SCWrite(pCon,pBueffel,eLog);
|
||||
}
|
||||
free(lCounts);
|
||||
return 1;
|
||||
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int FourMessStore(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
double fHkl[3], fPosition[4];
|
||||
int i;
|
||||
|
||||
if(nPar < 7) {
|
||||
SCWrite(pCon,"ERROR: not enough arguments for store",eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* load hkl */
|
||||
for(i = 0; i < 3; i++){
|
||||
fHkl[i] = par[i]->value.v.doubleValue;
|
||||
}
|
||||
|
||||
/* load positions */
|
||||
for(i = 0; i < 4; i++){
|
||||
fPosition[i] = par[i+3]->value.v.doubleValue;
|
||||
}
|
||||
|
||||
return FourMessStoreIntern(self, pCon,fHkl, fPosition);
|
||||
}
|
||||
/*------------------------------------------------------------------*/
|
||||
static int weakScan(pSICSOBJ self, SConnection *pCon){
|
||||
int i, np;
|
||||
long low = 99999, high = -99999, *lCounts = NULL;
|
||||
pFourMess priv = self->pPrivate;
|
||||
hdbValue v;
|
||||
|
||||
/*
|
||||
the scan is always OK if we do not test for weak conditions or we are in psd mode
|
||||
*/
|
||||
SICSHdbGetPar(self,pCon,"weak",&v);
|
||||
if(v.v.intValue == 0){
|
||||
return 0;
|
||||
}
|
||||
|
||||
np = GetScanNP(priv->pScanner);
|
||||
lCounts = malloc(np*sizeof(long));
|
||||
if(lCounts == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory in weakScan test", eLogError);
|
||||
return 0;
|
||||
}
|
||||
GetScanCounts(priv->pScanner,lCounts,np);
|
||||
for(i = 0; i < np; i++){
|
||||
if(lCounts[i] < low){
|
||||
low = lCounts[i];
|
||||
}
|
||||
if(lCounts[i] > high){
|
||||
high = lCounts[i];
|
||||
}
|
||||
}
|
||||
/*
|
||||
I am using the weakest point here as a rough estimate of
|
||||
the background
|
||||
*/
|
||||
SICSHdbGetPar(self,pCon,"weakthreshold",&v);
|
||||
if(high - 2 * low > v.v.intValue){
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int FourMessWeak(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
int weak;
|
||||
|
||||
weak = weakScan(self,pCon);
|
||||
SCPrintf(pCon,eLog,"weak = %d", weak);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int GenIndex(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
double lambda = SXGetLambda(), d, om, hkl[3];
|
||||
int h, k, l, minh, mink, minl, suppress;
|
||||
hdbValue hkllim, sttlim;
|
||||
T_SgInfo *sginfo = SXGetSpaceGroup();
|
||||
pFourMess priv = self->pPrivate;
|
||||
int count = 0;
|
||||
MATRIX B, H, Z1;
|
||||
const double *cell;
|
||||
lattice direct;
|
||||
|
||||
if(nPar < 1) {
|
||||
SCWrite(pCon,"ERROR: need a suppression flag for indgen",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
SICSHdbGetPar(self,pCon,"hkllim",&hkllim);
|
||||
SICSHdbGetPar(self,pCon,"sttlim",&sttlim);
|
||||
suppress = par[0]->value.v.intValue;
|
||||
|
||||
minh = hkllim.v.intArray[3];
|
||||
mink = hkllim.v.intArray[4];
|
||||
minl = hkllim.v.intArray[5];
|
||||
|
||||
SetListMin_hkl(sginfo,hkllim.v.intArray[1], hkllim.v.intArray[2],
|
||||
&minh, &mink, &minl);
|
||||
ClearReflectionList(priv->messList);
|
||||
cell = SXGetCell();
|
||||
direct.a = cell[0];
|
||||
direct.b = cell[1];
|
||||
direct.c = cell[2];
|
||||
direct.alpha = cell[3];
|
||||
direct.beta = cell[4];
|
||||
direct.gamma = cell[5];
|
||||
B = mat_creat(3,3,UNIT_MATRIX);
|
||||
if(!calculateBMatrix(direct,B)){
|
||||
SCWrite(pCon,"ERROR: invalid cell", eError);
|
||||
return 0;
|
||||
}
|
||||
H = mat_creat(3,1,ZERO_MATRIX);
|
||||
|
||||
|
||||
for(h = hkllim.v.intArray[0]; h < hkllim.v.intArray[3]; h++){
|
||||
for(k = hkllim.v.intArray[1]; k < hkllim.v.intArray[4]; k++){
|
||||
for(l = hkllim.v.intArray[2]; l < hkllim.v.intArray[5]; l++){
|
||||
/* first test: extinct */
|
||||
if(IsSysAbsent_hkl(sginfo,h,k,l,NULL) != 0 ){
|
||||
continue;
|
||||
}
|
||||
/* second test: a symmetrically equivalent already seen */
|
||||
if((suppress != 0) && IsSuppressed_hkl(sginfo,minh,mink,minl,
|
||||
hkllim.v.intArray[1],hkllim.v.intArray[2],h,k,l ) != 0){
|
||||
continue;
|
||||
}
|
||||
/* third test: within stt limits */
|
||||
H[0][0] = (double)h;
|
||||
H[1][0] = (double)k;
|
||||
H[2][0] = (double)l;
|
||||
Z1 = mat_mul(B,H);
|
||||
calcTheta(lambda,Z1,&d,&om);
|
||||
om *= 2.;
|
||||
mat_free(Z1);
|
||||
if(om > sttlim.v.floatArray[0] && om < sttlim.v.floatArray[1]){
|
||||
hkl[0] = (double)h;
|
||||
hkl[1] = (double)k;
|
||||
hkl[2] = (double)l;
|
||||
AddRefIdx(priv->messList,hkl);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mat_free(B);
|
||||
mat_free(H);
|
||||
priv->masterCount = count;
|
||||
SCPrintf(pCon,eValue,"%d reflections generated", count);
|
||||
return 1;
|
||||
}
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
static int GenInconsumerate(pSICSOBJ self, SConnection *pCon, pHdb commandNode,
|
||||
pHdb par[], int nPar){
|
||||
double hkl[3], qvec[3];
|
||||
pFourMess priv = self->pPrivate;
|
||||
int i, j;
|
||||
|
||||
if(nPar < 3) {
|
||||
SCWrite(pCon,
|
||||
"ERROR: need q displacement vector with three compononts",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
qvec[0] = par[0]->value.v.doubleValue;
|
||||
qvec[1] = par[1]->value.v.doubleValue;
|
||||
qvec[2] = par[2]->value.v.doubleValue;
|
||||
|
||||
for(i = 0; i < priv->masterCount; i++){
|
||||
GetRefIndex(priv->messList,i,hkl);
|
||||
for(j = 0; j < 3; j++){
|
||||
hkl[j] += qvec[j];
|
||||
}
|
||||
AddRefIdx(priv->messList, hkl);
|
||||
}
|
||||
SCPrintf(pCon,eValue,"%d additional inconsumerate reflections generated",
|
||||
priv->masterCount);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int hklCompare(const void *h1, const void *h2){
|
||||
const double *hkl1 = h1, *hkl2 = h2;
|
||||
|
||||
if(hkl1[3] < hkl2[3]){
|
||||
return -1;
|
||||
} else if (hkl1[3] == hkl2[3]) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
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;
|
||||
int nRefl, i, j;
|
||||
MATRIX B, H, Z1;
|
||||
lattice direct;
|
||||
pFourMess priv = self->pPrivate;
|
||||
|
||||
lambda = SXGetLambda();
|
||||
cell = SXGetCell();
|
||||
direct.a = cell[0];
|
||||
direct.b = cell[1];
|
||||
direct.c = cell[2];
|
||||
direct.alpha = cell[3];
|
||||
direct.beta = cell[4];
|
||||
direct.gamma = cell[5];
|
||||
B = mat_creat(3,3,UNIT_MATRIX);
|
||||
if(!calculateBMatrix(direct,B)){
|
||||
SCWrite(pCon,"ERROR: invalid cell", eError);
|
||||
return 0;
|
||||
}
|
||||
H = mat_creat(3,1,ZERO_MATRIX);
|
||||
|
||||
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 theta value to sort for! */
|
||||
for(i = 0; i < nRefl; i++){
|
||||
GetRefIndex(priv->messList,i,hkl);
|
||||
for(j = 0; j < 3; j++){
|
||||
H[j][0] = hkl[j];
|
||||
}
|
||||
Z1 = mat_mul(B,H);
|
||||
calcTheta(lambda,Z1,&d, &om);
|
||||
mat_free(Z1);
|
||||
hkl[3] = om;
|
||||
memcpy(sortlist + i*4, hkl, 4*sizeof(double));
|
||||
}
|
||||
|
||||
qsort(sortlist,nRefl,4*sizeof(double),hklCompare);
|
||||
|
||||
ClearReflectionList(priv->messList);
|
||||
for(i = 0; i < nRefl; i++){
|
||||
ang[1] = sortlist[i*4+3];
|
||||
ang[0] = 2.*ang[1];
|
||||
ang[2] = .0;
|
||||
ang[3] = .0;
|
||||
/* AddRefIdxAng(priv->messList, sortlist+i*4,ang); */
|
||||
AddRefIdx(priv->messList, sortlist+i*4);
|
||||
}
|
||||
free(sortlist);
|
||||
mat_free(B);
|
||||
mat_free(H);
|
||||
SCSendOK(pCon);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int FourMessSave(void *data, char *name, FILE *fd){
|
||||
pSICSOBJ self = data;
|
||||
pFourMess priv = self->pPrivate;
|
||||
|
||||
SaveSICSOBJ(data,name,fd);
|
||||
SaveFourCircleTable(priv->stepTable, name, fd);
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void InstallFourMess(SConnection *pCon, SicsInterp *pSics){
|
||||
pFourMess priv = NULL;
|
||||
pSICSOBJ pNew = NULL;
|
||||
pHdb cmd = NULL;
|
||||
int hkl[] = {-10,-10,10,10,10,10};
|
||||
double sttlim[] = {5.0, 180};
|
||||
|
||||
pNew = MakeSICSOBJ("fmess","FourMess");
|
||||
priv = calloc(1,sizeof(FourMess));
|
||||
if(pNew == NULL || priv == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating fourmess", eError);
|
||||
}
|
||||
pNew->pDes->SaveStatus = FourMessSave;
|
||||
pNew->pPrivate = priv;
|
||||
pNew->KillPrivate = KillFourMess;
|
||||
|
||||
priv->stepTable = MakeFourCircleTable();
|
||||
priv->messList = CreateReflectionList(pCon,pSics,"messref");
|
||||
if(priv->stepTable < 0 || priv->messList == NULL){
|
||||
SCWrite(pCon,"ERROR: out of memory creating fourmess", eError);
|
||||
}
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"weak", usUser, MakeHdbInt(0));
|
||||
SetHdbProperty(cmd,"__save","true");
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"weakthreshold", usUser,
|
||||
MakeHdbInt(20));
|
||||
SetHdbProperty(cmd,"__save","true");
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"mode", usUser, MakeHdbText("Monitor"));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"hkllim", usUser, MakeHdbIntArray(6,hkl));
|
||||
SetHdbProperty(cmd,"__save","true");
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"sttlim", usUser, MakeHdbFloatArray(2,sttlim));
|
||||
SetHdbProperty(cmd,"__save","true");
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"start", usUser, MakeSICSFunc(FourMessStart));
|
||||
cmd = AddSICSHdbPar(cmd,"filename", usUser, MakeHdbText("Unknown"));
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"close", usUser, MakeSICSFunc(FourMessClose));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"scanpar", usUser, MakeSICSFunc(FourMessScanPar));
|
||||
cmd = AddSICSHdbPar(cmd,"twotheta", usUser, MakeHdbFloat(.0));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"store", usUser, MakeSICSFunc(FourMessStore));
|
||||
AddSICSHdbPar(cmd,"h", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"k", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"l", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"stt", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"om", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"chi", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"phi", usUser, MakeHdbFloat(.0));
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"weak", usUser, MakeSICSFunc(FourMessWeak));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"indgen", usUser, MakeSICSFunc(GenIndex));
|
||||
AddSICSHdbPar(cmd,"sup", usUser, MakeHdbInt(1));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"genw", usUser, MakeSICSFunc(GenInconsumerate));
|
||||
AddSICSHdbPar(cmd,"hw", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"kw", usUser, MakeHdbFloat(.0));
|
||||
AddSICSHdbPar(cmd,"lw", usUser, MakeHdbFloat(.0));
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"indsort", usUser, MakeSICSFunc(SortRef));
|
||||
|
||||
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"template", usMugger, MakeHdbText("Unknown"));
|
||||
cmd = AddSICSHdbPar(pNew->objectNode,"scanobj", usMugger, MakeHdbText("xxxscan"));
|
||||
PrependHipadabaCallback(cmd,
|
||||
MakeHipadabaCallback(SetScannerCB, priv,NULL));
|
||||
|
||||
priv->pScanner = FindCommandData(pSics,"xxxscan","ScanObject");
|
||||
|
||||
AddCommand(pSics,
|
||||
"fmess",
|
||||
FourMessAction,
|
||||
KillSICSOBJ,
|
||||
pNew);
|
||||
}
|
||||
|
Reference in New Issue
Block a user