- 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:
koennecke
2009-03-16 14:24:34 +00:00
parent 299ad44be3
commit 3e8b11675a
15 changed files with 948 additions and 2519 deletions

View File

@ -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;
}