1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
/*******************************************************************************
*
* McStas, the neutron ray-tracing package: Vitess_output.comp
* Copyright 1997-2001 Risoe National Laboratory, Roskilde, Denmark
*
* Component: Vitess_output
*
* %I
* Written by: Kristian Nielsen
* Date: June 6, 2000
* Origin: Risoe/ILL
* Modified by: E. Farhi, Sep 28th, 2001: added spin
*
* Write neutron state parameters to VITESS neutron filename.
*
* %D
* Detector-like component writing neutron state parameters to a
* VITESS neutron filename. Used to interface McStas components or
* simulations into VITESS. Each neutron is 104 bytes.
*
* Note that when standard output is used, as is the default, no
* monitors or other components that produce terminal output must be
* used, or the neutron output from this component will become
* corrupted.
*
* Example: Vitess_output(filename="MySource.vit", bufsize = 10000, progress = 1)
*
* %BUGS
* This component will NOT work with parallel execution (MPI).
*
* %P
* INPUT PARAMETERS
*
* filename: [string] Filename of neutron file to write. Default is standard output
* bufsize: [records] Size of neutron output buffer
* progress: [flag] If not zero, output dots as progress indicator
*
* %E
*******************************************************************************/
DEFINE COMPONENT Vitess_output
SETTING PARAMETERS (string filename = 0, int bufsize = 10000, int progress = 0)
/* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */
SHARE
%{
%include "general"
%include "vitess-lib"
%}
DECLARE
%{
char *file; /* path + filename */
FILE *hfile; /* Neutron output filename handle */
Neutron *obuf; /* Neutron output buffer */
int pos; /* Current position in buffer */
double p_out; /* sum of output weight */
double p2_out; /* square sum of output weight */
%}
INITIALIZE
%{
file=NULL;
hfile=NULL;
#if defined (USE_MPI)
if (mpi_node_count > 1) {
exit(printf("Vitess_output: %s: ERROR: This component can not be used in parallel execution mode (MPI). Abort.\n", NAME_CURRENT_COMP));
}
#endif
/* Open neutron output filename. */
if (!filename || !strcmp(filename,"NULL") || !strcmp(filename,"0") || !strcmp(filename,"stdout"))
{
hfile = stdout;
}
else if (!strlen(filename) || !strcmp(filename, "no_filename"))
{
hfile = NULL;
}
else
{
hfile = fopen((file=FullParName(filename)), "wb");
if(!hfile)
{
fprintf(stderr, "Vitess_output: Error: Cannot open output filename %s.\n", file);
exit(1);
}
}
#ifdef WIN32
if(hfile==stdout)
{ if(_setmode(_fileno( stdout ), _O_BINARY ) == -1)
{ fprintf(stderr,"Can't set stdout to binary mode\n");
exit(1);
}
}
#endif
/* Allocate neutron output buffer. */
obuf = calloc(bufsize, sizeof(Neutron));
if(!obuf)
{
fprintf(stderr, "Vitess_output: Error: Cannot allocate neutron buffer.\n");
exit(1);
}
/* Initialize buffer. */
pos = 0;
%}
TRACE
%{
int count;
/* Flush output buffer if full. */
if(hfile && pos >= bufsize)
{ count = fwrite(obuf, sizeof(Neutron), bufsize, hfile);
if(progress)
{
fputc('.', stderr); /* Output progress indicator. */
fflush(stderr);
}
if(count != bufsize)
{
fprintf(stderr, "Vitess_output: Error during write of neutron filename.\n");
exit(1);
}
else
{
pos = 0; /* Reposition at start of buffer */
}
}
obuf[pos] = mcstas2vitess(x, y, z, vx, vy, vz, t, sx, sy, sz, p);
/* The following three lines have references to things that are no longer
in the McStas vitess libs */
/* obuf[pos].Color = vitess_col;
obuf[pos].ID.IDNo = vitess_ID.IDNo;
memcpy(obuf[pos].ID.IDGrp, vitess_ID.IDGrp, 2); */
p_out += p;
p2_out += p*p;
++pos;
%}
FINALLY
%{
int count;
/* Flush output buffer if necessary. */
if(hfile && pos > 0)
{ count = fwrite(obuf, sizeof(Neutron), pos, hfile);
if(count != pos)
{
fprintf(stderr, "Vitess_output: Error during write of neutron file %s.\n", file);
exit(1);
}
}
if(progress)
fprintf(stderr, ".\n"); /* Output final progress indicator. */
if(obuf)
free(obuf);
if(hfile && filename)
fclose(hfile);
%}
MCDISPLAY
%{
/* Invisible component. */
%}
END
|