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 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 }