- Added separate drivable motors for four circle H, K, L

- Added a listen mode to commandlog in order to support the batchEditor
- Some small fixes to exe* for BatchEditor
This commit is contained in:
koennecke
2005-02-23 10:11:18 +00:00
parent ef1de4589c
commit 28ddbc420d
39 changed files with 1274 additions and 130 deletions

365
diffscan.c Normal file
View File

@ -0,0 +1,365 @@
/*-------------------------------------------------------------------
diffscan is an operator which can perform a fast differential scan
while a motor is running.
copyright: see file COPYRIGHT
Mark Koennecke, November 2004
---------------------------------------------------------------------*/
#include <stdio.h>
#include <assert.h>
#include <tcl.h>
#include "fortify.h"
#include "sics.h"
#include "diffscan.h"
#include "drive.h"
#include "counter.h"
#define DIFFMONITOR 0
#define SKIP 1
/*-------------------------------------------------------------------*/
static void KillDiffScan(void *data){
pDiffScan self = (pDiffScan)data;
if(self == NULL){
return;
}
if(self->pDes != NULL){
DeleteDescriptor(self->pDes);
}
if(self->parArray != NULL){
ObParDelete(self->parArray);
}
free(self);
}
/*---------------------------------------------------------------------*/
static int SaveDiffScan(void *data, char *name, FILE *fd){
pDiffScan self = (pDiffScan)data;
if(self == NULL){
return 0;
}
fprintf(fd,"%s monitor %f\n",name,ObVal(self->parArray,DIFFMONITOR));
fprintf(fd,"%s skip %f\n",name,ObVal(self->parArray,SKIP));
return 1;
}
/*----------------------------------------------------------------------*/
int MakeDiffScan(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pDiffScan pNew = NULL;
int status;
pNew = (pDiffScan)malloc(sizeof(DiffScan));
if(pNew == NULL){
SCWrite(pCon,"ERROR: out of memory creating differential scan",
eError);
return 0;
}
memset(pNew,0,sizeof(DiffScan));
pNew->pDes = CreateDescriptor("DiffScan");
pNew->parArray = ObParCreate(2);
if(!pNew->pDes || !pNew->parArray){
SCWrite(pCon,"ERROR: out of memory creating differential scan",
eError);
KillDiffScan(pNew);
return 0;
}
ObParInit(pNew->parArray, DIFFMONITOR,"monitor",4.0,usUser);
ObParInit(pNew->parArray, SKIP,"skip",.0,usUser);
pNew->pDes->SaveStatus = SaveDiffScan;
if(argc > 1) {
status = AddCommand(pSics,argv[2],
DiffScanWrapper,
KillDiffScan,
pNew);
} else {
status = AddCommand(pSics,"diffscan",
DiffScanWrapper,
KillDiffScan,
pNew);
}
if(status != 1){
SCWrite(pCon,"ERROR: duplicate diffscan not created",eError);
return 0;
}
return 1;
}
/*----------------------------------------------------------------------*/
int DiffScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData,
int argc, char *argv[]){
pDiffScan self = NULL;
pScanData pScan = NULL;
ObPar *par = NULL;
char pBueffel[255];
int status;
self = (pDiffScan)pData;
assert(self);
if(argc < 2){
SCWrite(pCon,"ERROR: need arguments to diffscan",eError);
return 0;
}
if(!SCMatchRights(pCon,usUser)){
return 0;
}
/*
first try to find a scan object and to run
*/
strtolower(argv[1]);
pScan = (pScanData)FindCommandData(pSics,argv[1],"ScanObject");
if(pScan != NULL && argc > 2){
status = RunDiffScan(self,pScan,pCon, atof(argv[2]));
return status;
}
/*
if we end here we are treating variables
*/
if(argc > 2){
/*
set case
*/
return ObParSet(self->parArray,argv[0],argv[1],atof(argv[2]),pCon);
} else {
/*
get case
*/
par = ObParFind(self->parArray,argv[1]);
if(par != NULL){
snprintf(pBueffel,255,"%s.%s = %f",argv[0],argv[1],par->fVal);
SCWrite(pCon,pBueffel,eValue);
return 1;
} else {
snprintf(pBueffel,255,"ERROR: parameter %s not found",argv[1]);
SCWrite(pCon,pBueffel,eError);
return 0;
}
}
return 1;
}
/*--------------------------------------------------------------------*/
static int StartDiffScan(pDiffScan self, pScanData pScan,
SConnection *pCon, float fEnd){
pVarEntry pVar = NULL;
void *pPtr = NULL;
pCounter pCount = NULL;
char pBueffel[255];
int status;
/*
error checks
*/
if(pScan->iScanVar < 1) {
SCWrite(pCon,"ERROR: no scan variable to diffscan",eError);
return 0;
}
if(pScan->iScanVar > 1) {
snprintf(pBueffel,255,
"WARNING: diffscan handles only first scan variable, %d %s",
pScan->iScanVar - 1,
"scan variables ignored");
SCWrite(pCon,pBueffel, eWarning);
}
/*
initialize data structure
*/
self->scanObject = pScan;
self->scanObject->pCon = pCon;
self->skip = (int)ObVal(self->parArray,SKIP);
self->scaleMonitor = (int)ObVal(self->parArray,DIFFMONITOR);
self->normalizationScale = -1;
pScan->iCounts = 0;
/*
get variable
*/
DynarGet(pScan->pScanVar,0,&pPtr);
pVar = (pVarEntry)pPtr;
if(pVar == NULL){
SCWrite(pCon,"ERROR: cannot access scan variable",eError);
return 0;
}
/*
drive to start position
*/
status = Drive(pCon,pServ->pSics,ScanVarName(pVar),ScanVarStart(pVar));
if(status != 1){
return 0;
}
/*
Configure counter. We operate in timer mode with a very long
preset mode. Stopping is done explicitly in the diffscan task
*/
SetCounterMode(pScan->pCounterData,eTimer);
SetCounterPreset(pScan->pCounterData,3600.);
/*
start motor and counter
*/
status = pVar->pInter->SetValue(pVar->pObject,pCon,fEnd);
if(status != OKOK){
/*
errors will already have been reported in SetValue
*/
return 0;
}
pCount = (pCounter)pScan->pCounterData;
assert(pCount);
status = pCount->pCountInt->StartCount(pCount,pCon);
if(status != OKOK){
return 0;
}
return 1;
}
/*--------------------------------------------------------------------*/
static float normalizeEntry(pCountEntry pCount, pCountEntry last,
long monValue, int scaleMon){
int i;
float fScale;
float value;
long diff;
/*
calculate scale
*/
diff = pCount->Monitors[scaleMon-1] - last->Monitors[scaleMon-1];
if(diff > 0) {
fScale = (float)monValue/(float)diff;
} else {
fScale = 0.;
}
value = ((float)(pCount->lCount - last->lCount))*fScale;
pCount->lCount = (long)value;
for(i = 0; i < 10; i++){
pCount->Monitors[i] = (pCount->Monitors[i] - last->Monitors[i])*fScale;
}
return value;
}
/*--------------------------------------------------------------------*/
static void copyCountData(pCountEntry last, pCountEntry pCount){
memcpy(last,pCount,sizeof(CountEntry));
}
/*---------------------------------------------------------------------*/
static int DiffScanTask(void *pData){
pCounter pCount = NULL;
pCountEntry data;
pVarEntry pVar = NULL;
void *pPtr = NULL;
float fPos, countValue;
int status, finish = 1, count;
char pBueffel[255];
long rawCount, rawMon;
CountEntry rawCopy;
pDiffScan self = (pDiffScan)pData;
/*
manage skip
*/
if(self->skip > 0){
if(self->skipCount > self->skip){
self->skipCount = 0;
} else {
self->skipCount++;
return 1;
}
}
/*
read motor status
*/
DynarGet(self->scanObject->pScanVar,0,&pPtr);
pVar = (pVarEntry)pPtr;
status = pVar->pInter->CheckStatus(pVar->pObject,self->scanObject->pCon);
if(status != HWBusy) {
finish = 0;
}
/*
read values
*/
status = GetDrivablePosition(pVar->pObject,self->scanObject->pCon,
&fPos);
if(status == 0){
return finish;
}
AppendScanVar(pVar,fPos);
pCount = (pCounter)self->scanObject->pCounterData;
pCount->pCountInt->TransferData(pCount,self->scanObject->pCon);
CollectCounterData(self->scanObject);
/*
normalize (or not)
*/
DynarGet(self->scanObject->pCounts,self->scanObject->iCounts-1,&pPtr);
data = (pCountEntry)pPtr;
copyCountData(&rawCopy,data);
if(self->normalizationScale < 0){
countValue = (float)data->lCount;
rawCount = data->lCount;
rawMon = data->Monitors[self->scaleMonitor-1];
self->normalizationScale = data->Monitors[self->scaleMonitor-1];
} else {
if(data->Monitors[self->scaleMonitor -1] -
self->last.Monitors[self->scaleMonitor-1] < 5) {
SCWrite(self->scanObject->pCon,
"WARNING: low count rate",eWarning);
}
rawCount = data->lCount;
rawMon = data->Monitors[self->scaleMonitor-1];
countValue = normalizeEntry(data,&self->last,
self->normalizationScale,
self->scaleMonitor);
}
copyCountData(&self->last,&rawCopy);
/*
print progress
*/
snprintf(pBueffel,255,"%5d %12.4f %12.4f RAW: %10d %10d",
self->scanObject->iCounts -1,
fPos, countValue, rawCount,
rawMon);
SCWrite(self->scanObject->pCon,pBueffel,eWarning);
InvokeCallBack(self->scanObject->pCall,SCANPOINT,self->scanObject);
/*
check for interrupt
*/
if(SCGetInterrupt(self->scanObject->pCon) >= eAbortScan){
finish = 0;
}
return finish;
}
/*----------------------------------------------------------------------*/
int RunDiffScan(pDiffScan self, pScanData pScan,
SConnection *pCon, float fEnd){
long lID;
pCounter pCount = NULL;
if(StartDiffScan(self,pScan,pCon,fEnd) != 1) {
return 0;
}
InvokeCallBack(self->scanObject->pCall,SCANSTART,self->scanObject);
lID = TaskRegister(pServ->pTasker,DiffScanTask,NULL,NULL,self,10);
TaskWait(pServ->pTasker,lID);
pCount = (pCounter)self->scanObject->pCounterData;
pCount->pCountInt->Halt(pCount);
InvokeCallBack(self->scanObject->pCall,SCANEND,self->scanObject);
return 1;
}