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-2026.
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.xray.commands;
39  
40  import ffx.algorithms.cli.AlgorithmsCommand;
41  import ffx.numerics.Potential;
42  import ffx.potential.MolecularAssembly;
43  import ffx.potential.bonded.Atom;
44  import ffx.potential.bonded.MSNode;
45  import ffx.potential.bonded.Molecule;
46  import ffx.utilities.FFXBinding;
47  import picocli.CommandLine.Option;
48  import picocli.CommandLine.Command;
49  import picocli.CommandLine.Parameters;
50  
51  import java.io.File;
52  import java.util.List;
53  
54  import static org.apache.commons.io.FilenameUtils.removeExtension;
55  
56  /**
57   * EditPDB edits a PDB model for use in experimental refinement.
58   * <br>
59   * Usage:
60   * <br>
61   * ffxc xray.EditPDB &lt;pdbfile1&gt;
62   */
63  @Command(description = " Edit a PDB model for use in refinement.", name = "xray.EditPDB")
64  public class EditPDB extends AlgorithmsCommand {
65  
66    /**
67     * Replace deuterium atoms with hydrogen.
68     */
69    @Option(names = {"--rd", "--repaceDeuterium"}, paramLabel = "false", defaultValue = "false",
70        description = "Replace deuterium with hydrogen.")
71    private boolean replaceDeuterium = false;
72  
73    /**
74     * --altLoc Save a specific alternate location. All atoms are assigned the root alternate
75     * location ' '.
76     */
77    @Option(names = {"--altLoc", "--saveAltLoc"}, paramLabel = " ", defaultValue = " ",
78        description = "Save a specific alternate location")
79    private Character altLoc = ' ';
80  
81    /**
82     * If a single alternate conformation is being saved, set occupancy values to 1.0.
83     */
84    @Option(names = {"-o", "--occupancy"}, paramLabel = "false", defaultValue = "false",
85        description = "If a single alternate conformation is being saved, set occupancy values to 1.0.")
86    private boolean occupancy = false;
87  
88    /**
89     * One or more filenames.
90     */
91    @Parameters(arity = "1", paramLabel = "file", description = "PDB input file.")
92    private String filename;
93  
94    private MolecularAssembly[] molecularAssemblies;
95  
96    /**
97     * Deuterate constructor.
98     */
99    public EditPDB() {
100     super();
101   }
102 
103   /**
104    * Deuterate constructor that sets the command line arguments.
105    *
106    * @param args Command line arguments.
107    */
108   public EditPDB(String[] args) {
109     super(args);
110   }
111 
112   /**
113    * Deuterate constructor.
114    *
115    * @param binding The Binding to use.
116    */
117   public EditPDB(FFXBinding binding) {
118     super(binding);
119   }
120 
121   /**
122    * Execute the script.
123    */
124   @Override
125   public EditPDB run() {
126 
127     if (!init()) {
128       return this;
129     }
130 
131     if (filename != null) {
132       molecularAssemblies = algorithmFunctions.openAll(filename);
133       activeAssembly = molecularAssemblies[0];
134     } else if (activeAssembly == null) {
135       logger.info(helpString());
136       return this;
137     } else {
138       molecularAssemblies = new MolecularAssembly[]{activeAssembly};
139       filename = activeAssembly.getFile().getAbsolutePath();
140     }
141 
142     logger.info("\n Running xray.EditPDB on " + filename);
143 
144     for (MolecularAssembly molecularAssembly : molecularAssemblies) {
145       // Replace deuterium with hydrogen.
146       if (replaceDeuterium) {
147         List<Atom> atoms = molecularAssembly.getAtomList();
148         for (Atom atom : atoms) {
149           if (atom.isDeuterium()) {
150             String name = atom.getName().toUpperCase();
151             atom.setName(name.replaceFirst("D", "H"));
152           }
153         }
154         List<MSNode> water = molecularAssembly.getWater();
155         for (MSNode node : water) {
156           Molecule wat = (Molecule) node;
157           wat.setName("HOH");
158         }
159       }
160 
161       if (altLoc == ' ' || molecularAssembly.getAlternateLocation().equals(altLoc)) {
162         if (altLoc != ' ') {
163           // We will save this alternate location with the alternate location set to ' '.
164           molecularAssembly.setAtomicAltLoc(' ');
165           if (occupancy) {
166             // Set all residues to have an occupancy of 1.0.
167             molecularAssembly.setOccupancy(1.0);
168           }
169           algorithmFunctions.saveAsPDB(molecularAssembly, new File(filename));
170         }
171       }
172     }
173 
174     // Only save all alternate locations if the altLoc flag is not set.
175     if (altLoc == ' ') {
176       algorithmFunctions.saveAsPDB(molecularAssemblies, new File(filename));
177     }
178     return this;
179   }
180 
181   @Override
182   public List<Potential> getPotentials() {
183     return getPotentialsFromAssemblies(molecularAssemblies);
184   }
185 }