-- $Id: xss_distance_01.lua,v 1.5 1998/04/29 21:17:23 dj Exp dj $ -- -- xss_distance: returns the distance from an XSS source to CAP -- datum A in mm. upon error it calls error() with an appropriate -- message. -- -- Parameters: -- -- For EIPS, HIREFS, and PIGS sources call the function as either -- d = xss_distance( 'EIPS' ) -- d = xss_distance( 'PIGS' ) -- or -- d = xss_distance( 'HIREFS' ) -- -- For the DCM source, if you know the glancing angle, -- call it as -- d = xss_distance( 'DCM', ga ) -- -- If you don't know the glancing angle, you'll need to specify -- the crystal and either the requested energy or wavelength. -- The crystal is one of 'TAP', 'Ge', or 'Al'. The energy is -- in keV, and the wavelength is in Angstroms. -- -- d = xss_distance( 'DCM', crystal, 'energy', energy ) -- d = xss_distance( 'DCM', crystal, 'wavelength', wavelength ) -- -- -- All constants and formulae are taken from -- http://wwwastro.msfc.nasa.gov/xray/xraycal/distance.htm -- on Wed Apr 29 15:28:49 EDT 1998. It is archived in distance.htm -- -- Author: D. Jerius function xss_distance( source, ... ) local distance, func local EIPS_distance, PIGS_distance, DCM_45_distance local spacing, node2datumA -- distances to HRMA node [m] EIPS_distance = 527.522 PIGS_distance = 527.895 HIREFS_distance = 527.414 DCM_45_distance = 528.439 -- crystal lattice spacing [Angstrom] spacing = { TAP = 12.8784, Ge = 3.26643, Si = 1.35776 } -- distance from HRMA node to CAP datum A [m] node2datumA = -0.018 func = 'xss_distance: ' if ( source == 'EIPS' ) then distance = EIPS_distance elseif ( source == 'PIGS' ) then distance = PIGS_distance elseif ( source == 'HIREFS' ) then distance = HIREFS_distance elseif ( source == 'DCM' ) then local ga -- figure out how this is being called -- just the glancing angle if ( 1 == arg.n and 'number' == type(arg[1]) ) then ga = arg[1] -- must be specifying a crystal elseif ( nil ~= spacing[arg[1]] ) then local wavelength local unit = arg[2] local value = arg[3] local crystal = arg[1] -- energy or wavelength? if ( 'energy' == unit ) then local hc = 12.3980 -- planck's constant * speed of light in keV Angstroms if ( 'number' ~= type( value ) ) then error( func .. 'illegal value for energy: ' .. value ) end wavelength = hc / value elseif ( 'wavelength' == unit ) then if ( 'number' ~= type( value ) ) then error( func .. 'illegal value for wavelength: ' .. value ) end wavelength = value else error ( func .. 'unknown DCM unit: ' .. unit ) end ga = asin( wavelength / spacing[crystal] / 2 ) else error( func .. "unknown DCM option: " .. arg[1]) end distance = DCM_45_distance + 0.030 * ( 1/sin(2 * ga) - cos(2 * ga)/sin(2 * ga) - 1 ) end return 1000 * ( distance + node2datumA ) end $if nil print ( xss_distance( 'EIPS' ) ) print ( xss_distance( 'PIGS' ) ) print ( xss_distance( 'DCM', 'TAP', 'energy', 2.315 ) ) print ( xss_distance( 'DCM', 'Ge', 'energy', 9.128 ) ) print ( xss_distance( 'DCM', 'Si', 'energy', 21.959 ) ) print ( xss_distance( 'DCM', 'TAP', 'energy', 0.819 ) ) print ( xss_distance( 'DCM', 'Ge', 'energy', 3.229 ) ) print ( xss_distance( 'DCM', 'Si', 'energy', 7.768 ) ) print ( xss_distance( 'DCM', 12 ) ) print ( xss_distance( 'DCM', 'foo' ) ) print ( xss_distance( 'DCM', 'Ge', 'foo' ) ) print ( xss_distance( 'DCM', 'Ge', 'energy', 'foo' ) ) print ( xss_distance( 'DCM', 'Ge', 'wavelength', 'foo' ) ) $end