/*------------------------------------------------------------------------- M E S U R E An object for doing simple four circle diffractometer measurements with a single counter. copyright: see copyright.h Mark Koennecke, April 1998 ---------------------------------------------------------------------------*/ #include #include #include #include #include "fortify.h" #include "sics.h" #include "motor.h" #include "o2t.h" #include "scan.h" #include "scan.i" #include "danu.h" #include "integrate.h" #include "hkl.h" #include "sicsvar.h" #include "evcontroller.h" #include "mesure.h" extern void SNXFormatTime(char *pBueffel, int iLen); #define ANGERR 0.2 /* nxutil.h */ /* #define MESSDEBUG 1 define MESSDEBUG for simulated peaks. This helps in debugging this code and the initial data correction code */ extern void SNXFormatTime(char *pBueffel, int iLen); /* nxutil.c */ /*------------------- the data structure -----------------------------------*/ typedef struct __Mesure { pObjectDescriptor pDes; /* standard object descriptor */ pICallBack pCall; /* callback interface for automatic notification */ pScanData pScanner; /* scan object to use for scans */ pHKL pCryst; /* hkl object for crystallographic calc and reflection driving */ pMotor pOmega; /* motor for omega scans */ char *pCOmega; /* name of omega motor */ char *pO2T; /* name of omega 2 theta virtual motor */ char *pFileRoot; /* where to write files */ pDataNumber pDanu; /* where to get data file number */ FILE *fRefl; /* reflection profile file */ FILE *fHKL; /* integrated intensity file */ int iLogFile; /* log file num at connection */ SConnection *pCon; /* log file owning connection */ char *pCurrentFile; /* current file root */ int iCount; /* count of reflection */ int CountMode; /* timer or preset */ int np; /* number of scan points */ float fPreset; /* counting preset */ float fStep; /* omega step widths */ int iMode; /* omega or omega 2 theta scan flag */ long *lCounts; /* array to store counting values */ float fPosition[4]; /* the real positions after driving */ int iCompact; /* true if compact scan ouput. */ } Mesure; /*--------------------------------------------------------------------------*/ pMesure CreateMesure(pHKL pCryst, pScanData pScanner, pMotor pOmega, char *pOm, char *po2t, char *pFileRoot, pDataNumber pDanu) { pMesure pNew = NULL; assert(pCryst); assert(pScanner); assert(pOmega); assert(pFileRoot); assert(pDanu); /* allocate space............. */ pNew = (pMesure)malloc(sizeof(Mesure)); if(!pNew) { return NULL; } memset(pNew,0,sizeof(Mesure)); pNew->pDes = CreateDescriptor("Mesure"); pNew->pCall = CreateCallBackInterface(); if( !pNew->pDes || !pNew->pCall) { free(pNew); return NULL; } /* asssign defaults */ pNew->pScanner = pScanner; pNew->pCryst = pCryst; pNew->pOmega = pOmega; pNew->pCOmega = strdup(pOm); pNew->pO2T = strdup(po2t); pNew->pFileRoot = strdup(pFileRoot); pNew->pDanu = pDanu; pNew->iCount = 0; pNew->CountMode = 0; pNew->np = 50; pNew->fStep = 0.05; pNew->fPreset = 2; pNew->iMode = 0; pNew->iCompact = 1; #ifdef MESSDEBUG pNew->lCounts = (long *)malloc(90*sizeof(long)); #endif pNew->lCounts = (long *)malloc(50*sizeof(long)); return pNew; } /*------------------------------------------------------------------------*/ void DeleteMesure(void *pData) { pMesure self = NULL; self = (pMesure)pData; if(!pData) { return; } if(self->pDes) DeleteDescriptor(self->pDes); if(self->pCall) DeleteCallBackInterface(self->pCall); if(self->pFileRoot) free(self->pFileRoot); if(self->pCOmega) free(self->pCOmega); if(self->pO2T) free(self->pO2T); if(self->fRefl) MesureClose(self); if(self->lCounts) free(self->lCounts); free(self); } /*------------------------------------------------------------------------*/ int MesureFactory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { pMesure pNew = NULL; pHKL pCryst = NULL; pScanData pScan = NULL; CommandList *pCom = NULL; pMotor pMot = NULL; pDataNumber pDanu = NULL; pSicsO2T pO2T = NULL; char pBueffel[512]; pDummy pDum = NULL; int iRet; assert(pCon); assert(pSics); /* check no of parameters inicom name hkl scan omega o2t root danu */ if(argc < 8) { SCWrite(pCon, "ERROR: Insufficient number of parameters to MesureFactory",eError); return 0; } /* work parameters one by one, first hkl */ pCom = FindCommand(pSics,argv[2]); if(pCom) { pDum = (pDummy)pCom->pData; if(pDum) { if(strcmp(pDum->pDescriptor->name,"4-Circle-Calculus") == 0) { pCryst = (pHKL)pCom->pData; } } } if(!pCryst) { sprintf(pBueffel,"ERROR: %s is no four circle calculus object",argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } /* scanner */ pCom = FindCommand(pSics,argv[3]); if(pCom) { pDum = (pDummy)pCom->pData; if(pDum) { if(strcmp(pDum->pDescriptor->name,"ScanObject") == 0) { pScan = (pScanData)pCom->pData; } } } if(!pScan) { sprintf(pBueffel,"ERROR: %s is no scan object",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } /* omega */ pMot = FindMotor(pSics,argv[4]); if(!pMot) { sprintf(pBueffel,"ERROR: %s is no motor object ",argv[4]); SCWrite(pCon,pBueffel,eError); return 0; } /* o2t */ pCom = FindCommand(pSics,argv[5]); if(pCom) { pDum = (pDummy)pCom->pData; if(pDum) { if(strcmp(pDum->pDescriptor->name,"Omega2Theta") == 0) { pO2T = (pSicsO2T)pCom->pData; } } } if(!pO2T) { sprintf(pBueffel,"ERROR: %s is no omega 2 theta object",argv[5]); SCWrite(pCon,pBueffel,eError); return 0; } /* Data Number */ pCom = FindCommand(pSics,argv[7]); if(pCom) { pDum = (pDummy)pCom->pData; if(pDum) { if(strcmp(pDum->pDescriptor->name,"DataNumber") == 0) { pDanu = (pDataNumber)pCom->pData; } } } if(!pDanu) { sprintf(pBueffel,"ERROR: %s is no DataNumber object",argv[7]); SCWrite(pCon,pBueffel,eError); return 0; } /* finally create the thing */ pNew = CreateMesure(pCryst,pScan,pMot,argv[4],argv[5],argv[6],pDanu); if(!pNew) { SCWrite(pCon,"ERROR: no meory in MesureFactory",eError); return 0; } /* add the new command */ iRet = AddCommand(pSics,argv[1],MesureAction,DeleteMesure,pNew); if(!iRet) { sprintf(pBueffel,"ERROR: duplicate command %s not created",argv[1]); SCWrite(pCon,pBueffel,eError); return 0; } return 1; } /*------------------------------------------------------------------------ This implements the compact scan output for TRICS scans */ static int CompactScanData(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); /* 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); } if(self->iChannel == 0) { sCount.lCount = GetCounts((pCounter)self->pCounterData,self->pCon); } else { sCount.lCount = GetMonitor((pCounter)self->pCounterData, self->iChannel, self->pCon); } /* stow away */ DynarReplace(self->pCounts,self->iCounts,&sCount,sizeof(CountEntry)); self->iCounts++; return 1; } /*--------------------------------------------------------------------------*/ int MesureReflection(pMesure self, float fHKL[3], SConnection *pCon) { int iRet, i; float fStart; float fDelta, fSet[4]; char pBueffel[132]; assert(self); /* drive to reflection */ iRet = DriveHKL(self->pCryst,fHKL,0.,0,pCon); if(!iRet) { return iRet; } /* store achieved position for reporting */ iRet = GetCurrentPosition(self->pCryst,pCon,self->fPosition); if(iRet != 1) { return iRet; } /* check if we are really there. All this only because Jurg does not fix his rotten cradle. */ CalculateSettings(self->pCryst,fHKL,0.,0,fSet,pCon); for(i = 0; i < 4; i++) { fDelta = fSet[i] - self->fPosition[i]; if(fDelta < 0.) fDelta = -fDelta; if(fDelta > ANGERR) { sprintf(pBueffel, "ERROR: angle %d positioned badly, aborting Reflection", i); SCWrite(pCon,pBueffel,eError); return 0; } } /* calculate scan start */ iRet = MotorGetSoftPosition(self->pOmega,pCon,&fStart); if(!iRet) { return iRet; } fStart -= (self->np/2)*self->fStep; /* set the scan up */ ClearScanVar(self->pScanner); if(self->iMode == 0) { AddScanVar(self->pScanner, pServ->pSics,pCon,self->pCOmega, fStart, self->fStep); } else { AddScanVar(self->pScanner, pServ->pSics,pCon,self->pO2T, fStart, self->fStep); } /* do the scan */ if(self->iCompact) { self->pScanner->CollectScanData = CompactScanData; } iRet = SilentScan(self->pScanner,self->np,self->CountMode, self->fPreset,pServ->pSics,pCon); ResetScanFunctions(self->pScanner); return iRet; } /*------------------------------------------------------------------------*/ int MesureGenReflection(pMesure self, float fHKL[3], float fSet[4], SConnection *pCon) { int iRet, i; float fStart, fDelta; char pBueffel[132]; assert(self); /* drive to reflection */ iRet = DriveSettings(self->pCryst,fSet,pCon); if(!iRet) { return iRet; } /* store achieved position for reporting */ iRet = GetCurrentPosition(self->pCryst,pCon,self->fPosition); if(iRet != 1) { return iRet; } /* check if we are really there. All this only because Jurg does not fix his rotten cradle. */ for(i = 0; i < 4; i++) { fDelta = fSet[i] - self->fPosition[i]; if(fDelta < 0.) fDelta = -fDelta; if(fDelta > ANGERR) { sprintf(pBueffel, "ERROR: angle %d positioned badly, aborting Reflection", i); SCWrite(pCon,pBueffel,eError); return 0; } } /* calculate scan start */ iRet = MotorGetSoftPosition(self->pOmega,pCon,&fStart); if(!iRet) { return iRet; } fStart -= (self->np/2)*self->fStep; /* set the scan up */ ClearScanVar(self->pScanner); if(self->iMode == 0) { AddScanVar(self->pScanner, pServ->pSics,pCon,self->pCOmega, fStart, self->fStep); } else { AddScanVar(self->pScanner, pServ->pSics,pCon,self->pO2T, fStart, self->fStep); } /* do the scan */ if(self->iCompact) { self->pScanner->CollectScanData = CompactScanData; } iRet = SilentScan(self->pScanner,self->np,self->CountMode, self->fPreset,pServ->pSics,pCon); ResetScanFunctions(self->pScanner); return iRet; } /*--------------------------------------------------------------------------*/ int MesureStart(pMesure self, SConnection *pCon) { char pFilename[512], pRoot[512]; char pBueffel[1024]; char pBuff[132]; int iYear, iNum; float fVal, fUB[9]; pSicsVariable pVar = NULL; assert(self); assert(pCon); /* close open files if so */ if(self->fRefl != NULL) { MesureClose(self); } /* create filename root */ iNum = IncrementDataNumber(self->pDanu,&iYear); sprintf(pRoot,"%s/trics%5.5d%4.4d.",self->pFileRoot,iNum,iYear); self->pCurrentFile = strdup(pRoot); /* do the logfile */ strcpy(pFilename,pRoot); strcat(pFilename,"log"); self->iLogFile = SCAddLogFile(pCon,pFilename); self->pCon = pCon; sprintf(pBueffel,"Writing to %s.log, .ccl, .rfl",pRoot); SCWrite(pCon,pBueffel,eValue); /* open the reflection file */ strcpy(pFilename,pRoot); strcat(pFilename,"ccl"); self->fRefl = fopen(pFilename,"w"); if(!self->fRefl) { sprintf(pBueffel,"ERROR: SERIOUS TROUBLE: cannot open %s!", pFilename); SCWrite(pCon,pBueffel,eError); SCSetInterrupt(pCon,eAbortBatch); return 0; } /* put filename fputs(pFilename,self->fRefl); fputs("\n",self->fRefl); */ /* open hkl-data file */ strcpy(pFilename,pRoot); strcat(pFilename,"rfl"); self->fHKL = fopen(pFilename,"w"); if(!self->fHKL) { sprintf(pBueffel,"ERROR: SERIOUS TROUBLE: cannot open %s!", pFilename); SCWrite(pCon,pBueffel,eError); SCSetInterrupt(pCon,eAbortBatch); return 0; } fputs(pFilename,self->fHKL); fputs("\n",self->fHKL); /* write some header data */ SNXFormatTime(pBueffel,1024); /* fprintf(self->fRefl,"filetime = %s\n",pBueffel); */ fprintf(self->fHKL,"filetime = %s\n",pBueffel); GetLambda(self->pCryst,&fVal); /* fprintf(self->fRefl,"lambda = %f Angstroem\n",fVal); */ fprintf(self->fHKL,"lambda = %f Angstroem\n",fVal); GetUB(self->pCryst,fUB); /* fprintf(self->fRefl, "UB = %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f\n", fUB[0], fUB[1],fUB[2],fUB[3],fUB[4],fUB[5],fUB[6],fUB[7],fUB[8]); */ fprintf(self->fHKL, "UB = %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f %7.6f\n", fUB[0], fUB[1],fUB[2],fUB[3],fUB[4],fUB[5],fUB[6],fUB[7],fUB[8]); /* write sample & user info */ strcpy(pBueffel,"CCL, Instr=TRICS, "); pVar = FindVariable(pServ->pSics,"sample"); if(pVar) { fprintf(self->fHKL,"sample = %s\n",pVar->text); sprintf(pBuff,"sample = %s, ",pVar->text); strcat(pBueffel,pBuff); } pVar = FindVariable(pServ->pSics,"user"); if(pVar) { fprintf(self->fHKL,"user = %s \n",pVar->text); sprintf(pBuff,"user = %s",pVar->text); strcat(pBueffel,pBuff); } fprintf(self->fRefl,"%s\n",pBueffel); return 1; } /*---------------------------------------------------------------------------*/ int MesureReopen(pMesure self, char *fileroot, SConnection *pCon) { char pBueffel[1024]; char pFile[512]; assert(self); assert(fileroot); assert(pCon); /* close pending files */ if(self->fRefl != NULL) { MesureClose(self); } /* check if this is possible */ strcpy(pFile,self->pFileRoot); strcat(pFile,"/"); strcat(pFile,fileroot); strcat(pFile,".col"); self->fRefl = fopen(pFile,"r"); if(!self->fRefl) { fclose(self->fRefl); sprintf(pBueffel,"ERROR: there is no such measurement at %s",fileroot); SCWrite(pCon,pBueffel,eError); return 0; } fclose(self->fRefl); /* well seems to exist, open for append */ self->fRefl = fopen(pFile,"a"); /* rfl file */ strcpy(pFile,self->pFileRoot); strcat(pFile,"/"); strcat(pFile,fileroot); self->pCurrentFile = strdup(pFile); strcat(pFile,".rfl"); self->fHKL = fopen(pFile,"a"); /* log file */ strcpy(pFile,self->pFileRoot); strcat(pFile,"/"); strcat(pFile,fileroot); strcat(pFile,".log"); self->iLogFile = SCAddLogFile(pCon,pFile); self->pCon = pCon; return 1; } /*------------------------------------------------------------------------*/ int MesureClose(pMesure self) { assert(self); if(self->fRefl) { fclose(self->fRefl); self->fRefl = NULL; } if(self->fHKL) { fclose(self->fHKL); self->fHKL = NULL; } SCDelLogFile(self->pCon,self->iLogFile); self->pCon = NULL; self->iLogFile = -1; if(self->pCurrentFile) free(self->pCurrentFile); return 1; } /*---------------------------------------------------------------------------*/ static int WriteReflection(pMesure self, float fHKL[3],SConnection *pCon) { float fSum, fSigma, fSet[4], fTemp, fPreset, fStep; static float fMax = 10.; int iRet, i,ii, iLF, iNP; char pBueffel[512], pNum[10], pTime[132]; pEVControl pEva = NULL; assert(self); assert(pCon); #ifdef MESSDEBUG self->np = 90; fMax += 10; SimScan(self->pScanner,14.,0.5,fMax); if(fMax > 1000) { fMax = 10.; } #endif /* get necessary data */ fSum = 0.; fSigma = 0.; iRet = ScanIntegrate(self->pScanner,&fSum, &fSigma); if(iRet != 1) { switch(iRet) { case INTEGLEFT: sprintf(pBueffel, "WARNING: integration failed --> no left side to: %f %f %f", fHKL[0], fHKL[1],fHKL[2]); break; case INTEGRIGHT: sprintf(pBueffel, "WARNING: integration failed -->no right side to: %f %f %f", fHKL[0], fHKL[1],fHKL[2]); break; case INTEGNOPEAK: sprintf(pBueffel, "WARNING: integration failed -->no peak found: %f %f %f", fHKL[0], fHKL[1],fHKL[2]); break; case INTEGFUNNYBACK: sprintf(pBueffel, "WARNING: integration problem, asymmetric background: %f %f %f", fHKL[0], fHKL[1],fHKL[2]); break; } SCWrite(pCon,pBueffel,eWarning); } GetScanCounts(self->pScanner,self->lCounts,self->np); /* write it */ if(self->fRefl) { fprintf(self->fRefl,"%4d%8.3f%8.3f%8.3f%8.2f%8.2f%8.2f%8.2f%8.0f%8.2f\n", self->iCount, fHKL[0],fHKL[1],fHKL[2], self->fPosition[0], self->fPosition[1], self->fPosition[2],self->fPosition[3], fSum,fSigma); } if(self->fHKL) { fprintf(self->fHKL,"%5d%7.2f%7.2f%7.2f%8.2f%8.2f%8.2f%8.2f%8.0f%8.2f\n", self->iCount, fHKL[0],fHKL[1],fHKL[2], self->fPosition[0], self->fPosition[1], self->fPosition[2],self->fPosition[3], fSum,fSigma); } sprintf(pBueffel,"%5d%7.2f%7.2f%7.2f%8.2f%8.2f%8.2f%8.2f%8.0f%8.2f\n", self->iCount, fHKL[0],fHKL[1],fHKL[2], self->fPosition[0], self->fPosition[1], self->fPosition[2],self->fPosition[3], fSum,fSigma); SCWrite(pCon,pBueffel,eStatus); /* get temperature */ fTemp = -777.77; pEva = (pEVControl)FindCommandData(pServ->pSics,"temperature", "Environment Controller"); if(pEva) { iRet = EVCGetPos(pEva, pCon,&fTemp); } /* write profile */ if(self->fRefl) { /* collect data */ SNXFormatTime(pBueffel,512); GetScanVarStep(self->pScanner,0,&fStep); iNP = GetScanNP(self->pScanner); fPreset = GetScanPreset(self->pScanner); fprintf(self->fRefl,"%3d%8.3f%10.0f%8.3f %s\n",iNP,fStep, fPreset,fTemp,pBueffel); for(i = 0; i < iNP; i++) { for(ii = 0; ii < 10 && i < iNP; ii++) { fprintf(self->fRefl,"%8d",self->lCounts[i]); iLF = 1; i++; } fprintf(self->fRefl,"\n"); i--; iLF = 0; } if(iLF) { fprintf(self->fRefl,"\n"); } fflush(self->fRefl); } /* write data if compact output */ if(self->iCompact == 1) { strcpy(pTime,pBueffel); sprintf(pBueffel,"%3d%8.3f%10.0f%8.3f %s\n",iNP,fStep, fPreset,fTemp,pTime); SCWrite(pCon,pBueffel,eValue); pBueffel[0] = '\0'; for(i = 0; i < iNP; i++) { for(ii = 0; ii < 10 && i < iNP; ii++) { sprintf(pNum,"%7d",self->lCounts[i]); strcat(pBueffel,pNum); iLF = 1; i++; } SCWrite(pCon,pBueffel,eValue); pBueffel[0] = '\0'; i--; iLF = 0; } if(iLF) { SCWrite(pCon,pBueffel,eValue); } } return 1; } /*------------------------------------------------------------------------*/ int MesureFile(pMesure self, char *pFile, int iSkip, SConnection *pCon) { FILE *fd = NULL; char pBueffel[512], pTime[132]; int i, iRet; float fHKL[3]; assert(self); assert(pCon); /* well before doing a thing, open the list file */ fd = fopen(pFile,"r"); if(!fd) { sprintf(pBueffel,"ERROR: reflection file %s NOT found!",pFile); SCWrite(pCon,pBueffel,eError); return 0; } /* check that files are open, if not open */ if(self->fRefl == NULL) { MesureStart(self,pCon); } /* make a mark */ SNXFormatTime(pTime,131); sprintf(pBueffel,"Starting at list %s at %s",pFile,pTime); SCWrite(pCon,pBueffel,eStatus); /* skippy! */ for(i = 0; i < iSkip; i++) { fgets(pBueffel,510,fd); } self->iCount = iSkip; /* loop through space and measure! */ while(fgets(pBueffel,510,fd) != NULL) { for(i = 0; i < 3;i++) fHKL[i] = 0.; iRet = sscanf(pBueffel,"%f%f%f",&fHKL[0],&fHKL[1],&fHKL[2]); self->iCount++; iRet = MesureReflection(self,fHKL,pCon); if(iRet == 0) { if(SCGetInterrupt(pCon) >= eAbortBatch) { return 0; } else { SCSetInterrupt(pCon,eContinue); continue; } } WriteReflection(self,fHKL,pCon); } /* we are done */ SNXFormatTime(pTime,131); sprintf(pBueffel,"Finishing list %s at %s",pFile,pTime); SCWrite(pCon,pBueffel,eStatus); fclose(fd); return 1; } /*------------------------------------------------------------------------*/ int MesureGenFile(pMesure self, char *pFile, int iSkip, SConnection *pCon) { FILE *fd = NULL; char pBueffel[512], pTime[132]; int i, iRet, iH, iK, iL; float fHKL[3], fSet[4]; char pDum[4]; assert(self); assert(pCon); /* well before doing a thing, open the list file */ fd = fopen(pFile,"r"); if(!fd) { sprintf(pBueffel,"ERROR: reflection file %s NOT found!",pFile); SCWrite(pCon,pBueffel,eError); return 0; } /* check that files are open, if not open */ if(self->fRefl == NULL) { MesureStart(self,pCon); } /* make a mark */ SNXFormatTime(pTime,131); sprintf(pBueffel,"Starting at list %s at %s",pFile,pTime); SCWrite(pCon,pBueffel,eStatus); /* skippy! */ for(i = 0; i < iSkip; i++) { fgets(pBueffel,510,fd); } self->iCount = iSkip; /* loop through space and measure! */ while(fgets(pBueffel,510,fd) != NULL) { for(i = 0; i < 3;i++) fHKL[i] = 0.; for(i = 0; i < 4;i++) fSet[i] = 0.; iRet = sscanf(pBueffel,"%4d%4d%4d%s%f%f%f%f", &iH,&iK,&iL,pDum, &fSet[0], &fSet[1],&fSet[2],&fSet[3]); fHKL[0] = (float)iH; fHKL[1] = (float)iK; fHKL[2] = (float)iL; self->iCount++; iRet = MesureGenReflection(self,fHKL,fSet,pCon); if(iRet == 0) { if(SCGetInterrupt(pCon) >= eAbortBatch) { return 0; } else { SCSetInterrupt(pCon,eContinue); continue; } } WriteReflection(self,fHKL,pCon); } /* we are done */ SNXFormatTime(pTime,131); sprintf(pBueffel,"Finishing list %s at %s",pFile,pTime); SCWrite(pCon,pBueffel,eStatus); fclose(fd); return 1; } /*--------------------------------------------------------------------------*/ int MesureSetPar(pMesure self, char *name, float fVal) { if(strcmp(name,"np") == 0) { #ifndef MESSDEBUG self->np = (int)fVal; if(self->lCounts) free(self->lCounts); self->lCounts = (long *)malloc(self->np*sizeof(long)); if(!self->lCounts) { return 0; } #else #endif return 1; } else if(strcmp(name,"step") == 0) { self->fStep = fVal; return 1; } else if(strcmp(name,"preset") == 0) { self->fPreset = fVal; return 1; } else if(strcmp(name,"mode") == 0) { if(fVal <= 0) { self->iMode = 0; } else { self->iMode = 1; } return 1; } else if(strcmp(name,"countmode") == 0) { if(fVal < 0.05) { self->CountMode = eTimer; } else { self->CountMode = ePreset; } return 1; } else if(strcmp(name,"compact") == 0) { if(fVal >= 1.) { self->iCompact = 1; } else { self->iCompact = 0; } return 1; } else { return 0; } } /*-------------------------------------------------------------------------*/ int MesureGetPar(pMesure self, char *name, float *fVal) { if(strcmp(name,"np") == 0) { *fVal = self->np; return 1; } else if(strcmp(name,"step") == 0) { *fVal = self->fStep; return 1; } else if(strcmp(name,"mode") == 0) { *fVal = self->iMode; return 1; } else if(strcmp(name,"preset") == 0) { *fVal = self->fPreset; return 1; } else if(strcmp(name,"countmode") == 0) { if(self->CountMode == eTimer) { *fVal = 0.; } else { *fVal = 1.0; } return 1; } else if(strcmp(name,"compact") == 0) { *fVal = self->iCompact; return 1; } else { return 0; } } /*---------------------------------------------------------------------------*/ int MesureAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { int iRet, iSkip; char pBueffel[1024]; pMesure self = NULL; double d; float fVal, fHKL[3]; self = (pMesure)pData; assert(self); assert(pCon); if(argc < 2) { sprintf(pBueffel,"ERROR: Insufficient arguments to %s",argv[0]); SCWrite(pCon,pBueffel,eError); return 0; } strtolower(argv[1]); /*------ start */ if(strcmp(argv[1],"start") == 0) { if(!SCMatchRights(pCon,usUser)) { return 0; } iRet = MesureStart(self,pCon); if(iRet) { SCSendOK(pCon); } return iRet; } /*------ file */ else if(strcmp(argv[1],"file") == 0) { sprintf(pBueffel,"Currently writing to: %s",self->pCurrentFile); SCWrite(pCon,pBueffel,eValue); return 1; } /*------ nb */ else if(strcmp(argv[1],"nb") == 0) { if(!SCMatchRights(pCon,usUser)) { return 0; } iRet = SetNOR(self->pCryst,1); if(!iRet) { SCWrite(pCon, "ERROR: nu motor not configured at hkl, cannot do normal beam", eError); return 0; } SCSendOK(pCon); return 1; } /*------ bi */ else if(strcmp(argv[1],"bi") == 0) { if(!SCMatchRights(pCon,usUser)) { return 0; } iRet = SetNOR(self->pCryst,0); SCSendOK(pCon); return 1; } /*--------- close */ else if(strcmp(argv[1],"close") == 0) { if(!SCMatchRights(pCon,usUser)) { return 0; } MesureClose(self); return 1; } /*-------- reopen */ else if(strcmp(argv[1],"reopen") == 0) { if(!SCMatchRights(pCon,usUser)) { return 0; } if(argc < 3) { SCWrite(pCon,"ERROR: expected filename as parameter for reopen",eError); return 0; } iRet = MesureReopen(self,argv[2],pCon); if(iRet) { SCSendOK(pCon); } return iRet; } /*------- measure */ else if(strcmp(argv[1],"measure") == 0) { iSkip = 0; if(!SCMatchRights(pCon,usUser)) { return 0; } if(argc < 3) { SCWrite(pCon,"ERROR: expected list file name as parameter for measure ",eError); return 0; } if(argc >= 4) { iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iSkip); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected integer, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } } iRet = MesureFile(self,argv[2],iSkip,pCon); if(iRet) { SCSendOK(pCon); } return iRet; } /*------- genlist */ else if(strcmp(argv[1],"genlist") == 0) { iSkip = 0; if(!SCMatchRights(pCon,usUser)) { return 0; } if(argc < 3) { SCWrite(pCon,"ERROR: expected list file name as parameter for measure ",eError); return 0; } if(argc >= 4) { iRet = Tcl_GetInt(pSics->pTcl,argv[3],&iSkip); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected integer, got %s",argv[3]); SCWrite(pCon,pBueffel,eError); return 0; } } iRet = MesureGenFile(self,argv[2],iSkip,pCon); if(iRet) { SCSendOK(pCon); } return iRet; } /* ------ writereflection*/ else if(strcmp(argv[1],"writereflection") == 0) { GetCurrentHKL(self->pCryst,fHKL); WriteReflection(self,fHKL,pCon); SCSendOK(pCon); return 1; } /* ------ count mode */ else if(strcmp(argv[1],"countmode") == 0) { if(argc > 2) /* set case */ { /* check rights */ if(!SCMatchRights(pCon,usUser)) { SCWrite(pCon,"ERROR: You are not aurhorised to do this!",eError); return 0; } if(strcmp(argv[2],"timer") == 0) { fVal = 0.; } else if(strcmp(argv[2],"monitor") == 0) { fVal = 1.; } else { SCWrite(pCon,"ERROR: Invalid parameter for countmode",eError); return 0; } MesureSetPar(self,"countmode",fVal); SCSendOK(pCon); return 1; } else /* get case */ { MesureGetPar(self,"countmode",&fVal); if(fVal < 0.05) { sprintf(pBueffel,"%s.countmode = timer",argv[0]); } else { sprintf(pBueffel,"%s.countmode = monitor", argv[0]); } SCWrite(pCon,pBueffel,eValue); return 1; } } /*------- mode */ if(strcmp(argv[1],"mode") == 0) { if(argc > 2) /* set case */ { /* check rights */ if(!SCMatchRights(pCon,usUser)) { SCWrite(pCon,"ERROR: You are not aurhorised to do this!",eError); return 0; } if(strcmp(argv[2],"omega") == 0) { fVal = 0.; } else if(strcmp(argv[2],"omega2theta") == 0) { fVal = 1.; } else { SCWrite(pCon,"ERROR: Invalid parameter for mode",eError); return 0; } MesureSetPar(self,"mode",fVal); SCSendOK(pCon); return 1; } else /* get case */ { MesureGetPar(self,"mode",&fVal); if(fVal < 0.05) { sprintf(pBueffel,"%s.countmode = omega",argv[0]); } else { sprintf(pBueffel,"%s.countmode = omega2theta", argv[0]); } SCWrite(pCon,pBueffel,eValue); return 1; } } /*------ can be other pars */ else { if(argc > 2) /* set case */ { /* check rights */ if(!SCMatchRights(pCon,usUser)) { SCWrite(pCon,"ERROR: You are not aurhorised to do this!",eError); return 0; } iRet = Tcl_GetDouble(pSics->pTcl,argv[2],&d); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: expected numeric value for %s but got %s", argv[1],argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } fVal = (float)d; iRet = MesureSetPar(self,argv[1],fVal); if(iRet) { SCSendOK(pCon); return 1; } else { sprintf(pBueffel,"ERROR: parameter %s not known",argv[1]); SCWrite(pCon,pBueffel,eError); return 0; } } else /* get case */ { iRet = MesureGetPar(self,argv[1],&fVal); if(!iRet) { sprintf(pBueffel,"ERROR: parameter %s not known",argv[1]); SCWrite(pCon,pBueffel,eError); return 0; } sprintf(pBueffel,"%s.%s = %f",argv[0],argv[1],fVal); SCWrite(pCon,pBueffel,eValue); return 1; } } }