/*--------------------------------------------------------------------------- F O U R T A B L E A SICS object which holds the variation of scan parameters for four circle reflection list measurements. copyright: see copyright.h Mark Koennecke, February 2005 ---------------------------------------------------------------------------*/ #include #include #include "sics.h" #include "fortify.h" #include "lld.h" #include #include "splitter.h" #include "fourtable.h" /*====================== table entry ===================================*/ typedef struct { double twoThetaStart; double twoThetaEnd; double step; char scanVar[30]; }FourTableEntry, *pFourTableEntry; /*==================== functions =======================================*/ int MakeFourCircleTable(){ return LLDcreate(sizeof(FourTableEntry)); } /*-----------------------------------------------------------------------*/ void DeleteFourCircleTable(int handle){ LLDdelete(handle); } /*------------------------------------------------------------------------*/ static void clearTable(int handle){ int status; status = LLDnodePtr2First(handle); while(status == 1) { LLDnodeDelete(handle); status = LLDnodePtr2Next(handle); } } /*------------------------------------------------------------------------*/ 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 %8.3f %s %8.3f\n", entry.twoThetaStart, entry.twoThetaEnd, entry.scanVar,entry.step); 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); } /*-----------------------------------------------------------------------*/ static int addToList(int handle, SConnection *pCon, int argc, char *argv[]){ 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.twoThetaStart = atof(argv[3]); } else { snprintf(pBueffel,131,"ERROR: expected numeric argument, received %s", argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } if(isNumeric(argv[4])){ entry.twoThetaEnd = atof(argv[4]); } else { snprintf(pBueffel,131,"ERROR: expected numeric argument, received %s", argv[4]); SCWrite(pCon,pBueffel,eError); return 0; } strncpy(entry.scanVar,argv[5],29); if(isNumeric(argv[6])){ entry.step = atof(argv[6]); } else { snprintf(pBueffel,131,"ERROR: expected numeric argument, received %s", argv[6]); SCWrite(pCon,pBueffel,eError); return 0; } LLDnodePrependFrom(handle,&entry); return 1; } /*-----------------------------------------------------------------------*/ 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 handle, SConnection *pCon, int argc, char *argv[], int *err){ *err = 1; /* test if this is for us */ if(argc >= 3){ strtolower(argv[1]); if(strcmp(argv[1],"table") != 0){ return 0; } } else { 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; } clearTable(handle); 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) { 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])); 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; } return 1; } /*-----------------------------------------------------------------------*/ static FourTableEntry findEntry(int handle, double two_theta){ int status; FourTableEntry entry; status = LLDnodePtr2First(handle); while(status == 1) { LLDnodeDataTo(handle,&entry); if(two_theta > entry.twoThetaStart && two_theta <= entry.twoThetaEnd){ return entry; } status = LLDnodePtr2Next(handle); } strcpy(entry.scanVar,"NOT FOUND"); return entry; } /*------------------------------------------------------------------------*/ char *GetFourCircleScanVar(int 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; } } /*------------------------------------------------------------------------*/ int SaveFourCircleTable(int handle, char *objName, FILE *fd){ 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 %f %s %f\n",objName, entry.twoThetaStart, entry.twoThetaEnd,entry.scanVar, entry.step); status = LLDnodePtr2Prev(handle); } return 1; }