/* * Copyright (C) 2010-2014 Rotimi X Ojo, Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */ package edu.stanford.rsl.conrad.physics.materials.materialsTest; import junit.framework.Assert; import org.junit.Test; import edu.stanford.rsl.conrad.physics.materials.Material; import edu.stanford.rsl.conrad.physics.materials.database.FormulaToNameMap; import edu.stanford.rsl.conrad.physics.materials.database.MaterialsDB; import edu.stanford.rsl.conrad.physics.materials.database.OnlineMassAttenuationDB; import edu.stanford.rsl.conrad.physics.materials.utils.AttenuationType; import edu.stanford.rsl.conrad.physics.materials.utils.LocalMassAttenuationCalculator; import edu.stanford.rsl.conrad.physics.materials.utils.WeightedAtomicComposition; /** * <p>Class for comparing the results from local mass attenuation calculator with online mass attenuation calculation from XCOM</p> * <p>Class asserts that Max Error < 3%, in reality maximum error is significantly less than this value in most materials. * @author Rotimi X Ojo * @author Andreas Maier * */ public class TestMassAttenuationData { @Test public void reportPredefinedMaterials(){ String [] materials = MaterialsDB.getPredefinedMaterials(); System.out.println("Number of predefined materials:" + materials.length); for (String material:materials) System.out.println(material); // Standard configuration of CONRAD comes with at least 105 known materials. Assert.assertTrue(materials.length > 104); } @Test public void reportKnownMaterials(){ String [] materials = MaterialsDB.getMaterials(); System.out.println("Number of known materials:" + materials.length); for (String material:materials) System.out.println(material); // Standard configuration of CONRAD comes with at least 105 known materials. Assert.assertTrue(materials.length > 104); } @Test public void testMaterialMassAttenutationCalculator(){ System.out.println("Testing LocalMassAttenuationCalculator Accuracy: " ); String [] identifiers = FormulaToNameMap.map.keySet().toArray(new String[FormulaToNameMap.map.size()]); int numEnergies = 1000; int maxEnergy = 100000; for(int i =0; i < 1/*identifiers.length*/; i++){ String iden = identifiers[i]; System.out.println("\tTesting " + iden); Material mat = MaterialsDB.getMaterial(iden); //double [] results1 = testKnownMaterials(mat,AttenuationType.TOTAL_WITHOUT_COHERENT_ATTENUATION,numEnergies, maxEnergy); testKnownMaterials(mat,AttenuationType.TOTAL_WITH_COHERENT_ATTENUATION,numEnergies, maxEnergy ); //double [] results3 = testKnownMaterials(mat,AttenuationType.COHERENT_ATTENUATION,numEnergies, maxEnergy); //double [] results4 = testKnownMaterials(mat,AttenuationType.INCOHERENT_ATTENUATION,numEnergies, maxEnergy); //double [] results5 = testKnownMaterials(mat,AttenuationType.NUCLEAR_FIELD_PAIRPRODUCTION,numEnergies, maxEnergy); //double [] results6 = testKnownMaterials(mat,AttenuationType.PHOTOELECTRIC_ABSORPTION,numEnergies, maxEnergy); } System.out.println("Testing Completed" ); } /** * Compare local and online mass attenuation values of know materials * @param mat is material of interest * @param att is attenuation of interest * @param numEnergies is energies to be tested */ public static double [] testKnownMaterials(Material mat,AttenuationType att, int numEnergies, int maxEnergy) { return testArbitraryMaterial(mat.getWeightedAtomicComposition(), att, numEnergies, maxEnergy); } /** * CompareCompare local and online mass attenuation values of arbitrarily defined material * @param formula is chemical formula of material * @param att is attenuation of interest * @param numEnergies */ public static double [] testArbitraryMaterial(String formula, AttenuationType att, int numEnergies, int maxEnergy){ return testArbitraryMaterial(new WeightedAtomicComposition(formula), att, numEnergies, maxEnergy); } /** * CompareCompare local and online mass attenuation values of arbitrarily defined material * @param comp is weighted atomic composition * @param att is attenuation of interest * @param numEnergies */ public static double [] testArbitraryMaterial(WeightedAtomicComposition comp, AttenuationType att, int numEnergies, int maxEnergy){ System.out.println("\t\tTesting " + att); double [] energies = new double[numEnergies]; for(int i = 0;i < energies.length;i++){ energies[i] = (Math.random()*maxEnergy) + 1; } double maxError = 0; double minError = Double.MAX_VALUE; double errorSum = 0; int nonZeroErrorCount = 0; for(double energy:energies){ double val = OnlineMassAttenuationDB.getMassAttenuationData(comp, energy/1000, att); double val2 = LocalMassAttenuationCalculator.getMassAttenuationData(comp, energy/1000, att); double error = Math.abs(val-val2)/val; if(error > maxError ){ maxError = error; } if(error < minError){ minError = error; } if(error > 0){ nonZeroErrorCount++; errorSum+= error; } } double meanErr = errorSum/nonZeroErrorCount; assert(maxError < 3); double [] results = {minError,maxError,meanErr}; System.out.println("Min Error is: " + minError + "%"); System.out.println("Max Error is: " + maxError+ "%"); System.out.println("Mean Error is: " + meanErr+ "%"); return results; } }