/******************************************************************************* * * McStas, neutron ray-tracing package * Copyright 1997-2002, All rights reserved * Risoe National Laboratory, Roskilde, Denmark * Institut Laue Langevin, Grenoble, France * Component: Virtual_output * * %I * Written by: E. Farhi * Date: Dec 17th, 2002 * Version: $Revision: 1.13 $ * Origin: ILL * Release: McStas 1.6 * Modified by: E. Farhi, Dec 17th, 2002: based on Vitess_output and Monitor_nD lib. * * Detector-like component that writes neutron state parameters into a 'virtual * source' neutron file. * * %D * Detector-like component writing neutron state parameters to a * virtual source neutron file. The component geometry is the full * plane, and saves the neutron state as it exits from the previous * component. * * It is particularly useful to generate a virtual source at a point that few * neutron reach. A long simulation will then only be performed once, to create * the upstream 'source' file. Further simulations are much faster if they start * from this low flux position with the 'source' file. * * Possible file formats are: * 1-text column formatted with lines containing 11 values in the order: * p x y z vx vy vz t sx sy sz stored into about 83 bytes/n. * 2-float/double binary files (with the 11 values 'p x y z vx vy vz t sx sy sz') * stored into 44 and 88 bytes/n respectively for float/double. * * Beware the size of generated files ! When saving all events (bufsize=0) the * required memory has been optimized and remains very small. On the other hand * using large bufsize values (not recommanded) requires huge storage memory. * Moreover, using the 'bufsize' parameter will often lead to wrong intentities. * Both methods will generate huge files. * * A Vitess file may be obtained from the 'Vitess_output' component or from a * Vitess simulation (104 bytes per neutron) and read with Vitess_input. * * Example: Virtual_output(file="MySource.dat") * will generate a 9 Mo text file for 1e5 events stored. * * %BUGS * Using bufsize non-zero generates a virtual source with wrong intensity * * %P * INPUT PARAMETERS * * file: [str] Filename of neutron file to write. Default is standard * output [string]. If not given, a unique name will be used. * bufsize:[1] Size of neutron output buffer * default is 0, i.e. save all - recommanded. * type: [str] Type of output file 'text','float','double' * default is text * * %E *******************************************************************************/ DEFINE COMPONENT Virtual_output DEFINITION PARAMETERS (file=0, type=0) SETTING PARAMETERS (bufsize=0) OUTPUT PARAMETERS (DEFS, Vars, mcformat_sim, mcformat_vo, mcformat_override) STATE PARAMETERS (x,y,z,vx,vy,vz,t,s1,s2,p) POLARISATION PARAMETERS (sx,sy,sz) SHARE %{ %include "monitor_nd-lib" %} DECLARE %{ MonitornD_Defines_type DEFS; MonitornD_Variables_type Vars; struct mcformats_struct mcformat_sim; struct mcformats_struct mcformat_vo; char mcformat_override; %} INITIALIZE %{ long element_size; strcpy(Vars.compcurname, NAME_CURRENT_COMP); if (bufsize > 0) sprintf(Vars.option, "list=%g", bufsize); else strcpy(Vars.option, "list all"); if (type) { if (strstr(type, "Vitess")) { fprintf(stderr, "Virtual_output: %s: Vitess files may be generated using the Vitess_output component\n", NAME_CURRENT_COMP); exit(-1); } if (strstr(type, "binary") || strstr(type, "float")) { strcat(Vars.option, ", binary float"); element_size = sizeof(float); } else if (strstr(type, "double")) { strcat(Vars.option, ", binary double"); element_size = sizeof(double); } else element_size = 85; } strcat(Vars.option,", x y z vx vy vz t sx sy sz"); Monitor_nD_Init(&DEFS, &Vars, 0.1, 0.1, 0, 0,0,0,0,0,0); /* dims for mcdisplay */ if (file != NULL) strncpy(Vars.Mon_File, file, 128); mcformat_override = !strstr(Vars.option, "binary"); mcformat_sim = mcformat; mcformat_vo = mcuse_format("McStas"); if (bufsize > 0) { printf("Warning: Virtual_output: %s: buffer size=%g not recommanded\n" " Beware virtual output generated file size (about %g Mo)\n" " Memory required is about %g Mo\n", NAME_CURRENT_COMP, bufsize, bufsize*element_size/1e6, bufsize*sizeof(double)/1e6); } %} TRACE %{ double pp; PROP_Z0; /* transfert current neutron to Monitor_nD vars */ 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 (mcformat_override) mcformat = mcformat_vo; pp = Monitor_nD_Trace(&DEFS, &Vars); if (mcformat_override) mcformat = mcformat_sim; Vars.Nsum++; Vars.psum += pp; Vars.p2sum += pp*pp; SCATTER; %} SAVE %{ if (mcformat_override) mcformat = mcformat_vo; Monitor_nD_Save(&DEFS, &Vars); if (mcformat_override) mcformat = mcformat_sim; %} FINALLY %{ /* free pointers */ Monitor_nD_Finally(&DEFS, &Vars); if (bufsize) { printf("Virtual_output: %s: Saved %li events in file %s\n" "WARNING When using this source, intensities must be divided\n" " by a factor %g\n", NAME_CURRENT_COMP, Vars.Buffer_Block, Vars.Mon_File, Vars.Nsum/bufsize); } else printf("Virtual_output: %s: Saved %15f events (all) in file %s\n", NAME_CURRENT_COMP, Vars.Nsum, Vars.Mon_File); %} MCDISPLAY %{ Monitor_nD_McDisplay(&DEFS, &Vars); %} END