$darkmode
DENOPTIM
TinkerUtils.java
Go to the documentation of this file.
1/*
2 * DENOPTIM
3 * Copyright (C) 2019 Vishwesh Venkatraman <vishwesh.venkatraman@ntnu.no> and
4 * Marco Foscato <marco.foscato@uib.no>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published
8 * by the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20package denoptim.integration.tinker;
21
22import java.io.BufferedReader;
23import java.io.File;
24import java.io.FileReader;
25import java.io.FileWriter;
26import java.io.IOException;
27import java.util.ArrayList;
28import java.util.HashMap;
29import java.util.List;
30
31import org.apache.commons.io.input.ReversedLinesFileReader;
32
33import denoptim.exception.DENOPTIMException;
34import denoptim.molecularmodeling.MMBuilderUtils;
35import denoptim.molecularmodeling.zmatrix.ZMatrix;
36import denoptim.molecularmodeling.zmatrix.ZMatrixAtom;
37import denoptim.utils.GeneralUtils;
38
39
46public class TinkerUtils
47{
48 private static final String NL = System.getProperty("line.separator");
49 private static boolean debug = false;
50
51
52//------------------------------------------------------------------------------
102 public static ZMatrix readTinkerINT(String filename) throws DENOPTIMException
103 {
104 BufferedReader br = null;
105 String line = null;
106 int natom = 0;
107
108 ZMatrix zmat = new ZMatrix();
109
110 try
111 {
112 br = new BufferedReader(new FileReader(filename));
113 line = br.readLine().trim();
114
115 // read the number of atoms and store
116 String[] arr = line.split(" +");
117 natom = Integer.parseInt(arr[0]);
118 if (natom < 1)
119 {
120 String msg = "Invalid number of atoms in " + filename;
121 throw new DENOPTIMException(msg);
122 }
123
124 if (arr.length >= 2)
125 {
126 arr = line.split(" +", 2);
127 zmat.setId(arr[1]);
128 }
129
130 for (int i = 0; i < natom; i++)
131 {
132 line = br.readLine();
133 if (line == null)
134 {
135 break;
136 }
137
138 arr = line.trim().split(" +");
139 if (arr == null || arr.length < 3)
140 {
141 String msg = "Check atom " + (i + 1) + " in " + filename;
142 throw new DENOPTIMException(msg);
143 }
144
145 int id = Integer.parseInt(arr[0])-1;
146 String symbol = arr[1];
147 String type = arr[2];
148 ZMatrixAtom bndRef = null;
149 ZMatrixAtom angRef = null;
150 ZMatrixAtom ang2Ref = null;
151 Double bondLength = null;
152 Double angleValue = null;
153 Double angle2Value = null;
154 Integer chiralFlag = null;
155
156 // Bond partner and bond value
157 if (arr.length >= 5)
158 {
159 bndRef = zmat.getAtom(Integer.parseInt(arr[3])-1);
160 bondLength = Double.parseDouble(arr[4]);
161 }
162 // Angle partner and angle value
163 if (arr.length >= 7)
164 {
165 angRef = zmat.getAtom(Integer.parseInt(arr[5])-1);
166 angleValue = Double.parseDouble(arr[6]);
167 }
168 // Torsion partner and dihedral value
169 if (arr.length >= 10)
170 {
171 ang2Ref = zmat.getAtom(Integer.parseInt(arr[7])-1);
172 angle2Value = Double.parseDouble(arr[8]);
173 chiralFlag = Integer.parseInt(arr[9]);
174 }
175 ZMatrixAtom zatm = new ZMatrixAtom(id, symbol, type,
176 bndRef, angRef, ang2Ref,
177 bondLength, angleValue, angle2Value,
178 chiralFlag);
179 zmat.addAtom(zatm);
180 if (bndRef!=null)
181 {
182 zmat.addBond(zatm, bndRef);
183 }
184 }
185
186 if (br.ready())
187 {
188 line = br.readLine();
189 // Check for a first blank line
190 if (line.trim().equalsIgnoreCase(""))
191 {
192 // Parse bond pairs to add until EOF or a blank line is
193 // reached
194 boolean blank = false;
195 while (br.ready() && !blank)
196 {
197 line = br.readLine();
198 if (line.trim().equalsIgnoreCase(""))
199 {
200 blank = true;
201 }
202 else
203 {
204 arr = line.trim().split(" +");
205 if (arr.length != 2)
206 {
207 String msg = "Check Bond Pair to Remove: '"
208 + line + "' in " + filename;
209 throw new DENOPTIMException(msg);
210 }
211 zmat.addBond(Integer.parseInt(arr[0])-1,
212 Integer.parseInt(arr[1])-1);
213 }
214 }
215 // Parse bond pairs to be removed until EOF
216 while (br.ready())
217 {
218 line = br.readLine();
219 arr = line.trim().split(" +");
220 if (arr.length != 2)
221 {
222 String msg = "Check Bond Pair to Remove: '"
223 + line + "' in " + filename;
224 throw new DENOPTIMException(msg);
225 }
226 zmat.delBond(Integer.parseInt(arr[0])-1,
227 Integer.parseInt(arr[1])-1);
228 }
229 }
230 }
231 }
232 catch (NumberFormatException | IOException nfe)
233 {
234 throw new DENOPTIMException(nfe);
235 }
236 finally
237 {
238 try
239 {
240 if (br != null)
241 {
242 br.close();
243 }
244 }
245 catch (IOException ioe)
246 {
247 throw new DENOPTIMException(ioe);
248 }
249 }
250
251 return zmat;
252 }
253
254//------------------------------------------------------------------------------
255
264 public static List<double[]> readTinkerXYZ(String filename)
265 throws DENOPTIMException
266 {
267 List<double[]> coords = new ArrayList<>();
268
269 BufferedReader br = null;
270 String line = null;
271
272 int natom = 0;
273
274 try
275 {
276 br = new BufferedReader(new FileReader(filename));
277 line = br.readLine().trim();
278
279 // read the number of atoms and store
280 String[] arr = line.split("\\s+");
281 natom = Integer.parseInt(arr[0]);
282 if (natom < 1)
283 {
284 String msg = "Invalid number of atoms in " + filename;
285 throw new DENOPTIMException(msg);
286 }
287
288 while ((line = br.readLine()) != null)
289 {
290 if (line.trim().length() == 0)
291 {
292 continue;
293 }
294
295 arr = line.trim().split("\\s+");
296 if (arr.length >= 5)
297 {
298 // Atom number, name, type
299 //String name = arr[1];
300 double[] f = new double[3];
301 f[0] = Double.parseDouble(arr[2]);
302 f[1] = Double.parseDouble(arr[3]);
303 f[2] = Double.parseDouble(arr[4]);
304
305 coords.add(f);
306 }
307 }
308 }
309 catch (NumberFormatException | IOException nfe)
310 {
311 throw new DENOPTIMException(nfe);
312 }
313 finally
314 {
315 try
316 {
317 if (br != null)
318 {
319 br.close();
320 }
321 }
322 catch (IOException ioe)
323 {
324 throw new DENOPTIMException(ioe);
325 }
326 }
327
328 if (coords.size() != natom)
329 {
330 throw new DENOPTIMException("Incorrect number of atoms perceived "
331 + "in " + filename);
332 }
333
334 return coords;
335
336 }
337
338//------------------------------------------------------------------------------
339
348 public static void writeTinkerINT(String filename, ZMatrix zmat)
349 throws DENOPTIMException
350 {
351 FileWriter fw = null;
352 try
353 {
354 fw = new FileWriter(new File(filename));
355 int numatoms = zmat.getAtoms().size();
356 // write out the number of atoms and the title
357 String header = String.format("%6d %s%n", numatoms, zmat.getId());
358 fw.write(header);
359 fw.flush();
360
361 String line = "";
362
363 for (int i = 0; i < numatoms; i++)
364 {
365 ZMatrixAtom atom = zmat.getAtoms().get(i);
366 if (i == 0)
367 {
368 line = String.format("%6d %-3s%6s%n",
369 atom.getId()+1, // 1-based indexing
370 atom.getSymbol(),
371 atom.getType());
372 fw.write(line);
373 fw.flush();
374 }
375 else
376 {
377 if (i == 1)
378 {
379 line = String.format("%6d %-3s%6s%6d%10.5f%n",
380 atom.getId()+1, atom.getSymbol(),
381 atom.getType(),
382 zmat.getBondRefAtomIndex(i)+1, // 1-based indexing
383 zmat.getBondLength(i));
384 fw.write(line);
385 fw.flush();
386 }
387 else
388 {
389 if (i == 2)
390 {
391 line = String.format("%6d %-3s%6s%6d%10.5f%6d%10.4f%n",
392 atom.getId()+1, atom.getSymbol(),
393 atom.getType(),
394 zmat.getBondRefAtomIndex(i)+1,
395 zmat.getBondLength(i),
396 zmat.getAngleRefAtomIndex(i)+1,
397 zmat.getAngleValue(i));
398 fw.write(line);
399 fw.flush();
400 } // output the fourth through final atoms
401 else
402 {
403 line = String.format("%6d %-3s%6s%6d%10.5f%6d%10.4f%6d%10.4f%6d%n",
404 atom.getId()+1, atom.getSymbol(),
405 atom.getType(),
406 zmat.getBondRefAtomIndex(i)+1,
407 zmat.getBondLength(i),
408 zmat.getAngleRefAtomIndex(i)+1,
409 zmat.getAngleValue(i),
410 zmat.getAngle2RefAtomIndex(i)+1,
411 zmat.getAngle2Value(i),
412 zmat.getChiralFlag(i));
413 fw.write(line);
414 fw.flush();
415 }
416 }
417 }
418 }
419
420 // addition and deletion of bonds as required
421 List<int[]> zadd = zmat.getBondsToAdd();
422 List<int[]> zdel = zmat.getBondsToDel();
423
424 if (zadd.size() > 0 || zdel.size() > 0)
425 {
426 fw.write(NL);
427 fw.flush();
428
429 for (int i = 0; i < zadd.size(); i++)
430 {
431 int[] z = zadd.get(i);
432 line = String.format("%6d%6d%n", z[0]+1, z[1]+1);
433 fw.write(line);
434 fw.flush();
435 }
436
437 if (zdel.size() > 0)
438 {
439 fw.write(NL);
440 fw.flush();
441
442 for (int i = 0; i < zdel.size(); i++)
443 {
444 int[] z = zdel.get(i);
445 line = String.format("%6d%6d%n", z[0]+1, z[1]+1);
446 fw.write(line);
447 fw.flush();
448 }
449 }
450 }
451
452 }
453 catch (IOException ioe)
454 {
455 throw new DENOPTIMException(ioe);
456 }
457 finally
458 {
459 try
460 {
461 if (fw != null)
462 {
463 fw.close();
464 }
465 }
466 catch (IOException ioe)
467 {
468 throw new DENOPTIMException(ioe);
469 }
470 }
471 }
472
473//------------------------------------------------------------------------------
474
482 public static List<Double> readPSSROTOutput(String filename)
483 throws DENOPTIMException
484 {
485 List<Double> energies = new ArrayList<>();
486
487 BufferedReader br = null;
488 String line;
489 try
490 {
491 br = new BufferedReader(new FileReader(filename));
492
493 while ((line = br.readLine()) != null)
494 {
495 line = line.trim();
496 if (line.contains("Final Function Value and Deformation"))
497 {
498 String str = line.substring(38);
499 // read the number of atoms and store
500 String[] arr = str.split("\\s+");
501 energies.add(Double.parseDouble(arr[1]));
502 }
503 }
504 }
505 catch (NumberFormatException | IOException nfe)
506 {
507 throw new DENOPTIMException(nfe);
508 }
509 finally
510 {
511 try
512 {
513 if (br != null)
514 {
515 br.close();
516 }
517 }
518 catch (IOException ioe)
519 {
520 throw new DENOPTIMException(ioe);
521 }
522 }
523
524 if (energies.isEmpty())
525 {
526 String msg = "No data found in file: " + filename;
527 throw new DENOPTIMException(msg);
528 }
529 return energies;
530 }
531
532//------------------------------------------------------------------------------
533
541 public static void readPSSROTParams(String filename,
542 List<String> initPars, List<String> restPars)
543 throws DENOPTIMException
544 {
545 BufferedReader br = null;
546 String line;
547 int fnd = -1;
548
549 try
550 {
551 br = new BufferedReader(new FileReader(filename));
552 while ((line = br.readLine()) != null)
553 {
554 if (line.trim().length() == 0)
555 continue;
556 if (line.contains("INIT"))
557 {
558 fnd = 0;
559 continue;
560 }
561 if (line.contains("REST"))
562 {
563 fnd = 1;
564 continue;
565 }
566 if (fnd == 0)
567 initPars.add(line.trim());
568 if (fnd == 1)
569 restPars.add(line.trim());
570 }
571 }
572 catch (IOException nfe)
573 {
574 String msg = "File '" + filename + "' not found.";
575 throw new DENOPTIMException(msg, nfe);
576 }
577 finally
578 {
579 try
580 {
581 if (br != null)
582 {
583 br.close();
584 }
585 }
586 catch (IOException ioe)
587 {
588 throw new DENOPTIMException(ioe);
589 }
590 }
591
592 if (initPars.isEmpty())
593 {
594 String msg = "No data found in file: " + filename;
595 throw new DENOPTIMException(msg);
596 }
597 if (restPars.isEmpty())
598 {
599 String msg = "No data found in file: " + filename;
600 throw new DENOPTIMException(msg);
601 }
602 }
603
604//------------------------------------------------------------------------------
605
614 public static HashMap<String, Integer> readTinkerAtomTypes(String filename)
615 throws DENOPTIMException
616 {
617 HashMap<String, Integer> atomTypesMap = new HashMap<>();
618
619 BufferedReader br = null;
620 String line;
621
622 try
623 {
624 br = new BufferedReader(new FileReader(filename));
625 while ((line = br.readLine()) != null)
626 {
627 //Read only lines starting with keyword "atom"
628 line = line.trim();
629 if (!line.startsWith("atom"))
630 {
631 continue;
632 }
633
634 //Format:
635 //key, class, symbol, "label", Z, atomic weight, connectivity
636 try
637 {
638 //extract atom type (or 'class' according to Tinker's
639 // nomenclature) and atom symbol
640 String[] dq = line.split("\"");
641 String fp = dq[0];
642 String[] str1 = fp.split("\\s+");
643
644 //Check the format by reading all parts of atom type def.
645 int atomType = Integer.parseInt(str1[1]);
646 String symbol = str1[2];
647 /* Not needed so far...
648 String sp = dq[2];
649 String[] str2 = sp.split("\\s+");
650 String label = dq[1];
651 int z = Integer.parseInt(str2[1]);
652 double atmWeight = Double.parseDouble(str2[2]);
653 int cn = Integer.parseInt(str2[3]);
654 */
655
656 //Store
657 atomTypesMap.put(symbol,atomType);
658 }
659 catch (Throwable t)
660 {
661 String msg = "Format of Tinker's atom type definition not "
662 + "recognized. " + NL + "Details: " + NL
663 + t.getMessage();
664 throw new DENOPTIMException(msg);
665 }
666 }
667 }
668 catch (NumberFormatException | IOException nfe)
669 {
670 throw new DENOPTIMException(nfe);
671 }
672 finally
673 {
674 try
675 {
676 if (br != null)
677 {
678 br.close();
679 }
680 }
681 catch (IOException ioe)
682 {
683 throw new DENOPTIMException(ioe);
684 }
685 }
686
687 if (atomTypesMap.isEmpty())
688 {
689 String msg = "No data found in file: " + filename;
690 throw new DENOPTIMException(msg);
691 }
692
693 return atomTypesMap;
694 }
695
696//------------------------------------------------------------------------------
697
712 public static void ensureOutputExistsOrRelayError(String outputPathName,
713 String logPathName, String taskName) throws TinkerException
714 {
715 File output = new File(outputPathName);
716 if (output.exists() && output.canRead())
717 {
718 return;
719 }
720
721 String errMsg = "TINKER ERROR: ";
722 ReversedLinesFileReader fr = null;
723 try
724 {
725 fr = new ReversedLinesFileReader(new File(
726 logPathName), null);
727
728 int numEmpty = 0;
729 for (int i=0; i<100; i++) //at most 100 lines are read
730 {
731 String line = fr.readLine();
732 if (line==null)
733 break;
734
735 if (line.trim().isEmpty())
736 numEmpty++;
737
738 if (numEmpty==2)
739 break;
740 errMsg = errMsg + NL + line;
741 }
742 fr.close();
743 } catch (IOException e)
744 {
745 throw new TinkerException("Missing Tinker log '" + logPathName + "'",
746 taskName);
747 }
748
749 throw new TinkerException(errMsg, taskName);
750 }
751
752//------------------------------------------------------------------------------
753
770 public static String getNameLastCycleFile(String workDir, String fname,
771 String tinkerLog, String pattern) throws DENOPTIMException
772 {
773 int lastI = MMBuilderUtils.countLinesWKeywordInFile(tinkerLog, pattern);
774 String xyzfile = workDir + System.getProperty("file.separator") + fname
775 + "." + GeneralUtils.getPaddedString(3, lastI - 1);
776 return xyzfile;
777 }
778
779
780//------------------------------------------------------------------------------
781
782}
Exceptions resulting from a failure of Tinker.
Toolbox of utilities for Tinker style molecular representation.
static HashMap< String, Integer > readTinkerAtomTypes(String filename)
Read the Tinker atom mapping from Tinker Force Field.
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 List< double[]> readTinkerXYZ(String filename)
Read the tinker XYZ coordinate representation.
static List< Double > readPSSROTOutput(String filename)
Read the PSSROT output 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,...
static void readPSSROTParams(String filename, List< String > initPars, List< String > restPars)
Read the parameter settings to be used by PSSROT.
Utilities for molecular models builder.
static int countLinesWKeywordInFile(String filename, String keyword)
Count the number of lines starting with a keyword.
Representation of an atom in the ZMatrix.
Definition: ZMatrixAtom.java:9
String getSymbol()
Get the symbol of the atom.
String getType()
Get the type of the atom.
Representation of an atom container's geometry with internal coordinates.
Definition: ZMatrix.java:27
void delBond(int a1, int a2)
Delete the bond between the two atoms at the given indices.
Definition: ZMatrix.java:426
void setId(String id)
Set the id of the ZMatrix.
Definition: ZMatrix.java:142
void addBond(int a1, int a2)
Add a bond between the two atoms at the given indices.
Definition: ZMatrix.java:461
ZMatrixAtom getAtom(int index)
Get the atom at the given index.
Definition: ZMatrix.java:223
void addAtom(ZMatrixAtom atom)
Add an atom to the ZMatrix.
Definition: ZMatrix.java:61
static String getPaddedString(int count, int number)
returns the padded string with zeroes placed to the left of 'number' up to reach the desired number o...