/*--------------------------------------------------------------------------- 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); return 0; } /*---------------------------------------------------------------------------*/ 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); 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.) { 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; commandContext comCon; /* 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; } comCon.transID = 0; strncpy(comCon.deviceID, "internal", SCDEVIDLEN); 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; }