Files
sics/mcstas/dmc/dmcafter.c
2012-11-26 11:33:14 +11:00

8437 lines
297 KiB
C
Raw Permalink Blame History

/* Automatically generated file. Do not edit.
* Format: ANSI C source code
* Creator: McStas <http://neutron.risoe.dk>
* 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$
*
* $Log$
* 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$"
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/* 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 <signal.h>
#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$
*
* $Log$
* 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
* <instr> -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 <stdarg.h>
#include <limits.h>
#include <errno.h>
#include <time.h>
#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,'`!\"<EFBFBD>^&*()-+=|\\,.<>/?@''~#{[}]',/extract),'_')\n"
"d.ylabel=strjoin(strsplit(d.ylabel,'`!\"<EFBFBD>^&*()-+=|\\,.<>/?@''~#{[}]',/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",
"<?xml version=\"1.0\" ?>\n<!--\n"
"URL: http://www.neutron.anl.gov/nexus/xml/NXgroup.xml\n"
"Editor: %6$s\n"
"Creator:%2$s McStas " MCSTAS_VERSION " [neutron.risoe.dk].\n"
"Date: Simulation started (%8$li) %5$s\n"
"File: %3$s\n-->\n"
"<NX%7$s file_name=\"%3$s\" file_time=\"%5$s\" user=\"%6$s\">\n"
"<NXentry name=\"McStas " MCSTAS_VERSION "\"><start_time>%5$s</start_time>\n",
"<end_time>%5$s</end_time></NXentry></NX%7$s>\n<!-- EndDate:%5$s -->\n",
"%1$s<NX%2$s name=\"%3$s\">\n",
"%1$s</NX%2$s>\n",
"%1$s<%3$s>%4$s</%3$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\"></%6$s>\n"
"%1$s<%8$s long_name=\"%7$s\" axis=\"2\" primary=\"1\" min=\"%19$g\""
" max=\"%20$g\" dims=\"%15$d\" range=\"1\"></%8$s>\n"
"%1$s<%10$s long_name=\"%9$s\" axis=\"3\" primary=\"1\" min=\"%21$g\""
" max=\"%22$g\" dims=\"%16$d\" range=\"1\"></%10$s>\n"
"%1$s<data long_name=\"%3$s\" signal=\"1\" axis=\"[%6$s,%8$s,%10$s]\" file_name=\"%4$s\">",
"%1$s<errors>", "%1$s<monitor>",
"%1$s</data>\n", "%1$s</errors>\n", "%1$s</monitor>\n"},
{ "HTML", "html",
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD %5$s//EN\"\n"
"\"http://www.w3.org/TR/html4/strict.dtd\">\n"
"<HTML><HEAD><META name=\"Author\" content=\"%7$s\">\n"
"<META name=\"Creator\" content=\"%2$s McStas " MCSTAS_VERSION " [neutron.risoe.dk] simulation\">\n"
"<META name=\"Date\" content=\"%5$s\">\n"
"<TITLE>[McStas %2$s]%3$s</TITLE></HEAD>\n"
"<BODY><h1><a name=\"%7$s\">"
"McStas simulation %2$s: %3$s</a></h1><br>\n"
"This simulation report was automatically created by"
" <a href=\"http://neutron.risoe.dk/\"><i>McStas " MCSTAS_VERSION "</i></a><br>\n"
"<pre>User: %6$s<br>\n"
"%1$sCreator: <a href=\"%2$s\">%2$s</a> McStas simulation<br>\n"
"%1$sDate: (%8$li) %5$s<br></pre>\n",
"<b>EndDate: </b>(%8$li) %5$s<br></BODY></HTML>\n",
"%1$s<h%7$d><a name=\"%3$s\">%2$s %3$s</a></h%7$d> "
"[child of <a href=\"#%5$s\">%5$s</a>]<br>\n"
"%1$sAssociated <a href=\"%3$s\">data file %3$s</a><br>\n"
"%1$sAssociated <a href=\"%3$s.png\">%2$s image %3$s.png<br> (when available)\n"
"%1$s<img src=\"%3$s.png\" alt=\"%2$s %3$s image\" width=100></a><br>\n",
"[end of <a href=\"#%3$s\">%2$s %3$s</a>]<br>\n",
"%1$s<b>%3$s: </b>%4$s<br>\n",
"%1$s<b>DATA</b><br>\n",
"%1$s<b>ERRORS</b><br>\n","%1$s<b>EVENTS</b><br>\n",
"%1$sEnd of DATA<br>\n", "%1$sEnd of ERRORS<br>\n", "%1$sEnd of EVENTS<br>\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 <stdio.h>
/* 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<N; mti++) {
mt[mti] =
(1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 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<N-M;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL];
}
for (;kk<N-1;kk++) {
y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK);
mt[kk] = mt[kk+(M-N)] ^ (y >> 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; arg_num[this_arg++] =0); this_arg = 0;
fmt_pos = fmt;
while(1) /* analyse the format string 'fmt' */
{
char *tmp;
arg_posB[this_arg] = (char *)strchr(fmt_pos, '%');
tmp = arg_posB[this_arg];
if (tmp)
{
arg_posE[this_arg] = (char *)strchr(tmp, '$');
if (arg_posE[this_arg] && tmp[1] != '%')
{
char this_arg_chr[10];
char printf_formats[]="dliouxXeEfgGcs\0";
/* extract positional argument index %*$ in fmt */
strncpy(this_arg_chr, arg_posB[this_arg]+1, arg_posE[this_arg]-arg_posB[this_arg]-1);
this_arg_chr[arg_posE[this_arg]-arg_posB[this_arg]-1] = '\0';
arg_num[this_arg] = atoi(this_arg_chr);
if (arg_num[this_arg] <=0 || arg_num[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_arg<strlen(fmt_args); this_arg++)
{
switch(fmt_args[this_arg])
{
case 's': /* string */
arg_char[this_arg] = va_arg(ap, char *);
break;
case 'd':
case 'i':
case 'c': /* int */
arg_int[this_arg] = va_arg(ap, int);
break;
case 'l': /* int */
arg_long[this_arg] = va_arg(ap, long int);
break;
case 'f':
case 'g':
case 'G': /* double */
arg_double[this_arg] = va_arg(ap, double);
break;
default: fprintf(stderr,"pfprintf: argument type is not implemented (arg %%%i$ type %c).\n", this_arg+1, fmt_args[this_arg]);
}
}
va_end(ap);
/* split fmt string into bits containing only 1 argument */
fmt_pos = fmt;
for (this_arg=0; this_arg<arg_max; this_arg++)
{
char *fmt_bit;
int arg_n;
if (arg_posB[this_arg]-fmt_pos>0)
{
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<m*n*p; i++)
{ if (isdata != 2) s[i] = (float)d[i];
else s[i] = (float)mcestimate_error(p0[i],p1[i],p2[i]); }
count = fwrite(s, sizeof(float), m*n*p, datafile);
if (count != m*n*p) fprintf(stderr, "McStas: error writing float binary file '%s' (%li instead of %li).\n", filename,count, (long)m*n*p);
free(s);
} else fprintf(stderr, "McStas: Out of memory for writing float binary file '%s'.\n", filename);
}
else if (d && isBinary == 2) /* double */
{
long count;
double *s=NULL;
if (isdata == 2)
{
s = (double*)malloc(m*n*p*sizeof(double));
if (s) { long i;
for (i=0; i<m*n*p; i++)
s[i] = (double)mcestimate_error(p0[i],p1[i],p2[i]);
d = s;
}
else fprintf(stderr, "McStas: Out of memory for writing 'errors' part of double binary file '%s'.\n", filename);
}
count = fwrite(d, sizeof(double), m*n*p, datafile);
if (isdata == 2 && s) free(s);
if (count != m*n*p) fprintf(stderr, "McStas: error writing double binary file '%s' (%li instead of %li).\n", filename,count, (long)m*n*p);
}
} /* end if Binary */
}
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 end: end_data */
if (strlen(End) && just_header != 1 && f)
{
pfprintf(f, End, "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 and datafile:
* datablock part+footer
* write file footer
* close datafile
*/
if (!mcsingle_file && just_header == 0)
{
char mode[32];
if (datafile && datafile != f && !mcascii_only)
{
sprintf(mode, "%s end", part);
/* write header+data block end 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);
if ((isdata == 1 && is1d) || strstr(part,"ncount") || !p0 || !p2) /* either ncount, or 1d */
if (!strstr(format.Name, "partial"))
mcfile_header(datafile, format, "footer",
(strstr(format.Name, "McStas") ? "# " : ""),
filename, valid_parent);
}
if (datafile) fclose(datafile);
}
else
{
if (strstr(format.Name, "McStas") && just_header == 0 && m*n*p > 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<strlen(low_format); i++) low_format[i]=tolower(format[i]);
if (!strcmp(low_format, "pgplot")) strcpy(low_format, "mcstas");
tmp = malloc(256);
if(!tmp) exit(fprintf(stderr, "Error: insufficient memory (mcuse_format)\n"));
/* look for a specific format in mcformats.Name table */
for (i=0; i < mcNUMFORMATS; i++)
{
strcpy(tmp, mcformats[i].Name);
for (j=0; j<strlen(tmp); j++) tmp[j] = tolower(tmp[j]);
if (strstr(low_format, tmp)) i_format = i;
}
if (i_format < 0)
{
i_format = 0; /* default format is #0 McStas */
fprintf(stderr, "Warning: unknown output format '%s'. Using default (%s).\n", format, mcformats[i_format].Name);
}
mcformat = mcformats[i_format];
strcpy(tmp, mcformat.Name);
mcformat.Name = tmp;
if (strstr(format,"binary"))
{
if (strstr(format,"double")) strcat(mcformat.Name," binary double data");
else if (strstr(format,"NeXus")) strcat(mcformat.Name," binary NeXus data");
else strcat(mcformat.Name," binary float data");
mcascii_only = 1;
}
} /* mcuse_format */
static void
mcinfo(void)
{
mcsiminfo_init(stdout);
mcsiminfo_close();
exit(0);
}
void
mcparseoptions(int argc, char *argv[])
{
int i, j;
char *p;
int paramset = 0, *paramsetarray;
/* Add one to mcnumipar to avoid allocating zero size memory block. */
paramsetarray = malloc((mcnumipar + 1)*sizeof(*paramsetarray));
if(paramsetarray == NULL)
{
fprintf(stderr, "Error: insufficient memory (mcparseoptions)\n");
exit(1);
}
for(j = 0; j < mcnumipar; j++)
{
paramsetarray[j] = 0;
if (mcinputtable[j].val && strlen(mcinputtable[j].val))
{
int status;
char buf[1024];
strncpy(buf, mcinputtable[j].val, 1024);
status = (*mcinputtypes[mcinputtable[j].type].getparm)
(buf, mcinputtable[j].par);
if(!status) fprintf(stderr, "Invalid %s default value %s in instrument definition.\n", mcinputtable[j].name, buf);
else paramsetarray[j] = 1;
} else {
(*mcinputtypes[mcinputtable[j].type].getparm)
(NULL, mcinputtable[j].par);
paramsetarray[j] = 1;
}
}
for(i = 1; i < argc; i++)
{
if(!strcmp("-s", argv[i]) && (i + 1) < argc)
mcsetseed(argv[++i]);
else if(!strncmp("-s", argv[i], 2))
mcsetseed(&argv[i][2]);
else if(!strcmp("--seed", argv[i]) && (i + 1) < argc)
mcsetseed(argv[++i]);
else if(!strncmp("--seed=", argv[i], 7))
mcsetseed(&argv[i][7]);
else if(!strcmp("-n", argv[i]) && (i + 1) < argc)
mcsetn_arg(argv[++i]);
else if(!strncmp("-n", argv[i], 2))
mcsetn_arg(&argv[i][2]);
else if(!strcmp("--ncount", argv[i]) && (i + 1) < argc)
mcsetn_arg(argv[++i]);
else if(!strncmp("--ncount=", argv[i], 9))
mcsetn_arg(&argv[i][9]);
else if(!strcmp("-d", argv[i]) && (i + 1) < argc)
mcuse_dir(argv[++i]);
else if(!strncmp("-d", argv[i], 2))
mcuse_dir(&argv[i][2]);
else if(!strcmp("--dir", argv[i]) && (i + 1) < argc)
mcuse_dir(argv[++i]);
else if(!strncmp("--dir=", argv[i], 6))
mcuse_dir(&argv[i][6]);
else if(!strcmp("-f", argv[i]) && (i + 1) < argc)
mcuse_file(argv[++i]);
else if(!strncmp("-f", argv[i], 2))
mcuse_file(&argv[i][2]);
else if(!strcmp("--file", argv[i]) && (i + 1) < argc)
mcuse_file(argv[++i]);
else if(!strncmp("--file=", argv[i], 7))
mcuse_file(&argv[i][7]);
else if(!strcmp("-h", argv[i]))
mcshowhelp(argv[0]);
else if(!strcmp("--help", argv[i]))
mcshowhelp(argv[0]);
else if(!strcmp("-i", argv[i])) {
mcuse_format(MCSTAS_FORMAT);
mcinfo();
}
else if(!strcmp("--info", argv[i]))
mcinfo();
else if(!strcmp("-t", argv[i]))
mcenabletrace();
else if(!strcmp("--trace", argv[i]))
mcenabletrace();
else if(!strcmp("-a", argv[i]))
mcascii_only = 1;
else if(!strcmp("+a", argv[i]))
mcascii_only = 0;
else if(!strcmp("--data-only", argv[i]))
mcascii_only = 1;
else if(!strcmp("--gravitation", argv[i]))
mcgravitation = 1;
else if(!strcmp("-g", argv[i]))
mcgravitation = 1;
else if(!strncmp("--format=", argv[i], 9)) {
mcascii_only = 0;
mcuse_format(&argv[i][9]);
}
else if(!strcmp("--format", argv[i]) && (i + 1) < argc) {
mcascii_only = 0;
mcuse_format(argv[++i]);
}
else if(!strcmp("--no-output-files", argv[i]))
mcdisable_output_files = 1;
else if(argv[i][0] != '-' && (p = strchr(argv[i], '=')) != NULL)
{
*p++ = '\0';
for(j = 0; j < mcnumipar; j++)
if(!strcmp(mcinputtable[j].name, argv[i]))
{
int status;
status = (*mcinputtypes[mcinputtable[j].type].getparm)(p,
mcinputtable[j].par);
if(!status || !strlen(p))
{
(*mcinputtypes[mcinputtable[j].type].error)
(mcinputtable[j].name, p);
exit(1);
}
paramsetarray[j] = 1;
paramset = 1;
break;
}
if(j == mcnumipar)
{ /* Unrecognized parameter name */
fprintf(stderr, "Error: unrecognized parameter %s\n", argv[i]);
exit(1);
}
}
else
mcusage(argv[0]);
}
if (!mcascii_only) {
if (strstr(mcformat.Name,"binary")) fprintf(stderr, "Warning: %s files will contain text headers.\n Use -a option to clean up.\n", mcformat.Name);
strcat(mcformat.Name, " with text headers");
}
if(!paramset)
mcreadparams(); /* Prompt for parameters if not specified. */
else
{
for(j = 0; j < mcnumipar; j++)
if(!paramsetarray[j])
{
fprintf(stderr, "Error: Instrument parameter %s left unset\n",
mcinputtable[j].name);
exit(1);
}
}
free(paramsetarray);
}
#ifndef MC_PORTABLE
#ifndef MAC
#ifndef WIN32
/* This is the signal handler that makes simulation stop, and save results */
void sighandler(int sig)
{
/* MOD: E. Farhi, Sep 20th 2001: give more info */
time_t t1;
printf("\n# McStas: [pid %i] Signal %i detected", getpid(), sig);
if (!strcmp(mcsig_message, "sighandler") && (sig != SIGUSR1) && (sig != SIGUSR2))
{
printf("\n# Fatal : unrecoverable loop ! Suicide (naughty boy).\n");
kill(0, SIGKILL); /* kill myself if error occurs within sighandler: loops */
}
switch (sig) {
case SIGINT : printf(" SIGINT (interrupt from terminal, Ctrl-C)"); break;
case SIGQUIT : printf(" SIGQUIT (quit from terminal)"); break;
case SIGABRT : printf(" SIGABRT (abort)"); break;
case SIGTRAP : printf(" SIGTRAP (trace trap)"); break;
case SIGTERM : printf(" SIGTERM (termination)"); break;
case SIGPIPE : printf(" SIGPIPE (broken pipe)"); break;
case SIGUSR1 : printf(" SIGUSR1 (Display info)"); break;
case SIGUSR2 : printf(" SIGUSR2 (Save simulation)"); break;
case SIGILL : printf(" SIGILL (Illegal instruction)"); break;
case SIGFPE : printf(" SIGFPE (Math Error)"); break;
case SIGBUS : printf(" SIGBUS (bus error)"); break;
case SIGSEGV : printf(" SIGSEGV (Mem Error)"); break;
case SIGURG : printf(" SIGURG (urgent socket condition)"); break;
default : printf(" (look at signal list for signification)"); break;
}
printf("\n");
printf("# Simulation: %s (%s) \n", mcinstrument_name, mcinstrument_source);
printf("# Breakpoint: %s ", mcsig_message);
if (!strcmp(mcsig_message, "Save") && (sig == SIGUSR2)) sig = SIGUSR1;
strcpy(mcsig_message, "sighandler");
if (mcget_ncount() == 0)
printf("(0 %%)\n" );
else
{
printf("%.2f %% (%10.1f/%10.1f)\n", 100*mcget_run_num()/mcget_ncount(), mcget_run_num(), mcget_ncount());
}
t1 = time(NULL);
printf("# Date : %s",ctime(&t1));
if (sig == SIGUSR1)
{
printf("# McStas: Resuming simulation (continue)\n");
fflush(stdout);
return;
}
else
if (sig == SIGUSR2)
{
printf("# McStas: Saving data and resume simulation (continue)\n");
mcsave(NULL);
fflush(stdout);
return;
}
else
if ((sig == SIGTERM) || (sig == SIGINT))
{
printf("# McStas: Finishing simulation (save results and exit)\n");
mcfinally();
exit(0);
}
else
{
fflush(stdout);
perror("# Last I/O Error");
printf("# McStas: Simulation stop (abort)\n");
exit(-1);
}
}
#endif /* !MAC */
#endif /* !WIN32 */
#endif /* !MC_PORTABLE */
/* McStas main() function. */
int
mcstas_main(int argc, char *argv[])
{
/* double run_num = 0; */
time_t t;
#ifdef MAC
argc = ccommand(&argv);
#endif
t = (time_t)mcstartdate;
srandom(time(&t));
mcstartdate = t;
strcpy(mcsig_message, "main (Start)");
if (getenv("MCSTAS_FORMAT")) mcuse_format(getenv("MCSTAS_FORMAT"));
else mcuse_format(MCSTAS_FORMAT); /* default is to output as McStas format */
mcparseoptions(argc, argv);
#ifndef MC_PORTABLE
#ifndef MAC
#ifndef WIN32
/* install sig handler, but only once !! after parameters parsing */
signal( SIGQUIT ,sighandler); /* quit (ASCII FS) */
signal( SIGABRT ,sighandler); /* used by abort, replace SIGIOT in the future */
signal( SIGTRAP ,sighandler); /* trace trap (not reset when caught) */
signal( SIGTERM ,sighandler); /* software termination signal from kill */
/* signal( SIGPIPE ,sighandler);*/ /* write on a pipe with no one to read it, used by mcdisplay */
signal( SIGUSR1 ,sighandler); /* display simulation status */
signal( SIGUSR2 ,sighandler);
signal( SIGILL ,sighandler); /* illegal instruction (not reset when caught) */
signal( SIGFPE ,sighandler); /* floating point exception */
signal( SIGBUS ,sighandler); /* bus error */
signal( SIGSEGV ,sighandler); /* segmentation violation */
#ifdef SIGSYS
signal( SIGSYS ,sighandler); /* bad argument to system call */
#endif
signal( SIGURG ,sighandler); /* urgent socket condition */
#endif /* !MAC */
#endif /* !WIN32 */
#endif /* !MC_PORTABLE */
mcsiminfo_init(NULL); mcsiminfo_close(); /* makes sure we can do that */
strcpy(mcsig_message, "main (Init)");
mcinit();
#ifndef MC_PORTABLE
#ifndef MAC
#ifndef WIN32
signal( SIGINT ,sighandler); /* interrupt (rubout) only after INIT */
#endif /* !MAC */
#endif /* !WIN32 */
#endif /* !MC_PORTABLE */
while(mcrun_num < mcncount)
{
mcsetstate(0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
mcraytrace();
mcrun_num++;
}
mcfinally();
if (mcformat.Name) free(mcformat.Name);
return 0;
}
/* End of file "mcstas-r.c". */
#line 4184 "dmcafter.c"
#ifdef MC_TRACE_ENABLED
int mctraceenabled = 1;
#else
int mctraceenabled = 0;
#endif
#define MCSTAS "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/"
int mcdefaultmain = 1;
char mcinstrument_name[] = "DMC_diff";
char mcinstrument_source[] = "dmcafter.instr";
int main(int argc, char *argv[]){return mcstas_main(argc, argv);}
void mcinit(void);
void mcraytrace(void);
void mcsave(FILE *);
void mcfinally(void);
void mcdisplay(void);
/* Instrument parameters. */
MCNUM mcipDet_start;
char* mcipsamplefile;
char* mcipmonfile;
char* mciplambdafile;
int mciprepeat;
#define mcNUMIPAR 5
int mcnumipar = 5;
struct mcinputtable_struct mcinputtable[mcNUMIPAR+1] = {
"Det_start", &mcipDet_start, instr_type_double, "",
"samplefile", &mcipsamplefile, instr_type_string, "",
"monfile", &mcipmonfile, instr_type_string, "",
"lambdafile", &mciplambdafile, instr_type_string, "",
"repeat", &mciprepeat, instr_type_int, "",
NULL, NULL, instr_type_double, ""
};
/* User declarations from instrument definition. */
#define Det_start mcipDet_start
#define samplefile mcipsamplefile
#define monfile mcipmonfile
#define lambdafile mciplambdafile
#define repeat mciprepeat
#line 5 "dmcafter.instr"
double sample_radius = 0.005;
double sample_height = 0.03;
double Det_start;
double Det_end;
char option_list[150];
#line 4231 "dmcafter.c"
#undef repeat
#undef lambdafile
#undef monfile
#undef samplefile
#undef Det_start
/* Declarations of component definition and setting parameters. */
/* Neutron state table at each component input (local coords) */
/* [x, y, z, vx, vy, vz, t, sx, sy, sz, p] */
MCNUM mccomp_storein[11*9];
/* Components position table (absolute and relative coords) */
Coords mccomp_posa[9];
Coords mccomp_posr[9];
/* Flag true when previous component acted on the neutron (SCATTER) */
char mcScattered=0;
/* Definition parameters for component 'in' [2]. */
#define mccin_file mciplambdafile
#define mccin_type 0
/* Setting parameters for component 'in' [2]. */
MCNUM mccin_repeat_count;
MCNUM mccin_bufsize;
/* Setting parameters for component 'out2_slit' [3]. */
MCNUM mccout2_slit_xmin;
MCNUM mccout2_slit_xmax;
MCNUM mccout2_slit_ymin;
MCNUM mccout2_slit_ymax;
MCNUM mccout2_slit_radius;
/* Setting parameters for component 'PSD_sample' [4]. */
MCNUM mccPSD_sample_xmin;
MCNUM mccPSD_sample_xmax;
MCNUM mccPSD_sample_ymin;
MCNUM mccPSD_sample_ymax;
char mccPSD_sample_controlfile[1024];
int mccPSD_sample_dumpCount;
/* Definition parameters for component 'sample' [6]. */
#define mccsample_reflections mcipsamplefile
/* Setting parameters for component 'sample' [6]. */
MCNUM mccsample_d_phi0;
MCNUM mccsample_radius;
MCNUM mccsample_focus_r;
MCNUM mccsample_h;
MCNUM mccsample_pack;
MCNUM mccsample_Vc;
MCNUM mccsample_sigma_a;
MCNUM mccsample_sigma_inc;
MCNUM mccsample_frac;
MCNUM mccsample_focus_xw;
MCNUM mccsample_focus_yh;
MCNUM mccsample_focus_aw;
MCNUM mccsample_focus_ah;
MCNUM mccsample_target_x;
MCNUM mccsample_target_y;
MCNUM mccsample_target_z;
int mccsample_target_index;
/* Definition parameters for component 'Det9' [7]. */
#define mccDet9_options option_list
#define mccDet9_filename 0
/* Setting parameters for component 'Det9' [7]. */
MCNUM mccDet9_xwidth;
MCNUM mccDet9_yheight;
MCNUM mccDet9_zthick;
MCNUM mccDet9_xmin;
MCNUM mccDet9_xmax;
MCNUM mccDet9_ymin;
MCNUM mccDet9_ymax;
MCNUM mccDet9_zmin;
MCNUM mccDet9_zmax;
/* User component declarations. */
/* User declarations for component 'msa' [7]. */
#define mccompcurname msa
#define mccompcurindex 1
/* Shared user declarations for all components 'Arm'. */
#undef mccompcurname
#undef mccompcurindex
/* User declarations for component 'in' [7]. */
#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
#define repeat_count mccin_repeat_count
#define bufsize mccin_bufsize
/* Shared user declarations for all components 'Virtual_input'. */
#line 75 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/sources/Virtual_input.comp"
/*******************************************************************************
*
* 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.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 components that may read data from table files
* It handles some shared functions.
*
* Usage: within SHARE
* %include "read_table-lib"
*
*
* $Id$
*
* $Log$
* 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/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 <sys/stat.h>
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$
*
* $Log$
* 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_i<mc_rt_nelements; mc_rt_i++)
mc_rt_dataf[mc_rt_i]=mc_rt_s[mc_rt_i];
free(mc_rt_data);
mc_rt_Table->data = 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; i<size; i++)
{
/* printf("Reading in line %i\n",i);*/
double h, k, l, j, q, w, DW, F2;
double b1[3], b2[3];
/* get data from table */
j = Table_Index(sTable, i, sTable.columns-5);
q = Table_Index(sTable, i, sTable.columns-4);
F2= Table_Index(sTable, i, sTable.columns-3);
DW = Table_Index(sTable, i, sTable.columns-2);
w = Table_Index(sTable, i, sTable.columns-1); /* last column */
if (size<11) {
printf("\nReflection %d: j=%g, q=%g, F2=%g, DW=%g, w=%g",i,j,q,F2,DW,w);
}
list[i].j = j;
list[i].q = q;
list[i].DW = DW;
list[i].w = w;
list[i].F2 = F2;
}
printf("\ndone!\n");
Table_Free(&sTable);
info->list = 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$
*
* $Log$
* 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$
*
* $Log$
* 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<Nq; i++)
{
my_s_v2[i] = PI*PI*PI*pack*L[i].DW /(Vc*Vc*V2K*V2K)*(L[i].j * L[i].F2 / L[i].q);
/* Is not yet divided by v^2 */
my_s_v2_sum+=my_s_v2[i];
q_v[i] = L[i].q*K2V;
w_v[i] = L[i].w*K2V;
}
}
#line 7350 "dmcafter.c"
} /* End of SETTING parameter declarations. */
#undef q_v
#undef my_a_v
#undef my_s_v2
#undef reflections
#undef mccompcurname
#undef mccompcurindex
/* Initializations for component Det9. */
strcpy(mcsig_message, "Det9 (Init)");
#line 62 "dmcafter.instr"
mccDet9_xwidth = 3.0;
#line 62 "dmcafter.instr"
mccDet9_yheight = 0.09;
#line 198 "dmcafter.instr"
mccDet9_zthick = 0;
#line 198 "dmcafter.instr"
mccDet9_xmin = 0;
#line 198 "dmcafter.instr"
mccDet9_xmax = 0;
#line 198 "dmcafter.instr"
mccDet9_ymin = 0;
#line 198 "dmcafter.instr"
mccDet9_ymax = 0;
#line 198 "dmcafter.instr"
mccDet9_zmin = 0;
#line 198 "dmcafter.instr"
mccDet9_zmax = 0;
#line 7379 "dmcafter.c"
#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 218 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/monitors/Monitor_nD.comp"
{
strcpy(Vars.compcurname, NAME_CURRENT_COMP);
if (options != NULL)
strncpy(Vars.option, options, 1024);
else
strcpy(Vars.option, "x y");
if (strstr(Vars.option, "source"))
strcat(Vars.option, " list, x y z vx vy vz t sx sy sz ");
Monitor_nD_Init(&DEFS, &Vars, xwidth, yheight, zthick, xmin,xmax,ymin,ymax,zmin,zmax);
if (filename != NULL)
strncpy(Vars.Mon_File, filename, 128);
}
#line 7413 "dmcafter.c"
} /* End of SETTING parameter declarations. */
#undef Vars
#undef DEFS
#undef filename
#undef options
#undef mccompcurname
#undef mccompcurindex
if(mcdotrace) mcdisplay();
mcDEBUG_INSTR_END()
}
}
void mcraytrace(void) {
/* Copy neutron state to local variables. */
MCNUM mcnlx = mcnx;
MCNUM mcnly = mcny;
MCNUM mcnlz = mcnz;
MCNUM mcnlvx = mcnvx;
MCNUM mcnlvy = mcnvy;
MCNUM mcnlvz = mcnvz;
MCNUM mcnlt = mcnt;
MCNUM mcnlsx = mcnsx;
MCNUM mcnlsy = mcnsy;
MCNUM mcnlsz = mcnsz;
MCNUM mcnlp = mcnp;
mcDEBUG_ENTER()
mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp)
#define mcabsorb mcabsorbAll
/* Component msa. */
strcpy(mcsig_message, "msa (Trace)");
mcDEBUG_COMP("msa")
mccoordschange(mcposrmsa, mcrotrmsa,
&mcnlx, &mcnly, &mcnlz,
&mcnlvx, &mcnlvy, &mcnlvz,
&mcnlt, &mcnlsx, &mcnlsy);
mccoordschange_polarisation(mcrotrmsa, &mcnlsx, &mcnlsy, &mcnlsz);
mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp)
STORE_NEUTRON(1,mcnlx, mcnly, mcnlz, mcnlvx,mcnlvy,mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlsz, mcnlp);
mcScattered=0;
#define mccompcurname msa
#define mccompcurindex 1
#undef mccompcurname
#undef mccompcurindex
mcDEBUG_STATE(mcnlx, mcnly, mcnlz, mcnlvx, mcnlvy, mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlp)
/* Component in. */
strcpy(mcsig_message, "in (Trace)");
mcDEBUG_COMP("in")
mccoordschange(mcposrin, mcrotrin,
&mcnlx, &mcnly, &mcnlz,
&mcnlvx, &mcnlvy, &mcnlvz,
&mcnlt, &mcnlsx, &mcnlsy);
mccoordschange_polarisation(mcrotrin, &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(2,mcnlx, mcnly, mcnlz, mcnlvx,mcnlvy,mcnlvz,mcnlt,mcnlsx,mcnlsy, mcnlsz, mcnlp);
mcScattered=0;
#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 130 "/afs/psi.ch/project/sinq/sl-linux/lib/mcstas/sources/Virtual_input.comp"
{
/* while not eof */
/* read file at offset */
if (rep >= 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) && (x<xmin || x>xmax || y<ymin || y>ymax))
|| ((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 && x<xmax && y>ymin && y<ymax)
{
Nsum++;
psum += p;
p2sum += p*p;
currentCount++;
if(dumpCount > 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