/***********************************************************************
*
* McStas, neutron ray-tracing package
* Copyright 1997-2002, All rights reserved
* Risoe National Laboratory, Roskilde, Denmark
* Institut Laue Langevin, Grenoble, France
*
* Component: Filter_gen
* %I
* Written by: E. Farhi
* Date: Dec, 15th, 2002
* Version: $Revision$
* Origin: ILL
* Release: McStas 1.6
*
* This components may either set the flux or change it (filter-like), using
* an external data filename.
*
* %D
* This component changes the neutron flux (weight) in order to match
* a reference table in a filename.
* Typically you may set the neutron flux (source-like), or multiply it
* using a transmission table (filter-like).
* The component may be placed after a source, in order to e.g.
* simulate a real source from a reference table, or used as a filter (BeO)
* or as a window (Al). The behaviour of the component is
* specified using the 'options' parameter, or from the filename itself (see below)
* If the thickness for the transmission data filename D was t0, and a different
* thickness t1 would be required, then the resulting transmission is:
* D^(t1/t0).
* You may use the 'thickness' and 'scaling' parameter for that purpose.
*
* File format:
* This filename may be of any 2-columns free format (k[Angs-1],p), (omega[meV],p)
* and (lambda[Angs],p) where p is the weight. The type of the filename may be
* written explicitely in the filename, as a comment, or using the 'options'
* parameter.
* Non mumerical content in filename is treated as comment (e.g. lines starting
* with '#' character).
* A table rebinning and linear interpolation are performed.
*
* EXAMPLE : in order to simulate a PG filter, using the lib/data/HOPG.trm file
* Filter_gen(xwidth=.1 yheight=.1, filename="HOPG.trm")
* A Sapphire filter, using the lib/data/Al2O3_sapphire.trm file
* Filter_gen(xwidth=.1 yheight=.1, filename="Al2O3_sapphire.trm")
* A Berylium filter, using the lib/data/Be.trm file
* Filter_gen(xwidth=.1 yheight=.1, filename="Be.trm")
* an other possibility to simulate a Be filter is to use the PowderN component:
* PowderN(xwidth=.1, yheight=.1, zdepth=.1, reflections="Be.laz", p_inc=1e-4)
*
* in this filename, the comment line
* # wavevector multiply
* sets the behaviour of the component. One may as well have used
* options="wavevector multiply"
* in the component instance parameters.
*
*%P
* filename: [str] name of the filename to look at (first two columns data). Data D should rather be sorted (ascending order) and monotonic filename may contain options (see below) as comment
* options: [str] string that can contain: "[ k p ]" or "wavevector" for filename type, "[ omega p]" or "energy", "[ lambda p ]" or "wavelength", "set" to set the weight according to the table,"multiply" to multiply (instead of set) the weight by factor,"add" to add to current flux,"verbose" to display additional informations.
* thickness: [1] relative thickness. D = D^(thickness).
* scaling: [1] scaling factor. D = D*scaling.
* xmin: [m] dimension of filter
* xmax: [m] dimension of filter
* ymin: [m] dimension of filter
* ymax: [m] dimension of filter
* xwidth: [m] Width/diameter of filter). Overrides xmin,xmax.
* yheight: [m] Height of filter. Overrides ymin,ymax.
* verbose: [1] Flag to select verbose output.
*
* %L
* HOPG.trm filename as an example.
*%E
***********************************************************************/
DEFINE COMPONENT Filter_gen
DEFINITION PARAMETERS ()
SETTING PARAMETERS (string filename=0, string options=0, xmin=-0.05, xmax=0.05, ymin=-0.05, ymax=0.05,
xwidth=0, yheight=0, thickness=1, scaling=1, verbose=0)
OUTPUT PARAMETERS ()
/* Neutron parameters: (x,y,z,vx,vy,vz,t,sx,sy,sz,p) */
SHARE
%{
#ifndef FILTER_GEN
#define FILTER_GEN $Revision$
#define UNKNOWN_TABLE 0
#define ENERGY_TABLE 1
#define WAVEVECTOR_TABLE 2
#define WAVELENGTH_TABLE 3
#define FLUX_ADAPT_SET 0
#define FLUX_ADAPT_MULT 1
#define FLUX_ADAPT_ADD 2
char FilterGen_Mode(char *str, char *Mode, char *Type, double *verbose)
{
long i;
char *c;
if (!str || !strlen(str)) return(0);
c = malloc(strlen(str));
for (i=0; i 0) { xmax = xwidth/2; xmin = -xmax; }
if (yheight > 0) { ymax = yheight/2; ymin = -ymax; }
FilterGen_Mode(options, &Mode_Table, &Type_Table, &verbose);
if (filename != NULL && strlen(filename) && strcmp(filename,"NULL") && strcmp(filename,"0"))
{
if (Table_Read(&pTable, filename, 1) <= 0) /* read 1st block data from filename into pTable */
exit(fprintf(stderr,"Filter_gen: %s: can not read filename %s\n", NAME_CURRENT_COMP, filename));
Table_Rebin(&pTable); /* rebin as evenly, increasing array */
if (pTable.rows < 2 || !pTable.step_x) {
Table_Free(&pTable);
}
if (pTable.data)
{
FilterGen_Mode(pTable.header, &Mode_Table, &Type_Table, &verbose);
if (verbose)
{
Table_Info(pTable);
printf("Filter_gen: %s: Filter data [", NAME_CURRENT_COMP);
if (Type_Table == ENERGY_TABLE) printf("Energy");
if (Type_Table == WAVEVECTOR_TABLE) printf("Wavevector");
if (Type_Table == WAVELENGTH_TABLE) printf("Wavelength");
if (Type_Table == UNKNOWN_TABLE) printf("UNKNOWN (not used)");
printf(", Flux] in ");
if (Mode_Table == FLUX_ADAPT_MULT) printf("multiply");
else if (Mode_Table == FLUX_ADAPT_ADD) printf("add");
else printf("set");
printf(" mode\n");
}
} else fprintf(stderr,"Filter_gen: %s: file %s contains no data.\n", NAME_CURRENT_COMP, filename);
} else pTable.data = NULL;
%}
TRACE
%{
double v2, K, L, E, X, new_p;
PROP_Z0;
if (Type_Table && (x>xmin && xymin && y