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.potential.utils;
39  
40  import ffx.potential.ForceFieldEnergy;
41  import ffx.potential.MolecularAssembly;
42  import ffx.potential.parsers.SystemFilter;
43  
44  import java.io.File;
45  import java.util.List;
46  import java.util.logging.Level;
47  import java.util.logging.Logger;
48  
49  import static ffx.utilities.TinkerUtils.version;
50  
51  /**
52   * PotentialsFunctions describes core functionality for many Force Field X algorithms and scripts,
53   * such as opening and closing structure files, basic force field energy evaluations, etc.
54   *
55   * <p>This is implemented in two locations: UIUtils in the User Interfaces package, and in
56   * PotentialsUtils in the Potentials package.
57   *
58   * <p>The UIUtils implementation is the default for Force Field X; on top of the core functionality,
59   * it also updates the FFX graphical user interface and tree structure.
60   *
61   * <p>The PotentialsUtils implementation lacks the extra functionality of the UIUtils
62   * implementation and simply achieves the required task. This is used by our tests, and is also
63   * potentially useful for third parties who would like to use FFX without its GUI.
64   *
65   * @author Jacob M. Litman
66   * @author Michael J. Schnieders
67   * @since 1.0
68   */
69  public interface PotentialsFunctions {
70  
71    /**
72     * Constant <code>logger</code>
73     */
74    Logger logger = Logger.getLogger(PotentialsFunctions.class.getName());
75  
76    /**
77     * Performs any necessary shutdown operations on a MolecularAssembly, primarily shutting down
78     * Parallel Java threads and closing any other open resources.
79     *
80     * @param assembly Assembly to close.
81     */
82    void close(MolecularAssembly assembly);
83  
84    /**
85     * Performs any necessary shutdown operations on an array of MolecularAssembly, primarily shutting
86     * down Parallel Java threads and closing any other open resources.
87     *
88     * @param assemblies Assemblies to close.
89     */
90    void closeAll(MolecularAssembly[] assemblies);
91  
92    /**
93     * Evaluates the energy of a MolecularAssembly and returns its ForceFieldEnergy object.
94     *
95     * @param assembly To evaluate
96     * @return assembly's ForceFieldEnergy.
97     */
98    ForceFieldEnergy energy(MolecularAssembly assembly);
99  
100   /**
101    * Evaluates the energy of each MolecularAssembly and returns their ForceFieldEnergy instances.
102    *
103    * @param molecularAssemblies An array of molecularAssembly instances.
104    * @return An array of ForceFieldEnergy instances.
105    */
106   ForceFieldEnergy[] energy(MolecularAssembly[] molecularAssemblies);
107 
108   /**
109    * Returns either the active assembly from the overlying UI, or the "active" molecular assembly
110    * from the last used SystemFilter.
111    *
112    * @return A MolecularAssembly or null
113    */
114   default MolecularAssembly getActiveAssembly() {
115     SystemFilter systemFilter = getFilter();
116     if (systemFilter != null) {
117       return systemFilter.getActiveMolecularSystem();
118     } else {
119       return null;
120     }
121   }
122 
123   /**
124    * If available, returns CLI arguments; the default implementation does not have access to CLI
125    * arguments and throws UnsupportedOperationException.
126    *
127    * @return CLI arguments
128    * @throws java.lang.UnsupportedOperationException If unimplemented
129    * @throws java.lang.UnsupportedOperationException if any.
130    */
131   default List<String> getArguments() throws UnsupportedOperationException {
132     throw new UnsupportedOperationException();
133   }
134 
135   /**
136    * Returns the last SystemFilter created by this (can be null).
137    *
138    * @return Last SystemFilter
139    */
140   SystemFilter getFilter();
141 
142   /**
143    * True if using a local implementation (not in a user interfaces module).
144    *
145    * @return If a local implementation
146    */
147   boolean isLocal(); // Return true if the local implementation from Potentials.
148 
149   /**
150    * open.
151    *
152    * @param filename a {@link java.lang.String} object.
153    * @return a {@link ffx.potential.MolecularAssembly} object.
154    */
155   default MolecularAssembly open(String filename) {
156     MolecularAssembly[] assemblies = openAll(filename);
157     if (assemblies.length > 1) {
158       logger.log(Level.WARNING, " Found multiple assemblies in file {0}, opening first.", filename);
159     }
160     return assemblies[0];
161   }
162 
163   /**
164    * Opens an array of files and returns all created MolecularAssembly objects, setting any
165    * underlying Potential to use a certain number of threads. Default implementation simply ignores
166    * nThreads.
167    *
168    * @param files    an array of {@link java.lang.String} objects.
169    * @param nThreads Use non-default num threads
170    * @return Array of MolecularAssembly.
171    */
172   default MolecularAssembly[] open(String[] files, int nThreads) {
173     return openAll(files);
174   }
175 
176   /**
177    * Opens a file and returns all created MolecularAssembly objects.
178    *
179    * @param file Filename to open
180    * @return Array of MolecularAssembly.
181    */
182   MolecularAssembly[] openAll(String file);
183 
184   /**
185    * Opens an array of files and returns the created MolecularAssembly objects.
186    *
187    * @param files Filenames to open.
188    * @return Array of MolecularAssembly.
189    */
190   MolecularAssembly[] openAll(String[] files);
191 
192   /**
193    * Opens a file and returns all created MolecularAssembly objects, setting any underlying Potential
194    * to use a certain number of threads. Default implementation simply ignores nThreads.
195    *
196    * @param file     Filename to open
197    * @param nThreads Use non-default num threads
198    * @return Array of MolecularAssembly.
199    */
200   default MolecularAssembly[] openAll(String file, int nThreads) {
201     return openAll(file);
202   }
203 
204   /**
205    * Returns the energy of a MolecularAssembly in kcal/mol (as a double) and prints the energy
206    * evaluation
207    *
208    * @param assembly To evaluate energy of
209    * @return Potential energy (kcal/mol)
210    */
211   double returnEnergy(MolecularAssembly assembly);
212 
213   /**
214    * Saves the current state of a MolecularAssembly to an XYZ file.
215    *
216    * @param assembly MolecularAssembly to save
217    * @param file     Destination .xyz
218    */
219   void save(MolecularAssembly assembly, File file);
220 
221   /**
222    * Saves the current state of a MolecularAssembly to an XYZ file as a P1 crystal.
223    *
224    * @param assembly MolecularAssembly to save
225    * @param file     Destination .xyz
226    */
227   void saveAsXYZinP1(MolecularAssembly assembly, File file);
228 
229   /**
230    * Saves the current state of a MolecularAssembly to an XYZ file as a replicates crystal.
231    *
232    * @param assembly         MolecularAssembly to save
233    * @param file             Destination .xyz
234    * @param replicatesVector Dimensions for replicates crystal.
235    */
236   void saveAsXYZasReplicates(MolecularAssembly assembly, File file, int[] replicatesVector);
237 
238   /**
239    * Saves the current state of a MolecularAssembly to a PDB file.
240    *
241    * @param assembly MolecularAssembly to save
242    * @param file     Destination .pdb
243    */
244   void saveAsPDB(MolecularAssembly assembly, File file);
245 
246   /**
247    * Saves the current state of an array of MolecularAssembly instances to a PDB file.
248    *
249    * @param assemblies MolecularAssembly array to save
250    * @param file       Destination .pdb
251    */
252   void saveAsPDB(MolecularAssembly[] assemblies, File file);
253 
254   void saveAsPDB(MolecularAssembly assembly, File file, boolean writeEnd, boolean append);
255 
256   /**
257    * Saves the current state of a MolecularAssembly to an XYZ file.
258    *
259    * @param assembly MolecularAssembly to save
260    * @param file     Destination .xyz
261    */
262   void saveAsXYZ(MolecularAssembly assembly, File file);
263 
264   /**
265    * Saves the symmetry mates of a MolecularAssembly to PDB files.
266    *
267    * @param assembly To save
268    * @param file     Destination file
269    */
270   void saveAsPDBinP1(MolecularAssembly assembly, File file);
271 
272   /**
273    * Logs time elapsed since last call.
274    *
275    * @return Time.
276    */
277   double time();
278 
279   /**
280    * Versions a file, attempting to find an unused filename in the set filename, and filename_1 to
281    * filename_999.
282    *
283    * @param filename To version
284    * @return Versioned filename.
285    */
286   default String versionFile(String filename) {
287     if (filename == null) {
288       throw new IllegalArgumentException("Filename must not be null!");
289     }
290     return versionFile(new File(filename)).getName();
291   }
292 
293   /**
294    * Versions a file, attempting to find an unused filename in the set filename, and filename_1 to
295    * filename_999.
296    *
297    * @param file To version
298    * @return Versioned file
299    */
300   default File versionFile(File file) {
301     if (file == null) {
302       throw new IllegalArgumentException("File must not be null!");
303     }
304     return version(file);
305   }
306 }