Java tutorial
/** * Title: Force Field X. * * Description: Force Field X - Software for Molecular Biophysics. * * Copyright: Copyright (c) Michael J. Schnieders 2001-2017. * * This file is part of Force Field X. * * Force Field X is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published by * the Free Software Foundation. * * Force Field X is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple * Place, Suite 330, Boston, MA 02111-1307 USA * * Linking this library statically or dynamically with other modules is making a * combined work based on this library. Thus, the terms and conditions of the * GNU General Public License cover the whole combination. * * As a special exception, the copyright holders of this library give you * permission to link this library with independent modules to produce an * executable, regardless of the license terms of these independent modules, and * to copy and distribute the resulting executable under terms of your choice, * provided that you also meet, for each linked independent module, the terms * and conditions of the license of that module. An independent module is a * module which is not derived from or based on this library. If you modify this * library, you may extend this exception to your version of the library, but * you are not obligated to do so. If you do not wish to do so, delete this * exception statement from your version. */ package ffx.potential.utils; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import static java.lang.String.format; import org.apache.commons.configuration.CompositeConfiguration; import org.apache.commons.io.FilenameUtils; import ffx.potential.ForceFieldEnergy; import ffx.potential.MolecularAssembly; import ffx.potential.Utilities; import ffx.potential.bonded.RotamerLibrary; import ffx.potential.nonbonded.CoordRestraint; import ffx.potential.parameters.ForceField; import ffx.potential.parsers.ARCFileFilter; import ffx.potential.parsers.FileOpener; import ffx.potential.parsers.ForceFieldFilter; import ffx.potential.parsers.INTFileFilter; import ffx.potential.parsers.INTFilter; import ffx.potential.parsers.PDBFileFilter; import ffx.potential.parsers.PDBFilter; import ffx.potential.parsers.SystemFilter; import ffx.potential.parsers.XYZFileFilter; import ffx.potential.parsers.XYZFilter; import ffx.utilities.Keyword; /** * The PotentialsFileOpener class specifies a Runnable object which is * constructed with a File and, when run, allows returning any opened * MolecularAssembly objects and their associated properties. * * @author Jacob M. Litman * @author Michael J. Schnieders */ public class PotentialsFileOpener implements FileOpener { private static final Logger logger = Logger.getLogger(PotentialsFileOpener.class.getName()); private final File file; private final Path filepath; private final File[] allFiles; private final Path[] allPaths; private int nThreads = -1; private List<MolecularAssembly> assemblies; private MolecularAssembly activeAssembly; // Presently, will just be the first element of assemblies. private List<CompositeConfiguration> propertyList; private CompositeConfiguration activeProperties; private SystemFilter filter; public PotentialsFileOpener(File file) { if (!file.exists() || !file.isFile()) { throw new IllegalArgumentException( String.format(" File %s either did not exist or was not a file.", file.getName())); } this.file = file; Path pwdPath; Path absPath; try { pwdPath = Paths.get(new File("").getCanonicalPath()); } catch (IOException ex) { pwdPath = Paths.get(new File("").getAbsolutePath()); } try { absPath = Paths.get(file.getCanonicalPath()); } catch (IOException ex) { absPath = Paths.get(file.getAbsolutePath()); } filepath = pwdPath.relativize(absPath); allFiles = new File[1]; allFiles[0] = this.file; allPaths = new Path[1]; allPaths[0] = this.filepath; assemblies = new ArrayList<>(); propertyList = new ArrayList<>(); } public PotentialsFileOpener(String filename) { this(new File(filename)); } public PotentialsFileOpener(Path filepath) { this(filepath.toString()); } public PotentialsFileOpener(File[] files) { if (files == null) { throw new IllegalArgumentException(" Array of files to be opened was null."); } int numFiles = files.length; if (numFiles == 0) { throw new IllegalArgumentException(" Array of files to be opened was empty."); } List<File> fileList = new ArrayList<>(); List<Path> pathList = new ArrayList<>(); Path pwdPath; try { pwdPath = Paths.get(new File("").getCanonicalPath()); } catch (IOException ex) { pwdPath = Paths.get(new File("").getAbsolutePath()); } for (File tryFile : files) { if (!(tryFile.exists() && tryFile.isFile())) { continue; } Path absPath; try { absPath = Paths.get(tryFile.getCanonicalPath()); } catch (IOException ex) { absPath = Paths.get(tryFile.getAbsolutePath()); } Path thisPath = pwdPath.relativize(absPath); fileList.add(tryFile); pathList.add(thisPath); } int numAccepted = fileList.size(); if (numAccepted < 1) { throw new IllegalArgumentException(" No valid files could be found to open."); } allFiles = fileList.toArray(new File[numAccepted]); allPaths = pathList.toArray(new Path[numAccepted]); this.file = allFiles[0]; this.filepath = allPaths[0]; assemblies = new ArrayList<>(); propertyList = new ArrayList<>(); } public PotentialsFileOpener(String[] filenames) { if (filenames == null) { throw new IllegalArgumentException(" Array of files to be opened was null."); } int numFiles = filenames.length; if (numFiles == 0) { throw new IllegalArgumentException(" Array of files to be opened was empty."); } List<File> fileList = new ArrayList<>(); List<Path> pathList = new ArrayList<>(); Path pwdPath; try { pwdPath = Paths.get(new File("").getCanonicalPath()); } catch (IOException ex) { pwdPath = Paths.get(new File("").getAbsolutePath()); } for (String filename : filenames) { try { File tryFile = new File(filename); if (!(tryFile.exists() && tryFile.isFile())) { continue; } Path absPath; try { absPath = Paths.get(tryFile.getCanonicalPath()); } catch (IOException ex) { absPath = Paths.get(tryFile.getAbsolutePath()); } Path thisPath = pwdPath.relativize(absPath); fileList.add(tryFile); pathList.add(thisPath); } catch (Exception ex) { // Simply continue. } } int numAccepted = fileList.size(); if (numAccepted < 1) { throw new IllegalArgumentException(" No valid files could be found to open."); } allFiles = fileList.toArray(new File[numAccepted]); allPaths = pathList.toArray(new Path[numAccepted]); this.file = allFiles[0]; this.filepath = allPaths[0]; assemblies = new ArrayList<>(); propertyList = new ArrayList<>(); } public void setNThreads(int nThreads) { this.nThreads = nThreads; } /** * At present, parses the PDB, XYZ, INT, or ARC file from the constructor * and creates MolecularAssembly and properties objects. */ @Override public void run() { int numFiles = allFiles.length; for (int i = 0; i < numFiles; i++) { File fileI = allFiles[i]; Path pathI = allPaths[i]; MolecularAssembly assembly = new MolecularAssembly(pathI.toString()); assembly.setFile(fileI); CompositeConfiguration properties = Keyword.loadProperties(fileI); ForceFieldFilter forceFieldFilter = new ForceFieldFilter(properties); ForceField forceField = forceFieldFilter.parse(); String patches[] = properties.getStringArray("patch"); for (String patch : patches) { logger.info(" Attempting to read force field patch from " + patch + "."); CompositeConfiguration patchConfiguration = new CompositeConfiguration(); try { patchConfiguration.addProperty("propertyFile", fileI.getCanonicalPath()); } catch (IOException e) { logger.log(Level.INFO, " Error loading {0}.", patch); } patchConfiguration.addProperty("parameters", patch); forceFieldFilter = new ForceFieldFilter(patchConfiguration); ForceField patchForceField = forceFieldFilter.parse(); forceField.append(patchForceField); if (RotamerLibrary.addRotPatch(patch)) { logger.info(String.format(" Loaded rotamer definitions from patch %s.", patch)); } } assembly.setForceField(forceField); if (new PDBFileFilter().acceptDeep(fileI)) { filter = new PDBFilter(fileI, assembly, forceField, properties); } else if (new XYZFileFilter().acceptDeep(fileI)) { filter = new XYZFilter(fileI, assembly, forceField, properties); } else if (new INTFileFilter().acceptDeep(fileI) || new ARCFileFilter().accept(fileI)) { filter = new INTFilter(fileI, assembly, forceField, properties); } else { throw new IllegalArgumentException( String.format(" File %s could not be recognized as a valid PDB, XYZ, INT, or ARC file.", pathI.toString())); } if (filter.readFile()) { if (!(filter instanceof PDBFilter)) { Utilities.biochemistry(assembly, filter.getAtomList()); } filter.applyAtomProperties(); assembly.finalize(true, forceField); //ForceFieldEnergy energy = new ForceFieldEnergy(assembly, filter.getCoordRestraints()); ForceFieldEnergy energy; if (nThreads > 0) { energy = new ForceFieldEnergy(assembly, filter.getCoordRestraints(), nThreads); } else { energy = new ForceFieldEnergy(assembly, filter.getCoordRestraints()); } assembly.setPotential(energy); assemblies.add(assembly); propertyList.add(properties); if (filter instanceof PDBFilter) { PDBFilter pdbFilter = (PDBFilter) filter; List<Character> altLocs = pdbFilter.getAltLocs(); if (altLocs.size() > 1 || altLocs.get(0) != ' ') { StringBuilder altLocString = new StringBuilder("\n Alternate locations found [ "); for (Character c : altLocs) { // Do not report the root conformer. if (c == ' ') { continue; } altLocString.append(format("(%s) ", c)); } altLocString.append("]\n"); logger.info(altLocString.toString()); } /** * Alternate conformers may have different chemistry, so * they each need to be their own MolecularAssembly. */ for (Character c : altLocs) { if (c.equals(' ') || c.equals('A')) { continue; } MolecularAssembly newAssembly = new MolecularAssembly(pathI.toString()); newAssembly.setForceField(assembly.getForceField()); pdbFilter.setAltID(newAssembly, c); pdbFilter.clearSegIDs(); if (pdbFilter.readFile()) { String fileName = assembly.getFile().getAbsolutePath(); newAssembly.setName(FilenameUtils.getBaseName(fileName) + " " + c); filter.applyAtomProperties(); newAssembly.finalize(true, assembly.getForceField()); //energy = new ForceFieldEnergy(newAssembly, filter.getCoordRestraints()); if (nThreads > 0) { energy = new ForceFieldEnergy(assembly, filter.getCoordRestraints(), nThreads); } else { energy = new ForceFieldEnergy(assembly, filter.getCoordRestraints()); } newAssembly.setPotential(energy); assemblies.add(newAssembly); } } } } else { logger.warning(String.format(" Failed to read file %s", fileI.toString())); } } activeAssembly = assemblies.get(0); activeProperties = propertyList.get(0); } /** * Returns the first MolecularAssembly created by the run() function. * * @return A MolecularAssembly */ @Override public MolecularAssembly getAssembly() { return activeAssembly; } /** * Returns all MolecularAssembly objects created by this opener. * * @return Array of MolecularAssemblys */ @Override public MolecularAssembly[] getAllAssemblies() { return assemblies.toArray(new MolecularAssembly[assemblies.size()]); } /** * Returns the properties associated with the first MolecularAssembly. * * @return Active properties */ @Override public CompositeConfiguration getProperties() { return activeProperties; } /** * Returns the properties of all MolecularAssembly objects created by this * opener. * * @return Array of all properties */ @Override public CompositeConfiguration[] getAllProperties() { return propertyList.toArray(new CompositeConfiguration[propertyList.size()]); } public SystemFilter getFilter() { return filter; } }