/******************************************************************************* * * McStas, the neutron ray-tracing package: Vitess_input.comp * Copyright 1997-2001 Risoe National Laboratory, Roskilde, Denmark * * Component: Vitess_input * * %I * Written by: Kristian Nielsen * Date: June 6, 2000 * Version: $Revision: 1.18 $ * Origin: McStas 1.5.0 * Release: McStas 1.6 * Modified by: E. Farhi, Sep 28th, 2001: added spin * * Read neutron state parameters from VITESS neutron file. * * %D * Source-like component reading neutron state parameters from a * VITESS neutron file. Used to interface McStas components or * simulations into VITESS. Each neutron is 104 bytes. * * Example: Vitess_input(file="MySource.vit", bufsize = 10000, repeat_count = 2) * * %P * INPUT PARAMETERS * * file: Filename of neutron file to read. Default is * standard input [string] * bufsize: Size of neutron input buffer [records] * repeat_count: Number of times to repeat each neutron read [1] * * OUTPUT PARAMETERS * * finished: Set to 1 when the last neutron has been read [int] * * %E *******************************************************************************/ DEFINE COMPONENT Vitess_input DEFINITION PARAMETERS (file = 0) SETTING PARAMETERS (int bufsize = 10000, repeat_count = 1) OUTPUT PARAMETERS (hfile, buf, size, pos, rep, finished) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) POLARISATION PARAMETERS (sx,sy,sz) SHARE %{ %include "general" %include "vitess-lib" %} DECLARE %{ FILE *hfile; /* Neutron input file handle */ Neutron *buf; /* Neutron input buffer */ int size; /* Number of neutrons currently in buffer */ int pos; /* Current position in buffer */ int rep; /* Neutron repeat count */ int finished; /* Set to 1 when last neutron read */ %} INITIALIZE %{ /* Open neutron input file. */ if(file) hfile = fopen(file, "rb"); else hfile = stdin; if(!hfile) { fprintf(stderr, "Vitess_input: Error: Cannot open input file.\n"); exit(1); } /* Allocate neutron input buffer. */ buf = calloc(bufsize, sizeof(Neutron)); if(!buf) { fprintf(stderr, "Vitess_input: Error: Cannot allocate neutron buffer.\n"); exit(1); } /* Initialize buffer. */ size = 0; pos = 0; rep = 0; finished = 0; %} TRACE %{ if(pos >= size) { /* Buffer is empty. */ size = fread(buf, sizeof(Neutron), bufsize, hfile); if(size <= 0) { if(ferror(hfile)) fprintf(stderr, "Vitess_input: Error during read of neutron file.\n"); if(feof(hfile) || ferror(hfile)) finished = 1; /* End of file or error reached */ } else { pos = 0; /* Reposition at start of buffer */ } } /* When no more neutron records are available in the neutron file, any remaining iterations are skipped by immediately ABSORB'ing the neutron. */ if(finished) ABSORB; vitess2mcstas(buf[pos], &x, &y, &z, &vx, &vy, &vz, &t, &sx, &sy, &sz, &p); /* Repeat the same neutron state parameters the required number of times. */ ++rep; if(rep >= repeat_count) { rep = 0; ++pos; } %} FINALLY %{ if(buf) free(buf); if(hfile && file) fclose(hfile); %} MCDISPLAY %{ /* Invisible component. */ %} END