1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 package ffx.crystal;
39
40 import static org.apache.commons.math3.util.FastMath.abs;
41 import static org.apache.commons.math3.util.FastMath.random;
42
43
44
45
46
47
48
49
50
51
52
53
54 public enum LatticeSystem {
55 TRICLINIC_LATTICE,
56 MONOCLINIC_LATTICE,
57 ORTHORHOMBIC_LATTICE,
58 TETRAGONAL_LATTICE,
59 RHOMBOHEDRAL_LATTICE,
60 HEXAGONAL_LATTICE,
61 CUBIC_LATTICE;
62
63
64
65
66
67
68
69
70
71 private static final double tolerance = 1.0e-15;
72
73
74
75
76
77
78
79
80 public static boolean check(double x1, double x2) {
81 return abs(x1 - x2) < tolerance;
82 }
83
84
85
86
87
88
89 public double[] resetUnitCellParams() {
90 double alpha = 60.0 + random() * 60.0;
91 double beta = 60.0 + random() * 60.0;
92 double gamma = 60.0 + random() * 60.0;
93 double[] params = {0.25 + random(), 0.25 + random(), 0.25 + random(), alpha, beta, gamma};
94 double ab = 0.5 * (params[0] + params[1]);
95 double abc = (params[0] + params[1] + params[2]) / 3.0;
96 switch (this) {
97 default -> {
98
99 }
100 case MONOCLINIC_LATTICE -> {
101
102 params[3] = 90.0;
103 params[5] = 90.0;
104 }
105 case ORTHORHOMBIC_LATTICE -> {
106
107 params[3] = 90.0;
108 params[4] = 90.0;
109 params[5] = 90.0;
110 }
111 case TETRAGONAL_LATTICE -> {
112
113 params[0] = ab;
114 params[1] = ab;
115 params[3] = 90.0;
116 params[4] = 90.0;
117 params[5] = 90.0;
118 }
119 case RHOMBOHEDRAL_LATTICE -> {
120
121 double angles = (params[3] + params[4] + params[5]) / 3.0;
122 params[0] = abc;
123 params[1] = abc;
124 params[2] = abc;
125 params[3] = angles;
126 params[4] = angles;
127 params[5] = angles;
128 }
129 case HEXAGONAL_LATTICE -> {
130
131 params[0] = ab;
132 params[1] = ab;
133 params[3] = 90.0;
134 params[4] = 90.0;
135 params[5] = 120.0;
136 }
137 case CUBIC_LATTICE -> {
138
139 params[0] = abc;
140 params[1] = abc;
141 params[2] = abc;
142 params[3] = 90.0;
143 params[4] = 90.0;
144 params[5] = 90.0;
145 }
146 }
147 return params;
148 }
149
150
151
152
153
154
155
156
157
158
159
160
161 public boolean validParameters(double a, double b, double c, double alpha, double beta,
162 double gamma) {
163 switch (this) {
164 default -> {
165
166 return true;
167 }
168 case MONOCLINIC_LATTICE -> {
169
170 return check(alpha, 90.0) && check(gamma, 90.0);
171 }
172 case ORTHORHOMBIC_LATTICE -> {
173
174 return check(alpha, 90.0) && check(beta, 90.0) && check(gamma, 90.0);
175 }
176 case TETRAGONAL_LATTICE -> {
177
178 return check(a, b) && check(alpha, 90.0) && check(beta, 90.0) && check(gamma, 90.0);
179 }
180 case RHOMBOHEDRAL_LATTICE -> {
181
182 return check(a, b) && check(b, c) && check(alpha, beta) && check(beta, gamma);
183 }
184 case HEXAGONAL_LATTICE -> {
185
186 return check(a, b) && check(alpha, 90.0) && check(beta, 90.0) && check(gamma, 120.0);
187 }
188 case CUBIC_LATTICE -> {
189
190 return check(a, b) && check(b, c) && check(alpha, 90.0) && check(beta, 90.0) && check(gamma,
191 90.0);
192 }
193 }
194 }
195
196
197
198
199
200
201
202
203
204
205
206
207 public double[] fixParameters(double a, double b, double c, double alpha, double beta,
208 double gamma) {
209 double[] parameters = {a, b, c, alpha, beta, gamma};
210 double ab = (parameters[0] + parameters[1]) / 2;
211 double abc = (parameters[0] + parameters[1] + parameters[2]) / 3;
212 switch (this) {
213 default -> {
214
215 return parameters;
216 }
217 case MONOCLINIC_LATTICE -> {
218
219 parameters[3] = 90.0;
220 parameters[5] = 90.0;
221 return parameters;
222 }
223 case ORTHORHOMBIC_LATTICE -> {
224
225 parameters[3] = 90.0;
226 parameters[4] = 90.0;
227 parameters[5] = 90.0;
228 return parameters;
229 }
230 case TETRAGONAL_LATTICE -> {
231
232 parameters[0] = ab;
233 parameters[1] = ab;
234 parameters[3] = 90.0;
235 parameters[4] = 90.0;
236 parameters[5] = 90.0;
237 return parameters;
238 }
239 case RHOMBOHEDRAL_LATTICE -> {
240
241 double angles = (parameters[3] + parameters[4] + parameters[5]) / 3;
242 parameters[0] = abc;
243 parameters[1] = abc;
244 parameters[2] = abc;
245 parameters[3] = angles;
246 parameters[4] = angles;
247 parameters[5] = angles;
248 return parameters;
249 }
250 case HEXAGONAL_LATTICE -> {
251
252 parameters[0] = ab;
253 parameters[1] = ab;
254 parameters[3] = 90.0;
255 parameters[4] = 90.0;
256 parameters[5] = 120.0;
257 return parameters;
258 }
259 case CUBIC_LATTICE -> {
260
261 parameters[0] = abc;
262 parameters[1] = abc;
263 parameters[2] = abc;
264 parameters[3] = 90.0;
265 parameters[4] = 90.0;
266 parameters[5] = 90.0;
267 return parameters;
268 }
269 }
270 }
271
272
273
274
275
276
277
278 public double getDefaultBAxis(double aaxis) {
279 return aaxis;
280 }
281
282
283
284
285
286
287 public double getDefaultCAxis(double aaxis, double baxis) {
288 return (aaxis + baxis) / 2;
289 }
290
291
292
293
294
295
296 public double getDefaultAlpha() {
297 return 90.0;
298 }
299
300
301
302
303
304
305 public double getDefaultBeta() {
306 return 90.0;
307 }
308
309
310
311
312
313
314 public double getDefaultGamma() {
315 double gamma = 90.0;
316 if (this == HEXAGONAL_LATTICE) {
317 gamma = 120.0;
318 }
319 return gamma;
320 }
321 }