\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               (*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[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:

@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 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.
    */

/*------------------------ 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[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}
@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@>
@}         




