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.crystal;
39  
40  import java.util.Objects;
41  
42  import static org.apache.commons.math3.util.FastMath.PI;
43  
44  /**
45   * The HKL class represents a single reflection.
46   *
47   * @author Timothy D. Fenn
48   * @see ReflectionList
49   * @since 1.0
50   */
51  public class HKL {
52  
53    /**
54     * Constant <code>ndiv=12.0</code>
55     */
56    static final double ndiv = 12.0;
57  
58    /**
59     * The h-index of the reflection.
60     */
61    protected int h;
62    /**
63     * The k-index of the reflection.
64     */
65    protected int k;
66    /**
67     * The l-index of the reflection.
68     */
69    protected int l;
70    /**
71     * The epsilon value of the reflection, which is used for systematic absences.
72     */
73    protected int epsilon;
74    /**
75     * Allowed is used for centric reflections.
76     */
77    protected int allowed;
78    /**
79     * The bin number of this reflection, which is used for resolution dependent R/Rfree.
80     */
81    protected int bin;
82    /**
83     * The unique index of this reflection.
84     */
85    protected int index;
86  
87    /**
88     * Constructor for HKL.
89     */
90    public HKL() {
91    }
92  
93    /**
94     * Constructor for HKL.
95     *
96     * @param h The h-index of the reflection.
97     * @param k The k-index of the reflection.
98     * @param l The l-index of the reflection.
99     */
100   public HKL(int h, int k, int l) {
101     this.h = h;
102     this.k = k;
103     this.l = l;
104     allowed = 255;
105   }
106 
107   /**
108    * Constructor for HKL.
109    *
110    * @param h       The h-index of the reflection.
111    * @param k       The k-index of the reflection.
112    * @param l       The l-index of the reflection.
113    * @param eps     an int.
114    * @param allowed an int.
115    */
116   public HKL(int h, int k, int l, int eps, int allowed) {
117     this.h = h;
118     this.k = k;
119     this.l = l;
120     this.epsilon = eps;
121     this.allowed = allowed;
122   }
123 
124   /**
125    * Negate the reflection.
126    *
127    * @return a {@link ffx.crystal.HKL} object.
128    */
129   public HKL neg() {
130     return new HKL(-h, -k, -l);
131   }
132 
133   /**
134    * Is this reflection a systematic absence?
135    *
136    * @return a boolean.
137    */
138   public boolean sysAbs() {
139     return (epsilon == 0);
140   }
141 
142   /**
143    * quadForm
144    *
145    * @param mat an array of double.
146    * @return a double.
147    */
148   public double quadForm(double[][] mat) {
149     return h * (h * mat[0][0] + 2 * (k * mat[0][1] + l * mat[0][2]))
150         + k * (k * mat[1][1] + 2 * (l * mat[1][2]))
151         + l * l * mat[2][2];
152   }
153 
154   /**
155    * getAllowed
156    *
157    * @return a double.
158    */
159   public double getAllowed() {
160     return ((double) allowed) * (PI / ndiv);
161   }
162 
163   /**
164    * setAllowed
165    *
166    * @param allowed an int.
167    */
168   public void setAllowed(int allowed) {
169     this.allowed = allowed;
170   }
171 
172   /**
173    * The bin number of this reflection, which is used for resolution dependent R/Rfree.
174    *
175    * @return the bin number of this reflection.
176    */
177   public int getBin() {
178     return bin;
179   }
180 
181   /**
182    * Set the bin number of this reflection, which is used for resolution dependent R/Rfree.
183    *
184    * @param bin the bin number of this reflection.
185    */
186   public void setBin(int bin) {
187     this.bin = bin;
188   }
189 
190   /**
191    * Is this reflection centric?
192    *
193    * @return a boolean.
194    */
195   public boolean centric() {
196     return (allowed != 255);
197   }
198 
199   /**
200    * getEpsilon
201    *
202    * @return an int.
203    */
204   public int getEpsilon() {
205     return epsilon;
206   }
207 
208   /**
209    * setEpsilon
210    *
211    * @param eps an int.
212    */
213   public void setEpsilon(int eps) {
214     this.epsilon = eps;
215   }
216 
217   /**
218    * epsilonc
219    *
220    * @return an int.
221    */
222   public int epsilonc() {
223     if (centric()) {
224       return 2 * epsilon;
225     } else {
226       return epsilon;
227     }
228   }
229 
230   /**
231    * {@inheritDoc}
232    */
233   @Override
234   public boolean equals(Object o) {
235     if (this == o) {
236       return true;
237     }
238     if (o == null || getClass() != o.getClass()) {
239       return false;
240     }
241     HKL hkl = (HKL) o;
242     return (h == hkl.getH() && k == hkl.getK() && l == hkl.getL());
243   }
244 
245   /**
246    * The h-index of the reflection.
247    *
248    * @return The h-index of the reflection.
249    */
250   public int getH() {
251     return h;
252   }
253 
254   /**
255    * Set the h-index of the reflection.
256    *
257    * @param h The h-index of the reflection.
258    */
259   public void setH(int h) {
260     this.h = h;
261   }
262 
263   /**
264    * {@inheritDoc}
265    */
266   @Override
267   public int hashCode() {
268     return Objects.hash(h, k, l);
269   }
270 
271   /**
272    * Get the index of this reflection.
273    *
274    * @return an int.
275    */
276   public int getIndex() {
277     return index;
278   }
279 
280   /**
281    * Set the index of this reflection.
282    *
283    * @param index The unique index of this reflection.
284    */
285   public void setIndex(int index) {
286     this.index = index;
287   }
288 
289   /**
290    * Get the k-index of the reflection.
291    *
292    * @return an int.
293    */
294   public int getK() {
295     return k;
296   }
297 
298   /**
299    * Set the k-index of the reflection.
300    *
301    * @param k an int.
302    */
303   public void setK(int k) {
304     this.k = k;
305   }
306 
307   /**
308    * Get the l-index of the reflection.
309    *
310    * @return an int.
311    */
312   public int getL() {
313     return l;
314   }
315 
316   /**
317    * Set the l-index of the reflection.
318    *
319    * @param l an int.
320    */
321   public void setL(int l) {
322     this.l = l;
323   }
324 
325   /**
326    * {@inheritDoc}
327    */
328   @Override
329   public String toString() {
330     return h + " " + k + " " + l
331         + "(allowed: " + allowed + " eps: " + epsilon + ") ";
332   }
333 }