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.utils.MathUtils;
54import denoptim.utils.ObjectPair;
73 private IAtomContainer
fmol;
137 this.molGraph =
new DGraph();
138 IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
139 this.fmol = builder.newAtomContainer();
141 this.attractors =
new ArrayList<RingClosingAttractor>();
142 this.attToAtmID =
new HashMap<RingClosingAttractor,Integer>();
143 this.allRCACombs =
new ArrayList<Set<ObjectPair>>();
144 this.rotatableBnds =
new ArrayList<ObjectPair>();
145 this.newRingClosures =
new ArrayList<RingClosure>();
146 this.molName =
"none";
147 this.oldToNewOrder =
new ArrayList<Integer>();
148 this.newToOldOrder =
new ArrayList<Integer>();
176 ArrayList<RingClosure> ringClosures,
189 this.newRingClosures = ringClosures;
190 this.overalRCScore = Double.NaN;
191 this.atmOveralScore = Double.NaN;
192 if (this.attractors.size() != 0)
238 this.attractors =
new ArrayList<RingClosingAttractor>();
239 this.attToAtmID =
new HashMap<RingClosingAttractor,Integer>();
241 this.allRCACombs =
new ArrayList<Set<ObjectPair>>();
242 if (this.attractors.size() != 0)
250 this.newRingClosures =
new ArrayList<RingClosure>();
251 this.overalRCScore = Double.NaN;
252 this.atmOveralScore = Double.NaN;
277 for (IAtom atm :
fmol.atoms())
294 Set<ObjectPair> singleRCAcomb =
new HashSet<ObjectPair>();
300 if (ringOwnerI==
null)
307 if (ringOwnerJ==
null)
309 if (ringOwnerI==ringOwnerJ)
311 singleRCAcomb.add(
new ObjectPair(rcaI, rcaJ));
327 ArrayList<Point3d> newCoords =
new ArrayList<Point3d>();
328 for (
int i=0; i<
fmol.getAtomCount(); i++)
335 if (ia > i || ib > i || ic > i)
337 String msg =
"ERROR! Cannot convert internal coordinates of "
338 +
"atom " + i +
" " + tAtm +
". Reference "
339 +
"atoms have higher ID. The atoms list in "
340 +
"Molecule3DBuilder needs to be reordered.";
345 double angle1 = tAtm.
getDistAngle()[1] * 2 * Math.PI / 360.0;
346 double angle2 = tAtm.
getDistAngle()[2] * 2 * Math.PI / 360.0;
347 double[] newXYZ = {0.0, 0.0, 0.0};
349 double s1 = Math.sin(angle1);
350 double s2 = Math.sin(angle2);
351 double c1 = Math.cos(angle1);
352 double c2 = Math.cos(angle2);
364 newCoords.get(ia-1),newCoords.get(ib-1));
366 newCoords.get(ia-1),newCoords.get(ib-1));
367 newXYZ[0] = bond * s1;
368 newXYZ[2] = newCoords.get(ib-1).z + (rab - bond*c1)*nab.z;
370 else if (angleFlag == 0)
373 newCoords.get(ia-1),newCoords.get(ib-1));
375 newCoords.get(ib-1),newCoords.get(ic-1));
376 Vector3d t =
new Vector3d();
378 double c = nab.x*nbc.x + nab.y*nbc.y + nab.z*nbc.z;
379 if (Math.abs(c) > (1.0 - smallDble))
381 String msg =
"ERROR! Linearity does not allow definition "
382 +
"of the dihedral angle for atom " + i +
" " + tAtm
383 +
" (Value of c="+c+
" too close to unity; threshold is "
384 + (1.0 - smallDble) +
"). "
385 +
"You better use dummy atoms to avoid linearities.";
388 t.scale(1/Math.sqrt(Math.max(1.00 - c*c, smallDble)));
389 Vector3d u =
new Vector3d();
391 newXYZ[0] = newCoords.get(ia-1).x
392 + bond*(u.x*s1*c2 + t.x*s1*s2 - nab.x*c1);
393 newXYZ[1] = newCoords.get(ia-1).y
394 + bond*(u.y*s1*c2 + t.y*s1*s2 - nab.y*c1);
395 newXYZ[2] = newCoords.get(ia-1).z
396 + bond*(u.z*s1*c2 + t.z*s1*s2 - nab.z*c1);
398 else if (Math.abs(angleFlag) == 1)
401 newCoords.get(ib-1),newCoords.get(ia-1));
403 newCoords.get(ia-1),newCoords.get(ic-1));
404 Vector3d t =
new Vector3d();
406 double c = nba.x*nac.x + nba.y*nac.y + nba.z*nac.z;
407 if (Math.abs(c) > (1.0 - smallDble))
409 logger.log(Level.WARNING,
"WARNING! close-to-linear system "
410 +
"in the definition of atom " + i +
" " + tAtm +
". "
411 +
"You better use dummy atoms to avoid linearities.");
413 double s = Math.max(1.00 - c*c, smallDble);
414 double a = (-c2 - c*c1) / s;
415 double b = (c1 + c*c2) / s;
416 double ci = (1.00 + a*c2 - b*c1) / s;
419 ci = angleFlag * Math.sqrt(ci);
421 else if (ci < -smallDble)
423 ci = Math.sqrt((a*nac.x+b*nba.x)*(a*nac.x+b*nba.x)
424 + (a*nac.y+b*nba.y)*(a*nac.y+b*nba.y)
425 + (a*nac.z+b*nba.z)*(a*nac.z+b*nba.z));
429 logger.log(Level.WARNING,
"WARNING! close-to-linear system "
430 +
"in the definition of atom " + i +
" " + tAtm +
". "
431 +
"You better use dummy atoms to avoid linearities.");
437 newXYZ[0] = newCoords.get(ia-1).x
438 + bond*(a*nac.x + b*nba.x + ci*t.x);
439 newXYZ[1] = newCoords.get(ia-1).y
440 + bond*(a*nac.y + b*nba.y + ci*t.y);
441 newXYZ[2] = newCoords.get(ia-1).z
442 + bond*(a*nac.z + b*nba.z + ci*t.z);
444 Point3d p3d =
new Point3d(newXYZ[0],newXYZ[1],newXYZ[2]);
449 for (
int i=0; i<
fmol.getAtomCount(); i++)
451 fmol.getAtom(i).setPoint3d(newCoords.get(i));
599 score = score + rc.getRingClosureQuality();
618 for (IAtom atmA :
fmol.atoms())
620 String elA = atmA.getSymbol();
625 IAtom[] toExclude = PathTools.findClosestByBond(
fmol,atmA,4);
626 for (IAtom atmB :
fmol.atoms())
631 if (Arrays.asList(toExclude).contains(atmB))
634 String elB = atmB.getSymbol();
638 double dist = atmA.getPoint3d().distance(atmB.getPoint3d());
639 score = score + dist;
673 this.newRingClosures.add(nRc);
674 this.overalRCScore = Double.NaN;
676 int iA =
fmol.indexOf(atmA);
677 int iB =
fmol.indexOf(atmB);
682 logger.log(Level.FINE,
"ADDING BOND: "+iA+
" "+iB);
684 logger.log(Level.FINE,
"WARNING! Attempt to add ring closing bond "
685 +
"did not add any actual chemical bond because the "
686 +
"bond type of the chord is '" + bndTyp +
"'.");
709 SpanningTree st =
new SpanningTree(
fmol);
710 IRingSet allRings =
new RingSet();
712 allRings = st.getAllRings();
713 }
catch (Exception ex) {
718 ArrayList<ObjectPair> toRemove =
new ArrayList<ObjectPair>();
721 int i1 = ((Integer)op.getFirst()).intValue();
722 int i2 = ((Integer)op.getSecond()).intValue();
724 IBond bnd =
fmol.getBond(
fmol.getAtom(i1),
fmol.getAtom(i2));
725 IRingSet rs = allRings.getRings(bnd);
729 logger.log(Level.FINE,
"Bond " + i1 +
"-" + i2 +
" (TnkID:"
730 + (i1+1) +
"-" + (i2+1) +
") is not rotatable anymore");
750 @SuppressWarnings(
"unchecked")
753 String nMolName = this.
molName;
755 IAtomContainer nFMol;
757 ArrayList<ObjectPair> nRotBnds;
761 nFMol = this.fmol.
clone();
763 nRotBnds = (ArrayList<ObjectPair>) this.rotatableBnds.
clone();
765 catch (CloneNotSupportedException cns)
770 ArrayList<RingClosingAttractor> nAttractors =
771 new ArrayList<RingClosingAttractor>();
772 Map<RingClosingAttractor,Integer> nAttToAtmID =
773 new HashMap<RingClosingAttractor,Integer>();
774 Map<RingClosingAttractor,RingClosingAttractor> oldToNewRCA =
775 new HashMap<RingClosingAttractor,RingClosingAttractor>();
776 for (
int iorca=0; iorca<
attractors.size(); iorca++)
780 IAtom atm = nFMol.getAtom(ioatm);
782 nAttractors.add(nRca);
783 nAttToAtmID.put(nRca, ioatm);
784 oldToNewRCA.put(oRca, nRca);
787 ArrayList<Set<ObjectPair>> nAllRCACombs =
788 new ArrayList<Set<ObjectPair>>();
789 for (Set<ObjectPair> sop : this.allRCACombs)
791 Set<ObjectPair> nSop =
new HashSet<ObjectPair>();
795 oldToNewRCA.get(op.getFirst()),
796 oldToNewRCA.get(op.getSecond()));
799 nAllRCACombs.add(nSop);
802 ArrayList<RingClosure> nNewRingClosures =
new ArrayList<RingClosure>();
805 nNewRingClosures.add(rc.deepCopy());
808 ArrayList<Integer> newOldToNewOrder =
new ArrayList<Integer>();
810 newOldToNewOrder.add(i.intValue());
812 ArrayList<Integer> newNewToOldOrder =
new ArrayList<Integer>();
814 newNewToOldOrder.add(i.intValue());
826 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.