From 0fac95ea9b0f36839fb4e542622e135b1fe2c287 Mon Sep 17 00:00:00 2001 From: cvs Date: Fri, 20 Jul 2001 08:05:25 +0000 Subject: [PATCH] - 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 --- Makefile | 2 +- danu.dat | 2 +- doc/manager/hwini.htm | 41 ++++++- doc/manager/ini.htm | 20 +++- doc/manager/manager.htm | 1 - doc/manager/option.htm | 7 +- doc/manager/setup.htm | 110 +++++++++++++++++- doc/user/trics.htm | 21 ++-- doc/user/tricsman | 2 +- faverage.c | 231 +++++++++++++++++++++++++------------ histmem.c | 8 ++ hkl.c | 170 ++++----------------------- nextrics.c | 62 +++++++--- scan.c | 97 +++++++++++++++- scan.h | 11 ++ scan.i | 2 + scan.tex | 28 ++++- scan.w | 28 ++++- sicsstatus.tcl | 16 +-- sinqhm/SinqHM_srv_filler.c | 10 +- test.tcl | 225 +----------------------------------- trics.dic | 24 ++-- userscan.c | 75 ++++++++++++ userscan.h | 19 +++ userscan.w | 51 ++++++++ 25 files changed, 741 insertions(+), 522 deletions(-) create mode 100644 userscan.c create mode 100644 userscan.h create mode 100644 userscan.w diff --git a/Makefile b/Makefile index 59de78ee..ce97a512 100644 --- a/Makefile +++ b/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 diff --git a/danu.dat b/danu.dat index 134b8581..2142b97b 100644 --- a/danu.dat +++ b/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 \ No newline at end of file diff --git a/doc/manager/hwini.htm b/doc/manager/hwini.htm index c385da7b..00a67819 100644 --- a/doc/manager/hwini.htm +++ b/doc/manager/hwini.htm @@ -34,7 +34,8 @@ The following commands are available to install motors into the system:
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.
Motor name EL734 host port chan no
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. +
MakePIMotor name c804 pararray +
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: +
+
Computer, port, channel +
The standard connection parameters. +
upperlimit, lowerlimit +
The limits for this motor. +
motor +
The number of the motor in the motor controller. +
+
Motor name pipiezo pararray +
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.

Counting Devices

-
MakeCounter name SIM +
MakeCounter name SIM failrate
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.
MakeCounter name EL737 host port chan
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.
+
MakeHMControl name counter hm1 hm2 hm3 +
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: +
+
name +
The name of the virtual counter in SICS +
counter The name of the master counter +
hm1, hm2, hm3 +
Up to three slave counting devices. +
+

+

Histogram Memory

