diff --git a/SCinter.c b/SCinter.c index 50299ec9..1ba7f178 100644 --- a/SCinter.c +++ b/SCinter.c @@ -41,7 +41,7 @@ Mark Koennecke, August 2001, modified SicsWriteStatus to write motor positions on demand. - Made ListObjects moe intelligent: list objects according to interface etc. + Made ListObjects more intelligent: list objects according to interface etc. Mark Koennecke, December 2003 Extended 'dir' command (function ListObjects) to list via typename from @@ -50,6 +50,8 @@ Modified printXXX functions to fix duplicate write of last buffer line. Paul Hathaway, May 2004 + + Added FindAlias function, Mark Koennecke, January 2007 ---------------------------------------------------------------------------*/ #include #include @@ -67,6 +69,7 @@ #include "motor.h" #include "obdes.h" #include "lld.h" +#include "dynstring.h" /* M.Z. */ #include "definealias.h" @@ -1042,3 +1045,64 @@ static void freeList(int listID) pCurrent = pNext; } } +/*---------------------------------------------------------------------*/ +char *FindAliases(SicsInterp *pSics, char *name) +{ + pDynString result = NULL; + CommandList *pOri = NULL, *pCom = NULL; + char *pTrans = NULL, *charResult = NULL; + int first; + + pOri = FindCommand(pSics, name); + if(pOri == NULL) + { + return NULL; + } + if(pOri->pData == NULL) + { + return NULL; + } + + result = CreateDynString(64,64); + if(result == NULL) + { + return NULL; + } + + /* try first to locate Markus style aliases */ + pTrans = TranslateAlias(&pSics->AList,name); + if(strcmp(pTrans,name) != 0) + { + DynStringCopy(result,pTrans); + charResult = strdup(GetCharArray(result)); + DeleteDynString(result); + return charResult; + } + + /* + * locate SicsAlias style aliases by comparing the original + * data pointer with the data pointers of other commands + */ + first = 1; + pCom = pSics->pCList; + while(pCom != NULL) + { + if(pCom != pOri && pCom->pData == pOri->pData) + { + if(first) + { + DynStringCopy(result,pCom->pName); + first = 0; + } + else + { + DynStringConcat(result,","); + DynStringConcat(result,pCom->pName); + } + } + pCom = pCom->pNext; + } + charResult = strdup(GetCharArray(result)); + DeleteDynString(result); + return charResult; +} diff --git a/devexec.c b/devexec.c index f908eb3c..bfd6911f 100644 --- a/devexec.c +++ b/devexec.c @@ -173,6 +173,20 @@ typedef struct { } ExeList; static pExeList pExecutor = NULL; +/*--------------------------------------------------------------------------*/ + static void *DevexecInterface(void *pData, int iInter) + { + pExeList self = NULL; + + self = (pExeList)pData; + assert(self); + + if(iInter == CALLBACKINTERFACE) + { + return self->pCall; + } + return NULL; + } /*--------------------------------------------------------------------------*/ pExeList CreateExeList(pTaskMan pTask) { @@ -208,6 +222,7 @@ typedef struct { pRes->paused = 0; pRes->pCall = CreateCallBackInterface(); pRes->lastRun = time(NULL); + pRes->pDes->GetInterface = DevexecInterface; return pRes; } /*-------------------------------------------------------------------------*/ @@ -1128,7 +1143,7 @@ static int testFinish(pExeList self){ { ListPending(self,pCon); return 1; - } + } iRet = StopExe(self,argv[1]); if(!iRet) @@ -1150,7 +1165,7 @@ static int testFinish(pExeList self){ SCPopContext(pCon); return 1; } -/*--------------------------------------------------------------------------*/ + /*--------------------------------------------------------------------------*/ int ListExe(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) { diff --git a/event.c b/event.c index f98cc833..98ab43be 100644 --- a/event.c +++ b/event.c @@ -67,6 +67,8 @@ "STATUS", "POSITION", "HDBVAL", + "STATESTART", + "STATEEND", NULL }; diff --git a/event.h b/event.h index 4b26bde5..eb8f9f18 100644 --- a/event.h +++ b/event.h @@ -1,5 +1,5 @@ -#line 96 "event.w" +#line 103 "event.w" /*---------------------------------------------------------------------------- E V E N T @@ -14,15 +14,15 @@ #ifndef SICSEVENT #define SICSEVENT -#line 13 "event.w" +#line 14 "event.w" int Text2Event(char *pText); -#line 109 "event.w" +#line 116 "event.w" -#line 20 "event.w" +#line 21 "event.w" #define VALUECHANGE 0 #define MOTDRIVE 1 @@ -45,13 +45,15 @@ #define STATUS 18 #define POSITION 19 #define HDBVAL 20 +#define STSTART 21 +#define STEND 22 -#line 111 "event.w" +#line 118 "event.w" /*--------------- Signals for the Signalfunction of each task ------------*/ -#line 80 "event.w" +#line 87 "event.w" #define SICSINT 300 #define SICSBROADCAST 301 @@ -59,6 +61,6 @@ #define TOKENRELEASE 303 #define COMLOG 304 -#line 114 "event.w" +#line 121 "event.w" #endif diff --git a/hipadaba.c b/hipadaba.c index 28d100a9..7ca1cf87 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -870,7 +870,7 @@ int copyHdbValue(hdbValue *source, hdbValue *target){ break; case HIPINTAR: case HIPINTVARAR: - if(target->arrayLength != source->arrayLength){ + if(target->arrayLength != source->arrayLength || target->v.intArray == NULL){ if(target->v.intArray != NULL){ free(target->v.intArray); } @@ -881,13 +881,15 @@ int copyHdbValue(hdbValue *source, hdbValue *target){ memset(target->v.intArray,0,source->arrayLength * sizeof(int)); target->arrayLength = source->arrayLength; } - for(i = 0; i < source->arrayLength; i++){ - target->v.intArray[i] = source->v.intArray[i]; + if(source->v.intArray != NULL){ + for(i = 0; i < source->arrayLength; i++){ + target->v.intArray[i] = source->v.intArray[i]; + } } break; case HIPFLOATAR: case HIPFLOATVARAR: - if(target->arrayLength != source->arrayLength){ + if(target->arrayLength != source->arrayLength || target->v.floatArray == NULL){ if(target->v.floatArray != NULL){ free(target->v.floatArray); } @@ -897,9 +899,11 @@ int copyHdbValue(hdbValue *source, hdbValue *target){ } memset(target->v.floatArray,0,source->arrayLength * sizeof(double)); target->arrayLength = source->arrayLength; - } - for(i = 0; i < source->arrayLength; i++){ - target->v.floatArray[i] = source->v.floatArray[i]; + } + if(source->v.floatArray != NULL){ + for(i = 0; i < source->arrayLength; i++){ + target->v.floatArray[i] = source->v.floatArray[i]; + } } break; case HIPOBJ: diff --git a/make_gen b/make_gen index 5171d3ae..32c80b63 100644 --- a/make_gen +++ b/make_gen @@ -32,7 +32,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ mcstashm.o initializer.o remob.o tclmotdriv.o protocol.o \ sinfox.o sicslist.o cone.o hipadaba.o sicshipadaba.o statistics.o \ moregress.o hdbcommand.o multicounter.o regresscter.o histregress.o \ - sicshdbadapter.o polldriv.o sicspoll.o + sicshdbadapter.o polldriv.o sicspoll.o statemon.o MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/mcstas/dmc/dmcafter.c b/mcstas/dmc/dmcafter.c new file mode 100644 index 00000000..3c5183d3 --- /dev/null +++ b/mcstas/dmc/dmcafter.c @@ -0,0 +1,8436 @@ +/* Automatically generated file. Do not edit. + * Format: ANSI C source code + * Creator: McStas + * Instrument: dmcafter.instr (DMC_diff) + * Date: Tue Aug 2 16:09:43 2005 + */ + + +#define MCSTAS_VERSION "1.8 - Mar. 05, 2004" +#define MC_USE_DEFAULT_MAIN +#define MC_EMBEDDED_RUNTIME + +#line 1 "mcstas-r.h" +/******************************************************************************* +* +* McStas, neutron ray-tracing package +* Copyright 1997-2002, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* Runtime: share/mcstas-r.h +* +* %Identification +* Written by: KN +* Date: Aug 29, 1997 +* Release: McStas 1.6 +* Version: 1.5 +* +* Runtime system header for McStas. +* +* Usage: Automatically embbeded in the c code. +* +* $Id: dmcafter.c,v 1.1 2007/01/30 03:19:43 koennecke Exp $ +* +* $Log: dmcafter.c,v $ +* Revision 1.1 2007/01/30 03:19:43 koennecke +* - Fixed state monitor eclipse commit problems. Siiiiiiiggggghhhhhh! +* +* Revision 1.55 2003/10/21 14:08:12 pkwi +* Rectangular focusing improved: Renamed randvec_target_rect to randvec_target_rect_angular. Wrote new randvec_target_rect routine, w/h in metres. Both routines use use component orientation (ROT_A_CURRENT_COMP) as input. +* +* Modifications to Res_sample and V_sample to match new features of the runtime. +* +* Revision 1.54 2003/09/05 08:59:18 farhi +* added INSTRUMENT parameter default value grammar +* mcinputtable now has also default values +* mcreadpar now uses default values if parameter not given +* extended instr_formal parameter struct +* extended mcinputtable structure type +* +* Revision 1.53 2003/04/07 11:50:51 farhi +* Extended the way mcplot:plotter is assigned. Set --portable ok +* Handle Scilab:Tk and ~GTk menu (shifted) +* Updated help in mcrun and mcstas-r.c +* +* Revision 1.52 2003/04/04 18:20:21 farhi +* remove some warnings (duplicated decl) for --no-runtime on Dec OSF +* +* Revision 1.51 2003/04/04 14:27:19 farhi +* Moved format definitions to mcstas-r.c for --no-runtime to work +* +* Revision 1.50 2003/02/11 12:28:46 farhi +* Variouxs bug fixes after tests in the lib directory +* mcstas_r : disable output with --no-out.. flag. Fix 1D McStas output +* read_table:corrected MC_SYS_DIR -> MCSTAS define +* monitor_nd-lib: fix Log(signal) log(coord) +* HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample +* Progress_bar: precent -> percent parameter +* CS: ---------------------------------------------------------------------- +* +* Revision 1.5 2002/10/19 22:46:21 ef +* gravitation for all with -g. Various output formats. +* +* Revision 1.4 2002/09/17 12:01:21 ef +* removed unused macros (PROP_Y0, X0), changed randvec_target_sphere to circle +* added randvec_target_rect +* +* Revision 1.3 2002/08/28 11:36:37 ef +* Changed to lib/share/c code +* +* Revision 1.2 2001/10/10 11:36:37 ef +* added signal handler +* +* Revision 1.1 1998/08/29 11:36:37 kn +* Initial revision +* +*******************************************************************************/ + +#ifndef MCSTAS_R_H +#define MCSTAS_R_H "$Revision: 1.1 $" + +#include +#include +#include +#include + +/* If the runtime is embedded in the simulation program, some definitions can + be made static. */ + +#ifdef MC_EMBEDDED_RUNTIME +#define mcstatic static +#else +#define mcstatic +#endif + +#ifdef __dest_os +#if (__dest_os == __mac_os) +#define MAC +#endif +#endif + +#ifdef WIN32 +#define MC_PATHSEP_C '\\' +#define MC_PATHSEP_S "\\" +#else /* !WIN32 */ +#ifdef MAC +#define MC_PATHSEP_C ':' +#define MC_PATHSEP_S ":" +#else /* !MAC */ +#define MC_PATHSEP_C '/' +#define MC_PATHSEP_S "/" +#endif /* !MAC */ +#endif /* !WIN32 */ + +#ifndef MC_PORTABLE +#ifndef MAC +#ifndef WIN32 +#include +#endif /* !MAC */ +#endif /* !WIN32 */ +#endif /* MC_PORTABLE */ + +typedef double MCNUM; +typedef struct {MCNUM x, y, z;} Coords; +typedef MCNUM Rotation[3][3]; + +/* Note: the enum instr_formal_types definition MUST be kept + synchronized with the one in mcstas.h and with the + instr_formal_type_names array in cogen.c. */ +enum instr_formal_types + { + instr_type_double, instr_type_int, instr_type_string + }; +struct mcinputtable_struct { + char *name; + void *par; + enum instr_formal_types type; + char *val; +}; +extern struct mcinputtable_struct mcinputtable[]; +extern int mcnumipar; +extern char mcinstrument_name[], mcinstrument_source[]; +extern int mctraceenabled, mcdefaultmain; +#ifndef MC_EMBEDDED_RUNTIME +extern FILE *mcsiminfo_file; +extern char mcsig_message[]; +extern int mcgravitation; +extern int mcdotrace; +extern struct mcformats_struct mcformats[]; +extern struct mcformats_struct mcformat; +#endif +void mcinit(void); +void mcraytrace(void); +void mcsave(FILE *); +void mcfinally(void); +void mcdisplay(void); + +/* MOD: E. Farhi, Sep 25th 2001 set Scattered flag (for groups) */ +#define SCATTER do {mcDEBUG_SCATTER(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz, \ + mcnlt,mcnlsx,mcnlsy, mcnlp); mcScattered++;} while(0) +#define ABSORB do {mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz, \ + mcnlt,mcnlsx,mcnlsy, mcnlp); mcDEBUG_ABSORB(); goto mcabsorb;} while(0) +/* Note: The two-stage approach to MC_GETPAR is NOT redundant; without it, +* after #define C sample, MC_GETPAR(C,x) would refer to component C, not to +* component sample. Such are the joys of ANSI C. + +* Anyway the usage of MCGETPAR requires that we use sometimes bare names... +*/ +#define MC_GETPAR2(comp, par) (mcc ## comp ## _ ## par) +#define MC_GETPAR(comp, par) MC_GETPAR2(comp,par) +#define DETECTOR_OUT(p0,p1,p2) mcdetector_out(NAME_CURRENT_COMP,p0,p1,p2,NULL) +#define DETECTOR_OUT_0D(t,p0,p1,p2) mcdetector_out_0D(t,p0,p1,p2,NAME_CURRENT_COMP) +#define DETECTOR_OUT_1D(t,xl,yl,xvar,x1,x2,n,p0,p1,p2,f) \ + mcdetector_out_1D(t,xl,yl,xvar,x1,x2,n,p0,p1,p2,f,NAME_CURRENT_COMP) +#define DETECTOR_OUT_2D(t,xl,yl,x1,x2,y1,y2,m,n,p0,p1,p2,f) \ + mcdetector_out_2D(t,xl,yl,x1,x2,y1,y2,m,n,p0,p1,p2,f,NAME_CURRENT_COMP) +#define DETECTOR_OUT_3D(t,xl,yl,zl,xv,yv,zv,x1,x2,y1,y2,z1,z2,m,n,p,p0,p1,p2,f) \ + mcdetector_out_3D(t,xl,yl,zl,xv,yv,zv,x1,x2,y1,y2,z1,z2,m,n,p,p0,p1,p2,f,NAME_CURRENT_COMP) +/* ADD: E. Farhi, Sep 20th 2001 save neutron state (in local coords) */ +#define STORE_NEUTRON(index, x, y, z, vx, vy, vz, t, sx, sy, sz, p) \ + mcstore_neutron(mccomp_storein,index, x, y, z, vx, vy, vz, t, sx, sy, sz, p); +/* ADD: E. Farhi, Sep 20th 2001 restore neutron state (in local coords) */ +#define RESTORE_NEUTRON(index, x, y, z, vx, vy, vz, t, sx, sy, sz, p) \ + mcrestore_neutron(mccomp_storein,index, &x, &y, &z, &vx, &vy, &vz, &t, &sx, &sy, &sz, &p); +#define POS_A_COMP_INDEX(index) \ + (mccomp_posa[index]) +#define POS_R_COMP_INDEX(index) \ + (mccomp_posr[index]) \ + +#ifdef MC_TRACE_ENABLED +#define DEBUG +#endif + +#ifdef DEBUG +#define mcDEBUG_INSTR() if(!mcdotrace); else printf("INSTRUMENT:\n"); +#define mcDEBUG_COMPONENT(name,c,t) if(!mcdotrace); else \ + printf("COMPONENT: \"%s\"\n" \ + "POS: %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g\n", \ + name, c.x, c.y, c.z, t[0][0], t[0][1], t[0][2], \ + t[1][0], t[1][1], t[1][2], t[2][0], t[2][1], t[2][2]); +#define mcDEBUG_INSTR_END() if(!mcdotrace); else printf("INSTRUMENT END:\n"); +#define mcDEBUG_ENTER() if(!mcdotrace); else printf("ENTER:\n"); +#define mcDEBUG_COMP(c) if(!mcdotrace); else printf("COMP: \"%s\"\n", c); +#define mcDEBUG_STATE(x,y,z,vx,vy,vz,t,s1,s2,p) if(!mcdotrace); else \ + printf("STATE: %g, %g, %g, %g, %g, %g, %g, %g, %g, %g\n", \ + x,y,z,vx,vy,vz,t,s1,s2,p); +#define mcDEBUG_SCATTER(x,y,z,vx,vy,vz,t,s1,s2,p) if(!mcdotrace); else \ + printf("SCATTER: %g, %g, %g, %g, %g, %g, %g, %g, %g, %g\n", \ + x,y,z,vx,vy,vz,t,s1,s2,p); +#define mcDEBUG_LEAVE() if(!mcdotrace); else printf("LEAVE:\n"); +#define mcDEBUG_ABSORB() if(!mcdotrace); else printf("ABSORB:\n"); +#else +#define mcDEBUG_INSTR() +#define mcDEBUG_COMPONENT(name,c,t) +#define mcDEBUG_INSTR_END() +#define mcDEBUG_ENTER() +#define mcDEBUG_COMP(c) +#define mcDEBUG_STATE(x,y,z,vx,vy,vz,t,s1,s2,p) +#define mcDEBUG_SCATTER(x,y,z,vx,vy,vz,t,s1,s2,p) +#define mcDEBUG_LEAVE() +#define mcDEBUG_ABSORB() +#endif + +#ifdef TEST +#define test_printf printf +#else +#define test_printf while(0) printf +#endif + +void mcdis_magnify(char *); +void mcdis_line(double, double, double, double, double, double); +void mcdis_multiline(int, ...); +void mcdis_circle(char *, double, double, double, double); + +#define RAD2MIN ((180*60)/PI) +#define MIN2RAD (PI/(180*60)) +#define DEG2RAD (PI/180) +#define RAD2DEG (180/PI) +#define AA2MS 629.719 /* Convert k[1/AA] to v[m/s] */ +#define MS2AA 1.58801E-3 /* Convert v[m/s] to k[1/AA] */ +#define K2V AA2MS +#define V2K MS2AA +#define Q2V AA2MS +#define V2Q MS2AA +#define SE2V 437.3949 /* Convert sqrt(E)[meV] to v[m/s] */ +#define VS2E 5.227e-6 /* Convert (v[m/s])**2 to E[meV] */ +#define FWHM2RMS 0.424660900144 /* Convert between full-width-half-max and */ +#define RMS2FWHM 2.35482004503 /* root-mean-square (standard deviation) */ +#define HBAR 1.05459E-34 +#define MNEUTRON 1.67492E-27 + +#ifndef PI +# ifdef M_PI +# define PI M_PI +# else +# define PI 3.14159265358979323846 +# endif +#endif + +typedef int mc_int32_t; +mc_int32_t mc_random(void); +void mc_srandom (unsigned int x); +unsigned long mt_random(void); +void mt_srandom (unsigned long x); + +#ifndef MC_RAND_ALG +#define MC_RAND_ALG 1 +#endif + +#if MC_RAND_ALG == 0 + /* Use system random() (not recommended). */ +# define MC_RAND_MAX RAND_MAX +#elif MC_RAND_ALG == 1 + /* "Mersenne Twister", by Makoto Matsumoto and Takuji Nishimura. */ +# define MC_RAND_MAX ((unsigned long)0xffffffff) +# define random mt_random +# define srandom mt_srandom +#elif MC_RAND_ALG == 2 + /* Algorithm used in McStas 1.1 and earlier (not recommended). */ +# define MC_RAND_MAX 0x7fffffff +# define random mc_random +# define srandom mc_srandom +#else +# error "Bad value for random number generator choice." +#endif + +#define rand01() ( ((double)random())/((double)MC_RAND_MAX+1) ) +#define randpm1() ( ((double)random()) / (((double)MC_RAND_MAX+1)/2) - 1 ) +#define rand0max(max) ( ((double)random()) / (((double)MC_RAND_MAX+1)/(max)) ) +#define randminmax(min,max) ( rand0max((max)-(min)) + (min) ) + +#define mcPROP_DT(dt) \ + do { \ + mcnlx += mcnlvx*(dt); \ + mcnly += mcnlvy*(dt); \ + mcnlz += mcnlvz*(dt); \ + mcnlt += (dt); \ + } while(0) + +/* ADD: E. Farhi, Aug 6th, 2001 PROP_GRAV_DT propagation with gravitation */ +#define PROP_GRAV_DT(dt, Ax, Ay, Az) \ + do { \ + mcnlx += mcnlvx*dt + Ax*dt*dt/2; \ + mcnly += mcnlvy*dt + Ay*dt*dt/2; \ + mcnlz += mcnlvz*dt + Az*dt*dt/2; \ + mcnlvx += Ax*dt; \ + mcnlvy += Ay*dt; \ + mcnlvz += Az*dt; \ + mcnlt += dt; \ + } while(0) + +#define PROP_DT(dt) \ + do { \ + if(dt < 0) ABSORB; \ + if (mcgravitation) { Coords mcLocG; double mc_gx, mc_gy, mc_gz; \ + mcLocG = rot_apply(ROT_A_CURRENT_COMP, coords_set(0,-9.8,0)); \ + coords_get(mcLocG, &mc_gx, &mc_gy, &mc_gz); \ + PROP_GRAV_DT(dt, mc_gx, mc_gy, mc_gz); } \ + else mcPROP_DT(dt); \ + } while(0) + +#define PROP_Z0 \ + do { \ + if (mcgravitation) { Coords mcLocG; int mc_ret; \ + double mc_dt, mc_gx, mc_gy, mc_gz; \ + mcLocG = rot_apply(ROT_A_CURRENT_COMP, coords_set(0,-9.8,0)); \ + coords_get(mcLocG, &mc_gx, &mc_gy, &mc_gz); \ + mc_ret = plane_intersect_Gfast(&mc_dt, -mc_gz/2, -mcnlvz, -mcnlz); \ + if (mc_ret && mc_dt>0) PROP_GRAV_DT(mc_dt, mc_gx, mc_gy, mc_gz); \ + else ABSORB; }\ + else mcPROP_Z0; \ + } while(0) + + +#define mcPROP_Z0 \ + do { \ + double mc_dt; \ + if(mcnlvz == 0) ABSORB; \ + mc_dt = -mcnlz/mcnlvz; \ + if(mc_dt < 0) ABSORB; \ + mcnlx += mcnlvx*mc_dt; \ + mcnly += mcnlvy*mc_dt; \ + mcnlt += mc_dt; \ + mcnlz = 0; \ + } while(0) + +#define vec_prod(x, y, z, x1, y1, z1, x2, y2, z2) \ + do { \ + double mcvp_tmpx, mcvp_tmpy, mcvp_tmpz; \ + mcvp_tmpx = (y1)*(z2) - (y2)*(z1); \ + mcvp_tmpy = (z1)*(x2) - (z2)*(x1); \ + mcvp_tmpz = (x1)*(y2) - (x2)*(y1); \ + (x) = mcvp_tmpx; (y) = mcvp_tmpy; (z) = mcvp_tmpz; \ + } while(0) + +#define scalar_prod(x1, y1, z1, x2, y2, z2) \ + ((x1)*(x2) + (y1)*(y2) + (z1)*(z2)) + +#define NORM(x,y,z) \ + do { \ + double mcnm_tmp = sqrt((x)*(x) + (y)*(y) + (z)*(z)); \ + if(mcnm_tmp != 0.0) \ + { \ + (x) /= mcnm_tmp; \ + (y) /= mcnm_tmp; \ + (z) /= mcnm_tmp; \ + } \ + } while(0) + +#define rotate(x, y, z, vx, vy, vz, phi, ax, ay, az) \ + do { \ + double mcrt_tmpx = (ax), mcrt_tmpy = (ay), mcrt_tmpz = (az); \ + double mcrt_vp, mcrt_vpx, mcrt_vpy, mcrt_vpz; \ + double mcrt_vnx, mcrt_vny, mcrt_vnz, mcrt_vn1x, mcrt_vn1y, mcrt_vn1z; \ + double mcrt_bx, mcrt_by, mcrt_bz; \ + double mcrt_cos, mcrt_sin; \ + NORM(mcrt_tmpx, mcrt_tmpy, mcrt_tmpz); \ + mcrt_vp = scalar_prod((vx), (vy), (vz), mcrt_tmpx, mcrt_tmpy, mcrt_tmpz); \ + mcrt_vpx = mcrt_vp*mcrt_tmpx; \ + mcrt_vpy = mcrt_vp*mcrt_tmpy; \ + mcrt_vpz = mcrt_vp*mcrt_tmpz; \ + mcrt_vnx = (vx) - mcrt_vpx; \ + mcrt_vny = (vy) - mcrt_vpy; \ + mcrt_vnz = (vz) - mcrt_vpz; \ + vec_prod(mcrt_bx, mcrt_by, mcrt_bz, \ + mcrt_tmpx, mcrt_tmpy, mcrt_tmpz, mcrt_vnx, mcrt_vny, mcrt_vnz); \ + mcrt_cos = cos((phi)); mcrt_sin = sin((phi)); \ + mcrt_vn1x = mcrt_vnx*mcrt_cos + mcrt_bx*mcrt_sin; \ + mcrt_vn1y = mcrt_vny*mcrt_cos + mcrt_by*mcrt_sin; \ + mcrt_vn1z = mcrt_vnz*mcrt_cos + mcrt_bz*mcrt_sin; \ + (x) = mcrt_vpx + mcrt_vn1x; \ + (y) = mcrt_vpy + mcrt_vn1y; \ + (z) = mcrt_vpz + mcrt_vn1z; \ + } while(0) + +Coords coords_set(MCNUM x, MCNUM y, MCNUM z); +Coords coords_get(Coords a, MCNUM *x, MCNUM *y, MCNUM *z); +Coords coords_add(Coords a, Coords b); +Coords coords_sub(Coords a, Coords b); +Coords coords_neg(Coords a); + +void rot_set_rotation(Rotation t, double phx, double phy, double phz); +void rot_mul(Rotation t1, Rotation t2, Rotation t3); +void rot_copy(Rotation dest, Rotation src); +void rot_transpose(Rotation src, Rotation dst); +Coords rot_apply(Rotation t, Coords a); +void mccoordschange(Coords a, Rotation t, double *x, double *y, double *z, + double *vx, double *vy, double *vz, double *time, + double *s1, double *s2); +void mccoordschange_polarisation(Rotation t, + double *sx, double *sy, double *sz); +double mcestimate_error(double N, double p1, double p2); +void mcreadparams(void); + +void mcsetstate(double x, double y, double z, double vx, double vy, double vz, + double t, double sx, double sy, double sz, double p); +void mcgenstate(void); +double randnorm(void); +void normal_vec(double *nx, double *ny, double *nz, + double x, double y, double z); +int box_intersect(double *dt_in, double *dt_out, double x, double y, double z, + double vx, double vy, double vz, double dx, double dy, double dz); +int cylinder_intersect(double *t0, double *t1, double x, double y, double z, + double vx, double vy, double vz, double r, double h); +int sphere_intersect(double *t0, double *t1, double x, double y, double z, + double vx, double vy, double vz, double r); +/* ADD: E. Farhi, Aug 6th, 2001 plane_intersect_Gfast */ +int plane_intersect_Gfast(double *Idt, + double A, double B, double C); +void randvec_target_circle(double *xo, double *yo, double *zo, + double *solid_angle, double xi, double yi, double zi, double radius); +#define randvec_target_sphere randvec_target_circle +void randvec_target_rect_angular(double *xo, double *yo, double *zo, + double *solid_angle, + double xi, double yi, double zi, double height, double width, Rotation A); +void randvec_target_rect(double *xo, double *yo, double *zo, + double *solid_angle, + double xi, double yi, double zi, double height, double width, Rotation A); +void extend_list(int count, void **list, int *size, size_t elemsize); + +void mcset_ncount(double count); +double mcget_ncount(void); +double mcget_run_num(void); +int mcstas_main(int argc, char *argv[]); + +/* file i/o definitions and function prototypes */ + +struct mcformats_struct { + char *Name; /* may also specify: append, partial(hidden), binary */ + char *Extension; + char *Header; + char *Footer; + char *BeginSection; + char *EndSection; + char *AssignTag; + char *BeginData; + char *BeginErrors; + char *BeginNcount; + char *EndData; + char *EndErrors; + char *EndNcount; + }; + +/* in order to be fully portable, the format specifiers must mention each + * fprintf parameters. In case we do not want to use some of them, we must + * set the precision to 0. + * ex: fprintf(f, "printed:%1$s %3$s not printed: %2$.0s\n", "1", "2", "3"); + * such are the joys of ANSI C99 and Single Unix Specification ! + * This 0-precision for unused data is automatically checked in mccheck_format + * Maximum number of positional arguments is NL_RGMAX, which is 9 on System V + * machines (Dec/Compaq/HP). Some more enjoyable stuff !! -> we use pfprintf + */ +/* The mcformat.Name may contain additional keywords: + * partial: will not show the monitor in mcstas.sim, omit the format footer + * (usually the end data), and not print the monitor sum in stdout + */ + +#ifndef MCSTAS_VERSION +#define MCSTAS_VERSION "External Run-time" +#endif + +/* function prototypes */ +void mcuse_format(char *format); +double mcdetector_out(char *cname, double p0, double p1, double p2, char *filename); +double mcdetector_out_0D(char *t, double p0, double p1, double p2, char *c); +double mcdetector_out_1D(char *t, char *xl, char *yl, + char *xvar, double x1, double x2, int n, + double *p0, double *p1, double *p2, char *f, char *c); +double mcdetector_out_2D(char *t, char *xl, char *yl, + double x1, double x2, double y1, double y2, int m, + int n, double *p0, double *p1, double *p2, char *f, char *c); +double mcdetector_out_3D(char *t, char *xl, char *yl, char *zl, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, int m, + int n, int p, double *p0, double *p1, double *p2, char *f, char *c); +void mcheader_out(FILE *f,char *parent, + int m, int n, int p, + char *xlabel, char *ylabel, char *zlabel, char *title, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, + char *filename); /* output header for user data file */ +void mcinfo_simulation(FILE *f, struct mcformats_struct format, + char *pre, char *name); /* used to add sim parameters (e.g. in Res_monitor) */ +void mcsiminfo_init(FILE *f); +void mcsiminfo_close(void); + + +#ifndef FLT_MAX +#define FLT_MAX 3.40282347E+38F /* max decimal value of a "float" */ +#endif + +/* Retrieve component information from the kernel */ +/* Name, position and orientation (both absolute and relative) */ +/* Any component: For "redundancy", see comment by KN */ +#define tmp_name_comp(comp) #comp +#define NAME_COMP(comp) tmp_name_comp(comp) +#define tmp_pos_a_comp(comp) (mcposa ## comp) +#define POS_A_COMP(comp) tmp_pos_a_comp(comp) +#define tmp_pos_r_comp(comp) (mcposr ## comp) +#define POS_R_COMP(comp) tmp_pos_r_comp(comp) +#define tmp_rot_a_comp(comp) (mcrota ## comp) +#define ROT_A_COMP(comp) tmp_rot_a_comp(comp) +#define tmp_rot_r_comp(comp) (mcrotr ## comp) +#define ROT_R_COMP(comp) tmp_rot_r_comp(comp) + +/* Current component */ +#define NAME_CURRENT_COMP NAME_COMP(mccompcurname) +#define INDEX_CURRENT_COMP mccompcurindex +#define POS_A_CURRENT_COMP POS_A_COMP(mccompcurname) +#define POS_R_CURRENT_COMP POS_R_COMP(mccompcurname) +#define ROT_A_CURRENT_COMP ROT_A_COMP(mccompcurname) +#define ROT_R_CURRENT_COMP ROT_R_COMP(mccompcurname) + +#define SCATTERED mcScattered + +#endif /* MCSTAS_R_H */ +/* End of file "mcstas-r.h". */ + +#line 546 "dmcafter.c" + +#line 1 "mcstas-r.c" +/******************************************************************************* +* +* McStas, neutron ray-tracing package +* Copyright 1997-2002, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* Runtime: share/mcstas-r.c +* +* %Identification +* Written by: KN +* Date: Aug 29, 1997 +* Release: McStas 1.6 +* Version: 1.7 +* +* Runtime system for McStas. +* Embedded within instrument in runtime mode. +* +* Usage: Automatically embbeded in the c code whenever required. +* +* $Id: dmcafter.c,v 1.1 2007/01/30 03:19:43 koennecke Exp $ +* +* $Log: dmcafter.c,v $ +* Revision 1.1 2007/01/30 03:19:43 koennecke +* - Fixed state monitor eclipse commit problems. Siiiiiiiggggghhhhhh! +* +* Revision 1.85 2004/03/05 17:43:47 farhi +* Default instr parameters are now correctly handled in all instrument usage cases. +* +* Revision 1.84 2004/03/03 13:41:23 pkwi +* Corrected error in relation to instrument default values: 0's were used in all cases. +* +* Revision 1.83 2004/02/26 12:53:27 farhi +* Scilab format now enables more than one monitor file for a single component +* (e.g. Monitor_nD with multiple detectors). +* +* Revision 1.82 2004/02/23 12:48:42 farhi +* Additional check for default value and unset parameters +* +* Revision 1.81 2004/02/19 14:42:52 farhi +* Experimental Octave/OpenGENIE output format (for ISIS) +* +* Revision 1.80 2004/01/23 16:14:12 pkwi +* Updated version of Mersenne Twister algorithm. make test'ed ok on my machine. +* +* Revision 1.79 2003/11/28 18:08:32 farhi +* Corrected error for IDL import +* +* Revision 1.77 2003/10/22 15:51:26 farhi +* -i also displays default parameter values (if any), which may be +* read by mcgui for init of Run Simulation dialog +* +* Revision 1.76 2003/10/22 09:18:00 farhi +* Solved name conflict problem for Matlab/Scilab by adding 'mc_' prefix +* to all component/file field names. Works ok for both, and also in binary. +* +* Revision 1.75 2003/10/21 14:08:12 pkwi +* Rectangular focusing improved: Renamed randvec_target_rect to randvec_target_rect_angular. Wrote new randvec_target_rect routine, w/h in metres. Both routines use use component orientation (ROT_A_CURRENT_COMP) as input. +* +* Modifications to Res_sample and V_sample to match new features of the runtime. +* +* Revision 1.74 2003/10/21 11:54:48 farhi +* instrument default parameter value handling now works better +* either from args or from mcreadparam (prompt) +* +* Revision 1.73 2003/09/05 08:59:17 farhi +* added INSTRUMENT parameter default value grammar +* mcinputtable now has also default values +* mcreadpar now uses default values if parameter not given +* extended instr_formal parameter struct +* extended mcinputtable structure type +* +* Revision 1.72 2003/08/26 12:32:43 farhi +* Corrected 4PI random vector generation to retain initial vector length +* +* Revision 1.71 2003/08/20 09:25:00 farhi +* Add the instrument Source tag in scan files (origin of data !) +* +* Revision 1.70 2003/08/12 13:35:52 farhi +* displays known signals list in instrument help (-h) +* +* Revision 1.68 2003/06/17 14:21:54 farhi +* removed 'clear %4$s' in Scilab/Matlab 'end of section' format which +* caused pb when comp_name == file_name +* +* Revision 1.67 2003/06/12 10:22:00 farhi +* -i show info as McStas format, --info use MCSTAS_FORMAT or --format setting +* +* Revision 1.66 2003/06/10 11:29:58 pkwi +* Corrected multiple parse errors: Added two missing sets of curly brackets { } in parameter parsing function. +* +* Revision 1.65 2003/06/05 09:25:59 farhi +* restore header support in data files when --format option found +* +* Revision 1.64 2003/05/26 10:21:00 farhi +* Correct core dump for instrument STRING parameters in 'string printer' +* +* Revision 1.63 2003/05/20 11:54:38 farhi +* make sighandler not restart SAVE when already saving (USR2) +* +* Revision 1.62 2003/05/16 12:13:03 farhi +* added path rehash for Matlab mcload_inline +* +* Revision 1.61 2003/04/25 16:24:44 farhi +* corrected 4PI scattering from randvec_* functions causing mcdisplay to crash +* when using (0,0,0) vector for coordinate transformations +* +* Revision 1.60 2003/04/16 14:55:47 farhi +* Major change in saving data so that it's shown just like PGPLOT +* and axes+labels should follow data orientation (if transposed) +* when in binary mode, sets -a as default. Use +a to force text header +* +* Revision 1.59 2003/04/09 15:51:33 farhi +* Moved MCSTAS_FORMAT define +* +* Revision 1.58 2003/04/08 18:55:56 farhi +* Made XML format more NeXus compliant +* +* Revision 1.57 2003/04/07 11:50:50 farhi +* Extended the way mcplot:plotter is assigned. Set --portable ok +* Handle Scilab:Tk and ~GTk menu (shifted) +* Updated help in mcrun and mcstas-r.c +* +* Revision 1.56 2003/04/04 18:36:12 farhi +* Corrected $ and % chars for IDL format, conflicting with pfprintf (Dec/SGI) +* +* Revision 1.55 2003/04/04 15:11:08 farhi +* Use MCSTAS_FORMAT env var for default plotter, or use mcstas_config +* Corrected strlen(NULL pointer) for getenv(MCSTAS_FORMAT)==NULL +* +* Revision 1.54 2003/04/04 14:26:25 farhi +* Managed --no-runtime to work. Use MCSTAS_FORMAT env/define for default format +* Make --no-output-files still print out the integrated counts +* +* Revision 1.53 2003/02/18 09:10:52 farhi +* Just changed a message (warning for -a flag binary) +* +* Revision 1.51 2003/02/11 12:28:46 farhi +* Variouxs bug fixes after tests in the lib directory +* mcstas_r : disable output with --no-out.. flag. Fix 1D McStas output +* read_table:corrected MC_SYS_DIR -> MCSTAS define +* monitor_nd-lib: fix Log(signal) log(coord) +* HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample +* Progress_bar: precent -> percent parameter +* CS: ---------------------------------------------------------------------- +* +* Revision 1.50 2003/02/06 14:25:05 farhi +* Made --no-output-files work again and 1D McStas data 4 columns again +* +* : ---------------------------------------------------------------------- +* +* Revision 1.7 2002/10/19 22:46:21 ef +* gravitation for all with -g. Various output formats. +* +* Revision 1.6 2002/09/17 12:01:21 ef +* changed randvec_target_sphere to circle +* added randvec_target_rect +* +* Revision 1.5 2002/09/03 19:48:01 ef +* corrected randvec_target_sphere. created target_rect. +* +* Revision 1.4 2002/09/02 18:59:05 ef +* moved adapt_tree functions to independent lib. Updated sighandler. +* +* Revision 1.3 2002/08/28 11:36:37 ef +* Changed to lib/share/c code +* +* Revision 1.2 2001/10/10 11:36:37 ef +* added signal handler +* +* Revision 1.1 1998/08/29 11:36:37 kn +* Initial revision +* +*******************************************************************************/ + +#include +#include +#include +#include + +#ifndef MCSTAS_R_H +#include "mcstas-r.h" +#endif + + +#ifdef MC_ANCIENT_COMPATIBILITY +int mctraceenabled = 0; +int mcdefaultmain = 0; +#endif + +static long mcseed = 0; +mcstatic int mcdotrace = 0; +static int mcascii_only = 0; +static int mcdisable_output_files = 0; +static int mcsingle_file= 0; +mcstatic int mcgravitation = 0; +static long mcstartdate = 0; + +mcstatic FILE *mcsiminfo_file = NULL; +static char *mcdirname = NULL; +static char *mcsiminfo_name= "mcstas"; +mcstatic char mcsig_message[256]; /* ADD: E. Farhi, Sep 20th 2001 */ + +/* Multiple output format support. ========================================== */ + +#define mcNUMFORMATS 8 +#ifndef MCSTAS_FORMAT +#define MCSTAS_FORMAT "McStas" /* default format */ +#endif + +mcstatic struct mcformats_struct mcformat; + +mcstatic struct mcformats_struct mcformats[mcNUMFORMATS] = { + { "McStas", "sim", + "%1$sFormat: %4$s file\n" + "%1$sURL: http://neutron.risoe.dk/\n" + "%1$sEditor: %6$s\n" + "%1$sCreator:%2$s simulation (McStas " MCSTAS_VERSION ")\n" + "%1$sDate: Simulation started (%8$li) %5$s\n" + "%1$sFile: %3$s\n", + "%1$sEndDate:%5$s\n", + "%1$sbegin %2$s\n", + "%1$send %2$s\n", + "%1$s%3$s: %4$s\n", + "", + "%1$sErrors [%2$s/%4$s]: \n", + "%1$sEvents [%2$s/%4$s]: \n", + "", "", "" }, + { "Scilab", "sci", + "function mc_%7$s = get_%7$s(p)\n" + "// %4$s function issued from McStas on %5$s\n" + "// McStas simulation %2$s: %3$s" MC_PATHSEP_S "%4$s\n" + "// import data using exec('%7$s.sci',-1); s=get_%7$s('plot');\nmode(-1); //silent execution\n" + "if argn(2) > 0, p=1; else p=0; end\n" + "mc_%7$s = struct();\n" + "mc_%7$s.Format ='%4$s';\n" + "mc_%7$s.URL ='http://neutron.risoe.dk';\n" + "mc_%7$s.Editor ='%6$s';\n" + "mc_%7$s.Creator='%2$s McStas " MCSTAS_VERSION " simulation';\n" + "mc_%7$s.Date =%8$li; // for getdate\n" + "mc_%7$s.File ='%3$s';\n", + "mc_%7$s.EndDate=%8$li; // for getdate\nendfunction\n" + "function d=mcload_inline(d)\n" + "// local inline func to load data\n" + "execstr(['S=['+part(d.type,10:(length(d.type)-1))+'];']);\n" + "if ~length(d.data)\n" + " if ~length(strindex(d.format, 'binary'))\n" + " exec(d.filename,-1);p=d.parent;\n" + " if ~execstr('d2='+d.func+'();','errcatch'),d=d2; d.parent=p;end\n" + " else\n" + " if length(strindex(d.format, 'float')), t='f';\n" + " elseif length(strindex(d.format, 'double')), t='d';\n" + " else return; end\n" + " fid=mopen(d.filename, 'rb');\n" + " pS = prod(S);\n" + " x = mget(3*pS, t, fid);\n" + " d.data =matrix(x(1:pS), S);\n" + " if length(x) >= 3*pS,\n" + " d.errors=matrix(x((pS+1):(2*pS)), S);\n" + " d.events=matrix(x((2*pS+1):(3*pS)), S);end\n" + " mclose(fid);\n" + " return\n" + " end\n" + "end\n" + "endfunction\n" + "function d=mcplot_inline(d,p)\n" + "// local inline func to plot data\n" + "if ~length(strindex(d.type,'0d')), d=mcload_inline(d); end\n" + "if ~p, return; end;\n" + "execstr(['l=[',d.xylimits,'];']); S=size(d.data);\n" + "t1=['['+d.parent+'] '+d.filename+': '+d.title];t = [t1;[' '+d.variables+'=['+d.values+']'];[' '+d.signal];[' '+d.statistics]];\n" + "mprintf('%%s\\n',t(:));\n" + "if length(strindex(d.type,'0d')),return;\n" + "else\nw=winsid();if length(w),w=w($)+1; else w=0; end\n" + "xbasr(w); xset('window',w);\n" + "if length(strindex(d.type,'2d'))\n" + " d.x=linspace(l(1),l(2),S(2)); d.y=linspace(l(3),l(4),S(1)); z=d.data;\n" + " xlab=d.xlabel; ylab=d.ylabel; x=d.x; y=d.y;\n" + " fz=max(abs(z));fx=max(abs(d.x));fy=max(abs(d.y));\n" + " if fx>0,fx=round(log10(fx)); x=x/10^fx; xlab=xlab+' [*10^'+string(fx)+']'; end\n" + " if fy>0,fy=round(log10(fy)); y=y/10^fy; ylab=ylab+' [*10^'+string(fy)+']'; end\n" + " if fz>0,fz=round(log10(fz)); z=z/10^fz; t1=t1+' [*10^'+string(fz)+']'; end\n" + " xset('colormap',hotcolormap(64));\n" + " plot3d1(x,y,z',90,0,xlab+'@'+ylab+'@'+d.zlabel); xtitle(t);\n" + "else\nd.x=linspace(l(1),l(2),max(S));\n" + " plot2d(d.x,d.data);xtitle(t,d.xlabel,d.ylabel);end\nend\n" + "xname(t1);\nendfunction\n" + "mc_%7$s=get_%7$s();\n", + "// Section %2$s [%3$s] (level %7$d)\n" + "%1$st=[]; execstr('t=mc_%4$s.class','errcatch'); if ~length(t), mc_%4$s = struct(); end; mc_%4$s.class = '%2$s';", + "%1$smc_%6$s.mc_%4$s = 0; mc_%6$s.mc_%4$s = mc_%4$s;\n", + "%1$smc_%2$s.%3$s = '%4$s';\n", + "%1$smc_%2$s.func='get_%2$s';\n%1$smc_%2$s.data = [ ", + "%1$serrors = [ ", + "%1$sevents = [ ", + " ]; // end of data\n%1$sif length(mc_%2$s.data) == 0, single_file=0; else single_file=1; end\n%1$smc_%2$s=mcplot_inline(mc_%2$s,p);\n", + " ]; // end of errors\n%1$sif single_file == 1, mc_%2$s.errors=errors; end\n", + " ]; // end of events\n%1$sif single_file == 1, mc_%2$s.events=events; end\n"}, + { "Matlab", "m", + "function mc_%7$s = get_%7$s(p)\n" + "%% %4$s function issued from McStas on %5$s\n" + "%% McStas simulation %2$s: %3$s\n" + "%% import data using s=%7$s('plot');\n" + "if nargout == 0 | nargin > 0, p=1; else p=0; end\n" + "mc_%7$s.Format ='%4$s';\n" + "mc_%7$s.URL ='http://neutron.risoe.dk';\n" + "mc_%7$s.Editor ='%6$s';\n" + "mc_%7$s.Creator='%2$s McStas " MCSTAS_VERSION " simulation';\n" + "mc_%7$s.Date =%8$li; %% for datestr\n" + "mc_%7$s.File ='%3$s';\n", + "mc_%7$s.EndDate=%8$li; %% for datestr\n" + "function d=mcload_inline(d)\n" + "%% local inline function to load data\n" + "S=d.type; eval(['S=[ ' S(10:(length(S)-1)) ' ];']);\n" + "if isempty(d.data)\n" + " if ~length(findstr(d.format, 'binary'))\n" + " copyfile(d.filename,[d.func,'.m']);p=d.parent;path(path);\n" + " eval(['d=',d.func,';']);d.parent=p;delete([d.func,'.m']);\n" + " else\n" + " if length(findstr(d.format, 'float')), t='single';\n" + " elseif length(findstr(d.format, 'double')), t='double';\n" + " else return; end\n" + " if length(S) == 1, S=[S 1]; end\n" + " fid=fopen(d.filename, 'r');\n" + " pS = prod(S);\n" + " x = fread(fid, 3*pS, t);\n" + " d.data =reshape(x(1:pS), S);\n" + " if prod(size(x)) >= 3*pS,\n" + " d.errors=reshape(x((pS+1):(2*pS)), S);\n" + " d.events=reshape(x((2*pS+1):(3*pS)), S);end\n" + " fclose(fid);\n" + " return\n" + " end\n" + "end\n" + "return;\n" + "function d=mcplot_inline(d,p)\n" + "%% local inline function to plot data\n" + "if isempty(findstr(d.type,'0d')), d=mcload_inline(d); end\nif ~p, return; end;\n" + "eval(['l=[',d.xylimits,'];']); S=size(d.data);\n" + "t1=['[',d.parent,'] ',d.filename,': ',d.title];t = strvcat(t1,[' ',d.variables,'=[',d.values,']'],[' ',d.signal],[' ',d.statistics]);\n" + "disp(t);\n" + "if ~isempty(findstr(d.type,'0d')), return; end\n" + "figure; if ~isempty(findstr(d.type,'2d'))\n" + "d.x=linspace(l(1),l(2),S(2)); d.y=linspace(l(3),l(4),S(1));\n" + "surface(d.x,d.y,d.data);\n" + "else\nd.x=linspace(l(1),l(2),max(S));\nplot(d.x,d.data);end\n" + "xlabel(d.xlabel); ylabel(d.ylabel); title(t); axis tight;" + "set(gca,'position',[.18,.18,.7,.65]); set(gcf,'name',t1);grid on;\n" + "if ~isempty(findstr(d.type,'2d')), colorbar; end\n", + "%% Section %2$s [%3$s] (level %7$d)\n" + "mc_%4$s.class = '%2$s';", + "mc_%6$s.mc_%4$s = mc_%4$s;\n", + "%1$smc_%2$s.%3$s = '%4$s';\n", + "%1$smc_%2$s.func='%2$s';\n%1$smc_%2$s.data = [ ", + "%1$serrors = [ ", + "%1$sevents = [ ", + " ]; %% end of data\nif length(mc_%2$s.data) == 0, single_file=0; else single_file=1; end\nmc_%2$s=mcplot_inline(mc_%2$s,p);\n", + " ]; %% end of errors\nif single_file, mc_%2$s.errors=errors; end\n", + " ]; %% end of events\nif single_file, mc_%2$s.events=events; end\n"}, + { "IDL", "pro", + "function mcload_inline,d\n" + "; local inline function to load external data\n" + "S=d.type & a=execute('S=long(['+strmid(S,9,strlen(S)-10)+'])')\n" + "if strpos(d.format, 'binary') lt 0 then begin\n" + " p=d.parent\n" + " x=read_binary(d.filename)\n" + " get_lun, lun\n" + " openw,lun,d.func+'.pro'\n" + " writeu, lun,x\n" + " free_lun,lun\n" + " resolve_routine, d.func, /is_func, /no\n" + " d=call_function(d.func)\n" + "endif else begin\n" + " if strpos(d.format, 'float') ge 0 then t=4 $\n" + " else if strpos(d.format, 'double') ge 0 then t=5 $\n" + " else return,d\n" + " x=read_binary(d.filename, data_type=t)\n" + " pS=n_elements(S)\nif pS eq 1 then pS=long(S) $\n" + " else if pS eq 2 then pS=long(S(0)*S(1)) $\n" + " else pS=long(S(0)*S(1)*S(2))\n" + " pS=pS(0)\nstv,d,'data',reform(x(0:(pS-1)),S)\n" + " d.data=transpose(d.data)\n" + " if n_elements(x) ge long(3*pS) then begin\n" + " stv,d,'errors',reform(x(pS:(2*pS-1)),S)\n" + " stv,d,'events',reform(x((2*pS):(3*pS-1)),S)\n" + " d.errors=transpose(d.errors)\n" + " d.events=transpose(d.events)\n" + " endif\n" + "endelse\n" + "return,d\nend ; FUN load\n" + "function mcplot_inline,d,p\n" + "; local inline function to plot data\n" + "if size(d.data,/typ) eq 7 and strpos(d.type,'0d') lt 0 then d=mcload_inline(d)\n" + "if p eq 0 or strpos(d.type,'0d') ge 0 then return, d\n" + "S=d.type & a=execute('S=long(['+strmid(S,9,strlen(S)-10)+'])')\n" + "stv,d,'data',reform(d.data,S,/over)\n" + "if total(strpos(tag_names(d),'ERRORS')+1) gt 0 then begin\n" + " stv,d,'errors',reform(d.errors,S,/over)\n" + " stv,d,'events',reform(d.events,S,/over)\n" + "endif\n" + "d.xylimits=strjoin(strsplit(d.xylimits,' ',/extract),',') & a=execute('l=['+d.xylimits+']')\n" + "t1='['+d.parent+'] '+d.filename+': '+d.title\n" + "t=[t1,' '+d.variables+'=['+d.values+']',' '+d.signal,' '+d.statistics]\n" + "print,t\n" + "if strpos(d.type,'0d') ge 0 then return,d\n" + "d.xlabel=strjoin(strsplit(d.xlabel,'`!\"£^&*()-+=|\\,.<>/?@''~#{[}]',/extract),'_')\n" + "d.ylabel=strjoin(strsplit(d.ylabel,'`!\"£^&*()-+=|\\,.<>/?@''~#{[}]',/extract),'_')\n" + "stv,d,'x',l(0)+indgen(S(0))*(l(1)-l(0))/S(0)\n" + "if strpos(d.type,'2d') ge 0 then begin\n" + " name={DATA:d.func,IX:d.xlabel,IY:d.ylabel}\n" + " stv,d,'y',l(2)+indgen(S(1))*(l(3)-l(2))/S(1)\n" + " live_surface,d.data,xindependent=d.x,yindependent=d.y,name=name,reference_out=Win\n" + "endif else begin\n" + " name={DATA:d.func,I:d.xlabel}\n" + " live_plot,d.data,independent=d.x,name=name,reference_out=Win\n" + "endelse\n" + "live_text,t,Window_In=Win.Win,location=[0.3,0.9]\n" + "return,d\nend ; FUN plot\n" + "pro stv,S,T,V\n" + "; procedure set-tag-value that does S.T=V\n" + "sv=size(V)\n" + "T=strupcase(T)\n" + "TL=strupcase(tag_names(S))\n" + "id=where(TL eq T)\n" + "sz=[0,0,0]\n" + "vd=n_elements(sv)-2\n" + "type=sv[vd]\n" + "if id(0) ge 0 then d=execute('sz=SIZE(S.'+T+')')\n" + "if (sz(sz(0)+1) ne sv(sv(0)+1)) or (sz(0) ne sv(0)) $\n" + " or (sz(sz(0)+2) ne sv(sv(0)+2)) $\n" + " or type eq 8 then begin\n" + " ES = ''\n" + " for k=0,n_elements(TL)-1 do begin\n" + " case TL(k) of\n" + " T:\n" + " else: ES=ES+','+TL(k)+':S.'+TL(k)\n" + " endcase\n" + " endfor\n" + " d=execute('S={'+T+':V'+ES+'}')\n" + "endif else d=execute('S.'+T+'=V')\n" + "end ; PRO stv\n" + "function %7$s,plot=plot\n" + "; %4$s function issued from McStas on %5$s\n" + "; McStas simulation %2$s: %3$s\n" + "; import using s=%7$s(/plot)\n" + "if keyword_set(plot) then p=1 else p=0\n" + "%7$s={Format:'%4$s',URL:'http://neutron.risoe.dk'," + "Editor:'%6$s',$\n" + "Creator:'%2$s McStas " MCSTAS_VERSION " simulation',$\n" + "Date:%8$li," + "File:'%3$s'}\n", + "stv,%7$s,'EndDate',%8$li ; for systime\nreturn, %7$s\nend\n", + "; Section %2$s [%3$s] (level %7$d)\n" + "%1$s%4$s={class:'%2$s'}\n", + "%1$sstv,%6$s,'%4$s',%4$s\n", + "%1$sstv,%2$s,'%3$s','%4$s'\n", + "%1$sstv,%2$s,'func','%2$s' & data=[ ", + "%1$sif single_file ne 0 then begin errors=[ ", + "%1$sif single_file ne 0 then begin events=[ ", + " ]\n%1$sif size(data,/type) eq 7 then single_file=0 else single_file=1\n" + "%1$sstv,%2$s,'data',data & data=0 & %2$s=mcplot_inline(%2$s,p)\n", + " ]\n%1$sstv,%2$s,'errors',reform(errors,%14$d,%15$d,/over) & errors=0\n%1$sendif\n", + " ]\n%1$sstv,%2$s,'events',reform(events,%14$d,%15$d,/over) & events=0\n%1$sendif\n\n"}, + { "XML", "xml", + "\n\n" + "\n" + "%5$s\n", + "%5$s\n\n", + "%1$s\n", + "%1$s\n", + "%1$s<%3$s>%4$s\n", + "%1$s<%6$s long_name=\"%5$s\" axis=\"1\" primary=\"1\" min=\"%17$g\"" + " max=\"%18$g\" dims=\"%14$d\" range=\"1\">\n" + "%1$s<%8$s long_name=\"%7$s\" axis=\"2\" primary=\"1\" min=\"%19$g\"" + " max=\"%20$g\" dims=\"%15$d\" range=\"1\">\n" + "%1$s<%10$s long_name=\"%9$s\" axis=\"3\" primary=\"1\" min=\"%21$g\"" + " max=\"%22$g\" dims=\"%16$d\" range=\"1\">\n" + "%1$s", + "%1$s", "%1$s", + "%1$s\n", "%1$s\n", "%1$s\n"}, + { "HTML", "html", + "\n" + "\n" + "\n" + "\n" + "[McStas %2$s]%3$s\n" + "

" + "McStas simulation %2$s: %3$s


\n" + "This simulation report was automatically created by" + " McStas " MCSTAS_VERSION "
\n" + "
User:   %6$s
\n" + "%1$sCreator: %2$s McStas simulation
\n" + "%1$sDate: (%8$li) %5$s
\n", + "EndDate: (%8$li) %5$s
\n", + "%1$s%2$s %3$s " + "[child of %5$s]
\n" + "%1$sAssociated data file %3$s
\n" + "%1$sAssociated %2$s image %3$s.png
(when available)\n" + "%1$s\"%2$s

\n", + "[end of %2$s %3$s]
\n", + "%1$s%3$s: %4$s
\n", + "%1$sDATA
\n", + "%1$sERRORS
\n","%1$sEVENTS
\n", + "%1$sEnd of DATA
\n", "%1$sEnd of ERRORS
\n", "%1$sEnd of EVENTS
\n"}, + { "OpenGENIE", "gcl", + "PROCEDURE get_%7$s\n" + "RESULT %7$s\n" + "# %4$s procedure issued from McStas on %5$s\n" + "# McStas simulation %2$s: %3$s" MC_PATHSEP_S "%4$s\n" + "# import data using s=get_%7$s();\n" + "%7$s = fields();\n" + "%7$s.Format =\"%4$s\";\n" + "%7$s.URL =\"http://neutron.risoe.dk\";\n" + "%7$s.Editor =\"%6$s\";\n" + "%7$s.Creator=\"%2$s McStas " MCSTAS_VERSION " simulation\";\n" + "%7$s.Date =%8$li;\n" + "%7$s.File =\"%3$s\";\n", + "%7$s.EndDate=%8$li;\nENDPROCEDURE\n", + "# Section %2$s [%3$s] (level %7$d)\n" + "%1$s%4$s = fields(); %4$s.class = \"%2$s\";", + "%1$s%6$s.%4$s = %4$s; free \"%4$s\";\n", + "%1$s%2$s.%3$s = \"%4$s\";\n", + "%1$s%2$s.func=\"get_%2$s\";\n%1$s%2$s.data = [ ", + "%1$sIF (single_file = 1); %2$s.errors = [ ", + "%1$sIF (single_file = 1); %2$s.ncount = [ ", + " ] array(%14$d,%15$d); # end of data\nIF (length(%2$s.data) = 0); single_file=0; ELSE single_file=1; ENDIF\n%2$s=mcplot_inline(%2$s,p);\n", + " ] array(%14$d,%15$d); # end of errors\nENDIF\n", + " ] array(%14$d,%15$d); # end of ncount\nENDIF\n"}, + { "Octave", "m", + "function mc_%7$s = get_%7$s(p)\n" + "%% %4$s function issued from McStas on %5$s\n" + "%% McStas simulation %2$s: %3$s\n" + "%% import data using s=%7$s('plot');\n" + "if nargin > 0, p=1; else p=0; end\n" + "mc_%7$s.Format ='%4$s';\n" + "mc_%7$s.URL ='http://neutron.risoe.dk';\n" + "mc_%7$s.Editor ='%6$s';\n" + "mc_%7$s.Creator='%2$s McStas " MCSTAS_VERSION " simulation';\n" + "mc_%7$s.Date =%8$li; %% for datestr\n" + "mc_%7$s.File ='%3$s';\n", + "mc_%7$s.EndDate=%8$li; %% for datestr\nendfunction\n" + "if exist('mcload_inline'), return; end\n" + "function d=mcload_inline(d)\n" + "%% local inline function to load data\n" + "S=d.type; eval(['S=[ ' S(10:(length(S)-1)) ' ];']);\n" + "if isempty(d.data)\n" + " if ~length(findstr(d.format, 'binary'))\n" + " source(d.filename);p=d.parent;\n" + " eval(['d=get_',d.func,';']);d.parent=p;\n" + " else\n" + " if length(findstr(d.format, 'float')), t='float';\n" + " elseif length(findstr(d.format, 'double')), t='double';\n" + " else return; end\n" + " if length(S) == 1, S=[S 1]; end\n" + " fid=fopen(d.filename, 'r');\n" + " pS = prod(S);\n" + " x = fread(fid, 3*pS, t);\n" + " d.data =reshape(x(1:pS), S);\n" + " if prod(size(x)) >= 3*pS,\n" + " d.errors=reshape(x((pS+1):(2*pS)), S);\n" + " d.events=reshape(x((2*pS+1):(3*pS)), S);end\n" + " fclose(fid);\n" + " return\n" + " end\n" + "end\n" + "return;\nendfunction\n\n" + "function d=mcplot_inline(d,p)\n" + "%% local inline function to plot data\n" + "if isempty(findstr(d.type,'0d')), d=mcload_inline(d); end\nif ~p, return; end;\n" + "eval(['l=[',d.xylimits,'];']); S=size(d.data);\n" + "t1=['[',d.parent,'] ',d.filename,': ',d.title];t = strcat(t1,[' ',d.variables,'=[',d.values,']'],[' ',d.signal],[' ',d.statistics]);\n" + "disp(t);\n" + "if ~isempty(findstr(d.type,'0d')), return; end\n" + "xlabel(d.xlabel); ylabel(d.ylabel); title(t);" + "figure; if ~isempty(findstr(d.type,'2d'))\n" + "d.x=linspace(l(1),l(2),S(2)); d.y=linspace(l(3),l(4),S(1));\n" + "mesh(d.x,d.y,d.data);\n" + "else\nd.x=linspace(l(1),l(2),max(S));\nplot(d.x,d.data);end\nendfunction\n", + "%% Section %2$s [%3$s] (level %7$d)\n" + "mc_%4$s.class = '%2$s';", + "mc_%6$s.mc_%4$s = mc_%4$s;\n", + "%1$smc_%2$s.%3$s = '%4$s';\n", + "%1$smc_%2$s.func='%2$s';\n%1$smc_%2$s.data = [ ", + "%1$serrors = [ ", + "%1$sevents = [ ", + " ]; %% end of data\nif length(mc_%2$s.data) == 0, single_file=0; else single_file=1; end\nmc_%2$s=mcplot_inline(mc_%2$s,p);\n", + " ]; %% end of errors\nif single_file, mc_%2$s.errors=errors; end\n", + " ]; %% end of events\nif single_file, mc_%2$s.events=events; end\n"} + }; + +/* MCDISPLAY support. ======================================================= */ + +void mcdis_magnify(char *what){ + printf("MCDISPLAY: magnify('%s')\n", what); +} + +void mcdis_line(double x1, double y1, double z1, + double x2, double y2, double z2){ + printf("MCDISPLAY: multiline(2,%g,%g,%g,%g,%g,%g)\n", + x1,y1,z1,x2,y2,z2); +} + +void mcdis_multiline(int count, ...){ + va_list ap; + double x,y,z; + + printf("MCDISPLAY: multiline(%d", count); + va_start(ap, count); + while(count--) + { + x = va_arg(ap, double); + y = va_arg(ap, double); + z = va_arg(ap, double); + printf(",%g,%g,%g", x, y, z); + } + va_end(ap); + printf(")\n"); +} + +void mcdis_circle(char *plane, double x, double y, double z, double r){ + printf("MCDISPLAY: circle('%s',%g,%g,%g,%g)\n", plane, x, y, z, r); +} + +/* coordinates handling ===================================================== */ + +/******************************************************************************* +* Since we use a lot of geometric calculations using Cartesian coordinates, +* we collect some useful routines here. However, it is also permissible to +* work directly on the underlying struct coords whenever that is most +* convenient (that is, the type Coords is not abstract). +* +* Coordinates are also used to store rotation angles around x/y/z axis. +* +* Since coordinates are used much like a basic type (such as double), the +* structure itself is passed and returned, rather than a pointer. +* +* At compile-time, the values of the coordinates may be unknown (for example +* a motor position). Hence coordinates are general expressions and not simple +* numbers. For this we used the type Coords_exp which has three CExp +* fields. For runtime (or calculations possible at compile time), we use +* Coords which contains three double fields. +*******************************************************************************/ + +/* Assign coordinates. */ +Coords +coords_set(MCNUM x, MCNUM y, MCNUM z) +{ + Coords a; + + a.x = x; + a.y = y; + a.z = z; + return a; +} + +Coords +coords_get(Coords a, MCNUM *x, MCNUM *y, MCNUM *z) +{ + *x = a.x; + *y = a.y; + *z = a.z; + return a; +} + +/* Add two coordinates. */ +Coords +coords_add(Coords a, Coords b) +{ + Coords c; + + c.x = a.x + b.x; + c.y = a.y + b.y; + c.z = a.z + b.z; + return c; +} + +/* Subtract two coordinates. */ +Coords +coords_sub(Coords a, Coords b) +{ + Coords c; + + c.x = a.x - b.x; + c.y = a.y - b.y; + c.z = a.z - b.z; + return c; +} + +/* Negate coordinates. */ +Coords +coords_neg(Coords a) +{ + Coords b; + + b.x = -a.x; + b.y = -a.y; + b.z = -a.z; + return b; +} + +/******************************************************************************* +* The Rotation type implements a rotation transformation of a coordinate +* system in the form of a double[3][3] matrix. +* +* Contrary to the Coords type in coords.c, rotations are passed by +* reference. Functions that yield new rotations do so by writing to an +* explicit result parameter; rotations are not returned from functions. The +* reason for this is that arrays cannot by returned from functions (though +* structures can; thus an alternative would have been to wrap the +* double[3][3] array up in a struct). Such are the ways of C programming. +* +* A rotation represents the tranformation of the coordinates of a vector when +* changing between coordinate systems that are rotated with respect to each +* other. For example, suppose that coordinate system Q is rotated 45 degrees +* around the Z axis with respect to coordinate system P. Let T be the +* rotation transformation representing a 45 degree rotation around Z. Then to +* get the coordinates of a vector r in system Q, apply T to the coordinates +* of r in P. If r=(1,0,0) in P, it will be (sqrt(1/2),-sqrt(1/2),0) in +* Q. Thus we should be careful when interpreting the sign of rotation angles: +* they represent the rotation of the coordinate systems, not of the +* coordinates (which has opposite sign). +*******************************************************************************/ + +/******************************************************************************* +* Get transformation for rotation first phx around x axis, then phy around y, +* then phz around z. +*******************************************************************************/ +void +rot_set_rotation(Rotation t, double phx, double phy, double phz) +{ + double cx = cos(phx); + double sx = sin(phx); + double cy = cos(phy); + double sy = sin(phy); + double cz = cos(phz); + double sz = sin(phz); + + t[0][0] = cy*cz; + t[0][1] = sx*sy*cz + cx*sz; + t[0][2] = sx*sz - cx*sy*cz; + t[1][0] = -cy*sz; + t[1][1] = cx*cz - sx*sy*sz; + t[1][2] = sx*cz + cx*sy*sz; + t[2][0] = sy; + t[2][1] = -sx*cy; + t[2][2] = cx*cy; +} + +/******************************************************************************* +* Matrix multiplication of transformations (this corresponds to combining +* transformations). After rot_mul(T1, T2, T3), doing T3 is equal to doing +* first T2, then T1. +* Note that T3 must not alias (use the same array as) T1 or T2. +*******************************************************************************/ +void +rot_mul(Rotation t1, Rotation t2, Rotation t3) +{ + int i,j; + + for(i = 0; i < 3; i++) + for(j = 0; j < 3; j++) + t3[i][j] = t1[i][0]*t2[0][j] + t1[i][1]*t2[1][j] + t1[i][2]*t2[2][j]; +} + +/******************************************************************************* +* Copy a rotation transformation (needed since arrays cannot be assigned in C). +*******************************************************************************/ +void +rot_copy(Rotation dest, Rotation src) +{ + dest[0][0] = src[0][0]; + dest[0][1] = src[0][1]; + dest[0][2] = src[0][2]; + dest[1][0] = src[1][0]; + dest[1][1] = src[1][1]; + dest[1][2] = src[1][2]; + dest[2][0] = src[2][0]; + dest[2][1] = src[2][1]; + dest[2][2] = src[2][2]; +} + +void +rot_transpose(Rotation src, Rotation dst) +{ + dst[0][0] = src[0][0]; + dst[0][1] = src[1][0]; + dst[0][2] = src[2][0]; + dst[1][0] = src[0][1]; + dst[1][1] = src[1][1]; + dst[1][2] = src[2][1]; + dst[2][0] = src[0][2]; + dst[2][1] = src[1][2]; + dst[2][2] = src[2][2]; +} + +Coords +rot_apply(Rotation t, Coords a) +{ + Coords b; + + b.x = t[0][0]*a.x + t[0][1]*a.y + t[0][2]*a.z; + b.y = t[1][0]*a.x + t[1][1]*a.y + t[1][2]*a.z; + b.z = t[2][0]*a.x + t[2][1]*a.y + t[2][2]*a.z; + return b; +} + +void +mccoordschange(Coords a, Rotation t, double *x, double *y, double *z, + double *vx, double *vy, double *vz, double *time, + double *s1, double *s2) +{ + Coords b, c; + + b.x = *x; + b.y = *y; + b.z = *z; + c = rot_apply(t, b); + b = coords_add(c, a); + *x = b.x; + *y = b.y; + *z = b.z; + + b.x = *vx; + b.y = *vy; + b.z = *vz; + c = rot_apply(t, b); + *vx = c.x; + *vy = c.y; + *vz = c.z; + /* ToDo: What to do about the spin? */ +} + + +void +mccoordschange_polarisation(Rotation t, double *sx, double *sy, double *sz) +{ + Coords b, c; + + b.x = *sx; + b.y = *sy; + b.z = *sz; + c = rot_apply(t, b); + *sx = c.x; + *sy = c.y; + *sz = c.z; +} + +void +mcstore_neutron(MCNUM *s, int index, double x, double y, double z, + double vx, double vy, double vz, double t, + double sx, double sy, double sz, double p) +{ + s[11*index+1] = x ; + s[11*index+2] = y ; + s[11*index+3] = z ; + s[11*index+4] = vx; + s[11*index+5] = vy; + s[11*index+6] = vz; + s[11*index+7] = t ; + s[11*index+8] = sx; + s[11*index+9] = sy; + s[11*index+10] = sz; + s[11*index+0] = p ; +} + +void +mcrestore_neutron(MCNUM *s, int index, double *x, double *y, double *z, + double *vx, double *vy, double *vz, double *t, + double *sx, double *sy, double *sz, double *p) +{ + *x = s[11*index+1] ; + *y = s[11*index+2] ; + *z = s[11*index+3] ; + *vx = s[11*index+4] ; + *vy = s[11*index+5] ; + *vz = s[11*index+6] ; + *t = s[11*index+7] ; + *sx = s[11*index+8] ; + *sy = s[11*index+9] ; + *sz = s[11*index+10] ; + *p = s[11*index+0]; +} + + +double +mcestimate_error(double N, double p1, double p2) +{ + double pmean, n1; + if(N <= 1) + return p1; + pmean = p1 / N; + n1 = N - 1; + /* Note: underflow may cause p2 to become zero; the fabs() below guards + against this. */ + return sqrt((N/n1)*fabs(p2 - pmean*pmean)); +} + +/* parameters handling ====================================================== */ + +/* Instrument input parameter type handling. */ +static int +mcparm_double(char *s, void *vptr) +{ + char *p; + double *v = (double *)vptr; + + if (!s) { *v = 0; return(1); } + *v = strtod(s, &p); + if(*s == '\0' || (p != NULL && *p != '\0') || errno == ERANGE) + return 0; /* Failed */ + else + return 1; /* Success */ +} + + +static char * +mcparminfo_double(char *parmname) +{ + return "double"; +} + + +static void +mcparmerror_double(char *parm, char *val) +{ + fprintf(stderr, "Error: Invalid value '%s' for floating point parameter %s\n", + val, parm); +} + + +static void +mcparmprinter_double(char *f, void *vptr) +{ + double *v = (double *)vptr; + sprintf(f, "%g", *v); +} + + +static int +mcparm_int(char *s, void *vptr) +{ + char *p; + int *v = (int *)vptr; + long x; + + if (!s) { *v = 0; return(1); } + *v = 0; + x = strtol(s, &p, 10); + if(x < INT_MIN || x > INT_MAX) + return 0; /* Under/overflow */ + *v = x; + if(*s == '\0' || (p != NULL && *p != '\0') || errno == ERANGE) + return 0; /* Failed */ + else + return 1; /* Success */ +} + + +static char * +mcparminfo_int(char *parmname) +{ + return "int"; +} + + +static void +mcparmerror_int(char *parm, char *val) +{ + fprintf(stderr, "Error: Invalid value '%s' for integer parameter %s\n", + val, parm); +} + + +static void +mcparmprinter_int(char *f, void *vptr) +{ + int *v = (int *)vptr; + sprintf(f, "%d", *v); +} + + +static int +mcparm_string(char *s, void *vptr) +{ + char **v = (char **)vptr; + if (!s) { *v = NULL; return(1); } + *v = (char *)malloc(strlen(s) + 1); + if(*v == NULL) + { + fprintf(stderr, "Error: Out of memory (mcparm_string).\n"); + exit(1); + } + strcpy(*v, s); + return 1; /* Success */ +} + + +static char * +mcparminfo_string(char *parmname) +{ + return "string"; +} + + +static void +mcparmerror_string(char *parm, char *val) +{ + fprintf(stderr, "Error: Invalid value '%s' for string parameter %s\n", + val, parm); +} + + +static void +mcparmprinter_string(char *f, void *vptr) +{ + char **v = (char **)vptr; + char *p; + + if (!*v) { *f='\0'; return; } + strcpy(f, ""); + for(p = *v; *p != '\0'; p++) + { + switch(*p) + { + case '\n': + strcat(f, "\\n"); + break; + case '\r': + strcat(f, "\\r"); + break; + case '"': + strcat(f, "\\\""); + break; + case '\\': + strcat(f, "\\\\"); + break; + default: + strncat(f, p, 1); + } + } + /* strcat(f, "\""); */ +} + + +static struct + { + int (*getparm)(char *, void *); + char * (*parminfo)(char *); + void (*error)(char *, char *); + void (*printer)(char *, void *); + } mcinputtypes[] = + { + mcparm_double, mcparminfo_double, mcparmerror_double, + mcparmprinter_double, + mcparm_int, mcparminfo_int, mcparmerror_int, + mcparmprinter_int, + mcparm_string, mcparminfo_string, mcparmerror_string, + mcparmprinter_string + }; + +/* init/run/rand handling =================================================== */ + +void +mcreadparams(void) +{ + int i,j,status; + char buf[1024]; + char *p; + int len; + + printf("Instrument parameters for %s (%s)\n", mcinstrument_name, mcinstrument_source); + for(i = 0; mcinputtable[i].name != 0; i++) + { + do + { + if (mcinputtable[i].val && strlen(mcinputtable[i].val)) + printf("Set value of instrument parameter %s (%s) [default='%s']:\n", + mcinputtable[i].name, + (*mcinputtypes[mcinputtable[i].type].parminfo) + (mcinputtable[i].name), mcinputtable[i].val); + else + printf("Set value of instrument parameter %s (%s):\n", + mcinputtable[i].name, + (*mcinputtypes[mcinputtable[i].type].parminfo) + (mcinputtable[i].name)); + + fflush(stdout); + p = fgets(buf, 1024, stdin); + if(p == NULL) + { + fprintf(stderr, "Error: empty input for paramater %s\n", mcinputtable[i].name); + exit(1); + } + len = strlen(buf); + if (!len || (len == 1 && (buf[0] == '\n' || buf[0] == '\r'))) + { + if (mcinputtable[i].val && strlen(mcinputtable[i].val)) { + strncpy(buf, mcinputtable[i].val, 1024); /* use default value */ + len = strlen(buf); + } + } + for(j = 0; j < 2; j++) + { + if(len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r')) + { + len--; + buf[len] = '\0'; + } + } + + status = (*mcinputtypes[mcinputtable[i].type].getparm) + (buf, mcinputtable[i].par); + if(!status) + { + (*mcinputtypes[mcinputtable[i].type].error)(mcinputtable[i].name, buf); + if (!mcinputtable[i].val || strlen(mcinputtable[i].val)) { + fprintf(stderr, " Change %s default value in instrument definition.\n", mcinputtable[i].name); + exit(1); + } + } + } while(!status); + } +} + + + +void +mcsetstate(double x, double y, double z, double vx, double vy, double vz, + double t, double sx, double sy, double sz, double p) +{ + extern double mcnx, mcny, mcnz, mcnvx, mcnvy, mcnvz; + extern double mcnt, mcnsx, mcnsy, mcnsz, mcnp; + + mcnx = x; + mcny = y; + mcnz = z; + mcnvx = vx; + mcnvy = vy; + mcnvz = vz; + mcnt = t; + mcnsx = sx; + mcnsy = sy; + mcnsz = sz; + mcnp = p; +} + +void +mcgenstate(void) +{ + mcsetstate(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1); +} + +/* McStas random number routine. */ + +/* + * Copyright (c) 1983 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* + * This is derived from the Berkeley source: + * @(#)random.c 5.5 (Berkeley) 7/6/88 + * It was reworked for the GNU C Library by Roland McGrath. + * Rewritten to use reentrant functions by Ulrich Drepper, 1995. + */ + +/******************************************************************************* +* Modified for McStas from glibc 2.0.7pre1 stdlib/random.c and +* stdlib/random_r.c. +* +* This way random() is more than four times faster compared to calling +* standard glibc random() on ix86 Linux, probably due to multithread support, +* ELF shared library overhead, etc. It also makes McStas generated +* simulations more portable (more likely to behave identically across +* platforms, important for parrallel computations). +*******************************************************************************/ + + +#define TYPE_3 3 +#define BREAK_3 128 +#define DEG_3 31 +#define SEP_3 3 + +static mc_int32_t randtbl[DEG_3 + 1] = + { + TYPE_3, + + -1726662223, 379960547, 1735697613, 1040273694, 1313901226, + 1627687941, -179304937, -2073333483, 1780058412, -1989503057, + -615974602, 344556628, 939512070, -1249116260, 1507946756, + -812545463, 154635395, 1388815473, -1926676823, 525320961, + -1009028674, 968117788, -123449607, 1284210865, 435012392, + -2017506339, -911064859, -370259173, 1132637927, 1398500161, + -205601318, + }; + +static mc_int32_t *fptr = &randtbl[SEP_3 + 1]; +static mc_int32_t *rptr = &randtbl[1]; +static mc_int32_t *state = &randtbl[1]; +#define rand_deg DEG_3 +#define rand_sep SEP_3 +static mc_int32_t *end_ptr = &randtbl[sizeof (randtbl) / sizeof (randtbl[0])]; + +mc_int32_t +mc_random (void) +{ + mc_int32_t result; + + *fptr += *rptr; + /* Chucking least random bit. */ + result = (*fptr >> 1) & 0x7fffffff; + ++fptr; + if (fptr >= end_ptr) + { + fptr = state; + ++rptr; + } + else + { + ++rptr; + if (rptr >= end_ptr) + rptr = state; + } + return result; +} + +void +mc_srandom (unsigned int x) +{ + /* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */ + state[0] = x ? x : 1; + { + long int i; + for (i = 1; i < rand_deg; ++i) + { + /* This does: + state[i] = (16807 * state[i - 1]) % 2147483647; + but avoids overflowing 31 bits. */ + long int hi = state[i - 1] / 127773; + long int lo = state[i - 1] % 127773; + long int test = 16807 * lo - 2836 * hi; + state[i] = test + (test < 0 ? 2147483647 : 0); + } + fptr = &state[rand_sep]; + rptr = &state[0]; + for (i = 0; i < 10 * rand_deg; ++i) + random (); + } +} + +/* "Mersenne Twister", by Makoto Matsumoto and Takuji Nishimura. */ +/* See http://www.math.keio.ac.jp/~matumoto/emt.html for original source. */ + + +/* + A C-program for MT19937, with initialization improved 2002/1/26. + Coded by Takuji Nishimura and Makoto Matsumoto. + + Before using, initialize the state by using mt_srandom(seed) + or init_by_array(init_key, key_length). + + Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. The names of its contributors may not be used to endorse or promote + products derived from this software without specific prior written + permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + Any feedback is very welcome. + http://www.math.keio.ac.jp/matumoto/emt.html + email: matumoto@math.keio.ac.jp +*/ + +#include + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0dfUL /* constant vector a */ +#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ + +static unsigned long mt[N]; /* the array for the state vector */ +static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ + +/* initializes mt[N] with a seed */ +void mt_srandom(unsigned long s) +{ + mt[0]= s & 0xffffffffUL; + for (mti=1; mti> 30)) + mti); + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous versions, MSBs of the seed affect */ + /* only MSBs of the array mt[]. */ + /* 2002/01/09 modified by Makoto Matsumoto */ + mt[mti] &= 0xffffffffUL; + /* for >32 bit machines */ + } +} + +/* initialize by an array with array-length */ +/* init_key is the array for initializing keys */ +/* key_length is its length */ +void init_by_array(init_key, key_length) +unsigned long init_key[], key_length; +{ + int i, j, k; + mt_srandom(19650218UL); + i=1; j=0; + k = (N>key_length ? N : key_length); + for (; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) + + init_key[j] + j; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + if (j>=key_length) j=0; + } + for (k=N-1; k; k--) { + mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) { mt[0] = mt[N-1]; i=1; } + } + + mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/* generates a random number on [0,0xffffffff]-interval */ +unsigned long mt_random(void) +{ + unsigned long y; + static unsigned long mag01[2]={0x0UL, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + if (mti >= N) { /* generate N words at one time */ + int kk; + + if (mti == N+1) /* if mt_srandom() has not been called, */ + mt_srandom(5489UL); /* a default initial seed is used */ + + for (kk=0;kk> 1) ^ mag01[y & 0x1UL]; + } + for (;kk> 1) ^ mag01[y & 0x1UL]; + } + y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); + mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; + + mti = 0; + } + + y = mt[mti++]; + + /* Tempering */ + y ^= (y >> 11); + y ^= (y << 7) & 0x9d2c5680UL; + y ^= (y << 15) & 0xefc60000UL; + y ^= (y >> 18); + + return y; +} + +#undef N +#undef M +#undef MATRIX_A +#undef UPPER_MASK +#undef LOWER_MASK + +/* End of "Mersenne Twister". */ + +/* End of McStas random number routine. */ + +double +randnorm(void) +{ + static double v1, v2, s; + static int phase = 0; + double X, u1, u2; + + if(phase == 0) + { + do + { + u1 = rand01(); + u2 = rand01(); + v1 = 2*u1 - 1; + v2 = 2*u2 - 1; + s = v1*v1 + v2*v2; + } while(s >= 1 || s == 0); + + X = v1*sqrt(-2*log(s)/s); + } + else + { + X = v2*sqrt(-2*log(s)/s); + } + + phase = 1 - phase; + return X; +} + +/* intersect handling ======================================================= */ + +/* Compute normal vector to (x,y,z). */ +void normal_vec(double *nx, double *ny, double *nz, + double x, double y, double z) +{ + double ax = fabs(x); + double ay = fabs(y); + double az = fabs(z); + double l; + if(x == 0 && y == 0 && z == 0) + { + *nx = 0; + *ny = 0; + *nz = 0; + return; + } + if(ax < ay) + { + if(ax < az) + { /* Use X axis */ + l = sqrt(z*z + y*y); + *nx = 0; + *ny = z/l; + *nz = -y/l; + return; + } + } + else + { + if(ay < az) + { /* Use Y axis */ + l = sqrt(z*z + x*x); + *nx = z/l; + *ny = 0; + *nz = -x/l; + return; + } + } + /* Use Z axis */ + l = sqrt(y*y + x*x); + *nx = y/l; + *ny = -x/l; + *nz = 0; +} + +/* If intersection with box dt_in and dt_out is returned */ +/* This function written by Stine Nyborg, 1999. */ +int box_intersect(double *dt_in, double *dt_out, + double x, double y, double z, + double vx, double vy, double vz, + double dx, double dy, double dz) +{ + double x_in, y_in, z_in, tt, t[6], a, b; + int i, count, s; + + /* Calculate intersection time for each of the six box surface planes + * If the box surface plane is not hit, the result is zero.*/ + + if(vx != 0) + { + tt = -(dx/2 + x)/vx; + y_in = y + tt*vy; + z_in = z + tt*vz; + if( y_in > -dy/2 && y_in < dy/2 && z_in > -dz/2 && z_in < dz/2) + t[0] = tt; + else + t[0] = 0; + + tt = (dx/2 - x)/vx; + y_in = y + tt*vy; + z_in = z + tt*vz; + if( y_in > -dy/2 && y_in < dy/2 && z_in > -dz/2 && z_in < dz/2) + t[1] = tt; + else + t[1] = 0; + } + else + t[0] = t[1] = 0; + + if(vy != 0) + { + tt = -(dy/2 + y)/vy; + x_in = x + tt*vx; + z_in = z + tt*vz; + if( x_in > -dx/2 && x_in < dx/2 && z_in > -dz/2 && z_in < dz/2) + t[2] = tt; + else + t[2] = 0; + + tt = (dy/2 - y)/vy; + x_in = x + tt*vx; + z_in = z + tt*vz; + if( x_in > -dx/2 && x_in < dx/2 && z_in > -dz/2 && z_in < dz/2) + t[3] = tt; + else + t[3] = 0; + } + else + t[2] = t[3] = 0; + + if(vz != 0) + { + tt = -(dz/2 + z)/vz; + x_in = x + tt*vx; + y_in = y + tt*vy; + if( x_in > -dx/2 && x_in < dx/2 && y_in > -dy/2 && y_in < dy/2) + t[4] = tt; + else + t[4] = 0; + + tt = (dz/2 - z)/vz; + x_in = x + tt*vx; + y_in = y + tt*vy; + if( x_in > -dx/2 && x_in < dx/2 && y_in > -dy/2 && y_in < dy/2) + t[5] = tt; + else + t[5] = 0; + } + else + t[4] = t[5] = 0; + + /* The intersection is evaluated and *dt_in and *dt_out are assigned */ + + a = b = s = 0; + count = 0; + + for( i = 0; i < 6; i = i + 1 ) + if( t[i] == 0 ) + s = s+1; + else if( count == 0 ) + { + a = t[i]; + count = 1; + } + else + { + b = t[i]; + count = 2; + } + + if ( a == 0 && b == 0 ) + return 0; + else if( a < b ) + { + *dt_in = a; + *dt_out = b; + return 1; + } + else + { + *dt_in = b; + *dt_out = a; + return 1; + } + +} + +/* Written by: EM,NB,ABA 4.2.98 */ +int +cylinder_intersect(double *t0, double *t1, double x, double y, double z, + double vx, double vy, double vz, double r, double h) +{ + double D, t_in, t_out, y_in, y_out; + int ret=1; + + D = (2*vx*x + 2*vz*z)*(2*vx*x + 2*vz*z) + - 4*(vx*vx + vz*vz)*(x*x + z*z - r*r); + + if (D>=0) + { + t_in = (-(2*vz*z + 2*vx*x) - sqrt(D))/(2*(vz*vz + vx*vx)); + t_out = (-(2*vz*z + 2*vx*x) + sqrt(D))/(2*(vz*vz + vx*vx)); + y_in = vy*t_in + y; + y_out =vy*t_out + y; + + if ( (y_in > h/2 && y_out > h/2) || (y_in < -h/2 && y_out < -h/2) ) + return 0; + else + { + if (y_in > h/2) + { t_in = ((h/2)-y)/vy; ret += 2; } + else if (y_in < -h/2) + { t_in = ((-h/2)-y)/vy; ret += 4; } + if (y_out > h/2) + { t_out = ((h/2)-y)/vy; ret += 8; } + else if (y_out < -h/2) + { t_out = ((-h/2)-y)/vy; ret += 16; } + } + *t0 = t_in; + *t1 = t_out; + return ret; + } + else + { + *t0 = *t1 = 0; + return 0; + } +} + + +/* Calculate intersection between line and sphere. */ +int +sphere_intersect(double *t0, double *t1, double x, double y, double z, + double vx, double vy, double vz, double r) +{ + double A, B, C, D, v; + + v = sqrt(vx*vx + vy*vy + vz*vz); + A = v*v; + B = 2*(x*vx + y*vy + z*vz); + C = x*x + y*y + z*z - r*r; + D = B*B - 4*A*C; + if(D < 0) + return 0; + D = sqrt(D); + *t0 = (-B - D) / (2*A); + *t1 = (-B + D) / (2*A); + return 1; +} + + +/* ADD: E. Farhi, Aug 6th, 2001 plane_intersect_Gfast + * intersection of a plane and a trajectory with gravitation + * this function calculates the intersection between a neutron trajectory + * and a plane with acceleration gx,gy,gz. The neutron starts at point x,y,z + * with velocity vx, vy, vz. The plane has a normal vector nx,ny,nz and + * contains the point wx,wy,wz + * The function returns 0 if no intersection occured after the neutron started + * and non 0 if there is an intersection. Then *Idt is the time until + * the neutron hits the roof. + * Let n=(nx,ny,nz) be the normal plane vector (one of the six sides) + * Let W=(wx,wy,wz) be Any point on this plane (for instance at z=0) + * The problem consists in solving the 2nd order equation: + * 1/2.n.g.t^2 + n.v.t + n.(r-W) = 0 (1) + * Without acceleration, t=-n.(r-W)/n.v + */ + +int plane_intersect_Gfast(double *Idt, + double A, double B, double C) +{ + /* plane_intersect_Gfast(&dt, A, B, C) + * A = 0.5 n.g; B = n.v; C = n.(r-W); + * no acceleration when A=0 + */ + int ret=0; + double dt0; + + *Idt = 0; + + if (B) dt0 = -C/B; + if (fabs(A) < 1E-10) /* this plane is parallel to the acceleration */ + { + if (B) + { *Idt = dt0; ret=3; } + /* else the speed is parallel to the plane, no intersection */ + } + else + { + double D, sD, dt1, dt2; + D = B*B - 4*A*C; + if (D >= 0) /* Delta > 0: neutron trajectory hits the mirror */ + { + sD = sqrt(D); + dt1 = (-B + sD)/2/A; + dt2 = (-B - sD)/2/A; + if (B) + { + if (fabs(dt0-dt1) < fabs(dt0-dt2)) ret=1; else ret=2; + } + else + { + if (dt1 <= dt2) ret=1; else ret=2; + } + if (ret==1) *Idt = dt1; + else if (ret==2) *Idt = dt2; + } /* else Delta <0: no intersection */ + } + return(ret); +} + + +/* Choose random direction towards target at (x,y,z) with given radius. */ +/* If radius is zero, choose random direction in full 4PI, no target. */ +void +randvec_target_circle(double *xo, double *yo, double *zo, double *solid_angle, + double xi, double yi, double zi, double radius) +{ + double l2, phi, theta, nx, ny, nz, xt, yt, zt, xu, yu, zu; + + if(radius == 0.0) + { + /* No target, choose uniformly a direction in full 4PI solid angle. */ + theta = acos (1 - rand0max(2)); + phi = rand0max(2 * PI); + if(solid_angle) + *solid_angle = 4*PI; + nx = 1; + ny = 0; + nz = 0; + yi = sqrt(xi*xi+yi*yi+zi*zi); + zi = 0; + xi = 0; + } + else + { + double costheta0; + l2 = xi*xi + yi*yi + zi*zi; /* sqr Distance to target. */ + costheta0 = sqrt(l2/(radius*radius+l2)); + if (radius < 0) costheta0 *= -1; + if(solid_angle) + { + /* Compute solid angle of target as seen from origin. */ + *solid_angle = 2*PI*(1 - costheta0); + } + + /* Now choose point uniformly on sphere surface within angle theta0 */ + theta = acos (1 - rand0max(1 - costheta0)); /* radius on circle */ + phi = rand0max(2 * PI); /* rotation on circle at given radius */ + /* Now, to obtain the desired vector rotate (xi,yi,zi) angle theta around a + perpendicular axis u=i x n and then angle phi around i. */ + if(xi == 0 && zi == 0) + { + nx = 1; + ny = 0; + nz = 0; + } + else + { + nx = -zi; + nz = xi; + ny = 0; + } + } + + /* [xyz]u = [xyz]i x n[xyz] (usually vertical) */ + vec_prod(xu, yu, zu, xi, yi, zi, nx, ny, nz); + /* [xyz]t = [xyz]i rotated theta around [xyz]u */ + rotate (xt, yt, zt, xi, yi, zi, theta, xu, yu, zu); + /* [xyz]o = [xyz]t rotated phi around n[xyz] */ + rotate (*xo, *yo, *zo, xt, yt, zt, phi, xi, yi, zi); +} + + +/* Choose random direction towards target at (xi,yi,zi) with given */ +/* ANGULAR dimension height x width. height=phi_x, width=phi_y (radians)*/ +/* If height or width is zero, choose random direction in full 4PI, no target. */ +void +randvec_target_rect_angular(double *xo, double *yo, double *zo, double *solid_angle, + double xi, double yi, double zi, double width, double height, Rotation A) +{ + double theta, phi, nx, ny, nz, xt, yt, zt, xu, yu, zu; + Coords tmp; + Rotation Ainverse; + + rot_transpose(A, Ainverse); + + if(height == 0.0 || width == 0.0) + { + randvec_target_circle(xo, yo, zo, solid_angle, + xi, yi, zi, 0); + } + else + { + if(solid_angle) + { + /* Compute solid angle of target as seen from origin. */ + *solid_angle = 2*fabs(width*sin(height/2)); + } + + /* Go to global coordinate system */ + + tmp = coords_set(xi, yi, zi); + tmp = rot_apply(Ainverse, tmp); + coords_get(tmp, &xi, &yi, &zi); + + /* Now choose point uniformly on quadrant within angle theta0/phi0 */ + theta = width*randpm1()/2.0; + phi = height*randpm1()/2.0; + /* Now, to obtain the desired vector rotate (xi,yi,zi) angle phi around + n, and then theta around u. */ + if(xi == 0 && zi == 0) + { + nx = 1; + ny = 0; + nz = 0; + } + else + { + nx = -zi; + nz = xi; + ny = 0; + } + } + + /* [xyz]u = [xyz]i x n[xyz] (usually vertical) */ + vec_prod(xu, yu, zu, xi, yi, zi, nx, ny, nz); + /* [xyz]t = [xyz]i rotated theta around [xyz]u */ + rotate (xt, yt, zt, xi, yi, zi, phi, nx, ny, nz); + /* [xyz]o = [xyz]t rotated phi around n[xyz] */ + rotate (*xo, *yo, *zo, xt, yt, zt, theta, xu, yu, zu); + + /* Go back to local coordinate system */ + tmp = coords_set(*xo, *yo, *zo); + tmp = rot_apply(A, tmp); + coords_get(tmp, &*xo, &*yo, &*zo); + +} + +/* Choose random direction towards target at (xi,yi,zi) with given */ +/* dimension height x width (in meters!). */ +/* If height or width is zero, choose random direction in full 4PI, no target. */ +void +randvec_target_rect(double *xo, double *yo, double *zo, double *solid_angle, + double xi, double yi, double zi, double width, double height, Rotation A) +{ + double dx, dy, dist, dist_p, nx, ny, nz, mx, my, mz, xt, yt, zt, xu, yu, zu, theta, phi, n_norm, m_norm; + Coords tmp; + Rotation Ainverse; + + rot_transpose(A, Ainverse); + + if(height == 0.0 || width == 0.0) + { + randvec_target_circle(xo, yo, zo, solid_angle, + xi, yi, zi, 0); + } + else + { + + /* Now choose point uniformly on quadrant within width x height */ + dx = width*randpm1()/2.0; + dy = height*randpm1()/2.0; + + /* Determine distance to target */ + dist = sqrt(xi*xi + yi*yi + zi*zi); + /* Go to global coordinate system */ + + tmp = coords_set(xi, yi, zi); + tmp = rot_apply(Ainverse, tmp); + coords_get(tmp, &xi, &yi, &zi); + + /* Determine vector normal to neutron axis (z) and gravity [0 1 0] */ + vec_prod(nx, ny, nz, xi, yi, zi, 0, 1, 0); + + /* This now defines the x-axis, normalize: */ + n_norm=sqrt(nx*nx + ny*ny + nz*nz); + nx = nx/n_norm; + ny = ny/n_norm; + nz = nz/n_norm; + + /* Now, determine our y-axis (vertical in many cases...) */ + vec_prod(mx, my, mz, xi, yi, zi, nx, ny, nz); + m_norm=sqrt(mx*mx + my*my + mz*mz); + mx = mx/m_norm; + my = my/m_norm; + mz = mz/m_norm; + + /* Our output, random vector can now be defined by linear combination: */ + + *xo = xi + dx * nx + dy * mx; + *yo = yi + dx * ny + dy * my; + *zo = zi + dx * nz + dy * mz; + + /* Go back to local coordinate system */ + tmp = coords_set(*xo, *yo, *zo); + tmp = rot_apply(A, tmp); + coords_get(tmp, &*xo, &*yo, &*zo); + + /* Determine distance to random point */ + dist_p = sqrt(dx*dx + dy*dy + dist*dist); + + /* Adjust the 'solid angle' (here more thought of as a normalization constant) */ + /* Works since we are in the relative coordinate system, origin is where we are at */ + *solid_angle = (width*height*dist)/(dist_p*dist_p*dist_p); + + } +} + + +/* Make sure a list is big enough to hold element COUNT. +* +* The list is an array, and the argument 'list' is a pointer to a pointer to +* the array start. The argument 'size' is a pointer to the number of elements +* in the array. The argument 'elemsize' is the sizeof() an element. The +* argument 'count' is the minimum number of elements needed in the list. +* +* If the old array is to small (or if *list is NULL or *size is 0), a +* sufficuently big new array is allocated, and *list and *size are updated. +*/ +void extend_list(int count, void **list, int *size, size_t elemsize) +{ + if(count >= *size) + { + void *oldlist = *list; + if(*size > 0) + *size *= 2; + else + *size = 32; + *list = malloc(*size*elemsize); + if(!*list) + { + fprintf(stderr, "\nError: Out of memory (extend_list).\n"); + exit(1); + } + if(oldlist) + { + memcpy(*list, oldlist, count*elemsize); + free(oldlist); + } + } +} + +/* Number of neutron histories to simulate. */ +static double mcncount = 1e6; +double mcrun_num = 0; + +void +mcset_ncount(double count) +{ + mcncount = count; +} + +double +mcget_ncount(void) +{ + return mcncount; +} + +double +mcget_run_num(void) +{ + return mcrun_num; +} + +static void +mcsetn_arg(char *arg) +{ + mcset_ncount(strtod(arg, NULL)); +} + +static void +mcsetseed(char *arg) +{ + mcseed = atol(arg); + if(mcseed) + srandom(mcseed); + else + { + fprintf(stderr, "Error: seed most not be zero.\n"); + exit(1); + } +} + +static void +mchelp(char *pgmname) +{ + int i; + + fprintf(stderr, "Usage: %s [options] [parm=value ...]\n", pgmname); + fprintf(stderr, +"Options are:\n" +" -s SEED --seed=SEED Set random seed (must be != 0)\n" +" -n COUNT --ncount=COUNT Set number of neutrons to simulate.\n" +" -d DIR --dir=DIR Put all data files in directory DIR.\n" +" -f FILE --file=FILE Put all data in a single file.\n" +" -t --trace Enable trace of neutron through instrument.\n" +" -g --gravitation Enable gravitation for all trajectories.\n" +" -a --data-only Do not put any headers in the data files.\n" +" --no-output-files Do not write any data files.\n" +" -h --help Show this help message.\n" +" -i --info Detailed instrument information.\n" +" --format=FORMAT Output data files using format FORMAT\n" +" (use option +a to include text header in files\n" +); + if(mcnumipar > 0) + { + fprintf(stderr, "Instrument parameters are:\n"); + for(i = 0; i < mcnumipar; i++) + if (mcinputtable[i].val && strlen(mcinputtable[i].val)) + fprintf(stderr, " %-16s(%s) [default='%s']\n", mcinputtable[i].name, + (*mcinputtypes[mcinputtable[i].type].parminfo)(mcinputtable[i].name), + mcinputtable[i].val); + else + fprintf(stderr, " %-16s(%s)\n", mcinputtable[i].name, + (*mcinputtypes[mcinputtable[i].type].parminfo)(mcinputtable[i].name)); + } + fprintf(stderr, "Available output formats are (default is %s):\n ", mcformat.Name); + for (i=0; i < mcNUMFORMATS; fprintf(stderr,"\"%s\" " , mcformats[i++].Name) ); + fprintf(stderr, "\n Format modifiers: FORMAT may be followed by 'binary float' or \n"); + fprintf(stderr, " 'binary double' to save data blocks as binary. This removes text headers.\n"); + fprintf(stderr, " The MCSTAS_FORMAT environment variable may set the default FORMAT to use.\n"); +#ifndef MC_PORTABLE +#ifndef MAC +#ifndef WIN32 + fprintf(stderr, "Known signals are: USR1 (status) USR2(save) TERM (save and exit)\n"); +#endif /* !MAC */ +#endif /* !WIN32 */ +#endif /* !MC_PORTABLE */ +} + +static void +mcshowhelp(char *pgmname) +{ + mchelp(pgmname); + exit(0); +} + +static void +mcusage(char *pgmname) +{ + fprintf(stderr, "Error: incorrect command line arguments\n"); + mchelp(pgmname); + exit(1); +} + +static void +mcenabletrace(void) +{ + if(mctraceenabled) + mcdotrace = 1; + else + { + fprintf(stderr, + "Error: trace not enabled.\n" + "Please re-run the McStas compiler " + "with the --trace option, or rerun the\n" + "C compiler with the MC_TRACE_ENABLED macro defined.\n"); + exit(1); + } +} + +/* file i/o handling ======================================================== */ +/* opens a new file within mcdirname if non NULL */ +/* if mode is non 0, then mode is used, else mode is 'w' */ + +FILE * +mcnew_file(char *name, char *mode) +{ + int dirlen; + char *mem; + FILE *file; + + if (!name || strlen(name) == 0) return(NULL); + + dirlen = mcdirname ? strlen(mcdirname) : 0; + mem = malloc(dirlen + 1 + strlen(name) + 1); + if(!mem) + { + fprintf(stderr, "Error: Out of memory (mcnew_file)\n"); + exit(1); + } + strcpy(mem, ""); + if(dirlen) + { + strcat(mem, mcdirname); + if(mcdirname[dirlen - 1] != MC_PATHSEP_C && + name[0] != MC_PATHSEP_C) + strcat(mem, MC_PATHSEP_S); + } + strcat(mem, name); + file = fopen(mem, (mode ? mode : "w")); + if(!file) + fprintf(stderr, "Warning: could not open output file '%s'\n", mem); + free(mem); + return file; +} /* mcnew_file */ + +/* mcvalid_name: makes a valid string for variable names. + * copy 'original' into 'valid', replacing invalid characters by '_' + * char arrays must be pre-allocated. n can be 0, or the maximum number of + * chars to be copied/checked + */ +static char *mcvalid_name(char *valid, char *original, int n) +{ + long i; + + + if (original == NULL || strlen(original) == 0) + { strcpy(valid, "noname"); return(valid); } + if (n <= 0) n = strlen(valid); + + if (n > strlen(original)) n = strlen(original); + strncpy(valid, original, n); + + for (i=0; i < n; i++) + { + if ( (valid[i] > 122) + || (valid[i] < 32) + || (strchr("!\"#$%&'()*+,-.:;<=>?@[\\]^`/ ", valid[i]) != NULL) ) + { + if (i) valid[i] = '_'; else valid[i] = 'm'; + } + } + valid[i] = '\0'; + + return(valid); +} /* mcvalid_name */ + +#if defined(NL_ARGMAX) || defined(WIN32) +static int pfprintf(FILE *f, char *fmt, char *fmt_args, ...) +{ +/* this function +1- look for the maximum %d$ field in fmt +2- looks for all %d$ fields up to max in fmt and set their type (next alpha) +3- retrieve va_arg up to max, and save pointer to arg in local arg array +4- use strchr to split around '%' chars, until all pieces are written + +usage: just as fprintf, but with (char *)fmt_args being the list of arg type + */ + + #define MyNL_ARGMAX 50 + char *fmt_pos; + + char *arg_char[MyNL_ARGMAX]; + int arg_int[MyNL_ARGMAX]; + long arg_long[MyNL_ARGMAX]; + double arg_double[MyNL_ARGMAX]; + + char *arg_posB[MyNL_ARGMAX]; /* position of '%' */ + char *arg_posE[MyNL_ARGMAX]; /* position of '$' */ + char *arg_posT[MyNL_ARGMAX]; /* position of type */ + + int arg_num[MyNL_ARGMAX]; /* number of argument (between % and $) */ + int this_arg=0; + int arg_max=0; + va_list ap; + + if (!f || !fmt_args || !fmt) return(-1); + for (this_arg=0; this_arg= MyNL_ARGMAX) + return(-fprintf(stderr,"pfprintf: invalid positional argument number (<=0 or >=%i) %s.\n", MyNL_ARGMAX, arg_posB[this_arg])); + /* get type of positional argument: follows '%' -> arg_posE[this_arg]+1 */ + fmt_pos = arg_posE[this_arg]+1; + if (!strchr(printf_formats, fmt_pos[0])) + return(-fprintf(stderr,"pfprintf: invalid positional argument type (%c != expected %c).\n", fmt_pos[0], fmt_args[arg_num[this_arg]-1])); + if (fmt_pos[0] == 'l' && fmt_pos[1] == 'i') fmt_pos++; + arg_posT[this_arg] = fmt_pos; + /* get next argument... */ + this_arg++; + } + else + { + if (tmp[1] != '%') + return(-fprintf(stderr,"pfprintf: must use only positional arguments (%s).\n", arg_posB[this_arg])); + else fmt_pos = arg_posB[this_arg]+2; /* found %% */ + } + } else + break; /* no more % argument */ + } + arg_max = this_arg; + /* get arguments from va_arg list, according to their type */ + va_start(ap, fmt_args); + for (this_arg=0; this_arg0) + { + fmt_bit = (char*)malloc(arg_posB[this_arg]-fmt_pos+10); + if (!fmt_bit) return(-fprintf(stderr,"pfprintf: not enough memory.\n")); + strncpy(fmt_bit, fmt_pos, arg_posB[this_arg]-fmt_pos); + fmt_bit[arg_posB[this_arg]-fmt_pos] = '\0'; + fprintf(f, fmt_bit); /* fmt part without argument */ + } else + { + fmt_bit = (char*)malloc(10); + if (!fmt_bit) return(-fprintf(stderr,"pfprintf: not enough memory.\n")); + } + arg_n = arg_num[this_arg]-1; /* must be >= 0 */ + strcpy(fmt_bit, "%"); + strncat(fmt_bit, arg_posE[this_arg]+1, arg_posT[this_arg]-arg_posE[this_arg]); + fmt_bit[arg_posT[this_arg]-arg_posE[this_arg]+1] = '\0'; + + switch(fmt_args[arg_n]) + { + case 's': fprintf(f, fmt_bit, arg_char[arg_n]); + break; + case 'd': + case 'i': + case 'c': /* int */ + fprintf(f, fmt_bit, arg_int[arg_n]); + break; + case 'l': /* long */ + fprintf(f, fmt_bit, arg_long[arg_n]); + break; + case 'f': + case 'g': + case 'G': /* double */ + fprintf(f, fmt_bit, arg_double[arg_n]); + break; + } + fmt_pos = arg_posT[this_arg]+1; + if (this_arg == arg_max-1) + { /* add eventual leading characters for last parameter */ + if (fmt_pos < fmt+strlen(fmt)) + fprintf(f, "%s", fmt_pos); + } + if (fmt_bit) free(fmt_bit); + + } + return(this_arg); +} +#else +static int pfprintf(FILE *f, char *fmt, char *fmt_args, ...) +{ /* wrapper to standard fprintf */ + va_list ap; + int tmp; + + va_start(ap, fmt_args); + tmp=vfprintf(f, fmt, ap); + va_end(ap); + return(tmp); +} +#endif + +/* mcfile_header: output header/footer using specific file format. + * outputs, in file 'name' having preallocated 'f' handle, the format Header + * 'part' may be 'header' or 'footer' depending on part to write + * if name == NULL, ignore function (no header/footer output) + */ +static int mcfile_header(FILE *f, struct mcformats_struct format, char *part, char *pre, char *name, char *parent) +{ + char user[64]; + char date[64]; + char *HeadFoot; + long date_l; /* date as a long number */ + time_t t; + char valid_parent[256]; + char instrname[256]; + char file[256]; + + if(!f) + return (-1); + + time(&t); + + if (part && !strcmp(part,"footer")) + { + HeadFoot = format.Footer; + date_l = (long)t;; + } + else + { + HeadFoot = format.Header; + date_l = mcstartdate; + } + t = (time_t)date_l; + + if (!strlen(HeadFoot) || (!name)) return (-1); + + sprintf(file,"%s",name); + sprintf(user,"%s on %s", getenv("USER"), getenv("HOST")); + sprintf(instrname,"%s (%s)", mcinstrument_name, mcinstrument_source); + strncpy(date, ctime(&t), 64); + if (strlen(date)) date[strlen(date)-1] = '\0'; + + if (parent && strlen(parent)) mcvalid_name(valid_parent, parent, 256); + else strcpy(valid_parent, "root"); + + return(pfprintf(f, HeadFoot, "sssssssl", + pre, /* %1$s */ + instrname, /* %2$s */ + file, /* %3$s */ + format.Name, /* %4$s */ + date, /* %5$s */ + user, /* %6$s */ + valid_parent, /* %7$s*/ + date_l)); /* %8$li */ +} /* mcfile_header */ + +/* mcfile_tag: output tag/value using specific file format. + * outputs, in file with 'f' handle, a tag/value pair. + * if name == NULL, ignore function (no section definition) + */ +static int mcfile_tag(FILE *f, struct mcformats_struct format, char *pre, char *section, char *name, char *value) +{ + char valid_section[256]; + int i; + + if (!strlen(format.AssignTag) || (!name) || (!f)) return(-1); + + mcvalid_name(valid_section, section, 256); + + /* remove quote chars in values */ + if (strstr(format.Name, "Scilab") || strstr(format.Name, "Matlab") || strstr(format.Name, "IDL")) + for(i = 0; i < strlen(value); i++) + if (value[i] == '"' || value[i] == '\'') value[i] = ' '; + + return(pfprintf(f, format.AssignTag, "ssss", + pre, /* %1$s */ + valid_section,/* %2$s */ + name, /* %3$s */ + value)); /* %4$s */ +} /* mcfile_tag */ + +/* mcfile_section: output section start/end using specific file format. + * outputs, in file 'name' having preallocated 'f' handle, the format Section. + * 'part' may be 'begin' or 'end' depending on section part to write + * 'type' may be e.g. 'instrument','simulation','component','data' + * if name == NULL, ignore function (no section definition) + * the prefix 'pre' is automatically idented/un-indented (pre-allocated !) + */ + +static int mcfile_section(FILE *f, struct mcformats_struct format, char *part, char *pre, char *name, char *type, char *parent, int level) +{ + char *Section; + char valid_name[256]; + char valid_parent[256]; + int ret; + + if(!f) + return (-1); + + if (part && !strcmp(part,"end")) Section = format.EndSection; + else Section = format.BeginSection; + + if (!strlen(Section) || (!name)) return (-1); + + mcvalid_name(valid_name, name, 256); + if (parent && strlen(parent)) mcvalid_name(valid_parent, parent, 256); + else strcpy(valid_parent, "root"); + + if (!strcmp(part,"end") && pre) + { + if (strlen(pre) <= 2) strcpy(pre,""); + else pre[strlen(pre)-2]='\0'; + } + + ret = pfprintf(f, Section, "ssssssl", + pre, /* %1$s */ + type, /* %2$s */ + name, /* %3$s */ + valid_name, /* %4$s */ + parent, /* %5$s */ + valid_parent, /* %6$s */ + level); /* %7$li */ + + if (!strcmp(part,"begin")) + { + strcat(pre," "); + if (name && strlen(name)) + mcfile_tag(f, format, pre, name, "name", name); + if (parent && strlen(parent)) + mcfile_tag(f, format, pre, name, "parent", parent); + } + + + return(ret); +} /* mcfile_section */ + +static void mcinfo_instrument(FILE *f, struct mcformats_struct format, + char *pre, char *name) +{ + char Value[1300] = ""; + int i; + + if (!f) return; + + for(i = 0; i < mcnumipar; i++) + { + char ThisParam[256]; + if (strlen(mcinputtable[i].name) > 200) break; + sprintf(ThisParam, " %s(%s)", mcinputtable[i].name, + (*mcinputtypes[mcinputtable[i].type].parminfo) + (mcinputtable[i].name)); + strcat(Value, ThisParam); + if (strlen(Value) > 1024) break; + } + mcfile_tag(f, format, pre, name, "Parameters", Value); + mcfile_tag(f, format, pre, name, "Source", mcinstrument_source); + mcfile_tag(f, format, pre, name, "Trace_enabled", mctraceenabled ? "yes" : "no"); + mcfile_tag(f, format, pre, name, "Default_main", mcdefaultmain ? "yes" : "no"); + mcfile_tag(f, format, pre, name, "Embedded_runtime", +#ifdef MC_EMBEDDED_RUNTIME + "yes" +#else + "no" +#endif + ); +} /* mcinfo_instrument */ + +void mcinfo_simulation(FILE *f, struct mcformats_struct format, + char *pre, char *name) +{ + int i; + double run_num, ncount; + time_t t; + char Value[256]; + + if (!f) return; + + run_num = mcget_run_num(); + ncount = mcget_ncount(); + time(&t); + strncpy(Value, ctime(&t), 256); if (strlen(Value)) Value[strlen(Value)-1] = '\0'; + mcfile_tag(f, format, pre, name, "Date", Value); + if (run_num == 0 || run_num == ncount) sprintf(Value, "%g", ncount); + else sprintf(Value, "%g/%g", run_num, ncount); + mcfile_tag(f, format, pre, name, "Ncount", Value); + mcfile_tag(f, format, pre, name, "Trace", mcdotrace ? "yes" : "no"); + mcfile_tag(f, format, pre, name, "Gravitation", mcgravitation ? "yes" : "no"); + if(mcseed) + { + sprintf(Value, "%ld", mcseed); + mcfile_tag(f, format, pre, name, "Seed", Value); + } + if (strstr(format.Name, "McStas")) + { + for(i = 0; i < mcnumipar; i++) + { + if (mcrun_num || (mcinputtable[i].val && strlen(mcinputtable[i].val))) { + (*mcinputtypes[mcinputtable[i].type].printer)(Value, mcinputtable[i].par); + fprintf(f, "%sParam: %s=%s", pre, mcinputtable[i].name, Value); + fprintf(f, "\n"); + } + } + } + else + { + mcfile_section(f, format, "begin", pre, "parameters", "parameters", name, 3); + for(i = 0; i < mcnumipar; i++) + { + (*mcinputtypes[mcinputtable[i].type].printer)(Value, mcinputtable[i].par); + mcfile_tag(f, format, pre, "parameters", mcinputtable[i].name, Value); + } + mcfile_section(f, format, "end", pre, "parameters", "parameters", name, 3); + } +} /* mcinfo_simulation */ + +static void mcinfo_data(FILE *f, struct mcformats_struct format, + char *pre, char *parent, char *title, + int m, int n, int p, + char *xlabel, char *ylabel, char *zlabel, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, + char *filename, + double *p0, double *p1, double *p2, char istransposed) +{ + char type[256]; + char stats[256]; + char vars[256]; + char signal[256]; + char values[256]; + char limits[256]; + char lim_field[10]; + char c[32]; + double run_num, ncount; + char ratio[256]; + + double sum_xz = 0; + double sum_yz = 0; + double sum_z = 0; + double sum_y = 0; + double sum_x = 0; + double sum_x2z = 0; + double sum_y2z = 0; + double min_z = 0; + double max_z = 0; + double fmon_x=0, smon_x=0, fmon_y=0, smon_y=0, mean_z=0; + double Nsum=0; + double P2sum=0; + + int i,j; + + if (!f || m*n*p == 0) return; + + if (p1) + { + min_z = p1[0]; + max_z = min_z; + for(j = 0; j < n*p; j++) + { + for(i = 0; i < m; i++) + { + double x,y,z; + double N, E; + long index; + + if (!istransposed) index = i*n*p + j; + else index = i+j*m; + if (p0) N = p0[index]; + if (p2) E = p2[index]; + + if (m) x = x1 + (i + 0.5)/m*(x2 - x1); else x = 0; + if (n) y = y1 + (j + 0.5)/n/p*(y2 - y1); else y = 0; + z = p1[index]; + sum_xz += x*z; + sum_yz += y*z; + sum_x += x; + sum_y += y; + sum_z += z; + sum_x2z += x*x*z; + sum_y2z += y*y*z; + if (z > max_z) max_z = z; + if (z < min_z) min_z = z; + + Nsum += p0 ? N : 1; + P2sum += p2 ? E : z*z; + } + } + if (sum_z && n*m*p) + { + fmon_x = sum_xz/sum_z; + fmon_y = sum_yz/sum_z; + smon_x = sqrt(sum_x2z/sum_z-fmon_x*fmon_x); + smon_y = sqrt(sum_y2z/sum_z-fmon_y*fmon_y); + mean_z = sum_z/n/m/p; + } + } + + if (m*n*p == 1) + { strcpy(type, "array_0d"); strcpy(stats, ""); } + else if (n == 1 || m == 1) + { if (m == 1) {m = n; n = 1; } + sprintf(type, "array_1d(%d)", m); + sprintf(stats, "X0=%g; dX=%g;", fmon_x, smon_x); } + else + { if (p == 1) sprintf(type, "array_2d(%d, %d)", m, n); + else sprintf(type, "array_3d(%d, %d, %d)", m, n, p); + sprintf(stats, "X0=%g; dX=%g; Y0=%g; dY=%g;", fmon_x, smon_x, fmon_y, smon_y); } + strcpy(c, "I "); + if (zvar && strlen(zvar)) strncpy(c, zvar,32); + else if (yvar && strlen(yvar)) strncpy(c, yvar,32); + else if (xvar && strlen(xvar)) strncpy(c, xvar,32); + else strncpy(c, xvar,32); + if (m == 1 || n == 1) sprintf(vars, "%s %s %s_err N", xvar, c, c); + else sprintf(vars, "%s %s_err N", c, c); + + run_num = mcget_run_num(); + ncount = mcget_ncount(); + sprintf(ratio, "%g/%g", run_num, ncount); + + mcfile_tag(f, format, pre, parent, "type", type); + mcfile_tag(f, format, pre, parent, "Source", mcinstrument_source); + if (parent) mcfile_tag(f, format, pre, parent, (strstr(format.Name,"McStas") ? "component" : "parent"), parent); + if (title) mcfile_tag(f, format, pre, parent, "title", title); + mcfile_tag(f, format, pre, parent, "ratio", ratio); + if (filename) { + mcfile_tag(f, format, pre, parent, "filename", filename); + mcfile_tag(f, format, pre, parent, "format", format.Name); + } else mcfile_tag(f, format, pre, parent, "filename", ""); + + if (p1) + { + if (n*m*p > 1) + { + sprintf(signal, "Min=%g; Max=%g; Mean= %g;", min_z, max_z, mean_z); + if (y1 == 0 && y2 == 0) { y1 = min_z; y2 = max_z;} + else if (z1 == 0 && z2 == 0) { z1 = min_z; z2 = max_z;} + } else strcpy(signal, ""); + + mcfile_tag(f, format, pre, parent, "statistics", stats); + mcfile_tag(f, format, pre, parent, "signal", signal); + + sprintf(values, "%g %g %g", sum_z, mcestimate_error(Nsum, sum_z, P2sum), Nsum); + mcfile_tag(f, format, pre, parent, "values", values); + } + strcpy(lim_field, "xylimits"); + if (n*m > 1) + { + mcfile_tag(f, format, pre, parent, "xvar", xvar); + mcfile_tag(f, format, pre, parent, "yvar", yvar); + mcfile_tag(f, format, pre, parent, "xlabel", xlabel); + mcfile_tag(f, format, pre, parent, "ylabel", ylabel); + if ((n == 1 || m == 1) && strstr(format.Name, "McStas")) + { + sprintf(limits, "%g %g", x1, x2); + strcpy(lim_field, "xlimits"); + } + else + { + mcfile_tag(f, format, pre, parent, "zvar", zvar); + mcfile_tag(f, format, pre, parent, "zlabel", zlabel); + sprintf(limits, "%g %g %g %g %g %g", x1, x2, y1, y2, z1, z2); + } + } else strcpy(limits, "0 0 0 0 0 0"); + mcfile_tag(f, format, pre, parent, lim_field, limits); + mcfile_tag(f, format, pre, parent, "variables", vars); +} /* mcinfo_data */ + +/* main output function, works for 0d, 1d, 2d data */ + +void +mcsiminfo_init(FILE *f) +{ + char info_name[256]; + + if (mcdisable_output_files) return; + if (!f && (!mcsiminfo_name || !strlen(mcsiminfo_name))) return; + if (!strchr(mcsiminfo_name,'.')) sprintf(info_name, "%s.%s", mcsiminfo_name, mcformat.Extension); else strcpy(info_name, mcsiminfo_name); + if (!f) mcsiminfo_file = mcnew_file(info_name, "w"); + else mcsiminfo_file = f; + if(!mcsiminfo_file) + fprintf(stderr, + "Warning: could not open simulation description file '%s'\n", + info_name); + else + { + char pre[20]; + int ismcstas; + char simname[1024]; + char root[10]; + + strcpy(pre, ""); + ismcstas = (strstr(mcformat.Name, "McStas") != NULL); + if (strstr(mcformat.Name, "XML") == NULL && strstr(mcformat.Name, "NeXus") == NULL) strcpy(root, "mcstas"); + else strcpy(root, "root"); + if (mcdirname) sprintf(simname, "%s%s%s", mcdirname, MC_PATHSEP_S, mcsiminfo_name); else sprintf(simname, "%s%s%s", ".", MC_PATHSEP_S, mcsiminfo_name); + + mcfile_header(mcsiminfo_file, mcformat, "header", pre, simname, root); + mcfile_section(mcsiminfo_file, mcformat, "begin", pre, mcinstrument_name, "instrument", root, 1); + mcinfo_instrument(mcsiminfo_file, mcformat, pre, mcinstrument_name); + if (ismcstas) mcfile_section(mcsiminfo_file, mcformat, "end", pre, mcinstrument_name, "instrument", root, 1); + mcfile_section(mcsiminfo_file, mcformat, "begin", pre, simname, "simulation", mcinstrument_name, 2); + mcinfo_simulation(mcsiminfo_file, mcformat, pre, simname); + if (ismcstas) mcfile_section(mcsiminfo_file, mcformat, "end", pre, simname, "simulation", mcinstrument_name, 2); + } +} /* mcsiminfo_init */ + +void +mcsiminfo_close(void) +{ + if (mcdisable_output_files) return; + if(mcsiminfo_file) + { + int ismcstas; + char simname[1024]; + char root[10]; + char pre[10]; + + strcpy(pre, " "); + ismcstas = (strstr(mcformat.Name, "McStas") != NULL); + if (mcdirname) sprintf(simname, "%s%s%s", mcdirname, MC_PATHSEP_S, mcsiminfo_name); else sprintf(simname, "%s%s%s", ".", MC_PATHSEP_S, mcsiminfo_name); + if (strstr(mcformat.Name, "XML") == NULL && strstr(mcformat.Name, "NeXus") == NULL) strcpy(root, "mcstas"); else strcpy(root, "root"); + + if (!ismcstas) + { + mcfile_section(mcsiminfo_file, mcformat, "end", pre, simname, "simulation", mcinstrument_name, 2); + mcfile_section(mcsiminfo_file, mcformat, "end", pre, mcinstrument_name, "instrument", root, 1); + } + mcfile_header(mcsiminfo_file, mcformat, "footer", pre, simname, root); + + if (mcsiminfo_file != stdout) fclose(mcsiminfo_file); + mcsiminfo_file = NULL; + } +} /* mcsiminfo_close */ + +/* mcfile_datablock: output a single data block using specific file format. + * 'part' can be 'data','errors','ncount' + * if y1 == y2 == 0 and McStas format, then stores as a 1D array with [I,E,N] + * return value: 0=0d/2d, 1=1d + * when !single_file, create independent data files, with header and data tags + * if one of the dimensions m,n,p is negative, the data matrix will be written + * after transposition of m/x and n/y dimensions + */ + +static int mcfile_datablock(FILE *f, struct mcformats_struct format, + char *pre, char *parent, char *part, + double *p0, double *p1, double *p2, int m, int n, int p, + char *xlabel, char *ylabel, char *zlabel, char *title, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, + char *filename, char istransposed) +{ + char *Begin; + char *End; + char valid_xlabel[64]; + char valid_ylabel[64]; + char valid_zlabel[64]; + char valid_parent[64]; + FILE *datafile= NULL; + int isdata=0; + int just_header=0; + int i,j, is1d; + double Nsum=0, Psum=0, P2sum=0; + char sec[256]; + char isdata_present; + + if (strstr(part,"data")) + { isdata = 1; Begin = format.BeginData; End = format.EndData; } + if (strstr(part,"errors")) + { isdata = 2; Begin = format.BeginErrors; End = format.EndErrors; } + if (strstr(part,"ncount")) + { isdata = 0; Begin = format.BeginNcount; End = format.EndNcount; } + if (strstr(part, "begin")) just_header = 1; + if (strstr(part, "end")) just_header = 2; + + isdata_present=((isdata==1 && p1) || (isdata==2 && p2) || (isdata==0 && p0)); + + is1d = ((m==1 || n==1) && strstr(format.Name,"McStas")); + mcvalid_name(valid_xlabel, xlabel, 64); + mcvalid_name(valid_ylabel, ylabel, 64); + mcvalid_name(valid_zlabel, zlabel, 64); + + if (strstr(format.Name, "McStas") || !filename || strlen(filename) == 0) + mcvalid_name(valid_parent, parent, 64); + else mcvalid_name(valid_parent, filename, 64); + + /* if normal or begin and part == data: output info_data (sim/data_file) */ + if (isdata == 1 && just_header != 2 && f) + { + mcinfo_data(f, format, pre, valid_parent, title, m, n, p, + xlabel, ylabel, zlabel, xvar, yvar, zvar, + x1, x2, y1, y2, z1, z2, filename, p0, p1, p2, istransposed); + } + + /* if normal or begin: begin part (sim/data file) */ + if (strlen(Begin) && just_header != 2 && f) + pfprintf(f, Begin, "ssssssssssssslllgggggg", + pre, /* %1$s */ + valid_parent, /* %2$s */ + title, /* %3$s */ + filename, /* %4$s */ + xlabel, /* %5$s */ + valid_xlabel, /* %6$s*/ + ylabel, /* %7$s */ + valid_ylabel, /* %8$s */ + zlabel, /* %9$s*/ + valid_zlabel, /* %10$s*/ + xvar, /* %11$s */ + yvar, /* %12$s */ + zvar, /* %13$s */ + m, /* %14$li */ + n, /* %15$li */ + p, /* %16$li */ + x1, /* %17$g */ + x2, /* %18$g */ + y1, /* %19$g*/ + y2, /* %20$g */ + z1, /* %21$g */ + z2); /* %22$g */ + + /* if normal, and !single: + * open datafile, + * if !ascii_only + * if data: write file header, + * call datablock part+header(begin) + * else data file = f + */ + if (!mcsingle_file && just_header == 0) + { + /* if data: open new file for data else append for error/ncount */ + if (filename) datafile = mcnew_file(filename, + (isdata != 1 || strstr(format.Name, "append") ? "a" : "w")); + else datafile = NULL; + /* special case of IDL: can not have empty vectors. Init to 'empty' */ + if (strstr(format.Name, "IDL") && f) fprintf(f, "'external'"); + /* if data, start with root header plus tags of parent data */ + if (datafile && !mcascii_only) + { + char mode[32]; + if (isdata == 1) mcfile_header(datafile, format, "header", + (strstr(format.Name, "McStas") ? "# " : ""), + filename, valid_parent); + sprintf(mode, "%s begin", part); + /* write header+data block begin tags into datafile */ + mcfile_datablock(datafile, format, + (strstr(format.Name, "McStas") ? "# " : ""), + valid_parent, mode, + p0, p1, p2, m, n, p, + xlabel, ylabel, zlabel, title, + xvar, yvar, zvar, + x1, x2, y1, y2, z1, z2, filename, istransposed); + + + } + } + else if (just_header == 0) + { + if (strstr(format.Name, "McStas") && m*n*p>1 && f) + { + if (is1d) sprintf(sec,"array_1d(%d)", m); + else if (p==1) sprintf(sec,"array_2d(%d,%d)", m,n); + else sprintf(sec,"array_3d(%d,%d,%d)", m,n,p); + fprintf(f,"%sbegin %s\n", pre, sec); + datafile = f; + } + if (mcsingle_file) datafile = f; + } + + /* if normal: [data] in data file */ + /* do loops: 2 loops on m,n. */ + if (just_header == 0) + { + char eol_char[3]; + int isIDL, isPython; + int isBinary=0; + + if (strstr(format.Name, "binary float")) isBinary=1; + else if (strstr(format.Name, "binary double")) isBinary=2; + isIDL = (strstr(format.Name, "IDL") != NULL); + isPython = (strstr(format.Name, "Python") != NULL); + if (isIDL) strcpy(eol_char,"$\n"); else strcpy(eol_char,"\n"); + + for(j = 0; j < n*p; j++) /* loop on rows(y) */ + { + if(datafile && !isBinary) + fprintf(datafile,"%s", pre); + for(i = 0; i < m; i++) /* write all columns (x) */ + { + double I=0, E=0, N=0; + double value=0; + long index; + + if (!istransposed) index = i*n*p + j; + else index = i+j*m; + if (p0) N = p0[index]; + if (p1) I = p1[index]; + if (p2) E = p2[index]; + + Nsum += p0 ? N : 1; + Psum += I; + P2sum += p2 ? E : I*I; + + if (p0 && p1 && p2) E = mcestimate_error(N,I,E); + if(datafile && !isBinary && isdata_present) + { + if (isdata == 1) value = I; + else if (isdata == 0) value = N; + else if (isdata == 2) value = E; + if (is1d) + { + double x; + + x = x1+(x2-x1)*(index)/(m*n*p); + if (m*n*p > 1) fprintf(datafile, "%g %g %g %g\n", x, I, E, N); + } + else + { + fprintf(datafile, "%g", value); + if ((isIDL || isPython) && ((i+1)*(j+1) < m*n*p)) fprintf(datafile, ","); + else fprintf(datafile, " "); + } + } + } + if (datafile && !isBinary && isdata_present) fprintf(datafile, eol_char); + } /* end 2 loops if not Binary */ + if (datafile && isBinary) + { + double *d=NULL; + if (isdata==1) d=p1; + else if (isdata==2) d=p2; + else if (isdata==0) d=p0; + + if (d && isBinary == 1) /* float */ + { + float *s; + s = (float*)malloc(m*n*p*sizeof(float)); + if (s) + { + long i, count; + for (i=0; i 1) + fprintf(f,"%send %s\n", pre, sec); + } + + /* set return value */ + return(is1d); +} /* mcfile_datablock */ + +/* mcfile_data: output data/errors/ncounts using specific file format. + * if McStas 1D then data is stored + * as a long 1D array [p0, p1, p2] to reorder -> don't output err/ncount again. + * if p1 or p2 is NULL then skip that part. + */ +static int mcfile_data(FILE *f, struct mcformats_struct format, + char *pre, char *parent, + double *p0, double *p1, double *p2, int m, int n, int p, + char *xlabel, char *ylabel, char *zlabel, char *title, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, + char *filename, char istransposed) +{ + int is1d; + + /* return if f,n,m,p1 NULL */ + if ((m*n*p == 0) || !p1) return (-1); + + /* output data block */ + is1d = mcfile_datablock(f, format, pre, parent, "data", + p0, p1, p2, m, n, p, + xlabel, ylabel, zlabel, title, + xvar, yvar, zvar, + x1, x2, y1, y2, z1, z2, filename, istransposed); + /* return if 1D data */ + if (is1d) return(is1d); + /* output error block and p2 non NULL */ + if (p0 && p2) mcfile_datablock(f, format, pre, parent, "errors", + p0, p1, p2, m, n, p, + xlabel, ylabel, zlabel, title, + xvar, yvar, zvar, + x1, x2, y1, y2, z1, z2, filename, istransposed); + /* output ncount block and p0 non NULL */ + if (p0 && p2) mcfile_datablock(f, format, pre, parent, "ncount", + p0, p1, p2, m, n, p, + xlabel, ylabel, zlabel, title, + xvar, yvar, zvar, + x1, x2, y1, y2, z1, z2, filename, istransposed); + + return(is1d); +} /* mcfile_data */ + +double +mcdetector_out(char *cname, double p0, double p1, double p2, char *filename) +{ + printf("Detector: %s_I=%g %s_ERR=%g %s_N=%g", + cname, p1, cname, mcestimate_error(p0,p1,p2), cname, p0); + if(filename && strlen(filename)) + printf(" \"%s\"", filename); + printf("\n"); + return(p0); +} + +/* parent is the component name */ + +static double mcdetector_out_012D(struct mcformats_struct format, + char *pre, char *parent, char *title, + int m, int n, int p, + char *xlabel, char *ylabel, char *zlabel, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, + char *filename, + double *p0, double *p1, double *p2) +{ + char simname[512]; + int i,j; + double Nsum=0, Psum=0, P2sum=0; + FILE *local_f=NULL; + char istransposed=0; + + if (m<0 || n<0 || p<0 || strstr(format.Name, "binary")) /* do the swap once for all */ + { + double tmp1, tmp2; + char *lab; + istransposed = 1; + + i=m; m=abs(n); n=abs(i); p=abs(p); + } + + if (!strstr(format.Name,"partial")) local_f = mcsiminfo_file; + if (mcdirname) sprintf(simname, "%s%s%s", mcdirname, MC_PATHSEP_S, mcsiminfo_name); else sprintf(simname, "%s%s%s", ".", MC_PATHSEP_S, mcsiminfo_name); + + if (!mcdisable_output_files) + { + + mcfile_section(local_f, format, "begin", pre, parent, "component", simname, 3); + mcfile_section(local_f, format, "begin", pre, filename, "data", parent, 4); + mcfile_data(local_f, format, + pre, parent, + p0, p1, p2, m, n, p, + xlabel, ylabel, zlabel, title, + xvar, yvar, zvar, + x1, x2, y1, y2, z1, z2, filename, istransposed); + + mcfile_section(local_f, format, "end", pre, filename, "data", parent, 4); + mcfile_section(local_f, format, "end", pre, parent, "component", simname, 3); + } + + if (local_f || mcdisable_output_files) + { + for(j = 0; j < n*p; j++) + { + for(i = 0; i < m; i++) + { + double N,I,E; + int index; + if (!istransposed) index = i*n*p + j; + else index = i+j*m; + if (p0) N = p0[index]; + if (p1) I = p1[index]; + if (p2) E = p2[index]; + + Nsum += p0 ? N : 1; + Psum += I; + P2sum += p2 ? E : I*I; + } + } + /* give 0D detector output. */ + mcdetector_out(parent, Nsum, Psum, P2sum, filename); + } + return(Psum); +} /* mcdetector_out_012D */ + +void mcheader_out(FILE *f,char *parent, + int m, int n, int p, + char *xlabel, char *ylabel, char *zlabel, char *title, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, + char *filename) +{ + int loc_single_file; + char pre[3]; + char simname[512]; + loc_single_file = mcsingle_file; mcsingle_file = 1; + + if (!strstr(mcformat.Name, "McStas")) strcpy(pre,""); else strcpy(pre,"# "); + + mcfile_header(f, mcformat, "header", pre, mcinstrument_name, "mcstas"); + mcinfo_instrument(f, mcformat, pre, mcinstrument_name); + if (mcdirname) sprintf(simname, "%s%s%s", mcdirname, MC_PATHSEP_S, mcsiminfo_name); else sprintf(simname, "%s%s%s", ".", MC_PATHSEP_S, mcsiminfo_name); + + mcfile_datablock(f, mcformat, + pre, parent, "data", + NULL,NULL,NULL, m, n, p, + xlabel, ylabel, zlabel, title, + xvar, yvar, zvar, x1, x2, y1, y2, z1, z2, + filename, 0); + + mcsingle_file = loc_single_file; + mcfile_header(f, mcformat, "footer", pre, mcinstrument_name, "mcstas"); +} + + +double mcdetector_out_0D(char *t, double p0, double p1, double p2, char *c) +{ + char pre[20]; + + strcpy(pre, ""); + return(mcdetector_out_012D(mcformat, + pre, c, t, + 1, 1, 1, + "I", "", "", + "I", "", "", + 0, 0, 0, 0, 0, 0, NULL, + &p0, &p1, &p2)); +} + +double mcdetector_out_1D(char *t, char *xl, char *yl, + char *xvar, double x1, double x2, int n, + double *p0, double *p1, double *p2, char *f, char *c) +{ + char pre[20]; + + strcpy(pre, ""); + return(mcdetector_out_012D(mcformat, + pre, c, t, + n, 1, 1, + xl, yl, "Intensity", + xvar, "(I,I_err)", "I", + x1, x2, x1, x2, 0, 0, f, + p0, p1, p2)); +} + +double mcdetector_out_2D(char *t, char *xl, char *yl, + double x1, double x2, double y1, double y2, int m, + int n, double *p0, double *p1, double *p2, char *f, char *c) +{ + char xvar[3]; + char yvar[3]; + char pre[20]; + + strcpy(pre, ""); strcpy(xvar, "x "); strcpy(yvar, "y "); + if (xl && strlen(xl)) strncpy(xvar, xl, 2); + if (yl && strlen(yl)) strncpy(yvar, yl, 2); + + return(mcdetector_out_012D(mcformat, + pre, c, t, + m, n, 1, + xl, yl, "Intensity", + xvar, yvar, "I", + x1, x2, y1, y2, 0, 0, f, + p0, p1, p2)); +} + +double mcdetector_out_3D(char *t, char *xl, char *yl, char *zl, + char *xvar, char *yvar, char *zvar, + double x1, double x2, double y1, double y2, double z1, double z2, int m, + int n, int p, double *p0, double *p1, double *p2, char *f, char *c) +{ + char pre[20]; + + strcpy(pre, ""); + return(mcdetector_out_012D(mcformat, + pre, c, t, + m, n, p, + xl, yl, zl, + xvar, yvar, zvar, + x1, x2, y1, y2, z1, z2, f, + p0, p1, p2)); +} + +/* end of file i/o functions */ + + + +static void +mcuse_dir(char *dir) +{ +#ifdef MC_PORTABLE + fprintf(stderr, "Error: " + "Directory output cannot be used with portable simulation.\n"); + exit(1); +#else /* !MC_PORTABLE */ + if(mkdir(dir, 0777)) + { + fprintf(stderr, "Error: unable to create directory '%s'.\n", dir); + fprintf(stderr, "(Maybe the directory already exists?)\n"); + exit(1); + } + mcdirname = dir; +#endif /* !MC_PORTABLE */ +} + +static void +mcuse_file(char *file) +{ + mcsiminfo_name = file; + mcsingle_file = 1; +} + +void mcuse_format(char *format) +{ + int i,j; + int i_format=-1; + char *tmp; + char low_format[256]; + + /* get the format to lower case */ + if (!format) return; + strcpy(low_format, format); + for (i=0; i MCSTAS define +* monitor_nd-lib: fix Log(signal) log(coord) +* HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample +* Progress_bar: precent -> percent parameter +* CS: ---------------------------------------------------------------------- +* +* Revision 1.1 2002/08/29 11:39:00 ef +* Initial revision extracted from lib/optics/Monochromators... +*******************************************************************************/ + +#ifndef READ_TABLE_LIB_H +#define READ_TABLE_LIB_H "1.1.0" + +#include + + typedef struct struct_table + { + char filename[128]; + char *header; + double *data; /* vector { x[0], y[0], ... x[n-1], y[n-1]... } */ + double min_x; + double max_x; + double step_x; + long rows; + long columns; + long block_number; + } t_Table; + +/* read_table-lib function prototypes */ +/* ========================================================================= */ +void Table_Init(t_Table *Table); +void Table_Free(t_Table *Table); +long Table_Read(t_Table *Table, char *File, long block_number); +long Table_Read_Offset(t_Table *mc_rt_Table, char *mc_rt_File, long mc_rt_block_number, long *offset, long max_lines); +long Table_Read_Offset_Binary(t_Table *mc_rt_Table, char *mc_rt_File, char *mc_rt_type, long *mc_rt_offset, long mc_rt_rows, long mc_rt_columns); +long Table_Read_Handle(t_Table *Table, FILE *fid, long block_number, long max_lines); +long Table_Rebin(t_Table *Table); +double Table_Index(t_Table Table, long i, long j); +double Table_Value(t_Table Table, double X, long j); +void Table_Info(t_Table Table); +static void Table_Stat(t_Table *mc_rt_Table); + +#endif + +/* end of read_table-lib.h */ +/******************************************************************************* +* +* McStas, neutron ray-tracing package +* Copyright 1997-2002, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* Library: share/read_table-lib.c +* +* %Identification +* Written by: EF +* Date: Aug 28, 2002 +* Origin: ILL +* Release: McStas 1.6 +* Version: 1.2 +* +* This file is to be imported by components that may read data from table files +* It handles some shared functions. Embedded within instrument in runtime mode. +* Variable names have prefix 'mc_rt_' for 'McStas Read Table' to avoid conflicts +* +* Usage: within SHARE +* %include "read_table-lib" +* +* $Id: dmcafter.c,v 1.1 2007/01/30 03:19:43 koennecke Exp $ +* +* $Log: dmcafter.c,v $ +* Revision 1.1 2007/01/30 03:19:43 koennecke +* - Fixed state monitor eclipse commit problems. Siiiiiiiggggghhhhhh! +* +* Revision 1.9 2003/05/20 15:12:33 farhi +* malloc size for read table binary now needs less memory +* +* Revision 1.8 2003/02/11 12:28:46 farhi +* Variouxs bug fixes after tests in the lib directory +* mcstas_r : disable output with --no-out.. flag. Fix 1D McStas output +* read_table:corrected MC_SYS_DIR -> MCSTAS define +* monitor_nd-lib: fix Log(signal) log(coord) +* HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample +* Progress_bar: precent -> percent parameter +* CS: ---------------------------------------------------------------------- +* +* Revision 1.8 2003/02/06 14:14:41 farhi +* Corrected MC_SYS_DIR into MCSTAS definition of default lib location +* +* Revision 1.2 2002/12/19 12:48:07 ef +* Added binary import. Fixed Rebin. Added Stat. +* +* Revision 1.1 2002/08/29 11:39:00 ef +* Initial revision extracted from lib/optics/Monochromators... +*******************************************************************************/ + +#ifndef READ_TABLE_LIB_H +#error McStas : please import this library with %include "read_table-lib" +#endif + +/******************************************************************************* +* long Read_Table(t_Table *Table, char *name, int block_number) +* input Table: pointer to a t_Table structure +* name: file name from which table should be extracted +* block_number: if the file does contain more than one +* data block, then indicates which one to get (from index 1) +* a 0 value means append/catenate all +* return modified Table t_Table structure containing data, header, ... +* number of read elements (-1: error, 0:header only) +* The routine stores any line starting with '#', '%' and ';' into the header +* File is opened, read and closed +* Other lines are interpreted as numerical data, and stored. +* Data block should be a rectangular matrix or vector. +* Data block may be rebined with Table_Rebin (also sort in ascending order) +*******************************************************************************/ + long Table_Read(t_Table *mc_rt_Table, char *mc_rt_File, long mc_rt_block_number) + { /* reads all/a data block in 'file' and returns a Table structure */ + long mc_rt_offset=0; + return(Table_Read_Offset(mc_rt_Table, mc_rt_File, mc_rt_block_number, &mc_rt_offset, 0)); + + } /* end Table_Read */ + +/******************************************************************************* +* long Table_Read_Offset(t_Table *Table, char *name, int block_number, long *mc_rt_offset +* long mc_rt_max_lines) +* Same as Table_Read(..) except: +* input mc_rt_offset: pointer to an mc_rt_offset (*mc_rt_offset should be 0 at start) +* mc_rt_max_lines: max number of data rows to read from file (0 means all) +* return also updated *mc_rt_offset position (where end of reading occured) +*******************************************************************************/ + long Table_Read_Offset(t_Table *mc_rt_Table, char *mc_rt_File, long mc_rt_block_number, long *mc_rt_offset, long mc_rt_max_lines) + { /* reads all/a data block in 'file' and returns a Table structure */ + FILE *mc_rt_hfile; + long mc_rt_nelements; + + if (!mc_rt_File) return (-1); + if (strlen(mc_rt_File) == 0) return (-1); + mc_rt_hfile = fopen(mc_rt_File, "r"); + if(!mc_rt_hfile) + { + char mc_rt_path[256]; + char mc_rt_dir[256]; + + if (!strchr(mc_rt_File, MC_PATHSEP_C)) + { + if (getenv("MCSTAS")) strcpy(mc_rt_dir, getenv("MCSTAS")); + else strcpy(mc_rt_dir, MCSTAS); + sprintf(mc_rt_path, "%s%c%s%c%s", mc_rt_dir, MC_PATHSEP_C, "data", MC_PATHSEP_C, mc_rt_File); + mc_rt_hfile = fopen(mc_rt_path, "r"); + } + if(!mc_rt_hfile) + { + fprintf(stderr, "Error: Could not open input file '%s' (Table_Read)\n", mc_rt_File); + return (-1); + } + } + if (mc_rt_offset && *mc_rt_offset) fseek(mc_rt_hfile, *mc_rt_offset, SEEK_SET); + mc_rt_nelements = Table_Read_Handle(mc_rt_Table, mc_rt_hfile, mc_rt_block_number, mc_rt_max_lines); + strncpy(mc_rt_Table->filename, mc_rt_File, 128); + if (mc_rt_offset) *mc_rt_offset=ftell(mc_rt_hfile); + fclose(mc_rt_hfile); + return(mc_rt_nelements); + + } /* end Table_Read_Offset */ + +/******************************************************************************* +* long Table_Read_Offset_Binary(t_Table *mc_rt_Table, char *mc_rt_File, char *mc_rt_type, +* long +mc_rt_offset, long mc_rt_max_lines) +* Same as Table_Read_Offset(..) except that it handles binary files. +* input mc_rt_type: may be "float" or "double" +* mc_rt_offset: pointer to an mc_rt_offset (*mc_rt_offset should be 0 at start) +* mc_rt_columns: number of columns +* mc_rt_rows : max number of data rows to read from file (0 means all) +* return also updated *mc_rt_offset position (where end of reading occured) +*******************************************************************************/ + long Table_Read_Offset_Binary(t_Table *mc_rt_Table, char *mc_rt_File, char *mc_rt_type, long *mc_rt_offset, long mc_rt_rows, long mc_rt_columns) + { + long mc_rt_nelements, mc_rt_sizeofelement; + long mc_rt_filesize; + FILE *mc_rt_hfile; + struct stat mc_rt_stfile; + double *mc_rt_data; + long mc_rt_i; + + Table_Init(mc_rt_Table); + + stat(mc_rt_File,&mc_rt_stfile); + mc_rt_filesize = mc_rt_stfile.st_size; + mc_rt_hfile = fopen(mc_rt_File, "r"); + if(!mc_rt_hfile) + { + char mc_rt_path[256]; + char mc_rt_dir[256]; + + if (!strchr(mc_rt_File, MC_PATHSEP_C)) + { + if (getenv("MCSTAS")) strcpy(mc_rt_dir, getenv("MCSTAS")); + else strcpy(mc_rt_dir, MCSTAS); + sprintf(mc_rt_path, "%s%c%s%c%s", mc_rt_dir, MC_PATHSEP_C, "data", MC_PATHSEP_C, mc_rt_File); + mc_rt_hfile = fopen(mc_rt_path, "r"); + } + if(!mc_rt_hfile) + { + fprintf(stderr, "Error: Could not open input file '%s' (Table_Read_Binary)\n", mc_rt_File); + return (-1); + } + } + if (mc_rt_type && !strcmp(mc_rt_type,"double")) mc_rt_sizeofelement = sizeof(double); + else mc_rt_sizeofelement = sizeof(float); + if (mc_rt_offset && *mc_rt_offset) fseek(mc_rt_hfile, *mc_rt_offset, SEEK_SET); + if (mc_rt_rows && mc_rt_filesize > mc_rt_sizeofelement*mc_rt_columns*mc_rt_rows) + mc_rt_nelements = mc_rt_columns*mc_rt_rows; + else mc_rt_nelements = (long)(mc_rt_filesize/mc_rt_sizeofelement); + if (!mc_rt_nelements || mc_rt_filesize <= *mc_rt_offset) return(0); + mc_rt_data = (double*)malloc(mc_rt_nelements*mc_rt_sizeofelement); + if (!mc_rt_data) { + fprintf(stderr,"Error: allocating %d elements for %s file '%s'. Too big (Table_Read_Offset_Binary).\n", mc_rt_nelements, mc_rt_type, mc_rt_File); + exit(-1); + } + mc_rt_nelements = fread(mc_rt_data, mc_rt_sizeofelement, mc_rt_nelements, mc_rt_hfile); + + if (!mc_rt_data || !mc_rt_nelements) + { + fprintf(stderr,"Error: reading %d elements from %s file '%s' (Table_Read_Offset_Binary)\n", mc_rt_nelements, mc_rt_type, mc_rt_File); + exit(-1); + } + if (mc_rt_offset) *mc_rt_offset=ftell(mc_rt_hfile); + fclose(mc_rt_hfile); + mc_rt_data = (double*)realloc(mc_rt_data, (double)mc_rt_nelements*mc_rt_sizeofelement); + /* copy file data into Table */ + if (mc_rt_type && !strcmp(mc_rt_type,"double")) mc_rt_Table->data = mc_rt_data; + else { + float *mc_rt_s; + double *mc_rt_dataf; + mc_rt_s = (float*)mc_rt_data; + mc_rt_dataf = (double*)malloc(sizeof(double)*mc_rt_nelements); + for (mc_rt_i=0; mc_rt_idata = mc_rt_dataf; + } + strcpy(mc_rt_Table->filename, mc_rt_File); + mc_rt_Table->rows = mc_rt_nelements/mc_rt_columns; + mc_rt_Table->columns = mc_rt_columns; + Table_Stat(mc_rt_Table); + + return(mc_rt_nelements); + } /* end Table_Read_Offset_Binary */ + +/******************************************************************************* +* long Read_Table_Handle(t_Table *Table, FILE *fid, int block_number) +* input Table:pointer to a t_Table structure +* fid: pointer to FILE handle +* block_number: if the file does contain more than one +* data block, then indicates which one to get (from index 1) +* a 0 value means append/catenate all +* mc_rt_max_lines: if non 0, only reads that number of lines +* return modified Table t_Table structure containing data, header, ... +* number of read elements (-1: error, 0:header only) +* The routine stores any line starting with '#', '%' and ';' into the header +* Other lines are interpreted as numerical data, and stored. +* Data block should be a rectangular matrix or vector. +* Data block may be rebined with Table_Rebin (also sort in ascending order) +*******************************************************************************/ + long Table_Read_Handle(t_Table *mc_rt_Table, FILE *mc_rt_hfile, long mc_rt_block_number, long mc_rt_max_lines) + { /* reads all/a data block in 'file' and returns a Table structure */ + double *mc_rt_Data; + char *mc_rt_Header; + long mc_rt_malloc_size = 1024; + long mc_rt_malloc_size_h = 4096; + char mc_rt_flag_exit_loop = 0; + long mc_rt_Rows = 0, mc_rt_Columns = 0; + long mc_rt_count_in_array = 0; + long mc_rt_count_in_header = 0; + long mc_rt_cur_block_number = 0; + char mc_rt_flag_in_array = 0; + + Table_Init(mc_rt_Table); + + if(!mc_rt_hfile) + { + fprintf(stderr, "Error: File handle is NULL (Table_Read_Handle).\n"); + return (-1); + } + mc_rt_Header = (char*) malloc(mc_rt_malloc_size_h*sizeof(char)); + mc_rt_Data = (double*)malloc(mc_rt_malloc_size *sizeof(double)); + if ((mc_rt_Header == NULL) || (mc_rt_Data == NULL)) + { + fprintf(stderr, "Error: Could not allocate Table and Header (Table_Read_Handle).\n"); + return (-1); + } + mc_rt_Header[0] = '\0'; + + while (!mc_rt_flag_exit_loop) + { + char mc_rt_line[4096]; + long mc_rt_back_pos=0; + + mc_rt_back_pos = ftell(mc_rt_hfile); + if (fgets(mc_rt_line, 4096, mc_rt_hfile) != NULL) + { /* tries to read some informations from the file */ + int mc_rt_i=0; + /* first skip blank and tabulation characters */ + while (mc_rt_line[mc_rt_i] == ' ' || mc_rt_line[mc_rt_i] == '\t') mc_rt_i++; + if ((mc_rt_line[mc_rt_i] == '#') || (mc_rt_line[mc_rt_i] == '%') + || (mc_rt_line[mc_rt_i] == ';') || (mc_rt_line[mc_rt_i] == '/')) + { + if (mc_rt_flag_in_array && mc_rt_block_number) + mc_rt_count_in_header = 0; /* comment comes after a data block */ + mc_rt_count_in_header += strlen(mc_rt_line); + if (mc_rt_count_in_header+4096 > mc_rt_malloc_size_h) + { /* if succeed and in array : add (and realloc if necessary) */ + mc_rt_malloc_size_h = mc_rt_count_in_header+4096; + mc_rt_Header = (char*)realloc(mc_rt_Header, mc_rt_malloc_size_h*sizeof(char)); + } + strncat(mc_rt_Header, mc_rt_line, 4096); + mc_rt_flag_in_array = 0; /* will start a new data block */ + } /* line is a comment */ + else + { + double mc_rt_X; + + /* get the number of columns splitting mc_rt_line with strtok */ + if (sscanf(mc_rt_line,"%lg ",&mc_rt_X) == 1) /* mc_rt_line begins at least with one num */ + { + char *mc_rt_InputTokens, *mc_rt_lexeme; + char mc_rt_End_Line_Scanning_Flag= 0; + long mc_rt_This_Line_Columns = 0; + + mc_rt_InputTokens = mc_rt_line; + + while (!mc_rt_End_Line_Scanning_Flag) + { + mc_rt_lexeme = (char *)strtok(mc_rt_InputTokens, " ,;\t\n\r"); + mc_rt_InputTokens = NULL; + if ((mc_rt_lexeme != NULL) && (strlen(mc_rt_lexeme) != 0)) + { + if (sscanf(mc_rt_lexeme,"%lg ",&mc_rt_X) == 1) /* found a number */ + { + if (mc_rt_flag_in_array == 0 + && (((mc_rt_block_number == 0) || (mc_rt_block_number > mc_rt_cur_block_number)))) /* not already in a block -> start */ + { /* starts a new data block */ + if (mc_rt_block_number) + { /* initialise a new data block */ + mc_rt_Rows = 0; + mc_rt_count_in_array = 0; + } /* else append */ + mc_rt_cur_block_number++; + mc_rt_flag_in_array = 1; + mc_rt_This_Line_Columns= 0; /* starts the first data row of this block */ + + } + if (mc_rt_flag_in_array && ((mc_rt_block_number == 0) || (mc_rt_block_number == mc_rt_cur_block_number))) + { /* append all, or within requested block -> store data in row */ + if (mc_rt_count_in_array >= mc_rt_malloc_size) + { /* if succeed and in array : add (and realloc if necessary) */ + mc_rt_malloc_size = mc_rt_count_in_array+1024; + mc_rt_Data = (double*)realloc(mc_rt_Data, mc_rt_malloc_size*sizeof(double)); + if (mc_rt_Data == NULL) + { + fprintf(stderr, "Error: Can not re-allocate memory %i (Table_Read_Handle).\n", mc_rt_malloc_size*sizeof(double)); + return (-1); + } + } + /* test if we've read already the desired number of data lines */ + if (mc_rt_This_Line_Columns == 0 + && mc_rt_max_lines && mc_rt_Rows >= mc_rt_max_lines) { + mc_rt_End_Line_Scanning_Flag = 1; + mc_rt_flag_exit_loop = 1; + mc_rt_flag_in_array = 0; + /* reposition to begining of line */ + fseek(mc_rt_hfile, mc_rt_back_pos, SEEK_SET); + } else { /* store into data array */ + if (mc_rt_This_Line_Columns == 0) mc_rt_Rows++; + mc_rt_Data[mc_rt_count_in_array] = mc_rt_X; + mc_rt_count_in_array++; + mc_rt_This_Line_Columns++; + } + } + else + { /* not in a block to store */ + if ((mc_rt_block_number) && (mc_rt_cur_block_number > mc_rt_block_number)) + { /* we finished to extract block -> force end of file reading */ + mc_rt_End_Line_Scanning_Flag = 1; + mc_rt_flag_exit_loop = 1; + mc_rt_flag_in_array = 0; + } + } + } /* end if sscanf mc_rt_lexeme -> numerical */ + else + { /* token is not numerical in that line */ + mc_rt_End_Line_Scanning_Flag = 1; mc_rt_flag_in_array = 0; + } + } + else + { /* no more tokens in mc_rt_line */ + mc_rt_End_Line_Scanning_Flag = 1; + if (mc_rt_This_Line_Columns) mc_rt_Columns = mc_rt_This_Line_Columns; + } + } /* end while mc_rt_End_Line_Scanning_Flag */ + } + else + { /* non-comment line does not begin with a number: ignore line */ + mc_rt_flag_in_array = 0; + } + } /* end: if not mc_rt_line comment else numerical */ + } /* end: if fgets */ + else mc_rt_flag_exit_loop = 1; /* else fgets : end of file */ + } /* end while mc_rt_flag_exit_loop */ + + mc_rt_Table->block_number = mc_rt_block_number; + if (mc_rt_count_in_header) mc_rt_Header = (char*)realloc(mc_rt_Header, mc_rt_count_in_header*sizeof(char)); + mc_rt_Table->header = mc_rt_Header; + if (mc_rt_count_in_array*mc_rt_Rows*mc_rt_Columns == 0) + { + mc_rt_Table->rows = 0; + mc_rt_Table->columns = 0; + free(mc_rt_Data); + return (0); + } + if (mc_rt_Rows * mc_rt_Columns != mc_rt_count_in_array) + { + fprintf(stderr, "Warning: Read_Table : Data has %li values that should be %li x %li\n", mc_rt_count_in_array, mc_rt_Rows, mc_rt_Columns); + mc_rt_Columns = mc_rt_count_in_array; mc_rt_Rows = 1; + } + mc_rt_Data = (double*)realloc(mc_rt_Data, mc_rt_count_in_array*sizeof(double)); + mc_rt_Table->data = mc_rt_Data; + mc_rt_Table->rows = mc_rt_Rows; + mc_rt_Table->columns = mc_rt_Columns; + Table_Stat(mc_rt_Table); + return (mc_rt_count_in_array); + + } /* end Table_Read_Handle */ + +/******************************************************************************* +* long Rebin_Table(t_Table *Table) +* input Table: table containing data +* return new Table with increasing, evenly spaced first column (index 0) +* number of data elements (-1: error, 0:header only) +*******************************************************************************/ + long Table_Rebin(t_Table *mc_rt_Table) + { + double mc_rt_new_step=0; + long mc_rt_i; + long mc_rt_tmp; + char mc_rt_monotonic = 1; + /* performs linear interpolation on X axis (0-th column) */ + + if (!mc_rt_Table->data + || mc_rt_Table->rows*mc_rt_Table->columns == 0 || !mc_rt_Table->step_x) + return(0); + mc_rt_tmp = mc_rt_Table->rows; + mc_rt_new_step = mc_rt_Table->step_x; + for (mc_rt_i=0; mc_rt_i < mc_rt_Table->rows - 1; mc_rt_i++) + { + double mc_rt_current_step; + double mc_rt_X, mc_rt_diff; + mc_rt_X = Table_Index(*mc_rt_Table,mc_rt_i ,0); + mc_rt_diff = Table_Index(*mc_rt_Table,mc_rt_i+1,0) - mc_rt_X; + mc_rt_current_step = fabs(mc_rt_diff); + if ((mc_rt_Table->max_x - mc_rt_Table->min_x)*mc_rt_diff < 0 && mc_rt_monotonic && mc_rt_Table->columns > 1) + { + fprintf(stderr, "Warning: Rebin_Table : Data from file '%s' (%li x %li) is not monotonic (at row %li)\n", mc_rt_Table->filename, mc_rt_Table->rows, mc_rt_Table->columns, mc_rt_i); + mc_rt_monotonic = 0; + } + if (mc_rt_current_step > 0 && mc_rt_current_step < mc_rt_new_step) mc_rt_new_step = mc_rt_current_step; + else mc_rt_tmp--; + } /* for */ + if (fabs(mc_rt_new_step/mc_rt_Table->step_x) >= 0.98) + return (mc_rt_Table->rows*mc_rt_Table->columns); + if (mc_rt_tmp > 0 && mc_rt_new_step > 0 && mc_rt_Table->columns > 1) /* table was not already evenly sampled */ + { + long mc_rt_Length_Table; + double *mc_rt_New_Table; + /* modify step if leads to too many points */ + if (mc_rt_Table->rows > 2000) + if (mc_rt_new_step < mc_rt_Table->step_x) + mc_rt_new_step = mc_rt_Table->step_x; + if (mc_rt_new_step*10 < mc_rt_Table->step_x) + mc_rt_new_step = mc_rt_Table->step_x/10; + mc_rt_Length_Table = ceil(fabs(mc_rt_Table->max_x - mc_rt_Table->min_x)/mc_rt_new_step); + mc_rt_New_Table = (double*)malloc(mc_rt_Length_Table*mc_rt_Table->columns*sizeof(double)); + + for (mc_rt_i=0; mc_rt_i < mc_rt_Length_Table; mc_rt_i++) + { + long mc_rt_j; + long mc_rt_old_i; + double mc_rt_X; + double mc_rt_X1, mc_rt_X2, mc_rt_Y1, mc_rt_Y2; + char mc_rt_test=0; + mc_rt_X = mc_rt_Table->min_x + mc_rt_i*mc_rt_new_step; + mc_rt_New_Table[mc_rt_i*mc_rt_Table->columns] = mc_rt_X; + /* look for index surrounding X in the old table -> index old_i, old-1 */ + for (mc_rt_old_i=1; mc_rt_old_i < mc_rt_Table->rows-1; mc_rt_old_i++) + { + mc_rt_X2 = Table_Index(*mc_rt_Table,mc_rt_old_i ,0); + mc_rt_X1 = Table_Index(*mc_rt_Table,mc_rt_old_i-1,0); + if (mc_rt_Table->min_x < mc_rt_Table->max_x) + mc_rt_test = ((mc_rt_X1 <= mc_rt_X) && (mc_rt_X < mc_rt_X2)); + else + mc_rt_test = ((mc_rt_X2 <= mc_rt_X) && (mc_rt_X < mc_rt_X1)); + if (mc_rt_test) break; + } + + for (mc_rt_j=1; mc_rt_j < mc_rt_Table->columns; mc_rt_j++) + { + mc_rt_Y2 = Table_Index(*mc_rt_Table,mc_rt_old_i ,mc_rt_j); + mc_rt_Y1 = Table_Index(*mc_rt_Table,mc_rt_old_i-1,mc_rt_j); + if (mc_rt_X2-mc_rt_X1) + { + /* linear interpolation */ + double mc_rt_slope = (mc_rt_Y2-mc_rt_Y1)/(mc_rt_X2-mc_rt_X1); + mc_rt_New_Table[mc_rt_i*mc_rt_Table->columns+mc_rt_j] = mc_rt_Y1+mc_rt_slope*(mc_rt_X-mc_rt_X1); + } + else + mc_rt_New_Table[mc_rt_i*mc_rt_Table->columns+mc_rt_j] = mc_rt_Y2; + } + + } /* end for i */ + mc_rt_Table->rows = mc_rt_Length_Table; + mc_rt_Table->step_x = mc_rt_new_step; + free(mc_rt_Table->data); + mc_rt_Table->data = mc_rt_New_Table; + } /* end if tmp */ + return (mc_rt_Table->rows*mc_rt_Table->columns); + } /* end Rebin_Table */ + +/******************************************************************************* +* double Table_Index(t_Table Table, long i, long j) +* input Table: table containing data +* i : index of row (0:mc_rt_Rows-1) +* j : index of column (0:Columns-1) +* return Value = data[i][j] +* Returns Value from the i-th row, j-th column of Table +* Tests are performed on indexes i,j to avoid errors +*******************************************************************************/ + double Table_Index(t_Table mc_rt_Table, long mc_rt_i, long mc_rt_j) + { + long mc_rt_AbsIndex; + + if (mc_rt_i < 0) mc_rt_i = 0; + if (mc_rt_i >= mc_rt_Table.rows) mc_rt_i = mc_rt_Table.rows-1; + if (mc_rt_j < 0) mc_rt_j = 0; + if (mc_rt_j >= mc_rt_Table.columns) mc_rt_j = mc_rt_Table.columns-1; + mc_rt_AbsIndex = mc_rt_i*(mc_rt_Table.columns)+mc_rt_j; + if (mc_rt_Table.data != NULL) + return(mc_rt_Table.data[mc_rt_AbsIndex]); + else + return(0); + } + +/******************************************************************************* +* double Table_Value(t_Table Table, double X, long j) +* input Table: table containing data +* X : data value in the first column (index 0) +* j : index of column from which is extracted the Value (0:Columns-1) +* return Value = data[index for X][j] +* Returns Value from the j-th column of Table corresponding to the +* X value for the 1st column (index 0) +* Tests are performed (within Table_Index) on indexes i,j to avoid errors +* NOTE: data should rather be monotonic, and evenly sampled. +*******************************************************************************/ + double Table_Value(t_Table mc_rt_Table, double X, long j) + { + long mc_rt_Index; + double mc_rt_Value; + + if (mc_rt_Table.step_x != 0) + mc_rt_Index = floor((X - mc_rt_Table.min_x)/mc_rt_Table.step_x); + else mc_rt_Index=0; + mc_rt_Value = Table_Index(mc_rt_Table, mc_rt_Index, j); + + return(mc_rt_Value); + } +/******************************************************************************* +* void Table_Free(t_Table *Table) +*******************************************************************************/ + void Table_Free(t_Table *mc_rt_Table) + { + if (mc_rt_Table->data != NULL) free(mc_rt_Table->data); + if (mc_rt_Table->header != NULL) free(mc_rt_Table->header); + mc_rt_Table->data = NULL; + mc_rt_Table->header = NULL; + } +/****************************************************************************** +* void Table_Info(t_Table Table) +* prints informations about a Table +*******************************************************************************/ + void Table_Info(t_Table mc_rt_Table) + { + printf("Table from file '%s'", mc_rt_Table.filename); + if (mc_rt_Table.block_number) printf(" (block %li)", mc_rt_Table.block_number); + if ((mc_rt_Table.data != NULL) && (mc_rt_Table.rows*mc_rt_Table.columns)) + { + printf(" is %li x %li.\n", mc_rt_Table.rows, mc_rt_Table.columns); + /* printf("Data axis range %f-%f, step=%f\n", mc_rt_Table.min_x, mc_rt_Table.max_x, mc_rt_Table.step_x); */ + } + else printf(" is empty.\n"); + } + +/****************************************************************************** +* void Table_Init(t_Table *Table) +* initialise a Table to empty +*******************************************************************************/ + void Table_Init(t_Table *mc_rt_Table) + { + mc_rt_Table->data = NULL; + mc_rt_Table->header = NULL; + mc_rt_Table->filename[0]= '\0'; + mc_rt_Table->rows = 0; + mc_rt_Table->columns = 0; + mc_rt_Table->min_x = 0; + mc_rt_Table->max_x = 0; + mc_rt_Table->step_x = 0; + mc_rt_Table->block_number = 0; + } + +/****************************************************************************** +* void Table_Star(t_Table *Table) +* computes min/max/mean step of 1st column +*******************************************************************************/ + static void Table_Stat(t_Table *mc_rt_Table) + { + long mc_rt_i; + double mc_rt_max_x, mc_rt_min_x; + + if (!mc_rt_Table->rows || !mc_rt_Table->columns) return; + mc_rt_max_x = mc_rt_Table->data[0]; + mc_rt_min_x = mc_rt_Table->data[(mc_rt_Table->rows-1)*mc_rt_Table->columns]; + + for (mc_rt_i=0; mc_rt_i < mc_rt_Table->rows - 1; mc_rt_i++) + { + double mc_rt_X; + mc_rt_X = Table_Index(*mc_rt_Table,mc_rt_i ,0); + if (mc_rt_X < mc_rt_min_x) mc_rt_min_x = mc_rt_X; + if (mc_rt_X > mc_rt_max_x) mc_rt_max_x = mc_rt_X; + } /* for */ + mc_rt_Table->max_x = mc_rt_max_x; + mc_rt_Table->min_x = mc_rt_min_x; + mc_rt_Table->step_x = (mc_rt_Table->max_x - mc_rt_Table->min_x)/mc_rt_Table->rows; + } + +/* end of read_table-lib.c */ + + +long Virtual_input_Read_Input(char *aFile, char *aType, t_Table *aTable, long *aOffset) + { + long max_lines = 50000; + long length=0; + char bType[32]; + + if (!aFile) return (-1); + if (aType) strcpy(bType, aType); + else strcpy(bType, "???"); + + Table_Free(aTable); + + /* Try to Open neutron input text file. */ + if((aFile && aType == NULL) || !strcmp(bType,"text")) { + Table_Read_Offset(aTable, aFile, 0, aOffset, max_lines); /* read data from file into rTable */ + strcpy(bType, "text"); + } + if (!aTable->data && aType && aType[0] != 't') + Table_Read_Offset_Binary(aTable, aFile, aType, aOffset, max_lines, 11); + + return(aTable->rows); + } +#line 5023 "dmcafter.c" +#line 103 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/sources/Virtual_input.comp" + int rep=0; /* Neutron repeat count */ + long pos=0; + long nrows=0; + long nread=0; + long Offset=0; + t_Table rTable; +#line 5031 "dmcafter.c" +#undef bufsize +#undef repeat_count +#undef Virtual_input_Read_Input +#undef rTable +#undef Offset +#undef nread +#undef nrows +#undef pos +#undef rep +#undef type +#undef file +#undef mccompcurname +#undef mccompcurindex + +/* User declarations for component 'out2_slit' [7]. */ +#define mccompcurname out2_slit +#define mccompcurindex 3 +#define xmin mccout2_slit_xmin +#define xmax mccout2_slit_xmax +#define ymin mccout2_slit_ymin +#define ymax mccout2_slit_ymax +#define radius mccout2_slit_radius +/* Shared user declarations for all components 'Slit'. */ +#undef radius +#undef ymax +#undef ymin +#undef xmax +#undef xmin +#undef mccompcurname +#undef mccompcurindex + +/* User declarations for component 'PSD_sample' [7]. */ +#define mccompcurname PSD_sample +#define mccompcurindex 4 +#define Nsum mccPSD_sample_Nsum +#define psum mccPSD_sample_psum +#define p2sum mccPSD_sample_p2sum +#define currentCount mccPSD_sample_currentCount +#define xmin mccPSD_sample_xmin +#define xmax mccPSD_sample_xmax +#define ymin mccPSD_sample_ymin +#define ymax mccPSD_sample_ymax +#define controlfile mccPSD_sample_controlfile +#define dumpCount mccPSD_sample_dumpCount +/* Shared user declarations for all components 'MKMonitor'. */ +#line 50 "MKMonitor.comp" + void dumpTotal(char *ffilename, long totalCounts){ + FILE *fd = NULL; + char tmp[1024]; + + strncpy(tmp,ffilename, 1000); + strcat(tmp,"tmp"); + fd = fopen(tmp,"w"); + if(fd != NULL){ + fprintf(fd,"%ld\n",totalCounts); + fclose(fd); + rename(tmp,ffilename); + unlink(tmp); + } + } +#line 5092 "dmcafter.c" +#line 67 "MKMonitor.comp" + long currentCount; + double Nsum; + double psum, p2sum; +#line 5097 "dmcafter.c" +#undef dumpCount +#undef controlfile +#undef ymax +#undef ymin +#undef xmax +#undef xmin +#undef currentCount +#undef p2sum +#undef psum +#undef Nsum +#undef mccompcurname +#undef mccompcurindex + +/* User declarations for component 'sample' [7]. */ +#define mccompcurname sample +#define mccompcurindex 6 +#define reflections mccsample_reflections +#define my_s_v2 mccsample_my_s_v2 +#define my_a_v mccsample_my_a_v +#define q_v mccsample_q_v +#define d_phi0 mccsample_d_phi0 +#define radius mccsample_radius +#define focus_r mccsample_focus_r +#define h mccsample_h +#define pack mccsample_pack +#define Vc mccsample_Vc +#define sigma_a mccsample_sigma_a +#define sigma_inc mccsample_sigma_inc +#define frac mccsample_frac +#define focus_xw mccsample_focus_xw +#define focus_yh mccsample_focus_yh +#define focus_aw mccsample_focus_aw +#define focus_ah mccsample_focus_ah +#define target_x mccsample_target_x +#define target_y mccsample_target_y +#define target_z mccsample_target_z +#define target_index mccsample_target_index +/* Shared user declarations for all components 'PowderN'. */ +#line 70 "PowderN.comp" + /* used for reading data table from file */ + +/* Declare structures and functions only once in each instrument. */ +#ifndef POWDERN_DECL +#define POWDERN_DECL + + struct line_data + { + double F2; /* Value of structure factor */ + double q; /* Qvector */ + int j; /* Multiplicity */ + double DW; /* Debye-Waller factor */ + double w; /* Intrinsic line width */ + }; + + struct line_info_struct + { + struct line_data *list; /* Reflection array */ + int count; /* Number of reflections */ + }; + + void + read_line_data(char *SC_file, struct line_info_struct *info) + { + struct line_data *list = NULL; + int size = 0; + t_Table sTable; /* sample data table structure from SC_file */ + int i=0; + + Table_Read(&sTable, SC_file, 1); /* read 1st block data from SC_file into sTable*/ + if (sTable.columns < 5) + exit(fprintf(stderr, "PowderN: Error: The number of columns in %s should be at least %d for [j,q,F2,DW,w]\n", SC_file, 5)); + if (!sTable.rows) + exit(fprintf(stderr, "PowderN: Error: The number of rows in %s should be at least %d\n", SC_file, 1)); + else size = sTable.rows; + printf("PowderN: Reading in %d rows from %s... ",size, SC_file); + /* allocate line_data array */ + list = (struct line_data*)malloc(size*sizeof(struct line_data)); + for (i=0; ilist = list; + info->count = i; + } +#endif /* !POWDERN_DECL */ + +#line 5203 "dmcafter.c" +#line 141 "PowderN.comp" + struct line_info_struct line_info; + int Nq; + double *my_s_v2, my_s_v2_sum; + double my_a_v, my_inc, *q_v; + double *w_v, v, solid_angle; +#line 5210 "dmcafter.c" +#undef target_index +#undef target_z +#undef target_y +#undef target_x +#undef focus_ah +#undef focus_aw +#undef focus_yh +#undef focus_xw +#undef frac +#undef sigma_inc +#undef sigma_a +#undef Vc +#undef pack +#undef h +#undef focus_r +#undef radius +#undef d_phi0 +#undef q_v +#undef my_a_v +#undef my_s_v2 +#undef reflections +#undef mccompcurname +#undef mccompcurindex + +/* User declarations for component 'Det9' [7]. */ +#define mccompcurname Det9 +#define mccompcurindex 7 +#define options mccDet9_options +#define filename mccDet9_filename +#define DEFS mccDet9_DEFS +#define Vars mccDet9_Vars +#define xwidth mccDet9_xwidth +#define yheight mccDet9_yheight +#define zthick mccDet9_zthick +#define xmin mccDet9_xmin +#define xmax mccDet9_xmax +#define ymin mccDet9_ymin +#define ymax mccDet9_ymax +#define zmin mccDet9_zmin +#define zmax mccDet9_zmax +/* Shared user declarations for all components 'Monitor_nD'. */ +#line 208 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/monitors/Monitor_nD.comp" +/******************************************************************************* +* +* McStas, neutron ray-tracing package +* Copyright 1997-2002, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* Library: share/monitor_nd-lib.h +* +* %Identification +* Written by: EF +* Date: Aug 28, 2002 +* Origin: ILL +* Release: McStas 1.6 +* Version: 1.1 +* +* This file is to be imported by the monitor_nd related components +* It handles some shared functions. +* +* Usage: within SHARE +* %include "monitor_nd-lib" +* +* $Id: dmcafter.c,v 1.1 2007/01/30 03:19:43 koennecke Exp $ +* +* $Log: dmcafter.c,v $ +* Revision 1.1 2007/01/30 03:19:43 koennecke +* - Fixed state monitor eclipse commit problems. Siiiiiiiggggghhhhhh! +* +* Revision 1.8 2003/02/11 12:28:46 farhi +* Variouxs bug fixes after tests in the lib directory +* mcstas_r : disable output with --no-out.. flag. Fix 1D McStas output +* read_table:corrected MC_SYS_DIR -> MCSTAS define +* monitor_nd-lib: fix Log(signal) log(coord) +* HOPG.trm: reduce 4000 points -> 400 which is enough and faster to resample +* Progress_bar: precent -> percent parameter +* CS: ---------------------------------------------------------------------- +* +* Revision 1.1 2002/08/28 11:39:00 ef +* Initial revision extracted from lib/monitors/Monitor_nD.comp +*******************************************************************************/ + +#ifndef MONITOR_ND_LIB_H + +#define MONITOR_ND_LIB_H "1.1.1" +#define MONnD_COORD_NMAX 30 /* max number of variables to record */ + + typedef struct MonitornD_Defines + { + char COORD_NONE ; + char COORD_X ; + char COORD_Y ; + char COORD_Z ; + char COORD_VX ; + char COORD_VY ; + char COORD_VZ ; + char COORD_T ; + char COORD_P ; + char COORD_SX ; + char COORD_SY ; + char COORD_SZ ; + char COORD_KX ; + char COORD_KY ; + char COORD_KZ ; + char COORD_K ; + char COORD_V ; + char COORD_ENERGY; + char COORD_LAMBDA; + char COORD_RADIUS; + char COORD_HDIV ; + char COORD_VDIV ; + char COORD_ANGLE ; + char COORD_NCOUNT; + char COORD_THETA ; + char COORD_PHI ; + char COORD_USER1 ; + char COORD_USER2 ; + + /* token modifiers */ + char COORD_VAR ; /* next token should be a variable or normal option */ + char COORD_MIN ; /* next token is a min value */ + char COORD_MAX ; /* next token is a max value */ + char COORD_DIM ; /* next token is a bin value */ + char COORD_FIL ; /* next token is a filename */ + char COORD_EVNT ; /* next token is a buffer size value */ + char COORD_3HE ; /* next token is a 3He pressure value */ + char COORD_INTERM; /* next token is an intermediate save value (percent) */ + char COORD_LOG ; /* next variable will be in log scale */ + char COORD_ABS ; /* next variable will be in abs scale */ + char COORD_SIGNAL; /* next variable will be the signal var */ + int COORD_AUTO ; /* set auto limits */ + + char TOKEN_DEL[32]; /* token separators */ + + char SHAPE_SQUARE; /* shape of the monitor */ + char SHAPE_DISK ; + char SHAPE_SPHERE; + char SHAPE_CYLIND; + char SHAPE_BANANA; /* cylinder without top/bottom, on restricted angular area */ + char SHAPE_BOX ; + + } MonitornD_Defines_type; + + typedef struct MonitornD_Variables + { + double area; + double Sphere_Radius ; + double Cylinder_Height ; + char Flag_With_Borders ; /* 2 means xy borders too */ + char Flag_List ; /* 1 store 1 buffer, 2 is list all, 3 list all+append */ + char Flag_Multiple ; /* 1 when n1D, 0 for 2D */ + char Flag_Verbose ; + int Flag_Shape ; + char Flag_Auto_Limits ; /* get limits from first Buffer */ + char Flag_Absorb ; /* monitor is also a slit */ + char Flag_per_cm2 ; /* flux is per cm2 */ + char Flag_log ; /* log10 of the flux */ + char Flag_parallel ; /* set neutron state back after detection (parallel components) */ + char Flag_Binary_List ; + char Flag_capture ; /* lambda monitor with lambda/lambda(2200m/s = 1.7985 Angs) weightening */ + int Flag_signal ; /* 0:monitor p, else monitor a mean value */ + + long Coord_Number ; /* total number of variables to monitor, plus intensity (0) */ + long Buffer_Block ; /* Buffer size for list or auto limits */ + long Neutron_Counter ; /* event counter, simulation total counts is mcget_ncount() */ + long Buffer_Counter ; /* index in Buffer size (for realloc) */ + long Buffer_Size ; + int Coord_Type[MONnD_COORD_NMAX]; /* type of variable */ + char Coord_Label[MONnD_COORD_NMAX][30]; /* label of variable */ + char Coord_Var[MONnD_COORD_NMAX][30]; /* short id of variable */ + long Coord_Bin[MONnD_COORD_NMAX]; /* bins of variable array */ + double Coord_Min[MONnD_COORD_NMAX]; + double Coord_Max[MONnD_COORD_NMAX]; + char Monitor_Label[MONnD_COORD_NMAX*30]; /* Label for monitor */ + char Mon_File[128]; /* output file name */ + + double cx,cy,cz; + double cvx, cvy, cvz; + double csx, csy, csz; + double cs1, cs2, ct, cp; + double He3_pressure; + char Flag_UsePreMonitor ; /* use a previously stored neutron parameter set */ + char UserName1[128]; + char UserName2[128]; + double UserVariable1; + double UserVariable2; + double Intermediate; + double IntermediateCnts; + char option[1024]; + + double Nsum; + double psum, p2sum; + double **Mon2D_N; + double **Mon2D_p; + double **Mon2D_p2; + double *Mon2D_Buffer; + + double mxmin,mxmax,mymin,mymax,mzmin,mzmax; + + char compcurname[128]; + + } MonitornD_Variables_type; + +/* monitor_nd-lib function prototypes */ +/* ========================================================================= */ + +void Monitor_nD_Init(MonitornD_Defines_type *, MonitornD_Variables_type *, MCNUM, MCNUM, MCNUM, MCNUM, MCNUM, MCNUM, MCNUM, MCNUM, MCNUM); +double Monitor_nD_Trace(MonitornD_Defines_type *, MonitornD_Variables_type *); +void Monitor_nD_Save(MonitornD_Defines_type *, MonitornD_Variables_type *); +void Monitor_nD_Finally(MonitornD_Defines_type *, MonitornD_Variables_type *); +void Monitor_nD_McDisplay(MonitornD_Defines_type *, + MonitornD_Variables_type *); + +#endif + +/* end of monitor_nd-lib.h */ +/******************************************************************************* +* +* McStas, neutron ray-tracing package +* Copyright 1997-2002, All rights reserved +* Risoe National Laboratory, Roskilde, Denmark +* Institut Laue Langevin, Grenoble, France +* +* Library: share/monitor_nd-lib.c +* +* %Identification +* Written by: EF +* Date: Aug 28, 2002 +* Origin: ILL +* Release: McStas 1.6 +* Version: 1.1 +* +* This file is to be imported by the monitor_nd related components +* It handles some shared functions. Embedded within instrument in runtime mode. +* Variable names have prefix 'mc_mn_' for 'McStas Monitor' to avoid conflicts +* +* Usage: within SHARE +* %include "monitor_nd-lib" +* +* $Id: dmcafter.c,v 1.1 2007/01/30 03:19:43 koennecke Exp $ +* +* $Log: dmcafter.c,v $ +* Revision 1.1 2007/01/30 03:19:43 koennecke +* - Fixed state monitor eclipse commit problems. Siiiiiiiggggghhhhhh! +* +* Revision 1.15 2004/02/26 12:55:41 farhi +* Handles 0d monitor outputs for bins=0, and limits are restrictive (i.e. neutron must be within all limits to be stored in monitor) +* +* Revision 1.14 2004/02/04 18:01:12 farhi +* Use hdiv=theta and vdiv=phi for banana. +* +* Revision 1.13 2003/08/26 12:33:27 farhi +* Corrected computation of angle PHI (was projected on vertical plane) +* +* Revision 1.12 2003/04/15 16:01:28 farhi +* incoming/outgoing syntax mismatch correction +* +* Revision 1.11 2003/04/15 15:45:56 farhi +* outgoing time is default (vs. incoming) +* +* Revision 1.10 2003/04/09 15:49:25 farhi +* corrected bug when no signal and auto limits requested +* +* Revision 1.9 2003/02/18 09:11:36 farhi +* Corrected binary format for lists +* +* Revision 1.1 2002/08/28 11:39:00 ef +* Initial revision extracted from lib/monitors/Monitor_nD.comp +*******************************************************************************/ + +#ifndef MONITOR_ND_LIB_H +#error McStas : please import this library with %include "monitor_nd-lib" +#endif + +/* ========================================================================= */ +/* ADD: E.Farhi, Aug 6th, 2001: Monitor_nD section */ +/* this routine is used to parse options */ +/* ========================================================================= */ + +void Monitor_nD_Init(MonitornD_Defines_type *mc_mn_DEFS, + MonitornD_Variables_type *mc_mn_Vars, + MCNUM mc_mn_xwidth, + MCNUM mc_mn_yheight, + MCNUM mc_mn_zthick, + MCNUM mc_mn_xmin, + MCNUM mc_mn_xmax, + MCNUM mc_mn_ymin, + MCNUM mc_mn_ymax, + MCNUM mc_mn_zmin, + MCNUM mc_mn_zmax) + { + long mc_mn_carg = 1; + char *mc_mn_option_copy, *mc_mn_token; + char mc_mn_Flag_New_token = 1; + char mc_mn_Flag_End = 1; + char mc_mn_Flag_All = 0; + char mc_mn_Flag_No = 0; + char mc_mn_Flag_abs = 0; + int mc_mn_Flag_auto = 0; /* -1: all, 1: the current variable */ + int mc_mn_Set_Vars_Coord_Type; + char mc_mn_Set_Vars_Coord_Label[30]; + char mc_mn_Set_Vars_Coord_Var[30]; + char mc_mn_Short_Label[MONnD_COORD_NMAX][30]; + int mc_mn_Set_Coord_Mode; + long mc_mn_i=0, mc_mn_j=0; + double mc_mn_lmin, mc_mn_lmax, mc_mn_XY; + long mc_mn_t; + + + mc_mn_t = (long)time(NULL); + + mc_mn_DEFS->COORD_NONE =0; + mc_mn_DEFS->COORD_X =1; + mc_mn_DEFS->COORD_Y =2; + mc_mn_DEFS->COORD_Z =3; + mc_mn_DEFS->COORD_VX =4; + mc_mn_DEFS->COORD_VY =5; + mc_mn_DEFS->COORD_VZ =6; + mc_mn_DEFS->COORD_T =7; + mc_mn_DEFS->COORD_P =8; + mc_mn_DEFS->COORD_SX =9; + mc_mn_DEFS->COORD_SY =10; + mc_mn_DEFS->COORD_SZ =11; + mc_mn_DEFS->COORD_KX =12; + mc_mn_DEFS->COORD_KY =13; + mc_mn_DEFS->COORD_KZ =14; + mc_mn_DEFS->COORD_K =15; + mc_mn_DEFS->COORD_V =16; + mc_mn_DEFS->COORD_ENERGY =17; + mc_mn_DEFS->COORD_LAMBDA =18; + mc_mn_DEFS->COORD_RADIUS =19; + mc_mn_DEFS->COORD_HDIV =20; + mc_mn_DEFS->COORD_VDIV =21; + mc_mn_DEFS->COORD_ANGLE =22; + mc_mn_DEFS->COORD_NCOUNT =23; + mc_mn_DEFS->COORD_THETA =24; + mc_mn_DEFS->COORD_PHI =25; + mc_mn_DEFS->COORD_USER1 =26; + mc_mn_DEFS->COORD_USER2 =27; + +/* mc_mn_token modifiers */ + mc_mn_DEFS->COORD_VAR =0; /* next mc_mn_token should be a variable or normal option */ + mc_mn_DEFS->COORD_MIN =1; /* next mc_mn_token is a min value */ + mc_mn_DEFS->COORD_MAX =2; /* next mc_mn_token is a max value */ + mc_mn_DEFS->COORD_DIM =3; /* next mc_mn_token is a bin value */ + mc_mn_DEFS->COORD_FIL =4; /* next mc_mn_token is a filename */ + mc_mn_DEFS->COORD_EVNT =5; /* next mc_mn_token is a buffer size value */ + mc_mn_DEFS->COORD_3HE =6; /* next mc_mn_token is a 3He pressure value */ + mc_mn_DEFS->COORD_INTERM =7; /* next mc_mn_token is an intermediate save value (%) */ + mc_mn_DEFS->COORD_LOG =32; /* next variable will be in log scale */ + mc_mn_DEFS->COORD_ABS =64; /* next variable will be in abs scale */ + mc_mn_DEFS->COORD_SIGNAL =128; /* next variable will be the signal var */ + mc_mn_DEFS->COORD_AUTO =256; /* set auto limits */ + + strcpy(mc_mn_DEFS->TOKEN_DEL, " =,;[](){}:"); /* mc_mn_token separators */ + + mc_mn_DEFS->SHAPE_SQUARE =0; /* shape of the monitor */ + mc_mn_DEFS->SHAPE_DISK =1; + mc_mn_DEFS->SHAPE_SPHERE =2; + mc_mn_DEFS->SHAPE_CYLIND =3; + mc_mn_DEFS->SHAPE_BANANA =4; + mc_mn_DEFS->SHAPE_BOX =5; + + mc_mn_Vars->Sphere_Radius = 0; + mc_mn_Vars->Cylinder_Height = 0; + mc_mn_Vars->Flag_With_Borders = 0; /* 2 means xy borders too */ + mc_mn_Vars->Flag_List = 0; /* 1 store 1 buffer, 2 is list all */ + mc_mn_Vars->Flag_Multiple = 0; /* 1 when n1D, 0 for 2D */ + mc_mn_Vars->Flag_Verbose = 0; + mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_SQUARE; + mc_mn_Vars->Flag_Auto_Limits = 0; /* get limits from first Buffer */ + mc_mn_Vars->Flag_Absorb = 0; /* monitor is also a slit */ + mc_mn_Vars->Flag_per_cm2 = 0; /* flux is per cm2 */ + mc_mn_Vars->Flag_log = 0; /* log10 of the flux */ + mc_mn_Vars->Flag_parallel = 0; /* set neutron state back after detection (parallel components) */ + mc_mn_Vars->Flag_Binary_List = 0; /* save list as a binary file (smaller) */ + mc_mn_Vars->Coord_Number = 0; /* total number of variables to monitor, plus intensity (0) */ + mc_mn_Vars->Buffer_Block = 10000; /* Buffer size for list or auto limits */ + mc_mn_Vars->Neutron_Counter = 0; /* event counter, simulation total counts is mcget_ncount() */ + mc_mn_Vars->Buffer_Counter = 0; /* mc_mn_index in Buffer size (for realloc) */ + mc_mn_Vars->Buffer_Size = 0; + mc_mn_Vars->UserVariable1 = 0; + mc_mn_Vars->UserVariable2 = 0; + mc_mn_Vars->He3_pressure = 0; + mc_mn_Vars->IntermediateCnts = 0; + mc_mn_Vars->Flag_capture = 0; + mc_mn_Vars->Flag_signal = mc_mn_DEFS->COORD_P; + + mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_NONE; + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; + + /* handle size parameters */ + /* normal use is with xwidth, yheight, zthick */ + /* if xmin,xmax,ymin,ymax,zmin,zmax are non 0, use them */ + if (fabs(mc_mn_xmin-mc_mn_xmax) == 0) + { mc_mn_Vars->mxmin = -fabs(mc_mn_xwidth)/2; mc_mn_Vars->mxmax = fabs(mc_mn_xwidth)/2; } + else + { if (mc_mn_xmin < mc_mn_xmax) {mc_mn_Vars->mxmin = mc_mn_xmin; mc_mn_Vars->mxmax = mc_mn_xmax;} + else {mc_mn_Vars->mxmin = mc_mn_xmax; mc_mn_Vars->mxmax = mc_mn_xmin;} + } + if (fabs(mc_mn_ymin-mc_mn_ymax) == 0) + { mc_mn_Vars->mymin = -fabs(mc_mn_yheight)/2; mc_mn_Vars->mymax = fabs(mc_mn_yheight)/2; } + else + { if (mc_mn_ymin < mc_mn_ymax) {mc_mn_Vars->mymin = mc_mn_ymin; mc_mn_Vars->mymax = mc_mn_ymax;} + else {mc_mn_Vars->mymin = mc_mn_ymax; mc_mn_Vars->mymax = mc_mn_ymin;} + } + if (fabs(mc_mn_zmin-mc_mn_zmax) == 0) + { mc_mn_Vars->mzmin = -fabs(mc_mn_zthick)/2; mc_mn_Vars->mzmax = fabs(mc_mn_zthick)/2; } + else + { if (mc_mn_zmin < mc_mn_zmax) {mc_mn_Vars->mzmin = mc_mn_zmin; mc_mn_Vars->mzmax = mc_mn_zmax; } + else {mc_mn_Vars->mzmin = mc_mn_zmax; mc_mn_Vars->mzmax = mc_mn_zmin; } + } + + if (fabs(mc_mn_Vars->mzmax-mc_mn_Vars->mzmin) == 0) + mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_SQUARE; + else + mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_BOX; + + /* parse option string */ + + mc_mn_option_copy = (char*)malloc(strlen(mc_mn_Vars->option)+1); + if (mc_mn_option_copy == NULL) + { + fprintf(stderr,"Monitor_nD: %s cannot allocate mc_mn_option_copy (%li). Fatal.\n", mc_mn_Vars->compcurname, strlen(mc_mn_Vars->option)); + exit(-1); + } + + if (strlen(mc_mn_Vars->option)) + { + mc_mn_Flag_End = 0; + strcpy(mc_mn_option_copy, mc_mn_Vars->option); + } + + if (strstr(mc_mn_Vars->option, "cm2") || strstr(mc_mn_Vars->option, "cm^2")) mc_mn_Vars->Flag_per_cm2 = 1; + + if (strstr(mc_mn_Vars->option, "binary") || strstr(mc_mn_Vars->option, "float")) + mc_mn_Vars->Flag_Binary_List = 1; + if (strstr(mc_mn_Vars->option, "double")) + mc_mn_Vars->Flag_Binary_List = 2; + + if (mc_mn_Vars->Flag_per_cm2) strncpy(mc_mn_Vars->Coord_Label[0],"Intensity [n/cm^2/s]",30); + else strncpy(mc_mn_Vars->Coord_Label[0],"Intensity [n/s]",30); + strncpy(mc_mn_Vars->Coord_Var[0],"p",30); + mc_mn_Vars->Coord_Type[0] = mc_mn_DEFS->COORD_P; + mc_mn_Vars->Coord_Bin[0] = 1; + mc_mn_Vars->Coord_Min[0] = 0; + mc_mn_Vars->Coord_Max[0] = FLT_MAX; + + /* default file name is comp name+dateID */ + sprintf(mc_mn_Vars->Mon_File, "%s_%li", mc_mn_Vars->compcurname, mc_mn_t); + + mc_mn_carg = 1; + while((mc_mn_Flag_End == 0) && (mc_mn_carg < 128)) + { + if (mc_mn_Flag_New_token) /* to get the previous mc_mn_token sometimes */ + { + if (mc_mn_carg == 1) mc_mn_token=(char *)strtok(mc_mn_option_copy,mc_mn_DEFS->TOKEN_DEL); + else mc_mn_token=(char *)strtok(NULL,mc_mn_DEFS->TOKEN_DEL); + if (mc_mn_token == NULL) mc_mn_Flag_End=1; + } + mc_mn_Flag_New_token = 1; + if ((mc_mn_token != NULL) && (strlen(mc_mn_token) != 0)) + { + /* first handle option values from preceeding keyword mc_mn_token detected */ + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_MAX) + { + if (!mc_mn_Flag_All) + mc_mn_Vars->Coord_Max[mc_mn_Vars->Coord_Number] = atof(mc_mn_token); + else + for (mc_mn_i = 0; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_Vars->Coord_Max[mc_mn_i++] = atof(mc_mn_token)); + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; mc_mn_Flag_All = 0; + } + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_MIN) + { + if (!mc_mn_Flag_All) + mc_mn_Vars->Coord_Min[mc_mn_Vars->Coord_Number] = atof(mc_mn_token); + else + for (mc_mn_i = 0; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_Vars->Coord_Min[mc_mn_i++] = atof(mc_mn_token)); + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_MAX; + } + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_DIM) + { + if (!mc_mn_Flag_All) + mc_mn_Vars->Coord_Bin[mc_mn_Vars->Coord_Number] = atoi(mc_mn_token); + else + for (mc_mn_i = 0; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_Vars->Coord_Bin[mc_mn_i++] = atoi(mc_mn_token)); + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; mc_mn_Flag_All = 0; + } + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_FIL) + { + if (!mc_mn_Flag_No) strncpy(mc_mn_Vars->Mon_File,mc_mn_token,128); + else { strcpy(mc_mn_Vars->Mon_File,""); mc_mn_Vars->Coord_Number = 0; mc_mn_Flag_End = 1;} + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; + } + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_EVNT) + { + if (!strcmp(mc_mn_token, "all") || mc_mn_Flag_All) mc_mn_Vars->Flag_List = 2; + else { mc_mn_i = atoi(mc_mn_token); if (mc_mn_i) mc_mn_Vars->Buffer_Block = mc_mn_i; + mc_mn_Vars->Flag_List = 1; } + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; mc_mn_Flag_All = 0; + } + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_3HE) + { + mc_mn_Vars->He3_pressure = atof(mc_mn_token); + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; mc_mn_Flag_All = 0; + } + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_INTERM) + { + mc_mn_Vars->Intermediate = atof(mc_mn_token); + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; mc_mn_Flag_All = 0; + } + + /* now look for general option keywords */ + if (!strcmp(mc_mn_token, "borders")) mc_mn_Vars->Flag_With_Borders = 1; + if (!strcmp(mc_mn_token, "verbose")) mc_mn_Vars->Flag_Verbose = 1; + if (!strcmp(mc_mn_token, "log")) mc_mn_Vars->Flag_log = 1; + if (!strcmp(mc_mn_token, "abs")) mc_mn_Flag_abs = 1; + if (!strcmp(mc_mn_token, "multiple")) mc_mn_Vars->Flag_Multiple = 1; + if (!strcmp(mc_mn_token, "list")) + { mc_mn_Vars->Flag_List = 1; + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_EVNT; } + + if (!strcmp(mc_mn_token, "limits") || !strcmp(mc_mn_token, "min")) mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_MIN; + if (!strcmp(mc_mn_token, "slit") || !strcmp(mc_mn_token, "absorb")) + { mc_mn_Vars->Flag_Absorb = 1; } + if (!strcmp(mc_mn_token, "max")) mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_MAX; + if (!strcmp(mc_mn_token, "bins")) mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_DIM; + if (!strcmp(mc_mn_token, "file")) + { mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_FIL; + if (mc_mn_Flag_No) { strcpy(mc_mn_Vars->Mon_File,""); mc_mn_Vars->Coord_Number = 0; mc_mn_Flag_End = 1;}} + if (!strcmp(mc_mn_token, "unactivate")) { mc_mn_Flag_End = 1; mc_mn_Vars->Coord_Number = 0; } + if (!strcmp(mc_mn_token, "all")) mc_mn_Flag_All = 1; + if (!strcmp(mc_mn_token, "sphere")) mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_SPHERE; + if (!strcmp(mc_mn_token, "cylinder")) mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_CYLIND; + if (!strcmp(mc_mn_token, "banana")) mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_BANANA; + if (!strcmp(mc_mn_token, "square")) mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_SQUARE; + if (!strcmp(mc_mn_token, "disk")) mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_DISK; + if (!strcmp(mc_mn_token, "box")) mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_BOX; + if (!strcmp(mc_mn_token, "parallel")) mc_mn_Vars->Flag_parallel = 1; + if (!strcmp(mc_mn_token, "capture")) mc_mn_Vars->Flag_capture = 1; + if (!strcmp(mc_mn_token, "auto") && (mc_mn_Flag_auto != -1)) + { mc_mn_Vars->Flag_Auto_Limits = 1; + if (mc_mn_Flag_All) mc_mn_Flag_auto = -1; + else mc_mn_Flag_auto = 1; + } + if (!strcmp(mc_mn_token, "premonitor")) + mc_mn_Vars->Flag_UsePreMonitor = 1; + if (!strcmp(mc_mn_token, "3He_pressure")) + mc_mn_Vars->He3_pressure = 3; + if (!strcmp(mc_mn_token, "intermediate")) + { mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_INTERM; + mc_mn_Vars->Intermediate = 5; } + if (!strcmp(mc_mn_token, "no") || !strcmp(mc_mn_token, "not")) mc_mn_Flag_No = 1; + if (!strcmp(mc_mn_token, "signal")) mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_SIGNAL; + + /* now look for variable names to monitor */ + mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_NONE; mc_mn_lmin = 0; mc_mn_lmax = 0; + + if (!strcmp(mc_mn_token, "x")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_X; strcpy(mc_mn_Set_Vars_Coord_Label,"x [m]"); strcpy(mc_mn_Set_Vars_Coord_Var,"x"); mc_mn_lmin = mc_mn_Vars->mxmin; mc_mn_lmax = mc_mn_Vars->mxmax; } + if (!strcmp(mc_mn_token, "y")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_Y; strcpy(mc_mn_Set_Vars_Coord_Label,"y [m]"); strcpy(mc_mn_Set_Vars_Coord_Var,"y"); mc_mn_lmin = mc_mn_Vars->mymin; mc_mn_lmax = mc_mn_Vars->mymax; } + if (!strcmp(mc_mn_token, "z")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_Z; strcpy(mc_mn_Set_Vars_Coord_Label,"z [m]"); strcpy(mc_mn_Set_Vars_Coord_Var,"z"); mc_mn_lmin = mc_mn_Vars->mzmin; mc_mn_lmax = mc_mn_Vars->mzmax; } + if (!strcmp(mc_mn_token, "k") || !strcmp(mc_mn_token, "wavevector")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_K; strcpy(mc_mn_Set_Vars_Coord_Label,"|k| [Angs-1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"k"); mc_mn_lmin = 0; mc_mn_lmax = 10; } + if (!strcmp(mc_mn_token, "v")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_V; strcpy(mc_mn_Set_Vars_Coord_Label,"Velocity [m/s]"); strcpy(mc_mn_Set_Vars_Coord_Var,"v"); mc_mn_lmin = 0; mc_mn_lmax = 10000; } + if (!strcmp(mc_mn_token, "t") || !strcmp(mc_mn_token, "time")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_T; strcpy(mc_mn_Set_Vars_Coord_Label,"TOF [s]"); strcpy(mc_mn_Set_Vars_Coord_Var,"t"); mc_mn_lmin = 0; mc_mn_lmax = .1; } + if ((!strcmp(mc_mn_token, "p") || !strcmp(mc_mn_token, "intensity") || !strcmp(mc_mn_token, "flux"))) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_P; + if (mc_mn_Vars->Flag_per_cm2) strcpy(mc_mn_Set_Vars_Coord_Label,"Intensity [n/cm^2/s]"); + else strcpy(mc_mn_Set_Vars_Coord_Label,"Intensity [n/s]"); + strcpy(mc_mn_Set_Vars_Coord_Var,"I"); + mc_mn_lmin = 0; mc_mn_lmax = FLT_MAX; } + + if (!strcmp(mc_mn_token, "vx")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_VX; strcpy(mc_mn_Set_Vars_Coord_Label,"vx [m/s]"); strcpy(mc_mn_Set_Vars_Coord_Var,"vx"); mc_mn_lmin = -1000; mc_mn_lmax = 1000; } + if (!strcmp(mc_mn_token, "vy")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_VY; strcpy(mc_mn_Set_Vars_Coord_Label,"vy [m/s]"); strcpy(mc_mn_Set_Vars_Coord_Var,"vy"); mc_mn_lmin = -1000; mc_mn_lmax = 1000; } + if (!strcmp(mc_mn_token, "vz")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_VZ; strcpy(mc_mn_Set_Vars_Coord_Label,"vz [m/s]"); strcpy(mc_mn_Set_Vars_Coord_Var,"vz"); mc_mn_lmin = -10000; mc_mn_lmax = 10000; } + if (!strcmp(mc_mn_token, "kx")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_KX; strcpy(mc_mn_Set_Vars_Coord_Label,"kx [Angs-1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"kx"); mc_mn_lmin = -1; mc_mn_lmax = 1; } + if (!strcmp(mc_mn_token, "ky")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_KY; strcpy(mc_mn_Set_Vars_Coord_Label,"ky [Angs-1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"ky"); mc_mn_lmin = -1; mc_mn_lmax = 1; } + if (!strcmp(mc_mn_token, "kz")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_KZ; strcpy(mc_mn_Set_Vars_Coord_Label,"kz [Angs-1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"kz"); mc_mn_lmin = -10; mc_mn_lmax = 10; } + if (!strcmp(mc_mn_token, "sx")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_SX; strcpy(mc_mn_Set_Vars_Coord_Label,"sx [1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"sx"); mc_mn_lmin = -1; mc_mn_lmax = 1; } + if (!strcmp(mc_mn_token, "sy")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_SY; strcpy(mc_mn_Set_Vars_Coord_Label,"sy [1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"sy"); mc_mn_lmin = -1; mc_mn_lmax = 1; } + if (!strcmp(mc_mn_token, "sz")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_SZ; strcpy(mc_mn_Set_Vars_Coord_Label,"sz [1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"sz"); mc_mn_lmin = -1; mc_mn_lmax = 1; } + + if (!strcmp(mc_mn_token, "energy") || !strcmp(mc_mn_token, "omega")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_ENERGY; strcpy(mc_mn_Set_Vars_Coord_Label,"Energy [meV]"); strcpy(mc_mn_Set_Vars_Coord_Var,"E"); mc_mn_lmin = 0; mc_mn_lmax = 100; } + if (!strcmp(mc_mn_token, "lambda") || !strcmp(mc_mn_token, "wavelength")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_LAMBDA; strcpy(mc_mn_Set_Vars_Coord_Label,"Wavelength [Angs]"); strcpy(mc_mn_Set_Vars_Coord_Var,"L"); mc_mn_lmin = 0; mc_mn_lmax = 100; } + if (!strcmp(mc_mn_token, "radius")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_RADIUS; strcpy(mc_mn_Set_Vars_Coord_Label,"Radius [m]"); strcpy(mc_mn_Set_Vars_Coord_Var,"R"); mc_mn_lmin = 0; mc_mn_lmax = mc_mn_xmax; } + if (!strcmp(mc_mn_token, "angle")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_ANGLE; strcpy(mc_mn_Set_Vars_Coord_Label,"Angle [deg]"); strcpy(mc_mn_Set_Vars_Coord_Var,"A"); mc_mn_lmin = -5; mc_mn_lmax = 5; } + if (!strcmp(mc_mn_token, "hdiv")|| !strcmp(mc_mn_token, "divergence") || !strcmp(mc_mn_token, "xdiv") || !strcmp(mc_mn_token, "dx")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_HDIV; strcpy(mc_mn_Set_Vars_Coord_Label,"Hor. Divergence [deg]"); strcpy(mc_mn_Set_Vars_Coord_Var,"HD"); mc_mn_lmin = -5; mc_mn_lmax = 5; } + if (!strcmp(mc_mn_token, "vdiv") || !strcmp(mc_mn_token, "ydiv") || !strcmp(mc_mn_token, "dy")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_VDIV; strcpy(mc_mn_Set_Vars_Coord_Label,"Vert. Divergence [deg]"); strcpy(mc_mn_Set_Vars_Coord_Var,"VD"); mc_mn_lmin = -5; mc_mn_lmax = 5; } + if (!strcmp(mc_mn_token, "theta") || !strcmp(mc_mn_token, "longitude")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_THETA; strcpy(mc_mn_Set_Vars_Coord_Label,"Longitude [deg]"); strcpy(mc_mn_Set_Vars_Coord_Var,"th"); mc_mn_lmin = -180; mc_mn_lmax = 180; } + if (!strcmp(mc_mn_token, "phi") || !strcmp(mc_mn_token, "lattitude")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_PHI; strcpy(mc_mn_Set_Vars_Coord_Label,"Lattitude [deg]"); strcpy(mc_mn_Set_Vars_Coord_Var,"ph"); mc_mn_lmin = -180; mc_mn_lmax = 180; } + if (!strcmp(mc_mn_token, "ncounts")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_NCOUNT; strcpy(mc_mn_Set_Vars_Coord_Label,"Neutrons [1]"); strcpy(mc_mn_Set_Vars_Coord_Var,"N"); mc_mn_lmin = 0; mc_mn_lmax = 1e10; } + if (!strcmp(mc_mn_token, "user") || !strcmp(mc_mn_token, "user1")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_USER1; strncpy(mc_mn_Set_Vars_Coord_Label,mc_mn_Vars->UserName1,32); strcpy(mc_mn_Set_Vars_Coord_Var,"U1"); mc_mn_lmin = -1e10; mc_mn_lmax = 1e10; } + if (!strcmp(mc_mn_token, "user2")) + { mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_USER2; strncpy(mc_mn_Set_Vars_Coord_Label,mc_mn_Vars->UserName2,32); strcpy(mc_mn_Set_Vars_Coord_Var,"U2"); mc_mn_lmin = -1e10; mc_mn_lmax = 1e10; } + + /* now stores variable keywords detected, if any */ + if (mc_mn_Set_Vars_Coord_Type != mc_mn_DEFS->COORD_NONE) + { + int mc_mn_Coord_Number = mc_mn_Vars->Coord_Number; + if (mc_mn_Vars->Flag_log) { mc_mn_Set_Vars_Coord_Type |= mc_mn_DEFS->COORD_LOG; mc_mn_Vars->Flag_log = 0; } + if (mc_mn_Flag_abs) { mc_mn_Set_Vars_Coord_Type |= mc_mn_DEFS->COORD_ABS; mc_mn_Flag_abs = 0; } + if (mc_mn_Flag_auto != 0) { mc_mn_Set_Vars_Coord_Type |= mc_mn_DEFS->COORD_AUTO; mc_mn_Flag_auto = 0; } + if (mc_mn_Set_Coord_Mode == mc_mn_DEFS->COORD_SIGNAL) + { + mc_mn_Coord_Number = 0; + mc_mn_Vars->Flag_signal = mc_mn_Set_Vars_Coord_Type; + } + else + { + if (mc_mn_Coord_Number < MONnD_COORD_NMAX) + { mc_mn_Coord_Number++; + mc_mn_Vars->Coord_Number = mc_mn_Coord_Number; } + else if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s reached max number of variables (%i).\n", mc_mn_Vars->compcurname, MONnD_COORD_NMAX); + } + mc_mn_Vars->Coord_Type[mc_mn_Coord_Number] = mc_mn_Set_Vars_Coord_Type; + strncpy(mc_mn_Vars->Coord_Label[mc_mn_Coord_Number], mc_mn_Set_Vars_Coord_Label,30); + strncpy(mc_mn_Vars->Coord_Var[mc_mn_Coord_Number], mc_mn_Set_Vars_Coord_Var,30); + if (mc_mn_lmin > mc_mn_lmax) { mc_mn_XY = mc_mn_lmin; mc_mn_lmin=mc_mn_lmax; mc_mn_lmax = mc_mn_XY; } + mc_mn_Vars->Coord_Min[mc_mn_Coord_Number] = mc_mn_lmin; + mc_mn_Vars->Coord_Max[mc_mn_Coord_Number] = mc_mn_lmax; + if (mc_mn_Set_Coord_Mode != mc_mn_DEFS->COORD_SIGNAL) mc_mn_Vars->Coord_Bin[mc_mn_Coord_Number] = 20; + mc_mn_Set_Coord_Mode = mc_mn_DEFS->COORD_VAR; + mc_mn_Flag_All = 0; + mc_mn_Flag_No = 0; + } + mc_mn_carg++; + } /* end if mc_mn_token */ + } /* end while mc_mn_carg */ + free(mc_mn_option_copy); + if (mc_mn_carg == 128) printf("Monitor_nD: %s reached max number of mc_mn_tokens (%i). Skipping.\n", mc_mn_Vars->compcurname, 128); + + if ((mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_BOX) && (fabs(mc_mn_Vars->mzmax - mc_mn_Vars->mzmin) == 0)) mc_mn_Vars->Flag_Shape = mc_mn_DEFS->SHAPE_SQUARE; + + if (mc_mn_Vars->Flag_log == 1) mc_mn_Vars->Coord_Type[0] |= mc_mn_DEFS->COORD_LOG; + if (mc_mn_Vars->Coord_Number == 0) + { mc_mn_Vars->Flag_Auto_Limits=0; mc_mn_Vars->Flag_Multiple=0; mc_mn_Vars->Flag_List=0; } + + /* now setting Monitor Name from variable mc_mn_labels */ + strcpy(mc_mn_Vars->Monitor_Label,""); + for (mc_mn_i = 0; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + if (mc_mn_Flag_auto != 0) mc_mn_Vars->Coord_Type[mc_mn_i] |= mc_mn_DEFS->COORD_AUTO; + mc_mn_Set_Vars_Coord_Type = (mc_mn_Vars->Coord_Type[mc_mn_i] & 31); + if ((mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_THETA) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_PHI) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_X) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_Y) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_Z) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_RADIUS)) + strcpy(mc_mn_Short_Label[mc_mn_i],"Position"); + else + if ((mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VX) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VY) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VZ) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_V)) + strcpy(mc_mn_Short_Label[mc_mn_i],"Velocity"); + else + if ((mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_KX) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_KY) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_KZ) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_K)) + strcpy(mc_mn_Short_Label[mc_mn_i],"Wavevector"); + else + if ((mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_SX) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_SY) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_SZ)) + strcpy(mc_mn_Short_Label[mc_mn_i],"Spin"); + else + if ((mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_HDIV) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VDIV) + || (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_ANGLE)) + strcpy(mc_mn_Short_Label[mc_mn_i],"Divergence"); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_ENERGY) + strcpy(mc_mn_Short_Label[mc_mn_i],"Energy"); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_LAMBDA) + strcpy(mc_mn_Short_Label[mc_mn_i],"Wavelength"); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_NCOUNT) + strcpy(mc_mn_Short_Label[mc_mn_i],"Neutron counts"); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_T) + strcpy(mc_mn_Short_Label[mc_mn_i],"Time Of Flight"); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_P) + strcpy(mc_mn_Short_Label[mc_mn_i],"Intensity"); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_USER1) + strncpy(mc_mn_Short_Label[mc_mn_i],mc_mn_Vars->UserName1,32); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_USER2) + strncpy(mc_mn_Short_Label[mc_mn_i],mc_mn_Vars->UserName2,32); + else + strcpy(mc_mn_Short_Label[mc_mn_i],"Unknown"); + + if (mc_mn_Vars->Coord_Type[mc_mn_i] & mc_mn_DEFS->COORD_ABS) + { strcat(mc_mn_Vars->Coord_Label[mc_mn_i]," (abs)"); } + + if (mc_mn_Vars->Coord_Type[mc_mn_i] & mc_mn_DEFS->COORD_LOG) + { strcat(mc_mn_Vars->Coord_Label[mc_mn_i]," (log)"); } + + strcat(mc_mn_Vars->Monitor_Label, " "); + strcat(mc_mn_Vars->Monitor_Label, mc_mn_Short_Label[mc_mn_i]); + } /* end for mc_mn_Short_Label */ + + strcat(mc_mn_Vars->Monitor_Label, " Monitor"); + if (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_SQUARE) strcat(mc_mn_Vars->Monitor_Label, " (Square)"); + if (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_DISK) strcat(mc_mn_Vars->Monitor_Label, " (Disk)"); + if (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_SPHERE) strcat(mc_mn_Vars->Monitor_Label, " (Sphere)"); + if (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_CYLIND) strcat(mc_mn_Vars->Monitor_Label, " (Cylinder)"); + if (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_BANANA) strcat(mc_mn_Vars->Monitor_Label, " (Banana)"); + if (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_BOX) strcat(mc_mn_Vars->Monitor_Label, " (Box)"); + if ((mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_CYLIND) || (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_BANANA) || (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_SPHERE) || (mc_mn_Vars->Flag_Shape == mc_mn_DEFS->SHAPE_BOX)) + { + if (strstr(mc_mn_Vars->option, "incoming")) + { + mc_mn_Vars->Flag_Shape = abs(mc_mn_Vars->Flag_Shape); + strcat(mc_mn_Vars->Monitor_Label, " [in]"); + } + else /* if strstr(mc_mn_Vars->option, "outgoing")) */ + { + mc_mn_Vars->Flag_Shape = -abs(mc_mn_Vars->Flag_Shape); + strcat(mc_mn_Vars->Monitor_Label, " [out]"); + } + } + if (mc_mn_Vars->Flag_UsePreMonitor == 1) + { + strcat(mc_mn_Vars->Monitor_Label, " at "); + strncat(mc_mn_Vars->Monitor_Label, mc_mn_Vars->UserName1,32); + } + if (mc_mn_Vars->Flag_log == 1) strcat(mc_mn_Vars->Monitor_Label, " [log] "); + + /* mc_mn_Vars->Coord_Number 0 : intensity or signal + * mc_mn_Vars->Coord_Number 1:n : detector variables */ + + /* now allocate memory to store variables in TRACE */ + if ((mc_mn_Vars->Coord_Number != 2) && !mc_mn_Vars->Flag_Multiple && !mc_mn_Vars->Flag_List) + { mc_mn_Vars->Flag_Multiple = 1; mc_mn_Vars->Flag_List = 0; } /* default is n1D */ + + /* list and auto limits case : mc_mn_Vars->Flag_List or mc_mn_Vars->Flag_Auto_Limits + * -> Buffer to flush and suppress after mc_mn_Vars->Flag_Auto_Limits + */ + if ((mc_mn_Vars->Flag_Auto_Limits || mc_mn_Vars->Flag_List) && mc_mn_Vars->Coord_Number) + { /* Dim : (mc_mn_Vars->Coord_Number+1)*mc_mn_Vars->Buffer_Block matrix (for p, dp) */ + mc_mn_Vars->Mon2D_Buffer = (double *)malloc((mc_mn_Vars->Coord_Number+1)*mc_mn_Vars->Buffer_Block*sizeof(double)); + if (mc_mn_Vars->Mon2D_Buffer == NULL) + { printf("Monitor_nD: %s cannot allocate mc_mn_Vars->Mon2D_Buffer (%li). No list and auto limits.\n", mc_mn_Vars->compcurname, mc_mn_Vars->Buffer_Block*(mc_mn_Vars->Coord_Number+1)*sizeof(double)); mc_mn_Vars->Flag_List = 0; mc_mn_Vars->Flag_Auto_Limits = 0; } + else + { + for (mc_mn_i=0; mc_mn_i < (mc_mn_Vars->Coord_Number+1)*mc_mn_Vars->Buffer_Block; mc_mn_Vars->Mon2D_Buffer[mc_mn_i++] = (double)0); + } + mc_mn_Vars->Buffer_Size = mc_mn_Vars->Buffer_Block; + } + + /* 1D and n1D case : mc_mn_Vars->Flag_Multiple */ + if (mc_mn_Vars->Flag_Multiple && mc_mn_Vars->Coord_Number) + { /* Dim : mc_mn_Vars->Coord_Number*mc_mn_Vars->Coord_Bin[mc_mn_i] vectors */ + mc_mn_Vars->Mon2D_N = (double **)malloc((mc_mn_Vars->Coord_Number)*sizeof(double *)); + mc_mn_Vars->Mon2D_p = (double **)malloc((mc_mn_Vars->Coord_Number)*sizeof(double *)); + mc_mn_Vars->Mon2D_p2 = (double **)malloc((mc_mn_Vars->Coord_Number)*sizeof(double *)); + if ((mc_mn_Vars->Mon2D_N == NULL) || (mc_mn_Vars->Mon2D_p == NULL) || (mc_mn_Vars->Mon2D_p2 == NULL)) + { fprintf(stderr,"Monitor_nD: %s n1D cannot allocate mc_mn_Vars->Mon2D_N/p/2p (%li). Fatal.\n", mc_mn_Vars->compcurname, (mc_mn_Vars->Coord_Number)*sizeof(double *)); exit(-1); } + for (mc_mn_i= 1; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + mc_mn_Vars->Mon2D_N[mc_mn_i-1] = (double *)malloc(mc_mn_Vars->Coord_Bin[mc_mn_i]*sizeof(double)); + mc_mn_Vars->Mon2D_p[mc_mn_i-1] = (double *)malloc(mc_mn_Vars->Coord_Bin[mc_mn_i]*sizeof(double)); + mc_mn_Vars->Mon2D_p2[mc_mn_i-1] = (double *)malloc(mc_mn_Vars->Coord_Bin[mc_mn_i]*sizeof(double)); + if ((mc_mn_Vars->Mon2D_N == NULL) || (mc_mn_Vars->Mon2D_p == NULL) || (mc_mn_Vars->Mon2D_p2 == NULL)) + { fprintf(stderr,"Monitor_nD: %s n1D cannot allocate %s mc_mn_Vars->Mon2D_N/p/2p[%li] (%li). Fatal.\n", mc_mn_Vars->compcurname, mc_mn_Vars->Coord_Var[mc_mn_i], mc_mn_i, (mc_mn_Vars->Coord_Bin[mc_mn_i])*sizeof(double *)); exit(-1); } + else + { + for (mc_mn_j=0; mc_mn_j < mc_mn_Vars->Coord_Bin[mc_mn_i]; mc_mn_j++ ) + { mc_mn_Vars->Mon2D_N[mc_mn_i-1][mc_mn_j] = (double)0; mc_mn_Vars->Mon2D_p[mc_mn_i-1][mc_mn_j] = (double)0; mc_mn_Vars->Mon2D_p2[mc_mn_i-1][mc_mn_j] = (double)0; } + } + } + } + else /* 2D case : mc_mn_Vars->Coord_Number==2 and !mc_mn_Vars->Flag_Multiple and !mc_mn_Vars->Flag_List */ + if ((mc_mn_Vars->Coord_Number == 2) && !mc_mn_Vars->Flag_Multiple) + { /* Dim : mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2] matrix */ + mc_mn_Vars->Mon2D_N = (double **)malloc((mc_mn_Vars->Coord_Bin[1])*sizeof(double *)); + mc_mn_Vars->Mon2D_p = (double **)malloc((mc_mn_Vars->Coord_Bin[1])*sizeof(double *)); + mc_mn_Vars->Mon2D_p2 = (double **)malloc((mc_mn_Vars->Coord_Bin[1])*sizeof(double *)); + if ((mc_mn_Vars->Mon2D_N == NULL) || (mc_mn_Vars->Mon2D_p == NULL) || (mc_mn_Vars->Mon2D_p2 == NULL)) + { fprintf(stderr,"Monitor_nD: %s 2D cannot allocate %s mc_mn_Vars->Mon2D_N/p/2p (%li). Fatal.\n", mc_mn_Vars->compcurname, mc_mn_Vars->Coord_Var[1], (mc_mn_Vars->Coord_Bin[1])*sizeof(double *)); exit(-1); } + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Bin[1]; mc_mn_i++) + { + mc_mn_Vars->Mon2D_N[mc_mn_i] = (double *)malloc(mc_mn_Vars->Coord_Bin[2]*sizeof(double)); + mc_mn_Vars->Mon2D_p[mc_mn_i] = (double *)malloc(mc_mn_Vars->Coord_Bin[2]*sizeof(double)); + mc_mn_Vars->Mon2D_p2[mc_mn_i] = (double *)malloc(mc_mn_Vars->Coord_Bin[2]*sizeof(double)); + if ((mc_mn_Vars->Mon2D_N == NULL) || (mc_mn_Vars->Mon2D_p == NULL) || (mc_mn_Vars->Mon2D_p2 == NULL)) + { fprintf(stderr,"Monitor_nD: %s 2D cannot allocate %s mc_mn_Vars->Mon2D_N/p/2p[%li] (%li). Fatal.\n", mc_mn_Vars->compcurname, mc_mn_Vars->Coord_Var[1], mc_mn_i, (mc_mn_Vars->Coord_Bin[2])*sizeof(double *)); exit(-1); } + else + { + for (mc_mn_j=0; mc_mn_j < mc_mn_Vars->Coord_Bin[2]; mc_mn_j++ ) + { mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j] = (double)0; mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j] = (double)0; mc_mn_Vars->Mon2D_p2[mc_mn_i][mc_mn_j] = (double)0; } + } + } + } + /* no Mon2D allocated for + * (mc_mn_Vars->Coord_Number != 2) && !mc_mn_Vars->Flag_Multiple && mc_mn_Vars->Flag_List */ + + mc_mn_Vars->psum = 0; + mc_mn_Vars->p2sum = 0; + mc_mn_Vars->Nsum = 0; + + mc_mn_Vars->area = fabs(mc_mn_Vars->mxmax - mc_mn_Vars->mxmin)*fabs(mc_mn_Vars->mymax - mc_mn_Vars->mymin)*1E4; /* in cm**2 for square and box shapes */ + mc_mn_Vars->Sphere_Radius = fabs(mc_mn_Vars->mxmax - mc_mn_Vars->mxmin)/2; + if ((abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_DISK) || (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_SPHERE)) + { + mc_mn_Vars->area = PI*mc_mn_Vars->Sphere_Radius*mc_mn_Vars->Sphere_Radius; /* disk shapes */ + } + if (mc_mn_Vars->area == 0) mc_mn_Vars->Coord_Number = 0; + if (mc_mn_Vars->Coord_Number == 0 && mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s is unactivated (0D)\n", mc_mn_Vars->compcurname); + mc_mn_Vars->Cylinder_Height = fabs(mc_mn_Vars->mymax - mc_mn_Vars->mymin); + + if (mc_mn_Vars->Intermediate < 0) mc_mn_Vars->Intermediate = 0; + if (mc_mn_Vars->Intermediate > 1) mc_mn_Vars->Intermediate /= 100; + mc_mn_Vars->IntermediateCnts = mc_mn_Vars->Intermediate*mcget_ncount(); + + if (mc_mn_Vars->Flag_Verbose) + { + printf("Monitor_nD: %s is a %s.\n", mc_mn_Vars->compcurname, mc_mn_Vars->Monitor_Label); + printf("Monitor_nD: version %s with options=%s\n", MONITOR_ND_LIB_H, mc_mn_Vars->option); + } + } /* end Monitor_nD_Init */ + +/* ========================================================================= */ +/* ADD: E.Farhi, Aug 6th, 2001: Monitor_nD section */ +/* this routine is used to monitor one propagating neutron */ +/* ========================================================================= */ + +double Monitor_nD_Trace(MonitornD_Defines_type *mc_mn_DEFS, MonitornD_Variables_type *mc_mn_Vars) +{ + + double mc_mn_XY=0; + long mc_mn_i,mc_mn_j; + double mc_mn_pp; + double mc_mn_Coord[MONnD_COORD_NMAX]; + long mc_mn_Coord_Index[MONnD_COORD_NMAX]; + char mc_mn_While_End =0; + long mc_mn_While_Buffer=0; + char mc_mn_Set_Vars_Coord_Type = mc_mn_DEFS->COORD_NONE; + + /* mc_mn_Vars->Flag_Auto_Limits */ + if ((mc_mn_Vars->Buffer_Counter >= mc_mn_Vars->Buffer_Block) && (mc_mn_Vars->Flag_Auto_Limits == 1) && (mc_mn_Vars->Coord_Number > 0)) + { + /* auto limits case : get limits in Buffer for each variable */ + /* Dim : (mc_mn_Vars->Coord_Number+1)*mc_mn_Vars->Buffer_Block matrix (for p, dp) */ + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s getting %li Auto Limits from List (%li).\n", mc_mn_Vars->compcurname, mc_mn_Vars->Coord_Number, mc_mn_Vars->Buffer_Counter); + for (mc_mn_i = 1; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + if (mc_mn_Vars->Coord_Type[mc_mn_i] & mc_mn_DEFS->COORD_AUTO) + { + mc_mn_Vars->Coord_Min[mc_mn_i] = FLT_MAX; + mc_mn_Vars->Coord_Max[mc_mn_i] = -FLT_MAX; + for (mc_mn_j = 0; mc_mn_j < mc_mn_Vars->Buffer_Block; mc_mn_j++) + { + mc_mn_XY = mc_mn_Vars->Mon2D_Buffer[mc_mn_i+mc_mn_j*(mc_mn_Vars->Coord_Number+1)]; /* scanning variables in Buffer */ + if (mc_mn_XY < mc_mn_Vars->Coord_Min[mc_mn_i]) mc_mn_Vars->Coord_Min[mc_mn_i] = mc_mn_XY; + if (mc_mn_XY > mc_mn_Vars->Coord_Max[mc_mn_i]) mc_mn_Vars->Coord_Max[mc_mn_i] = mc_mn_XY; + } + } + } + mc_mn_Vars->Flag_Auto_Limits = 2; /* pass to 2nd auto limits step */ + } + + /* manage realloc for list all if Buffer size exceeded */ + if ((mc_mn_Vars->Buffer_Counter >= mc_mn_Vars->Buffer_Block) && (mc_mn_Vars->Flag_List >= 2)) + { + if (mc_mn_Vars->Buffer_Size >= 20000 || mc_mn_Vars->Flag_List == 3) + { /* save current (possibly append) and re-use Buffer */ + Monitor_nD_Save(mc_mn_DEFS, mc_mn_Vars); + mc_mn_Vars->Flag_List = 3; + mc_mn_Vars->Buffer_Block = mc_mn_Vars->Buffer_Size; + mc_mn_Vars->Buffer_Counter = 0; + mc_mn_Vars->Neutron_Counter = 0; + } + else + { + mc_mn_Vars->Mon2D_Buffer = (double *)realloc(mc_mn_Vars->Mon2D_Buffer, (mc_mn_Vars->Coord_Number+1)*(mc_mn_Vars->Neutron_Counter+mc_mn_Vars->Buffer_Block)*sizeof(double)); + if (mc_mn_Vars->Mon2D_Buffer == NULL) + { printf("Monitor_nD: %s cannot reallocate mc_mn_Vars->Mon2D_Buffer[%li] (%li). Skipping.\n", mc_mn_Vars->compcurname, mc_mn_i, (mc_mn_Vars->Neutron_Counter+mc_mn_Vars->Buffer_Block)*sizeof(double)); mc_mn_Vars->Flag_List = 1; } + else { mc_mn_Vars->Buffer_Counter = 0; mc_mn_Vars->Buffer_Size = mc_mn_Vars->Neutron_Counter+mc_mn_Vars->Buffer_Block; } + } + } + + while (!mc_mn_While_End) + { /* we generate mc_mn_Coord[] and Coord_mc_mn_index[] from Buffer (auto limits) or passing neutron */ + if ((mc_mn_Vars->Flag_Auto_Limits == 2) && (mc_mn_Vars->Coord_Number > 0)) + { + if (mc_mn_While_Buffer < mc_mn_Vars->Buffer_Block) + { + /* first while loops (mc_mn_While_Buffer) */ + /* auto limits case : scan Buffer within limits and store in Mon2D */ + mc_mn_pp = mc_mn_Vars->Mon2D_Buffer[mc_mn_While_Buffer*(mc_mn_Vars->Coord_Number+1)]; + mc_mn_Coord[0] = mc_mn_pp; + + for (mc_mn_i = 1; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + /* scanning variables in Buffer */ + mc_mn_XY = (mc_mn_Vars->Coord_Max[mc_mn_i]-mc_mn_Vars->Coord_Min[mc_mn_i]); + + mc_mn_Coord[mc_mn_i] = mc_mn_Vars->Mon2D_Buffer[mc_mn_i+mc_mn_While_Buffer*(mc_mn_Vars->Coord_Number+1)]; + if (mc_mn_XY > 0) mc_mn_Coord_Index[mc_mn_i] = floor((mc_mn_Coord[mc_mn_i]-mc_mn_Vars->Coord_Min[mc_mn_i])*mc_mn_Vars->Coord_Bin[mc_mn_i]/mc_mn_XY); + else mc_mn_Coord_Index[mc_mn_i] = 0; + if (mc_mn_Vars->Flag_With_Borders) + { + if (mc_mn_Coord_Index[mc_mn_i] < 0) mc_mn_Coord_Index[mc_mn_i] = 0; + if (mc_mn_Coord_Index[mc_mn_i] >= mc_mn_Vars->Coord_Bin[mc_mn_i]) mc_mn_Coord_Index[mc_mn_i] = mc_mn_Vars->Coord_Bin[mc_mn_i] - 1; + } + } /* end for */ + mc_mn_While_Buffer++; + } /* end if in Buffer */ + else /* (mc_mn_While_Buffer >= mc_mn_Vars->Buffer_Block) && (mc_mn_Vars->Flag_Auto_Limits == 2) */ + { + mc_mn_Vars->Flag_Auto_Limits = 0; + if (!mc_mn_Vars->Flag_List) /* free Buffer not needed (no list to output) */ + { /* Dim : (mc_mn_Vars->Coord_Number+1)*mc_mn_Vars->Buffer_Block matrix (for p, dp) */ + free(mc_mn_Vars->Mon2D_Buffer); mc_mn_Vars->Mon2D_Buffer = NULL; + } + } + } + else /* mc_mn_Vars->Flag_Auto_Limits == 0 or 1 */ + { + for (mc_mn_i = 0; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { /* handle current neutron : last while */ + + mc_mn_XY = 0; + mc_mn_Set_Vars_Coord_Type = (mc_mn_Vars->Coord_Type[mc_mn_i] & 31); + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_X) mc_mn_XY = mc_mn_Vars->cx; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_Y) mc_mn_XY = mc_mn_Vars->cy; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_Z) mc_mn_XY = mc_mn_Vars->cz; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VX) mc_mn_XY = mc_mn_Vars->cvx; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VY) mc_mn_XY = mc_mn_Vars->cvy; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VZ) mc_mn_XY = mc_mn_Vars->cvz; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_KX) mc_mn_XY = V2K*mc_mn_Vars->cvx; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_KY) mc_mn_XY = V2K*mc_mn_Vars->cvy; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_KZ) mc_mn_XY = V2K*mc_mn_Vars->cvz; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_SX) mc_mn_XY = mc_mn_Vars->csx; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_SY) mc_mn_XY = mc_mn_Vars->csy; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_SZ) mc_mn_XY = mc_mn_Vars->csz; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_T) mc_mn_XY = mc_mn_Vars->ct; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_P) mc_mn_XY = mc_mn_Vars->cp; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_HDIV) mc_mn_XY = RAD2DEG*atan2(mc_mn_Vars->cvx,mc_mn_Vars->cvz); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VDIV) mc_mn_XY = RAD2DEG*atan2(mc_mn_Vars->cvy,mc_mn_Vars->cvz); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_V) mc_mn_XY = sqrt(mc_mn_Vars->cvx*mc_mn_Vars->cvx+mc_mn_Vars->cvy*mc_mn_Vars->cvy+mc_mn_Vars->cvz*mc_mn_Vars->cvz); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_RADIUS) mc_mn_XY = sqrt(mc_mn_Vars->cx*mc_mn_Vars->cx+mc_mn_Vars->cy*mc_mn_Vars->cy); + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_K) { mc_mn_XY = sqrt(mc_mn_Vars->cvx*mc_mn_Vars->cvx+mc_mn_Vars->cvy*mc_mn_Vars->cvy+mc_mn_Vars->cvz*mc_mn_Vars->cvz); mc_mn_XY *= V2K; } + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_ENERGY) { mc_mn_XY = mc_mn_Vars->cvx*mc_mn_Vars->cvx+mc_mn_Vars->cvy*mc_mn_Vars->cvy+mc_mn_Vars->cvz*mc_mn_Vars->cvz; mc_mn_XY *= VS2E; } + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_LAMBDA) { mc_mn_XY = sqrt(mc_mn_Vars->cvx*mc_mn_Vars->cvx+mc_mn_Vars->cvy*mc_mn_Vars->cvy+mc_mn_Vars->cvz*mc_mn_Vars->cvz); mc_mn_XY *= V2K; if (mc_mn_XY != 0) mc_mn_XY = 2*PI/mc_mn_XY; } + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_NCOUNT) mc_mn_XY = mc_mn_Coord[mc_mn_i]+1; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_ANGLE) + { mc_mn_XY = sqrt(mc_mn_Vars->cvx*mc_mn_Vars->cvx+mc_mn_Vars->cvy*mc_mn_Vars->cvy+mc_mn_Vars->cvz*mc_mn_Vars->cvz); + if (mc_mn_Vars->cvz != 0) + { + mc_mn_XY= RAD2DEG*atan2(mc_mn_XY,mc_mn_Vars->cvz); + } else mc_mn_XY = 0; + } + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_THETA) { if (mc_mn_Vars->cz != 0) mc_mn_XY = RAD2DEG*atan2(mc_mn_Vars->cx,mc_mn_Vars->cz); } + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_PHI) { if (mc_mn_Vars->cz != 0) mc_mn_XY = RAD2DEG*atan2(sqrt(mc_mn_Vars->cx*mc_mn_Vars->cx+mc_mn_Vars->cy*mc_mn_Vars->cy),mc_mn_Vars->cz); } + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_USER1) mc_mn_XY = mc_mn_Vars->UserVariable1; + else + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_USER2) mc_mn_XY = mc_mn_Vars->UserVariable2; + else + mc_mn_XY = 0; + + if (mc_mn_Vars->Coord_Type[mc_mn_i] & mc_mn_DEFS->COORD_ABS) mc_mn_XY=fabs(mc_mn_XY); + + if (mc_mn_i && (mc_mn_Vars->Coord_Type[mc_mn_i] & mc_mn_DEFS->COORD_LOG)) /* not for the flux */ + { if (mc_mn_XY > 0) mc_mn_XY = log(mc_mn_XY)/log(10); + else mc_mn_XY = -100; } + + mc_mn_Coord[mc_mn_i] = mc_mn_XY; + if (mc_mn_i == 0) { mc_mn_pp = mc_mn_XY; mc_mn_Coord_Index[mc_mn_i] = 0; } + else if (!mc_mn_Vars->Flag_Auto_Limits) + { + mc_mn_XY = (mc_mn_Vars->Coord_Max[mc_mn_i]-mc_mn_Vars->Coord_Min[mc_mn_i]); + if (mc_mn_XY > 0) mc_mn_Coord_Index[mc_mn_i] = floor((mc_mn_Coord[mc_mn_i]-mc_mn_Vars->Coord_Min[mc_mn_i])*mc_mn_Vars->Coord_Bin[mc_mn_i]/mc_mn_XY); + else mc_mn_Coord_Index[mc_mn_i] = 0; + if (mc_mn_Vars->Flag_With_Borders) + { + if (mc_mn_Coord_Index[mc_mn_i] < 0) mc_mn_Coord_Index[mc_mn_i] = 0; + if (mc_mn_Coord_Index[mc_mn_i] >= mc_mn_Vars->Coord_Bin[mc_mn_i]) mc_mn_Coord_Index[mc_mn_i] = mc_mn_Vars->Coord_Bin[mc_mn_i] - 1; + } + } /* else Auto_Limits will get Index later from Buffer */ + } /* end for mc_mn_i */ + mc_mn_While_End = 1; + } /* end else if mc_mn_Vars->Flag_Auto_Limits == 2 */ + + if (mc_mn_Vars->Flag_Auto_Limits != 2) /* not when reading auto limits Buffer */ + { /* now store Coord into Buffer (no mc_mn_index needed) if necessary */ + if ((mc_mn_Vars->Buffer_Counter < mc_mn_Vars->Buffer_Block) && ((mc_mn_Vars->Flag_List) || (mc_mn_Vars->Flag_Auto_Limits == 1))) + { + for (mc_mn_i = 0; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + mc_mn_Vars->Mon2D_Buffer[mc_mn_i + mc_mn_Vars->Neutron_Counter*(mc_mn_Vars->Coord_Number+1)] = mc_mn_Coord[mc_mn_i]; + } + mc_mn_Vars->Buffer_Counter++; + if (mc_mn_Vars->Flag_Verbose && (mc_mn_Vars->Buffer_Counter >= mc_mn_Vars->Buffer_Block) && (mc_mn_Vars->Flag_List == 1)) printf("Monitor_nD: %s %li neutrons stored in List.\n", mc_mn_Vars->compcurname, mc_mn_Vars->Buffer_Counter); + } + mc_mn_Vars->Neutron_Counter++; + } /* end (mc_mn_Vars->Flag_Auto_Limits != 2) */ + + /* store n1d/2d section for Buffer or current neutron in while */ + if (mc_mn_Vars->Flag_Auto_Limits != 1) /* not when storing auto limits Buffer */ + { + /* 1D and n1D case : mc_mn_Vars->Flag_Multiple */ + if (mc_mn_Vars->Flag_Multiple) + { /* Dim : mc_mn_Vars->Coord_Number*mc_mn_Vars->Coord_Bin[mc_mn_i] vectors (intensity is not included) */ + /* check limits: monitors define a phase space to record */ + char within_limits=1; + for (mc_mn_i= 1; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + mc_mn_j = mc_mn_Coord_Index[mc_mn_i]; + if (mc_mn_j < 0 || mc_mn_j >= mc_mn_Vars->Coord_Bin[mc_mn_i]) + within_limits=0; + } + if (within_limits) + for (mc_mn_i= 1; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + mc_mn_j = mc_mn_Coord_Index[mc_mn_i]; + if (mc_mn_j >= 0 && mc_mn_j < mc_mn_Vars->Coord_Bin[mc_mn_i]) + { + mc_mn_Vars->Mon2D_N[mc_mn_i-1][mc_mn_j]++; + mc_mn_Vars->Mon2D_p[mc_mn_i-1][mc_mn_j] += mc_mn_pp; + mc_mn_Vars->Mon2D_p2[mc_mn_i-1][mc_mn_j] += mc_mn_pp*mc_mn_pp; + } + } + } + else /* 2D case : mc_mn_Vars->Coord_Number==2 and !mc_mn_Vars->Flag_Multiple and !mc_mn_Vars->Flag_List */ + if ((mc_mn_Vars->Coord_Number == 2) && !mc_mn_Vars->Flag_Multiple) + { /* Dim : mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2] matrix */ + mc_mn_i = mc_mn_Coord_Index[1]; + mc_mn_j = mc_mn_Coord_Index[2]; + if (mc_mn_i >= 0 && mc_mn_i < mc_mn_Vars->Coord_Bin[1] && mc_mn_j >= 0 && mc_mn_j < mc_mn_Vars->Coord_Bin[2]) + { + mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j]++; + mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j] += mc_mn_pp; + mc_mn_Vars->Mon2D_p2[mc_mn_i][mc_mn_j] += mc_mn_pp*mc_mn_pp; + } + } + } /* end (mc_mn_Vars->Flag_Auto_Limits != 1) */ + } /* end while */ + return mc_mn_pp; +} /* end Monitor_nD_Trace */ + +/* ========================================================================= */ +/* ADD: E.Farhi, Aug 6th, 2001: Monitor_nD section */ +/* this routine is used to save data files */ +/* ========================================================================= */ + +void Monitor_nD_Save(MonitornD_Defines_type *mc_mn_DEFS, MonitornD_Variables_type *mc_mn_Vars) + { + char *mc_mn_fname; + long mc_mn_i,mc_mn_j; + double *mc_mn_p0m = NULL; + double *mc_mn_p1m = NULL; + double *mc_mn_p2m = NULL; + char mc_mn_Coord_X_Label[1024]; + double mc_mn_min1d, mc_mn_max1d; + double mc_mn_min2d, mc_mn_max2d; + long mc_mn_bin1d, mc_mn_bin2d; + char mc_mn_While_End = 0; + long mc_mn_While_Buffer = 0; + double mc_mn_XY, mc_mn_pp; + double mc_mn_Coord[MONnD_COORD_NMAX]; + long mc_mn_Coord_Index[MONnD_COORD_NMAX]; + char mc_mn_label[1024]; + double mc_mn_ratio; + + mc_mn_ratio = 100*mcget_run_num()/mcget_ncount(); + + if (mc_mn_ratio < 99) + { + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s save intermediate results (%.2f %%).\n", mc_mn_Vars->compcurname, mc_mn_ratio); + } + /* check Buffer flush when end of simulation reached */ + if ((mc_mn_Vars->Buffer_Counter <= mc_mn_Vars->Buffer_Block) && mc_mn_Vars->Flag_Auto_Limits && mc_mn_Vars->Mon2D_Buffer && mc_mn_Vars->Buffer_Counter) + { + /* Get Auto Limits */ + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s getting %li Auto Limits from List (%li).\n", mc_mn_Vars->compcurname, mc_mn_Vars->Coord_Number, mc_mn_Vars->Buffer_Counter); + for (mc_mn_i = 1; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + if (mc_mn_Vars->Coord_Type[mc_mn_i] & mc_mn_DEFS->COORD_AUTO) + { + mc_mn_Vars->Coord_Min[mc_mn_i] = FLT_MAX; + mc_mn_Vars->Coord_Max[mc_mn_i] = -FLT_MAX; + + for (mc_mn_j = 0; mc_mn_j < mc_mn_Vars->Buffer_Counter; mc_mn_j++) + { + mc_mn_XY = mc_mn_Vars->Mon2D_Buffer[mc_mn_i+mc_mn_j*(mc_mn_Vars->Coord_Number+1)]; /* scanning variables in Buffer */ + if (mc_mn_XY < mc_mn_Vars->Coord_Min[mc_mn_i]) mc_mn_Vars->Coord_Min[mc_mn_i] = mc_mn_XY; + if (mc_mn_XY > mc_mn_Vars->Coord_Max[mc_mn_i]) mc_mn_Vars->Coord_Max[mc_mn_i] = mc_mn_XY; + + } + } + } + mc_mn_Vars->Flag_Auto_Limits = 2; /* pass to 2nd auto limits step */ + mc_mn_Vars->Buffer_Block = mc_mn_Vars->Buffer_Counter; + + while (!mc_mn_While_End) + { /* we generate mc_mn_Coord[] and Coord_mc_mn_index[] from Buffer (auto limits) or passing neutron */ + if (mc_mn_While_Buffer < mc_mn_Vars->Buffer_Block) + { + /* first while loops (mc_mn_While_Buffer) */ + mc_mn_Coord[0] = mc_mn_Vars->Mon2D_Buffer[mc_mn_While_Buffer*(mc_mn_Vars->Coord_Number+1)]; + + /* auto limits case : scan Buffer within limits and store in Mon2D */ + for (mc_mn_i = 1; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + /* scanning variables in Buffer */ + mc_mn_XY = (mc_mn_Vars->Coord_Max[mc_mn_i]-mc_mn_Vars->Coord_Min[mc_mn_i]); + mc_mn_Coord[mc_mn_i] = mc_mn_Vars->Mon2D_Buffer[mc_mn_i+mc_mn_While_Buffer*(mc_mn_Vars->Coord_Number+1)]; + if (mc_mn_XY > 0) mc_mn_Coord_Index[mc_mn_i] = floor((mc_mn_Coord[mc_mn_i]-mc_mn_Vars->Coord_Min[mc_mn_i])*mc_mn_Vars->Coord_Bin[mc_mn_i]/mc_mn_XY); + else mc_mn_Coord_Index[mc_mn_i] = 0; + if (mc_mn_Vars->Flag_With_Borders) + { + if (mc_mn_Coord_Index[mc_mn_i] < 0) mc_mn_Coord_Index[mc_mn_i] = 0; + if (mc_mn_Coord_Index[mc_mn_i] >= mc_mn_Vars->Coord_Bin[mc_mn_i]) mc_mn_Coord_Index[mc_mn_i] = mc_mn_Vars->Coord_Bin[mc_mn_i] - 1; + } + } /* end for */ + mc_mn_While_Buffer++; + } /* end if in Buffer */ + else /* (mc_mn_While_Buffer >= mc_mn_Vars->Buffer_Block) && (mc_mn_Vars->Flag_Auto_Limits == 2) */ + { + mc_mn_Vars->Flag_Auto_Limits = 0; + mc_mn_While_End = 1; + } + + /* store n1d/2d section from Buffer */ + + mc_mn_pp = mc_mn_Coord[0]; + /* 1D and n1D case : mc_mn_Vars->Flag_Multiple */ + if (mc_mn_Vars->Flag_Multiple) + { /* Dim : mc_mn_Vars->Coord_Number*mc_mn_Vars->Coord_Bin[mc_mn_i] vectors (intensity is not included) */ + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Number; mc_mn_i++) + { + mc_mn_j = mc_mn_Coord_Index[mc_mn_i+1]; + if (mc_mn_j >= 0 && mc_mn_j < mc_mn_Vars->Coord_Bin[mc_mn_i+1]) + { + mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j]++; + mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j] += mc_mn_pp; + mc_mn_Vars->Mon2D_p2[mc_mn_i][mc_mn_j] += mc_mn_pp*mc_mn_pp; + } + } + } + else /* 2D case : mc_mn_Vars->Coord_Number==2 and !mc_mn_Vars->Flag_Multiple and !mc_mn_Vars->Flag_List */ + if ((mc_mn_Vars->Coord_Number == 2) && !mc_mn_Vars->Flag_Multiple) + { /* Dim : mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2] matrix */ + mc_mn_i = mc_mn_Coord_Index[1]; + mc_mn_j = mc_mn_Coord_Index[2]; + if (mc_mn_i >= 0 && mc_mn_i < mc_mn_Vars->Coord_Bin[1] && mc_mn_j >= 0 && mc_mn_j < mc_mn_Vars->Coord_Bin[2]) + { + mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j]++; + mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j] += mc_mn_pp; + mc_mn_Vars->Mon2D_p2[mc_mn_i][mc_mn_j] += mc_mn_pp*mc_mn_pp; + } + } /* end store 2D/1D */ + } /* end while */ + } /* end Force Get Limits */ + + /* write output files (sent to file as p[i*n + j] vectors) */ + if (mc_mn_Vars->Coord_Number == 0) + { + double mc_mn_Nsum; + double mc_mn_psum, mc_mn_p2sum; + mc_mn_Nsum = mc_mn_Vars->Nsum; + mc_mn_psum = mc_mn_Vars->psum; + mc_mn_p2sum= mc_mn_Vars->p2sum; + if (mc_mn_Vars->Flag_signal != mc_mn_DEFS->COORD_P && mc_mn_Nsum > 0) + { mc_mn_psum /=mc_mn_Nsum; mc_mn_p2sum /= mc_mn_Nsum*mc_mn_Nsum; } + /* DETECTOR_OUT_0D(mc_mn_Vars->Monitor_Label, mc_mn_Vars->Nsum, mc_mn_Vars->psum, mc_mn_Vars->p2sum); */ + mcdetector_out_0D(mc_mn_Vars->Monitor_Label, mc_mn_Nsum, mc_mn_psum, mc_mn_p2sum, mc_mn_Vars->compcurname); + } + else + if (strlen(mc_mn_Vars->Mon_File) > 0) + { + mc_mn_fname = (char*)malloc(strlen(mc_mn_Vars->Mon_File)+10*mc_mn_Vars->Coord_Number); + if (mc_mn_Vars->Flag_List && mc_mn_Vars->Mon2D_Buffer) /* List: DETECTOR_OUT_2D */ + { + int loc_ascii_only; + char formatName[64]; + char *formatName_orig; + + if (mc_mn_Vars->Flag_List >= 2) mc_mn_Vars->Buffer_Size = mc_mn_Vars->Neutron_Counter; + if (mc_mn_Vars->Buffer_Size >= mc_mn_Vars->Neutron_Counter) + mc_mn_Vars->Buffer_Size = mc_mn_Vars->Neutron_Counter; + strcpy(mc_mn_fname,mc_mn_Vars->Mon_File); + if (strchr(mc_mn_Vars->Mon_File,'.') == NULL) strcat(mc_mn_fname, "_list"); + + mc_mn_min1d = 1; mc_mn_max1d = mc_mn_Vars->Coord_Number+1; + mc_mn_min2d = 0; mc_mn_max2d = mc_mn_Vars->Buffer_Size; + mc_mn_bin1d = mc_mn_Vars->Coord_Number+1; mc_mn_bin2d = mc_mn_Vars->Buffer_Size; + strcpy(mc_mn_Coord_X_Label,""); + for (mc_mn_i= 0; mc_mn_i <= mc_mn_Vars->Coord_Number; mc_mn_i++) + { + if (mc_mn_min2d < mc_mn_Vars->Coord_Min[mc_mn_i]) mc_mn_min2d = mc_mn_Vars->Coord_Min[mc_mn_i]; + if (mc_mn_max2d < mc_mn_Vars->Coord_Max[mc_mn_i]) mc_mn_max2d = mc_mn_Vars->Coord_Max[mc_mn_i]; + strcat(mc_mn_Coord_X_Label, mc_mn_Vars->Coord_Var[mc_mn_i]); + strcat(mc_mn_Coord_X_Label, " "); + if (strchr(mc_mn_Vars->Mon_File,'.') == NULL) + { strcat(mc_mn_fname, "."); strcat(mc_mn_fname, mc_mn_Vars->Coord_Var[mc_mn_i]); } + } + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s write monitor file %s List (%lix%li).\n", mc_mn_Vars->compcurname, mc_mn_fname,mc_mn_bin2d,mc_mn_bin1d); + + /* handle the type of list output */ + loc_ascii_only = mcascii_only; + formatName_orig = mcformat.Name; /* copy the pointer position */ + strcpy(formatName, mcformat.Name); + if (mc_mn_Vars->Flag_List >= 1) + { + strcat(formatName, " partial "); + if (mc_mn_Vars->Flag_List > 2) + { strcat(formatName, " append "); mcascii_only = 1; } + if (mc_mn_Vars->Flag_Binary_List) mcascii_only = 1; + if (mc_mn_Vars->Flag_Binary_List == 1) + strcat(formatName, " binary float "); + else if (mc_mn_Vars->Flag_Binary_List == 2) + strcat(formatName, " binary double "); + } + if (mc_mn_min2d == mc_mn_max2d) mc_mn_max2d = mc_mn_min2d+1e-6; + if (mc_mn_min1d == mc_mn_max1d) mc_mn_max1d = mc_mn_min1d+1e-6; + strcpy(mc_mn_label, mc_mn_Vars->Monitor_Label); + if (!mc_mn_Vars->Flag_Binary_List) + { mc_mn_bin2d=-mc_mn_bin2d; } + mcformat.Name = formatName; + mcdetector_out_2D( + mc_mn_label, + "List of neutron events", + mc_mn_Coord_X_Label, + mc_mn_min2d, mc_mn_max2d, + mc_mn_min1d, mc_mn_max1d, + mc_mn_bin2d, + mc_mn_bin1d, + NULL,mc_mn_Vars->Mon2D_Buffer,NULL, + mc_mn_fname, mc_mn_Vars->compcurname); + + /* reset the original type of output */ + mcascii_only = loc_ascii_only; + mcformat.Name= formatName_orig; + } + if (mc_mn_Vars->Flag_Multiple) /* n1D: DETECTOR_OUT_1D */ + { + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Number; mc_mn_i++) + { + + strcpy(mc_mn_fname,mc_mn_Vars->Mon_File); + if (strchr(mc_mn_Vars->Mon_File,'.') == NULL) + { strcat(mc_mn_fname, "."); strcat(mc_mn_fname, mc_mn_Vars->Coord_Var[mc_mn_i+1]); } + sprintf(mc_mn_Coord_X_Label, "%s monitor", mc_mn_Vars->Coord_Label[mc_mn_i+1]); + strcpy(mc_mn_label, mc_mn_Coord_X_Label); + if (mc_mn_Vars->Coord_Bin[mc_mn_i+1] > 0) { /* 1D monitor */ + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s write monitor file %s 1D (%li).\n", mc_mn_Vars->compcurname, mc_mn_fname, mc_mn_Vars->Coord_Bin[mc_mn_i+1]); + mc_mn_min1d = mc_mn_Vars->Coord_Min[mc_mn_i+1]; + mc_mn_max1d = mc_mn_Vars->Coord_Max[mc_mn_i+1]; + if (mc_mn_min1d == mc_mn_max1d) mc_mn_max1d = mc_mn_min1d+1e-6; + mc_mn_p1m = (double *)malloc(mc_mn_Vars->Coord_Bin[mc_mn_i+1]*sizeof(double)); + mc_mn_p2m = (double *)malloc(mc_mn_Vars->Coord_Bin[mc_mn_i+1]*sizeof(double)); + if (mc_mn_p2m == NULL) /* use Raw Buffer line output */ + { + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s cannot allocate memory for output. Using raw data.\n", mc_mn_Vars->compcurname); + if (mc_mn_p1m != NULL) free(mc_mn_p1m); + mcdetector_out_1D( + mc_mn_label, + mc_mn_Vars->Coord_Label[mc_mn_i+1], + mc_mn_Vars->Coord_Label[0], + mc_mn_Vars->Coord_Var[mc_mn_i+1], + mc_mn_min1d, mc_mn_max1d, + mc_mn_Vars->Coord_Bin[mc_mn_i+1], + mc_mn_Vars->Mon2D_N[mc_mn_i],mc_mn_Vars->Mon2D_p[mc_mn_i],mc_mn_Vars->Mon2D_p2[mc_mn_i], + mc_mn_fname, mc_mn_Vars->compcurname); + } /* if (mc_mn_p2m == NULL) */ + else + { + if (mc_mn_Vars->Flag_log != 0) + { + mc_mn_XY = FLT_MAX; + for (mc_mn_j=0; mc_mn_j < mc_mn_Vars->Coord_Bin[mc_mn_i+1]; mc_mn_j++) /* search min of signal */ + if ((mc_mn_XY > mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j]) && (mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j] > 0)) mc_mn_XY = mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j]; + if (mc_mn_XY <= 0) mc_mn_XY = -log(FLT_MAX)/log(10); else mc_mn_XY = log(mc_mn_XY)/log(10)-1; + } /* if */ + + for (mc_mn_j=0; mc_mn_j < mc_mn_Vars->Coord_Bin[mc_mn_i+1]; mc_mn_j++) + { + mc_mn_p1m[mc_mn_j] = mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j]; + mc_mn_p2m[mc_mn_j] = mc_mn_Vars->Mon2D_p2[mc_mn_i][mc_mn_j]; + if (mc_mn_Vars->Flag_signal != mc_mn_DEFS->COORD_P && mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j] > 0) + { /* normalize mean signal to the number of events */ + mc_mn_p1m[mc_mn_j] /= mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j]; + mc_mn_p2m[mc_mn_j] /= mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j]*mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j]; + } + if (mc_mn_Vars->Flag_log != 0) + { + if ((mc_mn_p1m[mc_mn_j] > 0) && (mc_mn_p2m[mc_mn_j] > 0)) + { + mc_mn_p2m[mc_mn_j] /= mc_mn_p1m[mc_mn_j]*mc_mn_p1m[mc_mn_j]; + mc_mn_p1m[mc_mn_j] = log(mc_mn_p1m[mc_mn_j])/log(10); + } + else + { + mc_mn_p1m[mc_mn_j] = mc_mn_XY; + mc_mn_p2m[mc_mn_j] = 0; + } + } + } /* for */ + mcdetector_out_1D( + mc_mn_label, + mc_mn_Vars->Coord_Label[mc_mn_i+1], + mc_mn_Vars->Coord_Label[0], + mc_mn_Vars->Coord_Var[mc_mn_i+1], + mc_mn_min1d, mc_mn_max1d, + mc_mn_Vars->Coord_Bin[mc_mn_i+1], + mc_mn_Vars->Mon2D_N[mc_mn_i],mc_mn_p1m,mc_mn_p2m, + mc_mn_fname, mc_mn_Vars->compcurname); + + } /* else */ + if (mc_mn_p1m != NULL) free(mc_mn_p1m); mc_mn_p1m=NULL; + if (mc_mn_p2m != NULL) free(mc_mn_p2m); mc_mn_p2m=NULL; + } else { /* 0d monitor */ + mcdetector_out_0D(mc_mn_label, mc_mn_Vars->Mon2D_p[mc_mn_i][0], mc_mn_Vars->Mon2D_p2[mc_mn_i][0], mc_mn_Vars->Mon2D_N[mc_mn_i][0], mc_mn_Vars->compcurname); + } + + + } /* for */ + } /* if 1D */ + else + if (mc_mn_Vars->Coord_Number == 2) /* 2D: DETECTOR_OUT_2D */ + { + strcpy(mc_mn_fname,mc_mn_Vars->Mon_File); + + mc_mn_p0m = (double *)malloc(mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2]*sizeof(double)); + mc_mn_p1m = (double *)malloc(mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2]*sizeof(double)); + mc_mn_p2m = (double *)malloc(mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2]*sizeof(double)); + if (mc_mn_p2m == NULL) + { + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s cannot allocate memory for 2D array (%li). Skipping.\n", mc_mn_Vars->compcurname, 3*mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2]*sizeof(double)); + if (mc_mn_p0m != NULL) free(mc_mn_p0m); + if (mc_mn_p1m != NULL) free(mc_mn_p1m); + } + else + { + if (mc_mn_Vars->Flag_log != 0) + { + mc_mn_XY = FLT_MAX; + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Bin[1]; mc_mn_i++) + for (mc_mn_j= 0; mc_mn_j < mc_mn_Vars->Coord_Bin[2]; mc_mn_j++) /* search min of signal */ + if ((mc_mn_XY > mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j]) && (mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j]>0)) mc_mn_XY = mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j]; + if (mc_mn_XY <= 0) mc_mn_XY = -log(FLT_MAX)/log(10); else mc_mn_XY = log(mc_mn_XY)/log(10)-1; + } + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Bin[1]; mc_mn_i++) + { + for (mc_mn_j= 0; mc_mn_j < mc_mn_Vars->Coord_Bin[2]; mc_mn_j++) + { + long mc_mn_index; + mc_mn_index = mc_mn_j + mc_mn_i*mc_mn_Vars->Coord_Bin[2]; + mc_mn_p0m[mc_mn_index] = mc_mn_Vars->Mon2D_N[mc_mn_i][mc_mn_j]; + mc_mn_p1m[mc_mn_index] = mc_mn_Vars->Mon2D_p[mc_mn_i][mc_mn_j]; + mc_mn_p2m[mc_mn_index] = mc_mn_Vars->Mon2D_p2[mc_mn_i][mc_mn_j]; + if (mc_mn_Vars->Flag_signal != mc_mn_DEFS->COORD_P && mc_mn_p0m[mc_mn_index] > 0) + { + mc_mn_p1m[mc_mn_index] /= mc_mn_p0m[mc_mn_index]; + mc_mn_p2m[mc_mn_index] /= mc_mn_p0m[mc_mn_index]*mc_mn_p0m[mc_mn_index]; + } + + if (mc_mn_Vars->Flag_log != 0) + { + if ((mc_mn_p1m[mc_mn_index] > 0) && (mc_mn_p2m[mc_mn_index] > 0)) + { + mc_mn_p2m[mc_mn_index] /= (mc_mn_p1m[mc_mn_index]*mc_mn_p1m[mc_mn_index]); + mc_mn_p1m[mc_mn_index] = log(mc_mn_p1m[mc_mn_index])/log(10); + + } + else + { + mc_mn_p1m[mc_mn_index] = mc_mn_XY; + mc_mn_p2m[mc_mn_index] = 0; + } + } + } + } + if (strchr(mc_mn_Vars->Mon_File,'.') == NULL) + { strcat(mc_mn_fname, "."); strcat(mc_mn_fname, mc_mn_Vars->Coord_Var[1]); + strcat(mc_mn_fname, "_"); strcat(mc_mn_fname, mc_mn_Vars->Coord_Var[2]); } + if (mc_mn_Vars->Flag_Verbose) printf("Monitor_nD: %s write monitor file %s 2D (%lix%li).\n", mc_mn_Vars->compcurname, mc_mn_fname, mc_mn_Vars->Coord_Bin[1], mc_mn_Vars->Coord_Bin[2]); + + mc_mn_min1d = mc_mn_Vars->Coord_Min[1]; + mc_mn_max1d = mc_mn_Vars->Coord_Max[1]; + if (mc_mn_min1d == mc_mn_max1d) mc_mn_max1d = mc_mn_min1d+1e-6; + mc_mn_min2d = mc_mn_Vars->Coord_Min[2]; + mc_mn_max2d = mc_mn_Vars->Coord_Max[2]; + if (mc_mn_min2d == mc_mn_max2d) mc_mn_max2d = mc_mn_min2d+1e-6; + strcpy(mc_mn_label, mc_mn_Vars->Monitor_Label); + + mcdetector_out_2D( + mc_mn_label, + mc_mn_Vars->Coord_Label[1], + mc_mn_Vars->Coord_Label[2], + mc_mn_min1d, mc_mn_max1d, + mc_mn_min2d, mc_mn_max2d, + mc_mn_Vars->Coord_Bin[1], + mc_mn_Vars->Coord_Bin[2], + mc_mn_p0m,mc_mn_p1m,mc_mn_p2m, + mc_mn_fname, mc_mn_Vars->compcurname); + + if (mc_mn_p0m != NULL) free(mc_mn_p0m); + if (mc_mn_p1m != NULL) free(mc_mn_p1m); + if (mc_mn_p2m != NULL) free(mc_mn_p2m); + } + } + free(mc_mn_fname); + } + } /* end Monitor_nD_Save */ + +/* ========================================================================= */ +/* ADD: E.Farhi, Aug 6th, 2001: Monitor_nD section */ +/* this routine is used to free memory */ +/* ========================================================================= */ + +void Monitor_nD_Finally(MonitornD_Defines_type *mc_mn_DEFS, + MonitornD_Variables_type *mc_mn_Vars) + { + int mc_mn_i; + + /* Now Free memory Mon2D.. */ + if ((mc_mn_Vars->Flag_Auto_Limits || mc_mn_Vars->Flag_List) && mc_mn_Vars->Coord_Number) + { /* Dim : (mc_mn_Vars->Coord_Number+1)*mc_mn_Vars->Buffer_Block matrix (for p, dp) */ + if (mc_mn_Vars->Mon2D_Buffer != NULL) free(mc_mn_Vars->Mon2D_Buffer); + } + + /* 1D and n1D case : mc_mn_Vars->Flag_Multiple */ + if (mc_mn_Vars->Flag_Multiple && mc_mn_Vars->Coord_Number) + { /* Dim : mc_mn_Vars->Coord_Number*mc_mn_Vars->Coord_Bin[mc_mn_i] vectors */ + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Number; mc_mn_i++) + { + free(mc_mn_Vars->Mon2D_N[mc_mn_i]); + free(mc_mn_Vars->Mon2D_p[mc_mn_i]); + free(mc_mn_Vars->Mon2D_p2[mc_mn_i]); + } + free(mc_mn_Vars->Mon2D_N); + free(mc_mn_Vars->Mon2D_p); + free(mc_mn_Vars->Mon2D_p2); + } + + + /* 2D case : mc_mn_Vars->Coord_Number==2 and !mc_mn_Vars->Flag_Multiple and !mc_mn_Vars->Flag_List */ + if ((mc_mn_Vars->Coord_Number == 2) && !mc_mn_Vars->Flag_Multiple) + { /* Dim : mc_mn_Vars->Coord_Bin[1]*mc_mn_Vars->Coord_Bin[2] matrix */ + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Bin[1]; mc_mn_i++) + { + free(mc_mn_Vars->Mon2D_N[mc_mn_i]); + free(mc_mn_Vars->Mon2D_p[mc_mn_i]); + free(mc_mn_Vars->Mon2D_p2[mc_mn_i]); + } + free(mc_mn_Vars->Mon2D_N); + free(mc_mn_Vars->Mon2D_p); + free(mc_mn_Vars->Mon2D_p2); + } + } /* end Monitor_nD_Finally */ + +/* ========================================================================= */ +/* ADD: E.Farhi, Aug 6th, 2001: Monitor_nD section */ +/* this routine is used to display component */ +/* ========================================================================= */ + +void Monitor_nD_McDisplay(MonitornD_Defines_type *mc_mn_DEFS, + MonitornD_Variables_type *mc_mn_Vars) + { + double mc_mn_radius, mc_mn_h; + double mc_mn_xmin; + double mc_mn_xmax; + double mc_mn_ymin; + double mc_mn_ymax; + double mc_mn_zmin; + double mc_mn_zmax; + int mc_mn_i; + double mc_mn_hdiv_min=-180, mc_mn_hdiv_max=180, mc_mn_vdiv_min=-180, mc_mn_vdiv_max=180; + char mc_mn_restricted = 0; + + mc_mn_radius = mc_mn_Vars->Sphere_Radius; + mc_mn_h = mc_mn_Vars->Cylinder_Height; + mc_mn_xmin = mc_mn_Vars->mxmin; + mc_mn_xmax = mc_mn_Vars->mxmax; + mc_mn_ymin = mc_mn_Vars->mymin; + mc_mn_ymax = mc_mn_Vars->mymax; + mc_mn_zmin = mc_mn_Vars->mzmin; + mc_mn_zmax = mc_mn_Vars->mzmax; + + /* determine if there are angular limits set at start (no auto) in coord_types + * cylinder/banana: look for hdiv + * sphere: look for angle, radius (->atan2(val,mc_mn_radius)), hdiv, vdiv + * this activates a 'restricted' flag, to draw a region as blades on cylinder/sphere + */ + for (mc_mn_i= 0; mc_mn_i < mc_mn_Vars->Coord_Number; mc_mn_i++) + { + int mc_mn_Set_Vars_Coord_Type; + mc_mn_Set_Vars_Coord_Type = (mc_mn_Vars->Coord_Type[mc_mn_i] & 31); + if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_HDIV || mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_THETA) + { mc_mn_hdiv_min = mc_mn_Vars->Coord_Min[mc_mn_i]; mc_mn_hdiv_max = mc_mn_Vars->Coord_Max[mc_mn_i]; mc_mn_restricted = 1; } + else if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_VDIV || mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_PHI) + { mc_mn_vdiv_min = mc_mn_Vars->Coord_Min[mc_mn_i]; mc_mn_vdiv_max = mc_mn_Vars->Coord_Max[mc_mn_i];mc_mn_restricted = 1; } + else if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_ANGLE) + { mc_mn_hdiv_min = mc_mn_vdiv_min = mc_mn_Vars->Coord_Min[mc_mn_i]; + mc_mn_hdiv_max = mc_mn_vdiv_max = mc_mn_Vars->Coord_Max[mc_mn_i]; + mc_mn_restricted = 1; } + else if (mc_mn_Set_Vars_Coord_Type == mc_mn_DEFS->COORD_RADIUS) + { double angle; + angle = RAD2DEG*atan2(mc_mn_Vars->Coord_Max[mc_mn_i], mc_mn_radius); + mc_mn_hdiv_min = mc_mn_vdiv_min = angle; + mc_mn_hdiv_max = mc_mn_vdiv_max = angle; + mc_mn_restricted = 1; } + } + + if (!mc_mn_restricted && (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_SPHERE)) + { + mcdis_magnify(""); + mcdis_circle("xy",0,0,0,mc_mn_radius); + mcdis_circle("xz",0,0,0,mc_mn_radius); + mcdis_circle("yz",0,0,0,mc_mn_radius); + } + else if (mc_mn_restricted && ((abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_CYLIND) || (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_BANANA) || (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_SPHERE))) + { + int NH=24, NV=24; + int ih, iv; + double width, height; + int issphere; + issphere = (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_SPHERE); + width = (mc_mn_hdiv_max-mc_mn_hdiv_min)/NH; + height= (mc_mn_vdiv_max-mc_mn_vdiv_min)/NV; + mcdis_magnify("xyz"); + for(ih = 0; ih < NH; ih++) + for(iv = 0; iv < NV; iv++) + { + double theta0, phi0, theta1, phi1; + double x0,y0,z0,x1,y1,z1,x2,y2,z2,x3,y3,z3; + double ymin, ymax; + phi0 = (mc_mn_hdiv_min+ width*ih)*DEG2RAD; /* in xz plane */ + phi1 = (mc_mn_hdiv_min+ width*(ih+1))*DEG2RAD; + if (issphere) + { + theta0= (90-mc_mn_vdiv_min+height*iv)*DEG2RAD; + theta1= (90-mc_mn_vdiv_min+height*(iv+1))*DEG2RAD; + } else + { + theta0= theta1 = PI/2; + ymin = mc_mn_ymin+(mc_mn_ymax-mc_mn_ymin)*(iv/NV); + ymax = mc_mn_ymin+(mc_mn_ymax-mc_mn_ymin)*((iv+1)/NV); + } + z0 = mc_mn_radius*sin(theta0)*cos(phi0); + x0 = mc_mn_radius*sin(theta0)*sin(phi0); + if (issphere) y0 = mc_mn_radius*cos(theta0); else y0 = ymin; + z1 = mc_mn_radius*sin(theta1)*cos(phi0); + x1 = mc_mn_radius*sin(theta1)*sin(phi0); + if (issphere) y1 = mc_mn_radius*cos(theta1); else y1 = ymax; + z2 = mc_mn_radius*sin(theta1)*cos(phi1); + x2 = mc_mn_radius*sin(theta1)*sin(phi1); + y2 = y1; + z3 = mc_mn_radius*sin(theta0)*cos(phi1); + x3 = mc_mn_radius*sin(theta0)*sin(phi1); + y3 = y0; + mcdis_multiline(5, + x0,y0,z0, + x1,y1,z1, + x2,y2,z2, + x3,y3,z3, + x0,y0,z0); + } + } + else + if (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_DISK) + { + mcdis_magnify(""); + mcdis_circle("xy",0,0,0,mc_mn_radius); + } + else + if (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_SQUARE) + { + mcdis_magnify("xy"); + mcdis_multiline(5, (double)mc_mn_xmin, (double)mc_mn_ymin, 0.0, + (double)mc_mn_xmax, (double)mc_mn_ymin, 0.0, + (double)mc_mn_xmax, (double)mc_mn_ymax, 0.0, + (double)mc_mn_xmin, (double)mc_mn_ymax, 0.0, + (double)mc_mn_xmin, (double)mc_mn_ymin, 0.0); + } + else + if (!mc_mn_restricted && ((abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_CYLIND) || (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_BANANA))) + { + mcdis_magnify("xyz"); + mcdis_circle("xz", 0, mc_mn_h/2.0, 0, mc_mn_radius); + mcdis_circle("xz", 0, -mc_mn_h/2.0, 0, mc_mn_radius); + mcdis_line(-mc_mn_radius, -mc_mn_h/2.0, 0, -mc_mn_radius, +mc_mn_h/2.0, 0); + mcdis_line(+mc_mn_radius, -mc_mn_h/2.0, 0, +mc_mn_radius, +mc_mn_h/2.0, 0); + mcdis_line(0, -mc_mn_h/2.0, -mc_mn_radius, 0, +mc_mn_h/2.0, -mc_mn_radius); + mcdis_line(0, -mc_mn_h/2.0, +mc_mn_radius, 0, +mc_mn_h/2.0, +mc_mn_radius); + } + else + if (abs(mc_mn_Vars->Flag_Shape) == mc_mn_DEFS->SHAPE_BOX) + { + mcdis_magnify("xyz"); + mcdis_multiline(5, mc_mn_xmin, mc_mn_ymin, mc_mn_zmin, + mc_mn_xmax, mc_mn_ymin, mc_mn_zmin, + mc_mn_xmax, mc_mn_ymax, mc_mn_zmin, + mc_mn_xmin, mc_mn_ymax, mc_mn_zmin, + mc_mn_xmin, mc_mn_ymin, mc_mn_zmin); + mcdis_multiline(5, mc_mn_xmin, mc_mn_ymin, mc_mn_zmax, + mc_mn_xmax, mc_mn_ymin, mc_mn_zmax, + mc_mn_xmax, mc_mn_ymax, mc_mn_zmax, + mc_mn_xmin, mc_mn_ymax, mc_mn_zmax, + mc_mn_xmin, mc_mn_ymin, mc_mn_zmax); + mcdis_line(mc_mn_xmin, mc_mn_ymin, mc_mn_zmin, mc_mn_xmin, mc_mn_ymin, mc_mn_zmax); + mcdis_line(mc_mn_xmax, mc_mn_ymin, mc_mn_zmin, mc_mn_xmax, mc_mn_ymin, mc_mn_zmax); + mcdis_line(mc_mn_xmin, mc_mn_ymax, mc_mn_zmin, mc_mn_xmin, mc_mn_ymax, mc_mn_zmax); + mcdis_line(mc_mn_xmax, mc_mn_ymax, mc_mn_zmin, mc_mn_xmax, mc_mn_ymax, mc_mn_zmax); + } + } /* end Monitor_nD_McDisplay */ + +/* end of monitor_nd-lib.c */ + +#line 6873 "dmcafter.c" +#line 213 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/monitors/Monitor_nD.comp" + MonitornD_Defines_type DEFS; + MonitornD_Variables_type Vars; +#line 6877 "dmcafter.c" +#undef zmax +#undef zmin +#undef ymax +#undef ymin +#undef xmax +#undef xmin +#undef zthick +#undef yheight +#undef xwidth +#undef Vars +#undef DEFS +#undef filename +#undef options +#undef mccompcurname +#undef mccompcurindex + +Coords mcposamsa, mcposrmsa; +Rotation mcrotamsa, mcrotrmsa; +Coords mcposain, mcposrin; +Rotation mcrotain, mcrotrin; +Coords mcposaout2_slit, mcposrout2_slit; +Rotation mcrotaout2_slit, mcrotrout2_slit; +Coords mcposaPSD_sample, mcposrPSD_sample; +Rotation mcrotaPSD_sample, mcrotrPSD_sample; +Coords mcposasa_arm, mcposrsa_arm; +Rotation mcrotasa_arm, mcrotrsa_arm; +Coords mcposasample, mcposrsample; +Rotation mcrotasample, mcrotrsample; +Coords mcposaDet9, mcposrDet9; +Rotation mcrotaDet9, mcrotrDet9; + +MCNUM mcnx, mcny, mcnz, mcnvx, mcnvy, mcnvz, mcnt, mcnsx, mcnsy, mcnsz, mcnp; + +void mcinit(void) { +#define Det_start mcipDet_start +#define samplefile mcipsamplefile +#define monfile mcipmonfile +#define lambdafile mciplambdafile +#define repeat mciprepeat +#line 13 "dmcafter.instr" +{ +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); +} +#line 6923 "dmcafter.c" +#undef repeat +#undef lambdafile +#undef monfile +#undef samplefile +#undef Det_start + /* Computation of coordinate transformations. */ + { + Coords mctc1, mctc2; + Rotation mctr1; + + mcDEBUG_INSTR() + /* Component msa. */ + strcpy(mcsig_message, "msa (Init:Place/Rotate)"); + rot_set_rotation(mcrotamsa, + (0.0)*DEG2RAD, + (0.0)*DEG2RAD, + (0.0)*DEG2RAD); +#line 6941 "dmcafter.c" + rot_copy(mcrotrmsa, mcrotamsa); + mcposamsa = coords_set( +#line 23 "dmcafter.instr" + 0, +#line 23 "dmcafter.instr" + 0, +#line 23 "dmcafter.instr" + 0); +#line 6950 "dmcafter.c" + mctc1 = coords_neg(mcposamsa); + mcposrmsa = rot_apply(mcrotamsa, mctc1); + mcDEBUG_COMPONENT("msa", mcposamsa, mcrotamsa) + mccomp_posa[1] = mcposamsa; + mccomp_posr[1] = mcposrmsa; + /* Component in. */ + strcpy(mcsig_message, "in (Init:Place/Rotate)"); + rot_set_rotation(mctr1, +#line 31 "dmcafter.instr" + (0)*DEG2RAD, +#line 31 "dmcafter.instr" + (0)*DEG2RAD, +#line 31 "dmcafter.instr" + (0)*DEG2RAD); +#line 6965 "dmcafter.c" + rot_mul(mctr1, mcrotamsa, mcrotain); + rot_transpose(mcrotamsa, mctr1); + rot_mul(mcrotain, mctr1, mcrotrin); + mctc1 = coords_set( +#line 31 "dmcafter.instr" + 0, +#line 31 "dmcafter.instr" + 0, +#line 31 "dmcafter.instr" + 0.64); +#line 6976 "dmcafter.c" + rot_transpose(mcrotamsa, mctr1); + mctc2 = rot_apply(mctr1, mctc1); + mcposain = coords_add(mcposamsa, mctc2); + mctc1 = coords_sub(mcposamsa, mcposain); + mcposrin = rot_apply(mcrotain, mctc1); + mcDEBUG_COMPONENT("in", mcposain, mcrotain) + mccomp_posa[2] = mcposain; + mccomp_posr[2] = mcposrin; + /* Component out2_slit. */ + strcpy(mcsig_message, "out2_slit (Init:Place/Rotate)"); + rot_set_rotation(mctr1, +#line 35 "dmcafter.instr" + (0)*DEG2RAD, +#line 35 "dmcafter.instr" + (0)*DEG2RAD, +#line 35 "dmcafter.instr" + (0)*DEG2RAD); +#line 6994 "dmcafter.c" + rot_mul(mctr1, mcrotamsa, mcrotaout2_slit); + rot_transpose(mcrotain, mctr1); + rot_mul(mcrotaout2_slit, mctr1, mcrotrout2_slit); + mctc1 = coords_set( +#line 35 "dmcafter.instr" + 0, +#line 35 "dmcafter.instr" + 0, +#line 35 "dmcafter.instr" + 0.65); +#line 7005 "dmcafter.c" + rot_transpose(mcrotamsa, mctr1); + mctc2 = rot_apply(mctr1, mctc1); + mcposaout2_slit = coords_add(mcposamsa, mctc2); + mctc1 = coords_sub(mcposain, mcposaout2_slit); + mcposrout2_slit = rot_apply(mcrotaout2_slit, mctc1); + mcDEBUG_COMPONENT("out2_slit", mcposaout2_slit, mcrotaout2_slit) + mccomp_posa[3] = mcposaout2_slit; + mccomp_posr[3] = mcposrout2_slit; + /* Component PSD_sample. */ + strcpy(mcsig_message, "PSD_sample (Init:Place/Rotate)"); + rot_set_rotation(mctr1, + (0.0)*DEG2RAD, + (0.0)*DEG2RAD, + (0.0)*DEG2RAD); +#line 7020 "dmcafter.c" + rot_mul(mctr1, mcrotamsa, mcrotaPSD_sample); + rot_transpose(mcrotaout2_slit, mctr1); + rot_mul(mcrotaPSD_sample, mctr1, mcrotrPSD_sample); + mctc1 = coords_set( +#line 39 "dmcafter.instr" + 0, +#line 39 "dmcafter.instr" + 0, +#line 39 "dmcafter.instr" + 1.5); +#line 7031 "dmcafter.c" + rot_transpose(mcrotamsa, mctr1); + mctc2 = rot_apply(mctr1, mctc1); + mcposaPSD_sample = coords_add(mcposamsa, mctc2); + mctc1 = coords_sub(mcposaout2_slit, mcposaPSD_sample); + mcposrPSD_sample = rot_apply(mcrotaPSD_sample, mctc1); + mcDEBUG_COMPONENT("PSD_sample", mcposaPSD_sample, mcrotaPSD_sample) + mccomp_posa[4] = mcposaPSD_sample; + mccomp_posr[4] = mcposrPSD_sample; + /* Component sa_arm. */ + strcpy(mcsig_message, "sa_arm (Init:Place/Rotate)"); + rot_set_rotation(mctr1, +#line 53 "dmcafter.instr" + (0)*DEG2RAD, +#line 53 "dmcafter.instr" + (0)*DEG2RAD, +#line 53 "dmcafter.instr" + (0)*DEG2RAD); +#line 7049 "dmcafter.c" + rot_mul(mctr1, mcrotamsa, mcrotasa_arm); + rot_transpose(mcrotaPSD_sample, mctr1); + rot_mul(mcrotasa_arm, mctr1, mcrotrsa_arm); + mctc1 = coords_set( +#line 52 "dmcafter.instr" + 0, +#line 52 "dmcafter.instr" + 0, +#line 52 "dmcafter.instr" + 2.82); +#line 7060 "dmcafter.c" + rot_transpose(mcrotamsa, mctr1); + mctc2 = rot_apply(mctr1, mctc1); + mcposasa_arm = coords_add(mcposamsa, mctc2); + mctc1 = coords_sub(mcposaPSD_sample, mcposasa_arm); + mcposrsa_arm = rot_apply(mcrotasa_arm, mctc1); + mcDEBUG_COMPONENT("sa_arm", mcposasa_arm, mcrotasa_arm) + mccomp_posa[5] = mcposasa_arm; + mccomp_posr[5] = mcposrsa_arm; + /* Component sample. */ + strcpy(mcsig_message, "sample (Init:Place/Rotate)"); + rot_set_rotation(mctr1, + (0.0)*DEG2RAD, + (0.0)*DEG2RAD, + (0.0)*DEG2RAD); +#line 7075 "dmcafter.c" + rot_mul(mctr1, mcrotasa_arm, mcrotasample); + rot_transpose(mcrotasa_arm, mctr1); + rot_mul(mcrotasample, mctr1, mcrotrsample); + mctc1 = coords_set( +#line 59 "dmcafter.instr" + 0, +#line 59 "dmcafter.instr" + 0, +#line 59 "dmcafter.instr" + 0); +#line 7086 "dmcafter.c" + rot_transpose(mcrotasa_arm, mctr1); + mctc2 = rot_apply(mctr1, mctc1); + mcposasample = coords_add(mcposasa_arm, mctc2); + mctc1 = coords_sub(mcposasa_arm, mcposasample); + mcposrsample = rot_apply(mcrotasample, mctc1); + mcDEBUG_COMPONENT("sample", mcposasample, mcrotasample) + mccomp_posa[6] = mcposasample; + mccomp_posr[6] = mcposrsample; + /* Component Det9. */ + strcpy(mcsig_message, "Det9 (Init:Place/Rotate)"); + rot_set_rotation(mctr1, +#line 65 "dmcafter.instr" + (0)*DEG2RAD, +#line 65 "dmcafter.instr" + (0)*DEG2RAD, +#line 65 "dmcafter.instr" + (180)*DEG2RAD); +#line 7104 "dmcafter.c" + rot_mul(mctr1, mcrotasa_arm, mcrotaDet9); + rot_transpose(mcrotasample, mctr1); + rot_mul(mcrotaDet9, mctr1, mcrotrDet9); + mctc1 = coords_set( +#line 64 "dmcafter.instr" + 0, +#line 64 "dmcafter.instr" + 0, +#line 64 "dmcafter.instr" + 0.000001); +#line 7115 "dmcafter.c" + rot_transpose(mcrotasa_arm, mctr1); + mctc2 = rot_apply(mctr1, mctc1); + mcposaDet9 = coords_add(mcposasa_arm, mctc2); + mctc1 = coords_sub(mcposasample, mcposaDet9); + mcposrDet9 = rot_apply(mcrotaDet9, mctc1); + mcDEBUG_COMPONENT("Det9", mcposaDet9, mcrotaDet9) + mccomp_posa[7] = mcposaDet9; + mccomp_posr[7] = mcposrDet9; + /* Component initializations. */ + /* Initializations for component msa. */ + strcpy(mcsig_message, "msa (Init)"); + + + /* Initializations for component in. */ + strcpy(mcsig_message, "in (Init)"); +#line 30 "dmcafter.instr" + mccin_repeat_count = mciprepeat; +#line 68 "dmcafter.instr" + mccin_bufsize = 0; +#line 7135 "dmcafter.c" + +#define mccompcurname in +#define mccompcurindex 2 +#define file mccin_file +#define type mccin_type +#define rep mccin_rep +#define pos mccin_pos +#define nrows mccin_nrows +#define nread mccin_nread +#define Offset mccin_Offset +#define rTable mccin_rTable +#define Virtual_input_Read_Input mccin_Virtual_input_Read_Input +{ /* Declarations of SETTING parameters. */ +MCNUM repeat_count = mccin_repeat_count; +MCNUM bufsize = mccin_bufsize; +#line 112 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/sources/Virtual_input.comp" +{ + Table_Init(&rTable); + rep = repeat_count+1; + + if (!file || !repeat_count) + { + fprintf(stderr,"Virtual_input: %s: please give me a file name (file) to read (repeat_count>0).\n", NAME_CURRENT_COMP); + exit(-1); + } + if (type && strstr(type, "Vitess")) + { fprintf(stderr, "Virtual_input: %s: Vitess files may be read using the Vitess_input component\n", NAME_CURRENT_COMP); exit(-1); } + + if (bufsize) mcset_ncount(bufsize*repeat_count); + + printf("Virtual_input: %s: Reading neutron events from file '%s'. Repeat %g time(s)\n", NAME_CURRENT_COMP, file, repeat_count); +} +#line 7168 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Virtual_input_Read_Input +#undef rTable +#undef Offset +#undef nread +#undef nrows +#undef pos +#undef rep +#undef type +#undef file +#undef mccompcurname +#undef mccompcurindex + + /* Initializations for component out2_slit. */ + strcpy(mcsig_message, "out2_slit (Init)"); +#line 34 "dmcafter.instr" + mccout2_slit_xmin = -0.01; +#line 34 "dmcafter.instr" + mccout2_slit_xmax = 0.01; +#line 34 "dmcafter.instr" + mccout2_slit_ymin = -0.06; +#line 34 "dmcafter.instr" + mccout2_slit_ymax = 0.06; +#line 42 "dmcafter.instr" + mccout2_slit_radius = 0; +#line 7194 "dmcafter.c" + +#define mccompcurname out2_slit +#define mccompcurindex 3 +{ /* Declarations of SETTING parameters. */ +MCNUM xmin = mccout2_slit_xmin; +MCNUM xmax = mccout2_slit_xmax; +MCNUM ymin = mccout2_slit_ymin; +MCNUM ymax = mccout2_slit_ymax; +MCNUM radius = mccout2_slit_radius; +#line 46 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/optics/Slit.comp" +{ + if (xmin == 0 && xmax == 0 && ymin == 0 & ymax == 0 && radius == 0) + { fprintf(stderr,"Slit: %s: Error: give geometry\n", NAME_CURRENT_COMP); exit(-1); } + +} +#line 7210 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef mccompcurname +#undef mccompcurindex + + /* Initializations for component PSD_sample. */ + strcpy(mcsig_message, "PSD_sample (Init)"); +#line 38 "dmcafter.instr" + mccPSD_sample_xmin = -0.05; +#line 38 "dmcafter.instr" + mccPSD_sample_xmax = 0.05; +#line 38 "dmcafter.instr" + mccPSD_sample_ymin = -0.07; +#line 38 "dmcafter.instr" + mccPSD_sample_ymax = 0.07; +#line 38 "dmcafter.instr" + if(mcipmonfile) strncpy(mccPSD_sample_controlfile,mcipmonfile, 1024); else mccPSD_sample_controlfile[0]='\0'; +#line 45 "dmcafter.instr" + mccPSD_sample_dumpCount = 1000; +#line 7229 "dmcafter.c" + +#define mccompcurname PSD_sample +#define mccompcurindex 4 +#define Nsum mccPSD_sample_Nsum +#define psum mccPSD_sample_psum +#define p2sum mccPSD_sample_p2sum +#define currentCount mccPSD_sample_currentCount +{ /* Declarations of SETTING parameters. */ +MCNUM xmin = mccPSD_sample_xmin; +MCNUM xmax = mccPSD_sample_xmax; +MCNUM ymin = mccPSD_sample_ymin; +MCNUM ymax = mccPSD_sample_ymax; +char* controlfile = mccPSD_sample_controlfile; +int dumpCount = mccPSD_sample_dumpCount; +#line 72 "MKMonitor.comp" +{ + psum = 0; + p2sum = 0; + Nsum = 0; + currentCount = 0; +} +#line 7251 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef currentCount +#undef p2sum +#undef psum +#undef Nsum +#undef mccompcurname +#undef mccompcurindex + + /* Initializations for component sa_arm. */ + strcpy(mcsig_message, "sa_arm (Init)"); + + + /* Initializations for component sample. */ + strcpy(mcsig_message, "sample (Init)"); +#line 56 "dmcafter.instr" + mccsample_d_phi0 = 0; +#line 56 "dmcafter.instr" + mccsample_radius = sample_radius; +#line 61 "dmcafter.instr" + mccsample_focus_r = 0; +#line 56 "dmcafter.instr" + mccsample_h = sample_height; +#line 57 "dmcafter.instr" + mccsample_pack = 1; +#line 57 "dmcafter.instr" + mccsample_Vc = 1076.98; +#line 58 "dmcafter.instr" + mccsample_sigma_a = 0.2; +#line 62 "dmcafter.instr" + mccsample_sigma_inc = 0; +#line 63 "dmcafter.instr" + mccsample_frac = 0; +#line 63 "dmcafter.instr" + mccsample_focus_xw = 0; +#line 63 "dmcafter.instr" + mccsample_focus_yh = 0; +#line 58 "dmcafter.instr" + mccsample_focus_aw = 80; +#line 58 "dmcafter.instr" + mccsample_focus_ah = 3.5; +#line 64 "dmcafter.instr" + mccsample_target_x = 0; +#line 64 "dmcafter.instr" + mccsample_target_y = 0; +#line 64 "dmcafter.instr" + mccsample_target_z = 0; +#line 58 "dmcafter.instr" + mccsample_target_index = + 1; +#line 7300 "dmcafter.c" + +#define mccompcurname sample +#define mccompcurindex 6 +#define reflections mccsample_reflections +#define my_s_v2 mccsample_my_s_v2 +#define my_a_v mccsample_my_a_v +#define q_v mccsample_q_v +{ /* Declarations of SETTING parameters. */ +MCNUM d_phi0 = mccsample_d_phi0; +MCNUM radius = mccsample_radius; +MCNUM focus_r = mccsample_focus_r; +MCNUM h = mccsample_h; +MCNUM pack = mccsample_pack; +MCNUM Vc = mccsample_Vc; +MCNUM sigma_a = mccsample_sigma_a; +MCNUM sigma_inc = mccsample_sigma_inc; +MCNUM frac = mccsample_frac; +MCNUM focus_xw = mccsample_focus_xw; +MCNUM focus_yh = mccsample_focus_yh; +MCNUM focus_aw = mccsample_focus_aw; +MCNUM focus_ah = mccsample_focus_ah; +MCNUM target_x = mccsample_target_x; +MCNUM target_y = mccsample_target_y; +MCNUM target_z = mccsample_target_z; +int target_index = mccsample_target_index; +#line 148 "PowderN.comp" +{ + struct line_data *L; + read_line_data(reflections, &line_info); + L = line_info.list; + + Nq = line_info.count; + my_s_v2 = malloc(Nq*sizeof(double)); + q_v = malloc(Nq*sizeof(double)); + w_v = malloc(Nq*sizeof(double)); + int i; + my_a_v = pack*sigma_a/Vc*2200; /* Is not yet divided by v */ + my_inc = pack*sigma_inc/Vc; + my_s_v2_sum=0; + + for(i=0; i= repeat_count) { + nrows = Virtual_input_Read_Input(file, type, &rTable, &Offset); + if (nrows) { rep = 0; pos = 0; nread++; } + } + + if (!nrows) + { mcset_ncount(mcget_run_num()); ABSORB; } + /* for each buffer, loop: repeat counts */ + /* for each repeat count: loop: generate neutrons */ + if (pos >= nrows) + { rep++; pos = 0; } /* Reposition at start of buffer */ + + /* &p, &x, &y, &z, &vx, &vy, &vz, &t, &sx, &sy, &sz */ + mcrestore_neutron(rTable.data,pos, &x, &y, &z, &vx, &vy, &vz, &t, &sx, &sy, &sz, &p); + + pos++; + p /= repeat_count; + SCATTER; +} +#line 7523 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Virtual_input_Read_Input +#undef rTable +#undef Offset +#undef nread +#undef nrows +#undef pos +#undef rep +#undef type +#undef file +#undef mccompcurname +#undef mccompcurindex +#undef sz +#undef sy +#undef sx +#undef p +#undef s2 +#undef s1 +#undef t +#undef vz +#undef vy +#undef vx +#undef z +#undef y +#undef x + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + + /* Component out2_slit. */ + strcpy(mcsig_message, "out2_slit (Trace)"); + mcDEBUG_COMP("out2_slit") + mccoordschange(mcposrout2_slit, mcrotrout2_slit, + &mcnlx, &mcnly, &mcnlz, + &mcnlvx, &mcnlvy, &mcnlvz, + &mcnlt, &mcnlsx, &mcnlsy); + mccoordschange_polarisation(mcrotrout2_slit, &mcnlsx, &mcnlsy, &mcnlsz); + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) +#define x mcnlx +#define y mcnly +#define z mcnlz +#define vx mcnlvx +#define vy mcnlvy +#define vz mcnlvz +#define t mcnlt +#define s1 mcnlsx +#define s2 mcnlsy +#define p mcnlp + STORE_NEUTRON(3,mcnlx, mcnly, mcnlz, mcnlvx,mcnlvy,mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlsz, mcnlp); + mcScattered=0; +#define mccompcurname out2_slit +#define mccompcurindex 3 +{ /* Declarations of SETTING parameters. */ +MCNUM xmin = mccout2_slit_xmin; +MCNUM xmax = mccout2_slit_xmax; +MCNUM ymin = mccout2_slit_ymin; +MCNUM ymax = mccout2_slit_ymax; +MCNUM radius = mccout2_slit_radius; +#line 53 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/optics/Slit.comp" +{ + PROP_Z0; + if (((radius == 0) && (xxmax || yymax)) + || ((radius != 0) && (x*x + y*y > radius*radius))) + ABSORB; + else + SCATTER; +} +#line 7589 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef mccompcurname +#undef mccompcurindex +#undef p +#undef s2 +#undef s1 +#undef t +#undef vz +#undef vy +#undef vx +#undef z +#undef y +#undef x + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + + /* Component PSD_sample. */ + strcpy(mcsig_message, "PSD_sample (Trace)"); + mcDEBUG_COMP("PSD_sample") + mccoordschange(mcposrPSD_sample, mcrotrPSD_sample, + &mcnlx, &mcnly, &mcnlz, + &mcnlvx, &mcnlvy, &mcnlvz, + &mcnlt, &mcnlsx, &mcnlsy); + mccoordschange_polarisation(mcrotrPSD_sample, &mcnlsx, &mcnlsy, &mcnlsz); + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) +#define x mcnlx +#define y mcnly +#define z mcnlz +#define vx mcnlvx +#define vy mcnlvy +#define vz mcnlvz +#define t mcnlt +#define s1 mcnlsx +#define s2 mcnlsy +#define p mcnlp + STORE_NEUTRON(4,mcnlx, mcnly, mcnlz, mcnlvx,mcnlvy,mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlsz, mcnlp); + mcScattered=0; +#define mccompcurname PSD_sample +#define mccompcurindex 4 +#define Nsum mccPSD_sample_Nsum +#define psum mccPSD_sample_psum +#define p2sum mccPSD_sample_p2sum +#define currentCount mccPSD_sample_currentCount +{ /* Declarations of SETTING parameters. */ +MCNUM xmin = mccPSD_sample_xmin; +MCNUM xmax = mccPSD_sample_xmax; +MCNUM ymin = mccPSD_sample_ymin; +MCNUM ymax = mccPSD_sample_ymax; +char* controlfile = mccPSD_sample_controlfile; +int dumpCount = mccPSD_sample_dumpCount; +#line 79 "MKMonitor.comp" +{ + PROP_Z0; + if (x>xmin && xymin && y 0 && currentCount > dumpCount){ + dumpTotal(controlfile,(long)Nsum); + currentCount = 0; + } + SCATTER; + } +} +#line 7655 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef currentCount +#undef p2sum +#undef psum +#undef Nsum +#undef mccompcurname +#undef mccompcurindex +#undef p +#undef s2 +#undef s1 +#undef t +#undef vz +#undef vy +#undef vx +#undef z +#undef y +#undef x + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + + /* Component sa_arm. */ + strcpy(mcsig_message, "sa_arm (Trace)"); + mcDEBUG_COMP("sa_arm") + mccoordschange(mcposrsa_arm, mcrotrsa_arm, + &mcnlx, &mcnly, &mcnlz, + &mcnlvx, &mcnlvy, &mcnlvz, + &mcnlt, &mcnlsx, &mcnlsy); + mccoordschange_polarisation(mcrotrsa_arm, &mcnlsx, &mcnlsy, &mcnlsz); + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + STORE_NEUTRON(5,mcnlx, mcnly, mcnlz, mcnlvx,mcnlvy,mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlsz, mcnlp); + mcScattered=0; +#define mccompcurname sa_arm +#define mccompcurindex 5 +#undef mccompcurname +#undef mccompcurindex + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + + /* Component sample. */ + strcpy(mcsig_message, "sample (Trace)"); + mcDEBUG_COMP("sample") + mccoordschange(mcposrsample, mcrotrsample, + &mcnlx, &mcnly, &mcnlz, + &mcnlvx, &mcnlvy, &mcnlvz, + &mcnlt, &mcnlsx, &mcnlsy); + mccoordschange_polarisation(mcrotrsample, &mcnlsx, &mcnlsy, &mcnlsz); + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) +#define x mcnlx +#define y mcnly +#define z mcnlz +#define vx mcnlvx +#define vy mcnlvy +#define vz mcnlvz +#define t mcnlt +#define s1 mcnlsx +#define s2 mcnlsy +#define p mcnlp + STORE_NEUTRON(6,mcnlx, mcnly, mcnlz, mcnlvx,mcnlvy,mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlsz, mcnlp); + mcScattered=0; +#define mccompcurname sample +#define mccompcurindex 6 +#define reflections mccsample_reflections +#define my_s_v2 mccsample_my_s_v2 +#define my_a_v mccsample_my_a_v +#define q_v mccsample_q_v +{ /* Declarations of SETTING parameters. */ +MCNUM d_phi0 = mccsample_d_phi0; +MCNUM radius = mccsample_radius; +MCNUM focus_r = mccsample_focus_r; +MCNUM h = mccsample_h; +MCNUM pack = mccsample_pack; +MCNUM Vc = mccsample_Vc; +MCNUM sigma_a = mccsample_sigma_a; +MCNUM sigma_inc = mccsample_sigma_inc; +MCNUM frac = mccsample_frac; +MCNUM focus_xw = mccsample_focus_xw; +MCNUM focus_yh = mccsample_focus_yh; +MCNUM focus_aw = mccsample_focus_aw; +MCNUM focus_ah = mccsample_focus_ah; +MCNUM target_x = mccsample_target_x; +MCNUM target_y = mccsample_target_y; +MCNUM target_z = mccsample_target_z; +int target_index = mccsample_target_index; +#line 172 "PowderN.comp" +{ + double t0, t1, v, v1,l_full, l, l_1, dt, d_phi, theta, my_s, my_s_n; + double aim_x, aim_y, aim_z, axis_x, axis_y, axis_z; + double arg, tmp_vx, tmp_vy, tmp_vz, p_in, vout_x, vout_y, vout_z; + int line; + + if(cylinder_intersect(&t0, &t1, x, y, z, vx, vy, vz, radius, h)) + { + if(t0 < 0) + ABSORB; + /* Neutron enters at t=t0. */ + v = sqrt(vx*vx + vy*vy + vz*vz); + l_full = v * (t1 - t0); /* Length of full path through sample */ + dt = rand01()*(t1 - t0); /* Time of scattering */ + PROP_DT(dt+t0); /* Point of scattering */ + l = v*dt; /* Penetration in sample */ + if (target_index){ + Coords ToTarget; + ToTarget = coords_sub(POS_A_COMP_INDEX(INDEX_CURRENT_COMP+target_index),POS_A_CURRENT_COMP); + ToTarget = rot_apply(ROT_A_CURRENT_COMP, ToTarget); + coords_get(ToTarget, &target_x, &target_y, &target_z); + } + aim_x = target_x-x; /* Vector pointing at target (anal./det.) */ + aim_y = target_y-y; + aim_z = target_z-z; + my_s = my_s_v2_sum/(v*v)+my_inc; + /* Total attenuation from scattering */ + + if (rand01() >= frac) + { /* Make coherent scattering event */ + /* Choose point on Debye-Scherrer cone */ + if (d_phi>0) + { + d_phi = d_phi0*DEG2RAD/2.0*randpm1(); + p *= d_phi0/360.0; + } + else + d_phi = 180*DEG2RAD*randpm1(); + line=floor(Nq*rand01()); /* Select between Nq powder lines */ + arg = (q_v[line]+w_v[line]*randnorm())/(2.0*v); + my_s_n = my_s_v2[line]/(v*v); + if(arg > 1) + ABSORB; /* No bragg scattering possible*/ + theta = asin(arg); /* Bragg scattering law */ + + vec_prod(axis_x, axis_y, axis_z, vx, vy, vz, aim_x, aim_y, aim_z); + rotate(tmp_vx, tmp_vy, tmp_vz, vx, vy, vz, 2*theta, axis_x, axis_y, axis_z); + rotate(vout_x, vout_y, vout_z, tmp_vx, tmp_vy, tmp_vz, d_phi, vx, vy, vz); + vx = vout_x; + vy = vout_y; + vz = vout_z; + + if(!cylinder_intersect(&t0, &t1, x, y, z, + vx, vy, vz, radius, h)) + { + /* Strange error: did not hit cylinder */ + printf("FATAL ERROR: Did not hit cylinder from inside.\n"); + exit(1); + } + l_1 = v*t1; + + p *= Nq*l_full*my_s_n*exp(-(my_a_v/v+my_s)*(l+l_1))/(1-frac); + /* printf("Powder p: %g , exp: %g\n",p,exp(-(my_a_v/v+my_s)*(l+l_1)));*/ + } /* Coherent scattering event */ + else + { /* Make incoherent scattering event */ + v = sqrt(vx*vx+vy*vy+vz*vz); + if(focus_aw && focus_ah) { + randvec_target_rect_angular(&vx, &vy, &vz, &solid_angle, + aim_x, aim_y, aim_z, focus_aw*DEG2RAD, focus_ah*DEG2RAD, ROT_A_CURRENT_COMP); + } else if(focus_xw && focus_yh) { + randvec_target_rect(&vx, &vy, &vz, &solid_angle, + aim_x, aim_y, aim_z, focus_xw, focus_yh, ROT_A_CURRENT_COMP); + } else { + randvec_target_sphere(&vx, &vy, &vz, &solid_angle, aim_x, aim_y, aim_z, focus_r); + } + v1 = sqrt(vx*vx+vy*vy+vz*vz); + vx *= v/v1; + vy *= v/v1; + vz *= v/v1; + if(!cylinder_intersect(&t0, &t1, x, y, z, + vx, vy, vz, radius, h)) + { + /* Strange error: did not hit cylinder */ + printf("FATAL ERROR: Did not hit cylinder from inside.\n"); + exit(1); + } + l_1 = v*t1; + + p_in=p; + p *= l_full*my_inc*exp(-(my_a_v/v+my_s)*(l+l_1))/(frac); + p *= solid_angle/(4*PI); + /* printf("Incoherent p_in: %g arg: %g l_1: %g t0: %g t1: %g p: %g \n", + p_in,(my_a_v/v+my_s)*(l+l_1),l_1,t0,t1,p); */ + } /* Incoherent scattering event */ + } + else + ABSORB; +} +#line 7837 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef q_v +#undef my_a_v +#undef my_s_v2 +#undef reflections +#undef mccompcurname +#undef mccompcurindex +#undef p +#undef s2 +#undef s1 +#undef t +#undef vz +#undef vy +#undef vx +#undef z +#undef y +#undef x + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + + /* Component Det9. */ + strcpy(mcsig_message, "Det9 (Trace)"); + mcDEBUG_COMP("Det9") + mccoordschange(mcposrDet9, mcrotrDet9, + &mcnlx, &mcnly, &mcnlz, + &mcnlvx, &mcnlvy, &mcnlvz, + &mcnlt, &mcnlsx, &mcnlsy); + mccoordschange_polarisation(mcrotrDet9, &mcnlsx, &mcnlsy, &mcnlsz); + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) +#define x mcnlx +#define y mcnly +#define z mcnlz +#define vx mcnlvx +#define vy mcnlvy +#define vz mcnlvz +#define t mcnlt +#define s1 mcnlsx +#define s2 mcnlsy +#define p mcnlp +#define sx mcnlsx +#define sy mcnlsy +#define sz mcnlsz + STORE_NEUTRON(7,mcnlx, mcnly, mcnlz, mcnlvx,mcnlvy,mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlsz, mcnlp); + mcScattered=0; +#define mccompcurname Det9 +#define mccompcurindex 7 +#define options mccDet9_options +#define filename mccDet9_filename +#define DEFS mccDet9_DEFS +#define Vars mccDet9_Vars +{ /* Declarations of SETTING parameters. */ +MCNUM xwidth = mccDet9_xwidth; +MCNUM yheight = mccDet9_yheight; +MCNUM zthick = mccDet9_zthick; +MCNUM xmin = mccDet9_xmin; +MCNUM xmax = mccDet9_xmax; +MCNUM ymin = mccDet9_ymin; +MCNUM ymax = mccDet9_ymax; +MCNUM zmin = mccDet9_zmin; +MCNUM zmax = mccDet9_zmax; +#line 235 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/monitors/Monitor_nD.comp" +{ + double XY=0; + double t0 = 0; + double t1 = 0; + double pp; + int intersect = 0; + char Flag_Restore = 0; + + if (abs(Vars.Flag_Shape) == DEFS.SHAPE_SQUARE) /* square xy */ + { + PROP_Z0; + intersect = (x>=Vars.mxmin && x<=Vars.mxmax && y>=Vars.mymin && y<=Vars.mymax); + } + else if (abs(Vars.Flag_Shape) == DEFS.SHAPE_DISK) /* disk xy */ + { + PROP_Z0; + intersect = ((x*x + y*y) <= Vars.Sphere_Radius*Vars.Sphere_Radius); + } + else if (abs(Vars.Flag_Shape) == DEFS.SHAPE_SPHERE) /* sphere */ + { + intersect = sphere_intersect(&t0, &t1, x, y, z, vx, vy, vz, Vars.Sphere_Radius); + /* intersect = (intersect && t0 > 0); */ + } + else if ((abs(Vars.Flag_Shape) == DEFS.SHAPE_CYLIND) || (abs(Vars.Flag_Shape) == DEFS.SHAPE_BANANA)) /* cylinder */ + { + intersect = cylinder_intersect(&t0, &t1, x, y, z, vx, vy, vz, Vars.Sphere_Radius, Vars.Cylinder_Height); + if ((abs(Vars.Flag_Shape) == DEFS.SHAPE_BANANA) && (intersect != 1)) intersect = 0; /* remove top/bottom for banana */ + } + else if (abs(Vars.Flag_Shape) == DEFS.SHAPE_BOX) /* box */ + { + intersect = box_intersect(&t0, &t1, x, y, z, vx, vy, vz, fabs(Vars.mxmax-Vars.mxmin), fabs(Vars.mymax-Vars.mymin), fabs(Vars.mzmax-Vars.mzmin)); + } + + if (intersect) + { + if ((abs(Vars.Flag_Shape) == DEFS.SHAPE_SPHERE) || (abs(Vars.Flag_Shape) == DEFS.SHAPE_CYLIND) || (abs(Vars.Flag_Shape) == DEFS.SHAPE_BOX) || (abs(Vars.Flag_Shape) == DEFS.SHAPE_BANANA)) + { + if (t0 < 0 && t1 > 0) + t0 = t; /* neutron was already inside ! */ + if (t1 < 0 && t0 > 0) /* neutron exit before entering !! */ + t1 = t; + /* t0 is now time of incoming intersection with the sphere. */ + if ((Vars.Flag_Shape < 0) && (t1 > 0)) + PROP_DT(t1); /* t1 outgoing beam */ + else + PROP_DT(t0); /* t0 incoming beam */ + } + + /* Now get the data to monitor: current or keep from PreMonitor */ + if (Vars.Flag_UsePreMonitor != 1) + { + Vars.cp = p; + Vars.cx = x; + Vars.cvx = vx; + Vars.csx = sx; + Vars.cy = y; + Vars.cvy = vy; + Vars.csy = sy; + Vars.cz = z; + Vars.cvz = vz; + Vars.csz = sz; + Vars.ct = t; + } + + if ((Vars.He3_pressure > 0) && (t1 != t0) && ((abs(Vars.Flag_Shape) == DEFS.SHAPE_SPHERE) || (abs(Vars.Flag_Shape) == DEFS.SHAPE_CYLIND) || (abs(Vars.Flag_Shape) == DEFS.SHAPE_BOX))) + { + XY = exp(-7.417*Vars.He3_pressure*fabs(t1-t0)*2*PI*K2V); + /* will monitor the absorbed part */ + Vars.cp *= 1-XY; + /* and modify the neutron weight after monitor, only remains 1-p_detect */ + p *= XY; + } + + if (Vars.Flag_per_cm2 && Vars.area != 0) Vars.cp /= Vars.area; + if (Vars.Flag_capture) + { + XY = sqrt(Vars.cvx*Vars.cvx+Vars.cvy*Vars.cvy+Vars.cvz*Vars.cvz); + XY *= V2K; + if (XY != 0) XY = 2*PI/XY; /* lambda. lambda(2200 m/2) = 1.7985 Angs */ + Vars.cp *= XY/1.7985; + } + + pp = Monitor_nD_Trace(&DEFS, &Vars); + Vars.Nsum++; + Vars.psum += pp; + Vars.p2sum += pp*pp; + SCATTER; + + /* now handles intermediate results saving */ + if ((Vars.Intermediate > 0) && (mcget_run_num() > Vars.IntermediateCnts)) + { + Vars.IntermediateCnts += Vars.Intermediate*mcget_ncount(); + /* save results for all monitors in the simulation */ + mcsave(NULL); + } + if (Vars.Flag_parallel) /* back to neutron state before detection */ + Flag_Restore = 1; + } /* end if intersection */ + else { + if (Vars.Flag_Absorb && !Vars.Flag_parallel) ABSORB; + else Flag_Restore = 1; /* no intersection, back to previous state */ + } + + if (Flag_Restore) + { + RESTORE_NEUTRON(mccompcurindex, x, y, z, vx, vy, vz, t, sx, sy, sz, p); + } +} +#line 8006 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Vars +#undef DEFS +#undef filename +#undef options +#undef mccompcurname +#undef mccompcurindex +#undef sz +#undef sy +#undef sx +#undef p +#undef s2 +#undef s1 +#undef t +#undef vz +#undef vy +#undef vx +#undef z +#undef y +#undef x + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + + mcabsorbAll: + mcDEBUG_LEAVE() + mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp) + /* Copy neutron state to global variables. */ + mcnx = mcnlx; + mcny = mcnly; + mcnz = mcnlz; + mcnvx = mcnlvx; + mcnvy = mcnlvy; + mcnvz = mcnlvz; + mcnt = mcnlt; + mcnsx = mcnlsx; + mcnsy = mcnlsy; + mcnsz = mcnlsz; + mcnp = mcnlp; +} + +void mcsave(FILE *handle) { + if (!handle) mcsiminfo_init(NULL); + /* User component SAVE code. */ + + /* User SAVE code for component 'PSD_sample'. */ + strcpy(mcsig_message, "PSD_sample (Save)"); +#define mccompcurname PSD_sample +#define mccompcurindex 4 +#define Nsum mccPSD_sample_Nsum +#define psum mccPSD_sample_psum +#define p2sum mccPSD_sample_p2sum +#define currentCount mccPSD_sample_currentCount +{ /* Declarations of SETTING parameters. */ +MCNUM xmin = mccPSD_sample_xmin; +MCNUM xmax = mccPSD_sample_xmax; +MCNUM ymin = mccPSD_sample_ymin; +MCNUM ymax = mccPSD_sample_ymax; +char* controlfile = mccPSD_sample_controlfile; +int dumpCount = mccPSD_sample_dumpCount; +#line 95 "MKMonitor.comp" +{ + DETECTOR_OUT_0D("Single monitor", Nsum, psum, p2sum); +} +#line 8069 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef currentCount +#undef p2sum +#undef psum +#undef Nsum +#undef mccompcurname +#undef mccompcurindex + + /* User SAVE code for component 'Det9'. */ + strcpy(mcsig_message, "Det9 (Save)"); +#define mccompcurname Det9 +#define mccompcurindex 7 +#define options mccDet9_options +#define filename mccDet9_filename +#define DEFS mccDet9_DEFS +#define Vars mccDet9_Vars +{ /* Declarations of SETTING parameters. */ +MCNUM xwidth = mccDet9_xwidth; +MCNUM yheight = mccDet9_yheight; +MCNUM zthick = mccDet9_zthick; +MCNUM xmin = mccDet9_xmin; +MCNUM xmax = mccDet9_xmax; +MCNUM ymin = mccDet9_ymin; +MCNUM ymax = mccDet9_ymax; +MCNUM zmin = mccDet9_zmin; +MCNUM zmax = mccDet9_zmax; +#line 345 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/monitors/Monitor_nD.comp" +{ + /* save results, but do not free pointers */ + Monitor_nD_Save(&DEFS, &Vars); +} +#line 8101 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Vars +#undef DEFS +#undef filename +#undef options +#undef mccompcurname +#undef mccompcurindex + + if (!handle) mcsiminfo_close(); +} +void mcfinally(void) { + /* User component FINALLY code. */ + mcsiminfo_init(NULL); + mcsave(mcsiminfo_file); /* save data when simulation ends */ + + /* User FINALLY code for component 'in'. */ + strcpy(mcsig_message, "in (Finally)"); +#define mccompcurname in +#define mccompcurindex 2 +#define file mccin_file +#define type mccin_type +#define rep mccin_rep +#define pos mccin_pos +#define nrows mccin_nrows +#define nread mccin_nread +#define Offset mccin_Offset +#define rTable mccin_rTable +#define Virtual_input_Read_Input mccin_Virtual_input_Read_Input +{ /* Declarations of SETTING parameters. */ +MCNUM repeat_count = mccin_repeat_count; +MCNUM bufsize = mccin_bufsize; +#line 154 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/sources/Virtual_input.comp" +{ + Table_Free(&rTable); +} +#line 8137 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Virtual_input_Read_Input +#undef rTable +#undef Offset +#undef nread +#undef nrows +#undef pos +#undef rep +#undef type +#undef file +#undef mccompcurname +#undef mccompcurindex + + /* User FINALLY code for component 'Det9'. */ + strcpy(mcsig_message, "Det9 (Finally)"); +#define mccompcurname Det9 +#define mccompcurindex 7 +#define options mccDet9_options +#define filename mccDet9_filename +#define DEFS mccDet9_DEFS +#define Vars mccDet9_Vars +{ /* Declarations of SETTING parameters. */ +MCNUM xwidth = mccDet9_xwidth; +MCNUM yheight = mccDet9_yheight; +MCNUM zthick = mccDet9_zthick; +MCNUM xmin = mccDet9_xmin; +MCNUM xmax = mccDet9_xmax; +MCNUM ymin = mccDet9_ymin; +MCNUM ymax = mccDet9_ymax; +MCNUM zmin = mccDet9_zmin; +MCNUM zmax = mccDet9_zmax; +#line 351 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/monitors/Monitor_nD.comp" +{ + /* free pointers */ + Monitor_nD_Finally(&DEFS, &Vars); +} +#line 8174 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Vars +#undef DEFS +#undef filename +#undef options +#undef mccompcurname +#undef mccompcurindex + + mcsiminfo_close(); +} +#define magnify mcdis_magnify +#define line mcdis_line +#define multiline mcdis_multiline +#define circle mcdis_circle +void mcdisplay(void) { + printf("MCDISPLAY: start\n"); + /* Component MCDISPLAY code. */ + + /* MCDISPLAY code for component 'msa'. */ + strcpy(mcsig_message, "msa (McDisplay)"); + printf("MCDISPLAY: component %s\n", "msa"); +#define mccompcurname msa +#define mccompcurindex 1 +#line 42 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/optics/Arm.comp" +{ + /* A bit ugly; hard-coded dimensions. */ + magnify(""); + line(0,0,0,0.2,0,0); + line(0,0,0,0,0.2,0); + line(0,0,0,0,0,0.2); +} +#line 8206 "dmcafter.c" +#undef mccompcurname +#undef mccompcurindex + + /* MCDISPLAY code for component 'in'. */ + strcpy(mcsig_message, "in (McDisplay)"); + printf("MCDISPLAY: component %s\n", "in"); +#define mccompcurname in +#define mccompcurindex 2 +#define file mccin_file +#define type mccin_type +#define rep mccin_rep +#define pos mccin_pos +#define nrows mccin_nrows +#define nread mccin_nread +#define Offset mccin_Offset +#define rTable mccin_rTable +#define Virtual_input_Read_Input mccin_Virtual_input_Read_Input +{ /* Declarations of SETTING parameters. */ +MCNUM repeat_count = mccin_repeat_count; +MCNUM bufsize = mccin_bufsize; +#line 159 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/sources/Virtual_input.comp" +{ + /* A bit ugly; hard-coded dimensions. */ + magnify(""); + line(0,0,0,0.1,0,0); + line(0,0,0,0,0.1,0); + line(0,0,0,0,0,0.1); +} +#line 8235 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Virtual_input_Read_Input +#undef rTable +#undef Offset +#undef nread +#undef nrows +#undef pos +#undef rep +#undef type +#undef file +#undef mccompcurname +#undef mccompcurindex + + /* MCDISPLAY code for component 'out2_slit'. */ + strcpy(mcsig_message, "out2_slit (McDisplay)"); + printf("MCDISPLAY: component %s\n", "out2_slit"); +#define mccompcurname out2_slit +#define mccompcurindex 3 +{ /* Declarations of SETTING parameters. */ +MCNUM xmin = mccout2_slit_xmin; +MCNUM xmax = mccout2_slit_xmax; +MCNUM ymin = mccout2_slit_ymin; +MCNUM ymax = mccout2_slit_ymax; +MCNUM radius = mccout2_slit_radius; +#line 63 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/optics/Slit.comp" +{ + double xw, yh; + magnify("xy"); + xw = (xmax - xmin)/2.0; + yh = (ymax - ymin)/2.0; + multiline(3, xmin-xw, (double)ymax, 0.0, + (double)xmin, (double)ymax, 0.0, + (double)xmin, ymax+yh, 0.0); + multiline(3, xmax+xw, (double)ymax, 0.0, + (double)xmax, (double)ymax, 0.0, + (double)xmax, ymax+yh, 0.0); + multiline(3, xmin-xw, (double)ymin, 0.0, + (double)xmin, (double)ymin, 0.0, + (double)xmin, ymin-yh, 0.0); + multiline(3, xmax+xw, (double)ymin, 0.0, + (double)xmax, (double)ymin, 0.0, + (double)xmax, ymin-yh, 0.0); +} +#line 8279 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef mccompcurname +#undef mccompcurindex + + /* MCDISPLAY code for component 'PSD_sample'. */ + strcpy(mcsig_message, "PSD_sample (McDisplay)"); + printf("MCDISPLAY: component %s\n", "PSD_sample"); +#define mccompcurname PSD_sample +#define mccompcurindex 4 +#define Nsum mccPSD_sample_Nsum +#define psum mccPSD_sample_psum +#define p2sum mccPSD_sample_p2sum +#define currentCount mccPSD_sample_currentCount +{ /* Declarations of SETTING parameters. */ +MCNUM xmin = mccPSD_sample_xmin; +MCNUM xmax = mccPSD_sample_xmax; +MCNUM ymin = mccPSD_sample_ymin; +MCNUM ymax = mccPSD_sample_ymax; +char* controlfile = mccPSD_sample_controlfile; +int dumpCount = mccPSD_sample_dumpCount; +#line 100 "MKMonitor.comp" +{ + 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); +} +#line 8309 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef currentCount +#undef p2sum +#undef psum +#undef Nsum +#undef mccompcurname +#undef mccompcurindex + + /* MCDISPLAY code for component 'sa_arm'. */ + strcpy(mcsig_message, "sa_arm (McDisplay)"); + printf("MCDISPLAY: component %s\n", "sa_arm"); +#define mccompcurname sa_arm +#define mccompcurindex 5 +#line 42 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/optics/Arm.comp" +{ + /* A bit ugly; hard-coded dimensions. */ + magnify(""); + line(0,0,0,0.2,0,0); + line(0,0,0,0,0.2,0); + line(0,0,0,0,0,0.2); +} +#line 8331 "dmcafter.c" +#undef mccompcurname +#undef mccompcurindex + + /* MCDISPLAY code for component 'sample'. */ + strcpy(mcsig_message, "sample (McDisplay)"); + printf("MCDISPLAY: component %s\n", "sample"); +#define mccompcurname sample +#define mccompcurindex 6 +#define reflections mccsample_reflections +#define my_s_v2 mccsample_my_s_v2 +#define my_a_v mccsample_my_a_v +#define q_v mccsample_q_v +{ /* Declarations of SETTING parameters. */ +MCNUM d_phi0 = mccsample_d_phi0; +MCNUM radius = mccsample_radius; +MCNUM focus_r = mccsample_focus_r; +MCNUM h = mccsample_h; +MCNUM pack = mccsample_pack; +MCNUM Vc = mccsample_Vc; +MCNUM sigma_a = mccsample_sigma_a; +MCNUM sigma_inc = mccsample_sigma_inc; +MCNUM frac = mccsample_frac; +MCNUM focus_xw = mccsample_focus_xw; +MCNUM focus_yh = mccsample_focus_yh; +MCNUM focus_aw = mccsample_focus_aw; +MCNUM focus_ah = mccsample_focus_ah; +MCNUM target_x = mccsample_target_x; +MCNUM target_y = mccsample_target_y; +MCNUM target_z = mccsample_target_z; +int target_index = mccsample_target_index; +#line 273 "PowderN.comp" +{ + magnify("xyz"); + circle("xz", 0, h/2.0, 0, radius); + circle("xz", 0, -h/2.0, 0, radius); + line(-radius, -h/2.0, 0, -radius, +h/2.0, 0); + line(+radius, -h/2.0, 0, +radius, +h/2.0, 0); + line(0, -h/2.0, -radius, 0, +h/2.0, -radius); + line(0, -h/2.0, +radius, 0, +h/2.0, +radius); +} +#line 8372 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef q_v +#undef my_a_v +#undef my_s_v2 +#undef reflections +#undef mccompcurname +#undef mccompcurindex + + /* MCDISPLAY code for component 'Det9'. */ + strcpy(mcsig_message, "Det9 (McDisplay)"); + printf("MCDISPLAY: component %s\n", "Det9"); +#define mccompcurname Det9 +#define mccompcurindex 7 +#define options mccDet9_options +#define filename mccDet9_filename +#define DEFS mccDet9_DEFS +#define Vars mccDet9_Vars +{ /* Declarations of SETTING parameters. */ +MCNUM xwidth = mccDet9_xwidth; +MCNUM yheight = mccDet9_yheight; +MCNUM zthick = mccDet9_zthick; +MCNUM xmin = mccDet9_xmin; +MCNUM xmax = mccDet9_xmax; +MCNUM ymin = mccDet9_ymin; +MCNUM ymax = mccDet9_ymax; +MCNUM zmin = mccDet9_zmin; +MCNUM zmax = mccDet9_zmax; +#line 357 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/monitors/Monitor_nD.comp" +{ + Monitor_nD_McDisplay(&DEFS, &Vars); +} +#line 8404 "dmcafter.c" +} /* End of SETTING parameter declarations. */ +#undef Vars +#undef DEFS +#undef filename +#undef options +#undef mccompcurname +#undef mccompcurindex + + printf("MCDISPLAY: end\n"); +} +#undef magnify +#undef line +#undef multiline +#undef circle diff --git a/mcstas/dmc/vdmc.tcl b/mcstas/dmc/vdmc.tcl index ea8e78dc..8eebf1cb 100644 --- a/mcstas/dmc/vdmc.tcl +++ b/mcstas/dmc/vdmc.tcl @@ -6,13 +6,13 @@ #--------------------------------------------------------------------------- # O P T I O N S # wwwMode = 1 when running for the WWW-VDMC application -set wwwMode 1 +set wwwMode 0 if {$wwwMode == 1} { set home /home/lnswww/vinstrument/mcstas/dmc set datahome /home/lnswww/www/vinstrument } else { - set home $env(HOME)/src/workspace/sics/mcstas/dmc + set home $env(HOME)/psi/workspace/sics/mcstas/dmc } #--------------------------------- first all the server options are set #ServerOption RedirectFile $home/stdcdmc @@ -147,7 +147,6 @@ commandlog auto commandlog intervall 5 #----------- enable sycamore -#InstallProtocolHandler #InstallSinfox #source sycFormat.tcl #source /usr/lib/tcllib1.6.1/stooop/stooop.tcl @@ -155,3 +154,95 @@ commandlog intervall 5 #source sinfo.tcl #source sycamore.tcl #Publish sinfo Spy + +#==================== install Hipadaba +proc hdbReadOnly {} { + error "Parameter is READ ONLY" +} +#------------------------------------ +proc maketwotheta {} { + set txt [TwoThetaD] + set l [split $txt =] + set start [string trim [lindex $l 1]] + for {set i 0} {$i < 400} {incr i } { + append result [expr $start + $i * .2] " " + } + return $result +} +#------------------------------------- +InstallProtocolHandler +InstallHdb +MakeStateMon +hmake /dmc spy none +hsetprop /dmc type instrument +#-------- experiment +hmake /dmc/experiment spy none +hattach /dmc/experiment title title +hattach /dmc/experiment user user +hattach /dmc/experiment starttime starttime +hattach /dmc/experiment user user +hattach /dmc/experiment/user adress address +hattach /dmc/experiment/user phone phone +hattach /dmc/experiment/user email email +hattach /dmc/experiment comment1 comment1 +hattach /dmc/experiment comment2 comment2 +hattach /dmc/experiment comment3 comment3 +#------- SINQ +hmake /dmc/sinq spy none +hmakescript /dmc/sinq/proton_monitor "counter getmonitor 4" hdbReadOnly int +sicspoll /dmc/sinq/proton_monitor hdb 10 +#-------- monochromator +hmake /dmc/monochromator spy none +hattach /dmc/monochromator lambda wavelength +hattach /dmc/monochromator OmegaM theta +hattach /dmc/monochromator TwoThetaM two_theta +hattach /dmc/monochromator MonoX x_translation +hattach /dmc/monochromator MonoY y_translation +hattach /dmc/monochromator MonoChi chi +hattach /dmc/monochromator MonoPhi phi +hattach /dmc/monochromator CurveM vertical_focusing +hmakescript /dmc/monochromator/d_value "mono dd" "mono dd" float +hsetprop /dmc/monochromator/d_value priv manager +hmakescript /dmc/monochromator/scattering_sense "mono ss" "mono ss" int +hsetprop /dmc/monochromator/scattering_sense priv manager + +#----------- sample +hmake /dmc/sample spy none +hmakescript /dmc/sample/name sample sample Text +hattach /dmc/sample Table rotation +hmakescript /dmc/sample/monitor "counter getmonitor 1" hdbReadOnly int +hsetprop /dmc/sample/monitor priv internal +#---------- detector +hmake /dmc/detector spy none +hattach /dmc/detector TwoThetaD two_theta +hmakescript /dmc/detector/preset "counter getpreset" hdbReadOnly float +hsetprop /dmc/detector/preset priv internal +hmakescript /dmc/detector/countmode "counter getmode" hdbReadOnly text +hsetprop /dmc/detector/countmode priv internal +sicspoll add /dmc/detector/preset hdb 30 +sicspoll add /dmc/detector/countmode hdb 30 +#------------ commands +hmake /commands spy none +hcommand /commands/count count +hsetprop /commands/count type command +hmake /commands/count/mode user text +hmake /commands/count/preset user float +hset /commands/count/preset 5 +hset /commands/count/mode timer +#---------------- graphics +hmake /Graphics spy none +hmake /Graphics/powder_diagram spy none +hsetprop /Graphics/powder_diagram type graphdata +hsetprop /Graphics/powder_diagram viewer default +hmake /Graphics/powder_diagram/rank internal int +hset /Graphics/powder_diagram/rank 1 +hmake /Graphics/powder_diagram/dim internal intar 1 +hset /Graphics/powder_diagram/dim 400 +hmakescript /Graphics/powder_diagram/two_theta maketwotheta hdbReadOnly floatar 400 +sicspoll add /Graphics/powder_diagram/two_theta hdb 30 +hsetprop /Graphics/powder_diagram/two_theta type axis +hsetprop /Graphics/powder_diagram/two_theta dim 0 +hattach /Graphics/powder_diagram banana counts +hsetprop /Graphics/powder_diagram/counts type data +hsetprop /Graphics/powder_diagram/counts priv internal +sicspoll add /Graphics/powder_diagram/counts hdb 60 diff --git a/mcstas/dmc/vdmccom.tcl b/mcstas/dmc/vdmccom.tcl index 8cf451c3..a78a78f1 100644 --- a/mcstas/dmc/vdmccom.tcl +++ b/mcstas/dmc/vdmccom.tcl @@ -164,6 +164,7 @@ proc rundmcoptsim {mode preset } { } else { return $msg } + wait 5 } #------------------------------------------------------------------------ proc copydmcdataold { } { diff --git a/ofac.c b/ofac.c index 47f1eef9..6e7ba8d6 100644 --- a/ofac.c +++ b/ofac.c @@ -6,7 +6,7 @@ - Mark Koennecke, November 1996 -- ???? + Mark Koennecke, November 1996 -- ???? heavy modifications to separate PSI specific commands into a separate library. Mark Koennecke, June 2003 @@ -121,6 +121,7 @@ #include "sicshipadaba.h" #include "multicounter.h" #include "sicspoll.h" +#include "statemon.h" /*----------------------- Server options creation -------------------------*/ static int IFServerOption(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]) @@ -276,7 +277,8 @@ AddCommand(pInter,"MakeEnergy",MakeEnergyVar,NULL,NULL); AddCommand(pInter,"MakeCounter",MakeCounter,NULL,NULL); AddCommand(pInter,"MakeO2T",CreateO2T,NULL,NULL); - AddCommand(pInter,"SicsAlias",SicsAlias,NULL,NULL); + AddCommand(pInter,"SicsAlias",SicsAlias,NULL,NULL); + AddCommand(pInter,"SicsAlias",DefineAlias,NULL,NULL); AddCommand(pInter,"DefineAlias",DefineAlias,NULL,NULL); /* M.Z. */ AddCommand(pInter,"MakeHM",MakeHistMemory,NULL,NULL); AddCommand(pInter,"VelocitySelector",VelSelFactory,NULL,NULL); @@ -335,6 +337,8 @@ MakeMultiCounter,NULL,NULL); AddCommand(pInter,"MakeSicsPoll", InstallSICSPoll,NULL,NULL); + AddCommand(pInter,"MakeStateMon", + StateMonFactory,NULL,NULL); /* install site specific commands @@ -404,6 +408,7 @@ RemoveCommand(pSics,"InstallSinfox"); RemoveCommand(pSics,"MakeCone"); RemoveCommand(pSics,"MakeMultiCounter"); + RemoveCommand(pSics,"MakeStateMon"); /* remove site specific installation commands */ diff --git a/sicshdbadapter.c b/sicshdbadapter.c index 4de4e94f..44470917 100644 --- a/sicshdbadapter.c +++ b/sicshdbadapter.c @@ -244,7 +244,8 @@ static pHdb CreateMotorAdapter(char *name, pMotor pMot){ } MotorGetPar(pMot,"accesscode",&access); AddPrivProperty(result,(int)access); - SetHdbProperty(result,"type","Motor"); + SetHdbProperty(result,"type","drivable"); + SetHdbProperty(result,"sicsdev",pMot->name); /* * We want to be notified when this motor drives around. Or * its parameters change. @@ -273,7 +274,10 @@ static pHdb CreateMotorAdapter(char *name, pMotor pMot){ static long totalSum(int *data, int length){ long result = 0l; int i; - + + if(data == NULL){ + return 0; + } for(i = 0; i < length; i++){ result += data[i]; } @@ -389,7 +393,11 @@ static pHdb MakeSicsVarNode(pSicsVariable pVar, char *name){ if(node == NULL){ return NULL; } - AddPrivProperty(node,pVar->iAccessCode); + if(pVar->iLock == 1) { + AddPrivProperty(node,usInternal); + } else { + AddPrivProperty(node,pVar->iAccessCode); + } pCall = MakeHipadabaCallback(SicsVarSetCallback,pVar,NULL,-1,-1); if(pCall == NULL){ return NULL; @@ -460,6 +468,7 @@ int SICSHdbAdapter(SConnection *pCon, SicsInterp *pSics, void *pData, } SetHdbProperty(node,PRIVNAM,"user"); SetHdbProperty(node,"type","drivable"); + SetHdbProperty(node,"sicsdev",argv[2]); AddHipadabaChild(path,node,pCon); SCSendOK(pCon); return 1;