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.realspace.commands;
39  
40  import ffx.algorithms.cli.AlgorithmsCommand;
41  import ffx.algorithms.cli.AnnealOptions;
42  import ffx.algorithms.cli.DynamicsOptions;
43  import ffx.algorithms.optimize.anneal.SimulatedAnnealing;
44  import ffx.numerics.Potential;
45  import ffx.potential.MolecularAssembly;
46  import ffx.potential.cli.AtomSelectionOptions;
47  import ffx.potential.cli.WriteoutOptions;
48  import ffx.realspace.cli.RealSpaceOptions;
49  import ffx.utilities.FFXBinding;
50  import ffx.xray.RefinementEnergy;
51  import org.apache.commons.io.FilenameUtils;
52  import picocli.CommandLine.Command;
53  import picocli.CommandLine.Mixin;
54  import picocli.CommandLine.Parameters;
55  
56  import java.io.File;
57  import java.util.Collections;
58  import java.util.List;
59  
60  /**
61   * The Real Space Annealing script.
62   * <br>
63   * Usage:
64   * <br>
65   * ffxc realspace.Anneal [options] &lt;filename&gt;
66   */
67  @Command(description = " Simulated annealing on a Real Space target.", name = "realspace.Anneal")
68  public class Anneal extends AlgorithmsCommand {
69  
70    @Mixin
71    private AnnealOptions annealOptions;
72  
73    @Mixin
74    private AtomSelectionOptions atomSelectionOptions;
75  
76    @Mixin
77    private DynamicsOptions dynamicsOptions;
78  
79    @Mixin
80    private RealSpaceOptions realSpaceOptions;
81  
82    @Mixin
83    private WriteoutOptions writeoutOptions;
84  
85    /**
86     * One or more filenames.
87     */
88    @Parameters(arity = "1..*", paramLabel = "files", description = "PDB and Real Space input files.")
89    private List<String> filenames;
90  
91    private RefinementEnergy refinementEnergy;
92  
93    /**
94     * Anneal constructor.
95     */
96    public Anneal() {
97      super();
98    }
99  
100   /**
101    * Anneal constructor that sets the command line arguments.
102    * @param args Command line arguments.
103    */
104   public Anneal(String[] args) {
105     super(args);
106   }
107 
108   /**
109    * Anneal constructor.
110    * @param binding The Binding to use.
111    */
112   public Anneal(FFXBinding binding) {
113     super(binding);
114   }
115 
116   @Override
117   public Anneal run() {
118 
119     if (!init()) {
120       return this;
121     }
122 
123     dynamicsOptions.init();
124 
125     String filename;
126     if (filenames != null && !filenames.isEmpty()) {
127       activeAssembly = algorithmFunctions.open(filenames.get(0));
128       filename = filenames.get(0);
129     } else if (activeAssembly == null) {
130       logger.info(helpString());
131       return this;
132     } else {
133       filename = activeAssembly.getFile().getAbsolutePath();
134     }
135     MolecularAssembly[] molecularAssemblies = new MolecularAssembly[]{activeAssembly};
136 
137     logger.info(
138         "\n Running simulated annealing on on real-space target including " + filename + "\n");
139 
140     // Set atom (in)active selections.
141     atomSelectionOptions.setActiveAtoms(activeAssembly);
142 
143     // Create the refinement target.
144     Potential potential = realSpaceOptions.toRealSpaceEnergy(filenames, molecularAssemblies);
145 
146     // Beginning force field energy.
147     algorithmFunctions.energy(activeAssembly);
148 
149     // Restart File
150     File dyn = new File(FilenameUtils.removeExtension(filename) + ".dyn");
151     if (!dyn.exists()) {
152       dyn = null;
153     }
154 
155     SimulatedAnnealing simulatedAnnealing =
156         annealOptions.createAnnealer(dynamicsOptions, activeAssembly,
157             potential, algorithmListener, dyn);
158 
159     simulatedAnnealing.setPrintInterval(dynamicsOptions.getReport());
160     simulatedAnnealing.setSaveFrequency(dynamicsOptions.getWrite());
161     simulatedAnnealing.setRestartFrequency(dynamicsOptions.getCheckpoint());
162     simulatedAnnealing.setTrajectorySteps(dynamicsOptions.getTrajSteps());
163 
164     simulatedAnnealing.anneal();
165 
166     if (baseDir == null || !baseDir.exists() || !baseDir.isDirectory() || !baseDir.canWrite()) {
167       baseDir = new File(FilenameUtils.getFullPath(filename));
168     }
169 
170     String dirName = baseDir.toString() + File.separator;
171     String fileName = FilenameUtils.getName(filename);
172     fileName = FilenameUtils.removeExtension(fileName);
173 
174     writeoutOptions.saveFile(String.format("%s%s", dirName, fileName), algorithmFunctions, activeAssembly);
175 
176     return this;
177   }
178 
179   @Override
180   public List<Potential> getPotentials() {
181     return refinementEnergy == null ? Collections.emptyList() : Collections.singletonList((Potential) refinementEnergy);
182   }
183 }