PSI sics-cvs-psi-2006
This commit is contained in:
31
.cdtproject
Normal file
31
.cdtproject
Normal 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>
|
108
.project
Normal file
108
.project
Normal 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
27
.rfl
@ -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
|
@ -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);
|
||||
|
@ -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
324
SCinter.c
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -51,7 +51,7 @@
|
||||
}
|
||||
if(!iRet)
|
||||
{
|
||||
printf("Unrecoverable error on server startup, exiting.........");
|
||||
printf("Unrecoverable error on server startup, exiting.........\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,9 @@ typedef enum {
|
||||
eInError,
|
||||
eStatus,
|
||||
eValue,
|
||||
eStart,
|
||||
eFinish,
|
||||
eEvent,
|
||||
eWarning,
|
||||
eError
|
||||
} OutCode;
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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}
|
||||
|
29
callback.c
29
callback.c
@ -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
2
cd_obj
@ -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
187
cell.c
Normal 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
58
cell.h
Normal 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
|
2
choco.c
2
choco.c
@ -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
16
commandcontext.h
Normal 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
|
15
commandlog.c
15
commandlog.c
@ -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
357
cone.c
Normal 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
33
cone.h
Normal 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
69
cone.w
Normal 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
|
||||
@}
|
@ -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
21
confvirtmot.h
Normal 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
22
confvirtmot.i
Normal 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
580
confvirtualmot.c
Normal 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
82
confvirtualmot.w
Normal 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
|
||||
|
||||
@}
|
107
conman.h
107
conman.h
@ -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
|
||||
|
||||
|
@ -92,9 +92,7 @@
|
||||
if(self->KillPrivate != NULL)
|
||||
{
|
||||
self->KillPrivate(self);
|
||||
} else {
|
||||
free(self->pData);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(self);
|
||||
}
|
||||
|
@ -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
|
||||
|
36
counter.c
36
counter.c
@ -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);
|
||||
|
@ -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
8
danu.c
@ -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
257
devexec.c
@ -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");
|
||||
}
|
||||
|
15
devexec.h
15
devexec.h
@ -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 -------------------------*/
|
||||
|
||||
|
@ -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@ /*@\\
|
||||
|
@ -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
368
diffscan.c
Normal 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
47
diffscan.h
Normal 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
97
diffscan.w
Normal 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
113
doc/manager/amor.htm
Normal 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>
|
@ -12,6 +12,9 @@ initialisation file. Such special commands are described here.
|
||||
<DL>
|
||||
<DT>MakeRuenBuffer
|
||||
<DD>MakeRuenBuffer makes the Rü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
47
doc/manager/focus.htm
Normal 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
97
doc/manager/four.htm
Normal 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
243
doc/manager/gencom.htm
Normal 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ü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>
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
BIN
doc/manager/managerman.dvi
Normal file
Binary file not shown.
2341
doc/manager/managerman.tex
Normal file
2341
doc/manager/managerman.tex
Normal file
File diff suppressed because it is too large
Load Diff
80
doc/manager/managerman.toc
Normal file
80
doc/manager/managerman.toc
Normal 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
165
doc/manager/mcstas.htm
Normal 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>
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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
44
doc/manager/sans.htm
Normal 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
11
doc/manager/scan.htm
Normal 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
4
doc/manager/scrap1.htm
Normal 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.
|
@ -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
37
doc/manager/tas.htm
Normal 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>
|
@ -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>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
176
doc/master.tex
176
doc/master.tex
@ -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
77
doc/user/Conescan.html
Normal 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>
|
||||
|
@ -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
104
doc/user/amor.htm
Normal 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>
|
@ -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
|
||||
|
@ -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
22
doc/user/auto.htm
Normal 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
31
doc/user/autosms.htm
Normal 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>
|
@ -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>
|
||||
|
@ -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ünbuffer</a> system.
|
||||
<li>Third there is the new <a href="exeman.htm">Batch File</a> execution
|
||||
system.
|
||||
</ul>
|
||||
</P>
|
||||
</BODY>
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
65
doc/user/exeman.html
Normal 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>
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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ü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
|
||||
|
@ -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
47
doc/user/hrptdev.htm
Executable 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>
|
@ -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
|
||||
|
@ -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
24
doc/user/madsim.htm
Normal 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>
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
Reference in New Issue
Block a user