diff --git a/doc/manager/mcstas.htm b/doc/manager/mcstas.htm index bb4acd7f..fcc4269f 100644 --- a/doc/manager/mcstas.htm +++ b/doc/manager/mcstas.htm @@ -47,21 +47,24 @@ in a certain way: Alternatively SICS can write the data to be passed to McStas into a file. But then this file must be read in the INITIALIZE section of the instrument definition and values must be assigned to the appropriate McStas variables. -
  • McStas must dump its data into a single file: use the -f filename option. - The format must be --format=XML. -
  • In order to count on monitor, a modified PSD_monitor component MUST be used in the +
  • In order for the NeXus-XML based reading to work McStas must dump its data into a single file: + use the -f filename option. The format must be --format=XML. +
  • In order to count on monitor, a modified monitor component, MKMonitor MUST be used in the simulation. This component writes the collected total counts into a file. This file is - the read by SICS in order to determine the control monitor. Evaluating the McStas XML dump \ + the read by SICS in order to determine the control monitor. Evaluating the McStas dump \ file each time proved to be to inaccurate. The name of the file containing the monitor must be configured through: mccontrol configure mcmonfile name-of-file.
  • The mcstas simulation executable must be declared with allowexec in order to be able to start with the Tcl exec command. +
  • Though McStas can be made to dump its data by sending it a USR2 signal, it is + much cleaner and simpler to have McStas dump its data regularly through the use of the + Progress_bar component.

    The McStas Reader

    -In order to enable trasnfer from McStas result files into SICS objects a reader object is -needed. This module supports only XML formatted McStas files, with the output dumped into +In order to enable transfer from McStas result files into SICS objects a reader object is +needed. This module supports XML formatted McStas files, with the output dumped into one file. The McStas options to achieve this are: -f filename --format="XML" This module supports the following commands:

    @@ -69,7 +72,7 @@ This module supports the following commands:
    Opens a McStas simulation file for reading.
    mcreader close
    Closes a McStas file after use. -
    mcreader insertmon path object monitornumber +
    mcreader insertmon path object monitornumber scale
    This transfers a monitor value from a previously opened McStas file into a SICS monitor field. The McStas field read is the values tag belonging to the component. The parameters: @@ -83,12 +86,28 @@ groups, the name attribute is used a path component. this McStas interface only counters can store monitors.
    monitornumber
    Monitornumber is the monitor channel into which the value is to be stored. +
    scale +
    Scale is an optional scale factor for the monitor. Real monitors have a + sensitivity of E-6, McStas monitors have an efficiency of 1.0. This factor allows to + correct for this.
    -
    mcreader inserthm path hmobject +
    mcreader inserthm path hmobject scale
    Inserts array data stored under path in the histogram memory array of hmobject which must be a valid SICS histogram memory object. The path is the same as given for insertmon, - but of course the data part of the detector must be addressed. + but of course the data part of the detector must be addressed. Scale is again an optional + scale factor which allows to scale the McStas counts to real counts. +The mccreader module also supports reading data from any ASCII file into SICS. Mcreader +close and open are not required then. For reading histogram memory data, the appropriate + data has to be parsed into a SICSdata object first. Then + data can be trasnferred using the following commands: +
    +
    mcreader insertmondirect counter num value +
    Assigns value to the monitor num at the counter object counter. Monitor 0 is the + actual counts data. +
    +
    mcreader inserthmfromdata hm data +
    Inserts the data in the SICSData object data into the histogram memory hm.

    The McStas Controller

    @@ -123,6 +142,11 @@ line and finally starts the simulation. This script is expected to return either

    This configures the minimum time between McStas dumps in seconds. The idea is that SICS buffers values during a simulation run and does not interrupt the McStas process to often. +
    mccontrol configure update monitorscale +
    Configures the scaling factor to use on the monitor in monfile. Normal monitors have + a efficeincy of 1E-6, the McStas monitor counts every neutron. This can be compensated + for by this scaling factor. Note that this scaling factor may be dependent on the + wavelength used.
    mccontrol configure mcmonfile filename
    This configures the file which mccontrol is going to read in order to watch the simulation control monitor. @@ -131,6 +155,10 @@ line and finally starts the simulation. This script is expected to return either
    mccontrol run scriptkey
    Invokes one of the scripts configure for testing purposes. scripkey can be one of: mcstart, mcisrunning, mcdump, mckill and mccopydata. +
    mccontrol finish +
    This calls waitpid on the PID of the McStas process. This should be done in + the mckill script. Otherwise it may occur that the McStas simulation turns into + a Zombie process. Standard scripts for many of the script routines required are provided for the unix environment in the file mcsupport.tcl. Please note, that all system executables called diff --git a/histmem.c b/histmem.c index 331af5c4..2f59e4ac 100644 --- a/histmem.c +++ b/histmem.c @@ -295,6 +295,7 @@ if(!self->iInit) { SCWrite(pCon,"ERROR: histogram memory not initialised",eError); + InvokeCallBack(self->pCall,COUNTEND,NULL); return COTERM; } @@ -309,6 +310,7 @@ { SCWrite(pCon,"ERROR: failed to fix histogram memory problem",eError); SCSetInterrupt(pCon,eAbortBatch); + InvokeCallBack(self->pCall,COUNTEND,NULL); return eCt; } else @@ -325,7 +327,8 @@ /* force an update of local histogram data with next GetHistogram */ - updateHMData(self->pDriv->data); + updateHMData(self->pDriv->data); + InvokeCallBack(self->pCall,COUNTEND,NULL); } return eCt; @@ -760,8 +763,6 @@ void HistDirty(pHistMem self) iRet = 1; } - /* whatever happened, send a COUNTEND event */ - InvokeCallBack(self->pCall,COUNTEND,NULL); return iRet; diff --git a/hmdata.c b/hmdata.c index a57c373b..4d847951 100644 --- a/hmdata.c +++ b/hmdata.c @@ -150,9 +150,8 @@ int genTimeBinning(pHMdata self, float start, float step, int noSteps){ } /*----------------------------------------------------------------------*/ int setTimeBin(pHMdata self, int index, float value){ - if(index > 0 || index < MAXCHAN){ + if(index >= 0 && index < MAXCHAN){ self->timeBinning[index] = value; - return 1; } else { return 0; } diff --git a/mccontrol.c b/mccontrol.c index da079f73..e30121fa 100644 --- a/mccontrol.c +++ b/mccontrol.c @@ -1,11 +1,13 @@ /*---------------------------------------------------------------------------- - McStas simulation to SICS controller module mplementation file. For more details - see mcstas.tex. + McStas simulation to SICS controller module implementation file. For more + details see mcstas.tex. copyright: see file COPYRIGHT Mark Koennecke, June 2005 -----------------------------------------------------------------------------*/ +#include +#include #include #include #include @@ -54,6 +56,7 @@ int McStasControllerFactory(SConnection *pCon, SicsInterp *pSics, StringDictAddPair(pNew->scripts,"mccopydata","UNDEFINED"); StringDictAddPair(pNew->scripts,"mcmonfile","UNDEFINED"); pNew->pid = -1; + pNew->monitorScale = 1; return AddCommand(pSics,"mccontrol", McStasControllerWrapper, @@ -77,6 +80,16 @@ static int configureController(pMcStasController self, SConnection *pCon, SCSendOK(pCon); return 1; } + if(strcmp(argv[2],"monitorscale") == 0){ + self->monitorScale = atof(argv[3]); + if(self->monitorScale <= 0){ + SCWrite(pCon,"ERROR: invalid monitor scale",eError); + self->monitorScale = 1; + return 0; + } + SCSendOK(pCon); + return 1; + } if(!StringDictExists(self->scripts,argv[2])){ snprintf(pBueffel,255,"ERROR: scriptkey %s does not exist",argv[2]); SCWrite(pCon,pBueffel,eError); @@ -114,6 +127,9 @@ static void listConfiguration(pMcStasController self, SConnection *pCon){ snprintf(pLine,255,"mccontrol.updateintervall = %d\n", self->updateIntervall); Tcl_DStringAppend(&txt,pLine,-1); + snprintf(pLine,255,"mccontrol.monitorscale = %f\n", + self->monitorScale); + Tcl_DStringAppend(&txt,pLine,-1); snprintf(pLine,255,"mccontrol.pid = %d", self->pid); Tcl_DStringAppend(&txt,pLine,-1); @@ -187,11 +203,22 @@ static int start(pMcStasController self, SConnection *pCon){ SCSendOK(pCon); return 1; } +/*-----------------------------------------------------------------------*/ +static void wait4Finish(pMcStasController self){ + int status; + + if(self->pid > 0){ + status = waitpid(self->pid,NULL,WNOHANG); + if(status >= 0){ + self->pid = -1; + } + } +} /*-------------------------------------------------------------------------*/ int McStasControllerWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){ pMcStasController self = NULL; - char pBueffel[255]; + char pBueffel[255], pFile[132]; self = (pMcStasController)pData; assert(self); @@ -210,7 +237,11 @@ int McStasControllerWrapper(SConnection *pCon, SicsInterp *pSics, return runScript(self,pCon,pSics,argc,argv); } else if(strcmp(argv[1],"start") == 0){ return start(self,pCon); - } else { + } else if(strcmp(argv[1],"finish") == 0){ + wait4Finish(self); + SCSendOK(pCon); + return 1; + } else { snprintf(pBueffel,255,"ERROR: subcommand %s to mccontrol unknown", argv[1]); SCWrite(pCon,pBueffel,eError); @@ -256,6 +287,7 @@ int McStasStart(pMcStasController self, CounterMode mode, float fPreset){ self->pid = atoi(pResult); self->startTime = time(NULL); self->lastUpdate = self->startTime - self->updateIntervall; + self->lastMonitorRead = self->startTime; return OKOK; } /*------------------------------------------------------------------------*/ @@ -277,9 +309,15 @@ static long readMonFile(pMcStasController self){ /*------------------------------------------------------------------------*/ int McStasStatus(pMcStasController self, float *fControl){ char pResult[256]; - long monValue; + float monValue; int status, i; + /* + * check at max any second, else we keep the system busy and + * there is no CPU left for McStas + */ + SicsWait(1); + status = invokeScript(self,"mcisrunning",pServ->pSics,pResult, 255); if(status == 0){ strncpy(self->errorText,pResult,255); @@ -300,23 +338,31 @@ int McStasStatus(pMcStasController self, float *fControl){ * handle monitor mode */ if(status == 1 && self->mode == ePreset){ + /* + * check only any three seconds, else SICS uses up all the CPU time + * and the simulation has no chance. + */ + if(time(NULL) < self->lastMonitorRead + 3) { + return HWBusy; + } monValue = -1; /* * try to read the monfile up to three times. Problems reading it * can be synchronisation problems with McStas */ - for(i = 0, monValue = -1; i < 3; i++){ - monValue = readMonFile(self); + for(i = 0, monValue = -1; i < 7; i++){ + monValue = (float)readMonFile(self); if(monValue >= 0){ break; } } if(monValue < 0){ - strncpy(self->errorText,"Failed to read monitor file",255); - return HWFault; + return HWBusy; } - *fControl = (float)monValue; - if(monValue >= (long)self->fPreset){ + self->lastMonitorRead = time(NULL); + monValue *= self->monitorScale; + *fControl = monValue; + if(monValue >= self->fPreset){ McStasStop(self); } } @@ -348,10 +394,12 @@ int McStasTransferData(pMcStasController self){ return OKOK; } + self->lastUpdate = time(NULL); if(self->pid >= 0){ status = invokeScript(self,"mcdump",pServ->pSics,pResult, 255); if(status == 0){ strncpy(self->errorText,pResult,255); + self->lastUpdate = time(NULL) - self->updateIntervall; return HWFault; } } @@ -359,9 +407,9 @@ int McStasTransferData(pMcStasController self){ status = invokeScript(self,"mccopydata",pServ->pSics,pResult, 255); if(status == 0){ strncpy(self->errorText,pResult,255); + self->lastUpdate = time(NULL) - self->updateIntervall; return HWFault; } - self->lastUpdate = time(NULL); return OKOK; } /*-------------------------------------------------------------------------*/ diff --git a/mccontrol.h b/mccontrol.h index 66b3a6b8..21004fa6 100644 --- a/mccontrol.h +++ b/mccontrol.h @@ -19,6 +19,7 @@ pStringDict scripts; int updateIntervall; int pid; + float monitorScale; int lastError; char errorText[256]; CounterMode mode; @@ -26,6 +27,7 @@ time_t lastUpdate; time_t startTime; time_t stopTime; + time_t lastMonitorRead; }McStasController, *pMcStasController; /*---------------------- function prototypes -------------------------------------------*/ diff --git a/mcreader.c b/mcreader.c index 96b5e19d..082e1ffa 100644 --- a/mcreader.c +++ b/mcreader.c @@ -10,6 +10,7 @@ #include "mcreader.h" #include "counter.h" #include "HistMem.h" +#include "sicsdata.h" /*-------------------------------------------------------------------------*/ static void KillMcReader(void *pData){ pMcStasReader self = (pMcStasReader)pData; @@ -127,7 +128,8 @@ static int insertMonitor(pMcStasReader self, SConnection *pCon, SicsInterp *pSics, int argc, char *argv[]){ char pBueffel[512], *pPtr, pNumber[80]; pCounter pCount = NULL; - int status, mon, monValue, type, rank, iDim[NX_MAXRANK]; + int status, mon, type, rank, iDim[NX_MAXRANK]; + float monValue, scale = 1.; if(argc < 5){ SCWrite(pCon,\ @@ -157,6 +159,10 @@ static int insertMonitor(pMcStasReader self, SConnection *pCon, return 0; } + if(argc > 5) { + scale = atof(argv[5]); + } + status = NXgetinfo(self->handle,&rank,iDim,&type); if(status != NX_OK){ snprintf(pBueffel,511,"ERROR: Nexus error %s while reading %s", @@ -187,7 +193,40 @@ static int insertMonitor(pMcStasReader self, SConnection *pCon, pPtr = getNextMCNumber(pPtr,pNumber); pPtr = getNextMCNumber(pPtr,pNumber); pPtr = getNextMCNumber(pPtr,pNumber); - monValue = atoi(pNumber); + monValue = atof(pNumber); + monValue *= scale; + + if(pCount != NULL){ + SetMonitorValue(pCount,mon,(long)monValue); + } + SCSendOK(pCon); + return 1; +} +/*--------------------------------------------------------------------------*/ +static int insertMonitorDirect(pMcStasReader self, SConnection *pCon, + SicsInterp *pSics, int argc, char *argv[]){ + char pBueffel[512], *pPtr, pNumber[80]; + pCounter pCount = NULL; + int status, mon; + float monValue; + + if(argc < 5){ + SCWrite(pCon,\ + "ERROR: insufficient number of arguments to mcreader insertmondirect", + eError); + return 0; + } + + pCount = FindCommandData(pSics,argv[2],"SingleCounter"); + if(pCount == NULL){ + snprintf(pBueffel,511, + "ERROR: %s is no counter object", + argv[3]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + mon = atoi(argv[3]); + monValue = atof(argv[4]); if(pCount != NULL){ SetMonitorValue(pCount,mon,(long)monValue); @@ -203,6 +242,8 @@ static int insertHM(pMcStasReader self, SConnection *pCon, int status, type, rank, iDim[NX_MAXRANK]; int length, i; HistInt *lData = NULL; + float scale = 1.; + double val; if(argc < 4){ SCWrite(pCon,\ @@ -230,6 +271,9 @@ static int insertHM(pMcStasReader self, SConnection *pCon, SCWrite(pCon,pBueffel,eError); return 0; } + if(argc > 4){ + scale = atof(argv[4]); + } status = NXgetinfo(self->handle,&rank,iDim,&type); if(status != NX_OK){ @@ -266,7 +310,9 @@ static int insertHM(pMcStasReader self, SConnection *pCon, pPtr = pData; for(i = 0; i < length && pPtr != NULL; i++){ pPtr = getNextMCNumber(pPtr,pNumber); - lData[i] = atoi(pNumber); + val = atof(pNumber); + val *= scale; + lData[i] = (HistInt)val; } SetHistogram(pHM,pCon,0,0,length,lData); @@ -275,6 +321,61 @@ static int insertHM(pMcStasReader self, SConnection *pCon, SCSendOK(pCon); return 1; } +/*--------------------------------------------------------------------------*/ +static int insertHMFromData(pMcStasReader self, SConnection *pCon, + SicsInterp *pSics, int argc, char *argv[]){ + char pBueffel[512]; + pHistMem pHM = NULL; + int length, i; + HistInt *lData = NULL; + pSICSData data = NULL; + + if(argc < 4){ + SCWrite(pCon,\ + "ERROR: insufficient number of arguments to mcreader inserthmfromdata", + eError); + return 0; + } + pHM = FindCommandData(pSics,argv[2],"HistMem"); + if(pHM == NULL){ + snprintf(pBueffel,511, + "ERROR: %s is no histogram memory object", + argv[3]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + data = FindCommandData(pSics,argv[3],"SICSData"); + if(data == NULL){ + snprintf(pBueffel,511, + "ERROR: %s is no SICSData object", + argv[3]); + SCWrite(pCon,pBueffel,eError); + return 0; + } + + length = GetHistLength(pHM); + if(data->currentDataSize < length){ + snprintf(pBueffel,511,"WARNING: data in %s to short for HM %s", + argv[3],argv[2]); + SCWrite(pCon,pBueffel,eWarning); + } + lData = (HistInt *)malloc(length*sizeof(HistInt)); + if(lData== NULL){ + SCWrite(pCon,"ERROR: out of memory in mcreader inserthm",eError); + return 0; + } + memset(lData,0,length*sizeof(HistInt)); + if(data->currentDataSize < length){ + length = data->currentDataSize; + } + for(i = 0; i < length; i++){ + lData[i] = (HistInt)data->data[i]; + } + SetHistogram(pHM,pCon,0,0,length,lData); + free(lData); + SCSendOK(pCon); + return 1; +} /*--------------------------------------------------------------------------*/ int McStasReaderWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){ @@ -296,8 +397,12 @@ int McStasReaderWrapper(SConnection *pCon, SicsInterp *pSics, return closeMcStasFile(self,pCon); } else if(strcmp(argv[1],"insertmon") == 0){ return insertMonitor(self,pCon, pSics,argc,argv); + } else if(strcmp(argv[1],"insertmondirect") == 0){ + return insertMonitorDirect(self,pCon, pSics,argc,argv); } else if(strcmp(argv[1],"inserthm") == 0){ return insertHM(self,pCon, pSics,argc,argv); + } else if(strcmp(argv[1],"inserthmfromdata") == 0){ + return insertHMFromData(self,pCon, pSics,argc,argv); } else { snprintf(pBueffel,511,"ERROR: invalid subcommand %s to %s", argv[1],argv[0]); diff --git a/mcstas.tex b/mcstas.tex index 0a5e8f6a..4455c639 100644 --- a/mcstas.tex +++ b/mcstas.tex @@ -24,6 +24,10 @@ in a certain way: be assigned to the appropriate McStas variables. \item McStas must dump its data into a single file: use the {\it -f filename} option. The format must be {\it --format=\"XML\"}. +\item In order to count on monitor, a modified PSD_monitor component MUST be used in the + simulation. This component writes the collected total counts into a file. This file is + the read by SICS in order to determine the control monitor. Evaluating the McStas XML dump \ + file each time proved to be to inaccurate. \end{itemize} \subsubsection{The McStas Controller} @@ -69,6 +73,7 @@ $\langle$mcconint {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ pStringDict scripts;@\\ \mbox{}\verb@ int updateIntervall;@\\ \mbox{}\verb@ int pid;@\\ +\mbox{}\verb@ float monitorScale;@\\ \mbox{}\verb@ int lastError;@\\ \mbox{}\verb@ char errorText[256];@\\ \mbox{}\verb@ CounterMode mode;@\\ @@ -76,6 +81,7 @@ $\langle$mcconint {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ time_t lastUpdate;@\\ \mbox{}\verb@ time_t startTime;@\\ \mbox{}\verb@ time_t stopTime;@\\ +\mbox{}\verb@ time_t lastMonitorRead;@\\ \mbox{}\verb@ }McStasController, *pMcStasController;@\\ \mbox{}\verb@ @$\diamond$ \end{list} diff --git a/mcstas.w b/mcstas.w index acd8ef30..57368723 100644 --- a/mcstas.w +++ b/mcstas.w @@ -68,6 +68,7 @@ deemed advisable to separate this logic into a separate module. The McStas contr pStringDict scripts; int updateIntervall; int pid; + float monitorScale; int lastError; char errorText[256]; CounterMode mode; @@ -75,6 +76,7 @@ deemed advisable to separate this logic into a separate module. The McStas contr time_t lastUpdate; time_t startTime; time_t stopTime; + time_t lastMonitorRead; }McStasController, *pMcStasController; @} The fields are: diff --git a/mcstas/dmc/DataNumber b/mcstas/dmc/DataNumber index c8093d83..f7ab7dfd 100644 --- a/mcstas/dmc/DataNumber +++ b/mcstas/dmc/DataNumber @@ -1,3 +1,3 @@ - 6 + 71 NEVER, EVER modify or delete this file You'll risk eternal damnation and a reincarnation as a cockroach!|n \ No newline at end of file diff --git a/mcstas/dmc/MKMonitor.comp b/mcstas/dmc/MKMonitor.comp new file mode 100644 index 00000000..27274eb4 --- /dev/null +++ b/mcstas/dmc/MKMonitor.comp @@ -0,0 +1,104 @@ +/******************************************************************************* +* +* McStas, neutron ray-tracing package +* Copyright 1997-2002, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* Component: Monitor +* +* %I +* Written by: Kim Lefmann +* Date: October 4, 1997 +* Version: $Revision: 1.19 $ +* Origin: Risoe +* Release: McStas 1.6 +* Modified to write monitor file for SICS: Mark Koennecke, June 2005 +* +* Simple single detector/monitor. +* +* %D +* Sums neutrons (0th, 1st, and 2nd moment of p) flying through +* the rectangular monitor opening. May also be used as detector. +* +* Example: Monitor(xmin=-0.1, xmax=0.1, ymin=-0.1, ymax=0.1) +* +* %P +* INPUT PARAMETERS: +* +* xmin: Lower x bound of opening [m] +* xmax: Upper x bound of opening [m] +* ymin: Lower y bound of opening [m] +* ymax: Upper y bound of opening [m] +* +* OUTPUT PARAMETERS: +* +* Nsum: Number of neutron hits +* psum: Sum of neutron weights +* p2sum: 2nd moment of neutron weights +* +* %E +*******************************************************************************/ + +DEFINE COMPONENT MKMonitor +DEFINITION PARAMETERS () +SETTING PARAMETERS (xmin, xmax, ymin, ymax,char *controlfile="mon1.dat",int dumpCount=1000) +OUTPUT PARAMETERS (Nsum, psum, p2sum,currentCount) +STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) +SHARE +%{ + void dumpTotal(char *ffilename, long totalCounts){ + FILE *fd = NULL; + + fd = fopen(ffilename,"w"); + if(fd != NULL){ + fprintf(fd,"%ld\n",totalCounts); + fclose(fd); + } + } +%} +DECLARE + %{ + long currentCount; + double Nsum; + double psum, p2sum; + %} +INITIALIZE + %{ + psum = 0; + p2sum = 0; + Nsum = 0; + currentCount = 0; + %} +TRACE + %{ + PROP_Z0; + if (x>xmin && xymin && y 0 && currentCount > dumpCount){ + dumpTotal(controlfile,Nsum); + currentCount = 0; + } + SCATTER; + } + %} +SAVE + %{ + DETECTOR_OUT_0D("Single monitor", Nsum, psum, p2sum); + %} + +MCDISPLAY +%{ + magnify("xy"); + multiline(5, (double)xmin, (double)ymin, 0.0, + (double)xmax, (double)ymin, 0.0, + (double)xmax, (double)ymax, 0.0, + (double)xmin, (double)ymax, 0.0, + (double)xmin, (double)ymin, 0.0); +%} + +END diff --git a/mcstas/dmc/PSD_monitor.comp b/mcstas/dmc/PSD_monitor.comp index cb72e484..8ae68401 100644 --- a/mcstas/dmc/PSD_monitor.comp +++ b/mcstas/dmc/PSD_monitor.comp @@ -10,7 +10,7 @@ * %I * Written by: Kim Lefmann * Date: Feb 3, 1998 -* Version: $Revision: 1.1 $ +* Version: $Revision: 1.2 $ * Origin: Risoe * Release: McStas 1.6 * @@ -118,24 +118,10 @@ TRACE %} SAVE %{ - DETECTOR_OUT_2D( - "PSD monitor", - "X position [cm]", - "Y position [cm]", - xmin*100.0, xmax*100.0, ymin*100.0, ymax*100.0, - nx, ny, - &PSD_N[0][0],&PSD_p[0][0],&PSD_p2[0][0], - filename); %} MCDISPLAY %{ - magnify("xy"); - multiline(5, (double)xmin, (double)ymin, 0.0, - (double)xmax, (double)ymin, 0.0, - (double)xmax, (double)ymax, 0.0, - (double)xmin, (double)ymax, 0.0, - (double)xmin, (double)ymin, 0.0); %} END diff --git a/mcstas/dmc/conv.tcl b/mcstas/dmc/conv.tcl new file mode 100644 index 00000000..15073a4d --- /dev/null +++ b/mcstas/dmc/conv.tcl @@ -0,0 +1,62 @@ +#!/usr/bin/tclsh +#-------------------------------------------------------------------------- +# script for extracting detector data with error bars from a simulation +# XML file. The output can be used for plotting with gnuplot +# The program reads from stdin and prints to stdout. +# +# Mark Koennecke, July 2005 +#------------------------------------------------------------------------- + +#------- locate detector data +while { [gets stdin line] >= 0} { + if {[string first det9.dat $line] > 0} { + break + } +} + +#------- locate data record +while { [gets stdin line] >= 0} { + if {[string first " 0} { + break + } +} + +#------ remove XML stuff +set idx [string first > $line] +set line [string range $line [expr $idx + 1] end] + +set l [split $line] +set count 0 +foreach e $l { + set e [string trim $e] + if { [string length $e] > 0} { + set data($count) $e + incr count + } +} +set maxCount $count + +#---- find errors line +while { [gets stdin line] >= 0} { + if {[string first " 0} { + break + } +} + +#------ remove XML stuff +set idx [string first > $line] +set line [string range $line [expr $idx + 1] end] + +set l [split $line] +set count 0 +foreach e $l { + set e [string trim $e] + if { [string length $e] > 0} { + set err($count) $e + incr count + } +} + +for {set i 0} {$i < $maxCount} {incr i} { + puts stdout "$i $data($i) $err($i)" +} diff --git a/mcstas/dmc/dmc_sics01.instr b/mcstas/dmc/dmc_sics01.instr index 59b08c23..1c009d5e 100644 --- a/mcstas/dmc/dmc_sics01.instr +++ b/mcstas/dmc/dmc_sics01.instr @@ -101,7 +101,7 @@ COMPONENT out2_slit = Slit( AT (0,0,0.65) RELATIVE msa ROTATED (0,0,0) RELATIVE msa COMPONENT PSD_sample = PSD_monitor( - xmin=-0.05, xmax=0.05, ymin=-0.07, ymax=0.07, + xmin=-0.02, xmax=0.02, ymin=-0.065, ymax=0.065, nx=80, ny=80, filename="PSD_sample.dat",controlfile=monfile, dumpCount=500) AT ( 0, 0, 1.5) RELATIVE msa @@ -125,60 +125,3 @@ AT (0,0,0) RELATIVE sa_arm ROTATED (0, 0, 180) RELATIVE sa_arm END - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/mcstas/dmc/dmc_sics05.instr b/mcstas/dmc/dmc_sics05.instr new file mode 100644 index 00000000..4b38a27b --- /dev/null +++ b/mcstas/dmc/dmc_sics05.instr @@ -0,0 +1,145 @@ +DEFINE INSTRUMENT DMC_diff(lambda,Det_start, char *samplefile, char *monfile) +DECLARE +%{ +double mono_q; +double dm; +double OMA; +double RV; +double NV = 5; +double TKOFF; +double sample_radius = 0.005; +double sample_height = 0.03; +double lambda; +double ldiff=0.5; +double Det_start; +double Det_end; +char option_list[150]; +%} + +INITIALIZE +%{ +dm = 3.3537; +TKOFF = lambda/(2.*dm); +TKOFF = 2.*asin(TKOFF)*57.29577951308232087679815481410517; +printf("TKOFF = %f\n", TKOFF); +OMA = TKOFF/2; +RV = fabs(2*2.82*sin(DEG2RAD*OMA)); +Det_end= Det_start + 80; +sprintf(option_list,"banana theta limits [%f %f] bins=400, file=det9.dat",Det_start,Det_end); +printf("%s \n",option_list); +%} + +TRACE + +COMPONENT source_arm = Arm() +AT (0, 0, 0) ABSOLUTE + +COMPONENT progress = Progress_bar(percent=5,flag_save=1) + AT (0,0,0) ABSOLUTE + +/* values for guide side window RNR12 */ +COMPONENT csource = Source_gen( + radius = 0.08,xw = 0.02, yh = 0.12, dist = 1.5, + Lambda0 = lambda, dLambda = ldiff, + T1=150.42,I1=5.98e11, + T2=37.23,I2=5.637e11,T3=14.9,I3=0.962e11) +AT (0,0,0) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide segment 1, m=2, 4.66 m */ + COMPONENT guide1 = Guide(w1=0.02, h1=0.12, w2=0.02, h2=0.12, + l=4.66, R0=0.995, Qc=0.0217, alpha = 5.76, + m = 2.0, W = 0.0033) + AT (0,0,1.5) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide segment 2, curved, m=2, 24.5 m */ +COMPONENT guide2 = Bender( + w = 0.02, h = 0.12, r = 3612, R0a = 0.995, Qca = 0.0217, + alphaa = 5.76, ma = 2, Wa = 0.0033, R0i = 0.995, Qci = 0.0217, + alphai = 5.76, mi = 2, Wi = 0.0033, R0s = 0.995, Qcs = 0.0217, + alphas = 5.76, ms = 2, Ws = 0.0033, l = 24.5) + AT (0,0,6.16) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* bunker wall, m=2, 3.0 m */ + COMPONENT bunker = Guide( + w1=0.02, h1=.12, w2=0.02, h2=.12, + l=3.0, R0=0.995, Qc=0.0217, alpha = 5.76, + m = 2.0, W = 0.0033) + AT (0,0,30.66) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide segment 3, m=2, 8.84 m */ + + COMPONENT guide3 = Guide( + w1=0.02, h1=.12, w2=0.02, h2=.12, + l=8.84, R0=0.995,Qc=0.0217, alpha = 5.76, + m = 2.0, W = 0.0033) + AT (0,0,33.66) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide exit at 42.5 m - measured flux 2.46 10e8 cm-2 s-1 mA-1 */ + +COMPONENT in_slit = Slit( + xmin = -0.01, xmax=0.01 , ymin = -0.06, ymax = 0.06) + AT (0,0,42.5) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* Monochromator description */ + +COMPONENT sma = Arm() /* source - monochromator arm */ +AT (0, 0, 43.15) RELATIVE source_arm ROTATED (0,OMA,0) RELATIVE source_arm + + +COMPONENT foc_mono = Monochromator_curved( + zwidth = 0.05, yheight = 0.025, gap = 0.0005, NH = 1, NV = 5, + mosaich = 38, mosaicv = 38, r0 = 0.7, DM=dm, RV = RV, + RH = 0) +AT (0, 0, 0) RELATIVE sma + +COMPONENT msa = Arm() /* monochromator - sample arm */ + AT (0, 0, 0) RELATIVE sma ROTATED (0, TKOFF, 0) RELATIVE source_arm + +COMPONENT out1_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.2) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +COMPONENT Amoin_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.325) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +COMPONENT Bmoin_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.525) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + + +COMPONENT out2_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.65) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +COMPONENT PSD_sample = MKMonitor( + xmin=-0.05, xmax=0.05, ymin=-0.07, ymax=0.07,controlfile=monfile) + AT ( 0, 0, 1.5) RELATIVE msa + +/* +COMPONENT PSD_sample = PSD_monitor( + xmin=-0.05, xmax=0.05, ymin=-0.07, ymax=0.07, + nx=80, ny=80, filename="PSD_sample.dat",controlfile=monfile,dumpCount=1000) + AT ( 0, 0, 1.5) RELATIVE msa +COMPONENT PSD_sample = PSD_monitor( + xmin=-0.05, xmax=0.05, ymin=-0.07, ymax=0.07, + nx=80, ny=80, filename="PSD_sample.dat") + AT ( 0, 0, 1.5) RELATIVE msa +*/ +COMPONENT sa_arm = Arm() + AT (0, 0, 2.82) RELATIVE msa + ROTATED (0, 0, 0) RELATIVE msa + +COMPONENT sample = PowderN ( + d_phi0=0, radius=sample_radius, h=sample_height, + pack=1, Vc=1076.98, reflections = samplefile, + sigma_a=0.2, focus_aw=80, focus_ah=3.5, target_index=+1) + AT ( 0, 0, 0) RELATIVE sa_arm + +COMPONENT Det9 = Monitor_nD( + xwidth=3.0,yheight=0.09, + options=option_list) + AT (0,0,0.000001) RELATIVE sa_arm + ROTATED (0, 0, 180) RELATIVE sa_arm + +END diff --git a/mcstas/dmc/dmcafter.instr b/mcstas/dmc/dmcafter.instr new file mode 100644 index 00000000..fc4accf3 --- /dev/null +++ b/mcstas/dmc/dmcafter.instr @@ -0,0 +1,68 @@ +DEFINE INSTRUMENT DMC_diff(Det_start, char *samplefile, char *monfile, + char *lambdafile,int repeat) +DECLARE +%{ +double sample_radius = 0.005; +double sample_height = 0.03; +double Det_start; +double Det_end; +char option_list[150]; +%} + +INITIALIZE +%{ +Det_end= Det_start + 80; +sprintf(option_list,"banana theta limits [%f %f] bins=400, file=det9.dat",Det_start,Det_end); +printf("%s \n",option_list); +%} + + +TRACE + +COMPONENT msa = Arm() /* monochromator - sample arm */ + AT (0, 0, 0) ABSOLUTE + +/* +COMPONENT progress = Progress_bar(percent=5,flag_save=1) + AT (0,0,.1) ABSOLUTE +*/ + +COMPONENT in = Virtual_input(file=lambdafile,repeat_count=repeat) + AT (0,0,0.64) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +COMPONENT out2_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.65) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +COMPONENT PSD_sample = MKMonitor( + xmin=-0.05, xmax=0.05, ymin=-0.07, ymax=0.07,controlfile=monfile) + AT ( 0, 0, 1.5) RELATIVE msa + +/* +COMPONENT PSD_sample = PSD_monitor( + xmin=-0.05, xmax=0.05, ymin=-0.07, ymax=0.07, + nx=80, ny=80, filename="PSD_sample.dat",controlfile=monfile,dumpCount=1000) + AT ( 0, 0, 1.5) RELATIVE msa +COMPONENT PSD_sample = PSD_monitor( + xmin=-0.05, xmax=0.05, ymin=-0.07, ymax=0.07, + nx=80, ny=80, filename="PSD_sample.dat") + AT ( 0, 0, 1.5) RELATIVE msa +*/ +COMPONENT sa_arm = Arm() + AT (0, 0, 2.82) RELATIVE msa + ROTATED (0, 0, 0) RELATIVE msa + +COMPONENT sample = PowderN ( + d_phi0=0, radius=sample_radius, h=sample_height, + pack=1, Vc=1076.98, reflections = samplefile, + sigma_a=0.2, focus_aw=80, focus_ah=3.5, target_index=+1) + AT ( 0, 0, 0) RELATIVE sa_arm + +COMPONENT Det9 = Monitor_nD( + xwidth=3.0,yheight=0.09, + options=option_list) + AT (0,0,0.000001) RELATIVE sa_arm + ROTATED (0, 0, 180) RELATIVE sa_arm + + +END diff --git a/mcstas/dmc/dmcprecalc.instr b/mcstas/dmc/dmcprecalc.instr new file mode 100644 index 00000000..a8837bef --- /dev/null +++ b/mcstas/dmc/dmcprecalc.instr @@ -0,0 +1,113 @@ +DEFINE INSTRUMENT DMC_diff(lambda,Det_start, char *samplefile, char *monfile, + char *lambdafile) +DECLARE +%{ +double mono_q; +double dm; +double OMA; +double RV; +double NV = 5; +double TKOFF; +double sample_radius = 0.005; +double sample_height = 0.03; +double lambda; +double ldiff=0.5; +double Det_start; +double Det_end; +char option_list[150]; +%} + +INITIALIZE +%{ +dm = 3.3537; +TKOFF = lambda/(2.*dm); +TKOFF = 2.*asin(TKOFF)*57.29577951308232087679815481410517; +printf("TKOFF = %f\n", TKOFF); +OMA = TKOFF/2; +RV = fabs(2*2.82*sin(DEG2RAD*OMA)); +Det_end= Det_start + 80; +sprintf(option_list,"banana theta limits [%f %f] bins=400, file=det9.dat",Det_start,Det_end); +printf("%s \n",option_list); +%} + +TRACE + +COMPONENT source_arm = Arm() +AT (0, 0, 0) ABSOLUTE + + +/* values for guide side window RNR12 */ +COMPONENT csource = Source_gen( + radius = 0.08,xw = 0.02, yh = 0.12, dist = 1.5, + Lambda0 = lambda, dLambda = ldiff, + T1=150.42,I1=5.98e11, + T2=37.23,I2=5.637e11,T3=14.9,I3=0.962e11) +AT (0,0,0) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide segment 1, m=2, 4.66 m */ + COMPONENT guide1 = Guide(w1=0.02, h1=0.12, w2=0.02, h2=0.12, + l=4.66, R0=0.995, Qc=0.0217, alpha = 5.76, + m = 2.0, W = 0.0033) + AT (0,0,1.5) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide segment 2, curved, m=2, 24.5 m */ +COMPONENT guide2 = Bender( + w = 0.02, h = 0.12, r = 3612, R0a = 0.995, Qca = 0.0217, + alphaa = 5.76, ma = 2, Wa = 0.0033, R0i = 0.995, Qci = 0.0217, + alphai = 5.76, mi = 2, Wi = 0.0033, R0s = 0.995, Qcs = 0.0217, + alphas = 5.76, ms = 2, Ws = 0.0033, l = 24.5) + AT (0,0,6.16) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* bunker wall, m=2, 3.0 m */ + COMPONENT bunker = Guide( + w1=0.02, h1=.12, w2=0.02, h2=.12, + l=3.0, R0=0.995, Qc=0.0217, alpha = 5.76, + m = 2.0, W = 0.0033) + AT (0,0,30.66) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide segment 3, m=2, 8.84 m */ + + COMPONENT guide3 = Guide( + w1=0.02, h1=.12, w2=0.02, h2=.12, + l=8.84, R0=0.995,Qc=0.0217, alpha = 5.76, + m = 2.0, W = 0.0033) + AT (0,0,33.66) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* guide exit at 42.5 m - measured flux 2.46 10e8 cm-2 s-1 mA-1 */ + +COMPONENT in_slit = Slit( + xmin = -0.01, xmax=0.01 , ymin = -0.06, ymax = 0.06) + AT (0,0,42.5) RELATIVE source_arm ROTATED (0,0,0) RELATIVE source_arm + +/* Monochromator description */ + +COMPONENT sma = Arm() /* source - monochromator arm */ +AT (0, 0, 43.15) RELATIVE source_arm ROTATED (0,OMA,0) RELATIVE source_arm + + +COMPONENT foc_mono = Monochromator_curved( + zwidth = 0.05, yheight = 0.025, gap = 0.0005, NH = 1, NV = 5, + mosaich = 38, mosaicv = 38, r0 = 0.7, DM=dm, RV = RV, + RH = 0) +AT (0, 0, 0) RELATIVE sma + +COMPONENT msa = Arm() /* monochromator - sample arm */ + AT (0, 0, 0) RELATIVE sma ROTATED (0, TKOFF, 0) RELATIVE source_arm + +COMPONENT out1_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.2) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +COMPONENT Amoin_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.325) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +COMPONENT Bmoin_slit = Slit( + xmin=-0.01, xmax=0.01, ymin=-0.06, ymax=0.06) + AT (0,0,0.525) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + + +COMPONENT out = Virtual_output(file=lambdafile) + AT(0,0,0.64) RELATIVE msa ROTATED (0,0,0) RELATIVE msa + +END diff --git a/mcstas/dmc/makelambda.sh b/mcstas/dmc/makelambda.sh new file mode 100644 index 00000000..20e041d1 --- /dev/null +++ b/mcstas/dmc/makelambda.sh @@ -0,0 +1,4 @@ +dmcprecalc -n 1e9 lambda=2.56 Det_start=19. monfile=monfile samplefile=na2ca3al2f14.q lambdafile="dmc256.dat" +dmcprecalc -n 1e9 lambda=4.2 Det_start=19. monfile=monfile samplefile=na2ca3al2f14.q lambdafile="dmc420.dat" +dmcprecalc -n 1e9 lambda=2.45 Det_start=19. monfile=monfile samplefile=na2ca3al2f14.q lambdafile="dmc245.dat" +dmcprecalc -n 1e9 lambda=3.8 Det_start=19. monfile=monfile samplefile=na2ca3al2f14.q lambdafile="dmc380.dat" diff --git a/mcstas/dmc/mcsupport.tcl b/mcstas/dmc/mcsupport.tcl index 582c0a5a..6ad4db41 100644 --- a/mcstas/dmc/mcsupport.tcl +++ b/mcstas/dmc/mcsupport.tcl @@ -34,23 +34,59 @@ set mcwaittime 7 #---------------------------------------------------------------------- proc mcstasdump {pid} { global mcwaittime + if { $pid <= 0} { + error "Trying to dump invalid PID: $pid" + } + clientput "Dumping ..." catch {eval exec /usr/bin/kill -USR2 $pid} wait $mcwaittime } #----------------------------------------------------------------------- +# mcstasisrunning has to open a pipe to ps and to read the results of +# the ps command. This is because a terminated McStas simulation turns +# into a Zombie process which finishes never. This can only be cured +# by checking for this in the STAT field of ps's output. According to +# the Unix FAQ this is the best solution...... +#---------------------------------------------------------------------- +proc readPID {pid} { + set f [ open "| /bin/ps -up $pid" r] + set pstxt [read $f] + close $f + return $pstxt +} +#---------------------------------------------------------------------- proc mcstasisrunning {pid} { - set ret [catch {eval exec /bin/ps --pid $pid} msg] - if {$ret == 0} { - return 1 - } else { - return 0; + global runningCount runningLast + + if { $pid <= 0} { + return 0 } + set pstxt " " + set ret [catch {set pstxt [readPID $pid]} msg] + set pslist [split $pstxt "\n"] + if { [llength $pslist] < 2} { + return 0 + } + set header [lindex $pslist 0] + set idx [string first STAT $header] + set stat [string trim [string range [lindex $pslist 1] $idx [expr $idx + 4]]] + if { [string first Z $stat] >= 0 || [string first T $stat] >= 0} { + mccontrol finish + return 0 + } else { + return 1 + } } #----------------------------------------------------------------------- proc mcstaskill {pid} { global mcwaittime + if { $pid <= 0} { + error "Trying to kill invalid PID $pid" + } + clientput "Killing $pid" catch {eval exec /usr/bin/kill -TERM $pid} - wait $mcwaittime +# catch {mccontrol finish} + wait 10 } #----------------------------------------------------------------------- proc mcinstall {} { diff --git a/mcstas/dmc/vdmc.tcl b/mcstas/dmc/vdmc.tcl index 87a10d2d..4772c0ee 100644 --- a/mcstas/dmc/vdmc.tcl +++ b/mcstas/dmc/vdmc.tcl @@ -10,8 +10,8 @@ set home $env(HOME)/src/workspace/sics/mcstas/dmc #--------------------------------- first all the server options are set #ServerOption RedirectFile $home/stdcdmc -ServerOption ReadTimeOut 0 -ServerOption AcceptTimeOut 0 +ServerOption ReadTimeOut 1 +ServerOption AcceptTimeOut 1 ServerOption ReadUserPasswdTimeout 500000 ServerOption LogFileBaseName "$home/vdmclog" ServerOption LogFileDir $home/ @@ -57,7 +57,8 @@ MakeWaveLength lambda Mono #-------------------------------------------------------------------------- MakeMcStasReader MakeMcStasController -allowexec $home/dmc_sics01 +allowexec $home/dmcafter +allowexec $home/dmc_sics05 ClientPut "Installing counter" MakeCounter counter mcstas @@ -107,8 +108,8 @@ Instrument lock VarMake Title Text User VarMake User Text User VarMake Collimation Text User -VarMake Sample Text User -Sample Kellerit +VarMake SampleIntern Text User +SampleIntern Kellerit VarMake comment1 Text User VarMake comment2 Text User VarMake comment3 Text User diff --git a/mcstas/dmc/vdmccom.tcl b/mcstas/dmc/vdmccom.tcl index fe106fb1..6f1d3bfd 100644 --- a/mcstas/dmc/vdmccom.tcl +++ b/mcstas/dmc/vdmccom.tcl @@ -13,6 +13,7 @@ if { [info exists vdmcinit] == 0 } { Publish storedmcdata User Publish rundmcsim User Publish copydmcdata User + Publish sample User mcinstall } source $home/log.tcl @@ -23,19 +24,85 @@ proc SplitReply { text } { set l [split $text =] return [lindex $l 1] } +#--------------------------------------------------------------------- +# load a lazy pulverix file +#--------------------------------------------------------------------- +proc washlazy {name} { + global home + set newNam [file rootname [file tail $name]] + set in [open $name r] + set out [open $home/$newNam.q w] +#------- proceed to first header line + while { [gets $in line] >= 0} { + if { [string first "H K L THETA 2THETA D VALUE" $line] > 0} { + break + } + } +#------- process data lines + puts $out "// mult Q(hkl) F2 DW w" + while { [gets $in line] >= 0} { + set num [scan $line "%d %d %d %f %f %f %f %f %d %d %d %f %f %f %f %f %d"\ + h k l th th2 d di sin h2 k2 l2 I F A B ang mul] + if { $num == 17} { + set q [expr (2.*3.14159265358979323846)/$d] + set f2 [expr $F * $F] + puts $out [format "%d %f %f 1 0" $mul $q $f2] + } + } + close $in + close $out +} +#---------------------------------------------------------------------- +# script for setting the sample. We only allow samples for which +# there is a corresponing q data file +#------------------------------------------------------------------------ +proc sample args { + global home + if { [llength $args] < 1} { + set sa [SplitReply [sampleintern]] + return "sample = $sa" + } + set txt [lindex $args 0] +#-------- list + if { [string compare $txt list] == 0} { + set l [glob $home/*.q] + foreach f $l { + append out [file rootname [file tail $f]] "\n" + } + return $out + } +#--------- load + if { [string compare $txt load] == 0} { + if { [llength $args] < 2} { + error "Need path to lazy pulverix output file to load" + } + set nam [lindex $args 1] + washlazy $nam + set nam2 [file rootname [file tail $nam]] + eval sampleintern $nam2 + return OK + } + if { ![file exists $home/$txt.q] } { + error "No Q data for sample $txt" + } else { + eval sampleintern $txt + return OK + } +} #----------------------------------------------------------------------- # Scripts required for controlling McStas simulations #----------------------------------------------------------------------- proc rundmcsim {mode preset} { global home - append command $home/dmc_sics01 " -f $home/dmc.xml --format=\"XML\"" - append command " -n 9e15 " + append command $home/dmc_sics05 " -f $home/dmc.xml --format=\"XML\"" + append command " -n 1e10 " append command " lambda=[string trim [SplitReply [lambda]]]" - append command " TKOFF=[string trim [SplitReply [TwoThetaM]]]" - append command " samplefile=$home/[string trim [SplitReply [sample]]].q" + append command " Det_start=[string trim [SplitReply [TwoThetaD]]]" + append command " samplefile=$home/[string trim [SplitReply [sampleintern]]].q" append command " monfile=$home/monfile " append command " >& $home/dmc.log &" clientput "Starting McStas.. " +# clientput $command set ret [catch {eval exec $command} msg] if {$ret != 0} { error $msg @@ -44,23 +111,85 @@ proc rundmcsim {mode preset} { } } #------------------------------------------------------------------------ +# Run the DMC simulation in an optimized mode with neutrons +# precalculated for various wave length until the sample slit +#------------------------------------------------------------------------ +set dmcdata(2.56) dmc256.dat +set dmcdata(4.2) dmc420.dat +set dmcdata(2.45) dmc245.dat +set dmcdata(3.8) dmc380.dat +#------------------------------------------------------------------------- +proc rundmcoptsim {mode preset } { + global home dmcdata +#--------- locate closest precalculated neutron data file + set lambda [SplitReply [lambda]] + set myLambda $lambda + set wv [array names dmcdata] + set diff 999999.99 + set lambdafile $dmcdata(2.56) + foreach w $wv { + set tmp [expr abs($w - $lambda)] + if { $tmp < $diff} { + set diff $tmp + set lambdafile $dmcdata($w) + set myLambda $w + } + } +#-------- build McStas command line + append command $home/dmcafter " -f $home/dmc.xml --format=\"XML\"" + append command " -n 1e10 " + append command " lambdafile=$home/$lambdafile" + append command " Det_start=[string trim [SplitReply [TwoThetaD]]]" + append command " samplefile=$home/[string trim [SplitReply [sampleintern]]].q" + append command " monfile=$home/monfile " + append command " repeat=1000000000 " + append command " >& $home/dmc.log &" +#--------- start McStas + clientput "Starting McStas.. " + clientput "Coercing $lambda to precalculated $myLambda" +# clientput $command + set ret [catch {eval exec $command} msg] + if {$ret != 0} { + error "ERROR: $msg" + } else { + return $msg + } +} +#------------------------------------------------------------------------ proc copydmcdata { } { global home set mcversion "McStas 1.8 - Mar. 05, 2004" washsimfile $home/dmc.xml mcreader open $home/dmc.xml mcreader insertmon \ - "/$mcversion/DMC_diff/dmc.xml/PSD_sample/PSD_sample.dat/values" \ - counter 1 + "/$mcversion/DMC_diff/dmc.xml/PSD_sample/values" \ + counter 1 [expr 1./10000] + mcreader insertmon \ + "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/values" \ + counter 5 + set hmScale [SplitReply [counter getmonitor 5]] + if { $hmScale <= 0} { + set hmScale 1e9 + } else { + set hmScale [expr $hmScale * 1e9] + } + clientput "HM scale = $hmScale" mcreader inserthm \ - "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/data" banana + "/$mcversion/DMC_diff/dmc.xml/Det9/det9.dat/data" banana $hmScale mcreader close } +#------------------------------------------------------------------------- +proc dmcdump {pid} { +#--do nothing: progress is doing it for us +} #-------------------------------------------------------------------------- -mccontrol configure mcstart rundmcsim +#mccontrol configure mcstart rundmcsim +mccontrol configure mcstart rundmcoptsim mccontrol configure mccopydata copydmcdata mccontrol configure update 60 mccontrol configure mcmonfile $home/monfile +mccontrol configure monitorscale [expr 1. /10000] +mccontrol configure mcdump mcstasdump #-------------------------------------------------------------------------- # A count command for VDMC # All arguments are optional. The current values will be used if not diff --git a/mcstas/dmc/vdmcstatus.tcl b/mcstas/dmc/vdmcstatus.tcl index db4bda9c..e4e015e0 100644 --- a/mcstas/dmc/vdmcstatus.tcl +++ b/mcstas/dmc/vdmcstatus.tcl @@ -14,7 +14,7 @@ sicsdatapostfix .hdf sicsdatapostfix setAccess 0 sicsdataprefix powder sicsdataprefix setAccess 0 -starttime 2005-06-21 14:21:44 +starttime 2005-07-01 16:19:39 starttime setAccess 2 comment3 UNKNOWN comment3 setAccess 2 @@ -22,8 +22,8 @@ comment2 UNKNOWN comment2 setAccess 2 comment1 UNKNOWN comment1 setAccess 2 -sample na2ca3al2f14 -sample setAccess 2 +sampleintern na2ca3al2f14 +sampleintern setAccess 2 collimation UNKNOWN collimation setAccess 2 user UNKNOWN @@ -120,11 +120,11 @@ a1 InterruptMode 0.000000 a1 precision 0.010000 a1 AccessCode 2.000000 a1 movecount 10.000000 -banana CountMode timer -banana preset 180.000000 +banana CountMode monitor +banana preset 5.000000 # Counter counter -counter SetPreset 180.000000 -counter SetMode Timer +counter SetPreset 5000.000000 +counter SetMode Monitor # Motor twothetad twothetad sign 1.000000 twothetad SoftZero 0.000000 diff --git a/mcstashm.c b/mcstashm.c index 9f9fa0c4..cfde18e8 100644 --- a/mcstashm.c +++ b/mcstashm.c @@ -114,14 +114,11 @@ static int McHMGetData(pHistDriver self, SConnection *pCon){ } /*-----------------------------------------------------------------------*/ static int McHMGetHistogram(pHistDriver self, SConnection *pCon, - int bank, int start, int end, HistInt *pData){ - /* - * normally this would update HM data from the actual histogram mmeory. - * With the McStas simulation, the updated values for the hiistogram - * mmeory data are pushed through SetHistogram. Thus this routine has - * to do nothing. - */ - return 1; + int bank, int start, int end, HistInt *pData){ + /* + * make sure data gets transferred + */ + return McHMGetData(self,pCon); } /*-------------------------------------------------------------------------*/ static int McHMSetHistogram(pHistDriver self, SConnection *pCon,