public SingleMaterialMonteCarlo() { double energyEV = 1000000; System.out.println("energy " + energyEV / 1000000 + " MeV"); double photo = material.getAttenuation(energyEV / 1000, AttenuationType.PHOTOELECTRIC_ABSORPTION); double compton = material.getAttenuation(energyEV / 1000, AttenuationType.INCOHERENT_ATTENUATION); System.out.println("cross section photo: " + photo + "cm" + " compton " + compton + "cm"); System.out.println("mean free path compton " + 1 / compton + "cm"); System.out.println("mean free path photo " + 1 / photo + "cm"); double totalCrossSection = material.getAttenuation( energyEV / 1000, AttenuationType.TOTAL_WITHOUT_COHERENT_ATTENUATION); System.out.println("total attenuation " + 1 / totalCrossSection + "cm"); System.out.println("total attenuation sum " + 1 / (photo + compton) + "cm"); raytrace(energyEV, numRays); double mean = XRayTracer.computeMean(pathlengths); double stddev = XRayTracer.computeStddev(pathlengths, mean); System.out.println("pathlength = " + mean + " +- " + stddev); mean = XRayTracer.computeMean(xs); stddev = XRayTracer.computeStddev(xs, mean); System.out.println("x = " + mean + " +- " + stddev); mean = XRayTracer.computeMean(ys); stddev = XRayTracer.computeStddev(ys, mean); System.out.println("y = " + mean + " +- " + stddev); mean = XRayTracer.computeMean(zs); stddev = XRayTracer.computeStddev(zs, mean); System.out.println("z = " + mean + " +- " + stddev); // rayTrace(800000, numRays); // visualize the klein-nishina angle distribution and the rejection // sampling for different energies // visualizeKleinNishina(10000000*eV); visualizeKleinNishina(140000 * eV); // visualizeKleinNishina(2.75*eV); // // visualizeKleinNishina(55000*eV); }
private void followRay( SimpleVector pos, SimpleVector dir, double energyEV, FloatProcessor imp, int scatterCount, double totalDistance) { if (energyEV <= 1 || scatterCount > 20000) { System.out.println("energy low, times scattered: " + scatterCount); return; } // follow ray until next interaction point SimpleVector oldPos = pos.clone(); double dist = sampler.getDistanceUntilNextInteractionCm(material, energyEV); pos.add(dir.multipliedBy(dist)); pathlengths.add(dist); // draw the entire path // imp.drawLine((int)(scale*oldPos.getElement(0)), (int)(scale*oldPos.getElement(1)), // (int)(scale*pos.getElement(0)), (int)(scale*pos.getElement(1))); // draw interaction points only imp.drawDot((int) (scale * pos.getElement(0)), (int) (scale * pos.getElement(1))); // choose compton or photoelectric effect double photo = material.getAttenuation(energyEV / 1000, AttenuationType.PHOTOELECTRIC_ABSORPTION); double compton = material.getAttenuation(energyEV / 1000, AttenuationType.INCOHERENT_ATTENUATION); if (sampler.random() * (photo + compton) <= photo) { // photoelectric absorption energyEV = 0; // System.out.println("absorbed after " + scatterCount + " collisions"); xs.add(pos.getElement(0)); ys.add(pos.getElement(1)); zs.add(pos.getElement(2)); return; } else { // compton scattering energyEV = sampler.sampleComptonScattering(energyEV, dir); // send new ray followRay(pos, dir, energyEV, imp, scatterCount + 1, totalDistance + dist); } }
public static synchronized void updateAttenuationCoefficientsMap( HashMap<Material, double[]> attenuationCoefficientsMap, double[] energies, Material mat, AttenuationType att) { double[] attenuation = new double[energies.length]; try { for (int j = 0; j < attenuation.length; j++) { attenuation[j] = mat.getAttenuation(energies[j], att); } attenuationCoefficientsMap.put(mat, attenuation); } catch (NoSuchElementException e) { System.out.println( "Skipping " + mat + " as attenuation data is incomplete for the configured energies."); } catch (NullPointerException e2) { System.out.println("Skipping " + mat + " as attenuation data is incomplete."); } }