19package denoptim.molecularmodeling;
21import java.util.ArrayList;
22import java.util.Arrays;
23import java.util.HashMap;
24import java.util.HashSet;
28import java.util.logging.Level;
29import java.util.logging.Logger;
31import javax.vecmath.Point3d;
32import javax.vecmath.Vector3d;
34import org.openscience.cdk.graph.PathTools;
35import org.openscience.cdk.graph.SpanningTree;
36import org.openscience.cdk.interfaces.IAtom;
37import org.openscience.cdk.interfaces.IAtomContainer;
38import org.openscience.cdk.interfaces.IBond;
39import org.openscience.cdk.interfaces.IChemObjectBuilder;
40import org.openscience.cdk.interfaces.IRingSet;
41import org.openscience.cdk.silent.RingSet;
42import org.openscience.cdk.silent.SilentChemObjectBuilder;
44import denoptim.constants.DENOPTIMConstants;
45import denoptim.exception.DENOPTIMException;
46import denoptim.graph.DGraph;
47import denoptim.graph.Edge.BondType;
48import denoptim.graph.Ring;
49import denoptim.graph.rings.RingClosingAttractor;
50import denoptim.graph.rings.RingClosure;
51import denoptim.integration.tinker.TinkerAtom;
52import denoptim.integration.tinker.TinkerMolecule;
53import denoptim.integration.tinker.TinkerUtils;
54import denoptim.io.DenoptimIO;
55import denoptim.utils.MathUtils;
56import denoptim.utils.ObjectPair;
75 private IAtomContainer
fmol;
139 this.molGraph =
new DGraph();
140 IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
141 this.fmol = builder.newAtomContainer();
143 this.attractors =
new ArrayList<RingClosingAttractor>();
144 this.attToAtmID =
new HashMap<RingClosingAttractor,Integer>();
145 this.allRCACombs =
new ArrayList<Set<ObjectPair>>();
146 this.rotatableBnds =
new ArrayList<ObjectPair>();
147 this.newRingClosures =
new ArrayList<RingClosure>();
148 this.molName =
"none";
149 this.oldToNewOrder =
new ArrayList<Integer>();
150 this.newToOldOrder =
new ArrayList<Integer>();
178 ArrayList<RingClosure> ringClosures,
191 this.newRingClosures = ringClosures;
192 this.overalRCScore = Double.NaN;
193 this.atmOveralScore = Double.NaN;
194 if (this.attractors.size() != 0)
240 this.attractors =
new ArrayList<RingClosingAttractor>();
241 this.attToAtmID =
new HashMap<RingClosingAttractor,Integer>();
243 this.allRCACombs =
new ArrayList<Set<ObjectPair>>();
244 if (this.attractors.size() != 0)
252 this.newRingClosures =
new ArrayList<RingClosure>();
253 this.overalRCScore = Double.NaN;
254 this.atmOveralScore = Double.NaN;
279 for (IAtom atm :
fmol.atoms())
296 Set<ObjectPair> singleRCAcomb =
new HashSet<ObjectPair>();
302 if (ringOwnerI==
null)
309 if (ringOwnerJ==
null)
311 if (ringOwnerI==ringOwnerJ)
313 singleRCAcomb.add(
new ObjectPair(rcaI, rcaJ));
329 ArrayList<Point3d> newCoords =
new ArrayList<Point3d>();
330 for (
int i=0; i<
fmol.getAtomCount(); i++)
337 if (ia > i || ib > i || ic > i)
339 String msg =
"ERROR! Cannot convert internal coordinates of "
340 +
"atom " + i +
" " + tAtm +
". Reference "
341 +
"atoms have higher ID. The atoms list in "
342 +
"Molecule3DBuilder needs to be reordered.";
347 double angle1 = tAtm.
getDistAngle()[1] * 2 * Math.PI / 360.0;
348 double angle2 = tAtm.
getDistAngle()[2] * 2 * Math.PI / 360.0;
349 double[] newXYZ = {0.0, 0.0, 0.0};
351 double s1 = Math.sin(angle1);
352 double s2 = Math.sin(angle2);
353 double c1 = Math.cos(angle1);
354 double c2 = Math.cos(angle2);
366 newCoords.get(ia-1),newCoords.get(ib-1));
368 newCoords.get(ia-1),newCoords.get(ib-1));
369 newXYZ[0] = bond * s1;
370 newXYZ[2] = newCoords.get(ib-1).z + (rab - bond*c1)*nab.z;
372 else if (angleFlag == 0)
375 newCoords.get(ia-1),newCoords.get(ib-1));
377 newCoords.get(ib-1),newCoords.get(ic-1));
378 Vector3d t =
new Vector3d();
380 double c = nab.x*nbc.x + nab.y*nbc.y + nab.z*nbc.z;
381 if (Math.abs(c) > (1.0 - smallDble))
383 String msg =
"ERROR! Linearity does not allow definition "
384 +
"of the dihedral angle for atom " + i +
" " + tAtm
385 +
" (Value of c="+c+
" too close to unity; threshold is "
386 + (1.0 - smallDble) +
"). "
387 +
"You better use dummy atoms to avoid linearities.";
390 t.scale(1/Math.sqrt(Math.max(1.00 - c*c, smallDble)));
391 Vector3d u =
new Vector3d();
393 newXYZ[0] = newCoords.get(ia-1).x
394 + bond*(u.x*s1*c2 + t.x*s1*s2 - nab.x*c1);
395 newXYZ[1] = newCoords.get(ia-1).y
396 + bond*(u.y*s1*c2 + t.y*s1*s2 - nab.y*c1);
397 newXYZ[2] = newCoords.get(ia-1).z
398 + bond*(u.z*s1*c2 + t.z*s1*s2 - nab.z*c1);
400 else if (Math.abs(angleFlag) == 1)
403 newCoords.get(ib-1),newCoords.get(ia-1));
405 newCoords.get(ia-1),newCoords.get(ic-1));
406 Vector3d t =
new Vector3d();
408 double c = nba.x*nac.x + nba.y*nac.y + nba.z*nac.z;
409 if (Math.abs(c) > (1.0 - smallDble))
411 logger.log(Level.WARNING,
"WARNING! close-to-linear system "
412 +
"in the definition of atom " + i +
" " + tAtm +
". "
413 +
"You better use dummy atoms to avoid linearities.");
415 double s = Math.max(1.00 - c*c, smallDble);
416 double a = (-c2 - c*c1) / s;
417 double b = (c1 + c*c2) / s;
418 double ci = (1.00 + a*c2 - b*c1) / s;
421 ci = angleFlag * Math.sqrt(ci);
423 else if (ci < -smallDble)
425 ci = Math.sqrt((a*nac.x+b*nba.x)*(a*nac.x+b*nba.x)
426 + (a*nac.y+b*nba.y)*(a*nac.y+b*nba.y)
427 + (a*nac.z+b*nba.z)*(a*nac.z+b*nba.z));
431 logger.log(Level.WARNING,
"WARNING! close-to-linear system "
432 +
"in the definition of atom " + i +
" " + tAtm +
". "
433 +
"You better use dummy atoms to avoid linearities.");
439 newXYZ[0] = newCoords.get(ia-1).x
440 + bond*(a*nac.x + b*nba.x + ci*t.x);
441 newXYZ[1] = newCoords.get(ia-1).y
442 + bond*(a*nac.y + b*nba.y + ci*t.y);
443 newXYZ[2] = newCoords.get(ia-1).z
444 + bond*(a*nac.z + b*nba.z + ci*t.z);
446 Point3d p3d =
new Point3d(newXYZ[0],newXYZ[1],newXYZ[2]);
451 for (
int i=0; i<
fmol.getAtomCount(); i++)
453 fmol.getAtom(i).setPoint3d(newCoords.get(i));
601 score = score + rc.getRingClosureQuality();
620 for (IAtom atmA :
fmol.atoms())
622 String elA = atmA.getSymbol();
627 IAtom[] toExclude = PathTools.findClosestByBond(
fmol,atmA,4);
628 for (IAtom atmB :
fmol.atoms())
633 if (Arrays.asList(toExclude).contains(atmB))
636 String elB = atmB.getSymbol();
640 double dist = atmA.getPoint3d().distance(atmB.getPoint3d());
641 score = score + dist;
675 this.newRingClosures.add(nRc);
676 this.overalRCScore = Double.NaN;
678 int iA =
fmol.indexOf(atmA);
679 int iB =
fmol.indexOf(atmB);
684 logger.log(Level.FINE,
"ADDING BOND: "+iA+
" "+iB);
686 logger.log(Level.FINE,
"WARNING! Attempt to add ring closing bond "
687 +
"did not add any actual chemical bond because the "
688 +
"bond type of the chord is '" + bndTyp +
"'.");
711 SpanningTree st =
new SpanningTree(
fmol);
712 IRingSet allRings =
new RingSet();
714 allRings = st.getAllRings();
715 }
catch (Exception ex) {
720 ArrayList<ObjectPair> toRemove =
new ArrayList<ObjectPair>();
723 int i1 = ((Integer)op.getFirst()).intValue();
724 int i2 = ((Integer)op.getSecond()).intValue();
726 IBond bnd =
fmol.getBond(
fmol.getAtom(i1),
fmol.getAtom(i2));
727 IRingSet rs = allRings.getRings(bnd);
731 logger.log(Level.FINE,
"Bond " + i1 +
"-" + i2 +
" (TnkID:"
732 + (i1+1) +
"-" + (i2+1) +
") is not rotatable anymore");
752 @SuppressWarnings(
"unchecked")
755 String nMolName = this.
molName;
757 IAtomContainer nFMol;
759 ArrayList<ObjectPair> nRotBnds;
763 nFMol = this.fmol.
clone();
765 nRotBnds = (ArrayList<ObjectPair>) this.rotatableBnds.
clone();
767 catch (CloneNotSupportedException cns)
772 ArrayList<RingClosingAttractor> nAttractors =
773 new ArrayList<RingClosingAttractor>();
774 Map<RingClosingAttractor,Integer> nAttToAtmID =
775 new HashMap<RingClosingAttractor,Integer>();
776 Map<RingClosingAttractor,RingClosingAttractor> oldToNewRCA =
777 new HashMap<RingClosingAttractor,RingClosingAttractor>();
778 for (
int iorca=0; iorca<
attractors.size(); iorca++)
782 IAtom atm = nFMol.getAtom(ioatm);
784 nAttractors.add(nRca);
785 nAttToAtmID.put(nRca, ioatm);
786 oldToNewRCA.put(oRca, nRca);
789 ArrayList<Set<ObjectPair>> nAllRCACombs =
790 new ArrayList<Set<ObjectPair>>();
791 for (Set<ObjectPair> sop : this.allRCACombs)
793 Set<ObjectPair> nSop =
new HashSet<ObjectPair>();
797 oldToNewRCA.get(op.getFirst()),
798 oldToNewRCA.get(op.getSecond()));
801 nAllRCACombs.add(nSop);
804 ArrayList<RingClosure> nNewRingClosures =
new ArrayList<RingClosure>();
807 nNewRingClosures.add(rc.deepCopy());
810 ArrayList<Integer> newOldToNewOrder =
new ArrayList<Integer>();
812 newOldToNewOrder.add(i.intValue());
814 ArrayList<Integer> newNewToOldOrder =
new ArrayList<Integer>();
816 newNewToOldOrder.add(i.intValue());
828 newNewToOldOrder,
logger);
General set of constants used in DENOPTIM.
static final double FLOATCOMPARISONTOLERANCE
Smallest difference for comparison of double and float numbers.
static final String DUMMYATMSYMBOL
Symbol of dummy atom.
Container for the list of vertices and the edges that connect them.
DGraph clone()
Returns almost "deep-copy" of this graph.
boolean hasOrEmbedsRings()
Check for rings in this graph and in any graph that is embedded at any level in any vertex of this gr...
This class represents the closure of a ring in a spanning tree.
The RingClosingAttractor represent the available valence/connection that allows to close a ring.
Ring getRingUser()
Get the reference to the graph representation of the ring this attractor is meant to close.
boolean isAttractor()
Checks whether the constructed RingClosingAttractor does corresponds to a RingClosingAttractor in the...
RingClosure represents the arrangement of atoms and PseudoAtoms identifying the head and tail of a ch...
Based on the code from ffx.kenai.com Michael J.
void moveTo(double[] d)
Add a vector to the Atom's current position vector.
int[] getAtomNeighbours()
TinkerMolecule deepCopy()
This method produces a deep copy of the object.
void addBond(int a1, int a2)
Add one bond by appending a pair of indeces into the z-add section.
TinkerAtom getAtom(int pos)
Returns the atom which has the XYZ index set to pos.
Object clone()
This method produces a shallow copy of the object.
Collector of molecular information, related to a single chemical object, that is deployed within the ...
void convertRingsToRCACombinations()
ChemicalObjectModel(DGraph molGraph, IAtomContainer fmol, TinkerMolecule tmol, String molName, ArrayList< ObjectPair > rotatableBnds, ArrayList< Integer > oldToNewOrder, ArrayList< Integer > newToOldOrder, Logger logger)
Constructs a Molecule3DBuilder specifying all its features.
double getAtomOverlapScore()
Return the atoms overlap score which is calculated for all atoms pairs not in 1-4 or lower relationsh...
ArrayList< Integer > newToOldOrder
double overalRCScore
Quality score of the list of RingClosures.
double getNewRingClosuresQuality()
Return the overal evaluation of the whole list of RingClosures.
Map< RingClosingAttractor, Integer > attToAtmID
Relation between RingClosingAttractor and atom ID.
int getTnkAtmIdOfRCA(RingClosingAttractor rca)
Returns the Tinker atom number, 1 to n,of the given RingClosingAttractor.
ArrayList< RingClosingAttractor > attractors
List of Ring Closing Attractors.
ChemicalObjectModel deepcopy()
Return a new Molecule3DBuilder having exactly the same features of this Molecule3DBuilder.
int getNumberRotatableBonds()
Returns the size of the current list of rotatable bonds.
String molName
Reference name.
DGraph getGraph()
Returns the graph representation of this molecule as it was originally generated by DEOPTIM.
int getAtmIdOfRCA(RingClosingAttractor rca)
Returns the CDK atom number, 0 to (n-1), of the given RingClosingAttractor.
Logger logger
Program-specific logger.
ChemicalObjectModel()
Constructs an empty item.
DGraph molGraph
DENOPTIM representation.
String getName()
Return the name of this molecule.
void purgeListRotatableBonds()
Remove the cyclic bonds from the list of rotatable bonds.
ArrayList< ObjectPair > rotatableBnds
List of rotatable bonds.
IAtomContainer getIAtomContainer()
Returns the CDK representation of the molecular system.
void addBond(IAtom atmA, IAtom atmB, RingClosure nRc, BondType bndTyp)
Modify the molecule adding a cyclic bond between two atoms.
ArrayList< RingClosingAttractor > getAttractorsList()
Returns the list of RuingClosingAttractors.
List< Integer > getOldToNewOrder()
ArrayList< ObjectPair > getRotatableBonds()
Returns the list of rotatable bonds.
ChemicalObjectModel(DGraph molGraph, IAtomContainer fmol, TinkerMolecule tmol, String molName, ArrayList< ObjectPair > rotatableBnds, ArrayList< RingClosingAttractor > attractors, Map< RingClosingAttractor, Integer > attToAtmID, ArrayList< Set< ObjectPair > > allRCACombs, ArrayList< RingClosure > ringClosures, ArrayList< Integer > oldToNewOrder, ArrayList< Integer > newToOldOrder, Logger logger)
Constructs an item specifying all its features.
ArrayList< RingClosure > newRingClosures
List of new ring closing environments.
void updateXYZFromINT()
Converts currently loaded internal coordinates into Cartesian overwriting the current XYZ.
double atmOveralScore
Atom overlap score (for atoms not is 1-4 or lower relationship)
ArrayList< Set< ObjectPair > > getRCACombinations()
Returns the list of combinations of RingClosingAttractor.
TinkerMolecule tmol
Tinker internal coordinates representation.
List< Integer > getNewToOldOrder()
ArrayList< Set< ObjectPair > > allRCACombs
List of combinations of RingClosingAttractors (i.e., possible set of rings to create)
ArrayList< Integer > oldToNewOrder
TinkerMolecule getTinkerMolecule()
Returns the Tinker Internal Coordination representation of the molecule.
IAtomContainer fmol
CDK representation.
ArrayList< RingClosure > getNewRingClosures()
Return the list of RingClosures that have been identified as closable head/tail of atom chains during...
RingClosingAttractor getAttractor(int i)
Returns the attractor given its position in the list of attractors.
Some useful math operations.
static Vector3d normDist(Point3d p1, Point3d p2)
Get normalized distance between two point.
static double distance(Point3d a, Point3d b)
Calculates distance between point a and point b.
This class is the equivalent of the Pair data structure used in C++ Although AbstractMap....
Possible chemical bond types an edge can represent.
boolean hasCDKAnalogue()
Checks if it is possible to convert this edge type into a CDK bond.