View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2025.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.xray.scatter;
39  
40  import java.util.HashMap;
41  import java.util.logging.Logger;
42  
43  /**
44   * Represents neutron scattering parameters for a given atom, including its name, atomic number,
45   * and form factor.
46   * <p>
47   * This class uses a static cache to store precomputed neutron scattering parameters for atoms
48   * and allows for retrieval of these parameters by atom name.
49   *
50   * @see <a href="https://www.ncnr.nist.gov/resources/n-lengths/list.html" target="_blank">
51   * NIST Center for Neutron Research</a>
52   * @see <a href="http://dx.doi.org/10.1107/97809553602060000594" target="_blank"> V. F. Sears, Int.
53   * Tables Vol. C (2006). Table 4.4.4.1</a>
54   * @see <a href="http://dx.doi.org/10.1107/97809553602060000600" target="_blank"> B. T. M. Willis,
55   * Int. Tables Vol. C (2006). Chapter 6.1.3</a>
56   *
57   * @author Michael J. Schnieders
58   * @since 1.0
59   */
60  public record NeutronScatteringParameters(String name, int atomicNumber, double[] formFactor) {
61  
62      private static final Logger logger = Logger.getLogger(NeutronScatteringParameters.class.getName());
63  
64      /**
65       * Retrieves the neutron scattering parameters (form factor) for a specified atom.
66       * If the atom does not exist in the form factors map, returns null.
67       *
68       * @param atom the name of the atom for which the form factor is requested
69       * @return the neutron scattering parameters for the specified atom,
70       * or null if the atom is not found in the form factors map
71       */
72      public static NeutronScatteringParameters getFormFactor(String atom) {
73          if (formfactors.containsKey(atom)) {
74              return formfactors.get(atom);
75          } else {
76              String message = " Form factor for atom: " + atom + " not found!";
77              logger.severe(message);
78          }
79          return null;
80      }
81  
82      /**
83       * Cache of created form factors.
84       */
85      private static final HashMap<String, NeutronScatteringParameters> formfactors = new HashMap<>();
86  
87      private static final String[] atomNames = {
88              "H", "D", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S",
89              "Cl", "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge",
90              "As", "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In",
91              "Sn", "Sb", "Te", "I", "Xe", "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Sm", "Eu", "Gd", "Tb", "Dy",
92              "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W", "Re", "Os", "Ir", "Pt", "Au", "Hg", "Tl", "Pb",
93              "Bi", "Th", "U"
94      };
95      private static final String[] atomicNumbers = {
96              "1_1", "1_2", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16",
97              "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32",
98              "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
99              "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", "60", "62", "63", "64", "65", "66",
100             "67", "68", "69", "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", "80", "81", "82",
101             "83", "90", "92"
102     };
103     private static final double[][] neutronFormFactors = {
104             {-3.7390, 0.0},  // H
105             {6.671, 0.0},    // D
106             {3.26, 0.0},     // He
107             {-1.90, 0.0},    // Li
108             {7.79, 0.0},     // Be
109             {5.30, 0.213},   // B
110             {6.6460, 0.0},   // C
111             {9.36, 0.0},     // N
112             {5.803, 0.0},    // O
113             {5.654, 0.0},    // F
114             {4.566, 0.0},   // Ne
115             {3.63, 0.0},    // Na
116             {5.375, 0.0},   // Mg
117             {3.449, 0.0},   // Al
118             {4.1491, 0.0},  // Si
119             {5.13, 0.0},    // P
120             {2.847, 0.0},   // S
121             {9.5770, 0.0},  // Cl
122             {1.909, 0.0},   // Ar
123             {3.67, 0.0},    // K
124             {4.70, 0.0},    // Ca
125             {12.29, 0.0},   // Sc
126             {-3.370, 0.0},  // Ti
127             {-0.3824, 0.0}, // V
128             {3.635, 0.0},   // Cr
129             {-3.750, 0.0},  // Mn
130             {9.45, 0.0},    // Fe
131             {2.49, 0.0},    // Co
132             {10.3, 0.0},    // Ni
133             {7.718, 0.0},   // Cu
134             {5.60, 0.0},    // Zn
135             {7.288, 0.0},   // Ga
136             {8.185, 0.0},   // Ge
137             {6.58, 0.0},    // As
138             {7.970, 0.0},   // Se
139             {6.795, 0.0},   // Br
140             {7.81, 0.0},    // Kr
141             {7.09, 0.0},    // Rb
142             {7.02, 0.0},    // Sr
143             {7.75, 0.0},    // Y
144             {7.16, 0.0},    // Zr
145             {7.054, 0.0},   // Nb
146             {6.715, 0.0},   // Mo
147             {6.80, 0.0},    // Tc
148             {7.03, 0.0},    // Ru
149             {5.88, 0.0},    // Rh
150             {5.91, 0.0},    // Pd
151             {5.922, 0.0},   // Ag
152             {4.87, -0.70},  // Cd
153             {4.065, -0.0539}, // In
154             {6.225, 0.0},   // Sn
155             {5.57, 0.0},    // Sb
156             {5.80, 0.0},    // Te
157             {5.28, 0.0},    // I
158             {4.92, 0.0},    // Xe
159             {5.42, 0.0},    // Cs
160             {5.07, 0.0},    // Ba
161             {8.24, 0.0},    // La
162             {4.84, 0.0},    // Ce
163             {4.58, 0.0},    // Pr
164             {7.69, 0.0},    // Nd
165             // No PM
166             {0.80, -1.65},  // Sm
167             {7.22, -1.26},  // Eu
168             {6.5, -13.82},  // Gd
169             {7.38, 0.0},    // Tb
170             {16.9, -0.276}, // Dy
171             {8.01, 0.0},    // Ho
172             {7.79, 0.0},    // Er
173             {7.07, 0.0},    // Tm
174             {12.43, 0.0},   // Yb
175             {7.21, 0.0},    // Lu
176             {7.77, 0.0},    // Hf
177             {6.91, 0.0},    // Ta
178             {4.86, 0.0},    // W
179             {9.2, 0.0},     // Re
180             {10.7, 0.0},    // Os
181             {10.6, 0.0},    // Ir
182             {9.60, 0.0},    // Pt
183             {7.63, 0.0},    // Au
184             {12.692, 0.0},  // Hg
185             {8.776, 0.0},   // Tl
186             {9.405, 0.0},   // Pb
187             {8.532, 0.0},   // Bi
188             {10.31, 0.0},   // Th
189             {8.417, 0.0}    // U
190     };
191 
192     // Load form factors.
193     static {
194         for (int i = 0; i < atomNames.length; i++) {
195             String number = atomicNumbers[i];
196             if (number.contains("_")) {
197                 number = "1";
198             }
199             int atomicNumber = Integer.parseInt(number);
200             NeutronScatteringParameters parameters = new NeutronScatteringParameters(
201                     atomNames[i], atomicNumber, neutronFormFactors[i]);
202             formfactors.put(atomicNumbers[i], parameters);
203         }
204     }
205 
206 }