- 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:
2
Makefile
2
Makefile
@ -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
|
||||
|
2
danu.dat
2
danu.dat
@ -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
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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\\
|
||||
|
231
faverage.c
231
faverage.c
@ -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;
|
||||
}
|
||||
|
@ -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
170
hkl.c
@ -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 */
|
||||
|
62
nextrics.c
62
nextrics.c
@ -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
97
scan.c
@ -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
11
scan.h
@ -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[]);
|
||||
|
28
scan.tex
28
scan.tex
@ -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
28
scan.w
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
225
test.tcl
@ -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
|
||||
|
24
trics.dic
24
trics.dic
@ -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
75
userscan.c
Normal 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
19
userscan.h
Normal 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
51
userscan.w
Normal 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
|
||||
@}
|
Reference in New Issue
Block a user