1/******************************************************************************* 2* 3* McCode, neutron/xray ray-tracing package 4* Copyright (C) 1997-2009, All rights reserved 5* Risoe National Laboratory, Roskilde, Denmark 6* Institut Laue Langevin, Grenoble, France 7* 8* Runtime: share/mccode-r.h 9* 10* %Identification 11* Written by: KN 12* Date: Aug 29, 1997 13* Release: McXtrace 1.2 14* Version: $Revision$ 15* 16* Runtime system header for McStas/McXtrace. 17* 18* In order to use this library as an external library, the following variables 19* and macros must be declared (see details in the code) 20* 21* struct mcinputtable_struct mcinputtable[]; 22* int mcnumipar; 23* char mcinstrument_name[], mcinstrument_source[]; 24* int mctraceenabled, mcdefaultmain; 25* extern MCNUM mccomp_storein[]; 26* extern MCNUM mcAbsorbProp[]; 27* extern MCNUM mcScattered; 28* #define MCCODE_STRING "the McStas/McXtrace version" 29* 30* Usage: Automatically embbeded in the c code. 31* 32* $Id$ 33* 34*******************************************************************************/ 35 36#ifndef MCCODE_R_H 37#define MCCODE_R_H "$Revision$" 38 39#include <math.h> 40#include <string.h> 41#include <stdlib.h> 42#include <stdio.h> 43#include <stdarg.h> 44#include <limits.h> 45#include <errno.h> 46#include <time.h> 47#include <float.h> 48 49/* If the runtime is embedded in the simulation program, some definitions can 50 be made static. */ 51 52#ifdef MC_EMBEDDED_RUNTIME 53#define mcstatic static 54#else 55#define mcstatic 56#endif 57 58#ifdef __dest_os 59#if (__dest_os == __mac_os) 60#define MAC 61#endif 62#endif 63 64#ifdef __FreeBSD__ 65#define NEED_STAT_H 66#endif 67 68#if defined(__APPLE__) && defined(__GNUC__) 69#define NEED_STAT_H 70#endif 71 72#ifdef NEED_STAT_H 73#include <sys/stat.h> 74#endif 75 76#ifndef MC_PATHSEP_C 77#ifdef WIN32 78#define MC_PATHSEP_C '\\' 79#define MC_PATHSEP_S "\\" 80#else /* !WIN32 */ 81#define MC_PATHSEP_C '/' 82#define MC_PATHSEP_S "/" 83#endif /* !WIN32 */ 84#endif /* MC_PATHSEP_C */ 85 86 87 88/* the version string is replaced when building distribution with mkdist */ 89#ifndef MCCODE_STRING 90#define MCCODE_STRING "McXtrace 1.2 - Jul. 02, 2015" 91#endif 92 93#ifndef MCCODE_DATE 94#define MCCODE_DATE "Jul. 02, 2015" 95#endif 96 97#ifndef MCCODE_VERSION 98#define MCCODE_VERSION "1.2" 99#endif 100 101#ifndef MCCODE_NAME 102#define MCCODE_NAME "McXtrace" 103#endif 104 105#ifndef MCCODE_PARTICLE 106#define MCCODE_PARTICLE "@MCCODE_PARTICLE@" 107#endif 108 109#ifndef MCCODE_LIBENV 110#define MCCODE_LIBENV "@MCCODE_LIBENV@" 111#endif 112 113#ifndef FLAVOR_UPPER 114#define FLAVOR_UPPER MCCODE_NAME 115#endif 116 117#ifdef MC_PORTABLE 118#ifndef NOSIGNALS 119#define NOSIGNALS 1 120#endif 121#endif 122 123#ifdef MAC 124#ifndef NOSIGNALS 125#define NOSIGNALS 1 126#endif 127#endif 128 129#if (USE_MPI == 0) 130#undef USE_MPI 131#endif 132 133#ifdef USE_MPI /* default is to disable signals with MPI, as MPICH uses them to communicate */ 134#ifndef NOSIGNALS 135#define NOSIGNALS 1 136#endif 137#endif 138 139#if (NOSIGNALS == 0) 140#undef NOSIGNALS 141#endif 142 143/* Note: the enum instr_formal_types definition MUST be kept 144 synchronized with the one in mccode.h and with the 145 instr_formal_type_names array in cogen.c. */ 146enum instr_formal_types 147 { 148 instr_type_double, instr_type_int, instr_type_string 149 }; 150struct mcinputtable_struct { /* defines instrument parameters */ 151 char *name; /* name of parameter */ 152 void *par; /* pointer to instrument parameter (variable) */ 153 enum instr_formal_types type; 154 char *val; /* default value */ 155}; 156 157typedef double MCNUM; 158typedef struct {MCNUM x, y, z;} Coords; 159typedef MCNUM Rotation[3][3]; 160 161/* the following variables are defined in the McStas generated C code 162 but should be defined externally in case of independent library usage */ 163#ifndef DANSE 164extern struct mcinputtable_struct mcinputtable[]; /* list of instrument parameters */ 165extern int mcnumipar; /* number of instrument parameters */ 166extern char mcinstrument_name[], mcinstrument_source[]; /* instrument name and filename */ 167extern char *mcinstrument_exe; /* executable path = argv[0] or NULL */ 168extern MCNUM mccomp_storein[]; /* 11 coords * number of components in instrument */ 169extern MCNUM mcAbsorbProp[]; 170extern MCNUM mcScattered; /* number of SCATTER calls in current component */ 171extern MCNUM mcRestore; /* Flag to indicate if neutron needs to be restored */ 172#ifndef MC_ANCIENT_COMPATIBILITY 173extern int mctraceenabled, mcdefaultmain; 174#endif 175#endif 176 177 178/* Useful macros ============================================================ */ 179 180/* MPI stuff */ 181 182#ifdef USE_MPI 183#include "mpi.h" 184 185#ifdef OMPI_MPI_H /* openmpi does not use signals: we may install our sighandler */ 186#undef NOSIGNALS 187#endif 188 189/* 190 * MPI_MASTER(i): 191 * execution of i only on master node 192 */ 193#define MPI_MASTER(statement) { \ 194 if(mpi_node_rank == mpi_node_root)\ 195 { statement; } \ 196} 197 198#ifndef MPI_REDUCE_BLOCKSIZE 199#define MPI_REDUCE_BLOCKSIZE 1000 200#endif 201 202int mc_MPI_Sum(double* buf, long count); 203int mc_MPI_Send(void *sbuf, long count, MPI_Datatype dtype, int dest); 204int mc_MPI_Recv(void *rbuf, long count, MPI_Datatype dtype, int source); 205 206/* MPI_Finalize exits gracefully and should be preferred to MPI_Abort */ 207#define exit(code) do { \ 208 MPI_Finalize(); \ 209 exit(code); \ 210 } while(0) 211 212#else /* !USE_MPI */ 213#define MPI_MASTER(instr) instr 214#endif /* USE_MPI */ 215 216#ifdef USE_MPI 217static int mpi_node_count; 218#endif 219 220#ifdef USE_THREADS /* user want threads */ 221#error Threading (USE_THREADS) support has been removed for very poor efficiency. Use MPI/SSH grid instead. 222#endif 223 224 225void mcset_ncount(unsigned long long count); /* wrapper to get mcncount */ 226unsigned long long int mcget_ncount(void); /* wrapper to set mcncount */ 227unsigned long long mcget_run_num(void); /* wrapper to get mcrun_num=0:mcncount */ 228 229 230/* Following part is only embedded when not redundant with mccode.h ========= */ 231 232#ifndef MCCODE_H 233 234#ifndef NOSIGNALS 235#include <signal.h> 236#define SIG_MESSAGE(msg) strcpy(mcsig_message, msg); 237#else 238#define SIG_MESSAGE(msg) 239#endif /* !NOSIGNALS */ 240 241/* Useful macros and constants ============================================== */ 242 243#ifndef FLT_MAX 244#define FLT_MAX 3.40282347E+38F /* max decimal value of a "float" */ 245#endif 246 247#ifndef MIN 248#define MIN(a, b) (((a) < (b)) ? (a) : (b)) 249#endif 250#ifndef MAX 251#define MAX(a, b) (((a) > (b)) ? (a) : (b)) 252#endif 253#ifndef SQR 254#define SQR(x) ( (x) * (x) ) 255#endif 256#ifndef SIGN 257#define SIGN(x) (((x)>0.0)?(1):(-1)) 258#endif 259 260#ifndef PI 261# ifdef M_PI 262# define PI M_PI 263# else 264# define PI 3.14159265358979323846 265# endif 266#endif 267 268#define RAD2MIN ((180*60)/PI) 269#define MIN2RAD (PI/(180*60)) 270#define DEG2RAD (PI/180) 271#define RAD2DEG (180/PI) 272#define FWHM2RMS 0.424660900144 /* Convert between full-width-half-max and */ 273#define RMS2FWHM 2.35482004503 /* root-mean-square (standard deviation) */ 274#define HBAR 1.05457168e-34 /* [Js] h bar Planck constant CODATA 2002 */ 275#define MNEUTRON 1.67492728e-27 /* [kg] mass of neutron CODATA 2002 */ 276#define GRAVITY 9.81 /* [m/s^2] gravitational acceleration */ 277#define NA 6.02214179e23 /* [#atoms/g .mole] Avogadro's number*/ 278 279 280/* wrapper to get absolute and relative position of comp */ 281/* mccomp_posa and mccomp_posr are defined in McStas generated C code */ 282#define POS_A_COMP_INDEX(index) \ 283 (mccomp_posa[index]) 284#define POS_R_COMP_INDEX(index) \ 285 (mccomp_posr[index]) 286/* number of SCATTER calls in current comp: mcScattered defined in generated C code */ 287#define SCATTERED mcScattered 288/* Flag to indicate if neutron needs to be restored: mcRestore defined in generated C code */ 289#define RESTORE mcRestore 290 291 292/* Retrieve component information from the kernel */ 293/* Name, position and orientation (both absolute and relative) */ 294/* Any component: For "redundancy", see comment by KN */ 295#define tmp_name_comp(comp) #comp 296#define NAME_COMP(comp) tmp_name_comp(comp) 297#define tmp_pos_a_comp(comp) (mcposa ## comp) 298#define POS_A_COMP(comp) tmp_pos_a_comp(comp) 299#define tmp_pos_r_comp(comp) (mcposr ## comp) 300#define POS_R_COMP(comp) tmp_pos_r_comp(comp) 301#define tmp_rot_a_comp(comp) (mcrota ## comp) 302#define ROT_A_COMP(comp) tmp_rot_a_comp(comp) 303#define tmp_rot_r_comp(comp) (mcrotr ## comp) 304#define ROT_R_COMP(comp) tmp_rot_r_comp(comp) 305 306/* Current component name, index, position and orientation */ 307#define NAME_CURRENT_COMP NAME_COMP(mccompcurname) 308#define INDEX_CURRENT_COMP mccompcurindex 309#define POS_A_CURRENT_COMP POS_A_COMP(mccompcurname) 310#define POS_R_CURRENT_COMP POS_R_COMP(mccompcurname) 311#define ROT_A_CURRENT_COMP ROT_A_COMP(mccompcurname) 312#define ROT_R_CURRENT_COMP ROT_R_COMP(mccompcurname) 313 314/* Note: The two-stage approach to MC_GETPAR is NOT redundant; without it, 315* after #define C sample, MC_GETPAR(C,x) would refer to component C, not to 316* component sample. Such are the joys of ANSI C. 317 318* Anyway the usage of MCGETPAR requires that we use sometimes bare names... 319*/ 320#define MC_GETPAR2(comp, par) (mcc ## comp ## _ ## par) 321#define MC_GETPAR(comp, par) MC_GETPAR2(comp,par) 322 323/* MCDISPLAY/trace and debugging message sent to stdout */ 324#ifdef MC_TRACE_ENABLED 325#define DEBUG 326#endif 327 328#ifdef DEBUG 329#define mcDEBUG_INSTR() if(!mcdotrace); else { printf("INSTRUMENT:\n"); printf("Instrument '%s' (%s)\n", mcinstrument_name, mcinstrument_source); } 330#define mcDEBUG_COMPONENT(name,c,t) if(!mcdotrace); else {\ 331 printf("COMPONENT: \"%s\"\n" \ 332 "POS: %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g, %g\n", \ 333 name, c.x, c.y, c.z, t[0][0], t[0][1], t[0][2], \ 334 t[1][0], t[1][1], t[1][2], t[2][0], t[2][1], t[2][2]); \ 335 printf("Component %30s AT (%g,%g,%g)\n", name, c.x, c.y, c.z); \ 336 } 337#define mcDEBUG_INSTR_END() if(!mcdotrace); else printf("INSTRUMENT END:\n"); 338#define mcDEBUG_ENTER() if(!mcdotrace); else printf("ENTER:\n"); 339#define mcDEBUG_COMP(c) if(!mcdotrace); else printf("COMP: \"%s\"\n", c); 340#define mcDEBUG_LEAVE() if(!mcdotrace); else printf("LEAVE:\n"); 341#define mcDEBUG_ABSORB() if(!mcdotrace); else printf("ABSORB:\n"); 342#else 343#define mcDEBUG_INSTR() 344#define mcDEBUG_COMPONENT(name,c,t) 345#define mcDEBUG_INSTR_END() 346#define mcDEBUG_ENTER() 347#define mcDEBUG_COMP(c) 348#define mcDEBUG_LEAVE() 349#define mcDEBUG_ABSORB() 350#endif 351 352// mcDEBUG_STATE and mcDEBUG_SCATTER are defined by mcstas-r.h and mcxtrace-r.h 353 354 355 356#ifdef TEST 357#define test_printf printf 358#else 359#define test_printf while(0) printf 360#endif 361 362/* send MCDISPLAY message to stdout to show gemoetry */ 363void mcdis_magnify(char *what); 364void mcdis_line(double x1, double y1, double z1, 365 double x2, double y2, double z2); 366void mcdis_dashed_linemcdis_dashed_line(double x1, double y1, double z1, 367 double x2, double y2, double z2, int n); 368void mcdis_multiline(int count, ...); 369void mcdis_rectangle(char* plane, double x, double y, double z, 370 double width, double height); 371void mcdis_box(double x, double y, double z, 372 double width, double height, double length); 373void mcdis_circle(char *plane, double x, double y, double z, double r); 374 375/* selection of random number generator. default is MT */ 376#ifndef MC_RAND_ALG 377#define MC_RAND_ALG 1 378#endif 379 380#if MC_RAND_ALG == 0 381 /* Use system random() (not recommended). */ 382# define MC_RAND_MAX RAND_MAX 383#elif MC_RAND_ALG == 1 384 /* "Mersenne Twister", by Makoto Matsumoto and Takuji Nishimura. */ 385# define MC_RAND_MAX ((unsigned long)0xffffffff) 386# define random mt_random 387# define srandom mt_srandom 388#elif MC_RAND_ALG == 2 389 /* Algorithm used in McStas CVS-080208 and earlier (not recommended). */ 390# define MC_RAND_MAX 0x7fffffff 391# define random mc_random 392# define srandom mc_srandom 393#else 394# error "Bad value for random number generator choice." 395#endif 396 397typedef int mc_int32_t; 398mc_int32_t mc_random(void); 399void mc_srandom (unsigned int x); 400unsigned long mt_random(void); 401void mt_srandom (unsigned long x); 402 403double rand01(); 404double randpm1(); 405double rand0max(double max); 406double randminmax(double min, double max); 407 408double randnorm(void); 409double randtriangle(void); 410 411#ifndef DANSE 412void mcinit(void); 413void mcraytrace(void); 414void mcsave(FILE *); 415void mcfinally(void); 416void mcdisplay(void); 417#endif 418 419/* simple vector algebra ==================================================== */ 420#define vec_prod(x, y, z, x1, y1, z1, x2, y2, z2) \ 421 vec_prod_func(&x, &y, &z, x1, y1, z1, x2, y2, z2) 422mcstatic inline void vec_prod_func(double *x, double *y, double *z, 423 double x1, double y1, double z1, double x2, double y2, double z2); 424 425mcstatic inline double scalar_prod( 426 double x1, double y1, double z1, double x2, double y2, double z2); 427 428#define NORM(x,y,z) \ 429 norm_func(&x, &y, &z) 430mcstatic inline void norm_func(double *x, double *y, double *z) { 431 double temp = (*x * *x) + (*y * *y) + (*z * *z); 432 if (temp != 0) { 433 temp = sqrt(temp); 434 *x /= temp; 435 *y /= temp; 436 *z /= temp; 437 } 438} 439 440void normal_vec(double *nx, double *ny, double *nz, 441 double x, double y, double z); 442 443/** 444 * Rotate the vector vx,vy,vz psi radians around the vector ax,ay,az 445 * and put the result in x,y,z. 446 */ 447#define rotate(x, y, z, vx, vy, vz, phi, ax, ay, az) \ 448 do { \ 449 double mcrt_tmpx = (ax), mcrt_tmpy = (ay), mcrt_tmpz = (az); \ 450 double mcrt_vp, mcrt_vpx, mcrt_vpy, mcrt_vpz; \ 451 double mcrt_vnx, mcrt_vny, mcrt_vnz, mcrt_vn1x, mcrt_vn1y, mcrt_vn1z; \ 452 double mcrt_bx, mcrt_by, mcrt_bz; \ 453 double mcrt_cos, mcrt_sin; \ 454 NORM(mcrt_tmpx, mcrt_tmpy, mcrt_tmpz); \ 455 mcrt_vp = scalar_prod((vx), (vy), (vz), mcrt_tmpx, mcrt_tmpy, mcrt_tmpz); \ 456 mcrt_vpx = mcrt_vp*mcrt_tmpx; \ 457 mcrt_vpy = mcrt_vp*mcrt_tmpy; \ 458 mcrt_vpz = mcrt_vp*mcrt_tmpz; \ 459 mcrt_vnx = (vx) - mcrt_vpx; \ 460 mcrt_vny = (vy) - mcrt_vpy; \ 461 mcrt_vnz = (vz) - mcrt_vpz; \ 462 vec_prod(mcrt_bx, mcrt_by, mcrt_bz, \ 463 mcrt_tmpx, mcrt_tmpy, mcrt_tmpz, mcrt_vnx, mcrt_vny, mcrt_vnz); \ 464 mcrt_cos = cos((phi)); mcrt_sin = sin((phi)); \ 465 mcrt_vn1x = mcrt_vnx*mcrt_cos + mcrt_bx*mcrt_sin; \ 466 mcrt_vn1y = mcrt_vny*mcrt_cos + mcrt_by*mcrt_sin; \ 467 mcrt_vn1z = mcrt_vnz*mcrt_cos + mcrt_bz*mcrt_sin; \ 468 (x) = mcrt_vpx + mcrt_vn1x; \ 469 (y) = mcrt_vpy + mcrt_vn1y; \ 470 (z) = mcrt_vpz + mcrt_vn1z; \ 471 } while(0) 472 473/** 474 * Mirror (xyz) in the plane given by the point (rx,ry,rz) and normal (nx,ny,nz) 475 * 476 * TODO: This define is seemingly never used... 477 */ 478#define mirror(x,y,z,rx,ry,rz,nx,ny,nz) \ 479 do { \ 480 double mcrt_tmpx= (nx), mcrt_tmpy = (ny), mcrt_tmpz = (nz); \ 481 double mcrt_tmpt; \ 482 NORM(mcrt_tmpx, mcrt_tmpy, mcrt_tmpz); \ 483 mcrt_tmpt=scalar_prod((rx),(ry),(rz),mcrt_tmpx,mcrt_tmpy,mcrt_tmpz); \ 484 (x) = rx -2 * mcrt_tmpt*mcrt_rmpx; \ 485 (y) = ry -2 * mcrt_tmpt*mcrt_rmpy; \ 486 (z) = rz -2 * mcrt_tmpt*mcrt_rmpz; \ 487 } while (0) 488 489Coords coords_set(MCNUM x, MCNUM y, MCNUM z); 490Coords coords_get(Coords a, MCNUM *x, MCNUM *y, MCNUM *z); 491Coords coords_add(Coords a, Coords b); 492Coords coords_sub(Coords a, Coords b); 493Coords coords_neg(Coords a); 494Coords coords_scale(Coords b, double scale); 495double coords_sp(Coords a, Coords b); 496Coords coords_xp(Coords b, Coords c); 497void coords_print(Coords a); 498mcstatic inline void coords_norm(Coords* c); 499 500void rot_set_rotation(Rotation t, double phx, double phy, double phz); 501int rot_test_identity(Rotation t); 502void rot_mul(Rotation t1, Rotation t2, Rotation t3); 503void rot_copy(Rotation dest, Rotation src); 504void rot_transpose(Rotation src, Rotation dst); 505Coords rot_apply(Rotation t, Coords a); 506 507void mccoordschange(Coords a, Rotation t, double *x, double *y, double *z, 508 double *vx, double *vy, double *vz, double *sx, double *sy, double *sz); 509void 510mccoordschange_polarisation(Rotation t, double *sx, double *sy, double *sz); 511 512double mcestimate_error(double N, double p1, double p2); 513void mcreadparams(void); 514 515/* this is now in mcstas-r.h and mcxtrace-r.h as the number of state parameters is no longer equal*/ 516/* void mcsetstate(double x, double y, double z, double vx, double vy, double vz, 517 double t, double sx, double sy, double sz, double p); 518*/ 519void mcgenstate(void); 520 521/* trajectory/shape intersection routines */ 522int inside_rectangle(double, double, double, double); 523int box_intersect(double *dt_in, double *dt_out, double x, double y, double z, 524 double vx, double vy, double vz, double dx, double dy, double dz); 525int cylinder_intersect(double *t0, double *t1, double x, double y, double z, 526 double vx, double vy, double vz, double r, double h); 527int sphere_intersect(double *t0, double *t1, double x, double y, double z, 528 double vx, double vy, double vz, double r); 529/* second order equation roots */ 530int solve_2nd_order(double *t1, double *t2, 531 double A, double B, double C); 532 533/* random vector generation to shape */ 534void randvec_target_circle(double *xo, double *yo, double *zo, 535 double *solid_angle, double xi, double yi, double zi, double radius); 536#define randvec_target_sphere randvec_target_circle 537void randvec_target_rect_angular(double *xo, double *yo, double *zo, 538 double *solid_angle, 539 double xi, double yi, double zi, double height, double width, Rotation A); 540#define randvec_target_rect(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9) randvec_target_rect_real(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,0,0,0,1) 541void randvec_target_rect_real(double *xo, double *yo, double *zo, 542 double *solid_angle, 543 double xi, double yi, double zi, double height, double width, Rotation A, 544 double lx, double ly, double lz, int order); 545 546/* this is the main() */ 547int mccode_main(int argc, char *argv[]); 548 549 550#endif /* !MCCODE_H */ 551 552#ifndef MCCODE_R_IO_H 553#define MCCODE_R_IO_H "$Revision$" 554 555#if (USE_NEXUS == 0) 556#undef USE_NEXUS 557#endif 558 559#ifndef CHAR_BUF_LENGTH 560#define CHAR_BUF_LENGTH 1024 561#endif 562 563/* I/O section part ========================================================= */ 564 565/* ========================================================================== */ 566 567/* MCCODE_R_IO_C */ 568 569/* ========================================================================== */ 570 571 572/* main DETECTOR structure which stores most information to write to data files */ 573struct mcdetector_struct { 574 char filename[CHAR_BUF_LENGTH]; /* file name of monitor */ 575 char position[CHAR_BUF_LENGTH]; /* position of detector component */ 576 char component[CHAR_BUF_LENGTH]; /* component instance name */ 577 char instrument[CHAR_BUF_LENGTH]; /* instrument name */ 578 char type[CHAR_BUF_LENGTH]; /* data type, e.g. 0d, 1d, 2d, 3d */ 579 char user[CHAR_BUF_LENGTH]; /* user name, e.g. HOME */ 580 char date[CHAR_BUF_LENGTH]; /* date of simulation end/write time */ 581 char title[CHAR_BUF_LENGTH]; /* title of detector */ 582 char xlabel[CHAR_BUF_LENGTH]; /* X axis label */ 583 char ylabel[CHAR_BUF_LENGTH]; /* Y axis label */ 584 char zlabel[CHAR_BUF_LENGTH]; /* Z axis label */ 585 char xvar[CHAR_BUF_LENGTH]; /* X variable name */ 586 char yvar[CHAR_BUF_LENGTH]; /* Y variable name */ 587 char zvar[CHAR_BUF_LENGTH]; /* Z variable name */ 588 char ncount[CHAR_BUF_LENGTH]; /* number of events initially generated */ 589 char limits[CHAR_BUF_LENGTH]; /* X Y Z limits, e.g. [xmin xmax ymin ymax zmin zmax] */ 590 char variables[CHAR_BUF_LENGTH]; /* variables written into data block */ 591 char statistics[CHAR_BUF_LENGTH]; /* center, mean and half width along axis */ 592 char signal[CHAR_BUF_LENGTH]; /* min max and mean of signal (data block) */ 593 char values[CHAR_BUF_LENGTH]; /* integrated values e.g. [I I_err N] */ 594 double xmin,xmax; /* min max of axes */ 595 double ymin,ymax; 596 double zmin,zmax; 597 double intensity; /* integrated values for data block */ 598 double error; 599 double events; 600 double min; /* statistics for data block */ 601 double max; 602 double mean; 603 double centerX; /* statistics for axes */ 604 double halfwidthX; 605 double centerY; 606 double halfwidthY; 607 int rank; /* dimensionaly of monitor, e.g. 0 1 2 3 */ 608 char istransposed; /* flag to transpose matrix for some formats */ 609 610 long m,n,p; /* dimensions of data block and along axes */ 611 long date_l; /* same as date, but in sec since 1970 */ 612 613 double *p0, *p1, *p2; /* pointers to saved data, NULL when freed */ 614 char format[CHAR_BUF_LENGTH]; /* format for file generation */ 615}; 616 617typedef struct mcdetector_struct MCDETECTOR; 618 619static char *mcdirname = NULL; /* name of output directory */ 620static char *mcsiminfo_name = "mccode"; /* default output sim file name */ 621char *mcformat = NULL; /* NULL (default) or a specific format */ 622 623/* file I/O definitions and function prototypes */ 624 625#ifndef MC_EMBEDDED_RUNTIME /* the mcstatic variables (from mccode-r.c) */ 626extern FILE * mcsiminfo_file; /* handle to the output siminfo file */ 627extern int mcgravitation; /* flag to enable gravitation */ 628extern int mcdotrace; /* flag to print MCDISPLAY messages */ 629#else 630mcstatic FILE *mcsiminfo_file = NULL; 631#endif 632 633/* I/O function prototypes ================================================== */ 634 635/* output functions */ 636MCDETECTOR mcdetector_out_0D(char *t, double p0, double p1, double p2, char *c, Coords pos); 637MCDETECTOR mcdetector_out_1D(char *t, char *xl, char *yl, 638 char *xvar, double x1, double x2, long n, 639 double *p0, double *p1, double *p2, char *f, char *c, Coords pos); 640MCDETECTOR mcdetector_out_2D(char *t, char *xl, char *yl, 641 double x1, double x2, double y1, double y2, long m, 642 long n, double *p0, double *p1, double *p2, char *f, 643 char *c, Coords pos); 644MCDETECTOR mcdetector_out_list(char *t, char *xl, char *yl, 645 long m, long n, 646 double *p1, char *f, 647 char *c, Coords posa); 648 649/* wrappers to output functions, that automatically set NAME and POSITION */ 650#define DETECTOR_OUT(p0,p1,p2) mcdetector_out_0D(NAME_CURRENT_COMP,p0,p1,p2,NAME_CURRENT_COMP,POS_A_CURRENT_COMP) 651#define DETECTOR_OUT_0D(t,p0,p1,p2) mcdetector_out_0D(t,p0,p1,p2,NAME_CURRENT_COMP,POS_A_CURRENT_COMP) 652#define DETECTOR_OUT_1D(t,xl,yl,xvar,x1,x2,n,p0,p1,p2,f) \ 653 mcdetector_out_1D(t,xl,yl,xvar,x1,x2,n,p0,p1,p2,f,NAME_CURRENT_COMP,POS_A_CURRENT_COMP) 654#define DETECTOR_OUT_2D(t,xl,yl,x1,x2,y1,y2,m,n,p0,p1,p2,f) \ 655 mcdetector_out_2D(t,xl,yl,x1,x2,y1,y2,m,n,p0,p1,p2,f,NAME_CURRENT_COMP,POS_A_CURRENT_COMP) 656 657#ifdef USE_NEXUS 658#include "napi.h" 659NXhandle nxhandle; 660#endif 661 662#endif /* ndef MCCODE_R_IO_H */ 663 664#endif /* MCCODE_R_H */ 665