Contents
- Process 'Energy' Input Parameter
- Process 'Material' Input Parameter
- Process 'Options' Input Parameter
- Process 'Thickness' Input Parameter
- Initialize output variables
- Main Loop: preform calculation for each material
- Parse material
- Look up the data, average contributions of different elements and save
- Lookup density and atomic molar mass if needed
- Calculate Transmission if needed
- if Energy has a spectrum than integrate
- Cast output in a chosen format
function X = PhotonAttenuation(Material, Energy, Options, Thickness)
% PhotonAttenuation provides photon attenuation in different materials. % % X = PhotonAttenuation(Material, Energy, Options, Thickness) % Function providing the attenuation and energy absorption of x-ray and % gamma-ray photons in various materials including mixtures and compounds, % based on NIST report 5632, by J. Hubbell and S.M. Seltzer. % % Input : % 1) Material - string, number or array of strings, numbers or cells % describing material type. % - Element atomic number Z - in 1 to 100 range % - Element symbols - 'Pb', 'Fe' % - Element names - 'Lead', 'Iron', 'Cesium' or 'Caesium' % - Some common names and full compound names - 'Water', 'Polyethylene' % (see function PhysProps for more details) % - Compound formulas - 'H2SO4', 'C3H7NO2'- those are case sensitive % - Mixtures of any of above with fractions by weight - like % 'H(0.057444)C(0.774589)O(0.167968)' for Bakelite or % 'B(10)H(11)C(58)O(21)' for Borated Polyethylene (BPE-10) % 2) Energy - Energy of the photons. Can be single energy or vector of % energies. Several formats are allowed: % - Energy in MeV, should be in [0.001, 20] MeV range. % - Wavelengths in nano-meters. Encoded as negative numbers. The valid % range is 6.1982e-5 to 1.2396 nm; % - Continuous Spectrum - Encoded in 2 columns: column one contains % energy in MeV and column two contains relative number of photons at that % energy. Spectrum is assumed to be continuous and output is % calculated through integration using 'trapz' function. % 3) Options - specifies what to return. String or number: % 1 - 'mac' - function returns Mass Attenuation Coefficients in cm^2/g % 2 - 'meac' - function returns Mass Energy-Absorption Coefficients % in cm^2/g. See link below for more info: % http://physics.nist.gov/PhysRefData/XrayMassCoef/chap3.html % 3 - 'cross section' or 'x' - function returns cross section in barns per % atom (convert to cm^2 per atom by multiplying by 10^-24). % Available only for elements. % 4 - 'mean free path' or 'mfp' - function returns mean free path (in cm) of % photon in the given material . Available only for chemicals % recognized by 'PhysProps' function (since density is needed). % 5 - 'transmission' or 't' - fraction of protons absorbed by given thickness % of material % 6 - 'ln_T' - log of transmission % 7 - 'lac' - Linear Attenuation Coefficients in 1/cm same as 1/(Cross % Section) or mac*density. % 8 - 'half value layer' or 'hvl' - function returns half-value layer (in cm) of % photon in the given material . Available only for chemicals % recognized by 'CompoundProps' function (since density is needed). % 9 - 'tenth value layer' or 'tvl' - analogous to 'hvl' . % 4) Thickness - Thickness of material in cm. Either scalar or vector of % the same length as number of materials. Negative numbers indicate % mass thickness measured in g/cm^2 (density*thickness). Needed only % if energy spectrum is used or in case of Options set to % 'Transmission'. % Output : % X - output depends on 'Options' parameter. Columns always correspond % to the materials and rows correspond to energy. In case of spectrum % input only single row is returned. % % History: % Written by Jarek Tuszynski (SAIC), 2006 % Updated by Jarek Tuszynski (Leidos), 2014, jaroslaw.w.tuszynski@leidos.com % Inspired by John Schweppe Mathematica code available at % http://library.wolfram.com/infocenter/MathSource/4267/ % Tables are based on NIST's XAAMDI and XCOM databases. See % PhotonAttenuationQ function for more details. % % Examples: % %% Plot Cross sections of elements for different energy photons % figure % Z = 1:100; % elements with Z in 1-100 range % E = logspace(log10(0.001), log10(20), 500); % define energy grid % X = PhotonAttenuation(Z, E, 'cross section'); % imagesc(log10(X)); colorbar; % title('Cross sections of elements for different energy photons'); % xlabel('Atomic Number of Elements'); % ylabel('Photon Energy in MeV'); % set(gca,'YTick',linspace(1, length(E), 10)); % set(gca,'YTickLabel',1e-3*round(1e3*logspace(log10(0.001), log10(20), 10))) % % %% Plot Photon Attenuation Coefficients, using different input styles % figure % E = logspace(log10(0.001), log10(20), 500); % define energy grid % Z = {'Concrete', 'Air', 'B(10)H(11)C(58)O(21)', 100, 'Ag'}; % mac = PhotonAttenuation(Z, E, 'mac'); % loglog(E, mac); % legend({'Concrete', 'Air', 'BPE-10', 'Fermium', 'Silver'}); % ylabel('Attenuation in cm^2/g'); % xlabel('Photon Energy in MeV'); % title('Photon Attenuation Coefficients for different materials');
Process 'Energy' Input Parameter
s = size(Energy); nEnergy = prod(s); Spectrum = []; if (min(s)==2) if (s(1)==2), Energy=Energy'; end Spectrum = Energy(:,2); Energy = Energy(:,1); Spectrum = Spectrum / trapz(Energy, Spectrum); % normalize spectrum nEnergy = 1; % this is a spectrum output will be an array instead of matrix end Energy = Energy(:); if (any(Energy<0)) idx = find(Energy<0); PlanckConstant = 4.1350e-021; % Planks constant in MeV*sec SpeedOfLight = 299792458E9; % in nano meters per second WaveLength = -Energy(idx); Energy(idx) = (PlanckConstant*SpeedOfLight) ./ WaveLength; end if (any(Energy<0.0009) || any(Energy>21)) warning('PhotonAttenuation:wrongEnergy',... 'Warning in PhotonAttenuation function: energy is outside of the recomended range from 0.001 MeV to 20 MeV'); end
Error using PhotonAttenuation (line 93) Not enough input arguments.
Process 'Material' Input Parameter
if (ischar (Material)), Material = {Material}; end if (isnumeric(Material)), Material = num2cell(Material); end nMaterial = length(Material);
Process 'Options' Input Parameter
OptNames = {'mac','meac', 'cross section', 'mean free path', 'transmission', 'ln_t', 'lac', 'half value layer', 'tenth value layer', ... 'mac','meac', 'x', 'mfp', 't', 'log_t', 'lac', 'hvl', 'tvl'}; nOpt = length(OptNames)/2; if (nargin<3), Options = 1; end if (ischar(Options)) Options = find(strcmpi( Options, OptNames),1); if (Options>nOpt), Options=Options-nOpt; end else if (Options>nOpt), Options=[]; end end if (isempty(Options)) error(['Error in PhotonAttenuation function: Options parameter was not recognized: ', Options]); end param = (Options==2)+1; % param=2 if Option==2 and param=1 otherwise
Process 'Thickness' Input Parameter
if (nargin<4), Thickness=1; end if (length(Thickness)==1 && nMaterial>1) Thickness = repmat(Thickness(1), 1, nMaterial); end if (length(Thickness)>1 && nMaterial==1) nMaterial = length(Thickness); Material = repmat(Material(1), 1, nMaterial); end if (length(Thickness)~=nMaterial) error('Error in PhotonAttenuation function: missmatch between lengths or Material and Thickness arrays'); end
Initialize output variables
if (isempty(Spectrum)), X = zeros(nEnergy,nMaterial); else X = zeros(1 ,nMaterial); end u = 1.6605402E-24 ; % atomic mass unit (1/12 of the mass of C-12) barns = 1E24; % barns
Main Loop: preform calculation for each material
old_material = [];
for iMat = 1:nMaterial
Parse material
VARIABLES: Z - array of element numbers contained in the material Ratios - array of element ratios in the material MatStr - string representation of the material
material = Material{iMat}; if (isempty(material)) error('Error in PhotonAttenuation function: compound formula was empty'); end if (~isempty(old_material) && length(old_material)==length(material) && all(old_material==material)) if (Option<3 && isempty(Spectrum)) % a shortcut for common configuration X(:,iMat) = mu; continue; end end if (ischar(material)) % check if this is element name or known compound [Z, Ratios] = ParseChemicalFormula(material); if (isempty(Z)) error(['Error in PhotonAttenuation function: compound formula was not recognized: ', material]); end MatStr = material; elseif (isnumeric(material)) Z = material; Ratios = 1; MatStr = num2str(material); else error('Error in PhotonAttenuation function: compound formula was not recognized.'); end if (length(Z)>1 && Options==3) error('Error in PhotonAttenuation function: Cross section "Option" is only supported for elements.'); end
Look up the data, average contributions of different elements and save
mu = PhotonAttenuationQ(Z, Energy, param); old_material = material; % old_material will store the name of material for which we calculated mu Ratios = Ratios(:) / sum(Ratios); % normalize ratios so they add up to one % if mu is 2D (spectrum and compound) it will become 1D % if mu is 1D (because of compound) it will become scalar % if mu is 1D (because of spectrum) it will not change % if mu is a scalar (monoenergetic & element) it will not change mu = mu * Ratios;
Lookup density and atomic molar mass if needed
if (Options>=3 || ~isempty(Spectrum)) PP = PhysProps(material); Density = PP{1,2}; A = Z/PP{1,1}; % atomic molar mass in g/mol if (Options>3 && isnan(Density)) error(['Error in PhotonAttenuation function: Physical properties of "',... MatStr,'" not found in PhysProps function.']); end if (Options==3 && isnan(A)) % calculate <Z/A> and atomic molar mass P = PhysProps(Z); ZA = [P{:,1}]'; % extract <Z/A> of all elements in the compound A = Z/dot(R,ZA); % atomic molar mass in g/mol if (isnan(A)) error(['Error in PhotonAttenuation function: Physical properties of "',... MatStr,'" not found in PhysProps function.']); end end end
Calculate Transmission if needed
if (Options==5 || Options==6 || ~isempty(Spectrum)) % a shortcut for common configuration if(Thickness(iMat)>0), MassThick = Thickness(iMat)*Density; % mass thickness measured in g/cm^2 else MassThick = -Thickness(iMat); end % user provided linear thickness MassThick = max(MassThick, 1e-6); T = exp(-mu*MassThick); % always convert to transmission end
if Energy has a spectrum than integrate
if (~isempty(Spectrum)) T = trapz(Energy, T.*Spectrum); % integrate over energy (T become a scalar) mac = -log(T)/MassThick; else mac = mu; end
Cast output in a chosen format
switch (Options) case {1,2} % mac & meac x = mac; case 3 % 'cross section' x = mac * (barns*u*A); case 4 % 'mean free path' x = 1./(mac*Density); case 5 % 'transmission' x = T; case 6 % 'log T' x = -log(T); case 7 % 'linear attenuation coefficiant' x = mac*Density; case 8 % 'half-value layer' x = -log(0.5)./(mac*Density); case 9 % 'tenth-value layer' x = -log(0.1)./(mac*Density); end X(:,iMat) = x; if (any(isnan(X(:,iMat)))) error(['Error in PhotonAttenuation function: Physical properties of "',... MatStr,'" not found in PhysProps function.']); end
end