- A couple of small fixes for memory and initialization problems.
This is to make valgrind happy SKIPPED: psi/amorscan.c psi/el734hp.c psi/psi.c psi/tasscan.c
This commit is contained in:
@ -77,6 +77,7 @@
|
|||||||
SICSLogWrite("Error allocating memory for Interpreter",eInternal);
|
SICSLogWrite("Error allocating memory for Interpreter",eInternal);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
memset(pInter,0,sizeof(SicsInterp));
|
||||||
pInter->pCList = NULL;
|
pInter->pCList = NULL;
|
||||||
pInter->AList.pFirst = NULL; /* M.Z. */
|
pInter->AList.pFirst = NULL; /* M.Z. */
|
||||||
pInter->pTcl = (void *)MacroInit(pInter);
|
pInter->pTcl = (void *)MacroInit(pInter);
|
||||||
|
41
conman.c
41
conman.c
@ -35,6 +35,10 @@
|
|||||||
Introduced SCPrintf to avoid many of these pBueffel.
|
Introduced SCPrintf to avoid many of these pBueffel.
|
||||||
Markus Zolliker, Sept 2004.
|
Markus Zolliker, Sept 2004.
|
||||||
|
|
||||||
|
Cleaned up conman data structure. Removed left over and unused
|
||||||
|
fields.
|
||||||
|
Mark Koennecke, December 2004
|
||||||
|
|
||||||
Copyright: see copyright.h
|
Copyright: see copyright.h
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
@ -167,7 +171,6 @@ extern pServer pServ;
|
|||||||
pRes->inUse = 0;
|
pRes->inUse = 0;
|
||||||
pRes->iMacro = 0;
|
pRes->iMacro = 0;
|
||||||
pRes->iTelnet = 0;
|
pRes->iTelnet = 0;
|
||||||
pRes->pSics = pSics;
|
|
||||||
pRes->eInterrupt = eContinue;
|
pRes->eInterrupt = eContinue;
|
||||||
pRes->lMagic = CONMAGIC;
|
pRes->lMagic = CONMAGIC;
|
||||||
pRes->iLogin = 0;
|
pRes->iLogin = 0;
|
||||||
@ -179,7 +182,7 @@ extern pServer pServ;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* install command */
|
/* install command */
|
||||||
AddCommand(pRes->pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
|
AddCommand(pSics, ConName(pRes->ident), ConSicsAction, NULL,pRes);
|
||||||
return pRes;
|
return pRes;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -411,7 +414,7 @@ extern pServer pServ;
|
|||||||
fclose(pVictim->pFiles[i]);
|
fclose(pVictim->pFiles[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveCommand(pVictim->pSics,ConName(pVictim->ident));
|
RemoveCommand(pServ->pSics,ConName(pVictim->ident));
|
||||||
|
|
||||||
if(pVictim->pDes)
|
if(pVictim->pDes)
|
||||||
{
|
{
|
||||||
@ -428,14 +431,6 @@ extern pServer pServ;
|
|||||||
}
|
}
|
||||||
LLDdelete(pVictim->iList);
|
LLDdelete(pVictim->iList);
|
||||||
|
|
||||||
/* remove standing data connections */
|
|
||||||
if(pVictim->pDataSock)
|
|
||||||
{
|
|
||||||
NETClosePort(pVictim->pDataSock);
|
|
||||||
free(pVictim->pDataSock);
|
|
||||||
free(pVictim->pDataComp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove command stack */
|
/* remove command stack */
|
||||||
if(pVictim->pStack)
|
if(pVictim->pStack)
|
||||||
{
|
{
|
||||||
@ -549,7 +544,9 @@ extern pServer pServ;
|
|||||||
l = vsnprintf(buf, sizeof buf, fmt, ap);
|
l = vsnprintf(buf, sizeof buf, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
if (l >= sizeof buf) {
|
if (l >= sizeof buf) {
|
||||||
/* we have probably a C99 conforming snprintf and need a larger buffer */
|
/* we have probably a C99 conforming snprintf and
|
||||||
|
need a larger buffer
|
||||||
|
*/
|
||||||
dyn = malloc(l+1);
|
dyn = malloc(l+1);
|
||||||
if (dyn != NULL) {
|
if (dyn != NULL) {
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
@ -662,7 +659,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
/* put it into the interpreter if present */
|
/* put it into the interpreter if present */
|
||||||
if(SCinMacro(self))
|
if(SCinMacro(self))
|
||||||
{
|
{
|
||||||
InterpWrite(self->pSics,buffer);
|
InterpWrite(pServ->pSics,buffer);
|
||||||
/* print it to client if error message */
|
/* print it to client if error message */
|
||||||
if((iOut== eError) || (iOut == eWarning) )
|
if((iOut== eError) || (iOut == eWarning) )
|
||||||
{
|
{
|
||||||
@ -742,7 +739,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
/* put it into the interpreter if present */
|
/* put it into the interpreter if present */
|
||||||
if(SCinMacro(self))
|
if(SCinMacro(self))
|
||||||
{
|
{
|
||||||
InterpWrite(self->pSics,buffer);
|
InterpWrite(pServ->pSics,buffer);
|
||||||
/* print it to client if error message */
|
/* print it to client if error message */
|
||||||
if((iOut== eError) || (iOut == eWarning) )
|
if((iOut== eError) || (iOut == eWarning) )
|
||||||
{
|
{
|
||||||
@ -793,7 +790,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
/* put it into the interpreter if present */
|
/* put it into the interpreter if present */
|
||||||
if(SCinMacro(self))
|
if(SCinMacro(self))
|
||||||
{
|
{
|
||||||
InterpWrite(self->pSics,buffer);
|
InterpWrite(pServ->pSics,buffer);
|
||||||
}
|
}
|
||||||
else /* not in interpreter, normal logic */
|
else /* not in interpreter, normal logic */
|
||||||
{
|
{
|
||||||
@ -861,7 +858,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
/* put it into the interpreter if present */
|
/* put it into the interpreter if present */
|
||||||
if(SCinMacro(self))
|
if(SCinMacro(self))
|
||||||
{
|
{
|
||||||
InterpWrite(self->pSics,buffer);
|
InterpWrite(pServ->pSics,buffer);
|
||||||
}
|
}
|
||||||
else /* not in interpreter, normal logic */
|
else /* not in interpreter, normal logic */
|
||||||
{
|
{
|
||||||
@ -1641,7 +1638,7 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
|
|
||||||
if(self->pAction)
|
if(self->pAction)
|
||||||
{
|
{
|
||||||
InterpExecute(self->pSics,self->pCon,self->pAction);
|
InterpExecute(pServ->pSics,self->pCon,self->pAction);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1799,9 +1796,8 @@ static void writeToLogFiles(SConnection *self, char *buffer)
|
|||||||
}
|
}
|
||||||
/* invoke command */
|
/* invoke command */
|
||||||
CostaLock(self->pStack);
|
CostaLock(self->pStack);
|
||||||
SCInvoke(self,self->pSics,pPtr);
|
SCInvoke(self,pServ->pSics,pPtr);
|
||||||
CostaUnlock(self->pStack);
|
CostaUnlock(self->pStack);
|
||||||
/* SCWrite(self,"\b",eError); */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1897,9 +1893,12 @@ int SCActive(SConnection *self)
|
|||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(GetExeOwner(pServ->pExecutor) == self)
|
if(pServ->pExecutor != NULL)
|
||||||
{
|
{
|
||||||
return 1;
|
if(GetExeOwner(pServ->pExecutor) == self)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
24
conman.h
24
conman.h
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
Mark Koennecke, Aprl 2003
|
Mark Koennecke, Aprl 2003
|
||||||
|
|
||||||
|
Mark Koennecke, December 2004
|
||||||
|
|
||||||
copyright: see copyright.h
|
copyright: see copyright.h
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#ifndef SICSCONNECT
|
#ifndef SICSCONNECT
|
||||||
@ -30,33 +32,31 @@ typedef int (*writeFunc)(struct __SConnection *pCon,
|
|||||||
typedef struct __SConnection {
|
typedef struct __SConnection {
|
||||||
/* object basics */
|
/* object basics */
|
||||||
pObjectDescriptor pDes;
|
pObjectDescriptor pDes;
|
||||||
/* char *pName; now generated on the fly from ident */
|
|
||||||
long lMagic;
|
long lMagic;
|
||||||
long ident;
|
long ident;
|
||||||
struct __SConnection *next;
|
struct __SConnection *next;
|
||||||
|
|
||||||
/* I/O control */
|
/* I/O control */
|
||||||
|
/* our socket */
|
||||||
mkChannel *pSock;
|
mkChannel *pSock;
|
||||||
|
|
||||||
|
/* per connection log files */
|
||||||
FILE *pFiles[MAXLOGFILES];
|
FILE *pFiles[MAXLOGFILES];
|
||||||
int iMacro;
|
|
||||||
int iTelnet;
|
|
||||||
int iOutput;
|
|
||||||
int iFiles;
|
int iFiles;
|
||||||
writeFunc write;
|
|
||||||
mkChannel *pDataSock;
|
int iMacro; /* suppress I/O in macro*/
|
||||||
char *pDataComp;
|
int iTelnet; /* telnet flag */
|
||||||
int iDataPort;
|
int iOutput;
|
||||||
|
writeFunc write; /* function doing
|
||||||
|
writing */
|
||||||
|
|
||||||
/* execution context */
|
/* execution context */
|
||||||
int eInterrupt;
|
int eInterrupt;
|
||||||
int iUserRights;
|
int iUserRights;
|
||||||
int inUse;
|
int inUse;
|
||||||
int iDummy;
|
int iGrab; /* grab flag for token*/
|
||||||
int iGrab;
|
|
||||||
int iErrCode;
|
|
||||||
int parameterChange;
|
int parameterChange;
|
||||||
int sicsError;
|
int sicsError;
|
||||||
SicsInterp *pSics;
|
|
||||||
|
|
||||||
/* a FIFO */
|
/* a FIFO */
|
||||||
pCosta pStack;
|
pCosta pStack;
|
||||||
|
@ -654,7 +654,7 @@
|
|||||||
{
|
{
|
||||||
self->pCountInt->TransferData(self,pCon);
|
self->pCountInt->TransferData(self,pCon);
|
||||||
}
|
}
|
||||||
if( (iNum < 0) || (iNum > self->pDriv->iNoOfMonitors) )
|
if( (iNum < 0) || (iNum >= self->pDriv->iNoOfMonitors) )
|
||||||
{
|
{
|
||||||
return -1L;
|
return -1L;
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,7 @@
|
|||||||
DeleteCallBackInterface(self->pCall);
|
DeleteCallBackInterface(self->pCall);
|
||||||
|
|
||||||
free(self);
|
free(self);
|
||||||
|
pServ->pExecutor = NULL;
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
|
void ExeInterest(pExeList self, pDevEntry pDev, char *text) {
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<TITLE>The Internal Scan Command</TITLE>
|
<TITLE>The Internal Scan Command</TITLE>
|
||||||
</HEAD>
|
</HEAD>
|
||||||
<BODY>
|
<BODY>
|
||||||
<H1>The Internal Scan Command</H1>
|
<H1>The Internal Scan Commands</H1>
|
||||||
<P>
|
<P>
|
||||||
Scans are preformed from a variety of commands in SICS. All these commands
|
Scans are preformed from a variety of commands in SICS. All these commands
|
||||||
are just Tcl--wrappers around an internal scan object implemented in C. This
|
are just Tcl--wrappers around an internal scan object implemented in C. This
|
||||||
@ -13,6 +13,29 @@ command</a> in the initialisation file. This command install the internal
|
|||||||
scan object under a user defined name. For the rest of this document it is
|
scan object under a user defined name. For the rest of this document it is
|
||||||
assumed that this name is xxscan.
|
assumed that this name is xxscan.
|
||||||
</P>
|
</P>
|
||||||
|
<h2>Scan Concepts</2>
|
||||||
|
<p>
|
||||||
|
Scanning in SICS evolved a little over time. It turned out that scans
|
||||||
|
are a demanding job for a programmer because of the plethora of
|
||||||
|
special scans people wish to perform and the many data file formats which
|
||||||
|
have to be supported. This requires a very high degree of
|
||||||
|
configurability. Under several refactorings the internal scan command
|
||||||
|
has grown to become:
|
||||||
|
<ul>
|
||||||
|
<li>A controller for the scan process.
|
||||||
|
<li>A container to store scanned variables and counts during the
|
||||||
|
process of a scan. This includes commands to store and retrieve such
|
||||||
|
values.
|
||||||
|
<li>A container for the configuration of the scan. A scan is
|
||||||
|
configured by specifying functions to be called at the various steps
|
||||||
|
during the scan. These are preconfigured to the standard scan
|
||||||
|
functions. An API is provided to replace some or all of the scan
|
||||||
|
functions by user defined ones.
|
||||||
|
</ul>
|
||||||
|
The internal scan object is augmented by a library of standard scan
|
||||||
|
functions. The transition to the new model is not yet clean in order
|
||||||
|
not to break to much old code.
|
||||||
|
</p>
|
||||||
The scan object (named here xxscan, but may have another name) understands
|
The scan object (named here xxscan, but may have another name) understands
|
||||||
the following commands:
|
the following commands:
|
||||||
<DL>
|
<DL>
|
||||||
@ -28,6 +51,8 @@ different parameters.
|
|||||||
the counter mode to use (this can be either timer or monitor) and preset
|
the counter mode to use (this can be either timer or monitor) and preset
|
||||||
which is the preset value for the counter. Scan data is written to an output
|
which is the preset value for the counter. Scan data is written to an output
|
||||||
file.
|
file.
|
||||||
|
<dt>xxscan continue NP mode preset
|
||||||
|
<dd>Continues an interrupted scan. Used by the recovery feauture.
|
||||||
<DT>xxscan silent NP mode preset
|
<DT>xxscan silent NP mode preset
|
||||||
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
|
<DD>Executes a scan. The arguments are: NP the number of scan points, mode
|
||||||
the counter mode to use (this can be either timer or monitor) and preset
|
the counter mode to use (this can be either timer or monitor) and preset
|
||||||
@ -47,16 +72,33 @@ command sets the channel to collect data from. The argument n is an integer
|
|||||||
ID for the channel to use.
|
ID for the channel to use.
|
||||||
<DT>xxscan getcounts
|
<DT>xxscan getcounts
|
||||||
<DD>Retrieves the counst collected during the scan.
|
<DD>Retrieves the counst collected during the scan.
|
||||||
|
<dt>xxscan getmonitor i
|
||||||
|
<dd>Prints the monitor values collected during the scan for the
|
||||||
|
monitor number i
|
||||||
|
<dt>xxscan gettime
|
||||||
|
<dd>Prints the counting times for the scan points in the current scan.
|
||||||
|
<dt>xxscan np
|
||||||
|
<dd>Prints the number of points in the current scan.
|
||||||
<DT>xxscan getvardata n
|
<DT>xxscan getvardata n
|
||||||
<DD>This command retrieves the values of a scan variable during the scan
|
<DD>This command retrieves the values of a scan variable during the scan
|
||||||
(the x axis). The argument n is the ID of the scan variable to retrieve data
|
(the x axis). The argument n is the ID of the scan variable to retrieve data
|
||||||
for. ID is 0 for the first scan variable added, 1 for the second etc.
|
for. ID is 0 for the first scan variable added, 1 for the second etc.
|
||||||
|
<dt>xxscan noscanvar
|
||||||
|
<dd>Prints the number of scan variables
|
||||||
|
<dt>xxscan getvarpar i
|
||||||
|
<dd>Prints the name , start and step of the scan variable number i
|
||||||
<DT>xxscan interest
|
<DT>xxscan interest
|
||||||
<DD>A SICS client can be automatically notified about scan progress. This is
|
<DD>A SICS client can be automatically notified about scan progress. This is
|
||||||
switched on with this command. Three types of messages are sent: A string
|
switched on with this command. Three types of messages are sent: A string
|
||||||
NewScan on start of the scan, a string ScanEnd after the scan has finished
|
NewScan on start of the scan, a string ScanEnd after the scan has finished
|
||||||
and a string scan.Counts = {109292 8377 ...} with the scan values after each
|
and a string scan.Counts = {109292 8377 ...} with the scan values after each
|
||||||
finished scan point.
|
finished scan point.
|
||||||
|
<dt>xxscan uuinterest
|
||||||
|
<dd>As above but the array of counts is transferred in UU encoded
|
||||||
|
format.
|
||||||
|
<dt>xxscan dyninterest
|
||||||
|
<dd>As above but scan points are printed one by one as a list
|
||||||
|
containing: point number first_scan_var_pos counts.
|
||||||
<DT>xxscan uninterest
|
<DT>xxscan uninterest
|
||||||
<DD> Uninterest switches automatic notification about scan progress off.
|
<DD> Uninterest switches automatic notification about scan progress off.
|
||||||
<DT>xxscan integrate
|
<DT>xxscan integrate
|
||||||
@ -87,10 +129,70 @@ object. Currently there are two:
|
|||||||
<li><b>amor</b>, a special mode the reflectometer AMOR which writes
|
<li><b>amor</b>, a special mode the reflectometer AMOR which writes
|
||||||
NeXus files.
|
NeXus files.
|
||||||
</ul>
|
</ul>
|
||||||
|
<dt>xxscan storecounts counts time mon1 mon2 ...
|
||||||
|
<dD>This stores an entry of count values into the scan data
|
||||||
|
structure. To be used from user defined scan functions. The scan
|
||||||
|
pointer is incremented by one.
|
||||||
|
<dt>xxscan storecounter
|
||||||
|
<dd>Store the counts and monitors in the counter object configured for
|
||||||
|
the scan into the scan data structure. Increments the scan pointer by
|
||||||
|
one.
|
||||||
|
<dt>xxscan appendvarpos i pos
|
||||||
|
<dd>Append pos to the array of positions for scan variable i. To be
|
||||||
|
used from user defined scan functions.
|
||||||
|
<dt>xxscan callback scanstart | scanpoint | scanend
|
||||||
|
<dd>Triggers callbacks configured on the scan object. May be used by
|
||||||
|
user functions implementing own scan loops.
|
||||||
|
<dt>xxscan function list
|
||||||
|
<dd>Lists the available configurable function names. The calling style
|
||||||
|
of these functions is described in the next section about stdscan.
|
||||||
|
<dt>xxscan function functionname
|
||||||
|
<dd>Returns the currently configured function for functionname.
|
||||||
|
<dt>xxscan function functionname newfunctionname
|
||||||
|
<dd>Sets a new function to be called for the function functionname in
|
||||||
|
the scan.
|
||||||
</DL>
|
</DL>
|
||||||
</P>
|
</P>
|
||||||
<p>
|
<h2>User Definable Scan Functions</h2>
|
||||||
<h2>User Defined Scans</h2>
|
<p>The last commands in the last section allowed to overload the
|
||||||
|
functions implementing various operations during the scan with user
|
||||||
|
defined methods. This section is the reference for these
|
||||||
|
functions. The following operations during a scan be configured:
|
||||||
|
<dl>
|
||||||
|
<dt>writeheader
|
||||||
|
<dd>Is supposed to write the header of the data file
|
||||||
|
<dt>prepare
|
||||||
|
<dd>Prepare does all the necessary operations necessary before a scan
|
||||||
|
starts.
|
||||||
|
<dt>drive
|
||||||
|
<dd>Is called to drive to the next scan point
|
||||||
|
<dt>count
|
||||||
|
<dd>Is called at each scan point to perform the counting operation
|
||||||
|
<dt>collect
|
||||||
|
<dd>Is called for each scan point. This function is supposed to store
|
||||||
|
the scan data into the scan data structure.
|
||||||
|
<dt>writepoint
|
||||||
|
<dd>Is called for each scan point and is meant to print information
|
||||||
|
about the scan point to the data file and to the user.
|
||||||
|
<dt>userdata
|
||||||
|
<dd>This is the name of a user defined object which may be used to
|
||||||
|
store user data for the scan.
|
||||||
|
</dl>
|
||||||
|
The exact invocations of the functions:
|
||||||
|
<ul>
|
||||||
|
<li>writeheader scanobjectname userobjectname
|
||||||
|
<li>prepare scanobjectname userobjectname
|
||||||
|
<li>drive scanobjectname userobjectname point
|
||||||
|
<li>count scanobjectname userobjectname point
|
||||||
|
<li>collect scanobjectname userobjectname point
|
||||||
|
<li>writepoint scanobjectname userobjectname point
|
||||||
|
</ul>
|
||||||
|
scanobjectname is the name of the scan object invoking the
|
||||||
|
function. This can be used for querying the scan
|
||||||
|
object. userobjectname is the name of a entity as specified as
|
||||||
|
userdata in the configuration. point is the number of the current scan point.
|
||||||
|
</p>
|
||||||
|
<h2>User Defined Scans(Old Style)</h2>
|
||||||
<p>
|
<p>
|
||||||
In some cases users wish to control the scan more closely, i.e. do
|
In some cases users wish to control the scan more closely, i.e. do
|
||||||
multiple counting operations at the same point etc. This is especially
|
multiple counting operations at the same point etc. This is especially
|
||||||
@ -133,6 +235,44 @@ command:
|
|||||||
In all this replace xxxscan with the name of the internal scan
|
In all this replace xxxscan with the name of the internal scan
|
||||||
command.
|
command.
|
||||||
</p>
|
</p>
|
||||||
|
<h2>Differential Scans</h2>
|
||||||
|
<p>
|
||||||
|
When aligning or when searching peaks a very fast scan is
|
||||||
|
required. This is the differential scan. It starts a motor and
|
||||||
|
collects counts while the motor is running. The counts collected are
|
||||||
|
the monitor normalized difference to the previous reading. This
|
||||||
|
functionality can be configured into SICS with the command:
|
||||||
|
<pre>
|
||||||
|
MakeDiffScan
|
||||||
|
</pre> in the configuration file. An optional parameter defines
|
||||||
|
another name then diffscan (the default) for this object. Differential
|
||||||
|
scans can only be run against one motor as it cannot be guaranteed that
|
||||||
|
motors in a coordinated movement operate at the same speed. The
|
||||||
|
procedure to use diffscan is:
|
||||||
|
<ul>
|
||||||
|
<li>Configure a scan variable into a SICS scan object: xxscan add var
|
||||||
|
start step
|
||||||
|
<li>Run diffscan as: diffscan scanobjectname end_position_of_scan
|
||||||
|
This runs the differential scan. Scanobjectname is the name of a SICS
|
||||||
|
internal scan object. It will be used to store the results of the
|
||||||
|
scan. While the scan is running some basic information is printed. The
|
||||||
|
scan will range from the start given in the xxscan add command to the
|
||||||
|
end position given in this call.
|
||||||
|
</ul>
|
||||||
|
The diffscan object has two configurable parameters:
|
||||||
|
<dl>
|
||||||
|
<dt>monitor
|
||||||
|
<dd>The monitor number to normalize against. For maximum precision
|
||||||
|
this should be a monitor with a lot of intensity on it.
|
||||||
|
<dt>skip
|
||||||
|
<dd>The number of SICS main loop cycles to skip between readings. This
|
||||||
|
can be used to control the amount of data generated during a
|
||||||
|
differential scan. This may become a problem if there is fast hardware.
|
||||||
|
</dl>
|
||||||
|
A word of warning: positions found in differential scans may not be
|
||||||
|
totally correct. The differential scan might even miss peaks when the
|
||||||
|
relationship between motor speed and sampling rate is bad.
|
||||||
|
</p>
|
||||||
</BODY>
|
</BODY>
|
||||||
</HTML>
|
</HTML>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
E N V I R O N M E N T C O N T R O L L E R
|
E N V I R O N M E N T C O N T R O L L E R
|
||||||
|
|
||||||
This is the implementation file for a base class for all environement
|
This is the implementation file for a base class for all environment
|
||||||
control devices in SICS.
|
control devices in SICS.
|
||||||
|
|
||||||
Mark Koennecke, Juli 1997
|
Mark Koennecke, Juli 1997
|
||||||
@ -1426,7 +1426,8 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
|
|||||||
SCSendOK(pCon);
|
SCSendOK(pCon);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else if(strcmp(argv[1],"new") == 0 || strcmp(argv[1], "replace") == 0) /* make a new one */
|
else if(strcmp(argv[1],"new") == 0 || strcmp(argv[1], "replace") == 0)
|
||||||
|
/* make a new one */
|
||||||
{
|
{
|
||||||
/* argv[2] = name */
|
/* argv[2] = name */
|
||||||
/* argv[3] must be type */
|
/* argv[3] must be type */
|
||||||
@ -1462,7 +1463,9 @@ static pEVControl InstallCommonControllers(SicsInterp *pSics,
|
|||||||
if(site != NULL){
|
if(site != NULL){
|
||||||
pNew = site->InstallEnvironmentController(pSics,pCon,argc,argv);
|
pNew = site->InstallEnvironmentController(pSics,pCon,argc,argv);
|
||||||
} else {
|
} else {
|
||||||
sprintf(pBueffel,"ERROR: %s not recognized as a valid driver type", argv[3]);
|
sprintf(pBueffel,
|
||||||
|
"ERROR: %s not recognized as a valid driver type",
|
||||||
|
argv[3]);
|
||||||
SCWrite(pCon,pBueffel,eError);
|
SCWrite(pCon,pBueffel,eError);
|
||||||
pNew = NULL;
|
pNew = NULL;
|
||||||
}
|
}
|
||||||
|
2
exeman.c
2
exeman.c
@ -322,7 +322,7 @@ static void registerCallbacks(SConnection *pCon, SicsInterp *pSics,
|
|||||||
info, NULL);
|
info, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack,
|
lID = RegisterCallback(self->pCall, BATCHAREA, LineCallBack,
|
||||||
info, killExeInfo);
|
info, NULL);
|
||||||
SCRegister(pCon,pSics, self->pCall,lID);
|
SCRegister(pCon,pSics, self->pCall,lID);
|
||||||
}
|
}
|
||||||
/*--------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------*/
|
||||||
|
27
interface.c
27
interface.c
@ -41,7 +41,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "fortify.h"
|
#include "fortify.h"
|
||||||
#include "sics.h"
|
#include "sics.h"
|
||||||
|
#include "motor.h"
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
pIDrivable CreateDrivableInterface(void)
|
pIDrivable CreateDrivableInterface(void)
|
||||||
@ -108,6 +108,31 @@
|
|||||||
{
|
{
|
||||||
return (pIDrivable)FindInterface(pObject,DRIVEID);
|
return (pIDrivable)FindInterface(pObject,DRIVEID);
|
||||||
}
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int GetDrivablePosition(void *pObject, SConnection *pCon, float *fPos)
|
||||||
|
{
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
pMotor pMot = NULL;
|
||||||
|
float value;
|
||||||
|
|
||||||
|
pDriv = GetDrivableInterface(pObject);
|
||||||
|
if(pDriv == NULL)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(iHasType(pObject,"Motor"))
|
||||||
|
{
|
||||||
|
pMot = (pMotor)pObject;
|
||||||
|
return MotorGetSoftPosition(pMot,pCon,fPos);
|
||||||
|
}
|
||||||
|
value = pDriv->GetValue(pObject,pCon);
|
||||||
|
if(value < 9999.99)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
*fPos = value;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
pICountable GetCountableInterface(void *pObject)
|
pICountable GetCountableInterface(void *pObject)
|
||||||
{
|
{
|
||||||
|
26
interface.h
26
interface.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 359 "interface.w"
|
#line 365 "interface.w"
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
I N T E R F A C E S
|
I N T E R F A C E S
|
||||||
@ -42,16 +42,18 @@
|
|||||||
} IDrivable, *pIDrivable;
|
} IDrivable, *pIDrivable;
|
||||||
|
|
||||||
pIDrivable GetDrivableInterface(void *pObject);
|
pIDrivable GetDrivableInterface(void *pObject);
|
||||||
|
int GetDrivablePosition(void *pObject, SConnection *pCon,
|
||||||
|
float *fPos);
|
||||||
|
|
||||||
|
|
||||||
#line 384 "interface.w"
|
#line 390 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
pIDrivable CreateDrivableInterface(void);
|
pIDrivable CreateDrivableInterface(void);
|
||||||
|
|
||||||
/* ------------------------ The countable interface ---------------------*/
|
/* ------------------------ The countable interface ---------------------*/
|
||||||
|
|
||||||
#line 177 "interface.w"
|
#line 183 "interface.w"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int ID;
|
int ID;
|
||||||
@ -68,23 +70,23 @@
|
|||||||
pICountable GetCountableInterface(void *pObject);
|
pICountable GetCountableInterface(void *pObject);
|
||||||
|
|
||||||
|
|
||||||
#line 389 "interface.w"
|
#line 395 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
pICountable CreateCountableInterface(void);
|
pICountable CreateCountableInterface(void);
|
||||||
|
|
||||||
/* ------------------------- The CallBack Interface --------------------*/
|
/* ------------------------- The CallBack Interface --------------------*/
|
||||||
|
|
||||||
#line 230 "interface.w"
|
#line 236 "interface.w"
|
||||||
|
|
||||||
typedef void (*KillFuncIT)(void *pData);
|
typedef void (*KillFuncIT)(void *pData);
|
||||||
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
typedef int (*SICSCallBack)(int iEvent, void *pEventData,
|
||||||
void *pUserData);
|
void *pUserData);
|
||||||
|
|
||||||
#line 394 "interface.w"
|
#line 400 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 252 "interface.w"
|
#line 258 "interface.w"
|
||||||
|
|
||||||
typedef struct __ICallBack *pICallBack;
|
typedef struct __ICallBack *pICallBack;
|
||||||
|
|
||||||
@ -104,11 +106,11 @@
|
|||||||
|
|
||||||
pICallBack GetCallbackInterface(void *pData);
|
pICallBack GetCallbackInterface(void *pData);
|
||||||
|
|
||||||
#line 395 "interface.w"
|
#line 401 "interface.w"
|
||||||
|
|
||||||
/*---------------------- The Environment Interface --------------------*/
|
/*---------------------- The Environment Interface --------------------*/
|
||||||
|
|
||||||
#line 323 "interface.w"
|
#line 329 "interface.w"
|
||||||
|
|
||||||
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
typedef enum { EVIdle, EVDrive, EVMonitor, EVError } EVMode;
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -118,13 +120,13 @@
|
|||||||
int (*HandleError)(void *self);
|
int (*HandleError)(void *self);
|
||||||
} EVInterface, *pEVInterface;
|
} EVInterface, *pEVInterface;
|
||||||
|
|
||||||
#line 397 "interface.w"
|
#line 403 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 349 "interface.w"
|
#line 355 "interface.w"
|
||||||
|
|
||||||
pEVInterface CreateEVInterface(void);
|
pEVInterface CreateEVInterface(void);
|
||||||
|
|
||||||
#line 398 "interface.w"
|
#line 404 "interface.w"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -146,6 +146,8 @@ $\langle$driv {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
|
\mbox{}\verb@ } IDrivable, *pIDrivable;@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
|
\mbox{}\verb@ pIDrivable GetDrivableInterface(void *pObject); @\\
|
||||||
|
\mbox{}\verb@ int GetDrivablePosition(void *pObject, SConnection *pCon,@\\
|
||||||
|
\mbox{}\verb@ float *fPos);@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@$\diamond$
|
||||||
\end{list}
|
\end{list}
|
||||||
@ -195,6 +197,10 @@ the existence of a drivable interface. If it exists a pointer to it will be
|
|||||||
returned. NEVER free this pointer. If no drivable interface exists, NULL
|
returned. NEVER free this pointer. If no drivable interface exists, NULL
|
||||||
will be returned.
|
will be returned.
|
||||||
|
|
||||||
|
{\bf GetDrivablePosition retrieves the position of the drivabel
|
||||||
|
object. If the device is a motor corrections for zero points and signs
|
||||||
|
will be applied. Returns 1 on success and 0 on failure}
|
||||||
|
|
||||||
\subsubsection{The Countable Interface}
|
\subsubsection{The Countable Interface}
|
||||||
This is an interface for interacting with anything which counts.
|
This is an interface for interacting with anything which counts.
|
||||||
|
|
||||||
|
@ -129,6 +129,8 @@ environment controllers fit this bill as well.
|
|||||||
} IDrivable, *pIDrivable;
|
} IDrivable, *pIDrivable;
|
||||||
|
|
||||||
pIDrivable GetDrivableInterface(void *pObject);
|
pIDrivable GetDrivableInterface(void *pObject);
|
||||||
|
int GetDrivablePosition(void *pObject, SConnection *pCon,
|
||||||
|
float *fPos);
|
||||||
|
|
||||||
@}
|
@}
|
||||||
The first member of this structure is an ID which can be used in order to
|
The first member of this structure is an ID which can be used in order to
|
||||||
@ -170,6 +172,10 @@ the existence of a drivable interface. If it exists a pointer to it will be
|
|||||||
returned. NEVER free this pointer. If no drivable interface exists, NULL
|
returned. NEVER free this pointer. If no drivable interface exists, NULL
|
||||||
will be returned.
|
will be returned.
|
||||||
|
|
||||||
|
{\bf GetDrivablePosition retrieves the position of the drivabel
|
||||||
|
object. If the device is a motor corrections for zero points and signs
|
||||||
|
will be applied. Returns 1 on success and 0 on failure}
|
||||||
|
|
||||||
\subsubsection{The Countable Interface}
|
\subsubsection{The Countable Interface}
|
||||||
This is an interface for interacting with anything which counts.
|
This is an interface for interacting with anything which counts.
|
||||||
|
|
||||||
|
6
macro.c
6
macro.c
@ -511,7 +511,11 @@ static int ProtectedExec(ClientData clientData, Tcl_Interp *interp,
|
|||||||
{ /* Tcl error */
|
{ /* Tcl error */
|
||||||
if(strlen(pTcl->result) > 2)
|
if(strlen(pTcl->result) > 2)
|
||||||
{
|
{
|
||||||
SCWrite(pCon,pTcl->result,eError);
|
/*
|
||||||
|
local copy in order to resolve a valgrind error
|
||||||
|
*/
|
||||||
|
strncpy(pBueffel,pTcl->result,511);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
}
|
}
|
||||||
pCom = Tcl_DStringValue(&command);
|
pCom = Tcl_DStringValue(&command);
|
||||||
SCWrite(pCon,"ERROR: in Tcl block:",eError);
|
SCWrite(pCon,"ERROR: in Tcl block:",eError);
|
||||||
|
4
make_gen
4
make_gen
@ -25,8 +25,8 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \
|
|||||||
rmtrail.o help.o nxupdate.o confvirtualmot.o \
|
rmtrail.o help.o nxupdate.o confvirtualmot.o \
|
||||||
simchop.o choco.o chadapter.o trim.o scaldate.o \
|
simchop.o choco.o chadapter.o trim.o scaldate.o \
|
||||||
hklscan.o xytable.o exebuf.o exeman.o\
|
hklscan.o xytable.o exebuf.o exeman.o\
|
||||||
circular.o maximize.o sicscron.o \
|
circular.o maximize.o sicscron.o scanvar.o \
|
||||||
d_sign.o d_mod.o tcldrivable.o \
|
d_sign.o d_mod.o tcldrivable.o stdscan.o diffscan.o\
|
||||||
synchronize.o definealias.o oscillate.o \
|
synchronize.o definealias.o oscillate.o \
|
||||||
hmcontrol.o userscan.o rs232controller.o lomax.o \
|
hmcontrol.o userscan.o rs232controller.o lomax.o \
|
||||||
fourlib.o motreg.o motreglist.o anticollider.o \
|
fourlib.o motreg.o motreglist.o anticollider.o \
|
||||||
|
8
mesure.c
8
mesure.c
@ -322,7 +322,7 @@ typedef struct {
|
|||||||
if(pVar)
|
if(pVar)
|
||||||
{
|
{
|
||||||
fVal = pVar->pInter->GetValue(pVar->pObject,self->pCon);
|
fVal = pVar->pInter->GetValue(pVar->pObject,self->pCon);
|
||||||
pVar->fData[iPoint] = fVal;
|
AppendScanVar(pVar,fVal);
|
||||||
sprintf(pItem,"%-10.10s",pVar->Name);
|
sprintf(pItem,"%-10.10s",pVar->Name);
|
||||||
strcat(pHead,pItem);
|
strcat(pHead,pItem);
|
||||||
sprintf(pItem,"%-10.3f",fVal);
|
sprintf(pItem,"%-10.3f",fVal);
|
||||||
@ -419,8 +419,7 @@ static float determineStepWidth(pMesure self, float two_theta)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
check if we are really there. All this only because Jurg
|
check if we are really there.
|
||||||
does not fix his rotten cradle.
|
|
||||||
*/
|
*/
|
||||||
CalculateSettings(self->pCryst,fHKL,fPsi,0,fSet,pCon);
|
CalculateSettings(self->pCryst,fHKL,fPsi,0,fSet,pCon);
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
@ -503,8 +502,7 @@ static float determineStepWidth(pMesure self, float two_theta)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
check if we are really there. All this only because Jurg
|
check if we are really there.
|
||||||
does not fix his rotten cradle.
|
|
||||||
*/
|
*/
|
||||||
for(i = 0; i < 4; i++)
|
for(i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
|
142
motor.c
142
motor.c
@ -71,11 +71,11 @@
|
|||||||
#define INT 6
|
#define INT 6
|
||||||
#define PREC 7
|
#define PREC 7
|
||||||
#define USRIGHTS 8
|
#define USRIGHTS 8
|
||||||
#define SPEED 9
|
#define SIGN 9
|
||||||
#define SIGN 10
|
#define ECOUNT 10
|
||||||
#define ECOUNT 11
|
#define POSCOUNT 11
|
||||||
#define POSCOUNT 12
|
#define IGNOREFAULT 12
|
||||||
#define IGNOREFAULT 13
|
#define MOVECOUNT 13
|
||||||
|
|
||||||
/*------------------------------------------------------------------------
|
/*------------------------------------------------------------------------
|
||||||
a tiny structure used in CallBack work
|
a tiny structure used in CallBack work
|
||||||
@ -179,6 +179,8 @@
|
|||||||
fputs(pBueffel,fd);
|
fputs(pBueffel,fd);
|
||||||
sprintf(pBueffel,"%s poscount %f\n",name,
|
sprintf(pBueffel,"%s poscount %f\n",name,
|
||||||
ObVal(self->ParArray,POSCOUNT));
|
ObVal(self->ParArray,POSCOUNT));
|
||||||
|
sprintf(pBueffel,"%s movecount %f\n",name,
|
||||||
|
ObVal(self->ParArray,MOVECOUNT));
|
||||||
fputs(pBueffel,fd);
|
fputs(pBueffel,fd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -348,138 +350,13 @@ static int evaluateStatus(pMotor self, SConnection *pCon)
|
|||||||
}
|
}
|
||||||
return newStatus;
|
return newStatus;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------
|
|
||||||
old version, kept for time being.
|
|
||||||
----------------------------------------------------------------------*/
|
|
||||||
static int eevaluateStatus(pMotor self, SConnection *pCon)
|
|
||||||
{
|
|
||||||
int iRet, iCode;
|
|
||||||
MotCallback sCall;
|
|
||||||
char pBueffel[256], pError[132];
|
|
||||||
float fHard;
|
|
||||||
|
|
||||||
iRet = self->pDriver->GetStatus(self->pDriver);
|
|
||||||
if( (iRet == OKOK) || (iRet == HWIdle))
|
|
||||||
{
|
|
||||||
MotorGetSoftPosition(self,pCon,&sCall.fVal);
|
|
||||||
sCall.pName = self->name;
|
|
||||||
InvokeCallBack(self->pCall, MOTEND, &sCall);
|
|
||||||
|
|
||||||
MotorGetHardPosition(self,pCon,&fHard);
|
|
||||||
self->fPosition = fHard;
|
|
||||||
if(absf(fHard - self->fTarget) > ObVal(self->ParArray,PREC))
|
|
||||||
{
|
|
||||||
snprintf(pBueffel,131,"WARNING: %s off position by %f",
|
|
||||||
self->name, absf(fHard - self->fTarget));
|
|
||||||
SCWrite(pCon,pBueffel, eWarning);
|
|
||||||
MotorInterrupt(pCon,ObVal(self->ParArray,INT));
|
|
||||||
self->retryCount = 0;
|
|
||||||
/*
|
|
||||||
suppress HWPosFaults when ignore flag set
|
|
||||||
*/
|
|
||||||
if(ObVal(self->ParArray,IGNOREFAULT) > 0)
|
|
||||||
{
|
|
||||||
return HWIdle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return HWPosFault;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self->retryCount = 0;
|
|
||||||
return HWIdle;
|
|
||||||
}
|
|
||||||
/* motor suggests a fault */
|
|
||||||
else if(iRet == HWFault)
|
|
||||||
{
|
|
||||||
self->pDriver->GetError(self->pDriver,&iCode, pError,131);
|
|
||||||
iRet = self->pDriver->TryAndFixIt(self->pDriver,iCode, self->fTarget);
|
|
||||||
if(iRet == MOTFAIL)
|
|
||||||
{
|
|
||||||
snprintf(pBueffel,255,"ERROR: %s on %s",pError,self->name);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
MotorInterrupt(pCon,ObVal(self->ParArray,INT));
|
|
||||||
self->retryCount = 0;
|
|
||||||
return HWFault;
|
|
||||||
}
|
|
||||||
else if(iRet == MOTREDO)
|
|
||||||
{
|
|
||||||
self->pDriver->RunTo(self->pDriver,self->fTarget);
|
|
||||||
self->retryCount++;
|
|
||||||
if(self->retryCount >= 3)
|
|
||||||
{
|
|
||||||
self->retryCount = 0;
|
|
||||||
return HWFault;
|
|
||||||
}
|
|
||||||
return HWBusy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
self->retryCount = 0;
|
|
||||||
return HWBusy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* a positioning fault */
|
|
||||||
else if(iRet == HWPosFault)
|
|
||||||
{
|
|
||||||
self->pDriver->GetError(self->pDriver,&iCode, pError,131);
|
|
||||||
iRet = self->pDriver->TryAndFixIt(self->pDriver,iCode, self->fTarget);
|
|
||||||
if(iRet == MOTFAIL)
|
|
||||||
{
|
|
||||||
snprintf(pBueffel,255,"ERROR: %s on %s",pError,self->name);
|
|
||||||
SCWrite(pCon,pBueffel,eError);
|
|
||||||
MotorInterrupt(pCon,ObVal(self->ParArray,INT));
|
|
||||||
self->retryCount = 0;
|
|
||||||
return HWFault;
|
|
||||||
}
|
|
||||||
else if(iRet == MOTREDO)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
abort if to many positioning faults
|
|
||||||
*/
|
|
||||||
self->posFaultCount++;
|
|
||||||
if(self->posFaultCount >= 4)
|
|
||||||
{
|
|
||||||
self->posFaultCount = 0;
|
|
||||||
self->retryCount = 0;
|
|
||||||
/*
|
|
||||||
do not do pass on positioning fault errors when the
|
|
||||||
appropriate flag has been set
|
|
||||||
*/
|
|
||||||
if(ObVal(self->ParArray,IGNOREFAULT) > 0)
|
|
||||||
{
|
|
||||||
return HWIdle;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return HWPosFault;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self->pDriver->RunTo(self->pDriver,self->fTarget);
|
|
||||||
return HWBusy;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return HWBusy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(iRet == HWWarn)
|
|
||||||
{
|
|
||||||
self->pDriver->GetError(self->pDriver,&iCode,pError,131);
|
|
||||||
snprintf(pBueffel,255,"WARNING: %s on %s",pError,self->name);
|
|
||||||
SCWrite(pCon,pBueffel,eStatus);
|
|
||||||
return HWIdle;
|
|
||||||
}
|
|
||||||
self->retryCount = 0;
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------*/
|
||||||
static void handleMoveCallback(pMotor self, SConnection *pCon)
|
static void handleMoveCallback(pMotor self, SConnection *pCon)
|
||||||
{
|
{
|
||||||
MotCallback sCall;
|
MotCallback sCall;
|
||||||
|
|
||||||
self->posCount++;
|
self->posCount++;
|
||||||
if(self->posCount >= ObVal(self->ParArray,POSCOUNT))
|
if(self->posCount >= ObVal(self->ParArray,MOVECOUNT))
|
||||||
{
|
{
|
||||||
MotorGetSoftPosition(self,pCon,&sCall.fVal);
|
MotorGetSoftPosition(self,pCon,&sCall.fVal);
|
||||||
sCall.pName = self->name;
|
sCall.pName = self->name;
|
||||||
@ -536,11 +413,11 @@ static void handleMoveCallback(pMotor self, SConnection *pCon)
|
|||||||
ObParInit(pM->ParArray,INT,"interruptmode",INTCONT,usMugger);
|
ObParInit(pM->ParArray,INT,"interruptmode",INTCONT,usMugger);
|
||||||
ObParInit(pM->ParArray,PREC,"precision",0.01,usMugger);
|
ObParInit(pM->ParArray,PREC,"precision",0.01,usMugger);
|
||||||
ObParInit(pM->ParArray,USRIGHTS,"accesscode",(float)usUser,usMugger);
|
ObParInit(pM->ParArray,USRIGHTS,"accesscode",(float)usUser,usMugger);
|
||||||
ObParInit(pM->ParArray,SPEED,"speed",0.02,usInternal);
|
|
||||||
ObParInit(pM->ParArray,SIGN,"sign",1.0,usMugger);
|
ObParInit(pM->ParArray,SIGN,"sign",1.0,usMugger);
|
||||||
ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger);
|
ObParInit(pM->ParArray,ECOUNT,"failafter",3.0,usMugger);
|
||||||
ObParInit(pM->ParArray,POSCOUNT,"maxretry",3.0,usMugger);
|
ObParInit(pM->ParArray,POSCOUNT,"maxretry",3.0,usMugger);
|
||||||
ObParInit(pM->ParArray,IGNOREFAULT,"ignorefault",0.0,usMugger);
|
ObParInit(pM->ParArray,IGNOREFAULT,"ignorefault",0.0,usMugger);
|
||||||
|
ObParInit(pM->ParArray,MOVECOUNT,"movecount",10.0,usMugger);
|
||||||
pDriv->GetPosition(pDriv,&(pM->fPosition));
|
pDriv->GetPosition(pDriv,&(pM->fPosition));
|
||||||
pM->fTarget = pM->fPosition;
|
pM->fTarget = pM->fPosition;
|
||||||
pM->endScriptID = 0;
|
pM->endScriptID = 0;
|
||||||
@ -878,6 +755,7 @@ extern void KillPiPiezo(void *pData);
|
|||||||
self->retryCount = 0;
|
self->retryCount = 0;
|
||||||
self->stopped = 0;
|
self->stopped = 0;
|
||||||
self->fTarget = fHard;
|
self->fTarget = fHard;
|
||||||
|
self->posCount = 0;
|
||||||
iRet = self->pDriver->RunTo(self->pDriver,fHard);
|
iRet = self->pDriver->RunTo(self->pDriver,fHard);
|
||||||
if(iRet != OKOK)
|
if(iRet != OKOK)
|
||||||
{ /* try three times to fix it */
|
{ /* try three times to fix it */
|
||||||
|
@ -103,7 +103,6 @@ CreateSocketAdress(
|
|||||||
sockaddrPtr->sin_addr.s_addr = addr.s_addr;
|
sockaddrPtr->sin_addr.s_addr = addr.s_addr;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
mkChannel *NETOpenPort(int iPort)
|
mkChannel *NETOpenPort(int iPort)
|
||||||
|
1
nread.c
1
nread.c
@ -139,6 +139,7 @@ extern VerifyChannel(mkChannel *self); /* defined in network.c */
|
|||||||
sItem.pCon = pCon;
|
sItem.pCon = pCon;
|
||||||
sItem.iEOD = 0;
|
sItem.iEOD = 0;
|
||||||
sItem.tStatus = tData;
|
sItem.tStatus = tData;
|
||||||
|
sItem.iReadable = 0;
|
||||||
memset(sItem.pHold,0,511);
|
memset(sItem.pHold,0,511);
|
||||||
|
|
||||||
LLDnodeAppendFrom(self->iList, &sItem);
|
LLDnodeAppendFrom(self->iList, &sItem);
|
||||||
|
@ -348,7 +348,10 @@
|
|||||||
if(pSICSOptions)
|
if(pSICSOptions)
|
||||||
IFDeleteOptions(pSICSOptions);
|
IFDeleteOptions(pSICSOptions);
|
||||||
if(self->pSics)
|
if(self->pSics)
|
||||||
|
{
|
||||||
DeleteInterp(self->pSics);
|
DeleteInterp(self->pSics);
|
||||||
|
self->pSics = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* close the server port */
|
/* close the server port */
|
||||||
if(self->pServerPort)
|
if(self->pServerPort)
|
||||||
|
4
obdes.h
4
obdes.h
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
#line 355 "interface.w"
|
#line 361 "interface.w"
|
||||||
|
|
||||||
|
|
||||||
#line 29 "interface.w"
|
#line 29 "interface.w"
|
||||||
@ -52,5 +52,5 @@ typedef struct {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#line 356 "interface.w"
|
#line 362 "interface.w"
|
||||||
|
|
||||||
|
4
ofac.c
4
ofac.c
@ -107,6 +107,7 @@
|
|||||||
#include "confvirtmot.h"
|
#include "confvirtmot.h"
|
||||||
#include "exeman.h"
|
#include "exeman.h"
|
||||||
#include "oscillate.h"
|
#include "oscillate.h"
|
||||||
|
#include "diffscan.h"
|
||||||
/*----------------------- Server options creation -------------------------*/
|
/*----------------------- Server options creation -------------------------*/
|
||||||
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
int argc, char *argv[])
|
int argc, char *argv[])
|
||||||
@ -288,6 +289,8 @@
|
|||||||
MakeExeManager,NULL,NULL);
|
MakeExeManager,NULL,NULL);
|
||||||
AddCommand(pInter,"MakeOscillator",
|
AddCommand(pInter,"MakeOscillator",
|
||||||
MakeOscillator,NULL,NULL);
|
MakeOscillator,NULL,NULL);
|
||||||
|
AddCommand(pInter,"MakeDiffScan",
|
||||||
|
MakeDiffScan,NULL,NULL);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -348,6 +351,7 @@
|
|||||||
RemoveCommand(pSics,"MakeConfigurableMotor");
|
RemoveCommand(pSics,"MakeConfigurableMotor");
|
||||||
RemoveCommand(pSics,"MakeBatchManager");
|
RemoveCommand(pSics,"MakeBatchManager");
|
||||||
RemoveCommand(pSics,"MakeOscillator");
|
RemoveCommand(pSics,"MakeOscillator");
|
||||||
|
RemoveCommand(pSics,"MakeDiffScan");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
remove site specific installation commands
|
remove site specific installation commands
|
||||||
|
@ -115,7 +115,7 @@
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pNew->pScanner = CreateScanObject(NULL,NULL,pCount);
|
pNew->pScanner = CreateScanObject(NULL,NULL,pCount,"optiscan");
|
||||||
if(!pNew->pScanner)
|
if(!pNew->pScanner)
|
||||||
{
|
{
|
||||||
DeleteDescriptor(pNew->pDes);
|
DeleteDescriptor(pNew->pDes);
|
||||||
|
10
oscillate.c
10
oscillate.c
@ -49,6 +49,16 @@ static int OscillationTask(void *data){
|
|||||||
errStatus = self->pMot->pDriver->TryAndFixIt(self->pMot->pDriver,code,pos);
|
errStatus = self->pMot->pDriver->TryAndFixIt(self->pMot->pDriver,code,pos);
|
||||||
self->errorCount++;
|
self->errorCount++;
|
||||||
if(errStatus == MOTFAIL){
|
if(errStatus == MOTFAIL){
|
||||||
|
/*
|
||||||
|
try driving the other way on a serious error
|
||||||
|
*/
|
||||||
|
if(self->nextTargetFlag == 1){
|
||||||
|
pos = self->upperLimit;
|
||||||
|
self->nextTargetFlag = 0;
|
||||||
|
} else {
|
||||||
|
pos = self->lowerLimit;
|
||||||
|
self->nextTargetFlag = 1;
|
||||||
|
}
|
||||||
MotorRun(self->pMot,self->pCon,pos);
|
MotorRun(self->pMot,self->pCon,pos);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
4
scan.h
4
scan.h
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
Mark Koennecke, October 1997
|
Mark Koennecke, October 1997
|
||||||
|
|
||||||
|
Extracted scan variable: Mark Koennecke, November 2004
|
||||||
|
|
||||||
copyright: see copyright.h
|
copyright: see copyright.h
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
#ifndef SICSSCAN1
|
#ifndef SICSSCAN1
|
||||||
@ -16,7 +18,7 @@
|
|||||||
|
|
||||||
/*------------------------- live & death ----------------------------------*/
|
/*------------------------- live & death ----------------------------------*/
|
||||||
pScanData CreateScanObject(char *pRecover, char *pHeader,
|
pScanData CreateScanObject(char *pRecover, char *pHeader,
|
||||||
pCounter pCount);
|
pCounter pCount, char *objName);
|
||||||
void DeleteScanObject(void *self);
|
void DeleteScanObject(void *self);
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
||||||
|
24
scan.i
24
scan.i
@ -6,16 +6,9 @@
|
|||||||
Mark Koennecke, October 1997
|
Mark Koennecke, October 1997
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#include "sdynar.h"
|
#include "sdynar.h"
|
||||||
|
#include "scanvar.h"
|
||||||
|
#include "stringdict.h"
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char Name[132];
|
|
||||||
pIDrivable pInter;
|
|
||||||
pDummy pObject;
|
|
||||||
float fStart;
|
|
||||||
float fStep;
|
|
||||||
float *fData;
|
|
||||||
int dataList;
|
|
||||||
}VarEntry, *pVarEntry;
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int i;
|
int i;
|
||||||
@ -28,6 +21,7 @@
|
|||||||
pObjectDescriptor pDes;
|
pObjectDescriptor pDes;
|
||||||
pICallBack pCall;
|
pICallBack pCall;
|
||||||
pDynar pScanVar;
|
pDynar pScanVar;
|
||||||
|
char objectName[132];
|
||||||
int iScanVar;
|
int iScanVar;
|
||||||
int iNP;
|
int iNP;
|
||||||
int iMode;
|
int iMode;
|
||||||
@ -50,6 +44,7 @@
|
|||||||
int (*CollectScanData)
|
int (*CollectScanData)
|
||||||
(pScanData self,
|
(pScanData self,
|
||||||
int iP);
|
int iP);
|
||||||
|
pStringDict scanFunctions;
|
||||||
long lPos;
|
long lPos;
|
||||||
int posSoft;
|
int posSoft;
|
||||||
void *pCounterData;
|
void *pCounterData;
|
||||||
@ -63,3 +58,14 @@
|
|||||||
void *pSpecial;
|
void *pSpecial;
|
||||||
} ScanData;
|
} ScanData;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
internal helper functions for scan implementations
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
CollectCounterData collects all the data from the configured counter
|
||||||
|
ans stows it away
|
||||||
|
*/
|
||||||
|
CountEntry CollectCounterData(pScanData self);
|
||||||
|
void InitCountEntry(pCountEntry pCount);
|
||||||
|
344
scan.tex
344
scan.tex
@ -1,37 +1,46 @@
|
|||||||
\subsection{Scan}
|
\subsection{Scan}
|
||||||
The first version of the scan command was implemented in Tcl. This prooved
|
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
|
to be inefficient. Therefore scan was reimplemented in C. Scanning
|
||||||
C. A scan is in principle simple. However some complications are due to the
|
seems to be simple but is not because of the many special cases
|
||||||
fact that data files need to be written. Disk files need to be updated after
|
involved:
|
||||||
each scan point. It must be possible to create derivations of the scan
|
\begin{itemize}
|
||||||
command which create other data formats or scan strategies. This
|
\item Scans must be interruptable and continuable
|
||||||
configurability is catered for the function pointers in the ScanData
|
\item Data files need to be written in different formats
|
||||||
structure. Individual functions can be exchanged and thus differently
|
\item Different output has to be generated at various steps
|
||||||
behaving scans created.
|
\item In polarization measurements, several points with different
|
||||||
|
magnetic field orientations need to be measured at the same instrument
|
||||||
|
position.
|
||||||
|
\item Users might want to be specify complex scan paths or scan on
|
||||||
|
logarithmic axis.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
I order to cope with all this, the scan module is modifiable in two
|
||||||
|
ways: For each step of the scanning process there is an overloadable
|
||||||
|
function in the scan data structure. The first way to modify scan
|
||||||
|
behavious thus is to write new functions in C and to assign them to
|
||||||
|
the scan module. In order to support scriptable scans another system
|
||||||
|
is in place: Stored in a string dictioanary there are the names of
|
||||||
|
SICS functions which will be called at each scan operation. The scan
|
||||||
|
functions then invoke the functions specified. In order for this to
|
||||||
|
work, the scan must be configured "newscan". These two schemes exits
|
||||||
|
because the scan module is in transition to a refactoring towards the
|
||||||
|
second scheme.
|
||||||
|
|
||||||
|
The principal setup thus is a central scan object which deals with
|
||||||
|
all the scan management: storing variables, positions, counting
|
||||||
|
results etc. and the configuration of the scan. This is augmented by
|
||||||
|
libraries of scan functions which get invoked at the various
|
||||||
|
steps. There is a standard scan library which is doumented here as well.
|
||||||
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\subsubsection{Scan Variables}
|
||||||
|
Scan variables are held in this data structure:
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap1}
|
\begin{minipage}{\linewidth} \label{scrap1}
|
||||||
$\langle$scandata {\footnotesize ?}$\rangle\equiv$
|
$\langle$scanvar {\footnotesize ?}$\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
@ -42,7 +51,116 @@ $\langle$scandata {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ float fStart;@\\
|
\mbox{}\verb@ float fStart;@\\
|
||||||
\mbox{}\verb@ float fStep;@\\
|
\mbox{}\verb@ float fStep;@\\
|
||||||
\mbox{}\verb@ float *fData;@\\
|
\mbox{}\verb@ float *fData;@\\
|
||||||
|
\mbox{}\verb@ int dataList;@\\
|
||||||
\mbox{}\verb@ }VarEntry, *pVarEntry;@\\
|
\mbox{}\verb@ }VarEntry, *pVarEntry;@\\
|
||||||
|
\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 dataList the positions actually reached
|
||||||
|
during the scan.
|
||||||
|
|
||||||
|
Scan variables have an interface:
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap2}
|
||||||
|
$\langle$scanvarint {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/**@\\
|
||||||
|
\mbox{}\verb@ * MakeScanVar creates a scan variable. All the necessary checks are @\\
|
||||||
|
\mbox{}\verb@ * performed@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pSics The interpreter in order to locate the variable.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pCon A connection object for error reporting@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param name The name of the variable to scan@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param start The start position from which to scan@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param step The step width with which to scan.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@return A pointer to a new scan variable object on success, NULL@\\
|
||||||
|
\mbox{}\verb@ * else@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ pVarEntry MakeScanVar(SicsInterp *pSics, SConnection *pCon, char@\\
|
||||||
|
\mbox{}\verb@ *name, float start, float step);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * InitScanVar clears the list of scan points@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pvar The scna variable to clear@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ void InitScanVar(pVarEntry pVar);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * DeleteVarEntry deletes a scan variable.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pData The scan variable entry to delete.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ void DeleteVarEntry(void *pData);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * ScanVarName returns the name of the scan variable@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to query.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@return The name of the scan variable. Do not delete pointer.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ char *ScanVarName(pVarEntry pVar);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * ScanVarStart returns the start value for the scan @\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to query.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@return The start point for the scan.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ float ScanVarStart(pVarEntry pVar);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * ScanVarStep returns the start value for the scan @\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to query.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@return The step width for the scan.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ float ScanVarStep(pVarEntry pVar);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * StartScanVar starts the scan variable to drive to the next@\\
|
||||||
|
\mbox{}\verb@ * position.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to start.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pCon The connection to report errors to.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param i The position number to drive to@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@return 1 on success, 0 on failure@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int StartScanVar(pVarEntry pVar, SConnection *pCon, int i);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * AppendScanVar appends a position to the list of positions@\\
|
||||||
|
\mbox{}\verb@ * reached while scanning this variable.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to append to.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pos The position to append.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ void AppendScanVar(pVarEntry pVar, float pos);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * GetScanVarPos returns a position for an index.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to append to.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param i The position number to retrieve@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@return The positiopn or -99999.99 for an error@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ float GetScanVarPos(pVarEntry pVar, int i);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * CopyScanVar copies the scan positions to the array given.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param pVar The scan variable to copy from@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param fData The array to copy to.@\\
|
||||||
|
\mbox{}\verb@ * @{\tt @}\verb@param np The number of slots in fData.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ void CopyScanVar(pVarEntry pVar, float *fData, int np);@\\
|
||||||
|
\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}
|
||||||
|
\subsubsection{The Scan Object}
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap3}
|
||||||
|
$\langle$scandata {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@/*--------------------------------------------------------------------------*/@\\
|
||||||
\mbox{}\verb@ typedef struct {@\\
|
\mbox{}\verb@ typedef struct {@\\
|
||||||
\mbox{}\verb@ int i;@\\
|
\mbox{}\verb@ int i;@\\
|
||||||
@ -55,6 +173,7 @@ $\langle$scandata {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
\mbox{}\verb@ pObjectDescriptor pDes;@\\
|
||||||
\mbox{}\verb@ pICallBack pCall;@\\
|
\mbox{}\verb@ pICallBack pCall;@\\
|
||||||
\mbox{}\verb@ pDynar pScanVar;@\\
|
\mbox{}\verb@ pDynar pScanVar;@\\
|
||||||
|
\mbox{}\verb@ char objectName[132];@\\
|
||||||
\mbox{}\verb@ int iScanVar;@\\
|
\mbox{}\verb@ int iScanVar;@\\
|
||||||
\mbox{}\verb@ int iNP;@\\
|
\mbox{}\verb@ int iNP;@\\
|
||||||
\mbox{}\verb@ int iMode;@\\
|
\mbox{}\verb@ int iMode;@\\
|
||||||
@ -77,6 +196,7 @@ $\langle$scandata {\footnotesize ?}$\rangle\equiv$
|
|||||||
\mbox{}\verb@ int (*CollectScanData)@\\
|
\mbox{}\verb@ int (*CollectScanData)@\\
|
||||||
\mbox{}\verb@ (pScanData self,@\\
|
\mbox{}\verb@ (pScanData self,@\\
|
||||||
\mbox{}\verb@ int iP);@\\
|
\mbox{}\verb@ int iP);@\\
|
||||||
|
\mbox{}\verb@ pStringDict scanFunctions;@\\
|
||||||
\mbox{}\verb@ long lPos;@\\
|
\mbox{}\verb@ long lPos;@\\
|
||||||
\mbox{}\verb@ int posSoft;@\\
|
\mbox{}\verb@ int posSoft;@\\
|
||||||
\mbox{}\verb@ void *pCounterData;@\\
|
\mbox{}\verb@ void *pCounterData;@\\
|
||||||
@ -98,11 +218,6 @@ $\langle$scandata {\footnotesize ?}$\rangle\equiv$
|
|||||||
\end{list}
|
\end{list}
|
||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\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
|
The CountEntry structure holds the entries for one counting
|
||||||
operations. These are the lCounts collected, up to 10 monitors and the
|
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.
|
time needed for counting. This is the time read from the counter box.
|
||||||
@ -158,6 +273,8 @@ This function together with ScanDrive and the data writing functions allow for
|
|||||||
\item[CollectScanData] reads all the scan data into the scan's data
|
\item[CollectScanData] reads all the scan data into the scan's data
|
||||||
structures after any scan point. Overload this if a different storage
|
structures after any scan point. Overload this if a different storage
|
||||||
scheme is required especiallay for polarising scans.
|
scheme is required especiallay for polarising scans.
|
||||||
|
\item[scanFunctions] A string dictionary holding the names of the
|
||||||
|
configured functions for the various steps of the scan.
|
||||||
\item[posSoft] is a flag which is true if scan variable are stored with
|
\item[posSoft] is a flag which is true if scan variable are stored with
|
||||||
soft position, i.e. with zeropoints applied.
|
soft position, i.e. with zeropoints applied.
|
||||||
\item[pCounterData] is a pointer to a counter structure. This defines the
|
\item[pCounterData] is a pointer to a counter structure. This defines the
|
||||||
@ -184,14 +301,14 @@ The functional interface to the scan module includes the following
|
|||||||
functions:
|
functions:
|
||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap2}
|
\begin{minipage}{\linewidth} \label{scrap4}
|
||||||
$\langle$scaninter {\footnotesize ?}$\rangle\equiv$
|
$\langle$scaninter {\footnotesize ?}$\rangle\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@/*------------------------- live & death ----------------------------------*/@\\
|
\mbox{}\verb@/*------------------------- live & death ----------------------------------*/@\\
|
||||||
\mbox{}\verb@ pScanData CreateScanObject(char *pRecover, char *pHeader, @\\
|
\mbox{}\verb@ pScanData CreateScanObject(char *pRecover, char *pHeader, @\\
|
||||||
\mbox{}\verb@ pCounter pCount);@\\
|
\mbox{}\verb@ pCounter pCount, char *objName);@\\
|
||||||
\mbox{}\verb@ void DeleteScanObject(void *self);@\\
|
\mbox{}\verb@ void DeleteScanObject(void *self);@\\
|
||||||
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\
|
||||||
\mbox{}\verb@ int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon, @\\
|
\mbox{}\verb@ int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon, @\\
|
||||||
@ -320,8 +437,125 @@ for the scan object.
|
|||||||
\item[ScanWrapper] is the SICS interpreter object function for
|
\item[ScanWrapper] is the SICS interpreter object function for
|
||||||
interacting with the scan module.
|
interacting with the scan module.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
|
\subsubsection{The Standard Scan Library}
|
||||||
|
The following functions constitute the standard scan library. Please
|
||||||
|
note that the scan file data format is driven by a template. The
|
||||||
|
format of this template is documented in the SICS managers
|
||||||
|
documentation.
|
||||||
|
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap3}
|
\begin{minipage}{\linewidth} \label{scrap5}
|
||||||
|
$\langle$stdscan {\footnotesize ?}$\rangle\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * write the header of the scan file@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int WriteHeader(pScanData self);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * WriteScanPoints is called for each point to write the scan data@\\
|
||||||
|
\mbox{}\verb@ * to screen and to file.@\\
|
||||||
|
\mbox{}\verb@ */ @\\
|
||||||
|
\mbox{}\verb@ int WriteScanPoints(pScanData self, int iPoint);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * Called before the scan to prepare. The default implementation@\\
|
||||||
|
\mbox{}\verb@ * checks if all scan positions are available and configures the@\\
|
||||||
|
\mbox{}\verb@ * counter.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int PrepareScan(pScanData self);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * second version of PrepareScan which does not check scan limits@\\
|
||||||
|
\mbox{}\verb@ */ @\\
|
||||||
|
\mbox{}\verb@ int NonCheckPrepare(pScanData self);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * ScanDrive handles driving to the scan point iPoint.@\\
|
||||||
|
\mbox{}\verb@ */ @\\
|
||||||
|
\mbox{}\verb@ int ScanDrive(pScanData self, int iPoint);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * ScanCount is called at each scan step to do the counting.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int ScanCount(pScanData self, int iPoint);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * CollectScanData stores the scans count results into @\\
|
||||||
|
\mbox{}\verb@ * the scan data structure and prints the information about the@\\
|
||||||
|
\mbox{}\verb@ * scan progress.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int CollectScanData(pScanData self, int iPoint);@\\
|
||||||
|
\mbox{}\verb@ int CollectScanDataJochen(pScanData self, int iPoint);@\\
|
||||||
|
\mbox{}\verb@/*===================================================================*/@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * Script invocation for writing the scan header.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int ScriptWriteHeader(pScanData self); @\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * Script writing each scan point@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int ScriptWriteScanPoints(pScanData self, int iPoint);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * Script preparation of the scan.@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int ScriptPrepareScan(pScanData self);@\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * Script driving to a scan point@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int ScriptScanDrive(pScanData self, int iPoint); @\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * Script counting a scan point@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int ScriptScanCount(pScanData self, int iPoint); @\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * Script collecting scan data for each scan point@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ int ScriptScanCollect(pScanData self, int iPoint); @\\
|
||||||
|
\mbox{}\verb@ /**@\\
|
||||||
|
\mbox{}\verb@ * ConfigureScript assigns the script invocation functions for@\\
|
||||||
|
\mbox{}\verb@ * scan@\\
|
||||||
|
\mbox{}\verb@ */@\\
|
||||||
|
\mbox{}\verb@ void ConfigureScript(pScanData self);@\\
|
||||||
|
\mbox{}\verb@/*=====================================================================*/@\\
|
||||||
|
\mbox{}\verb@ int StandardScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,@\\
|
||||||
|
\mbox{}\verb@ int argc, char *argv[]);@\\
|
||||||
|
\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}
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap6}
|
||||||
|
\verb@"scanvar.h"@ {\footnotesize ? }$\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/*-----------------------------------------------------------------------@\\
|
||||||
|
\mbox{}\verb@ Header file for the SICS ScanVariable. This is a support module for@\\
|
||||||
|
\mbox{}\verb@ the SICS scan system.@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ Evolved during refactoring scan in November 2004@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@ copyright: see file COPYRIGHT@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ Mark Koennecke, November 2004@\\
|
||||||
|
\mbox{}\verb@-------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@#ifndef SICSSCANVAR@\\
|
||||||
|
\mbox{}\verb@#define SICSSCANVAR@\\
|
||||||
|
\mbox{}\verb@#include "sics.h"@\\
|
||||||
|
\mbox{}\verb@@$\langle$scanvar {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@/*---------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@@$\langle$scanvarint {\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{scrap7}
|
||||||
\verb@"scan.h"@ {\footnotesize ? }$\equiv$
|
\verb@"scan.h"@ {\footnotesize ? }$\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
@ -333,6 +567,8 @@ interacting with the scan module.
|
|||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ Mark Koennecke, October 1997@\\
|
\mbox{}\verb@ Mark Koennecke, October 1997@\\
|
||||||
\mbox{}\verb@@\\
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ Extracted scan variable: Mark Koennecke, November 2004@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
\mbox{}\verb@ copyright: see copyright.h@\\
|
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||||
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@-----------------------------------------------------------------------------*/@\\
|
||||||
\mbox{}\verb@#ifndef SICSSCAN1@\\
|
\mbox{}\verb@#ifndef SICSSCAN1@\\
|
||||||
@ -348,7 +584,7 @@ interacting with the scan module.
|
|||||||
\end{minipage}\\[4ex]
|
\end{minipage}\\[4ex]
|
||||||
\end{flushleft}
|
\end{flushleft}
|
||||||
\begin{flushleft} \small
|
\begin{flushleft} \small
|
||||||
\begin{minipage}{\linewidth} \label{scrap4}
|
\begin{minipage}{\linewidth} \label{scrap8}
|
||||||
\verb@"scan.i"@ {\footnotesize ? }$\equiv$
|
\verb@"scan.i"@ {\footnotesize ? }$\equiv$
|
||||||
\vspace{-1ex}
|
\vspace{-1ex}
|
||||||
\begin{list}{}{} \item
|
\begin{list}{}{} \item
|
||||||
@ -360,7 +596,45 @@ interacting with the scan module.
|
|||||||
\mbox{}\verb@ Mark Koennecke, October 1997@\\
|
\mbox{}\verb@ Mark Koennecke, October 1997@\\
|
||||||
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||||
\mbox{}\verb@#include "sdynar.h"@\\
|
\mbox{}\verb@#include "sdynar.h"@\\
|
||||||
|
\mbox{}\verb@#include "scanvar.h"@\\
|
||||||
|
\mbox{}\verb@#include "stringdict.h"@\\
|
||||||
\mbox{}\verb@@$\langle$scandata {\footnotesize ?}$\rangle$\verb@@\\
|
\mbox{}\verb@@$\langle$scandata {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/*@\\
|
||||||
|
\mbox{}\verb@ internal helper functions for scan implementations@\\
|
||||||
|
\mbox{}\verb@*/@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/*@\\
|
||||||
|
\mbox{}\verb@ CollectCounterData collects all the data from the configured counter@\\
|
||||||
|
\mbox{}\verb@ ans stows it away@\\
|
||||||
|
\mbox{}\verb@*/@\\
|
||||||
|
\mbox{}\verb@CountEntry CollectCounterData(pScanData self);@\\
|
||||||
|
\mbox{}\verb@void InitCountEntry(pCountEntry pCount);@\\
|
||||||
|
\mbox{}\verb@@$\diamond$
|
||||||
|
\end{list}
|
||||||
|
\vspace{-2ex}
|
||||||
|
\end{minipage}\\[4ex]
|
||||||
|
\end{flushleft}
|
||||||
|
\begin{flushleft} \small
|
||||||
|
\begin{minipage}{\linewidth} \label{scrap9}
|
||||||
|
\verb@"stdscan.h"@ {\footnotesize ? }$\equiv$
|
||||||
|
\vspace{-1ex}
|
||||||
|
\begin{list}{}{} \item
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@/*--------------------------------------------------------------------------@\\
|
||||||
|
\mbox{}\verb@ S T A N D A R D S C A N@\\
|
||||||
|
\mbox{}\verb@ @\\
|
||||||
|
\mbox{}\verb@ This is a library of scan functions for the SICS standard scan. @\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ copyright: see copyright.h@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@ Extracted from scan.c: Mark Koennecke, November 2004 @\\
|
||||||
|
\mbox{}\verb@----------------------------------------------------------------------------*/@\\
|
||||||
|
\mbox{}\verb@#ifndef SICSSTDSCAN@\\
|
||||||
|
\mbox{}\verb@#define SICSSTDSCAN@\\
|
||||||
|
\mbox{}\verb@@$\langle$stdscan {\footnotesize ?}$\rangle$\verb@@\\
|
||||||
|
\mbox{}\verb@@\\
|
||||||
|
\mbox{}\verb@#endif@\\
|
||||||
\mbox{}\verb@@$\diamond$
|
\mbox{}\verb@@$\diamond$
|
||||||
\end{list}
|
\end{list}
|
||||||
\vspace{-2ex}
|
\vspace{-2ex}
|
||||||
|
284
scan.w
284
scan.w
@ -1,35 +1,44 @@
|
|||||||
\subsection{Scan}
|
\subsection{Scan}
|
||||||
The first version of the scan command was implemented in Tcl. This prooved
|
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
|
to be inefficient. Therefore scan was reimplemented in C. Scanning
|
||||||
C. A scan is in principle simple. However some complications are due to the
|
seems to be simple but is not because of the many special cases
|
||||||
fact that data files need to be written. Disk files need to be updated after
|
involved:
|
||||||
each scan point. It must be possible to create derivations of the scan
|
\begin{itemize}
|
||||||
command which create other data formats or scan strategies. This
|
\item Scans must be interruptable and continuable
|
||||||
configurability is catered for the function pointers in the ScanData
|
\item Data files need to be written in different formats
|
||||||
structure. Individual functions can be exchanged and thus differently
|
\item Different output has to be generated at various steps
|
||||||
behaving scans created.
|
\item In polarization measurements, several points with different
|
||||||
|
magnetic field orientations need to be measured at the same instrument
|
||||||
|
position.
|
||||||
|
\item Users might want to be specify complex scan paths or scan on
|
||||||
|
logarithmic axis.
|
||||||
|
\end{itemize}
|
||||||
|
|
||||||
|
I order to cope with all this, the scan module is modifiable in two
|
||||||
|
ways: For each step of the scanning process there is an overloadable
|
||||||
|
function in the scan data structure. The first way to modify scan
|
||||||
|
behavious thus is to write new functions in C and to assign them to
|
||||||
|
the scan module. In order to support scriptable scans another system
|
||||||
|
is in place: Stored in a string dictioanary there are the names of
|
||||||
|
SICS functions which will be called at each scan operation. The scan
|
||||||
|
functions then invoke the functions specified. In order for this to
|
||||||
|
work, the scan must be configured "newscan". These two schemes exits
|
||||||
|
because the scan module is in transition to a refactoring towards the
|
||||||
|
second scheme.
|
||||||
|
|
||||||
|
The principal setup thus is a central scan object which deals with
|
||||||
|
all the scan management: storing variables, positions, counting
|
||||||
|
results etc. and the configuration of the scan. This is augmented by
|
||||||
|
libraries of scan functions which get invoked at the various
|
||||||
|
steps. There is a standard scan library which is doumented here as well.
|
||||||
|
|
||||||
|
|
||||||
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 @{
|
|
||||||
|
\subsubsection{Scan Variables}
|
||||||
|
Scan variables are held in this data structure:
|
||||||
|
@d scanvar @{
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char Name[132];
|
char Name[132];
|
||||||
pIDrivable pInter;
|
pIDrivable pInter;
|
||||||
@ -37,7 +46,91 @@ steps in scan processing which is already partly implemented.
|
|||||||
float fStart;
|
float fStart;
|
||||||
float fStep;
|
float fStep;
|
||||||
float *fData;
|
float *fData;
|
||||||
|
int dataList;
|
||||||
}VarEntry, *pVarEntry;
|
}VarEntry, *pVarEntry;
|
||||||
|
@}
|
||||||
|
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 dataList the positions actually reached
|
||||||
|
during the scan.
|
||||||
|
|
||||||
|
Scan variables have an interface:
|
||||||
|
@d scanvarint @{
|
||||||
|
/**
|
||||||
|
* MakeScanVar creates a scan variable. All the necessary checks are
|
||||||
|
* performed
|
||||||
|
* @@param pSics The interpreter in order to locate the variable.
|
||||||
|
* @@param pCon A connection object for error reporting
|
||||||
|
* @@param name The name of the variable to scan
|
||||||
|
* @@param start The start position from which to scan
|
||||||
|
* @@param step The step width with which to scan.
|
||||||
|
* @@return A pointer to a new scan variable object on success, NULL
|
||||||
|
* else
|
||||||
|
*/
|
||||||
|
pVarEntry MakeScanVar(SicsInterp *pSics, SConnection *pCon, char
|
||||||
|
*name, float start, float step);
|
||||||
|
/**
|
||||||
|
* InitScanVar clears the list of scan points
|
||||||
|
* @@param pvar The scna variable to clear
|
||||||
|
*/
|
||||||
|
void InitScanVar(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* DeleteVarEntry deletes a scan variable.
|
||||||
|
* @@param pData The scan variable entry to delete.
|
||||||
|
*/
|
||||||
|
void DeleteVarEntry(void *pData);
|
||||||
|
/**
|
||||||
|
* ScanVarName returns the name of the scan variable
|
||||||
|
* @@param pVar The scan variable to query.
|
||||||
|
* @@return The name of the scan variable. Do not delete pointer.
|
||||||
|
*/
|
||||||
|
char *ScanVarName(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* ScanVarStart returns the start value for the scan
|
||||||
|
* @@param pVar The scan variable to query.
|
||||||
|
* @@return The start point for the scan.
|
||||||
|
*/
|
||||||
|
float ScanVarStart(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* ScanVarStep returns the start value for the scan
|
||||||
|
* @@param pVar The scan variable to query.
|
||||||
|
* @@return The step width for the scan.
|
||||||
|
*/
|
||||||
|
float ScanVarStep(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* StartScanVar starts the scan variable to drive to the next
|
||||||
|
* position.
|
||||||
|
* @@param pVar The scan variable to start.
|
||||||
|
* @@param pCon The connection to report errors to.
|
||||||
|
* @@param i The position number to drive to
|
||||||
|
* @@return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int StartScanVar(pVarEntry pVar, SConnection *pCon, int i);
|
||||||
|
/**
|
||||||
|
* AppendScanVar appends a position to the list of positions
|
||||||
|
* reached while scanning this variable.
|
||||||
|
* @@param pVar The scan variable to append to.
|
||||||
|
* @@param pos The position to append.
|
||||||
|
*/
|
||||||
|
void AppendScanVar(pVarEntry pVar, float pos);
|
||||||
|
/**
|
||||||
|
* GetScanVarPos returns a position for an index.
|
||||||
|
* @@param pVar The scan variable to append to.
|
||||||
|
* @@param i The position number to retrieve
|
||||||
|
* @@return The positiopn or -99999.99 for an error
|
||||||
|
*/
|
||||||
|
float GetScanVarPos(pVarEntry pVar, int i);
|
||||||
|
/**
|
||||||
|
* CopyScanVar copies the scan positions to the array given.
|
||||||
|
* @@param pVar The scan variable to copy from
|
||||||
|
* @@param fData The array to copy to.
|
||||||
|
* @@param np The number of slots in fData.
|
||||||
|
*/
|
||||||
|
void CopyScanVar(pVarEntry pVar, float *fData, int np);
|
||||||
|
@}
|
||||||
|
|
||||||
|
\subsubsection{The Scan Object}
|
||||||
|
@d scandata @{
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int i;
|
int i;
|
||||||
@ -50,6 +143,7 @@ steps in scan processing which is already partly implemented.
|
|||||||
pObjectDescriptor pDes;
|
pObjectDescriptor pDes;
|
||||||
pICallBack pCall;
|
pICallBack pCall;
|
||||||
pDynar pScanVar;
|
pDynar pScanVar;
|
||||||
|
char objectName[132];
|
||||||
int iScanVar;
|
int iScanVar;
|
||||||
int iNP;
|
int iNP;
|
||||||
int iMode;
|
int iMode;
|
||||||
@ -72,6 +166,7 @@ steps in scan processing which is already partly implemented.
|
|||||||
int (*CollectScanData)
|
int (*CollectScanData)
|
||||||
(pScanData self,
|
(pScanData self,
|
||||||
int iP);
|
int iP);
|
||||||
|
pStringDict scanFunctions;
|
||||||
long lPos;
|
long lPos;
|
||||||
int posSoft;
|
int posSoft;
|
||||||
void *pCounterData;
|
void *pCounterData;
|
||||||
@ -86,10 +181,6 @@ steps in scan processing which is already partly implemented.
|
|||||||
} ScanData;
|
} 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
|
The CountEntry structure holds the entries for one counting
|
||||||
operations. These are the lCounts collected, up to 10 monitors and the
|
operations. These are the lCounts collected, up to 10 monitors and the
|
||||||
@ -146,6 +237,8 @@ This function together with ScanDrive and the data writing functions allow for
|
|||||||
\item[CollectScanData] reads all the scan data into the scan's data
|
\item[CollectScanData] reads all the scan data into the scan's data
|
||||||
structures after any scan point. Overload this if a different storage
|
structures after any scan point. Overload this if a different storage
|
||||||
scheme is required especiallay for polarising scans.
|
scheme is required especiallay for polarising scans.
|
||||||
|
\item[scanFunctions] A string dictionary holding the names of the
|
||||||
|
configured functions for the various steps of the scan.
|
||||||
\item[posSoft] is a flag which is true if scan variable are stored with
|
\item[posSoft] is a flag which is true if scan variable are stored with
|
||||||
soft position, i.e. with zeropoints applied.
|
soft position, i.e. with zeropoints applied.
|
||||||
\item[pCounterData] is a pointer to a counter structure. This defines the
|
\item[pCounterData] is a pointer to a counter structure. This defines the
|
||||||
@ -174,7 +267,7 @@ functions:
|
|||||||
@d scaninter @{
|
@d scaninter @{
|
||||||
/*------------------------- live & death ----------------------------------*/
|
/*------------------------- live & death ----------------------------------*/
|
||||||
pScanData CreateScanObject(char *pRecover, char *pHeader,
|
pScanData CreateScanObject(char *pRecover, char *pHeader,
|
||||||
pCounter pCount);
|
pCounter pCount, char *objName);
|
||||||
void DeleteScanObject(void *self);
|
void DeleteScanObject(void *self);
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon,
|
||||||
@ -295,6 +388,105 @@ for the scan object.
|
|||||||
\item[ScanWrapper] is the SICS interpreter object function for
|
\item[ScanWrapper] is the SICS interpreter object function for
|
||||||
interacting with the scan module.
|
interacting with the scan module.
|
||||||
\end{description}
|
\end{description}
|
||||||
|
|
||||||
|
\subsubsection{The Standard Scan Library}
|
||||||
|
The following functions constitute the standard scan library. Please
|
||||||
|
note that the scan file data format is driven by a template. The
|
||||||
|
format of this template is documented in the SICS managers
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
@d stdscan @{
|
||||||
|
/**
|
||||||
|
* write the header of the scan file
|
||||||
|
*/
|
||||||
|
int WriteHeader(pScanData self);
|
||||||
|
/**
|
||||||
|
* WriteScanPoints is called for each point to write the scan data
|
||||||
|
* to screen and to file.
|
||||||
|
*/
|
||||||
|
int WriteScanPoints(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Called before the scan to prepare. The default implementation
|
||||||
|
* checks if all scan positions are available and configures the
|
||||||
|
* counter.
|
||||||
|
*/
|
||||||
|
int PrepareScan(pScanData self);
|
||||||
|
/**
|
||||||
|
* second version of PrepareScan which does not check scan limits
|
||||||
|
*/
|
||||||
|
int NonCheckPrepare(pScanData self);
|
||||||
|
/**
|
||||||
|
* ScanDrive handles driving to the scan point iPoint.
|
||||||
|
*/
|
||||||
|
int ScanDrive(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* ScanCount is called at each scan step to do the counting.
|
||||||
|
*/
|
||||||
|
int ScanCount(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* CollectScanData stores the scans count results into
|
||||||
|
* the scan data structure and prints the information about the
|
||||||
|
* scan progress.
|
||||||
|
*/
|
||||||
|
int CollectScanData(pScanData self, int iPoint);
|
||||||
|
int CollectScanDataJochen(pScanData self, int iPoint);
|
||||||
|
/*===================================================================*/
|
||||||
|
/**
|
||||||
|
* Script invocation for writing the scan header.
|
||||||
|
*/
|
||||||
|
int ScriptWriteHeader(pScanData self);
|
||||||
|
/**
|
||||||
|
* Script writing each scan point
|
||||||
|
*/
|
||||||
|
int ScriptWriteScanPoints(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Script preparation of the scan.
|
||||||
|
*/
|
||||||
|
int ScriptPrepareScan(pScanData self);
|
||||||
|
/**
|
||||||
|
* Script driving to a scan point
|
||||||
|
*/
|
||||||
|
int ScriptScanDrive(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Script counting a scan point
|
||||||
|
*/
|
||||||
|
int ScriptScanCount(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Script collecting scan data for each scan point
|
||||||
|
*/
|
||||||
|
int ScriptScanCollect(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* ConfigureScript assigns the script invocation functions for
|
||||||
|
* scan
|
||||||
|
*/
|
||||||
|
void ConfigureScript(pScanData self);
|
||||||
|
/*=====================================================================*/
|
||||||
|
int StandardScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
@}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@o scanvar.h @{
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
Header file for the SICS ScanVariable. This is a support module for
|
||||||
|
the SICS scan system.
|
||||||
|
|
||||||
|
Evolved during refactoring scan in November 2004
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, November 2004
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSSCANVAR
|
||||||
|
#define SICSSCANVAR
|
||||||
|
#include "sics.h"
|
||||||
|
@<scanvar@>
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
@<scanvarint@>
|
||||||
|
#endif
|
||||||
|
@}
|
||||||
|
|
||||||
@o scan.h @{
|
@o scan.h @{
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
S C A N
|
S C A N
|
||||||
@ -303,6 +495,8 @@ interacting with the scan module.
|
|||||||
|
|
||||||
Mark Koennecke, October 1997
|
Mark Koennecke, October 1997
|
||||||
|
|
||||||
|
Extracted scan variable: Mark Koennecke, November 2004
|
||||||
|
|
||||||
copyright: see copyright.h
|
copyright: see copyright.h
|
||||||
-----------------------------------------------------------------------------*/
|
-----------------------------------------------------------------------------*/
|
||||||
#ifndef SICSSCAN1
|
#ifndef SICSSCAN1
|
||||||
@ -322,9 +516,37 @@ interacting with the scan module.
|
|||||||
Mark Koennecke, October 1997
|
Mark Koennecke, October 1997
|
||||||
----------------------------------------------------------------------------*/
|
----------------------------------------------------------------------------*/
|
||||||
#include "sdynar.h"
|
#include "sdynar.h"
|
||||||
|
#include "scanvar.h"
|
||||||
|
#include "stringdict.h"
|
||||||
@<scandata@>
|
@<scandata@>
|
||||||
|
|
||||||
|
/*
|
||||||
|
internal helper functions for scan implementations
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
CollectCounterData collects all the data from the configured counter
|
||||||
|
ans stows it away
|
||||||
|
*/
|
||||||
|
CountEntry CollectCounterData(pScanData self);
|
||||||
|
void InitCountEntry(pCountEntry pCount);
|
||||||
@}
|
@}
|
||||||
|
|
||||||
|
|
||||||
|
@o stdscan.h @{
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
S T A N D A R D S C A N
|
||||||
|
|
||||||
|
This is a library of scan functions for the SICS standard scan.
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Extracted from scan.c: Mark Koennecke, November 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSSTDSCAN
|
||||||
|
#define SICSSTDSCAN
|
||||||
|
@<stdscan@>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@}
|
||||||
|
|
||||||
|
154
scanvar.c
Normal file
154
scanvar.c
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
Implementation file for the SICS ScanVariable. This is a support module
|
||||||
|
for the SICS scan system.
|
||||||
|
|
||||||
|
Evolved during refactoring scan in November 2004
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, November 2004
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include "fortify.h"
|
||||||
|
#include "sics.h"
|
||||||
|
#include "scanvar.h"
|
||||||
|
#include "lld.h"
|
||||||
|
#include "devexec.h"
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
pVarEntry MakeScanVar(SicsInterp *pSics, SConnection *pCon, char
|
||||||
|
*name, float start, float step){
|
||||||
|
CommandList *pCom = NULL;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
pDummy pData = NULL;
|
||||||
|
pVarEntry pVar = NULL;
|
||||||
|
char pBueffel[512];
|
||||||
|
|
||||||
|
/*
|
||||||
|
allocate space
|
||||||
|
*/
|
||||||
|
pVar = (pVarEntry)malloc(sizeof(VarEntry));
|
||||||
|
if(pVar == NULL){
|
||||||
|
SCWrite(pCon,"ERROR: out of memory allocating scan variable",eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(pVar,0,sizeof(VarEntry));
|
||||||
|
|
||||||
|
/* find the thing */
|
||||||
|
pCom = FindCommand(pSics,name);
|
||||||
|
if(!pCom){
|
||||||
|
snprintf(pBueffel,511,"ERROR: Cannot find variable %s to scan",name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pData = (pDummy)pCom->pData;
|
||||||
|
if(!pData){
|
||||||
|
snprintf(pBueffel,511,"ERROR: Cannot find data for variable %s",name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pDriv = pData->pDescriptor->GetInterface(pData,DRIVEID);
|
||||||
|
if(!pDriv){
|
||||||
|
snprintf(pBueffel,511,
|
||||||
|
"ERROR: variable %s is NOT driveable and cannot be scanned",name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* got everything, fill in the VarEntry structure */
|
||||||
|
strcpy(pVar->Name,name);
|
||||||
|
pVar->pInter = pDriv;
|
||||||
|
pVar->pObject = pData;
|
||||||
|
pVar->fStart = start;
|
||||||
|
pVar->fStep = step;
|
||||||
|
pVar->dataList = LLDcreate(sizeof(float));
|
||||||
|
|
||||||
|
return pVar;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------*/
|
||||||
|
void InitScanVar(pVarEntry pVar){
|
||||||
|
LLDdelete(pVar->dataList);
|
||||||
|
pVar->dataList = LLDcreate(sizeof(float));
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
void DeleteVarEntry(void *pData){
|
||||||
|
pVarEntry pVar = NULL;
|
||||||
|
|
||||||
|
pVar = (pVarEntry)pData;
|
||||||
|
|
||||||
|
if(pVar == NULL){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pVar->fData){
|
||||||
|
free(pVar->fData);
|
||||||
|
}
|
||||||
|
LLDdelete(pVar->dataList);
|
||||||
|
free(pVar);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
char *ScanVarName(pVarEntry pVar){
|
||||||
|
return pVar->Name;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
float ScanVarStart(pVarEntry pVar){
|
||||||
|
return pVar->fStart;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
float ScanVarStep(pVarEntry pVar){
|
||||||
|
return pVar->fStep;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int StartScanVar(pVarEntry pVar, SConnection *pCon, int i){
|
||||||
|
float fVal;
|
||||||
|
pDummy pDum;
|
||||||
|
char pBueffel[512];
|
||||||
|
int status;
|
||||||
|
|
||||||
|
pDum = (pDummy)pVar->pObject;
|
||||||
|
fVal = pVar->fStart + i * pVar->fStep;
|
||||||
|
status = StartDevice(pServ->pExecutor,
|
||||||
|
pVar->Name,
|
||||||
|
pDum->pDescriptor,
|
||||||
|
pVar->pObject,
|
||||||
|
pCon,
|
||||||
|
fVal);
|
||||||
|
if(!status){
|
||||||
|
snprintf(pBueffel,511,"ERROR: Failed to start %s",pVar->Name);
|
||||||
|
SCWrite(pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
void AppendScanVar(pVarEntry pVar, float pos){
|
||||||
|
float fVal = pos;
|
||||||
|
LLDnodeAppendFrom(pVar->dataList,&fVal);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
float GetScanVarPos(pVarEntry pVar, int i){
|
||||||
|
int count = 0, status;
|
||||||
|
|
||||||
|
status = LLDnodePtr2First(pVar->dataList);
|
||||||
|
while(count < i && (status = LLDnodePtr2Next(pVar->dataList)) != 0){
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
if(count == i){
|
||||||
|
return LLDnodeFloat(pVar->dataList);
|
||||||
|
} else {
|
||||||
|
return -99999.99;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
void CopyScanVar(pVarEntry pVar, float *fData, int np){
|
||||||
|
int i, count = 0, status;
|
||||||
|
|
||||||
|
status = LLDnodePtr2First(pVar->dataList);
|
||||||
|
while(status > 0 && count < np){
|
||||||
|
fData[count] = LLDnodeFloat(pVar->dataList);
|
||||||
|
count++;
|
||||||
|
status = LLDnodePtr2Next(pVar->dataList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
100
scanvar.h
Normal file
100
scanvar.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
|
||||||
|
/*-----------------------------------------------------------------------
|
||||||
|
Header file for the SICS ScanVariable. This is a support module for
|
||||||
|
the SICS scan system.
|
||||||
|
|
||||||
|
Evolved during refactoring scan in November 2004
|
||||||
|
|
||||||
|
copyright: see file COPYRIGHT
|
||||||
|
|
||||||
|
Mark Koennecke, November 2004
|
||||||
|
-------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSSCANVAR
|
||||||
|
#define SICSSCANVAR
|
||||||
|
#include "sics.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char Name[132];
|
||||||
|
pIDrivable pInter;
|
||||||
|
pDummy pObject;
|
||||||
|
float fStart;
|
||||||
|
float fStep;
|
||||||
|
float *fData;
|
||||||
|
int dataList;
|
||||||
|
}VarEntry, *pVarEntry;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MakeScanVar creates a scan variable. All the necessary checks are
|
||||||
|
* performed
|
||||||
|
* @param pSics The interpreter in order to locate the variable.
|
||||||
|
* @param pCon A connection object for error reporting
|
||||||
|
* @param name The name of the variable to scan
|
||||||
|
* @param start The start position from which to scan
|
||||||
|
* @param step The step width with which to scan.
|
||||||
|
* @return A pointer to a new scan variable object on success, NULL
|
||||||
|
* else
|
||||||
|
*/
|
||||||
|
pVarEntry MakeScanVar(SicsInterp *pSics, SConnection *pCon, char
|
||||||
|
*name, float start, float step);
|
||||||
|
/**
|
||||||
|
* InitScanVar clears the list of scan points
|
||||||
|
* @param pvar The scna variable to clear
|
||||||
|
*/
|
||||||
|
void InitScanVar(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* DeleteVarEntry deletes a scan variable.
|
||||||
|
* @param pData The scan variable entry to delete.
|
||||||
|
*/
|
||||||
|
void DeleteVarEntry(void *pData);
|
||||||
|
/**
|
||||||
|
* ScanVarName returns the name of the scan variable
|
||||||
|
* @param pVar The scan variable to query.
|
||||||
|
* @return The name of the scan variable. Do not delete pointer.
|
||||||
|
*/
|
||||||
|
char *ScanVarName(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* ScanVarStart returns the start value for the scan
|
||||||
|
* @param pVar The scan variable to query.
|
||||||
|
* @return The start point for the scan.
|
||||||
|
*/
|
||||||
|
float ScanVarStart(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* ScanVarStep returns the start value for the scan
|
||||||
|
* @param pVar The scan variable to query.
|
||||||
|
* @return The step width for the scan.
|
||||||
|
*/
|
||||||
|
float ScanVarStep(pVarEntry pVar);
|
||||||
|
/**
|
||||||
|
* StartScanVar starts the scan variable to drive to the next
|
||||||
|
* position.
|
||||||
|
* @param pVar The scan variable to start.
|
||||||
|
* @param pCon The connection to report errors to.
|
||||||
|
* @param i The position number to drive to
|
||||||
|
* @return 1 on success, 0 on failure
|
||||||
|
*/
|
||||||
|
int StartScanVar(pVarEntry pVar, SConnection *pCon, int i);
|
||||||
|
/**
|
||||||
|
* AppendScanVar appends a position to the list of positions
|
||||||
|
* reached while scanning this variable.
|
||||||
|
* @param pVar The scan variable to append to.
|
||||||
|
* @param pos The position to append.
|
||||||
|
*/
|
||||||
|
void AppendScanVar(pVarEntry pVar, float pos);
|
||||||
|
/**
|
||||||
|
* GetScanVarPos returns a position for an index.
|
||||||
|
* @param pVar The scan variable to append to.
|
||||||
|
* @param i The position number to retrieve
|
||||||
|
* @return The positiopn or -99999.99 for an error
|
||||||
|
*/
|
||||||
|
float GetScanVarPos(pVarEntry pVar, int i);
|
||||||
|
/**
|
||||||
|
* CopyScanVar copies the scan positions to the array given.
|
||||||
|
* @param pVar The scan variable to copy from
|
||||||
|
* @param fData The array to copy to.
|
||||||
|
* @param np The number of slots in fData.
|
||||||
|
*/
|
||||||
|
void CopyScanVar(pVarEntry pVar, float *fData, int np);
|
||||||
|
|
||||||
|
#endif
|
@ -259,8 +259,8 @@
|
|||||||
{
|
{
|
||||||
printf("ERROR: cannot open logfile %s for writing\n",
|
printf("ERROR: cannot open logfile %s for writing\n",
|
||||||
pFile);
|
pFile);
|
||||||
|
fLogFile = NULL;
|
||||||
exit(1);
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
749
stdscan.c
Normal file
749
stdscan.c
Normal file
@ -0,0 +1,749 @@
|
|||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
S T A N D A R D S C A N
|
||||||
|
|
||||||
|
This is a library of scan functions for the SICS standard scan.
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Extracted from scan.c: Mark Koennecke, November 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#include "sics.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <tcl.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "fortify.h"
|
||||||
|
#include "sdynar.h"
|
||||||
|
#include "dynstring.h"
|
||||||
|
#include "stringdict.h"
|
||||||
|
#include "status.h"
|
||||||
|
#include "sicsvar.h"
|
||||||
|
#include "counter.h"
|
||||||
|
#include "scan.h"
|
||||||
|
#include "scan.i"
|
||||||
|
#include "splitter.h"
|
||||||
|
#include "danu.h"
|
||||||
|
#include "userscan.h"
|
||||||
|
#include "motor.h"
|
||||||
|
#include "nxscript.h"
|
||||||
|
#include "nxutil.h"
|
||||||
|
#include "site.h"
|
||||||
|
#include "lld.h"
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int WriteHeader(pScanData self)
|
||||||
|
{
|
||||||
|
int i, iRet;
|
||||||
|
FILE *fd;
|
||||||
|
char pBuffer[512], pError[512], *pPtr, *pName;
|
||||||
|
CommandList *pCom = NULL;
|
||||||
|
pSicsVariable pVar = NULL;
|
||||||
|
pDummy pDum = NULL;
|
||||||
|
pIDrivable pDriv = NULL;
|
||||||
|
float fVal;
|
||||||
|
pMotor pMot = NULL;
|
||||||
|
pVarEntry pScanVar = NULL;
|
||||||
|
void *pVoid = NULL;
|
||||||
|
|
||||||
|
assert(self->pSics);
|
||||||
|
assert(self->pCon);
|
||||||
|
|
||||||
|
/* open data file */
|
||||||
|
self->fd = fopen(self->pFile,"w");
|
||||||
|
if(!self->fd)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,"ERROR: cannot write data file",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* open header description file */
|
||||||
|
fd = fopen(self->pHeaderFile,"r");
|
||||||
|
if(!fd)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,"ERROR: cannot open header description file",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* loop through description file and act along the way */
|
||||||
|
while(fgets(pBuffer,511,fd) != NULL)
|
||||||
|
{
|
||||||
|
pPtr = strstr(pBuffer,"!!VAR(");
|
||||||
|
if(pPtr) /* handle a Sics variable */
|
||||||
|
{
|
||||||
|
/* extract the name */
|
||||||
|
pName = pPtr + 6; /* first char of name */
|
||||||
|
*pPtr = '\0'; /* this is the starter of the line */
|
||||||
|
pPtr = pName;
|
||||||
|
while( (*pPtr != '\0') && (*pPtr != ')') )
|
||||||
|
{
|
||||||
|
pPtr++;
|
||||||
|
}
|
||||||
|
*pPtr = '\0';
|
||||||
|
/* find the variable */
|
||||||
|
pCom = FindCommand(self->pSics,pName);
|
||||||
|
if(!pCom)
|
||||||
|
{
|
||||||
|
sprintf(pError,"ERROR: variable %s NOT found",pName);
|
||||||
|
SCWrite(self->pCon,pError,eError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pVar = (pSicsVariable)pCom->pData;
|
||||||
|
if(!pVar)
|
||||||
|
{
|
||||||
|
sprintf(pError,"ERROR: variable %s NOT found",pName);
|
||||||
|
SCWrite(self->pCon,pError,eError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(pVar->eType)
|
||||||
|
{
|
||||||
|
case veFloat:
|
||||||
|
sprintf(pError,"%f",pVar->fVal);
|
||||||
|
break;
|
||||||
|
case veInt:
|
||||||
|
sprintf(pError,"%d",pVar->iVal);
|
||||||
|
break;
|
||||||
|
case veText:
|
||||||
|
sprintf(pError,"%s",pVar->text);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* finally write */
|
||||||
|
fprintf(self->fd,"%s %s\n",pBuffer,pError);
|
||||||
|
continue;
|
||||||
|
}/* end variable */
|
||||||
|
/*------- Drivable */
|
||||||
|
pPtr = strstr(pBuffer,"!!DRIV(");
|
||||||
|
if(pPtr)
|
||||||
|
{
|
||||||
|
/* extract the name */
|
||||||
|
pName = pPtr + 7; /* first char of name */
|
||||||
|
*pPtr = '\0'; /* this is the starter of the line */
|
||||||
|
pPtr = pName;
|
||||||
|
while( (*pPtr != '\0') && (*pPtr != ')') )
|
||||||
|
{
|
||||||
|
pPtr++;
|
||||||
|
}
|
||||||
|
*pPtr = '\0';
|
||||||
|
/* find the variable */
|
||||||
|
pCom = FindCommand(self->pSics,pName);
|
||||||
|
if(!pCom)
|
||||||
|
{
|
||||||
|
sprintf(pError,"ERROR: variable %s NOT found",pName);
|
||||||
|
SCWrite(self->pCon,pError,eError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pDum = (pDummy)pCom->pData;
|
||||||
|
if(!pDum)
|
||||||
|
{
|
||||||
|
sprintf(pError,"ERROR: variable %s is NOT drivable",pName);
|
||||||
|
SCWrite(self->pCon,pError,eError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pDriv = (pIDrivable)pDum->pDescriptor->GetInterface(pDum,DRIVEID);
|
||||||
|
if(!pDriv)
|
||||||
|
{
|
||||||
|
sprintf(pError,"ERROR: variable %s is NOT drivable",pName);
|
||||||
|
SCWrite(self->pCon,pError,eError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fVal = pDriv->GetValue(pDum,self->pCon);
|
||||||
|
fprintf(self->fd,"%s %f\n",pBuffer,fVal);
|
||||||
|
continue;
|
||||||
|
} /* end drive */
|
||||||
|
/*------- zero point */
|
||||||
|
pPtr = strstr(pBuffer,"!!ZERO(");
|
||||||
|
if(pPtr)
|
||||||
|
{
|
||||||
|
/* extract the name */
|
||||||
|
pName = pPtr + 7; /* first char of name */
|
||||||
|
*pPtr = '\0'; /* this is the starter of the line */
|
||||||
|
pPtr = pName;
|
||||||
|
while( (*pPtr != '\0') && (*pPtr != ')') )
|
||||||
|
{
|
||||||
|
pPtr++;
|
||||||
|
}
|
||||||
|
*pPtr = '\0';
|
||||||
|
/* find the motor */
|
||||||
|
pMot = FindMotor(self->pSics,pName);
|
||||||
|
if(!pMot)
|
||||||
|
{
|
||||||
|
sprintf(pError,"ERROR: motor %s NOT found",pName);
|
||||||
|
SCWrite(self->pCon,pError,eError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
iRet = MotorGetPar(pMot,"softzero",&fVal);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,"ERROR: failed to read zero point",eError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
fprintf(self->fd,"%s %f\n",pBuffer,fVal);
|
||||||
|
continue;
|
||||||
|
} /* end zero point */
|
||||||
|
/* ------- date */
|
||||||
|
pPtr = strstr(pBuffer,"!!DATE!!");
|
||||||
|
if(pPtr)
|
||||||
|
{
|
||||||
|
*pPtr = '\0';
|
||||||
|
SNXFormatTime(pError,511);
|
||||||
|
fprintf(self->fd,"%s %s\n",pBuffer,pError);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*-------- filename */
|
||||||
|
pPtr = strstr(pBuffer,"!!FILE!!");
|
||||||
|
if(pPtr)
|
||||||
|
{
|
||||||
|
*pPtr = '\0';
|
||||||
|
fprintf(self->fd,"%s %s\n",pBuffer,self->pFile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/*------------ scanzero */
|
||||||
|
pPtr = strstr(pBuffer,"!!SCANZERO!!");
|
||||||
|
if(pPtr)
|
||||||
|
{
|
||||||
|
*pPtr = '\0';
|
||||||
|
/* write zero point of first scan variable if motor */
|
||||||
|
DynarGet(self->pScanVar,0,&pVoid);
|
||||||
|
pScanVar = (pVarEntry)pVoid;
|
||||||
|
if(pScanVar)
|
||||||
|
{
|
||||||
|
pMot = NULL;
|
||||||
|
pMot = FindMotor(self->pSics,ScanVarName(pScanVar));
|
||||||
|
if(pMot != NULL)
|
||||||
|
{
|
||||||
|
MotorGetPar(pMot,"softzero",&fVal);
|
||||||
|
fprintf(self->fd,"%s zero = %8.3f\n",ScanVarName(pScanVar),
|
||||||
|
fVal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* --------- plain text */
|
||||||
|
fprintf(self->fd,"%s",pBuffer);
|
||||||
|
} /* end while */
|
||||||
|
|
||||||
|
|
||||||
|
/* remember position for seeking to it for writing data */
|
||||||
|
self->lPos = ftell(self->fd);
|
||||||
|
|
||||||
|
fclose(fd);
|
||||||
|
fclose(self->fd);
|
||||||
|
self->fd = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int WriteScanPoints(pScanData self, int iPoint)
|
||||||
|
{
|
||||||
|
int i, i2;
|
||||||
|
char pLine[512], pItem[30], pInfo[512];
|
||||||
|
pVarEntry pVar = NULL;
|
||||||
|
pCountEntry pData = NULL;
|
||||||
|
void *pPtr = NULL;
|
||||||
|
|
||||||
|
assert(self->pCon);
|
||||||
|
assert(self->pSics);
|
||||||
|
|
||||||
|
/* reopen file */
|
||||||
|
self->fd = fopen(self->pFile,"r+");
|
||||||
|
if(!self->fd)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,
|
||||||
|
"ERROR: Failed to reopen scan file, aborting scan",
|
||||||
|
eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* jump to end of header */
|
||||||
|
fseek(self->fd,self->lPos, SEEK_SET);
|
||||||
|
if(self->iChannel != 0)
|
||||||
|
{
|
||||||
|
fprintf(self->fd,"WARNING: Scanning monitor %d\n",self->iChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make the data header */
|
||||||
|
sprintf(pLine,"%-5s","NP");
|
||||||
|
strcpy(pInfo,"Scanning Variables: ");
|
||||||
|
for(i = 0; i < self->iScanVar;i++)
|
||||||
|
{
|
||||||
|
DynarGet(self->pScanVar,i,&pPtr);
|
||||||
|
pVar = (pVarEntry)pPtr;
|
||||||
|
if(pVar)
|
||||||
|
{
|
||||||
|
sprintf(pItem,"%-9.9s ",ScanVarName(pVar));
|
||||||
|
strcat(pLine,pItem);
|
||||||
|
sprintf(pItem,"%s, ",ScanVarName(pVar));
|
||||||
|
strcat(pInfo,pItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcat(pLine," Counts ");
|
||||||
|
strcat(pLine,"Monitor1 ");
|
||||||
|
strcat(pLine,"Monitor2 ");
|
||||||
|
strcat(pLine,"Monitor3 ");
|
||||||
|
strcat(pLine,"Time ");
|
||||||
|
sprintf(pItem,"\n%d Points,",self->iNP);
|
||||||
|
strcat(pInfo,pItem);
|
||||||
|
if(self->iMode == eTimer)
|
||||||
|
{
|
||||||
|
strcat(pInfo," Mode: Timer,");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcat(pInfo," Mode: Monitor,");
|
||||||
|
}
|
||||||
|
sprintf(pItem," Preset %f",self->fPreset);
|
||||||
|
strcat(pInfo,pItem);
|
||||||
|
fprintf(self->fd,"%s\n",pInfo);
|
||||||
|
fprintf(self->fd,"%s\n",pLine);
|
||||||
|
|
||||||
|
/* now the scan points */
|
||||||
|
for(i = 0; i < self->iCounts; i++)
|
||||||
|
{
|
||||||
|
sprintf(pLine,"%-5d",i);
|
||||||
|
/* print vars */
|
||||||
|
for(i2 = 0; i2 < self->iScanVar; i2++)
|
||||||
|
{
|
||||||
|
DynarGet(self->pScanVar,i2,&pPtr);
|
||||||
|
pVar = (pVarEntry)pPtr;
|
||||||
|
if(pVar)
|
||||||
|
{
|
||||||
|
sprintf(pItem,"%-10.3f",GetScanVarPos(pVar,i));
|
||||||
|
strcat(pLine,pItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* print Counts & Monitor */
|
||||||
|
DynarGet(self->pCounts,i,&pPtr);
|
||||||
|
pData = (pCountEntry)pPtr;
|
||||||
|
if(pData)
|
||||||
|
{
|
||||||
|
sprintf(pItem," %-12ld",pData->lCount);
|
||||||
|
strcat(pLine,pItem);
|
||||||
|
sprintf(pItem,"%-12ld",pData->Monitors[0]);
|
||||||
|
strcat(pLine,pItem);
|
||||||
|
sprintf(pItem,"%-12ld",pData->Monitors[1]);
|
||||||
|
strcat(pLine,pItem);
|
||||||
|
sprintf(pItem,"%-12ld",pData->Monitors[2]);
|
||||||
|
strcat(pLine,pItem);
|
||||||
|
sprintf(pItem,"%-6.1f",pData->fTime);
|
||||||
|
strcat(pLine,pItem);
|
||||||
|
}
|
||||||
|
fprintf(self->fd,"%s\n",pLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
fprintf(self->fd,"END-OF-DATA\n");
|
||||||
|
fclose(self->fd);
|
||||||
|
self->fd = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int PrepareScan(pScanData self)
|
||||||
|
{
|
||||||
|
pVarEntry pVar = NULL;
|
||||||
|
void *pDings;
|
||||||
|
int i, iRet;
|
||||||
|
float fVal;
|
||||||
|
char pBueffel[512];
|
||||||
|
char pMessage[1024];
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
assert(self->iNP > 0);
|
||||||
|
assert(self->pCon);
|
||||||
|
|
||||||
|
/* check boundaries of scan variables and allocate storage */
|
||||||
|
for(i = 0; i < self->iScanVar; i++)
|
||||||
|
{
|
||||||
|
DynarGet(self->pScanVar,i,&pDings);
|
||||||
|
pVar = (pVarEntry)pDings;
|
||||||
|
if(pVar)
|
||||||
|
{
|
||||||
|
/* start value */
|
||||||
|
fVal = ScanVarStart(pVar);
|
||||||
|
iRet = pVar->pInter->CheckLimits(pVar->pObject,
|
||||||
|
fVal,pBueffel,511);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
sprintf(pMessage,"ERROR: %s, scan aborted",pBueffel);
|
||||||
|
SCWrite(self->pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* end value */
|
||||||
|
fVal = pVar->fStart + (self->iNP - 1) * ScanVarStep(pVar);
|
||||||
|
iRet = pVar->pInter->CheckLimits(pVar->pObject,
|
||||||
|
fVal,pBueffel,511);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
sprintf(pMessage,"ERROR: %s, scan aborted",pBueffel);
|
||||||
|
SCWrite(self->pCon,pBueffel,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
InitScanVar(pVar);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,
|
||||||
|
"WARNING: Internal error, no scan variable, I try to continue",
|
||||||
|
eWarning);
|
||||||
|
}
|
||||||
|
pVar = NULL;
|
||||||
|
} /* end for */
|
||||||
|
|
||||||
|
/* configure counter */
|
||||||
|
SetCounterMode((pCounter)self->pCounterData,self->iMode);
|
||||||
|
SetCounterPreset((pCounter)self->pCounterData, self->fPreset);
|
||||||
|
self->iCounts = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int NonCheckPrepare(pScanData self)
|
||||||
|
{
|
||||||
|
pVarEntry pVar = NULL;
|
||||||
|
void *pDings;
|
||||||
|
int i, iRet;
|
||||||
|
float fVal;
|
||||||
|
char pBueffel[512];
|
||||||
|
char pMessage[1024];
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
assert(self->iNP > 0);
|
||||||
|
assert(self->pCon);
|
||||||
|
|
||||||
|
/* allocate storage for scan variables */
|
||||||
|
for(i = 0; i < self->iScanVar; i++)
|
||||||
|
{
|
||||||
|
DynarGet(self->pScanVar,i,&pDings);
|
||||||
|
pVar = (pVarEntry)pDings;
|
||||||
|
if(pVar)
|
||||||
|
{
|
||||||
|
/* start value */
|
||||||
|
fVal = ScanVarStart(pVar);
|
||||||
|
InitScanVar(pVar);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,
|
||||||
|
"WARNING: Internal error, no scan variable, I try to continue",
|
||||||
|
eWarning);
|
||||||
|
}
|
||||||
|
pVar = NULL;
|
||||||
|
} /* end for */
|
||||||
|
|
||||||
|
/* configure counter */
|
||||||
|
SetCounterMode((pCounter)self->pCounterData,self->iMode);
|
||||||
|
SetCounterPreset((pCounter)self->pCounterData, self->fPreset);
|
||||||
|
self->iCounts = 0;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
static int CollectScanDataIntern(pScanData self, int iPoint, int jochenFlag)
|
||||||
|
{
|
||||||
|
pVarEntry pVar = NULL;
|
||||||
|
void *pDings;
|
||||||
|
int i, iRet, status;
|
||||||
|
char pStatus[512], pItem[20];
|
||||||
|
char pHead[512];
|
||||||
|
float fVal;
|
||||||
|
CountEntry sCount;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
assert(self->pCon);
|
||||||
|
InitCountEntry(&sCount);
|
||||||
|
|
||||||
|
/* prepare output header */
|
||||||
|
sprintf(pHead,"%-5.5s","NP");
|
||||||
|
sprintf(pStatus,"%-5d",iPoint);
|
||||||
|
|
||||||
|
/* loop over all scan variables */
|
||||||
|
status = 1;
|
||||||
|
for(i = 0; i < self->iScanVar; i++)
|
||||||
|
{
|
||||||
|
DynarGet(self->pScanVar,i,&pDings);
|
||||||
|
pVar = (pVarEntry)pDings;
|
||||||
|
if(pVar)
|
||||||
|
{
|
||||||
|
if(jochenFlag == 1 &&
|
||||||
|
strcmp(pVar->pObject->pDescriptor->name, "Motor") == 0)
|
||||||
|
{
|
||||||
|
MotorGetSoftPosition((pMotor)pVar->pObject,self->pCon,&fVal);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fVal = pVar->pInter->GetValue(pVar->pObject,self->pCon);
|
||||||
|
}
|
||||||
|
AppendScanVar(pVar,fVal);
|
||||||
|
sprintf(pItem,"%-10.10s",ScanVarName(pVar));
|
||||||
|
strcat(pHead,pItem);
|
||||||
|
sprintf(pItem,"%-10.3f",fVal);
|
||||||
|
strcat(pStatus,pItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* store counter data */
|
||||||
|
sCount = CollectCounterData(self);
|
||||||
|
|
||||||
|
/*
|
||||||
|
format header
|
||||||
|
*/
|
||||||
|
strcat(pHead,"Counts ");
|
||||||
|
|
||||||
|
sprintf(pItem,"%-15d",sCount.lCount);
|
||||||
|
strcat(pStatus,pItem);
|
||||||
|
|
||||||
|
strcat(pHead,"Monitor1 ");
|
||||||
|
sprintf(pItem,"%-12d",sCount.Monitors[0]);
|
||||||
|
strcat(pStatus,pItem);
|
||||||
|
strcat(pHead,"Monitor2 ");
|
||||||
|
sprintf(pItem,"%-12d",sCount.Monitors[1]);
|
||||||
|
strcat(pStatus,pItem);
|
||||||
|
strcat(pHead,"Monitor3 ");
|
||||||
|
sprintf(pItem,"%-12d",sCount.Monitors[2]);
|
||||||
|
strcat(pStatus,pItem);
|
||||||
|
strcat(pHead,"Time ");
|
||||||
|
sprintf(pItem,"%-6.1f",sCount.fTime);
|
||||||
|
strcat(pStatus,pItem);
|
||||||
|
|
||||||
|
/* write progress */
|
||||||
|
strcat(pHead,"\n");
|
||||||
|
strcat(pStatus,"\n");
|
||||||
|
SCWrite(self->pCon,pHead,eWarning);
|
||||||
|
SCWrite(self->pCon,pStatus,eWarning);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int CollectScanData(pScanData self, int iPoint)
|
||||||
|
{
|
||||||
|
return CollectScanDataIntern(self,iPoint,0);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int CollectScanDataJochen(pScanData self, int iPoint)
|
||||||
|
{
|
||||||
|
return CollectScanDataIntern(self,iPoint,1);
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
static int StartToDrive(pScanData self, int iPoint)
|
||||||
|
{
|
||||||
|
pVarEntry pVar = NULL;
|
||||||
|
void *pDings;
|
||||||
|
int i, iRet, status;
|
||||||
|
|
||||||
|
assert(self);
|
||||||
|
assert(self->pCon);
|
||||||
|
|
||||||
|
|
||||||
|
/* loop over all scan variables */
|
||||||
|
status = 1;
|
||||||
|
for(i = 0; i < self->iScanVar; i++)
|
||||||
|
{
|
||||||
|
DynarGet(self->pScanVar,i,&pDings);
|
||||||
|
pVar = (pVarEntry)pDings;
|
||||||
|
if(pVar)
|
||||||
|
{
|
||||||
|
iRet = StartScanVar(pVar,self->pCon,iPoint);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
status = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int ScanDrive(pScanData self, int iPoint)
|
||||||
|
{
|
||||||
|
int iRet;
|
||||||
|
long lTask;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
iRet = StartToDrive(self,iPoint);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,"ERROR: Cannot Drive, Scan aborted",eError);
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
/* wait for finish */
|
||||||
|
lTask = GetDevexecID(pServ->pExecutor);
|
||||||
|
if(lTask > 0)
|
||||||
|
{
|
||||||
|
TaskWait(pServ->pTasker,lTask);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
int ScanCount(pScanData self, int iPoint)
|
||||||
|
{
|
||||||
|
pDummy pDum;
|
||||||
|
int iRet;
|
||||||
|
long lTask;
|
||||||
|
|
||||||
|
pDum = (pDummy)self->pCounterData;
|
||||||
|
iRet = StartDevice(pServ->pExecutor,
|
||||||
|
"ScanCounter",
|
||||||
|
pDum->pDescriptor,
|
||||||
|
self->pCounterData,
|
||||||
|
self->pCon,
|
||||||
|
self->fPreset);
|
||||||
|
if(!iRet)
|
||||||
|
{
|
||||||
|
SCWrite(self->pCon,"ERROR: Cannot Count, Scan aborted",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SetStatus(eCounting);
|
||||||
|
/* wait for finish */
|
||||||
|
lTask = GetDevexecID(pServ->pExecutor);
|
||||||
|
if(lTask > 0);
|
||||||
|
{
|
||||||
|
TaskWait(pServ->pTasker,lTask);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/*====================== script invocation functions ====================*/
|
||||||
|
static pDynString GetStandardInvocation(pScanData self, char *function){
|
||||||
|
pDynString result = NULL;
|
||||||
|
char value[132];
|
||||||
|
|
||||||
|
result = CreateDynString(80,80);
|
||||||
|
if(result == NULL){
|
||||||
|
SCWrite(self->pCon,"ERROR: out of memory in scan invocation",eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(StringDictGet(self->scanFunctions,function,value,131) != 1){
|
||||||
|
snprintf(value,131,"ERROR: scan function %s not found",function);
|
||||||
|
SCWrite(self->pCon,value,eError);
|
||||||
|
DeleteDynString(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
DynStringCopy(result,value);
|
||||||
|
DynStringConcatChar(result,' ');
|
||||||
|
DynStringConcat(result, self->objectName);
|
||||||
|
DynStringConcatChar(result,' ');
|
||||||
|
value[0] = '\0';
|
||||||
|
StringDictGet(self->scanFunctions,"userdata",value,131);
|
||||||
|
DynStringConcat(result,value);
|
||||||
|
DynStringConcatChar(result,' ');
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static int StandardScriptInvoke(pScanData self, char *function){
|
||||||
|
pDynString command = NULL;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
command = GetStandardInvocation(self,function);
|
||||||
|
if(command == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
status = InterpExecute(self->pSics, self->pCon,
|
||||||
|
GetCharArray(command));
|
||||||
|
DeleteDynString(command);
|
||||||
|
if(status != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
static int StandardScriptInvokeWithPoint(pScanData self,
|
||||||
|
char *function, int iPoint){
|
||||||
|
pDynString command = NULL;
|
||||||
|
int status;
|
||||||
|
char pNumber[50];
|
||||||
|
|
||||||
|
command = GetStandardInvocation(self,function);
|
||||||
|
if(command == NULL){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
snprintf(pNumber,49,"%d",iPoint);
|
||||||
|
DynStringConcat(command,pNumber);
|
||||||
|
status = InterpExecute(self->pSics, self->pCon,
|
||||||
|
GetCharArray(command));
|
||||||
|
DeleteDynString(command);
|
||||||
|
if(status != 1) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int ScriptWriteHeader(pScanData self){
|
||||||
|
return StandardScriptInvoke(self,"writeheader");
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
int ScriptPrepareScan(pScanData self){
|
||||||
|
return StandardScriptInvoke(self,"prepare");
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
int ScriptScanDrive(pScanData self, int iPoint){
|
||||||
|
return StandardScriptInvokeWithPoint(self,"drive",iPoint);
|
||||||
|
}
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
int ScriptScanCount(pScanData self, int iPoint){
|
||||||
|
return StandardScriptInvokeWithPoint(self,"count",iPoint);
|
||||||
|
}
|
||||||
|
/*-------------------------------------------------------------------------*/
|
||||||
|
int ScriptScanCollect(pScanData self, int iPoint){
|
||||||
|
return StandardScriptInvokeWithPoint(self,"collect",iPoint);
|
||||||
|
}
|
||||||
|
/*----------------------------------------------------------------------*/
|
||||||
|
int ScriptWriteScanPoints(pScanData self, int iPoint){
|
||||||
|
return StandardScriptInvokeWithPoint(self,"writepoint",iPoint);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------*/
|
||||||
|
void ConfigureScript(pScanData self){
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
self->PrepareScan = ScriptPrepareScan;
|
||||||
|
self->WriteHeader = ScriptWriteHeader;
|
||||||
|
self->WriteScanPoints = ScriptWriteScanPoints;
|
||||||
|
self->ScanDrive = ScriptScanDrive;
|
||||||
|
self->ScanCount = ScriptScanCount;
|
||||||
|
self->CollectScanData = ScriptScanCollect;
|
||||||
|
}
|
||||||
|
/*======================================================================*/
|
||||||
|
int StandardScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]){
|
||||||
|
pScanData self = NULL;
|
||||||
|
int iPoint;
|
||||||
|
char pError[132];
|
||||||
|
|
||||||
|
if(argc < 4) {
|
||||||
|
SCWrite(pCon,"ERROR: not enough arguments to stdscan",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
strtolower(argv[1]);
|
||||||
|
self = (pScanData)FindCommandData(pSics,argv[2],"ScanObject");
|
||||||
|
assert(self);
|
||||||
|
|
||||||
|
if(strcmp(argv[1],"writeheader") == 0){
|
||||||
|
return WriteHeader(self);
|
||||||
|
} else if(strcmp(argv[1],"prepare") == 0){
|
||||||
|
return PrepareScan(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
from here on we need a scan point
|
||||||
|
*/
|
||||||
|
if(argc < 5) {
|
||||||
|
SCWrite(pCon,"ERROR: not enough arguments to stdscan",eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
iPoint = atoi(argv[4]);
|
||||||
|
|
||||||
|
if(strcmp(argv[1],"drive") == 0){
|
||||||
|
return ScanDrive(self,iPoint);
|
||||||
|
} else if(strcmp(argv[1],"count") == 0){
|
||||||
|
return ScanCount(self,iPoint);
|
||||||
|
} else if(strcmp(argv[1],"collect") == 0){
|
||||||
|
return CollectScanData(self,iPoint);
|
||||||
|
} else if(strcmp(argv[1],"writepoint") == 0){
|
||||||
|
return WriteScanPoints(self,iPoint);
|
||||||
|
} else {
|
||||||
|
snprintf(pError,131,"ERROR: subcommand %s to stdscan not found",
|
||||||
|
argv[1]);
|
||||||
|
SCWrite(pCon,pError,eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
83
stdscan.h
Normal file
83
stdscan.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
/*--------------------------------------------------------------------------
|
||||||
|
S T A N D A R D S C A N
|
||||||
|
|
||||||
|
This is a library of scan functions for the SICS standard scan.
|
||||||
|
|
||||||
|
copyright: see copyright.h
|
||||||
|
|
||||||
|
Extracted from scan.c: Mark Koennecke, November 2004
|
||||||
|
----------------------------------------------------------------------------*/
|
||||||
|
#ifndef SICSSTDSCAN
|
||||||
|
#define SICSSTDSCAN
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write the header of the scan file
|
||||||
|
*/
|
||||||
|
int WriteHeader(pScanData self);
|
||||||
|
/**
|
||||||
|
* WriteScanPoints is called for each point to write the scan data
|
||||||
|
* to screen and to file.
|
||||||
|
*/
|
||||||
|
int WriteScanPoints(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Called before the scan to prepare. The default implementation
|
||||||
|
* checks if all scan positions are available and configures the
|
||||||
|
* counter.
|
||||||
|
*/
|
||||||
|
int PrepareScan(pScanData self);
|
||||||
|
/**
|
||||||
|
* second version of PrepareScan which does not check scan limits
|
||||||
|
*/
|
||||||
|
int NonCheckPrepare(pScanData self);
|
||||||
|
/**
|
||||||
|
* ScanDrive handles driving to the scan point iPoint.
|
||||||
|
*/
|
||||||
|
int ScanDrive(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* ScanCount is called at each scan step to do the counting.
|
||||||
|
*/
|
||||||
|
int ScanCount(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* CollectScanData stores the scans count results into
|
||||||
|
* the scan data structure and prints the information about the
|
||||||
|
* scan progress.
|
||||||
|
*/
|
||||||
|
int CollectScanData(pScanData self, int iPoint);
|
||||||
|
int CollectScanDataJochen(pScanData self, int iPoint);
|
||||||
|
/*===================================================================*/
|
||||||
|
/**
|
||||||
|
* Script invocation for writing the scan header.
|
||||||
|
*/
|
||||||
|
int ScriptWriteHeader(pScanData self);
|
||||||
|
/**
|
||||||
|
* Script writing each scan point
|
||||||
|
*/
|
||||||
|
int ScriptWriteScanPoints(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Script preparation of the scan.
|
||||||
|
*/
|
||||||
|
int ScriptPrepareScan(pScanData self);
|
||||||
|
/**
|
||||||
|
* Script driving to a scan point
|
||||||
|
*/
|
||||||
|
int ScriptScanDrive(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Script counting a scan point
|
||||||
|
*/
|
||||||
|
int ScriptScanCount(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* Script collecting scan data for each scan point
|
||||||
|
*/
|
||||||
|
int ScriptScanCollect(pScanData self, int iPoint);
|
||||||
|
/**
|
||||||
|
* ConfigureScript assigns the script invocation functions for
|
||||||
|
* scan
|
||||||
|
*/
|
||||||
|
void ConfigureScript(pScanData self);
|
||||||
|
/*=====================================================================*/
|
||||||
|
int StandardScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||||
|
int argc, char *argv[]);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
5
tclev.c
5
tclev.c
@ -328,7 +328,8 @@
|
|||||||
free(pPriv);
|
free(pPriv);
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------*/
|
||||||
pEVDriver CreateTclDriver(int argc, char *argv[],char *pName, SConnection *pCon)
|
pEVDriver CreateTclDriver(int argc, char *argv[],char *pName,
|
||||||
|
SConnection *pCon)
|
||||||
{
|
{
|
||||||
pEVDriver pNew = NULL;
|
pEVDriver pNew = NULL;
|
||||||
pTclEv pPriv = NULL;
|
pTclEv pPriv = NULL;
|
||||||
@ -348,7 +349,7 @@
|
|||||||
memset(pPriv,0,sizeof(TclEv));
|
memset(pPriv,0,sizeof(TclEv));
|
||||||
|
|
||||||
/* find the names of all the functions we need in the Tcl Array */
|
/* find the names of all the functions we need in the Tcl Array */
|
||||||
pPriv->pTcl = pCon->pSics->pTcl;
|
pPriv->pTcl = InterpGetTcl(pServ->pSics);
|
||||||
assert(pPriv->pTcl);
|
assert(pPriv->pTcl);
|
||||||
pPriv->pArray = strdup(argv[0]);
|
pPriv->pArray = strdup(argv[0]);
|
||||||
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"Init",TCL_GLOBAL_ONLY);
|
pPtr = Tcl_GetVar2(pPriv->pTcl,argv[0],"Init",TCL_GLOBAL_ONLY);
|
||||||
|
2
telnet.c
2
telnet.c
@ -133,7 +133,7 @@
|
|||||||
}
|
}
|
||||||
/* invoke command */
|
/* invoke command */
|
||||||
CostaLock(self->pCon->pStack);
|
CostaLock(self->pCon->pStack);
|
||||||
SCInvoke(self->pCon,self->pCon->pSics,pPtr);
|
SCInvoke(self->pCon,pServ->pSics,pPtr);
|
||||||
CostaUnlock(self->pCon->pStack);
|
CostaUnlock(self->pCon->pStack);
|
||||||
SendGA(self->pCon);
|
SendGA(self->pCon);
|
||||||
free(pPtr);
|
free(pPtr);
|
||||||
|
Reference in New Issue
Block a user