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