\subsection{Monochromators}
The code in these modules support standard crystal monochromators. The code
is divided into two groups: There is the selector module which does most of
the monochromator handling. And there are selvars, virtual motors which
allow to drive the wavelength or the energy (for those triple axis guys)
directly via the drive command. The monochromator module does not only
adjust theta and two theta for the monochromator but also horizontal and
vertical benders. The formula used for calculating the bending radius is: $b
= C1 + \frac{C2}{sin(Theta)}$.  This object is implemented in the
files selector.h and selector.c. 

As the configuration parameters of this object include the scattering
sense, ss, it is also suitable for running the analyzer of a triple
axis instrument. 

\subsubsection{The Selector Device} 
The monochromator is described by the following data structure:
\begin{verbatim}
  typedef struct __SicsSelector {
  			ObjectDescriptor *pDes;
  			ObPar *pParams;
  			char *name;
  			pMotor pTheta;
  			pMotor pTwoTheta;
  			pMotor pBend1;
  			pMotor pBend2;
  			char *pType;
		  } SicsSelector;
\end{verbatim}
The fields:
\begin{description}
\item[pDes] A pointer to the usual SICS object descriptor.
\item[pParams] A pointer to a SICS parameter array (see helper modules for
more details).
\item[name] The name of the monochromator.
\item[pTheta] A pointer to the data structure for the Theta motor.
\item[pTwoTheta] A pointer to the data structure for the Two Theta motor.
\item[pBend1] A pointer to the data structure for the first bender motor.
\item[pBend2] A pointer to the data structure for the second bender  motor.
\end{description}
Please note, that troughout the code the bender motors are handled as
optional.

The monochromator can be accessed with the following functions:
\begin{description}
\item[pSicsSelector CreateSelector(char *name, pMotor pTheta, pMotor pTwoTheta,\\
                               pMotor pBend1, pMotor pBend2)]
 creates a new monochromator name with motors. The bender motors are
optional, theta and two theta are required. Returns a pointer to a new
monochromator data structure on success or NULL on failure.
\item[int MonoInit(SConnection *pCon,SicsInterp *pSics, void *pData, \\
               int argc, char *argv[])] The monochromator factory function.
\item[void DeleteSelector(void *self)] deletes a monochromator.
\item[int MonoAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
                 int argc, char *argv[])] The object wrapper function for
the monochromator. 
\item[int MonoRun(pSicsSelector self, SConnection *pCon, float fWaveLength)]
starts the selector to run to wavelength fWaveLength. Does not wait for
finish. Eventual error messages are sent to pCon.
\item[int MonoLimits(pSicsSelector self, float fWaveLength, char *error, \\
                 int iErrLen)] checks if fWaveLength violates any motor
limits. If so maximum iErrLen characters of description are copied to error.  
\item[int MonoCheck(pSicsSelector self, SConnection *pCon)] does a status
check on all the monochromator motors. The result is the worst of the
motor status codes as returned from the motors.
\item[int MonoHalt(pSicsSelector self)]  emergency halts the monochromator.               
\item[float GetMonoPosition(pSicsSelector self, SConnection *pCon)] get the
current wavelength of the monochromator. Possible errors are rported to
pcon. On error this function returns -999, else the current wavelength is
returned. 
\item[char *MonoGetType(pSicsSelector self)] gets the type of the
monochromator.
\item[int GetMonoPositions(pSicsSelector self, SConnection *pCon, \\
                       float *fTheta, float *fTwtTh, float *fB1, float
*fB2)] gets the positions for all the monochromators motors.
\end{description}

\subsubsection{The Monochromator Virtual Motors}
This module implements the wavelength or energy variable to act upon a
monochromator. Both types are represented by a special data structure:
\begin{verbatim}
   typedef struct __SelVar {
                             pObjectDescriptor pDes;
                             pSicsSelector pSel;
                             pIDrivable pDrivInt;
                             float fValue;
                             char *name;
                             } SelVar;
                             
\end{verbatim}
The fields:
\begin{description}
\item[pDes] A pointer to the usual SICS object descriptor.
\item[pSel] A pointer to the monochromator object to use for adjusting.
\item[pDrivInt] A pointer to the drivable interface implemented.
\item[fValue] The current value of the variable.
\item[name] The name of the virtual motor.
\end{description}

Most of the action for these variables is hidden in the drivable interface.
This is also where the conversions between energy and wavelength are done.
Consequently the interface to this module consists mostly of creation and
deletion functions:
\begin{description}
\item[pSelVar CreateWLVar(char *name, pSicsSelector pSel)] creates a
wavelength variable.
\item[pSelVar CreateEnergy(char *name, pSicsSelector pSel)] creates an
energy variable for monochromator pSel Both functions return NULL on failure
and a pointer to a selector variable data structure in case of success.
\item[void DeleteSelVar(void *pSelf)] deletes a selector variable.
\item[int MakeWaveLengthVar(SConnection *pCon, SicsInterp *pSics, void *pData,\\
                     int argc, char *argv[])] factory function for a
wavelength variable.
\item[int MakeEnergyVar(SConnection *pCon, SicsInterp *pSics, void *pData,\\
                     int argc, char *argv[])] factory function for a energy
variable.
\item[float GetSelValue(pSelVar self, SConnection *pCon)] retrieves the
current value of the variable. In case of errors -999 is returned and error
messages are printed to pCon.
\item[int WaveLengthAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
                     int argc, char *argv[])] The object wrapper function
for a wavelength variable.
\item[int EnergyAction(SConnection *pCon, SicsInterp *pSics, void *pData,\\
                     int argc, char *argv[])] The object wrapper function
for a energy variable.
\end{description}

Please note, that most of the important variables for handling a
monochromator reside with the monochromator object and not with the virtual
motors.

