- Adapted indenation to new agreed upon system
- Added support for second generation scriptcontext based counter
This commit is contained in:
517
simidx.c
517
simidx.c
@ -31,10 +31,10 @@
|
||||
#define MAXREF 20
|
||||
#define MAXIDX 20
|
||||
#define MAXSOLUTION 20
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
#define ABS(x) (x < 0 ? -(x) : (x))
|
||||
/*======================== types =============================*/
|
||||
typedef struct {
|
||||
int h,k,l;
|
||||
int h, k, l;
|
||||
double diff;
|
||||
} HKL, *pHKL;
|
||||
|
||||
@ -62,179 +62,208 @@ static int outLevel = 10;
|
||||
static IndexSolution solutions[MAXSOLUTION];
|
||||
static int nSolutions;
|
||||
/*------------------------------------------------------------*/
|
||||
void SimIdxInit(){
|
||||
void SimIdxInit()
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < MAXREF; i++){
|
||||
reflections[i].UVW = mat_creat(3,1,ZERO_MATRIX);
|
||||
for (i = 0; i < MAXREF; i++) {
|
||||
reflections[i].UVW = mat_creat(3, 1, ZERO_MATRIX);
|
||||
}
|
||||
}
|
||||
|
||||
/*=============== configuration functions =====================*/
|
||||
void SimIdxSetCell(double cell[6]){
|
||||
void SimIdxSetCell(double cell[6])
|
||||
{
|
||||
direct.a = cell[0];
|
||||
direct.b = cell[1];
|
||||
direct.c = cell[2];
|
||||
direct.alpha = cell[3];
|
||||
direct.beta = cell[4];
|
||||
direct.beta = cell[4];
|
||||
direct.gamma = cell[5];
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
void SimIdxSetLambda(double lmda){
|
||||
void SimIdxSetLambda(double lmda)
|
||||
{
|
||||
lambda = lmda;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
void SimIdxSetSttLim(double lmda){
|
||||
void SimIdxSetSttLim(double lmda)
|
||||
{
|
||||
sttlim = lmda;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
void SimIdxSetAngLim(double lmda){
|
||||
void SimIdxSetAngLim(double lmda)
|
||||
{
|
||||
anglim = lmda;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
void SimIdxSetSpacegroup(T_SgInfo *sg){
|
||||
void SimIdxSetSpacegroup(T_SgInfo * sg)
|
||||
{
|
||||
spgrp = sg;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
void SimIdxClearReflection(){
|
||||
nReflections = 0;
|
||||
void SimIdxClearReflection()
|
||||
{
|
||||
nReflections = 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
void SimIdxAddReflection(double uvw[3]){
|
||||
void SimIdxAddReflection(double uvw[3])
|
||||
{
|
||||
int i;
|
||||
if(nReflections < MAXREF){
|
||||
memcpy(&reflections[nReflections].uvw, uvw, 3*sizeof(double));
|
||||
if (nReflections < MAXREF) {
|
||||
memcpy(&reflections[nReflections].uvw, uvw, 3 * sizeof(double));
|
||||
reflections[nReflections].nHKL = 0;
|
||||
reflections[nReflections].currentIDX = 0;
|
||||
reflections[nReflections].originalID = nReflections;
|
||||
for(i = 0; i < 3; i++){
|
||||
for (i = 0; i < 3; i++) {
|
||||
reflections[nReflections].UVW[i][0] = uvw[i];
|
||||
}
|
||||
nReflections++;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
void SimIdxOutput(void *data, OutFunc out, int level){
|
||||
void SimIdxOutput(void *data, OutFunc out, int level)
|
||||
{
|
||||
userData = data;
|
||||
outFunc = out;
|
||||
outLevel = level;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
static void SimIdxPrint(int level, char *fmt, ...){
|
||||
static void SimIdxPrint(int level, char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char buf[1024];
|
||||
int l;
|
||||
|
||||
if(level > outLevel){
|
||||
if (level > outLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
va_start(ap, fmt);
|
||||
l = vsnprintf(buf, sizeof buf, fmt, ap);
|
||||
va_end(ap);
|
||||
if(outFunc != NULL){
|
||||
outFunc(userData,buf);
|
||||
if (outFunc != NULL) {
|
||||
outFunc(userData, buf);
|
||||
} else {
|
||||
printf("%s\n",buf);
|
||||
printf("%s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/*=============== The alkoholism ===============================*/
|
||||
static int thetaCompare(const void *d1, const void *d2){
|
||||
static int thetaCompare(const void *d1, const void *d2)
|
||||
{
|
||||
pIndexVector iv1, iv2;
|
||||
|
||||
iv1 = (pIndexVector)d1;
|
||||
iv2 = (pIndexVector)d2;
|
||||
iv1 = (pIndexVector) d1;
|
||||
iv2 = (pIndexVector) d2;
|
||||
|
||||
if(iv1->twotheta == iv2->twotheta) {
|
||||
if (iv1->twotheta == iv2->twotheta) {
|
||||
return 0;
|
||||
}
|
||||
if(iv1->twotheta < iv2->twotheta){
|
||||
if (iv1->twotheta < iv2->twotheta) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
static void calcRefTheta(){
|
||||
static void calcRefTheta()
|
||||
{
|
||||
int i;
|
||||
double theta, d;
|
||||
|
||||
for(i = 0; i < nReflections; i++){
|
||||
for (i = 0; i < nReflections; i++) {
|
||||
calcTheta(lambda, reflections[i].UVW, &d, &theta);
|
||||
reflections[i].twotheta = 2.* theta;
|
||||
reflections[i].twotheta = 2. * theta;
|
||||
}
|
||||
qsort(reflections,nReflections, sizeof(IndexVector),
|
||||
thetaCompare);
|
||||
qsort(reflections, nReflections, sizeof(IndexVector), thetaCompare);
|
||||
|
||||
SimIdxPrint(10,"%d Reflections", nReflections);
|
||||
SimIdxPrint(10, "%d Reflections", nReflections);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
double calcIdxTwoTheta(int h, int k, int l, MATRIX B){
|
||||
double calcIdxTwoTheta(int h, int k, int l, MATRIX B)
|
||||
{
|
||||
MATRIX H, Z1;
|
||||
double om, d;
|
||||
|
||||
H = mat_creat(3,1,ZERO_MATRIX);
|
||||
if(H == NULL){
|
||||
SimIdxPrint(1,"ERROR: out of memory calculating H matrix");
|
||||
H = mat_creat(3, 1, ZERO_MATRIX);
|
||||
if (H == NULL) {
|
||||
SimIdxPrint(1, "ERROR: out of memory calculating H matrix");
|
||||
return 0.;
|
||||
}
|
||||
H[0][0] = (double)h;
|
||||
H[1][0] = (double)k;
|
||||
H[2][0] = (double)l;
|
||||
Z1 = mat_mul(B,H);
|
||||
calcTheta(lambda,Z1,&d,&om);
|
||||
H[0][0] = (double) h;
|
||||
H[1][0] = (double) k;
|
||||
H[2][0] = (double) l;
|
||||
Z1 = mat_mul(B, H);
|
||||
calcTheta(lambda, Z1, &d, &om);
|
||||
om *= 2.;
|
||||
mat_free(Z1);
|
||||
mat_free(H);
|
||||
|
||||
|
||||
return om;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
static void AddCandidate(int n, int h, int k, int l,
|
||||
double diff){
|
||||
static void AddCandidate(int n, int h, int k, int l, double diff)
|
||||
{
|
||||
int cur = reflections[n].nHKL;
|
||||
if(cur < MAXCANDIDATES){
|
||||
if (cur < MAXCANDIDATES) {
|
||||
reflections[n].indices[cur].h = h;
|
||||
reflections[n].indices[cur].k = k;
|
||||
reflections[n].indices[cur].l = l;
|
||||
reflections[n].indices[cur].diff = diff ;
|
||||
reflections[n].indices[cur].diff = diff;
|
||||
reflections[n].nHKL++;
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
static int calcIndexes(){
|
||||
static int calcIndexes()
|
||||
{
|
||||
int h, k, l, i, status;
|
||||
int minh, mink, minl;
|
||||
MATRIX B;
|
||||
double twotheta;
|
||||
|
||||
B = mat_creat(3,3,UNIT_MATRIX);
|
||||
if(B == NULL){
|
||||
SimIdxPrint(1,"ERROR: out of memory calculating B matrix");
|
||||
B = mat_creat(3, 3, UNIT_MATRIX);
|
||||
if (B == NULL) {
|
||||
SimIdxPrint(1, "ERROR: out of memory calculating B matrix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = calculateBMatrix(direct,B);
|
||||
if(status < 0) {
|
||||
SimIdxPrint(1,"ERROR: invalid cell constants, failed to calculate B matrix");
|
||||
status = calculateBMatrix(direct, B);
|
||||
if (status < 0) {
|
||||
SimIdxPrint(1,
|
||||
"ERROR: invalid cell constants, failed to calculate B matrix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
minh = -MAXIDX;
|
||||
mink = -MAXIDX;
|
||||
minl = -MAXIDX;
|
||||
SetListMin_hkl(spgrp,MAXIDX, MAXIDX,&minh, &mink, &minl);
|
||||
SetListMin_hkl(spgrp, MAXIDX, MAXIDX, &minh, &mink, &minl);
|
||||
|
||||
for(h = MAXIDX; h > -MAXIDX; h--){
|
||||
for(k = MAXIDX; k > -MAXIDX; k--){
|
||||
for(l = MAXIDX; l > -MAXIDX; l--){
|
||||
if(IsSysAbsent_hkl(spgrp,h,k,l,NULL) != 0) {
|
||||
continue;
|
||||
}
|
||||
twotheta = calcIdxTwoTheta(h,k,l,B);
|
||||
for(i = 0; i < nReflections; i++){
|
||||
if(reflections[i].twotheta > twotheta - sttlim &&
|
||||
reflections[i].twotheta < twotheta + sttlim){
|
||||
AddCandidate(i, h,k,l, ABS(twotheta - reflections[i].twotheta));
|
||||
}
|
||||
for (h = MAXIDX; h > -MAXIDX; h--) {
|
||||
for (k = MAXIDX; k > -MAXIDX; k--) {
|
||||
for (l = MAXIDX; l > -MAXIDX; l--) {
|
||||
if (IsSysAbsent_hkl(spgrp, h, k, l, NULL) != 0) {
|
||||
continue;
|
||||
}
|
||||
twotheta = calcIdxTwoTheta(h, k, l, B);
|
||||
for (i = 0; i < nReflections; i++) {
|
||||
if (reflections[i].twotheta > twotheta - sttlim &&
|
||||
reflections[i].twotheta < twotheta + sttlim) {
|
||||
AddCandidate(i, h, k, l,
|
||||
ABS(twotheta - reflections[i].twotheta));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -242,53 +271,59 @@ static int calcIndexes(){
|
||||
mat_free(B);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
static double angleBetweenScatVec(MATRIX v1, MATRIX v2){
|
||||
static double angleBetweenScatVec(MATRIX v1, MATRIX v2)
|
||||
{
|
||||
double angle;
|
||||
|
||||
angle = angleBetween(v1,v2);
|
||||
angle = angleBetween(v1, v2);
|
||||
return angle;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------*/
|
||||
static void printRefDiagnostic(){
|
||||
static void printRefDiagnostic()
|
||||
{
|
||||
int i, j;
|
||||
double angle;
|
||||
|
||||
SimIdxPrint(10,"Reflection List and Candidate Indices");
|
||||
SimIdxPrint(10," N STT U V W");
|
||||
|
||||
for(i = 0; i < nReflections; i++){
|
||||
SimIdxPrint(10,"%3.3d %8.4f %8.4f %8.4f %8.4f", i,
|
||||
reflections[i].twotheta,
|
||||
reflections[i].uvw[0],
|
||||
reflections[i].uvw[1], reflections[i].uvw[2]);
|
||||
for(j = 0; j < reflections[i].nHKL; j++){
|
||||
SimIdxPrint(10,"\t%4d %4d %4d",
|
||||
reflections[i].indices[j].h,
|
||||
reflections[i].indices[j].k,
|
||||
reflections[i].indices[j].l);
|
||||
SimIdxPrint(10, "Reflection List and Candidate Indices");
|
||||
SimIdxPrint(10, " N STT U V W");
|
||||
|
||||
for (i = 0; i < nReflections; i++) {
|
||||
SimIdxPrint(10, "%3.3d %8.4f %8.4f %8.4f %8.4f", i,
|
||||
reflections[i].twotheta,
|
||||
reflections[i].uvw[0],
|
||||
reflections[i].uvw[1], reflections[i].uvw[2]);
|
||||
for (j = 0; j < reflections[i].nHKL; j++) {
|
||||
SimIdxPrint(10, "\t%4d %4d %4d",
|
||||
reflections[i].indices[j].h,
|
||||
reflections[i].indices[j].k,
|
||||
reflections[i].indices[j].l);
|
||||
}
|
||||
}
|
||||
SimIdxPrint(10,"Angles between reflections");
|
||||
SimIdxPrint(10,"IDX1 IDX2 Angle");
|
||||
for(i = 0; i < nReflections; i++){
|
||||
for(j = i; j < nReflections; j++){
|
||||
if(i != j){
|
||||
angle = angleBetweenScatVec(reflections[i].UVW, reflections[j].UVW);
|
||||
SimIdxPrint(10,"%3d %3d %8.2f",i,j,angle);
|
||||
}
|
||||
}
|
||||
SimIdxPrint(10, "Angles between reflections");
|
||||
SimIdxPrint(10, "IDX1 IDX2 Angle");
|
||||
for (i = 0; i < nReflections; i++) {
|
||||
for (j = i; j < nReflections; j++) {
|
||||
if (i != j) {
|
||||
angle =
|
||||
angleBetweenScatVec(reflections[i].UVW, reflections[j].UVW);
|
||||
SimIdxPrint(10, "%3d %3d %8.2f", i, j, angle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
static double calculateVolume(double v1[3], double v2[3],
|
||||
double v3[3]){
|
||||
static double calculateVolume(double v1[3], double v2[3], double v3[3])
|
||||
{
|
||||
MATRIX m;
|
||||
int i;
|
||||
double vol;
|
||||
|
||||
m = mat_creat(3,3,ZERO_MATRIX);
|
||||
for(i = 0; i < 3; i++){
|
||||
m = mat_creat(3, 3, ZERO_MATRIX);
|
||||
for (i = 0; i < 3; i++) {
|
||||
m[i][0] = v1[i];
|
||||
m[i][1] = v2[i];
|
||||
m[i][2] = v3[i];
|
||||
@ -297,31 +332,34 @@ static double calculateVolume(double v1[3], double v2[3],
|
||||
mat_free(m);
|
||||
return vol;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
static int areCoplanar(MATRIX v1, MATRIX v2,
|
||||
MATRIX v3){
|
||||
static int areCoplanar(MATRIX v1, MATRIX v2, MATRIX v3)
|
||||
{
|
||||
MATRIX norm;
|
||||
double dot;
|
||||
|
||||
norm = vectorCrossProduct(v1,v2);
|
||||
if(norm != NULL){
|
||||
dot = vectorDotProduct(norm,v3);
|
||||
norm = vectorCrossProduct(v1, v2);
|
||||
if (norm != NULL) {
|
||||
dot = vectorDotProduct(norm, v3);
|
||||
mat_free(norm);
|
||||
} else {
|
||||
dot = .0;
|
||||
}
|
||||
if(ABS(dot) > .00001){
|
||||
if (ABS(dot) > .00001) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* - We want the shortest vectors
|
||||
* - We do not want vectors at 180 to each other
|
||||
* - We do not want the three vectors to be coplanar
|
||||
*-------------------------------------------------------------*/
|
||||
static int chooseTriplet(int triplet[3]){
|
||||
static int chooseTriplet(int triplet[3])
|
||||
{
|
||||
double angle, vol;
|
||||
int idx = 1;
|
||||
|
||||
@ -329,36 +367,36 @@ static int chooseTriplet(int triplet[3]){
|
||||
/*
|
||||
* test for 180
|
||||
*/
|
||||
while(idx < nReflections){
|
||||
angle = angleBetweenScatVec(reflections[0].UVW,
|
||||
reflections[idx].UVW);
|
||||
if(angle < 160 && angle > -160){
|
||||
while (idx < nReflections) {
|
||||
angle = angleBetweenScatVec(reflections[0].UVW, reflections[idx].UVW);
|
||||
if (angle < 160 && angle > -160) {
|
||||
triplet[1] = idx;
|
||||
break;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
if(idx >= nReflections){
|
||||
SimIdxPrint(1,"ERROR: no second index found");
|
||||
if (idx >= nReflections) {
|
||||
SimIdxPrint(1, "ERROR: no second index found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(idx = 1; idx < nReflections; idx++){
|
||||
if(idx != triplet[1]) {
|
||||
if(!areCoplanar(reflections[triplet[0]].UVW,
|
||||
reflections[triplet[1]].UVW,
|
||||
reflections[idx].UVW)){
|
||||
triplet[2] = idx;
|
||||
return 1;
|
||||
for (idx = 1; idx < nReflections; idx++) {
|
||||
if (idx != triplet[1]) {
|
||||
if (!areCoplanar(reflections[triplet[0]].UVW,
|
||||
reflections[triplet[1]].UVW,
|
||||
reflections[idx].UVW)) {
|
||||
triplet[2] = idx;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
SimIdxPrint(1,"ERROR: no three non coplanar reflections found");
|
||||
SimIdxPrint(1, "ERROR: no three non coplanar reflections found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------*/
|
||||
static double reflectionsAngle(MATRIX B, int hkl1[3],
|
||||
int hkl2[3]){
|
||||
static double reflectionsAngle(MATRIX B, int hkl1[3], int hkl2[3])
|
||||
{
|
||||
double angle;
|
||||
reflection r1, r2;
|
||||
|
||||
@ -370,45 +408,48 @@ int hkl2[3]){
|
||||
r2.k = hkl2[1];
|
||||
r2.l = hkl2[2];
|
||||
|
||||
return angleBetweenReflections(B,r1,r2);
|
||||
return angleBetweenReflections(B, r1, r2);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
static int findAngleMatch(MATRIX B, int idxr1, int r1,
|
||||
int r2start, int r2, double *diff){
|
||||
static int findAngleMatch(MATRIX B, int idxr1, int r1,
|
||||
int r2start, int r2, double *diff)
|
||||
{
|
||||
double scatAngle, hklAngle;
|
||||
MATRIX H1, H2;
|
||||
int i, r, hkl1[3], hkl2[3];
|
||||
|
||||
scatAngle = angleBetweenScatVec(reflections[r1].UVW,
|
||||
reflections[r2].UVW);
|
||||
scatAngle = angleBetweenScatVec(reflections[r1].UVW,
|
||||
reflections[r2].UVW);
|
||||
hkl1[0] = reflections[r1].indices[idxr1].h;
|
||||
hkl1[1] = reflections[r1].indices[idxr1].k;
|
||||
hkl1[2] = reflections[r1].indices[idxr1].l;
|
||||
|
||||
for(i = r2start; i < reflections[r2].nHKL; i++){
|
||||
for (i = r2start; i < reflections[r2].nHKL; i++) {
|
||||
hkl2[0] = reflections[r2].indices[i].h;
|
||||
hkl2[1] = reflections[r2].indices[i].k;
|
||||
hkl2[2] = reflections[r2].indices[i].l;
|
||||
hklAngle = reflectionsAngle(B,hkl1, hkl2);
|
||||
hklAngle = reflectionsAngle(B, hkl1, hkl2);
|
||||
*diff = ABS(scatAngle - hklAngle);
|
||||
if(*diff < anglim){
|
||||
if (*diff < anglim) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
* If the system is right handed the determinat of the
|
||||
* matrix having the indices as columns must be positive
|
||||
-------------------------------------------------------------*/
|
||||
static int testRightHandedness(int r1, int r1idx,
|
||||
int r2, int r2idx,
|
||||
int r3, int r3idx){
|
||||
static int testRightHandedness(int r1, int r1idx,
|
||||
int r2, int r2idx, int r3, int r3idx)
|
||||
{
|
||||
MATRIX T;
|
||||
double vol;
|
||||
|
||||
T = mat_creat(3,3,ZERO_MATRIX);
|
||||
if(T == NULL){
|
||||
T = mat_creat(3, 3, ZERO_MATRIX);
|
||||
if (T == NULL) {
|
||||
return 0;
|
||||
}
|
||||
T[0][0] = reflections[r1].indices[r1idx].h;
|
||||
@ -422,30 +463,32 @@ static int testRightHandedness(int r1, int r1idx,
|
||||
T[2][2] = reflections[r3].indices[r3idx].l;
|
||||
vol = mat_det(T);
|
||||
mat_free(T);
|
||||
if(vol > .0){
|
||||
if (vol > .0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
static void storeSolution(int r1, int r1idx,
|
||||
int r2, int r2idx,
|
||||
int r3, int r3idx, double diff){
|
||||
static void storeSolution(int r1, int r1idx,
|
||||
int r2, int r2idx,
|
||||
int r3, int r3idx, double diff)
|
||||
{
|
||||
IndexSolution is;
|
||||
is.h[0] = reflections[r1].indices[r1idx].h;
|
||||
is.k[0] = reflections[r1].indices[r1idx].k;
|
||||
is.l[0] = reflections[r1].indices[r1idx].l;
|
||||
is.originalID[0] = reflections[r1].originalID;
|
||||
is.diff = reflections[r1].indices[r1idx].diff;
|
||||
|
||||
|
||||
is.h[1] = reflections[r2].indices[r2idx].h;
|
||||
is.k[1] = reflections[r2].indices[r2idx].k;
|
||||
is.l[1] = reflections[r2].indices[r2idx].l;
|
||||
is.originalID[1] = reflections[r2].originalID;
|
||||
is.diff += reflections[r2].indices[r2idx].diff;
|
||||
|
||||
if(r3 != 999){
|
||||
if (r3 != 999) {
|
||||
is.h[2] = reflections[r3].indices[r3idx].h;
|
||||
is.k[2] = reflections[r3].indices[r3idx].k;
|
||||
is.l[2] = reflections[r3].indices[r3idx].l;
|
||||
@ -458,21 +501,23 @@ static void storeSolution(int r1, int r1idx,
|
||||
is.originalID[2] = 999;
|
||||
}
|
||||
is.diff += diff;
|
||||
|
||||
|
||||
solutions[nSolutions] = is;
|
||||
nSolutions++;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
static int compareSolution(const void *d1, const void *d2){
|
||||
static int compareSolution(const void *d1, const void *d2)
|
||||
{
|
||||
IndexSolution *iv1, *iv2;
|
||||
|
||||
iv1 = (IndexSolution *)d1;
|
||||
iv2 = (IndexSolution *)d2;
|
||||
iv1 = (IndexSolution *) d1;
|
||||
iv2 = (IndexSolution *) d2;
|
||||
|
||||
if(iv1->diff == iv2->diff) {
|
||||
if (iv1->diff == iv2->diff) {
|
||||
return 0;
|
||||
}
|
||||
if(iv1->diff < iv2->diff){
|
||||
if (iv1->diff < iv2->diff) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
@ -480,7 +525,8 @@ static int compareSolution(const void *d1, const void *d2){
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
static int findSolutionsForTriplet(int triplet[3], int testRight){
|
||||
static int findSolutionsForTriplet(int triplet[3], int testRight)
|
||||
{
|
||||
int r1, r2, r3, i, status;
|
||||
int match1, match2, r2start, r3start;
|
||||
double diff1, diff2;
|
||||
@ -490,54 +536,55 @@ static int findSolutionsForTriplet(int triplet[3], int testRight){
|
||||
r2 = triplet[1];
|
||||
r3 = triplet[2];
|
||||
|
||||
B = mat_creat(3,3,UNIT_MATRIX);
|
||||
if(B == NULL){
|
||||
SimIdxPrint(1,"ERROR: out of memory calculating B matrix");
|
||||
B = mat_creat(3, 3, UNIT_MATRIX);
|
||||
if (B == NULL) {
|
||||
SimIdxPrint(1, "ERROR: out of memory calculating B matrix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = calculateBMatrix(direct,B);
|
||||
if(status < 0) {
|
||||
SimIdxPrint(1,"ERROR: invalid cell constants, failed to calculate B matrix");
|
||||
status = calculateBMatrix(direct, B);
|
||||
if (status < 0) {
|
||||
SimIdxPrint(1,
|
||||
"ERROR: invalid cell constants, failed to calculate B matrix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < reflections[r1].nHKL; i++){
|
||||
for (i = 0; i < reflections[r1].nHKL; i++) {
|
||||
r2start = 0;
|
||||
while((match1 = findAngleMatch(B, i, r1, r2start, r2,&diff1)) >=0){
|
||||
while ((match1 = findAngleMatch(B, i, r1, r2start, r2, &diff1)) >= 0) {
|
||||
r3start = 0;
|
||||
while((match2 = findAngleMatch(B, i, r1, r3start, r3,&diff2)) >= 0){
|
||||
if(testRight == 1){
|
||||
if(testRightHandedness(r1, i, r2, match1, r3, match2)){
|
||||
storeSolution(r1,i,r2,match1, r3,match2, diff1 + diff2);
|
||||
}
|
||||
} else {
|
||||
storeSolution(r1,i,r2,match1, r3,match2, diff1 + diff2);
|
||||
}
|
||||
r3start = match2 + 1;
|
||||
while ((match2 = findAngleMatch(B, i, r1, r3start, r3, &diff2)) >= 0) {
|
||||
if (testRight == 1) {
|
||||
if (testRightHandedness(r1, i, r2, match1, r3, match2)) {
|
||||
storeSolution(r1, i, r2, match1, r3, match2, diff1 + diff2);
|
||||
}
|
||||
} else {
|
||||
storeSolution(r1, i, r2, match1, r3, match2, diff1 + diff2);
|
||||
}
|
||||
r3start = match2 + 1;
|
||||
}
|
||||
r2start = match1 + 1;
|
||||
}
|
||||
}
|
||||
qsort(solutions,nSolutions, sizeof(IndexSolution),
|
||||
compareSolution);
|
||||
|
||||
qsort(solutions, nSolutions, sizeof(IndexSolution), compareSolution);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------
|
||||
* If the system is right handed the determinat of the
|
||||
* matrix having the indices as columns must be positive.
|
||||
* As I have only two vectors, I simulate the third by
|
||||
* using the nromal on the other two.
|
||||
-------------------------------------------------------------*/
|
||||
static int testDuoRightHandedness(int r1, int r1idx,
|
||||
int r2, int r2idx){
|
||||
static int testDuoRightHandedness(int r1, int r1idx, int r2, int r2idx)
|
||||
{
|
||||
MATRIX T;
|
||||
double vol;
|
||||
int r3, r3idx;
|
||||
|
||||
T = mat_creat(3,3,ZERO_MATRIX);
|
||||
if(T == NULL){
|
||||
T = mat_creat(3, 3, ZERO_MATRIX);
|
||||
if (T == NULL) {
|
||||
return 0;
|
||||
}
|
||||
T[0][0] = reflections[r1].indices[r1idx].h;
|
||||
@ -551,92 +598,102 @@ static int testDuoRightHandedness(int r1, int r1idx,
|
||||
T[2][2] = reflections[r3].indices[r3idx].l;
|
||||
vol = mat_det(T);
|
||||
mat_free(T);
|
||||
if(vol > .0){
|
||||
if (vol > .0) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
static int findSolutionsForDuett(int triplet[3]){
|
||||
static int findSolutionsForDuett(int triplet[3])
|
||||
{
|
||||
MATRIX B;
|
||||
int r1, r2, r2start, i, status, match1;
|
||||
double diff;
|
||||
|
||||
if(triplet[1] == 999){
|
||||
SimIdxPrint(1,"ERROR: No suitable reflection set found");
|
||||
|
||||
if (triplet[1] == 999) {
|
||||
SimIdxPrint(1, "ERROR: No suitable reflection set found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
r1 = triplet[0];
|
||||
r2 = triplet[1];
|
||||
|
||||
B = mat_creat(3,3,UNIT_MATRIX);
|
||||
if(B == NULL){
|
||||
SimIdxPrint(1,"ERROR: out of memory calculating B matrix");
|
||||
|
||||
B = mat_creat(3, 3, UNIT_MATRIX);
|
||||
if (B == NULL) {
|
||||
SimIdxPrint(1, "ERROR: out of memory calculating B matrix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
status = calculateBMatrix(direct,B);
|
||||
if(status < 0) {
|
||||
SimIdxPrint(1,"ERROR: invalid cell constants, failed to calculate B matrix");
|
||||
status = calculateBMatrix(direct, B);
|
||||
if (status < 0) {
|
||||
SimIdxPrint(1,
|
||||
"ERROR: invalid cell constants, failed to calculate B matrix");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < reflections[r1].nHKL; i++){
|
||||
for (i = 0; i < reflections[r1].nHKL; i++) {
|
||||
r2start = 0;
|
||||
while((match1 = findAngleMatch(B, i, r1, r2start, r2,&diff)) >=0){
|
||||
storeSolution(r1,i,r2,match1,999,0,diff);
|
||||
while ((match1 = findAngleMatch(B, i, r1, r2start, r2, &diff)) >= 0) {
|
||||
storeSolution(r1, i, r2, match1, 999, 0, diff);
|
||||
r2start = match1 + 1;
|
||||
}
|
||||
}
|
||||
qsort(solutions,nSolutions, sizeof(IndexSolution),
|
||||
compareSolution);
|
||||
qsort(solutions, nSolutions, sizeof(IndexSolution), compareSolution);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
* This is used if we cannot find a solution for a triplet.
|
||||
* Then we try to reduce to a duett. So we look for a second
|
||||
* reflection in the original triplett which is closest
|
||||
* to 90 degree in angle.
|
||||
*/
|
||||
static int secondForDuett(int triplet[3]){
|
||||
double diff1, diff2;
|
||||
|
||||
diff1 = ABS(90. - angleBetweenScatVec(
|
||||
reflections[triplet[0]].UVW,reflections[triplet[1]].UVW));
|
||||
diff2 = ABS(90. - angleBetweenScatVec(
|
||||
reflections[triplet[0]].UVW,reflections[triplet[2]].UVW));
|
||||
if(diff1 < diff2){
|
||||
return triplet[1];
|
||||
} else {
|
||||
return triplet[2];
|
||||
}
|
||||
}
|
||||
/*--------------------------------------------------------------*/
|
||||
int SimIdxRun(){
|
||||
int triplet[3] = {999,999,999}, status;
|
||||
*/
|
||||
static int secondForDuett(int triplet[3])
|
||||
{
|
||||
double diff1, diff2;
|
||||
|
||||
SimIdxPrint(10,"SimIdx calculating with parameters:");
|
||||
SimIdxPrint(10, "Cell = %f %f %f %f %f %f", direct.a, direct.b, direct.c,
|
||||
direct.alpha, direct.beta, direct.gamma);
|
||||
SimIdxPrint(10,"Lambda = %f", lambda);
|
||||
SimIdxPrint(10,"Sttlim, anglim = %f %f", sttlim, anglim);
|
||||
diff1 =
|
||||
ABS(90. -
|
||||
angleBetweenScatVec(reflections[triplet[0]].UVW,
|
||||
reflections[triplet[1]].UVW));
|
||||
diff2 =
|
||||
ABS(90. -
|
||||
angleBetweenScatVec(reflections[triplet[0]].UVW,
|
||||
reflections[triplet[2]].UVW));
|
||||
if (diff1 < diff2) {
|
||||
return triplet[1];
|
||||
} else {
|
||||
return triplet[2];
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
int SimIdxRun()
|
||||
{
|
||||
int triplet[3] = { 999, 999, 999 }, status;
|
||||
|
||||
SimIdxPrint(10, "SimIdx calculating with parameters:");
|
||||
SimIdxPrint(10, "Cell = %f %f %f %f %f %f", direct.a, direct.b, direct.c,
|
||||
direct.alpha, direct.beta, direct.gamma);
|
||||
SimIdxPrint(10, "Lambda = %f", lambda);
|
||||
SimIdxPrint(10, "Sttlim, anglim = %f %f", sttlim, anglim);
|
||||
|
||||
nSolutions = 0;
|
||||
|
||||
calcRefTheta();
|
||||
|
||||
if(!calcIndexes()){
|
||||
if (!calcIndexes()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(outLevel >= 10){
|
||||
if (outLevel >= 10) {
|
||||
printRefDiagnostic();
|
||||
}
|
||||
|
||||
if(nReflections >= 3){
|
||||
if(!chooseTriplet(triplet)){
|
||||
if (nReflections >= 3) {
|
||||
if (!chooseTriplet(triplet)) {
|
||||
return findSolutionsForDuett(triplet);
|
||||
}
|
||||
} else {
|
||||
@ -645,30 +702,35 @@ int SimIdxRun(){
|
||||
return findSolutionsForDuett(triplet);
|
||||
}
|
||||
|
||||
SimIdxPrint(10,"Choosen triplet: %d, %d, %d\n", triplet[0],
|
||||
triplet[1], triplet[2]);
|
||||
SimIdxPrint(10, "Choosen triplet: %d, %d, %d\n", triplet[0],
|
||||
triplet[1], triplet[2]);
|
||||
|
||||
status = findSolutionsForTriplet(triplet,1);
|
||||
if(nSolutions == 0){
|
||||
SimIdxPrint(1,"WARNING: found no right handed solution set, trying to find lefthanded");
|
||||
status = findSolutionsForTriplet(triplet,0);
|
||||
status = findSolutionsForTriplet(triplet, 1);
|
||||
if (nSolutions == 0) {
|
||||
SimIdxPrint(1,
|
||||
"WARNING: found no right handed solution set, trying to find lefthanded");
|
||||
status = findSolutionsForTriplet(triplet, 0);
|
||||
}
|
||||
if(nSolutions == 0){
|
||||
SimIdxPrint(10,"Failed to find solution for triplet, trying duett");
|
||||
status = secondForDuett(triplet);
|
||||
triplet[1] = status;
|
||||
status = findSolutionsForDuett(triplet);
|
||||
if (nSolutions == 0) {
|
||||
SimIdxPrint(10, "Failed to find solution for triplet, trying duett");
|
||||
status = secondForDuett(triplet);
|
||||
triplet[1] = status;
|
||||
status = findSolutionsForDuett(triplet);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/*=========================== solution retrieval ===================*/
|
||||
int SimIdxGetNSolutions(){
|
||||
int SimIdxGetNSolutions()
|
||||
{
|
||||
return nSolutions;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*/
|
||||
IndexSolution SimIdxGetSolution(int id){
|
||||
IndexSolution SimIdxGetSolution(int id)
|
||||
{
|
||||
IndexSolution broken;
|
||||
if(id >= 0 && id < nSolutions){
|
||||
if (id >= 0 && id < nSolutions) {
|
||||
return solutions[id];
|
||||
}
|
||||
broken.h[0] = -999;
|
||||
@ -676,4 +738,3 @@ IndexSolution SimIdxGetSolution(int id){
|
||||
broken.h[2] = -999;
|
||||
return broken;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user