201 lines
5.1 KiB
C
201 lines
5.1 KiB
C
/*---------------------------------------------------------------------------
|
|
F O U R T A B L E
|
|
|
|
A SICS object which holds the variation of scan parameters for four circle
|
|
reflection list measurements.
|
|
copyright: see copyright.h
|
|
|
|
Mark Koennecke, February 2005
|
|
|
|
Massively reworked to make use of the new hdbtable object.
|
|
|
|
Mark Koennecke, March 2009
|
|
---------------------------------------------------------------------------*/
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include "sics.h"
|
|
#include "hdbtable.h"
|
|
#include <sicshipadaba.h>
|
|
#include "fourtable.h"
|
|
/*==================== functions =======================================*/
|
|
pSICSOBJ MakeFourCircleTable()
|
|
{
|
|
pSICSOBJ table = NULL;
|
|
pHdb node = NULL;
|
|
|
|
table = MakeHdbTable("fmesstable","FourMess");
|
|
node = GetHipadabaNode(table->objectNode,"template");
|
|
assert(node != NULL);
|
|
AddSICSHdbPar(node, "endTTH", usUser, MakeHdbFloat(.0));
|
|
AddSICSHdbPar(node, "scanvar", usUser, MakeHdbText(""));
|
|
AddSICSHdbPar(node, "step", usUser, MakeHdbFloat(.0));
|
|
AddSICSHdbPar(node, "np", usUser, MakeHdbInt(0));
|
|
AddSICSHdbPar(node, "preset", usUser, MakeHdbFloat(.0));
|
|
ReadTableTemplate(table, NULL);
|
|
return table;
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
void DeleteFourCircleTable(pSICSOBJ data)
|
|
{
|
|
KillSICSOBJ(data);
|
|
}
|
|
/*---------------------------------------------------------------------
|
|
Make sure that the entry is added in a sorted way according to two_theta
|
|
----------------------------------------------------------------------*/
|
|
static int rowCompare(const void *r1, const void *r2)
|
|
{
|
|
pHdb *row1, *row2;
|
|
pHdb tth1, tth2;
|
|
|
|
row1 = (pHdb *)r1;
|
|
row2 = (pHdb *)r2;
|
|
tth1 = GetHipadabaNode(*row1,"endTTH");
|
|
tth2 = GetHipadabaNode(*row2,"endTTH");
|
|
assert(tth1 != NULL && tth2 != NULL);
|
|
if(tth1->value.v.doubleValue < tth2->value.v.doubleValue){
|
|
return -1;
|
|
} else if(tth1->value.v.doubleValue > tth2->value.v.doubleValue){
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
/*--------------------------------------------------------------------*/
|
|
static void sortFourTable(pSICSOBJ self)
|
|
{
|
|
pHdb data, *dataArray, child;
|
|
int count, i;
|
|
char number[10];
|
|
|
|
data = GetHipadabaNode(self->objectNode,"data");
|
|
assert(data != NULL);
|
|
count = CountHdbChildren(data);
|
|
if(count <= 1){
|
|
return;
|
|
}
|
|
|
|
dataArray = malloc(count*sizeof(pHdb));
|
|
if(dataArray == NULL){
|
|
return;
|
|
}
|
|
child = data->child;
|
|
count = 0;
|
|
while(child != NULL){
|
|
dataArray[count] = child;
|
|
count++;
|
|
child = child->next;
|
|
}
|
|
|
|
qsort(dataArray, count, sizeof(pHdb), rowCompare);
|
|
|
|
data->child = NULL;
|
|
for(i = 0; i < count; i++){
|
|
snprintf(number,10,"%4.4d", i);
|
|
child = dataArray[i];
|
|
if(child->name != NULL){
|
|
free(child->name);
|
|
}
|
|
child->name = strdup(number);
|
|
AddHipadabaChild(data,child, NULL);
|
|
}
|
|
free(dataArray);
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
int HandleFourCircleCommands(pSICSOBJ self, SConnection * pCon,
|
|
int argc, char *argv[], int *err)
|
|
{
|
|
int status;
|
|
/*
|
|
test if this is for us
|
|
*/
|
|
if (argc >= 3) {
|
|
strtolower(argv[1]);
|
|
if (strcmp(argv[1], "table") != 0) {
|
|
return 0;
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
|
|
status = InvokeSICSOBJ(pCon,pServ->pSics,self,argc-1,&argv[1]);
|
|
if(strcmp(argv[2],"addrow") == 0){
|
|
sortFourTable(self);
|
|
}
|
|
return status;
|
|
}
|
|
/*-----------------------------------------------------------------------*/
|
|
static pHdb findEntry(pSICSOBJ self, double two_theta)
|
|
{
|
|
pHdb data, row, tth;
|
|
|
|
data = GetHipadabaNode(self->objectNode,"data");
|
|
assert(data != NULL);
|
|
row = data->child;
|
|
while(row != NULL){
|
|
tth = GetHipadabaNode(row,"endTTH");
|
|
if(tth != NULL){
|
|
if(tth->value.v.doubleValue > two_theta){
|
|
return row;
|
|
}
|
|
}
|
|
row = row->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
char *GetFourCircleScanVar(pSICSOBJ handle, double two_theta)
|
|
{
|
|
pHdb row, val;
|
|
|
|
row = findEntry(handle, two_theta);
|
|
if(row != NULL){
|
|
val = GetHipadabaNode(row,"scanvar");
|
|
if(val != NULL){
|
|
return strdup(val->value.v.text);
|
|
}
|
|
}
|
|
return strdup("Not found");
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
double GetFourCircleStep(pSICSOBJ handle, double two_theta)
|
|
{
|
|
pHdb row, val;
|
|
|
|
row = findEntry(handle, two_theta);
|
|
if(row != NULL){
|
|
val = GetHipadabaNode(row,"step");
|
|
if(val != NULL){
|
|
return val->value.v.doubleValue;
|
|
}
|
|
}
|
|
return -999.99;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
float GetFourCirclePreset(pSICSOBJ handle, double two_theta)
|
|
{
|
|
pHdb row, val;
|
|
|
|
row = findEntry(handle, two_theta);
|
|
if(row != NULL){
|
|
val = GetHipadabaNode(row,"preset");
|
|
if(val != NULL){
|
|
return val->value.v.doubleValue;
|
|
}
|
|
}
|
|
return -999.99;
|
|
}
|
|
/*------------------------------------------------------------------------*/
|
|
int GetFourCircleScanNP(pSICSOBJ handle, double two_theta)
|
|
{
|
|
pHdb row, val;
|
|
|
|
row = findEntry(handle, two_theta);
|
|
if(row != NULL){
|
|
val = GetHipadabaNode(row,"np");
|
|
if(val != NULL){
|
|
return val->value.v.intValue;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|