- Introduced a general Hipadaba table module and modified the four
circle codes to use it. - Added to functions to histmem, getdelay and formattof, to support new HM - Removed obsolete mesure.*
This commit is contained in:
432
fourtable.c
432
fourtable.c
@ -6,196 +6,105 @@
|
||||
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 "fortify.h"
|
||||
#include "lld.h"
|
||||
#include <tcl.h>
|
||||
#include "splitter.h"
|
||||
#include "hdbtable.h"
|
||||
#include <sicshipadaba.h>
|
||||
#include "fourtable.h"
|
||||
/*====================== table entry ===================================*/
|
||||
typedef struct {
|
||||
double twoThetaEnd;
|
||||
char scanVar[30];
|
||||
double step;
|
||||
int np;
|
||||
float preset;
|
||||
} FourTableEntry, *pFourTableEntry;
|
||||
/*==================== functions =======================================*/
|
||||
int MakeFourCircleTable()
|
||||
pSICSOBJ MakeFourCircleTable()
|
||||
{
|
||||
return LLDcreate(sizeof(FourTableEntry));
|
||||
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(int handle)
|
||||
void DeleteFourCircleTable(pSICSOBJ data)
|
||||
{
|
||||
LLDdelete(handle);
|
||||
KillSICSOBJ(data);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
static void printList(int handle, SConnection * pCon)
|
||||
{
|
||||
FourTableEntry entry;
|
||||
char pBueffel[132];
|
||||
int status, printed = 0;
|
||||
Tcl_DString list;
|
||||
|
||||
Tcl_DStringInit(&list);
|
||||
status = LLDnodePtr2First(handle);
|
||||
while (status == 1) {
|
||||
LLDnodeDataTo(handle, &entry);
|
||||
snprintf(pBueffel, 131, "%8.3f %10s %8.3f %d %8.3f\n",
|
||||
entry.twoThetaEnd, entry.scanVar, entry.step, entry.np,
|
||||
entry.preset);
|
||||
Tcl_DStringAppend(&list, pBueffel, -1);
|
||||
printed = 1;
|
||||
status = LLDnodePtr2Next(handle);
|
||||
}
|
||||
if (printed == 0) {
|
||||
Tcl_DStringAppend(&list, "table is empty", -1);
|
||||
}
|
||||
SCWrite(pCon, Tcl_DStringValue(&list), eValue);
|
||||
Tcl_DStringFree(&list);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
Make sure that the entry is added in a sorted way according to two_theta
|
||||
----------------------------------------------------------------------*/
|
||||
static void insertEntry(int list, FourTableEntry newEntry)
|
||||
----------------------------------------------------------------------*/
|
||||
static int rowCompare(const void *r1, const void *r2)
|
||||
{
|
||||
int status, count = 0, pos;
|
||||
FourTableEntry test;
|
||||
|
||||
/*
|
||||
locate the last entry bigger then us
|
||||
*/
|
||||
status = LLDnodePtr2First(list);
|
||||
while (status == 1) {
|
||||
LLDnodeDataTo(list, &test);
|
||||
count++;
|
||||
if (test.twoThetaEnd == newEntry.twoThetaEnd) {
|
||||
LLDnodeDataFrom(list, &newEntry);
|
||||
return;
|
||||
}
|
||||
if (test.twoThetaEnd > newEntry.twoThetaEnd) {
|
||||
break;
|
||||
}
|
||||
status = LLDnodePtr2Next(list);
|
||||
}
|
||||
/*
|
||||
special case: empty list
|
||||
*/
|
||||
if (count == 0) {
|
||||
LLDnodeAppendFrom(list, &newEntry);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
special case: append after last
|
||||
*/
|
||||
LLDnodePtr2Last(list);
|
||||
LLDnodeDataTo(list, &test);
|
||||
if (newEntry.twoThetaEnd > test.twoThetaEnd) {
|
||||
LLDnodeAppendFrom(list, &newEntry);
|
||||
return;
|
||||
}
|
||||
|
||||
status = LLDnodePtr2First(list);
|
||||
pos = 0;
|
||||
while (status == 1) {
|
||||
LLDnodeDataTo(list, &test);
|
||||
pos++;
|
||||
if (pos == count) {
|
||||
LLDnodeInsertFrom(list, &newEntry);
|
||||
return;
|
||||
}
|
||||
status = LLDnodePtr2Next(list);
|
||||
}
|
||||
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 int addToList(int handle, SConnection * pCon, int argc,
|
||||
char *argv[])
|
||||
/*--------------------------------------------------------------------*/
|
||||
static void sortFourTable(pSICSOBJ self)
|
||||
{
|
||||
FourTableEntry entry;
|
||||
char pBueffel[132];
|
||||
|
||||
if (argc < 7) {
|
||||
SCWrite(pCon, "ERROR: not enough arguments to table add", eError);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (isNumeric(argv[3])) {
|
||||
entry.twoThetaEnd = atof(argv[3]);
|
||||
} else {
|
||||
snprintf(pBueffel, 131,
|
||||
"ERROR: expected numeric argument, received %s", argv[3]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
strncpy(entry.scanVar, argv[4], 29);
|
||||
strtolower(entry.scanVar);
|
||||
if (strcmp(entry.scanVar, "om") != 0
|
||||
&& strstr(entry.scanVar, "o2t") == NULL) {
|
||||
SCWrite(pCon,
|
||||
"ERROR: Invalied scan variable specified, only om, o2t allowed",
|
||||
eError);
|
||||
return 0;
|
||||
}
|
||||
if (isNumeric(argv[5])) {
|
||||
entry.step = atof(argv[5]);
|
||||
} else {
|
||||
snprintf(pBueffel, 131,
|
||||
"ERROR: expected numeric argument, received %s", argv[4]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
if (isNumeric(argv[6])) {
|
||||
entry.np = atoi(argv[6]);
|
||||
} else {
|
||||
snprintf(pBueffel, 131,
|
||||
"ERROR: expected numeric argument, received %s", argv[6]);
|
||||
SCWrite(pCon, pBueffel, eError);
|
||||
return 0;
|
||||
}
|
||||
entry.preset = -1.0;
|
||||
if (argc > 7) {
|
||||
if (isNumeric(argv[7])) {
|
||||
entry.preset = atof(argv[7]);
|
||||
}
|
||||
}
|
||||
insertEntry(handle, entry);
|
||||
return 1;
|
||||
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);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static void delEntry(int handle, int index)
|
||||
{
|
||||
int count = 0, status;
|
||||
|
||||
status = LLDnodePtr2First(handle);
|
||||
while (status == 1) {
|
||||
if (count == index) {
|
||||
LLDnodeDelete(handle);
|
||||
break;
|
||||
} else {
|
||||
count++;
|
||||
status = LLDnodePtr2Next(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
int HandleFourCircleCommands(int *table, SConnection * pCon,
|
||||
int HandleFourCircleCommands(pSICSOBJ self, SConnection * pCon,
|
||||
int argc, char *argv[], int *err)
|
||||
{
|
||||
int handle;
|
||||
|
||||
*err = 1;
|
||||
handle = *table;
|
||||
|
||||
int status;
|
||||
/*
|
||||
test if this is for us
|
||||
*/
|
||||
@ -208,141 +117,84 @@ int HandleFourCircleCommands(int *table, SConnection * pCon,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
what are we supposed to do?
|
||||
*/
|
||||
strtolower(argv[2]);
|
||||
if (strcmp(argv[2], "clear") == 0) {
|
||||
if (!SCMatchRights(pCon, usUser)) {
|
||||
*err = 0;
|
||||
return 1;
|
||||
}
|
||||
LLDdelete(handle);
|
||||
handle = LLDcreate(sizeof(FourTableEntry));
|
||||
*table = handle;
|
||||
SCparChange(pCon);
|
||||
SCSendOK(pCon);
|
||||
} else if (strcmp(argv[2], "list") == 0) {
|
||||
printList(handle, pCon);
|
||||
} else if (strcmp(argv[2], "add") == 0) {
|
||||
if (!SCMatchRights(pCon, usUser)) {
|
||||
*err = 0;
|
||||
return 1;
|
||||
}
|
||||
*err = addToList(handle, pCon, argc, argv);
|
||||
if (*err != 0) {
|
||||
SCparChange(pCon);
|
||||
SCSendOK(pCon);
|
||||
}
|
||||
} else if (strcmp(argv[2], "del") == 0) {
|
||||
if (!SCMatchRights(pCon, usUser)) {
|
||||
*err = 0;
|
||||
return 1;
|
||||
}
|
||||
if (argc < 4) {
|
||||
SCWrite(pCon, "ERROR: insufficnet number of arguments to table del",
|
||||
eError);
|
||||
*err = 0;
|
||||
} else {
|
||||
if (isNumeric(argv[3])) {
|
||||
delEntry(handle, atoi(argv[3]));
|
||||
SCparChange(pCon);
|
||||
SCSendOK(pCon);
|
||||
} else {
|
||||
SCWrite(pCon,
|
||||
"ERROR: bad argument: expected numeric argument to table del",
|
||||
eError);
|
||||
*err = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SCWrite(pCon, "ERROR: subcommand to table not known", eError);
|
||||
*err = 0;
|
||||
status = InvokeSICSOBJ(pCon,pServ->pSics,self,argc-1,&argv[1]);
|
||||
if(strcmp(argv[2],"addrow") == 0){
|
||||
sortFourTable(self);
|
||||
}
|
||||
|
||||
return 1;
|
||||
return status;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static FourTableEntry findEntry(int handle, double two_theta)
|
||||
static pHdb findEntry(pSICSOBJ self, double two_theta)
|
||||
{
|
||||
int status;
|
||||
FourTableEntry entry;
|
||||
|
||||
status = LLDnodePtr2First(handle);
|
||||
while (status == 1) {
|
||||
LLDnodeDataTo(handle, &entry);
|
||||
if (entry.twoThetaEnd > two_theta) {
|
||||
return entry;
|
||||
}
|
||||
status = LLDnodePtr2Next(handle);
|
||||
}
|
||||
strcpy(entry.scanVar, "NOT FOUND");
|
||||
return entry;
|
||||
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(int handle, double two_theta)
|
||||
char *GetFourCircleScanVar(pSICSOBJ handle, double two_theta)
|
||||
{
|
||||
FourTableEntry entry;
|
||||
|
||||
entry = findEntry(handle, two_theta);
|
||||
return strdup(entry.scanVar);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
double GetFourCircleStep(int handle, double two_theta)
|
||||
{
|
||||
FourTableEntry entry;
|
||||
|
||||
entry = findEntry(handle, two_theta);
|
||||
if (strcmp(entry.scanVar, "NOT FOUND") == 0) {
|
||||
return -999.99;
|
||||
} else {
|
||||
return entry.step;
|
||||
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");
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
float GetFourCirclePreset(int handle, double two_theta)
|
||||
double GetFourCircleStep(pSICSOBJ handle, double two_theta)
|
||||
{
|
||||
FourTableEntry entry;
|
||||
|
||||
entry = findEntry(handle, two_theta);
|
||||
if (strcmp(entry.scanVar, "NOT FOUND") == 0) {
|
||||
return -999.99;
|
||||
} else {
|
||||
return entry.preset;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
int GetFourCircleScanNP(int handle, double two_theta)
|
||||
float GetFourCirclePreset(pSICSOBJ handle, double two_theta)
|
||||
{
|
||||
FourTableEntry entry;
|
||||
|
||||
entry = findEntry(handle, two_theta);
|
||||
if (strcmp(entry.scanVar, "NOT FOUND") == 0) {
|
||||
return -999;
|
||||
} else {
|
||||
return entry.np;
|
||||
}
|
||||
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 SaveFourCircleTable(int handle, char *objName, FILE * fd)
|
||||
int GetFourCircleScanNP(pSICSOBJ handle, double two_theta)
|
||||
{
|
||||
FourTableEntry entry;
|
||||
int status;
|
||||
|
||||
fprintf(fd, "%s table clear\n", objName);
|
||||
status = LLDnodePtr2Last(handle);
|
||||
while (status != 0) {
|
||||
LLDnodeDataTo(handle, &entry);
|
||||
fprintf(fd, "%s table add %f %s %f %d %f\n", objName,
|
||||
entry.twoThetaEnd, entry.scanVar,
|
||||
entry.step, entry.np, entry.preset);
|
||||
status = LLDnodePtr2Prev(handle);
|
||||
}
|
||||
return 1;
|
||||
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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user