$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.Collections;
29import java.util.HashMap;
30import java.util.List;
31
32import org.apache.commons.io.input.ReversedLinesFileReader;
33import org.openscience.cdk.interfaces.IAtom;
34import org.openscience.cdk.interfaces.IAtomContainer;
35import org.openscience.cdk.interfaces.IBond;
36
37import denoptim.constants.DENOPTIMConstants;
38import denoptim.exception.DENOPTIMException;
39import denoptim.molecularmodeling.MMBuilderUtils;
40import denoptim.utils.ConnectedLigand;
41import denoptim.utils.ConnectedLigandComparator;
42import denoptim.utils.GeneralUtils;
43import denoptim.utils.MathUtils;
44import denoptim.utils.MoleculeUtils;
45import denoptim.utils.ObjectPair;
46
47
54public class TinkerUtils
55{
56 private static final String NL = System.getProperty("line.separator");
57 private static boolean debug = false;
58
59
60//------------------------------------------------------------------------------
110 public static TinkerMolecule readTinkerIC(String filename)
111 throws DENOPTIMException
112 {
113 BufferedReader br = null;
114 String line = null;
115 int natom = 0;
116
117 TinkerMolecule tinkermol = new TinkerMolecule();
118
119 try
120 {
121 br = new BufferedReader(new FileReader(filename));
122 line = br.readLine().trim();
123
124 // read the number of atoms and store
125 String[] arr = line.split(" +");
126 natom = Integer.parseInt(arr[0]);
127 if (natom < 1)
128 {
129 String msg = "Invalid number of atoms in " + filename;
130 throw new DENOPTIMException(msg);
131 }
132
133 if (arr.length >= 2)
134 {
135 arr = line.split(" +", 2);
136 // set the name
137 //System.err.println("Name: " + arr[1]);
138 tinkermol.setName(arr[1]);
139 }
140
141
142 ArrayList<int[]> zadd = new ArrayList<>();
143 ArrayList<int[]> zdel = new ArrayList<>();
144
145 ArrayList<TinkerAtom> lstAtom = new ArrayList<>();
146
147 for (int i = 0; i < natom; i++)
148 {
149 line = br.readLine();
150 if (line == null)
151 {
152 break;
153 }
154
155 arr = line.trim().split(" +");
156 if (arr == null || arr.length < 3)
157 {
158 String msg = "Check atom " + (i + 1) + " in " + filename;
159 throw new DENOPTIMException(msg);
160 }
161
162 // Atom number, name, type
163 String name = arr[1];
164 int type = Integer.parseInt(arr[2]);
165 double zv[] = new double[3];
166 int zi[] = new int[4];
167 double d[] =
168 {
169 0.0d, 0.0d, 0.0d
170 };
171
172 // Bond partner and bond value
173 if (arr.length >= 5)
174 {
175 zi[0] = Integer.parseInt(arr[3]);
176 zv[0] = Double.parseDouble(arr[4]);
177 }
178 else
179 {
180 zi[0] = 0;
181 zv[0] = 0.0d;
182 }
183 // Angle partner and angle value
184 if (arr.length >= 7)
185 {
186 zi[1] = Integer.parseInt(arr[5]);
187 zv[1] = Double.parseDouble(arr[6]);
188 }
189 else
190 {
191 zi[1] = 0;
192 zv[1] = 0.0d;
193 }
194 // Torsion partner and dihedral value
195 if (arr.length >= 10)
196 {
197 zi[2] = Integer.parseInt(arr[7]);
198 zv[2] = Double.parseDouble(arr[8]);
199 zi[3] = Integer.parseInt(arr[9]);
200 }
201 else
202 {
203 zi[2] = 0;
204 zv[2] = 0.0d;
205 zi[3] = 0;
206 }
207 TinkerAtom tkatm = new TinkerAtom(i + 1,name,type,d,zi,zv);
208 lstAtom.add(tkatm);
209 } // end for
210
211 if (br.ready())
212 {
213 line = br.readLine();
214 // Check for a first blank line
215 if (line.trim().equalsIgnoreCase(""))
216 {
217 // Parse bond pairs to add until EOF or a blank line is
218 // reached
219 boolean blank = false;
220 while (br.ready() && !blank)
221 {
222 line = br.readLine();
223 if (line.trim().equalsIgnoreCase(""))
224 {
225 blank = true;
226 }
227 else
228 {
229 arr = line.trim().split(" +");
230 if (arr.length != 2)
231 {
232 String msg = "Check Bond Pair to Remove: "
233 + (zadd.size() + 1) + " in " + filename;
234 throw new DENOPTIMException(msg);
235 }
236 int pair[] = new int[2];
237 pair[0] = Integer.parseInt(arr[0]);
238 pair[1] = Integer.parseInt(arr[1]);
239 zadd.add(pair);
240 }
241 }
242 // Parse bond pairs to be removed until EOF
243 while (br.ready())
244 {
245 line = br.readLine();
246 arr = line.trim().split(" +");
247 if (arr.length != 2)
248 {
249 String msg = "Check Bond Pair to Remove: "
250 + (zadd.size() + 1) + " in " + filename;
251 throw new DENOPTIMException(msg);
252 }
253 int pair[] = new int[2];
254 pair[0] = Integer.parseInt(arr[0]);
255 pair[1] = Integer.parseInt(arr[1]);
256 zdel.add(pair);
257 }
258 }
259 }
260
261 tinkermol.setAtoms(lstAtom);
262 tinkermol.setBondPairs(zdel, zadd);
263 }
264 catch (NumberFormatException | IOException nfe)
265 {
266 throw new DENOPTIMException(nfe);
267 }
268 finally
269 {
270 try
271 {
272 if (br != null)
273 {
274 br.close();
275 }
276 }
277 catch (IOException ioe)
278 {
279 throw new DENOPTIMException(ioe);
280 }
281 }
282
283 return tinkermol;
284 }
285
286//------------------------------------------------------------------------------
287
296 public static ArrayList<double[]> readTinkerXYZ(String filename)
297 throws DENOPTIMException
298 {
299 ArrayList<double[]> coords = new ArrayList<>();
300
301 BufferedReader br = null;
302 String line = null;
303
304 int natom = 0;
305
306 try
307 {
308 br = new BufferedReader(new FileReader(filename));
309 line = br.readLine().trim();
310
311 // read the number of atoms and store
312 String[] arr = line.split("\\s+");
313 natom = Integer.parseInt(arr[0]);
314 if (natom < 1)
315 {
316 String msg = "Invalid number of atoms in " + filename;
317 throw new DENOPTIMException(msg);
318 }
319
320 while ((line = br.readLine()) != null)
321 {
322 if (line.trim().length() == 0)
323 {
324 continue;
325 }
326
327 arr = line.trim().split("\\s+");
328 if (arr.length >= 5)
329 {
330 // Atom number, name, type
331 //String name = arr[1];
332 double[] f = new double[3];
333 f[0] = Double.parseDouble(arr[2]);
334 f[1] = Double.parseDouble(arr[3]);
335 f[2] = Double.parseDouble(arr[4]);
336
337 coords.add(f);
338 }
339 }
340 }
341 catch (NumberFormatException | IOException nfe)
342 {
343 throw new DENOPTIMException(nfe);
344 }
345 finally
346 {
347 try
348 {
349 if (br != null)
350 {
351 br.close();
352 }
353 }
354 catch (IOException ioe)
355 {
356 throw new DENOPTIMException(ioe);
357 }
358 }
359
360 if (coords.size() != natom)
361 {
362 throw new DENOPTIMException("Incorrect number of atoms perceived "
363 + "in " + filename);
364 }
365
366 return coords;
367
368 }
369
370//------------------------------------------------------------------------------
371
380 public static void writeIC(String filename, TinkerMolecule tmol)
381 throws DENOPTIMException
382 {
383 FileWriter fw = null;
384 try
385 {
386 fw = new FileWriter(new File(filename));
387 int numatoms = tmol.getAtoms().size();
388 // write out the number of atoms and the title
389 String header = String.format("%6d %s%n", numatoms, tmol.getName());
390 fw.write(header);
391 fw.flush();
392
393 String line = "";
394
395 for (int i = 0; i < numatoms; i++)
396 {
397 TinkerAtom atom = tmol.getAtoms().get(i);
398 int[] d1 = atom.getAtomNeighbours();
399 double[] d2 = atom.getDistAngle();
400 // output of first three atoms is handled separately
401 if (i == 0)
402 {
403 line = String.format("%6d %-3s%6d%n",
404 atom.getXYZIndex(), atom.getAtomString(),
405 atom.getAtomType());
406 fw.write(line);
407 fw.flush();
408 }
409 else
410 {
411 if (i == 1)
412 {
413 line = String.format("%6d %-3s%6d%6d%10.5f%n",
414 atom.getXYZIndex(), atom.getAtomString(),
415 atom.getAtomType(), d1[0], d2[0]);
416 fw.write(line);
417 fw.flush();
418 }
419 else
420 {
421 if (i == 2)
422 {
423 line = String.format("%6d %-3s%6d%6d%10.5f%6d%10.4f%n",
424 atom.getXYZIndex(), atom.getAtomString(),
425 atom.getAtomType(), d1[0], d2[0],
426 d1[1], d2[1]);
427 fw.write(line);
428 fw.flush();
429 } // output the fourth through final atoms
430 else
431 {
432 line = String.format("%6d %-3s%6d%6d%10.5f%6d%10.4f%6d%10.4f%6d%n",
433 atom.getXYZIndex(), atom.getAtomString(),
434 atom.getAtomType(), d1[0], d2[0],
435 d1[1], d2[1], d1[2], d2[2], d1[3]);
436 fw.write(line);
437 fw.flush();
438 }
439 }
440 }
441 }
442
443 // addition and deletion of bonds as required
444 ArrayList<int[]> zadd = tmol.getBondAdd();
445 ArrayList<int[]> zdel = tmol.getBondDel();
446
447 if (zadd.size() > 0 || zdel.size() > 0)
448 {
449 fw.write(NL);
450 fw.flush();
451
452 for (int i = 0; i < zadd.size(); i++)
453 {
454 int[] z = zadd.get(i);
455 line = String.format("%6d%6d%n", z[0], z[1]);
456 fw.write(line);
457 fw.flush();
458 }
459
460 if (zdel.size() > 0)
461 {
462 fw.write(NL);
463 fw.flush();
464
465 for (int i = 0; i < zdel.size(); i++)
466 {
467 int[] z = zdel.get(i);
468 line = String.format("%6d%6d%n", z[0], z[1]);
469 fw.write(line);
470 fw.flush();
471 }
472 }
473 }
474
475 }
476 catch (IOException ioe)
477 {
478 throw new DENOPTIMException(ioe);
479 }
480 finally
481 {
482 try
483 {
484 if (fw != null)
485 {
486 fw.close();
487 }
488 }
489 catch (IOException ioe)
490 {
491 throw new DENOPTIMException(ioe);
492 }
493 }
494 }
495
496//------------------------------------------------------------------------------
497
505 public static ArrayList<Double> readPSSROTOutput(String filename)
506 throws DENOPTIMException
507 {
508 ArrayList<Double> energies = new ArrayList<>();
509
510 BufferedReader br = null;
511 String line;
512 try
513 {
514 br = new BufferedReader(new FileReader(filename));
515
516 while ((line = br.readLine()) != null)
517 {
518 line = line.trim();
519 if (line.contains("Final Function Value and Deformation"))
520 {
521 String str = line.substring(38);
522 // read the number of atoms and store
523 String[] arr = str.split("\\s+");
524 energies.add(Double.parseDouble(arr[1]));
525 }
526 }
527 }
528 catch (NumberFormatException | IOException nfe)
529 {
530 throw new DENOPTIMException(nfe);
531 }
532 finally
533 {
534 try
535 {
536 if (br != null)
537 {
538 br.close();
539 }
540 }
541 catch (IOException ioe)
542 {
543 throw new DENOPTIMException(ioe);
544 }
545 }
546
547 if (energies.isEmpty())
548 {
549 String msg = "No data found in file: " + filename;
550 throw new DENOPTIMException(msg);
551 }
552 return energies;
553 }
554
555//------------------------------------------------------------------------------
556
564 public static void readPSSROTParams(String filename,
565 ArrayList<String> initPars, ArrayList<String> restPars)
566 throws DENOPTIMException
567 {
568 BufferedReader br = null;
569 String line;
570 int fnd = -1;
571
572 try
573 {
574 br = new BufferedReader(new FileReader(filename));
575 while ((line = br.readLine()) != null)
576 {
577 if (line.trim().length() == 0)
578 continue;
579 if (line.contains("INIT"))
580 {
581 fnd = 0;
582 continue;
583 }
584 if (line.contains("REST"))
585 {
586 fnd = 1;
587 continue;
588 }
589 if (fnd == 0)
590 initPars.add(line.trim());
591 if (fnd == 1)
592 restPars.add(line.trim());
593 }
594 }
595 catch (IOException nfe)
596 {
597 String msg = "File '" + filename + "' not found.";
598 throw new DENOPTIMException(msg, nfe);
599 }
600 finally
601 {
602 try
603 {
604 if (br != null)
605 {
606 br.close();
607 }
608 }
609 catch (IOException ioe)
610 {
611 throw new DENOPTIMException(ioe);
612 }
613 }
614
615 if (initPars.isEmpty())
616 {
617 String msg = "No data found in file: " + filename;
618 throw new DENOPTIMException(msg);
619 }
620 if (restPars.isEmpty())
621 {
622 String msg = "No data found in file: " + filename;
623 throw new DENOPTIMException(msg);
624 }
625 }
626
627//------------------------------------------------------------------------------
628
637 public static HashMap<String, Integer> readTinkerAtomTypes(String filename)
638 throws DENOPTIMException
639 {
640 HashMap<String, Integer> atomTypesMap = new HashMap<>();
641
642 BufferedReader br = null;
643 String line;
644
645 try
646 {
647 br = new BufferedReader(new FileReader(filename));
648 while ((line = br.readLine()) != null)
649 {
650 //Read only lines starting with keyword "atom"
651 line = line.trim();
652 if (!line.startsWith("atom"))
653 {
654 continue;
655 }
656
657 //Format:
658 //key, class, symbol, "label", Z, atomic weight, connectivity
659 try
660 {
661 //extract atom type (or 'class' according to Tinker's
662 // nomenclature) and atom symbol
663 String[] dq = line.split("\"");
664 String fp = dq[0];
665 String[] str1 = fp.split("\\s+");
666
667 //Check the format by reading all parts of atom type def.
668 int atomType = Integer.parseInt(str1[1]);
669 String symbol = str1[2];
670 /* Not needed so far...
671 String sp = dq[2];
672 String[] str2 = sp.split("\\s+");
673 String label = dq[1];
674 int z = Integer.parseInt(str2[1]);
675 double atmWeight = Double.parseDouble(str2[2]);
676 int cn = Integer.parseInt(str2[3]);
677 */
678
679 //Store
680 atomTypesMap.put(symbol,atomType);
681 }
682 catch (Throwable t)
683 {
684 String msg = "Format of Tinker's atom type definition not "
685 + "recognized. " + NL + "Details: " + NL
686 + t.getMessage();
687 throw new DENOPTIMException(msg);
688 }
689 }
690 }
691 catch (NumberFormatException | IOException nfe)
692 {
693 throw new DENOPTIMException(nfe);
694 }
695 finally
696 {
697 try
698 {
699 if (br != null)
700 {
701 br.close();
702 }
703 }
704 catch (IOException ioe)
705 {
706 throw new DENOPTIMException(ioe);
707 }
708 }
709
710 if (atomTypesMap.isEmpty())
711 {
712 String msg = "No data found in file: " + filename;
713 throw new DENOPTIMException(msg);
714 }
715
716 return atomTypesMap;
717 }
718
719//------------------------------------------------------------------------------
720
730 public static TinkerMolecule getICFromIAC(IAtomContainer mol,
731 HashMap<String,Integer> tMap ) throws DENOPTIMException
732 {
734 String doneBnd = "visitedBond";
735 for (int i=0; i<mol.getAtomCount(); i++)
736 {
737 int i2 = 0;
738 int i3 = 0;
739 int i4 = 0;
740 int i5 = 0;
741 double d = 0.0;
742 double a = 0.0;
743 double t = 0.0;
744
745 int[] nbrs = new int[] {0, 0, 0, 0};
746
747 IAtom atmI = mol.getAtom(i);
748 if (debug)
749 {
750 System.err.println("Atom to IC: "
751 +MoleculeUtils.getSymbolOrLabel(atmI)+" "+i);
752 }
753
754 // define the bond length
755 if (i>0)
756 {
757 i2 = getFirstRefAtomId(i,mol);
758 d = atmI.getPoint3d().distance(mol.getAtom(i2).getPoint3d());
759 mol.getBond(atmI,mol.getAtom(i2)).setProperty(doneBnd,"T");
760 if (debug)
761 {
762 System.err.println(" i2 = " + i2 + " d: " + d);
763 }
764 nbrs[0] = i2+1;
765 }
766
767 // define the bond angle
768 if (i>1)
769 {
770 i3 = getSecondRefAtomId(i,i2,mol);
771 a = MathUtils.angle(atmI.getPoint3d(),
772 mol.getAtom(i2).getPoint3d(),
773 mol.getAtom(i3).getPoint3d());
774 if (debug)
775 {
776 System.err.println(" i3 = "+ i3 + " a: " + a);
777 }
778 nbrs[0] = i2+1;
779 nbrs[1] = i3+1;
780 }
781
782 // decide on dihedral or second angle
783 if (i>2)
784 {
785 ObjectPair op = getThirdRefAtomId(i,i2,i3,mol,tm);
786 i4 = (int) op.getFirst();
787 i5 = (int) op.getSecond();
788 if (i5==1)
789 {
790 t = MathUtils.angle(atmI.getPoint3d(),
791 mol.getAtom(i2).getPoint3d(),
792 mol.getAtom(i4).getPoint3d());
793 double sign = MathUtils.torsion(
794 atmI.getPoint3d(),
795 mol.getAtom(i2).getPoint3d(),
796 mol.getAtom(i3).getPoint3d(),
797 mol.getAtom(i4).getPoint3d());
798 if (sign > 0.0)
799 {
800 i5 = -1;
801 }
802 }
803 else
804 {
805 t = MathUtils.torsion(atmI.getPoint3d(),
806 mol.getAtom(i2).getPoint3d(),
807 mol.getAtom(i3).getPoint3d(),
808 mol.getAtom(i4).getPoint3d());
809 }
810 if (debug)
811 {
812 System.err.println(" i4 = "+ i4 + " t: " + t + " " + i5);
813 }
814 nbrs[0] = i2+1;
815 nbrs[1] = i3+1;
816 nbrs[2] = i4+1;
817 nbrs[3] = i5;
818 }
819
820 String symb = MoleculeUtils.getSymbolOrLabel(atmI);
821 int atyp = 0; // Tinker types are assigned later
822
823 TinkerAtom ta = new TinkerAtom(i+1, symb, atyp,
824 new double[] {atmI.getPoint3d().x,
825 atmI.getPoint3d().y,
826 atmI.getPoint3d().z},
827 nbrs,
828 new double[] {d,a,t});
829
830 long vidx = atmI.getProperty(DENOPTIMConstants.ATMPROPVERTEXID);
831 ta.setVertexId(vidx);
832
833 if (debug)
834 {
835 System.err.println(" TinkerAtom: "+ta.toString());
836 }
837
838 tm.addAtom(ta);
839
840 if (debug)
841 {
842 System.err.println("TinkerMolecule: ");
843 tm.printIC();
844 }
845 }
846
847 // Add bonds not visited
848 for (IBond b : mol.bonds())
849 {
850 if (b.getProperty(doneBnd) == null)
851 {
852 tm.addBond(mol.indexOf(b.getAtom(0))+1,
853 mol.indexOf(b.getAtom(1))+1);
854 }
855 }
856
857 // Due to the assumption that all atoms are part of the same
858 // connected network, no bond has to be deleted
859
860 // Fix TinkerAtom types
861 setTinkerTypes(tm,tMap);
862
863 return tm;
864 }
865
866//----------------------------------------------------------------------------
867
868 private static int getFirstRefAtomId(int i1, IAtomContainer mol)
869 {
870 List<ConnectedLigand> candidates = new ArrayList<ConnectedLigand>();
871 for (IAtom nbr : mol.getConnectedAtomsList(mol.getAtom(i1)))
872 {
873 if (mol.indexOf(nbr) < i1)
874 {
875 ConnectedLigand cl = new ConnectedLigand(nbr,1);
876 candidates.add(cl);
877 }
878 }
879 Collections.sort(candidates, new ConnectedLigandComparator());
880 int i2 = mol.indexOf(candidates.get(0).getAtom());
881 return i2;
882 }
883
884//----------------------------------------------------------------------------
885
886 private static int getSecondRefAtomId(int i1, int i2, IAtomContainer mol)
887 {
888 List<ConnectedLigand> candidates = new ArrayList<ConnectedLigand>();
889 for (IAtom nbr : mol.getConnectedAtomsList(mol.getAtom(i2)))
890 {
891 if ((mol.indexOf(nbr) < i1) && (nbr != mol.getAtom(i1)))
892 {
893 ConnectedLigand cl = new ConnectedLigand(nbr,1);
894 candidates.add(cl);
895 }
896 }
897 Collections.sort(candidates, new ConnectedLigandComparator());
898 int i3 = mol.indexOf(candidates.get(0).getAtom());
899 return i3;
900 }
901
902//----------------------------------------------------------------------------
903
904 private static ObjectPair getThirdRefAtomId(int i1, int i2, int i3,
905 IAtomContainer mol, TinkerMolecule tm) throws DENOPTIMException
906 {
907 int i5 = 0;
908 IAtom atmI1 = mol.getAtom(i1);
909 IAtom atmI2 = mol.getAtom(i2);
910 IAtom atmI3 = mol.getAtom(i3);
911 List<ConnectedLigand> candidates = new ArrayList<ConnectedLigand>();
912 if (tm.isTorsionUsed(i2+1, i3+1) ||
913 countPredefinedNeighbours(i1,atmI3,mol)==1)
914 {
915 i5 = 1;
916 for (IAtom nbr : mol.getConnectedAtomsList(atmI2))
917 {
918 if (debug)
919 {
920 System.err.println(" Eval. 3rd (ANG): " +
922 + mol.indexOf(nbr) + " "
923 + (mol.indexOf(nbr) < i1) + " "
924 + (nbr != atmI1) + " "
925 + (nbr != atmI3));
926 }
927 if ((mol.indexOf(nbr) < i1) && (nbr != atmI1) &&
928 (nbr != atmI3))
929 {
930 double dbcAng = MathUtils.angle(nbr.getPoint3d(),
931 atmI2.getPoint3d(),
932 atmI3.getPoint3d());
933 if(dbcAng > 1.0)
934 {
935 ConnectedLigand cl = new ConnectedLigand(nbr,1);
936 candidates.add(cl);
937 }
938 else
939 {
940 if (debug)
941 {
942 System.err.println(" ...but collinear with "
943 + MoleculeUtils.getSymbolOrLabel(atmI3) + i3
944 + " (i4-i2-i3: " + dbcAng
945 + ")");
946 }
947 }
948 }
949 }
950 }
951 else
952 {
953 i5 = 0;
954 for (IAtom nbr : mol.getConnectedAtomsList(atmI3))
955 {
956 if (debug)
957 {
958 System.err.println(" Eval. 3rd (TOR): "
960 + mol.indexOf(nbr) + " "
961 + (mol.indexOf(nbr) < i1) + " "
962 + (nbr != atmI1) + " "
963 + (nbr != atmI2));
964 }
965 if ((mol.indexOf(nbr) < i1) && (nbr != atmI1) &&
966 (nbr != atmI2))
967 {
968 ConnectedLigand cl = new ConnectedLigand(nbr,1);
969 candidates.add(cl);
970 }
971 }
972 }
973 Collections.sort(candidates, new ConnectedLigandComparator());
974 if (candidates.size() == 0)
975 {
976 String msg = "Unable to make internal coordinates. Please, "
977 + "consider the use of dummy atoms in proximity "
978 + "of atom " + tm.getAtom(i1+1);
979 throw new DENOPTIMException(msg);
980 }
981 int i4 = mol.indexOf(candidates.get(0).getAtom());
982
983 ObjectPair op = new ObjectPair(i4,i5);
984
985 return op;
986 }
987
988//------------------------------------------------------------------------------
989
990 private static int countPredefinedNeighbours(int i, IAtom a, IAtomContainer mol)
991 {
992 int tot = 0;
993 for (IAtom nbr : mol.getConnectedAtomsList(a))
994 {
995 if (mol.indexOf(nbr) < i)
996 tot++;
997 }
998 return tot;
999 }
1000
1001//------------------------------------------------------------------------------
1002
1011 public static void setTinkerTypes(TinkerMolecule tmol,
1012 HashMap<String,Integer> tMap) throws DENOPTIMException
1013 {
1014 ArrayList<TinkerAtom> lstAtoms = tmol.getAtoms();
1015 int numberOfAtoms = lstAtoms.size();
1016 for (int i = 0; i < numberOfAtoms; i++)
1017 {
1018 TinkerAtom tatom = lstAtoms.get(i);
1019
1020 String st = tatom.getAtomString().trim();
1021 if (!tMap.containsKey(st))
1022 {
1023 String msg = "Unable to assign atom type to atom '" + st +"'. ";
1024 if (st.equals("R"))
1025 {
1026 msg = msg + "Unusual dummy atom symbols get atom symbol "
1027 + "'R'. Please, add atom type 'R' in your atom type map.";
1028 }
1029 throw new DENOPTIMException(msg);
1030 }
1031 Integer val = tMap.get(st);
1032 if (val != null)
1033 {
1034 tatom.setAtomType(val.intValue());
1035 if (debug)
1036 System.err.println("Set parameter for " + st + " " + val);
1037 }
1038 else
1039 {
1040 String msg = "No valid Tinker atom type assigned for atom "
1041 + st + ".\n";
1042 throw new DENOPTIMException(msg);
1043 }
1044 }
1045 }
1046
1047//------------------------------------------------------------------------------
1048
1063 public static void ensureOutputExistsOrRelayError(String outputPathName,
1064 String logPathName, String taskName) throws TinkerException
1065 {
1066 File output = new File(outputPathName);
1067 if (output.exists() && output.canRead())
1068 {
1069 return;
1070 }
1071
1072 String errMsg = "TINKER ERROR: ";
1073 ReversedLinesFileReader fr = null;
1074 try
1075 {
1076 fr = new ReversedLinesFileReader(new File(
1077 logPathName), null);
1078
1079 int numEmpty = 0;
1080 for (int i=0; i<100; i++) //at most 100 lines are read
1081 {
1082 String line = fr.readLine();
1083 if (line==null)
1084 break;
1085
1086 if (line.trim().isEmpty())
1087 numEmpty++;
1088
1089 if (numEmpty==2)
1090 break;
1091 errMsg = errMsg + NL + line;
1092 }
1093 fr.close();
1094 } catch (IOException e)
1095 {
1096 throw new TinkerException("Missing Tinker log '" + logPathName + "'",
1097 taskName);
1098 }
1099
1100 throw new TinkerException(errMsg, taskName);
1101 }
1102
1103//------------------------------------------------------------------------------
1104
1121 public static String getNameLastCycleFile(String workDir, String fname,
1122 String tinkerLog, String pattern) throws DENOPTIMException
1123 {
1124 int lastI = MMBuilderUtils.countLinesWKeywordInFile(tinkerLog, pattern);
1125 String xyzfile = workDir + System.getProperty("file.separator") + fname
1126 + "." + GeneralUtils.getPaddedString(3, lastI - 1);
1127 return xyzfile;
1128 }
1129
1130
1131//------------------------------------------------------------------------------
1132
1133}
General set of constants used in DENOPTIM.
static final String ATMPROPVERTEXID
String tag of Atom property used to store the unique ID of the Vertex corresponding to the molecular ...
Based on the code from ffx.kenai.com Michael J.
Definition: TinkerAtom.java:26
int getXYZIndex()
Gets the XYZ Index.
Exceptions resulting from a failure of Tinker.
void addBond(int a1, int a2)
Add one bond by appending a pair of indeces into the z-add section.
void addAtom(TinkerAtom ta)
Add one atom to this molecule.
void setAtoms(ArrayList< TinkerAtom > lstAtoms)
void setBondPairs(ArrayList< int[]> zdel, ArrayList< int[]> zadd)
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 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 int getSecondRefAtomId(int i1, int i2, IAtomContainer mol)
static ObjectPair getThirdRefAtomId(int i1, int i2, int i3, IAtomContainer mol, TinkerMolecule tm)
static int countPredefinedNeighbours(int i, IAtom a, IAtomContainer mol)
static void writeIC(String filename, TinkerMolecule tmol)
Write Tinker INT file.
static ArrayList< Double > readPSSROTOutput(String filename)
Read the PSSROT output file.
static int getFirstRefAtomId(int i1, IAtomContainer mol)
static ArrayList< double[]> readTinkerXYZ(String filename)
Read the tinker XYZ coordinate representation.
static void readPSSROTParams(String filename, ArrayList< String > initPars, ArrayList< String > restPars)
Read the parameter settings to be used by PSSROT.
static TinkerMolecule getICFromIAC(IAtomContainer mol, HashMap< String, Integer > tMap)
Convert IAtomContainer to TinkerMolecule.
static TinkerMolecule readTinkerIC(String filename)
Reads a Tinker INT file.
static void setTinkerTypes(TinkerMolecule tmol, HashMap< String, Integer > tMap)
Conversion to tinker IC may not always have the necessary atom types.
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,...
Utilities for molecular models builder.
static int countLinesWKeywordInFile(String filename, String keyword)
Count the number of lines starting with a keyword.
Compare two ConnectedLigand according to the number of connected atoms and the mass number.
A ConnectedLigand is just an atom with an explicit field reporting the number of connected atoms.
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...
Some useful math operations.
Definition: MathUtils.java:39
static double angle(Point3d a, Point3d b, Point3d c)
Calculate the angle between the 3 points.
Definition: MathUtils.java:284
static double torsion(Point3d p1, Point3d p2, Point3d p3, Point3d p4)
Calculate the torsion angle between the 4 points.
Definition: MathUtils.java:363
Utilities for molecule conversion.
static String getSymbolOrLabel(IAtom atm)
Gets either the elemental symbol (for standard atoms) of the label (for pseudo-atoms).
This class is the equivalent of the Pair data structure used in C++ Although AbstractMap....
Definition: ObjectPair.java:30