- Added an edge function to peakcenter for NARZISS

- Fixed ei interrupt bug in tasdrive.c
- Made eiger A2 driving work
- Added force start facility to devexec for POLDI HV


SKIPPED:
	psi/eigera2.c
	psi/polterwrite.c
This commit is contained in:
koennecke
2011-12-19 12:24:58 +00:00
parent a207ebf46d
commit 14f257c2ab
14 changed files with 361 additions and 43 deletions

123
devexec.c
View File

@ -398,7 +398,106 @@ int StartDevice(pExeList self, char *name, pObjectDescriptor pDes,
}
return 0;
}
/*------------------------------------------------------------------------
* This is a hacking thing to bypass the whole access checking thing. I
* need it at POLDI to run the fucking high voltage while the instrument is
* still counting.
*/
static int ForceStartDevice(pExeList self, char *name, pObjectDescriptor pDes,
void *pData, SConnection * pCon, float fNew)
{
pDevEntry pNew = NULL;
int iRet;
char pBueffel[132], pError[80];
pIDrivable pDrivInt = NULL;
pICountable pCountInt = NULL;
static int overwriteOwner = -1;
char *overwriteOption;
float oldVal;
assert(self);
assert(pDes);
assert(pCon);
/* may we? */
if (self->pOwner != NULL) {
pCon = self->pOwner;
}
if (self->iLock == 1) {
SCWrite(pCon, "ERROR: instrument is locked", eError);
return 0;
}
/* well create a new entry */
self->iStop = 0;
pNew = CreateDevEntry(pDes, SCCopyConnection(pCon),
pData, fNew, name, RUNRUN);
if (!pNew) {
SCWrite(pCon, "ERROR: memory exhausted in Device Executor ", eError);
return 0;
}
/* start it */
pDrivInt = pDes->GetInterface(pData, DRIVEID);
pCountInt = pDes->GetInterface(pData, COUNTID);
if (pDrivInt) {
iRet = pDrivInt->SetValue(pData, pCon, fNew);
if (iRet == OKOK && self->drivePrint == 1) {
oldVal = pDrivInt->GetValue(pData, pCon);
snprintf(pBueffel, 131, "Driving %s from %8.3f to %8.3f",
name, oldVal, fNew);
SCWrite(pCon, pBueffel, eValue);
}
if(iRet == OKOK){
InvokeNewTarget(self,name,fNew);
}
} else if (pCountInt) {
/**
* Cannot set count parameters here: means of getting hold of the
* count mode missing here. As this is a POLDI hack where I only need
* to run a HV, I omit this now. But it will work if a proper
* preset and mode is set on a counter to start it.
*/
iRet = pCountInt->StartCount(pData, pCon);
} else { /* this is a programmers error */
SCWrite(pCon, "ERROR: Programmer error in StartDevice ", eError);
iRet = 0;
}
/* check return status */
if (iRet == OKOK) {
LLDnodeAppendFrom(self->iList, &pNew);
sprintf(pBueffel, "started");
if (NULL != pNew->pCon->deviceID) {
snprintf(pBueffel, 130, "started (%s)", pNew->pCon->deviceID);
}
ExeInterest(self, pNew, pBueffel);
self->iRun = 1;
self->iStatus = DEVDONE;
/* if no task: start it */
if (self->lTask < 0) {
self->lTask = TaskRegister(self->pTask,
DevExecTask,
DevExecSignal, NULL, self, 1);
self->iEnd = 0;
pCon->conStatus = HWBusy;
}
DevexecLog("START", pNew->name);
return 1;
} else {
snprintf(pBueffel,131, "ERROR: cannot start device %s", name);
SCWrite(pCon, pBueffel, eError);
DeleteDevEntry(pNew);
if (LLDcheck(self->iList) >= LIST_EMPTY) {
if (self->pOwner != NULL) {
SCDeleteConnection(self->pOwner);
}
self->pOwner = NULL;
}
return 0;
}
return 0;
}
/*--------------------------------------------------------------------------*/
int StartMotor(pExeList self, SicsInterp * pSics, SConnection * pCon,
char *name, int level, float fVal)
@ -1147,6 +1246,10 @@ int DevexecAction(SConnection * pCon, SicsInterp * pSics, void *pData,
{
int val;
char pBueffel[256];
void *data = NULL;
pDummy pDum = NULL;
float fTarget;
CommandList *pCom = NULL;
pExeList self = (pExeList) pData;
if (argc < 2) {
@ -1166,6 +1269,26 @@ int DevexecAction(SConnection * pCon, SicsInterp * pSics, void *pData,
SCWrite(pCon, pBueffel, eValue);
return 1;
}
} else if(strcmp(argv[1],"force") == 0) {
if(argc < 4){
SCWrite(pCon,"ERROR: insufficient number of arguments to devexec force",
eError);
return 0;
}
pCom = FindCommand(pSics,argv[2]);
fTarget = atof(argv[3]);
if(pCom == NULL){
SCPrintf(pCon,eError,"ERROR: command %s to force not found", argv[2]);
return 0;
}
data = pCom->pData;
pDum = (pDummy)data;
if(GetDrivableInterface(data) == NULL && GetCountableInterface(data) == NULL ){
SCPrintf(pCon,eError,"ERROR: command %s not startable", argv[2]);
return 0;
}
val = ForceStartDevice(self,argv[2],pDum->pDescriptor,data, pCon, fTarget);
return val;
} else {
SCWrite(pCon, "ERROR: unknown subcommand to devexec", eError);
return 0;

View File

@ -6,6 +6,11 @@
copyright: see copyright.h
Mark Koennecke, October 1997
Added center of edge finding
Mark Koennecke, Octover 2011
-----------------------------------------------------------------------------*/
#include <limits.h>
#include <math.h>
@ -221,6 +226,51 @@ static int CalculateFitIntern(pFit self)
return iRet;
}
/*-------------------------------------------------------------------------*/
static int CalculateEdgeIntern(pFit self)
{
int i, iRet, iPeak, nSlope = 0;;
long lCount;
float fNenner,fSum, fCI;
/* find the maximum counts */
iRet = FindMax(self);
self->lPeak = self->lCounts[iRet];
/* a default fit is the peak maximum. This
helps optimise to do the right thing if no proper calculation
could be performed
*/
if (self->lPeak < 3) {
return -3;
}
/*
* calculate the COG between .9*max < counts < .1*max
*/
fSum = 0.;
fNenner = 0.;
for (i = 0; i < self->iNP; i++) {
lCount = self->lCounts[i];
if(lCount > self->lPeak *.20 && lCount < self->lPeak * .80){
fSum += lCount * self->fAxis[i];
fNenner += lCount;
nSlope++;
}
}
if(fNenner > .0001){
fCI = fSum / fNenner;
} else {
return -3;
}
self->fCenter = fCI;
self->fStddev = 1.0;
if(nSlope < 3) {
iRet = -7;
}
return iRet;
}
/*--------------------------------------------------------------------------*/
int CalculateFit(pFit self)
@ -328,7 +378,7 @@ int FitFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
pDummy pDum = NULL;
CommandList *pCom = NULL;
char pBueffel[132];
int iRet, iRet1;
int iRet, iRet1, iRet2;
if (argc < 2) {
SCWrite(pCon,
@ -365,6 +415,7 @@ int FitFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
iRet = AddCommand(pSics, "peak", FitWrapper, DeleteFitCenter, self);
iRet1 = AddCommand(pSics, "center", CenterWrapper, NULL, self);
iRet2 = AddCommand(pSics, "edge", EdgeWrapper, NULL, self);
if (!iRet || !iRet1) {
snprintf(pBueffel,sizeof(pBueffel)-1,
"ERROR: duplicate commands peak and center not created");
@ -374,7 +425,6 @@ int FitFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
}
return 1;
}
/*--------------------------------------------------------------------------*/
int FitWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
@ -451,7 +501,65 @@ int FitWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
return 1;
}
/*---------------------------------------------------------------------------*/
int EdgeWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])
{
pFit self = NULL;
int iRet;
char pBueffel[256];
pDynString buf = NULL;
self = (pFit) pData;
assert(self);
Init(self);
iRet = CalculateEdgeIntern(self);
switch (iRet) {
case 0:
SCWrite(pCon, "ERROR: failure to fit your data!", eError);
return 0;
break;
case -3:
SCWrite(pCon, "ERROR: No counts found in Fit!", eError);
return 0;
break;
case -4:
SCWrite(pCon, "ERROR: Insufficient counts in peak", eError);
return 0;
break;
case -7:
SCWrite(pCon,
"WARNING: not enough points in slope, results may be inreliable, remeasure with smaller step width",
eWarning);
break;
}
/*
This is a little feature to get the peak without rubbish for
the TAS routines
*/
if (argc > 1) {
strtolower(argv[1]);
if (strcmp(argv[1], "value") == 0) {
snprintf(pBueffel,sizeof(pBueffel)-1, "%f", self->fCenter);
SCWrite(pCon, pBueffel, eValue);
return 1;
}
}
/* print results */
SCStartBuffering(pCon);
snprintf(pBueffel,sizeof(pBueffel)-1, "Estimated Edge Center: %f\n",
self->fCenter);
SCWrite(pCon, pBueffel, eValue);
buf = SCEndBuffering(pCon);
if (buf != NULL) {
SCWrite(pCon, GetCharArray(buf), eValue);
}
return 1;
}
/*---------------------------------------------------------------------------*/
int CenterWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[])

