/*-------------------------------------------------------------------------- S C A N Implementation file for the SICS scan command. Mark Koennecke, October 1997 copyright: see copyright.h ----------------------------------------------------------------------------*/ #include "sics.h" #include #include #include #include #include "fortify.h" #include "sdynar.h" #include "status.h" #include "sicsvar.h" #include "counter.h" #include "scan.h" #include "scan.i" #include "integrate.h" #include "udpquieck.h" #include "splitter.h" #include "danu.h" #include "amorscan.h" #include "motor.h" extern void SNXFormatTime(char *pBuffer, int iLen); /* from nxdata.c */ /*------------------------------------------------------------------------*/ char *ScanMakeFileName(SicsInterp *pSics, SConnection *pCon, char *pExt) { pSicsVariable pPath = NULL, pPref = NULL, pEnd = NULL; char *pRes = NULL; int iLen, iNum, iYear; char pNumText[10]; CommandList *pCom = NULL; /* Try, get all the Variables */ pPath = FindVariable(pSics,"sicsdatapath"); pPref = FindVariable(pSics,"sicsdataprefix"); pCom = FindCommand(pSics,"sicsdatanumber"); if( (!pPath) || (!pPref) || (!pCom)) { SCWrite(pCon, "ERROR: cannot read variables for automatic data file name creation", eError); SCWrite(pCon,"ERROR: This is a VERY, VERY, VERY serious installation problem", eError); SCWrite(pCon,"ERROR: your data will be dumped into emergency.hdf",eError); return strdup("emergency.hdf"); } /* find length */ iLen = strlen(pPath->text); iLen += strlen(pPref->text); iLen += 8; /* for number + year */ iLen += 3; iLen += 10; /* safety margin */ /* allocate memory */ pRes = (char *)malloc(iLen*sizeof(char)); if(!pRes) { SCWrite(pCon,"ERROR: no memory in SNXMakeFileName",eError); return NULL; } memset(pRes,0,iLen); /* build the filename */ strcpy(pRes,pPath->text); strcat(pRes,pPref->text); iNum = IncrementDataNumber(pCom->pData,&iYear); if(iNum < 0) { SCWrite(pCon,"ERROR: cannot increment data number!",eError); SCWrite(pCon,"ERROR: your data will be dumped to emergency.dat",eError); free(pRes); return strdup("emergency.dat"); } sprintf(pNumText,"%5.5d",iNum); strcat(pRes,pNumText); sprintf(pNumText,"%4.4d",iYear); strcat(pRes,pNumText); strcat(pRes,pExt); return pRes; } /*--------------------- VarEntry Management --------------------------------*/ static void DeleteVarEntry(void *pData) { pVarEntry pVar = NULL; pVar = (pVarEntry)pData; assert(pVar); if(pVar->fData) { free(pVar->fData); } free(pVar); } /*---------------------------------------------------------------------------*/ static void DeleteCountEntry(void *pData) { free(pData); } /*--------------------------------------------------------------------------*/ static int DummyWrite(pScanData self) { return 1; } /*--------------------------------------------------------------------------*/ static int DummyWrite2(pScanData self, int iPoint) { return 1; } /*---------------------------------------------------------------------------*/ static 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,pScanVar->Name); if(pMot != NULL) { MotorGetPar(pMot,"softzero",&fVal); fprintf(self->fd,"%s zero = %8.3f\n",pScanVar->Name, 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); return 1; } /*--------------------------------------------------------------------------*/ static 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 ",pVar->Name); strcat(pLine,pItem); sprintf(pItem,"%s, ",pVar->Name); 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",pVar->fData[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; } /*---------------------------------------------------------------------------*/ static void *ScanInterface(void *pData, int iInter) { pScanData self = NULL; self = (pScanData)pData; assert(self); if(iInter == CALLBACKINTERFACE) { return self->pCall; } return NULL; } /*-------------------------------------------------------------------------*/ static int ScanDrive(pScanData self, int iPoint); static int ScanCount(pScanData self, int iPoint); static int CollectScanData(pScanData self, int iPoint); /*--------------------------------------------------------------------------*/ pScanData CreateScanObject(char *pRecover, char *pHeader,pCounter pCount) { pScanData pNew = NULL; pNew = (pScanData)malloc(sizeof(ScanData)); if(!pNew) { return NULL; } memset(pNew,0,sizeof(ScanData)); /* create an ObjectDescriptor */ pNew->pDes = CreateDescriptor("ScanObject"); if(!pNew->pDes) { free(pNew); return NULL; } pNew->pDes->GetInterface = ScanInterface; /* allocate the dynamic arrays */ pNew->pScanVar = CreateDynar(0,10,10,DeleteVarEntry); pNew->pCounts = CreateDynar(0,10,10,DeleteCountEntry); if( (!pNew->pScanVar) || (!pNew->pCounts) ) { DeleteDescriptor(pNew->pDes); free(pNew); return NULL; } /* make a callback interface */ pNew->pCall = CreateCallBackInterface(); if(!pNew->pCall) { DeleteScanObject(pNew); return NULL; } /* assign various things */ if(pRecover) { strcpy(pNew->pRecover,pRecover); } if(pHeader) { strcpy(pNew->pHeaderFile,pHeader); } pNew->iMode = eTimer; pNew->fPreset = 10.; strcpy(pNew->pCounterName,pCount->name); pNew->pCounterData = pCount; pNew->WriteHeader = WriteHeader; pNew->WriteScanPoints = WriteScanPoints; pNew->ScanDrive = ScanDrive; pNew->ScanCount = ScanCount; pNew->CollectScanData = CollectScanData; strcpy(pNew->ext,".dat"); pNew->iWindow = 6; return pNew; } /*---------------------------------------------------------------------------*/ void DeleteScanObject(void *pData) { pScanData self = NULL; self = (pScanData)pData; if(!self) { return; } if(self->pDes) { DeleteDescriptor(self->pDes); } if(self->pCall) { DeleteCallBackInterface(self->pCall); } if(self->pScanVar) { DeleteDynar(self->pScanVar); } if(self->pCounts) { DeleteDynar(self->pCounts); } if(self->pCommand) { free(self->pCommand); } free(self); } /*------------------------------------------------------------------------*/ int ResetScanFunctions(pScanData self) { assert(self); self->WriteHeader = WriteHeader; self->WriteScanPoints = WriteScanPoints; self->ScanDrive = ScanDrive; self->ScanCount = ScanCount; self->CollectScanData = CollectScanData; strcpy(self->ext,".dat"); return 1; } /*-------------------------------------------------------------------------*/ int AddScanVar(pScanData self, SicsInterp *pSics, SConnection *pCon, char *name, float fStart, float fStep) { CommandList *pCom = NULL; pIDrivable pDriv = NULL; pDummy pData = NULL; VarEntry pVar; char pBueffel[512]; if(self->iActive) { SCWrite(pCon,"ERROR: cannot change parameters while scan is running",eError); return 0; } /* find the thing */ pCom = FindCommand(pSics,name); if(!pCom) { sprintf(pBueffel,"ERROR: Cannot find variable %s to scan",name); SCWrite(pCon,pBueffel,eError); return 0; } pData = (pDummy)pCom->pData; if(!pData) { sprintf(pBueffel,"ERROR: Cannot find data for variable %s",name); SCWrite(pCon,pBueffel,eError); return 0; } pDriv = pData->pDescriptor->GetInterface(pData,DRIVEID); if(!pDriv) { sprintf(pBueffel,"ERROR: variable %s is NOT driveable and cannot be scanned",name); SCWrite(pCon,pBueffel,eError); return 0; } /* got everything, fill in the VarEntry structure */ strcpy(pVar.Name,name); pVar.pInter = pDriv; pVar.pObject = pData; pVar.fStart = fStart; pVar.fStep = fStep; pVar.fData = NULL; /* put it away */ DynarPutCopy(self->pScanVar,self->iScanVar,&pVar,sizeof(VarEntry)); self->iScanVar++; return 1; } /*--------------------------------------------------------------------------*/ int ClearScanVar(pScanData self) { if(self->iActive) { return 0; } self->iScanVar = 0; return 1; } /*-------------------------------------------------------------------------*/ struct RecoHead { int iScanVar; int iNP; int iMode; float fPreset; int iCounts; int iChannel; }; struct VarHead { char pName[256]; float fStart; float fStep; }; /*--------------------------------------------------------------------------*/ static int WriteRecover(pScanData self) { FILE *fd; struct RecoHead sHead; struct VarHead sVar; void *pData; pVarEntry pVar = NULL; pCountEntry pCount = NULL; int i; fd = fopen(self->pRecover,"wb"); if(!fd) { return 0; } /* write Header */ sHead.iScanVar = self->iScanVar; sHead.iNP = self->iNP; sHead.iMode = self->iMode; sHead.fPreset = self->fPreset; sHead.iCounts = self->iCounts; sHead.iChannel = self->iChannel; fwrite(&sHead,sizeof(struct RecoHead),1,fd); /* write scan vars */ for(i = 0; i < self->iScanVar; i++) { DynarGet(self->pScanVar,i,&pData); pVar = (pVarEntry)pData; if(pVar) { strcpy(sVar.pName,pVar->Name); sVar.fStep = pVar->fStep; sVar.fStart = pVar->fStart; fwrite(&sVar,sizeof(struct VarHead),1,fd); fwrite(pVar->fData,sizeof(float),sHead.iNP,fd); } pData = NULL; } /* write counts */ for(i = 0; i < self->iCounts; i++) { DynarGet(self->pCounts,i,&pData); pCount = (pCountEntry)pData; if(pCount) { fwrite(pCount,sizeof(CountEntry),1,fd); } } fclose(fd); return 1; } /*-------------------------------------------------------------------------*/ static int ReadRecover(pScanData self) { FILE *fd; struct RecoHead sHead; struct VarHead sVar; pVarEntry pVar; void *pData; CountEntry CountData; int i,iRet; assert(self); assert(self->pCon); fd = fopen(self->pRecover,"rb"); if(!fd) { return 0; } /* read Header */ iRet = fread(&sHead,sizeof(struct RecoHead),1,fd); if(iRet != 1) { SCWrite(self->pCon,"ERROR: Recover File corrupted",eError); fclose(fd); return 0; } self->iNP = sHead.iNP; self->iMode = sHead.iMode; self->fPreset = sHead.fPreset; self->iCounts = sHead.iCounts; self->iChannel = sHead.iChannel; /* read Scan Variables */ self->iScanVar = 0; for(i = 0; i < sHead.iScanVar; i++) { iRet = fread(&sVar,sizeof(struct VarHead),1,fd); if(iRet != 1) { SCWrite(self->pCon,"ERROR: Recover File corrupted",eError); fclose(fd); return 0; } AddScanVar(self,self->pSics,self->pCon, sVar.pName, sVar.fStart, sVar.fStep); DynarGet(self->pScanVar,i,&pData); pVar = (pVarEntry)pData; pVar->fData = (float *)malloc(sHead.iNP*sizeof(float)); if(!pVar->fData) { SCWrite(self->pCon,"ERROR: out of memory in scan::ReadRecover",eError); fclose(fd); return 0; } fread(pVar->fData,sizeof(float),sHead.iNP,fd); } /* read counts */ for(i = 0; i < sHead.iCounts; i++) { fread(&CountData,sizeof(CountEntry),1,fd); DynarPutCopy(self->pCounts,i,&CountData,sizeof(CountEntry)); } fclose(fd); return 1; } /*--------------------------------------------------------------------------*/ static 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 = pVar->fStart; 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 * pVar->fStep; 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; } /* allocate data space */ if(pVar->fData) { free(pVar->fData); pVar->fData = NULL; } pVar->fData = (float *)malloc(self->iNP * sizeof(float)); if(!pVar->fData) { SCWrite(self->pCon,"ERROR: out of memory in scan, aborting",eError); return 0; } memset(pVar->fData,0,self->iNP * sizeof(float)); } 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 StartToDrive(pScanData self, int iPoint) { pVarEntry pVar = NULL; void *pDings; int i, iRet, status; float fVal; pDummy pDum; char pBueffel[512]; 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) { pDum = (pDummy)pVar->pObject; fVal = pVar->fStart + iPoint * pVar->fStep; iRet = StartDevice(pServ->pExecutor, pVar->Name, pDum->pDescriptor, pVar->pObject, self->pCon, fVal); if(!iRet) { sprintf(pBueffel,"ERROR: Failed to start %s",pVar->Name); SCWrite(self->pCon,pBueffel,eError); status = 0; break; } } } return status; } /*---------------------------------------------------------------------------*/ static int CollectScanData(pScanData self, int iPoint) { pVarEntry pVar = NULL; void *pDings; int i, iRet, status; float fVal; char pStatus[512], pItem[20]; char pHead[512]; CountEntry sCount; char *pAns = NULL, *pPtr = NULL ; Tcl_Interp *pTcl; assert(self); assert(self->pCon); /* 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) { fVal = pVar->pInter->GetValue(pVar->pObject,self->pCon); pVar->fData[iPoint] = fVal; sprintf(pItem,"%-10.10s",pVar->Name); strcat(pHead,pItem); sprintf(pItem,"%-10.3f",fVal); strcat(pStatus,pItem); } } /* store counter data */ /* monitors */ for(i = 1; i < 10; i++) { sCount.Monitors[i-1] = GetMonitor((pCounter)self->pCounterData,i, self->pCon); } if( self->iChannel != 0 && self->iChannel != -10 ) { sCount.Monitors[self->iChannel - 1] = GetCounts((pCounter)self->pCounterData, self->pCon); } /* counts, depending on iChannel */ strcat(pHead,"Counts "); if(self->iChannel == -10) { /* execute the Tcl-script for getting the data */ pTcl = (Tcl_Interp *)self->pSics->pTcl; if(!self->pCommand) { SCWrite(self->pCon, "ERROR: command must be configured for user defined scans", eError); SCSetInterrupt(self->pCon,eAbortBatch); return 0; } iRet = Tcl_Eval(pTcl,self->pCommand); if(iRet != TCL_OK) { SCWrite(self->pCon,pTcl->result,eError); return 0; } /* interprete the Tcl result as a list of counts WARNING: this may need to be changed when switching to future versions of Tcl */ pAns = strdup(pTcl->result); pPtr = strtok(pAns," "); if(!pPtr) { SCWrite(self->pCon,"ERROR: no counts found in Tcl-result",eError); return 0; } sscanf(pPtr,"%f",&fVal); sCount.lCount = (long)fVal; i = 0; while( (pPtr != NULL) && (i < 10)) { pPtr = strtok(NULL," "); if(pPtr) { sscanf(pPtr,"%f",&fVal); sCount.Monitors[i] = (long)fVal; i++; } } free(pAns); } else if(self->iChannel == 0) { sCount.lCount = GetCounts((pCounter)self->pCounterData,self->pCon); } else { sCount.lCount = GetMonitor((pCounter)self->pCounterData, self->iChannel, self->pCon); } sprintf(pItem,"%-15d",sCount.lCount); strcat(pStatus,pItem); /* get time */ sCount.fTime = GetCountTime((pCounter)self->pCounterData, self->pCon); 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); /* stow away */ DynarReplace(self->pCounts,self->iCounts,&sCount,sizeof(CountEntry)); self->iCounts++; return 1; } /*------------------------------------------------------------------------*/ static 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; } /*--------------------------------------------------------------------------*/ static 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; } /*---------------------------------------------------------------------------*/ static int ScanLoop(pScanData self) { int i,iInt,iRet,iStatus; assert(self); assert(self->pCon); InvokeCallBack(self->pCall,SCANSTART,self); for(i = self->iCounts; i < self->iNP; i++) { /*--------- drive */ iRet = self->ScanDrive(self,i); if(!iRet) { return 0; } /* finished, check for interrupts. Whatever happened, user interrupt or HW interrupt, it will be on our connection */ iInt = SCGetInterrupt(self->pCon); switch(iInt) { case eContinue: break; case eAbortOperation: continue; break; case eAbortScan: SCWrite(self->pCon,"ERROR: Scan aborted",eError); /* eat the interrupt, the requested op has been done */ SCSetInterrupt(self->pCon,eContinue); return 0; break; default: /* all others */ SCWrite(self->pCon,"ERROR: Scan aborted",eError); return 0; break; } /*-------------- count */ iRet = self->ScanCount(self, i); if(!iRet) { return 0; } /* finished, check for interrupts. Whatever happened, user interrupt or HW interrupt, it will be on our connection */ iInt = SCGetInterrupt(self->pCon); switch(iInt) { case eContinue: break; case eAbortOperation: continue; break; case eAbortScan: SCWrite(self->pCon,"ERROR: Scan aborted",eError); /* eat the interrupt, the requested op has been done */ SCSetInterrupt(self->pCon,eContinue); return 0; break; default: /* all others */ SCWrite(self->pCon,"ERROR: Scan aborted",eError); return 0; break; } /*-------- scan post processing */ self->CollectScanData(self,i); InvokeCallBack(self->pCall,SCANPOINT,self); self->WriteScanPoints(self,i); if(self->pRecover) { WriteRecover(self); } } return 1; } /*--------------------------------------------------------------------------*/ int DoScan(pScanData self, int iNP, int iMode, float fPreset, SicsInterp *pSics, SConnection *pCon) { int iRet; char *pPtr = NULL; char pBueffel[1024]; assert(self); assert(pCon); assert(pSics); self->pCon = pCon; self->pSics = pSics; /* check arguments */ if(iNP <= 0) { SCWrite(self->pCon,"ERROR: iNP < 0, nothing to do, Scan aborted",eError); self->pCon = NULL; self->pSics = NULL; return 0; } if(self->iScanVar <= 0) { SCWrite(self->pCon,"WARNING: no scan variables given",eWarning); } if( (iMode != eTimer) && (iMode != ePreset)) { SCWrite(self->pCon,"ERROR: Invalid counter mode given",eError); self->pCon = NULL; self->pSics = NULL; return 0; } self->iNP = iNP; self->iMode = iMode; self->fPreset = fPreset; /* do some preprocessing */ iRet = PrepareScan(self); if(!iRet) { self->pCon = NULL; self->pSics = NULL; return 0; } /* allocate a new data file */ pPtr = ScanMakeFileName(self->pSics,self->pCon,self->ext); if(!pPtr) { SCWrite(self->pCon,"ERROR: cannot allocate new data filename, Scan aborted", eError); self->pCon = NULL; self->pSics = NULL; return 0; } sprintf(pBueffel,"Writing data file: %s ...",pPtr); SCWrite(self->pCon,pBueffel,eWarning); strcpy(self->pFile,pPtr); free(pPtr); iRet = self->WriteHeader(self); if(!iRet) { SCWrite(self->pCon,"ERROR: cannot open data file, Scan aborted", eError); self->pCon = NULL; self->pSics = NULL; return 0; } self->iActive = 1; iRet = ScanLoop(self); InvokeCallBack(self->pCall,SCANEND,self); SendQuieck(QUIECK,self->pFile); self->iActive = 0; self->pCon = NULL; self->pSics = NULL; return iRet; } /*---------------------------------------------------------------------------- SilentScan does a scan which does not produce a data file. It is intended for internal use. Only status messages appear on screen. ---------------------------------------------------------------------------*/ int SilentScan(pScanData self, int iNP, int iMode, float fPreset, SicsInterp *pSics, SConnection *pCon) { int iRet; char *pPtr = NULL; char pBueffel[1024]; int (*HeaderFunc)(pScanData self), (*ScanFunc)(pScanData self, int iPoint); assert(self); assert(pCon); assert(pSics); /* check arguments */ if(iNP <= 0) { SCWrite(self->pCon,"ERROR: iNP < 0, nothing to do, Scan aborted",eError); return 0; } if(self->iScanVar <= 0) { SCWrite(self->pCon,"WARNING: no scan variables given",eWarning); } if( (iMode != eTimer) && (iMode != ePreset)) { SCWrite(self->pCon,"ERROR: Invalid counter mode given",eError); return 0; } HeaderFunc = self->WriteHeader; self->WriteHeader = DummyWrite; ScanFunc = self->WriteScanPoints; self->WriteScanPoints = DummyWrite2; self->pCon = pCon; self->pSics = pSics; self->iNP = iNP; self->iMode = iMode; self->fPreset = fPreset; /* do some preprocessing */ iRet = PrepareScan(self); if(!iRet) { self->WriteHeader = HeaderFunc; self->WriteScanPoints = ScanFunc; self->pCon = NULL; self->pSics = NULL; return 0; } self->iActive = 1; iRet = ScanLoop(self); self->iActive = 0; self->pCon = NULL; self->pSics = NULL; self->WriteHeader = HeaderFunc; self->WriteScanPoints = ScanFunc; return iRet; } /*--------------------------------------------------------------------------*/ int RecoverScan(pScanData self, SicsInterp *pSics, SConnection *pCon) { int iRet; char *pPtr = NULL, pBueffel[512]; assert(pSics); assert(pCon); self->pCon = pCon; self->pSics = pSics; /* read recover file */ iRet = ReadRecover(self); if(!iRet) { return iRet; } /* configure counter */ SetCounterMode((pCounter)self->pCounterData,self->iMode); SetCounterPreset((pCounter)self->pCounterData, self->fPreset); /* new scan data file */ pPtr = ScanMakeFileName(self->pSics,self->pCon,self->ext); if(!pPtr) { SCWrite(self->pCon,"ERROR: cannot allocate new data filename, Scan aborted", eError); self->pCon = NULL; self->pSics = NULL; return 0; } sprintf(pBueffel,"Writing data file: %s ...",pPtr); SCWrite(self->pCon,pBueffel,eWarning); strcpy(self->pFile,pPtr); free(pPtr); iRet = self->WriteHeader(self); if(!iRet) { SCWrite(self->pCon,"ERROR: cannot open data file, Scan aborted", eError); self->pCon = NULL; self->pSics = NULL; return 0; } self->iActive = 1; iRet = ScanLoop(self); InvokeCallBack(self->pCall,SCANEND,self); SendQuieck(QUIECK,self->pFile); self->iActive = 0; self->pCon = NULL; self->pSics = NULL; return iRet; } /*--------------------------------------------------------------------------*/ int GetScanNP(pScanData self) { assert(self); return self->iNP; } /*--------------------------------------------------------------------------*/ float GetScanPreset(pScanData self) { assert(self); return self->fPreset; } /*--------------------------------------------------------------------------*/ int GetScanCounts(pScanData self,long *lData, int iDataLen) { int i, iEnd; pCountEntry pData = NULL; void *pPtr = NULL; assert(self); /* hanlde iEnd */ if(self->iCounts < iDataLen) { iEnd = self->iCounts; } else { iEnd = iDataLen; } /* initialise to 0 */ memset(lData,0,iDataLen*sizeof(long)); /* the loop */ for(i = 0; i < iEnd; i++) { DynarGet(self->pCounts,i,&pPtr); pData = (pCountEntry)pPtr; if(pData) { lData[i] = pData->lCount; } pData = NULL; } return 1; } /*--------------------------------------------------------------------------*/ int GetScanMonitor(pScanData self,int iWhich,long *lData, int iDataLen) { int i, iEnd; pCountEntry pData = NULL; void *pPtr = NULL; assert(self); /* hanlde iEnd */ if(self->iCounts < iDataLen) { iEnd = self->iCounts; } else { iEnd = iDataLen; } /* initialise to 0 */ memset(lData,0,iDataLen*sizeof(long)); /* the loop */ for(i = 0; i < iEnd; i++) { DynarGet(self->pCounts,i,&pPtr); pData = (pCountEntry)pPtr; if(pData) { lData[i] = pData->Monitors[iWhich]; } pData = NULL; } return 1; } /*--------------------------------------------------------------------------*/ int GetScanVar(pScanData self, int iWhich, float *fData, int iDataLen) { int iEnd, i; pVarEntry pVar = NULL; void *pPtr = NULL; /* does it exist ?*/ if( (iWhich < 0) || (iWhich >= self->iScanVar) ) { return 0; } /* handle iEnd */ if(self->iCounts < iDataLen) { iEnd = self->iCounts; } else { iEnd = iDataLen; } DynarGet(self->pScanVar,iWhich,&pPtr); pVar = (pVarEntry)pPtr; if(pVar) { /* initialise to theoretical values */ for(i = 0; i < self->iNP; i++) { fData[i] = pVar->fStart + i * pVar->fStep; } /* copy the actual scan data */ memcpy(fData,pVar->fData,iEnd*sizeof(float)); return 1; } else { return 0; } /* not reached */ assert(0); } /*--------------------------------------------------------------------------*/ int GetSoftScanVar(pScanData self, int iWhich, float *fData, int iDataLen) { int iEnd, i; pVarEntry pVar = NULL; void *pPtr = NULL; /* does it exist ?*/ if( (iWhich < 0) || (iWhich >= self->iScanVar) ) { return 0; } /* handle iEnd */ if(self->iCounts < iDataLen) { iEnd = self->iCounts; } else { iEnd = iDataLen; } DynarGet(self->pScanVar,iWhich,&pPtr); pVar = (pVarEntry)pPtr; if(pVar) { /* initialise to theoretical values */ for(i = 0; i < self->iNP; i++) { fData[i] = pVar->fStart + i * pVar->fStep; } return 1; } else { return 0; } /* not reached */ assert(0); } /*-------------------------------------------------------------------------*/ int GetScanVarName(pScanData self, int iWhich, char *pName, int iLength) { pVarEntry pVar = NULL; void *pPtr = NULL; /* does it exist ?*/ if( (iWhich < 0) || (iWhich >= self->iScanVar) ) { return 0; } /* get the scan var */ DynarGet(self->pScanVar,iWhich,&pPtr); pVar = (pVarEntry)pPtr; if(pVar) { strncpy(pName,pVar->Name,iLength); return 1; } else { return 0; } } /*-------------------------------------------------------------------------*/ int GetScanVarStep(pScanData self, int iWhich, float *fStep) { pVarEntry pVar = NULL; void *pPtr = NULL; /* does it exist ?*/ if( (iWhich < 0) || (iWhich >= self->iScanVar) ) { return 0; } /* get the scan var */ DynarGet(self->pScanVar,iWhich,&pPtr); pVar = (pVarEntry)pPtr; if(pVar) { *fStep = pVar->fStep; return 1; } else { return 0; } } /*-------------------------------------------------------------------------- ScanIntegrate does an integration of the current scan data. It returns 1 on success or one of the integrate error codes defined in integrate.h -----------------------------------------------------------------------------*/ int ScanIntegrate(pScanData self, float *fSum, float *fVar) { long *lData = NULL; int iRet; assert(self); /* no integration if no peak measured */ if(self->iCounts <= self->iWindow*2) return INTEGNOPEAK; /* get some memory */ lData = (long *)malloc(self->iNP*sizeof(long)); if(!lData) { return INTEGNOPEAK; } /* get counts */ GetScanCounts(self,lData,self->iNP); /* Do it */ iRet = GabePeakIntegrate(self->iWindow,self->iNP,lData, fSum, fVar); free(lData); return iRet; } /*-------------------------------------------------------------------------- SimScan is a debugging aid for other modules. It simulates a scan on a variable in the range from 10 -20 degrees in angle and 100 points. Data is created as a Gauss function located at fPos, with a halfwidth of FWHM and a height of fHeight. All data is randomized a little in a range of 5 counts. The peak will sit on a background of 20 counts. This requires a motor a4 to exist as it will be used for x-axis simulation. This routine will not stop you from simulating shit if you throw shit at it! ----------------------------------------------------------------------------*/ int SimScan(pScanData self, float fPos, float FWHM, float fHeight) { int i, iRet; SConnection *pCon = NULL; CountEntry sCount; pVarEntry pVar = NULL; void *pDings = NULL; float x, y, fTmp, fStdDev; assert(self); /* go to a clean state */ ClearScanVar(self); /* put in the scan variable */ pCon = SCCreateDummyConnection(pServ->pSics); if(!pCon) { return 0; } iRet = AddScanVar(self,pServ->pSics,pCon,"a4",10., 0.1); SCDeleteConnection(pCon); if(!iRet) { return 0; } /* do the x-axis of the scan */ DynarGet(self->pScanVar,0,&pDings); pVar = (pVarEntry)pDings; if(!pVar) { return 0; } pVar->fData = (float *)malloc(90*sizeof(float)); if(!pVar->fData) { return 0; } /* create scan data in loop */ fStdDev = FWHM/2.354; for(i = 0; i < 90; i++) { x = pVar->fData[i] = 10. + 0.1 * i; sCount.i = i; /* gaussian */ fTmp = (x - fPos)/fStdDev; y = fHeight*0.4* exp(-0.5*fTmp*fTmp); /* randomize a little */ y += 7. * (float)rand()/(float)RAND_MAX; /* add a little background */ sCount.lCount = (long)(10 + y); /* stow away */ DynarReplace(self->pCounts,i,&sCount,sizeof(CountEntry)); } self->iCounts = 90; self->iNP = 90; return 1; } /*---------------------------------------------------------------------------*/ int ScanFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pScanData pNew = NULL; pCounter pCount = NULL; pDummy pDum = NULL; CommandList *pCom = NULL; char pBueffel[512]; int iRet; if(argc < 5) { SCWrite(pCon,"ERROR: Insufficient number of arguments to ScanFactory", eError); return 0; } strtolower(argv[1]); strtolower(argv[2]); pCom = FindCommand(pSics,argv[2]); if(!pCom) { sprintf(pBueffel,"ERROR: cannot find counter %s",argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } pDum = (pDummy)pCom->pData; if(!pDum) { sprintf(pBueffel,"ERROR: counter %s has no data",argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } if(!(pDum->pDescriptor->GetInterface(pDum,COUNTID))) { sprintf(pBueffel,"ERROR: object %s is NO counter",argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } pNew = CreateScanObject(argv[4],argv[3],(pCounter)pCom->pData); if(!pNew) { SCWrite(pCon,"ERROR: failure to allocate scan data structure", eError); return 0; } iRet = AddCommand(pSics, argv[1], ScanWrapper, DeleteScanObject, pNew); if(!iRet) { sprintf(pBueffel,"ERROR: duplicate command %s not created",argv[1]); SCWrite(pCon,pBueffel,eError); return 0; } return 1; } /*--------------------------------------------------------------------------*/ static int ScanInterest(int iEvent, void *pEventData, void *pUser) { pScanData self = NULL; SConnection *pCon = NULL; char *pPtr = NULL, pItem[20]; long *lData = NULL; int i; self = (pScanData)pEventData; pCon = (SConnection *)pUser; assert(self); assert(pCon); if(iEvent == SCANSTART) { SCWrite(pCon,"NewScan",eWarning); return 1; } else if(iEvent == SCANEND) { SCWrite(pCon,"ScanEnd",eWarning); return 1; } else if(iEvent == SCANPOINT) { /* allocate space */ pPtr = (char *)malloc((self->iNP*20+20)*sizeof(char)); if(!pPtr) { return 0; } memset(pPtr,0,(self->iNP*20+20)*sizeof(char)); lData = (long *)malloc(self->iNP*sizeof(long)); if(!lData) { return 0; } memset(lData,0,self->iNP*sizeof(long)); /* get counts */ GetScanCounts(self,lData,self->iNP); /* format a message */ strcpy(pPtr,"scan.Counts= "); for(i = 0; i < self->iNP; i++) { sprintf(pItem,"{%d} ",lData[i]); strcat(pPtr,pItem); } SCWrite(pCon,pPtr,eWarning); free(lData); free(pPtr); return 1; } return 1; } /*--------------------------------------------------------------------------*/ static int ScanUUInterest(int iEvent, void *pEventData, void *pUser) { pScanData self = NULL; SConnection *pCon = NULL; char pItem[20]; long *lData = NULL; int *iData = NULL; int i; self = (pScanData)pEventData; pCon = (SConnection *)pUser; assert(self); assert(pCon); if(iEvent == SCANSTART) { SCWrite(pCon,"NewScan",eWarning); return 1; } else if(iEvent == SCANEND) { SCWrite(pCon,"ScanEnd",eWarning); return 1; } else if(iEvent == SCANPOINT) { /* allocate space */ lData = (long *)malloc(self->iNP*sizeof(long)); iData = (int *)malloc(self->iNP*sizeof(int)); if(!lData || !iData) { return 0; } memset(lData,0,self->iNP*sizeof(long)); memset(iData,0,self->iNP*sizeof(int)); /* get counts */ GetScanCounts(self,lData,self->iNP); /* put into network byte order */ for(i = 0; i < self->iNP; i++) { iData[i] = htonl((int)lData[i]); } SCWriteUUencoded(pCon,"ScanData",iData,self->iNP*sizeof(int)); free(lData); free(iData); return 1; } return 1; } /*---------------------------------------------------------------------------*/ int ScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pScanData self = NULL; char pBueffel[512]; double fStep, fStart, fPreset; float *fData = NULL; int lNP; int iChannel; int iRet, iMode,i; char *pPtr = NULL, pItem[20]; long *lData = NULL, lID; int *iData; void *pVarData = NULL; pVarEntry pVar = NULL; float fSum, fVar; double x; float fPos, FWHM, fHeight; self = (pScanData)pData; assert(self); argtolower(argc,argv); if(argc < 2) { sprintf(pBueffel,"ERROR: not enough arguments for %s",argv[0]); SCWrite(pCon,pBueffel,eError); return 0; } /*------------ first interpret commands which do not require user rights */ /*---------- getfile */ if(strcmp(argv[1],"getfile") == 0) { sprintf(pBueffel,"scan.File = %s",self->pFile); SCWrite(pCon,pBueffel,eValue); return 1; } /*--------- getcounts */ else if(strcmp(argv[1],"getcounts") == 0) { /* get some memory */ if(self->iNP < 1) { SCWrite(pCon,"ERROR: no counts available",eError); return 0; } lData = (long *)malloc(self->iNP*sizeof(long)); if(!lData) { SCWrite(pCon,"ERROR: out of memory in scan",eError); return 0; } pPtr = (char *)malloc((self->iNP*20+20)*sizeof(char)); if(!pPtr) { SCWrite(pCon,"ERROR: out of memory in scan",eError); return 0; } memset(pPtr,0,(self->iNP*20+20)*sizeof(char)); /* get counts */ GetScanCounts(self,lData,self->iNP); /* format them */ strcpy(pPtr,"scan.Counts= "); for(i = 0; i < self->iNP; i++) { sprintf(pItem,"{%d} ",lData[i]); strcat(pPtr,pItem); } SCWrite(pCon,pPtr,eValue); free(lData); free(pPtr); return 1; } /*---------- uucounts */ else if(strcmp(argv[1],"uucounts") == 0) { /* get some memory */ if(self->iNP < 1) { SCWrite(pCon,"ERROR: no counts available",eError); return 0; } lData = (long *)malloc(self->iNP*sizeof(long)); iData = (int *)malloc((self->iNP + 1)*sizeof(int)); if(!lData || !iData ) { SCWrite(pCon,"ERROR: out of memory in scan",eError); return 0; } /* get counts */ GetScanCounts(self,lData,self->iNP); /* copy them */ memset(iData,0,self->iNP+1); iData[0] = self->iNP; for(i = 0; i < self->iNP; i++) { iData[i+1] = htonl(lData[i]); } SCWriteUUencoded(pCon,"ScanCounts",iData, (self->iNP + 1)*sizeof(int)); return 1; } /*--------- getvardata */ else if(strcmp(argv[1],"getvardata") == 0) { /* we need an integer parameter saying which */ if(argc >= 3) { iRet = Tcl_GetInt(pSics->pTcl,argv[2],&i); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected integer, got %s",argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } } else { SCWrite(pCon,"ERROR: expected number of variable to retrieve data for ", eError); return 0; } /* check the int for validity */ if( (i < 0) || (i >= self->iScanVar)) { SCWrite(pCon,"ERROR: non existent scan variable requested!",eError); return 0; } /* get some memory */ fData = (float *)malloc(self->iNP*sizeof(float)); if(!fData) { SCWrite(pCon,"ERROR: out of memory in scan",eError); return 0; } pPtr = (char *)malloc((self->iNP*20+20)*sizeof(char)); if(!pPtr) { SCWrite(pCon,"ERROR: out of memory in scan",eError); return 0; } memset(pPtr,0,(self->iNP*20+20)*sizeof(char)); /* get data */ GetScanVar(self,i,fData,self->iNP); /* get name of ScanVar */ DynarGet(self->pScanVar,i,&pVarData); pVar = (pVarEntry)pVarData; if(!pVar) { SCWrite(pCon,"ERROR: Corrupted data structures, inform Programmer", eError); return 0; } /* format them */ sprintf(pPtr,"scan.%s = ", pVar->Name); for(i = 0; i < self->iNP; i++) { sprintf(pItem,"{%12.3f} ",fData[i]); strcat(pPtr,pItem); } SCWrite(pCon,pPtr,eValue); free(fData); free(pPtr); return 1; } /*-------- interest */ else if(strcmp(argv[1],"interest") == 0) { lID = RegisterCallback(self->pCall, SCANSTART, ScanInterest, pCon, NULL); SCRegister(pCon,pSics, self->pCall,lID); lID = RegisterCallback(self->pCall, SCANEND, ScanInterest, pCon, NULL); SCRegister(pCon,pSics, self->pCall,lID); lID = RegisterCallback(self->pCall, SCANPOINT, ScanInterest, pCon, NULL); SCRegister(pCon,pSics, self->pCall,lID); SCSendOK(pCon); return 1; } /*-------- uuinterest */ else if(strcmp(argv[1],"uuinterest") == 0) { lID = RegisterCallback(self->pCall, SCANSTART, ScanUUInterest, pCon, NULL); SCRegister(pCon,pSics, self->pCall,lID); lID = RegisterCallback(self->pCall, SCANEND, ScanUUInterest, pCon, NULL); SCRegister(pCon,pSics, self->pCall,lID); lID = RegisterCallback(self->pCall, SCANPOINT, ScanUUInterest, pCon, NULL); SCRegister(pCon,pSics, self->pCall,lID); SCSendOK(pCon); return 1; } /* ------- uninterest */ else if(strcmp(argv[1],"uninterest") == 0) { RemoveCallback2(self->pCall,pCon); SCUnregister(pCon,self->pCall); SCSendOK(pCon); return 1; } /*------- deal with command needing user rights in all cases */ /* check User Rights */ if(!(SCMatchRights(pCon,usUser))) { SCWrite(pCon,"ERROR: You are NOT authorised to use scan",eError); return 0; } /*---------- add command */ if(strcmp(argv[1],"add") == 0) { if(argc < 5) { sprintf(pBueffel,"ERROR: Insufficient number of arguments given for %s add", argv[0]); SCWrite(pCon,pBueffel,eError); return 0; } /* get numbers */ iRet = Tcl_GetDouble(pSics->pTcl,argv[3],&fStart); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } iRet = Tcl_GetDouble(pSics->pTcl,argv[4],&fStep); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } iRet = AddScanVar(self,pSics,pCon,argv[2],(float)fStart,(float)fStep); if(iRet) { SCSendOK(pCon); } return iRet; } /* --------clear */ else if(strcmp(argv[1],"clear") == 0) { iRet = ClearScanVar(self); if(iRet) { SCSendOK(pCon); } else { SCWrite(pCon,"ERROR: cannot change parameters while scanning", eError); return 0; } return 1; } /*------------ configure */ else if(strcmp(argv[1],"configure") == 0) { /* managers only */ if(!SCMatchRights(pCon,usMugger)) return 0; if(argc < 3) { SCWrite(pCon,"ERROR: missing configure option",eError); return 0; } strtolower(argv[2]); if(strcmp(argv[2],"standard") == 0) { ResetScanFunctions(self); SCSendOK(pCon); return 1; } else if(strcmp(argv[2],"amor") == 0) { ConfigureAmor(self); SCSendOK(pCon); return 1; } else { sprintf(pBueffel,"ERROR: option %s not recognized by configure", argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } } /*---------- scan */ else if(strcmp(argv[1],"run") == 0) { /* get NP */ iRet = Tcl_GetInt(pSics->pTcl,argv[2],&lNP); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } /* interpret Mode */ if(strcmp(argv[3],"timer") == 0) { iMode = eTimer; } else if(strcmp(argv[3],"monitor") == 0) { iMode = ePreset; } else { sprintf(pBueffel,"ERROR: %s not recognized as valid counter mode", argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } /* preset */ iRet = Tcl_GetDouble(pSics->pTcl,argv[4],&fPreset); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } iRet = DoScan(self,(int)lNP,iMode,(float)fPreset, pSics,pCon); if(iRet) { SCSendOK(pCon); } return iRet; } /*---------- silent */ else if(strcmp(argv[1],"silent") == 0) { /* get NP */ iRet = Tcl_GetInt(pSics->pTcl,argv[2],&lNP); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } /* interpret Mode */ if(strcmp(argv[3],"timer") == 0) { iMode = eTimer; } else if(strcmp(argv[3],"monitor") == 0) { iMode = ePreset; } else { sprintf(pBueffel,"ERROR: %s not recognized as valid counter mode", argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } /* preset */ iRet = Tcl_GetDouble(pSics->pTcl,argv[4],&fPreset); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } iRet = SilentScan(self,(int)lNP,iMode,(float)fPreset, pSics,pCon); if(iRet) { SCSendOK(pCon); } return iRet; } /*--------- recover */ else if(strcmp(argv[1],"recover") == 0) { iRet = RecoverScan(self,pSics,pCon); if(iRet) { SCSendOK(pCon); } return iRet; } /*----------- setchannel */ else if(strcmp(argv[1],"setchannel") == 0) { if(argc < 3) { SCWrite(pCon,"ERROR: setchannel expects an integer argument",eError); return 0; } /* convert to int */ iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iChannel); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected integer, got %s", argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } if( ((iChannel < 0) && (iChannel != -10)) || (iChannel >= GetNMonitor((pCounter)self->pCounterData)) ) { SCWrite(pCon,"ERROR: requested counter channel out of range ", eError); return 0; } self->iChannel = iChannel; SCSendOK(pCon); return 1; } /*--------- command */ else if(strcmp(argv[1],"command") == 0) { /* inquire */ if(argc < 3) { sprintf(pBueffel,"%s.command = %s",argv[0], self->pCommand); SCWrite(pCon,pBueffel,eValue); return 1; } /* set case */ Arg2Text(argc-2,&argv[2],pBueffel,511); if(self->pCommand) free(self->pCommand); self->pCommand = strdup(pBueffel); SCSendOK(pCon); return 1; } /*--------- integration window */ else if(strcmp(argv[1],"window") == 0) { if(argc > 2) { /* set value */ iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iChannel); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } if(iChannel < 0) { SCWrite(pCon,"ERROR: new integration window size out of range", eError); return 0; } self->iWindow = iChannel; SCSendOK(pCon); return 1; } else { /* request the value */ sprintf(pBueffel,"Integration Window = %d",self->iWindow); SCWrite(pCon,pBueffel,eValue); return 1; } } /*------------- integrate */ else if(strcmp(argv[1],"integrate") == 0) { iRet = ScanIntegrate(self,&fSum,&fVar); switch(iRet) { case INTEGLEFT: SCWrite(pCon,"ERROR: no left limit found for peak",eError); return 0; break; case INTEGRIGHT: SCWrite(pCon,"ERROR: no right limit found for peak",eError); return 0; break; case INTEGNOPEAK: SCWrite(pCon,"ERROR: no data found for peak",eError); return 0; break; case INTEGFUNNYBACK: SCWrite(pCon,"WARNING: background asymmetric or worse",eWarning); default: sprintf(pBueffel,"Intensity = %f, Variance = %f",fSum,fVar); SCWrite(pCon,pBueffel,eValue); return 1; break; } } /*---------- simscan */ else if(strcmp(argv[1],"simscan") == 0) { if(argc < 5) { SCWrite(pCon,"ERROR expected fPos FWHM Height parameters",eError); return 0; } iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&x); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } fPos = x; iRet = Tcl_GetDouble(pSics->pTcl,argv[3],&x); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } FWHM = x; iRet = Tcl_GetDouble(pSics->pTcl,argv[4],&x); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected number, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } fHeight = x; iRet = SimScan(self,fPos,FWHM,fHeight); if(!iRet) { SCWrite(pCon,"ERROR: cannot create simulated scan data",eError); return 0; } SCSendOK(pCon); return 1; } else { sprintf(pBueffel,"ERROR: %s not recognized as subcommand to %s", argv[1], argv[0]); SCWrite(pCon,pBueffel,eError); return 0; } }