\subsection{Optimise} In instrument control the need arises to optimise a peak with respect to several variables. This is usually the case during instrument calibration. Four circle diffractometers however use this facility on a day to day basis for finding and verifying the exact position of reflections. In order to support both usages a more general module has been implemented. The way of operation is like this: \begin{verbatim} while errors > precision and cycles < maxcycles for all variables treated do a scan Try find the maximum, two halfwidth points and the peak center. if failure extend the scan. if success shift the variable, remember last shift. If shift < precicison mark this variable as done end for end while \end{verbatim} Possible outcomes of this procedure are: success, the peak was lost or the maximum number of cycles was reached. This routine requires that the instrument is currently placed somewhere on the peak and not miles away. In order to use this scheme some general control variables are required: \begin{description} \item[iMaxCycles] The maximum number of cycles to run. \item[lThreshold] A threshold value used when determining if the peak was lost. \item[eMode] The counter mode to count in. \item[fPreset] The preset to use when counting. \item[iChannel] The channel to use as signal when counting. This is to support this technique on a monitor rather then with a counter. Useful for calibration. \end{description} For each variable to optimise we have to hold the following items: \begin{description} \item[name] Variable name. \item[fStep] The step size to use for scanning \item[nStep] The number of steps to go in each direction by default. This parameter and the step size should together encompass somewhat more then the width of the peak. \item[fPrecision] The precision required or expected for this variable. \item[fShift] The shift necessary for the last variable. \end{description} Of this the user is required to enter: name, fStep, nStep and fPrecision. For some of its work, this module relies on the scan object (scan.*) and the fitcenter object (fitcenter.*). Internally the optimiser uses the following data structures: \begin{verbatim} typedef struct { char *pName; float fStep; int iStep; float fPrecision; float fCenter; float fShift; pIDrivable pDriv; void *pData; int iLost; } OVarEntry, *pOVarEntry; \end{verbatim} This is the data structure for each variable to optimise during an optimser run. The fields are: \begin{description} \item[pName] the name of the variable. \item[fStep] The step width to use for scanning the variable. \item[fPrecision] The precision required for this variable. Used to mark this variable OK if the last shift is less then this precision value. \item[fCenter] The calculated center of this variable. \item[fShift] The last shift calculated for this variable. \item[pDriv] A pointer to the drivable interface of this variable. \item[pData] A pointer to this variables data structure. \item[iLost] A flag which marks if the peak has been lost with respect to this variable. \end{description} The optimiser itself uses the following data structure: \begin{verbatim} typedef struct __OptimiseStruct { pObjectDescriptor pDes; int iMaxCycles; CounterMode eCount; float fPreset; int iChannel; float fThreshold; int iVar; pDynar pVariables; pScanData pScanner; pFit pPeakFitter; } Optimiser; \end{verbatim} The fields are: \begin{description} \item[pDes]The usual object descriptor. \item[iMaxCycles] The maximum number of cycles to perform. \item[eCount] The countmode to use for scanning. \item[fPreset] The preset to use for scanning. \item[iChannel] The channel to use for scanning. \item[fThreshold] The threshold to use for identifying lost peaks. \item[iVar] The number of variables to optimise. \item[pVariables] A dynamic array of variables to optimise. \item[pScanner] The scan object to use for scanning. \item[pFit] The peak center determination object to use. \end{description} The interface to this object looks like this: @o optimise.h @{ /*------------------------------------------------------------------------- O P T I M I S E Optimise a peak with respect to several variables. copyright: see copyright.h Mark Koennecke, March 1998-1999 -----------------------------------------------------------------------------*/ #ifndef SICSOPTIMISE #define SICSOPTIMISE typedef struct __OptimiseStruct *pOptimise; /*------------------- live & death -----------------------------------------*/ pOptimise CreateOptimiser(pCounter pCount); void DeleteOptimiser(void *pData); int MakeOptimiser(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); /*------------------- operation -------------------------------------------*/ #define PEAKLOST -1 #define MAXCYCLE -2 #define SCANERROR -3 #define SCANABORT -4 #define SYSERROR -5 #define DRIVEERROR -6 #define VARREDO -7 void OptimiserClear(pOptimise self); int OptimiserAdd(pOptimise self, char *pVarName, float fStep, int nStep, float fPrecision); int OptimiserSetPar(pOptimise self, char *name, float fVal); int OptimiserGetPar(pOptimise self, char *name, float *fVal); int OptimiserRun(pOptimise self, SConnection *pCon); int OptimiserAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); #endif @} All functions except the installation functions take a pointer to the optimiser structure as first parameter. The function reference: \begin{description} \item[CreateOptimiser] creates an optimiser object. Takes a pointer to a counter object as a parameter. Returns a pointer to a nice and good optimiser object on return. Or NULL, if there was some sort of problem. \item[DeleteOptimiser] is the deletion function used in the interpreter for properly removing the optimiser object from the system. \item[MakeOptimiser] is the installation function which configures an optimiser into SICS. \item[OptimiserClear] removes all configured optimisation variables and all remnants of a previous optimiser run. \item[OptimiserAdd] adds a variable to be optimised. Parameter to this call are: pVarName, the name of the variable to optimise, fStep, the step width to use for scanning, nStep, the initial number of steps to use for scanning, fPrecision, the precision to achive for this variable. \item[OptimiserSetPar] sets the configuration parameters for the optimiser. The parameter name is the same name as stated in the command reference. \item[OptimiserGetPar] retrieves the value of a configuration parameters for the optimiser. The parameter name is the same name as stated in the command reference. \item[OptimiserRun] starts the optimser run with the current parameters. Output is sent to the connection pCon. \item[OptimiserAction] is the interpreter interface function for the optimiser. \end{description}