PSI sics-cvs-psi-2006

This commit is contained in:
2006-05-08 02:00:00 +00:00
committed by Douglas Clowes
parent ae77364de2
commit 6e926b813f
388 changed files with 445529 additions and 14109 deletions

31
.cdtproject Normal file
View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse-cdt version="2.0"?>
<cdtproject id="org.eclipse.cdt.make.core.make">
<extension point="org.eclipse.cdt.core.BinaryParser" id="org.eclipse.cdt.core.ELF"/>
<extension point="org.eclipse.cdt.core.CIndexer" id="org.eclipse.cdt.core.domsourceindexer"/>
<data>
<item id="org.eclipse.cdt.core.pathentry">
<pathentry kind="src" path=""/>
<pathentry kind="out" path=""/>
<pathentry kind="con" path="org.eclipse.cdt.make.core.DISCOVERED_SCANNER_INFO"/>
</item>
<item id="cdt_indexer">
<indexEnabled indexValue="true"/>
<indexerProblemsEnabled indexProblemsValue="0"/>
</item>
<item id="scannerConfiguration">
<autodiscovery enabled="true" selectedProfileId="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile" problemReportingEnabled="true"/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="false" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction useDefault="true" command="gcc" arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</item>
</data>
</cdtproject>

2722
.log

File diff suppressed because it is too large Load Diff

108
.project Normal file
View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>sics</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.make.core.makeBuilder</name>
<arguments>
<dictionary>
<key>org.eclipse.cdt.core.errorOutputParser</key>
<value>org.eclipse.cdt.core.MakeErrorParser;org.eclipse.cdt.core.GCCErrorParser;org.eclipse.cdt.core.GASErrorParser;org.eclipse.cdt.core.GLDErrorParser;org.eclipse.cdt.core.VCErrorParser;</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>clean all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.incrementalBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enabledIncrementalBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value>-f makefile_slinux</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>false</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.make.core.ScannerConfigBuilder</name>
<arguments>
<dictionary>
<key>org.eclipse.cdt.make.core.ScannerConfigDiscoveryEnabled</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.makeBuilderParserId</key>
<value>org.eclipse.cdt.make.core.GCCScannerInfoConsoleParser</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.esiProviderCommandEnabled</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.siProblemGenerationEnabled</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultESIProviderCmd</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.makeBuilderParserEnabled</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.esiProviderParserId</key>
<value>org.eclipse.cdt.make.core.GCCSpecsConsoleParser</value>
</dictionary>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.make.core.makeNature</nature>
<nature>org.eclipse.cdt.make.core.ScannerConfigNature</nature>
</natures>
</projectDescription>

27
.rfl
View File

@ -1,27 +0,0 @@
1 14.0 1.0 -3.0 34.93 17.4662365.2f -120.3757635.2f 57.86 0.00 0.00
2 25.0 20.0 3.0 121.37 60.6874285.2f -161.7680215.2f 151.81 0.00 0.00
3 14.0 1.0 -1.0 30.08 15.0386245.2f -105.8243565.2f 57.33 0.00 0.00
4 13.0 1.0 0.0 26.43 13.2171475.2f -97.0895085.2f 62.61 0.00 0.00
5 13.0 1.0 -2.0 30.17 15.0827995.2f -114.8090905.2f 59.43 0.00 0.00
6 0.0 7.0 1.0 38.10 19.0499325.2f 168.9476015.2f 154.39 0.00 0.00
7 -1.0 7.0 1.0 39.00 19.4981695.2f 166.0153055.2f 154.70 0.00 0.00
8 1.0 7.0 1.0 37.31 18.6574575.2f 172.0074465.2f 154.08 0.00 0.00
9 1.0 2.0 2.0 13.43 6.7168745.2f 176.1939855.2f -170.37 0.00 0.00
1 14.0 1.0 -3.0 34.93 17.47 -120.38 57.86 0.00 0.00
2 25.0 20.0 3.0 121.37 60.69 -161.77 151.81 0.00 0.00
3 14.0 1.0 -1.0 30.08 15.04 -105.82 57.33 0.00 0.00
4 13.0 1.0 0.0 26.43 13.22 -97.09 62.61 0.00 0.00
5 13.0 1.0 -2.0 30.17 15.08 -114.81 59.43 0.00 0.00
6 0.0 7.0 1.0 38.10 19.05 168.95 154.39 0.00 0.00
7 -1.0 7.0 1.0 39.00 19.50 166.02 154.70 0.00 0.00
8 1.0 7.0 1.0 37.31 18.66 172.01 154.08 0.00 0.00
9 1.0 2.0 2.0 13.43 6.72 176.19 -170.37 0.00 0.00
1 14.0 1.0 -3.0 34.93 17.47 -120.38 57.86 0.00 0.00
2 25.0 20.0 3.0 121.37 60.69 -161.77 151.81 0.00 0.00
3 14.0 1.0 -1.0 30.08 15.04 -105.82 57.33 0.00 0.00
4 13.0 1.0 0.0 26.43 13.22 -97.09 62.61 0.00 0.00
5 13.0 1.0 -2.0 30.17 15.08 -114.81 59.43 0.00 0.00
6 0.0 7.0 1.0 38.10 19.05 168.95 154.39 0.00 0.00
7 -1.0 7.0 1.0 39.00 19.50 166.02 154.70 0.00 0.00
8 1.0 7.0 1.0 37.31 18.66 172.01 154.08 0.00 0.00
9 1.0 2.0 2.0 13.43 6.72 176.19 -170.37 0.00 0.00

View File