View File

@ -8,6 +8,10 @@
copyright: see copyright.h
Mark Koennecke, October 1997
Added center of edge finding
Mark Koennecke, Octover 2011
----------------------------------------------------------------------------*/
#ifndef SICSFITCENTER
#define SICSFITCENTER
@ -33,6 +37,8 @@ int FitFactory(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
int FitWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
int EdgeWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);
int CenterWrapper(SConnection * pCon, SicsInterp * pSics, void *pData,
int argc, char *argv[]);

View File

@ -1089,7 +1089,7 @@ int CaptureAction(SConnection *pCon, SicsInterp * pSics, void *pData,
comCon = SCCopyConnection(pCon);
if (comCon == NULL) {
SCWrite(pCon, "EROOR: out of memory in capture", eError);
SCWrite(pCon, "ERROR: out of memory in capture", eError);
return 0;
}
/*

View File

@ -1,3 +1,4 @@
/*------------------------------------------------------------------------
M O T O R S

View File

@ -125,6 +125,12 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
break;
case HWFault:
case HWPosFault:
/**
* It is questionable if one should not set a flag here
* and keep p;olling: it is not clear if this error is a
* communication problem or that the motor really
* has stopped.
*/
return status;
break;
default:
@ -138,6 +144,47 @@ static int MOLICheckStatus(void *data, SConnection * pCon)
}
return result;
}
/*---------------------------------------------------------
A special version for EIGER. I am coutious: I have problems
with this at EIGER but I do not want to propogate the fix
elsewhere even if it may be the right thing to do.
-----------------------------------------------------------*/
int MOLIEigerStatus(void *data, SConnection * pCon)
{
int self = 0, iRet, status, result = HWIdle;
MotControl tuktuk;
self = *(int *) data;
iRet = LLDnodePtr2First(self);
while (iRet != 0) {
LLDnodeDataTo(self, &tuktuk);
if (tuktuk.running == 1) {
status = tuktuk.pDriv->CheckStatus(tuktuk.data, pCon);
switch (status) {
case HWIdle:
tuktuk.running = 0;
LLDnodeDataFrom(self, &tuktuk);
break;
case HWBusy:
result = HWBusy;
break;
case HWFault:
case HWPosFault:
tuktuk.running = 0;
LLDnodeDataFrom(self, &tuktuk);
break;
default:
/*
this is a programming error and has to be fixed
*/
assert(0);
}
}
iRet = LLDnodePtr2Next(self);
}
return result;
}
/*----------------------------------------------------------------
GetValue is supposed to read a motor position

View File

@ -210,13 +210,13 @@ static int checkPosition(pMotor self, SConnection * pCon)
float precision, hard, target, maxretry;
pHdb node = NULL;
if (SCGetInterrupt(pCon) != eContinue) {
return HWFault;
}
if (self->stopped) {
SCPrintf(pCon, eWarning, "WARNING: %s stopped", self->name);
return HWFault;
}
if (SCGetInterrupt(pCon) != eContinue) {
return HWFault;
}
SecMotorGetPar(self, "hardposition", &hard);
SecMotorGetPar(self, "targetposition", &target);
SecMotorGetPar(self, "precision", &precision);

View File

@ -2405,6 +2405,7 @@ static int UpdateHdbNode(SConnection * pCon, SicsInterp * pSics,
if (targetNode == NULL) {
return 0;
}
/* SCPrintf(pCon,eWarning, "Updating %s", argv[1]); */
if (argc > 2) {
if (!cloneHdbValue(&targetNode->value, &newValue)) {
SCWrite(pCon, "ERROR: out of memory cloning node", eError);

View File

@ -72,9 +72,11 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon,
}
ang->monochromator_two_theta = val;
if (ABS(val / 2. - theta) > .1) {
if(DevExecLevelRunning(pServ->pExecutor,RUNRUN) != 1) {
SCWrite(pCon, "WARNING: theta monochromator not half of two theta",
eWarning);
}
}
/*
Analyzer
@ -90,7 +92,7 @@ static int readTASMotAngles(ptasUB self, SConnection * pCon,
return status;
}
ang->analyzer_two_theta = val;
if (ABS(val / 2. - theta) > .1) {
if (ABS(val / 2. - theta) > .1 && DevExecLevelRunning(pServ->pExecutor,RUNRUN) != 1) {
SCWrite(pCon, "WARNING: theta analyzer not half of two theta",
eWarning);
}
@ -236,7 +238,7 @@ static void writeMotPos(SConnection * pCon, int silent, char *name,
if (silent != 1) {
snprintf(pBueffel, 131, "Driving %5s from %8.3f to %8.3f",
name, val, target);
SCWrite(pCon, pBueffel, eWarning);
SCWrite(pCon, pBueffel, eLog);
}
}
@ -258,6 +260,7 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
char buffer[132];
pIDrivable pDriv = NULL;
pDummy dum = NULL;
pDynString mes = NULL;
dum = (pDummy)mot;
if(strcmp(dum->pDescriptor->name,"Motor") == 0){
@ -272,8 +275,11 @@ static int startTASMotor(pMotor mot, SConnection * pCon, char *name,
mot->stopped = 0;
if (ABS(val - target) > MOTPREC) {
pDriv = GetDrivableInterface(mot);
SCStartBuffering(pCon);
status = pDriv->SetValue(mot, pCon, (float) target);
mes = SCEndBuffering(pCon);
if (status != OKOK) {
SCPrintf(pCon,eLogError, GetCharArray(mes));
return status;
}
}
@ -310,7 +316,8 @@ static int startMotors(ptasMot self, tasAngles angles,
status = startTASMotor(self->math->motors[MCV], pCon, "mcv",
curve, silent);
if (status != OKOK) {
return status;
SCWrite(pCon,"WARNING: monochromator vertical curvature motor failed to start", eWarning);
SCSetInterrupt(pCon,eContinue);
}
}
@ -320,7 +327,8 @@ static int startMotors(ptasMot self, tasAngles angles,
status = startTASMotor(self->math->motors[MCH], pCon, "mch",
curve, silent);
if (status != OKOK) {
return status;
SCWrite(pCon,"WARNING: monochromator horizontal curvature motor failed to start", eWarning);
SCSetInterrupt(pCon,eContinue);
}
}
@ -346,7 +354,8 @@ static int startMotors(ptasMot self, tasAngles angles,
status = startTASMotor(self->math->motors[ACV], pCon, "acv",
curve, silent);
if (status != OKOK) {
return status;
SCWrite(pCon,"WARNING: analyzer vertical curvature motor failed to start", eWarning);
SCSetInterrupt(pCon,eContinue);
}
}
if (self->math->motors[ACH] != NULL) {
@ -355,7 +364,8 @@ static int startMotors(ptasMot self, tasAngles angles,
status = startTASMotor(self->math->motors[ACH], pCon, "ach",
curve, silent);
if (status != OKOK) {
return status;
SCWrite(pCon,"WARNING: analyzer horizontal curvature motor failed to start", eWarning);
SCSetInterrupt(pCon,eContinue);
}
}
}
@ -450,7 +460,6 @@ static int checkQMotorLimits(ptasMot self, SConnection * pCon,
}
return retVal;
}
/*-----------------------------------------------------------------------------*/
static int calculateAndDrive(ptasMot self, SConnection * pCon)
{
@ -461,9 +470,11 @@ static int calculateAndDrive(ptasMot self, SConnection * pCon)
if (self->math->ubValid == 0) {
SCWrite(pCon, "WARNING: UB matrix invalid", eWarning);
}
status = calcAllTasAngles(&self->math->machine, self->math->target,
&angles);
self->math->mustDrive = 0;
switch (status) {
case ENERGYTOBIG:
SCWrite(pCon, "ERROR: desired energy to big", eError);
@ -523,8 +534,8 @@ static int calculateAndDrive(ptasMot self, SConnection * pCon)
/*-----------------------------------------------------------------------------*/
static int checkMotors(ptasMot self, SConnection * pCon)
{
int i, status, length = 12;
int mask[12];
int i, status, length = 12, count;
int mask[12], busy[12];
pIDrivable pDrivInt = NULL;
self->math->mustRecalculate = 1;
@ -532,8 +543,10 @@ static int checkMotors(ptasMot self, SConnection * pCon)
length = 8;
}
memset(mask, 0, 12 * sizeof(int));
memset(busy, 0, 12 * sizeof(int));
for (i = 0; i < length; i++) {
mask[i] = 1;
busy[i] = 1;
}
if (self->math->outOfPlaneAllowed == 0) {
mask[SGU] = 0;
@ -541,15 +554,26 @@ static int checkMotors(ptasMot self, SConnection * pCon)
}
for (i = 0; i < 12; i++) {
if (self->math->motors[i] != NULL && mask[i] != 0) {
if(self->math->motors[i] == NULL){
busy[i] = 0;
} else {
if(mask[i] != 0) {
pDrivInt = GetDrivableInterface(self->math->motors[i]);
status = pDrivInt->CheckStatus(self->math->motors[i], pCon);
if (status != HWIdle && status != OKOK) {
return status;
if(status == HWIdle || status == OKOK || status == HWFault || status == HWPosFault){
busy[i] = 0;
}
}
}
}
for(i = 0, count = 0; i < 12; i++){
count += busy[i];
}
if(count == 0) {
return HWIdle;
} else {
return HWBusy;
}
}
/*------------------------------------------------------------------------------*/

View File

@ -560,6 +560,11 @@ static int TASUBScanPoint(pScanData self, int iPoint)
long m1, m2, m3, cnts;
char pBueffel[1024], pWork[80], pError[132];
/*
* force an update to write the right things
*/
tasUpdate(self->pCon,pTAS->ub);
/*
after polarisation analysis, this has to be ignored as it is called
another time from the ScanLoop
@ -746,7 +751,7 @@ static int TASUBScanCount(pScanData self, int iPoint)
*/
fVal = GetCounterPreset(self->pCounterData);
eOld = GetStatus();
status = DoCount(self->pCounterData, fVal, self->pCon, 0);
status = DoCount(self->pCounterData, fVal, self->pCon, 1);
iRet = Wait4Success(GetExecutor());
if (iRet == DEVINT) {
SCWrite(self->pCon, "Counting aborted due to Interrupt", eLog);

View File

@ -1769,7 +1769,7 @@ static int setTarget(SConnection * pCon, SicsInterp * pSics, ptasUB self,
}
/*------------------------------------------------------------------*/
static int tasUpdate(SConnection * pCon, ptasUB self)
int tasUpdate(SConnection * pCon, ptasUB self)
{
int status;
tasAngles angles;

View File

@ -52,4 +52,5 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
int findReflection(int list, int idx, ptasReflection r);
int tasUpdate(SConnection *pCon, ptasUB self);
#endif

View File

@ -110,6 +110,7 @@ int TasUBWrapper(SConnection *pCon,SicsInterp *pSics, void *pData,
/*--------------------------------------------------------------------*/
@<tasubint@>
int findReflection(int list, int idx, ptasReflection r);
int tasUpdate(SConnection *pCon, ptasUB self);
#endif
@}
@o tasdrive.h @{

View File

@ -25,6 +25,7 @@ set txt [counter getcounts]
set cts [omGetNum $txt]
omth add 3 $cts
drive stt 66 om 33.
counter count $preset
set txt [counter getcounts]