From 3e8b11675ab267c01d5d7f888add8d1f7c90c5c1 Mon Sep 17 00:00:00 2001 From: koennecke Date: Mon, 16 Mar 2009 14:24:34 +0000 Subject: [PATCH] - 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.* --- fourmess.c | 7 +- fourtable.c | 432 +++++-------- fourtable.h | 16 +- hdbtable.c | 381 ++++++++++++ hdbtable.h | 16 + hipadaba.c | 2 +- hipadaba.h | 7 + histmem.c | 63 +- make_gen | 4 +- mesure.c | 1692 --------------------------------------------------- mesure.h | 45 -- ofac.c | 2 - reflist.c | 765 +++++++++-------------- sicsobj.c | 24 +- sicsobj.h | 11 + 15 files changed, 948 insertions(+), 2519 deletions(-) create mode 100644 hdbtable.c create mode 100644 hdbtable.h delete mode 100644 mesure.c delete mode 100644 mesure.h diff --git a/fourmess.c b/fourmess.c index 78c8bf8a..68d13076 100644 --- a/fourmess.c +++ b/fourmess.c @@ -41,7 +41,7 @@ extern void SNXFormatTime(char *pBueffel, int iLen); typedef struct { FILE *profFile; /* file with reflection profiles, ccl */ FILE *hklFile; /* file with integrated intensities */ - int stepTable; /* table with the scan parameters */ + pSICSOBJ stepTable; /* table with the scan parameters */ char *currentFileRoot; pSICSOBJ messList; pHdb currentRefl; /* the current reflection being measured */ @@ -90,7 +90,7 @@ static int FourMessAction(SConnection * pCon, SicsInterp * pSics, } if (strcmp(argv[1], "table") == 0) { - return HandleFourCircleCommands(&priv->stepTable, pCon, + return HandleFourCircleCommands(priv->stepTable, pCon, argc, argv, &err); } @@ -774,7 +774,7 @@ static int FourMessSave(void *data, char *name, FILE * fd) pFourMess priv = self->pPrivate; SaveSICSOBJ(data, name, fd); - SaveFourCircleTable(priv->stepTable, name, fd); + priv->stepTable->pDes->SaveStatus(priv->stepTable,"fmess table", fd); return 1; } @@ -878,6 +878,7 @@ void InstallFourMess(SConnection * pCon, SicsInterp * pSics) MakeHipadabaCallback(SetScannerCB, priv, NULL)); priv->pScanner = FindCommandData(pSics, "xxxscan", "ScanObject"); + AddHipadabaChild(pNew->objectNode, priv->stepTable->objectNode,pCon); AddCommand(pSics, "fmess", FourMessAction, KillSICSOBJ, pNew); } diff --git a/fourtable.c b/fourtable.c index 17d4c62e..4236e5b5 100644 --- a/fourtable.c +++ b/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 #include #include "sics.h" -#include "fortify.h" -#include "lld.h" -#include -#include "splitter.h" +#include "hdbtable.h" +#include #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; } diff --git a/fourtable.h b/fourtable.h index a10e2423..35a02f43 100644 --- a/fourtable.h +++ b/fourtable.h @@ -10,15 +10,15 @@ ---------------------------------------------------------------------------*/ #ifndef FOURTABLE #define FOURTABLE +#include -int MakeFourCircleTable(); -void DeleteFourCircleTable(int handle); -int HandleFourCircleCommands(int *handle, SConnection * pCon, +pSICSOBJ MakeFourCircleTable(); +void DeleteFourCircleTable(pSICSOBJ self); +int HandleFourCircleCommands(pSICSOBJ self, SConnection * pCon, int argc, char *argv[], int *err); -char *GetFourCircleScanVar(int handle, double two_theta); -double GetFourCircleStep(int handle, double two_theta); -int SaveFourCircleTable(int handle, char *objName, FILE * fd); -float GetFourCirclePreset(int handle, double twoTheta); -int GetFourCircleScanNP(int handle, double twoTheta); +char *GetFourCircleScanVar(pSICSOBJ self, double two_theta); +double GetFourCircleStep(pSICSOBJ self, double two_theta); +float GetFourCirclePreset(pSICSOBJ self, double twoTheta); +int GetFourCircleScanNP(pSICSOBJ self, double twoTheta); #endif diff --git a/hdbtable.c b/hdbtable.c new file mode 100644 index 00000000..dc90eccb --- /dev/null +++ b/hdbtable.c @@ -0,0 +1,381 @@ +/** + * Hdbtable is a more generic implementation for a table based on a Hipadaba + * tree structure. This table will be used at various instances in SICS. The general + * approach is that there is a child node called template whose children will be + * the nodes describing each column. Another entry called data will hold the + * rows of the table. Each row is a clone of the template. The result is + * an inefficient mapping of a table into a tree. But then, for smaller tables this + * is good enough and fits nicely into the Hipadaba and gumtree schemes. This file + * provides a couple of commands to deal with such tables. A user of this module will + * have to add content to the template first. And then run readtemplate in order + * to activate the new structure. + * + * I use a descriptor key called rowcount for the row ID management rather then + * the private data structure. This leaves clients of this module to use the + * private data structure at will. + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, March 2009 + */ +#include +#include "sicshipadaba.h" +#include +/*------------------------------------------------------------------------*/ +int SaveHdbTable(void *data, char *name, FILE * fd) +{ + pSICSOBJ self = (pSICSOBJ) data; + pHdb datanode, row, child; + pDynString val; + + datanode = GetHipadabaNode(self->objectNode,"data"); + assert(datanode != NULL); + row = datanode->child; + while(row != NULL){ + fprintf(fd,"%s addrow ", name); + child = row->child; + while(child != NULL){ + val = formatValue(child->value, child); + if(val != NULL){ + fprintf(fd," %s", GetCharArray(val)); + DeleteDynString(val); + } + child = child->next; + } + fprintf(fd,"\n"); + row = row->next; + } + return 1; +} +/*------------------------------------------------------------------------*/ +static int ClearTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + pHdb node; + + node = GetHipadabaNode(self->objectNode,"data"); + if(node != NULL){ + DeleteNodeData(node); + RemoveHdbNodeFromParent(node, pCon); + } + node = MakeHipadabaNode("data",HIPNONE,1); + if(node == NULL){ + SCWrite(pCon,"ERROR: out of memory in ClearTblCmd", eError); + return 0; + } + AddHipadabaChild(self->objectNode,node,NULL); + SetDescriptorKey(self->pDes,"rowcount","0"); + if(pCon != NULL){ + SCparChange(pCon); + } + return 1; +} +/*----------------------------------------------------------------------*/ +static int AddTblRowCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + int count; + char *ct, number[10]; + pHdb row, val, child, template; + + ct = GetDescriptorKey(self->pDes,"rowcount"); + count = atoi(ct); + snprintf(number,10,"%4.4d", count); + row = MakeHipadabaNode(number,HIPNONE,1); + if(row == NULL){ + SCWrite(pCon,"ERROR: out of memory in AddTblRow", eError); + return 0; + } + count++; + snprintf(number,10,"%d",count); + SetDescriptorKey(self->pDes,"rowcount",number); + SetHdbProperty(row,"__save","true"); + + template = GetHipadabaNode(self->objectNode,"template"); + assert(template != NULL); + child = template->child; + count = 0; + while(child != NULL){ + val = MakeHipadabaNode(child->name,child->value.dataType, child->value.arrayLength); + if(count < nPar){ + UpdateHipadabaPar(val,par[count]->value,pCon); + } + AddHipadabaChild(row,val, pCon); + SetHdbProperty(val,"__save","true"); + count++; + child = child->next; + } + child = GetHipadabaNode(self->objectNode,"data"); + assert(child != NULL); + AddHipadabaChild(child,row, pCon); + if(pCon != NULL){ + SCparChange(pCon); + } + return 1; +} +/*----------------------------------------------------------------------*/ +static int RepTblRowCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + int count; + char path[132]; + pHdb row, val, child; + + snprintf(path,131,"data/%s", par[0]->value.v.text); + row = GetHipadabaNode(self->objectNode,path); + if(row == NULL){ + SCPrintf(pCon,eError,"ERROR: row with ID %s not found", par[0]->value.v.text); + return 0; + } + + child = row->child; + count = 1; + while(child != NULL){ + if(count < nPar){ + UpdateHipadabaPar(child,par[count]->value,pCon); + } + count++; + child = child->next; + } + if(pCon != NULL){ + SCparChange(pCon); + } + return 1; +} +/*---------------------------------------------------------------------- + * ReadTemplateCmd does something interesting: it rewrites the parameter + * lists of both addrow and reprow according to the template + * ---------------------------------------------------------------------*/ +int ReadTableTemplate(pSICSOBJ self, SConnection *con) +{ + pHdb node, template, child, cmd; + SConnection *pCon = con; + + if(pCon == NULL){ + pCon = pServ->dummyCon; + } + + template = GetHipadabaNode(self->objectNode,"template"); + assert(template != NULL); + + node = GetHipadabaNode(self->objectNode,"addrow"); + if(node != NULL){ + DeleteHipadabaNode(node,pCon); + } + + cmd = AddSICSHdbPar(self->objectNode, "addrow", usUser, + MakeSICSFunc(AddTblRowCmd)); + if(cmd == NULL){ + SCWrite(pCon,"ERROR: out of memory in ReadTemplateCmd",eError ); + return 0; + } + child = template->child; + while(child != NULL){ + node = MakeHipadabaNode(child->name, child->value.dataType, child->value.arrayLength); + if(node == NULL){ + SCWrite(pCon,"ERROR: out of memory in ReadTemplateCmd",eError ); + return 0; + } + AddHipadabaChild(cmd,node,pCon); + child = child->next; + } + + cmd = AddSICSHdbPar(self->objectNode, "reprow", usUser, + MakeSICSFunc(AddTblRowCmd)); + if(cmd == NULL){ + SCWrite(pCon,"ERROR: out of memory in ReadTemplateCmd",eError ); + return 0; + } + node = MakeHipadabaNode("id",HIPTEXT,1); + AddHipadabaChild(cmd,node, pCon); + + child = template->child; + while(child != NULL){ + node = MakeHipadabaNode(child->name, child->value.dataType, child->value.arrayLength); + if(node == NULL){ + SCWrite(pCon,"ERROR: out of memory in ReadTemplateCmd",eError ); + return 0; + } + AddHipadabaChild(cmd,node,pCon); + child = child->next; + } + return 1; +} +/*----------------------------------------------------------------------*/ +static int ReadTemplateCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + return ReadTableTemplate(self,pCon); +} +/*----------------------------------------------------------------------*/ +static int DelRowCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + pHdb row = NULL; + char path[132]; + + if(nPar < 1){ + SCWrite(pCon,"ERROR: need ID of row to kill",eError); + return 0; + } + snprintf(path,132,"data/%s",par[0]->value.v.text); + row = GetHipadabaNode(self->objectNode,path); + if(row == NULL){ + SCPrintf(pCon,eError,"ERROR: row with ID %s not found", par[0]->value.v.text); + return 0; + } + DeleteHipadabaNode(row,pCon); + if(pCon != NULL){ + SCparChange(pCon); + } + SCSendOK(pCon); + return 1; +} +/*----------------------------------------------------------------------*/ +static int GetRowCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + pHdb row = NULL, child; + char path[132]; + pDynString result, val; + + if(nPar < 1){ + SCWrite(pCon,"ERROR: need ID of row to read",eError); + return 0; + } + snprintf(path,132,"data/%s",par[0]->value.v.text); + row = GetHipadabaNode(self->objectNode,path); + if(row == NULL){ + SCPrintf(pCon,eError,"ERROR: row with ID %s not found", par[0]->value.v.text); + return 0; + } + result = CreateDynString(128,128); + if(result == NULL){ + SCWrite(pCon,"ERROR: out of memory in GetRowCmd", eError); + return 0; + } + child = row->child; + while(child != NULL){ + val = formatValue(child->value, child); + if(val != NULL){ + DynStringConcat(result,GetCharArray(val)); + if(child->next != NULL){ + DynStringConcatChar(result,','); + } + DeleteDynString(val); + } + child = child->next; + } + SCWrite(pCon,GetCharArray(result),eValue); + DeleteDynString(result); + return 1; +} +/*----------------------------------------------------------------------*/ +static int ListTblCmd(pSICSOBJ self, SConnection *pCon, pHdb commandNode, + pHdb par[], int nPar) +{ + pHdb node, row, child, data, template; + char buffer[20]; + pDynString list = NULL, val; + + list = CreateDynString(25,256); + if(list == NULL){ + SCWrite(pCon,"ERROR: out of memory in LisTblCmd", eError); + return 0; + } + + /* + * create the list header + */ + DynStringConcat(list," ID"); + template = GetHipadabaNode(self->objectNode,"template"); + assert(template != NULL); + child = template->child; + while(child != NULL){ + snprintf(buffer,20," %8s", child->name); + DynStringConcat(list,buffer); + child = child->next; + } + DynStringConcatChar(list,'\n'); + + data = GetHipadabaNode(self->objectNode,"data"); + assert(data != NULL); + + /* + * list the data + */ + row = data->child; + while(row != NULL){ + snprintf(buffer,20," %8s", row->name); + DynStringConcat(list,buffer); + child = row->child; + while(child != NULL){ + val = formatValue(child->value,child); + snprintf(buffer,20," %8s", GetCharArray(val)); + DynStringConcat(list,buffer); + DeleteDynString(val); + child = child->next; + } + DynStringConcatChar(list,'\n'); + row = row->next; + } + + SCWrite(pCon,GetCharArray(list),eValue); + DeleteDynString(list); + return 1; +} +/*----------------------------------------------------------------------*/ +pSICSOBJ MakeHdbTable(char *name, char *hdbclass) +{ + pSICSOBJ result = NULL; + pHdb node, cmd; + + result = MakeSICSOBJv(name,hdbclass,HIPNONE,usSpy); + if(result == NULL){ + return NULL; + } + SetDescriptorKey(result->pDes,"rowcount","0"); + SetHdbProperty(result->objectNode,"viewer","mountaingumui.TableViewer"); + result->pDes->SaveStatus = SaveHdbTable; + + node = MakeHipadabaNode("template",HIPNONE,1); + if(node == NULL){ + return NULL; + } + SetHdbProperty(node,"__save","true"); + + AddHipadabaChild(result->objectNode,node,NULL); + node = MakeHipadabaNode("data",HIPNONE,1); + if(node == NULL){ + return NULL; + } + SetHdbProperty(node,"__save","true"); + AddHipadabaChild(result->objectNode,node,NULL); + + cmd = AddSICSHdbPar(result->objectNode, "clear", usUser, + MakeSICSFunc(ClearTblCmd)); + + cmd = AddSICSHdbPar(result->objectNode, "print", usUser, + MakeSICSFunc(ListTblCmd)); + + cmd = AddSICSHdbPar(result->objectNode, "addrow", usUser, + MakeSICSFunc(AddTblRowCmd)); + + cmd = AddSICSHdbPar(result->objectNode, "reprow", usUser, + MakeSICSFunc(RepTblRowCmd)); + + cmd = AddSICSHdbPar(result->objectNode, "readtemplate", usUser, + MakeSICSFunc(ReadTemplateCmd)); + + cmd = AddSICSHdbPar(result->objectNode, "del", usUser, + MakeSICSFunc(DelRowCmd)); + node = MakeHipadabaNode("id",HIPTEXT,1); + AddHipadabaChild(cmd,node, NULL); + + cmd = AddSICSHdbPar(result->objectNode, "get", usUser, + MakeSICSFunc(GetRowCmd)); + node = MakeHipadabaNode("id",HIPTEXT,1); + AddHipadabaChild(cmd,node, NULL); + + return result; +} diff --git a/hdbtable.h b/hdbtable.h new file mode 100644 index 00000000..3bf00b80 --- /dev/null +++ b/hdbtable.h @@ -0,0 +1,16 @@ +/** + * Hdbtable is a more generic implementation for a table based on a Hipadaba + * tree structure. This table will be used at various instances in SICS. + * + * copyright: see file COPYRIGHT + * + * Mark Koennecke, March 2009 + */ +#ifndef HDBTABLE_H_ +#define HDBTABLE_H_ +#include + +pSICSOBJ MakeHdbTable(char *name, char *hdbclass); +int ReadTableTemplate(pSICSOBJ self, SConnection *con); + +#endif /*HDBTABLE_H_*/ diff --git a/hipadaba.c b/hipadaba.c index bff09f7c..0f4404f4 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -202,7 +202,7 @@ int InvokeCallbackChain(pHdb node, pHdbMessage message) } /*-----------------------------------------------------------------------*/ -static void SendTreeChangeMessage(pHdb node, void *callData) +void SendTreeChangeMessage(pHdb node, void *callData) { hdbTreeChangeMessage treeChangeMes; treeChangeMes.type = treeChange; diff --git a/hipadaba.h b/hipadaba.h index 554da777..9db6792e 100644 --- a/hipadaba.h +++ b/hipadaba.h @@ -274,6 +274,13 @@ void AddHipadabaChild(pHdb parent, pHdb child, void *callData); * @param node The node to delete. */ void DeleteNodeData(pHdb node); +/** + * Send a treechange message for node. + * @param node The node whose child list has changed + * @param calldata The connection or calldata associated with this operation. + */ +void SendTreeChangeMessage(pHdb node, void *callData); + /** * delete a hipadaba node and all its children. Then invoke the tree * change callback to notify listeners. diff --git a/histmem.c b/histmem.c index 4ad548f0..d7e7b8f4 100644 --- a/histmem.c +++ b/histmem.c @@ -12,6 +12,11 @@ Refactored data handling into separater HMdata class. Mark Koennecke, January 2003 + + Added function to retrieve time delay and to format TOF bin array in order + to speed up TOF configuration for new http based HM's + + Mark Koennecke, March 2009 Copyright: @@ -1034,7 +1039,40 @@ void HMListOption(pHistMem self, SConnection * pCon) } /*--------------------------------------------------------------------------*/ - +static pDynString formatTOF(pHistMem self) +{ + const float *timebin; + int iLength, i, delay, delta; + char number[20]; + pDynString result = NULL; + + timebin = GetHistTimeBin(self, &iLength); + if(timebin != NULL){ + delay = timebin[0]; + result = CreateDynString(512,512); + if(result == NULL){ + return NULL; + } + for(i = 0; i < iLength; i++){ + snprintf(number,20," %12d", (int)(timebin[i] - delay)); + DynStringConcat(result,number); + if(i % 5 == 0 && i != 0){ + DynStringConcatChar(result,'\n'); + } + } + /* + * add the extra one + */ + if(iLength > 3){ + delta = timebin[iLength -2] - timebin[iLength -1]; + } + snprintf(number,20," %12d", (int)(timebin[iLength -1] + delta)); + DynStringConcat(result,number); + return result; + } else { + return NULL; + } +} /*--------------------------------------------------------------------------*/ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]) @@ -1049,6 +1087,7 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData, long lVal; HistInt *lData = NULL; int iStart, iEnd, iNum, i; + pDynString tofres = NULL; CounterMode eCount; char *pMode[] = { "timer", @@ -1527,6 +1566,28 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData, Tcl_DStringFree(&tResult); return 1; } + /* getdelay */ + else if(strcmp(argv[1],"getdelay") == 0){ + if(self->pDriv->data->nTimeChan > 1) { + SCPrintf(pCon,eValue,"hm.delay = %d", self->pDriv->data->timeBinning[0]); + return 1; + } else { + SCPrintf(pCon,eError,"ERROR: no TOF configured"); + return 0; + } + } + /* formattof */ + else if(strcmp(argv[1],"formattof") == 0){ + tofres = formatTOF(self); + if(tofres == NULL){ + SCWrite(pCon,"ERROR: out of memory or not TOF", eError); + return 0; + } else { + SCWrite(pCon,GetCharArray(tofres), eValue); + DeleteDynString(tofres); + return 1; + } + } /* generate time binning */ else if (strcmp(argv[1], "genbin") == 0) { if (isRunning(self->pCountInt)) { diff --git a/make_gen b/make_gen index ab87e66f..32d9377d 100644 --- a/make_gen +++ b/make_gen @@ -18,7 +18,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ danu.o nxdict.o varlog.o stptok.o nread.o trigd.o cell.o\ scan.o fitcenter.o telnet.o token.o wwildcard.o hklmot.o\ tclev.o hkl.o integrate.o optimise.o dynstring.o nxutil.o \ - mesure.o uubuffer.o commandlog.o udpquieck.o fourtable.o\ + uubuffer.o commandlog.o udpquieck.o fourtable.o\ rmtrail.o help.o nxupdate.o confvirtualmot.o vector.o\ simchop.o choco.o chadapter.o trim.o scaldate.o tasub.o\ xytable.o exebuf.o exeman.o ubfour.o ubcalc.o\ @@ -40,7 +40,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.o \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \ singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \ - rwpuffer.o asynnet.o background.o countersec.o + rwpuffer.o asynnet.o background.o countersec.o hdbtable.o MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/mesure.c b/mesure.c deleted file mode 100644 index 3cf5e44d..00000000 --- a/mesure.c +++ /dev/null @@ -1,1692 +0,0 @@ -/*------------------------------------------------------------------------- - M E S U R E - - An object for doing four circle diffractometer measurements with - a single counter. - - copyright: see copyright.h - - Mark Koennecke, April 1998 - heavily reworked: Mark Koennecke, February-March 2005 ----------------------------------------------------------------------------*/ -#include -#include -#include -#include -#include -#include "fortify.h" -#include "sics.h" -#include "motor.h" -#include "o2t.h" -#include "scan.h" -#include "scan.i" -#include "stdscan.h" -#include "danu.h" -#include "integrate.h" -#include "hkl.h" -#include "matrix/matrix.h" -#include "hkl.i" -#include "sicsvar.h" -#include "evcontroller.h" -#include "mesure.h" -#include "nxscript.h" -#include "fourtable.h" -#include "lld.h" -#include "stdscan.h" -#include "exeman.h" - -extern void SNXFormatTime(char *pBueffel, int iLen); -extern float nintf(float f); -#define ANGERR 0.2 - -/* -#define MESSDEBUG 1 - - define MESSDEBUG for simulated peaks. This helps in debugging - this code and the initial data correction code -*/ - -extern void SNXFormatTime(char *pBueffel, int iLen); /* nxutil.c */ - -/*------------------- the data structure -----------------------------------*/ -typedef struct __Mesure { - pObjectDescriptor pDes; /* standard object descriptor */ - pICallBack pCall; /* callback interface for automatic notification */ - pScanData pScanner; /* scan object to use for scans */ - pHKL pCryst; /* hkl object for crystallographic calc - and reflection driving */ - pMotor pOmega; /* motor for omega scans */ - pMotor p2Theta; /* motor for 2 theta scans */ - char *pCOmega; /* name of omega motor */ - char *pC2Theta; /* name of 2 theta motor */ - char *pFileRoot; /* where to write files */ - pDataNumber pDanu; /* where to get data file number */ - FILE *fRefl; /* reflection profile file */ - FILE *fHKL; /* integrated intensity file */ - int iLogFile; /* log file num at connection */ - SConnection *pCon; /* log file owning connection */ - char *pCurrentFile; /* current file root */ - char headerTemplate[512]; - int iCount; /* count of reflection */ - int CountMode; /* timer or preset */ - int np; /* number of scan points */ - float fPreset; /* counting preset */ - float fStep; /* omega step widths */ - long *lCounts; /* array to store counting values */ - float fPosition[4]; /* the real positions after driving */ - int iCompact; /* true if compact scan ouput. */ - int weak; /* weak flag: remeasure weak reflections */ - long weakThreshold; /* threshold when a peak is so weak that is has to - remeasured */ - int fastScan; /* flag for using fastscans for scanning reflections */ - int psiMode; /* 1 for psi scan mode, 0 else */ - int psd; /* a flag for making 2D detector scans */ - int stepTable; /* mapping of two theta ranges to step width and - variable to scan */ -} Mesure; -/*-------------------------------------------------------------------------*/ -static int SaveMesure(void *pData, char *name, FILE * fd) -{ - pMesure self = (pMesure) pData; - - fprintf(fd, "#Four Circle Dataset Module %s\n", name); - if (self->CountMode == eTimer) { - fprintf(fd, "%s countmode timer\n", name); - } else { - fprintf(fd, "%s countmode monitor\n", name); - } - fprintf(fd, "%s np %d\n", name, self->np); - fprintf(fd, "%s preset %f\n", name, self->fPreset); - fprintf(fd, "%s step %f\n", name, self->fStep); - fprintf(fd, "%s weakthreshold %ld\n", name, self->weakThreshold); - fprintf(fd, "%s compact %d\n", name, self->iCompact); - fprintf(fd, "%s psd %d\n", name, self->psd); - fprintf(fd, "%s weak %d\n", name, self->weak); - fprintf(fd, "%s fastscan %d\n", name, self->fastScan); - SaveFourCircleTable(self->stepTable, name, fd); - return 1; -} - -/*-------------------------------------------------------------------------*/ -static void ListMesure(pMesure self, char *name, SConnection * pCon) -{ - Tcl_DString list; - char pBuffer[132]; - - Tcl_DStringInit(&list); - if (self->CountMode == eTimer) { - snprintf(pBuffer, 131, "%s.countmode timer\n", name); - } else { - snprintf(pBuffer, 131, "%s.countmode monitor\n", name); - } - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.np %d\n", name, self->np); - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.preset %f\n", name, self->fPreset); - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.step %f\n", name, self->fStep); - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.weakthreshold %ld\n", name, - self->weakThreshold); - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.compact %d\n", name, self->iCompact); - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.psd %d\n", name, self->psd); - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.weak %d\n", name, self->weak); - Tcl_DStringAppend(&list, pBuffer, -1); - snprintf(pBuffer, 131, "%s.fastscan %d\n", name, self->fastScan); - Tcl_DStringAppend(&list, pBuffer, -1); - SCWrite(pCon, Tcl_DStringValue(&list), eValue); - Tcl_DStringFree(&list); -} - -/*--------------------------------------------------------------------------*/ -pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMotor pOmega, - char *pOm, pMotor p2Theta, char *p2t, - char *pFileRoot, pDataNumber pDanu, char *hdTemplate) -{ - pMesure pNew = NULL; - - assert(pCryst); - assert(pScanner); - assert(pOmega); - assert(pFileRoot); - assert(pDanu); - - /* allocate space............. */ - pNew = (pMesure) malloc(sizeof(Mesure)); - if (!pNew) { - return NULL; - } - memset(pNew, 0, sizeof(Mesure)); - - pNew->pDes = CreateDescriptor("Mesure"); - pNew->pDes->SaveStatus = SaveMesure; - pNew->pCall = CreateCallBackInterface(); - if (!pNew->pDes || !pNew->pCall) { - free(pNew); - return NULL; - } - - /* asssign defaults */ - pNew->pScanner = pScanner; - pNew->pCryst = pCryst; - pNew->pOmega = pOmega; - pNew->p2Theta = p2Theta; - pNew->pCOmega = strdup(pOm); - pNew->pC2Theta = strdup(p2t); - pNew->pFileRoot = strdup(pFileRoot); - pNew->pDanu = pDanu; - pNew->iCount = 0; - pNew->CountMode = 0; - pNew->np = 50; - pNew->fStep = 0.05; - pNew->fPreset = 2; - pNew->iCompact = 1; - pNew->psd = 0; - pNew->weak = 0; - pNew->weakThreshold = 99999; - pNew->fastScan = 0; - pNew->psiMode = 0; -#ifdef MESSDEBUG - pNew->lCounts = (long *) malloc(90 * sizeof(long)); -#endif - pNew->lCounts = (long *) malloc(50 * sizeof(long)); - pNew->stepTable = MakeFourCircleTable(); - strncpy(pNew->headerTemplate, hdTemplate, 511); - return pNew; -} - -/*------------------------------------------------------------------------*/ -void DeleteMesure(void *pData) -{ - pMesure self = NULL; - - self = (pMesure) pData; - - if (!pData) { - return; - } - - if (self->pDes) - DeleteDescriptor(self->pDes); - - if (self->pCall) - DeleteCallBackInterface(self->pCall); - if (self->pFileRoot) - free(self->pFileRoot); - if (self->pCOmega) - free(self->pCOmega); - if (self->fRefl) - MesureClose(self); - if (self->lCounts) - free(self->lCounts); - DeleteFourCircleTable(self->stepTable); - free(self); -} - -/*------------------------------------------------------------------------*/ -int MesureFactory(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]) -{ - pMesure pNew = NULL; - pHKL pCryst = NULL; - pScanData pScan = NULL; - CommandList *pCom = NULL; - pMotor pMot = NULL, pMot2 = NULL; - pDataNumber pDanu = NULL; - pSicsO2T pO2T = NULL; - char pBueffel[512]; - pDummy pDum = NULL; - int iRet; - - assert(pCon); - assert(pSics); - - /* check no of parameters - inicom name hkl scan omega root danu - */ - if (argc < 9) { - SCWrite(pCon, - "ERROR: Insufficient number of parameters to MesureFactory", - eError); - return 0; - } - - /* work parameters one by one, first hkl */ - pCom = FindCommand(pSics, argv[2]); - if (pCom) { - pDum = (pDummy) pCom->pData; - if (pDum) { - if (strcmp(pDum->pDescriptor->name, "4-Circle-Calculus") == 0) { - pCryst = (pHKL) pCom->pData; - } - } - } - if (!pCryst) { - sprintf(pBueffel, "ERROR: %s is no four circle calculus object", - argv[2]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* scanner */ - pCom = FindCommand(pSics, argv[3]); - if (pCom) { - pDum = (pDummy) pCom->pData; - if (pDum) { - if (strcmp(pDum->pDescriptor->name, "ScanObject") == 0) { - pScan = (pScanData) pCom->pData; - } - } - } - if (!pScan) { - sprintf(pBueffel, "ERROR: %s is no scan object", argv[3]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* omega */ - pMot = FindMotor(pSics, argv[4]); - if (!pMot) { - sprintf(pBueffel, "ERROR: %s is no motor object ", argv[4]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* 2 theta */ - pMot2 = FindMotor(pSics, argv[5]); - if (!pMot2) { - sprintf(pBueffel, "ERROR: %s is no motor object ", argv[5]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* Data Number */ - pCom = FindCommand(pSics, argv[7]); - if (pCom) { - pDum = (pDummy) pCom->pData; - if (pDum) { - if (strcmp(pDum->pDescriptor->name, "DataNumber") == 0) { - pDanu = (pDataNumber) pCom->pData; - } - } - } - if (!pDanu) { - sprintf(pBueffel, "ERROR: %s is no DataNumber object", argv[7]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* finally create the thing */ - pNew = CreateMesure(pCryst, pScan, pMot, argv[4], pMot2, argv[5], - argv[6], pDanu, argv[8]); - if (!pNew) { - SCWrite(pCon, "ERROR: no memory in MesureFactory", eError); - return 0; - } - - /* add the new command */ - iRet = AddCommand(pSics, argv[1], MesureAction, DeleteMesure, pNew); - if (!iRet) { - sprintf(pBueffel, "ERROR: duplicate command %s not created", argv[1]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - return 1; -} - -/*------------------------------------------------------------------------ - This implements the compact scan output for TRICS scans -*/ -static int CompactScanData(pScanData self, int iPoint) -{ - pVarEntry pVar = NULL; - void *pDings; - int i, iRet, status; - float fVal; - char pStatus[512], pItem[20]; - char pHead[512]; - CountEntry sCount; - char *pAns = NULL, *pPtr = NULL; - Tcl_Interp *pTcl; - - assert(self); - assert(self->pCon); - - /* loop over all scan variables */ - status = 1; - memset(pHead, 0, 512 * sizeof(char)); - memset(pStatus, 0, 512 * sizeof(char)); - memset(pItem, 0, 20 * sizeof(char)); - for (i = 0; i < self->iScanVar; i++) { - DynarGet(self->pScanVar, i, &pDings); - pVar = (pVarEntry) pDings; - if (pVar) { - fVal = pVar->pInter->GetValue(pVar->pObject, self->pCon); - AppendScanVar(pVar, fVal); - sprintf(pItem, "%-10.10s", pVar->Name); - strcat(pHead, pItem); - sprintf(pItem, "%-10.3f", fVal); - strcat(pStatus, pItem); - } - } - - /* store counter data */ - /* monitors */ - for (i = 1; i < 10; i++) { - sCount.Monitors[i - 1] = GetMonitor((pCounter) self->pCounterData, i, - self->pCon); - } - if (self->iChannel != 0 && self->iChannel != -10) { - sCount.Monitors[self->iChannel - 1] = - GetCounts((pCounter) self->pCounterData, self->pCon); - } - if (self->iChannel == 0) { - sCount.lCount = GetCounts((pCounter) self->pCounterData, self->pCon); - } else { - sCount.lCount = GetMonitor((pCounter) self->pCounterData, - self->iChannel, self->pCon); - } - - /* stow away */ - DynarReplace(self->pCounts, self->iCounts, &sCount, sizeof(CountEntry)); - self->iCounts++; - - return 1; -} - -/*------------------------------------------------------------------------*/ -static int getMesureNP(pMesure self, double twoTheta) -{ - int np; - np = GetFourCircleScanNP(self->stepTable, twoTheta); - if (np < -800) { - np = self->np; - } - return np; -} - -/*------------------------------------------------------------------------- - This is slightly tricky: the crystallography module has a scan tolerance. - This is supposed to be automatically set. In order to do so, I need - the step width which in turn is dependent on two theta. Therefore I calculate - two times: the first time with a scan tolerance of 0 to get two theta, the - second time with the scan tolerance ste to a decent value to get the - real thing. - ---------------------------------------------------------------------------*/ -static int MesureCalculateSettings(pMesure self, float fHKL[3], - float fSet[4], float fPsi, - SConnection * pCon) -{ - int status, np; - float step, tolerance, fHard; - char *scanvar = NULL; - char buffer[256]; - - SetHKLScanTolerance(self->pCryst, .0); - status = CalculateSettings(self->pCryst, fHKL, fPsi, 0, fSet, pCon); - if (!status) { - return status; - } - step = GetFourCircleStep(self->stepTable, fSet[0]); - if (step < -900.) { - step = self->fStep; - } - np = getMesureNP(self, (double) fSet[0]); - tolerance = (step * (float) np) / 2. + .2; - SetHKLScanTolerance(self->pCryst, tolerance); - status = CalculateSettings(self->pCryst, fHKL, fPsi, 0, fSet, pCon); - if (status != 1) { - return status; - } - scanvar = GetFourCircleScanVar(self->stepTable, fSet[0]); - if (scanvar != NULL && strcmp(scanvar, "om") != 0) { - tolerance *= 2.; - strcpy(buffer, "ERROR: 2theta limit problem:"); - if (!MotorCheckBoundary(self->p2Theta, fSet[0] - tolerance, &fHard, - buffer, 256 - strlen(buffer))) { - SCWrite(pCon, buffer, eWarning); - return 0; - } - if (!MotorCheckBoundary(self->p2Theta, fSet[0] + tolerance, &fHard, - buffer, 256 - strlen(buffer))) { - SCWrite(pCon, buffer, eWarning); - return 0; - } - } - return status; -} - -/*--------------------------------------------------------------------------*/ -int MesureReflection(pMesure self, float fHKL[3], float fPsi, - SConnection * pCon) -{ - int iRet; - float fSet[4]; - - assert(self); - - iRet = MesureCalculateSettings(self, fHKL, fSet, fPsi, pCon); - if (!iRet) { - return iRet; - } - return MesureGenReflection(self, fHKL, fSet, pCon); -} - -/*-----------------------------------------------------------------------*/ -static int DriveToReflection(pMesure self, float fSet[4], - SConnection * pCon) -{ - int iRet, i; - float fDelta; - char pBueffel[132]; - - iRet = DriveSettings(self->pCryst, fSet, pCon); - if (!iRet) { - return iRet; - } - - /* store achieved position for reporting */ - iRet = GetCurrentPosition(self->pCryst, pCon, self->fPosition); - if (iRet != 1) { - return iRet; - } - - /* - check if we are really there. - */ - for (i = 0; i < 4; i++) { - fDelta = fSet[i] - self->fPosition[i]; - if (fDelta < 0.) - fDelta = -fDelta; - if (fDelta > ANGERR) { - snprintf(pBueffel, 131, - "ERROR: angle %d positioned badly, aborting Reflection", i); - SCWrite(pCon, pBueffel, eError); - return 0; - } - } - return 1; -} - -/*----------------------------------------------------------------------- - test if this scan has to be remeasured because it is weak - ------------------------------------------------------------------------*/ -int weakScan(pMesure self, double twoTheta) -{ - int i, np; - long low = 99999, high = -99999; - - /* - the scan is always OK if we do not test for weak conditions or we are in psd mode - */ - if (self->weak == 0 || self->psd == 1) { - return 0; - } - - np = getMesureNP(self, twoTheta); - GetScanCounts(self->pScanner, self->lCounts, np); - for (i = 0; i < np; i++) { - if (self->lCounts[i] < low) { - low = self->lCounts[i]; - } - if (self->lCounts[i] > high) { - high = self->lCounts[i]; - } - } - /* - I am using the weakest point here as a rough estimate of - the background - */ - if (high - 2 * low > self->weakThreshold) { - return 0; - } else { - return 1; - } -} - -/*-----------------------------------------------------------------------*/ -static int PerformPSDScan(pMesure self, char *scanVar, float fStart, - float step, int np, float two_theta) -{ - int status; - char pCommand[1024]; - char countMode[20]; - Tcl_Interp *pTcl; - float fPreset; - - /* - PSD scans are done by calling the routine Tcl procedure tricsscan with the - appropriate parameters. tricsscan does only omega scans! - */ - if (self->CountMode == eTimer) { - strcpy(countMode, "timer"); - } else { - strcpy(countMode, "monitor"); - } - fPreset = GetFourCirclePreset(self->stepTable, (double) two_theta); - if (fPreset < .0) { - fPreset = self->fPreset; - } - snprintf(pCommand, 1023, "tricsscan %f %f %d %s %f", fStart, step, np, - countMode, fPreset); - pTcl = InterpGetTcl(pServ->pSics); - status = Tcl_Eval(pTcl, pCommand); - if (status != TCL_OK) { - return 0; - } else { - return 1; - } -} - -/*------------------------------------------------------------------------*/ -static int ScanReflection(pMesure self, float twoTheta, SConnection * pCon) -{ - float fStart, stepWidth, fPreset; - int iRet, np; - char pBueffel[132]; - char *scanVar = NULL; - - /* calculate scan start */ - iRet = MotorGetSoftPosition(self->pOmega, pCon, &fStart); - if (!iRet) { - return iRet; - } - scanVar = GetFourCircleScanVar(self->stepTable, (double) twoTheta); - if (strcmp(scanVar, "NOT FOUND") == 0) { - free(scanVar); - scanVar = strdup(self->pCOmega); - stepWidth = self->fStep; - } else { - stepWidth = GetFourCircleStep(self->stepTable, (double) twoTheta); - } - np = getMesureNP(self, (double) twoTheta); - - if (stepWidth != self->fStep) { - snprintf(pBueffel, 130, "Using stepwidth %f, %d points", stepWidth, - np); - SCWrite(pCon, pBueffel, eWarning); - } - fStart -= (np / 2) * stepWidth; - - /* - special case: psd mode - */ - if (self->psd == 1) { - iRet = PerformPSDScan(self, scanVar, fStart, stepWidth, np, twoTheta); - free(scanVar); - return iRet; - } - - /* - below is the code for a single counter scan. - TODO: (maybe) make this clearer and separate this into another subroutine - - Set the scan up - */ - ClearScanVar(self->pScanner); - AddScanVar(self->pScanner, pServ->pSics, pCon, self->pCOmega, - fStart, stepWidth); - snprintf(pBueffel, 131, "Scanning om from %f with step %f", fStart, - stepWidth); - SCWrite(pCon, pBueffel, eLog); - /* - Oksana does not want o2t scans to be tightly coupled, this is why we - cannot use the normal o2t scan variable. Instead we calculate new limits and - steps for 2 theta and use it as a second scan variable - */ - if (strstr(scanVar, "o2t") != NULL) { - iRet = MotorGetSoftPosition(self->p2Theta, pCon, &fStart); - if (!iRet) { - return iRet; - } - stepWidth *= 2.; - fStart -= (np / 2.) * stepWidth; - AddScanVar(self->pScanner, pServ->pSics, pCon, self->pC2Theta, - fStart, stepWidth); - snprintf(pBueffel, 131, "Scanning 2theta from %f with step %f", fStart, - stepWidth); - SCWrite(pCon, pBueffel, eLog); - } - - /* - as np can change, we have to reallocate enough space - */ - if (self->lCounts != NULL) { - free(self->lCounts); - self->lCounts = (long *) malloc(np * sizeof(long)); - if (self->lCounts == NULL) { - SCWrite(pCon, "ERROR: out of memory for scan scan data", eError); - SCSetInterrupt(pCon, eAbortScan); - return 0; - } - memset(self->lCounts, 0, np * sizeof(long)); - } - - /* - * determine preset - */ - fPreset = GetFourCirclePreset(self->stepTable, (double) twoTheta); - if (fPreset < .0) { - fPreset = self->fPreset; - } - - /* do the scan */ - free(scanVar); - if (self->iCompact) { - self->pScanner->CollectScanData = CompactScanData; - } - if (self->fastScan >= 1) { - self->pScanner->ScanDrive = ScanFastDrive; - } - iRet = SilentScan(self->pScanner, np, self->CountMode, - fPreset, pServ->pSics, pCon); - if (weakScan(self, twoTheta)) { - /* - look for interrupts before restarting scan - */ - if (iRet == 0) { - if (SCGetInterrupt(pCon) >= eAbortBatch) { - return 0; - } else { - SCSetInterrupt(pCon, eContinue); - } - } - /* - redo scan with preset * 5 - */ - SCWrite(pCon, "Remeasuring weak reflection", eLog); - iRet = SilentScan(self->pScanner, np, self->CountMode, - fPreset * 5., pServ->pSics, pCon); - - } - ResetScanFunctions(self->pScanner); - return iRet; -} - -/*------------------------------------------------------------------------*/ -int MesureGenReflection(pMesure self, float fHKL[3], float fSet[4], - SConnection * pCon) -{ - - int iRet, i; - char pBueffel[132]; - - assert(self); - - iRet = DriveToReflection(self, fSet, pCon); - if (!iRet) { - return iRet; - } - - iRet = ScanReflection(self, fSet[0], pCon); - - return iRet; -} - -/*--------------------------------------------------------------------------*/ -int MesureStart(pMesure self, SConnection * pCon) -{ - char pFilename[512], pRoot[512]; - char pBueffel[1024]; - char pBuff[132]; - int iYear, iNum, iTaus; - float fVal, fUB[9]; - pSicsVariable pVar = NULL; - char *pFile = NULL, *pPtr; - float zero, pos; - pMotor pMot = NULL; - FILE *temp = NULL; - - assert(self); - assert(pCon); - - /* close open files if so */ - if (self->fRefl != NULL) { - MesureClose(self); - } - - /* create filename root */ - pFile = makeFilename(pServ->pSics, pCon); - if (!pFile) { - return 0; - } - pPtr = strrchr(pFile, (int) '.'); - pPtr++; - *pPtr = '\0'; - self->pCurrentFile = strdup(pFile); - free(pFile); - strncpy(pRoot, self->pCurrentFile, 511); - - /* do the logfile */ - strcpy(pFilename, pRoot); - strcat(pFilename, "log"); - /* TODO - self->iLogFile = SCAddLogFile(pCon,pFilename); - */ - self->pCon = pCon; - - /* - we do not need reflection files when doing a PSD scan - */ - if (self->psd == 1) { - sprintf(pBueffel, "Logging to %s.log", pRoot); - SCWrite(pCon, pBueffel, eValue); - return 1; - } - - /* open the reflection file */ - sprintf(pBueffel, "Writing to %s.log, .ccl, .rfl", pRoot); - SCWrite(pCon, pBueffel, eValue); - strcpy(pFilename, pRoot); - strcat(pFilename, "ccl"); - self->fRefl = fopen(pFilename, "w"); - if (!self->fRefl) { - sprintf(pBueffel, "ERROR: SERIOUS TROUBLE: cannot open %s!", - pFilename); - SCWrite(pCon, pBueffel, eError); - SCSetInterrupt(pCon, eAbortBatch); - return 0; - } - temp = fopen(self->headerTemplate, "r"); - if (temp == NULL) { - SCWrite(pCon, "ERROR: failed to open header template", eError); - } - if (temp != NULL && self->fRefl != NULL) { - WriteTemplate(self->fRefl, temp, pFilename, NULL, pCon, pServ->pSics); - fclose(temp); - } - - - - /* open hkl-data file */ - strcpy(pFilename, pRoot); - strcat(pFilename, "rfl"); - self->fHKL = fopen(pFilename, "w"); - if (!self->fHKL) { - sprintf(pBueffel, "ERROR: SERIOUS TROUBLE: cannot open %s!", - pFilename); - SCWrite(pCon, pBueffel, eError); - SCSetInterrupt(pCon, eAbortBatch); - return 0; - } - fputs(pFilename, self->fHKL); - fputs("\n", self->fHKL); - - /* write some header data */ - SNXFormatTime(pBueffel, 1024); - fprintf(self->fHKL, "filetime = %s\n", pBueffel); - GetLambda(self->pCryst, &fVal); - fprintf(self->fHKL, "lambda = %f Angstroem\n", fVal); - GetUB(self->pCryst, fUB); - fprintf(self->fHKL, - "UB = %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f\n", - fUB[0], fUB[1], fUB[2], fUB[3], fUB[4], fUB[5], fUB[6], fUB[7], - fUB[8]); - - /* write sample & user info */ - strcpy(pBueffel, "CCL, Instr=TRICS, "); - pVar = FindVariable(pServ->pSics, "sample"); - if (pVar) { - fprintf(self->fHKL, "sample = %s\n", pVar->text); - sprintf(pBuff, "sample = %s, ", pVar->text); - strcat(pBueffel, pBuff); - } - pVar = FindVariable(pServ->pSics, "user"); - if (pVar) { - fprintf(self->fHKL, "user = %s \n", pVar->text); - sprintf(pBuff, "user = %s", pVar->text); - strcat(pBueffel, pBuff); - } - return 1; -} - -/*---------------------------------------------------------------------------*/ -int MesureReopen(pMesure self, char *fileroot, SConnection * pCon) -{ - char pBueffel[1024]; - char pFile[512]; - - assert(self); - assert(fileroot); - assert(pCon); - - /* close pending files */ - if (self->fRefl != NULL) { - MesureClose(self); - } - - /* log file */ - strcpy(pFile, self->pFileRoot); - strcat(pFile, "/"); - strcat(pFile, fileroot); - strcat(pFile, ".log"); - /* TODO: - self->iLogFile = SCAddLogFile(pCon,pFile); - */ - self->pCon = pCon; - - /* - No reopening of reflection files in psd mode - */ - if (self->psd == 1) { - return 1; - } - - /* check if this is possible */ - strcpy(pFile, self->pFileRoot); - strcat(pFile, "/"); - strcat(pFile, fileroot); - strcat(pFile, ".col"); - self->fRefl = fopen(pFile, "r"); - if (!self->fRefl) { - sprintf(pBueffel, "ERROR: there is no such measurement at %s", - fileroot); - SCWrite(pCon, pBueffel, eError); - return 0; - } - fclose(self->fRefl); - - /* well seems to exist, open for append */ - self->fRefl = fopen(pFile, "a"); - - /* rfl file */ - strcpy(pFile, self->pFileRoot); - strcat(pFile, "/"); - strcat(pFile, fileroot); - self->pCurrentFile = strdup(pFile); - strcat(pFile, ".rfl"); - self->fHKL = fopen(pFile, "a"); - - - return 1; -} - -/*------------------------------------------------------------------------*/ -int MesureClose(pMesure self) -{ - assert(self); - - /* TODO - * SCDelLogFile(self->pCon,self->iLogFile); - */ - if (self->psd == 1) { - self->pCon = NULL; - self->iLogFile = -1; - if (self->pCurrentFile) - free(self->pCurrentFile); - return 1; - } - - if (self->fRefl) { - fclose(self->fRefl); - self->fRefl = NULL; - } - if (self->fHKL) { - fclose(self->fHKL); - self->fHKL = NULL; - } - self->pCon = NULL; - self->iLogFile = -1; - if (self->pCurrentFile) - free(self->pCurrentFile); - - return 1; -} - -/*---------------------------------------------------------------------------*/ -static double getProtonAverage(pMesure self) -{ - int np, i; - long *lData = NULL, lSum = 0; - - np = GetScanNP(self->pScanner); - lData = (long *) malloc((np + 1) * sizeof(long)); - if (lData == NULL || np == 0) { - return 0.; - } - memset(lData, 0, (np + 1) * sizeof(long)); - GetScanMonitor(self->pScanner, 2, lData, np); - for (i = 0; i < np; i++) { - lSum += lData[i]; - } - return (double) lSum / (double) np; -} - -/*---------------------------------------------------------------------------*/ -static int WriteReflection(pMesure self, float fHKL[3], SConnection * pCon) -{ - float fSum, fSigma, fSet[4], fTemp, fPreset, fStep; - double prot; - static float fMax = 10.; - int iRet, i, ii, iLF, iNP; - char pBueffel[512], pNum[10], pTime[132]; - pEVControl pEva = NULL; - pDummy pPtr = NULL; - pIDrivable pDriv = NULL; - - assert(self); - assert(pCon); - memset(pTime, 0, 132 * sizeof(char)); - -#ifdef MESSDEBUG - self->np = 90; - fMax += 10; - SimScan(self->pScanner, 14., 0.5, fMax); - if (fMax > 1000) { - fMax = 10.; - } -#endif - - /* - no writing in PSD mode - */ - if (self->psd == 1) { - return 1; - } - - /* get necessary data */ - fSum = 0.; - fSigma = 0.; - iRet = ScanIntegrate(self->pScanner, &fSum, &fSigma); - if (iRet != 1) { - switch (iRet) { - case INTEGLEFT: - sprintf(pBueffel, - "WARNING: integration failed --> no left side to: %f %f %f", - fHKL[0], fHKL[1], fHKL[2]); - break; - case INTEGRIGHT: - sprintf(pBueffel, - "WARNING: integration failed -->no right side to: %f %f %f", - fHKL[0], fHKL[1], fHKL[2]); - break; - case INTEGNOPEAK: - sprintf(pBueffel, - "WARNING: integration failed -->no peak found: %f %f %f", - fHKL[0], fHKL[1], fHKL[2]); - break; - case INTEGFUNNYBACK: - sprintf(pBueffel, - "WARNING: integration problem, asymmetric background: %f %f %f", - fHKL[0], fHKL[1], fHKL[2]); - break; - } - SCWrite(pCon, pBueffel, eWarning); - } - iNP = GetScanNP(self->pScanner); - GetScanCounts(self->pScanner, self->lCounts, iNP); - - /* write it */ - if (self->fRefl) { - fprintf(self->fRefl, - "%4d %7.3f %7.3f %7.3f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n", - self->iCount, fHKL[0], fHKL[1], fHKL[2], self->fPosition[0], - self->fPosition[1], self->fPosition[2], self->fPosition[3], - fSum, fSigma); - } - if (self->fHKL) { - fprintf(self->fHKL, - "%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n", - self->iCount, fHKL[0], fHKL[1], fHKL[2], self->fPosition[0], - self->fPosition[1], self->fPosition[2], self->fPosition[3], - fSum, fSigma); - } - sprintf(pBueffel, - "%5d %6.2f %6.2f %6.2f %7.2f %7.2f %7.2f %7.2f %7.0f %7.2f\n", - self->iCount, fHKL[0], fHKL[1], fHKL[2], self->fPosition[0], - self->fPosition[1], self->fPosition[2], self->fPosition[3], fSum, - fSigma); - SCWrite(pCon, pBueffel, eLog); - - /* get temperature */ - fTemp = -777.77; - pEva = (pEVControl) FindCommandData(pServ->pSics, "temperature", - "Environment Controller"); - if (pEva == NULL) { - pPtr = (pDummy) FindCommandData(pServ->pSics, "temperature", - "RemObject"); - if (pPtr != NULL) { - pDriv = pPtr->pDescriptor->GetInterface(pPtr, DRIVEID); - if (pDriv != NULL) { - fTemp = pDriv->GetValue(pPtr, pCon); - } - } - } else { - iRet = EVCGetPos(pEva, pCon, &fTemp); - } - - /* write profile */ - if (self->fRefl) { - /* collect data */ - SNXFormatTime(pBueffel, 512); - GetScanVarStep(self->pScanner, 0, &fStep); - fPreset = GetScanPreset(self->pScanner); - prot = getProtonAverage(self); - fprintf(self->fRefl, "%3d %7.4f %9.0f %7.3f %12f %s\n", iNP, fStep, - fPreset, fTemp, prot, pBueffel); - for (i = 0; i < iNP; i++) { - for (ii = 0; ii < 10 && i < iNP; ii++) { - fprintf(self->fRefl, " %7ld", self->lCounts[i]); - iLF = 1; - i++; - } - fprintf(self->fRefl, "\n"); - i--; - iLF = 0; - } - if (iLF) { - fprintf(self->fRefl, "\n"); - } - fflush(self->fRefl); - } - - /* write data if compact output */ - if (self->iCompact == 1) { - strcpy(pTime, pBueffel); - sprintf(pBueffel, "%3d%8.4f%10.0f%8.3f %s\n", iNP, fStep, - fPreset, fTemp, pTime); - SCWrite(pCon, pBueffel, eValue); - pBueffel[0] = '\0'; - for (i = 0; i < iNP; i++) { - for (ii = 0; ii < 10 && i < iNP; ii++) { - sprintf(pNum, " %6ld", self->lCounts[i]); - strcat(pBueffel, pNum); - iLF = 1; - i++; - } - SCWrite(pCon, pBueffel, eValue); - pBueffel[0] = '\0'; - i--; - iLF = 0; - } - if (iLF) { - SCWrite(pCon, pBueffel, eValue); - } - } - return 1; -} - - /*---------------------------------------------------------------------*/ -static FILE *openListFile(char *pName) -{ - FILE *fd = NULL; - pDynString filename = NULL; - filename = findBatchFile(pServ->pSics, pName); - if (filename != NULL) { - fd = fopen(GetCharArray(filename), "r"); - DeleteDynString(filename); - } else { - fd = fopen(pName, "r"); - } - return fd; -} - -/*------------------------------------------------------------------------*/ -int MesureFile(pMesure self, char *pFile, int iSkip, SConnection * pCon) -{ - FILE *fd = NULL; - char pBueffel[512], pTime[132], pError[256]; - int i, iRet; - float fHKL[3], fPsi = .0; - - assert(self); - assert(pCon); - - /* well before doing a thing, open the list file */ - fd = openListFile(pFile); - if (!fd) { - sprintf(pBueffel, "ERROR: reflection file %s NOT found!", pFile); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* check that files are open, if not open */ - if (self->fRefl == NULL) { - MesureStart(self, pCon); - } - - /* make a mark */ - SNXFormatTime(pTime, 131); - sprintf(pBueffel, "Starting at list %s at %s", pFile, pTime); - SCWrite(pCon, pBueffel, eLog); - - /* skippy! */ - for (i = 0; i < iSkip; i++) { - fgets(pBueffel, 510, fd); - } - self->iCount = iSkip; - - if (self->psiMode > 0) { - SCWrite(pCon, "WARNING: measuring in psi mode", eWarning); - } - - /* loop through space and measure! */ - while (fgets(pBueffel, 510, fd) != NULL) { - for (i = 0; i < 3; i++) - fHKL[i] = 0.; - if (self->psiMode > 0) { - iRet = sscanf(pBueffel, "%f%f%f%f", - &fHKL[0], &fHKL[1], &fHKL[2], &fPsi); - if (iRet != 4) { - snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel); - SCWrite(pCon, pError, eWarning); - continue; - } - } else { - iRet = sscanf(pBueffel, "%f%f%f", &fHKL[0], &fHKL[1], &fHKL[2]); - if (iRet != 3) { - snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel); - SCWrite(pCon, pError, eWarning); - continue; - } - } - self->iCount++; - iRet = MesureReflection(self, fHKL, fPsi, pCon); - if (iRet == 0) { - if (SCGetInterrupt(pCon) >= eAbortBatch) { - return 0; - } else { - SCSetInterrupt(pCon, eContinue); - continue; - } - } - WriteReflection(self, fHKL, pCon); - } - - /* we are done */ - SNXFormatTime(pTime, 131); - sprintf(pBueffel, "Finishing list %s at %s", pFile, pTime); - SCWrite(pCon, pBueffel, eLog); - - fclose(fd); - return 1; -} - -/*------------------------------------------------------------------------*/ -int TestFile(pMesure self, char *pFile, SConnection * pCon) -{ - FILE *fd = NULL; - char pBueffel[512], pError[256]; - int i, iRet; - float fHKL[3], fSet[4], fPsi = .0; - int count = 0, good = 0; - - assert(self); - assert(pCon); - - /* well before doing a thing, open the list file */ - fd = openListFile(pFile); - if (!fd) { - sprintf(pBueffel, "ERROR: reflection file %s NOT found!", pFile); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - if (self->psiMode > 0) { - SCWrite(pCon, "WARNING: measuring in psi mode", eWarning); - } - - /* loop through space and test! */ - while (fgets(pBueffel, 510, fd) != NULL) { - for (i = 0; i < 3; i++) - fHKL[i] = 0.; - if (self->psiMode > 0) { - iRet = sscanf(pBueffel, "%f%f%f%f", - &fHKL[0], &fHKL[1], &fHKL[2], &fPsi); - if (iRet != 4) { - snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel); - SCWrite(pCon, pError, eWarning); - continue; - } - } else { - iRet = sscanf(pBueffel, "%f%f%f", &fHKL[0], &fHKL[1], &fHKL[2]); - if (iRet != 3) { - snprintf(pError, 255, "WARNING: skipping bad line %s", pBueffel); - SCWrite(pCon, pError, eWarning); - continue; - } - } - count++; - iRet = MesureCalculateSettings(self, fHKL, fSet, fPsi, pCon); - if (iRet == 1) { - good++; - } - } - fclose(fd); - snprintf(pBueffel, 511, - "Of %d reflections on file, %d are good and %d are rotten", - count, good, count - good); - SCWrite(pCon, pBueffel, eValue); - return 1; -} - -/*------------------------------------------------------------------------*/ -int MesureGenFile(pMesure self, char *pFile, int iSkip, SConnection * pCon) -{ - FILE *fd = NULL; - char pBueffel[512], pTime[132]; - int i, iRet, iH, iK, iL; - float fHKL[3], fSet[4]; - char pDum[4]; - - assert(self); - assert(pCon); - - /* well before doing a thing, open the list file */ - fd = openListFile(pFile); - if (!fd) { - sprintf(pBueffel, "ERROR: reflection file %s NOT found!", pFile); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* check that files are open, if not open */ - if (self->fRefl == NULL) { - MesureStart(self, pCon); - } - - /* make a mark */ - SNXFormatTime(pTime, 131); - sprintf(pBueffel, "Starting at list %s at %s", pFile, pTime); - SCWrite(pCon, pBueffel, eLog); - - /* skippy! */ - for (i = 0; i < iSkip; i++) { - fgets(pBueffel, 510, fd); - } - self->iCount = iSkip; - - - /* loop through space and measure! */ - while (fgets(pBueffel, 510, fd) != NULL) { - for (i = 0; i < 3; i++) - fHKL[i] = 0.; - for (i = 0; i < 4; i++) - fSet[i] = 0.; - iRet = sscanf(pBueffel, "%4d%4d%4d%s%f%f%f%f", - &iH, &iK, &iL, pDum, - &fSet[0], &fSet[1], &fSet[2], &fSet[3]); - fHKL[0] = (float) iH; - fHKL[1] = (float) iK; - fHKL[2] = (float) iL; - self->iCount++; - iRet = MesureGenReflection(self, fHKL, fSet, pCon); - if (iRet == 0) { - if (SCGetInterrupt(pCon) >= eAbortBatch) { - return 0; - } else { - SCSetInterrupt(pCon, eContinue); - continue; - } - } - WriteReflection(self, fHKL, pCon); - } - - /* we are done */ - SNXFormatTime(pTime, 131); - sprintf(pBueffel, "Finishing list %s at %s", pFile, pTime); - SCWrite(pCon, pBueffel, eLog); - - fclose(fd); - return 1; -} - -/*--------------------------------------------------------------------------*/ -int MesureSetPar(pMesure self, char *name, float fVal) -{ - if (strcmp(name, "np") == 0) { -#ifndef MESSDEBUG - self->np = (int) fVal; - if (self->lCounts) - free(self->lCounts); - self->lCounts = (long *) malloc(self->np * sizeof(long)); - if (!self->lCounts) { - return 0; - } -#else - -#endif - return 1; - } else if (strcmp(name, "step") == 0) { - self->fStep = fVal; - return 1; - } else if (strcmp(name, "weakthreshold") == 0) { - self->weakThreshold = (long) nintf(fVal); - return 1; - } else if (strcmp(name, "preset") == 0) { - self->fPreset = fVal; - return 1; - } else if (strcmp(name, "countmode") == 0) { - if (fVal < 0.05) { - self->CountMode = eTimer; - } else { - self->CountMode = ePreset; - } - return 1; - } else if (strcmp(name, "compact") == 0) { - if (fVal >= 1.) { - self->iCompact = 1; - } else { - self->iCompact = 0; - } - return 1; - } else if (strcmp(name, "psd") == 0) { - if (fVal >= 1.) { - self->psd = 1; - } else { - self->psd = 0; - } - return 1; - } else if (strcmp(name, "weak") == 0) { - if (fVal >= 1.) { - self->weak = 1; - } else { - self->weak = 0; - } - return 1; - } else if (strcmp(name, "fastscan") == 0) { - if (fVal >= 1.) { - self->fastScan = 1; - } else { - self->fastScan = 0; - } - return 1; - } else if (strcmp(name, "psimode") == 0) { - if (fVal >= 1.) { - self->psiMode = 1; - } else { - self->psiMode = 0; - } - return 1; - } else { - return 0; - } -} - -/*-------------------------------------------------------------------------*/ -int MesureGetPar(pMesure self, char *name, float *fVal) -{ - if (strcmp(name, "np") == 0) { - *fVal = self->np; - return 1; - } else if (strcmp(name, "step") == 0) { - *fVal = self->fStep; - return 1; - } else if (strcmp(name, "weakthreshold") == 0) { - *fVal = (float) self->weakThreshold; - return 1; - } else if (strcmp(name, "preset") == 0) { - *fVal = self->fPreset; - return 1; - } else if (strcmp(name, "countmode") == 0) { - if (self->CountMode == eTimer) { - *fVal = 0.; - } else { - *fVal = 1.0; - } - return 1; - } else if (strcmp(name, "compact") == 0) { - *fVal = self->iCompact; - return 1; - } else if (strcmp(name, "psd") == 0) { - *fVal = self->psd; - return 1; - } else if (strcmp(name, "fastscan") == 0) { - *fVal = (float) self->fastScan; - return 1; - } else if (strcmp(name, "weak") == 0) { - *fVal = (float) self->weak; - return 1; - } else if (strcmp(name, "psimode") == 0) { - *fVal = self->psiMode; - return 1; - } else { - return 0; - } -} - -/*---------------------------------------------------------------------------*/ -int MesureAction(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]) -{ - int iRet, iSkip, err; - char pBueffel[1024]; - pMesure self = NULL; - double d; - float fVal, fHKL[3], start, end, step; - - self = (pMesure) pData; - assert(self); - assert(pCon); - - if (argc < 2) { - sprintf(pBueffel, "ERROR: Insufficient arguments to %s", argv[0]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - - /* - catch table processing commands - */ - iRet = - HandleFourCircleCommands(&self->stepTable, pCon, argc, argv, &err); - if (iRet == 1) { - return err; - } - - strtolower(argv[1]); -/*------ start */ - if (strcmp(argv[1], "open") == 0) { - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - iRet = MesureStart(self, pCon); - if (iRet) { - SCSendOK(pCon); - } - return iRet; - } -/*----------- list*/ - else if (strcmp(argv[1], "list") == 0) { - ListMesure(self, argv[0], pCon); - return 1; - } -/*------ file */ - else if (strcmp(argv[1], "file") == 0) { - sprintf(pBueffel, "Currently writing to: %s", self->pCurrentFile); - SCWrite(pCon, pBueffel, eValue); - return 1; - } -/*------ nb */ - else if (strcmp(argv[1], "nb") == 0) { - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - iRet = SetNOR(self->pCryst, 1); - if (!iRet) { - SCWrite(pCon, - "ERROR: nu motor not configured at hkl, cannot do normal beam", - eError); - return 0; - } - SCSendOK(pCon); - return 1; - } -/*------ bi */ - else if (strcmp(argv[1], "bi") == 0) { - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - iRet = SetNOR(self->pCryst, 0); - SCSendOK(pCon); - return 1; - } -/*--------- close */ - else if (strcmp(argv[1], "close") == 0) { - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - MesureClose(self); - return 1; - } -/*-------- reopen */ - else if (strcmp(argv[1], "reopen") == 0) { - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - if (argc < 3) { - SCWrite(pCon, "ERROR: expected filename as parameter for reopen", - eError); - return 0; - } - iRet = MesureReopen(self, argv[2], pCon); - if (iRet) { - SCSendOK(pCon); - } - return iRet; - } -/*------- measure */ - else if (strcmp(argv[1], "measure") == 0) { - iSkip = 0; - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - if (argc < 3) { - SCWrite(pCon, - "ERROR: expected list file name as parameter for measure ", - eError); - return 0; - } - if (argc >= 4) { - iRet = Tcl_GetInt(pSics->pTcl, argv[3], &iSkip); - if (iRet != TCL_OK) { - sprintf(pBueffel, "ERROR: expected integer, got %s", argv[3]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - } - iRet = MesureFile(self, argv[2], iSkip, pCon); - if (iRet) { - SCSendOK(pCon); - } - return iRet; - } -/*------- calc */ - else if (strcmp(argv[1], "calc") == 0) { - if (argc < 3) { - SCWrite(pCon, - "ERROR: expected list file name as parameter for measure ", - eError); - return 0; - } - iRet = TestFile(self, argv[2], pCon); - return iRet; - } -/*------- genlist */ - else if (strcmp(argv[1], "genlist") == 0) { - iSkip = 0; - if (!SCMatchRights(pCon, usUser)) { - return 0; - } - if (argc < 3) { - SCWrite(pCon, - "ERROR: expected list file name as parameter for measure ", - eError); - return 0; - } - if (argc >= 4) { - iRet = Tcl_GetInt(pSics->pTcl, argv[3], &iSkip); - if (iRet != TCL_OK) { - sprintf(pBueffel, "ERROR: expected integer, got %s", argv[3]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - } - iRet = MesureGenFile(self, argv[2], iSkip, pCon); - if (iRet) { - SCSendOK(pCon); - } - return iRet; - } -/* ------ writereflection*/ - else if (strcmp(argv[1], "writereflection") == 0) { - GetCurrentHKL(self->pCryst, fHKL); - WriteReflection(self, fHKL, pCon); - SCSendOK(pCon); - return 1; - } -/* ------ count mode */ - else if (strcmp(argv[1], "countmode") == 0) { - if (argc > 2) { /* set case */ - /* check rights */ - if (!SCMatchRights(pCon, usUser)) { - SCWrite(pCon, "ERROR: You are not aurhorised to do this!", eError); - return 0; - } - if (strcmp(argv[2], "timer") == 0) { - fVal = 0.; - } else if (strcmp(argv[2], "monitor") == 0) { - fVal = 1.; - } else { - SCWrite(pCon, "ERROR: Invalid parameter for countmode", eError); - return 0; - } - MesureSetPar(self, "countmode", fVal); - SCSendOK(pCon); - return 1; - } else { /* get case */ - - MesureGetPar(self, "countmode", &fVal); - if (fVal < 0.05) { - sprintf(pBueffel, "%s.countmode = timer", argv[0]); - } else { - sprintf(pBueffel, "%s.countmode = monitor", argv[0]); - } - SCWrite(pCon, pBueffel, eValue); - return 1; - } - } -/*------ can be other pars */ - else { - if (argc > 2) { /* set case */ - /* check rights */ - if (!SCMatchRights(pCon, usUser)) { - SCWrite(pCon, "ERROR: You are not aurhorised to do this!", eError); - return 0; - } - iRet = Tcl_GetDouble(pSics->pTcl, argv[2], &d); - if (iRet != TCL_OK) { - sprintf(pBueffel, - "ERROR: expected numeric value for %s but got %s", argv[1], - argv[2]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - fVal = (float) d; - - iRet = MesureSetPar(self, argv[1], fVal); - if (iRet) { - SCSendOK(pCon); - return 1; - } else { - sprintf(pBueffel, "ERROR: parameter %s not known", argv[1]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - } else { /* get case */ - - iRet = MesureGetPar(self, argv[1], &fVal); - if (!iRet) { - sprintf(pBueffel, "ERROR: parameter %s not known", argv[1]); - SCWrite(pCon, pBueffel, eError); - return 0; - } - sprintf(pBueffel, "%s.%s = %f", argv[0], argv[1], fVal); - SCWrite(pCon, pBueffel, eValue); - return 1; - } - } -} diff --git a/mesure.h b/mesure.h deleted file mode 100644 index cec6670f..00000000 --- a/mesure.h +++ /dev/null @@ -1,45 +0,0 @@ - -/*---------------------------------------------------------------------------- - M E S U R E - - A SICS object for doing four circle measurements with a single - counter. - - copyright: see copyright.h - - Mark Koennecke, April 1998 - Heavily reworked: Mark Koennecke, February-March 2005 ----------------------------------------------------------------------------*/ -#ifndef SICSMESURE -#define SICSMESURE - -typedef struct __Mesure *pMesure; -/*--------------------- live & death --------------------------------------*/ -pMesure CreateMesure(pHKL pCryst, pScanData pScanner, - pMotor pOmega, char *pom, - pMotor p2Theta, char *p2t, - char *pFileRoot, pDataNumber pDanu, - char *headerTemplate); -void DeleteMesure(void *pData); - -int MesureFactory(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]); -/*------------------- object functions -----------------------------------*/ -int MesureReflection(pMesure self, float fHKL[3], float fPsi, - SConnection * pCon); -int MesureGenReflection(pMesure self, float fHKL[3], float fSet[4], - SConnection * pCon); -int MesureStart(pMesure self, SConnection * pCon); -int MesureReopen(pMesure self, char *filename, SConnection * pCon); -int MesureClose(pMesure self); -int MesureFile(pMesure self, char *pFile, int iSkip, SConnection * pCon); -int MesureGenFile(pMesure self, char *pFile, int iSkip, - SConnection * pCon); -int MesureSetPar(pMesure self, char *name, float fVal); -int MesureGetPar(pMesure self, char *name, float *fVal); - -int MesureAction(SConnection * pCon, SicsInterp * pSics, void *pData, - int argc, char *argv[]); - - -#endif diff --git a/ofac.c b/ofac.c index 8436e0b1..1dab74b6 100644 --- a/ofac.c +++ b/ofac.c @@ -80,7 +80,6 @@ #include "token.h" #include "hkl.h" #include "optimise.h" -#include "mesure.h" #include "commandlog.h" #include "udpquieck.h" #include "choco.h" @@ -291,7 +290,6 @@ static void InitIniCommands(SicsInterp * pInter, pTaskMan pTask) AddCommand(pInter, "MakePeakCenter", FitFactory, NULL, NULL); AddCommand(pInter, "MakeHKL", HKLFactory, NULL, NULL); AddCommand(pInter, "MakeOptimise", MakeOptimiser, NULL, NULL); - AddCommand(pInter, "MakeMesure", MesureFactory, NULL, NULL); AddCommand(pInter, "kill_command", SICSKill, NULL, NULL); AddCommand(pInter, "MakeChopper", ChocoFactory, NULL, NULL); AddCommand(pInter, "ChopperAdapter", CHAdapterFactory, NULL, NULL); diff --git a/reflist.c b/reflist.c index d9cd95c2..c3030a68 100644 --- a/reflist.c +++ b/reflist.c @@ -12,6 +12,7 @@ #include "reflist.h" #include "sicshipadaba.h" #include "stptok.h" +#include "hdbtable.h" #define INAME "index" #define ANAME "angles" @@ -35,12 +36,21 @@ static void UpdateConfiguration(pSICSOBJ refl) pRLPriv priv = refl->pPrivate; hdbValue v; char *pPtr = NULL, token[50]; - - + pHdb template, node; + + template = GetHipadabaNode(refl->objectNode,"template"); + if(template != NULL){ + DeleteHipadabaNode(template,NULL); + } + template = MakeHipadabaNode("template",HIPNONE, 1); + AddHipadabaChild(refl->objectNode, template, NULL); + SICSHdbGetPar(refl, NULL, "indexheader", &v); pPtr = v.v.text; priv->idxCount = 0; while ((pPtr = stptok(pPtr, token, 50, ",")) != NULL) { + node = MakeHipadabaNode(token,HIPFLOAT,1); + AddHipadabaChild(template,node,NULL); priv->idxCount++; } @@ -48,9 +58,18 @@ static void UpdateConfiguration(pSICSOBJ refl) pPtr = v.v.text; priv->angCount = 0; while ((pPtr = stptok(pPtr, token, 50, ",")) != NULL) { + node = MakeHipadabaNode(token,HIPFLOAT,1); + AddHipadabaChild(template,node,NULL); priv->angCount++; } - ClearReflectionList(refl); + node = GetHipadabaNode(refl->objectNode,"clear"); + assert(node != NULL); + runObjFunction(refl,pServ->dummyCon,node); + + node = GetHipadabaNode(refl->objectNode,"readtemplate"); + assert(node != NULL); + runObjFunction(refl,pServ->dummyCon,node); + } /*-----------------------------------------------------------------------*/ @@ -67,26 +86,6 @@ static hdbCallbackReturn CalcConfiguration(pHdb node, void *userData, } return hdbContinue; } - -/*-----------------------------------------------------------------------*/ -static int SaveRefList(void *data, char *name, FILE * fd) -{ - int i; - double ang[4], hkl[3]; - pSICSOBJ self = data; - - SaveSICSOBJ(data, name, fd); - for (i = 0; i < ReflectionListCount(self); i++) { - memset(hkl, 0, 3 * sizeof(double)); - memset(ang, 0, 4 * sizeof(double)); - GetRefIndex(self, i, hkl); - GetRefAngles(self, i, ang); - fprintf(fd, "%s addax %f %f %f %f %f %f %f\n", name, - hkl[0], hkl[1], hkl[2], ang[0], ang[1], ang[2], ang[3]); - } - return 1; -} - /*-----------------------------------------------------------------------*/ pSICSOBJ MakeReflectionListInt(char *name) { @@ -95,7 +94,7 @@ pSICSOBJ MakeReflectionListInt(char *name) hdbValue v; pRLPriv priv = NULL; - pNew = MakeSICSOBJ(name, "ReflectionList"); + pNew = MakeHdbTable(name, "ReflectionList"); priv = malloc(sizeof(RLPriv)); if (pNew == NULL || priv == NULL) { return NULL; @@ -103,7 +102,6 @@ pSICSOBJ MakeReflectionListInt(char *name) pNew->pPrivate = priv; pNew->KillPrivate = DefaultKill; - pNew->pDes->SaveStatus = SaveRefList; v = MakeHdbText("h,k,l"); node = MakeSICSHdbPar("indexheader", usMugger, v); @@ -117,248 +115,197 @@ pSICSOBJ MakeReflectionListInt(char *name) AppendHipadabaCallback(node, MakeHipadabaCallback(CalcConfiguration, pNew, NULL)); AddHipadabaChild(pNew->objectNode, node, NULL); + UpdateConfiguration(pNew); priv->angCount = 4; priv->count = 0; - v = makeHdbValue(HIPNONE, 0); - node = MakeSICSHdbPar("list", usMugger, v); - AddHipadabaChild(pNew->objectNode, node, NULL); - return pNew; } - -/*-----------------------------------------------------------------------*/ -static int MakeCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, - pHdb par[], int nPar) -{ - int status; - - status = NewListReflection(self); - if (status >= 0) { - SCPrintf(pCon, eValue, "newref = %4.4d", status); - return 1; - } else { - SCWrite(pCon, "ERROR: failed to create reflection", eError); - return 0; - } - return 0; -} - -/*-----------------------------------------------------------------------*/ -static int ClearCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, - pHdb par[], int nPar) -{ - ClearReflectionList(self); - return 1; -} - /*----------------------------------------------------------------------*/ static int AddIndexCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { char path[80]; - int status; - pHdb node = NULL; + int status, i; + pHdb node = NULL, addrowNode = NULL; hdbValue v; - if (nPar < 1) { + if (nPar < 3) { SCWrite(pCon, "ERROR: need indexes as arguments", eError); return 0; } - status = NewListReflection(self); - snprintf(path, 80, "list/%4.4d/%s", status, INAME); - node = GetHipadabaNode(self->objectNode, path); - assert(node != NULL); + addrowNode = GetHipadabaNode(self->objectNode,"addrow"); + assert(addrowNode != NULL); + /* copy HKL */ + node = addrowNode->child; + UpdateHipadabaPar(node, par[0]->value, pCon); + node = node->next; + UpdateHipadabaPar(node, par[1]->value, pCon); + node = node->next; + UpdateHipadabaPar(node, par[2]->value, pCon); - cloneHdbValue(&node->value, &v); - if (!readHdbValue(&v, par[0]->value.v.text, path, 80)) { - SCPrintf(pCon, eError, "ERROR: failed to convert %s to indices", - par[0]->value.v.text); - return 0; + /* set angles to zero */ + node = node->next; + v = MakeHdbFloat(.0); + while(node != NULL){ + UpdateHipadabaPar(node,v,pCon); + node = node->next; } - SetHipadabaPar(node, v, pCon); - ReleaseHdbValue(&v); - return 1; + + return runObjFunction(self, pCon, addrowNode); } /*----------------------------------------------------------------------*/ void AddRefIdx(pSICSOBJ refl, double hkl[]) { - int status; - hdbValue v; - char path[80]; - pHdb node; + int status; + hdbValue v; + pHdb node, child; - status = NewListReflection(refl); - snprintf(path, 80, "list/%4.4d/%s", status, INAME); - node = GetHipadabaNode(refl->objectNode, path); - assert(node != NULL); + node = GetHipadabaNode(refl->objectNode,"addrow"); + assert(node != NULL); + child = node->child; + UpdateHipadabaPar(child, MakeHdbFloat(hkl[0]),NULL); + child = child->next; + UpdateHipadabaPar(child, MakeHdbFloat(hkl[1]),NULL); + child = child->next; + UpdateHipadabaPar(child, MakeHdbFloat(hkl[2]),NULL); - v = MakeHdbFloatArray(3, hkl); - SetHipadabaPar(node, v, NULL); + v = MakeHdbFloat(.0); + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, v,NULL); + } + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, v,NULL); + } + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, v,NULL); + } + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, v,NULL); + } + runObjFunction(refl, pServ->dummyCon, node); } +/*----------------------------------------------------------------------*/ +static void AddRowIntern(pSICSOBJ refl, double hkl[], double ang[], + SConnection *pCon) +{ + int status; + hdbValue v; + pHdb node, child; + node = GetHipadabaNode(refl->objectNode,"addrow"); + assert(node != NULL); + child = node->child; + UpdateHipadabaPar(child, MakeHdbFloat(hkl[0]),NULL); + child = child->next; + UpdateHipadabaPar(child, MakeHdbFloat(hkl[1]),NULL); + child = child->next; + UpdateHipadabaPar(child, MakeHdbFloat(hkl[2]),NULL); + + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, MakeHdbFloat(ang[0]),NULL); + } + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, MakeHdbFloat(ang[1]),NULL); + } + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, MakeHdbFloat(ang[2]),NULL); + } + child = child->next; + if(child != NULL){ + UpdateHipadabaPar(child, MakeHdbFloat(ang[3]),NULL); + } + runObjFunction(refl, pCon, node); +} /*----------------------------------------------------------------------*/ void AddRefIdxAng(pSICSOBJ refl, double hkl[], double ang[]) { - int status; - hdbValue v; - char path[80]; - pHdb node; - - status = NewListReflection(refl); - snprintf(path, 80, "list/%4.4d/%s", status, INAME); - node = GetHipadabaNode(refl->objectNode, path); - assert(node != NULL); - - v = MakeHdbFloatArray(3, hkl); - SetHipadabaPar(node, v, NULL); - - snprintf(path, 80, "list/%4.4d/%s", status, ANAME); - node = GetHipadabaNode(refl->objectNode, path); - assert(node != NULL); - - v = MakeHdbFloatArray(3, ang); - SetHipadabaPar(node, v, NULL); + AddRowIntern(refl,hkl,ang,pServ->dummyCon); } /*----------------------------------------------------------------------*/ static int AddAnglesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { - char path[80]; - int status; - pHdb node = NULL; - hdbValue v; + int i; + double hkl[3], ang[4]; - if (nPar < 1) { - SCWrite(pCon, "ERROR: need angles as arguments", eError); - return 0; + memset(hkl,0,3*sizeof(double)); + memset(ang,0,4*sizeof(double)); + for(i = 0; i < nPar; i++){ + ang[i] = par[i]->value.v.doubleValue; } - - status = NewListReflection(self); - snprintf(path, 80, "list/%4.4d/%s", status, ANAME); - node = GetHipadabaNode(self->objectNode, path); - assert(node != NULL); - - cloneHdbValue(&node->value, &v); - if (!readHdbValue(&v, par[0]->value.v.text, path, 80)) { - SCPrintf(pCon, eError, "ERROR: failed to convert %s to angles", - par[0]->value.v.text); - return 0; - } - SetHipadabaPar(node, v, pCon); - ReleaseHdbValue(&v); + + AddRowIntern(self,hkl,ang,pCon); return 1; } - /*----------------------------------------------------------------------*/ static int AddIndexesAnglesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { - char path[80]; - int status, i; - pHdb node = NULL; + pHdb node = NULL, addrowNode; hdbValue v; - char *pPtr = NULL; pRLPriv priv = self->pPrivate; - if (nPar < 1) { + + if (nPar < 6) { SCWrite(pCon, "ERROR: need indexes/angles as arguments", eError); return 0; } - status = NewListReflection(self); - snprintf(path, 80, "list/%4.4d/%s", status, INAME); - node = GetHipadabaNode(self->objectNode, path); - assert(node != NULL); + addrowNode = GetHipadabaNode(self->objectNode,"addrow"); + assert(addrowNode != NULL); + /* copy HKL */ + node = addrowNode->child; + UpdateHipadabaPar(node, par[0]->value, pCon); + node = node->next; + UpdateHipadabaPar(node, par[1]->value, pCon); + node = node->next; + UpdateHipadabaPar(node, par[2]->value, pCon); - cloneHdbValue(&node->value, &v); - if (!readHdbValue(&v, par[0]->value.v.text, path, 80)) { - SCPrintf(pCon, eError, "ERROR: failed to convert %s to indices", - par[0]->value.v.text); - return 0; + /* copy angles */ + v = MakeHdbFloat(.0); + node = node->next; + if(node != NULL && nPar > 3){ + UpdateHipadabaPar(node, par[3]->value, pCon); + } else if(node != NULL) { + UpdateHipadabaPar(node, v, pCon); } - SetHipadabaPar(node, v, pCon); - ReleaseHdbValue(&v); - - /* advance pointer beyond indices */ - pPtr = par[0]->value.v.text; - for (i = 0; i < priv->idxCount; i++) { - pPtr = stptok(pPtr, path, 80, " "); + node = node->next; + if(node != NULL && nPar > 4){ + UpdateHipadabaPar(node, par[4]->value, pCon); + } else if(node!= NULL) { + UpdateHipadabaPar(node, v, pCon); } - - snprintf(path, 80, "list/%4.4d/%s", status, ANAME); - node = GetHipadabaNode(self->objectNode, path); - assert(node != NULL); - - cloneHdbValue(&node->value, &v); - if (!readHdbValue(&v, pPtr, path, 80)) { - SCPrintf(pCon, eError, "ERROR: failed to convert %s to angles", - par[0]->value.v.text); - return 0; + node = node->next; + if(node != NULL && nPar > 5){ + UpdateHipadabaPar(node, par[5]->value, pCon); + } else if (node != NULL) { + UpdateHipadabaPar(node, v, pCon); } - SetHipadabaPar(node, v, pCon); - ReleaseHdbValue(&v); - - return 1; + node = node->next; + if(node != NULL && nPar > 6){ + UpdateHipadabaPar(node, par[6]->value, pCon); + } else if(node!= NULL) { + UpdateHipadabaPar(node, v, pCon); + } + + return runObjFunction(self, pCon, addrowNode); } - -/*-----------------------------------------------------------------------*/ -static int DelCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, - pHdb par[], int nPar) -{ - pHdb node = NULL; - char path[132]; - - if (nPar < 1) { - SCWrite(pCon, "ERROR: need id to delete as argument", eError); - return 0; - } - snprintf(path, 132, "list/%s", par[0]->value.v.text); - node = GetHipadabaNode(self->objectNode, path); - if (node != NULL) { - DeleteHipadabaNode(node, pCon); - return 1; - } - SCWrite(pCon, "ERROR: reflection not found", eError); - return 0; -} - -/*-----------------------------------------------------------------------*/ -static int FlagCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, - pHdb par[], int nPar) -{ - pHdb node = NULL; - char path[132]; - - if (nPar < 1) { - SCWrite(pCon, "ERROR: need id to flag for", eError); - return 0; - } - snprintf(path, 132, "list/%s/%s", par[0]->value.v.text, FLAG); - node = GetHipadabaNode(self->objectNode, path); - if (node == NULL) { - SCPrintf(pCon, eError, "ERROR: bad ID %s", par[0]->value.v.text); - return 0; - } - if (nPar < 2) { - SCPrintf(pCon, eValue, "%s.%s.flag = %d", self->pDes->name, - par[0]->value.v.text, node->value.v.intValue); - return 1; - } else { - SetHipadabaPar(node, par[1]->value, pCon); - return 1; - } - return 0; -} - /*-----------------------------------------------------------------------*/ static int ShowCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { - pHdb node = NULL; + pHdb row = NULL, child = NULL; char path[132], num[20]; char data[1024]; hdbValue v; @@ -368,92 +315,25 @@ static int ShowCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, SCWrite(pCon, "ERROR: need id for reflection to show", eError); return 0; } - snprintf(path, 132, "list/%s/%s", par[0]->value.v.text, FLAG); - node = GetHipadabaNode(self->objectNode, path); - if (node == NULL) { + snprintf(path, 132, "data/%s", par[0]->value.v.text); + row = GetHipadabaNode(self->objectNode, path); + if (row == NULL) { SCPrintf(pCon, eError, "ERROR: bad ID %s", par[0]->value.v.text); return 0; } - GetHipadabaPar(node, &v, pCon); - snprintf(data, 1024, "%s %d", par[0]->value.v.text, v.v.intValue); - - snprintf(path, 132, "list/%s/%s", par[0]->value.v.text, INAME); - node = GetHipadabaNode(self->objectNode, path); - assert(node != NULL); - GetHipadabaPar(node, &v, pCon); - for (i = 0; i < v.arrayLength; i++) { - snprintf(num, 20, " %f", v.v.floatArray[i]); - strncat(data, num, 1024); - } - - snprintf(path, 132, "list/%s/%s", par[0]->value.v.text, ANAME); - node = GetHipadabaNode(self->objectNode, path); - assert(node != NULL); - GetHipadabaPar(node, &v, pCon); - for (i = 0; i < v.arrayLength; i++) { - snprintf(num, 20, " %f", v.v.floatArray[i]); - strncat(data, num, 1024); + + child = row->child; + strcpy(data,par[0]->value.v.text); + strcat(data," 1"); + while(child != NULL){ + snprintf(num,20," %f",child->value.v.doubleValue); + strcat(data,num); + child = child->next; } + SCWrite(pCon, data, eValue); return 1; } - -/*-----------------------------------------------------------------------*/ -static int ListCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, - pHdb par[], int nPar) -{ - char buffer[132], path[132], *pPtr, token[20], entry[20]; - pRLPriv priv = self->pPrivate; - int i; - pHdb node = NULL, data; - pDynString txt; - - SCStartBuffering(pCon); - /* - * build header - */ - strcpy(buffer, " ID FLAG"); - node = GetHipadabaNode(self->objectNode, "indexheader"); - assert(node != NULL); - pPtr = node->value.v.text; - while ((pPtr = stptok(pPtr, token, 20, ",")) != NULL) { - snprintf(entry, 20, " %8s", token); - strncat(buffer, entry, 132); - } - node = GetHipadabaNode(self->objectNode, "anglesheader"); - assert(node != NULL); - pPtr = node->value.v.text; - while ((pPtr = stptok(pPtr, token, 20, ",")) != NULL) { - snprintf(entry, 20, " %8s", token); - strncat(buffer, entry, 132); - } - SCWrite(pCon, buffer, eValue); - - node = GetHipadabaNode(self->objectNode, "list"); - node = node->child; - while (node != NULL) { - data = GetHipadabaNode(node, FLAG); - assert(data != NULL); - snprintf(buffer, 132, " %5s %4d", node->name, data->value.v.intValue); - data = GetHipadabaNode(node, INAME); - for (i = 0; i < priv->idxCount; i++) { - sprintf(entry, IDXFMT, data->value.v.floatArray[i]); - strncat(buffer, entry, 132); - } - data = GetHipadabaNode(node, ANAME); - for (i = 0; i < priv->angCount; i++) { - sprintf(entry, ANGFMT, data->value.v.floatArray[i]); - strncat(buffer, entry, 132); - } - SCWrite(pCon, buffer, eValue); - node = node->next; - } - - txt = SCEndBuffering(pCon); - SCWrite(pCon, GetCharArray(txt), eValue); - return 1; -} - /*-----------------------------------------------------------------------*/ static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) @@ -464,7 +344,7 @@ static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, SCStartBuffering(pCon); - node = GetHipadabaNode(self->objectNode, "list"); + node = GetHipadabaNode(self->objectNode, "data"); node = node->child; while (node != NULL) { snprintf(buffer, 132, "%s", node->name); @@ -476,76 +356,69 @@ static int NamesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, SCWrite(pCon, GetCharArray(txt), eValue); return 1; } - /*----------------------------------------------------------------------*/ static int SetIndexCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { char path[80]; - int status; - pHdb node = NULL; - hdbValue v; - char *pPtr = NULL, refl[20]; + int i; + pHdb row = NULL, child; - if (nPar < 1) { + if (nPar < 4) { SCWrite(pCon, "ERROR: need id and indexes as arguments", eError); return 0; } - pPtr = par[0]->value.v.text; - pPtr = stptok(pPtr, refl, 20, " "); - - snprintf(path, 80, "list/%s/%s", refl, INAME); - node = GetHipadabaNode(self->objectNode, path); - assert(node != NULL); - - cloneHdbValue(&node->value, &v); - if (!readHdbValue(&v, pPtr, path, 80)) { - SCPrintf(pCon, eError, "ERROR: failed to convert %s to indices", - par[0]->value.v.text); - return 0; + snprintf(path,80,"data/%s", par[0]->value.v.text); + row = GetHipadabaNode(self->objectNode, path); + if(row == NULL){ + SCPrintf(pCon,eError, "ERROR: reflection with ID %s not found", par[0]->value.v.text); + return 0; } - SetHipadabaPar(node, v, pCon); - ReleaseHdbValue(&v); + + child = row->child; + for(i = 0; i < 3; i++, child = child->next){ + if(child != NULL){ + UpdateHipadabaPar(child, par[i+1]->value, pCon); + } + } + SCSendOK(pCon); return 1; } - /*----------------------------------------------------------------------*/ static int SetAnglesCmd(pSICSOBJ self, SConnection * pCon, pHdb commandNode, pHdb par[], int nPar) { - char path[80]; - int status; - pHdb node = NULL; - hdbValue v; - char *pPtr = NULL, refl[20]; + char path[80]; + int i; + pHdb row = NULL, child; + hdbValue v; - if (nPar < 1) { + if (nPar < 4) { SCWrite(pCon, "ERROR: need id and angles as arguments", eError); return 0; } - - pPtr = par[0]->value.v.text; - pPtr = stptok(pPtr, refl, 20, " "); - - snprintf(path, 80, "list/%s/%s", refl, ANAME); - node = GetHipadabaNode(self->objectNode, path); - if (node == NULL) { - SCPrintf(pCon, eError, "ERROR: reflection with ID %s not found", refl); - return 0; + snprintf(path,80,"data/%s", par[0]->value.v.text); + row = GetHipadabaNode(self->objectNode, path); + if(row == NULL){ + SCPrintf(pCon,eError, "ERROR: reflection with ID %s not found", par[0]->value.v.text); + return 0; } - - cloneHdbValue(&node->value, &v); - if (!readHdbValue(&v, pPtr, path, 80)) { - SCPrintf(pCon, eError, "ERROR: failed to convert %s to angles", - par[0]->value.v.text); - return 0; + + child = row->child; + /* skip over hkl */ + for(i = 0; i < 3; i++, child = child->next) {} + + /* do angles */ + v = MakeHdbFloat(.0); + for(i = 0; i < 4 && child != NULL; i++, child = child->next){ + if(child != NULL){ + UpdateHipadabaPar(child, par[i+1]->value, pCon); + } } - SetHipadabaPar(node, v, pCon); - ReleaseHdbValue(&v); + SCSendOK(pCon); return 1; } - /*-----------------------------------------------------------------------*/ int MakeReflectionList(SConnection * pCon, SicsInterp * pSics, void *data, int argc, char *argv[]) @@ -577,47 +450,51 @@ pSICSOBJ CreateReflectionList(SConnection * pCon, SicsInterp * pSics, return 0; } - /* command initialization */ - AddSICSHdbPar(pNew->objectNode, "make", usUser, MakeSICSFunc(MakeCmd)); - - AddSICSHdbPar(pNew->objectNode, "clear", usUser, MakeSICSFunc(ClearCmd)); - - AddSICSHdbPar(pNew->objectNode, "print", usUser, MakeSICSFunc(ListCmd)); - AddSICSHdbPar(pNew->objectNode, "names", usUser, MakeSICSFunc(NamesCmd)); - cmd = - AddSICSHdbPar(pNew->objectNode, "del", usUser, MakeSICSFunc(DelCmd)); - AddSICSHdbPar(cmd, "id", usUser, MakeHdbText("")); - cmd = AddSICSHdbPar(pNew->objectNode, "addx", usUser, MakeSICSFunc(AddIndexCmd)); - AddSICSHdbPar(cmd, "args", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "h", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "k", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "l", usUser, MakeHdbFloat(.0)); cmd = AddSICSHdbPar(pNew->objectNode, "setx", usUser, MakeSICSFunc(SetIndexCmd)); - AddSICSHdbPar(cmd, "args", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "id", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "h", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "k", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "l", usUser, MakeHdbFloat(.0)); cmd = AddSICSHdbPar(pNew->objectNode, "adda", usUser, MakeSICSFunc(AddAnglesCmd)); - AddSICSHdbPar(cmd, "args", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "stt", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "om", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "chi", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "phi", usUser, MakeHdbFloat(.0)); cmd = AddSICSHdbPar(pNew->objectNode, "seta", usUser, MakeSICSFunc(SetAnglesCmd)); - AddSICSHdbPar(cmd, "args", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "id", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "stt", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "om", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "chi", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "phi", usUser, MakeHdbFloat(.0)); + cmd = AddSICSHdbPar(pNew->objectNode, "addax", usUser, MakeSICSFunc(AddIndexesAnglesCmd)); - AddSICSHdbPar(cmd, "args", usUser, MakeHdbText("")); + AddSICSHdbPar(cmd, "h", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "k", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "l", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "stt", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "om", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "chi", usUser, MakeHdbFloat(.0)); + AddSICSHdbPar(cmd, "phi", usUser, MakeHdbFloat(.0)); - cmd = AddSICSHdbPar(pNew->objectNode, "flag", usUser, - MakeSICSFunc(FlagCmd)); - AddSICSHdbPar(cmd, "id", usUser, MakeHdbText("")); - AddSICSHdbPar(cmd, "value", usUser, MakeHdbInt(0)); cmd = AddSICSHdbPar(pNew->objectNode, "show", usUser, MakeSICSFunc(ShowCmd)); @@ -626,7 +503,6 @@ pSICSOBJ CreateReflectionList(SConnection * pCon, SicsInterp * pSics, AddCommand(pSics, name, InterInvokeSICSOBJ, KillSICSOBJ, pNew); return pNew; } - /*------------------------------------------------------------------------*/ void ClearReflectionList(pSICSOBJ refl) { @@ -634,12 +510,9 @@ void ClearReflectionList(pSICSOBJ refl) hdbValue v; pRLPriv priv = refl->pPrivate; - node = GetHipadabaNode(refl->objectNode, "list"); - assert(node); - DeleteHipadabaNode(node, NULL); - v = makeHdbValue(HIPNONE, 0); - node = MakeSICSHdbPar("list", usMugger, v); - AddHipadabaChild(refl->objectNode, node, NULL); + node = GetHipadabaNode(refl->objectNode, "clear"); + assert(node != NULL); + runObjFunction(refl,pServ->dummyCon,node); priv->count = 0; } @@ -648,40 +521,10 @@ int ReflectionListCount(pSICSOBJ refl) { pHdb node = NULL; - node = GetHipadabaNode(refl->objectNode, "list"); + node = GetHipadabaNode(refl->objectNode, "data"); assert(node); return CountHdbChildren(node); } - -/*-------------------------------------------------------------------------*/ -int NewListReflection(pSICSOBJ refl) -{ - int count; - char path[20]; - pHdb listNode = NULL, node = NULL, refNode = NULL; - hdbValue v; - pRLPriv priv = refl->pPrivate; - - listNode = GetHipadabaNode(refl->objectNode, "list"); - assert(listNode); - - count = priv->count; - priv->count++; - snprintf(path, 20, "%4.4d", count); - node = MakeHipadabaNode(path, HIPNONE, 0); - AddHipadabaChild(listNode, node, NULL); - - v = makeHdbValue(HIPFLOATAR, priv->idxCount); - AddSICSHdbPar(node, INAME, usUser, v); - - v = makeHdbValue(HIPFLOATAR, priv->angCount); - AddSICSHdbPar(node, ANAME, usUser, v); - - v = makeHdbValue(HIPINT, 0); - AddSICSHdbPar(node, FLAG, usUser, v); - return count; -} - /*--------------------------------------------------------------------------*/ static pHdb findReflection(pSICSOBJ refl, int idx) { @@ -692,7 +535,7 @@ static pHdb findReflection(pSICSOBJ refl, int idx) return node; } - node = GetHipadabaNode(refl->objectNode, "list"); + node = GetHipadabaNode(refl->objectNode, "data"); assert(node); node = node->child; @@ -702,7 +545,6 @@ static pHdb findReflection(pSICSOBJ refl, int idx) } return node; } - /*---------------------------------------------------------------------------*/ void DelListReflection(pSICSOBJ refl, int idx) { @@ -713,157 +555,134 @@ void DelListReflection(pSICSOBJ refl, int idx) DeleteHipadabaNode(node, NULL); } } - /*-----------------------------------------------------------------------------*/ int SetRefIndex(pSICSOBJ refl, int idx, double hkl[]) { - pHdb node = NULL; - hdbValue v; + pHdb node = NULL, child; + int i; pRLPriv priv = refl->pPrivate; node = findReflection(refl, idx); if (node != NULL) { - node = GetHipadabaNode(node, INAME); - assert(node); - v = MakeHdbFloatArray(priv->idxCount, hkl); - SetHipadabaPar(node, v, NULL); - return 1; + child = node->child; + for(i = 0; i < 3; i++, child = child->next){ + if(child != NULL){ + UpdateHipadabaPar(child, MakeHdbFloat(hkl[i]), NULL); + } + } + return 1; } else { - return 0; + return 0; } } - /*-----------------------------------------------------------------------------*/ int SetRefAngles(pSICSOBJ refl, int idx, double ang[]) { - pHdb node = NULL; + pHdb node = NULL, child = NULL; hdbValue v; + int i; pRLPriv priv = refl->pPrivate; node = findReflection(refl, idx); if (node != NULL) { - node = GetHipadabaNode(node, ANAME); - assert(node); - v = MakeHdbFloatArray(priv->angCount, ang); - SetHipadabaPar(node, v, NULL); + child = node->child; + /* skip over hkl */ + for(i = 0; i < 3; i++, child = child->next){} + /* set angles */ + for(i = 0; i < 4; i++, child = child->next){ + if(child != NULL){ + UpdateHipadabaPar(child, MakeHdbFloat(ang[i]), NULL); + } + } return 1; } else { return 0; } } - -/*-----------------------------------------------------------------------------*/ -int SetRefFlag(pSICSOBJ refl, int idx, int val) -{ - pHdb node = NULL; - hdbValue v; - pRLPriv priv = refl->pPrivate; - - - node = findReflection(refl, idx); - if (node != NULL) { - node = GetHipadabaNode(node, FLAG); - assert(node); - v = MakeHdbInt(val); - SetHipadabaPar(node, v, NULL); - return 1; - } else { - return 0; - } -} - /*-------------------------------------------------------------------------------*/ int GetRefIndex(pSICSOBJ refl, int idx, double hkl[]) { - pHdb node = NULL; + pHdb node = NULL, child; + int i; pRLPriv priv = refl->pPrivate; node = findReflection(refl, idx); if (node != NULL) { - node = GetHipadabaNode(node, INAME); - assert(node); - memcpy(hkl, node->value.v.floatArray, priv->idxCount * sizeof(double)); - return 1; + child = node->child; + for(i = 0; i < 3; i++, child = child->next){ + hkl[i] = child->value.v.doubleValue; + } + return 1; } else { return 0; } } - /*-------------------------------------------------------------------------------*/ int GetRefIndexID(pSICSOBJ refl, char *id, double hkl[]) { - pHdb node = NULL; + pHdb node = NULL, child; pRLPriv priv = refl->pPrivate; char path[132]; + int i; - snprintf(path, 132, "list/%s", id); + snprintf(path, 132, "data/%s", id); node = GetHipadabaNode(refl->objectNode, path); if (node != NULL) { - node = GetHipadabaNode(node, INAME); - assert(node); - memcpy(hkl, node->value.v.floatArray, priv->idxCount * sizeof(double)); + child = node->child; + for(i = 0; i < 3; i++, child = child->next){ + hkl[i] = child->value.v.doubleValue; + } return 1; } else { return 0; } } - /*-------------------------------------------------------------------------------*/ int GetRefAngles(pSICSOBJ refl, int idx, double ang[]) { - pHdb node = NULL; + pHdb node = NULL, child; pRLPriv priv = refl->pPrivate; - + int i; node = findReflection(refl, idx); if (node != NULL) { - node = GetHipadabaNode(node, ANAME); - assert(node); - memcpy(ang, node->value.v.floatArray, priv->angCount * sizeof(double)); - return 1; + child = node->child; + /* skip hkl */ + for(i = 0; i < 3; i++, child = child->next){} + /* do angles */ + for(i = 0; i < 4; i++, child = child->next){ + ang[i] = child->value.v.doubleValue; + } + return 1; } else { return 0; } } - /*-------------------------------------------------------------------------------*/ -int GetRefAnglesID(pSICSOBJ refl, char *id, double hkl[]) +int GetRefAnglesID(pSICSOBJ refl, char *id, double ang[]) { - pHdb node = NULL; + pHdb node = NULL, child; pRLPriv priv = refl->pPrivate; char path[132]; - - snprintf(path, 132, "list/%s", id); + int i; + + snprintf(path, 132, "data/%s", id); node = GetHipadabaNode(refl->objectNode, path); if (node != NULL) { - node = GetHipadabaNode(node, ANAME); - assert(node); - memcpy(hkl, node->value.v.floatArray, priv->angCount * sizeof(double)); - return 1; + child = node->child; + /* skip hkl */ + for(i = 0; i < 3; i++, child = child->next){} + /* do angles */ + for(i = 0; i < 4 && child != NULL; i++, child = child->next){ + ang[i] = child->value.v.doubleValue; + } + return 1; } else { return 0; } } - -/*-------------------------------------------------------------------------------*/ -int GetRefFlag(pSICSOBJ refl, int idx) -{ - pHdb node = NULL; - pRLPriv priv = refl->pPrivate; - - - node = findReflection(refl, idx); - if (node != NULL) { - node = GetHipadabaNode(node, FLAG); - assert(node); - return node->value.v.intValue; - } else { - return -1; - } -} - /*--------------------------------------------------------------------------------*/ char *GetRefName(pSICSOBJ refl, int idx) { diff --git a/sicsobj.c b/sicsobj.c index 393268c7..8e0addf0 100644 --- a/sicsobj.c +++ b/sicsobj.c @@ -6,6 +6,7 @@ * Mark Koennecke, July 2007 */ #include +#include #include #include #include "assert.h" @@ -186,7 +187,26 @@ static int assignPar(pHdb node, SConnection * pCon, char *data) } return 1; } - +/*---------------------------------------------------------------------------*/ +int runObjFunction(pSICSOBJ object, SConnection *pCon, pHdb commandNode) +{ + pHdb parArray[64], child; + int status, count = 0; + SICSOBJFunc pFunc = NULL; + + assert(commandNode != NULL); + + child = commandNode->child; + while(child != NULL){ + parArray[count] = child; + count++; + child = child->next; + } + pFunc = (SICSOBJFunc)commandNode->value.v.func; + assert(pFunc != NULL); + status = pFunc(object, pCon, commandNode, parArray, count); + return status; +} /*---------------------------------------------------------------------------*/ static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, SConnection * pCon, int argc, char *argv[]) @@ -210,7 +230,7 @@ static int invokeOBJFunction(pSICSOBJ object, pHdb commandNode, count = 1; goto invoke; } - + /* * assign parameters and fill parameter array for function at the same * time. Be lenient about missing parameters: Then the old values will diff --git a/sicsobj.h b/sicsobj.h index 11444e0e..f615af8f 100644 --- a/sicsobj.h +++ b/sicsobj.h @@ -9,6 +9,7 @@ #define SICSOBJ2_H_ #include #include +#include "sics.h" /*====================================================================== * Be careful when changing this data structure. It has to be compatible * in its first fields with the SICS object descriptor as defined in @@ -43,6 +44,16 @@ int SaveSICSOBJ(void *data, char *name, FILE * fd); */ pSICSOBJ SetupSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData, int argc, char *argv[]); +/** + * runObjectFunction is an internal function for running an existing object + * command. The user has to search the node first, prime the parameters, + * and then call this command to actually execute. + * @param object The object on which the command is executed + * @param pCon a connection to use for error reporting + * @param commandNode The node to invoke. + */ +int runObjFunction(pSICSOBJ object, SConnection *pCon, pHdb commandNode); + /*====================== Interpreter Interface =========================== * InvokeSICSObj is special in that it returns -1 if it cannot handle * the command. This leaves calling code the opportunity to process