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