- Updated the managers documentation a little

- The  crystal settings calculation in hkl now tried to put omega into
  the limts by calculating a delta omega.
- TRICS data files now include HKL and the UB
- The scan module has been expanded to support user defined scans which
  run a script at any scan point.
- A small fix to the PSD code in SinqHM_srv_filler
This commit is contained in:
cvs
2001-07-20 08:05:25 +00:00
parent 8f84d45dd6
commit 0fac95ea9b
25 changed files with 741 additions and 522 deletions

View File

@ -48,7 +48,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
circular.o el755driv.o maximize.o sicscron.o tecsdriv.o sanscook.o \
tasinit.o tasutil.o t_rlp.o t_conv.o d_sign.o d_mod.o \
tasdrive.o tasscan.o synchronize.o definealias.o swmotor.o t_update.o \
hmcontrol.o
hmcontrol.o userscan.o
MOTOROBJ = motor.o el734driv.o simdriv.o el734dc.o pipiezo.o pimotor.o
COUNTEROBJ = countdriv.o simcter.o counter.o

View File

@ -1,3 +1,3 @@
7746
2
NEVER, EVER modify or delete this file
You'll risk eternal damnation and a reincarnation as a cockroach!|n

View File

@ -34,7 +34,8 @@ The following commands are available to install motors into the system:
<DD> This command creates a simulated
motor with the lower limits lowlim, the upper limit uplim, an ratio of
randomly generated errors err and a driving speed of speed. Use this for
testing and instrument simulation.
testing and instrument simulation. If err is less then 0, the motor will
not create failures and thus can be used in a instrument simulation server.
<DT>Motor name EL734 host port chan no
<DD>This command creates a stepper motor named name which is controlled through a
El734 motor controller. The
@ -46,20 +47,54 @@ 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.
</DL>
<DT>MakePIMotor name c804 pararray
<DD>Creates a motr 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:
<dl>
<dt>Computer, port, channel
<dd>The standard connection parameters.
<dt>upperlimit, lowerlimit
<dd>The limits for this motor.
<dt>motor
<dd>The number of the motor in the motor controller.
</dl>
<dt>Motor name pipiezo pararray
<dd>Creates a piezo electric positioning device. Again the controller is a
Physik Instrumente controller. pararray has the same meaning as for the
C804 controller given above.
</p>
<h3>Counting Devices</h3>
<p>
<DL>
<DT>MakeCounter name SIM
<DT>MakeCounter name SIM failrate
<DD>This command creates a simulated single counter
accessible as object name.
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 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.
</DL>
<DT>MakeHMControl name counter hm1 hm2 hm3
<dd>At some instruments (for instance TRICS) multiple counters or
histogram memories are controlled by a master counter which watches
over presets and the like. This command installs a virtual counter
which does exactly that. The parameters are:
<dl>
<dt>name
<dd>The name of the virtual counter in SICS
<dt>counter The name of the master counter
<dt>hm1, hm2, hm3
<dd>Up to three slave counting devices.
</dl>
</dl>
</p>
<h4>Histogram Memory</h4>
<p>
Due to the large amount of parameters, histogram memories are configured

View File

@ -34,6 +34,24 @@ file) may use special commands for the installation of:
<LI>Hardware
</ul>
</p>
<p>
Actually the SICS servers configuration is rarely stored in one file
but in several files which are included by the main configuration
file. In general the following files are present:
<DL>
<dt>inst.tcl
<DD>Replace inst with the name of the instrument in lowercase. This is
the main initialization file. It should contain all the hardware
initialization.
<dt>instcom.tcl
<DD>Again replace inst with name of the instrument in
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
are included from instcom.tcl.
</dl>
</p>
</body>
</html>

View File

@ -35,7 +35,6 @@ which is described elsewhere.
<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 <a href = client.htm>client </a> configuration 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.

View File

@ -44,7 +44,7 @@ SICSINT followed by an interrupt number. For interrupt numbers see file
interrupt.h.
<li> <b> DefaultTclDirectory </b> specifies where Tcl defined commands are
stored. When this is properly defined Tcl will autoload commands.
<li> <b> StatusFile </b> defines the file to which he current state will be
<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
@ -54,6 +54,11 @@ needed. The login word, This option defines this word. If this option is
missing telnet login to SICS is disabled.
<li><b>LogFileDir</b> This server option defines the directory where
commandlog log files are kept.
<li><b>RedirectFile</b> This defines a filename to which all output to
stdout and stderr is logged by the SICS server. This is mainly a
debugging feature.
<li><b>TecsPort</b> The port number at which the Tecs temperature
control server is listening.
</ul>
</p>
</body>

View File

@ -1,8 +1,78 @@
<HTML>
<HEAD>
<TITLE>General SICS Setup</TITLE>
<TITLE>SICS Setup</TITLE>
</HEAD>
<BODY>
<H1>SICS programs, Scripts and Prerequisites<h1>
<p>
<h2>Hardware</h2>
The following hardware is usually present for any SICs instrument:
<ul>
<li>An instrument computer
<li>A Lantronix terminal server with 8-16 serial ports for connecting:
<li>Motor controllers
<li>Counter boxes
<li>Temperature controllers.
<li>Optionally 1-n histogram memory computers are present.
</ul>
The terminal server software is provided by Lantronix, see the
appropriate manuals for the device for a description. The histogram
memories are 6800 VME onboard computers running the VXworks realtime
operating system and some home grown histogramming software documented
elsewhere.
</p>
<h2>Server programs</h2>
<p>
On the instrument computer the following software must run:
<dl>
<dt>SerPortServer
<dd>This is a TCP/IP server which implements a special protocoll for
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.
<dt>TecsServer
<dd>This is a TCP/IP server which watches over temperature
controllers. The only knwon 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
instrument control program. Then the server starts a script which
synchronizes the local data directory with the central data storage on
the labarotory server. FileSync is configured through an
initilaization file usually called fs.ini. See the comments therein
for more information.
<dt>SICServer
<dd>This is the actual instrument control server. The configuration of
this program is documented in this manual.
</dl>
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>
SICS is a client server system. This implies that there is a server program
@ -24,10 +94,16 @@ server is kept along with local copies of all necessary clients, the server
initialisation files and special macro files defined for the instrument.
<DT>data
<DD>The data directory is the central place where all data files collected
at the instrument are stored. Additionally this directory holds a file named
at the instrument are stored. This directory contains subdirectories
for each year. These directories hold the data collected at the
instrument in this year plus a file named
DataNumber which keeps the current serial number of the data files. This
file should never be edited. However, on the first of january an instrument
manager should reset the serial number in this file to 0.
file should never be edited. At the start of each year the instruement manager
must create a new directory with an empty DataNumber
file. Additionally the
path variables both for the data file directory and the DataNumber
file have to be set to the new directory in the instrument
initialization file.
<DT>log
<DD> The log directory contains the server log files and the automatically
generated client log files. Any now and then, and especially when disk space
@ -41,6 +117,12 @@ as lynx or netscape.
<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.
</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
@ -55,7 +137,8 @@ source /data/lnslib/bin/lns.login</b> into her .login file.
<h2> SICS Installation</h2>
<p>
All executables and files necessary to run SICS for each instrument is
avaialable under the /data/lnslib/src/sics hierarchy. The bin directory
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
@ -74,6 +157,23 @@ directory. This command is meant to be used by computing staff only.
<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

