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 ffx.crystal.HKL;
41  import ffx.potential.bonded.Atom;
42  import ffx.xray.refine.RefinementMode;
43  
44  import java.util.HashMap;
45  import java.util.logging.Level;
46  import java.util.logging.Logger;
47  
48  import static ffx.numerics.math.DoubleMath.dot;
49  import static ffx.numerics.math.DoubleMath.length2;
50  import static ffx.numerics.math.DoubleMath.sub;
51  import static ffx.numerics.math.MatrixMath.determinant3;
52  import static ffx.numerics.math.MatrixMath.mat3Inverse;
53  import static ffx.numerics.math.MatrixMath.mat3Mat3;
54  import static ffx.numerics.math.MatrixMath.scalarMat3Mat3;
55  import static ffx.numerics.math.MatrixMath.vec3Mat3;
56  import static ffx.numerics.math.ScalarMath.b2u;
57  import static ffx.numerics.math.ScalarMath.quadForm;
58  import static ffx.numerics.math.ScalarMath.u2b;
59  import static java.util.Arrays.fill;
60  import static org.apache.commons.math3.util.FastMath.PI;
61  import static org.apache.commons.math3.util.FastMath.exp;
62  import static org.apache.commons.math3.util.FastMath.pow;
63  import static org.apache.commons.math3.util.FastMath.sqrt;
64  
65  /**
66   * This implementation uses the coefficients from Su and Coppens and 3 coefficient parameters derived
67   * from CCTBX.
68   *
69   * @author Timothy D. Fenn<br>
70   * @see <a href="http://dx.doi.org/10.1107/S0108767397004558" target="_blank"> Z. Su and P. Coppens,
71   * Acta Cryst. (1997). A53, 749-762</a>
72   * @see <a href="http://dx.doi.org/10.1107/S010876739800124X" target="_blank"> Z. Su and P. Coppens,
73   * Acta Cryst. (1998). A54, 357</a>
74   * @see <a href="http://harker.chem.buffalo.edu/group/groupindex.html" target="_blank"> The Coppens
75   * lab website (Source data)</a>
76   * @see <a href="http://www.iucr.org/resources/commissions/crystallographic-computing/newsletters/3"
77   * target="_blank"> R. W. Grosse-Kunstleve, N. K. Sauter and P. D. Adams. Newsletter of the IUCr
78   * Commission on Crystallographic Computing. (2004). 3, 22-31.</a>
79   * @see <a href="http://dx.doi.org/10.1107/S0907444909022707" target="_blank"> M. J. Schnieders, T.
80   * D. Fenn, V. S. Pande and A. T. Brunger, Acta Cryst. (2009). D65 952-965.</a>
81   * @since 1.0
82   */
83  public final class XRayFormFactor implements FormFactor {
84  
85    private static final Logger logger = Logger.getLogger(XRayFormFactor.class.getName());
86    private static final double twopi2 = 2.0 * PI * PI;
87    private static final double twopi32 = pow(2.0 * PI, -1.5);
88    private static final double oneThird = 1.0 / 3.0;
89    private static final double[] vx = {1.0, 0.0, 0.0};
90    private static final double[] vy = {0.0, 1.0, 0.0};
91    private static final double[] vz = {0.0, 0.0, 1.0};
92    private static final double[][] u11 = {{1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
93    private static final double[][] u22 = {{0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 0.0}};
94    private static final double[][] u33 = {{0.0, 0.0, 0.0}, {0.0, 0.0, 0.0}, {0.0, 0.0, 1.0}};
95    private static final double[][] u12 = {{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 0.0}};
96    private static final double[][] u13 = {{0.0, 0.0, 1.0}, {0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}};
97    private static final double[][] u23 = {{0.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}};
98    private static final HashMap<String, double[][]> formFactors = new HashMap<>();
99    private static final String[] atoms = {
100       "H", "He", "Li", "Be", "B", "C", "N", "O", "F", "Ne", "Na", "Mg", "Al", "Si", "P", "S", "Cl",
101       "Ar", "K", "Ca", "Sc", "Ti", "V", "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", "As",
102       "Se", "Br", "Kr", "Rb", "Sr", "Y", "Zr", "Nb", "Mo", "Tc", "Ru", "Rh", "Pd", "Ag", "Cd", "In",
103       "Sn", "Sb", "Te", "I", "Xe", "Li+", "Be2+", "Cv", "O-", "F-", "Na+", "Mg2+", "Al3+", "Si0",
104       "Si4+", "Cl-", "K+", "Ca2+", "Sc3+", "Ti2+", "Ti3+", "Ti4+", "V2+", "V3+", "V5+", "Cr2+",
105       "Cr3+", "Mn2+", "Mn3+", "Mn4+", "Fe2+", "Fe3+", "Co2+", "Co3+", "Ni2+", "Ni3+", "Cu+", "Cu2+",
106       "Zn2+", "Ga3+", "Ge4+", "Br-", "Rb+", "Sr2+", "Y3+", "Zr4+", "Nb3+", "Nb5+", "Mo3+", "Mo6+",
107       "Ru3+", "Ru4+", "Rh3+", "Rh4+", "Pd2+", "Pd4+", "Ag+", "Ag2+", "Cd2+", "In3+", "Sn2+", "Sn4+",
108       "Sb3+", "Sb5+", "I-", "Be2+_3g", "Mg2+_3g", "Al3+_3g", "Si4+_3g", "Ca2+_3g", "Sc3+_3g",
109       "Ti2+_3g", "Ti3+_3g", "Ti4+_3g", "V2+_3g", "V3+_3g", "V5+_3g", "Cr2+_3g", "Cr3+_3g", "Mn2+_3g",
110       "Mn3+_3g", "Mn4+_3g", "Fe2+_3g", "Fe3+_3g", "Co2+_3g", "Co3+_3g", "Ni2+_3g", "Ni3+_3g",
111       "Cu2+_3g", "Zn2+_3g", "Ga3+_3g", "Ge4+_3g", "Sr2+_3g", "Y3+_3g", "Zr4+_3g", "Nb3+_3g",
112       "Nb5+_3g", "Mo3+_3g", "Mo6+_3g", "Ru3+_3g", "Ru4+_3g", "Rh3+_3g", "Rh4+_3g", "Pd2+_3g",
113       "Pd4+_3g", "Ag2+_3g", "Cd2+_3g", "In3+_3g", "Sn2+_3g", "Sn4+_3g", "Sb3+_3g", "Sb5+_3g",
114       "Hg2+_3g", "H_3g", "He_3g", "Li_3g", "Be_3g", "B_3g", "C_3g", "N_3g", "O_3g", "F_3g", "Ne_3g",
115       "Na_3g", "Mg_3g", "Al_3g", "Si_3g", "P_3g", "S_3g", "Cl_3g", "Ar_3g", "K_3g", "Ca_3g", "Sc_3g",
116       "Ti_3g", "V_3g", "Cr_3g", "Mn_3g", "Fe_3g", "Co_3g", "Ni_3g", "Cu_3g", "Zn_3g", "Ga_3g",
117       "Ge_3g", "As_3g", "Se_3g", "Br_3g", "Kr_3g", "Rb_3g", "Sr_3g", "Y_3g", "Zr_3g", "Nb_3g",
118       "Mo_3g", "Tc_3g", "Ru_3g", "Rh_3g", "Pd_3g", "Ag_3g", "Cd_3g", "In_3g", "Sn_3g", "Sb_3g",
119       "Te_3g", "I_3g", "Xe_3g", "Hg_3g"
120   };
121   private static final String[] atomsi = {
122       "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17",
123       "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33",
124       "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48", "49",
125       "50", "51", "52", "53", "54", "3_1", "4_2", "6_5", "8_-1", "9_-1", "11_1", "12_2", "13_3",
126       "14_0", "14_4", "17_-1", "19_1", "20_2", "21_3", "22_2", "22_3", "22_4", "23_2", "23_3",
127       "23_5",
128       "24_2", "24_3", "25_2", "25_3", "25_4", "26_2", "26_3", "27_2", "27_3", "28_2", "28_3", "29_1",
129       "29_2", "30_2", "31_3", "32_4", "35_-1", "37_1", "38_2", "39_3", "40_4", "41_3", "41_5",
130       "42_3",
131       "42_6", "44_3", "44_4", "45_3", "45_4", "46_2", "46_4", "47_1", "47_2", "48_2", "49_3", "50_2",
132       "50_4", "51_3", "51_5", "53_-1", "4_2_3g", "12_2_3g", "13_3_3g", "14_4_3g", "20_2_3g",
133       "21_3_3g", "22_2_3g", "22_3_3g", "22_4_3g", "23_2_3g", "23_3_3g", "23_5_3g", "24_2_3g",
134       "24_3_3g", "25_2_3g", "25_3_3g", "25_4_3g", "26_2_3g", "26_3_3g", "27_2_3g", "27_3_3g",
135       "28_2_3g", "28_3_3g", "29_2_3g", "30_2_3g", "31_3_3g", "32_4_3g", "38_2_3g", "39_3_3g",
136       "40_4_3g", "41_3_3g", "41_5_3g", "42_3_3g", "42_6_3g", "44_3_3g", "44_4_3g", "45_3_3g",
137       "45_4_3g", "46_2_3g", "46_4_3g", "47_2_3g", "48_2_3g", "49_3_3g", "50_2_3g", "50_4_3g",
138       "51_3_3g", "51_5_3g", "80_2_3g", "1_3g", "2_3g", "3_3g", "4_3g", "5_3g", "6_3g", "7_3g",
139       "8_3g",
140       "9_3g", "10_3g", "11_3g", "12_3g", "13_3g", "14_3g", "15_3g", "16_3g", "17_3g", "18_3g",
141       "19_3g", "20_3g", "21_3g", "22_3g", "23_3g", "24_3g", "25_3g", "26_3g", "27_3g", "28_3g",
142       "29_3g", "30_3g", "31_3g", "32_3g", "33_3g", "34_3g", "35_3g", "36_3g", "37_3g", "38_3g",
143       "39_3g", "40_3g", "41_3g", "42_3g", "43_3g", "44_3g", "45_3g", "46_3g", "47_3g", "48_3g",
144       "49_3g", "50_3g", "51_3g", "52_3g", "53_3g", "54_3g", "80_3g"
145   };
146   /**
147    * Su and Coppens data: 0 through 113.
148    *
149    * <p>CCTBX 3 Gaussians: 114 through 216.
150    */
151   private static final double[][][] ffactors = {
152       {
153           {0},
154           {0.43028, 0.28537, 0.17134, 0.09451, 0.01725, 0.00114},
155           {23.02312, 10.20138, 51.25444, 4.13511, 1.35427, 0.24269}
156       },
157       {
158           {1},
159           {0.69475, 0.62068, 0.38661, 0.15223, 0.12661, 0.01907},
160           {5.83366, 12.87682, 2.53296, 28.16171, 0.97507, 0.25308}
161       },
162       {
163           {2},
164           {0.84645, 0.81146, 0.81096, 0.26115, 0.26055, 0.00930},
165           {4.63253, 1.71862, 97.87364, 0.50620, 200.00000, 0.00010}
166       },
167       {
168           {3},
169           {1.59261, 1.12768, 0.70296, 0.53815, 0.03863, 0.00010},
170           {43.67397, 1.86275, 0.54243, 103.44910, 0.00010, 0.34975}
171       },
172       {
173           {4},
174           {2.07418, 1.20577, 1.07592, 0.52023, 0.12280, 0.00010},
175           {23.39543, 1.07672, 60.93249, 0.27132, 0.27192, 0.11361}
176       },
177       {
178           {5},
179           {2.09921, 1.80832, 1.26159, 0.56775, 0.26303, 0.00010},
180           {13.18997, 30.37956, 0.69255, 0.16381, 68.42774, 0.44083}
181       },
182       {
183           {6},
184           {2.45424, 2.15782, 1.05782, 0.57557, 0.44959, 0.30480},
185           {18.66694, 8.31271, 0.46989, 42.44646, 0.08747, 0.47126}
186       },
187       {
188           {7},
189           {2.34752, 1.83006, 1.61538, 1.52402, 0.41423, 0.26867},
190           {9.69710, 18.59876, 5.19879, 0.32408, 39.79099, 0.01150}
191       },
192       {
193           {8},
194           {2.96981, 2.04536, 1.78123, 1.52086, 0.42253, 0.26008},
195           {7.52365, 15.41441, 3.79721, 0.25209, 33.76478, 0.00488}
196       },
197       {
198           {9},
199           {3.56413, 2.72559, 1.67359, 1.58884, 0.25468, 0.19320},
200           {7.30559, 3.34491, 15.93226, 0.13859, 0.69111, 35.26368}
201       },
202       {
203           {10},
204           {4.16491, 2.38097, 1.70484, 1.59622, 0.66291, 0.48971},
205           {4.23096, 9.48502, 0.12559, 1.98358, 172.13327, 82.23091}
206       },
207       {
208           {11},
209           {3.90882, 2.62159, 1.69157, 1.52610, 1.47907, 0.77262},
210           {3.06041, 6.12146, 0.10357, 58.65022, 1.56940, 125.49980}
211       },
212       {
213           {12},
214           {4.25474, 3.58301, 2.37351, 1.72366, 0.99400, 0.07031},
215           {3.76670, 1.69151, 45.27810, 0.09238, 113.96978, 17.47922}
216       },
217       {
218           {13},
219           {4.94976, 3.25403, 2.84957, 1.66053, 1.22949, 0.05611},
220           {2.70254, 34.45314, 1.24059, 0.07201, 84.53648, 56.34208}
221       },
222       {
223           {14},
224           {6.48197, 4.31666, 1.73759, 1.35793, 1.10559, 0.00010},
225           {1.89537, 27.61455, 0.50991, 66.28296, 0.00010, 12.05652}
226       },
227       {
228           {15},
229           {6.90565, 5.24410, 1.54516, 1.42922, 0.87564, 0.00010},
230           {1.46764, 22.31576, 56.06328, 0.25588, 0.00010, 26.96892}
231       },
232       {
233           {16},
234           {7.13381, 6.26972, 1.82658, 1.62579, 0.14431, 0.00010},
235           {1.17455, 18.57626, 0.07869, 48.08203, 0.07871, 23.23894}
236       },
237       {
238           {17},
239           {7.28551, 7.24549, 1.74775, 1.72174, 0.00010, 0.00010},
240           {15.63295, 0.95562, 0.04456, 41.07550, 0.00617, 20.09628}
241       },
242       {
243           {18},
244           {8.13161, 7.43972, 1.42159, 1.12030, 0.88342, 0.00010},
245           {12.73675, 0.77443, 0.00010, 200.00000, 36.18711, 82.98380}
246       },
247       {
248           {19},
249           {8.62965, 7.38765, 1.63044, 1.37681, 0.97538, 0.00010},
250           {10.45238, 0.66036, 87.06258, 0.00010, 181.27760, 28.57890}
251       },
252       {
253           {20},
254           {9.18894, 7.36727, 1.60214, 1.33655, 0.78386, 0.72047},
255           {9.02948, 0.57364, 137.40503, 0.00010, 51.53615, 53.74395}
256       },
257       {
258           {21},
259           {9.75861, 7.35354, 1.46842, 1.40591, 1.28669, 0.72609},
260           {7.86172, 0.50107, 32.75146, 90.95131, 0.00010, 149.02872}
261       },
262       {
263           {22},
264           {10.25443, 7.34699, 1.84039, 1.72148, 1.22611, 0.61000},
265           {6.86177, 0.43939, 23.70259, 79.72053, 0.00010, 149.36488}
266       },
267       {
268           {23},
269           {10.67225, 4.62093, 3.33159, 2.72784, 1.45281, 1.19090},
270           {6.12143, 0.39293, 20.15470, 0.39293, 92.01317, 0.00010}
271       },
272       {
273           {24},
274           {10.98576, 7.35617, 2.92091, 1.65707, 1.08018, 0.99906},
275           {5.27951, 0.34199, 14.55791, 54.87900, 0.00010, 118.26511}
276       },
277       {
278           {25},
279           {11.18858, 7.37206, 3.55141, 1.68125, 1.20893, 0.99652},
280           {4.64599, 0.30327, 12.07655, 44.15316, 104.11866, 0.00010}
281       },
282       {
283           {26},
284           {11.41624, 7.38902, 4.21351, 1.80189, 1.26103, 0.91710},
285           {4.12258, 0.27069, 10.36636, 38.32442, 97.14970, 0.00010}
286       },
287       {
288           {27},
289           {11.76300, 7.39888, 4.85491, 1.98079, 1.14857, 0.85325},
290           {3.69729, 0.24374, 9.30593, 36.58880, 96.02875, 0.00010}
291       },
292       {
293           {28},
294           {11.87211, 7.37491, 6.08548, 1.94337, 0.86475, 0.85837},
295           {3.34773, 0.22522, 8.46165, 27.95010, 98.02165, 0.00012}
296       },
297       {
298           {29},
299           {12.53020, 6.57092, 5.84880, 2.07610, 1.65893, 1.31388},
300           {3.05828, 0.14326, 7.58930, 28.50706, 0.38369, 82.22092}
301       },
302       {
303           {30},
304           {10.69865, 7.89127, 4.74778, 3.83120, 2.59218, 1.23712},
305           {3.44787, 0.15426, 2.07387, 8.38441, 34.93356, 99.34732}
306       },
307       {
308           {31},
309           {9.56335, 7.86994, 7.64215, 3.31296, 2.13351, 1.47704},
310           {2.21494, 0.14284, 3.86490, 32.69417, 8.94286, 82.15827}
311       },
312       {
313           {32},
314           {10.86205, 7.83248, 5.48862, 4.21250, 2.56904, 2.03413},
315           {2.10046, 0.13209, 3.33631, 26.38254, 5.81992, 63.74567}
316       },
317       {
318           {33},
319           {12.63843, 7.77316, 5.80645, 4.44296, 1.82898, 1.50938},
320           {1.97006, 0.12167, 3.57609, 28.84348, 15.15766, 64.03025}
321       },
322       {
323           {34},
324           {12.56835, 7.70669, 5.76243, 4.78093, 2.48412, 1.69674},
325           {1.79826, 0.11204, 2.98848, 25.62856, 14.95420, 55.44329}
326       },
327       {
328           {35},
329           {13.32373, 7.64645, 5.71351, 4.95009, 2.80427, 1.56038},
330           {1.67399, 0.10346, 17.43646, 2.62566, 42.87908, 19.80281}
331       },
332       {
333           {36},
334           {17.73932, 7.70415, 5.33484, 4.92829, 1.28671, 0.00010},
335           {1.68298, 0.09944, 12.80739, 23.59343, 200.00000, 77.16806}
336       },
337       {
338           {37},
339           {11.77920, 9.53489, 7.57120, 6.03047, 2.02653, 1.05652},
340           {1.52266, 13.50271, 0.08995, 1.52251, 162.86971, 53.07068}
341       },
342       {
343           {38},
344           {17.89478, 9.91124, 7.40424, 2.14475, 1.64266, 0.00010},
345           {1.37779, 12.18084, 0.08009, 137.73235, 49.81442, 0.42187}
346       },
347       {
348           {39},
349           {18.00877, 10.47108, 7.22234, 2.43263, 1.86405, 0.00010},
350           {1.25042, 11.25972, 0.07050, 49.09408, 131.67513, 1.76480}
351       },
352       {
353           {40},
354           {18.18722, 11.07349, 7.02786, 3.35224, 1.35250, 0.00606},
355           {1.13993, 10.82683, 0.06116, 38.71734, 115.18009, 1.19550}
356       },
357       {
358           {41},
359           {18.36000, 6.75320, 6.25470, 5.52972, 3.76774, 1.33338},
360           {1.03291, 0.05000, 10.10135, 10.12179, 34.16693, 104.10497}
361       },
362       {
363           {42},
364           {18.53113, 12.72135, 6.39681, 2.88811, 1.72002, 0.74148},
365           {0.93112, 9.26800, 0.03703, 31.91681, 110.11821, 44.07274}
366       },
367       {
368           {43},
369           {18.82022, 13.49636, 6.01136, 3.54102, 1.19962, 0.93207},
370           {0.84363, 8.84277, 0.02355, 27.02179, 44.09284, 113.68484}
371       },
372       {
373           {44},
374           {19.15093, 14.43898, 4.66972, 4.66263, 1.22522, 0.85125},
375           {0.75936, 8.27523, 26.67965, 0.00694, 97.04210, 0.00695}
376       },
377       {
378           {45},
379           {19.32300, 15.30162, 5.26970, 5.12338, 0.98021, 0.00010},
380           {0.69750, 7.93132, 0.00010, 23.54133, 60.82499, 1.28291}
381       },
382       {
383           {46},
384           {19.28330, 16.71519, 5.18450, 4.77793, 1.03807, 0.00010},
385           {0.64519, 7.48785, 0.00010, 24.79225, 100.31405, 2.33951}
386       },
387       {
388           {47},
389           {19.22320, 17.67107, 5.07851, 4.43017, 1.59588, 0.00010},
390           {0.59542, 6.92490, 0.00010, 24.85505, 87.61222, 31.90172}
391       },
392       {
393           {48},
394           {19.16300, 18.59170, 4.95237, 4.27994, 2.00969, 0.00010},
395           {0.54868, 6.39500, 0.00010, 26.18224, 93.70112, 8.23922}
396       },
397       {
398           {49},
399           {19.22704, 19.09869, 4.79841, 4.37320, 2.50037, 0.00010},
400           {5.84698, 0.50421, 0.00010, 27.22571, 81.57248, 31.56814}
401       },
402       {
403           {50},
404           {19.04077, 13.05412, 6.63670, 4.95963, 4.60941, 2.69795},
405           {0.46176, 5.31900, 5.31953, 28.54198, 0.00010, 72.65174}
406       },
407       {
408           {51},
409           {19.96327, 18.99686, 6.19148, 4.38583, 2.46194, 0.00010},
410           {4.81879, 0.42169, 28.79858, 0.00010, 70.63864, 12.77096}
411       },
412       {
413           {52},
414           {18.97925, 15.69578, 7.06433, 4.42489, 4.10018, 2.73271},
415           {0.38267, 4.34879, 26.93604, 4.35210, 0.00010, 61.59836}
416       },
417       {
418           {53},
419           {20.29787, 19.00556, 9.04165, 3.76022, 1.89561, 0.00010},
420           {3.93838, 0.34588, 26.70066, 0.00010, 65.34476, 20.30305}
421       },
422       {
423           {54},
424           {0.79375, 0.54736, 0.46161, 0.13918, 0.05800, 0.00010},
425           {2.88678, 1.16905, 6.18250, 0.31715, 12.60983, 28.15927}
426       },
427       {
428           {55},
429           {0.82577, 0.73691, 0.23557, 0.20135, 0.00034, 0.00010},
430           {2.04212, 0.80252, 4.60157, 0.21162, 43.68258, 103.45510}
431       },
432       {
433           {56},
434           {2.03492, 1.64286, 0.68060, 0.67022, 0.51650, 0.45488},
435           {25.99675, 11.77809, 0.51013, 0.97866, 0.16915, 57.91874}
436       },
437       {
438           {57},
439           {3.56378, 2.14950, 1.52760, 1.47980, 0.27065, 0.00010},
440           {14.10561, 5.60491, 0.32801, 46.88862, 0.00980, 10.98084}
441       },
442       {
443           {58},
444           {3.22684, 2.47111, 1.59839, 1.28490, 1.11335, 0.30182},
445           {4.95997, 14.45952, 0.17267, 11.39653, 43.30817, 0.96703}
446       },
447       {
448           {59},
449           {3.69529, 3.30459, 1.68333, 0.69149, 0.62431, 0.00088},
450           {3.24183, 7.07179, 0.12279, 15.45334, 1.43664, 35.26383}
451       },
452       {
453           {60},
454           {4.30385, 2.58390, 1.71397, 1.39368, 0.00470, 0.00010},
455           {4.02045, 1.85304, 0.10693, 8.78523, 58.58712, 125.50050}
456       },
457       {
458           {61},
459           {4.19367, 3.00032, 1.71590, 1.08840, 0.00167, 0.00010},
460           {3.37134, 1.58637, 0.09158, 6.99679, 45.26456, 113.97270}
461       },
462       {
463           {62},
464           {5.49488, 3.33770, 2.38765, 1.59864, 1.17986, 0.00010},
465           {2.60802, 37.46289, 1.09647, 0.06439, 80.52337, 56.27056}
466       },
467       {
468           {63},
469           {3.98392, 3.53675, 1.72808, 0.75103, 0.00013, 0.00010},
470           {2.94648, 1.39488, 0.08069, 5.91604, 56.23176, 79.76580}
471       },
472       {
473           {64},
474           {7.13932, 6.34213, 2.29801, 1.97826, 0.22854, 0.00983},
475           {1.18073, 19.52901, 61.04850, 0.08057, 23.18225, 0.09759}
476       },
477       {
478           {65},
479           {8.00372, 7.44077, 1.42217, 1.13491, 0.00010, 0.00010},
480           {12.70476, 0.77473, 0.00010, 32.44270, 199.99900, 82.98298}
481       },
482       {
483           {66},
484           {8.66803, 7.39747, 1.38325, 0.55348, 0.00010, 0.00010},
485           {10.62955, 0.66306, 0.00010, 30.98476, 199.99880, 82.97898}
486       },
487       {
488           {67},
489           {9.01395, 7.36477, 1.32160, 0.30179, 0.00010, 0.00010},
490           {8.86658, 0.56771, 0.00010, 29.98133, 137.40030, 53.69811}
491       },
492       {
493           {68},
494           {9.67607, 7.35874, 1.66775, 1.29681, 0.00010, 0.00010},
495           {7.92858, 0.50388, 23.88214, 0.00010, 92.10388, 145.58810}
496       },
497       {
498           {69},
499           {9.56376, 7.35320, 1.26997, 0.81496, 0.00010, 0.00010},
500           {7.72729, 0.49604, 0.00010, 22.37931, 92.10560, 145.58920}
501       },
502       {
503           {70},
504           {9.22395, 7.35117, 1.23367, 0.19305, 0.00010, 0.00010},
505           {7.44634, 0.48595, 0.00010, 28.20512, 92.10930, 145.59010}
506       },
507       {
508           {71},
509           {10.14209, 7.35015, 2.25361, 1.23887, 0.01533, 0.00010},
510           {6.90615, 0.44224, 20.14575, 0.00010, 120.21700, 55.09812}
511       },
512       {
513           {72},
514           {10.05723, 7.34875, 1.38759, 1.20752, 0.00010, 0.00010},
515           {6.75290, 0.43509, 18.25122, 0.00010, 120.22150, 55.11062}
516       },
517       {
518           {73},
519           {9.37695, 7.36389, 1.11621, 0.14450, 0.00010, 0.00010},
520           {6.31625, 0.41568, 0.00010, 25.36044, 199.99870, 82.97847}
521       },
522       {
523           {74},
524           {10.54130, 4.41457, 2.93436, 2.87024, 1.17229, 0.06743},
525           {6.04009, 0.38967, 0.38966, 16.94938, 0.00010, 59.98400}
526       },
527       {
528           {75},
529           {10.45597, 4.43683, 2.92505, 2.06149, 1.11981, 0.00120},
530           {5.90641, 0.38863, 0.37041, 15.34221, 0.00010, 59.68271}
531       },
532       {
533           {76},
534           {10.86580, 7.35401, 3.49267, 1.09987, 0.18537, 0.00249},
535           {5.30450, 0.34487, 14.15718, 0.00010, 38.60730, 100.13560}
536       },
537       {
538           {77},
539           {11.04414, 4.43611, 4.06737, 2.44502, 0.00559, 0.00189},
540           {5.32462, 0.15971, 0.47488, 13.90108, 100.14020, 38.59723}
541       },
542       {
543           {78},
544           {10.80739, 7.37819, 1.80548, 1.00948, 0.00010, 0.00010},
545           {5.12031, 0.33181, 12.46589, 0.00010, 100.14660, 38.60185}
546       },
547       {
548           {79},
549           {11.32394, 7.35828, 4.08542, 1.03934, 0.19438, 0.00010},
550           {4.71611, 0.30793, 12.87900, 0.00024, 43.73118, 103.91920}
551       },
552       {
553           {80},
554           {11.27641, 7.37595, 3.32058, 0.98461, 0.04263, 0.00010},
555           {4.63894, 0.30169, 11.63908, 0.00010, 44.10289, 103.92070}
556       },
557       {
558           {81},
559           {11.59539, 7.37601, 4.75131, 0.95818, 0.31843, 0.00010},
560           {4.18474, 0.27510, 11.19206, 0.00010, 36.27509, 93.95933}
561       },
562       {
563           {82},
564           {11.58135, 7.38964, 4.01201, 0.91419, 0.10353, 0.00010},
565           {4.13155, 0.27012, 10.32693, 0.00010, 35.20369, 93.95908}
566       },
567       {
568           {83},
569           {11.83838, 5.16446, 4.59215, 3.72826, 0.67719, 0.00010},
570           {3.76040, 9.57707, 0.31557, 0.11646, 25.17286, 96.76703}
571       },
572       {
573           {84},
574           {12.08932, 7.37051, 4.53328, 0.89389, 0.11440, 0.00010},
575           {3.73486, 0.24588, 9.52524, 0.00100, 36.54998, 96.77110}
576       },
577       {
578           {85},
579           {11.74994, 6.77249, 6.21229, 1.75552, 1.47560, 0.03461},
580           {3.34714, 0.23831, 8.32820, 23.58346, 0.04331, 98.01738}
581       },
582       {
583           {86},
584           {11.83187, 5.78192, 5.77531, 2.46041, 1.14698, 0.00353},
585           {3.33965, 0.25530, 8.03031, 0.08201, 19.99327, 98.02090}
586       },
587       {
588           {87},
589           {12.49609, 7.88148, 4.99190, 2.05602, 0.57505, 0.00010},
590           {3.52509, 0.16619, 9.20541, 1.71372, 24.20427, 82.21923}
591       },
592       {
593           {88},
594           {10.80193, 7.89470, 5.30620, 3.91136, 0.08693, 0.00010},
595           {3.67800, 0.15468, 2.08510, 9.11568, 34.76155, 99.34953}
596       },
597       {
598           {89},
599           {8.64238, 8.44015, 7.88210, 2.99985, 0.03590, 0.00010},
600           {3.75852, 2.14595, 0.14366, 8.16207, 30.93576, 72.31449}
601       },
602       {
603           {90},
604           {14.72809, 7.73340, 4.08153, 3.89920, 2.84995, 2.70412},
605           {1.87781, 0.11285, 23.45650, 3.65207, 21.50646, 68.50430}
606       },
607       {
608           {91},
609           {17.72736, 7.70846, 6.22707, 4.23320, 0.10456, 0.00010},
610           {1.68258, 0.09962, 13.34713, 25.64859, 76.90928, 199.99860}
611       },
612       {
613           {92},
614           {13.56253, 9.15282, 7.57461, 4.23621, 1.47524, 0.00010},
615           {1.52639, 13.37893, 0.09009, 1.50827, 28.97999, 162.86130}
616       },
617       {
618           {93},
619           {17.83594, 10.00061, 7.34299, 0.76995, 0.05161, 0.00010},
620           {1.37290, 11.94201, 0.07979, 27.59179, 0.08311, 137.72530}
621       },
622       {
623           {94},
624           {17.88797, 10.57832, 7.18725, 0.34750, 0.00010, 0.00010},
625           {1.24006, 10.60035, 0.06944, 29.00543, 131.45550, 1.67829}
626       },
627       {
628           {95},
629           {17.94269, 11.64938, 7.03542, 1.17571, 0.20353, 0.00010},
630           {1.13911, 10.82291, 0.06147, 34.40293, 1.15832, 134.27490}
631       },
632       {
633           {96},
634           {17.35713, 10.99074, 7.04050, 0.57079, 0.04542, 0.00010},
635           {1.13181, 9.52278, 0.06199, 1.11378, 134.27980, 38.40765}
636       },
637       {
638           {97},
639           {16.70847, 11.98967, 6.70451, 1.98553, 1.61267, 0.00010},
640           {1.02628, 9.86398, 0.04848, 26.23584, 1.02613, 83.38388}
641       },
642       {
643           {98},
644           {16.84671, 11.18317, 6.67150, 1.21668, 0.08306, 0.00010},
645           {1.01489, 8.31776, 0.04772, 1.01511, 36.37142, 83.39908}
646       },
647       {
648           {99},
649           {16.20121, 13.68489, 5.92693, 2.62037, 2.56751, 0.00010},
650           {0.83651, 8.66621, 0.02083, 0.83653, 22.32915, 67.41669}
651       },
652       {
653           {100},
654           {15.97671, 13.58921, 5.91839, 2.79182, 1.72564, 0.00010},
655           {0.83452, 8.38679, 0.02066, 0.83387, 21.20783, 67.42265}
656       },
657       {
658           {101},
659           {14.55243, 14.36520, 5.43109, 3.60085, 2.86567, 1.18601},
660           {8.09600, 0.75250, 0.00422, 0.75381, 21.00325, 0.75895}
661       },
662       {
663           {102},
664           {14.57165, 14.10996, 5.40851, 3.65768, 1.90013, 1.35484},
665           {7.90759, 0.75012, 0.00354, 0.75338, 19.97214, 0.75124}
666       },
667       {
668           {103},
669           {19.27390, 15.67787, 5.26036, 3.78685, 0.00010, 0.00010},
670           {0.69511, 7.84482, 0.00010, 22.21775, 60.82368, 1.12994}
671       },
672       {
673           {104},
674           {19.16608, 15.58248, 5.24991, 1.97949, 0.02452, 0.00010},
675           {0.69220, 7.50980, 0.00010, 19.35021, 0.69139, 60.83056}
676       },
677       {
678           {105},
679           {19.29333, 16.76786, 5.18419, 4.69146, 0.06334, 0.00010},
680           {0.64534, 7.54710, 0.00010, 23.16034, 100.32570, 2.35114}
681       },
682       {
683           {106},
684           {19.26038, 16.76118, 5.17728, 3.80102, 0.00010, 0.00010},
685           {0.64383, 7.44215, 0.00010, 21.24567, 100.31430, 2.43992}
686       },
687       {
688           {107},
689           {19.24328, 17.81622, 5.07556, 3.86538, 0.00010, 0.00010},
690           {0.59548, 7.03822, 0.00010, 20.12238, 87.60555, 31.88584}
691       },
692       {
693           {108},
694           {19.15099, 19.02664, 5.11556, 1.72846, 1.00259, 0.00010},
695           {0.55860, 6.79490, 0.00370, 25.60539, 8.23095, 93.69624}
696       },
697       {
698           {109},
699           {19.14517, 19.11002, 4.80720, 4.48861, 0.25075, 0.20103},
700           {5.86776, 0.50516, 0.00010, 24.33452, 87.00222, 31.41846}
701       },
702       {
703           {110},
704           {19.71431, 19.14550, 4.79767, 2.34645, 0.00010, 0.00010},
705           {6.04052, 0.50506, 0.00010, 16.17828, 87.05909, 31.49791}
706       },
707       {
708           {111},
709           {19.06093, 12.90928, 6.64901, 4.63278, 4.60732, 0.14140},
710           {0.46390, 5.35884, 5.35853, 0.00010, 21.75129, 70.66362}
711       },
712       {
713           {112},
714           {19.55274, 19.11016, 4.62585, 1.75378, 0.96170, 0.00010},
715           {5.57560, 0.46433, 0.00010, 15.08594, 5.57571, 70.66860}
716       },
717       {
718           {113},
719           {18.97534, 15.68841, 6.74714, 4.42194, 4.08431, 4.06854},
720           {0.38165, 4.33217, 26.51128, 4.35007, 0.00013, 70.73529}
721       },
722 
723       // cctbx - 3 Gaussians.
724       {
725           {114},
726           {1.05674999997, 0.644323530897, 0.298305313502},
727           {1.10072695216, 3.30968118776, 0.263851354839}
728       },
729       {
730           {115},
731           {4.36297453919, 3.95402186199, 1.67261115359},
732           {5.84416794424, 2.0522287083, 0.0990905852289}
733       },
734       {
735           {116},
736           {4.1982011524, 4.10980380127, 1.68447184661},
737           {1.73308116771, 4.58815466909, 0.0858298380754}
738       },
739       {
740           {117},
741           {4.47168612436, 3.87243074662, 1.66071703302},
742           {1.44515163245, 3.79224664386, 0.0714406145137}
743       },
744       {
745           {118},
746           {9.00614617514, 7.11474468263, 1.85112246997},
747           {11.5043846011, 0.730949041574, 0.0473828343711}
748       },
749       {
750           {119},
751           {9.16075817591, 7.1050465418, 1.71459201986},
752           {9.35476737709, 0.620771447674, 0.0342761622543}
753       },
754       {
755           {120},
756           {7.93431359573, 7.75702894924, 4.27186054645},
757           {0.344341308343, 12.0850676027, 4.28886237826}
758       },
759       {
760           {121},
761           {10.0039669344, 6.48634784642, 2.47486846392},
762           {8.68083236931, 0.63076461812, 0.080571202237}
763       },
764       {
765           {122},
766           {9.30135876449, 7.07501002111, 1.60674098372},
767           {7.7294767073, 0.529160463879, 0.026439065502}
768       },
769       {
770           {123},
771           {7.97543708242, 7.63636302328, 5.34474255061},
772           {0.309079820533, 11.6025702687, 4.25903863771}
773       },
774       {
775           {124},
776           {8.18999077376, 7.90783514463, 3.88300169133},
777           {9.4272329602, 0.307235108471, 3.6928463073}
778       },
779       {
780           {125},
781           {9.35615562168, 7.03336806389, 1.60169919909},
782           {6.58156213681, 0.47100169955, 0.0241326952344}
783       },
784       {
785           {126},
786           {7.99912950446, 7.38596545164, 6.58011100415},
787           {0.283923739083, 4.4824019183, 12.0615843142}
788       },
789       {
790           {127},
791           {8.70462787589, 7.86457501857, 4.40400027591},
792           {8.79040932546, 0.275593957027, 3.39537512496}
793       },
794       {
795           {128},
796           {9.56593817028, 8.07602885623, 5.33445562929},
797           {4.56386883527, 0.259145646999, 12.8970300261}
798       },
799       {
800           {129},
801           {7.89836965773, 7.08191595383, 7.00167267967},
802           {0.251091897431, 9.28582994856, 3.8036260062}
803       },
804       {
805           {130},
806           {8.78159491796, 7.82567400183, 4.37597058338},
807           {7.25270024967, 0.247385674714, 3.06034043675}
808       },
809       {
810           {131},
811           {10.7556787804, 8.08468656259, 5.13923400598},
812           {4.30170995299, 0.237147049617, 12.6864130192}
813       },
814       {
815           {132},
816           {11.1450231671, 7.57801275896, 4.22386820999},
817           {7.10765696463, 0.214122838685, 2.25363704097}
818       },
819       {
820           {133},
821           {9.30087028578, 7.86055043642, 7.79103605212},
822           {3.34124560949, 0.207379836561, 9.72882671072}
823       },
824       {
825           {134},
826           {9.35811523679, 7.88288171805, 6.7382513407},
827           {3.45256987642, 0.209910830837, 8.73850168377}
828       },
829       {
830           {135},
831           {10.9574548068, 7.91364440258, 7.09037754465},
832           {3.30397344741, 0.193332220057, 9.84576083535}
833       },
834       {
835           {136},
836           {9.03277595215, 8.16707734383, 7.76819167497},
837           {2.96007681004, 7.67163956047, 0.188408691652}
838       },
839       {
840           {137},
841           {12.359628475, 7.87131386986, 6.73863127449},
842           {3.18130979285, 0.178269967352, 9.74802018078}
843       },
844       {
845           {138},
846           {13.4378597184, 7.98154466967, 6.5512483394},
847           {3.02261523908, 0.1687408754, 9.55493525266}
848       },
849       {
850           {139}, {11.4539, 8.90972752105, 7.60276831073},
851           {2.37794666223, 6.59530146321, 0.142862536768}
852       },
853       {
854           {140},
855           {13.8480203642, 7.75041063864, 6.39192497212},
856           {2.4567640923, 0.137907723422, 6.46766456568}
857       },
858       {
859           {141},
860           {18.0767914951, 10.2422601571, 7.64105919371},
861           {1.56063518321, 15.475201363, 0.0908340434334}
862       },
863       {
864           {142},
865           {17.9433074992, 10.5236761903, 7.50305231095},
866           {1.40475303467, 12.9752454537, 0.0824340965413}
867       },
868       {
869           {143},
870           {17.7734133861, 10.7877635507, 7.41457517106},
871           {1.26744992396, 11.0724056318, 0.0764947481608}
872       },
873       {
874           {144},
875           {17.6183400651, 11.881198903, 8.43509868407},
876           {1.31193510861, 12.7973587692, 0.105008616681}
877       },
878       {
879           {145},
880           {17.7398863368, 10.9188297535, 7.32567504128},
881           {1.160593637, 9.69655399567, 0.0710750543894}
882       },
883       {
884           {146},
885           {18.3188870634, 13.0152411164, 7.58377586849},
886           {1.14468107806, 12.0720126341, 0.072546006161}
887       },
888       {
889           {147},
890           {17.6781713727, 11.0390849019, 7.27524687075},
891           {1.06872809116, 8.57978579159, 0.0667266185651}
892       },
893       {
894           {148},
895           {18.3425380073, 14.9935363225, 7.56968941267},
896           {0.990303247192, 10.8757033155, 0.0658550377396}
897       },
898       {
899           {149},
900           {18.2136421714, 14.4015964784, 7.32335925891},
901           {0.953792258618, 9.83764291281, 0.0610368319049}
902       },
903       {
904           {150},
905           {15.5169232348, 14.6084670706, 11.7836912415},
906           {10.5233527721, 1.19805976888, 0.173293763471}
907       },
908       {
909           {151},
910           {18.2500753825, 15.4398316764, 7.24317937151},
911           {0.883340061883, 9.34400156369, 0.0566949236825}
912       },
913       {
914           {152},
915           {21.4258951173, 12.2630134383, 10.2462505043},
916           {0.382415912786, 13.6148868752, 3.88227600024}
917       },
918       {
919           {153},
920           {18.2501716117, 16.4875851039, 7.19092695047},
921           {0.820905236411, 8.85744233571, 0.0533496503559}
922       },
923       {
924           {154},
925           {21.1212947884, 13.6396062605, 10.1654365258},
926           {0.349668807221, 12.3702805418, 3.44568968188}
927       },
928       {
929           {155},
930           {20.8284525128, 15.0096107479, 10.0792911382},
931           {0.320672873475, 11.3005350502, 3.06922248664}
932       },
933       {
934           {156},
935           {20.1774443662, 16.9816497138, 8.77051768304},
936           {0.288373343583, 9.13033692607, 2.35002850502}
937       },
938       {
939           {157},
940           {22.1164438441, 18.4102698652, 7.39983890917},
941           {0.312440051695, 4.73418318858, 19.5310272638}
942       },
943       {
944           {158},
945           {20.9547831947, 18.1555765089, 6.81840971331},
946           {7.0152600456, 0.605887177524, 0.0401455609886}
947       },
948       {
949           {159},
950           {21.9870799745, 18.1894285843, 7.77246946156},
951           {0.294069193351, 4.28026514278, 16.4477064302}
952       },
953       {
954           {160},
955           {21.1518685061, 17.9939494168, 6.78998333403},
956           {6.32805369701, 0.566290989365, 0.0381542687902}
957       },
958       {
959           {161},
960           {30.112436978, 28.6235543927, 19.1340014396},
961           {1.77440063269, 0.184015028333, 12.1530773066}
962       },
963       {
964           {162},
965           {0.502196691881, 0.373818972889, 0.123052629233},
966           {13.478927669, 38.6665372038, 3.38304689207}
967       },
968       {
969           {163},
970           {1.08189530121, 0.467245206939, 0.4501601147},
971           {6.70265036943, 19.957676141, 1.5821652553}
972       },
973       {
974           {164},
975           {1.07146599943, 1.05534384128, 0.863685495839},
976           {4.30327380157, 114.129734127, 1.03599382371}
977       },
978       {
979           {165},
980           {2.06778108412, 1.03403401833, 0.878360479364},
981           {54.3775616887, 2.21128244408, 0.548264395981}
982       },
983       {
984           {166},
985           {2.40390483689, 1.74082003938, 0.840968677045},
986           {40.6492977422, 0.649340687236, 12.2463914516}
987       },
988       {
989           {167},
990           {2.51340127252, 1.74867019409, 1.72398202356},
991           {31.8053433708, 0.445605499982, 10.5831679451}
992       },
993       {
994           {168},
995           {2.99954939487, 2.25583887941, 1.7278842283},
996           {23.2726795155, 7.45433091596, 0.316224876669}
997       },
998       {
999           {169},
1000           {3.21184129664, 3.04156392126, 1.73156010601},
1001           {18.8370006399, 5.90590162558, 0.241263012791}
1002       },
1003       {
1004           {170},
1005           {3.76051707547, 3.47766990973, 1.74594840518},
1006           {4.73185569767, 15.4384441173, 0.194238121265}
1007       },
1008       {
1009           {171},
1010           {4.38310831035, 3.83422263038, 1.76279016611},
1011           {3.82501909721, 12.6640899017, 0.161786329667}
1012       },
1013       {
1014           {172},
1015           {6.6351112713, 3.01293367286, 1.30238479723},
1016           {5.5442312674, 0.545797156151, 90.8590190323}
1017       },
1018       {
1019           {173},
1020           {6.67814146187, 2.96430131029, 2.32496434711},
1021           {4.14073262313, 0.428901927646, 71.0199150719}
1022       },
1023       {
1024           {174},
1025           {6.62238016224, 3.27781520856, 3.05972557508},
1026           {3.3038329346, 59.3145382378, 0.374151395498}
1027       },
1028       {
1029           {175},
1030           {6.08447684913, 4.2732659722, 3.59835544898},
1031           {2.83886951807, 46.6331390474, 0.418767784547}
1032       },
1033       {
1034           {176},
1035           {5.27941125504, 5.27354842119, 4.40634943423},
1036           {36.7775304861, 2.58877453733, 0.47041178021}
1037       },
1038       {
1039           {177},
1040           {6.83012748437, 6.13863224738, 2.99357763173},
1041           {0.664089368899, 30.1886951281, 3.52397406633}
1042       },
1043       {
1044           {178},
1045           {8.12176088935, 6.65345104038, 2.19043698007},
1046           {0.697928192858, 25.8943955401, 6.00738032174}
1047       },
1048       {
1049           {179},
1050           {8.1978704772, 7.25214271687, 2.51643840211},
1051           {0.603152037749, 22.1423332433, 6.28874083466}
1052       },
1053       {
1054           {180},
1055           {8.66788257982, 8.58340898529, 1.68051604224},
1056           {12.3159255661, 0.562749994595, 110.002273029}
1057       },
1058       {
1059           {181},
1060           {8.75937156177, 8.41257168569, 2.76798129934},
1061           {9.64475680185, 0.475138202259, 97.3905740758}
1062       },
1063       {
1064           {182},
1065           {9.51340433555, 8.43057223084, 3.00293226194},
1066           {8.72304034893, 0.421969259986, 85.1544003488}
1067       },
1068       {
1069           {183},
1070           {10.2799540619, 8.45913489426, 3.20116956042},
1071           {7.88841343088, 0.381270873952, 73.589906538}
1072       },
1073       {
1074           {184},
1075           {11.1458421487, 8.52770210726, 3.27333965837},
1076           {7.26900302269, 0.350572882934, 67.9662846278}
1077       },
1078       {
1079           {185},
1080           {12.1965729193, 8.6651380941, 3.06905493686},
1081           {6.89852281719, 0.333439737044, 51.4431406852}
1082       },
1083       {
1084           {186},
1085           {12.7428954458, 8.68059401604, 3.51227744547},
1086           {6.09717645893, 0.307362041711, 54.7923744615}
1087       },
1088       {
1089           {187},
1090           {13.5386808693, 8.76290322281, 3.6282889925},
1091           {5.5999743031, 0.290387429344, 49.6184457459}
1092       },
1093       {
1094           {188},
1095           {14.2511611792, 9.13683816117, 3.55259119666},
1096           {5.36759291075, 0.305437893913, 48.447700971}
1097       },
1098       {
1099           {189},
1100           {14.9767789806, 9.35030169796, 3.61038378024},
1101           {5.01191696697, 0.302607553312, 44.9232209459}
1102       },
1103       {
1104           {190},
1105           {15.9430456345, 9.6553328387, 3.33083077178},
1106           {4.82663324046, 0.306553792833, 35.4599869576}
1107       },
1108       {
1109           {191},
1110           {15.9676170894, 10.4463803921, 3.5271729716},
1111           {4.64159415074, 0.358107174158, 41.3067132366}
1112       },
1113       {
1114           {192},
1115           {16.4944618554, 10.3236971493, 4.10716029583},
1116           {4.12737191087, 0.318425619984, 44.5159627214}
1117       },
1118       {
1119           {193},
1120           {16.4458600761, 10.5599493419, 4.92533026545},
1121           {3.72882293769, 0.316174473194, 42.0934525241}
1122       },
1123       {
1124           {194},
1125           {17.1960878679, 9.69900138738, 6.04192031603},
1126           {3.12619083301, 0.234035807171, 36.5140401994}
1127       },
1128       {
1129           {195},
1130           {17.0504033455, 9.78301185102, 7.10176272738},
1131           {2.79743745985, 0.227209294309, 31.7723375223}
1132       },
1133       {
1134           {196},
1135           {17.5420861481, 9.08359865439, 8.30546540071},
1136           {2.3876252301, 0.174206423325, 27.4378361399}
1137       },
1138       {
1139           {197},
1140           {17.3989367325, 9.36450036612, 9.17346482754},
1141           {2.16761932439, 24.4439214341, 0.170251945105}
1142       },
1143       {
1144           {198},
1145           {23.910804374, 10.5360489582, 2.44931455737},
1146           {0.928223646688, 13.1425847975, 87.5230688031}
1147       },
1148       {
1149           {199},
1150           {23.3302207832, 11.1676164796, 3.40901694124},
1151           {0.805464539522, 10.7378777121, 93.295102231}
1152       },
1153       {
1154           {200},
1155           {23.5235691064, 11.4829330129, 3.916262423},
1156           {0.757601750963, 10.2442370891, 83.0146587908}
1157       },
1158       {
1159           {201},
1160           {23.3726972532, 12.2519628369, 4.31377561634},
1161           {0.684926546016, 9.56037750445, 74.3015056094}
1162       },
1163       {
1164           {202},
1165           {23.5031600172, 12.6386032107, 4.7681241134},
1166           {0.642934099047, 9.20719558971, 52.8701133916}
1167       },
1168       {
1169           {203},
1170           {23.1827814092, 13.2100575903, 5.50231022913},
1171           {0.577001089934, 8.23840117065, 43.9978888806}
1172       },
1173       {
1174           {204},
1175           {23.5346902744, 14.5111421298, 4.88999302843},
1176           {0.555290522238, 8.51654999704, 55.4141673419}
1177       },
1178       {
1179           {205},
1180           {23.122417304, 14.8125929435, 5.95928154858},
1181           {0.497739492816, 7.50901560896, 36.7823648354}
1182       },
1183       {
1184           {206},
1185           {23.3012159473, 15.9533741871, 5.6515846267},
1186           {0.473398855106, 7.49282025419, 36.2469928289}
1187       },
1188       {
1189           {207},
1190           {22.7629045939, 14.6226398022, 8.54242304795},
1191           {0.423182233992, 6.12063761773, 22.660232699}
1192       },
1193       {
1194           {208},
1195           {23.3122067553, 18.4080605903, 5.20642112685},
1196           {0.414662819069, 7.07241088531, 34.9460945594}
1197       },
1198       {
1199           {209},
1200           {22.9961521829, 19.1440914287, 5.75799203993},
1201           {0.378523645723, 6.39052944494, 35.7007532116}
1202       },
1203       {
1204           {210},
1205           {23.1150202427, 20.2733776757, 5.50800401336},
1206           {0.361318740795, 6.21302979882, 43.859239884}
1207       },
1208       {
1209           {211},
1210           {23.073115678, 20.721043971, 6.11619707401},
1211           {0.341229928758, 5.77195480985, 45.0386050033}
1212       },
1213       {
1214           {212},
1215           {22.7485769177, 21.0063112152, 7.16102625262},
1216           {0.312929289314, 5.18082235944, 41.8483442701}
1217       },
1218       {
1219           {213},
1220           {22.4342311303, 21.2105816232, 8.27410663564},
1221           {0.28840668083, 4.66744106421, 38.2957918128}
1222       },
1223       {
1224           {214},
1225           {22.1334760622, 21.3152722398, 9.47258237105},
1226           {0.265661657324, 4.19946212892, 34.5739885559}
1227       },
1228       {
1229           {215},
1230           {21.8411079371, 21.3868466973, 10.6938907155},
1231           {0.245775394234, 3.79473697198, 31.3171324821}
1232       },
1233       {
1234           {216},
1235           {42.250520114, 25.51363075, 12.0790174828},
1236           {0.382882567089, 4.03482946811, 23.3930785954}
1237       }
1238   };
1239 
1240   static {
1241     for (int i = 0; i < atoms.length; i++) {
1242       formFactors.put(atomsi[i], ffactors[i]);
1243     }
1244   }
1245 
1246   final int ffIndex;
1247   private final Atom atom;
1248   private final double[] xyz = new double[3];
1249   private final double[] dxyz = new double[3];
1250   private final double[] resv = new double[3];
1251   private final double[] a = new double[6];
1252   private final double[] b = new double[6];
1253   private final double[] ainv = new double[6];
1254   private final double[] binv = new double[6];
1255   private final double[] gradp = new double[6];
1256   private final double[] gradu = new double[6];
1257   private final double[][] resm = new double[3][3];
1258   private final double[][][] u = new double[6][3][3];
1259   private final double[][][] uinv = new double[6][3][3];
1260   private final double[][][] jmat = new double[6][3][3];
1261   private final int nGaussians;
1262   private double[] anisou = null;
1263   private double uAdd;
1264   private double occupancy;
1265   private boolean hasAnisou;
1266 
1267   /**
1268    * Constructor for XRayFormFactor.
1269    *
1270    * @param atom a {@link ffx.potential.bonded.Atom} object.
1271    */
1272   public XRayFormFactor(Atom atom) {
1273     this(atom, true, 0.0, atom.getXYZ(null));
1274   }
1275 
1276   /**
1277    * Constructor for XRayFormFactor.
1278    *
1279    * @param atom  a {@link ffx.potential.bonded.Atom} object.
1280    * @param use3G a boolean.
1281    */
1282   public XRayFormFactor(Atom atom, boolean use3G) {
1283     this(atom, use3G, 0.0, atom.getXYZ(null));
1284   }
1285 
1286   /**
1287    * Constructor for XRayFormFactor.
1288    *
1289    * @param atom  a {@link ffx.potential.bonded.Atom} object.
1290    * @param use3G a boolean.
1291    * @param badd  a double.
1292    */
1293   public XRayFormFactor(Atom atom, boolean use3G, double badd) {
1294     this(atom, use3G, badd, atom.getXYZ(null));
1295   }
1296 
1297   /**
1298    * Constructor for XRayFormFactor.
1299    *
1300    * @param atom  a {@link ffx.potential.bonded.Atom} object.
1301    * @param use3G a boolean.
1302    * @param badd  a double.
1303    * @param xyz   an array of double.
1304    */
1305   public XRayFormFactor(Atom atom, boolean use3G, double badd, double[] xyz) {
1306     this.atom = atom;
1307     this.uAdd = b2u(badd);
1308     double[][] formFactor;
1309     String key = "" + atom.getAtomicNumber();
1310     int charge = 0;
1311     if (atom.getMultipoleType() != null) {
1312       charge = (int) atom.getMultipoleType().getCharge();
1313     }
1314 
1315 
1316     // if it has a charge, first try to find Su&Coppens 6G params
1317     if (formFactors.containsKey(key + "_" + charge)) {
1318       formFactor = getFormFactor(key + "_" + charge);
1319     } else {
1320       // if not, use 3G params if requested
1321       if (use3G) {
1322         // first look for charged form
1323         if (formFactors.containsKey(key + "_" + charge + "_3g")) {
1324           formFactor = getFormFactor(key + "_" + charge + "_3g");
1325         } else {
1326           // if this fails, we don't have the SFs
1327           formFactor = getFormFactor(key + "_3g");
1328         }
1329       } else {
1330         formFactor = getFormFactor(key);
1331       }
1332     }
1333     ffIndex = (int) formFactor[0][0];
1334 
1335     int i;
1336     for (i = 0; i < formFactor[1].length; i++) {
1337       if (formFactor[1][i] < 0.01) {
1338         break;
1339       }
1340       a[i] = formFactor[1][i];
1341       b[i] = formFactor[2][i];
1342     }
1343     nGaussians = i;
1344     assert (nGaussians > 0);
1345     occupancy = atom.getOccupancy();
1346 
1347     if (occupancy <= 0.0 && logger.isLoggable(Level.FINE)) {
1348       logger.log(Level.FINE, " Zero occupancy for atom: {0}", atom.toString());
1349     }
1350 
1351     update(xyz, uAdd);
1352   }
1353 
1354   /**
1355    * getFormFactorA
1356    *
1357    * @param atom a {@link java.lang.String} object.
1358    * @return an array of double.
1359    */
1360   public static double[] getFormFactorA(String atom) {
1361     double[][] formFactor = getFormFactor(atom);
1362     if (formFactor != null) {
1363       return formFactor[1];
1364     }
1365     return null;
1366   }
1367 
1368   /**
1369    * getFormFactorB
1370    *
1371    * @param atom a {@link java.lang.String} object.
1372    * @return an array of double.
1373    */
1374   public static double[] getFormFactorB(String atom) {
1375     double[][] formFactor = getFormFactor(atom);
1376     if (formFactor != null) {
1377       return formFactor[2];
1378     }
1379     return null;
1380   }
1381 
1382   /**
1383    * getFormFactorIndex
1384    *
1385    * @param atom a {@link java.lang.String} object.
1386    * @return a int.
1387    */
1388   public static int getFormFactorIndex(String atom) {
1389     double[][] formFactor = getFormFactor(atom);
1390     if (formFactor != null) {
1391       return (int) formFactor[0][0];
1392     }
1393     return -1;
1394   }
1395 
1396   /**
1397    * getFormFactor
1398    *
1399    * @param atom a {@link java.lang.String} object.
1400    * @return an array of double.
1401    */
1402   public static double[][] getFormFactor(String atom) {
1403     double[][] formFactor = null;
1404     if (formFactors.containsKey(atom)) {
1405       formFactor = formFactors.get(atom);
1406     } else {
1407       String message = " Form factor for atom: " + atom + " not found!\n";
1408       logger.severe(message);
1409     }
1410     return formFactor;
1411   }
1412 
1413   /**
1414    * f
1415    *
1416    * @param hkl a {@link ffx.crystal.HKL} object.
1417    * @return a double.
1418    */
1419   public double f(HKL hkl) {
1420     return fN(hkl, nGaussians);
1421   }
1422 
1423   /**
1424    * f_n
1425    *
1426    * @param hkl        a {@link ffx.crystal.HKL} object.
1427    * @param nGaussians a int.
1428    * @return a double.
1429    */
1430   public double fN(HKL hkl, int nGaussians) {
1431     double sum = 0.0;
1432 
1433     for (int i = 0; i < nGaussians; i++) {
1434       sum += a[i] * exp(-twopi2 * hkl.quadForm(u[i]));
1435     }
1436     return occupancy * sum;
1437   }
1438 
1439   /**
1440    * {@inheritDoc}
1441    */
1442   @Override
1443   public double rho(double f, double lambda, double[] xyz) {
1444     return rhoN(f, lambda, xyz, nGaussians);
1445   }
1446 
1447   /**
1448    * {@inheritDoc}
1449    */
1450   @Override
1451   public void rhoGrad(double[] xyz, double dfc, RefinementMode refinementMode) {
1452     rhoGradN(xyz, nGaussians, dfc, refinementMode);
1453   }
1454 
1455   /**
1456    * {@inheritDoc}
1457    */
1458   @Override
1459   public void update(double[] xyz) {
1460     update(xyz, u2b(uAdd));
1461   }
1462 
1463   /**
1464    * {@inheritDoc}
1465    */
1466   @Override
1467   public void update(double[] xyz, double bAdd) {
1468     this.xyz[0] = xyz[0];
1469     this.xyz[1] = xyz[1];
1470     this.xyz[2] = xyz[2];
1471     uAdd = b2u(bAdd);
1472     occupancy = atom.getOccupancy();
1473     double bIso = atom.getTempFactor();
1474 
1475     // check occ is valid
1476     if (occupancy < 0.0) {
1477       StringBuilder sb = new StringBuilder();
1478       sb.append(" Negative occupancy for atom: ").append(atom);
1479       sb.append("\n Resetting to 0.0");
1480       sb.append("\n this can cause instability in refinement and");
1481       sb.append("\n possibly checked/corrected!");
1482       logger.warning(sb.toString());
1483       occupancy = 0.0;
1484       atom.setOccupancy(0.0);
1485     }
1486 
1487     // check if anisou changed
1488     if (atom.getAnisou(null) == null) {
1489       if (anisou == null) {
1490         anisou = new double[6];
1491       }
1492       hasAnisou = false;
1493     } else {
1494       hasAnisou = true;
1495     }
1496 
1497     if (hasAnisou) {
1498       // first check the ANISOU is valid
1499       anisou = atom.getAnisou(null);
1500       double det = determinant3(anisou);
1501 
1502       if (det <= 1e-14) {
1503         StringBuilder sb = new StringBuilder();
1504         sb.append(" Non-positive definite ANISOU for atom: ").append(atom);
1505         sb.append("\n Resetting ANISOU based on isotropic B: (").append(bIso).append(")\n");
1506         logger.warning(sb.toString());
1507 
1508         anisou[0] = anisou[1] = anisou[2] = b2u(bIso);
1509         anisou[3] = anisou[4] = anisou[5] = 0.0;
1510         atom.setAnisou(anisou);
1511       }
1512     } else {
1513       if (bIso < 0.0) {
1514         StringBuilder sb = new StringBuilder();
1515         sb.append(" Negative B factor for atom: ").append(atom);
1516         sb.append("\n Resetting B to 5.0\n");
1517         logger.warning(sb.toString());
1518         bIso = 5.0;
1519         atom.setTempFactor(5.0);
1520       }
1521       anisou[0] = anisou[1] = anisou[2] = b2u(bIso);
1522       anisou[3] = anisou[4] = anisou[5] = 0.0;
1523     }
1524 
1525     for (int i = 0; i < nGaussians; i++) {
1526       u[i][0][0] = anisou[0] + b2u(b[i]) + uAdd;
1527       u[i][1][1] = anisou[1] + b2u(b[i]) + uAdd;
1528       u[i][2][2] = anisou[2] + b2u(b[i]) + uAdd;
1529       u[i][0][1] = u[i][1][0] = anisou[3];
1530       u[i][0][2] = u[i][2][0] = anisou[4];
1531       u[i][1][2] = u[i][2][1] = anisou[5];
1532 
1533       mat3Inverse(u[i], uinv[i]);
1534 
1535       double det = determinant3(u[i]);
1536       ainv[i] = a[i] / sqrt(det);
1537       // b[i] = pow(det, 0.33333333333);
1538       det = determinant3(uinv[i]);
1539       binv[i] = pow(det, oneThird);
1540     }
1541   }
1542 
1543   /**
1544    * rho_n
1545    *
1546    * @param f          a double.
1547    * @param lambda     a double.
1548    * @param xyz        an array of double.
1549    * @param nGaussians a int.
1550    * @return a double.
1551    */
1552   private double rhoN(double f, double lambda, double[] xyz, int nGaussians) {
1553     assert (nGaussians > 0 && nGaussians <= this.nGaussians);
1554     sub(this.xyz, xyz, xyz);
1555 
1556     // Compare r^2 to form factor width^2 to avoid expensive sqrt.
1557     if (length2(xyz) > atom.getFormFactorWidth2()) {
1558       return f;
1559     }
1560 
1561     double sum = 0.0;
1562     for (int i = 0; i < nGaussians; i++) {
1563       sum += ainv[i] * exp(-0.5 * quadForm(xyz, uinv[i]));
1564     }
1565     return f + (lambda * occupancy * twopi32 * sum);
1566   }
1567 
1568   /**
1569    * rho_grad_n
1570    *
1571    * @param xyz            an array of double.
1572    * @param nGaussians     a int.
1573    * @param dfc            a double.
1574    * @param refinementMode a {@link RefinementMode} object.
1575    */
1576   private void rhoGradN(double[] xyz, int nGaussians, double dfc, RefinementMode refinementMode) {
1577     assert (nGaussians > 0 && nGaussians <= this.nGaussians);
1578     sub(this.xyz, xyz, dxyz);
1579     double r2 = length2(dxyz);
1580 
1581     // Compare r^2 to form factor width^2 to avoid expensive sqrt.
1582     if (r2 > atom.getFormFactorWidth2()) {
1583       return;
1584     }
1585 
1586     fill(gradp, 0.0);
1587     fill(gradu, 0.0);
1588     double aex;
1589     boolean refinexyz = refinementMode.includesCoordinates();
1590     boolean refineb = refinementMode.includesBFactors();
1591     boolean refineanisou = refineb && hasAnisou;
1592     boolean refineocc = refinementMode.includesOccupancies();
1593 
1594     for (int i = 0; i < nGaussians; i++) {
1595       aex = ainv[i] * exp(-0.5 * quadForm(dxyz, uinv[i]));
1596 
1597       if (refinexyz) {
1598         vec3Mat3(dxyz, uinv[i], resv);
1599         gradp[0] += aex * dot(resv, vx);
1600         gradp[1] += aex * dot(resv, vy);
1601         gradp[2] += aex * dot(resv, vz);
1602       }
1603 
1604       if (refineocc) {
1605         gradp[3] += aex;
1606       }
1607 
1608       if (refineb) {
1609         gradp[4] += aex * 0.5 * (r2 * binv[i] * binv[i] - 3.0 * binv[i]);
1610         if (refineanisou) {
1611           scalarMat3Mat3(-1.0, uinv[i], u11, resm);
1612           mat3Mat3(resm, uinv[i], jmat[0]);
1613           scalarMat3Mat3(-1.0, uinv[i], u22, resm);
1614           mat3Mat3(resm, uinv[i], jmat[1]);
1615           scalarMat3Mat3(-1.0, uinv[i], u33, resm);
1616           mat3Mat3(resm, uinv[i], jmat[2]);
1617           scalarMat3Mat3(-1.0, uinv[i], u12, resm);
1618           mat3Mat3(resm, uinv[i], jmat[3]);
1619           scalarMat3Mat3(-1.0, uinv[i], u13, resm);
1620           mat3Mat3(resm, uinv[i], jmat[4]);
1621           scalarMat3Mat3(-1.0, uinv[i], u23, resm);
1622           mat3Mat3(resm, uinv[i], jmat[5]);
1623 
1624           gradu[0] += aex * 0.5 * (-quadForm(dxyz, jmat[0]) - uinv[i][0][0]);
1625           gradu[1] += aex * 0.5 * (-quadForm(dxyz, jmat[1]) - uinv[i][1][1]);
1626           gradu[2] += aex * 0.5 * (-quadForm(dxyz, jmat[2]) - uinv[i][2][2]);
1627           gradu[3] += aex * 0.5 * (-quadForm(dxyz, jmat[3]) - uinv[i][0][1] * 2.0);
1628           gradu[4] += aex * 0.5 * (-quadForm(dxyz, jmat[4]) - uinv[i][0][2] * 2.0);
1629           gradu[5] += aex * 0.5 * (-quadForm(dxyz, jmat[5]) - uinv[i][1][2] * 2.0);
1630         }
1631       }
1632     }
1633 
1634     // X, Y, Z
1635     if (refinexyz) {
1636       atom.addToXYZGradient(
1637           dfc * occupancy * -twopi32 * gradp[0],
1638           dfc * occupancy * -twopi32 * gradp[1],
1639           dfc * occupancy * -twopi32 * gradp[2]);
1640     }
1641 
1642     // Occupancy
1643     if (refineocc) {
1644       atom.addToOccupancyGradient(dfc * twopi32 * gradp[3]);
1645     }
1646 
1647     // Isotropic B
1648     if (refineb) {
1649       atom.addToTempFactorGradient(dfc * b2u(occupancy * twopi32 * gradp[4]));
1650       // Uaniso
1651       if (hasAnisou) {
1652         for (int i = 0; i < 6; i++) {
1653           gradu[i] = dfc * occupancy * twopi32 * gradu[i];
1654         }
1655         atom.addToAnisouGradient(gradu);
1656       }
1657     }
1658   }
1659 }