Initial revision
This commit is contained in:
329
scan.tex
Normal file
329
scan.tex
Normal file
@ -0,0 +1,329 @@
|
||||
\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.
|
||||
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap1}
|
||||
$\langle$scandata {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ char Name[132];@\\
|
||||
\mbox{}\verb@ pIDrivable pInter;@\\
|
||||
\mbox{}\verb@ pDummy pObject;@\\
|
||||
\mbox{}\verb@ float fStart;@\\
|
||||
\mbox{}\verb@ float fStep;@\\
|
||||
\mbox{}\verb@ float *fData;@\\
|
||||
\mbox{}\verb@ }VarEntry, *pVarEntry;@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ typedef struct {@\\
|
||||
\mbox{}\verb@ int i;@\\
|
||||
\mbox{}\verb@ long lCount;@\\
|
||||
\mbox{}\verb@ long Monitors[10];@\\
|
||||
\mbox{}\verb@ float fTime;@\\
|
||||
\mbox{}\verb@ } CountEntry, *pCountEntry;@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------*/ @\\
|
||||
\mbox{}\verb@ typedef struct __ScanData {@\\
|
||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||
\mbox{}\verb@ pICallBack pCall;@\\
|
||||
\mbox{}\verb@ pDynar pScanVar;@\\
|
||||
\mbox{}\verb@ int iScanVar;@\\
|
||||
\mbox{}\verb@ int iNP;@\\
|
||||
\mbox{}\verb@ int iMode;@\\
|
||||
\mbox{}\verb@ float fPreset;@\\
|
||||
\mbox{}\verb@ char pFile[1024];@\\
|
||||
\mbox{}\verb@ char ext[5];@\\
|
||||
\mbox{}\verb@ FILE *fd;@\\
|
||||
\mbox{}\verb@ SicsInterp *pSics;@\\
|
||||
\mbox{}\verb@ SConnection *pCon;@\\
|
||||
\mbox{}\verb@ char pRecover[1024];@\\
|
||||
\mbox{}\verb@ char pHeaderFile[1024];@\\
|
||||
\mbox{}\verb@ int (*WriteHeader)(pScanData self);@\\
|
||||
\mbox{}\verb@ int (*WriteScanPoints)@\\
|
||||
\mbox{}\verb@ (pScanData self, @\\
|
||||
\mbox{}\verb@ int iPoint);@\\
|
||||
\mbox{}\verb@ int (*ScanDrive)(pScanData self, @\\
|
||||
\mbox{}\verb@ int i);@\\
|
||||
\mbox{}\verb@ int (*ScanCount)(pScanData self,@\\
|
||||
\mbox{}\verb@ int i);@\\
|
||||
\mbox{}\verb@ int (*CollectScanData)@\\
|
||||
\mbox{}\verb@ (pScanData self,@\\
|
||||
\mbox{}\verb@ int iP);@\\
|
||||
\mbox{}\verb@ long lPos;@\\
|
||||
\mbox{}\verb@ void *pCounterData;@\\
|
||||
\mbox{}\verb@ char pCounterName[512];@\\
|
||||
\mbox{}\verb@ int iChannel;@\\
|
||||
\mbox{}\verb@ pDynar pCounts;@\\
|
||||
\mbox{}\verb@ int iCounts;@\\
|
||||
\mbox{}\verb@ int iActive;@\\
|
||||
\mbox{}\verb@ int iWindow;@\\
|
||||
\mbox{}\verb@ char *pCommand;@\\
|
||||
\mbox{}\verb@ void *pSpecial;@\\
|
||||
\mbox{}\verb@ } ScanData;@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
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[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 baove 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.
|
||||
\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:
|
||||
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap2}
|
||||
$\langle$scaninter {\footnotesize ?}$\rangle\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------- live & death ----------------------------------*/@\\
|
||||
\mbox{}\verb@ pScanData CreateScanObject(char *pRecover, char *pHeader, @\\
|
||||
\mbox{}\verb@ pCounter pCount);@\\
|
||||
\mbox{}\verb@ void DeleteScanObject(void *self);@\\
|
||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@ int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon, @\\
|
||||
\mbox{}\verb@ char *name, float fStart, float fStep);@\\
|
||||
\mbox{}\verb@ int ClearScanVar(pScanData self);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int DoScan(pScanData self, int iNP, int iMode, float fPreset,@\\
|
||||
\mbox{}\verb@ SicsInterp *pSics, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int SilentScan(pScanData self, int iNP, int iMode, float fPreset,@\\
|
||||
\mbox{}\verb@ SicsInterp *pSics, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ int RecoverScan(pScanData self, SicsInterp *pSics, SConnection *pCon);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int GetScanCounts(pScanData self, long *lData, int iDataLen);@\\
|
||||
\mbox{}\verb@ int GetScanVar(pScanData self, int iWhich, float *fData, int iDataLen);@\\
|
||||
\mbox{}\verb@ int GetScanVarName(pScanData self, int iWhich, @\\
|
||||
\mbox{}\verb@ char *pName, int iLength);@\\
|
||||
\mbox{}\verb@ int GetScanVarStep(pScanData self, int iWhich, @\\
|
||||
\mbox{}\verb@ float *fStep);@\\
|
||||
\mbox{}\verb@ int GetScanMonitor(pScanData self, int iWhich, @\\
|
||||
\mbox{}\verb@ long *lData, int iDataLen);@\\
|
||||
\mbox{}\verb@ int GetScanNP(pScanData self);@\\
|
||||
\mbox{}\verb@ float GetScanPreset(pScanData self);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int ScanIntegrate(pScanData self, float *fSum, float *fVariance);@\\
|
||||
\mbox{}\verb@ @\\
|
||||
\mbox{}\verb@ int SimScan(pScanData self, float fPos, float FHWM, float fHeight);@\\
|
||||
\mbox{}\verb@ /* @\\
|
||||
\mbox{}\verb@ creates a simulated gaussian shaped peak with the parameters given.@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@ int ResetScanFunctions(pScanData self);@\\
|
||||
\mbox{}\verb@ /*@\\
|
||||
\mbox{}\verb@ resets the configurable scan functions to their default values.@\\
|
||||
\mbox{}\verb@ */@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*------------------------ Interpreter Interface --------------------------*/@\\
|
||||
\mbox{}\verb@ int ScanFactory(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ int ScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-1ex}
|
||||
\footnotesize\addtolength{\baselineskip}{-1ex}
|
||||
\begin{list}{}{\setlength{\itemsep}{-\parsep}\setlength{\itemindent}{-\leftmargin}}
|
||||
\item Macro referenced in scrap ?.
|
||||
\end{list}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
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[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[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}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap3}
|
||||
\verb@"scan.h"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*---------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ S C A N@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Header file for the SICS scan object.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, October 1997@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#ifndef SICSSCAN1@\\
|
||||
\mbox{}\verb@#define SICSSCAN1@\\
|
||||
\mbox{}\verb@ typedef struct __ScanData *pScanData;@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#include "counter.h"@\\
|
||||
\mbox{}\verb@@$\langle$scaninter {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@#endif@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
||||
\begin{flushleft} \small
|
||||
\begin{minipage}{\linewidth} \label{scrap4}
|
||||
\verb@"scan.i"@ {\footnotesize ? }$\equiv$
|
||||
\vspace{-1ex}
|
||||
\begin{list}{}{} \item
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||
\mbox{}\verb@ Internal header file holding the definition of the scan objects data@\\
|
||||
\mbox{}\verb@ structure.@\\
|
||||
\mbox{}\verb@@\\
|
||||
\mbox{}\verb@ Mark Koennecke, October 1997@\\
|
||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||
\mbox{}\verb@#include "sdynar.h"@\\
|
||||
\mbox{}\verb@@$\langle$scandata {\footnotesize ?}$\rangle$\verb@@\\
|
||||
\mbox{}\verb@@$\diamond$
|
||||
\end{list}
|
||||
\vspace{-2ex}
|
||||
\end{minipage}\\[4ex]
|
||||
\end{flushleft}
|
Reference in New Issue
Block a user