View File

@ -6,25 +6,26 @@
<H1>The Four Circle Diffractometer TRICS</H1>
<P>
<h2>Introduction</h2>
The four circle diffractometer TRICS is used for the study of crystal structures
The four circle diffractometer TRICS is used for the study of dynamic
and magentic structures
by neutron diffraction at single crystals. TRICS can be operated in two
modes: 1.) with a single counter very much like a traditional four circle
diffractometer and 2.) with three position sensitive detectors operating
like a oscillation camera as used by protein crystallographers. The second
option has not yet been implemented due to the unavailability of suitable
detectors and electronics. This manual describes the operation of TRICS
like a oscillation camera as used by protein crystallographers.
This manual describes the operation of TRICS
using the SICS software.
</P>
<p>
TRICS is situated at one of the beamlines for hot neutrons at the spallation
source SINQ at PSI, Switzerland. The incident beam first hits a
monochromator crystal. The selected wavelength is in principle fixed. A
TRICS is situated at one of the beamlines for thermal neutrons at the
spallation source SINQ at PSI, Switzerland. The incident white neutron
beam first hits a
monochromator crystal. The selected wavelength is not variable. A
monochromator lift with two monochromators and the possiblity to select
different reflections for diffraction at the monochromator however make it
different reflections peaks however make it
possible to select between a few different neutron wavelength. The sample is
held in a standard eulerian cradle with the usual angles omega, chi and phi.
Up to three position sensitive detectors are held on a detector holder at
different angles in two theta. Or a single detector is fixed to this setup.
Up to three position sensitive detectors are held on detector holders at
different angles in gamma and nu. Or a single detector is fixed to this setup.
The three position sensitive detectors may be moved up and down on a sphere
around the sample. This allows to access different lattice planes when the
eulerian cradle has been replaced by some cryostat or other sample

View File

@ -18,7 +18,7 @@
\begin{huge}
TRICS--Reference Manual \\
\end{huge}
Version April, 2000\\
Version July, 2001\\
Dr. Mark K\"onnecke \\
Labor f\"ur Neutronenstreuung\\
Paul Scherrer Institut\\

View File

