$darkmode
DENOPTIM
ConformationalSearchPSSROT.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Marco Foscato <marco.foscato@uib.no>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19package denoptim.integration.tinker;
20
21import java.util.ArrayList;
22import java.util.List;
23import java.util.logging.Level;
24import java.util.logging.Logger;
25
26import denoptim.constants.DENOPTIMConstants;
27import denoptim.exception.DENOPTIMException;
28import denoptim.files.FileUtils;
29import denoptim.io.DenoptimIO;
30import denoptim.molecularmodeling.ChemicalObjectModel;
31import denoptim.task.ProcessHandler;
32import denoptim.utils.ObjectPair;
33
41{
45 private final static String FSEP = System.getProperty("file.separator");
46
50 private final static String NL = DENOPTIMConstants.EOL;
51
52//------------------------------------------------------------------------------
80 public static void performPSSROT(ArrayList<ChemicalObjectModel> mols,
81 String runLabel, String ffFilePathName, List<String> keyFileLines,
82 List<String> subParamsInit, List<String> subParamsRest,
83 String pssExePathName, String xyzintPathName, String workDir,
84 int taskId, Logger logger) throws DENOPTIMException, TinkerException
85 {
86 for (int i=0; i<mols.size(); i++)
87 {
88 Object molErroProp = mols.get(i).getIAtomContainer().getProperty(
90 if (molErroProp == null)
91 {
92 logger.log(Level.INFO, "Field MOL_ERROR is null: proceeding "
93 + "with conformational search.");
94 performPSSROT(mols.get(i), i,
95 runLabel, ffFilePathName, keyFileLines,
96 subParamsInit, subParamsRest,
97 pssExePathName, xyzintPathName,
98 workDir, taskId, logger);
99 } else {
100 logger.log(Level.INFO, "Field MOL_ERROR is NOT null: skiping "
101 + "conformational search. Reason: " + molErroProp);
102 }
103 }
104 }
105
106//------------------------------------------------------------------------------
107
137 public static void performPSSROT(ChemicalObjectModel chemObj,
138 int idm, String runLabel,
139 String ffFilePathName, List<String> keyFileLines,
140 List<String> subParamsInit, List<String> subParamsRest,
141 String pssrotPathName, String xyzintPathName, String workDir,
142 int taskId, Logger logger)
144 {
145 logger.log(Level.INFO, "Start conformational search on mol: " + idm);
146
147 // Is there any rotatable bond?
148 int sz = chemObj.getNumberRotatableBonds();
149 if (sz == 0)
150 {
151 logger.log(Level.FINE, "No rotatable bond: skiping "
152 + " PSSROT conformational search.");
153 return;
154 }
155
156 TinkerMolecule tmol = chemObj.getTinkerMolecule();
157 String molName = chemObj.getName();
158
159 // Prepare Tinker INT file (Internal coordinates)
160 String csIntFile = workDir + FSEP + molName + "_"+runLabel + idm
161 + ".int";
162 TinkerUtils.writeIC(csIntFile, tmol);
163
164 //Prepare Tinker KEY file (keywords, definition of potential)
165 String csKeyFile = workDir + FSEP + molName + "_"+runLabel + idm
166 + ".key";
167 StringBuilder csSbKey = new StringBuilder(512);
168 // Molecule-independent keywords
169 csSbKey.append("parameters ").append(ffFilePathName).append(NL);
170 for (String line : keyFileLines)
171 {
172 if (line.toUpperCase().startsWith("PARAMETERS"))
173 continue;
174 csSbKey.append(line).append(NL);
175 }
176 DenoptimIO.writeData(csKeyFile, csSbKey.toString(), false);
177
178 // Prepare Tinker Submit file (PSSROT parameters)
179 String csSubFile = workDir + FSEP + molName + "_"+runLabel + idm
180 + ".sub";
181 StringBuilder csSbSub = new StringBuilder(512);
182 csSbSub.append(csIntFile).append(NL);
183 // Molecule-independent section of SUB file
184 for (String line : subParamsInit)
185 {
186 csSbSub.append(line).append(NL);
187 }
188 // Rotatable bonds section of SUB file
189 for (ObjectPair rotBndOp : chemObj.getRotatableBonds())
190 {
191 int t1 = ((Integer)rotBndOp.getFirst()).intValue() + 1;
192 int t2 = ((Integer)rotBndOp.getSecond()).intValue() + 1;
193 csSbSub.append(t1).append(" ").append(t2).append(NL);
194 }
195 csSbSub.append(NL);
196 // Linear search section of SUB file
197 if (sz > 1)
198 {
199 for (int ir=0; ir<subParamsRest.size(); ir++)
200 {
201 // Control number of linear search directions
202 if (ir == 2)
203 {
204 int maxDirs = Integer.parseInt(subParamsRest.get(ir));
205 if (sz < maxDirs)
206 {
207 csSbSub.append(sz).append(NL);
208 } else {
209 csSbSub.append(maxDirs).append(NL);
210 }
211 } else {
212 String row = subParamsRest.get(ir);
213 csSbSub.append(row).append(NL);
214 }
215 }
216 } else {
217 if (sz == 1)
218 {
219 // No linear search if there is only 1 rotation bond
220 String firstLine = subParamsRest.get(0);
221 String lastLine = subParamsRest.get(subParamsRest.size()-1);
222 csSbSub.append(firstLine).append(NL);
223 csSbSub.append("N").append(NL); // no local search
224 csSbSub.append(lastLine).append(NL);
225 }
226 }
227 DenoptimIO.writeData(csSubFile, csSbSub.toString(), false);
228
229 logger.log(Level.INFO, "Submitting PSSTOR Conformational Search");
230
231 // Perform Ring Search with Tinker's PSSROT
232 String csLogFile = workDir + FSEP + molName + "_" + runLabel + idm
233 + ".log";
234 String csCmdStr = pssrotPathName + " < " + csSubFile + " > " +csLogFile;
235 String csID = "" + taskId;
236 logger.log(Level.FINE, "CMD: " + csCmdStr + " TskID: " + csID);
237 ProcessHandler csPh = new ProcessHandler(csCmdStr, csID);
238 try
239 {
240 csPh.runProcessInBASH();
241 if (csPh.getExitCode() != 0)
242 {
243 String msg = "PSSROT Conformational Search failed for ";
244 msg = msg + molName;
245 throw new DENOPTIMException(msg + NL + csPh.getErrorOutput());
246 }
247 }
248 catch (Exception ex)
249 {
250 throw new DENOPTIMException(ex);
251 }
252
253 //We check for the first output file, i.e., .000 but there could be many
255 + "_" + runLabel + idm + ".000", csLogFile,
256 runLabel + "PSSROT job");
257
258 // Convert XYZ output of Tinker to INT with same z.matrix
259 // Here we assume the file *.int with same basename exists
260 // (was used it as input the PSSTOR step) and that file works as
261 // template of the z-matrix
262 String ocsIntfile = TinkerUtils.getNameLastCycleFile(workDir,
263 molName + "_"+ runLabel + idm, csLogFile,
264 " Final Function Value and Deformation");
265
266 // But before that, need to handle case where Tinker splits line in two
267 fixLongeLinesInXYZ(ocsIntfile);
268
269 String newTnkICLog = workDir + FSEP + molName + "_"+runLabel + idm
270 + ".log2";
271 String ocsID = "" + taskId;
272 String ocsCmd = xyzintPathName + " " + ocsIntfile + " "
273 + " T " //set use of template
274 + " > " + newTnkICLog;
275 logger.log(Level.INFO, "CMD: " + ocsCmd+" TskID: "+ocsID);
276 ProcessHandler ocsPh = new ProcessHandler(ocsCmd, ocsID);
277 try
278 {
279 ocsPh.runProcessInBASH();
280 if (ocsPh.getExitCode() != 0)
281 {
282 String msg = "XYZINT (post conf.search) failed for " + molName;
283 throw new DENOPTIMException(msg + NL + ocsPh.getErrorOutput());
284 }
285 }
286 catch (Exception ex)
287 {
288 throw new DENOPTIMException(ex);
289 }
290
291 // Conversion can fail if system is beyond the capabilities of Tinker.
292 // Such capabilities can be expanded by altering Tinker's parameters
293 // such as maxval and maxtors (and others?)
294 String newTnkIC = workDir + FSEP + molName + "_" + runLabel + idm
295 + ".int_2";
296 TinkerUtils.ensureOutputExistsOrRelayError(newTnkIC, newTnkICLog,
297 "convert xyz to int for " + runLabel + "job");
298
299 // Update local molecular representation with output from PSSROT
300 TinkerMolecule tmpTmol = TinkerUtils.readTinkerIC(newTnkIC);
301 ArrayList<TinkerAtom> lstAtoms = tmpTmol.getAtoms();
302 for (int i=0; i<lstAtoms.size(); i++)
303 {
304 TinkerAtom ta = lstAtoms.get(i);
305 tmol.getAtom(i+1).setDistAngle(ta.getDistAngle());
306 }
307 chemObj.updateXYZFromINT();
308
309 // Cleanup
310 FileUtils.deleteFilesContaining(workDir,molName + "_" + runLabel + idm);
311 }
312
313//------------------------------------------------------------------------------
314
324 public static void fixLongeLinesInXYZ(String filename)
325 throws DENOPTIMException
326 {
327 ArrayList<String> txtLines = new ArrayList<String>();
328 try {
329 txtLines = DenoptimIO.readList(filename);
330 }
331 catch (Throwable t)
332 {
333 t.printStackTrace();
334 throw new DENOPTIMException(" unable to read file " + filename
335 + " " +t);
336 }
337 String[] wFrstLine = txtLines.get(0).trim().split("\\s+");
338 int numAtms = Integer.parseInt(wFrstLine[0]);
339
340 // Do we need to fix this file?
341 if (numAtms+1 == txtLines.size())
342 {
343 return;
344 }
345
346 StringBuilder sb = new StringBuilder(512);
347 sb.append(txtLines.get(0));
348 int newI = 1;
349 for (int i=1; i<txtLines.size(); i++)
350 {
351 String line = txtLines.get(i).trim();
352
353 if (line == "" || line == null)
354 continue;
355
356 String[] wLine = line.split("\\s+");
357 int atmNum = Integer.parseInt(wLine[0]);
358 if (newI == atmNum)
359 {
360 sb.append(NL).append(txtLines.get(i));
361 }
362 else
363 {
364 sb.append(" ").append(txtLines.get(i));
365 newI--;
366 }
367 newI++;
368 }
369
370 sb.append(NL);
371 DenoptimIO.writeData(filename, sb.toString(), false);
372 }
373
374//------------------------------------------------------------------------------
375}
General set of constants used in DENOPTIM.
static final String EOL
new line character
static final String MOLERRORTAG
SDF tag containing errors during execution of molecule specific tasks.
static void deleteFilesContaining(String path, String pattern)
Delete all files with pathname containing a given string.
Definition: FileUtils.java:289
Toolkit to perform conformational search via Tinker PSSROT program.
static void fixLongeLinesInXYZ(String filename)
The XYZ file generated by Tinker for molecules having atoms with many Neighbors is corrupted: the lin...
static void performPSSROT(ChemicalObjectModel chemObj, int idm, String runLabel, String ffFilePathName, List< String > keyFileLines, List< String > subParamsInit, List< String > subParamsRest, String pssrotPathName, String xyzintPathName, String workDir, int taskId, Logger logger)
Performs PSSROT conformational search on the given chemical object.
static void performPSSROT(ArrayList< ChemicalObjectModel > mols, String runLabel, String ffFilePathName, List< String > keyFileLines, List< String > subParamsInit, List< String > subParamsRest, String pssExePathName, String xyzintPathName, String workDir, int taskId, Logger logger)
Performs PSSROT conformational search for all chemical objects in the list.
Based on the code from ffx.kenai.com Michael J.
Definition: TinkerAtom.java:26
void setDistAngle(double[] distAngles)
Exceptions resulting from a failure of Tinker.
TinkerAtom getAtom(int pos)
Returns the atom which has the XYZ index set to pos.
Toolbox of utilities for Tinker style molecular representation.
static String getNameLastCycleFile(String workDir, String fname, String tinkerLog, String pattern)
Identifies how many iteration Tinker has done by looking into the log file, searching for a given pat...
static void writeIC(String filename, TinkerMolecule tmol)
Write Tinker INT file.
static TinkerMolecule readTinkerIC(String filename)
Reads a Tinker INT file.
static void ensureOutputExistsOrRelayError(String outputPathName, String logPathName, String taskName)
Check for the existence of an output file for a Tinker job and, if the output file is not found,...
Utility methods for input/output.
static ArrayList< String > readList(String fileName)
Read list of data as text.
static void writeData(String fileName, String data, boolean append)
Write text-like data file.
Collector of molecular information, related to a single chemical object, that is deployed within the ...
int getExitCode()
Get the exit code returned by the sub-process.
String getErrorOutput()
Get the content of the error output for the process.
void runProcessInBASH()
Run the process associated with the command from BASH http://www.javaworld.com/javaworld/jw-12-2000/j...
This class is the equivalent of the Pair data structure used in C++ Although AbstractMap....
Definition: ObjectPair.java:30