/*--------------------------------------------------------------------------- F O W R I T E FOCUS data writing object. copyright: see copyright.h Mark Koennecke, November 1998 Added code for three detector banks. Mark Koennecke, March 2000 -----------------------------------------------------------------------------*/ #include #include #include #include /* avoid irritating compiler warning M.Z.08.2001 */ #undef VOID #include "fortify.h" #include "sics.h" #include "event.h" #include "counter.h" #include "HistMem.h" #include "nxdict.h" #include "nxutil.h" #include "motor.h" #include "selector.h" #include "fowrite.h" #include "scan.h" #include "sicsvar.h" #include "fitcenter.h" #include "hmcontrol.h" #include "fomerge.h" /* histogram memory names */ #define HM1 "hm1" #define HM2 "hm2" #define HM3 "hm3" /* the name of the SICS chopper controller object */ #define CHOPPERNAME "choco" /*--------- the internal data structure ------------------------------------*/ typedef struct { pObjectDescriptor pDes; pHistMem pHistogram1, pHistogram2, pHistogram3; int iNew; time_t tUpdate; int iInterval; int iEnd; SConnection *pCon; pCounter pCount; char *pFile; char *pDictFile; pFit pFitter; float fElastic; pICallBack pCall; int iUpper, iMiddle, iLower; /* detector availability flags */ } FoWrite, *pFoWrite; /* ------------------- forward declaration of task function --------------*/ static int FoTask(void *pData); static void FoUpdate(pFoWrite self, SConnection *pCon); /*------------------ The Countstart Callback Function ----------------------*/ static int Countstartcallback(int iEvent, void *pEventData, void *pUser) { pFoWrite self = NULL; if(iEvent == COUNTSTART) { self = (pFoWrite)pUser; assert(self); self->iNew = 1; self->iEnd = 0; self->tUpdate = time(NULL); self->pCon = (SConnection *)pEventData; TaskRegister(pServ->pTasker,FoTask,NULL,NULL,self,1); return 1; } return 1; } /*------------------ The Countend Callback Function ----------------------*/ static int Countendcallback(int iEvent, void *pEventData, void *pUser) { pFoWrite self = NULL; if(iEvent == COUNTEND) { self = (pFoWrite)pUser; assert(self); self->tUpdate = time(NULL); self->iEnd = 1; /* FoUpdate(self,self->pCon); */ return 1; } return 1; } /*-----------------------------------------------------------------------*/ static void SNError(void *pData, char *text) { SConnection *pCon; assert(pData); pCon = (SConnection *)pData; SCWrite(pCon,text,eError); } /*------------------------------------------------------------------------*/ static void WriteSelector(NXhandle pFile, NXdict pDict, SConnection *pCon) { pSicsSelector pSel = NULL; char *pName = NULL; CommandList *pCom = NULL; pDummy pDum = NULL; float fTh, fTTH, fB1, fB2; int iRet; pCom = FindCommand(pServ->pSics,"mono"); if(!pCom) { SCWrite(pCon,"ERROR: no monochromator found",eError); return ; } pSel = (pSicsSelector)pCom->pData; if(!pSel) { SCWrite(pCon,"ERROR: no monochromator found",eError); return ; } pDum = (pDummy)pSel; if(strcmp(pDum->pDescriptor->name,"CrystalSelector") != 0) { SCWrite(pCon,"ERROR: monochromator is invalid",eError); return ; } NXDputalias(pFile,pDict,"mname",MonoGetType(pSel)); iRet = GetMonoPositions(pSel,pCon,&fTh, &fTTH, &fB1, &fB2); if(!iRet) { SCWrite(pCon,"ERROR: Problem reading monochromator positions",eError); SCWrite(pCon,"ERROR: monochromator data missing in file",eError); return; } NXDputalias(pFile,pDict,"mtheta",&fTh); NXDputalias(pFile,pDict,"mttheta",&fTTH); SNXSPutDrivable(pServ->pSics,pCon, pFile,pDict,"lambda","mlambda"); SNXSPutDrivable(pServ->pSics,pCon, pFile,pDict,"qi","menergy"); } /*----------------------------------------------------------------------*/ static float CalculateElastic(pFoWrite self, SConnection *pCon) { pIDrivable pDriv; pSicsVariable pVar; CommandList *pCom = NULL; float fLambda, fDist, fResult; pCom = FindCommand(pServ->pSics,"lambda"); if(!pCom) return 0.; pDriv = GetDrivableInterface(pCom->pData); if(!pDriv) return 0.; fLambda = pDriv->GetValue(pCom->pData,pCon); pVar = FindVariable(pServ->pSics,"sampledist"); if(!pVar) return 0.; fDist = pVar->fVal; pVar = FindVariable(pServ->pSics,"detectordist"); if(!pVar) return 0.; fDist += pVar->fVal; fResult = 252.78*fLambda*(fDist/1000.); return fResult; } /*------------------------------------------------------------------------- FoStart writes all the fixed data items, creates a new file etc. A complete file is obtained after FoStart plus a call to FoUpdate */ static int FoStart(pFoWrite self, SConnection *pCon) { NXhandle pFile = NULL; NXdict pDict = NULL; pSicsVariable var1 = NULL; pSicsVariable var2 = NULL; int lbank, mbank; int iStat, iLength, i; char pBueffel[512]; CounterMode eMode; float fVal, *fArray; const float *fTime; float *fTime2 = NULL; char pBuffer[50]; /* get a filename */ if(self->pFile) free(self->pFile); self->pFile = SNXMakeFileName(pServ->pSics,pCon); if(!self->pFile) { SCWrite(pCon,"ERROR: Extra severe: failed to create data file name", eError); return 0; } /* create a Nexus file */ NXopen(self->pFile,NXACC_CREATE,&pFile); if(!pFile) { SCWrite(pCon,"ERROR: cannot create data file ",eError); return 0; } /* tell Uwe User what we are doing */ sprintf(pBueffel,"Writing %s ......",self->pFile); SCWrite(pCon,pBueffel,eWarning); /* write globals */ SNXSPutGlobals(pFile,self->pFile,"FOCUS",pCon); /* open nxdict and configure nxdict parameters */ iStat = NXDinitfromfile(self->pDictFile,&pDict); if(iStat != NX_OK) { sprintf(pBueffel,"ERROR: failed to open dictionary file %s", self->pDictFile); SCWrite(pCon,pBueffel,eError); SCWrite(pCon,"ERROR: Aborting data file writing",eError); SCWrite(pCon,"ERROR: This is a SERIOUS problem!",eError); SCWrite(pCon,"ERROR: DATA NOT WRITTEN",eError); NXclose(&pFile); return 0; } /* put permanent data */ SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"etitle","title"); SNXFormatTime(pBueffel,511); /* entry & instrument stuff */ NXDputalias(pFile,pDict,"estart",pBueffel); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"iname","instrument"); NXDputalias(pFile,pDict,"sname","SINQ, PSI, Switzerland"); NXDputalias(pFile,pDict,"stype","continous spallation source"); /* disk chopper */ NXDputalias(pFile,pDict,"cname","Dornier disk chopper"); /* be-filter */ NXDputalias(pFile,pDict,"bname","BE-filter"); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"bstatus","bestatus"); /* flight path */ SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fltype","flightpath"); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fllength","flightpathlength"); /* monochromator */ WriteSelector(pFile,pDict,pCon); /* fermi chupper */ SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fcname","ferminame"); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"fcdist","fermidist"); /* counting data */ var2 = FindVariable(pServ->pSics,"mbank"); if(var2) { VarGetInt(var2,&mbank); } else { SCWrite(pCon,"ERROR: mbank value not found!",eError); } if(var2) { eMode = GetHistCountMode(self->pHistogram2); fTime = GetHistTimeBin(self->pHistogram2,&iLength); fVal = GetHistPreset(self->pHistogram2); } else { var1 = FindVariable(pServ->pSics,"lbank"); if(var1) { VarGetInt(var1,&lbank); } else { SCWrite(pCon,"ERROR: lbank value not found!",eError); } if(var1) { eMode = GetHistCountMode(self->pHistogram1); fTime = GetHistTimeBin(self->pHistogram1,&iLength); fVal = GetHistPreset(self->pHistogram1); } else { eMode = GetHistCountMode(self->pHistogram3); fTime = GetHistTimeBin(self->pHistogram3,&iLength); fVal = GetHistPreset(self->pHistogram3); } } if(eMode == eTimer) { strcpy(pBueffel,"timer"); } else { strcpy(pBueffel,"monitor"); } NXDputalias(pFile,pDict,"cnmode",pBueffel); NXDputalias(pFile,pDict,"cnpreset",&fVal); /* detector banks */ fTime2 = (float *)malloc(iLength*sizeof(float)); if(fTime2) { for(i = 0; i < iLength; i++) { fTime2[i] = fTime[i]/10.; } sprintf(pBueffel,"%d",iLength); NXDupdate(pDict,"timebin",pBueffel); if(self->iMiddle) { NXDupdate(pDict,"bank","bank1"); NXDputalias(pFile,pDict,"dtime",fTime2); } if(self->iUpper) { NXDupdate(pDict,"bank","upperbank"); NXDputalias(pFile,pDict,"dtime",fTime2); } if(self->iLower) { NXDupdate(pDict,"bank","lowerbank"); NXDputalias(pFile,pDict,"dtime",fTime2); } if( (self->iLower || self->iUpper) && self->iMiddle) { NXDupdate(pDict,"bank","merged"); NXDputalias(pFile,pDict,"dtime",fTime2); } NXDupdate(pDict,"bank","bank1"); /* calculate theoretical position of elastic peak */ fVal = CalculateElastic(self,pCon); self->fElastic = (fVal - fTime2[0]) / (fTime2[1] - fTime2[0]); free(fTime2); fTime2 = NULL; } else { SCWrite(pCon,"ERROR: out of memory while writing time binning", eError); } SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"ddist","detectordist"); /* theta arrays */ if(self->iMiddle) { NXDupdate(pDict,"bank","bank1"); iLength = 150; sprintf(pBuffer,"%d",iLength); NXDupdate(pDict,"noofdetectors",pBuffer); fArray = getFMBankTheta(MIDDLE); NXDputalias(pFile,pDict,"dtheta",fArray); } if(self->iLower) { NXDupdate(pDict,"bank","lowerbank"); iLength = 115; sprintf(pBuffer,"%d",iLength); NXDupdate(pDict,"noofdetectors",pBuffer); fArray = getFMBankTheta(LOWER); NXDputalias(pFile,pDict,"dtheta",fArray); } if(self->iUpper) { NXDupdate(pDict,"bank","upperbank"); iLength = 110; sprintf(pBuffer,"%d",iLength); NXDupdate(pDict,"noofdetectors",pBuffer); fArray = getFMBankTheta(UPPER); NXDputalias(pFile,pDict,"dtheta",fArray); } if(self->iMiddle && ( self->iLower || self->iUpper) ) { NXDupdate(pDict,"bank","merged"); iLength = 375; sprintf(pBuffer,"%d",iLength); NXDupdate(pDict,"noofdetectors",pBuffer); fArray = getFMBankTheta(MERGED); NXDputalias(pFile,pDict,"dtheta",fArray); } NXDupdate(pDict,"bank","bank1"); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"ddelay","delay"); /* sample info */ SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"saname","sample"); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"senvir","environment"); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"sdist","sampledist"); SNXSPutVariable(pServ->pSics,pCon,pFile,pDict,"saangle","sampleangle"); /* close everything */ NXclose(&pFile); NXDclose(pDict,NULL); } /*---------------------------------------------------------------------------*/ static void FoUpdate(pFoWrite self, SConnection *pCon) { char pBueffel[512]; int iInt, iStat, iTime, i,ii, j, iDet, iIndex; pSicsVariable var1 = NULL; pSicsVariable var2 = NULL; pSicsVariable var3 = NULL; int lbank, mbank, ubank; long lVal; float fVal; const float *fTime; NXhandle pFile = NULL; NXdict pDict; HistInt *lData = NULL; HistInt *mData = NULL; HistInt *uData = NULL; int *iSum = NULL; float *fAxis = NULL; long *lSum = NULL; float fCenter, fStdDev, fFWHM; /* open everything again */ NXopen(self->pFile,NXACC_RDWR,&pFile); if(!pFile) { SCWrite(pCon,"ERROR: cannot reopen data file ",eError); return; } iStat = NXDinitfromfile(self->pDictFile,&pDict); if(iStat != NX_OK) { sprintf(pBueffel,"ERROR: failed to open dictionary file %s", self->pDictFile); SCWrite(pCon,pBueffel,eError); SCWrite(pCon,"ERROR: Aborting data file writing",eError); SCWrite(pCon,"ERROR: This is a SERIOUS problem!",eError); SCWrite(pCon,"ERROR: DATA NOT WRITTEN",eError); NXclose(&pFile); return; } /* tell the user that something is happening */ sprintf(pBueffel,"Updating %s",self->pFile); SCWrite(pCon,pBueffel,eWarning); /* do the end time */ SNXFormatTime(pBueffel,511); NXDputalias(pFile,pDict,"eend",pBueffel); /* chopper speeds */ SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"diskspeed","crot"); SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"fermispeed","fcrot"); SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"phase","fcphase"); SNXSPutDrivable(pServ->pSics,pCon,pFile,pDict,"ratio","cratio"); /* counter data */ var2 = FindVariable(pServ->pSics,"mbank"); if(var2) { VarGetInt(var2,&mbank); } else { SCWrite(pCon,"ERROR: mbank value not found!",eError); } if(var2) { fVal = GetHistCountTime(self->pHistogram2,pCon); NXDputalias(pFile,pDict,"cntime",&fVal); lVal = GetHistMonitor(self->pHistogram2,1,pCon); NXDputalias(pFile,pDict,"cnmon1",&lVal); lVal = GetHistMonitor(self->pHistogram2,0,pCon); NXDputalias(pFile,pDict,"cnmon2",&lVal); lVal = GetHistMonitor(self->pHistogram2,4,pCon); NXDputalias(pFile,pDict,"cnmon3",&lVal); fTime = GetHistTimeBin(self->pHistogram2,&iInt); } else { var1 = FindVariable(pServ->pSics,"lbank"); if(var1) { VarGetInt(var1,&lbank); } else { SCWrite(pCon,"ERROR: lbank value not found!",eError); } if(var1) { fVal = GetHistCountTime(self->pHistogram1,pCon); NXDputalias(pFile,pDict,"cntime",&fVal); lVal = GetHistMonitor(self->pHistogram1,1,pCon); NXDputalias(pFile,pDict,"cnmon1",&lVal); lVal = GetHistMonitor(self->pHistogram1,0,pCon); NXDputalias(pFile,pDict,"cnmon2",&lVal); lVal = GetHistMonitor(self->pHistogram1,4,pCon); NXDputalias(pFile,pDict,"cnmon3",&lVal); fTime = GetHistTimeBin(self->pHistogram1,&iInt); } else { fVal = GetHistCountTime(self->pHistogram3,pCon); NXDputalias(pFile,pDict,"cntime",&fVal); lVal = GetHistMonitor(self->pHistogram3,1,pCon); NXDputalias(pFile,pDict,"cnmon1",&lVal); lVal = GetHistMonitor(self->pHistogram3,0,pCon); NXDputalias(pFile,pDict,"cnmon2",&lVal); lVal = GetHistMonitor(self->pHistogram3,4,pCon); NXDputalias(pFile,pDict,"cnmon3",&lVal); fTime = GetHistTimeBin(self->pHistogram3,&iInt); } } /* histogram with three detector banks */ iTime = iInt; sprintf(pBueffel,"%d",iInt); NXDupdate(pDict,"timebin",pBueffel); var1 = FindVariable(pServ->pSics,"lbank"); if(var1) { VarGetInt(var1,&lbank); } else { SCWrite(pCon,"ERROR: lbank value not found!",eError); } if (lbank == 1) { lData = GetHistogramPointer(self->pHistogram1,pCon); if(!lData) { SCWrite(pCon,"ERROR: failed to find Histogram Memory Data (lower bank)",eError); NXclose(&pFile); NXDclose(pDict,NULL); return; } } if (mbank == 1) { mData = GetHistogramPointer(self->pHistogram2,pCon); if(!mData) { SCWrite(pCon,"ERROR: failed to find Histogram Memory Data (middle bank)",eError); NXclose(&pFile); NXDclose(pDict,NULL); return; } } var3 = FindVariable(pServ->pSics,"ubank"); if(var3) { VarGetInt(var3,&ubank); } else { SCWrite(pCon,"ERROR: ubank value not found!",eError); } if (ubank == 1) { uData = GetHistogramPointer(self->pHistogram3,pCon); if(!uData) { SCWrite(pCon,"ERROR: failed to find Histogram Memory Data (upper bank)",eError); NXclose(&pFile); NXDclose(pDict,NULL); return; } } setFMDataPointer(lData,iTime,LOWER); setFMDataPointer(mData,iTime,MIDDLE); setFMDataPointer(uData,iTime,UPPER); /* middle bank */ if(self->iMiddle) { NXDupdate(pDict,"bank","bank1"); iDet = 150; sprintf(pBueffel,"%d",iDet); NXDupdate(pDict,"noofdetectors",pBueffel); mData = getFMBankPointer(MIDDLE); NXDputalias(pFile,pDict,"dcounts",mData); /* summed counts for each detector */ iSum = (int *)malloc(iDet*sizeof(int)); if(iSum) { memset(iSum,0,iDet*sizeof(int)); for(i = 0; i < iDet; i++) { iIndex = i * iTime; for(j = 0; j < iTime; j++) { iSum[i] += mData[iIndex+j]; } } NXDputalias(pFile,pDict,"dsums",iSum); free(iSum); } else { SCWrite(pCon,"WARNING: out of memory, failed to do sums", eWarning); } } if(self->iUpper) { NXDupdate(pDict,"bank","upperbank"); iDet = 110; sprintf(pBueffel,"%d",iDet); NXDupdate(pDict,"noofdetectors",pBueffel); uData = getFMBankPointer(UPPER); NXDputalias(pFile,pDict,"dcounts",uData); /* summed counts for each detector */ iSum = (int *)malloc(iDet*sizeof(int)); if(iSum) { memset(iSum,0,iDet*sizeof(int)); for(i = 0; i < iDet; i++) { iIndex = i * iTime; for(j = 0; j < iTime; j++) { iSum[i] += uData[iIndex+j]; } } NXDputalias(pFile,pDict,"dsums",iSum); free(iSum); } else { SCWrite(pCon,"WARNING: out of memory, failed to do sums", eWarning); } } if(self->iLower) { NXDupdate(pDict,"bank","lowerbank"); iDet = 115; sprintf(pBueffel,"%d",iDet); NXDupdate(pDict,"noofdetectors",pBueffel); lData = getFMBankPointer(LOWER); NXDputalias(pFile,pDict,"dcounts",lData); /* summed counts for each detector */ iSum = (int *)malloc(iDet*sizeof(int)); if(iSum) { memset(iSum,0,iDet*sizeof(int)); for(i = 0; i < iDet; i++) { iIndex = i * iTime; for(j = 0; j < iTime; j++) { iSum[i] += lData[iIndex+j]; } } NXDputalias(pFile,pDict,"dsums",iSum); free(iSum); } else { SCWrite(pCon,"WARNING: out of memory, failed to do sums", eWarning); } /* now get and write tof_monitor */ lData = (HistInt *)malloc(iTime*sizeof(HistInt)); if(!lData) { SCWrite(pCon,"ERROR: out of memory while writing tof-monitor", eError); } else { memset(lData,0,iTime*sizeof(HistInt)); GetHistogramDirect(self->pHistogram1,pCon,0,115*iTime, 116*iTime, lData, iTime*sizeof(HistInt)); NXDputalias(pFile,pDict,"tofmon",lData); } } /* merged data */ if( (self->iUpper || self->iLower) && self->iMiddle) { NXDupdate(pDict,"bank","merged"); iDet = 375; sprintf(pBueffel,"%d",iDet); NXDupdate(pDict,"noofdetectors",pBueffel); lData = getFMBankPointer(MERGED); NXDputalias(pFile,pDict,"dcounts",lData); /* summed counts for each detector */ iSum = (int *)malloc(iDet*sizeof(int)); if(iSum) { memset(iSum,0,iDet*sizeof(int)); for(i = 0; i < iDet; i++) { iIndex = i * iTime; for(j = 0; j < iTime; j++) { iSum[i] += lData[iIndex+j]; } } NXDputalias(pFile,pDict,"dsums",iSum); free(iSum); } else { SCWrite(pCon,"WARNING: out of memory, failed to do sums", eWarning); } } /* calculate elastic peak position */ NXDupdate(pDict,"bank","bank1"); mData = getFMBankPointer(MIDDLE); iDet = getFMdim(MIDDLE); if(mData) { lSum = (long *)malloc(iTime *sizeof(long)); fAxis = (float *)malloc(iTime *sizeof(float)); if( lSum && fAxis) { memset(lSum,0,iTime*sizeof(long)); memset(fAxis,0,iTime*sizeof(float)); for(i = 5; i < iDet - 5; i++) { iIndex = i * iTime; for(j = 0; j < iTime; j++) { lSum[j] += mData[iIndex+j]; } } for(i = 0; i < iTime; i++) { fAxis[i] = (float)i; } iStat = CalculateFitFromData(self->pFitter,fAxis,lSum,iTime); if(iStat != 1) { SCWrite(pCon,"WARNING: problem locating elastic peak",eWarning); } GetFitResults(self->pFitter,&fCenter,&fStdDev,&fFWHM,&fVal); fVal = fCenter - self->fElastic; if(fVal < 0.) fVal = - fVal; /* bad value, leave at theoretical value */ if(fVal > 10.) { SCWrite(pCon, "WARNING: bad fit result, using theoretical elastic peak position", eWarning); } else { self->fElastic = fCenter; } free(lSum); free(fAxis); } else { SCWrite(pCon,"WARNING: out of memory, failed to do sums",eWarning); } } sprintf(pBueffel,"Elastic peak found at detector: %f",self->fElastic); SCWrite(pCon,pBueffel,eWarning); NXDputalias(pFile,pDict,"delastic",&self->fElastic); /* sample temperature */ SNXSPutEVVar(pFile,pDict,"temperature",pCon,"stemp",NULL); /* close everything */ NXclose(&pFile); NXDclose(pDict,NULL); } /*------------------------------------------------------------------------- FoLink sets all the links for the NXdata vGroup. Had to be separate because at least one update is necessary before this can be done. */ static void FoLink(pFoWrite self, SConnection *pCon) { NXhandle pFile; NXdict pDict; int iStat; char pBueffel[512]; /* open everything again */ NXopen(self->pFile,NXACC_RDWR,&pFile); if(!pFile) { SCWrite(pCon,"ERROR: cannot reopen data file ",eError); return; } iStat = NXDinitfromfile(self->pDictFile,&pDict); if(iStat != NX_OK) { sprintf(pBueffel,"ERROR: failed to open dictionary file %s", self->pDictFile); SCWrite(pCon,pBueffel,eError); SCWrite(pCon,"ERROR: Aborting data file writing",eError); SCWrite(pCon,"ERROR: This is a SERIOUS problem!",eError); SCWrite(pCon,"ERROR: DATA NOT WRITTEN",eError); NXclose(&pFile); return; } if( (self->iUpper || self->iLower) && self->iMiddle) { NXDupdate(pDict,"bank","merged"); NXDaliaslink(pFile,pDict,"dana","dcounts"); NXDaliaslink(pFile,pDict,"dana","dtime"); NXDaliaslink(pFile,pDict,"dana","dtheta"); NXDaliaslink(pFile,pDict,"dana","cnmon1"); } if(self->iUpper) { NXDupdate(pDict,"bank","upperbank"); NXDaliaslink(pFile,pDict,"dana","dcounts"); NXDaliaslink(pFile,pDict,"dana","dtime"); NXDaliaslink(pFile,pDict,"dana","dtheta"); NXDaliaslink(pFile,pDict,"dana","cnmon1"); } if(self->iMiddle) { NXDupdate(pDict,"bank","bank1"); NXDaliaslink(pFile,pDict,"dana","dcounts"); NXDaliaslink(pFile,pDict,"dana","dtime"); NXDaliaslink(pFile,pDict,"dana","dtheta"); NXDaliaslink(pFile,pDict,"dana","cnmon1"); } if(self->iLower) { NXDupdate(pDict,"bank","lowerbank"); NXDaliaslink(pFile,pDict,"dana","dcounts"); NXDaliaslink(pFile,pDict,"dana","dtime"); NXDaliaslink(pFile,pDict,"dana","dtheta"); NXDaliaslink(pFile,pDict,"dana","cnmon1"); } /* close everything */ NXclose(&pFile); NXDclose(pDict,NULL); self->iNew = 0; } /*--------------------------------------------------------------------------- This is the task function for updating the data file any now and then automatically */ static int FoTask(void *pData) { pFoWrite self = NULL; int iWrite, iRet; self = (pFoWrite)pData; if(!self) return 0; /* figure out if we need to write */ iWrite = 0; iRet = 1; /* first case: update intervall */ if(time(NULL) >= self->tUpdate) { self->tUpdate = time(NULL) + self->iInterval; iWrite = 1; iRet = 1; } if(self->iEnd) { self->tUpdate = 0; iWrite = 0; iRet = 0; FoUpdate(self,self->pCon); } if(iWrite) { if(self->iNew) { FoStart(self,self->pCon); FoUpdate(self,self->pCon); FoLink(self,self->pCon); } else { FoUpdate(self,self->pCon); } } return iRet; } /*------------------------------------------------------------------------*/ static void KillFoWrite(void *pData) { pFoWrite self = NULL; self = (pFoWrite)pData; if(!self) return; if(self->pDes) DeleteDescriptor(self->pDes); if(self->pDictFile) free(self->pDictFile); if(self->pFile) free(self->pFile); if(self->pFitter) DeleteFitCenter(self->pFitter); /* free fomerge */ killFM(); free(self); } /*-----------------------------------------------------------------------*/ int FoInstall(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { CommandList *pCom = NULL; char pBueffel[512]; pFoWrite pNew = NULL; pICallBack pCall = NULL; pDummy pDum; pHMcontrol pHMC = NULL; /* check arguments */ if(argc < 4 ) { SCWrite(pCon,"ERROR: Insufficient number of arguments to FoInstall", eError); return 0; } /* allocate data structure */ pNew = (pFoWrite)malloc(sizeof(FoWrite)); if(!pNew) { SCWrite(pCon,"ERROR: out of memory in FoInstall",eError); return 0; } memset(pNew,0,sizeof(FoWrite)); pNew->pDes = CreateDescriptor("FocusWrite"); pNew->pCall = CreateCallBackInterface(); pNew->pFitter = CreateFitCenter(NULL); if( (!pNew->pDes) || (!pNew->pFitter) ) { SCWrite(pCon,"ERROR: out of memory in FoInstall",eError); free(pNew); return 0; } pNew->pDictFile = strdup(argv[2]); pNew->iInterval = 20*60; pHMC = FindCommandData(pSics,argv[1],"HMcontrol"); if(!pHMC){ SCWrite(pCon,"ERROR: no histogram memory control found!",eError); free(pNew); return 0; } /* find things in interpreter */ pCom = FindCommand(pSics,"hm1"); if(!pCom) { SCWrite(pCon,"ERROR: Histogram memory for lower detector bank NOT found",eError); pNew->pHistogram1 = NULL; } else { pNew->pHistogram1 = (pHistMem)pCom->pData; pNew->iLower =1; } pCom = FindCommand(pSics,HM2); if(pCom) { pNew->pHistogram2 = (pHistMem)pCom->pData; pNew->iMiddle =1; } else { SCWrite(pCon,"ERROR: Histogram memory for middle detector bank NOT found",eError); pNew->pHistogram2 = NULL; } pCom = FindCommand(pSics,HM3); if(pCom) { pNew->pHistogram3 = (pHistMem)pCom->pData; pNew->iUpper =1; } else { SCWrite(pCon,"ERROR: Histogram memory for upper detector bank NOT found",eError); pNew->pHistogram3 = NULL; } if(!initializeFM(argv[3])) { SCWrite(pCon,"ERROR: bad merge data file",eError); return 0; } pCom = FindCommand(pSics,"counter"); if(pCom) { pNew->pCount = (pCounter)pCom->pData; } RegisterCallback(pHMC->pCall,COUNTSTART,Countstartcallback,pNew,NULL); RegisterCallback(pHMC->pCall,COUNTEND,Countendcallback,pNew,NULL); /* install command */ AddCommand(pSics,"StoreFocus",FoAction,KillFoWrite,pNew); return 1; } /*-------------------------------------------------------------------------*/ int FoAction(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { int iRet, iVal; pFoWrite self = NULL; char pBueffel[512]; if(argc < 1) { SCWrite(pCon,"ERROR: Insufficient number of arguments to StoreFocus", eError); return 0; } self = (pFoWrite)pData; assert(self); strtolower(argv[1]); if(strcmp(argv[1],"start") == 0) { FoStart(self,pCon); FoUpdate(self,pCon); FoLink(self,pCon); return 1; } else if(strcmp(argv[1],"update") == 0) { if((self->iNew) || (!self->pFile)) { FoStart(self,pCon); FoUpdate(self,pCon); FoLink(self,pCon); } else { FoUpdate(self,pCon); } return 1; } else if(strcmp(argv[1],"getfile") == 0) { sprintf(pBueffel,"storefocus.file = %s",self->pFile); SCWrite(pCon,pBueffel,eValue); return 1; } else if(strcmp(argv[1],"interval") == 0) { if(argc > 2) /* set value */ { if(!SCMatchRights(pCon,usUser)) { return 0; } iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ",argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } self->iInterval = iVal*60; /* go to seconds from minutes*/ SCSendOK(pCon); return 1; } else /* read the value */ { sprintf(pBueffel,"storefocus.interval = %d",self->iInterval/60); SCWrite(pCon,pBueffel,eValue); return 1; } } else if(strcmp(argv[1],"middle") == 0) { if(argc > 2) /* set value */ { if(!SCMatchRights(pCon,usMugger)) { return 0; } iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ", argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } if(iVal < 0) iVal = 0; self->iMiddle = iVal; setFMconfiguration(self->iUpper,self->iMiddle,self->iLower); SCSendOK(pCon); return 1; } else /* read the value */ { sprintf(pBueffel,"storefocus.middle = %d",self->iMiddle); SCWrite(pCon,pBueffel,eValue); return 1; } } else if(strcmp(argv[1],"lower") == 0) { if(argc > 2) /* set value */ { if(!SCMatchRights(pCon,usMugger)) { return 0; } iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ", argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } if(iVal < 0) iVal = 0; self->iLower = iVal; setFMconfiguration(self->iUpper,self->iMiddle,self->iLower); SCSendOK(pCon); return 1; } else /* read the value */ { sprintf(pBueffel,"storefocus.lower = %d",self->iLower); SCWrite(pCon,pBueffel,eValue); return 1; } } else if(strcmp(argv[1],"upper") == 0) { if(argc > 2) /* set value */ { if(!SCMatchRights(pCon,usMugger)) { return 0; } iRet = Tcl_GetInt(pSics->pTcl,argv[2],&iVal); if(iRet != TCL_OK) { sprintf(pBueffel,"ERROR: cannot convert --> %s <-- to number ", argv[2]); SCWrite(pCon,pBueffel,eError); return 0; } if(iVal < 0) iVal = 0; self->iUpper = iVal; setFMconfiguration(self->iUpper,self->iMiddle,self->iLower); SCSendOK(pCon); return 1; } else /* read the value */ { sprintf(pBueffel,"storefocus.upper = %d",self->iUpper); SCWrite(pCon,pBueffel,eValue); return 1; } } SCWrite(pCon,"ERROR: subcommand to storefocus not recognized",eError); return 0; }