- Removed -fwritable-string
SKIPPED: psi/dornier2.c psi/ecbdriv.c psi/el734hp.c psi/libpsi.a psi/make_gen psi/makefile_linux psi/pimotor.c psi/pipiezo.c psi/sinqhttp.c psi/tcpdornier.c psi/velodornier.c
This commit is contained in:
@ -1006,6 +1006,7 @@ static void freeList(int listID)
|
|||||||
} while(0!=LLDnodePtr2First(listID));
|
} while(0!=LLDnodePtr2First(listID));
|
||||||
LLDdelete(listID);
|
LLDdelete(listID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
void RemoveStartupCommands(void)
|
void RemoveStartupCommands(void)
|
||||||
{
|
{
|
||||||
|
@ -192,9 +192,12 @@ int StartLevel(int level, int sequenceList, int motorList, SConnection *pCon){
|
|||||||
pMot = FindMotEntry(motorList,seq.pMotor);
|
pMot = FindMotEntry(motorList,seq.pMotor);
|
||||||
if(pMot){
|
if(pMot){
|
||||||
status = StartRegMot(pMot,pCon,seq.target);
|
status = StartRegMot(pMot,pCon,seq.target);
|
||||||
if(status){
|
/*
|
||||||
|
* I have to ignore the problem here: if I do not increment the count
|
||||||
|
* all the other levels will not be drive and the anticollider
|
||||||
|
* gets into a mess
|
||||||
|
*/
|
||||||
count++;
|
count++;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
sprintf(pBueffel,"ERROR: motor %s, requested from anticollider script",
|
sprintf(pBueffel,"ERROR: motor %s, requested from anticollider script",
|
||||||
seq.pMotor);
|
seq.pMotor);
|
||||||
|
@ -114,6 +114,9 @@ managed through the lld functions as everywhere within SICS.
|
|||||||
pMotReg FindMotFromDataStructure(int iList, void *pData);
|
pMotReg FindMotFromDataStructure(int iList, void *pData);
|
||||||
int CheckAllMotors(int iList, SConnection *pCon);
|
int CheckAllMotors(int iList, SConnection *pCon);
|
||||||
void KillMotList(int iList);
|
void KillMotList(int iList);
|
||||||
|
void StopAllMotors(int iList);
|
||||||
|
void DeactivateAllMotors(int iList);
|
||||||
|
|
||||||
@}
|
@}
|
||||||
The functions:
|
The functions:
|
||||||
\begin{description}
|
\begin{description}
|
||||||
|
356
cone.c
Normal file
356
cone.c
Normal file
@ -0,0 +1,356 @@
|
|||||||
|
/*----------------------------------------------------------------------
|
||||||
|
SICS cone module for cone scans. Form more details see conescan.tex
|
||||||
|
and cone.tex.
|
||||||
|
|
||||||
|
COPYRIGHT: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, March 2006
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "cone.h"
|
||||||
|
#include "hkl.i"
|
||||||
|
#include "vector.h"
|
||||||
|
#include "fourlib.h"
|
||||||
|
/*=================== Object Descriptor Interface ===================================================*/
|
||||||
|
static void *ConeGetInterface(void *pData, int iID){
|
||||||
|
pConeData self = NULL;
|
||||||
|
|
||||||
|
self = (pConeData)pData;
|
||||||
|
if(self == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(iID == DRIVEID){
|
||||||
|
return self->pDriv;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------------------------------*/
|
||||||
|
static void ConeSaveStatus(void *data, char *name, FILE *fd){
|
||||||
|
pConeData self = (pConeData)data;
|
||||||
|
if(self == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fprintf(fd,"%s center %d\n", name,self->center);
|
||||||
|
fprintf(fd,"%s target %f %f %f\n", name, self->target.h,
|
||||||
|
self->target.k, self->target.l);
|
||||||
|
}
|
||||||
|
/*=================== Drivable Interface ============================================================*/
|
||||||
|
static int ConeHalt(void *pData){
|
||||||
|
pConeData self = NULL;
|
||||||
|
|
||||||
|
self = (pConeData)pData;
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
self->pHkl->pTheta->pDrivInt->Halt(self->pHkl->pTheta);
|
||||||
|
self->pHkl->pOmega->pDrivInt->Halt(self->pHkl->pOmega);
|
||||||
|
self->pHkl->pChi->pDrivInt->Halt(self->pHkl->pChi);
|
||||||
|
self->pHkl->pPhi->pDrivInt->Halt(self->pHkl->pPhi);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------------------------*/
|
||||||
|
static int ConeCheckLimits(void *self, float fVal, char *error, int errLen){
|
||||||
|
/*
|
||||||
|
There is no meaningful implementation here. This gets called when starting the motor.
|
||||||
|
At that stage not all other values may be known. If the calculation fails, this will die
|
||||||
|
at status check time.
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static MATRIX makeCsToPsiMatrix(reflection center, double lambda){
|
||||||
|
MATRIX psiToCs = NULL, csToPsi = NULL, t1, t2;
|
||||||
|
double z1[3], u;
|
||||||
|
|
||||||
|
psiToCs = makeInstToConeVectorMatrix(center,lambda);
|
||||||
|
if(psiToCs == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
csToPsi = mat_inv(psiToCs);
|
||||||
|
/*
|
||||||
|
* this is debugging code: remove together with variables
|
||||||
|
*/
|
||||||
|
z1FromAngles(lambda,center.s2t,center.om,center.chi,center.phi,z1);
|
||||||
|
t1 = makeVectorInit(z1);
|
||||||
|
t2 = mat_mul(psiToCs,t1);
|
||||||
|
normalizeVector(t2);
|
||||||
|
t1[0][0] = .0;
|
||||||
|
t1[1][0] = .0;
|
||||||
|
t1[2][0] = 1.;
|
||||||
|
u = angleBetween(t1,t2);
|
||||||
|
|
||||||
|
mat_free(psiToCs);
|
||||||
|
return csToPsi;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------------------------------
|
||||||
|
* I am lazy in this function: I calculate anew from all the data. This saves
|
||||||
|
* me a lot of trouble keeping track of parameter changes in UBCALC etc.
|
||||||
|
* ---------------------------------------------------------------------------*/
|
||||||
|
static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
|
||||||
|
pConeData self = NULL;
|
||||||
|
float fSet[4];
|
||||||
|
double openingAngle, length, testAngle;
|
||||||
|
MATRIX csToPsi = NULL, B = NULL, newScat = NULL, cent;
|
||||||
|
int status;
|
||||||
|
reflection center;
|
||||||
|
char buffer[131];
|
||||||
|
double z1[3];
|
||||||
|
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
self = (pConeData)pData;
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate opening angle
|
||||||
|
*/
|
||||||
|
B = mat_creat(3,3,UNIT_MATRIX);
|
||||||
|
status = calculateBMatrix(self->ubi->direct,B);
|
||||||
|
if(status < 0){
|
||||||
|
SCWrite(pCon,"ERROR: cell has no volume",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
center = getReflection(self->ubi,self->center);
|
||||||
|
openingAngle = angleBetweenReflections(B,center,self->target);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate conversion matrix from cone system to PSI system
|
||||||
|
*/
|
||||||
|
csToPsi = makeCsToPsiMatrix(center,self->ubi->hkl->fLambda);
|
||||||
|
if(csToPsi == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: bad parameters: failed to generate conversion matrix",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* calculate scattering vector on cone and make its length
|
||||||
|
* match the length of the apropriate scattering vector
|
||||||
|
*/
|
||||||
|
length = scatteringVectorLength(B,self->target);
|
||||||
|
newScat = calcConeVector(openingAngle, fVal, length, csToPsi);
|
||||||
|
if(newScat == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: fails to calculate cone vector",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* this is debugging code
|
||||||
|
*/
|
||||||
|
length = vectorLength(newScat);
|
||||||
|
z1FromAngles(self->ubi->hkl->fLambda,center.s2t,center.om,center.chi,
|
||||||
|
center.phi,z1);
|
||||||
|
cent = makeVectorInit(z1);
|
||||||
|
testAngle = angleBetween(cent,newScat);
|
||||||
|
snprintf(buffer,131,"OpeningAngle = %f, testAngle = %f, length = %f",
|
||||||
|
openingAngle,testAngle,length);
|
||||||
|
SCWrite(pCon,buffer,eWarning);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* try to find setting angles for this vector
|
||||||
|
*/
|
||||||
|
status = findAllowedBisecting(self->pHkl->fLambda,newScat, fSet,
|
||||||
|
hklInRange, self->pHkl);
|
||||||
|
/*
|
||||||
|
* clean up matrices
|
||||||
|
*/
|
||||||
|
mat_free(B);
|
||||||
|
mat_free(newScat);
|
||||||
|
mat_free(csToPsi);
|
||||||
|
if(status != 1){
|
||||||
|
SCWrite(pCon,"ERROR: cannot get cone vector into scattering position",
|
||||||
|
eError);
|
||||||
|
SCSetInterrupt(pCon,eAbortOperation);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->lastConeAngle = fVal;
|
||||||
|
/*
|
||||||
|
* start motors
|
||||||
|
*/
|
||||||
|
return startHKLMotors(self->pHkl, pCon,fSet);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------------------------------*/
|
||||||
|
static int checkMotors(pConeData self, SConnection *pCon){
|
||||||
|
int status;
|
||||||
|
|
||||||
|
status = self->pHkl->pTheta->pDrivInt->CheckStatus(self->pHkl->pTheta, pCon);
|
||||||
|
if(status != HWIdle && status != OKOK){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
status = self->pHkl->pOmega->pDrivInt->CheckStatus(self->pHkl->pOmega, pCon);
|
||||||
|
if(status != HWIdle && status != OKOK){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
status = self->pHkl->pChi->pDrivInt->CheckStatus(self->pHkl->pChi, pCon);
|
||||||
|
if(status != HWIdle && status != OKOK){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
status = self->pHkl->pPhi->pDrivInt->CheckStatus(self->pHkl->pPhi, pCon);
|
||||||
|
if(status != HWIdle && status != OKOK){
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
return HWIdle;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------------------------*/
|
||||||
|
static int ConeCheckStatus(void *pData, SConnection *pCon){
|
||||||
|
pConeData self = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
self = (pConeData)pData;
|
||||||
|
assert(self != NULL);
|
||||||
|
return checkMotors(self,pCon);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------------------------*/
|
||||||
|
static float ConeGetValue(void *pData, SConnection *pCon){
|
||||||
|
pConeData self = NULL;
|
||||||
|
float fVal[3];
|
||||||
|
int status;
|
||||||
|
|
||||||
|
self = (pConeData)pData;
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
return self->lastConeAngle;
|
||||||
|
}
|
||||||
|
/*=============================== Live and Death ====================================*/
|
||||||
|
static pConeData MakeConeMot(pUBCALC u){
|
||||||
|
pConeData self = NULL;
|
||||||
|
|
||||||
|
assert(u != NULL);
|
||||||
|
|
||||||
|
self = (pConeData)malloc(sizeof(coneData));
|
||||||
|
if(self == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(self,0,sizeof(coneData));
|
||||||
|
self->pDes = CreateDescriptor("Cone");
|
||||||
|
self->pDriv = CreateDrivableInterface();
|
||||||
|
if(self->pDes == NULL || self->pDriv == NULL){
|
||||||
|
free(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
self->pDes->GetInterface = ConeGetInterface;
|
||||||
|
self->pDriv->Halt = ConeHalt;
|
||||||
|
self->pDriv->CheckLimits = ConeCheckLimits;
|
||||||
|
self->pDriv->SetValue = ConeSetValue;
|
||||||
|
self->pDriv->CheckStatus = ConeCheckStatus;
|
||||||
|
self->pDriv->GetValue = ConeGetValue;
|
||||||
|
self->ubi = u;
|
||||||
|
self->pHkl = u->hkl;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------------------*/
|
||||||
|
static void KillConeMot(void *pData){
|
||||||
|
pConeData self = NULL;
|
||||||
|
|
||||||
|
self = (pConeData)pData;
|
||||||
|
if(self == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(self->pDes != NULL){
|
||||||
|
DeleteDescriptor(self->pDes);
|
||||||
|
}
|
||||||
|
if(self->pDriv){
|
||||||
|
free(self->pDriv);
|
||||||
|
}
|
||||||
|
free(self);
|
||||||
|
}
|
||||||
|
/*=============================== Interpreter Interface ============================*/
|
||||||
|
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
|
||||||
|
pConeData self = NULL;
|
||||||
|
float value;
|
||||||
|
int id;
|
||||||
|
char pBuffer[132];
|
||||||
|
|
||||||
|
self = (pConeData)pData;
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
if(argc > 1) {
|
||||||
|
strtolower(argv[1]);
|
||||||
|
if(strcmp(argv[1],"center") == 0){
|
||||||
|
if(argc > 2){
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
id = atoi(argv[2]);
|
||||||
|
if(id < 0 || id > 2 ){
|
||||||
|
SCWrite(pCon,"ERROR: id must be between 0 - 3",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->center = id;
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBuffer,131,"%s.center = %d", argv[0], self->center);
|
||||||
|
SCWrite(pCon,pBuffer,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[1],"target") == 0){
|
||||||
|
if(argc >= 5){
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->target.h = atof(argv[2]);
|
||||||
|
self->target.k = atof(argv[3]);
|
||||||
|
self->target.l = atof(argv[4]);
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBuffer,131,"%s.target = %f %f %f", argv[0],
|
||||||
|
self->target.h, self->target.k, self->target.l);
|
||||||
|
SCWrite(pCon,pBuffer,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SCWrite(pCon,"ERROR: subcommand to cone not known",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* default: print value
|
||||||
|
*/
|
||||||
|
value = self->pDriv->GetValue(self,pCon);
|
||||||
|
if(value < -9000.){
|
||||||
|
snprintf(pBuffer,131,"ERROR: failed to read %s",argv[0]);
|
||||||
|
SCWrite(pCon,pBuffer,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
snprintf(pBuffer,131,"%s = %f", argv[0], value);
|
||||||
|
SCWrite(pCon,pBuffer,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------------------------*/
|
||||||
|
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
|
||||||
|
pUBCALC ubi = NULL;
|
||||||
|
pConeData pMot = NULL;
|
||||||
|
char pBuffer[131];
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if(argc < 3){
|
||||||
|
SCWrite(pCon,"ERROR: insuffient number of arguments to MakeCone",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ubi = FindCommandData(pSics,argv[2],"UBcalc");
|
||||||
|
if(ubi == NULL){
|
||||||
|
snprintf(pBuffer,131,"ERROR: %s is no UBcalc object" , argv[2]);
|
||||||
|
SCWrite(pCon,pBuffer,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMot = MakeConeMot(ubi);
|
||||||
|
if(pMot == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory creating cone virtual motor",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = AddCommand(pSics,argv[1],ConeAction,KillConeMot,pMot);
|
||||||
|
if(status != 1){
|
||||||
|
SCWrite(pCon,"ERROR: failed to create duplicate cone motor",eError);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
|
||||||
|
}
|
32
cone.h
Normal file
32
cone.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
SICS cone module for cone scans. Form more details see conescan.tex
|
||||||
|
and cone.tex.
|
||||||
|
|
||||||
|
COPYRIGHT: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, March 2006
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSCONE
|
||||||
|
#define SICSCONE
|
||||||
|
#include "sics.h"
|
||||||
|
#include "ubcalc.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pIDrivable pDriv;
|
||||||
|
reflection target;
|
||||||
|
float lastConeAngle;
|
||||||
|
pUBCALC ubi;
|
||||||
|
int center;
|
||||||
|
pHKL pHkl;
|
||||||
|
} coneData, *pConeData;
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
#endif
|
64
cone.w
Normal file
64
cone.w
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
\subsection{Cone}
|
||||||
|
This module is a virtual motor for driving on a cone around a give center reflection.
|
||||||
|
The application is in four circle diffractometry. Consider, a reflection has been
|
||||||
|
found and indexed. If the cell parameters are known, we now know that at a certain
|
||||||
|
two theta and at a certain agle around the first reflection there should be
|
||||||
|
another one. Serching this cone would speed up UB matrix determination. Driving on such
|
||||||
|
a cone and therewith scanning it is implemented in this module.
|
||||||
|
|
||||||
|
The math for doing this is detailed in a separate internal paper: conescan.tex.
|
||||||
|
For its implementation, cone works very closely with the UBCALC module. UBCALC
|
||||||
|
provides the cell constants and it also provides the list of reflections from
|
||||||
|
which to get the center reflection of the cone.
|
||||||
|
|
||||||
|
The module requires a data structure:
|
||||||
|
@d conedat @{
|
||||||
|
typedef struct {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pIDrivable pDriv;
|
||||||
|
reflection target;
|
||||||
|
float lastConeAngle;
|
||||||
|
pUBCALC ubi;
|
||||||
|
int center;
|
||||||
|
pHKL pHkl;
|
||||||
|
} coneData, *pConeData;
|
||||||
|
@}
|
||||||
|
The fields are:
|
||||||
|
\begin{description}
|
||||||
|
\item[pDes] The standard object descriptor
|
||||||
|
\item[pDriv] The drivable interface which implements most of this modules
|
||||||
|
functionality.
|
||||||
|
\item[target] The target reflection of the cone. This determines the length
|
||||||
|
of the scattering vector and the opening angle of the cone.
|
||||||
|
\item[ubi] A pointer to the UBCALC module which holds things like lattice constants.
|
||||||
|
\item[center] The reflection number in UBCALCS reflection list to use as the
|
||||||
|
center of the cone.
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
The external interface to cone is mostly defined by the drivable interface. In
|
||||||
|
addition there are only the usal interpreter interface functions to install and
|
||||||
|
configure cone.
|
||||||
|
|
||||||
|
@o cone.h @{
|
||||||
|
/*----------------------------------------------------------------------
|
||||||
|
SICS cone module for cone scans. Form more details see conescan.tex
|
||||||
|
and cone.tex.
|
||||||
|
|
||||||
|
COPYRIGHT: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, March 2006
|
||||||
|
------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSCONE
|
||||||
|
#define SICSCONE
|
||||||
|
#include "sics.h"
|
||||||
|
#include "ubcalc.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
@<conedat@>
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
#endif
|
||||||
|
@}
|
44
devexec.c
44
devexec.c
@ -105,6 +105,7 @@
|
|||||||
int iStop;
|
int iStop;
|
||||||
int iStatus;
|
int iStatus;
|
||||||
int iEnd;
|
int iEnd;
|
||||||
|
int drivePrint;
|
||||||
long lTask;
|
long lTask;
|
||||||
pTaskMan pTask;
|
pTaskMan pTask;
|
||||||
int iLock;
|
int iLock;
|
||||||
@ -144,6 +145,7 @@
|
|||||||
pRes->pTask = pTask;
|
pRes->pTask = pTask;
|
||||||
pRes->lTask = -1;
|
pRes->lTask = -1;
|
||||||
pRes->iLock = 0;
|
pRes->iLock = 0;
|
||||||
|
pRes->drivePrint = 0;
|
||||||
pRes->pCall = CreateCallBackInterface();
|
pRes->pCall = CreateCallBackInterface();
|
||||||
pRes->lastRun = time(NULL);
|
pRes->lastRun = time(NULL);
|
||||||
return pRes;
|
return pRes;
|
||||||
@ -187,6 +189,7 @@
|
|||||||
pICountable pCountInt = NULL;
|
pICountable pCountInt = NULL;
|
||||||
static int overwriteOwner = -1;
|
static int overwriteOwner = -1;
|
||||||
char *overwriteOption;
|
char *overwriteOption;
|
||||||
|
float oldVal;
|
||||||
|
|
||||||
assert(self);
|
assert(self);
|
||||||
assert(pDes);
|
assert(pDes);
|
||||||
@ -239,6 +242,13 @@
|
|||||||
if(pDrivInt)
|
if(pDrivInt)
|
||||||
{
|
{
|
||||||
iRet = pDrivInt->SetValue(pData,pCon,fNew);
|
iRet = pDrivInt->SetValue(pData,pCon,fNew);
|
||||||
|
if(iRet == OKOK && self->drivePrint == 1)
|
||||||
|
{
|
||||||
|
oldVal = pDrivInt->GetValue(pData,pCon);
|
||||||
|
snprintf(pBueffel,131,"Driving %s from %8.3f to %8.3f",
|
||||||
|
name, oldVal, fNew);
|
||||||
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(pCountInt)
|
else if(pCountInt)
|
||||||
{
|
{
|
||||||
@ -289,6 +299,7 @@
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
|
||||||
char *name, float fVal)
|
char *name, float fVal)
|
||||||
@ -988,6 +999,39 @@
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
char pBueffel[256];
|
||||||
|
|
||||||
|
pExeList self = (pExeList)pData;
|
||||||
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: not enough argumentd to devexec command",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strtolower(argv[1]);
|
||||||
|
if(strcmp(argv[1],"driveprint") == 0)
|
||||||
|
{
|
||||||
|
if(argc > 2 && SCMatchRights(pCon,usUser))
|
||||||
|
{
|
||||||
|
val = atoi(argv[2]);
|
||||||
|
self->drivePrint = val;
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,255,"devexe.drivePrint = %d",
|
||||||
|
self->drivePrint);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SCWrite(pCon,"ERROR: unknown subcommand to devexec",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int ContinueAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int ContinueAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
|
@ -152,7 +152,11 @@
|
|||||||
/*
|
/*
|
||||||
continues execution
|
continues execution
|
||||||
*/
|
*/
|
||||||
|
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
/*
|
||||||
|
* various commands
|
||||||
|
*/
|
||||||
/*--------------------------- Locking ---------------------------------*/
|
/*--------------------------- Locking ---------------------------------*/
|
||||||
|
|
||||||
#line 183 "devexec.w"
|
#line 183 "devexec.w"
|
||||||
|
42
fourlib.c
42
fourlib.c
@ -198,7 +198,7 @@ void pol2det(psdDescription *psd, double gamma, double nu, int *x, int *y){
|
|||||||
turn chi and phi in order to get Z1 into the equatorial plane
|
turn chi and phi in order to get Z1 into the equatorial plane
|
||||||
*/
|
*/
|
||||||
static void turnEquatorial(MATRIX z1, double *chi, double *phi){
|
static void turnEquatorial(MATRIX z1, double *chi, double *phi){
|
||||||
if(ABS(z1[0][0]) < .0001 || ABS(z1[1][0]) < .0001){
|
if(ABS(z1[0][0]) < .0001 && ABS(z1[1][0]) < .00001){
|
||||||
*phi = .0;
|
*phi = .0;
|
||||||
*chi = 90.;
|
*chi = 90.;
|
||||||
if(z1[2][0] < .0){
|
if(z1[2][0] < .0){
|
||||||
@ -607,6 +607,46 @@ void z1FromAllAngles(double lambda, double omega , double gamma,
|
|||||||
z1fromz3(z1,z3,chi,phi);
|
z1fromz3(z1,z3,chi,phi);
|
||||||
mat_free(z3);
|
mat_free(z3);
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
int findAllowedBisecting(double lambda, MATRIX z1, float fSet[4],
|
||||||
|
inRange testFunc, void *userData){
|
||||||
|
int status, i, mask[4];
|
||||||
|
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi;
|
||||||
|
float fTest[4];
|
||||||
|
|
||||||
|
status = z1mToBisecting(lambda,z1, &stt, &om, &chi, &phi);
|
||||||
|
chi = circlify(chi);
|
||||||
|
phi = circlify(phi);
|
||||||
|
fSet[0] = stt;
|
||||||
|
fSet[1] = om;
|
||||||
|
fSet[2] = chi;
|
||||||
|
fSet[3] = phi;
|
||||||
|
if(status != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(psi = .0; psi < 360.; psi += .5){
|
||||||
|
rotatePsi(om,chi,phi,psi,&ompsi,&chipsi,&phipsi);
|
||||||
|
fTest[0] = stt;
|
||||||
|
fTest[1] = ompsi;
|
||||||
|
fTest[2] = circlify(chipsi);
|
||||||
|
fTest[3] = circlify(phipsi);
|
||||||
|
status = testFunc(userData,fTest,mask);
|
||||||
|
if(status == 1){
|
||||||
|
for(i = 0; i < 4; i++){
|
||||||
|
fSet[i] = fTest[i];
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if(mask[0] == 0) {
|
||||||
|
/*
|
||||||
|
* useless: when two theta problem there is no solution
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/*------------------- a test program ------------------------------------*/
|
/*------------------- a test program ------------------------------------*/
|
||||||
#ifdef TESTCODE
|
#ifdef TESTCODE
|
||||||
int main(int argc, char *argv[]){
|
int main(int argc, char *argv[]){
|
||||||
|
19
fourlib.h
19
fourlib.h
@ -172,6 +172,25 @@ void phimat(MATRIX phim, double phi);
|
|||||||
*/
|
*/
|
||||||
int calcTheta(double lambda, MATRIX z1, double *d, double *theta);
|
int calcTheta(double lambda, MATRIX z1, double *d, double *theta);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* try very hard to calculate settings for the bisecting position
|
||||||
|
* within the instruments limits. Tries to tweak omega and to rotate
|
||||||
|
* psi until a usable position can be found.
|
||||||
|
* @param lambda The wavelength
|
||||||
|
* @param z1 The scattering for which to find a position
|
||||||
|
* @param fSet The output setting angles. In case of a failure this
|
||||||
|
* contains the normal setting angles for psi = 0. The order is:
|
||||||
|
* 2 theta, om, chi, phi
|
||||||
|
* @testFunc A user supplied function which test if the setting angles
|
||||||
|
* are in range.
|
||||||
|
* @param userData A user specified pointer to some data which may be needed
|
||||||
|
* in testing the range.
|
||||||
|
* @return 0 on failure, 1 on success.
|
||||||
|
*/
|
||||||
|
typedef int (*inRange)(void *userData, float dSet[4], int mask[4]);
|
||||||
|
int findAllowedBisecting(double lambda, MATRIX z1, float fSet[4],
|
||||||
|
inRange testFunc, void *userData);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
117
hkl.c
117
hkl.c
@ -597,7 +597,7 @@ static MATRIX calculateScatteringVector(pHKL self, float fHKL[3])
|
|||||||
return z1;
|
return z1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon,
|
static int calculateBisectingOld(MATRIX z1, pHKL self, SConnection *pCon,
|
||||||
float fSet[4], double myPsi, int iRetry)
|
float fSet[4], double myPsi, int iRetry)
|
||||||
{
|
{
|
||||||
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi;
|
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi;
|
||||||
@ -674,6 +674,74 @@ static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int hklInRange(void *data, float fSet[4], int mask[4])
|
||||||
|
{
|
||||||
|
pHKL self = (pHKL)data;
|
||||||
|
float fHard, fLimit;
|
||||||
|
char pError[132];
|
||||||
|
int i, test;
|
||||||
|
double dTheta;
|
||||||
|
|
||||||
|
/* check two theta */
|
||||||
|
dTheta = fSet[0];
|
||||||
|
mask[0] = checkTheta(self, &dTheta);
|
||||||
|
fSet[0] = dTheta;
|
||||||
|
|
||||||
|
/* for omega check against the limits +- SCANBORDER in order to allow for
|
||||||
|
a omega scan
|
||||||
|
*/
|
||||||
|
MotorGetPar(self->pOmega,"softlowerlim",&fLimit);
|
||||||
|
if((float)fSet[1] < fLimit + self->scanTolerance){
|
||||||
|
mask[1] = 0;
|
||||||
|
} else {
|
||||||
|
mask[1] = 1;
|
||||||
|
MotorGetPar(self->pOmega,"softupperlim",&fLimit);
|
||||||
|
if((float)fSet[1] > fLimit - self->scanTolerance){
|
||||||
|
mask[1] = 0;
|
||||||
|
} else {
|
||||||
|
mask[1] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check chi and phi*/
|
||||||
|
mask[2] = MotorCheckBoundary(self->pChi,fSet[2], &fHard,pError,131);
|
||||||
|
mask[3] = MotorCheckBoundary(self->pPhi,fSet[3], &fHard,pError,131);
|
||||||
|
for(i = 0, test = 0; i < 4; i++){
|
||||||
|
test += mask[i];
|
||||||
|
}
|
||||||
|
if(test != 4) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
static int calculateBisecting(MATRIX z1, pHKL self, SConnection *pCon,
|
||||||
|
float fSet[4], double myPsi, int iRetry)
|
||||||
|
{
|
||||||
|
double stt, om, chi, phi, psi, ompsi, chipsi, phipsi;
|
||||||
|
int i, test;
|
||||||
|
|
||||||
|
/*
|
||||||
|
just the plain angle calculation
|
||||||
|
*/
|
||||||
|
if(!z1mToBisecting(self->fLambda,z1,&stt,&om,&chi,&phi))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(iRetry == 1) {
|
||||||
|
rotatePsi(om,chi,phi,psi,&ompsi,&chipsi,&phipsi);
|
||||||
|
fSet[1] = ompsi;
|
||||||
|
fSet[2] = circlify(chipsi);
|
||||||
|
fSet[3] = circlify(phipsi);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return findAllowedBisecting(self->fLambda, z1, fSet, hklInRange,self);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
static int calculateNormalBeam(MATRIX z1, pHKL self, SConnection *pCon,
|
||||||
float fSet[4], double myPsi, int iRetry)
|
float fSet[4], double myPsi, int iRetry)
|
||||||
@ -917,22 +985,12 @@ static void stopHKLMotors(pHKL self)
|
|||||||
self->pNu->pDrivInt->Halt(self->pNu);
|
self->pNu->pDrivInt->Halt(self->pNu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*-------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
int RunHKL(pHKL self, float fHKL[3],
|
int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4])
|
||||||
float fPsi, int iHamil, SConnection *pCon)
|
|
||||||
{
|
{
|
||||||
float fSet[4];
|
|
||||||
int iRet,i;
|
|
||||||
char pBueffel[512];
|
char pBueffel[512];
|
||||||
pDummy pDum;
|
pDummy pDum;
|
||||||
|
int iRet;
|
||||||
assert(self);
|
|
||||||
iRet = CalculateSettings(self,fHKL,fPsi,iHamil,fSet,pCon);
|
|
||||||
if(!iRet)
|
|
||||||
{
|
|
||||||
SCWrite(pCon,"ERROR: NOT started",eError);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start all the motors */
|
/* start all the motors */
|
||||||
pDum = (pDummy)self->pTheta;
|
pDum = (pDummy)self->pTheta;
|
||||||
@ -966,15 +1024,8 @@ static void stopHKLMotors(pHKL self)
|
|||||||
SCWrite(pCon,"ERROR: cannot start nu motor",eError);
|
SCWrite(pCon,"ERROR: cannot start nu motor",eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
for(i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
self->fLastHKL[i] = fHKL[i];
|
|
||||||
}
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pDum = (pDummy)self->pChi;
|
pDum = (pDummy)self->pChi;
|
||||||
iRet = StartDevice(pServ->pExecutor, "HKL",
|
iRet = StartDevice(pServ->pExecutor, "HKL",
|
||||||
@ -994,6 +1045,30 @@ static void stopHKLMotors(pHKL self)
|
|||||||
stopHKLMotors(self);
|
stopHKLMotors(self);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int RunHKL(pHKL self, float fHKL[3],
|
||||||
|
float fPsi, int iHamil, SConnection *pCon)
|
||||||
|
{
|
||||||
|
float fSet[4];
|
||||||
|
int iRet,i;
|
||||||
|
char pBueffel[512];
|
||||||
|
pDummy pDum;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
iRet = CalculateSettings(self,fHKL,fPsi,iHamil,fSet,pCon);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(pCon,"ERROR: NOT started",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
iRet = startHKLMotors(self,pCon,fSet);
|
||||||
|
if(iRet != 1){
|
||||||
|
return iRet;
|
||||||
|
}
|
||||||
|
|
||||||
for(i = 0; i < 3; i++)
|
for(i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
self->fLastHKL[i] = fHKL[i];
|
self->fLastHKL[i] = fHKL[i];
|
||||||
|
3
hkl.h
3
hkl.h
@ -48,6 +48,7 @@
|
|||||||
|
|
||||||
int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
int hklInRange(void *data, float fSet[4], int mask[4]);
|
||||||
|
int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
3
hkl.tex
3
hkl.tex
@ -125,7 +125,8 @@ $\langle$hklint {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
\mbox{}\verb@ int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
\mbox{}\verb@ int argc, char *argv[]); @\\
|
\mbox{}\verb@ int argc, char *argv[]); @\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@ int hklInRange(void *data, float fSet[4], int mask[4]);@\\
|
||||||
|
\mbox{}\verb@ int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]);@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@$\diamond$
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
|
3
hkl.w
3
hkl.w
@ -108,7 +108,8 @@ module:
|
|||||||
|
|
||||||
int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int HKLAction(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
int hklInRange(void *data, float fSet[4], int mask[4]);
|
||||||
|
int startHKLMotors(pHKL self, SConnection *pCon, float fSet[4]);
|
||||||
@}
|
@}
|
||||||
All functions return 0 on failure, 1 on success if not stated otherwise.
|
All functions return 0 on failure, 1 on success if not stated otherwise.
|
||||||
Most functions take a pointer to a HKL data structure as first parameter.
|
Most functions take a pointer to a HKL data structure as first parameter.
|
||||||
|
2
make_gen
2
make_gen
@ -30,7 +30,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
|
s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) mcreader.o mccontrol.o\
|
||||||
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
|
hmdata.o nxscript.o tclintimpl.o sicsdata.o mcstascounter.o \
|
||||||
mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
|
mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \
|
||||||
sinfox.o sicslist.o
|
sinfox.o sicslist.o cone.o
|
||||||
|
|
||||||
MOTOROBJ = motor.o simdriv.o
|
MOTOROBJ = motor.o simdriv.o
|
||||||
COUNTEROBJ = countdriv.o simcter.o counter.o
|
COUNTEROBJ = countdriv.o simcter.o counter.o
|
||||||
|
@ -16,8 +16,8 @@ include sllinux_def
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \
|
CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \
|
||||||
-Ipsi/hardsup -I. \
|
-Ipsi/hardsup -I. \
|
||||||
-fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY) \
|
-Werror -DCYGNUS -DNONINTF -g $(DFORTIFY) \
|
||||||
-Wall -Wno-unused -Wno-comment -Wno-switch -Werror
|
-Wall -Wno-unused -Wno-comment -Wno-switch
|
||||||
|
|
||||||
BINTARGET = bin
|
BINTARGET = bin
|
||||||
EXTRA=nintf.o
|
EXTRA=nintf.o
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
119
|
120
|
||||||
NEVER, EVER modify or delete this file
|
NEVER, EVER modify or delete this file
|
||||||
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
You'll risk eternal damnation and a reincarnation as a cockroach!|n
|
@ -6,7 +6,7 @@
|
|||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
# O P T I O N S
|
# O P T I O N S
|
||||||
|
|
||||||
set home $env(HOME)/psi/sics/mcstas/dmc
|
set home $env(HOME)/src/workspace/sics/mcstas/dmc
|
||||||
|
|
||||||
#--------------------------------- first all the server options are set
|
#--------------------------------- first all the server options are set
|
||||||
#ServerOption RedirectFile $home/stdcdmc
|
#ServerOption RedirectFile $home/stdcdmc
|
||||||
@ -139,11 +139,11 @@ commandlog auto
|
|||||||
commandlog intervall 5
|
commandlog intervall 5
|
||||||
|
|
||||||
#----------- enable sycamore
|
#----------- enable sycamore
|
||||||
InstallProtocolHandler
|
#InstallProtocolHandler
|
||||||
InstallSinfox
|
#InstallSinfox
|
||||||
source sycFormat.tcl
|
#source sycFormat.tcl
|
||||||
source /usr/lib/tcllib1.6.1/stooop/stooop.tcl
|
#source /usr/lib/tcllib1.6.1/stooop/stooop.tcl
|
||||||
namespace import stooop::*
|
#namespace import stooop::*
|
||||||
source sinfo.tcl
|
#source sinfo.tcl
|
||||||
source sycamore.tcl
|
#source sycamore.tcl
|
||||||
Publish sinfo Spy
|
#Publish sinfo Spy
|
||||||
|
@ -98,10 +98,10 @@ twothetad ignorefault 0.000000
|
|||||||
twothetad AccessCode 2.000000
|
twothetad AccessCode 2.000000
|
||||||
twothetad movecount 10.000000
|
twothetad movecount 10.000000
|
||||||
# Counter counter
|
# Counter counter
|
||||||
counter SetPreset 60000.000000
|
counter SetPreset 60000000.000000
|
||||||
counter SetMode Monitor
|
counter SetMode Monitor
|
||||||
banana CountMode monitor
|
banana CountMode monitor
|
||||||
banana preset 60.000000
|
banana preset 60000.000000
|
||||||
# Motor a1
|
# Motor a1
|
||||||
a1 sign 1.000000
|
a1 sign 1.000000
|
||||||
a1 SoftZero 0.000000
|
a1 SoftZero 0.000000
|
||||||
@ -215,7 +215,7 @@ comment2 UNKNOWN
|
|||||||
comment2 setAccess 2
|
comment2 setAccess 2
|
||||||
comment3 UNKNOWN
|
comment3 UNKNOWN
|
||||||
comment3 setAccess 2
|
comment3 setAccess 2
|
||||||
starttime 2005-12-20 05:13:05
|
starttime 2006-03-10 15:33:04
|
||||||
starttime setAccess 2
|
starttime setAccess 2
|
||||||
adress UNKNOWN
|
adress UNKNOWN
|
||||||
adress setAccess 2
|
adress setAccess 2
|
||||||
|
7
motreg.c
7
motreg.c
@ -115,7 +115,14 @@ int StartRegMot(pMotReg self, SConnection *pCon, float fValue){
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
pDriv->SetValue = oldSet;
|
pDriv->SetValue = oldSet;
|
||||||
|
if(ret == 1){
|
||||||
self->iActive = 1;
|
self->iActive = 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,131,"ERROR: failed to start motor %s",
|
||||||
|
self->motorName);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
self->iActive = 0;
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
15
motreglist.c
15
motreglist.c
@ -91,6 +91,21 @@ void StopAllMotors(int iList){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
|
void DeactivateAllMotors(int iList){
|
||||||
|
int iRet, count = 0;
|
||||||
|
pMotReg pMot = NULL;
|
||||||
|
pIDrivable pDriv;
|
||||||
|
|
||||||
|
iRet = LLDnodePtr2First(iList);
|
||||||
|
while(iRet != 0){
|
||||||
|
LLDnodeDataTo(iList,&pMot);
|
||||||
|
if(pMot != NULL){
|
||||||
|
pMot->iActive = 0;
|
||||||
|
}
|
||||||
|
iRet = LLDnodePtr2Next(iList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
void KillMotList(int iList){
|
void KillMotList(int iList){
|
||||||
int iRet;
|
int iRet;
|
||||||
pMotReg pMot = NULL;
|
pMotReg pMot = NULL;
|
||||||
|
@ -20,6 +20,9 @@
|
|||||||
int CheckAllMotors(int iList, SConnection *pCon);
|
int CheckAllMotors(int iList, SConnection *pCon);
|
||||||
void KillMotList(int iList);
|
void KillMotList(int iList);
|
||||||
void StopAllMotors(int iList);
|
void StopAllMotors(int iList);
|
||||||
|
void DeactivateAllMotors(int iList);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
5
napi4.c
5
napi4.c
@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
For further information, see <http://www.neutron.anl.gov/NeXus/>
|
For further information, see <http://www.neutron.anl.gov/NeXus/>
|
||||||
|
|
||||||
$Id: napi4.c,v 1.7 2006/03/23 12:39:11 zolliker Exp $
|
$Id: napi4.c,v 1.8 2006/03/31 15:24:53 koennecke Exp $
|
||||||
|
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -1236,7 +1236,8 @@ extern void *NXpData;
|
|||||||
{
|
{
|
||||||
pNexusFile pFile;
|
pNexusFile pFile;
|
||||||
pFile = NXIassert (fid);
|
pFile = NXIassert (fid);
|
||||||
printf("HDF4 link: iTag = %ld, iRef = %ld, target=\"%s\"\n", sLink->iTag, sLink->iRef, sLink->targetPath);
|
printf("HDF4 link: iTag = %ld, iRef = %ld, target=\"%s\"\n",
|
||||||
|
sLink->iTag, sLink->iRef, sLink->targetPath);
|
||||||
return NX_OK;
|
return NX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
ofac.c
5
ofac.c
@ -117,6 +117,7 @@
|
|||||||
#include "protocol.h"
|
#include "protocol.h"
|
||||||
#include "sinfox.h"
|
#include "sinfox.h"
|
||||||
#include "sicslist.h"
|
#include "sicslist.h"
|
||||||
|
#include "cone.h"
|
||||||
/*----------------------- Server options creation -------------------------*/
|
/*----------------------- Server options creation -------------------------*/
|
||||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -252,6 +253,7 @@
|
|||||||
AddCommand(pInter,"Success",Success,NULL,pExe);
|
AddCommand(pInter,"Success",Success,NULL,pExe);
|
||||||
AddCommand(pInter,"pause",PauseAction,NULL,pExe);
|
AddCommand(pInter,"pause",PauseAction,NULL,pExe);
|
||||||
AddCommand(pInter,"continue",ContinueAction,NULL,pExe);
|
AddCommand(pInter,"continue",ContinueAction,NULL,pExe);
|
||||||
|
AddCommand(pInter,"devexec",DevexecAction,NULL,pExe);
|
||||||
|
|
||||||
/* add additional object creation commands here */
|
/* add additional object creation commands here */
|
||||||
AddCommand(pInter,"TokenInit",TokenInit,NULL,NULL);
|
AddCommand(pInter,"TokenInit",TokenInit,NULL,NULL);
|
||||||
@ -319,6 +321,8 @@
|
|||||||
InstallProtocol,NULL,NULL);
|
InstallProtocol,NULL,NULL);
|
||||||
AddCommand(pInter,"InstallSinfox",
|
AddCommand(pInter,"InstallSinfox",
|
||||||
InstallSinfox,NULL,NULL);
|
InstallSinfox,NULL,NULL);
|
||||||
|
AddCommand(pInter,"MakeCone",
|
||||||
|
MakeCone,NULL,NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
install site specific commands
|
install site specific commands
|
||||||
@ -386,6 +390,7 @@
|
|||||||
RemoveCommand(pSics,"MakemcStasReader");
|
RemoveCommand(pSics,"MakemcStasReader");
|
||||||
RemoveCommand(pSics,"InstallProtocolHandler");
|
RemoveCommand(pSics,"InstallProtocolHandler");
|
||||||
RemoveCommand(pSics,"InstallSinfox");
|
RemoveCommand(pSics,"InstallSinfox");
|
||||||
|
RemoveCommand(pSics,"MakeCone");
|
||||||
/*
|
/*
|
||||||
remove site specific installation commands
|
remove site specific installation commands
|
||||||
*/
|
*/
|
||||||
|
@ -3,3 +3,5 @@ counter SetPreset 10.000000
|
|||||||
counter SetMode Timer
|
counter SetMode Timer
|
||||||
hm CountMode timer
|
hm CountMode timer
|
||||||
hm preset 10.000000
|
hm preset 10.000000
|
||||||
|
hm genbin 0.000000 10.000000 10000
|
||||||
|
hm init
|
||||||
|
68
tasdrive.c
68
tasdrive.c
@ -190,9 +190,20 @@ static int TASHalt(void *pData){
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static void writeMotPos(SConnection *pCon, char *name,
|
||||||
|
float val, float target){
|
||||||
|
char pBueffel[132];
|
||||||
|
|
||||||
|
snprintf(pBueffel,131,"Driving %5s from %8.3f to %8.3f",
|
||||||
|
name, val, target);
|
||||||
|
SCWrite(pCon,pBueffel,eWarning);
|
||||||
|
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int startMotors(ptasMot self, tasAngles angles,
|
static int startMotors(ptasMot self, tasAngles angles,
|
||||||
SConnection *pCon, int driveQ){
|
SConnection *pCon, int driveQ, int driveTilt){
|
||||||
float val;
|
float val;
|
||||||
double curve;
|
double curve;
|
||||||
int status;
|
int status;
|
||||||
@ -209,6 +220,8 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"a1",val, angles.monochromator_two_theta/2.);
|
||||||
|
|
||||||
val = self->math->motors[A2]->pDrivInt->GetValue(self->math->motors[A2],pCon);
|
val = self->math->motors[A2]->pDrivInt->GetValue(self->math->motors[A2],pCon);
|
||||||
if(ABS(val - angles.monochromator_two_theta) > MOTPREC){
|
if(ABS(val - angles.monochromator_two_theta) > MOTPREC){
|
||||||
status = self->math->motors[A2]->pDrivInt->SetValue(self->math->motors[A2],
|
status = self->math->motors[A2]->pDrivInt->SetValue(self->math->motors[A2],
|
||||||
@ -218,6 +231,8 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"a2",val, angles.monochromator_two_theta);
|
||||||
|
|
||||||
if(self->math->motors[MCV] != NULL){
|
if(self->math->motors[MCV] != NULL){
|
||||||
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
|
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
|
||||||
angles.monochromator_two_theta);
|
angles.monochromator_two_theta);
|
||||||
@ -230,7 +245,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"mcv",val, curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self->math->motors[MCH] != NULL){
|
if(self->math->motors[MCH] != NULL){
|
||||||
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
|
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
|
||||||
angles.monochromator_two_theta);
|
angles.monochromator_two_theta);
|
||||||
@ -243,6 +260,7 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"mch",val, curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -259,6 +277,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,self->math->motors[A5]->name,
|
||||||
|
val, angles.analyzer_two_theta/2.);
|
||||||
|
|
||||||
val = self->math->motors[A6]->pDrivInt->GetValue(self->math->motors[A6],pCon);
|
val = self->math->motors[A6]->pDrivInt->GetValue(self->math->motors[A6],pCon);
|
||||||
if(ABS(val - angles.analyzer_two_theta) > MOTPREC){
|
if(ABS(val - angles.analyzer_two_theta) > MOTPREC){
|
||||||
status = self->math->motors[A6]->pDrivInt->SetValue(self->math->motors[A6],
|
status = self->math->motors[A6]->pDrivInt->SetValue(self->math->motors[A6],
|
||||||
@ -268,6 +289,8 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"a6",val, angles.analyzer_two_theta);
|
||||||
|
|
||||||
if(self->math->motors[ACV] != NULL){
|
if(self->math->motors[ACV] != NULL){
|
||||||
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta);
|
||||||
@ -280,6 +303,7 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"acv",val, curve);
|
||||||
}
|
}
|
||||||
if(self->math->motors[ACH] != NULL){
|
if(self->math->motors[ACH] != NULL){
|
||||||
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
||||||
@ -295,6 +319,7 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"ach",val, curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(driveQ == 0){
|
if(driveQ == 0){
|
||||||
@ -313,6 +338,8 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"a3",val, angles.a3);
|
||||||
|
|
||||||
val = self->math->motors[A4]->pDrivInt->GetValue(self->math->motors[A4],pCon);
|
val = self->math->motors[A4]->pDrivInt->GetValue(self->math->motors[A4],pCon);
|
||||||
if(ABS(val - angles.sample_two_theta) > MOTPREC){
|
if(ABS(val - angles.sample_two_theta) > MOTPREC){
|
||||||
status = self->math->motors[A4]->pDrivInt->SetValue(self->math->motors[A4],
|
status = self->math->motors[A4]->pDrivInt->SetValue(self->math->motors[A4],
|
||||||
@ -322,6 +349,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"a4",val, angles.sample_two_theta);
|
||||||
|
|
||||||
|
if(driveTilt == 1){
|
||||||
val = self->math->motors[SGL]->pDrivInt->GetValue(self->math->motors[SGL],pCon);
|
val = self->math->motors[SGL]->pDrivInt->GetValue(self->math->motors[SGL],pCon);
|
||||||
if(ABS(val - angles.sgl) > MOTPREC){
|
if(ABS(val - angles.sgl) > MOTPREC){
|
||||||
status = self->math->motors[SGL]->pDrivInt->SetValue(self->math->motors[SGL],
|
status = self->math->motors[SGL]->pDrivInt->SetValue(self->math->motors[SGL],
|
||||||
@ -331,6 +361,8 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"sgl",val, angles.sgl);
|
||||||
|
|
||||||
val = self->math->motors[SGU]->pDrivInt->GetValue(self->math->motors[SGU],pCon);
|
val = self->math->motors[SGU]->pDrivInt->GetValue(self->math->motors[SGU],pCon);
|
||||||
if(ABS(val - angles.sgu) > MOTPREC){
|
if(ABS(val - angles.sgu) > MOTPREC){
|
||||||
status = self->math->motors[SGU]->pDrivInt->SetValue(self->math->motors[SGU],
|
status = self->math->motors[SGU]->pDrivInt->SetValue(self->math->motors[SGU],
|
||||||
@ -340,12 +372,14 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writeMotPos(pCon,"sgu",val, angles.sgu);
|
||||||
|
}
|
||||||
self->math->mustDrive = 0;
|
self->math->mustDrive = 0;
|
||||||
return OKOK;
|
return OKOK;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int checkQMotorLimits(ptasMot self, SConnection *pCon,
|
static int checkQMotorLimits(ptasMot self, SConnection *pCon,
|
||||||
tasAngles angles){
|
tasAngles angles, int driveTilt){
|
||||||
int status, retVal = 1;
|
int status, retVal = 1;
|
||||||
char error[131];
|
char error[131];
|
||||||
char pBueffel[256];
|
char pBueffel[256];
|
||||||
@ -370,6 +404,7 @@ static int checkQMotorLimits(ptasMot self, SConnection *pCon,
|
|||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(driveTilt == 1){
|
||||||
status = self->math->motors[A3]->pDrivInt->CheckLimits(self->math->motors[SGU],
|
status = self->math->motors[A3]->pDrivInt->CheckLimits(self->math->motors[SGU],
|
||||||
angles.sgu,
|
angles.sgu,
|
||||||
error,
|
error,
|
||||||
@ -389,12 +424,14 @@ static int checkQMotorLimits(ptasMot self, SConnection *pCon,
|
|||||||
snprintf(pBueffel,256,"ERROR: limit violation an SGL: %s", error);
|
snprintf(pBueffel,256,"ERROR: limit violation an SGL: %s", error);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
static int calculateAndDrive(ptasMot self, SConnection *pCon){
|
static int calculateAndDrive(ptasMot self, SConnection *pCon){
|
||||||
tasAngles angles;
|
tasAngles angles;
|
||||||
int status, driveQ = 1;
|
int status, driveQ = 1, driveTilt = 1;
|
||||||
|
MATRIX scatteringPlaneNormal = NULL;
|
||||||
|
|
||||||
if(self->math->ubValid == 0){
|
if(self->math->ubValid == 0){
|
||||||
SCWrite(pCon,"WARNING: UB matrix invalid",eWarning);
|
SCWrite(pCon,"WARNING: UB matrix invalid",eWarning);
|
||||||
@ -424,14 +461,35 @@ static int calculateAndDrive(ptasMot self, SConnection *pCon){
|
|||||||
driveQ = 0;
|
driveQ = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!checkQMotorLimits(self,pCon,angles)){
|
/**
|
||||||
|
* check out of plane condition and permission
|
||||||
|
*/
|
||||||
|
if(self->math->outOfPlaneAllowed != 1){
|
||||||
|
scatteringPlaneNormal = calcScatteringPlaneNormal(self->math->r1.qe,
|
||||||
|
self->math->r2.qe);
|
||||||
|
if(scatteringPlaneNormal == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: unable to calculate scattering plane normal",eError);
|
||||||
driveQ = 0;
|
driveQ = 0;
|
||||||
|
} else {
|
||||||
|
if(!isInPlane(scatteringPlaneNormal,self->math->target)){
|
||||||
|
SCWrite(pCon,
|
||||||
|
"WARNING: scattering vector is out of plane and you disallowed me to try to drive there",
|
||||||
|
eWarning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
driveTilt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(driveQ != 0){
|
||||||
|
if(!checkQMotorLimits(self,pCon,angles,driveTilt)){
|
||||||
|
driveQ = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(driveQ == 0){
|
if(driveQ == 0){
|
||||||
SCWrite(pCon,"WARNING: NOT driving Q-vector because of errors",eError);
|
SCWrite(pCon,"WARNING: NOT driving Q-vector because of errors",eError);
|
||||||
}
|
}
|
||||||
return startMotors(self,angles,pCon, driveQ);
|
return startMotors(self,angles,pCon, driveQ,driveTilt);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
static int checkMotors(ptasMot self, SConnection *pCon){
|
static int checkMotors(ptasMot self, SConnection *pCon){
|
||||||
|
21
tasub.c
21
tasub.c
@ -65,6 +65,7 @@ static int tasUBSave(void *pData, char *name, FILE *fd){
|
|||||||
self->cell.b, self->cell.c, self->cell.alpha,
|
self->cell.b, self->cell.c, self->cell.alpha,
|
||||||
self->cell.beta, self->cell.gamma);
|
self->cell.beta, self->cell.gamma);
|
||||||
saveReflections(self,name,fd);
|
saveReflections(self,name,fd);
|
||||||
|
fprintf(fd,"%s outofplane %d\n", name, self->outOfPlaneAllowed);
|
||||||
if(self->tasMode == KICONST){
|
if(self->tasMode == KICONST){
|
||||||
fprintf(fd,"%s const ki\n",name);
|
fprintf(fd,"%s const ki\n",name);
|
||||||
}else if(self->tasMode == ELASTIC){
|
}else if(self->tasMode == ELASTIC){
|
||||||
@ -136,6 +137,7 @@ static ptasUB MakeTasUB(){
|
|||||||
pNew->tasMode = KICONST;
|
pNew->tasMode = KICONST;
|
||||||
pNew->targetEn = .0;
|
pNew->targetEn = .0;
|
||||||
pNew->actualEn = .0;
|
pNew->actualEn = .0;
|
||||||
|
pNew->outOfPlaneAllowed = 1;
|
||||||
pNew->mustRecalculate = 1;
|
pNew->mustRecalculate = 1;
|
||||||
|
|
||||||
return pNew;
|
return pNew;
|
||||||
@ -1468,6 +1470,25 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
|
|||||||
SCWrite(pCon,pBueffel,eValue);
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
} else if(strcmp(argv[1],"outofplane") == 0){
|
||||||
|
if(argc > 2){
|
||||||
|
strtolower(argv[2]);
|
||||||
|
if(!SCMatchRights(pCon,usUser)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = Tcl_GetInt(InterpGetTcl(pSics),argv[2],&newSS);
|
||||||
|
if(status != TCL_OK){
|
||||||
|
SCWrite(pCon,"ERROR: failed to convert argument to number",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->outOfPlaneAllowed = newSS;
|
||||||
|
SCSendOK(pCon);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel,131,"%s.outofplane = %d",argv[0],self->outOfPlaneAllowed);
|
||||||
|
SCWrite(pCon,pBueffel,eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf(pBueffel,131,"ERROR: subcommand %s to %s not defined",argv[1],
|
snprintf(pBueffel,131,"ERROR: subcommand %s to %s not defined",argv[1],
|
||||||
argv[0]);
|
argv[0]);
|
||||||
|
1
tasub.h
1
tasub.h
@ -23,6 +23,7 @@
|
|||||||
tasQEPosition target;
|
tasQEPosition target;
|
||||||
tasQEPosition current;
|
tasQEPosition current;
|
||||||
int tasMode;
|
int tasMode;
|
||||||
|
int outOfPlaneAllowed;
|
||||||
double targetEn, actualEn;
|
double targetEn, actualEn;
|
||||||
int mustRecalculate;
|
int mustRecalculate;
|
||||||
int mustDrive;
|
int mustDrive;
|
||||||
|
5
tasub.w
5
tasub.w
@ -25,11 +25,13 @@ A data structure:
|
|||||||
tasQEPosition target;
|
tasQEPosition target;
|
||||||
tasQEPosition current;
|
tasQEPosition current;
|
||||||
int tasMode;
|
int tasMode;
|
||||||
|
int outOfPlaneAllowed;
|
||||||
double targetEn, actualEn;
|
double targetEn, actualEn;
|
||||||
int mustRecalculate;
|
int mustRecalculate;
|
||||||
int mustDrive;
|
int mustDrive;
|
||||||
pMotor motors[12];
|
pMotor motors[12];
|
||||||
int r1, r2;
|
tasReflection r1, r2;
|
||||||
|
int ubValid;
|
||||||
}tasUB, *ptasUB;
|
}tasUB, *ptasUB;
|
||||||
@}
|
@}
|
||||||
\begin{description}
|
\begin{description}
|
||||||
@ -41,6 +43,7 @@ A data structure:
|
|||||||
\item[target] The Q energy target position
|
\item[target] The Q energy target position
|
||||||
\item[current] The actual Q energy position as calculated from angles.
|
\item[current] The actual Q energy position as calculated from angles.
|
||||||
\item[tasMode] The mode: constant KI or constant KF
|
\item[tasMode] The mode: constant KI or constant KF
|
||||||
|
\item[outOfPlaneAllowed] 0/1 determining if it is allowed to drive out of plane or not.
|
||||||
\item[ptargetEn] The target energy transfer.
|
\item[ptargetEn] The target energy transfer.
|
||||||
\item[actualEn] The actual energy transfer as calcluated from angles.
|
\item[actualEn] The actual energy transfer as calcluated from angles.
|
||||||
\item[mustRecalculate] A flag indicatin that the current Q energy psoition has to be
|
\item[mustRecalculate] A flag indicatin that the current Q energy psoition has to be
|
||||||
|
47
tasublib.c
47
tasublib.c
@ -20,6 +20,7 @@
|
|||||||
#define DEGREE_RAD (PI/180.0) /* Radians per degree */
|
#define DEGREE_RAD (PI/180.0) /* Radians per degree */
|
||||||
#define VERT 0
|
#define VERT 0
|
||||||
#define HOR 1
|
#define HOR 1
|
||||||
|
#define INPLANEPREC 0.01
|
||||||
/*============== monochromator/analyzer stuff =========================*/
|
/*============== monochromator/analyzer stuff =========================*/
|
||||||
double energyToK(double energy){
|
double energyToK(double energy){
|
||||||
double K;
|
double K;
|
||||||
@ -178,6 +179,9 @@ MATRIX calcPlaneNormal(tasReflection r1, tasReflection r2){
|
|||||||
planeNormal[i][0] = -1.*planeNormal[i][0];
|
planeNormal[i][0] = -1.*planeNormal[i][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mat_free(u1);
|
||||||
|
mat_free(u2);
|
||||||
|
normalizeVector(planeNormal);
|
||||||
return planeNormal;
|
return planeNormal;
|
||||||
} else {
|
} else {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -438,7 +442,7 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, tasQEPosition qe,
|
|||||||
|
|
||||||
angles->a3 = om + theta;
|
angles->a3 = om + theta;
|
||||||
/*
|
/*
|
||||||
put a3 into -180, 180 properly. We cal always turn by 180 because the
|
put a3 into -180, 180 properly. We can always turn by 180 because the
|
||||||
scattering geometry is symmetric in this respect. It is like looking at
|
scattering geometry is symmetric in this respect. It is like looking at
|
||||||
the scattering plane from the other side
|
the scattering plane from the other side
|
||||||
*/
|
*/
|
||||||
@ -674,3 +678,44 @@ double getTasPar(tasQEPosition qe, int tasVar){
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int isInPlane(MATRIX planeNormal, tasQEPosition qe){
|
||||||
|
MATRIX v = NULL;
|
||||||
|
double val;
|
||||||
|
|
||||||
|
v = makeVector();
|
||||||
|
v[0][0] = qe.qh;
|
||||||
|
v[1][0] = qe.qk;
|
||||||
|
v[2][0] = qe.ql;
|
||||||
|
val = vectorDotProduct(planeNormal,v);
|
||||||
|
mat_free(v);
|
||||||
|
if(ABS(val) > INPLANEPREC){
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
MATRIX calcScatteringPlaneNormal(tasQEPosition qe1, tasQEPosition qe2){
|
||||||
|
MATRIX v1 = NULL, v2 = NULL, planeNormal;
|
||||||
|
|
||||||
|
v1 = makeVector();
|
||||||
|
v2 = makeVector();
|
||||||
|
if(v1 != NULL && v2 != NULL){
|
||||||
|
v1[0][0] = qe1.qh;
|
||||||
|
v1[1][0] = qe1.qk;
|
||||||
|
v1[2][0] = qe1.ql;
|
||||||
|
|
||||||
|
v2[0][0] = qe2.qh;
|
||||||
|
v2[1][0] = qe2.qk;
|
||||||
|
v2[2][0] = qe2.ql;
|
||||||
|
|
||||||
|
planeNormal = vectorCrossProduct(v1,v2);
|
||||||
|
normalizeVector(planeNormal);
|
||||||
|
mat_free(v1);
|
||||||
|
mat_free(v2);
|
||||||
|
return planeNormal;
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
17
tasublib.h
17
tasublib.h
@ -14,7 +14,7 @@
|
|||||||
/*================= error codes =====================================*/
|
/*================= error codes =====================================*/
|
||||||
#define ENERGYTOBIG -700
|
#define ENERGYTOBIG -700
|
||||||
#define BADSYNC -701 /* mono/analyzer out of sync: 2*theta != two_theta*/
|
#define BADSYNC -701 /* mono/analyzer out of sync: 2*theta != two_theta*/
|
||||||
#define UBNOMEMORY -702
|
#define UBNOMEMORY -200
|
||||||
#define TRIANGLENOTCLOSED -703
|
#define TRIANGLENOTCLOSED -703
|
||||||
#define BADRMATRIX -704
|
#define BADRMATRIX -704
|
||||||
#define BADUBORQ -705
|
#define BADUBORQ -705
|
||||||
@ -224,5 +224,20 @@ void setTasPar(ptasQEPosition qe, int tasMode, int tasVar, double value);
|
|||||||
* @return The value of the TAS variable.
|
* @return The value of the TAS variable.
|
||||||
*/
|
*/
|
||||||
double getTasPar(tasQEPosition qe, int tasVar);
|
double getTasPar(tasQEPosition qe, int tasVar);
|
||||||
|
/**
|
||||||
|
* checks if a QE Position is in the scattering plane as defined by the
|
||||||
|
* planeNormal
|
||||||
|
* @param planeNormal The plane normal of the scattering plane
|
||||||
|
* @param qe The QE position to check
|
||||||
|
* @return 0 when not in plane,1 when in plane
|
||||||
|
*/
|
||||||
|
int isInPlane(MATRIX scatteringPlaneNormal, tasQEPosition qe);
|
||||||
|
/**
|
||||||
|
* calculate the normal of the scattering plane from two reflections
|
||||||
|
* @param qe1 QE Position of first reflection in scattering plane
|
||||||
|
* @param qe2 QE position of second reflection in scattering plane
|
||||||
|
* @return The scattering plane normal
|
||||||
|
*/
|
||||||
|
MATRIX calcScatteringPlaneNormal(tasQEPosition qe1, tasQEPosition qe2);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
32
ubcalc.c
32
ubcalc.c
@ -17,17 +17,6 @@
|
|||||||
#include "ubcalc.h"
|
#include "ubcalc.h"
|
||||||
#include "motor.h"
|
#include "motor.h"
|
||||||
#include "hkl.h"
|
#include "hkl.h"
|
||||||
/*---------------------------------------------------------------------*/
|
|
||||||
typedef struct {
|
|
||||||
pObjectDescriptor pDes;
|
|
||||||
pHKL hkl;
|
|
||||||
lattice direct;
|
|
||||||
reflection r1, r2, r3;
|
|
||||||
MATRIX UB;
|
|
||||||
double allowedDeviation;
|
|
||||||
int indexSearchLimit;
|
|
||||||
int maxSuggestions;
|
|
||||||
} UBCALC, *pUBCALC;
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
static void killUBCALC(void *pData){
|
static void killUBCALC(void *pData){
|
||||||
pUBCALC self = (pUBCALC)pData;
|
pUBCALC self = (pUBCALC)pData;
|
||||||
@ -610,3 +599,24 @@ int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
reflection getReflection(void *ubcalc, int no){
|
||||||
|
pUBCALC self = (pUBCALC)ubcalc;
|
||||||
|
|
||||||
|
assert(self != NULL);
|
||||||
|
|
||||||
|
switch(no){
|
||||||
|
case 0:
|
||||||
|
return self->r1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
return self->r2;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
return self->r3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
21
ubcalc.h
21
ubcalc.h
@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
UB caclualtion routines for four circle diffraction.
|
UB calculation routines for four circle diffraction.
|
||||||
This is the interpreter interface to functionality implemented
|
This is the interpreter interface to functionality implemented
|
||||||
in fourlib.c
|
in fourlib.c
|
||||||
|
|
||||||
@ -10,10 +10,27 @@
|
|||||||
-----------------------------------------------------------------------*/
|
-----------------------------------------------------------------------*/
|
||||||
#ifndef SICSUBCALC
|
#ifndef SICSUBCALC
|
||||||
#define SICSUBCALC
|
#define SICSUBCALC
|
||||||
|
#include "sics.h"
|
||||||
|
#include "matrix/matrix.h"
|
||||||
|
#include "cell.h"
|
||||||
|
#include "hkl.h"
|
||||||
|
#include "ubfour.h"
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pHKL hkl;
|
||||||
|
lattice direct;
|
||||||
|
reflection r1, r2, r3;
|
||||||
|
MATRIX UB;
|
||||||
|
double allowedDeviation;
|
||||||
|
int indexSearchLimit;
|
||||||
|
int maxSuggestions;
|
||||||
|
} UBCALC, *pUBCALC;
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
int MakeUBCalc(SConnection *pCon,SicsInterp *pSics, void *pData,
|
int MakeUBCalc(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
reflection getReflection(void *ubcalc, int no);
|
||||||
#endif
|
#endif
|
||||||
|
21
ubcalc.w
21
ubcalc.w
@ -7,7 +7,7 @@ This module helps in the calculation of UB matrices for four
|
|||||||
|
|
||||||
@o ubcalc.h @{
|
@o ubcalc.h @{
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
UB caclualtion routines for four circle diffraction.
|
UB calculation routines for four circle diffraction.
|
||||||
This is the interpreter interface to functionality implemented
|
This is the interpreter interface to functionality implemented
|
||||||
in fourlib.c
|
in fourlib.c
|
||||||
|
|
||||||
@ -17,12 +17,29 @@ This module helps in the calculation of UB matrices for four
|
|||||||
-----------------------------------------------------------------------*/
|
-----------------------------------------------------------------------*/
|
||||||
#ifndef SICSUBCALC
|
#ifndef SICSUBCALC
|
||||||
#define SICSUBCALC
|
#define SICSUBCALC
|
||||||
|
#include "sics.h"
|
||||||
|
#include "matrix/matrix.h"
|
||||||
|
#include "cell.h"
|
||||||
|
#include "hkl.h"
|
||||||
|
#include "ubfour.h"
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
typedef struct {
|
||||||
|
pObjectDescriptor pDes;
|
||||||
|
pHKL hkl;
|
||||||
|
lattice direct;
|
||||||
|
reflection r1, r2, r3;
|
||||||
|
MATRIX UB;
|
||||||
|
double allowedDeviation;
|
||||||
|
int indexSearchLimit;
|
||||||
|
int maxSuggestions;
|
||||||
|
} UBCALC, *pUBCALC;
|
||||||
|
/*-------------------------------------------------------------------*/
|
||||||
int MakeUBCalc(SConnection *pCon,SicsInterp *pSics, void *pData,
|
int MakeUBCalc(SConnection *pCon,SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
int UBCalcWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[]);
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
reflection getReflection(void *ubcalc, int no);
|
||||||
#endif
|
#endif
|
||||||
@}
|
@}
|
||||||
|
|
135
ubfour.c
135
ubfour.c
@ -10,6 +10,7 @@
|
|||||||
*
|
*
|
||||||
* Mark Koennecke, March 2005
|
* Mark Koennecke, March 2005
|
||||||
*/
|
*/
|
||||||
|
#include <math.h>
|
||||||
#include "ubfour.h"
|
#include "ubfour.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
@ -376,3 +377,137 @@ int searchIndex(lattice direct, double lambda, double two_theta, double max_devi
|
|||||||
LLDdelete(list);
|
LLDdelete(list);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
double angleBetweenReflections(MATRIX B, reflection r1, reflection r2){
|
||||||
|
MATRIX chi1, chi2, h1, h2;
|
||||||
|
double angle;
|
||||||
|
|
||||||
|
h1 = makeVector();
|
||||||
|
if(h1 == NULL){
|
||||||
|
return -9999.99;
|
||||||
|
}
|
||||||
|
h1[0][0] = r1.h;
|
||||||
|
h1[1][0] = r1.k;
|
||||||
|
h1[2][0] = r1.l;
|
||||||
|
|
||||||
|
h2 = makeVector();
|
||||||
|
if(h2 == NULL){
|
||||||
|
return -999.99;
|
||||||
|
}
|
||||||
|
h2[0][0] = r2.h;
|
||||||
|
h2[1][0] = r2.k;
|
||||||
|
h2[2][0] = r2.l;
|
||||||
|
|
||||||
|
chi1 = mat_mul(B,h1);
|
||||||
|
chi2 = mat_mul(B,h2);
|
||||||
|
if(chi1 != NULL && chi2 != NULL){
|
||||||
|
angle = angleBetween(chi1,chi2);
|
||||||
|
killVector(chi1);
|
||||||
|
killVector(chi2);
|
||||||
|
}
|
||||||
|
killVector(h1);
|
||||||
|
killVector(h2);
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
MATRIX makeInstToConeVectorMatrix(reflection r,double lambda){
|
||||||
|
double z1[3], alpha, beta;
|
||||||
|
MATRIX mAlpha = NULL, mBeta = NULL, inst2CS = NULL;
|
||||||
|
|
||||||
|
z1FromAngles(lambda,r.s2t,r.om,r.chi,r.phi,z1);
|
||||||
|
alpha = atan2(z1[1],z1[0]);
|
||||||
|
beta = -atan2(z1[0],z1[2]);
|
||||||
|
/* printf("alpha = %f, beta = %f\n", alpha*57.57, beta*57.57);*/
|
||||||
|
|
||||||
|
mAlpha = mat_creat(3,3,ZERO_MATRIX);
|
||||||
|
mBeta = mat_creat(3,3,ZERO_MATRIX);
|
||||||
|
if(mAlpha == NULL || mBeta == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
mAlpha[0][0] = cos(alpha);
|
||||||
|
mAlpha[0][1] = sin(alpha);
|
||||||
|
mAlpha[1][0] = -sin(alpha);
|
||||||
|
mAlpha[1][1] = cos(alpha);
|
||||||
|
mAlpha[2][2] = 1.;
|
||||||
|
|
||||||
|
mBeta[0][0] = cos(beta);
|
||||||
|
mBeta[0][2] = sin(beta);
|
||||||
|
mBeta[1][1] = 1.;
|
||||||
|
mBeta[2][0] = -sin(beta);
|
||||||
|
mBeta[2][2] = cos(beta);
|
||||||
|
|
||||||
|
inst2CS = mat_mul(mBeta,mAlpha);
|
||||||
|
mat_free(mAlpha);
|
||||||
|
mat_free(mBeta);
|
||||||
|
|
||||||
|
return inst2CS;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
MATRIX calcConeVector(double openingAngle, double coneAngle,
|
||||||
|
double length, MATRIX coneToPsi){
|
||||||
|
MATRIX coneRot = NULL, nullVector = NULL, coneVector = NULL;
|
||||||
|
MATRIX coneVectorScatter = NULL;
|
||||||
|
double testAngle;
|
||||||
|
MATRIX z;
|
||||||
|
|
||||||
|
z = makeVector();
|
||||||
|
z[2][0] = 1.;
|
||||||
|
|
||||||
|
|
||||||
|
coneRot = mat_creat(3,3,ZERO_MATRIX);
|
||||||
|
if(coneRot == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
coneRot[0][0] = Cosd(coneAngle);
|
||||||
|
coneRot[0][1] = -Sind(coneAngle);
|
||||||
|
coneRot[1][0] = Sind(coneAngle);
|
||||||
|
coneRot[1][1] = Cosd(coneAngle);
|
||||||
|
coneRot[2][2] = 1.0;
|
||||||
|
|
||||||
|
nullVector = makeVector();
|
||||||
|
if(nullVector == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
nullVector[0][0] = Sind(openingAngle);
|
||||||
|
nullVector[1][0] = .0;
|
||||||
|
nullVector[2][0] = Cosd(openingAngle);
|
||||||
|
normalizeVector(nullVector);
|
||||||
|
scaleVector(nullVector,length);
|
||||||
|
testAngle = angleBetween(z,nullVector);
|
||||||
|
|
||||||
|
coneVector = mat_mul(coneRot,nullVector);
|
||||||
|
if(coneVector == NULL){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
testAngle = angleBetween(z,coneVector);
|
||||||
|
|
||||||
|
coneVectorScatter = mat_mul(coneToPsi,coneVector);
|
||||||
|
|
||||||
|
mat_free(coneRot);
|
||||||
|
killVector(nullVector);
|
||||||
|
killVector(coneVector);
|
||||||
|
|
||||||
|
return coneVectorScatter;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
double scatteringVectorLength(MATRIX B, reflection r){
|
||||||
|
MATRIX h = NULL, psi = NULL;
|
||||||
|
double length;
|
||||||
|
|
||||||
|
h = makeVector();
|
||||||
|
if(h == NULL){
|
||||||
|
return -9999.9;
|
||||||
|
}
|
||||||
|
h[0][0] = r.h;
|
||||||
|
h[1][0] = r.k;
|
||||||
|
h[2][0] = r.l;
|
||||||
|
|
||||||
|
psi = mat_mul(B,h);
|
||||||
|
|
||||||
|
length = vectorLength(psi);
|
||||||
|
killVector(h);
|
||||||
|
killVector(psi);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
42
ubfour.h
42
ubfour.h
@ -5,9 +5,14 @@
|
|||||||
*
|
*
|
||||||
* Implemented:
|
* Implemented:
|
||||||
* - UB from cell cell constants and two reflections.
|
* - UB from cell cell constants and two reflections.
|
||||||
|
* - UB from three reflections
|
||||||
* - Brute force index search
|
* - Brute force index search
|
||||||
*
|
*
|
||||||
* Mark Koennecke, march 2005
|
* Mark Koennecke, March 2005
|
||||||
|
*
|
||||||
|
* Added some general crystallographic calculations and stuff for conus scans
|
||||||
|
*
|
||||||
|
* Mark Koennecke, March 2006
|
||||||
*/
|
*/
|
||||||
#ifndef SICSUBFOUR
|
#ifndef SICSUBFOUR
|
||||||
#define SICSUBFOUR
|
#define SICSUBFOUR
|
||||||
@ -73,4 +78,39 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
int searchIndex(lattice direct, double lambda, double two_theta, double max_deviation,
|
int searchIndex(lattice direct, double lambda, double two_theta, double max_deviation,
|
||||||
int limit, refIndex index[], int maxIndex);
|
int limit, refIndex index[], int maxIndex);
|
||||||
|
/**
|
||||||
|
* calculate the angle between two reflections, given their miller indices
|
||||||
|
* @param B The B metric matrix
|
||||||
|
* @param r1 first reflection
|
||||||
|
* @param r2 second reflection
|
||||||
|
* @return angle between reflections
|
||||||
|
*/
|
||||||
|
double angleBetweenReflections(MATRIX B, reflection r1, reflection r2);
|
||||||
|
/**
|
||||||
|
* calculate the length of the scattering vector belonging to r
|
||||||
|
* @param B The B metric matrix to use
|
||||||
|
* @param r The reflction for wihic to calculate
|
||||||
|
* @return The length of the scattering vector
|
||||||
|
*/
|
||||||
|
double scatteringVectorLength(MATRIX B, reflection r);
|
||||||
|
/**
|
||||||
|
* build the conversion MATRIX from the Busing Levy psi system (z = UB*h)
|
||||||
|
* to the coordinate system of a given center reflection for a cone
|
||||||
|
* @param r The reflection around which the cone is situated
|
||||||
|
* @param lambda The wavelength
|
||||||
|
* @return A sutiable conversion matrix or NULL in case of errors
|
||||||
|
*/
|
||||||
|
MATRIX makeInstToConeVectorMatrix(reflection r, double lambda);
|
||||||
|
/**
|
||||||
|
* calculate a scattering vector on a cone around a given reflection at a
|
||||||
|
* specified cone rotation angle and a cone opening angle. The center
|
||||||
|
* reflection of the cone is hidden in the conversion matrix.
|
||||||
|
* @param openingAngle The opening angle of the cone
|
||||||
|
* @param coneAngle The angle on the cone
|
||||||
|
* @param coneToPsi The matrix for the conversion from the cone coordinate
|
||||||
|
* system to the psi instrument coordinate system.
|
||||||
|
* @return a scattering vector on the cone
|
||||||
|
*/
|
||||||
|
MATRIX calcConeVector(double openingAngle, double coneAngle,
|
||||||
|
double length, MATRIX coneToPsi);
|
||||||
#endif
|
#endif
|
||||||
|
25
vector.c
25
vector.c
@ -12,6 +12,8 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "vector.h"
|
#include "vector.h"
|
||||||
|
#include "trigd.h"
|
||||||
|
|
||||||
/*----------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------*/
|
||||||
MATRIX makeVector(){
|
MATRIX makeVector(){
|
||||||
return mat_creat(3,1,ZERO_MATRIX);
|
return mat_creat(3,1,ZERO_MATRIX);
|
||||||
@ -143,3 +145,26 @@ MATRIX matFromTwoVectors(MATRIX v1, MATRIX v2){
|
|||||||
killVector(a3);
|
killVector(a3);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
double angleBetween(MATRIX v1, MATRIX v2){
|
||||||
|
double angle, angles;
|
||||||
|
MATRIX v3 = NULL;
|
||||||
|
|
||||||
|
angle = vectorDotProduct(v1,v2)/(vectorLength(v1) * vectorLength(v2));
|
||||||
|
v3 = vectorCrossProduct(v1,v2);
|
||||||
|
if(v3 != NULL){
|
||||||
|
angles = vectorLength(v3)/(vectorLength(v1) * vectorLength(v2));
|
||||||
|
angle = Atan2d(angles,angle);
|
||||||
|
} else {
|
||||||
|
angle = Acosd(angle);
|
||||||
|
}
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
void scaleVector(MATRIX v, double scale){
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < 3; i++){
|
||||||
|
v[i][0] *= scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
14
vector.h
14
vector.h
@ -90,4 +90,18 @@ MATRIX vectorCrossProduct(MATRIX v1, MATRIX v2);
|
|||||||
* @return A matrix as descibed above.
|
* @return A matrix as descibed above.
|
||||||
*/
|
*/
|
||||||
MATRIX matFromTwoVectors(MATRIX v1, MATRIX v2);
|
MATRIX matFromTwoVectors(MATRIX v1, MATRIX v2);
|
||||||
|
/**
|
||||||
|
* calculate the nagle between two vectors
|
||||||
|
* @param v1 first vector
|
||||||
|
* @param v2 second vector
|
||||||
|
* @return angle in degree
|
||||||
|
*/
|
||||||
|
double angleBetween(MATRIX v1, MATRIX v2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* scale the vector v with scale
|
||||||
|
* @param v The vector to scale
|
||||||
|
* @param scale the scaling factor apply
|
||||||
|
*/
|
||||||
|
void scaleVector(MATRIX v, double scale);
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user