SICS-720 Add autofocussing on Taipan using the following energy relations,
Avfocus = 115 + 2.13 * Ef Mvfocus = 102.2 + 1.78 * Ei Ahfocus = 45.68 - (-105.7) * (0.945) ^ Ef Mhfocus = 184.42 - (60.1) * (0.951) ^ Ei NOTE: Parameters are set via tasub mono/ana VB1/VB2/HB1/HB2/HB3
This commit is contained in:
34
tasdrive.c
34
tasdrive.c
@ -39,9 +39,9 @@
|
|||||||
static long TASSetValue(void *pData, SConnection * pCon, float value)
|
static long TASSetValue(void *pData, SConnection * pCon, float value)
|
||||||
{
|
{
|
||||||
ptasMot self = (ptasMot) pData;
|
ptasMot self = (ptasMot) pData;
|
||||||
assert(self);
|
|
||||||
int qcodes[] = {3,4,5,8}; /* qh,qk,ql, en */
|
int qcodes[] = {3,4,5,8}; /* qh,qk,ql, en */
|
||||||
int i;
|
int i;
|
||||||
|
assert(self);
|
||||||
|
|
||||||
if (self->code > 5 && self->math->tasMode == ELASTIC) {
|
if (self->code > 5 && self->math->tasMode == ELASTIC) {
|
||||||
SCWrite(pCon, "ERROR: cannot drive this motor in elastic mode",
|
SCWrite(pCon, "ERROR: cannot drive this motor in elastic mode",
|
||||||
@ -328,9 +328,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
self->math->busy[A2] = 1;
|
self->math->busy[A2] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->math->motors[MCV] != NULL) {
|
if (self->math->motors[MCV] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
|
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
|
||||||
angles.monochromator_two_theta);
|
angles.monochromator_two_theta, getTasPar(self->math->target, EI), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[MCV], pCon, self->math->motname[MCV],
|
status = startTASMotor(self->math->motors[MCV], pCon, self->math->motname[MCV],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
@ -341,9 +341,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->math->motors[MCH] != NULL) {
|
if (self->math->motors[MCH] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
|
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
|
||||||
angles.monochromator_two_theta);
|
angles.monochromator_two_theta, getTasPar(self->math->target, EI), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[MCH], pCon, self->math->motname[MCH],
|
status = startTASMotor(self->math->motors[MCH], pCon, self->math->motname[MCH],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
@ -374,9 +374,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
self->math->busy[A6] = 1;
|
self->math->busy[A6] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->math->motors[ACV] != NULL) {
|
if (self->math->motors[ACV] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta, getTasPar(self->math->target, EF), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[ACV], pCon, self->math->motname[ACV],
|
status = startTASMotor(self->math->motors[ACV], pCon, self->math->motname[ACV],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
@ -386,9 +386,9 @@ static int startMotors(ptasMot self, tasAngles angles,
|
|||||||
self->math->busy[ACV] = 1;
|
self->math->busy[ACV] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self->math->motors[ACH] != NULL) {
|
if (self->math->motors[ACH] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta, getTasPar(self->math->target, EF), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[ACH], pCon, self->math->motname[ACH],
|
status = startTASMotor(self->math->motors[ACH], pCon, self->math->motname[ACH],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
@ -666,9 +666,9 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
self->math->busy[A2] = 1;
|
self->math->busy[A2] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->math->motors[MCV] != NULL) {
|
if (self->math->motors[MCV] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
|
curve = maCalcVerticalCurvature(self->math->machine.monochromator,
|
||||||
angles.monochromator_two_theta);
|
angles.monochromator_two_theta, getTasPar(self->math->target, EI), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[MCV], pCon, self->math->motname[MCV],
|
status = startTASMotor(self->math->motors[MCV], pCon, self->math->motname[MCV],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
@ -678,9 +678,9 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->math->motors[MCH] != NULL) {
|
if (self->math->motors[MCH] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
|
curve = maCalcHorizontalCurvature(self->math->machine.monochromator,
|
||||||
angles.monochromator_two_theta);
|
angles.monochromator_two_theta, getTasPar(self->math->target, EI), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[MCH], pCon, self->math->motname[MCH],
|
status = startTASMotor(self->math->motors[MCH], pCon, self->math->motname[MCH],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
@ -709,9 +709,9 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
self->math->busy[A6] = 1;
|
self->math->busy[A6] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->math->motors[ACV] != NULL) {
|
if (self->math->motors[ACV] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
curve = maCalcVerticalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta, getTasPar(self->math->target, EF), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[ACV], pCon, self->math->motname[ACV],
|
status = startTASMotor(self->math->motors[ACV], pCon, self->math->motname[ACV],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
@ -720,9 +720,9 @@ static int startQMMotors(ptasMot self, tasAngles angles,
|
|||||||
self->math->busy[ACV] = 1;
|
self->math->busy[ACV] = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (self->math->motors[ACH] != NULL) {
|
if (self->math->motors[ACH] != NULL && self->math->autofocus) {
|
||||||
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
curve = maCalcHorizontalCurvature(self->math->machine.analyzer,
|
||||||
angles.analyzer_two_theta);
|
angles.analyzer_two_theta, getTasPar(self->math->target, EF), self->math->focusfn);
|
||||||
status = startTASMotor(self->math->motors[ACH], pCon, self->math->motname[ACH],
|
status = startTASMotor(self->math->motors[ACH], pCon, self->math->motname[ACH],
|
||||||
curve, silent,stopFixed);
|
curve, silent,stopFixed);
|
||||||
if (status != OKOK) {
|
if (status != OKOK) {
|
||||||
|
55
tasub.c
55
tasub.c
@ -173,6 +173,8 @@ static ptasUB MakeTasUB()
|
|||||||
pNew->actualEn = .0;
|
pNew->actualEn = .0;
|
||||||
pNew->outOfPlaneAllowed = 1;
|
pNew->outOfPlaneAllowed = 1;
|
||||||
pNew->mustRecalculate = 1;
|
pNew->mustRecalculate = 1;
|
||||||
|
pNew->autofocus = 0;
|
||||||
|
pNew->focusfn = THETA_FN;
|
||||||
|
|
||||||
return pNew;
|
return pNew;
|
||||||
}
|
}
|
||||||
@ -381,6 +383,10 @@ int TasUBFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
eError);
|
eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (pNew->motors[MCV] != NULL && pNew->motors[MCH] != NULL &&
|
||||||
|
pNew->motors[ACV] != NULL && pNew->motors[ACH] != NULL) {
|
||||||
|
pNew->autofocus = 1;
|
||||||
|
}
|
||||||
|
|
||||||
status = AddCommand(pSics, argv[1], TasUBWrapper, KillTasUB, pNew);
|
status = AddCommand(pSics, argv[1], TasUBWrapper, KillTasUB, pNew);
|
||||||
if (status != 1) {
|
if (status != 1) {
|
||||||
@ -453,6 +459,11 @@ static int setCrystalParameters(pmaCrystal crystal, SConnection * pCon,
|
|||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
SCparChange(pCon);
|
SCparChange(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (strcmp(argv[2], "hb3") == 0) {
|
||||||
|
crystal->HB3 = d;
|
||||||
|
SCSendOK(pCon);
|
||||||
|
SCparChange(pCon);
|
||||||
|
return 1;
|
||||||
} else if (strcmp(argv[2], "vb1") == 0) {
|
} else if (strcmp(argv[2], "vb1") == 0) {
|
||||||
crystal->VB1 = d;
|
crystal->VB1 = d;
|
||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
@ -493,6 +504,11 @@ static int getCrystalParameters(pmaCrystal crystal, SConnection * pCon,
|
|||||||
crystal->HB2);
|
crystal->HB2);
|
||||||
SCWrite(pCon, pBueffel, eValue);
|
SCWrite(pCon, pBueffel, eValue);
|
||||||
return 1;
|
return 1;
|
||||||
|
} else if (strcmp(argv[2], "hb3") == 0) {
|
||||||
|
snprintf(pBueffel, 131, "%s.%s.hb3 = %f", argv[0], argv[1],
|
||||||
|
crystal->HB3);
|
||||||
|
SCWrite(pCon, pBueffel, eValue);
|
||||||
|
return 1;
|
||||||
} else if (strcmp(argv[2], "vb1") == 0) {
|
} else if (strcmp(argv[2], "vb1") == 0) {
|
||||||
snprintf(pBueffel, 131, "%s.%s.vb1 = %f", argv[0], argv[1],
|
snprintf(pBueffel, 131, "%s.%s.vb1 = %f", argv[0], argv[1],
|
||||||
crystal->VB1);
|
crystal->VB1);
|
||||||
@ -2200,9 +2216,44 @@ int TasUBWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
|
|||||||
SCWrite(pCon, pBueffel, eValue);
|
SCWrite(pCon, pBueffel, eValue);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else if (strcmp(argv[1], "autofocus") == 0) {
|
||||||
|
if (argc > 2) {
|
||||||
|
status = Tcl_GetInt(InterpGetTcl(pSics), argv[2], &(self->autofocus));
|
||||||
|
if (status != TCL_OK) {
|
||||||
|
SCWrite(pCon, "ERROR: failed to convert argument to number",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snprintf(pBueffel, 131, "%s.autofocus = %d", argv[0], self->autofocus);
|
||||||
|
SCWrite(pCon, pBueffel, eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else if (strcmp(argv[1], "focusfn") == 0) {
|
||||||
|
if (argc > 2) {
|
||||||
|
strtolower(argv[2]);
|
||||||
|
if (strcmp(argv[2], "theta") == 0) {
|
||||||
|
self->focusfn = THETA_FN;
|
||||||
|
} else if (strcmp(argv[2], "energy") == 0) {
|
||||||
|
self->focusfn = ENERGY_FN;
|
||||||
|
} else {
|
||||||
|
SCWrite(pCon, "ERROR: Arguments should be theta or energy", eError);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (self->focusfn) {
|
||||||
|
case ENERGY_FN:
|
||||||
|
snprintf(pBueffel, 131, "%s.focusfn = %s", argv[0], "energy");
|
||||||
|
break;
|
||||||
|
case THETA_FN:
|
||||||
|
snprintf(pBueffel, 131, "%s.focusfn = %s", argv[0], "theta");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SCWrite(pCon, pBueffel, eValue);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
snprintf(pBueffel, 131, "ERROR: subcommand %s to %s not defined",
|
snprintf(pBueffel, 131, "ERROR: subcommand %s to %s not defined",
|
||||||
argv[1], argv[0]);
|
argv[1], argv[0]);
|
||||||
SCWrite(pCon, pBueffel, eError);
|
SCWrite(pCon, pBueffel, eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
4
tasub.h
4
tasub.h
@ -24,6 +24,8 @@
|
|||||||
tasQEPosition current;
|
tasQEPosition current;
|
||||||
int tasMode;
|
int tasMode;
|
||||||
int outOfPlaneAllowed;
|
int outOfPlaneAllowed;
|
||||||
|
int autofocus;
|
||||||
|
int focusfn;
|
||||||
double targetEn, actualEn;
|
double targetEn, actualEn;
|
||||||
int mustRecalculate;
|
int mustRecalculate;
|
||||||
int mustDrive;
|
int mustDrive;
|
||||||
@ -34,7 +36,7 @@
|
|||||||
tasReflection r1, r2;
|
tasReflection r1, r2;
|
||||||
int ubValid;
|
int ubValid;
|
||||||
int silent;
|
int silent;
|
||||||
int stopFixed; /* flag to stop multiple fixed messages in scans*/
|
int stopFixed; /* flag to stop multiple fixed messages in scans*/
|
||||||
char *updater;
|
char *updater;
|
||||||
}tasUB, *ptasUB;
|
}tasUB, *ptasUB;
|
||||||
|
|
||||||
|
24
tasublib.c
24
tasublib.c
@ -40,13 +40,21 @@ double KtoEnergy(double k)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
static double calcCurvature(double B1, double B2, double theta, int ori)
|
static double calcCurvature(double B1, double B2, double B3, double theta, double energy, int ori, int focusfn)
|
||||||
{
|
{
|
||||||
assert(ori == VERT || ori == HOR);
|
assert(ori == VERT || ori == HOR);
|
||||||
if (ori == VERT) {
|
if (focusfn == ENERGY_FN) {
|
||||||
return B1 + B2 / Sind(ABS(theta));
|
if (ori == VERT) {
|
||||||
|
return B1 + B2 * energy;
|
||||||
|
} else {
|
||||||
|
return B1 + B2 * pow(B3, energy);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return B1 + B2 * Sind(ABS(theta));
|
if (ori == VERT) {
|
||||||
|
return B1 + B2 / Sind(ABS(theta));
|
||||||
|
} else {
|
||||||
|
return B1 + B2 * Sind(ABS(theta));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,15 +74,15 @@ int maCalcTwoTheta(maCrystal data, double k, double *two_theta)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
double maCalcVerticalCurvature(maCrystal data, double two_theta)
|
double maCalcVerticalCurvature(maCrystal data, double two_theta, double energy, int focusfn)
|
||||||
{
|
{
|
||||||
return calcCurvature(data.VB1, data.VB2, two_theta / 2., VERT);
|
return calcCurvature(data.VB1, data.VB2, 1, two_theta / 2., energy, VERT, focusfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------*/
|
||||||
double maCalcHorizontalCurvature(maCrystal data, double two_theta)
|
double maCalcHorizontalCurvature(maCrystal data, double two_theta, double energy, int focusfn)
|
||||||
{
|
{
|
||||||
return calcCurvature(data.HB1, data.HB2, two_theta / 2., HOR);
|
return calcCurvature(data.HB1, data.HB2, data.HB3, two_theta / 2., energy, HOR, focusfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
|
11
tasublib.h
11
tasublib.h
@ -22,6 +22,9 @@
|
|||||||
#define KICONST 1
|
#define KICONST 1
|
||||||
#define KFCONST 2
|
#define KFCONST 2
|
||||||
#define ELASTIC 3
|
#define ELASTIC 3
|
||||||
|
/*========================== defines for focusfn ====================*/
|
||||||
|
#define ENERGY_FN 1
|
||||||
|
#define THETA_FN 2
|
||||||
/*
|
/*
|
||||||
* in elastic mode A5, A5 will be disregarded and ki = kf at all times
|
* in elastic mode A5, A5 will be disregarded and ki = kf at all times
|
||||||
*/
|
*/
|
||||||
@ -42,8 +45,8 @@
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
double dd; /* lattice spacing */
|
double dd; /* lattice spacing */
|
||||||
int ss; /* scattering sense */
|
int ss; /* scattering sense */
|
||||||
double HB1, HB2; /* horizontal curvature parameters */
|
double HB1, HB2, HB3; /* horizontal curvature parameters */
|
||||||
double VB1, VB2; /* vertical curvature parameters */
|
double VB1, VB2; /* vertical curvature parameters */
|
||||||
} maCrystal, *pmaCrystal;
|
} maCrystal, *pmaCrystal;
|
||||||
/**
|
/**
|
||||||
* the machine parameters of a triple axis spectrometer
|
* the machine parameters of a triple axis spectrometer
|
||||||
@ -109,14 +112,14 @@ int maCalcTwoTheta(maCrystal data, double k, double *two_theta);
|
|||||||
* @param two_theta The tow theta value for which to calculate the curvature.
|
* @param two_theta The tow theta value for which to calculate the curvature.
|
||||||
* @return A new value for the curvature.
|
* @return A new value for the curvature.
|
||||||
*/
|
*/
|
||||||
double maCalcVerticalCurvature(maCrystal data, double two_theta);
|
double maCalcVerticalCurvature(maCrystal data, double two_theta, double energy, int focusfn);
|
||||||
/**
|
/**
|
||||||
* calculate the value for the horizontal curvature
|
* calculate the value for the horizontal curvature
|
||||||
* @param data The input crystal parameters
|
* @param data The input crystal parameters
|
||||||
* @param two_theta The tow theta value for which to calculate the curvature.
|
* @param two_theta The tow theta value for which to calculate the curvature.
|
||||||
* @return A new value for the curvature.
|
* @return A new value for the curvature.
|
||||||
*/
|
*/
|
||||||
double maCalcHorizontalCurvature(maCrystal data, double two_theta);
|
double maCalcHorizontalCurvature(maCrystal data, double two_theta, double energy, int focusfn);
|
||||||
/**
|
/**
|
||||||
* calculate the value of the K vector from the angle
|
* calculate the value of the K vector from the angle
|
||||||
* @param data The crystals constants
|
* @param data The crystals constants
|
||||||
|
Reference in New Issue
Block a user