diff --git a/amorstat.c b/amorstat.c index 7671df5..354dbac 100644 --- a/amorstat.c +++ b/amorstat.c @@ -430,6 +430,9 @@ ScanPointCallback(SCANPOINT,pDum,pCon,SCGetContext(pCon)); } } + /* + * histmem + */ pDum = (pDummy)self->pHM; pCall = pDum->pDescriptor->GetInterface(pDum,CALLBACKINTERFACE); if(pCall) diff --git a/ecbcounter.c b/ecbcounter.c index 298f17d..01faefc 100644 --- a/ecbcounter.c +++ b/ecbcounter.c @@ -74,6 +74,26 @@ static int readScaler(pECBCounter pPriv, int scaler, int *count){ return 1; } +/*---------------------------------------------------------------------------*/ +static int readTime(pECBCounter pPriv,float *time){ + int status; + Z80_reg in, out; + Ecb_pack data; + + in.c = (unsigned char)0; + status = ecbExecute(pPriv->ecb,STREAD,in,&out); + if(status != 1){ + return COMMERROR; + } + + data.b.byt3 = out.c; + data.b.byt2 = out.b; + data.b.byt1 = out.d; + data.b.byt0 = out.e; + *time = (float)data.result/(float)pPriv->tfreq; + return 1; +} + /*---------------------------------------------------------------------*/ static int check4Beam(struct __COUNTER *pCter, int *beam){ Z80_reg in, out; @@ -147,6 +167,7 @@ static int ECBGetStatus(struct __COUNTER *self, float *fControl){ int status, result, scaler; Z80_reg in, out; int count, beam; + float time; assert(pPriv); @@ -210,16 +231,13 @@ static int ECBGetStatus(struct __COUNTER *self, float *fControl){ */ if(self->eMode == eTimer){ scaler = 0; + readTime(pPriv,fControl); }else { scaler = pPriv->control; + readScaler(pPriv,scaler,&count); + *fControl = (float)count; } - readScaler(pPriv,scaler,&count); - /* - ignore errors on this one - */ - *fControl = (float)count; - return result; } /*=====================================================================*/ @@ -361,12 +379,11 @@ static int ECBTransfer(struct __COUNTER *self){ /* read time */ - status = readScaler(pPriv,0,&count); + status = readTime(pPriv,&self->fTime); if(status <= 0){ self->iErrorCode = COMMERROR; return HWFault; } - self->fTime = (float)count; /* read other scalers diff --git a/ecbdriv.c b/ecbdriv.c index ed80e4f..1b0d970 100644 --- a/ecbdriv.c +++ b/ecbdriv.c @@ -927,6 +927,13 @@ static int ECBGetDriverPar(void *pData,char *name, float *value){ *value = self->ecbIndex; return 1; } + /* + * catch the command parameters + */ + if(strcmp(name,"putpos") == 0 || strcmp(name,"download") == 0){ + *value = .0; + return 1; + } par = ObParFind(self->driverPar,name); if(par != NULL){ @@ -1151,7 +1158,7 @@ static void ECBListPar(void *pData, char *motorName, SConnection *pCon){ assert(self); for(i = 0; i < MAXPAR-1; i++){ - sprintf(pBueffel,"%s.%s = %f", + snprintf(pBueffel,255,"%s.%s = %f", motorName,self->driverPar[i].name, self->driverPar[i].fVal); SCWrite(pCon,pBueffel,eValue); diff --git a/frame.c b/frame.c index 20ef729..14665f3 100644 --- a/frame.c +++ b/frame.c @@ -168,6 +168,9 @@ static int readFileFrame(SConnection *pCon, status = NXgetdata(fileHandle,buffer+2); } else { iStart[0] = iStart[1] = 0; + if(nFrame > iDim[2] - 2){ + nFrame = iDim[2] - 2; + } iStart[2] = nFrame; iSize[0] = iDim[0]; iSize[1] = iDim[1]; diff --git a/julcho.c b/julcho.c index db7a9a1..e9e4353 100644 --- a/julcho.c +++ b/julcho.c @@ -574,17 +574,7 @@ static int JulChoGetCallback(void *userData, void *callData, } /*--------------------------------------------------------------------------*/ static int AppendJulChoROPar(pHdb parent, char *name, int type){ - pHdb res = NULL; - hdbValue v; - - memset(&v,0,sizeof(hdbValue)); - v.dataType = type; - res = MakeSICSROPar(name,v); - if(res == NULL){ - return 0; - } - AddHipadabaChild(parent,res); - return 1; + return AddSICSHdbROPar(parent,name,makeHdbValue(type,1)); } /*---------------------------------------------------------------------------*/ static int ConfigureSingleJulCho(pHdb parent, pJulCho driv, diff --git a/libpsi.a b/libpsi.a index 9d73e81..cd40755 100644 Binary files a/libpsi.a and b/libpsi.a differ diff --git a/make_gen b/make_gen index 6b2b5e3..76a38bf 100644 --- a/make_gen +++ b/make_gen @@ -8,7 +8,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ pipiezo.o sanswave.o faverage.o fowrite.o amor2t.o nxamor.o \ - amorstat.o tasinit.o tasdrive.o tasutil.o tasscan.o swmotor.o \ + amorstat.o tasinit.o ptasdrive.o tasutil.o tasscan.o swmotor.o \ polterwrite.o ecb.o frame.o el734driv.o el734dc.o ecbdriv.o \ ecbcounter.o el737driv.o sinqhmdriv.o tdchm.o velodorn.o \ velodornier.o docho.o sanscook.o tecsdriv.o itc4driv.o itc4.o\ @@ -17,7 +17,8 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ t_rlp.o t_conv.o el737hpdriv.o dornier2.o el734hp.o \ el737hpv2driv.o swmotor2.o tricssupport.o amorcomp.o \ $(MZOBJ) amordrive.o amorset.o tcpdornier.o sinqhttp.o\ - dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o + dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o \ + ritastorage.o MZOBJ=fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.o logreader.o \ ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o \ diff --git a/psi.c b/psi.c index 8363ed6..d3ef58d 100644 --- a/psi.c +++ b/psi.c @@ -65,6 +65,9 @@ extern int VelSelTcpFactory(SConnection *pCon, SicsInterp *pSics, void *pData, */ extern int JulChoFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]); +/* from ritastorage.c */ +extern int MakeRitaFix(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]); /*--------------------------------------------------------------------------*/ void SiteInit(void) { @@ -116,6 +119,7 @@ static void AddPsiCommands(SicsInterp *pInter){ AddCommand(pInter,"MakeAmorSet",AmorSetFactory,NULL,NULL); AddCommand(pInter,"MakeTCPSelector",VelSelTcpFactory,NULL,NULL); AddCommand(pInter,"MakeJulCho",JulChoFactory,NULL,NULL); + AddCommand(pInter,"MakeRitaFix",MakeRitaFix,NULL,NULL); /* AddCommand(pInter,"MakeDifrac",MakeDifrac,NULL,NULL); */ @@ -137,6 +141,7 @@ static void RemovePsiCommands(SicsInterp *pSics){ RemoveCommand(pSics,"MakeAmorStatus"); RemoveCommand(pSics,"MakeTCPSelector"); RemoveCommand(pSics,"MakeJulCho"); + RemoveCommand(pSics,"MakeRitaFix"); /* RemoveCommand(pSics,"MakeDifrac"); */ diff --git a/ptasdrive.c b/ptasdrive.c new file mode 100644 index 0000000..239154c --- /dev/null +++ b/ptasdrive.c @@ -0,0 +1,336 @@ +/*-------------------------------------------------------------------------- + This is one implementation file for the TASMAD simulation module for + SICS. The requirement is to make SICS look as much as TASMAD as + possible. This includes: + - TASMAD is variable driven + - Sometimes variables are accessed in storage order. + - A complicated calculation has to be done for getting the instruments + settings right. The appropriate F77 routine from TASMAD will be + reused. + - The scan logic is different. + - Output of ILL-formatted data files is required. + + This file implements the MAD dr command for driving. + + Mark Koennecke, November 2000 + + Polarisation support added. + + Mark Koennecke, April 2002 +---------------------------------------------------------------------------*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "tas.h" +#include "tasu.h" + + +/* a token break function, implemented in stptok.c */ +extern char *stptok(const char *s, char *tok, size_t toklen, char *brk); + +#define VAR 1 +#define VALUE 2 + +/*---------------------------------------------------------------------- + TASDrive has to do an interesting parsing job: The normal syntax is + par=val. However, it is possible that the we get par = val, val, val + which means that the motors following par in storage order are + driven. Additionally we have to check for special energy or Q variables + which require a triple axis calculation. + + It helps if one understands some fundamental things used in the code + below: + - motorMask holds a value for each motor in the motor list. The + value can be either 0 for not to drive or 1 for drive. After + successfull parsing these motors will be started. The mask will be built + during parsing. + - newPositions holds the new positions for the normal motors. + - tasMask is a mask which indicates which triple axis special variable + (Energy or Q) is driven. + - tasTargetMask will be set by the TAS calculation and will indicate + which motors of the range A1-A6, curvature and currents need to be + driven. + - tasTargets holds after the TAS calculation the target values for the + A1-A6, curvature and currents motors. + + +-------------------------------------------------------------------------*/ +#define NUM 1 +#define TXT 2 + +int TASDrive(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]) +{ + pTASdata self = NULL; + int iTAS = 0; + float tasTargets[20], oldPos, oldEnergy[MAXEVAR]; + unsigned char tasTargetMask[20], tasMask[MAXEVAR]; + char *pPtr, pToken[20], pLine[256]; + int varPointer, i, motorPointer, status, rStatus, lastToken; + char pBueffel[256]; + unsigned char motorMask[MAXMOT]; + float newPositions[MAXMOT]; + pMotor pMot; + + + + assert(pCon); + assert(pSics); + self = (pTASdata)pData; + assert(self); + + /* + check authorization + */ + if(!SCMatchRights(pCon,usUser)) + return 0; + + + /* Initialize */ + Arg2Text(argc, argv,pLine,255); + strtolower(pLine); + lastToken = NUM; + pPtr = pLine + strlen(argv[0]); /* step over command */ + for(i = 0; i < 10; i++) + { + tasMask[i] = 0; + motorMask[i] = 0; + motorMask[10+i] = 0; + tasTargets[i] = .0; + tasTargets[i+10] = .0; + oldEnergy[i] = .0; + } + tasMask[10] = 0; + tasMask[11] = 0; + + for(i = 0; i < MAXMOT; i++) + { + motorMask[i] = 0; + } + varPointer = -1; + motorPointer = -1; + rStatus = 1; + + /* parse loop */ + while(pPtr != NULL) + { + pPtr = stptok(pPtr,pToken,20," ,="); + if(strlen(pToken) < 1 || pPtr == NULL ) + continue; + + if(tasNumeric(pToken)) /* numbers */ + { + if(lastToken == NUM) + { + /* handle storage order logic */ + if(motorPointer > -1) + { + motorPointer++; + } + else if(varPointer > -1) + { + varPointer++; + } + else + { + sprintf(pBueffel,"ERROR: parse error at %s, %s", + pToken,"need parameter to drive"); + SCWrite(pCon,pBueffel,eError); + return 0; + } + } + /* enter the parameter to drive into the appropriate mask */ + if(motorPointer >= 0) + { + motorMask[motorPointer] = 1; + newPositions[motorPointer] = atof(pToken); + } + else if(varPointer >= 0 ) + { + tasMask[varPointer] = 1; + oldEnergy[varPointer] = self->tasPar[EMIN+varPointer]->fVal; + self->tasPar[EMIN + varPointer]->fVal = atof(pToken); + self->tasPar[ETARGET + varPointer]->fVal = atof(pToken); + } + else + { + sprintf(pBueffel,"ERROR: parse error at %s, %s", + pToken,"need parameter to drive"); + SCWrite(pCon,pBueffel,eError); + return 0; + } + lastToken = NUM; + } + else /* text tokens */ + { + lastToken = TXT; + if( (status = isTASEnergy(pToken)) > -1) /* Ei, KI, EF, KF, Q.... */ + { + iTAS = 1; + motorPointer = -1; + varPointer = status; + } + else if( (status = isTASMotor(pToken)) > -1) + { + motorPointer = status; + varPointer = -1; + } + else + { + sprintf(pBueffel,"ERROR: cannot drive %s", pToken); + SCWrite(pCon,pBueffel,eError); + rStatus = 0; + break; + } + } + }/* end of parse loop */ + if(rStatus != 1) + return rStatus; + + /* + store SRO motor value + */ + getSRO(pCon,&self->oldSRO); + + + /* having done this, we can start the motors */ + for(i = 0; i < MAXMOT; i++) + { + if(motorMask[i] > 0) + { + pMot = FindMotor(pSics, tasMotorOrder[i]); + if(pMot) + { + MotorGetSoftPosition(pMot, pCon, &oldPos); + } + else + { + oldPos = -9999.; + } + sprintf(pBueffel,"Driving %s from %f to %f", + tasMotorOrder[i],oldPos,newPositions[i]); + SCWrite(pCon,pBueffel,eWarning); + status = StartMotor(pServ->pExecutor,pSics,pCon, + tasMotorOrder[i],newPositions[i]); + if(status == 0) + { + /* error should already have been reported by StartMotor*/ + rStatus = 0; + } + } + } + + /* + if in TAS mode do the TAS calculation and start the appropriate + motors. + */ + if(iTAS > 0) + { + status = TASCalc(self,pCon,tasMask,tasTargets, tasTargetMask); + if(status) + { + /* + do output, first Q-E variables + */ + for(i = 0; i < 12; i++) + { + if(tasMask[i]) + { + sprintf(pBueffel,"Driving %s from %f to %f", tasVariableOrder[EI+i], + oldEnergy[i], + self->tasPar[EI+i]->fVal); + SCWrite(pCon,pBueffel,eWarning); + } + } + /* + more output: the motor positions + */ + for(i = 0; i < 9; i++) + { + if(tasTargetMask[i]) + { + pMot = FindMotor(pSics, tasMotorOrder[i]); + if(pMot) + { + MotorGetSoftPosition(pMot, pCon, &oldPos); + } + else + { + oldPos = -9999.; + } + sprintf(pBueffel,"Driving %s from %f to %f",tasMotorOrder[i], + oldPos, tasTargets[i]); + SCWrite(pCon,pBueffel,eWarning); + } + } + /* + output for magnet currents + */ + for(i = 0; i < 8; i++) + { + if(tasTargetMask[9+i]) + { + oldPos = readDrivable(tasMotorOrder[CURMOT+i], pCon); + sprintf(pBueffel,"Driving %s from %f to %f",tasMotorOrder[CURMOT+i], + oldPos, tasTargets[9+i]); + SCWrite(pCon,pBueffel,eWarning); + } + } + + status = TASStart(self,pCon,pSics,tasTargets,tasTargetMask); + if(status == 0) + { + rStatus = 0; + } + } + else + { + rStatus = 0; + } + } + + + /* + wait till we are finished + */ + status = Wait4Success(GetExecutor()); + TASUpdate(self,pCon); + + /* + handle interrupts + */ + if(status == DEVINT) + { + if(SCGetInterrupt(pCon) == eAbortOperation) + { + SCSetInterrupt(pCon,eContinue); + sprintf(pBueffel,"Driving aborted"); + SCWrite(pCon,pBueffel,eStatus); + } + return 0; + } + else if(status == DEVDONE) + { + sprintf(pBueffel,"Driving done"); + SCWrite(pCon,pBueffel,eStatus); + } + else + { + sprintf(pBueffel, + "Driving finished"); + SCWrite(pCon,pBueffel,eStatus); + } + return rStatus; +} + + + + + + diff --git a/ritastorage.c b/ritastorage.c new file mode 100644 index 0000000..05961a0 --- /dev/null +++ b/ritastorage.c @@ -0,0 +1,81 @@ +/** +* This is module which fixes the storgae of the 2D detector at RITA. +* I wish to store a 3D array, 2 detector coordinates against NP, the number +* of scan points. However, intermediate storage can only be as snapshots +* of 2D arrays against scan points. This has to be formatted to a proper +* 3D data set in C storage order. This is to slow in tcl, therefore this +* has to be done in in C. +* +* copyright: see file COPYRIGHT +* +* Mark Koennecke, August 2006 +*/ +#include +#include + +/*---------------------------------------------------------------------------*/ +static int RitaFix(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]){ + int x, y, np, scanDim, wrongpos, goodpos, val, *iData = NULL; + int wrongmult, wrongconst; + pSICSData intermediate = NULL, result = NULL; + char buffer[256]; + + if(argc < 4){ + SCWrite(pCon,"ERROR: not enough arguments to RitaFix",eError); + return 0; + } + + intermediate = FindCommandData(pSics,argv[1],"SICSData"); + if(intermediate == NULL){ + snprintf(buffer,255,"ERROR: %s is no SICSdata",argv[1]); + SCWrite(pCon,buffer,eError); + return 0; + } + result = FindCommandData(pSics,argv[2],"SICSData"); + if(result == NULL){ + snprintf(buffer,255,"ERROR: %s is no SICSdata",argv[2]); + SCWrite(pCon,buffer,eError); + return 0; + } + + scanDim = atoi(argv[3]); + scanDim ++; + clearSICSData(result); + /* + * ensure enough memory in order to avoid memory allocation in the + * loop + */ + iData = getSICSDataPointer(result,0,(128*128*scanDim) +1); + wrongpos = 128*128*scanDim; + if(intermediate->dataUsed < wrongpos || iData == NULL){ + SCWrite(pCon,"ERROR: source data buffer to short or out of mem", + eError); + return 0; + } + wrongmult = 128*128; + for(x = 0; x < 128; x++){ + for(y = 0; y < 128; y++){ + goodpos = x*128*scanDim + y*scanDim; + wrongconst = y*128 + x; + for(np = 0; np < scanDim; np++, goodpos++){ + /* + wrongpos = 128*128*np + y*128 + x; + goodpos = x*128*scanDim + y*scanDim + np; + */ + wrongpos = wrongmult*np + wrongconst; + result->data[goodpos] = intermediate->data[wrongpos]; + } + } + } + SCSendOK(pCon); + return 1; +} +/*---------------------------------------------------------------------------*/ +int MakeRitaFix(SConnection *pCon, SicsInterp *pSics, void *pData, + int argc, char *argv[]){ + AddCommand(pSics,"ritafixstorage",RitaFix,NULL,NULL); + return 1; +} + +