@ -23,6 +23,7 @@
/* status flags */
int iReconfig;
int iUpdate;
pStringDict pOption;
/* interface functions */
int (*Configure)(pHistDriver self,
SConnection *pCon,
@ -71,7 +72,7 @@
#line 474 "histogram.w"
#line 228 "histogram.w"
#line 229 "histogram.w"
pHistDriver CreateHistDriver(pStringDict pDict);
void DeleteHistDriver(pHistDriver self);

View File

@ -11,7 +11,7 @@
#ifndef SICSHISTMEMINT
#define SICSHISTMEMINT
#line 250 "histogram.w"
#line 251 "histogram.w"
typedef struct __HistMem {
pObjectDescriptor pDes;
@ -21,7 +21,6 @@
int iInit;
pICountable pCountInt;
pICallBack pCall;
pStringDict pOption;
} HistMem;
#line 490 "histogram.w"

324
SCinter.c
View File

@ -2,11 +2,9 @@
Implementation file for the SICS-interpreter.
Mark Koennecke, November 1996
Made ListObjects moe intelligent: list objects according to interface etc.
Made ListObjects more intelligent: list objects according to interface etc.
Mark Koennecke, December 2003
Copyright:
@ -33,7 +31,7 @@
POSSIBILITY OF SUCH DAMAGE.
THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
@ -42,6 +40,16 @@
M. Zolliker, Sept 2000, introduced formal aliases, modifications marked M.Z
Mark Koennecke, August 2001, modified SicsWriteStatus to write motor
positions on demand.
Made ListObjects moe intelligent: list objects according to interface etc.
Mark Koennecke, December 2003
Extended 'dir' command (function ListObjects) to list via typename from
object descriptor. For completeness, added function PrintAllTypes.
Paul Hathaway, May 2004
Modified printXXX functions to fix duplicate write of last buffer line.
Paul Hathaway, May 2004
---------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
@ -57,13 +65,19 @@
#include "interface.h"
#include "motor.h"
#include "obdes.h"
#include "lld.h"
/* M.Z. */
#include "definealias.h"
/* pvh */
#include "lld_str.h"
static void printList(SConnection *pCon, int listID);
static void freeList(int listID);
#define MAXLEN 256
#define MAXPAR 100
#define MAXBUF 128
/*--------------------------------------------------------------------------*/
SicsInterp *InitInterp(void)
@ -77,6 +91,7 @@
SICSLogWrite("Error allocating memory for Interpreter",eInternal);
return NULL;
}
memset(pInter,0,sizeof(SicsInterp));
pInter->pCList = NULL;
pInter->AList.pFirst = NULL; /* M.Z. */
pInter->pTcl = (void *)MacroInit(pInter);
@ -90,10 +105,11 @@
return pInter;
}
/*------------------------------------------------------------------------*/
int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData)
int AddCommandWithFlag(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData, int startupOnly)
{
CommandList *pNew = NULL;
CommandList *p, *tail;
char pBueffel[512];
assert(pName);
@ -133,19 +149,42 @@
pNew->OFunc = pFunc;
pNew->KFunc = pKFunc;
pNew->pData = pData;
pNew->pNext = pInterp->pCList;
pNew->pNext = NULL;
pNew->startupOnly = startupOnly;
if(pInterp->pCList)
/* find end of list */
tail = NULL;
p = pInterp->pCList;
while(p != NULL)
{
pInterp->pCList->pPrevious = pNew;
tail = p;
p = p->pNext;
}
pNew->pPrevious = NULL;
if (tail==NULL) { /* first entry */
pInterp->pCList = pNew;
} else { /* insert at tail */
tail->pNext = pNew;
}
pNew->pPrevious = tail;
/* update headpointer */
pInterp->pCList = pNew;
return 1;
}
/*------------------------------------------------------------------------*/
int AddCommand(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData)
{
return AddCommandWithFlag(pInterp, pName, pFunc, pKFunc, pData, 0);
}
/*------------------------------------------------------------------------*/
int AddIniCmd(char *pName, ObjectFunc pFunc)
{
return AddCommandWithFlag(pServ->pSics, pName, pFunc, NULL, NULL, 1);
}
/*------------------------------------------------------------------------*/
int AddCmd(char *pName, ObjectFunc pFunc)
{
return AddCommandWithFlag(pServ->pSics, pName, pFunc, NULL, NULL, 0);
}
/*------------------------------------------------------------------------*/
int RemoveCommand(SicsInterp *pInterp, char *pName)
{
@ -201,7 +240,7 @@
#define MAXCOM 50
extern char *stptok(char *s, char *tok, unsigned int toklen, char *brk);
extern char *SkipSpace(char *pPtr);
/*------------------------------------------------------------------------*/
/*-----------------------------------------------------------------------*/
int InterpExecute(SicsInterp *self,SConnection *pCon, char *pText)
{
int iCount = 0;
@ -212,6 +251,7 @@ extern char *SkipSpace(char *pPtr);
char pBrk[] = {" \r\n\0"};
char *pPtr;
char **argv = NULL;
commandContext comCon;
assert(self);
@ -226,24 +266,28 @@ extern char *SkipSpace(char *pPtr);
}
else
{
printf("Executing -> %s <- from dummy socket\n", pText);
sprintf(pBueffel, "Executing -> %s <- from dummy socket\n", pText);
SICSLogWrite(pBueffel,eCommand);
}
/* convert to argc, argv */
argc = 0;
argv = NULL;
Text2Arg(pText,&argc,&argv);
/* the first one must be the target object. If not given an empty
command string was given which will be silently ignored */
if(argc < 1)
{
return 1;
iRet = 1;
goto deleteArgv;
}
if(argv[0] == NULL)
{
SCWrite(pCon,"ERROR: failed to parse command",eError);
return -1;
SCWrite(pCon,"ERROR: failed to parse command",eError);
iRet = -1;
goto deleteArgv;
}
/* find it */
@ -253,8 +297,8 @@ extern char *SkipSpace(char *pPtr);
sprintf(pBueffel,"ERROR: Object -> %s <- NOT found",
argv[0]);
SCWrite(pCon,pBueffel,eError);
return -1;
iRet = -1;
goto deleteArgv;
}
@ -262,19 +306,28 @@ extern char *SkipSpace(char *pPtr);
self->eOut = eStatus;
Tcl_ResetResult((Tcl_Interp *)self->pTcl);
MacroPush(pCon);
pCon->conStatus = 0;
iRet = pCommand->OFunc(pCon, self, pCommand->pData, argc, argv);
/* If a task is registered with the dev exec then conStatus is HWBusy*/
if (pCon->conStatus != HWBusy) {
comCon = SCGetContext(pCon);
if (0 != strcmp("contextdo",comCon.deviceID))
SCWrite(pCon,"",eFinish);
}
MacroPop();
/* delete argv */
for(i = 0; i < argc; i++)
{
if(argv[i] != NULL)
{
free(argv[i]);
}
deleteArgv:
if (argv) {
/* delete argv */
for(i = 0; i < argc; i++)
{
if(argv[i] != NULL)
{
free(argv[i]);
}
}
free(argv);
}
free(argv);
return iRet;
}
/*------------------------------------------------------------------------*/
@ -318,23 +371,24 @@ extern char *SkipSpace(char *pPtr);
float fVal;
pIDrivable pDriv = NULL;
void *pTest = NULL;
char tmpfile[PATH_MAX];
int l;
assert(self);
assert(file);
/* open file */
fd = fopen(file,"w");
if(!fd)
{
/* make sure that status file is always valid M.Z. Apr 2005 */
/* create a temporary file first */
l=strlen(file);
if (l >= sizeof tmpfile - 2) {
return 0;
}
/* remove it, as I found garbage from previous runs in the
status file
*/
fclose(fd);
remove(file);
strcpy(tmpfile, file);
tmpfile[l]='.';
tmpfile[l+1]='\0';
remove(tmpfile); /* remove already existing file */
fd = fopen(file,"w");
fd = fopen(tmpfile,"w");
if(!fd)
{
return 0;
@ -380,6 +434,10 @@ extern char *SkipSpace(char *pPtr);
fprintf(fd,"Success \n");
}
fclose(fd);
/* rename temporary to final file (this is an atomic action) */
if (0 > rename(tmpfile, file)) {
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
@ -420,7 +478,15 @@ extern char *SkipSpace(char *pPtr);
pTcl = (Tcl_Interp *)self->pTcl;
if(pTcl)
{
/*
uncommented: the current versions of Tcl (8.3,4) dump core with a
memory problem deep in the Tcl library. This causes a core dump on
each SICS restart and breaks the use of external tools.
Tcl_DeleteInterp(pTcl);
call KillSicsUnknown instead to clean up all memory properly. M.Z., Apr 05
*/
KillSicsUnknown();
}
free(self);
@ -456,6 +522,7 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
iNum = 0;
pBueffel[0]='\0';
}
pCurrent = pCurrent->pNext;
}
@ -467,6 +534,80 @@ static void printAll(SicsInterp *pSics, SConnection *pCon)
SCWrite(pCon,pBueffel,eStatus);
}
}
/*------------------------------------------------------------------------*/
/* compareStringNode wraps strcmp for use in findNode(LLD module) calls */
int compareStringNode(const void *pStr1, const void *ppStr2)
{
return strcmp((char *)pStr1,*(char **)ppStr2);
}
/*------------------------------------------------------------------------
printAllTypes prints the list of types of objects instantiated on the
CommandList.
iFiltered=0 gives all objects including interpreter command objects
iFiltered=1 gives types where object name is not the same as its type
-------------------------------------------------------------------------*/
static void printAllTypes(SicsInterp *pSics, SConnection *pCon, int iFiltered)
{
CommandList *pCurrent = NULL;
char pBueffel[256];
char pName_lc[256];
char pType_lc[256];
char *pType;
Dummy *pTest;
int typeListID;
assert(pSics);
assert(pCon);
pBueffel[0] = '\0';
typeListID = LLDstringCreate();
if(-1==typeListID)
{
strcpy(pBueffel,"ERROR: Cannot generate list of object types\r\n");
SCWrite(pCon,pBueffel,eStatus);
return;
}
pCurrent = pSics->pCList;
while(pCurrent)
{
if(NULL != pCurrent->pData)
{
pTest = (pDummy)pCurrent->pData;
if(NULL != pTest->pDescriptor)
{
pType = pTest->pDescriptor->name;
strcpy(pType_lc,pType);
strtolower(pType_lc);
LLDnodePtr2First(typeListID);
/* int LLDnodeFind( int List, CompFunPtr Compare, void * DataPtr ); */
/* */
/* Find *DataPtr in the List using the *Compare function. */
/* Returns the return value of *Compare. */
/* 0 == equal == found. */
/* non-zero == not found. Current node is set to found node. */
/* Returns 2 for an empty list. */
/* NB: First checked node is current node, then search to end of list*/
if(0!=LLDnodeFind(typeListID,compareStringNode,(void *)pType))
{ /* empty list or 'typename' not found */
strcpy(pName_lc, pCurrent->pName);
strtolower(pName_lc);
if((0==iFiltered)||((1==iFiltered)&&(0!=strcmp(pType_lc,pName_lc))))
{ /*ie Add if unfiltered or pass filter(name!=typename) */
LLDstringAdd(typeListID,pType);
}
}
}
}
pCurrent = pCurrent->pNext;
}
printList(pCon,typeListID);
freeList(typeListID);
}
/*-----------------------------------------------------------------------
printInterface prints only those objects which implement an interface
as specified bi the id given
@ -508,6 +649,7 @@ static void printInterface(SicsInterp *pSics, SConnection *pCon, int id)
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
iNum = 0;
pBueffel[0]='\0';
}
}
}
@ -559,6 +701,7 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
strcat(pBueffel,pCurrent->pName);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
pBueffel[0]='\0';
iNum = 0;
}
}
@ -571,24 +714,26 @@ static void printMatch(SicsInterp *pSics, SConnection *pCon, char *mask)
SCWrite(pCon,pBueffel,eStatus);
}
/*-----------------------------------------------------------------------
printType prints only those objects which match the type given
printType prints only those objects whose descriptor match the type given
-------------------------------------------------------------------------*/
static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
static void printType(SicsInterp *pSics, SConnection *pCon, char *typeName)
{
CommandList *pCurrent;
Tcl_DString txt;
char pBueffel[256];
int iNum = 0;
assert(pSics);
assert(pCon);
Tcl_DStringInit(&txt);
pBueffel[0] = '\0';
pCurrent = pSics->pCList;
while(pCurrent)
{
if(pCurrent->pData != NULL)
{
if(iHasType(pCurrent->pData,type))
if(iHasType(pCurrent->pData,typeName))
{
if(iNum == 0)
{
@ -606,7 +751,8 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
strcat(pBueffel," ");
strcat(pBueffel,pCurrent->pName);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
Tcl_DStringAppend(&txt,pBueffel,-1);
pBueffel[0]='\0';
iNum = 0;
}
}
@ -616,13 +762,15 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
/* write final entries */
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
SCWrite(pCon,Tcl_DStringValue(&txt),eStatus);
Tcl_DStringFree(&txt);
}
/*--------------------------------------------------------------------------*/
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
char pType[256];
int i;
if(argc < 2)
{
@ -644,6 +792,13 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printType(pSics,pCon,"Motor");
return 1;
}
/* Start Mod by Paul Hathaway May 2004 */
if(0 == strcmp(argv[1],"types"))
{
printAllTypes(pSics,pCon,1);
return 1;
}
/* End Mod by Paul Hathaway May 2004*/
/*
@ -677,7 +832,7 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printInterface(pSics,pCon,ENVIRINTERFACE);
return 1;
}
SCWrite(pCon,"ERROR: interface description nor recognized",eError);
SCWrite(pCon,"ERROR: interface description not recognized",eError);
return 0;
}
/*
@ -688,6 +843,33 @@ static void printType(SicsInterp *pSics, SConnection *pCon, char *type)
printMatch(pSics,pCon,argv[2]);
return 1;
}
/* Start Mod by Paul Hathaway May 2004 */
/*
* type-based dir
*/
if(0 == strcmp(argv[1],"type"))
{
if(0==strcmp(argv[2],"*"))
{
printAllTypes(pSics,pCon,0);
return 1;
}
strcpy(pType,argv[2]);
/* Cater for multi-word types eg 'Environment Monitor' */
if(argc > 3)
{
for(i=3;i<argc;i++)
{
strcat(pType," ");
strcat(pType,argv[i]);
}
}
printType(pSics,pCon,pType);
return 1;
}
/* End Mod by Paul Hathaway May 2004*/
return 1;
}
/*---------------------------------------------------------------------------*/
@ -791,3 +973,51 @@ void *FindDrivable(SicsInterp *pSics, char *name){
return NULL;
}
/*------------------------------------------------------------------------*/
/* printList: Print contents of an LLDstring list
* Envisaged to be used by other extensions/refactoring utilising dynamic
* linked list module. May extend toallow different output formats
* (eg multi/single column) via switches
*/
static void printList(SConnection *pCon, int listID)
{
char pBueffel[MAXBUF];
int retCode;
if(0!=LLDnodePtr2First(listID))
{
do
{
retCode = LLDstringData(listID,NULL);
if ((MAXBUF-3) > retCode) {
retCode = LLDstringData(listID,pBueffel);
strcat(pBueffel,"\r\n");
SCWrite(pCon,pBueffel,eStatus);
}
} while(0!=LLDnodePtr2Next(listID));
}
}
/*------------------------------------------------------------------------*/
static void freeList(int listID)
{
do {
LLDstringDelete(listID);
} while(0!=LLDnodePtr2First(listID));
LLDdelete(listID);
}
/*------------------------------------------------------------------------*/
void RemoveStartupCommands(void)
{
CommandList *pCurrent, *pNext;
pCurrent = pServ->pSics->pCList;
while(pCurrent)
{
pNext = pCurrent->pNext;
if (pCurrent->startupOnly) {
RemoveCommand(pServ->pSics, pCurrent->pName);
}
pCurrent = pNext;
}
}

View File

@ -30,6 +30,7 @@ typedef struct __Clist {
void *pData;
struct __Clist *pNext;
struct __Clist *pPrevious;
int startupOnly;
} CommandList;
typedef struct __SINTER
@ -63,6 +64,12 @@ typedef struct __SINTER
int RemoveCommand(SicsInterp *pInterp, char *pName);
/* kills the command name from the interpreter pInterp
*/
/*-------------------------------------------------------------------------*/
int AddCommandWithFlag(SicsInterp *pInterp, char *pName, ObjectFunc pFunc,
KillFunc pKFunc, void *pData, int startupFlag);
int AddIniCmd(char *pName, ObjectFunc pFunc); /* command will be deleted after startup */
int AddCmd(char *pName, ObjectFunc pFunc); /* syntactic sugar for AddCommand without data */
void RemoveStartupCommands(void); /* called after startup to delete startup commands */
/*-------------------------------------------------------------------------*/
int InterpExecute(SicsInterp *self,pSConnection pCon,char *pCommand);
@ -80,7 +87,6 @@ typedef struct __SINTER
If the command is found, 1 is returned on success, 0 on failure in
the command.
----------------------------------------------------------------------------*/
CommandList *FindCommand(SicsInterp *pInterp, char *name);
/*
Searches the Interpreters pInterp command list for a command

View File

@ -51,7 +51,7 @@
}
if(!iRet)
{
printf("Unrecoverable error on server startup, exiting.........");
printf("Unrecoverable error on server startup, exiting.........\n");
exit(1);
}

View File

@ -46,6 +46,9 @@ typedef enum {
eInError,
eStatus,
eValue,
eStart,
eFinish,
eEvent,
eWarning,
eError
} OutCode;

View File

@ -5,11 +5,11 @@
#==========================================================================
# the following lines only for fortified version
#DFORTIFY=-DFORTIFY -I$(ROOT)/$(SRC)
#DFORTIFY=-DFORTIFY
#FORTIFYOBJ=strdup.o fortify.o
#----------------select proper Makefile
MFLAGS= -f $(SRC)makefile_alpha$(DUMMY) SRC=$(SRC)
MFLAGS= -f makefile_alpha$(DUMMY)
#------------- path to HDF installation
HDFROOT=/data/lnslib
HDFROOT=/afs/psi.ch/project/sinq/tru64

View File

@ -191,15 +191,18 @@ int StartLevel(int level, int sequenceList, int motorList, SConnection *pCon){
if(seq.level == level){
pMot = FindMotEntry(motorList,seq.pMotor);
if(pMot){
status = StartRegMot(pMot,pCon,seq.target);
if(status){
count++;
}
status = StartRegMot(pMot,pCon,seq.target);
/*
* I have to ignore the problem here: if I do not increment the count
* all the other levels will not be drive and the anticollider
* gets into a mess
*/
count++;
} else {
sprintf(pBueffel,"ERROR: motor %s, requested from anticollider script",
seq.pMotor);
SCWrite(pCon,pBueffel,eError);
SCWrite(pCon,"ERROR: motor NOT found, fix script!",eError);
sprintf(pBueffel,"ERROR: motor %s, requested from anticollider script",
seq.pMotor);
SCWrite(pCon,pBueffel,eError);
SCWrite(pCon,"ERROR: motor NOT found, fix script!",eError);
}
}
iRet = LLDnodePtr2Next(sequenceList);
@ -309,7 +312,7 @@ int AntiColliderAction(SConnection *pCon, SicsInterp *pSics,
if(argc > 1){
if(strcmp(argv[1],"clear") == 0){
if(!SCMatchRights(pCon,usUser)){
return 0;
return 0;
}
LLDdelete(self->sequenceList);
self->sequenceList = LLDcreate(sizeof(Sequence));

View File

@ -114,6 +114,9 @@ managed through the lld functions as everywhere within SICS.
pMotReg FindMotFromDataStructure(int iList, void *pData);
int CheckAllMotors(int iList, SConnection *pCon);
void KillMotList(int iList);
void StopAllMotors(int iList);
void DeactivateAllMotors(int iList);
@}
The functions:
\begin{description}

View File

@ -47,11 +47,10 @@
#include "lld.h"
#include "sics.h"
#include "macro.h"
#include "splitter.h"
#define CALLBACK 17777
/*--------------------- The interface datastructure ---------------------*/
typedef struct __ICallBack {
int iID;
@ -65,6 +64,7 @@
void *pUserData;
KillFuncIT pKill;
int iEvent;
commandContext comCon;
} CallBackItem, *pCallBackItem;
/*------------------------------------------------------------------------*/
static int CheckPointer(pICallBack self)
@ -141,7 +141,7 @@
LLDnodeDataTo(self->iList,&sItem);
if(sItem.iEvent == iEvent)
{
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData);
iRet = sItem.pFunc(iEvent, pEventData,sItem.pUserData,sItem.comCon);
if(!iRet)
{
iResult = 0;
@ -154,7 +154,7 @@
/*--------------------------------------------------------------------------*/
static long lCount = 1L;
long RegisterCallback(pICallBack self, int iEvent,
long RegisterCallback(pICallBack self, commandContext comCon, int iEvent,
SICSCallBack pFunc,
void *pUserData, KillFunc pKFunc)
{
@ -171,7 +171,8 @@
sItem.iEvent = iEvent;
sItem.pUserData = pUserData;
sItem.pKill = pKFunc;
sItem.comCon = comCon;
LLDnodeAppendFrom(self->iList,&sItem);
return sItem.iID;
}
@ -245,7 +246,8 @@ static int CallbackWrite(SConnection *pCon,char *message, int outCode)
/*-----------------------------------------------------------------------
the actual callback function invoking the script
------------------------------------------------------------------------*/
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData)
static int ScriptCallback(int iEvent, void *pEventData, void *pUserData,
commandContext cc)
{
SConnection *pCon = NULL;
Tcl_Interp *pTcl;
@ -262,16 +264,21 @@ static int ScriptCallback(int iEvent, void *pEventData, void *pUserData)
fprintf(stdout,"ERROR: ScriptCallback: no script to execute\n");
return 0;
}
/*
SCSetWriteFunc(pCon,CallbackWrite);
MacroPush(pCon);
pTcl = InterpGetTcl(pServ->pSics);
status = Tcl_GlobalEval(pTcl,(char *)pUserData);
status = Tcl_Eval(pTcl,(char *)pUserData);
if(status != TCL_OK)
{
fprintf(stdout,"ERROR: in CallbackScript: %s\n",(char *)pUserData);
fprintf(stdout,"Tcl-error: %s\n",pTcl->result);
}
MacroPop();
*/
SCSetRights(pCon,usInternal);
status = InterpExecute(pServ->pSics,pCon,(char *)pUserData);
SCDeleteConnection(pCon);
return 1;
}
@ -302,7 +309,7 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
strtolower(argv[1]);
if(strcmp(argv[1],"connect") == 0)
{
if(argc < 5)
if(argc < 4)
{
SCWrite(pCon,"ERROR: not enough arguments to CallbackScript connect",
eError);
@ -327,8 +334,10 @@ int CallbackScript(SConnection *pCon, SicsInterp *pSics, void *pData,
SCWrite(pCon,"ERROR: event type not known",eError);
return 0;
}
lID = RegisterCallback(pCall,iEvent,ScriptCallback,
strdup(argv[4]),free);
Arg2Text(argc-4,&argv[4],pBuffer,131);
lID = RegisterCallback(pCall,SCGetContext(pCon),
iEvent,ScriptCallback,
strdup(pBuffer),free);
sprintf(pBuffer,"callback = %ld", lID);
SCWrite(pCon,pBuffer,eValue);
return 1;

2
cd_obj
View File

@ -1,2 +0,0 @@
# define an alias to 'source cd_obj' for switching quick to object directory
cd obj/$SICS_VERSION

187
cell.c Normal file
View File

@ -0,0 +1,187 @@
/**
* this is a little library for performing crystallographic cell transformations
* for SICS. Some of the actual code was lifted from the Risoe program tascom.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, March 2005
*/
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include "trigd.h"
#include "cell.h"
/* define constants */
#ifndef PI
#define PI (3.1415926536) /* pi */
#endif
#define TWOPI (2*PI) /* 2*pi */
/*****************************************************************************
* default value for a cell
****************************************************************************/
void defaultCell(plattice cell){
cell->a = 1.;
cell->b = 1.;
cell->c = 1.;
cell->alpha = 90.;
cell->beta = 90.;
cell->gamma = 90.;
}
/*******************************************************************************
* Transform direct lattice to reciprocal lattice.
*******************************************************************************/
int directToReciprocalLattice(lattice direct, plattice reciprocal)
{
double alfa, beta, gamma;
double cos_alfa, cos_beta, cos_gamma;
double sin_alfa, sin_beta, sin_gamma;
double ad, bd, cd;
double arg, vol;
alfa = direct.alpha;
beta = direct.beta;
gamma = direct.gamma;
cos_alfa = Cosd (alfa);
cos_beta = Cosd (beta);
cos_gamma = Cosd (gamma);
sin_alfa = Sind (alfa);
sin_beta = Sind (beta);
sin_gamma = Sind (gamma);
reciprocal->alpha = Acosd ((cos_beta*cos_gamma - cos_alfa)/sin_beta/sin_gamma);
reciprocal->beta =Acosd ((cos_alfa*cos_gamma - cos_beta)/sin_alfa/sin_gamma);
reciprocal->gamma = Acosd ((cos_alfa*cos_beta - cos_gamma)/sin_alfa/sin_beta);
ad = direct.a;
bd = direct.b;
cd = direct.c;
arg = 1 + 2*cos_alfa*cos_beta*cos_gamma - cos_alfa*cos_alfa -
cos_beta*cos_beta -
cos_gamma*cos_gamma;
if (arg < 0.0)
{
return REC_NO_VOLUME;
}
vol = ad*bd*cd*sqrt (arg);
reciprocal->a = bd*cd*sin_alfa/vol;
reciprocal->b = ad*cd*sin_beta/vol;
reciprocal->c = bd*ad*sin_gamma/vol;
return (0);
}
/*******************************************************************************
* Transform reciprocal lattice to direct lattice.
*******************************************************************************/
int reciprocalToDirectLattice(lattice reciprocal, plattice direct)
{
double alfa, beta, gamma;
double cos_alfa, cos_beta, cos_gamma;
double sin_alfa, sin_beta, sin_gamma;
double ar, br, cr;
double arg, vol;
alfa = reciprocal.alpha;
beta = reciprocal.beta;
gamma = reciprocal.gamma;
cos_alfa = Cosd (alfa);
cos_beta = Cosd (beta);
cos_gamma = Cosd (gamma);
sin_alfa = Sind (alfa);
sin_beta = Sind (beta);
sin_gamma = Sind (gamma);
direct->alpha = Acosd ((cos_beta*cos_gamma - cos_alfa)/sin_beta/sin_gamma);
direct->beta = Acosd ((cos_alfa*cos_gamma - cos_beta)/sin_alfa/sin_gamma);
direct->gamma = Acosd ((cos_alfa*cos_beta - cos_gamma)/sin_alfa/sin_beta);
ar = reciprocal.a;
br = reciprocal.b;
cr = reciprocal.c;
arg = 1 + 2*cos_alfa*cos_beta*cos_gamma - cos_alfa*cos_alfa -
cos_beta*cos_beta -
cos_gamma*cos_gamma;
if (arg < 0.0)
{
return REC_NO_VOLUME;
}
vol = ar*br*cr*sqrt (arg);
direct->a = br*cr*sin_alfa/vol;
direct->b = ar*cr*sin_beta/vol;
direct->c = br*ar*sin_gamma/vol;
return (0);
}
/***************************************************************************************
* Build a B matrix
***************************************************************************************/
int calculateBMatrix(lattice direct, MATRIX B) {
lattice reciprocal;
int status;
assert(MatRow(B) == 3);
assert(MatCol(B) == 3);
status = directToReciprocalLattice(direct,&reciprocal);
if(status < 0) {
return status;
}
mat_fill(B,ZERO_MATRIX);
/*
top row
*/
B[0][0] = reciprocal.a;
B[0][1] = reciprocal.b*Cosd(reciprocal.gamma);
B[0][2] = reciprocal.c*Cosd(reciprocal.beta);
/*
middle row
*/
B[1][1] = reciprocal.b*Sind(reciprocal.gamma);
B[1][2] = -reciprocal.c*Sind(reciprocal.beta)*Cosd(direct.alpha);
/*
bottom row
*/
B[2][2] = 1./direct.c;
return 1;
}
/*--------------------------------------------------------------------------*/
int cellFromUB(MATRIX UB, plattice direct){
MATRIX UBTRANS, GINV, G;
UBTRANS = mat_tran(UB);
if(UBTRANS == NULL){
return CELLNOMEMORY;
}
GINV = mat_mul(UBTRANS,UB);
if(GINV == NULL){
mat_free(UBTRANS);
return CELLNOMEMORY;
}
G = mat_inv(GINV);
if(G == NULL){
mat_free(UBTRANS);
mat_free(GINV);
return CELLNOMEMORY;
}
direct->a = sqrt(G[0][0]);
direct->b = sqrt(G[1][1]);
direct->c = sqrt(G[2][2]);
direct->alpha = Acosd(G[1][2]/(direct->b * direct->c));
direct->beta = Acosd(G[2][0]/(direct->a * direct->c));
direct->gamma = Acosd(G[0][1]/(direct->a * direct->c));
return 1;
}

58
cell.h Normal file
View File

@ -0,0 +1,58 @@
/**
* this is a little library for performing crystallographic cell transformations
* for SICS. Some of the actual code was lifted from the Risoe program tascom.
*
* copyright: see file COPYRIGHT
*
* Mark Koennecke, March 2005
*/
#ifndef SICSCELL
#define SICSCELL
#include "matrix/matrix.h"
/**
* error codes
*/
#define REC_NO_VOLUME -100
#define CELLNOMEMORY -101
/**
* lattice parameters: either reciprocal or direct
*/
typedef struct {
double a,b,c;
double alpha, beta, gamma;
}lattice, *plattice;
/**
* defaultCell assigns defualt values to cell parameters
* @param cell The lattice to assign default too
*/
void defaultCell(plattice cell);
/**
* conversion from a direct lattice to the recipcrocal one.
* @param direct The input direct cell parameters.
* @param reciprocal The output reciprocal cell constants
* @return 0 on success, > 0 else
*/
int directToReciprocalLattice(lattice direct, plattice reciprocal);
/**
* conversion from a reciprocal lattice to the directone.
* @param reciprocal The input reciprocal cell parameters.
* @param direct The output direct cell constants
* @return 0 on success, > 0 else
*/
int reciprocalToDirectLattice(lattice reciprocal, plattice direct);
/**
* calculate a crystallographic B matrix from the cell constants
* @param direct The direct cell lattice to calculate B from
* @param B will be filled with the B matrix. MUST be 3x3
* @return 1 on success, an negative error code else
*/
int calculateBMatrix(lattice direct, MATRIX B);
/**
* calculate the cell constants from a UB matrix
* @param UB The input UB matrix.
* @param direct A pointer to a structure holding the new cell constants
* @return 1 on success, an error c ode < 0 on failure
*/
int cellFromUB(MATRIX UB, plattice direct);
#endif

View File

@ -161,8 +161,6 @@
{
self->pDriv->Close(self->pDriv);
self->pDriv->Delete(self->pDriv);
if(self->pDriv->pParList)
free(self->pDriv->pParList);
free(self->pDriv);
}
if(self->pDes)

16
commandcontext.h Normal file
View File

@ -0,0 +1,16 @@
/*-------------------------------------------------
This file holds the command context structure which
is needed to make the sycamore protocol work.
Mark Koennecke, December 2005
-------------------------------------------------*/
#ifndef SICSCOMCONTEXT
#define SICSCOMCONTEXT
typedef struct{
int transID;
char deviceID[256];
}commandContext, *pCommandContext;
#define SCDEVIDLEN 256
#endif

View File

@ -27,8 +27,6 @@
/* in conman.c */
int TelnetWrite(mkChannel *pSock, char *pText);
/*-------------------- the command log file pointer ---------------------*/
static FILE *fd = NULL;
static FILE *fauto = NULL;
@ -82,9 +80,11 @@
}
/* suppress TRANSACTIONFINISHED as well in order to make the WWW
commandlog work
commandlog work and TRANSACTIONSTART in order to make the logfiles
shorter
*/
if(strstr(pText,"TRANSACTIONFINISHED") != NULL)
if(strstr(pText,"TRANSACTIONFINISHED") != NULL ||
strstr(pText,"TRANSACTIONSTART") != NULL)
{
if(pCopy != NULL){
free(pCopy);
@ -122,6 +122,13 @@
fprintf(fauto,"%s %s\n",prompt, pText);
}
}
/* to all listening sockets. The check is necessary to resolve a shutdown problem */
if(pServ->pTasker != NULL)
{
TaskSignal(pServ->pTasker,COMLOG,pText);
}
/* tail buffer */
if(pTail != NULL)
{

357
cone.c Normal file
View File

@ -0,0 +1,357 @@
/*----------------------------------------------------------------------
SICS cone module for cone scans. Form more details see conescan.tex
and cone.tex.
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, March 2006
------------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
#include "cone.h"
#include "hkl.i"
#include "vector.h"
#include "fourlib.h"
/*=================== Object Descriptor Interface ===================================================*/
static void *ConeGetInterface(void *pData, int iID){
pConeData self = NULL;
self = (pConeData)pData;
if(self == NULL){
return NULL;
}
if(iID == DRIVEID){
return self->pDriv;
}
return NULL;
}
/*---------------------------------------------------------------------------------------------------*/
static void ConeSaveStatus(void *data, char *name, FILE *fd){
pConeData self = (pConeData)data;
if(self == NULL){
return;
}
fprintf(fd,"%s center %d\n", name,self->center);
fprintf(fd,"%s target %f %f %f\n", name, self->target.h,
self->target.k, self->target.l);
fprintf(fd,"%s qscale %f \n", name, self->qScale);
}
/*=================== Drivable Interface ============================================================*/
static int ConeHalt(void *pData){
pConeData self = NULL;
self = (pConeData)pData;
assert(self != NULL);
self->pHkl->pTheta->pDrivInt->Halt(self->pHkl->pTheta);
self->pHkl->pOmega->pDrivInt->Halt(self->pHkl->pOmega);
self->pHkl->pChi->pDrivInt->Halt(self->pHkl->pChi);
self->pHkl->pPhi->pDrivInt->Halt(self->pHkl->pPhi);
return 1;
}
/*-----------------------------------------------------------------------------------------------------*/
static int ConeCheckLimits(void *self, float fVal, char *error, int errLen){
/*
There is no meaningful implementation here. This gets called when starting the motor.
At that stage not all other values may be known. If the calculation fails, this will die
at status check time.
*/
return 1;
}
/*------------------------------------------------------------------------*/
static MATRIX makeCsToPsiMatrix(reflection center, double lambda){
MATRIX psiToCs = NULL, csToPsi = NULL, t1, t2;
double z1[3], u;
psiToCs = makeInstToConeVectorMatrix(center,lambda);
if(psiToCs == NULL){
return NULL;
}
csToPsi = mat_inv(psiToCs);
/*
* this is debugging code: remove together with variables
*/
z1FromAngles(lambda,center.s2t,center.om,center.chi,center.phi,z1);
t1 = makeVectorInit(z1);
t2 = mat_mul(psiToCs,t1);
normalizeVector(t2);
t1[0][0] = .0;
t1[1][0] = .0;
t1[2][0] = 1.;
u = angleBetween(t1,t2);
mat_free(psiToCs);
return csToPsi;
}
/*----------------------------------------------------------------------------------------------------
* I am lazy in this function: I calculate anew from all the data. This saves
* me a lot of trouble keeping track of parameter changes in UBCALC etc.
* ---------------------------------------------------------------------------*/
static long ConeSetValue(void *pData, SConnection *pCon, float fVal){
pConeData self = NULL;
float fSet[4];
double openingAngle, length;
MATRIX csToPsi = NULL, B = NULL, newScat = NULL;
int status;
reflection center;
char buffer[131];
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self = (pConeData)pData;
assert(self != NULL);
/*
* calculate opening angle
*/
B = mat_creat(3,3,UNIT_MATRIX);
status = calculateBMatrix(self->ubi->direct,B);
if(status < 0){
SCWrite(pCon,"ERROR: cell has no volume",eError);
return 0;
}
center = getReflection(self->ubi,self->center);
openingAngle = angleBetweenReflections(B,center,self->target);
/*
* calculate conversion matrix from cone system to PSI system
*/
csToPsi = makeCsToPsiMatrix(center,self->ubi->hkl->fLambda);
if(csToPsi == NULL){
SCWrite(pCon,"ERROR: bad parameters: failed to generate conversion matrix",
eError);
return 0;
}
/*
* calculate scattering vector on cone and make its length
* match the length of the apropriate scattering vector
*/
length = scatteringVectorLength(B,self->target) * self->qScale;
newScat = calcConeVector(openingAngle, fVal, length, csToPsi);
if(newScat == NULL){
SCWrite(pCon,"ERROR: fails to calculate cone vector",eError);
return 0;
}
/*
* try to find setting angles for this vector
*/
status = findAllowedBisecting(self->pHkl->fLambda,newScat, fSet,
hklInRange, self->pHkl);
/*
* clean up matrices
*/
mat_free(B);
mat_free(newScat);
mat_free(csToPsi);
if(status != 1){
SCWrite(pCon,"ERROR: cannot get cone vector into scattering position",
eError);
SCSetInterrupt(pCon,eAbortOperation);
return 0;
}
self->lastConeAngle = fVal;
/*
* start motors
*/
return startHKLMotors(self->pHkl, pCon,fSet);
}
/*---------------------------------------------------------------------------------------------------*/
static int checkMotors(pConeData self, SConnection *pCon){
int status;
status = self->pHkl->pTheta->pDrivInt->CheckStatus(self->pHkl->pTheta, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pOmega->pDrivInt->CheckStatus(self->pHkl->pOmega, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pChi->pDrivInt->CheckStatus(self->pHkl->pChi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
status = self->pHkl->pPhi->pDrivInt->CheckStatus(self->pHkl->pPhi, pCon);
if(status != HWIdle && status != OKOK){
return status;
}
return HWIdle;
}
/*-----------------------------------------------------------------------------------------------------*/
static int ConeCheckStatus(void *pData, SConnection *pCon){
pConeData self = NULL;
int status;
self = (pConeData)pData;
assert(self != NULL);
return checkMotors(self,pCon);
}
/*-----------------------------------------------------------------------------------------------------*/
static float ConeGetValue(void *pData, SConnection *pCon){
pConeData self = NULL;
float fVal[3];
int status;
self = (pConeData)pData;
assert(self != NULL);
return self->lastConeAngle;
}
/*=============================== Live and Death ====================================*/
static pConeData MakeConeMot(pUBCALC u){
pConeData self = NULL;
assert(u != NULL);
self = (pConeData)malloc(sizeof(coneData));
if(self == NULL){
return NULL;
}
memset(self,0,sizeof(coneData));
self->pDes = CreateDescriptor("Cone");
self->pDriv = CreateDrivableInterface();
if(self->pDes == NULL || self->pDriv == NULL){
free(self);
return NULL;
}
self->pDes->GetInterface = ConeGetInterface;
self->pDriv->Halt = ConeHalt;
self->pDriv->CheckLimits = ConeCheckLimits;
self->pDriv->SetValue = ConeSetValue;
self->pDriv->CheckStatus = ConeCheckStatus;
self->pDriv->GetValue = ConeGetValue;
self->ubi = u;
self->pHkl = u->hkl;
self->qScale = 1.0;
return self;
}
/*----------------------------------------------------------------------------------*/
static void KillConeMot(void *pData){
pConeData self = NULL;
self = (pConeData)pData;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->pDriv){
free(self->pDriv);
}
free(self);
}
/*=============================== Interpreter Interface ============================*/
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pConeData self = NULL;
float value;
int id;
char pBuffer[132];
self = (pConeData)pData;
assert(self != NULL);
if(argc > 1) {
strtolower(argv[1]);
if(strcmp(argv[1],"center") == 0){
if(argc > 2){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
id = atoi(argv[2]);
if(id < 0 || id > 2 ){
SCWrite(pCon,"ERROR: id must be between 0 - 3",eError);
return 0;
}
self->center = id;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.center = %d", argv[0], self->center);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if(strcmp(argv[1],"qscale") == 0){
if(argc > 2){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->qScale = atof(argv[2]);
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.qscale = %f", argv[0], self->qScale);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else if (strcmp(argv[1],"target") == 0){
if(argc >= 5){
if(!SCMatchRights(pCon,usUser)){
return 0;
}
self->target.h = atof(argv[2]);
self->target.k = atof(argv[3]);
self->target.l = atof(argv[4]);
self->qScale = 1.;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBuffer,131,"%s.target = %f %f %f", argv[0],
self->target.h, self->target.k, self->target.l);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
} else {
SCWrite(pCon,"ERROR: subcommand to cone not known",eError);
return 0;
}
}
/*
* default: print value
*/
value = self->pDriv->GetValue(self,pCon);
if(value < -9000.){
snprintf(pBuffer,131,"ERROR: failed to read %s",argv[0]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
snprintf(pBuffer,131,"%s = %f", argv[0], value);
SCWrite(pCon,pBuffer,eValue);
return 1;
}
/*------------------------------------------------------------------------------------------*/
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){
pUBCALC ubi = NULL;
pConeData pMot = NULL;
char pBuffer[131];
int status;
if(argc < 3){
SCWrite(pCon,"ERROR: insuffient number of arguments to MakeCone",eError);
return 0;
}
ubi = FindCommandData(pSics,argv[2],"UBcalc");
if(ubi == NULL){
snprintf(pBuffer,131,"ERROR: %s is no UBcalc object" , argv[2]);
SCWrite(pCon,pBuffer,eError);
return 0;
}
pMot = MakeConeMot(ubi);
if(pMot == NULL){
SCWrite(pCon,"ERROR: out of memory creating cone virtual motor",eError);
return 0;
}
status = AddCommand(pSics,argv[1],ConeAction,KillConeMot,pMot);
if(status != 1){
SCWrite(pCon,"ERROR: failed to create duplicate cone motor",eError);
}
return status;
}

33
cone.h Normal file
View File

@ -0,0 +1,33 @@
/*----------------------------------------------------------------------
SICS cone module for cone scans. Form more details see conescan.tex
and cone.tex.
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, March 2006
------------------------------------------------------------------------*/
#ifndef SICSCONE
#define SICSCONE
#include "sics.h"
#include "ubcalc.h"
/*-----------------------------------------------------------------------*/
typedef struct {
pObjectDescriptor pDes;
pIDrivable pDriv;
reflection target;
float lastConeAngle;
float qScale;
pUBCALC ubi;
int center;
pHKL pHkl;
} coneData, *pConeData;
/*----------------------------------------------------------------------*/
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
#endif

69
cone.w Normal file
View File

@ -0,0 +1,69 @@
\subsection{Cone}
This module is a virtual motor for driving on a cone around a give center reflection.
The application is in four circle diffractometry. Consider, a reflection has been
found and indexed. If the cell parameters are known, we now know that at a certain
two theta and at a certain agle around the first reflection there should be
another one. Serching this cone would speed up UB matrix determination. Driving on such
a cone and therewith scanning it is implemented in this module.
The math for doing this is detailed in a separate internal paper: conescan.tex.
For its implementation, cone works very closely with the UBCALC module. UBCALC
provides the cell constants and it also provides the list of reflections from
which to get the center reflection of the cone.
The module requires a data structure:
@d conedat @{
typedef struct {
pObjectDescriptor pDes;
pIDrivable pDriv;
reflection target;
float lastConeAngle;
float qScale;
pUBCALC ubi;
int center;
pHKL pHkl;
} coneData, *pConeData;
@}
The fields are:
\begin{description}
\item[pDes] The standard object descriptor
\item[pDriv] The drivable interface which implements most of this modules
functionality.
\item[lastConeAngle] The last cone angle set. Used instead of the not implemented
back calculation.
\item[qScale] An adaptor factor to multiply onto the scattering vector length. This is
in order to find the target reflection even if the lattice constants are inaccurate.
\item[target] The target reflection of the cone. This determines the length
of the scattering vector and the opening angle of the cone.
\item[ubi] A pointer to the UBCALC module which holds things like lattice constants.
\item[center] The reflection number in UBCALCS reflection list to use as the
center of the cone.
\end{description}
The external interface to cone is mostly defined by the drivable interface. In
addition there are only the usal interpreter interface functions to install and
configure cone.
@o cone.h @{
/*----------------------------------------------------------------------
SICS cone module for cone scans. Form more details see conescan.tex
and cone.tex.
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, March 2006
------------------------------------------------------------------------*/
#ifndef SICSCONE
#define SICSCONE
#include "sics.h"
#include "ubcalc.h"
/*-----------------------------------------------------------------------*/
@<conedat@>
/*----------------------------------------------------------------------*/
int MakeCone(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int ConeAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
#endif
@}

View File

@ -19,8 +19,12 @@
int ListObjects(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
lists all avialable objects. Realised in Scinter.c
*/
int SicsAtt(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
handling of SICS object attributes. In SCinter.c
*/
#endif

21
confvirtmot.h Normal file
View File

@ -0,0 +1,21 @@
/*-----------------------------------------------------------------------
A configurable virtual motor object. At motor start a script is called
which returns the motors and positions to drive as a comma separated
list holding entries of the form mot=value.
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, August 2004
-------------------------------------------------------------------------*/
#ifndef CONFIGURABLEVIRTUALMOTOR
#define CONFIGURABLEVIRTUALMOTOR
#include "sics.h"
int MakeConfigurableVirtualMotor(SConnection *pCon, SicsInterp *pSics,
void *data, int aargc, char *argv[]);
int ConfigurableVirtualMotorAction(SConnection *pCon, SicsInterp *pSics,
void *data, int argc, char *argv[]);
#endif

22
confvirtmot.i Normal file
View File

@ -0,0 +1,22 @@
/*-----------------------------------------------------------------------
Configurable Virtual Motor. This is an generated file describing the
internal data structure of this object. Do not edit.
-----------------------------------------------------------------------*/
typedef struct __CONFVIRTMOT {
pObjectDescriptor pDes;
pIDrivable pDriv;
pICallBack pCall;
char *name;
char *scriptName;
char *readScript;
int motorList;
float targetValue;
int targetReached;
int posCount;
char scriptError[512];
int parseOK;
}ConfigurableVirtualMotor, *pConfigurableVirtualMotor;

580
confvirtualmot.c Normal file
View File

@ -0,0 +1,580 @@
/*-----------------------------------------------------------------------
A configurable virtual motor object. At motor start a script is called
which returns the motors and positions to drive as a comma separated
list holding entries of the form mot=value.
This is the implementation file.
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, August 2004
interest added: Ferdi Franceschini, April 2006
-------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include "fortify.h"
#include <tcl.h>
#include "lld.h"
#include "splitter.h"
#include "confvirtmot.h"
#include "confvirtmot.i"
extern char *stptok(char *s, char *t, int len, char *brk);
/*---------------------------------------------------------------------------
An internal data structure which holds information required to control
the real motors
----------------------------------------------------------------------------*/
typedef struct {
char name[132];
void *data;
pIDrivable pDriv;
float value;
int running;
} RealMotor, *pRealMotor;
/* Data passed by event generating object */
typedef struct {
float fVal;
char *pName;
} EventInfo;
/* Data available when registering interest */
typedef struct {
char *pName;
SConnection *pCon;
float lastValue;
} RegisteredInfo, *pRegisteredInfo;
/*---------------------------------------------------------------------*/
static int HaltMotors(void *pData){
pConfigurableVirtualMotor self = (pConfigurableVirtualMotor)pData;
RealMotor tuktuk;
int iRet;
iRet = LLDnodePtr2First(self->motorList);
while(iRet != 0)
{
LLDnodeDataTo(self->motorList,&tuktuk);
tuktuk.pDriv->Halt(tuktuk.data);
iRet = LLDnodePtr2Next(self->motorList);
}
return 1;
}
/*----------------------------------------------------------------------*/
static char *invokeMotorScript(pConfigurableVirtualMotor self,
float newValue){
char pBueffel[512];
Tcl_Interp *pTcl;
int status;
self->parseOK = 1;
if(self->scriptName == NULL){
snprintf(self->scriptError,511,
"ERROR: no script configured for configurable virtual motor");
self->parseOK = 0;
return NULL;
}
snprintf(pBueffel,510,"%s %f",self->scriptName, newValue);
pTcl = InterpGetTcl(pServ->pSics);
status = Tcl_Eval(pTcl, pBueffel);
if(status != TCL_OK){
snprintf(self->scriptError,510,"ERROR: Tcl subsystem reported %s",
Tcl_GetStringResult(pTcl));
self->parseOK = 0;
return NULL;
}
return (char *)Tcl_GetStringResult(pTcl);
}
/*--------------------------------------------------------------------*/
static int parseEntry(pConfigurableVirtualMotor self,
char *entry){
RealMotor tuktuk;
char *pPtr = NULL;
char number[80], pError[256];
CommandList *pCom = NULL;
int status;
pPtr = entry;
pPtr = stptok(pPtr,tuktuk.name,131,"=");
if(pPtr == NULL){
snprintf(self->scriptError,510,"ERROR: cannot interpret %s, %s", entry,
"require format: motor=value");
self->parseOK = 0;
return 0;
}
tuktuk.pDriv = (pIDrivable)FindDrivable(pServ->pSics,tuktuk.name);
pCom = FindCommand(pServ->pSics,tuktuk.name);
if(!pCom){
snprintf(self->scriptError,510,"ERROR: %s not found",tuktuk.name);
self->parseOK = 0;
return 0;
}
tuktuk.data = pCom->pData;
if(tuktuk.pDriv == NULL){
snprintf(self->scriptError,510,"ERROR: %s is not drivable",tuktuk.name);
self->parseOK = 0;
return 0;
}
pPtr = stptok(pPtr,number,79,"=");
tuktuk.value = atof(number);
LLDnodeAppendFrom(self->motorList,&tuktuk);
return 1;
}
/*----------------------------------------------------------------------*/
static int parseCommandList(pConfigurableVirtualMotor self,
char *commandList){
char pEntry[256], *pPtr;
int status;
LLDdelete(self->motorList);
self->motorList = LLDcreate(sizeof(RealMotor));
pPtr = commandList;
while((pPtr = stptok(pPtr,pEntry,255,",")) != NULL){
status = parseEntry(self,pEntry);
if(status != 1){
return 0;
}
}
return 1;
}
/*-----------------------------------------------------------------------*/
static int startMotorList(pConfigurableVirtualMotor self, SConnection *pCon){
RealMotor tuktuk;
int status, iRet;
iRet = LLDnodePtr2First(self->motorList);
while(iRet != 0)
{
LLDnodeDataTo(self->motorList,&tuktuk);
status = tuktuk.pDriv->SetValue(tuktuk.data,pCon,tuktuk.value);
if(status != 1){
return status;
}
tuktuk.running = 1;
LLDnodeDataFrom(self->motorList,&tuktuk);
iRet = LLDnodePtr2Next(self->motorList);
}
return OKOK;
}
/*------------------------------------------------------------------------*/
static long ConfSetValue(void *pData, SConnection *pCon, float newValue){
pConfigurableVirtualMotor self = (pConfigurableVirtualMotor)pData;
char *commandList = NULL;
int status;
assert(self != NULL);
commandList = invokeMotorScript(self,newValue);
if(commandList == NULL){
SCWrite(pCon,self->scriptError,eError);
return 0;
}
status = parseCommandList(self,commandList);
if(status != 1){
SCWrite(pCon,self->scriptError,eError);
return 0;
}
self->targetValue = newValue;
self->targetReached = 0;
self->posCount = 0;
status = startMotorList(self,pCon);
if(status != OKOK){
HaltMotors(self);
}
return OKOK;
}
/*-----------------------------------------------------------------------*/
static int ConfCheckLimits(void *pData, float fVal, char *error, int errLen){
pConfigurableVirtualMotor self = (pConfigurableVirtualMotor)pData;
char *commandList = NULL;
int status, iRet;
RealMotor tuktuk;
assert(self != NULL);
if(self->targetValue != fVal){
commandList = invokeMotorScript(self,fVal);
if(commandList == NULL){
strncpy(error,self->scriptError,errLen);
return 0;
}
status = parseCommandList(self,commandList);
if(status != 1){
strncpy(error,self->scriptError,errLen);
return 0;
}
}
iRet = LLDnodePtr2First(self->motorList);
while(iRet != 0)
{
LLDnodeDataTo(self->motorList,&tuktuk);
status = tuktuk.pDriv->CheckLimits(tuktuk.data,tuktuk.value,error,errLen);
if(status != 1){
return status;
}
iRet = LLDnodePtr2Next(self->motorList);
}
return 1;
}
static void KillInfo(void *pData)
{
pRegisteredInfo self = NULL;
assert(pData);
self = (pRegisteredInfo)pData;
if(self->pName)
{
free(self->pName);
}
free(self);
}
/*------------------- The CallBack function for interest ------------------
* iEvent: Event ID, see event.h for SICS events
* pEvent: May contain data from event generating object
* pUser: Data available when registering interest, see RegisteredInfo struct
* defined above for available info */
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{
pRegisteredInfo pInfo = NULL;
char pBueffel[80];
EventInfo *pEventData;
assert(pEvent);
assert(pUser);
pEventData = (EventInfo *)pEvent;
pInfo = (RegisteredInfo *)pUser;
if (pInfo->lastValue != pEventData->fVal) {
pInfo->lastValue = pEventData->fVal;
(pInfo->pCon)->conEventType=POSITION;
sprintf(pBueffel,"%s.position = %f ", pInfo->pName, pInfo->lastValue);
SCWriteInContext(pInfo->pCon,pBueffel,eEvent,cc);
}
return 1;
}
/*------------------------------------------------------------------------*/
static int ConfCheckStatus(void *pData, SConnection *pCon){
pConfigurableVirtualMotor self = (pConfigurableVirtualMotor)pData;
RealMotor tuktuk;
int iRet, status, result;
EventInfo event;
result = HWIdle;
iRet = LLDnodePtr2First(self->motorList);
while(iRet != 0)
{
LLDnodeDataTo(self->motorList,&tuktuk);
if(tuktuk.running == 1){
status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
switch(status){
case HWIdle:
tuktuk.running = 0;
LLDnodeDataFrom(self->motorList,&tuktuk);
break;
case HWBusy:
result = HWBusy;
break;
case HWFault:
case HWPosFault:
return status;
break;
default:
/*
this is a programming error and has to be fixed
*/
assert(0);
}
}
iRet = LLDnodePtr2Next(self->motorList);
}
if (result == HWIdle) {
event.pName = self->name;
event.fVal = self->pDriv->GetValue(self,pCon);
InvokeCallBack(self->pCall, MOTDRIVE, &event);
} else if (result == HWBusy) {
self->posCount++;
if(self->posCount >= 10/*ObVal(self->ParArray,MOVECOUNT)*/)
{
event.pName = self->name;
event.fVal = self->pDriv->GetValue(self,pCon);
InvokeCallBack(self->pCall, MOTDRIVE, &event);
self->posCount = 0;
}
}
return result;
}
/*---------------------------------------------------------------------*/
static float invokeReadScript(pConfigurableVirtualMotor self,
SConnection *pCon){
Tcl_Interp *pTcl;
int status;
pTcl = InterpGetTcl(pServ->pSics);
status = Tcl_Eval(pTcl, self->readScript);
if(status != TCL_OK){
snprintf(self->scriptError,510,"ERROR: Tcl subsystem reported %s",
Tcl_GetStringResult(pTcl));
}
return atof(Tcl_GetStringResult(pTcl));
}
/*---------------------------------------------------------------------*/
static void checkMotorValues(pConfigurableVirtualMotor self,
SConnection *pCon){
int iRet;
float value;
RealMotor tuktuk;
char pBueffel[512];
iRet = LLDnodePtr2First(self->motorList);
while(iRet != 0)
{
LLDnodeDataTo(self->motorList,&tuktuk);
value = tuktuk.pDriv->GetValue(tuktuk.data,pCon);
value -= tuktuk.value;
if(value < .0){
value *= -1;
}
if(value > .1) {
snprintf(pBueffel,510,"WARNING: motor %s of position by %f",
tuktuk.name,value);
SCWrite(pCon,pBueffel,eWarning);
return;
}
iRet = LLDnodePtr2Next(self->motorList);
}
self->targetReached = 1;
}
/*-----------------------------------------------------------------------*/
static float ConfGetValue(void *pData, SConnection *pCon){
pConfigurableVirtualMotor self = (pConfigurableVirtualMotor)pData;
float currentValue = -9999.99;
assert(self != NULL);
if(self->readScript != NULL){
currentValue = invokeReadScript(self,pCon);
} else {
if(self->targetReached == 1){
return self->targetValue;
} else {
checkMotorValues(self,pCon);
if(self->targetReached){
currentValue = self->targetValue;
}
}
}
return currentValue;
}
/*-----------------------------------------------------------------------*/
static void *GetConfigurableVirtualMotorInterface(void *pData, int iID){
pConfigurableVirtualMotor self = NULL;
self = (pConfigurableVirtualMotor)pData;
assert(self);
if(iID == DRIVEID){
return self->pDriv;
} else if(iID == CALLBACKINTERFACE)
{
return self->pCall;
}
return NULL;
}
/*-----------------------------------------------------------------------*/
static void KillConfigurableVirtualMotor(void *data){
pConfigurableVirtualMotor self = NULL;
self = (pConfigurableVirtualMotor)data;
if(self != NULL){
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
self->pDes = NULL;
}
LLDdelete(self->motorList);
if (self->name != NULL) {
free(self->name);
self->name = NULL;
}
if(self->scriptName != NULL){
free(self->scriptName);
self->scriptName = NULL;
}
if(self->readScript != NULL){
free(self->readScript);
self->readScript = NULL;
}
free(self);
self = NULL;
}
}
/*------------------------------------------------------------------------*/
int MakeConfigurableVirtualMotor(SConnection *pCon, SicsInterp *pSics,
void *data, int argc, char *argv[]){
pConfigurableVirtualMotor pNew = NULL;
char pBueffel[512];
if(argc < 2){
SCWrite(pCon,"ERROR: need name to create configurable motor",eError);
return 0;
}
pNew = (pConfigurableVirtualMotor)malloc(sizeof(ConfigurableVirtualMotor));
if(pNew == NULL){
SCWrite(pCon,"ERROR: no memory to create configurable virtual motor",
eError);
return 0;
}
memset(pNew,0,sizeof(ConfigurableVirtualMotor));
pNew->name = strdup(argv[1]);
pNew->posCount = 0;
pNew->pDes = CreateDescriptor("ConfigurableVirtualMotor");
pNew->pDriv = CreateDrivableInterface();
pNew->motorList = LLDcreate(sizeof(RealMotor));
if(pNew->pDes == NULL || pNew->pDriv == NULL || pNew->motorList < 0){
SCWrite(pCon,"ERROR: no memory to create configurable virtual motor",
eError);
return 0;
}
/*
assign functions
*/
pNew->pDes->GetInterface = GetConfigurableVirtualMotorInterface;
pNew->pDriv->Halt = HaltMotors;
pNew->pDriv->CheckLimits = ConfCheckLimits;
pNew->pDriv->SetValue = ConfSetValue;
pNew->pDriv->CheckStatus = ConfCheckStatus;
pNew->pDriv->GetValue = ConfGetValue;
/* initialise callback interface */
pNew->pCall = CreateCallBackInterface();
if(!pNew->pCall)
{
KillConfigurableVirtualMotor(pNew);
return 0;
}
/*
install command
*/
if( AddCommand(pSics,argv[1],ConfigurableVirtualMotorAction,
KillConfigurableVirtualMotor,pNew) != 1){
snprintf(pBueffel,510,"ERROR: duplicate command %s not created",
argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
} else {
SCSendOK(pCon);
}
return 1;
}
/*-----------------------------------------------------------------------*/
int ConfigurableVirtualMotorAction(SConnection *pCon, SicsInterp *pSics,
void *data, int argc, char *argv[]){
pConfigurableVirtualMotor self = NULL;
char pBueffel[512];
float value;
int iRet;
long lID;
pRegisteredInfo pRegInfo = NULL;
self = (pConfigurableVirtualMotor)data;
assert(self != NULL);
if(argc > 1){
strtolower(argv[1]);
if(strcmp(argv[1],"drivescript") == 0){
if(argc > 2){
/* set case */
Arg2Text(argc-2,&argv[2],pBueffel,510);
self->scriptName = strdup(pBueffel);
SCSendOK(pCon);
return 1;
} else {
/* inquiry */
if(self->scriptName == NULL){
snprintf(pBueffel,510,"%s.drivescript = UNDEFINED", argv[0]);
SCWrite(pCon,pBueffel,eValue);
return 1;
} else {
snprintf(pBueffel,510,"%s.drivescript = %s", argv[0],
self->scriptName);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
}else if(strcmp(argv[1],"readscript") == 0){
if(argc > 2){
/* set case */
Arg2Text(argc-2,&argv[2],pBueffel,510);
self->readScript = strdup(pBueffel);
SCSendOK(pCon);
return 1;
} else {
/* inquiry */
if(self->readScript == NULL){
snprintf(pBueffel,510,"%s.readscript = UNDEFINED", argv[0]);
SCWrite(pCon,pBueffel,eValue);
return 1;
} else {
snprintf(pBueffel,510,"%s.readscript = %s", argv[0],
self->readScript);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}
} else if(strcmp(argv[1],"interest") == 0)
{
pRegInfo = (pRegisteredInfo)malloc(sizeof(RegisteredInfo));
if(!pRegInfo)
{
SCWrite(pCon,"ERROR: out of memory in confvirtualmot.c",eError);
return 0;
}
pRegInfo->pName = strdup(argv[0]);
pRegInfo->pCon = pCon;
value = ConfGetValue(self,pCon);
if(!iRet)
{
sprintf(pBueffel,"Failed to register interest, Reason:Error obtaining current position for %s",argv[0]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pRegInfo->lastValue = value;
lID = RegisterCallback(self->pCall, SCGetContext(pCon),MOTDRIVE, InterestCallback, pRegInfo, KillInfo);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel,5120,"ERROR: subcommand %s to %s unknown",
argv[1],argv[0]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
} else {
value = self->pDriv->GetValue(self,pCon);
snprintf(pBueffel,510,"%s = %f", argv[0],value);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
}

82
confvirtualmot.w Normal file
View File

@ -0,0 +1,82 @@
\subsection{Configurable Virtual Motor}
This is an object which can help in realizing complex scans in space.
In principle this object implements a virtual motor. When this motor is
started a script is called with the desired new position as a parameter.
This script is supposed to either return an error or a comma separated
list of strings motor=value. The name of this script is a configurable
parameter. The object then takes care of starting all the motors (or
better Drivables) and watching over them during the driving operation.
This objects data structure:
@d confvirt @{
typedef struct __CONFVIRTMOT {
pObjectDescriptor pDes;
pIDrivable pDriv;
pICallBack pCall;
char *name;
char *scriptName;
char *readScript;
int motorList;
float targetValue;
int targetReached;
int posCount;
char scriptError[512];
int parseOK;
}ConfigurableVirtualMotor, *pConfigurableVirtualMotor;
@}
The fields are:
\begin{description}
\item[pDes] The standard object descriptor.
\item[pDriv] The drivable interface
\item[pCall] The callback interface
\item[name] The name of the virtual motor
\item[scriptName] The name of the program to calculate the new positions
of the real motors.
\item[readScript] A script to read back the current value of the virtual motor.
\item[motorList] A list of the motors to start and control.
\item[targetValue] The target value we wanted to have.
\item[posCount] This counter prevents the callback from being invoked too often. The frequency is currently set to every 10 cycles through the task loop.
\item[targetReached] A flag which becomes true when a check has showed that
all desired motors have reached their targets.
\item[scriptError] A temporary buffer holding all errors encountered
during processing of the script.
\item[parseOK] a flag which indicates if parsing and execution of the
script went OK.
\end{description}
All the magic of this object is hidden in the implementation of the methods
of the drivable interface. Additioanlly there is the standard interpreter
interface.
@o confvirtmot.i @{
/*-----------------------------------------------------------------------
Configurable Virtual Motor. This is an generated file describing the
internal data structure of this object. Do not edit.
-----------------------------------------------------------------------*/
@< confvirt @>
@}
@o confvirtmot.h @{
/*-----------------------------------------------------------------------
A configurable virtual motor object. At motor start a script is called
which returns the motors and positions to drive as a comma separated
list holding entries of the form mot=value.
COPYRIGHT: see file COPYRIGHT
Mark Koennecke, August 2004
-------------------------------------------------------------------------*/
#ifndef CONFIGURABLEVIRTUALMOTOR
#define CONFIGURABLEVIRTUALMOTOR
#include "sics.h"
int MakeConfigurableVirtualMotor(SConnection *pCon, SicsInterp *pSics,
void *data, int aargc, char *argv[]);
int ConfigurableVirtualMotorAction(SConnection *pCon, SicsInterp *pSics,
void *data, int argc, char *argv[]);
#endif
@}

959
conman.c

File diff suppressed because it is too large Load Diff

107
conman.h
View File

@ -12,6 +12,8 @@
Mark Koennecke, Aprl 2003
Mark Koennecke, December 2004
copyright: see copyright.h
----------------------------------------------------------------------------*/
#ifndef SICSCONNECT
@ -21,6 +23,7 @@
#include "SCinter.h"
#include "network.h"
#include "obdes.h"
#include "commandcontext.h"
#define MAXLOGFILES 10
@ -30,46 +33,58 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
typedef struct __SConnection {
/* object basics */
pObjectDescriptor pDes;
char *pName;
long lMagic;
long ident;
struct __SConnection *next;
/* I/O control */
/* our socket */
mkChannel *pSock;
/* per connection log files */
FILE *pFiles[MAXLOGFILES];
int iMacro;
int iTelnet;
int iOutput;
int iFiles;
writeFunc write;
mkChannel *pDataSock;
char *pDataComp;
int iDataPort;
int iMacro; /* suppress I/O in macro*/
int iTelnet; /* telnet flag */
int iOutput;
writeFunc write; /* function doing
writing */
int listening; /* for listening to commandlog or other data */
/* execution context */
int eInterrupt;
int eInterrupt;
int iUserRights;
int inUse;
int iDummy;
int iGrab;
int iErrCode;
int inUse;
int iGrab; /* grab flag for token*/
int parameterChange;
SicsInterp *pSics;
int sicsError;
/*
stuff supporting the sycamore protocol and a
command context
*/
long iCmdCtr;
int conEventType;
int conStatus; /* should use status enum ffr */
int iProtocolID;
int contextStack;
/* a FIFO */
pCosta pStack;
/* callback registry */
int iList;
/* Tasking Stuff */
int iEnd;
/* for keeping track of the login
process on a non telnet connection.
Should only be used in SCTaskFunction
*/
int iLogin;
time_t conStart;
}SConnection;
/* Tasking Stuff */
int iEnd;
/* for keeping track of the login
process on a non telnet connection.
Should only be used in SCTaskFunction
*/
int iLogin;
time_t conStart;
} SConnection;
#include "nserver.h"
@ -87,6 +102,7 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCDelLogFile(SConnection *pCon, int iFile);
void SCSetOutputClass(SConnection *self, int iClass);
int SCWrite(SConnection *self, char *pBuffer, int iOut);
int SCPrintf(SConnection *self, int iOut, char *fmt, ...);
int SCRead(SConnection *self, char *pBuffer, int iBufLen);
int SCPrompt(SConnection *pCon, char *pPrompt, char *pResult, int iLen);
int SCSendOK(SConnection *self);
@ -96,11 +112,25 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
writeFunc SCGetWriteFunc(SConnection *pCon);
void SCSetWriteFunc(SConnection *pCon, writeFunc x);
int SCOnlySockWrite(SConnection *self, char *buffer, int iOut);
int SCFileWrite(SConnection *self, char *buffer, int iOut);
int SCNotWrite(SConnection *self, char *buffer, int iOut);
int SCNormalWrite(SConnection *self, char *buffer, int iOut);
int SCWriteWithOutcode(SConnection *self, char *buffer, int iOut);
/************************* CallBack *********************************** */
int SCRegister(SConnection *pCon, SicsInterp *pSics,
void *pInter, long lID);
int SCUnregister(SConnection *pCon, void *pInter);
/**
* delete a callback with the given ID
*/
int SCUnregisterID(SConnection *pCon, long ID);
/**
* retrieve the ID of a callback on the callback interface
* given in pData. This, together with SCUnregisterID allows to
* ceanly remove all callbacks on a connection
* returns -1 if no ID can be found.
*/
long SCgetCallbackID(SConnection *pCon, void *pData);
/******************************* Error **************************************/
void SCSetInterrupt(SConnection *self, int eCode);
int SCGetInterrupt(SConnection *self);
@ -115,6 +145,7 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int SCMatchRights(SConnection *pCon, int iCode);
int SCGetOutClass(SConnection *self);
int SCGetGrab(SConnection *pCon);
int SCActive(SConnection *pCon);
/********************* simulation mode ************************************/
void SCSetSimMode(SConnection *pCon, int value);
int SCinSimMode(SConnection *pCon);
@ -126,7 +157,31 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
int argc, char *argv[]);
int ConSicsAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/******************************** Store ************************************/
typedef struct {
SConnection *pCon;
long ident;
} SCStore;
void SCSave(SCStore *con, SConnection *pCon);
/* save a connection for later use. */
SConnection *SCLoad(SCStore *con);
/* check con and return SConnection if still valid or NULL otherwise. */
void KillFreeConnections(void);
/*------------------------------------------------------------------------*/
int SCVerifyConnection(SConnection *self);
void SCWriteToLogFiles(SConnection *self, char *buffer);
int SCDoSockWrite(SConnection *self, char *buffer);
int SCWriteInContext(SConnection *pCon, char *buffer, int code, commandContext cc);
long SCTagContext(SConnection *self, char *tagName);
long SCAdvanceContext(SConnection *self, char *tagName);
int SCPushContext(SConnection *pCon, int ID, char *deviceID);
int SCPushContext2(SConnection *pCon, commandContext cc);
int SCPopContext(SConnection *pCon);
commandContext SCGetContext(SConnection *pCon);
#endif

View File

@ -92,9 +92,7 @@
if(self->KillPrivate != NULL)
{
self->KillPrivate(self);
} else {
free(self->pData);
}
}
}
free(self);
}

View File

@ -81,5 +81,11 @@
/* PSI Simulation counter, if you have no hardware */
/* simcter.c */
pCounterDriver NewSIMCounter(char *name, float fVal);
void KillSIMCounter(pCounterDriver self);
void KillSIMCounter(pCounterDriver self);
/*
* McStas simulation counter driver
* file: mcstascounter.c
*/
pCounterDriver NewMcStasCounter(char *name);
#endif

View File

@ -103,6 +103,7 @@
if(iRet == OKOK)
{
self->isUpToDate = 0;
self->badStatusCount = 0;
self->tStart = time(&tX);
InvokeCallBack(self->pCall,COUNTSTART,pCon);
return iRet;
@ -224,11 +225,12 @@
eCt = self->pDriv->GetStatus(self->pDriv,&fControl);
if(eCt == HWFault)
{
self->badStatusCount++;
iRet = self->pDriv->GetError(self->pDriv,&iErr,pError,79);
sprintf(pBueffel,"WARNING: %s ",pError);
SCWrite(pCon,pBueffel,eError);
iRet = self->pDriv->TryAndFixIt(self->pDriv,iErr);
if(iRet == COTERM)
if(iRet == COTERM || self->badStatusCount > 3)
{
SCWrite(pCon,"ERROR: Cannot fix counter problem, aborting",eError);
SCSetInterrupt(pCon,eAbortBatch);
@ -247,6 +249,7 @@
sMon.fCurrent = fControl;
sMon.fPreset = self->pDriv->fPreset;
sMon.pName = self->name;
self->badStatusCount = 0; /* clear: we managed to read OK */
if(self->iCallbackCounter > 20)
{
InvokeCallBack(self->pCall,MONITOR,&sMon);
@ -526,6 +529,13 @@
}
}
/*
* test for McStas simulation counter driver
*/
if(strcmp(argv[2],"mcstas") == 0){
pDriv = NewMcStasCounter(argv[1]);
}
if(!pDriv)
{
sprintf(pBueffel,"ERROR: cannot create requested driver %s",
@ -663,6 +673,16 @@
return self->pDriv->lCounts[iNum];
}
}
/*-----------------------------------------------------------------------*/
void SetMonitorValue(pCounter self, int index, long value)
{
assert(self);
if(index >= 0 && index < self->pDriv->iNoOfMonitors)
{
self->pDriv->lCounts[index] = value;
}
}
/*------------------------------------------------------------------------*/
float GetCountTime(pCounter self,SConnection *pCon)
{
@ -688,11 +708,13 @@
return 1;
}
/*-----------------------------------------------------------------------*/
static int CounterInterest(int iEvent, void *pEvent, void *pUser)
static int CounterInterest(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{
SConnection *pCon = NULL;
pMonEvent pMon = NULL;
char pBueffel[512];
int rights;
if(iEvent != MONITOR)
{
@ -705,7 +727,13 @@
assert(pMon);
sprintf(pBueffel,"%s.CountStatus = %f %d",pMon->pName,pMon->fPreset,
(int)nintf(pMon->fCurrent));
SCWrite(pCon,pBueffel,eWarning);
/**
* prevent this to be written to log files
*/
rights = SCGetRights(pCon);
SCSetRights(pCon,usSpy);
SCWriteInContext(pCon,pBueffel,eWarning,cc);
SCSetRights(pCon,rights);
return 1;
}
/*-----------------------------------------------------------------------*/
@ -869,7 +897,7 @@
SCWrite(pCon,pBueffel,eValue);
return 1;
case 9: /* interest */
lID = RegisterCallback(self->pCall, MONITOR, CounterInterest,
lID = RegisterCallback(self->pCall, SCGetContext(pCon), MONITOR, CounterInterest,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);

View File

@ -23,6 +23,7 @@
pICallBack pCall;
unsigned long tStart;
int iCallbackCounter;
int badStatusCount;
} Counter, *pCounter;
/*----------------------------- birth & death -----------------------------*/
@ -41,6 +42,7 @@
long GetCounts(pCounter self, SConnection *pCon);
long GetMonitor(pCounter self, int iNum, SConnection *pCon);
int GetNMonitor(pCounter self);
void SetMonitorValue(pCounter self, int index, long value);
float GetCountTime(pCounter self, SConnection *pCon);
int DoCount(pCounter self,float fPreset, SConnection *pCon,

8
danu.c
View File

@ -95,7 +95,8 @@ static int writeDataNumber(pDataNumber self, int iNum)
return 1;
}
/*------------------- The CallBack function for interest ------------------*/
static int InterestCallback(int iEvent, void *pEvent, void *pUser)
static int InterestCallback(int iEvent, void *pEvent, void *pUser,
commandContext cc)
{
pDataNumber self = NULL;
SConnection *pCon = NULL;
@ -120,7 +121,7 @@ static int writeDataNumber(pDataNumber self, int iNum)
if(iNum > 0)
{
snprintf(pBueffel,131,"sicsdatanumber = %d", iNum);
SCWrite(pCon,pBueffel,eValue);
SCWriteInContext(pCon,pBueffel,eValue,cc);
}
return 1;
}
@ -330,7 +331,8 @@ int NewThousand(pDataNumber self)
}
if(strcmp(argv[1],"interest") == 0)
{
lID = RegisterCallback(self->pCall, VALUECHANGE, InterestCallback,
lID = RegisterCallback(self->pCall, SCGetContext(pCon),
VALUECHANGE, InterestCallback,
pCon, NULL);
SCRegister(pCon,pSics, self->pCall,lID);
SCSendOK(pCon);

257
devexec.c
View File

@ -41,6 +41,7 @@
-----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <string.h>
#include "fortify.h"
#include "sics.h"
@ -61,6 +62,7 @@
pObjectDescriptor pDescriptor;
float fVal;
char *name;
commandContext comCon;
} DevEntry, *pDevEntry;
/*-------------------------------------------------------------------------*/
static pDevEntry CreateDevEntry(pObjectDescriptor pDes, void *pData,
@ -79,6 +81,7 @@
pNew->pData = pData;
pNew->name = strdup(name);
pNew->fVal = fVal;
memset(&pNew->comCon,0,sizeof(commandContext));
return pNew;
}
/*-------------------------------------------------------------------------*/
@ -102,9 +105,12 @@
int iStop;
int iStatus;
int iEnd;
int drivePrint;
long lTask;
pTaskMan pTask;
int iLock;
pICallBack pCall;
time_t lastRun;
} ExeList;
static pExeList pExecutor = NULL;
@ -139,6 +145,9 @@
pRes->pTask = pTask;
pRes->lTask = -1;
pRes->iLock = 0;
pRes->drivePrint = 0;
pRes->pCall = CreateCallBackInterface();
pRes->lastRun = time(NULL);
return pRes;
}
/*-------------------------------------------------------------------------*/
@ -153,8 +162,21 @@
DeleteDescriptor(self->pDes);
ClearExecutor(self);
LLDdelete(self->iList);
if(self->pCall)
DeleteCallBackInterface(self->pCall);
free(self);
pServ->pExecutor = NULL;
}
/*--------------------------------------------------------------------------*/
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
char buf[128];
if(pDev)
{
snprintf(buf, sizeof(buf),"%s %s",pDev->name,text);
InvokeCallBack(self->pCall, DRIVSTAT, buf);
}
}
/*------------------------------------------------------------------------*/
int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
@ -165,6 +187,9 @@
char pBueffel[132], pError[80];
pIDrivable pDrivInt = NULL;
pICountable pCountInt = NULL;
static int overwriteOwner = -1;
char *overwriteOption;
float oldVal;
assert(self);
assert(pDes);
@ -175,9 +200,19 @@
{
if(pCon != self->pOwner)
{
SCWrite(pCon,
"ERROR: somebody else is still driving, Request rejected",eError);
return 0;
/* this hack helps on rita2, when using the sendsics script
which opens a client for every command */
if (overwriteOwner < 0) {
overwriteOption = IFindOption(pSICSOptions, "overwriteOwner");
overwriteOwner = overwriteOption && *overwriteOption != '0';
}
if (overwriteOwner) {
self->pOwner = pCon;
} else {
SCWrite(pCon,
"ERROR: somebody else is still driving, Request rejected",eError);
return 0;
}
}
}
else
@ -198,13 +233,22 @@
SCWrite(pCon,"ERROR: memory exhausted in Device Executor ",eError);
return 0;
}
pNew->comCon = SCGetContext(pCon);
strncpy(pNew->comCon.deviceID,name,SCDEVIDLEN);
/* start it */
pDrivInt = pDes->GetInterface(pData,DRIVEID);
pCountInt = pDes->GetInterface(pData,COUNTID);
if(pDrivInt)
{
iRet = pDrivInt->SetValue(pData,pCon,fNew);
if(iRet == OKOK && self->drivePrint == 1)
{
oldVal = pDrivInt->GetValue(pData,pCon);
snprintf(pBueffel,131,"Driving %s from %8.3f to %8.3f",
name, oldVal, fNew);
SCWrite(pCon,pBueffel,eWarning);
}
}
else if(pCountInt)
{
@ -220,6 +264,12 @@
if(iRet == OKOK)
{
LLDnodeAppendFrom(self->iList,&pNew);
sprintf(pBueffel,"started");
if(NULL!=pNew->comCon.deviceID)
{
snprintf(pBueffel,130,"started (%s)",pNew->comCon.deviceID);
}
ExeInterest(self, pNew, pBueffel);
self->iRun = 1;
self->iStatus = DEVDONE;
/* if no task: start it */
@ -232,6 +282,7 @@
self,
1);
self->iEnd = 0;
pCon->conStatus = HWBusy;
}
return 1;
}
@ -248,6 +299,7 @@
}
return 0;
}
/*-----------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
int StartMotor(pExeList self, SicsInterp *pSics, SConnection *pCon,
char *name, float fVal)
@ -341,7 +393,11 @@
pICountable pCountInt = NULL;
pIDrivable pDrivInt = NULL;
int eCode;
int isCounting=0, isDriving=0;
char pBueffel[512];
SConnection *pCon;
pCon = self->pOwner;
assert(self);
/* Sometimes this gets called, though nothing is running. There are
@ -365,6 +421,11 @@
LLDnodeDataTo(self->iList,&pDev);
if(pDev)
{
/*
SCSetContext(self->pOwner,pDev->cmdID,pDev->name);
*/
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pDrivInt = pDev->pDescriptor->GetInterface(pDev->pData,DRIVEID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
@ -388,19 +449,27 @@
{
pDrivInt->iErrorCount = 0;
}
ExeInterest(self, pDev, "finished");
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
SCWrite(pCon, "", eFinish);
iRet = LLDnodePtr2Prev(self->iList);
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
self->iStatus = DEVDONE;
break;
case HWFault: /* real HW error: burning, no net etc.. */
ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev);
pDev = NULL;
SCWrite(pCon, "", eFinish);
LLDnodeDataTo(self->iList,&pDev);
LLDnodeDelete(self->iList);
iRet = LLDnodePtr2Prev(self->iList);
self->iStatus = DEVERROR;
if(pDrivInt)
{
@ -409,6 +478,7 @@
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
@ -418,6 +488,7 @@
{
SetStatus(eEager);
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
@ -427,27 +498,26 @@
{
ContinueExecution(self);
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
case HWBusy:
if(pCountInt != NULL && pDrivInt != NULL)
if(pDrivInt != NULL)
{
SetStatus(eCountDrive);
isDriving = 1;
}
else if(pCountInt != NULL && pDrivInt == NULL)
{
SetStatus(eCounting);
}
else if(pDrivInt != NULL && pCountInt == NULL)
else if(pCountInt != NULL)
{
SetStatus(eDriving);
isCounting = 1;
}
self->iStatus = DEVBUSY;
break;
case HWPosFault: /* cannot get somewhere... */
ExeInterest(self, pDev, "finished with problem");
DeleteDevEntry(pDev);
LLDnodeDelete(self->iList);
SCWrite(pCon, "", eFinish);
self->iStatus = DEVERROR;
if(pDrivInt)
{
@ -456,14 +526,26 @@
if(SCGetInterrupt(self->pOwner) != eContinue)
{
self->iStatus = DEVINT;
SCPopContext(self->pOwner);
return -1;
}
break;
}
SCPopContext(self->pOwner);
}
iRet = LLDnodePtr2Next(self->iList);
}
if (isCounting) {
if (isDriving) {
SetStatus(eCountDrive);
} else {
SetStatus(eCounting);
}
} else if (isDriving) {
SetStatus(eDriving);
}
iRet = LLDnodePtr2First(self->iList);
if(LLDcheck(self->iList) == LIST_EMPTY)
{
@ -484,12 +566,11 @@
int iRet;
assert(self);
self->iRun = 0;
/* do nothing if not running */
if(self->lTask < 0)
{
printf("Nothing to wait for....\n");
printf("Nothing to wait for.... \n");
self->iRun = 0; /* not sure if this is needed here, but does not harm */
return self->iStatus;
}
@ -498,6 +579,7 @@
#ifdef DEBUG
printf("Wait4Success finished\n");
#endif
self->iRun = 0;
return self->iStatus;
}
/*--------------------------------------------------------------------------*/
@ -561,23 +643,23 @@
return 1;
}
/*
check for stop flag. This is to stop unnecessary calls to StopExe.
There may be way to many, but each call is reasonable under certain
circumstances.
*/
if(self->iStop == 1)
{
return 0;
}
else
{
self->iStop = 1;
}
/* first the ALL case */
if(strcmp(name,"all") == 0)
{
/*
check for stop flag. This is to stop unnecessary calls to StopExe.
There may be way to many, but each call is reasonable under certain
circumstances.
*/
if(self->iStop == 1)
{
return 0;
}
else
{
self->iStop = 1;
}
iRet = LLDnodePtr2First(self->iList);
while(iRet != 0)
{
@ -597,7 +679,9 @@
}
iRet = LLDnodePtr2Next(self->iList);
}
SCPushContext(self->pOwner,0,"system");
SCWrite(self->pOwner,"ERROR: Full Stop called!!",eError);
SCPopContext(self->pOwner);
if(SCGetInterrupt(self->pOwner) > eContinue)
{
self->iStatus = DEVINT;
@ -622,7 +706,7 @@
}
else if(pCountInt)
{
pDrivInt->Halt(pDev->pData);
pCountInt->Halt(pDev->pData);
}
return 1;
}
@ -655,6 +739,8 @@
pDev = (pDevEntry)LLDnodePtr(self->iList);
if(pDev)
{
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCountInt)
{
@ -665,7 +751,8 @@
}
}
}
}
SCPopContext(self->pOwner);
iRet = LLDnodePtr2Next(self->iList);
}
SetStatus(ePaused);
@ -691,7 +778,6 @@
{
return 1;
}
}
iRet = LLDnodePtr2Next(self->iList);
}
@ -716,11 +802,13 @@
pCountInt = pDev->pDescriptor->GetInterface(pDev->pData,COUNTID);
if(pCountInt)
{
SCPushContext(self->pOwner, pDev->comCon.transID, pDev->comCon.deviceID);
iRet = pCountInt->Continue(pDev->pData,self->pOwner);
if(!iRet)
{
iRes = 0;
}
SCPopContext(self->pOwner);
}
}
@ -796,13 +884,68 @@
SCWrite(pCon,pBueffel,eError);
}
return iRet;
}
}
/*------------------- The CallBack function for interest ------------------*/
static int DrivStatCallback(int iEvent, void *text, void *pCon,
commandContext cc)
{
assert(pCon);
assert(text);
SCPushContext2(pCon,cc);
SCWrite(pCon, text, eValue);
SCPopContext(pCon);
return 1;
}
/*--------------------------------------------------------------------------*/
int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
return ListPending((pExeList)pData,pCon);
pExeList self = NULL;
int list;
if (argc == 1) {
return ListPending((pExeList)pData,pCon);
}
argtolower(argc,argv);
self = (pExeList)pData;
assert(self);
if (argc == 2) {
if (strcmp(argv[1], "interest") == 0)
{
list = RegisterCallback(self->pCall, SCGetContext(pCon),
DRIVSTAT, DrivStatCallback,
pCon, NULL);
SCRegister(pCon, pSics, self->pCall,list);
SCSendOK(pCon);
return 1;
}
if (strcmp(argv[1], "uninterest") == 0)
{
RemoveCallback2(self->pCall, pCon);
SCUnregister(pCon, self->pCall);
SCSendOK(pCon);
return 1;
}
}
SCWrite(pCon, "ERROR: illegal arguments for ListExe", eError);
return 0;
}
/*-------------------------------------------------------------------------*/
int SicsIdle(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pExeList self = NULL;
int idle;
char pBueffel[80];
self = (pExeList)pData;
assert(self);
idle = time(NULL) - self->lastRun;
snprintf(pBueffel,79,"sicsidle = %d",idle);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/*--------------------------------------------------------------------------
Usage:
Success
@ -830,7 +973,7 @@
SCWrite(pCon,"All done",eStatus);
iRet = 1;
}
else if(iRet = DEVERROR)
else if(iRet == DEVERROR)
{
SCWrite(pCon,"Finished with Problems",eStatus);
iRet = 1;
@ -856,6 +999,39 @@
return 0;
}
}
/*---------------------------------------------------------------------*/
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
int val;
char pBueffel[256];
pExeList self = (pExeList)pData;
if(argc < 2)
{
SCWrite(pCon,"ERROR: not enough argumentd to devexec command",eError);
return 0;
}
strtolower(argv[1]);
if(strcmp(argv[1],"driveprint") == 0)
{
if(argc > 2 && SCMatchRights(pCon,usUser))
{
val = atoi(argv[2]);
self->drivePrint = val;
SCSendOK(pCon);
return 1;
} else {
snprintf(pBueffel,255,"devexe.drivePrint = %d",
self->drivePrint);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
} else {
SCWrite(pCon,"ERROR: unknown subcommand to devexec",eError);
return 0;
}
}
/*-------------------------------------------------------------------------*/
int ContinueAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@ -920,6 +1096,7 @@
return 0;
}
self->lastRun = time(NULL);
iRet = CheckExeList(self);
switch(iRet)
{
@ -927,12 +1104,8 @@
iInterrupt = SCGetInterrupt(self->pOwner);
if(iInterrupt != eContinue)
{
SCWrite(self->pOwner,pBueffel, eError);
if(iInterrupt > 1)
{
Interrupt2Text(iInterrupt,pInterrupt,79);
snprintf(pBueffel,131,"ERROR: interrupt %s triggered",
pInterrupt);
StopExe(self,"all");
}
#ifdef DEBUG
@ -976,10 +1149,12 @@
{
if(self->pOwner)
{
SCPushContext(self->pOwner,0,"system");
SCWrite(self->pOwner,
"ERROR: Interrupting Current Hardware Operation",
eError);
SCSetInterrupt(self->pOwner,*iInt);
SCSetInterrupt(self->pOwner,*iInt);
SCPopContext(self->pOwner);
}
StopExe(self,"all");
}

View File

@ -126,10 +126,15 @@
int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
lists all currently executing objects
*/
int SicsIdle(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
prints the seconds since the device executor was running the last time
*/
int Success(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
@ -147,7 +152,11 @@
/*
continues execution
*/
int DevexecAction(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
* various commands
*/
/*--------------------------- Locking ---------------------------------*/
#line 183 "devexec.w"
@ -156,7 +165,7 @@
void UnlockDeviceExecutor(pExeList self);
#line 292 "devexec.w"
#line 297 "devexec.w"
/* -------------------------- Executor management -------------------------*/

View File

@ -320,10 +320,15 @@ to the global SICS device executor.
\mbox{}\verb@ @\\
\mbox{}\verb@ int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ lists all currently executing objects@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int SicsIdle(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ prints the seconds since the device executor was running the last time@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@@\\
\mbox{}\verb@ int Success(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
\mbox{}\verb@ /*@\\

View File

@ -266,10 +266,15 @@ to the global SICS device executor.
int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
lists all currently executing objects
*/
int SicsIdle(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*
prints the seconds since the device executor was running the last time
*/
int Success(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
/*

368
diffscan.c Normal file
View File

@ -0,0 +1,368 @@
/*-------------------------------------------------------------------
diffscan is an operator which can perform a fast differential scan
while a motor is running.
copyright: see file COPYRIGHT
Mark Koennecke, November 2004
---------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
#include <tcl.h>
#include "fortify.h"
#include "sics.h"
#include "diffscan.h"
#include "drive.h"
#include "counter.h"
#define DIFFMONITOR 0
#define SKIP 1
/*-------------------------------------------------------------------*/
static void KillDiffScan(void *data){
pDiffScan self = (pDiffScan)data;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->parArray != NULL){
ObParDelete(self->parArray);
}
free(self);
}
/*---------------------------------------------------------------------*/
static int SaveDiffScan(void *data, char *name, FILE *fd){
pDiffScan self = (pDiffScan)data;
if(self == NULL){
return 0;
}
fprintf(fd,"%s monitor %f\n",name,ObVal(self->parArray,DIFFMONITOR));
fprintf(fd,"%s skip %f\n",name,ObVal(self->parArray,SKIP));
return 1;
}
/*----------------------------------------------------------------------*/
int MakeDiffScan(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pDiffScan pNew = NULL;
int status;
pNew = (pDiffScan)malloc(sizeof(DiffScan));
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating differential scan",
eError);
return 0;
}
memset(pNew,0,sizeof(DiffScan));
pNew->pDes = CreateDescriptor("DiffScan");
pNew->parArray = ObParCreate(2);
if(!pNew->pDes || !pNew->parArray){
SCWrite(pCon,"ERROR: out of memory creating differential scan",
eError);
KillDiffScan(pNew);
return 0;
}
ObParInit(pNew->parArray, DIFFMONITOR,"monitor",4.0,usUser);
ObParInit(pNew->parArray, SKIP,"skip",.0,usUser);
pNew->pDes->SaveStatus = SaveDiffScan;
if(argc > 1) {
status = AddCommand(pSics,argv[2],
DiffScanWrapper,
KillDiffScan,
pNew);
} else {
status = AddCommand(pSics,"diffscan",
DiffScanWrapper,
KillDiffScan,
pNew);
}
if(status != 1){
SCWrite(pCon,"ERROR: duplicate diffscan not created",eError);
return 0;
}
return 1;
}
/*----------------------------------------------------------------------*/
int DiffScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pDiffScan self = NULL;
pScanData pScan = NULL;
ObPar *par = NULL;
char pBueffel[255];
int status;
self = (pDiffScan)pData;
assert(self);
if(argc < 2){
SCWrite(pCon,"ERROR: need arguments to diffscan",eError);
return 0;
}
if(!SCMatchRights(pCon,usUser)){
return 0;
}
/*
first try to find a scan object and to run
*/
strtolower(argv[1]);
pScan = (pScanData)FindCommandData(pSics,argv[1],"ScanObject");
if(pScan != NULL && argc > 2){
status = RunDiffScan(self,pScan,pCon, atof(argv[2]));
return status;
}
/*
if we end here we are treating variables
*/
if(argc > 2){
/*
set case
*/
return ObParSet(self->parArray,argv[0],argv[1],atof(argv[2]),pCon);
} else {
/*
get case
*/
par = ObParFind(self->parArray,argv[1]);
if(par != NULL){
snprintf(pBueffel,255,"%s.%s = %f",argv[0],argv[1],par->fVal);
SCWrite(pCon,pBueffel,eValue);
return 1;
} else {
snprintf(pBueffel,255,"ERROR: parameter %s not found",argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
return 1;
}
/*--------------------------------------------------------------------*/
static int StartDiffScan(pDiffScan self, pScanData pScan,
SConnection *pCon, float fEnd){
pVarEntry pVar = NULL;
void *pPtr = NULL;
pCounter pCount = NULL;
char pBueffel[255];
int status;
/*
error checks
*/
if(pScan->iScanVar < 1) {
SCWrite(pCon,"ERROR: no scan variable to diffscan",eError);
return 0;
}
if(pScan->iScanVar > 1) {
snprintf(pBueffel,255,
"WARNING: diffscan handles only first scan variable, %d %s",
pScan->iScanVar - 1,
"scan variables ignored");
SCWrite(pCon,pBueffel, eWarning);
}
/*
initialize data structure
*/
self->scanObject = pScan;
self->scanObject->pCon = pCon;
self->skip = (int)ObVal(self->parArray,SKIP);
self->scaleMonitor = (int)ObVal(self->parArray,DIFFMONITOR);
self->normalizationScale = -1;
pScan->iCounts = 0;
/*
get variable
*/
DynarGet(pScan->pScanVar,0,&pPtr);
pVar = (pVarEntry)pPtr;
if(pVar == NULL){
SCWrite(pCon,"ERROR: cannot access scan variable",eError);
return 0;
}
/*
drive to start position
*/
status = Drive(pCon,pServ->pSics,ScanVarName(pVar),ScanVarStart(pVar));
if(status != 1){
return 0;
}
/*
Configure counter. We operate in timer mode with a very long
preset mode. Stopping is done explicitly in the diffscan task
*/
SetCounterMode(pScan->pCounterData,eTimer);
SetCounterPreset(pScan->pCounterData,3600.);
/*
start motor and counter
*/
status = pVar->pInter->SetValue(pVar->pObject,pCon,fEnd);
if(status != OKOK){
/*
errors will already have been reported in SetValue
*/
return 0;
}
pCount = (pCounter)pScan->pCounterData;
assert(pCount);
status = pCount->pCountInt->StartCount(pCount,pCon);
if(status != OKOK){
return 0;
}
return 1;
}
/*--------------------------------------------------------------------*/
static float normalizeEntry(pCountEntry pCount, pCountEntry last,
long monValue, int scaleMon){
int i;
float fScale;
float value;
long diff;
/*
calculate scale
*/
diff = pCount->Monitors[scaleMon-1] - last->Monitors[scaleMon-1];
if(diff > 0) {
fScale = (float)monValue/(float)diff;
} else {
fScale = 0.;
}
value = ((float)(pCount->lCount - last->lCount))*fScale;
pCount->lCount = (long)value;
for(i = 0; i < 10; i++){
pCount->Monitors[i] = (pCount->Monitors[i] - last->Monitors[i])*fScale;
}
return value;
}
/*--------------------------------------------------------------------*/
static void copyCountData(pCountEntry last, pCountEntry pCount){
memcpy(last,pCount,sizeof(CountEntry));
}
/*---------------------------------------------------------------------*/
static int DiffScanTask(void *pData){
pCounter pCount = NULL;
pCountEntry data;
pVarEntry pVar = NULL;
void *pPtr = NULL;
float fPos, countValue;
int status, finish = 1, count;
char pBueffel[255];
long rawCount, rawMon;
CountEntry rawCopy;
pDiffScan self = (pDiffScan)pData;
/*
manage skip
*/
if(self->skip > 0){
if(self->skipCount > self->skip){
self->skipCount = 0;
} else {
self->skipCount++;
return 1;
}
}
/*
read motor status
*/
DynarGet(self->scanObject->pScanVar,0,&pPtr);
pVar = (pVarEntry)pPtr;
status = pVar->pInter->CheckStatus(pVar->pObject,self->scanObject->pCon);
if(status != HWBusy) {
finish = 0;
}
/*
read values
*/
status = GetDrivablePosition(pVar->pObject,self->scanObject->pCon,
&fPos);
if(status == 0){
return finish;
}
AppendScanVar(pVar,fPos);
pCount = (pCounter)self->scanObject->pCounterData;
pCount->pCountInt->TransferData(pCount,self->scanObject->pCon);
CollectCounterData(self->scanObject);
/*
normalize (or not)
*/
DynarGet(self->scanObject->pCounts,self->scanObject->iCounts-1,&pPtr);
data = (pCountEntry)pPtr;
copyCountData(&rawCopy,data);
if(self->normalizationScale < 0){
countValue = (float)data->lCount;
rawCount = data->lCount;
rawMon = data->Monitors[self->scaleMonitor-1];
self->normalizationScale = data->Monitors[self->scaleMonitor-1];
} else {
if(data->Monitors[self->scaleMonitor -1] -
self->last.Monitors[self->scaleMonitor-1] < 5) {
SCWrite(self->scanObject->pCon,
"WARNING: low count rate",eWarning);
}
rawCount = data->lCount;
rawMon = data->Monitors[self->scaleMonitor-1];
countValue = normalizeEntry(data,&self->last,
self->normalizationScale,
self->scaleMonitor);
}
copyCountData(&self->last,&rawCopy);
/*
print progress
*/
snprintf(pBueffel,255,"%5d %12.4f %12.4f RAW: %10ld %10ld",
self->scanObject->iCounts -1,
fPos, countValue, rawCount,
rawMon);
SCWrite(self->scanObject->pCon,pBueffel,eWarning);
InvokeCallBack(self->scanObject->pCall,SCANPOINT,self->scanObject);
/*
check for interrupt
*/
if(SCGetInterrupt(self->scanObject->pCon) >= eAbortScan){
pCount->pDriv->Halt(pCount->pDriv);
pVar->pInter->Halt(pVar->pObject);
SicsWait(1);
finish = 0;
}
return finish;
}
/*----------------------------------------------------------------------*/
int RunDiffScan(pDiffScan self, pScanData pScan,
SConnection *pCon, float fEnd){
long lID;
pCounter pCount = NULL;
if(StartDiffScan(self,pScan,pCon,fEnd) != 1) {
return 0;
}
InvokeCallBack(self->scanObject->pCall,SCANSTART,self->scanObject);
lID = TaskRegister(pServ->pTasker,DiffScanTask,NULL,NULL,self,10);
TaskWait(pServ->pTasker,lID);
pCount = (pCounter)self->scanObject->pCounterData;
pCount->pCountInt->Halt(pCount);
InvokeCallBack(self->scanObject->pCall,SCANEND,self->scanObject);
return 1;
}

47
diffscan.h Normal file
View File

@ -0,0 +1,47 @@
/*-------------------------------------------------------------------
diffscan is an operator which can perform a fast differential scan
while a motor is running.
copyright: see file COPYRIGHT
Mark Koennecke, November 2004
---------------------------------------------------------------------*/
#ifndef SICSDIFFSCAN
#define SICSDIFFSCAN
#include "obpar.h"
#include "scan.h"
#include "scan.i"
typedef struct {
pObjectDescriptor pDes;
ObPar *parArray;
int normalizationScale;
int scaleMonitor;
CountEntry last;
int skip;
int skipCount;
pScanData scanObject;
} DiffScan, *pDiffScan;
/*==================================================================*/
/**
* RunDiffScan runs a differential scan.
* @param self The Diffscan object to use
* @param pScan The scan object to use for configuration and for
* for storing the results.
* @param pCon The connection to use for output and errors.
* @param fEnd The end value for the diffscan
*/
int RunDiffScan(pDiffScan self, pScanData pScan,
SConnection *pCon, float fEnd);
/*==================== interpreter wrappers ==========================*/
int DiffScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int MakeDiffScan(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
#endif

97
diffscan.w Normal file
View File

@ -0,0 +1,97 @@
\subsection{Differential Scan}
This is a special very fast but inaccurate scan method. The scan motor is
set into motion and counts are collected on the fly, while the motor
is moving. As neither the motor speed, nor the counters response nor
the source stability can be relied upon to result in equally spaced
and well defined counts, the counts have to be scaled according to the
difference in monitor counts towards the previous count. This is why
this is called differential scan. This is not a
precise scan. But is a very fast one which helps locating peaks or
during alignment.
This is implemented as an operator on top of the standard scan
module. All scan details, scan variables etc have to be configured in
the main scan module. This object then just runs the diff scan and
stores the result in the main scan object for further processing. For
instance peak location. The end of the scan is calculated from the
start, step and NP of the main scan module. be aware that these values
have no well defined meaning during this kind of scan, NP will be
corrected to account for the points actually measured.
As motors cannot be guaranteed to run simulataneously, only one scan
variable is suported for this.
The actual control of this scan is hidden in a task function which is
responsible for storing the data and stopping when the motor has
finished driving.
In order to do a differential scan a data structure is required:
@d diffscandat @{
typedef struct {
pObjectDescriptor pDes;
ObPar *parArray;
int normalizationScale;
int scaleMonitor;
CountEntry last;
int skip;
int skipCount;
pScanData scanObject;
} DiffScan, *pDiffScan;
@}
The fields:
\begin{description}
\item[pDes] The standard object descriptor.
\item[parArray] An array of parameters for the module.
\item[normalizationScale] The scale to which to scale counts during
counting.This will be the monitor difference between the first and the
second point.
\item[lastMonitor] is the last monitor read for caluclating differences.
\item[scaleMonitor] The monitor to use for scaling. This should better
be a monitor with a high count rate for acurate scaling.
\item[skip] How many cycles of the main loop to skip between
recordings.
\item[skipCount] Counter for skipped cycles. Together with skip this
is a means to limit the sampling rate of diffscan.
\item[scanObject] The scan object we are operating upon.
\end{description}
The external interface to this module is like this:
@d diffscanint @{
/**
* RunDiffScan runs a differential scan.
* @@param self The Diffscan object to use
* @@param pScan The scan object to use for configuration and for
* for storing the results.
* @@param pCon The connection to use for output and errors.
* @@param fEnd The end value for the diffscan
*/
int RunDiffScan(pDiffScan self, pScanData pScan,
SConnection *pCon, float fEnd);
/*==================== interpreter wrappers ==========================*/
int DiffScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
int MakeDiffScan(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
@}
@o diffscan.h @{
/*-------------------------------------------------------------------
diffscan is an operator which can perform a fast differential scan
while a motor is running.
copyright: see file COPYRIGHT
Mark Koennecke, November 2004
---------------------------------------------------------------------*/
#ifndef SICSDIFFSCAN
#define SICSDIFFSCAN
#include "obpar.h"
#include "scan.h"
#include "scan.i"
@<diffscandat@>
/*==================================================================*/
@<diffscanint@>
#endif
@}

113
doc/manager/amor.htm Normal file
View File

@ -0,0 +1,113 @@
<HTML>
<HEAD>
<TITLE>Special Commands for the Reflectometer(AMOR)</TITLE>
</HEAD>
<BODY>
<H1>Special Commands for the Reflectometer (AMOR)</H1>
<P>
There are some special command initializations for the reflectometer AMOR.
These commands are most likely not portable to other instruments because
they encompass the special geometry at AMOR and the AMOR development has
not fully matured. The following initialization commands are available:
<dl>
<DT>MakeAmor2T name da
<DD>This creates a virtual two theta motor for the reflectometer
AMOR. The two parameters are the name of the object in SICS and a
Tcl-array with configuration parameters. The needed elements of this
array are:
<DL>
<DT>mom
<DD>The monochromator omega motor.
<DT>som
<DD>The sample omega motor.
<DT>coz
<DD> The height movement of the detector.
<DT>cox
<DD> The movement of the detector along the optical bench.
<DT>stz
<DD> The height movement of the sample connected to the omega circle.
<DT>soz
<DD> The height movement of the sample table.
<DT>d4b
<DD>The motor moving the whole diaphragm 4 up.
<DT>d5b
<DD>The motor moving the whole diaphragm 5 up.
<DT>com
<DD>The omega mevement of the detector.
</DL>
An example:
<pre>
set a2t(mom) mom
set a2t(som) som
set a2t(coz) coz
set a2t(cox) cox
set a2t(stz) stz
set a2t(soz) soz
set a2t(d4b) d4b
set a2t(d5b) d5b
set a2t(com) com
MakeAmor2T a2t a2t
</pre>
creates a virtual AMOR two theta motor with the name a2t.
<dt>MakeStoreAmor hm
<dd>Creates an object for writing reflectometer data files. The name
of the command is storeamor. The parameter hm denotes the histogram
memory object.
<dt>MakeAmorStatus name scan hm
<dd>This creates a helper object for the reflectometer status display
with name name. This object performs some operations on behalf of the
status display for the reflectometer AMOR. The parameter scan denotes
the name of the scan object. The parameter hm the name of the
histogram memory object.
</dl>
</P>
<h2>AMOR Status Display Commands</h2>
<p>
MakeAmorStatus creates a SICS command which is used by the AMOR status
display for displaying proceesed data, especially in TOF-mode. This module
provides the following commands:
<dl>
<dt>amorstatus interest
<dd>This registers this connection for receiving automatic
notifications. Automatic notifications send are:
<DL>
<dt>SCANSTART
<dd> At scan start a message <b>ScanClear</b> is sent followed by the
uuencoded new x-axis for the plot.
<dt>SCANPOINT
<dd>At each scan point the arrays of counts in both detector are sent
in uuencoded form labelled arrow_spinupup and arrow_spinuplo.
<DT>COUNTSTART
<DD>The start of counting on the histogram memory. Send a message
<b>TOFClear</b> and then the uuencoded time binning labelled
arrow_time.
<DT>FILELOADED
<DD>activated each time user defined model data is loaded into the
SICS server. This data gets send as arrow_name in uuencoded form. Both
x- and y-axis are sent in floating point.
</DL>
Please note that floating point data is transformed to fixed point by
multiplication of 65653 before transfer. The first number in each
uuencoded message is an integer describing the length of the data. In
case of double data such as fileloaded the y-data follows immediatetly
after the x-data. Also the appropriate data is automatically sent after
the interest command.
<dt>amorstatus collapse
<dd>sums all counts in all detectors in time and sends the data back
as an uuencoded image. The first two numbers in the message define the
dimensions of the data.
<dt>amorstatus sample name x1 x2 y1 y2
<dd>Sums the detector counts on an area defined by the rectangle x1,
x2, y1, y2. The length of this is the time binning. The data is sent
back in uuencoded form labelled arrow_name.
<dt>amorstatus clear
<dd> Clears all user loaded data.
<dt>amorstatus load filename scale
<dd> loads user defined data for distribution to the status display
clients. The y data is scaled according to the scale factor provided.
<dt>amorstatus projectytof
<dd>Returns a UUencoded 2D array of y against TOF.
</dl>
</p>
</BODY>
</HTML>

View File

@ -12,6 +12,9 @@ initialisation file. Such special commands are described here.
<DL>
<DT>MakeRuenBuffer
<DD>MakeRuenBuffer makes the R&#252;nBuffer system available.
<dt>MakeBatchManager [name]
<DD>Installs the new batch buffer management system. If no name is
given, the default will be exe.
<DT>MakeDrive
<DD>MakeDrive craetes the drive command.
<DT>MakeScanCommand name countername headfile recoverfil
@ -81,13 +84,17 @@ the token force command.
circle diffractometer. The four parameters are the names of the motors
driving the two theta, omega, chi and phi circles of the diffractometer.
These motors must already exists before this command may succeed.
<DT>MakeHKLMot hkl
<DD>Creates the drivable H, k, l virtual motors using hkl, an object created by
MakeHKL for calculations.
<DT>MakeDifrac tth om chi phi cter
<DD>This command installs the Difrac subsystem into SICS. Difrac is a
whole F77 package for controlling a four circle
diffractometer. Afterwards Difrac commands are available in SICS with
the prefix dif, for example dif ah calls the difrac ah command. Difrac
is described in more detail elsewhere. The parameters are the four
circle motors two theta, omega, chi and phi and the counter.
circle motors two theta, omega, chi and phi and the counter. This is no longer
maintained.
<DT>MakeOptimise name countername
<DD>This command installs the Peak Optimiser into the SICS server. The Peak
Optimiser is an object which can locate the maximum of a peak with respect
@ -154,7 +161,7 @@ with name name. This object performs some operations on behalf of the
status display for the reflectometer AMOR. The parameter scan denotes
the name of the scan object. The parameter hm the name of the
histogram memory object.
<DT>MakeMesure name scanobject hklobject omega o2t fileroot datanumberobject
<DT>MakeMesure name scanobject hklobject omega s2t fileroot datanumberobject
<DD>MakeMesure installs the single counter four circle diffractometer
measurement procedure into SICS. It will be accessible as object name
afterwards. MakeMesure takes a lot of parameters:
@ -165,8 +172,8 @@ afterwards. MakeMesure takes a lot of parameters:
<DD>The name of the object which does crystallographic calculations.
<DT>omega
<DD>The name of the motor driving omega.
<DT>o2t
<DD>The name of the omega two theta virtual motor for omega two theta scans.
<DT>s2t
<DD>The name of the two theta motor for use in omega two theta scans.
<DT>fileroot
<DD>The full path to the data file directory without final /
<dt>datanumberobject
@ -186,7 +193,13 @@ selector which is controlled by this wavelength variable.
<dT>MakeXYTable myname
<DD>Creates a XYTable object with the name myname. This object can store a
list of x-y values.
</DL>
<dt>MakeNXScript [name]
<dd>Installs the NeXus dictionary scripting module. If no name is given, the
name will be nxscript.
<dt>MakeSinq
<dd>Install the listener module for the accelerator divisions broadcast messages. This
creates a command sinq.
</DL>
</p>
<h4>The Scan Command Header Description File</h4>
<p>

47
doc/manager/focus.htm Normal file
View File

@ -0,0 +1,47 @@
<HTML>
<HEAD>
<TITLE>Special FOCUS Initializations</TITLE>
</HEAD>
<BODY>
<H1>Special FOCUS Initializations</H1>
<P>
These initailizations are special to the FOCUS instrument:
<dl>
<dt>InstallFocusmerge datafile
<dd>Installs the module which is responsible for merging focus data into
merged detector banks.
<dt>MakeFocusAverager average hmc
<dd>Installs the average command and the focusraw command into SICS which
are used by the FOCUS status client in order to display processed
histogram memory data.
</dl>
</P>
<h2>Special Internal FOCUS Support Commands</h2>
<p>
<dl>
<dt>focusraw bankid
<dd>Dumps in UUencoded form the content of the detector bank bankid. This is
required in order to add the TOF-binning to the data and in order to handle
the virtual merged detector bank which is built from contributions of the
three physical detector banks.
<dt>average start stop bankid
<dd>Sums the detectors between start and stop of detector bankid into a
histogram. A standard display in the status client.
<dt>focusmerge puttwotheta nxscriptmod bankname alias
<dd>Writes two theta values for the detector bank bankname into
the file described by the nxscript module nxsciptmod to the
alias alias. A helper function for data file writing.
<dt>focusmerge putmerged nxscriptmod alias
<dd>Writes the virtual merged detector bank into alias in
nxscriptmod.
<dt>focusmerge putsum nxscriptmod bankname alias
<dd>Writes the summed counts for detector bank bankname under alias
into nxscriptmod.
<dt>focusmerge putelastic nxscriptmod alias theoelastic
<dd>Calculate the position of the elastic line and write it to alias in
nxscriptmod. If no elastic line can be calculated, the theoretical
elastic line, theoelastic, is used.
</dl>
</p>
</BODY>
</HTML>

97
doc/manager/four.htm Normal file
View File

@ -0,0 +1,97 @@
<HTML>
<HEAD>
<TITLE>Initialization for Four Circle Diffractometers</TITLE>
</HEAD>
<BODY>
<H1>Initialization for Four Circle Diffractometers</H1>
<P>
This section describes how the modules which are special for a four
circle single crystal diffractometer are configured into SICS. The
following feautures are available:
<dl>
<DT>MakeHKL theta omega chi phi
<DD>MakeHKL creates the hkl command for the calculation of settings for a four
circle diffractometer. The four parameters are the names of the motors
driving the two theta, omega, chi and phi circles of the diffractometer.
These motors must already exists before this command may succeed.
<DT>MakeHKLMot hkl
<DD>Creates the drivable H, k, l virtual motors using hkl, an
object created by MakeHKL for calculations.
<DT>MakeDifrac tth om chi phi cter
<DD>This command installs the Difrac subsystem into SICS. Difrac is a
whole F77 package for controlling a four circle
diffractometer. Afterwards Difrac commands are available in SICS with
the prefix dif, for example dif ah calls the difrac ah command. Difrac
is described in more detail elsewhere. The parameters are the four
circle motors two theta, omega, chi and phi and the counter. This is no longer
maintained.
<DT>MakeMesure name scanobject hklobject omega s2t fileroot datanumberobject
<DD>MakeMesure installs the single counter four circle diffractometer
measurement procedure into SICS. It will be accessible as object name
afterwards. MakeMesure takes a lot of parameters:
<dl>
<Dt>scanobject
<DD>The name of the internal scan object.
<DT>hklobject
<DD>The name of the object which does crystallographic calculations.
<DT>omega
<DD>The name of the motor driving omega.
<DT>s2t
<DD>The name of the two theta motor for use in omega two theta scans.
<DT>fileroot
<DD>The full path to the data file directory without final /
<dt>datanumberobject
<DD>The name of the SICS data number object for creating unique file
numbers.
</dl>
<dt>MakeUBCalc name hklobject
<dd>This installs a UB matrix calculation module with the name name
into SICS. The second parameter is a hklobject as created with MakeHKL
to which any calculated UB's can be transferred.
<dt>MakeHklscan scanobject hklobject
<dd>Installs the hklscan command which allows to scan in reciprocal space.
Scanobject is the name of SICS internal scan object, hklobject the name of a
reciprocal space calculation object as configured with MakeHKL.
<dt>MakeTRICSSupport
<dd>Installs a command, tricssupport, which helps the TRICS status
display.
</dl>
</p>
<p>
Commands implemented by tricssupport:
<dl>
<dt>tricssupport oldframe file idet nFrame
<dd>Loads and sends the frame nFrame of detector idet from file file in
UUencoded form.
<dt>tricssupport interest
<dd>Enables this connection to receive notifications whenever a new frame
of data had been written
<dt>tricssupport newframe
<dd>Called from scripts. Triggers sending new frames to all registered
connections.
</dl>
</P>
There are also a lot of scripted command available for four circle
diffractometers. These may be copied from tricscom.tcl. These include:
<dl>
<dt>four
<dd>print the four all important angles
<dt>tricsscan start step np
<dd>Omega scan with a PSD
<dt>psdrefscan file step np mode preset
<dd>Read reflections from file, drive to them, do a omega scan with tricsscan
using the parameters specified.
<dt>detscan start step np
<dd>Do a detector calibration scan.
<dt>phscan start step np
<dd>Do a phi scan
<dt>hklscan2d
<dd>Scanning reciprocal space with the area detector
<dt>scan2d
<dd>Configure SICS for general scanning with the PSD. This is meant
to supersede many of the special scans above.
<dt>scan1d
<dd>Configure SICS for general scanning with the single detector.
</dl>
</BODY>
</HTML>

243
doc/manager/gencom.htm Normal file
View File

@ -0,0 +1,243 @@
<HTML>
<HEAD>
<TITLE>Initialization of General Commands</TITLE>
</HEAD>
<BODY>
<H1>Initialization of General Commands</H1>
<P>
This section gives details on the initialization of commands which are
common to many different instruments. The command set of SICS can be tailored
to cover many specific needs. Moreover this system allows to replace
functionality by other implementations suited to another users taste. This
is a list of common command initialization commands.
<DL>
<DT>MakeRuenBuffer
<DD>MakeRuenBuffer makes the R&#252;nBuffer system available.
<dt>MakeBatchManager [name]
<DD>Installs the new batch buffer management system. If no name is
given, the default will be exe.
<DT>MakeDrive
<DD>MakeDrive creates the drive and run command.
<DT> Publish name access
<DD> The SICS server uses Tcl as its internal macro language. However, it
was felt that the whole Tcl command set should not be available to all users
from the command line without any protection. There are reasons for this:
careless use of Tcl may clog up memory, thereby grinding the system to a
halt. Invalid Tcl statements may cause the server to hang. Last not least,
Tcl contains commands to manipulate files and access the operating system.
This is a potential security problem when the server is hacked. However,
in order to make macro procedures available the Publish
command exists. It makes a Tcl command name available to SICS users with the
access code access. Valid values for access are: Internal, Mugger, User
and Spy.
<DT>TokenInit tokenpassword
<DD> This command initialises the token control management system with the
token command. The single parameter tokenpassword specifies the password for
the token force command.
<DT>MakeOptimise name countername
<DD>This command installs the Peak Optimiser into the SICS server. The Peak
Optimiser is an object which can locate the maximum of a peak with respect
to several variables. The arguments are: name, the name under which the Peak
Optimiser can be accessed within SICS and countername, which is the name of
an already configured SICS counter box.
<dt>MakeO2T nam OM 2TM
<dd>creates an omega 2Theta virtual motor
with name nam for omega 2Theta scans. OM defines an omega motor, 2TM a two
theta motor.
<dt>MakeDataNumber SicsDataNumber filename
<dd>This command makes a
variable SicsDataNumber available which holds the current sequential data
file number. filename is the complete path to the file were this data
number is stored. This file should never, ever be edited without good
reason, i.e. resetting the sequential number to 0 at the beginning of a
year.
<dT>MakeXYTable myname
<DD>Creates a XYTable object with the name myname. This object can store a
list of x-y values.
<dt>MakeSinq
<dd>Install the listener module for the accelerator divisions broadcast
messages. This creates a command sinq.
<dt>MakeMaximize counter
<dd>Installs a command max into SICS which implements a more efficient
algorithm for locating the maximum of a peak then scanning and peak or
center.
<dt>MakeMaxDetector name
<dd>Installs name into SICS which implements a command for locating
maxima on a two dimensional histogram memory image.
<dt>MakeLin2Ang name motor
<dd>Creates a virtual motor name which translates an input angle into a
translation along a tangent to the rotation axis. The distance of the
translation table can be configured as variable: name length once this
is established.
<dt>MakeSWHPMotor realmotor switchscript mot1 mot2 mot3
<dd>Creates switched motors mot1, mot2 and mot3 for real motor
realmotor. For switching the script switchscript is used. This
can be used when several motors are operated through the same
motor driver. This implementation is not completely general now.
</dl>
</P>
<h2>Monochromators</h2>
<p>
A monochromator is represented in SICS through a monochromator object which
holds all the parameters associated with the monochromator and virtual
motors which drive wavelength or energy. The commands to configure such a
monochromator are:
<dl>
<DT>MakeMono name M1 M2 M3 M4
<DD>This command creates a crystal monochromator object. Such a
monochromator object is necessary for the usage of the wavelength or energy
variables. The parameter name defines the name of the monochromator object
in the system. M1 and M2 are the names of the Theta and two Theta motors
respectively. M3 is an optional parameter defining a motor for driving the
horizontal curvature. M4 is an optional parameter defining a motor for
driving the vertical curvature of the monochromator.
<dt>MakeWaveLength nam mono
<dd>creates a wavelength variable nam. The monochromator mono is used for
adjustment.
<dt>MakeEnergy nam mono
<dd>creates a energy variable nam. The
monochromator mono is used for adjustment.
<dt>MakeOscillator name motor
<dd>Installs a module name which oscillates motor between the software
limits of the motor. This is useful for suppressing preferred
orientation effects on powder diffractometers.name then supports the
commands: start, stop, status which are self explanatory.
</dl>
</p>
<H2>Reoccuring Tasks</H2>
<P>
Sometimes it may be necessary to execute a SICS command at regular
time intervalls. This can be achieved with the sicscron command:
<DL>
<DT>sicscron intervall bla blab blab
<DD>This command installs a reoccuring task into SICS. The first
parameter is the intervall in seconds between calls to the SICS
command. Everything behind that is treated as the command to execute.
</DL>
</P>
<H2>The SICS Online Help System</H2>
<P>
SICS has a simple built in help system. Help text is stored in simple
ASCII text files which are printed to the client on demand. The help
system can search for help files in several directories. Typically one
would want one directory with general SICS help files and another one
with instrument specific help files. If help is invoked without any
options, a default help file is printed. This file is supposed to
contain a directory of available help topics together with a brief
description. The normal usage is: help topicname . The help system
will then search for a file named topicname.txt in its help
directories.
</P>
<p>
A SICS manager will need to configure this help system. A new
directory can be added to the list of directories to search with the
command:
<pre>
help configure adddir dirname
</pre>
The default help file can be specified with:
<pre>
help configure defaultfile filename
</pre>
Each of these command given without a parameter print the current
settings.
</P>
<H2>Aliases in SICS</H2>
<P>
SICS knows three different kinds of aliases: object aliases,
runtime aliases and command
aliases. This is confusing but finds its explanation in the structure
of SICS internals.
</P>
<h3>Object Aliases</h3>
<p>
An object alias is another name for a first class object installed
into the SICS interpreter. For instance a second name for a motor. For
instance the motor twotheta is quite often aliased to a4. Such an
alias can be used like a normal SICS objects. Even in commands which
access internal SICS interfaces like the drive command or
others. Object aliases are installed into SICS with the SICSAlias
command:
<DL>
<DT>SicsAlias oldname newname
<DD>This command installs newname as alias for the object oldname.
</dl>
SicsAlias can only be used within initialization scripts. SicsAlias is
considered deprecated and can be replaced with the superior runtime
aliases described below.
</p>
<h3>Runtime Aliases</h3>
<p>
Runtime aliases are full object aliases which can be configured into the
system at run time by a SICS manager.
The syntax looks like this:
<dl>
<dt>DefineAlias aliasname SICSobject
<dd>This defines aliasname to be the alias for the SICS object SICSobject.
It is not needed that SICSobject already exists. If SICSobject is already
an alias, it is translated before definition.
Multiple translation is possible, depending on the order of definition.
When an alias is used, and it does not point to an existing object,
the behaviour is the same as if an unknown object would have been used.
<dt>DefineAlias aliasname
<dd>This command deletes the alias aliasname.
</dl>
</p>
<h3>Command Aliases</h3>
<p>
Command aliases are shortcuts for lengthy commands. For instance one
might want to define A4LL as a shortcut for "a4 softlowerlim". This is
just to save typing or adapt SICS to MAD users who appear to have an
unlimited memory for 2-4 letter acronyms. It is possible to redefine a
SICS object with this for instance to define tt as an alias for
temperature. However if one tries to use tt in a drive command it will
fail because it is just a text replacement. A command alias can be
installed into SICS at any time with manager privilege and the
command:
<DL>
<DT>alias shortcut bla bla bla ....
<DD>This define shortcut as an alias for everything behind it.
</DL>
A shortcut may take parameters.
</p>
<h2>The AntiCollision Module</h2>
<p>
In some cases motors have to be drive in a coordinated way. For instance,
at TRICS, the chi motor may need to move first before omega can be
driven in order to avoid collisions. Or at the ECB instruments, only one
of eight motors in a rack can be driven at any given time. The anti collision
module now allows to implement this. Anticollisions pattern of
operation: Each
collaborating motor is registered with the anti collision module. When trying
to start such a motor, the anti collider just takes a note where it shoud go.
On the first status check, a program is called which has to
arrange the running of the motors into a sequence. This sequence then is
executed by the anti collision module. The program which arranges the
motors into a sequence is a configurable parameter and usually implemented
as a script in SICS own marco language. In the SICS initialization file this
requires the commands:
<dl>
<dt>AntiCollisionInstall
<dd>Creates the anitcollision module.
<dt>anticollision register motorname
<dd>Registers motorname with the anti collision module.
<dt>anticollision script scriptname
<dd>This command configures the script which is responsible for
arranging the sequence of operations.
</dl>
The script configured into anticollision is called with pairs
or motor names and targets as parameters, Example:
<pre>
sans2rack mot1 target1 mot2 target2 .....
</pre>
Within the anticollision script, the following command may be
used in order to define the sequence.
<dl>
<dt>anticollision clear
<dd>Clears the sequence list
<dt>anticollision add level motor target
<dd>Add motor with target to level in the sequence.
</dl>
</p>
</BODY>
</HTML>

View File

@ -10,21 +10,392 @@ Hardware is configured into the SICS system by executing special hardware
configuration commands from the server initialisation file. These commands
are described here. Much SICS hardware is hooked up to the system via RS-232
interfaces. The SICS server communicates with such devices through a serial
port server program running on a Macintosh PC. All such devices require on
port server program running on the instrument computer.
All such devices require on
initialisation the following parameters:
<ul>
<li><b>hostname</b> The name of the macintosh computer.
<li><b>hostname</b> The name of the instrument computer.
<li><b>port</b> The port number where the serial port server program is
listening for requests. It is given on the Macintosh screen when the serial
port server is running. It is usually 4000.
<li><b>channel</b> The number of the RS-232 interface on the Macintosh. 0 is
the standard Macintosh modem port, 1 is the standard Macintosh printer port,
2 is the first connector on the interface extension box. This leads to much
confusion which can be healed with a simple rule: If a device is connected
to the Macintosh serial port extension box, then its channel number is the
interface number on the box plus one.
listening for requests. It is usually 4000.
<li><b>channel</b> The number of the RS-232 interface port
on the terminal server.
</ul>
</p>
<h3>Bus Access</h3>
<p>
SICS and its internals cover many common usage cases. However there are always
situations where SICS has to be bypassed and commands to be sent to a
controller directly. This can happen in order to satisfy a special request or
as first step in the integration of a special piece of hardware into SICS. In
order to do such things the following facilities are available:
<H4>Direct Access to RS232 Controllers or TCP/IP Controllers.</H4>
<p>
Both controllers listening on a TCP/IP port or RS-232 devices connected to a
terminal server can be directly accessed through the RS232 commands. The
first step in using this system is always to accounce the controller to SICS
using the command:
<pre>
MakeRS232Controller name terminalserver port
</pre>
in the SICS initialization file.
For example:
<pre>
MakeRS232Controller hugo psts213 3004
</pre>
name is the SICS name for the controller, terminalserver is the name
of the terminal server the device is connected to and port is the port
number at which the terminal server publishes the RS232 channel to
which the device is connected. This is usally the port number plus 3000.
</p>
<p>
Now various commands are available for interfacing with the RS232
controller. In the following description the SICS name of the
controller is replaced by the symbol rs232name.
<dl>
<dT>rs232name sendterminator
<dD>prints the current terminator used when sending data to the device
as hexadecimal numbers.
<dT>rs232name sendterminator h1h2..hn
<dD>sets the current terminator used when sending data to the device
to the characters described by the hexadecimal numbers h1 to hn. The
numbers are in the format 0xval, where val is the hex number.
<dT>rs232name replyterminator
<dD>prints the current terminator expected to terminate a response
from the device as a hexadecimal number.
<dT>rs232name replyterminator h1h2..hn
<dD>sets the current terminator expected to terminate a response from
the device to the characters described by the hexadecimal numbers h1
to hn.
The numbers are in the format 0xval, where val is the hex number.
<dt>rs232name timeout
<dd>prints the current timeout when waiting for a reponse from the
device.
<dt>rs232name timeout val
<dd>sets the timeout for waiting for responses from the device. The
value is in microseconds.
<dt>rs232name send data data data
<dd>sends the remainder of the line to the RS232 device and waits for
a response terminated with the proper reply terminator specified. This
commands waits at maximum timeout microseconds for a response. If a
valid response is obtained it is printed, otherwise an error message
occurs.
<dt>rs232name write data data data
<dd>writes the remainder of the line after write to the device without
waiting for a response.
<dt>rs232 available
<dd>checks if data is pending to be read from the device.
<dt>rs232 read
<dd>reads data from the device.
</dl>
</p>
<H4>Accessing Serial Ports (Old System)</H4>
<P>
In addition to the system describe above there is another system for accessing
serial ports which uses the SerPortServer program. The use of the system is
deprecated, new software should use the commands describe above. Nevertheless
the older sytem is described here for reference.
</p>
<p>
Serial port access is implemented as an extension to the Tcl macro language.
Essentially this is the same implementation as used in the program psish.
This section describes how to use serial port access. Several
steps have to be performed:
<ol>
<li>Install the serialport command into the SICS server. This requires two lines to be added to
the server startup script:
<ul>
<li>SerialInit
<li>TclPublish serialport UserRights
</ul>
Where UserRights stands for one of the possible SICS user rights.
See documentation
for TclPublish above.
<li> Each separate serial port will be represented by a name in the SICS server
after it has been initialized. This name is also a command. These port names
live in the Tcl interpreter and must be made accessible with TclPublish.
For example for
a port named p1 include this line in the server startup script:
<ul>
<li>TclPublish p1 User
</ul>
Replace User with the correct access code you want for a serial port. It is
recommended
to restrict serial port access to SICS managers only.
<li> After starting the SICS server the command serialport is now available.
<li> Now a serial port can be initialized with a command like this:
<ul>
<li>serialport name1 SerPortServer.host port channel force
<li>Example: serialport p1 localhost 4000 5
</ul>
Such a command creates the command name1 and links it with serial port channel
channel on the instrument computer (localhost) running the SerPortServer program . Port is the port number on which the
SerPortServer is listening for connections (usually 4000).
The last flag force is optional. If something is there, the connection to that
port is done on a separate socket of its own. This has to do with some
feature of the software interface to the SerPortServer serial port server.
This
software interface tries to direct messages for multiple channels through one
socket connection between the host and the Macintosh server. This is perfectly
fine as long as none of the commands through this socket takes a long time
to execute. However, if a RS-232 device takes a long time to respond, the whole
socket is blocked. Fortunately, the serial port server runs a separate
thread of execution for each different socket. By forcing a new socket it can
be achieved that such a slow device is decoupled from the rest. Exactly this
is achieved with the force flag.
<li> Once the port has been initialised (for example p1) it is ready to
operate.
The port object allows to send data to the serial port and receive data from
it. Furthermore some configuration is possible. The syntax is like this:
<DL>
<DT>portname -tmo number
<DD>Sets the timeout for the serial port. This is the maximum amount of time
the serial port server waits for data to arrive from the RS-232 device.
Increase this if a lot of <code>_BAD_TMO</code> error messages creep up.
<DT>portname -sendterm string
<DD> Sets the terminator which will be automatically added to the string
which is
sent. Some RS-232 devices require special terminators in order to accept a command.
The serial port implementation ensures that such a terminator is sent after
each message. This command allows to configure this terminator. Please note,
that the terminator string needs to be enclosed in quotes. An example:
<ul>
<li><code>p1 -sendterm "\r\n"</code>
</ul>
This sets the terminator to carriage return - line feed.
<DT>portname -replyterm string.
<DD>The serial port server expects the RS-232 device to send a terminator
when it is done with sending answers. It even supports multiple lines to be
sent as a reply. This expected reply terminator is set with this command.
The string may may be four characters long. An example: <code>1\r\n</code> sets
the expected terminator to one of <code>\r\n</code>. One of them is expected.
Thus the first character is the count of terminators to expect, followed by
the characters possible as terminators. This string must usually be quoted.
<DT>portname blablalakjdl
<DD>When none of the options -tmo, -replyterm, -sendterm, is found everything
after portname is sent to the RS-232 device. The reply from the RS-232
device is printed.
</DL>
</ol>
The defaults set for the configuration parameters of the serial port connection
are suited for the EL734, EL737 and ITC4 devices usually encountered at SINQ.
For other RS-232 devices consult the manuals hopefully delivered with the
device.
The defaults are: 100 for timeout, <code>1\r\n</code> for the reply terminator and
<code>\r\n</code>for the send terminator.
</p>
<h4>GPIB Controller Access</h4>
<p>
GPIB is yet another bus system. Up to 30 devices can share the bus and
transfer data on it. SICS likest to speak to GPIB devices through the
National Instrument ENET-100 TCP/IP bridge. In order for this to work
the National Instruments driver software must have been installed on
the computer running SICS. SICS has to be compiled with the define
HAVENI defined and the proper paths to the header file and library
configured. Then an GPIB controller can be installed into SICS with the
command:
<pre>
MakeGPIB name drivertype
</pre>
Name is the name under which the GPIB controller is addressable within
SICS afterwards. drivertype is the driver to use for the GPIB
device. Supported values are:
<dl>
<dt>sim
<dd>Simulation
<dt>ni
<dd>National instruments driver, see above.
</dl>
The GPIB controller supports a couple of commands for communicating
with devices on the GPIB bus directly. Use with extra care because it
is very easy to lock things up on the GPIB bus. In the following
documentation of the command set it is assumed that a GPIB controller
has been configured into the system under the name <b>gpib</b>. Please
note, that managers privilege is required in order to be allowed to
wrestle with this controller.
<dl>
<dt>gpib attach controller-no gpib-address gpib-secondary timeout
eos eot
<dd>This attaches the GPIB controller to a certain device at a certain
address for later communication. The return value is an integer
handle which will be used later on a s a handle devID when referring
to the connection. The parameters are:
<dl>
<dt>controller-no
<dd>The number of the GPIB controller on the computer. There may be
more then one GPIB controllerinstalled on a given system. Usually this
is 0.
<dt>gpib-address
<dd>The GPIB address of the device on the bus.
<dt>gpib-secondary
<DD>GPIB devices may have a seconadry address. This can be specified
with this parameter. Usually this is 0.
<dt>timeout
<dd>The time to wait for answers on the GPIB bus. 13 is 10 seconds and
ussually a good value.
<dt>eot
<dd>A parameter determining the termination mode on this
connection. Consult NI documentation for this or leave at 0.
<dt>eoi
<dd> A terminator. Set to 1 or understand NI documentation for this
parameter.
</dl>
<dt>gpib detach devID
<dd>Breaks the connection described through devID. devID is the return
value from attach.
<dt>gpib clear devID
<dd>Tries to clear the GPIB buffers for the conenction described
through devID. Usually in vain.
<dt>gpib send devID bal bla bla
<dd>sends data to the device at devID.
<dt>gpib sendwithterm devID string terminator
<dd>Sends string to the device at devID. The terminator character
identified through the integer terminator is automatically
appended. Use this to send things which require a
terminator. Terminators included in strings sent by send get messed up
through Tcl!
<dt>gpib read devID
<dd>Reads data from the device at devID and returns it as a string.
<dt>gpib readtillterm devID terminator
<dd>Read from teh device devID unti the terminator character described
through the interger terminator is read. Then return the data read as
a string.
</dl>
</p>
<h3>Controllers</h3>
<p>
For the same reason as stated above, it is necessary to represent controllers
within SICS. Controllers implement more then only device access but also
maintain common state or implement special behaviour.
</p>
<h4>ECB Controllers</h4>
<p>
ECB controllers are at the heart of the Risoe data aquisition
system. These are essentially Z80 processors wired to the GPIB
bus. Functions can be invoked in this processor by sending a function
code followed by the contents of 4 8 bit registers. As a result the
contents of the registers after the function call are returned. A ECB
can be made knwon to SICS through the initialisation command:
<pre>
MakeECB name gpib-controller gbib-controller-number gpib-address
</pre>
The parameters:
<dl>
<dt>name
<dd>The name used as a token for this controller later on.
<dt>gpib-controller
<dd>the name of the GPIB interface to use. See above.
<dt>gbib-controller-no
<dd>The number of the GPIB board in the system
<dt>gpib-address
<dd>The GPIB address of the ECB on the GPIB bus.
</dl>
Once installed, the ECB controller understands a few commands:
<dl>
<dt>ecb1 func funcode d e bc
<dd>Invoke ECB function funcode with the registers d e b c.Returns the
contents of the registers d e b c. Function codes and register
contents are documented, if at all, in the ECB documentation. In fact, as
ECB documentation is not available, the only documentation on ECB is the
source code of tascom.
<dt>ecb1 clear
<dd>Tries, usually in vain, to clear the communications interface to
the ECB.
<dt>ecb1 toint char
<dd>A helper function which converts the character char to an
integer. Tcl does not seem to be able to do that.
</dl>
<H4>Siematic SPS Controllers</H4>
<P>
Siematic SPS controllers are used at SinQ for handling all the things which
fit nowhere else. Such as operating air cushions on some instruments,
reading variables from ADC's, reading status of shutters or other parts of
the instrument and the like. Those SPS units have an RS-232 connector and
understand a simple ASCII command protocoll.
The Siematic SPS and its command protocoll are
special to PSI and this section is probably of no interest to SICS managers
outside. The SPS basiaclly support three operations:
<ul>
<li>Push a button (Set a Digital I/O Bit).
<li>Read a status of instrument status packed into a bit (Read Digital I/O) .
<li>Read an ADC.
</ul>
This is so user unfriendly that the usage of the SPS will mostly be packaged
into Tcl-macros.
</P>
<p>
A SPS unit can be configured into the SICS server with the command:<br>
<b>MakeSPS name macintosh port channel</b> <br>
The parameters are: the name of the SPS in SICS, the serial port server
computer, the port where the serial port server is listening and the
channel number of the SPS unit at the serial port server computer. An
example: <br>
MakeSPS sps1 lnsp25.psi.ch 4000 6 <br>
configures a SPS unit at lnsp25.psi.ch at channel 5. The serial port server
is listening at port number 4000. The SPS unit will be accessible as sps1 in
SICS.
</p>
<p>
After configuartion the following four commands are understood by name,
shown with sps1 as example:
<DL>
<DT>sps1 push byte bit
<DD>Corresponds to pushing the button mapped to the bit bit in the byte
byte.
<DT>sps1 adc num
<DD> Reads the value in the ADC num. num can be between 0 to 7 for a maximum
of eight ADC's. Please note, that the values read are raw values which
usually must be converted in some way to physically meaningful values.
<DT>sps1 status bit
<DD>Reads the status of the bit bit. bit can be in the range 0 - 128.
<DT>sps1 stat2 byte bit
<DD>Reads the status bit bit in status byte byte. Is equivalent to status,
but adds some syntatctic sugar.
</DL>
For all conversion factors, for all mappings of bytes and bits, consult the
electronician who coded the SPS.
</p>
<h4>General Controller Object and Choppers</h4>
<p>
Chopper systems are handled via a generic controller object. This basicly
consists of two components: One object represents the actual
controller. This basic object allows to query parameters only. Then
there is for each parameter which can be controlled from SICS in this
controller an adapter object. These adapter object are virtual motors
which can be driven with the normal run or drive commands. Currently
two drivers for this scheme exists: one for a simulated device, the
other for the Dornier Chopper Controller at FOCUS. The first step when
initializing this system is the installation of the general controller
object into SICS. This is done with the commands:
<pre>
MakeChopper name sim
MakeChopper name docho mac port channel
</pre>
The first command simply installs a simulated controller.
The second command install a controller with a driver for the FOCUS
Dornier Chopper system. Mac, port and channel are the usual Macintosh
terminal server parameters which describe where the chopper controller
is connected to through its RS-232 interface. After both commands the
controller is available as command name within SICS.
</p>
<p>
A drivable parameter at this controller is installed with a command
similar to this:
<pre>
ChopperAdapter vname cname pname lower upper
</pre>
vname is the name under which the virtual motor will appear in
SICS. cname is the name of the controller object installed into SICS
with the commands in the previous paragraph. pname is the name of the
drivable parameter in the controller. upper and lower are the upper
and lower limits for this parameter. More then one of these commands
can be given for each general controller.
</p>
<p>
After this, the parameter can be modified by a command like:
<pre>
drive vname newvalue
</pre>
</p>
<h3> Motors</h3>
<p>
@ -42,12 +413,18 @@ El734 motor controller. The
parameters host, port, chan have the meanings defined above. no is the
number of the motor in the EL734 motor controller.
<DT>Motor name EL734DC host port chan no
<DD>This command creates an analog motor named name which is controlled through a
El734DC motor controller. The
<DD>This command creates an analog motor named name which is controlled
through a El734DC motor controller. The
parameters host, port, chan have the meanings defined above. no is the
number of the motor in the EL734DC motor controller.
<dt>Motor name el734hp rs232controllername motornum
<dd>Creates a motor object name using the newer motor drivers which access
the motor controller directly, without the serial port server.
rs232controllername is the name of a connection to the motor controll which
has been set up with MakeRS232, above. Motornum is the number of the motor in
the controller.
<DT>MakePIMotor name c804 pararray
<DD>Creates a motr name connected to a C804 motor controller from the
<DD>Creates a motor name connected to a C804 motor controller from the
manufacturer Physik Instrumente. Pararray is a Tcl array holding the
initialization information. The follwoing elements are required in this
array:
@ -136,7 +513,6 @@ at any given time. In SICS this is directed through the anticollider
module described elsewhere.
</DL>
</p>
<h3>Counting Devices</h3>
<p>
<DL>
@ -146,10 +522,21 @@ accessible as object name. Failrate is the per centage of invocations
at which the counter will generate a random failure for testing error
treatment code. If failrate is less then 0, there are no
failures. This can be used in a instrument simulation server.
<dt>MakeCounter name mcstas
<dd>Creates a counter which interoperates with a
<a href="mcstas.htm">McStas</a> simulation. Please note,
that the McStas module mccontrol must have been initialized before this initialization
can work.
<DT>MakeCounter name EL737 host port chan
<DD>This command creates a single
counter name, using an EL737 driver. The counter is at host host, listening
at port port and sits at serial port chan.
<DT>MakeCounter name EL737hp terminalserver port
<DD>Creates a counter object name which uses the faster driver which connects
directly to the terminal server without the serial port server program.
Terminalserver is the name of the instruments terminal server. Port is the
port number at which the terminal server publishes the port at which the EL737
controller is connected. Usually this 3000 + port number.
<dt> MakeCounter name ecb ecb-controller
<dd>Installs a counetr on top of the Risoe ECB hardware. The only
parameter is the name of the ECB controller to use.
@ -183,12 +570,21 @@ HM. Histogram memory objects can be created using the command:
<DT> MakeHM name type
<DD> The parameter name specifies the name under which the HM will be
avialable in the system. type specifies which type of driver to use.
Currently three types of drivers are supported: SIM for a simulated HM
, SINQHM for the SINQ histogram memory and tdc for the Risoe histogram memory.
Please care to note, that the SINQHM
requires a EL737 counter box for count control. This counter must have been
defined before creating the HM object.
Currently these drivers are supported:
<dl>
<dt>SIM
<dd>for a simulated HM
<dt>SINQHM
<dd>for the SINQ histogram memory
<dt>tdc
<dd>for the Risoe histogram memory.
<dt>mcstas
<dd>for the integration with the <a href="mcstas.htm"> McStas</a> simulation.
</dl>
</DL>
Please care to note, that the SINQHM
requires a counter box for count control. This counter must have been
defined before creating the HM object.
As an example the configuration of a SINQHM HM with the name banana will be
shown:
<pre>
@ -246,188 +642,6 @@ nvs add 3800 4500
nvs add 5900 6700
nvs add 8100 9600
</pre>
</p>
<h3>Chopper</h3>
<p>
Chopper systems are handled via a generic controller object. This basicly
consists of two components: One object represents the actual
controller. This basic object allows to query parameters only. Then
there is for each parameter which can be controlled from SICS in this
controller an adapter object. These adapter object are virtual motors
which can be driven with the normal run or drive commands. Currently
two drivers for this scheme exists: one for a simulated device, the
other for the Dornier Chopper Controller at FOCUS. The first step when
initializing this system is the installation of the general controller
object into SICS. This is done with the commands:
<pre>
MakeChopper name sim
MakeChopper name docho mac port channel
</pre>
The first command simply installs a simulated controller.
The second command install a controller with a driver for the FOCUS
Dornier Chopper system. Mac, port and channel are the usual Macintosh
terminal server parameters which describe where the chopper controller
is connected to through its RS-232 interface. After both commands the
controller is available as command name within SICS.
</p>
<p>
A drivable parameter at this controller is installed with a command
similar to this:
<pre>
ChopperAdapter vname cname pname lower upper
</pre>
vname is the name under which the virtual motor will appear in
SICS. cname is the name of the controller object installed into SICS
with the commands in the previous paragraph. pname is the name of the
drivable parameter in the controller. upper and lower are the upper
and lower limits for this parameter. More then one of these commands
can be given for each general controller.
</p>
<p>
After this, the parameter can be modified by a command like:
<pre>
drive vname newvalue
</pre>
</p>
<h3>RS232 Controller Direct Access</h3>
<p>
RS232 controllers connected to a terminal server can be directly accessed
by SICS through the TCP/IP network, bypassing the SerPortServer
program. See the <a href="rs232.htm">description</a> of this facility
for more details. Such a controller can be configured into the system
through the command:
<pre>
MakeRS232Controller name terminalserver port
</pre>
For example:
<pre>
MakeRS232Controller hugo psts213 3004
</pre>
name is the SICS name for the controller, terminalserver is the name
of the terminal server the device is connected to and port is the port
number at which the terminal server publishes the RS232 channel to
which the device is connected. This is usally the port number plus 3000.
</p>
<p>
To be expanded. Please note, that environment devices such as temperature
controllers are dynamically configured into the system at run time.
Therefore the necessary commands are described in the user documentation.
</p>
<h3>GPIB Controller Access</h3>
<p>
GPIB is yet another bus system. Up to 30 devices can share the bus and
transfer data on it. SICS likest to speak to GPIB devices through the
National Instrument ENET-100 TCP/IP bridge. In order for this to work
the National Instruments driver software must have been installed on
the computer running SICS. SICS has to be compiled with the define
HAVENI defined and the proper paths to the header file and library
configured. The an GPIB controller can be installed into SICS with the
command:
<pre>
MakeGPIB name drivertype
</pre>
Name is the name under which the GPIB controller is addressable within
SICS afterwards. drivertype is the driver to use for the GPIB
device. Supported values are:
<dl>
<dt>sim
<dd>Simulation
<dd>ni
<>National instruments driver, see above.
</dl>
The GPIB controller supports a couple of commands for communicating
with devices on the GPIB bus directly. Use with extra care because it
is very easy to lock things up on the GPIB bus. In the following
documantation of the command set it is assumed that a GPIB controller
has been configured into the system under the name <b>gpib</>. Please
note, that managers privilege is required in order to be allowed to
wrestle with this controller.
<dL>
<dt>
</dl>gpib attach controller-no gpib-address gpib-secondary timeout
eos eot
<dd>This attaches the GPIB controller to a certain device at a certain
address for later communication. The return value is an integer
handle which will be used later on a s a handle devID when referring
to the conenction. The parameters are:
<dl>
<dt>controller-no
<dd>The number of the GPIB controller on the computer. There may be
more then one GPIB controllerinstalled on a given system. Usually this
is 0.
<dt>gpib-address
<dd>The GPIB address of the device on the bus.
<dt>gpib-secondary
<DD>GPIB devices may have a seconadry address. This can be specified
with this parameter. Usually this is 0.
<dt>timeout
<dd>The time to wait for answers on the GPIB bus. 13 is 10 seconds and
ussually a good value.
<dt>eot
<dd>A parameter determining the termination mode on this
connection. Consult NI documentation for this or leave at 0.
<dt>eoi
<dd> A terminator. Set to 1 or understand NI documentation for this
parameter.
</dt>
<dt>gpib detach devID
<dd>Breaks the connection described through devID. devID is the return
value from attach.
<dt>gpib clear devID
<dd>Tries to clear the GPIB buffers for the conenction described
through devID. Usually in vain.
<dt>gpib send devID bal bla bla
<dd>sends data to the device at devID.
<dt>gpib sendwithterm devID string terminator
<dd>Sends string to the device at devID. The terminator character
identified through the integer terminator is automatically
appended. Use this to send things which require a
terminator. Terminators included in strings sent by send get messed up
through Tcl!
<dt>gpib read devID
<dd>Reads data from the device at devID and returns it as a string.
<dt>gpib readtillterm devID terminator
<dd>Read from teh device devID unti the terminator character described
through the interger terminator is read. Then return the data read as
a string.
</dl>
</p>
<h3>ECB Controllers</h3>
<p>
ECB controllers are at the heart of the Risoe data aquisition
system. These are essentially Z80 processors wired to the GPIB
bus. Functions can be invoked in this processor by sending a function
code followed by the contents of 4 8 bit registers. As a result the
contents of the registers after the function call are returned. A ECB
can be made knwon to SICS through the initialisation command:
<pre>
MakeECB name gpib-controller gbib-controller-number gpib-address
</pre>
The parameters:
<dl>
<dt>name
<dd>The name used as a token for this controller later on.
<dt>gpib-controller
<dd>the name of the GPIB interface to use. See above.
<dt>gbib-controller-no
<dd>The number of the GPIB board in the system
<dt>gpib-address
<dd>The GPIB address of the ECB on the GPIB bus.
</dl>
Once installed, the ECB controller understands a few commands:
<dl>
<dt>ecb1 func funcode d e bc
<dd>Invoke ECB function funcode with the registers d e b c.Returns the
contents of the registers d e b c. Function codes and register
contents are documented, if at all, in the ECB documentation.
<dt>ecb1 clear
<dd>Tries, usually in vain, to clear the communications interface to
the ECB.
<dt>ecb1 toint char
<dd>A helper function which converts the character char to an
integer. Tcl does not seem to be able to do that.
</dl>
</p>
</body>
</html>

View File

@ -20,7 +20,7 @@ its internal command list (No need to carry them around all the time). Now a
status backup file will be read. This file contains normal SICS statements
which initialise parameter values to the values they had before the last
shutdown of the server. Such a file is automatically written whenever a
normal shutdown of the server happens.
normal shutdown of the server happens or variables change.
</p>
<p>
The SICS server configuration file is essentially a SICS macro language
@ -48,8 +48,8 @@ initialization.
lowercase. This file holds instrument specific commands defined in the
Tcl macro language. This file is automatically included by inst.tcl.
<dt>scancommand.tcl, tecs.tcl, log.tcl
<DD>Some macro definitions which are used by so many instruments that
it was deemed appropraite to hold them in separate files. Such files
<DD>Some macro definitions are used by so many instruments that
it was deemed appropriate to hold them in separate files. Such files
are included from instcom.tcl.
</dl>
</p>

View File

@ -20,6 +20,7 @@ Go to:
<li> Advice about <a href=hwini.htm> hardware </a> configuration.
<li> A description of <a href = command.htm> command </a> initialisation.
<li> Managing the SICS <a href="helpman.htm"> help </a> system.
<li> Connecting SICS to <a href="mcstas.htm">McStas</a> Simulations.
</ul>
</p>
<!latex-on>

View File

@ -3,31 +3,72 @@
<TITLE>The Internal Scan Command</TITLE>
</HEAD>
<BODY>
<H1>The Internal Scan Command</H1>
<P>
Scans are preformed from a variety of commands in SICS. All these commands
are just Tcl--wrappers around an internal scan object implemented in C. This
section describes this internal scan command and how it works. This internal
scan command is installed into the SICS server via the <a href=command.htm>MakeScanCommand
command</a> in the initialisation file. This command install the internal
scan object under a user defined name. For the rest of this document it is
assumed that this name is xxscan.
</P>
<H1>The Internal Scan Commands</H1>
<h2>Scan Concepts</h2>
<p>
Scans in SICS involve an internal scan module and a lot of scripts which
wrap the internal scan module into a syntax liked by the users.
</p>
<p>
The internal scan module in SICS evolved a little over time. It turned
out that scans
are a demanding job for a programmer because of the plethora of
special scans people wish to perform and the many data file formats which
have to be supported. This requires a very high degree of
configurability. Under several refactorings the internal scan command
has grown to become:
<ul>
<li>A controller for the scan process.
<li>A container to store scanned variables and counts during the
process of a scan. This includes commands to store and retrieve such
values.
<li>A container for the configuration of the scan. A scan is
configured by specifying functions to be called at the various steps
during the scan. These are preconfigured to the standard scan
functions. An API is provided to replace some or all of the scan
functions by user defined ones.
</ul>
The internal scan object is augmented by a library of standard scan
functions. The transition to the new model is not yet clean in order
not to break to much old code.
</p>
<p>
The standard scan command can be configured into SICS using the command:
<dl>
<DT>MakeScanCommand name countername headfile recoverfil
<DD>MakeScanCommand initialises the SICS internal scan command. It will be
accessible as name in the system. The next parameter is the name of a valid
counter object to use for counting. The next parameter is the full pathname of
a header description file. This file describes the contents of the header of
the data file. The format of this file is described below. The parameter
recoverfil is the full pathname of a file to store recover data. The internal
scan command writes the state of the scan to a file after each scan point.
This allows for restarting of aborted scans.
</dl>
</p>
<p>
The scan object (named here xxscan, but may have another name) understands
the following commands:
<DL>
<DT>xxscan clear
<DD>clears the list of scan variables. Must be called before each scan with
different parameters.
<DT>xxscan add name start step
<DD>This command adds the variable specified by the argument name to the
list of variables scanned in the next scan. The arguments start and step
define the starting point and the sptep width for the scan on this variable.
<DT>xxscan clear
<DD>clears the list of scan variables. Must be called before each scan with
different parameters.
<dt>xxxscan log var
<dd>This command adds a variable to be logged during the scan. Can be slave
motors such as stt, om, chi, phi during four circle work. These variables
are not driven, just logged. var is the SICS variable to log. Only drivable
parameters may be logged in such a way.
<DT>xxscan run NP mode preset
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
the counter mode to use (this can be either timer or monitor) and preset
which is the preset value for the counter. Scan data is written to an output
file.
<dt>xxscan continue NP mode preset
<dd>Continues an interrupted scan. Used by the recovery feauture.
<DT>xxscan silent NP mode preset
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
the counter mode to use (this can be either timer or monitor) and preset
@ -40,27 +81,44 @@ scan has been aborted due to user intervention or a system failure, this
scheme allows to continue the scan when everything is alright again. This
works only if the scan has been started with run, not with silent.
<DT>xxscan getfile
<DD>This command retuns the name of the current data file.
<DD>This command returns the name of the current data file.
<DT>xxscan setchannel n
<DD>Sometimes it is required to scan not the counter but a monitor. This
command sets the channel to collect data from. The argument n is an integer
ID for the channel to use.
<DT>xxscan getcounts
<DD>Retrieves the counst collected during the scan.
<DD>Retrieves the counts collected during the scan.
<dt>xxscan getmonitor i
<dd>Prints the monitor values collected during the scan for the
monitor number i
<dt>xxscan gettime
<dd>Prints the counting times for the scan points in the current scan.
<dt>xxscan np
<dd>Prints the number of points in the current scan.
<DT>xxscan getvardata n
<DD>This command retrieves the values of a scan variable during the scan
(the x axis). The argument n is the ID of the scan variable to retrieve data
for. ID is 0 for the first scan variable added, 1 for the second etc.
<dt>xxscan noscanvar
<dd>Prints the number of scan variables
<dt>xxscan getvarpar i
<dd>Prints the name , start and step of the scan variable number i
<DT>xxscan interest
<DD>A SICS client can be automatically notified about scan progress. This is
switched on with this command. Three types of messages are sent: A string
NewScan on start of the scan, a string ScanEnd after the scan has finished
and a string scan.Counts = {109292 8377 ...} with the scan values after each
finished scan point.
<dt>xxscan uuinterest
<dd>As above but the array of counts is transferred in UU encoded
format.
<dt>xxscan dyninterest
<dd>As above but scan points are printed one by one as a list
containing: point number first_scan_var_pos counts.
<DT>xxscan uninterest
<DD> Uninterest switches automatic notification about scan progress off.
<DT>xxscan integrate
<DD> Calculates the integrated intensity of the peak and the variance of teh
<DD> Calculates the integrated intensity of the peak and the variance of the
intensity for the last scan. Returns either an error, when insufficient scan
data is available or a pair of numbers. Peak integration is performed along
the method described by Grant and Gabe in J. Appl. Cryst. (1978), 11,
@ -77,20 +135,96 @@ from the arguments given: pos denotes the position of the peak maximum, FWHM
is the full width at half maximum for the peak and height is its height.
<DT>xxscan command tclcommand
<DD>Sets the tcl command procedure to invoke at each scan point. See below
for the description of user defined scans. Invoked without argument command
for the description of user defined scans (Old Style).
Invoked without argument command
returns the name of the current command procedure.
<dt>xxscan configure mode
<dd>Confugures the several possible scan modes for the scan
<dd>Configures the several possible scan modes for the scan
object. Currently there are two:
<ul>
<li><b>standard</b>, the default mode writing ASCII files.
<li><b>amor</b>, a special mode the reflectometer AMOR which writes
NeXus files.
<li><b>script</b> Scan functions are overriden by the user.
<li><b>soft</b> The scan stores and saves software zero point corrected
motor positions. The standard is to save the hardware positions as
read from the motor controller.
<li><b>user</b> configures the old style user overridable scans.
</ul>
<dt>xxscan storecounts counts time mon1 mon2 ...
<dD>This stores an entry of count values into the scan data
structure. To be used from user defined scan functions. The scan
pointer is incremented by one.
<dt>xxscan storecounter
<dd>Store the counts and monitors in the counter object configured for
the scan into the scan data structure. Increments the scan pointer by
one.
<dt>xxscan appendvarpos i pos
<dd>Append pos to the array of positions for scan variable i. To be
used from user defined scan functions.
<dt>xxscan callback scanstart | scanpoint | scanend
<dd>Triggers callbacks configured on the scan object. May be used by
user functions implementing own scan loops.
<dt>xxscan function list
<dd>Lists the available configurable function names. The calling style
of these functions is described in the next section about stdscan.
<dt>xxscan function functionname
<dd>Returns the currently configured function for functionname.
<dt>xxscan function functionname newfunctionname
<dd>Sets a new function to be called for the function functionname in
the scan.
</DL>
</P>
<h2>User Definable Scan Functions</h2>
<p>The last commands in the last section allowed to overload the
functions implementing various operations during the scan with user
defined methods. This section is the reference for these
functions. The following operations during a scan be configured:
<dl>
<dt>writeheader
<dd>Is supposed to write the header of the data file
<dt>prepare
<dd>Prepare does all the necessary operations necessary before a scan
starts.
<dt>drive
<dd>Is called to drive to the next scan point
<dt>count
<dd>Is called at each scan point to perform the counting operation
<dt>collect
<dd>Is called for each scan point. This function is supposed to store
the scan data into the scan data structure.
<dt>writepoint
<dd>Is called for each scan point and is meant to print information
about the scan point to the data ile and to the user.
<dt>finish
<dd>Is called after the scan finishes and may be used to dump a data file
or perform other clean up operations after a scan.
<dt>userdata
<dd>This is the name of a user defined object which may be used to
store user data for the scan.
</dl>
The exact invocations of the functions:
<ul>
<li>writeheader scanobjectname userobjectname
<li>prepare scanobjectname userobjectname
<li>drive scanobjectname userobjectname point
<li>count scanobjectname userobjectname point mode preset
<li>collect scanobjectname userobjectname point
<li>writepoint scanobjectname userobjectname point
<li>finish scanobjectname userobjname
</ul>
scanobjectname is the name of the scan object invoking the
function. This can be used for querying the scan
object. userobjectname is the name of a entity as specified as
userdata in the configuration. point is the number of the current scan point.
</p>
<h2>User Defined Scans(Old Style)</h2>
<p>
<h2>User Defined Scans</h2>
This feauture allows to override only the counting operation during a scan.
This feauture is deprecated in favour of the user overridable scan functions
described above. As it is still used, however, here is the documentation
for reference.
</p>
<p>
In some cases users wish to control the scan more closely, i.e. do
multiple counting operations at the same point etc. This is especially
@ -98,8 +232,8 @@ true when magnets are involved. In order to do this a facility has
been provided which allows the user to specify a macro routine which
is called at each point. This macro routine then performs all
necessary operations and then is responsible for storing its data. In
order to this commands have been defined which allow to append a line
to the scan data file and to store measured data in the scan data
order to allow for this commands have been defined which allow to append
a line to the scan data file and to store measured data in the scan data
structure. The last feature is necessary in order to make scan status
displays and scan analysis, such as center detection, work. The
following steps are required:
@ -133,6 +267,106 @@ command:
In all this replace xxxscan with the name of the internal scan
command.
</p>
<h2>The Scan Command Header Description File</h2>
<p>
As if all this configurability is not enough, there is another
level of configurability.
The SICS internal scan command allows to configure the contents of
the header of
the ASCII scan data file through a template header file. This is only
possible when the scan functions are left in their default configuration.
If scan functions are overloaded it is the users repsonsability to take
care of data file writing.
This section describes
the contents of the template file. This header description file
consists of normal
text mixed with a few special keywords. The normal test will be copied to
output verbatim. The keywords indicate that their place will be replaced by
values at run time. Currently only one keyword per line is supported.
Keywords recognized are:
<DL>
<DT>!!DATE!!
<DD>Will be replaced with the file creation date.
<DT>!!VAR(name)!!
<DD>Will be replaced with the value of the SICS variable name.
<DT>!!DRIV(name)!!
<DD>Will be replaced with the value drivable variable name. Drivable variables are
all motors and all variables which may be used in a drive or run command.
<DT>!!ZERO(name)!!
<DD>Will be replaced with the value of the softzero point for motor name.
<DT>!!FILE!!
<DD>Will be replaced by the creation name of the file.
</DL>
Please note that text behind such a keyword in the line will not be copied to
the output.
</p>
<h2>Differential Scans</h2>
<p>
When aligning or when searching peaks a very fast scan is
required. This is the differential scan. It starts a motor and
collects counts while the motor is running. The counts collected are
the monitor normalized difference to the previous reading. This
functionality can be configured into SICS with the command:
<pre>
MakeDiffScan
</pre> in the configuration file. An optional parameter defines
another name then diffscan (the default) for this object. Differential
scans can only be run against one motor as it cannot be guaranteed that
motors involved in a coordinated movement operate at the same speed
without mechanical coupling. The
procedure to use diffscan is:
<ul>
<li>Configure a scan variable into a SICS scan object: xxscan add var
start step
<li>Run diffscan as: diffscan scanobjectname end_position_of_scan
This runs the differential scan. Scanobjectname is the name of a SICS
internal scan object. It will be used to store the results of the
scan. While the scan is running some basic information is printed. The
scan will range from the start given in the xxscan add command to the
end position given in this call.
</ul>
The diffscan object has two configurable parameters:
<dl>
<dt>monitor
<dd>The monitor number to normalize against. For maximum precision
this should be a monitor with a lot of intensity on it.
<dt>skip
<dd>The number of SICS main loop cycles to skip between readings. This
can be used to control the amount of data generated during a
differential scan. This may become a problem if there is fast hardware.
</dl>
A word of warning: positions found in differential scans may not be
totally correct. The differential scan might even miss peaks when the
relationship between motor speed and sampling rate is bad.
</p>
<p>
Diffscan is usally wrapped in a common script command:
<dl>
<dt>fastscan motor start stop speed
<dd>which does a fast scan for motor from start to stop. Before the scan
the motors speed is set to speed. The motor is set to its original speed
after termination of the scan.
</dl>
This script can be copied from one of the older instrument command files.
</p>
<h2>Peak Analysis</h2>
<p>
There are several other feautures which can be configured into SICS
which interact very closely with the scan module:
<dl>
<DT>MakePeakCenter scancommand
<DD>MakePeakCenter initialises the peak analysis commands peak and center. The
only parameter is the name of the internal scan command.
</dl>
</p>
<h2>Common Scan Scripts</h2>
<p>
There exists a library of script functions around the scan module which are
commonly used. They provide an object oriented wrapper around the internal
scan command and the <b>cscan</b> and <b>sscan</b> commands. These
commands can be made available by including the scancommand.tcl file into
the instruments configuration file.
</p>
</BODY>
</HTML>

View File

@ -3,7 +3,7 @@
<TITLE>Programming SICS Macros</TITLE>
</HEAD>
<BODY>
<H2>Programming SICS Macros</H2>
<H1>Programming SICS Macros</H1>
<P>
The SICS server has a built in macro language. This macro language is basically
John Ousterhout's Tool Command Language Tcl. Tcl is described elsewhere.
@ -13,7 +13,7 @@ language can be used for the following purposes:
<li>Add hoc measurement procedures.
<LI>Trial measurement procedures.
<LI>Syntax adaptions to one's own favourite syntax.
<LI>Building of cmore complex commands from the SICS primitives.
<LI>Building of more complex commands from the SICS primitives.
</ul>
The general procedure for defining a macro requires defining the macro in a new
file, source this file from the configuration script and the use of the Publish
@ -28,7 +28,7 @@ In the following sections a few pecularities of the SICS macro system will be
discussed.
</P>
<h3>Input/Output</h3>
<h2>Input/Output</h2>
<p>
It would be quite verbose and confusing for the user if all output from SICS
commands called from a macro would appear on the screen during macro execution.
@ -39,19 +39,25 @@ client executing the macro. The output of a SICS command is available within the
macro script through the normal Tcl mechanism as a return value. This allows for
processing of SICS output within a macro. If the output to the client executing
the macro is required this can be done with the ClientPut command, detailed in the
user documantation.
user documentation.
</p>
<h3>Error Handling</h3>
<h2>Error Handling</h2>
<p>
Tcl has the feature that it aborts execution of a script when an error occurs.
If a macro script needs to handle errors either from Tcl or from SICS commands
this can be achieved by using the Tcl catch mechanism. A script can inquire the current interrupt value of the
this can be achieved by using the Tcl catch mechanism.
</p>
<P>
If things are seriously wrong or the users wishes to interrupt an operation
SICS interrupts are used. Scripts implementing measurement procedures may
need to test and even modify interrupt values.
A script can inquire the current interrupt value of the
connection with the command <b>GetInt</b>. If a script can handle an error condition
it may set the interrupt on the connection object with the <b>SetInt</b> command.
The textual representations of interrupts for these commands are:
continue, abortop, abortscan, abortbatch, halt, free, end.
</p>
<h3>Interacting with SICS within a Script</h3>
<h2>Interacting with SICS within a Script</h2>
<p>
There exist a few commands which allow to inquire or manipulate SICS
internals. Most of these commands are only available in macro scripts.
@ -73,10 +79,69 @@ the object var. var must be a drivable or countable object. The integer code ret
are defined in the SICS programmers documentation.
</DL>
</p>
<h2>SICS Interfaces in Tcl</h2>
<p>
Currently it is not possible to define object interfaces from within the SICS
macro language. For the notion of object interfaces see the
SICS programmers documentation. This may be implemented in future when needed.
Work has begun to implement SICS internal interfaces in Tcl. This opens the
port for writing even device drivers in Tcl. Another use is to define
virtual motors quickly in Tcl. At the time of writing, July 2005, this
is only developed for the object interface and the drivable interface.
For the meaning of internal SICS interfaces please consult the SICS
programmers documentation. Be warned: with the feautures described in this
section, you can mess up SICS badly.
</p>
<h3>The Object Interface</h3>
<p>
<dl>
<dt>MakeTclInt name
<dd>Creates an object name. This object then understands the following
commands:
<dl>
<dt> name savescript scriptname
<dd>Configures a script which will be called when it is time to dump
the status of the SICS server. This script will be called with the
name of the object as its only parameter.
<dt>name backup bla bla bla....
<dd>To be used from savescripts. Writes everything behind backup into the
status file.
</dl>
The use of this facility is to place special commands into the status file
which may, for instance, request calculations to be made or drive parameters
not caught in the standard SICS objects to special values. For example:
at SANS2 this is used in order to store attenuator and collimator
values. Both are implemented as scripted commands and thus do take part
in the standard SICS object saving scheme.
</dl>
</p>
<h3>Overriding the Drivable Interface with Tcl</h3>
<p>
The drivable interface of any given drivable object can be overriden with
tcl functions. This includes an object created with MakeTclInt. The syntax is:
<dl>
<dt>TclReplaceDrivable objname key scriptname tclName
<dd>This replaces the drivable interface function defined by key with the
script scriptname in the driveable interface of the SICS object object.
tclName is the name of an arbitrary Tcl object which can hold user data.
Possible function keys and their function signatures are:
<dl>
<dt>halt
<dd> haltscript, no parameters
<dt>checklimits
<dd>checklimitsscript targetvalue
<dt>setvalue
<dd>setvaluscript targetvalue
<dt>checkstatus
<dd>checkstatusscript, no parameters
<dt>getvalue
<dd>getvaluescript, no parameters
</dl>
All procedures, excpet getvaluescript, are supposed to return the
approriate SICS return codes (HW*) as integer numbers. Getvaluescript
is supposed to return the position of the device.
<dt>TclDrivableInvoke objname key
<dd>A debugging aid: Invokes the scripted function denoted by key of the
object objname and prints the results. The function keys are the same
as given above.
</dl>
</p>
</BODY>
</HTML>

View File

@ -33,14 +33,32 @@ which is described elsewhere.
<p>
Where to you want to go today?
<ul>
<li> To the general <a href =setup.htm> setup</a> section.
<Li> To the <a href = inifile.htm> server initialision</a> section.
<li> To the section describing <a href=special.htm>special commands</a> for
SICS administrators or programmers.
<li> Commands for <a href=status.htm>status display</a> support.
<li> To the general SICS setup section.
<ul>
<li><a href="setup.htm">SICS Installation</a>
<li><a href="move.htm">Exchanging Hardware</a>
<li><a href="trouble.htm">Troubleshooting SICS</a>
</ul>
<Li> To the SICS Initialization File section.
<ul>
<li><a href="ini.htm">SICS Initialization Overview</a>
<li><a href="option.htm">SICS Server Options</a>
<li><a href="var.htm">SICS Variables</a>
<li><a href="hwini.htm">Hardware Configuration</a>
<li><a href="gencom.htm">Initialization of General Commands</a>
<li><a href="iscan.htm">The SICS Scan System</a>
<li><a href="nxscript.htm">Scripting NeXus Files</a>
<li>Initialization of Instrument Specific Commands.
<ul>
<li><a href="four.htm">Four Circle Commands</a>
<li><a href="tas.htm">Triple Axis Commands</a>
<li><a href="amor.htm">Reflectometer Commands</a>
<li><a href="sans.htm">Small Angle Scattering<a/> Commands.
<li><a href="focus.htm">FOCUS<a/> Commands.
</ul>
</ul>
<li> To the <a href="macroman.htm">macro</a> programming section.
<LI> <a href = trouble.htm>Troubleshooting</a> hints.
<Li> Hints for <a href = "move.htm">moving</a> the SICS server or for Exchanging the serial port server.
<li> To the <a href="mcstas.htm">McStas simulation SICS</a> integration.
</ul>
</p>
<!latex-on>

View File

@ -26,6 +26,7 @@ CH--5232 Villigen--PSI\\
Switzerland\\
\end{center}
\clearpage
\clearpage
\tableofcontents
\clearpage
@ -40,23 +41,26 @@ to understand John Ousterhouts Tool Command Language,
which is described elsewhere.
%html setup.htm 1
%html inifile.htm 1
%html move.htm 2
%html trouble.htm 2
\chapter{The SICS Initialization File}
%html ini.htm 1
%html option.htm 1
%html var.htm 1
%html hwini.htm 1
%html command.htm 1
%html helpman.htm 2
%html special.htm 1
%html serial.htm 2
%html status.htm 2
%html sps.htm 2
%html iscan.htm 2
%html alias.htm 2
%html cron.htm 2
%html rs232.htm 2
%html gencom.htm 2
%html iscan.htm 2
%html nxscript.htm 2
%html nxupdate.htm 2
%html ../user/trouble.htm 1
%html move.htm 1
\section{Instrument Specific SICS Initializations}
%html four.htm 3
%html tas.htm 3
%html amor.htm 3
%html sans.htm 3
%html focus.htm 3
%html macroman.htm 1
%html mcstas.htm 1
\end{document}

BIN
doc/manager/managerman.dvi Normal file

Binary file not shown.

2341
doc/manager/managerman.tex Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
\contentsline {chapter}{\numberline {1}Introduction}{4}
\contentsline {chapter}{\numberline {2}SICS programs, Scripts and Prerequisites}{5}
\contentsline {section}{\numberline {2.1}Hardware}{5}
\contentsline {section}{\numberline {2.2}Server programs}{5}
\contentsline {chapter}{\numberline {3}General SICS Setup}{7}
\contentsline {section}{\numberline {3.1}System Control}{8}
\contentsline {section}{\numberline {3.2}Moving SICS}{9}
\contentsline {subsection}{\numberline {3.2.1} Moving the SICS Server to a new Computer}{9}
\contentsline {subsection}{\numberline {3.2.2}Exchanging the Serial Port Server}{9}
\contentsline {subsection}{\numberline {3.2.3}Exchanging the Histogram Memory}{10}
\contentsline {section}{\numberline {3.3}SICS Trouble Shooting }{10}
\contentsline {subsection}{\numberline {3.3.1}Check Server Status}{10}
\contentsline {subsection}{\numberline {3.3.2}Inspecting Log Files}{10}
\contentsline {subsection}{\numberline {3.3.3}Restarting SICS}{11}
\contentsline {subsection}{\numberline {3.3.4}Restart Everything}{11}
\contentsline {subsection}{\numberline {3.3.5}Starting SICS Manually}{11}
\contentsline {subsection}{\numberline {3.3.6}Test the SerPortServer Program}{11}
\contentsline {subsection}{\numberline {3.3.7}Trouble with Environment Devices}{12}
\contentsline {subsection}{\numberline {3.3.8} HELP debugging!!!!}{12}
\contentsline {chapter}{\numberline {4}The SICS Initialization File}{13}
\contentsline {section}{\numberline {4.1}Overview of SICS Initialization}{13}
\contentsline {section}{\numberline {4.2}SICS Options and Users}{14}
\contentsline {section}{\numberline {4.3}SICS Variables }{15}
\contentsline {section}{\numberline {4.4}SICS Hardware Configuration}{16}
\contentsline {subsection}{\numberline {4.4.1}Bus Access}{16}
\contentsline {subsubsection}{Direct Access to RS232 Controllers or TCP/IP Controllers.}{16}
\contentsline {subsubsection}{Accessing Serial Ports (Old System)}{17}
\contentsline {subsubsection}{GPIB Controller Access}{19}
\contentsline {subsection}{\numberline {4.4.2}Controllers}{20}
\contentsline {subsubsection}{ECB Controllers}{20}
\contentsline {subsubsection}{Siematic SPS Controllers}{21}
\contentsline {subsubsection}{General Controller Object and Choppers}{22}
\contentsline {subsection}{\numberline {4.4.3} Motors}{23}
\contentsline {subsection}{\numberline {4.4.4}Counting Devices}{24}
\contentsline {subsubsection}{Histogram Memory}{25}
\contentsline {subsection}{\numberline {4.4.5}Velocity Selectors}{26}
\contentsline {section}{\numberline {4.5}Initialization of General Commands}{27}
\contentsline {subsection}{\numberline {4.5.1}Monochromators}{28}
\contentsline {subsection}{\numberline {4.5.2}Reoccuring Tasks}{28}
\contentsline {subsection}{\numberline {4.5.3}The SICS Online Help System}{29}
\contentsline {subsection}{\numberline {4.5.4}Aliases in SICS}{29}
\contentsline {subsubsection}{Object Aliases}{29}
\contentsline {subsubsection}{Runtime Aliases}{29}
\contentsline {subsubsection}{Command Aliases}{30}
\contentsline {subsection}{\numberline {4.5.5}The AntiCollision Module}{30}
\contentsline {section}{\numberline {4.6}The Internal Scan Commands}{31}
\contentsline {subsection}{\numberline {4.6.1}Scan Concepts}{31}
\contentsline {subsection}{\numberline {4.6.2}User Definable Scan Functions}{34}
\contentsline {subsection}{\numberline {4.6.3}User Defined Scans(Old Style)}{35}
\contentsline {subsection}{\numberline {4.6.4}The Scan Command Header Description File}{35}
\contentsline {subsection}{\numberline {4.6.5}Differential Scans}{36}
\contentsline {subsection}{\numberline {4.6.6}Peak Analysis}{37}
\contentsline {subsection}{\numberline {4.6.7}Common Scan Scripts}{37}
\contentsline {section}{\numberline {4.7}Scripting NeXus Files}{37}
\contentsline {subsection}{\numberline {4.7.1}Usage}{38}
\contentsline {subsubsection}{File Opening and Closing}{38}
\contentsline {subsubsection}{Writing Things}{38}
\contentsline {section}{\numberline {4.8}Automatic Updating of NeXus Files}{39}
\contentsline {subsection}{\numberline {4.8.1}Prerequisites for Using the Automatic Update Manager}{39}
\contentsline {subsection}{\numberline {4.8.2}Installing Automatic Update}{40}
\contentsline {subsection}{\numberline {4.8.3}Configuring Automatic Update}{40}
\contentsline {section}{\numberline {4.9}Instrument Specific SICS Initializations}{40}
\contentsline {subsection}{\numberline {4.9.1}Initialization for Four Circle Diffractometers}{40}
\contentsline {subsection}{\numberline {4.9.2}Triple Axis Spectrometer Specific Commands}{42}
\contentsline {subsection}{\numberline {4.9.3}Special Commands for the Reflectometer (AMOR)}{42}
\contentsline {subsubsection}{AMOR Status Display Commands}{43}
\contentsline {subsection}{\numberline {4.9.4}SANS Special Commands}{44}
\contentsline {subsection}{\numberline {4.9.5}Special FOCUS Initializations}{45}
\contentsline {subsubsection}{Special Internal FOCUS Support Commands}{45}
\contentsline {chapter}{\numberline {5}Programming SICS Macros}{46}
\contentsline {section}{\numberline {5.1}Input/Output}{46}
\contentsline {section}{\numberline {5.2}Error Handling}{47}
\contentsline {section}{\numberline {5.3}Interacting with SICS within a Script}{47}
\contentsline {section}{\numberline {5.4}SICS Interfaces in Tcl}{47}
\contentsline {subsection}{\numberline {5.4.1}The Object Interface}{47}
\contentsline {subsection}{\numberline {5.4.2}Overriding the Drivable Interface with Tcl}{48}
\contentsline {chapter}{\numberline {6}The McStas SICS Interface}{49}
\contentsline {section}{\numberline {6.1}McStas Requirements and SICS Requirements}{50}
\contentsline {section}{\numberline {6.2}The McStas Reader}{50}
\contentsline {section}{\numberline {6.3}The McStas Controller}{51}

165
doc/manager/mcstas.htm Normal file
View File

@ -0,0 +1,165 @@
<HTML>
<HEAD>
<TITLE>The McStas SICS Interface</TITLE>
</HEAD>
<BODY>
<H1>The McStas SICS Interface</H1>
<P>
It is useful to drive a simulation of an instrument with the same interface as is used at
the original instruments. One of the better packages for performing simulations of neutron
scattering instruments, including samples, is McStas. This section describes the SICS
interface to McStas simulations. The interface consists of three parts:
<ul>
<li>A McStas controller module which controls the actual simulation.
<li>A McStas reader which is responsible for reading simulated data into
SICS counters and histogram memories.
<li>Counter and histogram memory drivers which redirect their actions to the
McStas controller module.
</ul>
The general ideas is that all parameters are handled through the normal SICS simulation
drivers. The counting operations, however, are linked with the McStas simulation. In order
to be portable, many aspects are controlled by scripts. These scripts are configured at the
McStas Controller. Several scripts must be defined:
<dl>
<dt>startmcstas
<dd>This script will be invoked when counting starts and has to collect the necessary
settings from SICS, construct a McStas command line and start the simulation. As a return
value this script has to return the PID of the started mcstat process.
<dt>mcstastest pid
<dd>Tests if the McStas simulation is still running.
<dt>mcstasdump pid
<dd>Has to send a signal to McStas which causes it to dump its data without terminating.
Current versions of McStas do this on receiving the USR2 signal.
<dt>mcstasstop pid
<dd>Stops the McStas simulation.
<dt>mcstasread
<dd>Reads the McStas simulation output and transfers monitor and histogram memory data
into the appropriate SICS objects.
</dl>
</p>
<h2>McStas Requirements and SICS Requirements</h2>
<p>
In order for the McStas SICS interface to work the McStas simulation has to be configured
in a certain way:
<ul>
<li>All parameters which have to pass between SICS and McStas have to be declared as
simulation parameters in the DEFINE INSTRUMENT section of the instrument definition file.
Alternatively SICS can write the data to be passed to McStas into a file. But then this
file must be read in the INITIALIZE section of the instrument definition and values must
be assigned to the appropriate McStas variables.
<li>In order for the NeXus-XML based reading to work McStas must dump its data into a single file:
use the <b>-f filename</b> option. The format must be <b> --format=XML</b>.
<li> In order to count on monitor, a modified monitor component, MKMonitor MUST be used in the
simulation. This component writes the collected total counts into a file. This file is
the read by SICS in order to determine the control monitor. Evaluating the McStas dump \
file each time proved to be to inaccurate. The name of the file containing the monitor
must be configured through: mccontrol configure mcmonfile name-of-file.
<li>The mcstas simulation executable must be declared with allowexec in order to be able
to start with the Tcl exec command.
</ul>
</p>
<h2>The McStas Reader</h2>
<p>
In order to enable transfer from McStas result files into SICS objects a reader object is
needed. This module supports XML formatted McStas files, with the output dumped into
one file. The McStas options to achieve this are: <b>-f filename --format="XML"</b>
This module supports the following commands:
<dl>
<dt>mcreader open filename
<dd>Opens a McStas simulation file for reading.
<dt>mcreader close
<dd>Closes a McStas file after use.
<dt>mcreader insertmon path object monitornumber scale
<dd>This transfers a monitor value from a previously opened McStas file into a SICS
monitor field. The McStas field read is the values tag belonging to the component. The
parameters:
<dl>
<dt>path
<dd>The path to the correct values field in the simulation file. The format is the same
as the path format for NXopenpath in the NeXus-API (which will internally be used). For
groups, the name attribute is used a path component.
<dt>object
<dd>The counter object into which the monitor is read. This is a limitation, with the
this McStas interface only counters can store monitors.
<dt>monitornumber
<dd>Monitornumber is the monitor\ channel into which the value is to be stored.
<dt>scale
<dd>Scale is an optional scale factor for the monitor. Real monitors have a
sensitivity of E-6, McStas monitors have an efficiency of 1.0. This factor allows to
correct for this.
</dl>
<dt>mcreader inserthm path hmobject scale
<dd>Inserts array data stored under path in the histogram memory array of hmobject which
must be a valid SICS histogram memory object. The path is the same as given for insertmon,
but of course the data part of the detector must be addressed. Scale is again an optional
scale factor which allows to scale the McStas counts to real counts.
</dl>
The mccreader module also supports reading data from any ASCII file into SICS. Mcreader
close and open are not required then. For reading histogram memory data, the appropriate
data has to be parsed into a SICSdata object first. Then
data can be trasnferred using the following commands:
<dl>
<dt>mcreader insertmondirect counter num value
<dd>Assigns value to the monitor num at the counter object counter. Monitor 0 is the
actual counts data.
<dt>mcreader inserthmfromdata hm data
<dd>Inserts the data in the SICSData object data into the histogram memory hm.
</dl>
</p>
<H2>The McStas Controller</h2>
<p>
The actual control of the "counting" operation of the McStas simulation is done by the
McStas controller module in SICS. Internally this module implements the routines for
counting virtual neutrons. Towards the SICS interpreter, an interface is exhibited which
allows to configure and test the McStas controller. The McStas Controller delegates many
tasks to script procedures written in SICS's internal Tcl scripting language. This is done
in order to achieve a degree of generality for various types of instruments and in order
to allow easier adaption to differing demands. This is the SICS interface implemented:
<dl>
<dt>mccontrol configure mcstart startscriptname
<dd>Configures the script which starts the McStas simulation. Startscriptname is the name
of a Tcl procedure which collects the necessary information from SICS, builds a command
line and finally starts the simulation. This script is expected to return either an error or
the PID of the started process. Startscriptname will be called with the parameters mode and
preset which represent the counting characteristics.
<dt>mccontrol configure mcisrunning runtestscriptname
<dd>Configures the name of a script which tests if the McStas process is still running.
Runtestscriptname is called with the PID as a parameter. This returns 0 in the case the
McStas simulation was stopped or 1 if it is still running.
<dt>mccontrol configure mcdump dumpscriptname
<dd>Configures the name of the script which causes McStas to dump intermediate results.
The script will be called with the PID of the started McStas process as a parameter.
<dt>mccontrol configure mckill killscript
<dd>Configure the name of a procedure which kills the current McStas simulation
process. KillScript will be called with the PID of the McStas simulation as a parameter.
<dt>mccontrol configure mccopydata copyscript
<dd>This configures the name of a script which has the task to read the results of
a McStas simulation and assign values to SICS monitors and histogram memories.
<dt>mccontrol configure update updateintervallinseconds
<dd>This configures the minimum time between McStas dumps in seconds. The idea is that
SICS buffers values during a simulation run and does not interrupt the McStas process to
often.
<dt>mccontrol configure update monitorscale
<dd>Configures the scaling factor to use on the monitor in monfile. Normal monitors have
a efficiency of 1E-6, the McStas monitor counts every neutron. This can be compensated
for by this scaling factor. Note that this scaling factor may be dependent on the
wavelength used.
<dt>mccontrol configure mcmonfile filename
<dd>This configures the file which mccontrol is going to read in order to watch the
simulation control monitor.
<dt>mccontrol list
<dd>Prints a listing of the configuration parameters.
<dt>mccontrol run scriptkey
<dd>Invokes one of the scripts configure for testing purposes. scripkey can be one of:
mcstart, mcisrunning, mcdump, mckill and mccopydata.
<dt>mccontrol finish
<dd>This calls waitpid on the PID of the McStas process. This should be done in
the mckill script. Otherwise it may occur that the McStas simulation turns into
a Zombie process.
</dl>
Standard scripts for many of the script routines required are provided for the unix
environment in the file mcsupport.tcl. Please note, that all system executables called
from scripts must be registrered with SICS using the allowexec command.
</p>
</BODY>
</HTML>

View File

@ -9,16 +9,13 @@
This requires the following steps:
<ol>
<li>Create a new local account on the host computer. There is a
prefabricated account with the credentials: INSTBCK/INSTBCKLNS on
lnsa15.
<li>Run <b>sicsinstall <tt>instrument</tt> </b> in the new instruemnt
account, thereby replacing instrument with the name of the instrument
you are moving.
<li>Create and edit a suitable DataNumber file for the instrument.
prefabricated account with the credentials: instbck/INSTBCKLNS on
lnsl15.
<li>Create the directory structure.
<li>Create and edit a suitable DataNumber file for the instrument and put it
into data/YYYY. YYYY is the year.
<li>Edit the instrument configuration files and adapt the path names
to match the new situation.
<li>Configure the histogram memory to boot from the new computer, se
histogram memory documsntation for instructions how to do that.
to match the new configuration.
<li>Try to start and debug.
</ol>
</P>
@ -28,22 +25,24 @@ histogram memory documsntation for instructions how to do that.
<ol>
<li>Fetch a new one and make sure that all cables are plugged as
they were in the old one.
<li>Edit the startsics script to start the SerPortServer program with
the name of the new serial port server.
<li>Create a new .monitrc file by running makemonit.
<li>Exchange all references to the old terminal server in the instrument
configuration files to the new terminal server.
<li>Done!
</ol>
</p>
<h2>Exchanging the Histogram Memory</h2>
<p>
<ol>
<li>Get a new histogram memory computer from either Peter Rasmussen,
the test setup in WHGA/247 or in cases of greatest need, from SLS.
<li>Get a new histogram memory computer from either Gerd Theidel,
the test setup in the electronics barrack.
<li>Put into the rack.
<li>Configure the HM boot parameters through the console conneted to
<li>Configure the HM boot parameters through the console connected to
the serial port belonging to the HM. Instructions for this can be
found in the histogram memory documentation.
<li>Include the new HM into the /etc/hosts file of the instrument
computer.
found in the histogram memory documentation. Up to date boot
configuration parameters should be available under
/afs/psi.ch/group/sinqhm/boot/INST where INST is a place holder for the
instrument in upper case.
<li>Adapt the instrument configuration file to reflect the new name of
the HM.
<li>Start and debug.

View File

@ -57,6 +57,9 @@ nexusFile. The dictionary file dictFile is used.
<dt>nxscript create4 nexusFile dictFile
<dd>Creates a new NeXus file based on HDF-4 with the name
nexusFile. The dictionary file dictFile is used.
<dt>nxscript createxml nexusFile dictFile
<dd>Creates a new NeXus file based on XML with the name
nexusFile. The dictionary file dictFile is used.
<dt>nxscript reopen nexusFile dictFile
<dd>Reopens an existing NeXus with the name
nexusFile for modification or appending.
@ -76,6 +79,10 @@ definition string for the alias should not contain a dimension
description, this is automatically appended.
<dt>nxscript putfloat alias value
<dd>Writes a single floating point value to alias alias.
<dt>nxscript putint alias value
<dd>Writes a single integer value to alias alias.
<dt>nxscript updatedictvar alias value
<dd>Updates the dictionary value alis to value.
<dt>nscript putmot aliasName motorName
<dd>Writes the position of the motor motorName into the NeXus file as
described by aliasName. Theposition is a zero point corrected position. If
@ -108,7 +115,7 @@ values requested make sense to the histogram memory. In the case of
subset writing, the dimensions have to be specified in the definition
string belonging to the alias. Nxscript sets a variable timedim in the
dictionary though which contains the length of a time binning if
appropriate. This is a special help for writing extra detectors at
appropriate. This is a special feauture for writing extra detectors at
SANS and AMOR.
<dt>nxscript puttimebinning aliasName hmName
<dd>Writes the time binning at histogram memory hmName to file using
@ -128,5 +135,69 @@ attribute.
designated by targetAlias.
</dl>
</p>
<H1>Automatic Updating of NeXus Files</H1>
<P>
Some instruments perform measurements for quite long counting
times. In such cases it is advisable to save the data measured so far
to file in order to protect against hardware or software failures. To
this purpose an automatic file upgrade manager is provided. On
installation the automatic update object is connected wth a counting
device through the the callback interface. This makes sure that the
update manager is automatically notified when counting starts or
finishes.
</P>
<h2>Prerequisites for Using the Automatic Update Manager</h2>
<p>
In order to use automatic updating, three programs must be
provided. Each of these programs can be a script which uses the
nxscript facility. It can also be a SICS command.
<dl>
<dt>startScript
<dd>This program is supposed to write the static part of the file. It
is called once when the file is created.
<dt>updateScript
<dd>This program is supposed to create and update the variable data
elements in the NeXus file. This is called frequently.
<dt>linkScript
<dd>This program is supposed to create the links within the NeXus
file. This is called once after startscript and updateScript have been
run.
</dl>
</p>
<h2>Installing Automatic Update</h2>
<p>
An automatic update object is installed into SICS with:
<pre>
updatefactory name countername
</pre>
name is a placeholder for the name under which SICS knows the
automatic update object. name is available as a SICS command later on.
countername is a placeholder for a counter
object (counter or HM) which triggers automatic updating of NeXus
files. This object has to support both the countable and callback
interfaces of SICS. Suitable SICS objects include counter and
histogram memory objects.
</p>
<h2>Configuring Automatic Update</h2>
<p>
The SICS command created with updatefactory (see above) supports a few
parameters which allow for the configuration of the whole
process. Parameters follow the normal SICS syntax. Futhermore there is
a subcommand list, which lists all configuration
parameters. Supported parameters are:
<dl>
<dt>startScript
<dd>The program supposed to write the static part of the file.
<dt>updateScript
<dd>The program supposed to create and update the variable data
elements in the NeXus file.
<dt>linkScript
<dd>This program supposed to create the links within the NeXus
file.
<dt>updateintervall
<dd>The time intervall in seconds between updates. The defualt is
1200, eg. 20 minutes.
</dl>
</p>
</BODY>
</HTML>

View File

@ -47,7 +47,7 @@ stored. When this is properly defined Tcl will autoload commands.
<li> <b> statusfile </b> defines the file to which he current state will be
saved on close down of the server and restored from at startup time.
<li><b>TelnetPort</b> The port number where the SICS server will be
listening for telnet connections. If this option is missing login via telent
listening for telnet connections. If this option is missing login via telnet
to the SICS server is disabled.
<li><b>TelWord</b> In order to login to SICS via telnet a magic word is
needed. The login word, This option defines this word. If this option is

44
doc/manager/sans.htm Normal file
View File

@ -0,0 +1,44 @@
<HTML>
<HEAD>
<TITLE>SANS Special Commands</TITLE>
</HEAD>
<BODY>
<H1>SANS Special Commands</H1>
<P>
Some special initializations for SANS Instruments:
<dl>
<DT> MakeMulti name
<DD> SANS uses a special syntax feature where several motors are grouped into a
component group. For example beamstop or detector. MakeMulti creates such a
group with the name name. Once such a group has been created, it has to be
configured. For this a few configuration commands are available:
<DL>
<DT>name alias motname compname
<DD> This command makes motor motname available as component motor compname.
For example: <b>bs alias bsx x</b> makes motor bsx available as x in the beamstop
group. Then the bsx motor can be driven by the command <b>bx x = 12.</b>.
<DT> name pos posname motname value motname value ....
<DD> The group command supports the notion of named positions. This means that
a special combination of angles can be accessed through a name. This commands
defines such a named position with the name posname. posname is followed by pairs
of motorname value which define the position.
<DT>name endconfig
<DD>Once a group has been completely defined the configuration process must be
ended with endconfig.
</DL>
<DT>MakeSANSWave name velo_name
<DD>> Installs a velocity selector wavelength variable into SICS. The
variable will have the name given as first parameter. Usually lambda is a
good idea. The second parameter, velo_name, is the name of the velocity
selector which is controlled by this wavelength variable. This module contains
a hard coded formula which may only be applicable to the SANS at PSI.
<dt>MakePSDFrame
<dd>This installs a command into SICS which allows to retrieve a detector
image from the histogram memory, even in TOF-mode.
</dl>
Many other commands for controlling collimators, attenuators, beamstops
and shutters are implemented in Tcl. These commands use non standardizable
hardware such as the Siematic SPS.
</P>
</BODY>
</HTML>

11
doc/manager/scan.htm Normal file
View File

@ -0,0 +1,11 @@
<HTML>
<HEAD>
<TITLE>The SICS Scan System</TITLE>
</HEAD>
<BODY>
<H1>The SICS Scan System</H1>
<P>
</P>
</BODY>
</HTML>

4
doc/manager/scrap1.htm Normal file
View File

@ -0,0 +1,4 @@
<li> <b> MakeWaveLength nam mono </b> creates a wavelength variable nam.
The monochromator mono is used for adjustment.
<li> <b> MakeEnergy nam mono </b> creates a energy variable nam. The
monochromator mono is used for adjustment.

View File

@ -3,7 +3,7 @@
<TITLE>SICS Setup</TITLE>
</HEAD>
<BODY>
<H1>SICS programs, Scripts and Prerequisites<h1>
<H1>SICS programs, Scripts and Prerequisites</h1>
<p>
<h2>Hardware</h2>
The following hardware is usually present for any SICs instrument:
@ -17,7 +17,8 @@ The following hardware is usually present for any SICs instrument:
</ul>
The terminal server software is provided by Lantronix, see the
appropriate manuals for the device for a description. The histogram
memories are 68000 VME onboard computers running the VXworks realtime
memories are 68000 VME or MEN-A12 onboard computers
running the VXworks realtime
operating system and some home grown histogramming software documented
elsewhere.
</p>
@ -31,10 +32,10 @@ required:
communicating with serial ports. The actual communication with the
serial ports is done through the Lantronix terminal server. Both the
serial port protocoll and the SerPortServer are only documented in the
source code.
source code. The SerPortServer program is on its way out.
<dt>TecsServer
<dd>This is a TCP/IP server which watches over temperature
controllers. The only knwon source of documentation about this
controllers. The only known source of documentation about this
software is Markus Zolliker.
<dt>FileSync
<dd>This is a little UDP server which waits for UDP messages from the
@ -51,28 +52,6 @@ Additionally a client program is needed which connects to the
instrument control server and provides a user interface to it.
</p>
<h2>Scripts</h2>
<p>
To get all this software up and running a couple of shell scripts have
been provided:
<dl>
<dt>startsics
<dd> This script starts all the necessary server programs for driving
the instrument.
<dt>killsics
<dd>This script shuts down all instrument control servers properly.
<dt>keepalice, keepaliveserp
<dd>The server programs are automatically restarted when they
die. This is done through these scripts. keepaliveserp is a special
script for the serial port server.
<dt>instsync
<dd>replace inst by the name of the instrument in lower case. This
script is invoked by the FileSync server and is responsible for
synchronizing the local data store with the one on the labaratory
server. This is usally done by calling the unix program rsync with
appropriate parameters.
</dl>
</p>
<H1>General SICS Setup</H1>
<P>
@ -90,9 +69,10 @@ instrument. In the following text this instrument root directory will be called
sicsroot. This root directory has the following subdirectories:
<DL>
<DT>bin
<DD> The bin directory is the place where the actual executable for the SICS
server is kept along with local copies of all necessary clients, the server
initialisation files and special macro files defined for the instrument.
<DD> The directory where some executables live.
<dt>inst_sics
<dd>All instrument configuration files and the SICServer live in
this directory. Replace inst by the name of the instrument as appropriate.
<DT>data
<DD>The data directory is the central place where all data files collected
at the instrument are stored. This directory contains subdirectories
@ -110,81 +90,107 @@ initialization file.
generated client log files. Any now and then, and especially when disk space
problems loom, the client*.log files should be deleted by the instrument
manager.
<dt>lib
<dd>Contains some files needed for running SICS clients locally.
<DT> doc
<DD> This directory holds a copy of the SICS user documentation for the
instrument. These are html files which can be viewed with WWW-browsers such
as lynx or netscape.
<DT> sim
<DD> The sim directory is meant to hold all files necessary for a SICServer
initialised for the instrument but configured with simulated hardware. This
facility is meant for testing of command files.
<DT>motor
<DD>This directory holds a script for reading and restoring the motor
parameter from the EL734 motor controllers. And the motor parameters
stored in parameter files. It is the instrument scientists
responsability to save the motor parameters after changes to the
configuration of the instrument.
<DT>tmp
<DD> A directory for temporary and PID files.
<DT>help
<DD>A directory for help files for the help system.
</DL>
Besides these directories there should be nothing on the instrument account.
All evaluated data, personal command files etc. should be held on the normal
user account of the instrument user.
</p>
<h2>System Control</h2>
<p>
For this purpose the /data/lnslib/bin directory holds copies of the
apropriate command line and status display clients for each instrument. A user can make
this directory (and much more) available by including the line <b>
source /data/lnslib/bin/lns.login</b> into her .login file.
All commands listed in this section have to issued with the privilege of the
instrument user account.
</p>
<h2> SICS Installation</h2>
<p>
All executables and files necessary to run SICS for each instrument is
avaialable under the /data/lnslib/distribution/sics hierarchy.
The bin directory
holds general executable files and a directory for each instrument which
holds instrument specific files. SICS installation on a unix system is
greatly simplified by using the <b>sicsinstall</b> korn shell script. This
script is available to each user. sicsinstall can be invoked simply by
typing sicsinstall at the command prompt. sicsinstall needs a subcommand in
order to know what it is expected to do:
In order to watch over all these servers, the <a
href="http://www.tildeslash.com/monit">monit</a> software is used. This is
a program which watches server processes and restarts them as necessary.
Monit can also be used to watch over hardware and the file system. Monit
writes a log file and can trigger e-mail alerts on certain
problematic conditions.
</p>
<p>
Monit itself is controlled through a configuration file, .monitrc, which lives
in the instrument accounts home directory. Monit also uses another Tcl program runwithpid which is responsible for starting and stopping server programs.
In order to configure all this, there is another program: makemonit which
creates the monit configuration file and copies and edits the runwithpid
program. The syntax of makemonit is:
<dl>
<DT>dev
<DD>copies knew executables from the development area to the distribution
directory. This command is meant to be used by computing staff only.
<DT>devfull
<DD>as dev, but copies all files. This command is meant to be used by computing staff only.
<DT>dmc
<DD>copies all files necessary for the instrument DMC.
<DT>topsi
<DD>copies all files necessary for the instrument TOPSI.
<DT>sans
<DD>copies all files necessary for the instrument SANS.
<DT>hrpt
<DD>copies all files necessary for the instrument HRPT.
<DT>amor
<DD>copies all files necessary for the instrument AMOR
<DT>focus
<DD>copies all files necessary for the instrument FOCUS
<DT>tasp
<DD>copies all files necessary for the instrument TASP
<DT>druechal
<DD>copies all files necessary for the instrument DRUECHAL
<DT>trics
<DD>copies all files necessary for the instrument TRICS
<DT>save inst
<DD>copies all the instrument configuration files from the instrument
account back to to the distribution area. Replace inst with the name
of the instrument in lower case. This call is necessary to save
modified instrument configurations.
<DT>doc
<DD>updates only the documentation on your disk.
<DT>exe
<DD>copies only new executable files from the distribution area. This is the
recommended option when you want to be sure, that you have the latest
version of SICS before reporting a bug.
</dl>
Most of these options require you to be in the home directory of the
instrument account. sicsinstall checks for this and warns you if this is not
the case. Directory structures are checked for and created as needed.
<dt>makemonit instrument terminalserver data-mount-point hm1 hm2 ..
<dd>instrument is the instrument name in lowercase, terminalserver is the
name of the terminal server used for serial port access, data-mount-point is
the name of file system onto which the instruments data is written. This is
followed by a list of all the histogram memory computers used by the
instrument.
<dt>monitinit
<dd>monitinit is an alias which calls makemonit with all required parameters
for a given instrument in standard configuration.
</dl>
</p>
<p>
Monit itself can be controlled with the following commands:
<dl>
<dt>monit
<dd>Starts the monit daemon and all configured processes. This is only
necessary after a reboot of the system.
<dt>monit status
<dd>This shows a status message listing the status of all configured servers
and the checked hardware. The monit status is also available on the WWW from
http://lns00.psi.ch/monit/instrument. Replace instrument with the appropriate
instrument name.
<dt>monit stop target
<dd>Stops the server process target. The following targest exist:
<dl>
<dt>all
<dd>All processes
<dt>sicsserver
<dd>The SICS server
<dt>SerPortServer
<dd>The serial port server.
<dt>sync
<dd>The file synchronisation server.
<dt>tecs
<dd>The TecsServer for controlling environment devices.
<dt>simserver
<dd>A simulation server(not on all instruments).
</dl>
<dt>monit start target
<dd>Starts a server process, targest are the same as described above.
<dt>monit restart target
<dd>Stops and starts the process target. Targets are as listed above.
<dt>monit quit
<dd>Stops monit alltogether. Please note, that servers stay running with
this command. In order to sop everything the sequence: monit stop all;
monit quit is required.
<dt>startsics
<dd> This script starts all the necessary server programs for driving
the instrument through monit.
<dt>killsics
<dd>This script shuts down all instrument control servers properly through
monit.
<dt>instsync
<dd>replace inst by the name of the instrument in lower case. This
script is invoked by the FileSync server and is responsible for
synchronizing the local data store with the one on the labaratory
server. This is usally done by calling the unix program rsync with
appropriate parameters.
</dl>
</p>
</BODY>
</HTML>

37
doc/manager/tas.htm Normal file
View File

@ -0,0 +1,37 @@
<HTML>
<HEAD>
<TITLE>Triple Axis Spectrometer Specific Commands</TITLE>
</HEAD>
<BODY>
<H1>Triple Axis Spectrometer Specific Commands</H1>
<P>
One aim for the implementation of the triple axis spectrometer in SICS
was to implement as closely as possible the command set of the ILL program
MAD. For this, there are two implementations: an older one where
most things werde done in C-code. And a newer one which implements
a relaxter MAD emulation. The problem with the MAD emulation is that
MAD relies on the order of variables and motors in memory. The newer
MAD emulation obeys this only for the qh, qk, ql and en variables.
This section describes the newer more portable TAS setup. There are
some C-modules and a lots of scripts which implement the MAD emulation.
</P>
<p>
The TAS requires the following initializations in its instrument file:
<dl>
<dt>MakeTasUB tasub
<dd>Installs the TAS crystallographic calculation module into SICS. It will
have the name tasub (recommended).
<dt>MakeTasScan iscan tasub
<dd>Installs the module with the TAS specific scan functions into SICS. The
TAS implements its own data format resembling the ILL TAS data format.
</dl>
Moreover it is required to add the peak center module, drive, exe and a lot of
variables: polfile, alf1-4, bet1-4, ETAM ETAS ETAA.
</p>
<p>
The scripts for the MAD emulation live in the file tasubcom.tcl. This file
will need little editing in order to cope with another triple axis machine,
just a couple of path variables will need to be changed.
</p>
</BODY>
</HTML>

View File

@ -1,9 +1,9 @@
<HTML>
<HEAD>
<TITLE>The Tcl-interface to the SINQ histogram memory</TITLE>
<TITLE></TITLE>
</HEAD>
<BODY>
<H1>The Tcl-interface to The SINQ histogram memory</H1>
<H1></H1>
<P>
</P>

View File

@ -6,6 +6,12 @@
<h1>SICS Trouble Shooting </h1>
<hr size=4 width="66%">
<H2>Check Server Status</h2>
<p>
One of the first things to do is to check the server status with:
monit status.
</p>
<hr size=4 width="66%">
<H2>Inspecting Log Files</h2>
<p>
Suppose something went wrong over the weekend or during the night and
@ -29,6 +35,11 @@ stamps which allow to find out when exactly a problem began to
appear.
</p>
<p>
There is also another log file, log/monit.log, which logs messages from
the monit daemon. This can be used to determine when server processes
were restarted or when hardware failed.
</p>
<p>
Quite often the inspection of the log files will indicate problems
which are not software related such as:
<ul>
@ -42,178 +53,65 @@ released before the motors move again.
<h2>Restarting SICS</h2>
<hr size=4 width="66%">
<p>
There is no such thing as bug free software. There are always bugs, nasty
behaviour etc. This document shall help to solve these problems. The usual
symptom will be that a client cannot connect to the server or the server is
not responding.
</p>
<p>
An essential prerequisite of SICS is that the servers are up
and running. The system is configured to restart the SICServer whenever it
fails. Only after a reboot or when the keepalive processes were killed (see
below) the SICServer must be restarted. This is done for all instruments by
typing:
<pre>
startsics
</pre>
at the command prompt. startsics actually starts several programs, see
the Setup section for details. All programs are started by means of a
shell script called
<b>keepalive</b>. keepalive is basically an endless loop which calls
the program again and agaian and thus ensures that the program will
never stop running.
</p>
<p>
When the SICS server hangs, or you want to enforce an reinitialization of
everything the server process must be killed. This can be accomplished either manually or through a shell script.
</p>
<h2>Stopping SICS</h2>
<p>
All SICS processes can be stopped through the command:
<pre>
killsics
</pre>
given at the unix command line. You must be the instrument user
(for example DMC) on the instrument computer for this to work properly.
</p>
<h2>Finding the SICS server</h2>
<p>The first thing when killing the SICS server manually is to find the
server process.
Log in as Instrument user on the instrument computer (for instance DMC on
lnsa05). Type the command:
<pre>
/home/DMC> ps -A
</pre>
Note the capital A given as parameter. The reward will be listing like this:
<pre width =132>
PID TTY S TIME CMD
0 ?? R 01:56:28 [kernel idle]
1 ?? I 1:24.44 /sbin/init -a
3 ?? IW 0:00.20 /sbin/kloadsrv
24 ?? S 40:39.58 /sbin/update
97 ?? S 0:04.87 /usr/sbin/syslogd
99 ?? IW 0:00.03 /usr/sbin/binlogd
159 ?? S 1:43.70 /usr/sbin/routed -q
285 ?? S 1:00.45 /usr/sbin/portmap
293 ?? S 6:03.45 /usr/sbin/ypserv
299 ?? I 0:00.37 /usr/sbin/ypbind -s -S psunix,lnsa05.psi.ch
307 ?? I 0:00.52 /usr/sbin/mountd -i
309 ?? I 0:00.07 /usr/sbin/nfsd -t8 -u8
311 ?? I 0:00.09 /usr/sbin/nfsiod 7
317 ?? S 5:51.54 /usr/sbin/automount -f /etc/auto.master -M /psi
370 ?? I 0:28.58 -accepting connections (sendmail)
389 ?? S 1:41.15 /usr/sbin/xntpd -g -c /etc/ntp.conf
419 ?? S 6:00.16 /usr/sbin/snmpd
422 ?? S 1:00.91 /usr/sbin/os_mibs
438 ?? S 34:29.67 /usr/sbin/advfsd
449 ?? I 3:16.29 /usr/sbin/inetd
482 ?? IW 0:11.53 /usr/sbin/cron
510 ?? IW 0:00.02 /usr/lbin/lpd
525 ?? I 5:31.67 /usr/opt/psw/psw_agent -x/dev/null -f/usr/opt/psw/psw_agent.conf
532 ?? I 0:00.74 /usr/opt/psw/psw_sensor_syswd 1 -x/dev/null
555 ?? I 0:00.58 /usr/bin/nsrexecd
571 ?? I 0:20.27 /usr/dt/bin/dtlogin -daemon
583 ?? S 1:38.27 lpsbootd -F /etc/lpsodb -l 0 -x 1
585 ?? IW 0:00.04 /usr/sbin/getty /dev/lat/620 console vt100
586 ?? IW 0:00.03 /usr/sbin/getty /dev/lat/621 console vt100
587 ?? I 35:59.85 /usr/bin/X11/X :0 -auth /var/dt/authdir/authfiles/A:0-aaarBa
657 ?? I 0:01.46 rpc.ttdbserverd
4705 ?? IW 0:00.05 dtlogin -daemon
9127 ?? I 0:00.37 /usr/bin/X11/dxconsole -geometry 480x150-0-0 -daemon -nobuttons -verbose -notify -exitOnFail -nostdin -bg gray
9317 ?? IW 0:00.73 dtgreet -display :0
14412 ?? S 0:39.71 netscape
15524 ?? I 0:00.57 rpc.cmsd
21678 ?? S 0:00.11 telnetd
31912 ?? S 0:10.65 /home/DMC/bin/SICServer /home/DMC/bin/dmc.tcl
584 console IW + 0:00.21 /usr/sbin/getty console console vt100
21978 ttyp1 S 0:00.63 -tcsh (tcsh)
22269 ttyp1 R + 0:00.10 ps -A
</pre>
This is a listing of all running processes on the machine where this command
has been typed. Note, in this case, at the bottom in the line starting with
<tt> 31912 ?? </tt> an entry for the SICS server. In this example the server
is running. If the server is down, no such entry would be present.
</p>
<h2> Killing a hanging SICS server </h2>
<p>
Suppose, the situation is that the SICS server does not respond anymore. It
needs to be forcefully exited. Please note, that it is always better to
close the server via the <tt>Sics_Exitus</tt> command typed with manager
privilege in one of the command clients. In order to kill the server it is
needed to find him first using the scheme given above. The information
needed is the number given as first item in the same line where the server
is listed. In this case: <tt>31912</tt>. Please note, that this number will
always be different. The command to force the server to stop is:
<pre>
/home/DMC> kill -9 31912
</pre>
Note, the second parameter is the number found with <tt>ps -A</tt>. The
SICServer will be restarted automatically by the system. Occasionally, it
may happen, that you cannot connect to the SICS server after such an
operation. This is due to some network buffering problems. Doing the killing
again usually solves the problem.
</p>
<h2> Shutting The SICS Server Down Completely</h2>
<p>
This is done for you by the killsics shell script. Just type
<pre>
killsics
</pre>
at the unix command line. Here is what killsics does for you:
In order to completely shutdown the SICS server two process must be killed:
the actual SICS server and the process which automatically restarts the
SICServer. The latter must be killed first. It can be found in the ps -A
listing as a line reading <b>keepalive SICServer </b>. Kill that one as
described above, then kill the SICServer. For restarting SICS after this,
use the startsics command.
<dl>
<dt>monit restart sicsserver
</dl>
</p>
<hr size=4 width="66%">
<h2>Restart Everything</h2>
<p>
If nothing seems to work any more, no connections can be obtained etc, then
the next guess is to restart everything. This is especially necessary if
mechanics or electronics people were closer to the instrument then 400 meters.
<OL>
mechanics or electronics people were closer to the instrument then a
nautical mile.
<uL>
<LI> Reboot the histogram memory. It has a tiny button labelled RST. That' s
the one. Can be operated with a hairpin, a ball point pen or the like.
<LI> Restart the SICServer. Watch for any messages about things not being
connected or configured.
<LI> Restart and reconnect the client programs.
</OL>
If this fails (even after a second) time there may be a network problem which
can not be resolved by simple means.
<li>Restart all of SICS with the sequence: monit stop all; monit quit; monit
<li>Wait for a couple of minutes for the system to come up.
</ul>
</p>
<h2>Getting New SICS Software</h2>
<hr size=4 width="66%">
<h2>Starting SICS Manually</h2>
<p>
Sometimes you might want to be sure that you have the latest SICS software.
This is how to get it:
<ol>
<li>Login to the instrument account.
<li>If you are no there type cd to get into the home directory.
<li>Type <b>killsics</b> at the unix prompt in order to stop the SICS server.
<li>Type <b>sicsinstall exe</b> at the unix prompt for copying new
SICS software from the general distribution area.
<li>Type <b> startsics</b> to restart the SICS software.
</ol>
In order to find out if some hardware is broken or if the SICS server
initializes badly it is useful to look at the SICS servers startup messages.
The following steps are required:
<ul>
<li>monit stop sicsserver
<li>cd ~/inst_sics
<li>./SICServer inst.tcl | more
</ul>
Replace inst by the name of the instrument, as usual. Look at the screen
output in
order to find out why SICS does not initialize things or where the
initialization hangs. Do not forget to kill the SICServer thus started when
you are done and to issue the command: <b>monit start sicsserver</b> in order
to place the SICS server back under monits control again.
</p>
<h2>Hot Fixes</h2>
<hr size=4 width="66%">
<h2>Test the SerPortServer Program</h2>
<p>
When there is trouble with SICS you may be asked by one of the SICS
programmers to copy the most recent development reason of the SICS server
to your machine. This is done as follows:
<ol>
<li>Login to the instrument account.
<li>cd into the bin directory, for example: /home/DMC/bin.
<li>Type <b> killsics</b> at the unix prompt in order to stop the SICS server.
<li>Type <b>cp /data/koenneck/src/sics/SICServer .</b> at the unix prompt.
<li>Type <b> startsics</b> to restart the SICS software.
</ol>
<b>!!!!!! WARNING !!!!!!!. Do this only when advised to do so by a competent
SICS programmer. Otherwise you might be copying a SICS server in an
instable experimental state!</b>
Sometimes the SerPortServer program hangs and inhibits the communication with
the RS-232 hardware. This can be diagnosed by the following procedure: Find
out at which port either a EL734 motor controller or a E737 counter box
lives. Then type:<b>asyncom localhost 4000 portnumber</b> This yields a
new prompt at which you type <b>ID</b>. If all is well a string identifying
the device will be printed. If not a large stack dump will come up.
The asyncom program can be exited by typing <b>quit</b>. If there is
a problem with the
SerPortServer program type: <b>monit restart SerPortServer</b> in order to
restart it.
</p>
<hr size=4 width="66%">
<h2>Trouble with Environment Devices</h2>
<p>
The first stop for trouble with temperature or other environment devices
is Markus Zolliker. A common problem is that old environment controllers
have not be deconfigured from the system and still reserve terminal server
ports. Thus take care to deconfigure your old devices when swapping.
</p>
<hr size=4 width="66%">
<h2> HELP debugging!!!!</h2>
<p>
The SICS server hanging or crashing should not happen. In order to sort such

View File

@ -12,12 +12,6 @@ from the user, which should go into data files. Such information is kept in
SICS variables, created with the command VarMake detailed below.
</p>
<p>
Another usage for variables is to control composite movements of instrument
components. For instance for changing the wavelength it is necessary to
drive at least two motors, Theta and TwoTheta. Such behaviour is implemented
with some SICS special variables. Their creation is described below.
</p>
<p>
Variables are also used in order to control the SINQ automatic file name
creation scheme for data files. At SINQ, data files are put into a special
directory. The actual name consists of a prefix, a sequential number, the
@ -31,19 +25,6 @@ The exact syntax for creating variables looks like this:
variable type can be Text, Int or Float. The access parameter defines who
may may change the variable. Possible values are: Internal, Manager, User
and Spy.
<li> <b> MakeWaveLength nam mono </b> creates a wavelength variable nam.
The monochromator mono is used for adjustment.
<li> <b> MakeEnergy nam mono </b> creates a energy variable nam. The
monochromator mono is used for adjustment.
<li> <b> MakeO2T nam OM 2TM </b> creates an omega 2Theta dummy variable
with name nam for omega 2Theta scans. OM defines an omega motor, 2TM a two
theta motor.
<li><b>MakeDataNumber SicsDataNumber filename</b> This command makes a
variable SicsDataNumber available which holds the current sequential data
file number. filename is the complete path to the file were this data
number is stored. This file should never, ever be edited without good
reason, i.e. resetting the sequential number to 0 at the beginning of a
year.
</ul>
</p>
<p>

View File

@ -28,25 +28,33 @@ Author: Mark K\"onnecke
This document gives an overview about all the hardware and software systems
involved in SINQ instrument control. It describes the relationships between
the various pieces and points to additional documentation, if available.
A copy of all documents referred in this paper is stored at: /data/lnslib/distribution/sics/doclib. If they exist in electronic form, this is. The SICS user
and manager information is available on the WWW starting from http://lns00.psi.ch/.
A copy of all documents referred in this paper is stored at:
/afs/psi.ch/project/sinq/commmon/share/sicsdoc.
If they exist in electronic form, this is. The SICS user
and manager information is available on the WWW starting from
http://lns00.psi.ch/.
\section{Hardware Overview}
For each SINQ instrument the following computing hardware is available:
\begin{itemize}
\item A dedicated instrument workstation. Most of them are Compaq Alpha stations
running True64Unix. One workstation is still running OpenVMS. Two instruments,
POLDI and RITA--2, are controlled through Intel--PC's running Linux.
\item A dedicated instrument workstation. Most of them are Intel x86
machines running Linux. Three instruments use alpha workstations
running Tru64Unix.
\item A TCP/IP terminal server providing access to serial ports.
\item Optionally, there are 1-3 histogram memory computers installed for those
instruments which have area detectors. These histogram memory computers are
Motorolla 6800 VME board processors running the vxWorks realtime
operating system.
operating system. Two types of boards are in use: the older Motorolla
MVME1603 boards with 16 MB of memory and MEN-A12 boards with 512MB
memory.
\item Optionally there are National Instruments ENET-100 GPIB/TCPIP
converters in use in order to access GPIB devices, especially those
which came with the Risoe instruments.
\end{itemize}
Most instrument hardware is accessed through RS--232 interfaces and the terminal
server. Histogram memories are accessed through the TCP/IP network. Generally
ethernet is used as the main instrument bus.
Most instrument hardware is accessed through RS--232 interfaces and
the terminal server. Histogram memories are accessed through the
TCP/IP network . Generally ethernet is used as the main instrument bus.
In addition to the computers at the instrument the following systems are
available:
@ -54,8 +62,9 @@ In addition to the computers at the instrument the following systems are
\item A True64Unix laboratory server (lnsa15) for data management and
primary data anlalysis.
\item True64Unix PSI server systems for data processing.
\item A dual processor linux science server (lnsl15).
\item The PSI Linux Login cluster (llc)
\item A WWW--server currently installed on lns00.
\item pss123 is a Sun workstation holding the vxWorks development environment.
\end{itemize}
\section{Software Overview}
@ -75,7 +84,8 @@ The main software component at the instrument is the Sinq Instrument Control
debugging. Clients to this SerPortServer such as the SICS server communicate
with the server through a special ASCII protocoll transported through TCP/IP.
The only documentation
for both the SerPortServer and the ASCII protocoll is the source code.
for both the SerPortServer and the ASCII protocoll is the source
code. And David Maden.
There exists another support program, the FileSync server, on any instrument
computer. This is a little Java server which listens at a UDP port for a
@ -88,8 +98,8 @@ Then there is the TecsServer. This is a server which maintains and configures
Lakeshore temperature controllers used as standard temperature controllers
at SINQ. The only documentation for this program is Markus Zolliker.
On many instruments there are histogram memory computers. These usually run the
following programs:
On many instruments there are histogram memory computers. These
usually run the following programs:
\begin{description}
\item[bootUtil] a utility running when the histogram memory is booted which
starts all the other tasks and configures the histogram memory from its
@ -114,30 +124,22 @@ The SICS software is described in a variety of documentation:
described in the "SICS Manager Manual".
\item The programming concepts of SICS are discussed in the "SICS Programmers
Reference".
\item An 90\% complete description of SICS source code modules is available
\item An 97\% complete description of SICS source code modules is available
as "SICS Reference Manual".
\end{itemize}
One instrument, TASP, is run with the TASMAD software from ILL which runs
on VMS systems. A user documentation for this system is available at: \newline
\centerline{http://sinq.web.psi.ch/sinq/doc/tasmad.html}
Some configuration issues are explained in this docuement as well. Further
documentation exists only in form of David Maden and an analysis of the
source code.
The RITA--2 instrument from Ris\o{ } runs the TASCOM software.
This software is quite well documented in various documents which can be
obtained at WHGA/247 or directly from the Ris\o{ } team and Per Skarup.
obtained at WHGA/112 or directly from the Ris\o{ } team and Per Skarup.
\subsection{Facilities at the Laboratory Server(LNSA15)}
\subsection{Central Facilities}
\subsubsection{Central Data Repository}
Under the /data/lnslib/data directory there exists a central storage area for
Under the /afs/psi.ch/project/sinqdata directory there exists a
central storage area for
data files measured at the instruments. Newly measured data files are
automatically mirrored to this area once a measurement has finished.
Not surprisingly there is a subdirectory for each instrument at SINQ.
These instrument directories contain further subdirectories for each year
of SINQ operation which hold the actual data files.
There are directories for each year of SINQ operation. These contain
subdirectories for the various instruments.
\subsubsection{The SINQ File Database}
Right early on it was decided to separate the file archival function from the
@ -155,20 +157,15 @@ which is part of the source distribution for the system. Here only an
The SINQ File Database consists of the following components:
\begin{itemize}
\item The database itself. This is the SQL database system mSQL from
Hughes Technology.
\item Any night the unix utility cron starts a shell script which is
responsible for updating the database. This is done with two special
utility programs:
\begin{itemize}
\item nx\_dbupdate scans a given directory for new files which are not
yet in the database. If such a file is found, the data fields for the
database are extracted and entered into the database.
\item The Java program ScanScan does the same job as nx\_dbupdate for
ASCII files.
\end{itemize}
\item The database itself. The database is installed on the central
database server PSIP0 provided by central computing. The database
software is oracle.
\item Any night a database update program is started as a cron
job. This programs runs on the linux server lnsl15. The program
itself is a tcl script which uses oratcl for accessing the Oracle
database server and nxinter for accessing NeXus files.
\item A querying system. Curently the only query interface is a WWW--interface
installed at the WWW--server.
installed at the WWW--server lns00.
\end{itemize}
@ -189,28 +186,19 @@ This document also explains how to get hold the source code for most
of the software used at SINQ.
\subsubsection{Backup}
The laboratory server is also the central backup server for SINQ. Backups are
performed with the Legato networker software onto a tape jukebox holding
5 tapes with 20GB capacity each. Currently only the /home (holding
user home directories) and the /lnsarchive hierarchy are backed up.
This backup system is a protection against a major harddisk failure. It is no
archive system. Though backup tapes are held as long as possible it
cannot be guaranteed that files older then half a year can be recovered.
The backup software is described in the documentation coming with the
system. No further documentation exists, but the setup can be viewed
through the nwadmin application.
Most user files and the raw data is stored within the AFS network file
system. These files are backed up by central computing. Data files of
older years are additionally archived in the PSI archive system.
The instrument accounts on the instrument computers must be backed up
as well because they sometimes contain valuable scripts. Unfortunately
there are not enough Networker licenses to go round and there is no
reliable linux client software for our version of Legato Networker.
Therefore the data in the instrument accounts is copied nightly to a
special account on lnsa15 which is subjected to the normal
backup. More details:
The instrument and guest accounts on the instrument computers should
be backed up
too because they sometimes contain valuable scripts. These are local
accounts, thus they are not covered through the AFS backup. Data from
these accounts is synchronized nightly onto a special account on the
linux server lnsl15.
\begin{itemize}
\item There is a script which does the copying. It is {\bf backupinst}
in either /data/lnslib/bin or
/afs/.psi.ch/project/sinq/linux/bin. This script is called with {\bf
in /afs/.psi.ch/project/sinq/linux/bin. This script is called with {\bf
backupinst INST} where INST must be replaced by the instrument name in
capitals. This script essentially calls rsync with appropriate
arguments to synchronize the instrument account minus the data
@ -221,8 +209,8 @@ instrument computer must have an entry in crontab reading like:
0 3 * * * /data/lnslib/bin/backupinst TOPSI >/tmp/topsi.log 2>&1
\end{verbatim}
Please replace paths and instrument names to match the instrument.
\item The backup account on lnsa15 is named SINQINST, password:
333SINQINST555. It contains a directory for each supported
\item The backup account on lnsl15 is named SINQINST, password:
SINQINSTLNS. It contains a directory for each supported
instruments. For backupinst to work properly there must be a line in
the .rhosts file of this account for each instrument computer which
reads:
@ -237,16 +225,12 @@ linux instrument computers, not the DNS alias.
At SINQ the PSI EL--734 motor controllers are used. These motor controllers
hold a set of parameters for each motor. As a safeguard against instrument
scientists gone wild or a loss of parameters due some electronic or
electrical incident these motor parameters are saved weekly. This happens
on wednesdays mornings. The unix utility crom triggers the process and
starts the script savemot which in turn does all necessary things. The
actual saving of the motor parameters is accomplished with David Maden's
el734 program. The saved parameters end up in the /data/lnslib/motors
hierarchy. There exists a directory for each backup date which in turn
holds a subdirectory for each instrument which holds the files with
the saved parameters. All necessary shell scripts and programs can be
found in the /data/lnslib/motors/bin directory.
electrical incident these motor parameters should be saved
regularly. To this purpose there exits motor subdirectories in each
instrument account. Motors are either saved into this directory
through a script in this directory or from SICS (TASP,
MORPHEUS). Motor parameter backup is a responsability of the
instrument scientists and must be triggered manually.
\subsubsection{License Server}
Unfortunately some people use the proprietary IDL programming system. This
@ -275,19 +259,18 @@ Unfortunately some people use the proprietary IDL programming system. This
\subsection{Software at the WWW--server}
The WWW--server running at lns00 does not provide static information only but also
active content calculated at runtime. The following services are
implemented:
The WWW--server running at lns00 does not provide static information
only but also active content calculated at runtime. The following
services are implemented:
\begin{itemize}
\item Keyword search in the SICS documentation.
\item Searching the SINQ file database for files matching various criteria.
\item Display of the current instrument status for a couple of instruments.
\item Display of the current instrument status for most instruments.
\item An experimental WWW control system for powder diffractometers.
\end{itemize}
Most of these services are provided through java servlets. In order to do this
a servlet engine was needed. The combination Apache WWW-server and Apache
JServ was choosen. However, it is planned to exchange the latter component
by the Jakarta engine in the near future.
Jakarta Tomcat was choosen.
The database search servlets are described in more detail in the document:
\newline \centerline{The SINQ File Database}
@ -299,8 +282,7 @@ The SICS documentation searching system is built on top of the program SWISH-E w
from http://sunsite.berkeley.edu/SWISH-E.
The actual search is performed through a TCL--cgi script which calls the swishe
application with appropriate parameters. This script can be found as
swishsearch.cgi together with a batch file to start it properly
(swishsearch.bat) in the cgi-bin directory of the WWW hierarchy on lns00.
swishsearch.cgi in the cgi-bin directory of the WWW hierarchy on lns00.
Prerequisite for such a search is the existence of an index file. This must
be created offline after any major change to the documentation. In order to
create this index, cd into the sics directory of the WWW hierarchy and run:
@ -321,12 +303,12 @@ In order to understand the system better it is useful to look at the flow
\begin{enumerate}
\item Data Files are generated by the instrument control programs at the
instrument computer.
\item Data Files are automatically mirrored to the central repository
on the laboratory server lnsa15. This happens through the FileSync server,
a shell script and last not least the unix rsync utility. All this is installed
at the instrument computer.
\item Data Files are automatically mirrored to the central AFS
repository. This happens through the FileSync server,
a shell script and last not least the unix rsync utility. All this is
installed at the instrument computer.
\item Nightly new files are scanned for relevant information and their
characteristics are entered into the database system on lnsa15.
characteristics are entered into the database system from lnsl15.
\end{enumerate}
@ -341,7 +323,7 @@ The SICS Java clients access the SICS servers on the selected instruments
laboratory server lnsa15.
\subsection{WWW Services}
The file search service on the WWW--server lns00 accesses the database
server running on the laboratory server lnsa15.
server PSIP0.
The instrument status display servlets on the WWW--server lns00 access the
SICS instrument control servers on the appropriate instrument computers
@ -349,9 +331,6 @@ The instrument status display servlets on the WWW--server lns00 access the
\section{Maintainance Tasks}
\subsection{Yearly Maintainance}
The only maintainance task at SINQ shutdown is to disable the cron job on
lnsa15 which performs the motor parameter backup.
Whith each new year a couple of things must be done in order to keep the
system ship shape:
@ -369,13 +348,10 @@ Whith each new year a couple of things must be done in order to keep the
\end{itemize}
\item On the laboratory server lnsa15:
\begin{itemize}
\item Reenable the motor parameter backup cron job.
\item Create new subdirectories for the new year in the data hierarchy.
\item In /data/lnslib/lib/nxdb create new configuration files for the new
year. Edit them to point to the new years subdirectory. Edit the
updatenxdb shell script to use the newly created configuration files.
Keep the old ones as they may come in handy if the whole database may
require an update.
\item Create a new year hierarchy for the new year.
\item Store the old years data into the PSI archive.
\item Move the old years data into the non backed up AFS area.
\item Make the new year the backed up data on AFS.
\end{itemize}
\item On the WWW--server lns00:
\begin{itemize}
@ -391,10 +367,14 @@ Do these things quite early on in the year. People start measuring background
In order to keep up with ageing 1-2 computers have to be exchanged any year.
A instrument computer change requires the following adaptions:
\begin{enumerate}
\item Start with a PC with the PSI Linux distribution installed.
\item Create two local user accounts: INST and instlnsg.
\item Copy the SICS software to the instrument computer.
\item Edit the instrument configuration file and change all occurences of
the old computers name to the new name.
\item On lnsa15 as user lnslib: enter the new computer name into the
.rhosts file. This is required for the mirroring to work.
\item Install the cron job for backing up the local instrument
accounts.
\item Make an entry in the .rhosts file of the SINQINST account on lnsl15.
\item For the Java clients edit lnet/SINQConfig.java to point to the
new computer and rebuild all clients. Redistribute them as well.
\item For the WWW status, adapt the sics.conf file on lns00 and restart

77
doc/user/Conescan.html Normal file
View File

@ -0,0 +1,77 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html><head><title>Conescan.radi</title></head><body>
<h2>Conescan </h2>
<p>A conescan is a possibly useful procedure when setting up a single crystal
diffraction experiment. The first thing which needs to be done when
starting a single crystal experiment is the determination of the UB
matrix. In order to do that at least two reflections need to be
located through a search procedure. Now, consider the situation when
one reflection has been found and indexed. Then it is known that other
reflections can be found on a cone
with an opening angle determined by the lattice parameters and the
indices of the target reflection around the first (center)
reflection. The SICS conescan module allows to do just that, do a scan
around a given center reflection. The syntax is:
</p></p><dl><dt>conescan list
<dd> lists all the parameters of the conescan
<dt>conescan cell
<dd> prints the cell constants.
<dt>conescan cell a b c alpha beta gamma
<dd> sets new cell constants.
<dt>conescan center
<dd> prints the current values for the center reflection
<dt>conescan center h k l
<dd> uses h, k, l as the indices of the center
reflection. Motor positions are read from motors.
<dt>conescan center h k l stt om chi phi
<dd> defines a center position
complete with all angles.
<dt>conescan target
<dd> prints the current target for the conescan
<dt>conescan target h k l
<dd> defines the target indices for the conescan.
<dt>conescan qscale
<dd> prints the Q scale for the conescan. The conescan
module calculates the length of then scattering vector from the
lattice parameters and the indices. When the lattice constants are
only approximatly known it might be useful to vary the scattering
vector length for the conescan a little. This can be doen with the
qscale factor.
<dt>conescan qscale value
<dd> sets a new value for the qscale factor
<dt>conescan run step mode preset
<dd> starts a conescan with the nstep width
step, the couent mode mode and the preset preset.
<dt>conescan run
<dd> starts a conescan with defaults: step = .5,
mode = monitor, preset = 10000
<p></dl>This is the simple usage of the conescan. In fact cone is implemented
as a virtual motor. This means that arbitray scans can be performed on
cone as with any other motor. As with any other motor, cone can also
be driven to a cone angle.
</p></p><h3>Implementation Reference </h3>
<p>The conescan commands are just wrapper routines around the cone and
ubcalc module which actually work together to implement the
conescan. The ubcalc module, documented elsewhere, holds the cell
constants and the center reflection.
</p></p><p>The cone module does the actual cone calculation. Cone can be
configured with commands:
<dl></p><dt>cone center
<dd> prints the number of the reflection in ubcalc to use as
a center.
<dt>cone center num
<dd> sets the reflection in ubcalc to use a the center
for driving on the cone. Set to 0 to use the first reflection in
ubcalc.
<dt>cone target
<dd> prints the target reflection indices for the cone.
<dt>cone target h k l
<dd> sets the target reflection indices.
<dt>cone qscale
<dd> prints the current value of the scattering vector scale.
<dt>cone qscale val
<dd> sets a value for the scaling factor for the
scattering vector. Values should be close to 1.0;
</dl></body></html>

View File

@ -4,7 +4,7 @@
# Mark Koennecke, Juli 1998
#------------------------------------------------------------------------
all: topsi dmc sans focus poldi
all: topsi dmc sans focus poldi tricsman userrefman
topsi:
html2tex topman
@ -30,4 +30,20 @@ poldi:
html2tex poldiman
latex poldiman
latex poldiman
dvips -o poldiman.ps poldiman.dvi
dvips -o poldiman.ps poldiman.dvi
poldi:
html2tex poldiman
latex poldiman
latex poldiman
dvips -o poldiman.ps poldiman.dvi
tricsman:
html2tex tricsman
latex tricsman
latex tricsman
dvips -o tricsman.ps tricsman.dvi
userrefman:
html2tex userrefman
latex userrefman
latex userrefman
dvips -o userrefman.ps userrefman.dvi

104
doc/user/amor.htm Normal file
View File

@ -0,0 +1,104 @@
<HTML>
<HEAD>
<TITLE>AMOR Reference Manual</TITLE>
</HEAD>
<BODY>
<!latex-off>
<H1>AMOR Reference Manual</H1>
<!latex-on>
<P>
Welcome to the reflectometer AMOR at SINQ! This manual describes how
to operate AMOR through the SICS instrument control software.
SICS means: Sinq Instrument Control System. AMOR can be operated in
one out of two modes:
<ul>
<li>Single Counter Mode. In this mode normal scans are performed with
a single counter.
<li>Time-Of-Flight Mode. In this mode the position sensitive detector
is operated in time of flight mode with a chopper providing the time
structure of the neutron beam.
</ul>
</p>
<h1>SICS Introduction</h1>
<p>
SICS is a client server system. This means there is a magic server
program running on the instrument computer which does all the work.
The user interacts with SICS
only with client applications which communicate with the server
through the network. Most instrument hardware (motor controllers,
counter boxes etc.) is connected to the system through RS-232 serial
connections. These RS-232 ports are connected to a terminal server
which is accessed through another server program, the SerPortServer
program, which is also running on the instrument computer. Then there
is the position sensitive detector. Neutrons collected in the PSD are
formatted into a special message format by the elctronics and
forwarded through a fibre optic link to the histogram memory
computer. This is a VME Motorola on board computer which then is
responsible for summing the neutrons events appropriatetly. The on
board computer is connected to the TCP/IP network and acts as a
server as well which handles the configuration and readout of the
histogram memory.
The SICS server communicates with this terminal server and other
devices through the network.
</P>
<!latex-off>
<h1>Starting and Stopping</h1>
<ul>
<li><a href="sicsinvoc.htm">Logging</a> in to SICS.
<li>The <a href="amorcli.htm">AMOR client</a> program.
</ul>
<h1>General User Commands</h1>
<p>
<ul>
<li><a href="drive.htm">Driving</a> motors.
<li><a href="amomot.htm">List</a> of AMOR motors.
<li><a href="amor2t.htm">AMOR Two Theta</a> virtual motor.
<li><a href="logging.htm">Logging</a> actions.
<li><a href="batch.htm">Batch</a> processing.
<li><a href="token.htm">Grabbing control</a>.
<li><a href="amomisc.htm#shutter">Shutter</a> control.
</UL>
</p>
<h1>AMOR in Single Counter Mode</h1>
<p>
<ul>
<li>Some <a href="amorsingle.htm">general</a> remarks.
<li>Doing a <a href="topscan.htm">scan</a>.
</ul>
</p>
<h1>AMOR in Time-Of-Flight Mode</h1>
<p>
<ul>
<li>General <a href="amortof.htm">Remarks</a>.
<li>Configuring the <a href="amortof.htm#conf">histogram memory</a>.
<li>Configuring <a href="amortof.htm#chop"> chopper</a> related
parameters.
<li><a href="count.htm">Counting</a>.
<li><a href="amorstore.htm">Data Storage</a>
</ul>
</p>
<h1>Advanced Topics</h1>
<p>
<UL>
<li>Handling <a href="samenv.htm">sample environment</a> devices in SICS.
<li>Configuring <a href="histogram.htm">histogram memory</a>
<li><a href="motor.htm">Motor Parameters</a>.
<li>Dealing with the <a href="counter.htm">counter box</a>.
<li>Directly access a <a href="ctrl.htm">serial device.</a>
<li>SICS <a href="system.htm">system commands</a>.
<li>Configuring a <a href="config.htm">client connection</a> manually.
<li><a href="trouble.htm">Trouble</a> shooting.
</UL>
</p>
<h1>Download Manual</h1>
<ul>
<li><a href="amorman.ps">Postscript Format</a>,246KB
</ul>
<!latex-on>
</BODY>
</HTML>

View File

@ -46,6 +46,7 @@ Switzerland\\
%html commandlog.htm 3
%html batch.htm 2
%html macro.htm 3
%html exeman.htm 3
%html buffer.htm 3
%html token.htm 2
%html amomisc.htm 2

View File

@ -34,8 +34,6 @@ interrogated by typing the name of the variable, and set by typing the
name of the variable followed by the new value. The following
variables are relevant:
<dl>
<dt>chopperrotation
<dd>Chopper Rotation speed.
<dt>user
<dd>User name
<dt>email

22
doc/user/auto.htm Normal file
View File

@ -0,0 +1,22 @@
<HTML>
<HEAD>
<TITLE>TRICS Data Analysis with Autocloud</TITLE>
</HEAD>
<BODY>
<H1>TRICS Data Analysis with Autocloud</H1>
<P>
Autcloud is an experimental software which integrates reflections from a
3D data volume without any prior information. Reflections are located
through a template matching approach in 3D. Template Matching is a common
digital signal processing method for enhancing a signal against a
background. This program may still contain very major algorithmical
and programming errors as it could not yet be tested against real data.
Data Analysis with autocloud requires two steps:
<ul>
<li>Reflection <a href="autocloud.htm"> integration </a> with autocloud.
<li>Indexing of the reflections found. This can be done with the program
<b>orient</b>. Just select data type 3 and answer the questions asked.
</ul>
</P>
</BODY>
</HTML>

31
doc/user/autosms.htm Normal file
View File

@ -0,0 +1,31 @@
<HTML>
<HEAD>
<TITLE>Automatic SMS Notification</TITLE>
</HEAD>
<BODY>
<H1>Automatic SMS Notification</H1>
<P>
On some instruments an automatic notification system is installed which
can be configured to send an SMS when the instrument is stopped. An
instrument is considered stopped when there has been no counting or driving
activity for a configurable amount of time and there is beam at SINQ. This
system can be controlled with the follwoing commands:
<dl>
<dt>autosms
<dd>Shows if the autosms system is enabled or disabled
<dt>autosms on | off
<dd>Switches automatic notfications on or off.
<dt>autosms number [val]
<dd>Without a parameter, displays the telphone number for the SMS, with a parameter
configures the telephone number. Telephone numbers must be all numbers without
hyphens or anything else.
<dt>autosms maxidle [val]
<dd>Without a parameter, queries the idle time before a SMS is sent. With a
parameter sets a new value for the inactivity period which triggers a message.
</dl>
Please use the configurable settle time with environment controllers such as
temperature controllers in order to avoid false messages while waiting for the
temperature to settle.
</P>
</BODY>
</HTML>

View File

@ -42,13 +42,16 @@ operation. The general syntax for handling such parameters is:
<pre>
objectname parametername
</pre>
prints the current value of the parameter
</p>
prints the current value of the parameter
<pre>
objectname parametername newvalue
</pre>
sets the parameter value to newvalue if you are properly authorized.
</p>
<h3>SICS variables</h3>
<p>
Most of the parameters SICS uses are hidden in the objects to which they belong. But some are separate objects of their own right and are accessible at top level. For instance things like Title or wavelength. They share a common syntax for changing and requesting their values. This is very simple: The command <i> objectname </i> will return the value, the command <i> objectname newvalue </i> will change the variable. But only if the authorisation codes match. </p>
<p>
<h3>Authorisation</h3>
<p>
A client server system is potentially open to unauthorised hackers
@ -60,25 +63,8 @@ sets the parameter value to newvalue if you are properly authorized.
<li> <b> Manager </b> has the permission to mess with almost everything. A very dangerous person.
<li> <b> Internal </b> is not accessible to the outside world and is used to circumvent protection for internal uses. However some parameters are considered to be so critical that they cannot be changed during the runtime of the SICS-server, not even by Managers.
</ul>
All this is stated here in order to explain the common error message: You are not authorised to do that and that or something along these lines.</p>
<h3>SICS variables</h3>
<p>
Most of the parameters SICS uses are hidden in the objects to which they belong. But some are separate objects of their own right and are accessible at top level. For instance things like Title or wavelength. They share a common syntax for changing and requesting their values. This is very simple: The command <i> objectname </i> will return the value, the command <i> objectname newvalue </i> will change the variable. But only if the authorisation codes match. </p>
<p>
<h3>The SICS Command Line Client</h3>
The most common client for controlling SICS is the <b>SICS command line
client</b>.
This application can be started by typing the command:
<pre>
sics &
</pre>
at the Unix prompt. Before this program is ready to collaborate with you you
have to connect it to an instrument using the options in the connect
pulldown menu. The screen is roughly divided in three areas: The top area
shows all input to and output from the server. The middle area shows the
command history. At the lower end is a text entry field which allows you to type
commands to be sent to the SICS server. For more information about this client consult
the online help of this application.
</p>
All this is stated here in order to explain the common error message:
You are not authorised to do that and that or something along these
lines.</p>
</body>
</html>

View File

@ -13,6 +13,8 @@ sleep. SICS supports two different ways of doing this:
popular scripting language Tcl. The most primitive usage of this
facility is processing batch files.
<li>Second there is the <a href="buffer.htm">LNS R&#252;nbuffer</a> system.
<li>Third there is the new <a href="exeman.htm">Batch File</a> execution
system.
</ul>
</P>
</BODY>

View File

@ -5,8 +5,8 @@
<BODY>
<H1>Chopper Control</H1>
<P>
FOCUS is equipped with a Dornier Chopper system running two choppers:
a disk chopper and a fermi chopper. In most situations the diskchopper is
Some instruments are equipped with a Dornier Chopper system running one or more choppers:
a disk chopper and possibly a fermi chopper. In most situations the diskchopper is
in slave mode. This means his speed is a predefined ratio of the
speed of the fermichopper. Furthermore, there is a phase difference between
the two choppers in order to allow for the fligh time of neutrons
@ -41,7 +41,7 @@ The following virtual motor variables exist for the chopper system.
<dL>
<DT>fermispeed
<DD>fermi chopper speed
<DT>diskspeed
<DT>diskspeed or chopperspeed
<DD>disk chopper speed. Note, that driving this parameter while the
chopper system is in synchronous mode will throw an error condition.
<DT>phase

View File

@ -40,6 +40,12 @@ filename in unix.
<li><b> config close num</b> closes the log file denoted by num again.
<li><b>config list</b> lists the currently active values for outcode and user
rights.
<li><b>config myname</b> retruns the name of the connection.
<li><b>config myrights</b> prints the rights associated with your connection.
<li><b>config listen 0 or 1</b>switches listening to the commandlog on
or off for this conenction. If this on, all output to the commandlog,
i.e. all interesting things happening in SICS, is printed to your
connection as well.
</ul>
<p>
</body>

View File

@ -15,6 +15,6 @@
<DD> Calls count num times. num is a required parameter. The other two are
optional and are handled as described above for count.
</dl>
Both commands make sure, that measured data is written to files.
Both commands make sure that measured data is written to files.
</body>
</html>

View File

@ -51,6 +51,7 @@ adjusted to any value within its wavelength range.
%html system.htm 1
%html config.htm 1
%html macro.htm 1
%html exeman.htm 2
%html buffer.htm 1
%html drive.htm 1
%html logbook.htm 2

View File

@ -5,7 +5,7 @@
<body>
<h2>Drive commands</h2>
<p>
Many objects in SICS are <b> drivable </b>. This means they can run to a new value. Obvious examples are motors. Less obvious examples include composite adjustments such as setting a wavelength or an energy. This class of objects can be operated by the <b> drive, run, Success </b> family of commands. These commands cater for blocking and non-blocking modes of operation.</p>
Many objects in SICS are <b> drivable </b>. This means they can run to a new value. Obvious examples are motors. Less obvious examples include composite adjustments such as setting a wavelength or an energy. Such devices are alos called virtual motors. This class of objects can be operated by the <b> drive, run, Success </b> family of commands. These commands cater for blocking and non-blocking modes of operation.</p>
<p>
<b> run var newval var newval ... </b> can be called with one to n pairs of object new value pairs. This command will set the variables in motion and return to the command prompt without waiting for the requested operations to finish. This feature allows to operate other devices of the instrument while perhaps a slow device is still running into position.</p>
<p>

65
doc/user/exeman.html Normal file
View File

@ -0,0 +1,65 @@
<HTML>
<HEAD>
<TITLE>The Batch Buffer Manager</TITLE>
</HEAD>
<BODY>
<H1>The Batch Buffer Manager</H1>
<P>
The batch buffer manager handles the execution of batch files. It can
execute batch files directly. Additionally, batch files can be added
into a queue for later processing. The batch buffer manager supports
the following command described below. Please note, that the examples
assume that the batch manager has been configured into SICS under the
name of exe.
<dl>
<dt>exe buffername
<dd>directly load the buffer stored in the file buffername and execute
it. The file is searched in the batch buffer search path.
<dt>exe batchpath [newpath]
<dd>Without an argument, this command lists the directories which are
searched for batch files. With an argument, a new search path is
set. It is possible to specify multiple directories by separating them
with colons.
<dt>exe syspath [newpath]
<dd>Without an argument, this command lists the system directories which are
searched for batch files. With an argument, a new system search path is
set. It is possible to specify multiple directories by separating them
with colons.
<dt>exe info
<dd>prints the name of the currently executing batch buffer
<dt>exe info stack
<dd>prints the stack of nested batch files (i.e. batch files calling
each other).
<dt>exe info range [name]
<dd>Without an argument prints the range of code currently being
executed. With a parameter, prints the range of code executing in
named buffer within the stack of nested buffers. The reply looks like:
number of start character = number of end character = line number.
<dt>exe info text [name]
<dd>Without an argument prints the code text currently being
executed. With a parameter, prints the range of code text executing in the
named buffer within the stack of nested buffers.
<dt>exe enqueue buffername
<dd>Appends buffername to the queue of batch buffers to execute.
<dt>exe clear
<dt>Clears the queue of batch buffers
<dt>exe queue
<dd>Prints the content of the batch buffer queue.
<dt>exe run
<dd>Starts executing the batch buffers in the queue.
<dt>exe print buffername
<dd>Prints the content of the batch buffer buffername to the screen.
<dt>exe interest
<dd>Switches on automatic notification about starting batch files,
executing a new bit of code or for finishing a batch file. This is
most useful for SICS clients watching the progress of the experiment.
<dt>exe upload
<dd>Prepares the batch manager for uploading a buffer to SICS
<dt>exe append some text
<dd> Appends a line with everything after append to the upload buffer
<dt>exe save filename
<dd>saves the recently uploaded buffer under filename on the SICS server.
</dl>
</P>
</BODY>
</HTML>

View File

@ -43,6 +43,7 @@ Switzerland\\
%html commandlog.htm 3
%html batch.htm 2
%html macro.htm 3
%html exeman.htm 3
%html buffer.htm 3
%html token.htm 2
%html focussps.htm 2

View File

@ -12,14 +12,16 @@ handled automatically by the <a href="count.htm">count</a>
command. However, data file writing can be initiated and configured
manually from the command line through the following commands:
<dl>
<DT>storefocus start
<DT>focusstart
<DD>Write a new data file
<DT>storefocus update
<DT>focusupdatescript
<DD>Updates the current data file.
<DT>storefocus intervall
<DT>focuslink
<DD>Creates NeXus links in the data file.
<DT>focusupdate updateintervall
<DD>prints the current update intervall to use during counting. Units
is minutes.
<DT>storefocus intervall newval
<DT>focusupdate updateintervall newval
<DD>Sets the update intervall to newval minutes.
</DL>
FOCUS has three detector banks which may not all be active at all

View File

@ -17,6 +17,7 @@ the SICS server.
<li> A few commands <a href="config.htm">change</a> user rights, set output files and the like.
<li> SICS has a built in <a href="macro.htm">macro</a> facility which is accessible through a few commands.
<li> Then there is the <a href="buffer.htm">famous</a> LNS-R&#252;nbuffer system.
<li> The new <a href="exeman.htm">batch file</a> processing system.
<li> Motors and parameters need to be <a href="drive.htm">drive</a>n.
<li> SICS has a facility to <a href=optimise.htm>optimise</a> a peak with respect to several
parameters.
@ -26,7 +27,7 @@ parameters.
SICS has various ways (to many!) to log the I/O from and to an
instrument control server. This has devolped over time and may need a
cleanup.
<ol>
<ul>
<li>There exists a server log where all I/O and internal
messages is written to automatically. As this can get quite large the
files

View File

@ -3,7 +3,7 @@
<TITLE>Hklscan</TITLE>
</HEAD>
<BODY>
<H1>Hklscan and Hklscan2d</H1>
<H1>Hklscan and Hklscan2d (Obsolete)</H1>
<P>
Hklscan is a command which allows to scan in reciprocal space expressed as
Miller indizes on a four circle diffractometer. Hklscan operates with
@ -39,5 +39,9 @@ Data is written automatically into a slightly modified TOPSI data format
might be slightly erratic as it uses two theta as x-axis. Hklscan2d
writes data into NeXus files.
</P>
<p>
hklscan is obsolete. As of 2005, h, k, l are normal virtual motors and can be
used with the SICS built in scan commands.
</p>
</BODY>
</HTML>

47
doc/user/hrptdev.htm Executable file
View File

@ -0,0 +1,47 @@
<html>
<head>
<title>HRPT motor list</title>
</head>
<body>
<H2>HRPT motor list</H2>
<P>
<DL>
<DT>CEX1
<DD>inner collimator drum
<DT>CEX2
<DD>outer collimator drum
<DT>MOMU, A1
<DD>omega rotation of upper monochromator crystal.
<DT>MTVU, A12
<DD>translation vertical to the upper crystal.
<DT>MTPU, A13
<DD>translation paralell to the upper crystal
<DT>MGVU, A14
<DD>tilt goniometer vertical to upper crystal.
<DT>MGPU, A15
<DD>tilt goniometer paralell to upper crystal.
<DT>MCVU, A16
<dd>vertical curvature of upper crystal.
<DT>MOML, B1
<DD>omega rotation of lower monochromator crystal.
<DT>MTVL, A22
<DD>translation vertical to the lower crystal.
<DT>MTPL, A23
<DD>translation paralell to the lower crystal
<DT>MGVL, A24
<DD>tilt goniometer vertical to lower crystal.
<DT>MGPL, A25
<DD>tilt goniometer paralell to lower crystal.
<DT>MCVL, A26
<dd>vertical curvature of lower crystal.
<dT>MEXZ, A37
<DD>lift
<DT>Table, A3
<DD>Sample rotation.
<DT>TwoThetaD, A4
<DD>Two Theta detector.
</DL>
</p>
</body>
</html>

View File

@ -8,15 +8,6 @@
SICS offers not less then three different ways of logging your
commands and the SICS server's responses:
<ul>
<li>The SICS command line client allows to open a log file on your
local computer and on your account. This can be achieved through the
File/Open Logfile menu entry. Select a file name and hit save. From
then on, any output in the SICS clients terminal area will be written
into the selected file. There is a gotcha: ouptut may not be immediately
visible in the file. This is due to buffering of I/O by the operating
system. If you want to flush, either open a new file or exit the
client. Flushing I/O at each line written is possible, but would have
a massive and unacceptable performance impact.
<li>You may create a similar per client log file on the computer running
the SICS server through the <a href="logbook.htm">logbook</a> command.
<li>Then there is a way to log all activity registered from users with

View File

@ -16,7 +16,11 @@ configured in the variable batchroot and then executes that
batchfile. The usage scenerio is that you have a directory where you
keep batch files. Then the variable batcroot is set to contain the path
to that directory. Batchrun then allows to start scripts in that
directory without specifying the full path.
directory without specifying the full path. Please note that fileeval and batchrun are obsolete and
to be replaced by the new batch manager command, <a href="exeman.htm">exe</a>, as described below.
</p>
<p>
Then there are some special commands which can be used within macro-sripts:
<p>
<b> ClientPut sometext1 ... </b>Usally SICS suppresses any messages

24
doc/user/madsim.htm Normal file
View File

@ -0,0 +1,24 @@
<HTML>
<HEAD>
<TITLE>Simulation Mode</TITLE>
</HEAD>
<BODY>
<H1>Simulation Mode</H1>
<P>
For testing batch files or in order to check the movement of the
instrument it may be helpful to run SICS in simulation mode. You must
theb connect to a special simulation
SICS server which may have been setup for you. In the
simulation server, everything is like in the actual SICS server,
except that no hardware is moved, co counts collected and no data file
written. There is one speciality, however. The command:
<pre>
<em>sync</em>
</pre>
synchronizes the parameters and limits in the simulation server with
those in the instrument server.
</P>
</BODY>
</HTML>

View File

@ -5,65 +5,73 @@
<BODY>
<H1>Reflection List Processor</H1>
<P>
This section describes the means for doing a standard single counter four
circle diffractometer measurement with SICS. A prerequisite for that is a
file with a list of reflections to measure. This is a simple file with
three floating point values per line giving the HKL of the reflection to
measure. Do not forget to put standard reflections into that file any now
and then. Another prerequisite is, that the UB-matrix had been determined
beforehand and that SICS has the updated values. Also check the value of
lambda in the hkl-object.
</P>
<p>
The measurement procedure is rather simple: If a reflection is accessible
the diffractometer is positioned on that reflection. Then a scan is done for
the reflection and data written to file. The scans all run with a fixed scan
widths, counter preset and countmode. There is a choice of omega scan or
omega two theta scan. It is known that there are more sophisticated
measurement schemes for four circle diffraction, but as TRICS is only
temporarily operated with a single counter not much optimisation seemed
necessary.
This module performs four circle diffractometer measurements with a single
counter . In a first view this
module takes a list of reflections as input, drive to each reflection in the list
and performs a scan for each reflection. Some more feautures are supported:
<ul>
<li>Two different input file formats are supported: the simplest contains a three
values for H,K,L per line. Some users prefer to perform the angle calculations
themselves; for such cases the input list can contain four values: two theta, omega, chi
and phi per line.
<li>This module supports phi scans: the reflection list must then contain H,K,L and phi
per line.
<li>Both measurements in normal bisecting mode and normal beam mode are supported.
<li>Optionally weak reflections can be remeasured with the preset multiplied by 5.
<li>Optionally scans are performed in fastscan mode: Between steps, the motor and the
counter are started at the same time. The step is finished when both operations terminate.
<li>The module maintains a table of two theta ranges and scan step widths and scan
variables. This allows to perform scans with varying step widths with two theta and to
switch between omega and omega - two theta scan mode.
</ul>
</p>
<p>
Three files will be written starting from a root such as tricsnumberyear.
For instance trics05601998 means file number 560 in 1998. The file ending in
Three files will be written starting from a root such as tricsyearnnumber.
For instance trics1998n000560 means file number 560 in 1998. The file ending in
.log will contain the console log. This is extremely verbose. Another file
ending with .col will contain the reflection, diffractometer settings and
the measured profile. The third file, ending with .rfl will contain for each
refelction, the HKL, the diffractometer settings and the intensity and sigma
intensity as calculated by the SICS internal integration routine. It does
a Grant Gabe integration (see J.Appl. Cryst (1978), 11, 114-120).
intensity as calculated by the SICS internal integration routine. A
Grant Gabe integration (see J.Appl. Cryst (1978), 11, 114-120) is performed.
</p>
<p>
For the purpose of the command description it is assumed, that this facility
is accessible as object mess within SICS.
is accessible as object dataset within SICS.
Interaction with this object happens through the following commands:
<dl>
<DT>mess start
<DT>dataset open
<DD>Creates a new set of files and writes some header info.
<DT>mess measure filename iSkip
<DT>dataset measure filename iSkip
<DD>Starts a measurement. Reads reflections from the file filename. iSkip is
an optional parameter which allows to skip iSkip lines in the file. This
is for recovery in cases of accidental or purposeful interruption
of the measurement.
<DT>mess genlist filename iSkip
<DT>dataset genlist filename iSkip
<DD>Mesures reflection from filename. The file is expected to have been
created by hklgen and to include all the angle settings. The optional
parameter iSkip determines the number of lines to skip in the file. This
feature allows to continue measurement on not fully processed files.
<DT>mess reopen filename
<DT>dataset reopen filename
<DT>dataset reopen 001/trics2005n000051
<DD>Reopens an already existing file set for appending. Only the file root
without directory info or endings needs to be given.
<DT>mess close
<DT>dataset close
<DD>Closes the current data file set.
<DT>mess file
<DT>dataset file
<DD>Prints the current data file name.
<dt>dataset list
<dd>prints the current parameters.
<dt>dataset calc file
<dd>Tries to calculate all the reflections listen in file and prints an estimate how
many reflections are within limits. As file format only a H,K,L type file is
supported.
</dl>
Then there are a few parameter commands. They follow the general scheme:
<dl>
<DT>mess parameter
<DT>dataset parameter
<DD>Prints the current value of the parameter
<DT>mess parameter value
<DT>dataset parameter value
<DD>Sets the parameter to the new value.
</dl>
This object knows about the following parameters:
@ -72,9 +80,6 @@ This object knows about the following parameters:
<DD>The counting mode to use. Possible values are timer or monitor.
<DT>preset
<DD>The preset to use for counting
<DT>mode
<DD>The measurement mode. Posssible values are omega for omega scans and
omega2theta for omega two theta scans.
<DT>np
<DD>number of points to collect for each profile.
<DT>step
@ -82,16 +87,51 @@ omega2theta for omega two theta scans.
<DT>compact
<DD>Determines if the scan data output to the SICS is in normal
(compact = 0) or condensed (compact = 1) form. The default is 1.
<DT>weak
<DD>0 or 1: switches on special processing of weak reflections.
<DT>weakthreshold
<dd>The threshold used to decide what constitues a weak reflection. The test is:
max count in scan - 2* min count in scan.
<dt>fastscan
<dd>0 or 1: switches fastscan mode.
<dt>psimode
<dd>0 or 1: switches psi scanning mode. Please note that suitable HKL input files for this mode
must contain four numbers: H, K, L and psi.
<dt>psd
<dd>0 or 1: switches on PSD mode for measuring with the area detector. Currently this is mapped
to doing a tricsscan with the scan parameters as evaluted from the two theta range table. The
psi, compact and weak flags are ignored in PSD mode. Only a log file is openend, the rest of
the file management is done by tricsscan.
</dl>
</p>
<p>
mess supports two geometries: the first is the usual bisecting geometry. The
second is the normal beam geometry where the detector is moved out of plane.
This si accounted for by two switches:
Then there are command which allow to configure the table of two theta ranges and
scan parameters. All table related commands start with: dataset table. The following
commands are supported:
<dl>
<dt>mess bi
<dd>switches into bissectiong mode. This is the default.
<dt>mess nb
<dt>dataset table list
<dd>prints the content of the table.
<dt>dataset table add end scanvar step np
<dd>configures a two theta range. The end parameter describes the end of the two theta range to
which these parameters can be applied. Scanmode can either
be om for omega scans or o2t for omega 2 theta scans. step is the step width to use. np is the
number of points in the scan.
<dt>dataset table del num
<dd>deletes the entry num from the table. Counting starts with 0!
<dt>dataset table clear
<dd>clears the whole table.
</dl>
When there is no two theta range configured for a given two theta value, the omega scan
mode applies with the step width given as a parameter to dataset.
</p>
<p>
dataset supports two geometries: the first is the usual bisecting geometry. The
second is the normal beam geometry where the detector is moved out of plane.
This is accounted for by two switches:
<dl>
<dt>dataset bi
<dd>switches into bissecting mode. This is the default.
<dt>dataset nb
<dd>switches into normal beam mode.
</dl>
</p>
@ -102,19 +142,19 @@ files and continuation of reflection processing at a point way down the
reflection file is supported. Consequently the start of a new experiment
requires the following steps:
<ul>
<li>Create a new set of files with <b>mess start</b>.
<li>Create a new set of files with <b>dataset start</b>.
<li>Configure the scans with the parameter commands.
<li>Start processing a reflection file with either the <b>mess genlist</b>
or <b>mess measure</b> commands.
<li>Start processing a reflection file with either the <b>dataset genlist</b>
or <b>dataset measure</b> commands.
</ul>
If you need to continue reflection file processing after an abort or after
solving a problem the following steps are required:
<ul>
<li>Determine the file number you were working at and the line number in the
reflection file where you wish to continue processing.
<li>Set the file root with the <b>mess reopen</b> command.
<li>Set the file root with the <b>dataset reopen</b> command.
<li>Configure the scan parameters again.
<li>Restart the measurement with either <b> mess genlist</b> or <b> mess
<li>Restart the measurement with either <b> dataset genlist</b> or <b> dataset
measure</b> but specify the iSkip parameter according to the position in
the reflection file where processing should continue.
</ul>

View File

@ -34,6 +34,7 @@ status display clients.
Please note that the actual driving of the motor is done via the <a href="drive.htm">drive</a> command.</p>
<hr size=4 width="66%">
<h2>The motor parameters</h2>
<p>
<ul>
<li> <b> HardLowerLim </b> is the hardware lower limit. This is read from the motor controller and is identical to the limit switch welded to the instrument. Can usually not be changed.
<li> <b> HardUpperLim </b> is the hardware upper limit. This is read from the motor controller and is identical to the limit switch welded to the instrument. Can usually not be changed.
@ -58,9 +59,12 @@ desired position was reached. If the position read back from the motor
is not within precision to the desired value, the motor is
restarted. This is done at max maxretry times. After maxretry retries,
the motor throws an error.
<li></b> ignorefault </b>If this is bigger then 0, positioning faults
<li><b> ignorefault </b>If this is bigger then 0, positioning faults
from the motor will be ignored.
</ul>
This list of parameters may be enhanced buy driver specific
parameters. motor list will show all parameters.
</p>
<p>
<h2>Motor Error Handling Concepts</h2>
<p>
@ -94,13 +98,13 @@ maxretries repositionings, a HWFault is assumed.
In any case lots of warnings and infos are printed.
</p>
<p>
If SICS tries to drive an axis which is for some reason broken to
often hardware damage may occur (and HAS occurred!). Now, SICS has no
If SICS tries to drive an axis which is broken hardware damage may
occur (and HAS occurred!). Now, SICS has no
means to detect if the mispositioning of a motor is due to a concrete
block in the path of the instrument or any other reason. What SICS can
do though is to count how often a motor mispositions in
sequence. This means SICS counts mispositionings if it cannot drive a
motor, if the motor is driven succesfully, the count is cleared. If
sequence. This means SICS increments a mispositioning counter if it cannot drive a
motor, if the motor is driven succesfully, the mispositioning counter is cleared. If
the count of mispositionings becomes higher then the parameter
failafter, SICS thinks that there is something really, really wrong
and aborts the measurement and prints an error message containing the
@ -116,7 +120,7 @@ check for the interrupt in upper level code.
<dt>SICS falsly reports mispositionings.
<dd>Solution: increase the precision parameter.
<dt>You know that a motor is broken, you cannot fix it, but you want
to measure anyway.
to measure anyway.
<dd>Solution: increase the precision parameter, if SICS finds the
positioning problem, increase maxretries, increase the failafter
parameter. In the worst case set the ignorefault parameter to greater

View File

@ -42,7 +42,8 @@ Switzerland\\
%html logbook.htm 3
%html commandlog.htm 3
%html batch.htm 2
%html macro.htm 3
%html macro.htm 3
%html exeman.htm 3
%html buffer.htm 3
%html token.htm 2

View File

@ -7,10 +7,12 @@
<p>
As of now two packages are provided:
<ul>
<li>A data analysis package based on <a href="xds.htm">XDS</a>.
<li>An experimental package based on a
novel <a href="auto.htm">volume matching </a> approach.
<li>A program called cami4pcd for visually inspecting TRICS data files and for performing
computer aided manual integration of TRICS data files.
<li>A program called anatric for extracting reflection positions for UB matrix refinement
and the extraction of integrated intensities for structure determination.
</ul>
Both programs are described in separate documents (or not as in the case of cami4psd).
</P>
</BODY>
</HTML>

View File

@ -88,6 +88,8 @@ implemented are:
<DT>Safe
<DD> Tries to run the environment device to a value considered safe by the
user.
<DT>Script
<DD>Run a user defined script to do any magic things you may want.
</DL>
</p>
@ -176,9 +178,13 @@ Possible values are:
<LI>1 for Pause.
<LI> 2 for Interrupt
<LI> 3 for Safe.
<LI> 4 for Script.
</UL> For an explanantion of these values see the section about <a
href="#error">error</a> handling
above.
<DT>errorscript
<DD>The user specified script to execute when the controlled value goes out of
tolerance. Will be used whne the ErrHandler 4, script, is used.
<DT> Interrupt
<DD> The interrupt to issue when an error is detected and Interrupt error
handling is set. Valid values are:

View File

@ -42,6 +42,7 @@ programmers reference.
%html system.htm 1
%html config.htm 1
%html macro.htm 1
%html exeman.htm 2
%html buffer.htm 1
%html drive.htm 1
%html logbook.htm 3

View File

@ -29,7 +29,7 @@ Currently the following SICS clients are available:
<li> A command line control client for sending commands to the SICS
server and displaying its repsonses.
<li> A status display for the powder diffractometers DMC and HRPT.
<li> A status display for TOPSI.
<li> A status display for MORPHEUS and general scans.
<li> A status display for SANS and SANS2.
<li> A status display for FOCUS.
<li> A AMOR control and status program.
@ -53,7 +53,7 @@ privileged SICS user.
</p>
<h2>Starting SICS client applications </h2>
<p>
These programs can be started on a DigitalUnix system by issuing the
These programs can be started on a Linux system by issuing the
following commands at the command prompt:
<dl>
<DT>sics &
@ -61,7 +61,7 @@ following commands at the command prompt:
<DT>powderstatus &
<DD> for the DMC status display client.
<DT>topsistatus &
<DD>for the TOPSI status display.
<DD>for the MORPHEUS status display.
<DT>sansstatus &
<DD> for the SANS status display.
<DT>focustatus
@ -72,13 +72,9 @@ following commands at the command prompt:
<DD> for the triple axis status display and control application.
<DT>varwatch &
<DD> for the variable watcher.
<dt>trics-&
<dt>trics &
<dd>for the starting the TRICS graphical client.
</dl>
On a PC you may find icons for starting the different programs on the
desktop.
Each of these clients has usage instructions online which can be displayed
through the help/about menu entry.
</p>
<p>
Another option to start SICS clients is the Java Webstart mechanism
@ -102,41 +98,82 @@ active. A connection is established through the connect menu of the client.
SICS is a multi user instrument control system. In order to prevent
malicious manipulations of the instrument SICS supports a hierarchy of user
rights. In order to run an experiment you need at least user level privilege.
In order to achieve this privilege you have to invoke the User Parameter/Set
Rights dialog. There you have to enter the apropriate username and password
In order to achieve this privilege you have to invoke the Authorize
dialog. There you have to enter the apropriate username and password
kindly provided by your instrument scientist.
</p>
<h2>Restarting the Server</h2>
<p>
The SICS server should be running all the time. It is only down if something
went wrong. You can check for the presence of the SICS server by loging in
to the instrument computer and typing <b>CheckSICS</b> at the command
to the instrument computer and typing <b>monit status</b> at the command
prompt. The output will tell you what is happening. If you need to restart
the SICS server log in as the instrument user at the instrument computer and
invoke the appropriate command to start the server. These are:
<dl>
<DT>DMC
<DD>Computer = lnsa05, User = DMC
<DD>Computer = dmc, User = dmc
<DT>TOPSI
<DD>Computer = topsi, User = TOPSI
<DD>Computer = morpheus, User = morpheus
<DT>SANS
<DD>Computer = sans, User = SANS
<DD>Computer = sans, User = sans
<DT>SANSLI
<DD>Computer = sans2, User = sans2
<DT>TRICS
<DD>Computer = lnsa18, User = TRICS
<DD>Computer = trics, User = trics
<DT>HRPT
<DD>Computer = lnsa11, User = HRPT
<DD>Computer = hrpt, User = hrpt
<DT>FOCUS
<DD>Computer = lnsa16, User = FOCUS
<DD>Computer = focus, User = focus
<DT>AMOR
<DD>Computer = lnsa14, User = AMOR
<DD>Computer = amor, User = amor
<DT>TASP
<DD>Computer = tasp, User = TASP
<DD>Computer = tasp, User = tasp
<DT>POLDI
<DD>Computer = poldi, User = POLDI
<DD>Computer = poldi, User = poldi
</dl>
For starting the SICS server type <b>startsics</b>. This is a shell script
which will starts all necessary server programs. This script works only on
the instrument computer and in the appropriate instrument account.
The SICS server process are controlled through the monit program. Usually the monit
daemon is running. If not, for instance after a reboot, it can be
started by typing <b>monit</b> at the unix prompt logged in as the
instrument user. Further monit commands:
<dl>
<dt> monit start target
<dd>start the monit surveyed process target. For the choice of targets
see below.
<dt> monit stop target
<dd>stops the monit surveyed process target. For the choice of targets
see below.
<dt> monit restart target
<dd>restart the monit surveyed process target. Possible targets are:
<dl>
<dt>sicsserver
<dd>The SICServer
<dt>SerPortServer
<dd>The serial port control program
<dt>sync
<dd>The file synchronisation program. This is responsible for coyping
data files to the common AFS area.
<dt>simserver
<dd>Only on TASP: a simulation SICS server
<dt>all
<dd>Stop all processes
</dl>
<dt>monit status
<dd>prints a status listing of everything watched by monit
<dt>monit quit
<dd>Stops monit itself
</dl>
Stopping everything thus involves two commands:
<ul>
<li> monit stop all
<li> monit quit
</ul>
Restarting after this involves:
<ul>
<li>monit
</ul>
The older command startsics and killsics are still working and operate
on the monit daemon as of now.
</p>
<p>
If all this does not help look under <a href="trouble.htm">trouble shooting

Some files were not shown because too many files have changed in this diff Show More