$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.Map;
24import java.util.logging.Level;
25import java.util.logging.Logger;
26
27import org.openscience.cdk.interfaces.IAtomContainer;
28
29import denoptim.constants.DENOPTIMConstants;
30import denoptim.exception.DENOPTIMException;
31import denoptim.files.FileUtils;
32import denoptim.io.DenoptimIO;
33import denoptim.molecularmodeling.ChemicalObjectModel;
34import denoptim.molecularmodeling.zmatrix.ZMatrix;
35import denoptim.molecularmodeling.zmatrix.ZMatrixAtom;
36import denoptim.task.ProcessHandler;
37import denoptim.utils.ObjectPair;
38
46{
50 private final static String FSEP = System.getProperty("file.separator");
51
55 private final static String NL = DENOPTIMConstants.EOL;
56
57//------------------------------------------------------------------------------
86 public static void performPSSROT(ArrayList<ChemicalObjectModel> mols,
87 Map<String, Integer> atmTypeMap,
88 String runLabel, String ffFilePathName, List<String> keyFileLines,
89 List<String> subParamsInit, List<String> subParamsRest,
90 String pssExePathName, String xyzintPathName, String workDir,
91 int taskId, Logger logger) throws DENOPTIMException, TinkerException
92 {
93 for (int i=0; i<mols.size(); i++)
94 {
95 Object molErroProp = mols.get(i).getIAtomContainer().getProperty(
97 if (molErroProp == null)
98 {
99 logger.log(Level.INFO, "Field MOL_ERROR is null: proceeding "
100 + "with conformational search.");
101 performPSSROT(mols.get(i),atmTypeMap, i,
102 runLabel, ffFilePathName, keyFileLines,
103 subParamsInit, subParamsRest,
104 pssExePathName, xyzintPathName,
105 workDir, taskId, logger);
106 } else {
107 logger.log(Level.INFO, "Field MOL_ERROR is NOT null: skiping "
108 + "conformational search. Reason: " + molErroProp);
109 }
110 }
111 }
112
113//------------------------------------------------------------------------------
114
145 public static void performPSSROT(ChemicalObjectModel chemObj,
146 Map<String, Integer> atmTypeMap,
147 int idm, String runLabel,
148 String ffFilePathName, List<String> keyFileLines,
149 List<String> subParamsInit, List<String> subParamsRest,
150 String pssrotPathName, String xyzintPathName, String workDir,
151 int taskId, Logger logger)
153 {
154 logger.log(Level.INFO, "Start conformational search on mol: " + idm);
155
156 // Is there any rotatable bond?
157 int sz = chemObj.getNumberRotatableBonds();
158 if (sz == 0)
159 {
160 logger.log(Level.FINE, "No rotatable bond: skipping "
161 + " PSSROT conformational search.");
162 return;
163 }
164
165 setTinkerTypes(chemObj, atmTypeMap);
166
167 ZMatrix zmat = chemObj.getZMatrix();
168 String molName = chemObj.getName();
169
170 // Prepare Tinker INT file (Internal coordinates)
171 String csIntFile = workDir + FSEP + molName + "_"+runLabel + idm
172 + ".int";
173 TinkerUtils.writeTinkerINT(csIntFile, zmat);
174
175 //Prepare Tinker KEY file (keywords, definition of potential)
176 String csKeyFile = workDir + FSEP + molName + "_"+runLabel + idm
177 + ".key";
178 StringBuilder csSbKey = new StringBuilder(512);
179 // Molecule-independent keywords
180 csSbKey.append("parameters ").append(ffFilePathName).append(NL);
181 for (String line : keyFileLines)
182 {
183 if (line.toUpperCase().startsWith("PARAMETERS"))
184 continue;
185 csSbKey.append(line).append(NL);
186 }
187 DenoptimIO.writeData(csKeyFile, csSbKey.toString(), false);
188
189 // Prepare Tinker Submit file (PSSROT parameters)
190 String csSubFile = workDir + FSEP + molName + "_"+runLabel + idm
191 + ".sub";
192 StringBuilder csSbSub = new StringBuilder(512);
193 csSbSub.append(csIntFile).append(NL);
194 // Molecule-independent section of SUB file
195 for (String line : subParamsInit)
196 {
197 csSbSub.append(line).append(NL);
198 }
199 // Rotatable bonds section of SUB file
200 for (ObjectPair rotBndOp : chemObj.getRotatableBonds())
201 {
202 int t1 = ((Integer)rotBndOp.getFirst()).intValue() + 1;
203 int t2 = ((Integer)rotBndOp.getSecond()).intValue() + 1;
204 csSbSub.append(t1).append(" ").append(t2).append(NL);
205 }
206 csSbSub.append(NL);
207 // Linear search section of SUB file
208 if (sz > 1)
209 {
210 for (int ir=0; ir<subParamsRest.size(); ir++)
211 {
212 // Control number of linear search directions
213 if (ir == 2)
214 {
215 int maxDirs = Integer.parseInt(subParamsRest.get(ir));
216 if (sz < maxDirs)
217 {
218 csSbSub.append(sz).append(NL);
219 } else {
220 csSbSub.append(maxDirs).append(NL);
221 }
222 } else {
223 String row = subParamsRest.get(ir);
224 csSbSub.append(row).append(NL);
225 }
226 }
227 } else {
228 if (sz == 1)
229 {
230 // No linear search if there is only 1 rotation bond
231 String firstLine = subParamsRest.get(0);
232 String lastLine = subParamsRest.get(subParamsRest.size()-1);
233 csSbSub.append(firstLine).append(NL);
234 csSbSub.append("N").append(NL); // no local search
235 csSbSub.append(lastLine).append(NL);
236 }
237 }
238 DenoptimIO.writeData(csSubFile, csSbSub.toString(), false);
239
240 logger.log(Level.INFO, "Submitting PSSTOR Conformational Search");
241
242 // Perform Ring Search with Tinker's PSSROT
243 String csLogFile = workDir + FSEP + molName + "_" + runLabel + idm
244 + ".log";
245 String csCmdStr = pssrotPathName + " < " + csSubFile + " > " +csLogFile;
246 String csID = "" + taskId;
247 logger.log(Level.FINE, "CMD: " + csCmdStr + " TskID: " + csID);
248 ProcessHandler csPh = new ProcessHandler(csCmdStr, csID);
249 try
250 {
251 csPh.runProcessInBASH();
252 if (csPh.getExitCode() != 0)
253 {
254 String msg = "PSSROT Conformational Search failed for ";
255 msg = msg + molName;
256 throw new DENOPTIMException(msg + NL + csPh.getErrorOutput());
257 }
258 }
259 catch (Exception ex)
260 {
261 throw new DENOPTIMException(ex);
262 }
263
264 //We check for the first output file, i.e., .000 but there could be many
266 + "_" + runLabel + idm + ".000", csLogFile,
267 runLabel + "PSSROT job");
268
269 // Convert XYZ output of Tinker to INT with same z.matrix
270 // Here we assume the file *.int with same basename exists
271 // (was used it as input the PSSTOR step) and that file works as
272 // template of the z-matrix
273 String ocsIntfile = TinkerUtils.getNameLastCycleFile(workDir,
274 molName + "_"+ runLabel + idm, csLogFile,
275 " Final Function Value and Deformation");
276
277 // But before that, need to handle case where Tinker splits line in two
278 fixLongeLinesInXYZ(ocsIntfile);
279
280 String newTnkICLog = workDir + FSEP + molName + "_"+runLabel + idm
281 + ".log2";
282 String ocsID = "" + taskId;
283 String ocsCmd = xyzintPathName + " " + ocsIntfile + " "
284 + " T " //set use of template
285 + " > " + newTnkICLog;
286 logger.log(Level.INFO, "CMD: " + ocsCmd+" TskID: "+ocsID);
287 ProcessHandler ocsPh = new ProcessHandler(ocsCmd, ocsID);
288 try
289 {
290 ocsPh.runProcessInBASH();
291 if (ocsPh.getExitCode() != 0)
292 {
293 String msg = "XYZINT (post conf.search) failed for " + molName;
294 throw new DENOPTIMException(msg + NL + ocsPh.getErrorOutput());
295 }
296 }
297 catch (Exception ex)
298 {
299 throw new DENOPTIMException(ex);
300 }
301
302 // Conversion can fail if system is beyond the capabilities of Tinker.
303 // Such capabilities can be expanded by altering Tinker's parameters
304 // such as maxval and maxtors (and others?)
305 String newTnkIC = workDir + FSEP + molName + "_" + runLabel + idm
306 + ".int_2";
307 TinkerUtils.ensureOutputExistsOrRelayError(newTnkIC, newTnkICLog,
308 "convert xyz to int for " + runLabel + "job");
309
310 // Update local molecular representation with output from PSSROT
311 ZMatrix tmpZmat = TinkerUtils.readTinkerINT(newTnkIC);
312 List<ZMatrixAtom> lstZAtoms = tmpZmat.getAtoms();
313 for (int i=0; i<lstZAtoms.size(); i++)
314 {
315 ZMatrixAtom za = lstZAtoms.get(i);
316 zmat.getAtom(i).setBondLength(za.getBondLength());
317 zmat.getAtom(i).setAngleValue(za.getAngleValue());
319 zmat.getAtom(i).setChiralFlag(za.getChiralFlag());
320 }
321 chemObj.updateXYZFromINT();
322
323 // Cleanup
324 FileUtils.deleteFilesContaining(workDir,molName + "_" + runLabel + idm);
325 }
326
327//------------------------------------------------------------------------------
328
335 private static void setTinkerTypes(ChemicalObjectModel chemObj,
336 Map<String, Integer> atmTypMap) throws DENOPTIMException
337 {
338 if (atmTypMap == null)
339 {
340 return;
341 }
342 ZMatrix zmat = chemObj.getZMatrix();
343 IAtomContainer iac = chemObj.getIAtomContainer();
344
345 for (int i = 0; i < iac.getAtomCount(); i++)
346 {
347 ZMatrixAtom zatm = zmat.getAtom(i);
348 String st = zatm.getSymbol().trim();
349 if (!atmTypMap.containsKey(st))
350 {
351 String msg = "Unable to assign atom type to atom '" + st +"'.";
352 throw new DENOPTIMException(msg);
353 }
354 Integer val = atmTypMap.get(st);
355 if (val == null)
356 {
357 String msg = "No valid Tinker atom type for atom " + st;
358 throw new DENOPTIMException(msg);
359 }
360 zatm.setType(val.toString());
361 }
362 }
363
364//------------------------------------------------------------------------------
365
375 public static void fixLongeLinesInXYZ(String filename)
376 throws DENOPTIMException
377 {
378 ArrayList<String> txtLines = new ArrayList<String>();
379 try {
380 txtLines = DenoptimIO.readList(filename);
381 }
382 catch (Throwable t)
383 {
384 t.printStackTrace();
385 throw new DENOPTIMException(" unable to read file " + filename
386 + " " +t);
387 }
388 String[] wFrstLine = txtLines.get(0).trim().split("\\s+");
389 int numAtms = Integer.parseInt(wFrstLine[0]);
390
391 // Do we need to fix this file?
392 if (numAtms+1 == txtLines.size())
393 {
394 return;
395 }
396
397 StringBuilder sb = new StringBuilder(512);
398 sb.append(txtLines.get(0));
399 int newI = 1;
400 for (int i=1; i<txtLines.size(); i++)
401 {
402 String line = txtLines.get(i).trim();
403
404 if (line == "" || line == null)
405 continue;
406
407 String[] wLine = line.split("\\s+");
408 int atmNum = Integer.parseInt(wLine[0]);
409 if (newI == atmNum)
410 {
411 sb.append(NL).append(txtLines.get(i));
412 }
413 else
414 {
415 sb.append(" ").append(txtLines.get(i));
416 newI--;
417 }
418 newI++;
419 }
420
421 sb.append(NL);
422 DenoptimIO.writeData(filename, sb.toString(), false);
423 }
424
425//------------------------------------------------------------------------------
426}
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
Tool to perform conformational search via Tinker PSSROT program.
static void performPSSROT(ChemicalObjectModel chemObj, Map< String, Integer > atmTypeMap, 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 setTinkerTypes(ChemicalObjectModel chemObj, Map< String, Integer > atmTypMap)
Used elemental symbols (ot pseudo-element symbols) to assign atom types.
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(ArrayList< ChemicalObjectModel > mols, Map< String, Integer > atmTypeMap, 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.
Exceptions resulting from a failure of Tinker.
Toolbox of utilities for Tinker style molecular representation.
static ZMatrix readTinkerINT(String filename)
Reads a Tinker INT file.
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 writeTinkerINT(String filename, ZMatrix zmat)
Write 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 ...
Representation of an atom in the ZMatrix.
Definition: ZMatrixAtom.java:9
String getSymbol()
Get the symbol of the atom.
Double getAngle2Value()
Get the angle2 value.
void setBondLength(Double bondLength)
Set the bond length.
Integer getChiralFlag()
Get the chiral flag.
void setChiralFlag(Integer chiralFlag)
Set the chiral flag.
void setType(String type)
Set the type of the atom.
void setAngleValue(Double angleValue)
Set the angle value.
void setAngle2Value(Double angle2Value)
Set the angle2 value.
Double getBondLength()
Get the bond length.
Double getAngleValue()
Get the angle value.
Representation of an atom container's geometry with internal coordinates.
Definition: ZMatrix.java:27
List< ZMatrixAtom > getAtoms()
Get the atoms in the ZMatrix.
Definition: ZMatrix.java:234
ZMatrixAtom getAtom(int index)
Get the atom at the given index.
Definition: ZMatrix.java:223
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