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