- Added triple axis scan command.

- Introduced simulation mode to simdriv and simcter, i.e they never fail and
  finish at once.
- Started defining MAD compatibility commands in Tcl
- Fixed a bug in FOCUS_src which caused it to leak sockets.
- Introduced setsockopt SO_REUSEADDR to all new sockets in sinqhm in order
  to loose the next sinqhm error.
This commit is contained in:
cvs
2000-12-05 09:05:03 +00:00
parent e83d3e6946
commit 876396bb7e
22 changed files with 2000 additions and 58 deletions

View File

@ -44,7 +44,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
hklscan.o xytable.o amor2t.o nxamor.o amorscan.o amorstat.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
tasdrive.o tasscan.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 @@
7307
7459
NEVER, EVER modify or delete this file
You'll risk eternal damnation and a reincarnation as a cockroach!|n

View File

@ -811,7 +811,14 @@
{
ObPar *pPar = NULL;
assert(self);
if(strcmp(name,"target") == 0)
{
*fVal = self->fTarget;
return 1;
}
pPar = ObParFind(self->pParam,name);
if(pPar)
{

View File

@ -158,7 +158,8 @@
return 0;
}
/* another parameter, if available describes the detector bank*
/* another parameter, if available describes the detector bank
*/
if(argc > 3)
{
iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iBank);

View File

@ -61,6 +61,7 @@
#include "sinqhmdriv.i"
#include "dynstring.h"
#include "event.h"
#include "status.h"
/*
#define LOADDEBUG 1
@ -1663,9 +1664,15 @@
{
if(!SCMatchRights(pCon,usMugger))
{
SCWrite(pCon,"ERROR: yoy are not authorised for this operation",eError);
SCWrite(pCon,"ERROR: you are not authorised for this operation",eError);
return 0;
}
if(GetStatus() == eCounting)
{
SCWrite(pCon,"ERROR: cannot modify timebinning while counting",
eError);
return 0;
}
if(argc < 5)
{
SCWrite(pCon,"ERROR: not enough aguments to genbin",eError);

View File

@ -41,7 +41,7 @@
extern void *NXpData;
extern void (*NXIReportError)(void *pData, char *pBuffer);
/*--------------------------------------------------------------------------*/
/* #define DEFDEBUG 1*/
/*#define DEFDEBUG 1*/
/* define DEFDEBUG when you wish to print your definition strings before
action. This can help a lot to resolve mysteries when working with
dictionaries.
@ -682,7 +682,7 @@
{"-LZW",DLZW},
{"-HUF",DHUF},
{"-RLE",DRLE},
{"",0} };
{NULL,0} };
/*-----------------------------------------------------------------------*/
static void NXDIDefToken(ParDat *sStat)
@ -995,7 +995,7 @@
{"DFNT_INT32",DFNT_INT32},
{"DFNT_UINT32",DFNT_UINT32},
{"DFNT_CHAR",DFNT_CHAR},
{"",0} };
{NULL,-122} };
@ -1088,7 +1088,7 @@
iRank = atoi(pParse->pToken);
break;
case DDIM:
iRet = NXDIParseDim (pParse, (int *) iDim);
iRet = NXDIParseDim(pParse, iDim);
if(iRet == NX_ERROR)
{
LLDdelete(iList);
@ -1153,7 +1153,7 @@
/* we need to create it, if we may */
if(pParse->iMayCreate)
{
iRet = NXmakedata (hfil, pName, iType, iRank, (int *) iDim);
iRet = NXmakedata(hfil,pName,iType, iRank,iDim);
if(iRet != NX_OK)
{
/* a comment on this one has already been written! */

View File

@ -1,3 +1,5 @@
sicsdatapath /data/koenneck/src/sics/tmp/
sicsdatapath setAccess 1
arx2 4.290000
arx2 setAccess 1
arx1 0.150000
@ -22,21 +24,21 @@ etam 0.000000
etam setAccess 2
wav 0.000000
wav setAccess 2
den 0.000000
den 0.100000
den setAccess 2
dql 0.000000
dql 0.010000
dql setAccess 2
dqk 0.000000
dqk setAccess 2
dqh 0.000000
dqh 0.010000
dqh setAccess 2
dkf 0.000000
dkf setAccess 2
def 0.000000
def 0.500000
def setAccess 2
dki 0.000000
dki setAccess 2
dei 0.000000
dei 0.500000
dei setAccess 2
dagl 0.000000
dagl setAccess 2
@ -68,7 +70,7 @@ da6 0.000000
da6 setAccess 2
da5 0.000000
da5 setAccess 2
da4 0.000000
da4 0.500000
da4 setAccess 2
da3 0.000000
da3 setAccess 2
@ -76,6 +78,32 @@ da2 0.000000
da2 setAccess 2
da1 0.000000
da1 setAccess 2
bet4 0.000000
bet4 setAccess 2
bet3 0.000000
bet3 setAccess 2
bet2 0.000000
bet2 setAccess 2
bet1 0.000000
bet1 setAccess 2
alf4 0.000000
alf4 setAccess 2
alf3 0.000000
alf3 setAccess 2
alf2 0.000000
alf2 setAccess 2
alf1 0.000000
alf1 setAccess 2
local Berty Chimney
local setAccess 2
output a1,a2,a3,a4
output setAccess 2
lastcommand sc qh 0 0 2 3 dqh 0.01 0.0 0.01 .1
lastcommand setAccess 2
user Billy Looser
user setAccess 2
title SimSulfid Test
title setAccess 2
f2 0
f2 setAccess 2
f1 0
@ -98,7 +126,7 @@ if1v 0.000000
if1v setAccess 2
mn 0
mn setAccess 2
ti 0.000000
ti 2.000000
ti setAccess 2
np 9
np setAccess 2
@ -114,25 +142,25 @@ da 3.354000
da setAccess 1
dm 3.354000
dm setAccess 1
en 2.800000
en 3.400000
en setAccess 2
ql 0.000000
ql 2.040000
ql setAccess 2
qk 0.000000
qk setAccess 2
qh 2.000000
qh 0.040000
qh setAccess 2
kf 1.964944
kf setAccess 2
ef 8.000000
ef setAccess 2
ki 2.283058
ki 2.345619
ki setAccess 2
ei 10.800000
ei 11.400000
ei setAccess 2
bz 0.000000
bz 1.000000
bz setAccess 2
by 1.000000
by 0.000000
by setAccess 2
bx 0.000000
bx setAccess 2
@ -144,18 +172,18 @@ ax 1.000000
ax setAccess 2
cc 90.000000
cc setAccess 2
bb 90.000000
bb 67.889999
bb setAccess 2
aa 90.000000
aa setAccess 2
cs 5.000000
cs 7.000000
cs setAccess 2
bs 5.000000
bs setAccess 2
as 5.000000
as setAccess 2
# Counter counter
counter SetPreset 1000.000000
counter SetPreset 2.000000
counter SetMode Timer
# Motor agl
agl SoftZero -0.490000
@ -192,7 +220,7 @@ mgl AccessCode 2.000000
# Motor atu
atu SoftZero -0.880000
atu SoftLowerLim -16.120001
atu SoftUpperLim 17.879999
atu SoftUpperLim 17.759998
atu Fixed -1.000000
atu sign 1.000000
atu InterruptMode 0.000000

View File

@ -48,9 +48,9 @@
#include "countdriv.h"
/*---------------------------------------------------------------------------
A SIMCOUNTER HAS a BUILT IN FAILURE RATE OF 10% FOR TESTING ERROR HANDLING
CODE.
CODE. A negative failure rate means absolute success.
*/
#define FAILRATE 0.05
#define FAILRATE -0.05
/*----------------------------------------------------------------------------*/
static float SimRandom(void)
{
@ -76,6 +76,14 @@
pSim = (SimSt *)self->pData;
assert(pSim);
/*
no fail, no wait case
*/
if(FAILRATE < .0)
{
return HWIdle;
}
if(SimRandom() < FAILRATE)
{
return HWFault;
@ -159,6 +167,14 @@
pSim->iPause = 1;
/*
no fail, no wait case
*/
if(FAILRATE < .0)
{
return OKOK;
}
if(SimRandom() < FAILRATE)
{
return HWFault;
@ -220,6 +236,18 @@
pSim = (SimSt *)self->pData;
assert(pSim);
/*
no fail, no wait case
*/
if(FAILRATE < .0)
{
for(i = 0; i < MAXCOUNT; i++)
{
self->lCounts[i] = (long)rand();
}
return OKOK;
}
if(SimRandom() < FAILRATE)
{
return HWFault;

View File

@ -73,6 +73,15 @@
assert(self);
pDriv = (SIMDriv *)self;
/*
no error checking case
*/
if(pDriv->fFailure < .0)
{
*fPos = pDriv->fPos;
return OKOK;
}
if(SimRandom() < pDriv->fFailure)
{
*fPos = SimRandom();
@ -100,6 +109,16 @@
assert(self);
pDriv = (SIMDriv *)self;
/*
no failure, no wait situation
*/
if(pDriv->fFailure < .0)
{
pDriv->fPos = fVal;
return OKOK;
}
/* calculate time for completion */
fDiff = fVal - pDriv->fPos;
if(fDiff < .0) fDiff = -fDiff;
@ -187,6 +206,15 @@
assert(self);
pDriv = (SIMDriv *)self;
/*
no wait, no fail situation
*/
if(pDriv->fFailure < .0)
{
return HWIdle;
}
if(RunComplete(pDriv))
{
return HWIdle;

View File

@ -245,8 +245,12 @@
&FS_bytes_got, &FS_bytes_put, FS_name[index]);
if (!status || (ntohl (my_rply_bf.status) != KER__SUCCESS)) {
if (ntohl (my_rply_bf.status) != KER__SUCCESS) {
printf ("\n%s: error response to SQHM_CNCT request to %s.\n",
FS_name[index], FS_slaves[i]);
printf (
"\n%s: %s to %s.\n, status = %d, substatus = %d ",
"error response to SINQHM_CNCT",
FS_name[index], FS_slaves[i],
ntohl(my_rply_bf.status),
ntohl(my_rply_bf.sub_status));
}
*iret = -6; /* Tell our parent we've given up */
close (clnt_skt);
@ -1765,14 +1769,77 @@
/*
**--------------------------------------------------------------------------
** FS_do_zero: Action routine for SQHM_ZERO command.
*
* This is only partially functional. The definition for SQHM_ZERO states
* that it is possible to zero only parts of the histogram. The version
* below just forwards a full zero request to all slaves and thus fits
* the bill for FOCUS. Probably for any other instrument as well.
*
* Mark Koennecke, November 2000
*/
int FS_do_zero (
/* ===========
*/ struct rply_buff_struct *reply,
int index,
int indx,
int nbins,
int first_bin,
int hist_no) {
int i, iret, all_ok = True;
struct req_buff_struct request;
/*
set up the request structure which zeros the whole histogram
*/
request.bigend = htonl(0x12345678);
request.cmnd = htonl(SQHM_ZERO);
request.u.zero.hist_no = htonl(-1);
request.u.zero.first_bin = htonl(-1);
request.u.zero.n_bins = htonl(-1);
/*
** Claim the sem to avoid race conditions with other threads
*/
if (FS_use_sem_tmo) {
iret = semTake (FS_sem_daq, FS_sem_tmo);
}else {
iret = semTake (FS_sem_daq, WAIT_FOREVER);
}
/*
send the request to all known slaves
*/
for (i = 0; i < FS_n_slaves; i++) {
if (FS_slv_active[i]) {
if (indx == 0) { /* If we are the master-server, send it to the
** master-servers in the slaves. */
iret = FS_send_cmnd_to_mstr (&FS_rmt_socknam[i],
&request, sizeof (request), reply,
&FS_bytes_got, &FS_bytes_put);
if (!iret || (ntohl (reply->status) != KER__SUCCESS)) all_ok=False;
}else {
iret = rqst_send_get (FS_skt[indx][i], &request, sizeof (request),
reply, sizeof (*reply),
&FS_bytes_got, &FS_bytes_put, FS_name[indx]);
if (!iret || (ntohl (reply->status) != KER__SUCCESS)) all_ok=False;
}
}
}
if (!all_ok) { /* If error, go no further! */
printf("Error zeroing histogram no %d\n", i);
semGive (FS_sem_daq);
return all_ok;
}
/*
tell the world about our success
*/
reply->status = htonl (KER__SUCCESS);
/* release semaphore */
semGive (FS_sem_daq);
return True;
}
/*
@ -2134,7 +2201,7 @@
uint *in_cntr,
uint *out_cntr) {
int status, cnct_skt, rmt_sockname_len;
int status, cnct_skt, rmt_sockname_len, i;
int bytes_to_come, nbytes;
char *p_nxt_byte;
struct sockaddr_in lcl_sockname;
@ -2142,12 +2209,20 @@
** Create a TCP/IP socket for connecting to SINQHM_SRV root and bind it.
*/
cnct_skt = socket (AF_INET, SOCK_STREAM, 0);
if (cnct_skt == -1) failInet ("\nFS_send_cmnd_to_mstr: socket error.");
i = 1;
setsockopt(cnct_skt,SOL_SOCKET, SO_REUSEADDR, &i,sizeof(int));
if (cnct_skt == -1) {
close(cnct_skt);
failInet ("\nFS_send_cmnd_to_mstr: socket error.");
}
setup_host (NULL, &lcl_sockname, 0, False);
status = bind (cnct_skt, (struct sockaddr *) &lcl_sockname,
sizeof (lcl_sockname));
if (status == -1) failInet ("\nFS_send_cmnd_to_mstr: bind error.");
if (status == -1){
close(cnct_skt);
failInet ("\nFS_send_cmnd_to_mstr: bind error.");
}
/*
** Connect to SINQHM_SRV root.
*/
@ -2155,6 +2230,7 @@
status = connect (cnct_skt, (struct sockaddr *) rmt_sockname,
rmt_sockname_len);
if (status == -1) {
close(cnct_skt);
getErrno (&FS_errno);
failInet ("\nFS_send_cmnd_to_mstr: connect error");
}
@ -2162,10 +2238,14 @@
** Send the request to the server
*/
status = send (cnct_skt, (char *) request, requ_len, 0);
if (status == -1) failInet ("\nFS_send_cmnd_to_mstr -- send error");
if (status == -1) {
close(cnct_skt);
failInet ("\nFS_send_cmnd_to_mstr -- send error");
}
if (status != requ_len) {
printf ("\nFS_send_cmnd_to_mstr -- wrong number of bytes sent: %d %d\n",
status, requ_len);
close(cnct_skt);
return False;
}
*out_cntr += requ_len;
@ -2182,17 +2262,21 @@
p_nxt_byte += nbytes;
}
if (nbytes == -1) {
close(cnct_skt);
failInet ("\nFS_send_cmnd_to_mstr -- recv error");
return False;
}else if (nbytes == 0) {
printf ("\nFS_send_cmnd_to_mstr -- server has closed connection!\n");
close(cnct_skt);
return False;
}else if (ntohl (reply->bigend) != 0x12345678) {
/* Network byte-order wrong! */
printf ("\nFS_send_cmnd_to_mstr -- big-endian/little-endian problem!\n"
" Buffer received in non-network byte order!\n");
close(cnct_skt);
return False;
}
close(cnct_skt);
return True;
}
/*
@ -2333,6 +2417,8 @@
" -- socket error in socket_bind"));
return skt;
}
status = 1;
setsockopt(skt,SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int));
setup_host (NULL, &sockname, port, False);
status = bind (skt, (struct sockaddr *) &sockname, sizeof (sockname));
@ -2513,6 +2599,8 @@
sprintf (buff, "\n%s -- Cnct-Socket socket error", FS_name[0]);
failInet (buff);
}
status = 1;
setsockopt(FS_cnct_skt, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int));
setup_host (NULL, &lcl_sockname, FS_port, False);
status = bind (FS_cnct_skt, (struct sockaddr *) &lcl_sockname,
sizeof (lcl_sockname));

View File

@ -12,7 +12,7 @@
#------------ for DigitalUnix (add -DFORTIFY to CFLAGS for fortified version)
FF = f90
CC = cc
CFLAGS = -std -g -I. -I../hardsup -I$(PGPLOT_DIR)
CFLAGS = -std -g -I. -I../hardsup -I$(PGPLOT_DIR) -I/data/koenneck/include
BIN = $(HOME)/bin
LFLAGS = -L../hardsup -L$PGPLOT_DIR
#------------ for Linux

View File

@ -675,6 +675,7 @@
}
if (FillTimer_expired) {
/*
if (Print_hdr) printf ("\nTaking data in TOF Mode\n"
" #-Events #-Skip #-TSI Delay-Time Sync-Status\n");
Print_hdr = False;
@ -696,6 +697,7 @@
if (is != 0) {
printf ("%s -- failed to set timer\n", Filler_name);
}
*/
}
}
/* Our flag has been set. There should be ..

View File

@ -213,6 +213,9 @@
cnct_skt = socket (AF_INET, SOCK_STREAM, 0);
if (cnct_skt == -1)
failInet_port ("\nhmRoot%d -- Cnct-Socket socket error", Port_base);
status = 1;
setsockopt(cnct_skt, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int));
lcl_sockname.sin_family = AF_INET;
lcl_sockname.sin_port = htons (Port_base);
lcl_sockname.sin_addr.s_addr = 0;

View File

@ -2500,11 +2500,19 @@
** Output the given text and exit the process.
*/
int my_errno;
static int showMem = 0;
if(showMem == 0)
{
memShowInit();
showMem = 1;
}
getErrno (&my_errno);
printf ("### Internet Error ###\n");
printf (" ### errno = %d.\n", my_errno);
perror (text);
memShow(1);
exit (EXIT_FAILURE);
}
/*--------------------------------------------------------------------------*/

View File

@ -148,6 +148,8 @@
is = semGive (Sem_Server); /* Let our parent continue */
exit (KER__BAD_VALUE);
}
status = 1;
setsockopt(cnct_skt, SOL_SOCKET, SO_REUSEADDR, &status, sizeof(int));
my_lcl_sockname.sin_family = AF_INET;
my_lcl_sockname.sin_port = htons (port);

23
tas.h
View File

@ -91,8 +91,23 @@
#define ARX1 76
#define ARX2 77
#define MAXPAR 78
#define INST 78
#define TIT 79
#define USR 80
#define COM 81
#define ALF1 82
#define ALF2 83
#define ALF3 84
#define ALF4 85
#define BET1 86
#define BET2 87
#define BET3 88
#define BET4 89
#define OUT 90
#define LOC 91
#define MAXPAR 92
#define MAXADD 20
/* --------------------- data structure -------------------------------*/
@ -100,6 +115,12 @@ typedef struct {
pObjectDescriptor pDes;
pSicsVariable tasPar[MAXPAR];
pCounter counter;
pScanData pScan;
int iPOL;
int addOutput[MAXADD];
int addType[MAXADD];
int addCount;
int iFileNO;
}TASdata, *pTASdata;

36
tas.w
View File

@ -38,6 +38,12 @@ typedef struct {
pObjectDescriptor pDes;
pSicsVariable tasPar[MAXPAR];
pCounter counter;
pScanData pScan;
int iPOL;
int addOutput[MAXADD];
int addType[MAXADD];
int addCount;
int iFileNO;
}TASdata, *pTASdata;
@}
\begin{description}
@ -45,12 +51,21 @@ typedef struct {
object.
\item[floatPar] An array of pointers to float parameters.
The parameters are indexed through defined constants.
\item[counter] A pointer to the neutron counter.
\item[pScan] A pointer to a SICS scan object.
\item[iPOL] a flag which is non zer when polarisation analysis is
required.
\item[addOutput] TAS scans may have additional output fields besides
the scan variables in the scan data. This array holds the indices of
such variables.
\item[addType] This array holds the type of additional output
variables. This can be 0 for simple variables or 1 for a motor.
\item[addCount] is the number of additional output variables.
\item[iFileNO] is the number of the current data file.
\end{description}
The constants for the parameters are defined in the header file.
\subsubsection{Exported Functions}
These are mainly the interpreter inetrface functions:
These are mainly the interpreter interface functions:
@d tasfunc @{
int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]);
@ -156,8 +171,23 @@ These are mainly the interpreter inetrface functions:
#define ARX1 76
#define ARX2 77
#define MAXPAR 78
#define INST 78
#define TIT 79
#define USR 80
#define COM 81
#define ALF1 82
#define ALF2 83
#define ALF3 84
#define ALF4 85
#define BET1 86
#define BET2 87
#define BET3 88
#define BET4 89
#define OUT 90
#define LOC 91
#define MAXPAR 92
#define MAXADD 20
/* --------------------- data structure -------------------------------*/
@<tasdata@>

289
tascom.tcl Normal file
View File

@ -0,0 +1,289 @@
#---------------------------------------------------------------------------
# In order to run a triple axis spectrometer, SICS has to be made to behave
# like the ancinet MAD program from ILL. Some of the MAD commands had to
# be implemented in C (see tas*.c) but others can be implemented in Tcl.
# This file contains the procedures and command definitions for this syntax
# adaption from SICS to MAD.
#
# Mark Koennecke, December 2000
#--------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Perform initialization, but only on first go
if { [info exists tasinit] == 0 } {
set tasinit 1
SicsAlias fileeval do User
Publish ou User
Publish fi User
Publish cl User
}
#--------------------------------------------------------------------------
# a list of motors, needed at various stages in this
set tasmot { a1 a2 a3 a4 a5 a6 mcv sro ach mtl mtu stl stu atu mgl sgl \
sgu agu agl}
#-------------------------------------------------------------------------
# some MAD variables can be directly mapped to internal SICS variables
# This mapping is done here through a mapping array
for {set i 0} {$i < [llength $tasmot]} { incr i } {
set mot [lindex $tasmot $i]
set tasmap(l$mot) [format "%s softlowerlim " $mot]
set tasmap(u$mot) [format "%s softupperlim " $mot]
}
#------------------------------------------------------------------------
# quite often we need to split a SICS answer of the form x = y and
# extract the y. This is done here.
proc tasSplit {text} {
set list [split $text =]
return [lindex $list 1]
}
#-------------------------------------------------------------------------
# motor zero points are handled differently in SICS and MAD:
# - MAD zero's are of opposite sign to SICS
# - Setting a MAD zero point also changes the limits.
# This function takes care of these issues.
proc madZero args {
set length [llength $args]
if { $length < 1} {
error "ERROR: expected at least motor name as a parameter to madZero"
}
set mot [lindex $args 0]
if {$length == 1 } {
#inquiry case
set zero [tasSplit [$mot softzero]]
return [expr -$zero]
} else {
# a new value has been given.
set val [lindex $args 1]
set val [expr -$val]
set zero [tasSplit [$mot softzero]]
set low [tasSplit [$mot softlowerlim]]
set high [tasSplit [$mot softupperlim]]
set displacement [expr $val - $zero]
$mot softzero $val
$mot softupperlim [expr $high + $displacement]
$mot softlowerlim [expr $low + $displacement]
}
}
#--------------------------------------------------------------------------
# This routine throws an error if a bad value for fx is given
proc fxi {val} {
if { $val != 1 && $val != 2} {
error "ERROR: Invalid value $val for parameter FX"
} else {
fx $val
}
}
#-------------------------------------------------------------------------
# Changing the scattering sense implies a change of the corresponding
# motors softzero as well: it is rotated by 180 degree. This is done
# by this function
proc scatSense {par val} {
switch $par {
ss {
set mot a3
}
sa {
set mot a5
}
sm {
set mot a1
}
default {
error "ERROR: unknown scattering sense $par"
}
if {$val != 1 && $val != -1 } {
error "ERROR: invalid scattering sense $val"
}
set oldzero [madZero $mot]
madZero $mot [expr 180 + $oldzero]
$par $val
}
#--------------------------------------------------------------------------
# The output command
proc ou args {
if {[llength $args] == 0 } {
output ""
}else {
output [join $args]
}
}
#--------------------------------------------------------------------------
# typeATokenizer extracts tokens from acpmmand string. Tokens can be
# either variable names or - indicating a series of variables.
# Returns the token value or END if the end of the string text is
# reached. Uses and updates a variable pos which indicates the current
# position in the string.
proc typeATokenizer {text pos} {
upvar pos p
set l [string length $text]
#------- check for end
if {$p >= $l} {
return END
}
#-------- skip spaces
for {} {$p < $l} {incr p} {
set c [string index $text $p]
if {$c == "-" } {
incr p
return "-"
}
if { $c != " " && $c != "," } {
break
}
}
if {$p >= $l} {
return END
}
#---- extract token
set start $p
#---- proceed to next terminator
for {} {$p < $l} {incr p} {
set c [string index $text $p]
if { $c == " " || $c == "," || $c == "-" } {
break
}
}
set stop [expr $p - 1]
return [string range $text $start $stop]
}
#---------------------------------------------------------------------------
# The cl(ear) command for unfixing motors
proc cl args {
global tasmot
if {llength $args] == 0} {
#------ clear all fixed motors
foreach m $tasmot {
if { [tasSplit [$m fixed]] > 0 } {
clientput [format "%s unfixed" $m]
$m fixed -1
}
}
}
#------ trying to clear individual fixed motors
set command [join $args]
set command [string tolower $command]
set pos 0
set token [typeATokenizer $command $pos]
while {[string compare $token END] != 0 } {
set last $token
if {$token == "-" } {
set l [llength $tasmot]
#------ handle a range, first find start
for {set start 0} {$start < $l} {incr start} {
set e [lindex $tasmot $start]
if { [string compare $e $last] == 0} {
incr start
break
}
}
if { $start >= $l} {
error [format "ERROR: %s is no motor" $last]
}
#---------- next token is range stop
set stop [typeATokenizer $command $pos]
#---------- now continue to loop until stop is found, thereby unfixing
for {set i $start} { $i < $l} {incr i} {
set e [lindex $tasmot $i]
set ret [catch {$e fixed -1} msg]
if {$ret != 0} {
error [format "ERROR: %s is no motor" $e]
} else {
clientput [format "$s unfixed" $e]
}
if {[string compare $e $stop] == 0 } {
return
}
}
}
#------ should be a single motor here
set ret [catch {$token fixed -1} msg]
if {$ret != 0} {
error [format "ERROR: %s is no motor" $token]
} else {
clientput [format "$s unfixed" $token]
}
#------- do not forget to proceed
set token [typeATokenizer $command $pos]
}
}
#------------------------------------------------------------------------
# fi fix motor command
proc fi args {
global tasmot
if {llength $args] == 0} {
#------ list all fixed motors
foreach m $tasmot {
if { [tasSplit [$m fixed]] > 0 } {
clientput [format "%s fixed" $m]
}
}
}
#------ parse motors to fix
set command [join $args]
set command [string tolower $command]
set pos 0
set token [typeATokenizer $command $pos]
while {[string compare $token END] != 0 } {
set last $token
if {$token == "-" } {
set l [llength $tasmot]
#------ handle a range, first find start
for {set start 0} {$start < $l} {incr start} {
set e [lindex $tasmot $start]
if { [string compare $e $last] == 0} {
incr start
break
}
}
if { $start >= $l} {
error [format "ERROR: %s is no motor" $last]
}
#---------- next token is range stop
set stop [typeATokenizer $command $pos]
#---------- now continue to loop until stop is found, thereby fixing
for {set i $start} { $i < $l} {incr i} {
set e [lindex $tasmot $i]
set ret [catch {$e fixed 1} msg]
if {$ret != 0} {
error [format "ERROR: %s is no motor" $e]
} else {
clientput [format "$s fixed" $e]
}
if {[string compare $e $stop] == 0 } {
return
}
}
}
#------ should be a single motor here
set ret [catch {$token fixed 1} msg]
if {$ret != 0} {
error [format "ERROR: %s is no motor" $token]
} else {
clientput [format "$s fixed" $token]
}
#------- do not forget to proceed
set token [typeATokenizer $command $pos]
}
}

View File

@ -21,9 +21,10 @@
#include "sicsvar.h"
#include "counter.h"
#include "motor.h"
#include "scan.h"
#include "splitter.h"
#include "tas.h"
#include "tasu.h"
#include "splitter.h"
/* a token break function, implemented in stptok.c */
@ -79,6 +80,13 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData,
self = (pTASdata)pData;
assert(self);
/*
check authorization
*/
if(!SCMatchRights(pCon,usUser))
return 0;
/* Initialize */
Arg2Text(argc, argv,pLine,255);
strtolower(pLine);
@ -180,7 +188,7 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData,
{
sprintf(pBueffel,"Driving %s to %f",
tasMotorOrder[i],newPositions[i]);
SCWrite(pCon,pBueffel,eValue);
SCWrite(pCon,pBueffel,eWarning);
status = StartMotor(pServ->pExecutor,pSics,pCon,
tasMotorOrder[i],newPositions[i]);
if(status == 0)
@ -209,7 +217,7 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData,
{
sprintf(pBueffel,"Driving %s to %f", tasVariableOrder[EI+i],
self->tasPar[EI+i]->fVal);
SCWrite(pCon,pBueffel,eValue);
SCWrite(pCon,pBueffel,eWarning);
}
}
/*
@ -221,7 +229,7 @@ int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData,
{
sprintf(pBueffel,"Driving %s to %f",tasMotorOrder[i],
tasTargets[i]);
SCWrite(pCon,pBueffel,eValue);
SCWrite(pCon,pBueffel,eWarning);
}
}
/*

View File

@ -21,6 +21,8 @@
#include "sicsvar.h"
#include "counter.h"
#include "motor.h"
#include "scan.h"
#include "scan.i"
#include "tas.h"
/*
@ -132,6 +134,20 @@ extern char *tasVariableOrder[] = {
"mrx2",
"arx1",
"arx2",
"instrument",
"title",
"user",
"lastcommand",
"alf1",
"alf2",
"alf3",
"alf4",
"bet1",
"bet2",
"bet3",
"bet4",
"output",
"local",
NULL};
/*---------------------------------------------------------------------
There is a special feauture in MAD where the count mode is determined
@ -148,7 +164,8 @@ static int MonitorCallback(int iEvent, void *pEvent, void *pUser)
if(iEvent != VALUECHANGE)
return 0;
SetCounterMode(self->counter,ePreset);
SetCounterMode(self->pScan->pCounterData,ePreset);
SetCounterPreset(self->pScan->pCounterData,self->tasPar[MN]->fVal);
return 1;
}
@ -160,7 +177,8 @@ static int TimerCallback(int iEvent, void *pEvent, void *pUser)
if(iEvent != VALUECHANGE)
return 0;
SetCounterMode(self->counter,eTimer);
SetCounterMode(self->pScan->pCounterData,eTimer);
SetCounterPreset(self->pScan->pCounterData,self->tasPar[TI]->fVal);
return 1;
}
/*-----------------------------------------------------------------------
@ -186,6 +204,13 @@ int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
pSicsVariable pVar = NULL;
CommandList *pCom = NULL;
/* check arguments*/
if(argc < 2)
{
SCWrite(pCon,"ERROR: insufficient paarameters to MakeTAS",eError);
return 0;
}
/* create a new data structure */
pNew = (pTASdata)malloc(sizeof(TASdata));
if(!pNew)
@ -203,6 +228,7 @@ int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
free(pNew);
return 0;
}
pNew->iPOL = -1;
/* connect to all the variables */
iPtr = 0; iError = 0;
@ -227,15 +253,15 @@ int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
return 0;
}
/* connect to the counter */
pCom = FindCommand(pSics,"counter");
/* connect to the scan object */
pCom = FindCommand(pSics,argv[1]);
if(!pCom)
{
SCWrite(pCon,"ERROR: no neutron counter for TAS found",eError);
SCWrite(pCon,"ERROR: no scan routine for TAS found",eError);
TASKill(pNew);
return 0;
}
pNew->counter = pCom->pData;
pNew->pScan = (pScanData)pCom->pData;
/*
Install the callbacks for TI and MN. Sloppy error checking because
@ -260,7 +286,6 @@ int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
TASKill(pNew);
return 0;
}
/*
iError = AddCommand(pSics,"sc",TASScan,NULL,pNew);
if(!iError)
{
@ -268,6 +293,7 @@ int TASFactory(SConnection *pCon, SicsInterp *pSics, void *pData,
TASKill(pNew);
return 0;
}
/*
iError = AddCommand(pSics,"set",TASSet,NULL,pNew);
if(!iError)
{

1358
tasscan.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
#include "sicsvar.h"
#include "counter.h"
#include "motor.h"
#include "scan.h"
#include "tas.h"
#include "tasu.h"
@ -86,10 +87,6 @@ isTASEnergy(char *val)
{
return iPtr-EMIN;
}
else
{
iPtr++;
}
}
return -1;
}
@ -304,6 +301,17 @@ int TASCalc(pTASdata self, SConnection *pCon,
ism = (integer)self->tasPar[SM]->iVal;
isa = (integer)self->tasPar[SA]->iVal;
/*
initialize the helmholts currents. This needs work when
polarisation anlaysis is really supported.
*/
for(i = 0; i < 4; i++)
{
helmconv[i] = .0;
currents[i] = .0;
currents[i+4] = .0;
}
/*
initalise the motorMasks to 0.
*/
@ -449,7 +457,7 @@ int TASStart(pTASdata self, SConnection *pCon, SicsInterp *pSics,
return 0;
}
}
if(motorMask[9])
if(motorMask[8])
{
status = StartMotor(pServ->pExecutor,pSics,pCon,
"ACH", motorTargets[8]);