public JComplex generateF0(JVector Q, int Z, JComplex energyFormFactor) { JComplex f0 = new JComplex(0, 0); double fTemp = elementConstants[Z - 1][9]; for (int i = 1; i < 5; i++) { double ai = elementConstants[Z - 1][i]; double bi = elementConstants[Z - 1][i + 4]; fTemp += ai * Math.exp(-1 * bi * Math.pow((Q.length()) / (4 * Math.PI), 2)); } f0 = JComplex.add(energyFormFactor, fTemp); return f0; }
/** * This method searches through the "sf" folder which contains the complex scattering factors at a * number of energies in eV for the desired energy. These files were obtained from the Berkeley * National Lab. url http://henke.lbl.gov/optical_constants/asf.html The files that will be * searched only have energy values between 10eV and 30keV. If a selection of > 30keV is made then * a complex value of Z + 0*i will be returned. * * @param energyOrWavelength set to 0 for an Energy in eV input. set to 1 for a wavelength in * Angstroms input * @param findMe The energy or wavelength that is to be found in the list * @param Z The number of electrons in the element * @return The complex scattering factor for the desired energy or wavelength * @throws Exception If the energyOrWavelength toggle is < 0 or > 1 then an exception is thrown. * If Z < 0 or > 92 an exception is thrown. If E < 10 eV or lambda > 1238.174 Angstroms an * exception is thrown */ public JComplex getComplexF(int energyOrWavelength, double findMe, int Z) throws Exception { /* make sure the input is 0 or 1 */ if (energyOrWavelength < 0 || energyOrWavelength > 1) throw new Exception( "Your selection of " + energyOrWavelength + " does not fall within the constraints." + "\nIf you want energy, set the energyOrWavelength value to 0.\nIf you want wavelength, set the energyOrWavelength value to 1."); /* make sure the 0 < Z < 92 */ if (Z < 0 || Z > 92) throw new Exception( "Your selection of " + Z + " does not fall within the current number of elements. Please choose a Z such that 0 < Z < 92"); /* Declare the file reader */ FileReader fr = null; /* define Planck's constant in terms of eV*s */ double h = 4.13566733e-15; /* define the speed of light in terms of Angstroms / second */ double c = 2.99792458e18; /* If the user passes in a wavelength (energyOrWavelength == 1), convert the wavelength to an energy in eV */ double energyDesired; if (energyOrWavelength != 0) energyDesired = h * c / findMe; else energyDesired = findMe; /* Check to make sure that the energy or wavelength passed in is within the parameters available to this method. */ if (energyDesired < 10) throw new Exception( "Your choice of an energy or wavelength of " + energyDesired + " is too low. \nPlease choose an energy such that " + "E > 10eV or a wavelength such that lambda < 1238.174 Angstroms."); /* If the energy that is passed in is greater than 30keV or less than .413 Angstroms, return a real scattering value of the Z value and 0 for the complex scattering. * This is a reasonable approximation. If more exact numbers are needed, please reference http://www.nist.gov/physlab/data/ffast/index.cfm */ if (energyDesired > 30000) return new JComplex(Z, 0); /* get the abbreviation for the element based on the index i and make it lower case */ String abbreviation = elementNameAbbrev[Z - 1][0].toLowerCase(); /* find the location of the program by creating a new file "." and getting the path. Then take the substring that includes the path less the file name */ String findLocation = (new File(".").getAbsolutePath()); findLocation = findLocation.substring(0, findLocation.length() - 1); /* Initialize the file reader */ try { fr = new FileReader(new File(findLocation + "/sf/" + abbreviation + ".nff")); } catch (FileNotFoundException e) { System.out.println("Cannot find the .nff files"); e.printStackTrace(); } /* Declare a new scanner to parse the file 'name.nff' */ Scanner s = new Scanner(fr); /* skip the first line of the file */ if (s.next().compareTo("E(eV)") == 0) s.nextLine(); /* declare two variables to hold the current and previous values of the energy to compare them */ double energyCurrent = 0; double energyPrevious = 0; /* declare two JComplex numbers to hold the current and previous values of the complex scattering factors */ JComplex current = new JComplex(0., 0.); JComplex previous = new JComplex(0., 0.); /* if findMe is between two energies then take a percentage of the surrounding energies or wavelengths */ double howMuchOf1 = 0; double howMuchOf2 = 0; /* declare a boolean toggle to break out of the while loop */ boolean found = false; /* Loop through the file as long as the desired energy has not been found*/ while (found == false) { /* set the previous energy value to what used to be the current energy value */ energyPrevious = energyCurrent; /* set the previous scattering factor to what used to be the current scattering factor */ previous.setRe(current.getRe()); previous.setIm(current.getIm()); /* read energy */ energyCurrent = Double.valueOf(s.next()); /* read real and imaginary parts of the scattering factor */ current.setRe(Double.valueOf(s.next())); current.setIm(Double.valueOf(s.next())); /* test the current energy value to the target energy value */ if (energyCurrent > energyDesired) { /* get out of the loop */ found = true; /* how far away is the first energy */ howMuchOf1 = Math.abs(energyPrevious - energyDesired) / (Math.abs(energyPrevious - energyDesired) + Math.abs(energyCurrent - energyDesired)); /* how far away is the second energy */ howMuchOf2 = Math.abs(energyCurrent - energyDesired) / (Math.abs(energyPrevious - energyDesired) + Math.abs(energyCurrent - energyDesired)); } if (found == false) s.nextLine(); } previous = JComplex.multiply(previous, howMuchOf1); /* set the second complex scattering factor to be how far away from the second energy your selection is times the complex scattering factor at the second energy */ current = JComplex.multiply(current, howMuchOf2); /* Test to see if the first complex scattering factor is near an absorption edge */ if (previous.getRe() < -1 * Z) previous.setRe(0); /* Test to see if the second complex scattering factor is near an absorption edge */ if (current.getRe() < -1 * Z) current.setRe(0); /* return the complex scattering factor to be how far away from the bracketing energies your selection is times the complex scattering factor */ return JComplex.add(previous, current); }