Due to the large amount of parameters, histogram memories are configured diff --git a/doc/manager/ini.htm b/doc/manager/ini.htm index 89f2d181..c8ec5fae 100644 --- a/doc/manager/ini.htm +++ b/doc/manager/ini.htm @@ -34,6 +34,24 @@ file) may use special commands for the installation of:

  • Hardware

    - +

    +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: +

    +
    inst.tcl +
    Replace inst with the name of the instrument in lowercase. This is +the main initialization file. It should contain all the hardware +initialization. +
    instcom.tcl +
    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. +
    scancommand.tcl, tecs.tcl, log.tcl +
    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. +
    +

    diff --git a/doc/manager/manager.htm b/doc/manager/manager.htm index d9af7741..eea0cb83 100644 --- a/doc/manager/manager.htm +++ b/doc/manager/manager.htm @@ -35,7 +35,6 @@ which is described elsewhere.
    • To the general setup section.
    • To the server initialision section. -
    • To the client configuration section.
    • To the section describing special commands for SICS administrators or programmers.
    • Commands for status display support. diff --git a/doc/manager/option.htm b/doc/manager/option.htm index 087a79d3..3ebdea60 100644 --- a/doc/manager/option.htm +++ b/doc/manager/option.htm @@ -44,7 +44,7 @@ SICSINT followed by an interrupt number. For interrupt numbers see file interrupt.h.
    • DefaultTclDirectory specifies where Tcl defined commands are stored. When this is properly defined Tcl will autoload commands. -
    • StatusFile defines the file to which he current state will be +
    • statusfile defines the file to which he current state will be saved on close down of the server and restored from at startup time.
    • TelnetPort 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.
    • LogFileDir This server option defines the directory where commandlog log files are kept. +
    • RedirectFile This defines a filename to which all output to +stdout and stderr is logged by the SICS server. This is mainly a +debugging feature. +
    • TecsPort The port number at which the Tecs temperature +control server is listening.

    diff --git a/doc/manager/setup.htm b/doc/manager/setup.htm index c77f91c8..fee8d4cf 100644 --- a/doc/manager/setup.htm +++ b/doc/manager/setup.htm @@ -1,8 +1,78 @@ -General SICS Setup +SICS Setup +

    SICS programs, Scripts and Prerequisites

    +

    +

    Hardware

    +The following hardware is usually present for any SICs instrument: +
      +
    • An instrument computer +
    • A Lantronix terminal server with 8-16 serial ports for connecting: +
    • Motor controllers +
    • Counter boxes +
    • Temperature controllers. +
    • Optionally 1-n histogram memory computers are present. +
    +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. +

    +

    Server programs

    +

    +On the instrument computer the following software must run: +

    +
    SerPortServer +
    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. +
    TecsServer +
    This is a TCP/IP server which watches over temperature +controllers. The only knwon source of documentation about this +software is Markus Zolliker. +
    FileSync +
    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. +
    SICServer +
    This is the actual instrument control server. The configuration of +this program is documented in this manual. +
    +Additionally a client program is needed which connects to the +instrument control server and provides a user interface to it. +

    + +

    Scripts

    +

    +To get all this software up and running a couple of shell scripts have +been provided: +

    +
    startsics +
    This script starts all the necessary server programs for driving +the instrument. +
    killsics +
    This script shuts down all instrument control servers properly. +
    keepalice, keepaliveserp +
    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. +
    instsync +
    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. +
    +

    +

    General SICS Setup

    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.

    data
    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.
    log
    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.
    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. +
    motor +
    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. 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 into her .login file.

    SICS Installation

    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 sicsinstall korn shell script. This @@ -74,6 +157,23 @@ directory. This command is meant to be used by computing staff only.

    copies all files necessary for the instrument TOPSI.
    sans
    copies all files necessary for the instrument SANS. +
    hrpt +
    copies all files necessary for the instrument HRPT. +
    amor +
    copies all files necessary for the instrument AMOR +
    focus +
    copies all files necessary for the instrument FOCUS +
    tasp +
    copies all files necessary for the instrument TASP +
    druechal +
    copies all files necessary for the instrument DRUECHAL +
    trics +
    copies all files necessary for the instrument TRICS +
    save inst +
    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.
    doc
    updates only the documentation on your disk.
    exe diff --git a/doc/user/trics.htm b/doc/user/trics.htm index 5c7ba1d8..d685bd8d 100644 --- a/doc/user/trics.htm +++ b/doc/user/trics.htm @@ -6,25 +6,26 @@

    The Four Circle Diffractometer TRICS

    Introduction

    -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.

    -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 diff --git a/doc/user/tricsman b/doc/user/tricsman index 44dc0fc4..f45d0005 100644 --- a/doc/user/tricsman +++ b/doc/user/tricsman @@ -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\\ diff --git a/faverage.c b/faverage.c index 7c0a1ae2..9a147066 100644 --- a/faverage.c +++ b/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 #include @@ -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; + } diff --git a/histmem.c b/histmem.c index ec301277..86f50877 100644 --- a/histmem.c +++ b/histmem.c @@ -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) { diff --git a/hkl.c b/hkl.c index 7b049f93..3d72ed62 100644 --- a/hkl.c +++ b/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 */ diff --git a/nextrics.c b/nextrics.c index 646947e6..6677b386 100644 --- a/nextrics.c +++ b/nextrics.c @@ -14,6 +14,7 @@ Mark Koennecke, April 1998 Revised: Mark Koennecke, October 2000 + Revised: Mark Koennecke, July 2001 ----------------------------------------------------------------------------*/ #include #include @@ -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); diff --git a/scan.c b/scan.c index 4017c706..6acc89a3 100644 --- a/scan.c +++ b/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", diff --git a/scan.h b/scan.h index eb2b26cb..1304f4fe 100644 --- a/scan.h +++ b/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[]); diff --git a/scan.i b/scan.i index 03e752f1..4b059e60 100644 --- a/scan.i +++ b/scan.i @@ -62,3 +62,5 @@ void *pSpecial; } ScanData; + + diff --git a/scan.tex b/scan.tex index 27fb5393..48bcd39c 100644 --- a/scan.tex +++ b/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 diff --git a/scan.w b/scan.w index b41bff28..d99a931a 100644 --- a/scan.w +++ b/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 diff --git a/sicsstatus.tcl b/sicsstatus.tcl index fa848d29..65281dad 100644 --- a/sicsstatus.tcl +++ b/sicsstatus.tcl @@ -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 diff --git a/sinqhm/SinqHM_srv_filler.c b/sinqhm/SinqHM_srv_filler.c index f16b7673..405e1bc6 100755 --- a/sinqhm/SinqHM_srv_filler.c +++ b/sinqhm/SinqHM_srv_filler.c @@ -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); diff --git a/test.tcl b/test.tcl index 6be643f5..3f38f810 100644 --- a/test.tcl +++ b/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 diff --git a/trics.dic b/trics.dic index fc590ac6..0e5fe9b7 100644 --- a/trics.dic +++ b/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} diff --git a/userscan.c b/userscan.c new file mode 100644 index 00000000..5579db35 --- /dev/null +++ b/userscan.c @@ -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 +#include +#include +#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; +} diff --git a/userscan.h b/userscan.h new file mode 100644 index 00000000..c9bd09c0 --- /dev/null +++ b/userscan.h @@ -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 diff --git a/userscan.w b/userscan.w new file mode 100644 index 00000000..fd7fa773 --- /dev/null +++ b/userscan.w @@ -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 + +@ + +#endif +@}