- 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
328 lines
16 KiB
OpenEdge ABL
328 lines
16 KiB
OpenEdge ABL
\subsection{Scan}
|
|
The first version of the scan command was implemented in Tcl. This prooved
|
|
to be inefficient. Therefore the main loop for scan was reimplemented in
|
|
C. A scan is in principle simple. However some complications are due to the
|
|
fact that data files need to be written. Disk files need to be updated after
|
|
each scan point. It must be possible to create derivations of the scan
|
|
command which create other data formats or scan strategies. This
|
|
configurability is catered for the function pointers in the ScanData
|
|
structure. Individual functions can be exchanged and thus differently
|
|
behaving scans created.
|
|
|
|
|
|
Another complication is, that users might want to interrupt scans and
|
|
restart from the last safe position. For this purpose
|
|
there exists the recover option.
|
|
|
|
Scan also uses a scheme for creating scan data data files from a
|
|
template. For more information about the template file see the SICS Managers
|
|
documentation.
|
|
|
|
There are currently two schemes for modifying scans: The first works
|
|
by implementing different scan handling functions and to assign them
|
|
to the function pointers in the ScanData structure. The second works
|
|
by defining a macro which will be called at each scan point and which
|
|
has to return the a list with the counts and monitors collected.
|
|
|
|
This has grown to be overly complex. A path for a redesign might
|
|
follow the idea of configurable functions to be called at various
|
|
steps in scan processing which is already partly implemented.
|
|
|
|
|
|
@d scandata @{
|
|
typedef struct {
|
|
char Name[132];
|
|
pIDrivable pInter;
|
|
pDummy pObject;
|
|
float fStart;
|
|
float fStep;
|
|
float *fData;
|
|
}VarEntry, *pVarEntry;
|
|
/*--------------------------------------------------------------------------*/
|
|
typedef struct {
|
|
int i;
|
|
long lCount;
|
|
long Monitors[10];
|
|
float fTime;
|
|
} CountEntry, *pCountEntry;
|
|
/*---------------------------------------------------------------------------*/
|
|
typedef struct __ScanData {
|
|
pObjectDescriptor pDes;
|
|
pICallBack pCall;
|
|
pDynar pScanVar;
|
|
int iScanVar;
|
|
int iNP;
|
|
int iMode;
|
|
float fPreset;
|
|
char pFile[1024];
|
|
char ext[5];
|
|
FILE *fd;
|
|
SicsInterp *pSics;
|
|
SConnection *pCon;
|
|
char pRecover[1024];
|
|
char pHeaderFile[1024];
|
|
int (*PrepareScan)(pScanData self);
|
|
int (*WriteHeader)(pScanData self);
|
|
int (*WriteScanPoints)
|
|
(pScanData self,
|
|
int iPoint);
|
|
int (*ScanDrive)(pScanData self,
|
|
int i);
|
|
int (*ScanCount)(pScanData self,
|
|
int i);
|
|
int (*CollectScanData)
|
|
(pScanData self,
|
|
int iP);
|
|
long lPos;
|
|
void *pCounterData;
|
|
char pCounterName[512];
|
|
int iChannel;
|
|
pDynar pCounts;
|
|
int iCounts;
|
|
int iActive;
|
|
int iWindow;
|
|
char *pCommand;
|
|
void *pSpecial;
|
|
} ScanData;
|
|
@}
|
|
|
|
The VarEntry structure holds the data for each single scan variable.
|
|
These are its name, its object data structures, the start and step
|
|
values for the scan and in fData the positions actually reached during
|
|
the scan.
|
|
|
|
The CountEntry structure holds the entries for one counting
|
|
operations. These are the lCounts collected, up to 10 monitors and the
|
|
time needed for counting. This is the time read from the counter box.
|
|
|
|
The ScanData datastructure contains the following fields:
|
|
\begin{description}
|
|
\item[pDes] The standard SICS object descriptor.
|
|
\item[pCall] A pointer to the standard SICS callback interface. Scan support
|
|
the SCANPOINT message which will be executed after each
|
|
scan point.
|
|
\item[pScanVar, iScanVar] A dynamic array of VarEntry structures which
|
|
define the variables to drive in the scan. iScanVar is the total number of
|
|
scan variables. A scan might drive more then one motor or variable.
|
|
\item[iNP] is the number of scan points.
|
|
\item[iMode] is the counter mode to use.
|
|
\item[fPreset] is the preset value for the counter at each scan point. The
|
|
exponents set for the counter apply.
|
|
\item[pFile] is the name of the data file to write. This will be created
|
|
automatically from SICS variables at the start of a scan.
|
|
\item[fd] is the file descriptor for the open file when writing. fd will
|
|
be opened by WriteHeader and closed again after WriteScanPoints.
|
|
\item[pRecover] is the name of the recover file. After each scan point scan
|
|
writes some data to file which allows to restart an aborted scan.
|
|
\item[pHeaderFile] is the name of a template file which will be used for
|
|
generating the scan file header. Its format is simple: Everything except a
|
|
few keywords will be copied verbatim. The keywords will be replaced by their
|
|
apropriate values. Valid keywords are: !!DATE!! for the current date,
|
|
!!VAR(name)!! for the value of a simple Sics variable, !!DRIV(name)!! for a Sics scan
|
|
variable. The name of the variable is given in parenthesis.
|
|
!!VAR!! and !!DRIV!! can be distinguished easily: Try a run or
|
|
drive command on the variable in question. If it works and does not
|
|
complain, it is the second sort. The second sort are mostly motors or
|
|
collective variables such as lambda etc. Only one value of such a type per
|
|
line is permitted.
|
|
\item[pSics] a pointer to a SICS interpreter to use while running for
|
|
finding data.
|
|
\item[pCon] The connection object to use for error reporting during scan
|
|
execution.
|
|
\item[PrepareScan] checks limits of scan variables and memorizes
|
|
important scan information. Sometimes this is not wanted, that is why
|
|
it is parametrized here.
|
|
\item[WriteHeader] is a pointer to a function which writes the header part
|
|
of the scan file. Replace this function if another data format is needed.
|
|
\item[WriteScanPoints] is a pointer to a function which will be called after
|
|
each scan point to write the scan data to the data file. Replace this
|
|
function when another data format is needed.
|
|
\item[ScanDrive] is executed when the next point of a scan has to be reached.
|
|
i is the point of the scan.
|
|
\item[ScanCount] is executed when a scan point had been reached and a
|
|
counting operation has to be performed. i is the scan point where we are.
|
|
This function together with ScanDrive and the data writing functions allow for
|
|
customized scans.
|
|
\item[CollectScanData] reads all the scan data into the scan's data
|
|
structures after any scan point. Overload this if a different storage
|
|
scheme is required especiallay for polarising scans.
|
|
\item[pCounterData] is a pointer to a counter structure. This defines the
|
|
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 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, 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}
|
|
|
|
The functional interface to the scan module includes the following
|
|
functions:
|
|
|
|
@d scaninter @{
|
|
/*------------------------- live & death ----------------------------------*/
|
|
pScanData CreateScanObject(char *pRecover, char *pHeader,
|
|
pCounter pCount);
|
|
void DeleteScanObject(void *self);
|
|
/*-------------------------------------------------------------------------*/
|
|
int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
|
char *name, float fStart, float fStep);
|
|
int ClearScanVar(pScanData self);
|
|
|
|
int DoScan(pScanData self, int iNP, int iMode, float fPreset,
|
|
SicsInterp *pSics, SConnection *pCon);
|
|
int SilentScan(pScanData self, int iNP, int iMode, float fPreset,
|
|
SicsInterp *pSics, SConnection *pCon);
|
|
int RecoverScan(pScanData self, SicsInterp *pSics, SConnection *pCon);
|
|
|
|
int GetScanCounts(pScanData self, long *lData, int iDataLen);
|
|
int GetScanVar(pScanData self, int iWhich, float *fData, int iDataLen);
|
|
int GetSoftScanVar(pScanData self, int iWhich, float *fData, int iDataLen);
|
|
|
|
int GetScanVarName(pScanData self, int iWhich,
|
|
char *pName, int iLength);
|
|
int GetScanVarStep(pScanData self, int iWhich,
|
|
float *fStep);
|
|
int GetScanMonitor(pScanData self, int iWhich,
|
|
long *lData, int iDataLen);
|
|
int GetScanNP(pScanData self);
|
|
float GetScanPreset(pScanData self);
|
|
|
|
int ScanIntegrate(pScanData self, float *fSum, float *fVariance);
|
|
|
|
int SimScan(pScanData self, float fPos, float FHWM, float fHeight);
|
|
/*
|
|
creates a simulated gaussian shaped peak with the parameters given.
|
|
*/
|
|
int ResetScanFunctions(pScanData self);
|
|
/*
|
|
resets the configurable scan functions to their default values.
|
|
*/
|
|
int NonCheckPrepare(pScanData self);
|
|
/*
|
|
a function for the PrepareScan field in the scan data structure
|
|
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[]);
|
|
|
|
int ScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
|
int argc, char *argv[]);
|
|
|
|
@}
|
|
All functions take a pointer to a ScanData structure as their first
|
|
parameter. The functions:
|
|
\begin{description}
|
|
\item[CreateScanObject] creates a scan object. The parameters are the
|
|
path to a recovery file, the path to a template file for file
|
|
generation and a pointer to a counter object.
|
|
\item[DeleteScanObject] removes the ScanData structure from memory
|
|
properly.
|
|
\item[AddScanVar] adds a variable to be scanned. Parameters are the
|
|
name of the scan variable, the start and step values for the scan and
|
|
a connection object to which errors shall be printed.
|
|
\item[ClearScanVar] clears all scan variables.
|
|
\item[DoScan] performs the actual scan. Parameters are the number of
|
|
points, the counter mode and preset, the connection object for which
|
|
the scan is done and the SICS interpreter executing the scan command.
|
|
\item[SilentScan] does the same as DoScan but suppresses all output to
|
|
data files. This is good for internal scans as in the optimize or
|
|
mesure modules.
|
|
\item[RecoverScan] loads the data about an aborted scan from the
|
|
recovery file and continues to execute it. This most certainly will
|
|
not work with custom scans. But is known to work with SICS TOPSI like
|
|
standard scans.
|
|
\item[GetScanCounts] allows to retrieve the counts collected in the
|
|
scan. Max iDatLen entries will be copied into lData.
|
|
\item[GetScanVar] retrieves the scan positions for the scan variable
|
|
number i. Max iDatLen entries get copied into fData.
|
|
\item[GetSoftScanVar] retrieves the scan positions for the scan variable
|
|
number i. The soft positions are retrieved, not the hard position stored
|
|
during the scan.
|
|
\item[GetScanVarName] retrieves the name of scan variable i.
|
|
\item[GetScanVarStep] gets the step of the scan variable i.
|
|
\item[GetScanMonitor] allows to retrieve the monitor counts collected
|
|
in monitor i during the
|
|
scan. Max iDatLen entries will be copied into lData.
|
|
\item[GetScanNP] returns the number of points in the scan.
|
|
\item[GetScanPreset] returns the counter preset value for the scan.
|
|
\item[ScanIntegrate] integrates the peak after a scan. Returns the
|
|
summed counts and the variance. See the section on integrate for more
|
|
details.
|
|
\item[ResetScanFunctions] reinstalls the default functions for scan
|
|
processing into the ScanData structure.
|
|
\item[NonCheckPrepare] Before a scan is started, various data
|
|
structures in the scan object are initialized. Thereby the scan
|
|
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
|
|
for the scan object.
|
|
\item[ScanWrapper] is the SICS interpreter object function for
|
|
interacting with the scan module.
|
|
\end{description}
|
|
@o scan.h @{
|
|
/*---------------------------------------------------------------------------
|
|
S C A N
|
|
|
|
Header file for the SICS scan object.
|
|
|
|
Mark Koennecke, October 1997
|
|
|
|
copyright: see copyright.h
|
|
-----------------------------------------------------------------------------*/
|
|
#ifndef SICSSCAN1
|
|
#define SICSSCAN1
|
|
typedef struct __ScanData *pScanData;
|
|
/*--------------------------------------------------------------------------*/
|
|
#include "counter.h"
|
|
@<scaninter@>
|
|
#endif
|
|
@}
|
|
|
|
@o scan.i @{
|
|
/*--------------------------------------------------------------------------
|
|
Internal header file holding the definition of the scan objects data
|
|
structure.
|
|
|
|
Mark Koennecke, October 1997
|
|
----------------------------------------------------------------------------*/
|
|
#include "sdynar.h"
|
|
@<scandata@>
|
|
@}
|
|
|
|
|
|
|
|
|