@ -10,6 +10,11 @@
Updated for additional detector banks
Mark Koennecke, March 2000
Added focusraw command for retrieving single detector banks in support
of the colour mapping part of the FOCUS status display.
Mark Koennecke, July 2001
---------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
@ -44,78 +49,6 @@
DeleteDescriptor(self->pDes);
free(self);
}
/*-------------------------------------------------------------------------*/
int MakeFA(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pFocusAverager pNew = NULL;
CommandList *pCom = NULL;
pDummy pDum = NULL;
char pBueffel[256];
int iRet;
assert(pCon);
assert(pSics);
/* we need two parameters: the name for the averager and the histogram
memory
*/
if(argc < 3)
{
SCWrite(pCon,"ERROR: Insufficient number of parameters to MakeFA",
eError);
return 0;
}
/* find histogram memory */
pCom = FindCommand(pSics,argv[2]);
if(!pCom)
{
sprintf(pBueffel,"ERROR: histogram memory %s NOT found!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pDum = (pDummy)pCom->pData;
if(!pDum)
{
sprintf(pBueffel,"ERROR: histogram memory %s INVALID!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(strcmp(pDum->pDescriptor->name,"HistMem") != 0)
{
sprintf(pBueffel,"ERROR: %s is NO histogram memory object!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* we got what we need: set things up */
pNew = (pFocusAverager)malloc(sizeof(FocusAverager));
if(!pNew)
{
SCWrite(pCon,"ERROR: out of memory in MakeFA",eError);
return 0;
}
memset(pNew,0,sizeof(FocusAverager));
pNew->pDes = CreateDescriptor("FocusAverager");
if(!pNew->pDes)
{
SCWrite(pCon,"ERROR: out of memory in MakeFA",eError);
return 0;
}
pNew->pHist = (pHistMem)pDum;
iRet = AddCommand(pSics,argv[1],FocusAverageDo, KillFA, pNew);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command %s not created", argv[1]);
SCWrite(pCon,pBueffel,eError);
KillFA(pNew);
return 0;
}
return 1;
}
/*-------------------------------------------------------------------------*/
int FocusAverageDo(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
@ -278,3 +211,157 @@
#endif
return 1;
}
/*-------------------------------------------------------------------------*/
static int FocusRaw(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pFocusAverager self = NULL;
int *iData = NULL;
int iLength, noTimebin, iRet, i;
char pBueffel[256];
const float *timeBin;
HistInt *hiData = NULL, *hiPtr;
int iBank = MIDDLE;
self = (pFocusAverager)pData;
assert(self);
assert(pCon);
assert(pSics);
/* we need one parameter, the bank to read */
if(argc < 2)
{
SCWrite(pCon,
"ERROR: insufficient number of parameters for FocusRaw",
eError);
return 0;
}
iRet = Tcl_GetInt(pSics->pTcl,argv[1],&iBank);
if(iRet != TCL_OK)
{
sprintf(pBueffel,"ERROR: cannot convert %d to integer",argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
timeBin = GetHistTimeBin(self->pHist,&iLength);
assert(timeBin);
hiData = GetHistogramPointer(self->pHist,pCon);
if(hiData == NULL)
{
SCWrite(pCon,"ERROR: failed to read histogram memory data",eError);
return 0;
}
setFMDataPointer(hiData, iLength);
hiData = getFMBankPointer(iBank);
/* get histogram length */
iLength = getFMdim(iBank);
noTimebin = getFMdim(TIMEBIN);
/* write dimension info*/
sprintf(pBueffel,"focusrawdim = %d = %d", iLength, noTimebin);
SCWrite(pCon,pBueffel,eValue);
/* allocate space */
iData = (int *)malloc((iLength*noTimebin+1)*sizeof(int));
if(iData == NULL)
{
SCWrite(pCon,"ERROR: out of memory in FocusRaw",eError);
return 0;
}
memset(iData,0,noTimebin*iLength*sizeof(int));
/* first int: length of things to come */
iData[0] = htonl(iLength*noTimebin);
/* network byte order for everything */
for(i = 0; i < noTimebin*iLength; i++)
{
iData[i+1] = htonl(hiData[i]);
}
/* send away, zipped */
SCWriteZipped(pCon,"focusraw",iData,(iLength*noTimebin+1)*sizeof(int));
free(iData);
return 1;
}
/*-------------------------------------------------------------------------*/
int MakeFA(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[])
{
pFocusAverager pNew = NULL;
CommandList *pCom = NULL;
pDummy pDum = NULL;
char pBueffel[256];
int iRet;
assert(pCon);
assert(pSics);
/* we need two parameters: the name for the averager and the histogram
memory
*/
if(argc < 3)
{
SCWrite(pCon,"ERROR: Insufficient number of parameters to MakeFA",
eError);
return 0;
}
/* find histogram memory */
pCom = FindCommand(pSics,argv[2]);
if(!pCom)
{
sprintf(pBueffel,"ERROR: histogram memory %s NOT found!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
pDum = (pDummy)pCom->pData;
if(!pDum)
{
sprintf(pBueffel,"ERROR: histogram memory %s INVALID!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
if(strcmp(pDum->pDescriptor->name,"HistMem") != 0)
{
sprintf(pBueffel,"ERROR: %s is NO histogram memory object!", argv[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* we got what we need: set things up */
pNew = (pFocusAverager)malloc(sizeof(FocusAverager));
if(!pNew)
{
SCWrite(pCon,"ERROR: out of memory in MakeFA",eError);
return 0;
}
memset(pNew,0,sizeof(FocusAverager));
pNew->pDes = CreateDescriptor("FocusAverager");
if(!pNew->pDes)
{
SCWrite(pCon,"ERROR: out of memory in MakeFA",eError);
return 0;
}
pNew->pHist = (pHistMem)pDum;
iRet = AddCommand(pSics,argv[1],FocusAverageDo, KillFA, pNew);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command %s not created", argv[1]);
SCWrite(pCon,pBueffel,eError);
KillFA(pNew);
return 0;
}
iRet = AddCommand(pSics,"focusraw",FocusRaw, NULL, pNew);
if(!iRet)
{
sprintf(pBueffel,"ERROR: duplicate command focusraw not created");
SCWrite(pCon,pBueffel,eError);
return 0;
}
return 1;
}

View File

@ -1683,6 +1683,14 @@
free(lData);
return 1;
}
/* retrive no of Timebins */
else if(strcmp(argv[1],"notimebin") == 0)
{
sprintf(pBueffel,
"%s.notimebin = %d",argv[0], self->pDriv->iTimeChan);
SCWrite(pCon,pBueffel,eValue);
return 1;
}
/* retrive time binning */
else if(strcmp(argv[1],"timebin") == 0)
{

170
hkl.c
View File

@ -652,154 +652,13 @@
return 1;
}
}
/*-------------------------------------------------------------------------*/
/* This may become dead code if the looping show does not work */
int CulculuteSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,
float fSet[4], SConnection *pCon)
{
int iRet, iSuccess = 0, iRes = 1, iRetry = 1;
int iQuad = 0;
int iTest;
float fDelom = 0.;
char pError[132];
char pBueffel[512];
float fHard;
float fVal;
/* catch shitty input */
if( (fHKL[0] == 0.) && (fHKL[1] == 0.) && (fHKL[2] == 0.))
{
SCWrite(pCon,"ERROR: I will not calculate angles for HKL = (0,0,0) ",
eError);
return 0;
}
/* no retries if normal beam calculation or specific Hamilton requested */
if( (self->iNOR) || (iHamil != 0) )
{
iRetry = 0;
}
/* loop till success */
while(!iSuccess)
{
/* just try it*/
iRet = ICAL(self,fHKL, fPsi, iHamil, self->iQuad,fSet,fDelom);
if(iRet < 0 ) /* could not do it */
{
sprintf(pBueffel,"ERROR: cannot calculate %4.1f %4.1f %4.1f",
fHKL[0], fHKL[1], fHKL[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* check two theta */
iTest = MotorCheckBoundary(self->pTheta,fSet[0], &fHard,pError,131);
if(!iTest)
{
/* this cannot be fixed */
sprintf(pBueffel,
"ERROR: %4.1f, %4.1f, %4.1f, %5.2f violates two theta limits",
fSet[0], fHKL[0], fHKL[1],fHKL[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
/* check omega */
iTest = MotorCheckBoundary(self->pOmega,fSet[1], &fHard,pError,131);
if(!iTest)
{
if((iRetry) && (ABS(fPsi) <= 0.) )
{
/* try tweaking omega a bit */
MotorGetPar(self->pOmega,"softupperlim",&fVal);
if(fSet[1] > fVal) /* upper limit violated */
{
fDelom = -(fSet[1] - fVal - .5);
iRetry = 0; /* do not try a second time */
}
MotorGetPar(self->pOmega,"softlowerlim",&fVal);
if(fSet[1] < fVal)
{
fDelom = (fVal +.5) -fSet[1];
iRetry = 0;
}
continue;
}
else
{
/* this cannot be fixed */
sprintf(pBueffel,
"ERROR: %4.1f, %4.1f, %4.1f, %5.2f violates omega limits",
fSet[1], fHKL[0], fHKL[1],fHKL[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
/* check nu if normal beam */
if(self->iNOR)
{
iTest = MotorCheckBoundary(self->pNu,fSet[2], &fHard,pError,131);
if(!iTest)
{
sprintf(pBueffel,
"ERROR: %4.1f, %4.1f, %4.1f, %5.2f %5.2f %5.2f violates nu limits",
fHKL[0], fHKL[1],fHKL[2],fSet[0], fSet[1],fSet[2]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
else
{
return 1;
}
}
/* check chi and phi, but first put into 0-360 degrees */
if(fSet[2] < 0.0)
{
fSet[2] = 360.0 + fSet[2];
}
if(fSet[3] < 0.0)
{
fSet[3] = 360.0 + fSet[3];
}
iTest = MotorCheckBoundary(self->pChi,fSet[2], &fHard,pError,131);
iTest += MotorCheckBoundary(self->pPhi,fSet[4], &fHard,pError,131);
if(iTest < 2) /* one of them burns */
{
if(iRetry)
{
/* try other quadrant */
if(self->iQuad == 1)
{
iQuad = 0;
}
else
{
iQuad = 1;
}
iRetry = 0;
continue;
}
else
{
sprintf(pBueffel,
"ERROR: %4.1f, %4.1f, %4.1f, %5.2f %5.2f %5.2f %5.2f violates chi, phi limits",
fHKL[0], fHKL[1],fHKL[2],fSet[0], fSet[1],fSet[2],fSet[3]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
iSuccess = 1; /* end loop, we got valid data */
}
return 1;
}
/*-------------------------------------------------------------------------
calculates the four circle settings. If the position can not be reached
because of a limit violation, then psi is rotated in 10 degree steps
until either the loop ends or we finally succed.
until either the loop ends or we finally succeed. If there is a omega
violation we first try to calculate a delta omega which puts omega
into the right range. This is a fix because the omega movement is quite
often restricted due to the crygenic garbage around the sample.
*/
int CalculateSettings(pHKL self, float fHKL[3], float fPsi, int iHamil,
float fSet[4], SConnection *pCon)
@ -810,8 +669,7 @@
float fDelom = 0.;
char pError[132];
char pBueffel[512];
float fHard;
float fVal;
float fHard, fVal, fUpper, fLower;
float myPsi = fPsi;
/* catch shitty input */
@ -844,6 +702,7 @@
iRetry = 35;
}
/* loop till success */
for(i = 0, myPsi = fPsi; i < iRetry; i++, myPsi += 10.)
{
@ -902,6 +761,23 @@
}
*/
iTest = MotorCheckBoundary(self->pOmega,fSet[1], &fHard,pError,131);
if(iTest == 0 && i == 0)
{
/*
calculate a delta omega to put omega into center of range
*/
MotorGetPar(self->pOmega,"softupperlim",&fUpper);
MotorGetPar(self->pOmega,"softlowerlim",&fLower);
if(fSet[1] > fUpper)
{
fVal = fUpper - 5.; /* 5 degree safety for scanning */
}
else if (fSet[1] < fLower)
{
fVal = fLower + 5.; /* same */
}
fDelom = fSet[1] - fVal;
}
iTest += MotorCheckBoundary(self->pChi,fSet[2], &fHard,pError,131);
iTest += MotorCheckBoundary(self->pPhi,fSet[3], &fHard,pError,131);
if(iTest == 3) /* none of them burns */

View File

@ -14,6 +14,7 @@
Mark Koennecke, April 1998
Revised: Mark Koennecke, October 2000
Revised: Mark Koennecke, July 2001
----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
@ -36,7 +37,7 @@
#define DET1Y 256 /* y-length of detector 1 */
#define DET1XS 2 /* pixel size in x of detector 1 */
#define DET1YS 2 /* pixel size in y of detector 1 */
#define DET1DESC "Non existent Detector"
#define DET1DESC "EMBL PSD"
#define DET2X 256 /* x -length of detector 1 */
#define DET2Y 256 /* y-length of detector 1 */
#define DET2XS 2 /* pixel size in x of detector 1 */
@ -60,6 +61,11 @@
#define HM2OFF "hm2off"
#define HM3OFF "hm3off"
/*
name of hkl object holding crystallographic information
*/
#define HKLNAME "hkl"
/*------------------------ the data structure ----------------------------*/
typedef struct __NexTrics {
pObjectDescriptor pDes;
@ -72,6 +78,7 @@
int iFrameNum;
pICallBack pCall;
float hm2Off, hm3Off;
pHKL pCrystal;
} NexTrics;
/* event type */
@ -138,6 +145,15 @@
{
pNew->pHistogram3 = NULL;
}
pCom = FindCommand(pSics,HKLNAME);
if(pCom)
{
pNew->pCrystal = (pHKL)pCom->pData;
}
else
{
pNew->pCrystal = NULL;
}
pNew->iFirst = 1;
pNew->iFrameNum = 0;
@ -419,6 +435,7 @@
CommandList *pCom = NULL;
pHKL pCryst = NULL;
float fVal, fPix[DETAMAX];
float fHKL[3], fUB[9];
iRet = NXopen(self->pCurrentFile,NXACC_RDWR,&hfil);
if(iRet != NX_OK)
@ -501,18 +518,9 @@
}
/* lambda */
pCom = FindCommand(pServ->pSics,"HKL");
if(pCom)
if(self->pCrystal != NULL)
{
pCryst = (pHKL)pCom->pData;
}
if(!pCryst)
{
SCWrite(pCon,"ERROR: HKL not found, cannot write lambda",eError);
}
else
{
GetLambda(pCryst,&fVal);
GetLambda(self->pCrystal,&fVal);
iRet = NXDputalias(hfil,self->pDict,"monolambda",&fVal);
if(iRet != NX_OK)
{
@ -846,6 +854,21 @@
{
SCWrite(pCon,"ERROR: failed to write sample name",eError);
}
if(self->pCrystal != NULL)
{
GetUB(self->pCrystal,fUB);
iRet = NXDputalias(hfil,self->pDict,"sampleub",fUB);
if(iRet != NX_OK)
{
SCWrite(pCon,"ERROR: failed to write sample UB",eError);
}
GetCurrentHKL(self->pCrystal,fHKL);
iRet = NXDputalias(hfil,self->pDict,"samplehkl",fHKL);
if(iRet != NX_OK)
{
SCWrite(pCon,"ERROR: failed to write HKL",eError);
}
}
/* put the frame number */
iRet = 0;
@ -914,7 +937,7 @@
iRet = NXDputalias(hfil,self->pDict,"fnum",&iFrameNum);
if(iRet != NX_OK)
{
SCWrite(pCon,"EERROR: cannot write new framenumber, NO data written",eError);
SCWrite(pCon,"ERROR: cannot write new framenumber, NO data written",eError);
return 0;
}
@ -1094,6 +1117,19 @@
{
SCWrite(pCon,"WARNING: cannot link against sample name",eWarning);
}
if(self->pCrystal != NULL)
{
iRet = NXDaliaslink(hfil,self->pDict,"samplev","sampleub");
if(iRet != NX_OK)
{
SCWrite(pCon,"WARNING: cannot link against sample UB",eWarning);
}
iRet = NXDaliaslink(hfil,self->pDict,"samplev","samplehkl");
if(iRet != NX_OK)
{
SCWrite(pCon,"WARNING: cannot link against sample HKL",eWarning);
}
}
/* write actual data */
iRet = DumpData(self,pCon,hfil,iFrameNum);

97
scan.c
View File

@ -5,7 +5,7 @@
Implementation file for the SICS scan command.
Mark Koennecke, October 1997
Mark Koennecke, October 1997, June 2001
copyright: see copyright.h
----------------------------------------------------------------------------*/
@ -26,6 +26,7 @@
#include "splitter.h"
#include "danu.h"
#include "amorscan.h"
#include "userscan.h"
#include "motor.h"
extern void SNXFormatTime(char *pBuffer, int iLen);
@ -889,6 +890,70 @@ extern void SNXFormatTime(char *pBuffer, int iLen);
return 1;
}
/*-------------------------------------------------------------------------*/
int AppendScanLine(pScanData self, char *line)
{
/* reopen file */
self->fd = fopen(self->pFile,"r+");
if(!self->fd)
{
SCWrite(self->pCon,
"ERROR: Failed to reopen scan file, aborting scan",
eError);
return 0;
}
/* jump to end of file */
fseek(self->fd,0,SEEK_END);
/* print */
fprintf(self->fd,"%s\n",line);
/* done */
fclose(self->fd);
self->fd = NULL;
return 1;
}
/*-------------------------------------------------------------------------*/
extern char *stptok(const char *s, char *t, int len, char *brk);
int StoreScanCounts(pScanData self, char *data)
{
CountEntry sCount;
char pNumber[20], *pPtr;
int iCount = 0;
if(data == NULL)
{
SCWrite(self->pCon,"WARNING: StoreScanCounst called without data",eWarning);
return 1;
}
/* parse the data */
pPtr = data;
pPtr = stptok(pPtr,pNumber,19," \t");
if(pPtr != NULL)
{
sCount.lCount = atoi(pNumber);
}
while((pPtr = stptok(pPtr,pNumber,19," \t")) != NULL)
{
sCount.Monitors[iCount] = atoi(pNumber);
iCount++;
if(iCount >= 10)
{
SCWrite(self->pCon,
"ERROR: I have only space for 10 Monitors in count structure",
eError);
return 0;
}
}
sCount.i = self->iCounts;
DynarReplace(self->pCounts,self->iCounts,&sCount,sizeof(CountEntry));
self->iCounts++;
return 1;
}
/*--------------------------------------------------------------------------*/
static int StartToDrive(pScanData self, int iPoint)
{
@ -2131,7 +2196,8 @@ extern void SNXFormatTime(char *pBuffer, int iLen);
{
if(argc < 5)
{
sprintf(pBueffel,"ERROR: Insufficient number of arguments given for %s add",
sprintf(pBueffel,
"ERROR: Insufficient number of arguments given for %s add",
argv[0]);
SCWrite(pCon,pBueffel,eError);
return 0;
@ -2151,7 +2217,8 @@ extern void SNXFormatTime(char *pBuffer, int iLen);
SCWrite(pCon,pBueffel,eError);
return 0;
}
iRet = AddScanVar(self,pSics,pCon,argv[2],(float)fStart,(float)fStep);
iRet = AddScanVar(self,pSics,pCon,argv[2],
(float)fStart,(float)fStep);
if(iRet)
{
SCSendOK(pCon);
@ -2177,9 +2244,6 @@ extern void SNXFormatTime(char *pBuffer, int iLen);
/*------------ configure */
else if(strcmp(argv[1],"configure") == 0)
{
/* managers only */
if(!SCMatchRights(pCon,usMugger))
return 0;
if(argc < 3)
{
SCWrite(pCon,"ERROR: missing configure option",eError);
@ -2194,10 +2258,19 @@ extern void SNXFormatTime(char *pBuffer, int iLen);
}
else if(strcmp(argv[2],"amor") == 0)
{
/* managers only */
if(!SCMatchRights(pCon,usMugger))
return 0;
ConfigureAmor(self);
SCSendOK(pCon);
return 1;
}
else if(strcmp(argv[2],"user") == 0)
{
ConfigureUserScan(self);
SCSendOK(pCon);
return 1;
}
else
{
sprintf(pBueffel,"ERROR: option %s not recognized by configure",
@ -2447,6 +2520,18 @@ extern void SNXFormatTime(char *pBuffer, int iLen);
SCSendOK(pCon);
return 1;
}
/*----------------- line */
else if(strcmp(argv[1],"line") == 0)
{
Arg2Text(argc-2,&argv[2],pBueffel,511);
return AppendScanLine(self,pBueffel);
}
/*----------------- storecounts */
else if(strcmp(argv[1],"storecounts") == 0)
{
Arg2Text(argc-2,&argv[2],pBueffel,511);
return StoreScanCounts(self,pBueffel);
}
else
{
sprintf(pBueffel,"ERROR: %s not recognized as subcommand to %s",

11
scan.h
View File

@ -58,6 +58,17 @@
which does not check the boundaries of the scan as the default
PrepareScan does.
*/
int AppendScanLine(pScanData self, char *line);
/*
AppendScanLine appends a line to the scan data file. When finished
it updates the position pointer in the file to point behind the
added line.
*/
int StoreScanCounts(pScanData self, char *data);
/*
parses the numbers in data and stores them as the count and
monitor data for the current scan point.
*/
/*------------------------ Interpreter Interface --------------------------*/
int ScanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);

2
scan.i
View File

@ -62,3 +62,5 @@
void *pSpecial;
} ScanData;

View File

@ -162,18 +162,18 @@ scheme is required especiallay for polarising scans.
counter to use and is initialized at creation of the scan data structure.
\item[pCountername] is the name of the counter used.
\item[iChannel] is the channel to use for counting. 0 is the main counter,
everything baove one of the monitors.
everything above one of the monitors.
\item[pCount, iCounts] is a dynamic array containing iCounts sets of
counting infomation. For each scan point this array holds the counts
measured. iCounts is also the current scan position.
\item[iWindow] the width of the window used for peak integration. See
integrate.w,c for more details.
\item[pCommand] It turned out that a way is needed to define user defined
speciality scans. This is implemented by setting the channel number to -10
and then have the scan command execute a Tcl script for each scan point.
This Tcl script has to return a Tcl list containing the values to enter for
counter and monitor for the scan point. pCommand now is the name of the
Tcl procedure to invoke.
speciality scans, especially for those magnetic polarized guys. The way
it is done is that scan has to be configured user. In this mode, ScanCount
will call a script which does everything necessary at the scan point,
including adding data to the data file. pCommand now holds the name of
the script to invoke.
\item[pSpecial] Usually NULL. A entry which allows customized scans to keep
some additional data in the scan data structure.
\end{description}
@ -231,6 +231,17 @@ $\langle$scaninter {\footnotesize ?}$\rangle\equiv$
\mbox{}\verb@ which does not check the boundaries of the scan as the default@\\
\mbox{}\verb@ PrepareScan does.@\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int AppendScanLine(pScanData self, char *line);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ AppendScanLine appends a line to the scan data file. When finished@\\
\mbox{}\verb@ it updates the position pointer in the file to point behind the@\\
\mbox{}\verb@ added line. @\\
\mbox{}\verb@ */@\\
\mbox{}\verb@ int StoreScanCounts(pScanData self, char *data);@\\
\mbox{}\verb@ /*@\\
\mbox{}\verb@ parses the numbers in data and stores them as the count and@\\
\mbox{}\verb@ monitor data for the current scan point.@\\
\mbox{}\verb@ */ @\\
\mbox{}\verb@/*------------------------ Interpreter Interface --------------------------*/@\\
\mbox{}\verb@ int ScanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
\mbox{}\verb@ int argc, char *argv[]);@\\
@ -294,6 +305,11 @@ boundaries are checked against the motor limits. For some scans this
is not feasible. This version omits this check and must be entered as
the PrepareScan function field in the scan data structure by code
using the scan module.
\item[AppendScanLine] appends a line to the scan file. This is useful
for user configured scans, for instance in polarisation mode.
\item[StoreScanCounts] parses the data given in data and stores the
numbers as count values as the count data for the current scan point.
Another feature for supporting user configurable scans.
\item[SimScan] creates a simulated gaussian peak with the given
parameters. Used for debugging several things.
\item[ScanFactory] is the SICS interpreter object creation function

28
scan.w
View File

@ -150,18 +150,18 @@ scheme is required especiallay for polarising scans.
counter to use and is initialized at creation of the scan data structure.
\item[pCountername] is the name of the counter used.
\item[iChannel] is the channel to use for counting. 0 is the main counter,
everything baove one of the monitors.
everything above one of the monitors.
\item[pCount, iCounts] is a dynamic array containing iCounts sets of
counting infomation. For each scan point this array holds the counts
measured. iCounts is also the current scan position.
\item[iWindow] the width of the window used for peak integration. See
integrate.w,c for more details.
\item[pCommand] It turned out that a way is needed to define user defined
speciality scans. This is implemented by setting the channel number to -10
and then have the scan command execute a Tcl script for each scan point.
This Tcl script has to return a Tcl list containing the values to enter for
counter and monitor for the scan point. pCommand now is the name of the
Tcl procedure to invoke.
speciality scans, especially for those magnetic polarized guys. The way
it is done is that scan has to be configured user. In this mode, ScanCount
will call a script which does everything necessary at the scan point,
including adding data to the data file. pCommand now holds the name of
the script to invoke.
\item[pSpecial] Usually NULL. A entry which allows customized scans to keep
some additional data in the scan data structure.
\end{description}
@ -214,6 +214,17 @@ functions:
which does not check the boundaries of the scan as the default
PrepareScan does.
*/
int AppendScanLine(pScanData self, char *line);
/*
AppendScanLine appends a line to the scan data file. When finished
it updates the position pointer in the file to point behind the
added line.
*/
int StoreScanCounts(pScanData self, char *data);
/*
parses the numbers in data and stores them as the count and
monitor data for the current scan point.
*/
/*------------------------ Interpreter Interface --------------------------*/
int ScanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
@ -269,6 +280,11 @@ boundaries are checked against the motor limits. For some scans this
is not feasible. This version omits this check and must be entered as
the PrepareScan function field in the scan data structure by code
using the scan module.
\item[AppendScanLine] appends a line to the scan file. This is useful
for user configured scans, for instance in polarisation mode.
\item[StoreScanCounts] parses the data given in data and stores the
numbers as count values as the count data for the current scan point.
Another feature for supporting user configurable scans.
\item[SimScan] creates a simulated gaussian peak with the given
parameters. Used for debugging several things.
\item[ScanFactory] is the SICS interpreter object creation function

View File

@ -1,12 +1,12 @@
hm3 CountMode timer
hm3 preset 50.000000
hm3 preset 2.000000
hm2 CountMode timer
hm2 preset 50.000000
hm2 preset 2.000000
hm1 CountMode timer
hm1 preset 50.000000
hm1 preset 2.000000
#Crystallographic Settings
hkl lambda 0.703790
hkl setub -0.124702 0.001618 -0.041357 -0.104448 -0.001326 0.049388 0.000751 0.084094 0.001574
hkl lambda 1.190000
hkl setub 0.004793 0.001687 0.064144 -0.160885 -0.000806 0.001924 0.001646 -0.083791 0.001273
det3dist 300.000000
det3dist setAccess 1
det3zeroy 128.000000
@ -125,7 +125,7 @@ twotheta Fixed -1.000000
twotheta sign 1.000000
twotheta InterruptMode 0.000000
twotheta AccessCode 2.000000
lastscancommand UNKNOWN
lastscancommand cscan a4 10. .1 10 5
lastscancommand setAccess 2
sample_mur 0.000000
sample_mur setAccess 2
@ -138,7 +138,7 @@ phone setAccess 2
adress UNKNOWN
adress setAccess 2
# Counter counter
counter SetPreset 50.000000
counter SetPreset 5.000000
counter SetMode Timer
# Motor som
som SoftZero 0.000000
@ -410,5 +410,5 @@ sample DanielOxid
sample setAccess 2
title TopsiTupsiTapsi
title setAccess 2
starttime 2001-06-06 14:23:05
starttime 2001-07-19 15:11:21
starttime setAccess 2

View File

@ -802,12 +802,12 @@
We have a valid PSD packet. Find and check positions.
*/
xPos = xData.ui2[1];
if(xPos >= 32767)
xPos -= 65536;
if(xPos > 32767)
xPos -= 65536 + psdXFactor;
yPos = yData.ui2[1];
if(yPos >= 32767)
yPos -= 65536;
if(yPos > 32767)
yPos -= 65536 + psdYFactor;
xPos = xPos/psdXFactor + psdXOffset;
yPos = yPos/psdYFactor + psdYOffset;
@ -914,7 +914,7 @@
if ((Tsi_flags & STATUS_FLAGS__GU) != 0) printf (" GU");
if(psdXORF) printf(" XORF");
if(psdConf) printf(" CONF");
is = timer_settime (FillTimerId, ~TIMER_ABSTIME, &FillerTime, NULL);
if (is != 0) {
printf ("%s -- failed to set timer\n", Filler_name);

225
test.tcl
View File

@ -48,7 +48,7 @@ ServerOption TecsPort 9753
ServerOption statusfile sicsstatus.tcl
ServerOption ServerPort 2911
ServerOption ServerPort 3006
# the port number the server is going to listen at. The client MUST know
# this number in order to connect. It is in client.ini
@ -325,229 +325,6 @@ fcircleinit
MakeDifrac twotheta omega chi phi counter
#----------- histogram memory
# --------------------------------------------------------------------------
# Initialization script for a simulated TOPSI instrument
#
#
# Dr. Mark Koennecke February, 1996
#---------------------------------------------------------------------------
# O P T I O N S
# --------------- Initialize Tcl internals --------------------------------
rename scan stscan
#-------- a home for this, everything else is in relation to this
set shome /data/koenneck/src
# first all the server options are set
#ServerOption RedirectFile $shome/sics/stdout
ServerOption ReadTimeOut 100
# timeout when checking for commands. In the main loop SICS checks for
# pending commands on each connection with the above timeout, has
# PERFORMANCE impact!
ServerOption AcceptTimeOut 100
# timeout when checking for connection req.
# Similar to above, but for connections
ServerOption ReadUserPasswdTimeout 10
# time to wiat for a user/passwd to be sent from a client. Increase this
# if there is a problem connecting to a server due to network overload\
ServerOption LogFileDir $shome/log
#LogFileDir is the directory where the command log is going
#ServerOption logstartfile $shome/sics/start.tcl
ServerOption LogFileBaseName $shome/sics/tmp/server
# the path and base name of the internal server logfile to which all
# activity will be logged.
ServerOption TecsStartCmd "tecs/bin/TecsServer -h lnsp26:4000/0"
# -h host:port/channel is for serial server
ServerOption TecsBinDir tecs/bin/
ServerOption TecsLogDir /data/koenneck/tmp/
ServerOption TecsPort 9753
ServerOption statusfile sicsstatus.tcl
ServerOption ServerPort 2911
# the port number the server is going to listen at. The client MUST know
# this number in order to connect. It is in client.ini
ServerOption InterruptPort 2914
# The UDP port where the server will wait for Interrupts from clients.
# Obviously, clients wishing to interrupt need to know this number.
# Telnet options
ServerOption TelnetPort 1301
ServerOption TelWord sicslogin
ServerOption DefaultTclDirectory $shome/sics/tcl
ServerOption DefaultCommandFile ""
#------ a port for broadcasting UDP messages
#ServerOption QuieckPort 2108
TokenInit connan
#---------------------------------------------------------------------------
# U S E R S
# than the SICS users are specified
# Syntax: SicsUser name password userRightsCode
SicsUser Mugger Diethelm 1
SicsUser User Rosy 2
SicsUser Spy 007 1
SicsUser me me 1
#--------------------------------------------------------------------------
# S I M P L E V A R I A B L E S
# now a few general variables are created
# Syntax: VarMake name type access
# type can be one of: Text, Int, Float
#access can be one of: Internal, Mugger, user, Spy
VarMake Instrument Text Internal
Instrument "TOPSI"
Instrument lock
VarMake starttime Text User
VarMake Title Text User
VarMake sample Text User
sample "DanielOxid"
Title "TopsiTupsiTapsi"
VarMake User Text User
User "Daniel_the_Clementine"
VarMake detectordist Float Mugger
detectordist 2500
detectordist lock
VarMake sampledist Float Mugger
sampledist 496.
sampledist lock
#--------------------------------------------------------------------------
# D E V I C E S : M O T O R S
# Motor a4 EL734 LNSP22 4000 5 6
# EL734 motor with parameters: hostname PortNumber Channel MotorID
#Motor D1V EL734 lnsp22.psi.ch 4000 3 3
Motor A1 SIM 15.0 120. .1 2. # Monochromator Theta
Motor A2 SIM -73. 137. .1 1. # Monochromator 2Theta
Motor A3 SIM -360. 360. .1 3. # Sample Omega
Motor A4 SIM -130. 130. .1 1. # Sample 2Theta
Motor A5 SIM -30. 30. .1 3. # ? horiz. Translation
Motor A6 SIM -30. 30. .1 3. # ? vert Translation
Motor MTL SIM -30. 30. .1 3. # mono lower translation
Motor MTU SIM -30. 30. .1 3. # mono upper translation
Motor STL SIM -30. 30. .1 3. # sample lower translation
Motor STU SIM -30. 30. .1 3. # sample upper translation
Motor MGU SIM -50. 50. .1 3. # mono upper goniometer
Motor SGL SIM -20. 20. .1 3. # sample lower goniometer
Motor SGU SIM -20. 20. .1 3. # sample upper goniometer
Motor SDM SIM -5 50. .1 3. # weird Motor
SicsAlias A4 Tasse
SicsAlias A5 MonoX
SicsAlias A5 MonoY
SicsAlias A5 MonoPhi
SicsAlias A5 MonoChi
Motor D1R SIM -20. 20. .1 3. # Diaphragm 1 right
Motor D1L SIM -20. 20. .1 3. # Diaphragm 1 left
Motor D1T SIM -20. 20. .1 3. # Diaphragm 1 top & Bottom
Motor D2R SIM -20. 20. .1 3. # Diaphragm 2 right
Motor D2L SIM -20. 20. .1 3. # Diaphragm 2 left
Motor D2T SIM -20. 20. .1 3. # Diaphragm 2 top & Bottom
Motor BeamStopX SIM -20. 20. .1 3. # Diaphragm 2 right
Motor BeamStopY SIM -20. 20. .1 3. # Diaphragm 2 left
Motor DetectorX SIM -20. 20. .1 3. # Diaphragm 2 right
Motor DetectorY SIM -20. 20. .1 3. # Diaphragm 2 left
Motor DetectorRotation SIM -20. 20. .1 3. # Diaphragm 2 top & Bottom
ClientPut "Motors done"
MakeMulti sampletable
sampletable alias D1r x
sampletable alias D1L y
sampletable alias D1T z
sampletable pos henry D1r 5. D1L -5. D1T 0.
sampletable endconfig
SicsAlias sampletable st
#------------------------------------------------------------------------
# Velocity selector
#Motor tilt EL734 lnsp25.psi.ch 4000 2 2
Motor tilt SIM -15 15 .1 3.
set dornen(Host) lnsp25.psi.ch
set dornen(Port) 4000
set dornen(Channel) 6
set dornen(Timeout) 5000
#VelocitySelector nvs tilt DORNIER dornen
VelocitySelector nvs tilt SIM
nvs add -20 28800
nvs add 3800 4500
nvs add 5900 6700
nvs add 8100 9600
unset dornen
MakeSANSWave lumbda nvs
ClientPut "Velocity Selector done"
SicsAlias MTL sax
SicsAlias A3 som
#--------------------------------------------------------------------------
# C O U N T E R S
MakeCounter counter SIM
#MakeCounter counter EL737 lnsp19.psi.ch 4000 4
#--------------------------------------------------------------------------
# M U L T I D E V I C E V A R I A B L E S
MakeMono Mono "Ge-111" A1 A2 SDM
Mono dd 3.3537
Mono vk1 -0.025942
Mono vk2 5.35166
MakeWaveLength lambda Mono
MakeO2T O2T A3 A4
#--------------------------------------------------------------------------
# P R O C E D U R E S
source tcl/log.tcl
MakeDrive
SicsAlias drive dr
Publish LogBook Spy
MakeRuenBuffer
#---------------- TestVariables for Storage
VarMake SicsDataPath Text Mugger
SicsDataPath "$shome/sics/"
SicsDataPath lock
VarMake SicsDataPrefix Text Mugger
SicsDataPrefix test
SicsDataPrefix lock
VarMake SicsDataPostFix Text Mugger
SicsDataPostFix ".hdf"
SicsDataPostFix lock
VarMake Adress Text User
VarMake phone Text User
VarMake fax Text User
VarMake email Text User
VarMake sample_mur Float User
MakeDataNumber SicsDataNumber "$shome/sics/danu.dat"
#InitSANS $shome/sics/sansdict.dic
InitDMC
MakeScanCommand xxxscan counter topsi.hdd recover.bin
MakePeakCenter xxxscan
#MakeHM hm1 SinqHM
MakeHM hm1 SIM

View File

@ -15,21 +15,21 @@
fnum = /frame0000,NXentry/SDS CurrentFrameNumber -type DFNT_INT32
framename = frame0000
#------ NXentry
etitle = /$(framename),NXentry/SDS title -type DFNT_UINT8 -rank 1 -dim {132}
etitle0 = /frame0000,NXentry/SDS title -type DFNT_UINT8 -rank 1 -dim {132}
etime = /$(framename),NXentry/SDS start_time -type DFNT_UINT8 -rank 1 -dim {132}
etitle = /$(framename),NXentry/SDS title -type DFNT_CHAR -rank 1 -dim {132}
etitle0 = /frame0000,NXentry/SDS title -type DFNT_CHAR -rank 1 -dim {132}
etime = /$(framename),NXentry/SDS start_time -type DFNT_CHAR -rank 1 -dim {132}
entry = /$(framename),NXentry/NXVGROUP
#--------------NXinstrument
iname = /$(framename),NXentry/TRICS,NXinstrument/SDS name -type DFNT_UINT8 \
iname = /$(framename),NXentry/TRICS,NXinstrument/SDS name -type DFNT_CHAR \
-rank 1 -dim {132}
iname0 = /frame0000,NXentry/TRICS,NXinstrument/SDS name -type DFNT_UINT8 \
iname0 = /frame0000,NXentry/TRICS,NXinstrument/SDS name -type DFNT_CHAR \
-rank 1 -dim {132}
inst0 = /$(framename),NXentry/TRICS,NXinstrument/NXVGROUP
#------------------------NXSource
sname = /$(framename),NXentry/TRICS,NXinstrument/SINQ,NXsource/SDS name \
-type DFNT_UINT8 -rank 1 -dim {20}
-type DFNT_CHAR -rank 1 -dim {20}
stype = /$(framename),NXentry/TRICS,NXinstrument/SINQ,NXsource/SDS type \
-type DFNT_UINT8 -rank 1 -dim {60}
-type DFNT_CHAR -rank 1 -dim {60}
source0 = /frame0000,NXentry/TRICS,NXinstrument/SINQ,NXsource/NXVGROUP
#------------------------Monochromator
monodes = /frame0000,NXentry/TRICS,NXinstrument/monochromator,NXcrystal/SDS \
@ -56,7 +56,7 @@ dnumber = detector1
framedim1 = 256
framedim2 = 256
ddescription = /frame0000,NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS \
name -type DFNT_UINT8 -rank 1 -dim {132}
name -type DFNT_CHAR -rank 1 -dim {132}
detectorx = /frame0000,NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS x \
-attr {axis,1} -attr {units,mm} -type DFNT_FLOAT32 \
-rank 1 -dim {$(framedim1)}
@ -72,7 +72,7 @@ frametilt = /$(framename),NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS
-attr {units,degrees}
framecounts = /$(framename),NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS counts \
-attr {signal,1} -attr {units,counts} -type DFNT_INT32 \
-rank 2 -dim {$(framedim1),$(framedim2)}
-LZW -rank 2 -dim {$(framedim1),$(framedim2)}
detzerox = \
/frame0000,NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS x_zero_point \
-attr {units,pixel}
@ -86,10 +86,12 @@ detvalid = \
/$(framename),NXentry/TRICS,NXinstrument/$(dnumber),NXdetector/SDS valid \
-type DFNT_INT32
#-------------- NXsample
samplename = /frame0000,NXentry/sample,NXsample/SDS name -type DFNT_UINT8 -rank 1 \
samplename = /frame0000,NXentry/sample,NXsample/SDS name -type DFNT_CHAR -rank 1 \
-dim {256}
sampleub = /frame0000,NXentry/sample/NXsample/SDS UB -type DFNT_FLOAT32 \
sampleub = /frame0000,NXentry/sample,NXsample/SDS UB -type DFNT_FLOAT32 \
-rank 2 -dim {3,3}
samplehkl = /frame0000,NXentry/sample,NXsample/SDS HKL -type DFNT_FLOAT32 \
-rank 1 -dim {3}
samplev = /$(framename),NXentry/sample,NXsample/NXVGROUP
framechi = /$(framename),NXentry/sample,NXsample/SDS chi -attr {units,degrees}
framephi = /$(framename),NXentry/sample,NXsample/SDS phi -attr {units,degrees}

75
userscan.c Normal file
View File

@ -0,0 +1,75 @@
/*------------------------------------------------------------------------
User configurable scans. At each scan point a scripted procedure is
called.
More info: userscan.tex
copyright: see copyright.h
Mark Koennecke, June 2001
-------------------------------------------------------------------------*/
#include <stdlib.h>
#include <assert.h>
#include <tcl.h>
#include "fortify.h"
#include "sics.h"
#include "scan.h"
#include "scan.i"
#include "userscan.h"
/*-----------------------------------------------------------------------*/
static int UserScanPoints(pScanData self, int iPoint)
{
/*
do nothing as the user is supposed to take care of the data file
*/
return 1;
}
/*-----------------------------------------------------------------------
Execute the users special procedure
------------------------------------------------------------------------*/
static int UserCount(pScanData self, int iPoint)
{
int status;
char pBueffel[512];
assert(self);
assert(self->pSics);
assert(self->pCon);
/* check for existence of command to run */
if(self->pCommand == NULL)
{
SCWrite(self->pCon,
"ERROR: configuration error, need procedure to run for user scan",
eError);
SCSetInterrupt(self->pCon,eAbortScan);
return 0;
}
/* invoke command */
sprintf(pBueffel,"%s %d",self->pCommand, iPoint);
status = Tcl_GlobalEval(self->pSics->pTcl,pBueffel);
if(status != TCL_OK)
{
sprintf(pBueffel,"ERROR in count script: %s",
Tcl_GetStringResult(self->pSics->pTcl));
SCWrite(self->pCon,pBueffel,eError);
return 0;
}
return 1;
}
/*------------------------------------------------------------------------*/
int UserCollect(pScanData self, int iPoint)
{
/* do nothing, its the users job*/
return 1;
}
/*------------------------------------------------------------------------*/
void ConfigureUserScan(pScanData self)
{
assert(self);
self->WriteScanPoints = UserScanPoints;
self->ScanCount = UserCount;
self->CollectScanData = UserCollect;
}

19
userscan.h Normal file
View File

@ -0,0 +1,19 @@
/*------------------------------------------------------------------------
User configurable scans. At each scan point a scripted procedure is
called.
More info: userscan.tex
copyright: see copyright.h
Mark Koennecke, June 2001
-------------------------------------------------------------------------*/
#ifndef USERSCAN
#define USERSCAN
void ConfigureUserScan(pScanData self);
#endif

51
userscan.w Normal file
View File

@ -0,0 +1,51 @@
\subsection{User Scans}
When operating with polarisation equipment a lot of things must be done
at each scan point: count, switch sloppy flippers, drive magnetic
fields, count again etc. In order to do that and other special things user
configurable scans have been introduced. For such scans a configurable
script procedure is called at each scan point with the current
scan point number as an argument. This script then has to perform
the necessary counting operations, store the data collected, print
status information and update the internal scan data structures with
the collected data so that data may be plotted or analyzed in SICS.
In the following section the internal scan object is referenced as xxxscan.
The script can contain the following commands:
\begin{itemize}
\item Normal SICS commands for driving magnets, counting, retrieving
data etc.
\item {\bf xxxscan line bla bla } appends everything after line to
the data file.
\item {\bf xxxscan store 1 2 3 4} stores the numbers after store in the
count data structure of the scan module.
\item clientput allows to write information to the controlling terminal.
\end{itemize}
In order to do all this some configurable scan functions have to be
overloaded. This is implemented in userscan.c. In terms of a public
interface only one function is defined:
@d usinter @{
void ConfigureUserScan(pScanData self);
@}
which simply sets the necessary function pointers in pScanData.
@o userscan.h @{
/*------------------------------------------------------------------------
User configurable scans. At each scan point a scripted procedure is
called.
More info: userscan.tex
copyright: see copyright.h
Mark Koennecke, June 2001
-------------------------------------------------------------------------*/
#ifndef USERSCAN
#define USERSCAN
@<usinter@>
#endif
@}