📄 structurediagramgenerator.java
字号:
*/ ringSystems = RingPartitioner.partitionRings(sssr); /* * We got our ring systems now */ /* * Do the layout for the first connected ring system ... */ int largest = 0; int largestSize = ((IRingSet) ringSystems.get(0)).getAtomContainerCount(); logger.debug("We have " + ringSystems.size() + " ring system(s)."); for (int f = 0; f < ringSystems.size(); f++) { logger.debug("RingSet " + f + " has size " + ((IRingSet) ringSystems.get(f)).getAtomContainerCount()); if (((IRingSet) ringSystems.get(f)).getAtomContainerCount() > largestSize) { largestSize = ((IRingSet) ringSystems.get(f)).getAtomContainerCount(); largest = f; } } logger.debug("Largest RingSystem is at RingSet collection's position " + largest); logger.debug("Size of Largest RingSystem: " + largestSize); layoutRingSet(firstBondVector, (IRingSet) ringSystems.get(largest)); logger.debug("First RingSet placed"); /* * and do the placement of all the directly connected atoms of this ringsystem */ ringPlacer.placeRingSubstituents((IRingSet) ringSystems.get(largest), bondLength); } else { logger.debug("*** Start of handling purely aliphatic molecules. ***"); /* * We are here because there are no rings in the molecule * so we get the longest chain in the molecule and placed in * on a horizontal axis */ logger.debug("Searching initialLongestChain for this purely aliphatic molecule"); IAtomContainer longestChain = atomPlacer.getInitialLongestChain(molecule); logger.debug("Found linear chain of length " + longestChain.getAtomCount()); logger.debug("Setting coordinated of first atom to 0,0"); longestChain.getAtom(0).setPoint2d(new Point2d(0, 0)); longestChain.getAtom(0).setFlag(CDKConstants.ISPLACED, true); /* * place the first bond such that the whole chain will be horizontally * alligned on the x axis */ angle = Math.toRadians(-30); logger.debug("Attempting to place the first bond such that the whole chain will be horizontally alligned on the x axis"); if (firstBondVector != null) atomPlacer.placeLinearChain(longestChain, firstBondVector, bondLength); else atomPlacer.placeLinearChain(longestChain, new Vector2d(Math.cos(angle), Math.sin(angle)), bondLength); logger.debug("Placed longest aliphatic chain"); } /* * Now, do the layout of the rest of the molecule */ do { safetyCounter++; logger.debug("*** Start of handling the rest of the molecule. ***"); /* * do layout for all aliphatic parts of the molecule which are * connected to the parts which have already been laid out. */ handleAliphatics(); /* * do layout for the next ring aliphatic parts of the molecule which are * connected to the parts which have already been laid out. */ layoutNextRingSystem(); } while (!atomPlacer.allPlaced(molecule) && safetyCounter <= molecule.getAtomCount()); fixRest(); new OverlapResolver().resolveOverlap(molecule, sssr); } /** * The main method of this StructurDiagramGenerator. Assign a molecule to the * StructurDiagramGenerator, call the generateCoordinates() method and get * your molecule back. * * @throws java.lang.Exception if an error occurs */ public void generateCoordinates() throws java.lang.Exception { generateCoordinates(new Vector2d(0, 1)); } /** * Does a layout of all the rings in a given connected RingSet. Uses a TemplateHandler * to treat templated mapped substructures differently if <code>useTemplates</code> is * set true. * * @param firstBondVector A vector giving the placement for the first bond * @param rs The connected RingSet for which the layout is to be * done * @throws java.lang.Exception if an error occurs */ private void layoutRingSet(Vector2d firstBondVector, IRingSet rs) throws Exception { IAtomContainer sharedAtoms; Vector2d ringCenterVector; int thisRing; logger.debug("Start of layoutRingSet"); /* * First we check if we can map any templates with predifined coordinates. * All mapped substructures are saved in: this.mappedSubstructures */ if (useTemplates && mappedSubstructures.getAtomContainerCount() > 0 && System.getProperty("java.version").indexOf("1.3.") == -1) { /* * Find mapped substructures */ for (Iterator substructureIterator = mappedSubstructures.atomContainers(); substructureIterator.hasNext(); ) { IAtomContainer substructure = (IAtomContainer) substructureIterator.next(); boolean substructureMapped = false; for (Iterator ringSetIterator = rs.atomContainers(); ringSetIterator.hasNext() && !substructureMapped; ) { IRing ring = (IRing) ringSetIterator.next(); for (Iterator atomIterator = ring.atoms(); atomIterator.hasNext() && !substructureMapped; ) { IAtom atom = (IAtom) atomIterator.next(); if (substructure.contains(atom)) substructureMapped = true; } } /* * Layout a found mapped substructure */ if (substructureMapped) { boolean mapped = getTemplateHandler().mapTemplateExact(substructure); if (!mapped) logger.warn("A supposedly matched substructure failed to match."); else { // Mark substructure atoms as CDKConstants.ISPLACED for (Iterator iterator = substructure.atoms(); iterator.hasNext(); ) { IAtom atom = (IAtom) iterator.next(); atom.setFlag(CDKConstants.ISPLACED, true); } // Mark rings of substrucure as CDKConstants.ISPLACED ringPlacer.checkAndMarkPlaced(rs); } } } } /* * Now layout the rest of this ring system */ /* * Get the most complex ring in this RingSet */ IRing ring = RingSetManipulator.getMostComplexRing(rs); int i = 0; /* * Place the most complex ring at the origin of the coordinate system */ if (!ring.getFlag(CDKConstants.ISPLACED)) { sharedAtoms = placeFirstBond((IBond) ring.getBond(i), firstBondVector); /* * Call the method which lays out the new ring. */ ringCenterVector = ringPlacer.getRingCenterOfFirstRing(ring, firstBondVector, bondLength); ringPlacer.placeRing(ring, sharedAtoms, GeometryToolsInternalCoordinates.get2DCenter(sharedAtoms), ringCenterVector, bondLength); /* * Mark the ring as placed */ ring.setFlag(CDKConstants.ISPLACED, true); } /* * Place all other rings in this ringsystem. */ thisRing = 0; do { if (ring.getFlag(CDKConstants.ISPLACED)) { ringPlacer.placeConnectedRings(rs, ring, RingPlacer.FUSED, bondLength); ringPlacer.placeConnectedRings(rs, ring, RingPlacer.BRIDGED, bondLength); ringPlacer.placeConnectedRings(rs, ring, RingPlacer.SPIRO, bondLength); } thisRing++; if (thisRing == rs.getAtomContainerCount()) { thisRing = 0; } ring = (IRing) rs.getAtomContainer(thisRing); } while (!allPlaced(rs)); logger.debug("End of layoutRingSet"); } /** * Does a layout of all aliphatic parts connected to the parts of the molecule * that have already been laid out. Starts at the first bond with unplaced * neighbours and stops when a ring is encountered. * * @throws org.openscience.cdk.exception.CDKException if an error occurs */ private void handleAliphatics() throws org.openscience.cdk.exception.CDKException { logger.debug("Start of handleAliphatics"); int safetyCounter = 0; IAtomContainer unplacedAtoms = null; IAtomContainer placedAtoms = null; IAtomContainer longestUnplacedChain = null; IAtom atom = null; Vector2d direction = null; Vector2d startVector = null; boolean done; do { safetyCounter++; done = false; atom = getNextAtomWithAliphaticUnplacedNeigbors(); if (atom != null) { unplacedAtoms = getUnplacedAtoms(atom); placedAtoms = getPlacedAtoms(atom); longestUnplacedChain = atomPlacer.getLongestUnplacedChain(molecule, atom); logger.debug("---start of longest unplaced chain---"); try { logger.debug("Start at atom no. " + (molecule.getAtomNumber(atom) + 1)); logger.debug(atomPlacer.listNumbers(molecule, longestUnplacedChain)); } catch (Exception exc) { logger.debug(exc); } logger.debug("---end of longest unplaced chain---"); if (longestUnplacedChain.getAtomCount() > 1) { if (placedAtoms.getAtomCount() > 1) { logger.debug("More than one atoms placed already"); logger.debug("trying to place neighbors of atom " + (molecule.getAtomNumber(atom) + 1)); atomPlacer.distributePartners(atom, placedAtoms, GeometryToolsInternalCoordinates.get2DCenter(placedAtoms), unplacedAtoms, bondLength); direction = new Vector2d(longestUnplacedChain.getAtom(1).getPoint2d()); startVector = new Vector2d(atom.getPoint2d()); direction.sub(startVector); logger.debug("Done placing neighbors of atom " + (molecule.getAtomNumber(atom) + 1)); } else { logger.debug("Less than or equal one atoms placed already"); logger.debug("Trying to get next bond vector."); direction = atomPlacer.getNextBondVector(atom, placedAtoms.getAtom(0), GeometryToolsInternalCoordinates.get2DCenter(molecule),true); } for (int f = 1; f < longestUnplacedChain.getAtomCount(); f++) { longestUnplacedChain.getAtom(f).setFlag(CDKConstants.ISPLACED, false); } atomPlacer.placeLinearChain(longestUnplacedChain, direction, bondLength); } else { done = true; } } else { done = true; } } while (!done && safetyCounter <= molecule.getAtomCount()); logger.debug("End of handleAliphatics"); } /** * Does the layout for the next RingSystem that is connected to those parts of * the molecule that have already been laid out. Finds the next ring with an * unplaced ring atom and lays out this ring. Then lays out the ring substituents * of this ring. Then moves and rotates the laid out ring to match the position * of its attachment bond to the rest of the molecule. * * @throws java.lang.Exception if an error occurs */ private void layoutNextRingSystem() throws Exception { logger.debug("Start of layoutNextRingSystem()"); resetUnplacedRings(); IAtomContainer tempAc = atomPlacer.getPlacedAtoms(molecule); logger.debug("Finding attachment bond to already placed part..."); IBond nextRingAttachmentBond = getNextBondWithUnplacedRingAtom(); if (nextRingAttachmentBond != null) { logger.debug("...bond found."); /* * Get the chain and the ring atom that are connected to where we are comming from. * Both are connected by nextRingAttachmentBond. */ IAtom ringAttachmentAtom = getRingAtom(nextRingAttachmentBond); IAtom chainAttachmentAtom = getOtherBondAtom(ringAttachmentAtom, nextRingAttachmentBond); /* * Get ring system which ringAttachmentAtom is part of */ IRingSet nextRingSystem = getRingSystemOfAtom(ringSystems, ringAttachmentAtom); /* * Get all rings of nextRingSytem as one IAtomContainer */ IAtomContainer ringSystem = tempAc.getBuilder().newAtomContainer(); for (Iterator containers = RingSetManipulator.getAllAtomContainers(nextRingSystem).iterator(); containers.hasNext(); ) ringSystem.add((IAtomContainer) containers.next()); /* * Save coordinates of ringAttachmentAtom and chainAttachmentAtom */ Point2d oldRingAttachmentAtomPoint = ringAttachmentAtom.getPoint2d(); Point2d oldChainAttachmentAtomPoint = chainAttachmentAtom.getPoint2d(); /* * Do the layout of the next ring system */ layoutRingSet(firstBondVector, nextRingSystem); /* * Place all the substituents of next ring system */ atomPlacer.markNotPlaced(tempAc); IAtomContainer placedRingSubstituents = ringPlacer.placeRingSubstituents(nextRingSystem, bondLength); ringSystem.add(placedRingSubstituents); atomPlacer.markPlaced(tempAc); /* * Move and rotate the laid out ring system to match the geometry of the * attachment bond */ logger.debug("Computing translation/rotation of new ringset to fit old attachment bond orientation..."); // old placed ring atom coordinate Point2d oldPoint2 = oldRingAttachmentAtomPoint; // old placed substituent atom coordinate Point2d oldPoint1 = oldChainAttachmentAtomPoint; // new placed ring atom coordinate Point2d newPoint2 = ringAttachmentAtom.getPoint2d(); // new placed substituent atom coordinate Point2d newPoint1 = chainAttachmentAtom.getPoint2d(); logger.debug("oldPoint1: " + oldPoint1); logger.debug("oldPoint2: " + oldPoint2); logger.debug("newPoint1: " + newPoint1); logger.debug("newPoint2: " + newPoint2); double oldAngle = GeometryToolsInternalCoordinates.getAngle(oldPoint2.x - oldPoint1.x, oldPoint2.y - oldPoint1.y); double newAngle = GeometryToolsInternalCoordinates.getAngle(newPoint2.x - newPoint1.x, newPoint2.y - newPoint1.y); double angleDiff = oldAngle - newAngle; logger.debug("oldAngle: " + oldAngle + ", newAngle: " + newAngle + "; diff = " + angleDiff);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -