예제 #1
0
 /**
  * Returns the ring that is formed by the atoms in the given vector.
  *
  * @param vec The vector that contains the atoms of the ring
  * @param mol The molecule this ring is a substructure of
  * @return The ring formed by the given atoms
  */
 private IRing prepareRing(List vec, IAtomContainer mol) {
   // add the atoms in vec to the new ring
   int atomCount = vec.size();
   IRing ring = mol.getBuilder().newInstance(IRing.class, atomCount);
   IAtom[] atoms = new IAtom[atomCount];
   vec.toArray(atoms);
   ring.setAtoms(atoms);
   // add the bonds in mol to the new ring
   try {
     IBond b;
     for (int i = 0; i < atomCount - 1; i++) {
       b = mol.getBond(atoms[i], atoms[i + 1]);
       if (b != null) {
         ring.addBond(b);
       } else {
         logger.error("This should not happen.");
       }
     }
     b = mol.getBond(atoms[0], atoms[atomCount - 1]);
     if (b != null) {
       ring.addBond(b);
     } else {
       logger.error("This should not happen either.");
     }
   } catch (Exception exc) {
     logger.debug(exc);
   }
   logger.debug("found Ring  ", ring);
   return ring;
 }
예제 #2
0
 /**
  * Convenience method for giving a string representation of this ring based on the number of the
  * atom in a given molecule.
  *
  * @param molecule A molecule to determine an atom number for each ring atom
  * @return string representation of this ring
  */
 private String toString(IRing ring, IAtomContainer molecule) throws Exception {
   String str = "";
   for (int f = 0; f < ring.getAtomCount(); f++) {
     str += molecule.getAtomNumber(ring.getAtom(f)) + " - ";
   }
   return str;
 }
예제 #3
0
 @Test
 public void testCalculateMissingHydrogens_Aromatic() throws Exception {
   IAtomContainer pyrrole = MoleculeFactory.makePyrrole();
   IAtom n = pyrrole.getAtom(1);
   IRingSet rs = (new SSSRFinder(pyrrole)).findSSSR();
   IRing ring = (IRing) rs.getAtomContainer(0);
   for (int j = 0; j < ring.getBondCount(); j++) {
     ring.getBond(j).setFlag(CDKConstants.ISAROMATIC, true);
   }
   Assert.assertEquals(5, ring.getBondCount());
   Assert.assertEquals(1, satcheck.calculateNumberOfImplicitHydrogens(n, pyrrole));
 }
예제 #4
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
  /**
   * Generated coordinates for a given ring, which is connected to a spiro ring. The rings share
   * exactly one atom.
   *
   * @param ring The ring to be placed
   * @param sharedAtoms The atoms of this ring, also members of another ring, which are already
   *     placed
   * @param sharedAtomsCenter The geometric center of these atoms
   * @param ringCenterVector A vector pointing the the center of the new ring
   * @param bondLength The standard bondlength
   */
  public void placeSpiroRing(
      IRing ring,
      IAtomContainer sharedAtoms,
      Point2d sharedAtomsCenter,
      Vector2d ringCenterVector,
      double bondLength) {

    logger.debug("placeSpiroRing");
    double radius = getNativeRingRadius(ring, bondLength);
    Point2d ringCenter = new Point2d(sharedAtomsCenter);
    ringCenterVector.normalize();
    ringCenterVector.scale(radius);
    ringCenter.add(ringCenterVector);
    double addAngle = 2 * Math.PI / ring.getRingSize();

    IAtom startAtom = sharedAtoms.getAtom(0);

    // double centerX = ringCenter.x;
    // double centerY = ringCenter.y;

    // int direction = 1;

    IAtom currentAtom = startAtom;
    double startAngle =
        GeometryTools.getAngle(
            startAtom.getPoint2d().x - ringCenter.x, startAtom.getPoint2d().y - ringCenter.y);
    /*
     * Get one bond connected to the spiro bridge atom.
     * It doesn't matter in which direction we draw.
     */
    java.util.List bonds = ring.getConnectedBondsList(startAtom);

    IBond currentBond = (IBond) bonds.get(0);

    Vector atomsToDraw = new Vector();
    /*
     * Store all atoms to draw in consequtive order relative to the
     * chosen bond.
     */
    for (int i = 0; i < ring.getBondCount(); i++) {
      currentBond = ring.getNextBond(currentBond, currentAtom);
      currentAtom = currentBond.getConnectedAtom(currentAtom);
      atomsToDraw.addElement(currentAtom);
    }
    logger.debug("currentAtom  " + currentAtom);
    logger.debug("startAtom  " + startAtom);

    atomPlacer.populatePolygonCorners(atomsToDraw, ringCenter, startAngle, addAngle, radius);
  }
예제 #5
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
 /**
  * Walks throught the atoms of each ring in a ring set and marks a ring as PLACED if all of its
  * atoms have been placed.
  *
  * @param rs The ringset to be checked
  */
 public void checkAndMarkPlaced(IRingSet rs) {
   IRing ring = null;
   boolean allPlaced = true;
   for (int i = 0; i < rs.getAtomContainerCount(); i++) {
     ring = (IRing) rs.getAtomContainer(i);
     allPlaced = true;
     for (int j = 0; j < ring.getAtomCount(); j++) {
       if (!((IAtom) ring.getAtom(j)).getFlag(CDKConstants.ISPLACED)) {
         allPlaced = false;
         break;
       }
     }
     ring.setFlag(CDKConstants.ISPLACED, allPlaced);
   }
 }
예제 #6
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
  /**
   * Layout all rings in the given RingSet that are connected to a given Ring
   *
   * @param rs The RingSet to be searched for rings connected to Ring
   * @param ring The Ring for which all connected rings in RingSet are to be layed out.
   */
  void placeConnectedRings(IRingSet rs, IRing ring, int handleType, double bondLength) {
    IRingSet connectedRings = rs.getConnectedRings(ring);
    IRing connectedRing;
    IAtomContainer sharedAtoms;
    int sac;
    Point2d oldRingCenter, sharedAtomsCenter, tempPoint;
    Vector2d tempVector, oldRingCenterVector, newRingCenterVector;

    //		logger.debug(rs.reportRingList(molecule));
    for (IAtomContainer container : connectedRings.atomContainers()) {
      connectedRing = (IRing) container;
      if (!connectedRing.getFlag(CDKConstants.ISPLACED)) {
        //				logger.debug(ring.toString(molecule));
        //				logger.debug(connectedRing.toString(molecule));
        sharedAtoms = AtomContainerManipulator.getIntersection(ring, connectedRing);
        sac = sharedAtoms.getAtomCount();
        logger.debug("placeConnectedRings-> connectedRing: " + (ring.toString()));
        if ((sac == 2 && handleType == FUSED)
            || (sac == 1 && handleType == SPIRO)
            || (sac > 2 && handleType == BRIDGED)) {
          sharedAtomsCenter = GeometryTools.get2DCenter(sharedAtoms);
          oldRingCenter = GeometryTools.get2DCenter(ring);
          tempVector = (new Vector2d(sharedAtomsCenter));
          newRingCenterVector = new Vector2d(tempVector);
          newRingCenterVector.sub(new Vector2d(oldRingCenter));
          oldRingCenterVector = new Vector2d(newRingCenterVector);
          logger.debug(
              "placeConnectedRing -> tempVector: "
                  + tempVector
                  + ", tempVector.length: "
                  + tempVector.length());
          logger.debug("placeConnectedRing -> bondCenter: " + sharedAtomsCenter);
          logger.debug(
              "placeConnectedRing -> oldRingCenterVector.length(): "
                  + oldRingCenterVector.length());
          logger.debug(
              "placeConnectedRing -> newRingCenterVector.length(): "
                  + newRingCenterVector.length());
          tempPoint = new Point2d(sharedAtomsCenter);
          tempPoint.add(newRingCenterVector);
          placeRing(connectedRing, sharedAtoms, sharedAtomsCenter, newRingCenterVector, bondLength);
          connectedRing.setFlag(CDKConstants.ISPLACED, true);
          placeConnectedRings(rs, connectedRing, handleType, bondLength);
        }
      }
    }
  }
예제 #7
0
  /**
   * Fixes Aromaticity of the molecule i.e. need to find rings and aromaticity again since added H's
   *
   * @param mol
   */
  @TestMethod("testFixAromaticity")
  public static void configure(IAtomContainer mol) {
    // need to find rings and aromaticity again since added H's

    IRingSet ringSet = null;
    try {
      AllRingsFinder arf = new AllRingsFinder();
      ringSet = arf.findAllRings(mol);
    } catch (Exception e) {
      e.printStackTrace();
    }

    try {
      // figure out which atoms are in aromatic rings:
      CDKHydrogenAdder cdk = CDKHydrogenAdder.getInstance(DefaultChemObjectBuilder.getInstance());
      cdk.addImplicitHydrogens(mol);
      ExtAtomContainerManipulator.percieveAtomTypesAndConfigureAtoms(mol);

      CDKHueckelAromaticityDetector.detectAromaticity(mol);
      // figure out which rings are aromatic:
      RingSetManipulator.markAromaticRings(ringSet);
      // figure out which simple (non cycles) rings are aromatic:

      // only atoms in 6 membered rings are aromatic
      // determine largest ring that each atom is a part of

      for (int i = 0; i < mol.getAtomCount(); i++) {
        mol.getAtom(i).setFlag(CDKConstants.ISAROMATIC, false);
        jloop:
        for (int j = 0; j < ringSet.getAtomContainerCount(); j++) {
          // logger.debug(i+"\t"+j);
          IRing ring = (IRing) ringSet.getAtomContainer(j);
          if (!ring.getFlag(CDKConstants.ISAROMATIC)) {
            continue jloop;
          }
          boolean haveatom = ring.contains(mol.getAtom(i));
          // logger.debug("haveatom="+haveatom);
          if (haveatom && ring.getAtomCount() == 6) {
            mol.getAtom(i).setFlag(CDKConstants.ISAROMATIC, true);
          }
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
예제 #8
0
 /**
  * Selects an optimum edge for elimination in structures without N2 nodes.
  *
  * <p>This might be severely broken! Would have helped if there was an explanation of how this
  * algorithm worked.
  *
  * @param ring
  * @param molecule
  */
 private IBond checkEdges(IRing ring, IAtomContainer molecule) {
   IRing r1, r2;
   IRingSet ringSet = ring.getBuilder().newInstance(IRingSet.class);
   IBond bond;
   int minMaxSize = Integer.MAX_VALUE;
   int minMax = 0;
   logger.debug("Molecule: " + molecule);
   Iterator<IBond> bonds = ring.bonds().iterator();
   while (bonds.hasNext()) {
     bond = (IBond) bonds.next();
     molecule.removeElectronContainer(bond);
     r1 = getRing(bond.getAtom(0), molecule);
     r2 = getRing(bond.getAtom(1), molecule);
     logger.debug("checkEdges: " + bond);
     if (r1.getAtomCount() > r2.getAtomCount()) {
       ringSet.addAtomContainer(r1);
     } else {
       ringSet.addAtomContainer(r2);
     }
     molecule.addBond(bond);
   }
   for (int i = 0; i < ringSet.getAtomContainerCount(); i++) {
     if (((IRing) ringSet.getAtomContainer(i)).getBondCount() < minMaxSize) {
       minMaxSize = ((IRing) ringSet.getAtomContainer(i)).getBondCount();
       minMax = i;
     }
   }
   return (IBond) ring.getElectronContainer(minMax);
 }
예제 #9
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
 /**
  * Calculated the center for the first ring so that it can layed out. Only then, all other rings
  * can be assigned coordinates relative to it.
  *
  * @param ring The ring for which the center is to be calculated
  * @return A Vector2d pointing to the new ringcenter
  */
 Vector2d getRingCenterOfFirstRing(IRing ring, Vector2d bondVector, double bondLength) {
   int size = ring.getAtomCount();
   double radius = bondLength / (2 * Math.sin((Math.PI) / size));
   double newRingPerpendicular = Math.sqrt(Math.pow(radius, 2) - Math.pow(bondLength / 2, 2));
   /* get the angle between the x axis and the bond vector */
   double rotangle = GeometryTools.getAngle(bondVector.x, bondVector.y);
   /* Add 90 Degrees to this angle, this is supposed to be the new ringcenter vector */
   rotangle += Math.PI / 2;
   return new Vector2d(
       Math.cos(rotangle) * newRingPerpendicular, Math.sin(rotangle) * newRingPerpendicular);
 }
예제 #10
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
 /**
  * Partition the bonding partners of a given atom into ring atoms and non-ring atoms
  *
  * @param atom The atom whose bonding partners are to be partitioned
  * @param ring The ring against which the bonding partners are checked
  * @param ringAtoms An AtomContainer to store the ring bonding partners
  * @param nonRingAtoms An AtomContainer to store the non-ring bonding partners
  */
 public void partitionNonRingPartners(
     IAtom atom, IRing ring, IAtomContainer ringAtoms, IAtomContainer nonRingAtoms) {
   java.util.List atoms = molecule.getConnectedAtomsList(atom);
   for (int i = 0; i < atoms.size(); i++) {
     IAtom curAtom = (IAtom) atoms.get(i);
     if (!ring.contains(curAtom)) {
       nonRingAtoms.addAtom(curAtom);
     } else {
       ringAtoms.addAtom(curAtom);
     }
   }
 }
예제 #11
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
  /**
   * Positions the aliphatic substituents of a ring system
   *
   * @param rs The RingSystem for which the substituents are to be laid out
   * @return A list of atoms that where laid out
   */
  public IAtomContainer placeRingSubstituents(IRingSet rs, double bondLength) {
    logger.debug("RingPlacer.placeRingSubstituents() start");
    IRing ring = null;
    IAtom atom = null;
    IRingSet rings = null;
    IAtomContainer unplacedPartners = rs.getBuilder().newInstance(IAtomContainer.class);
    IAtomContainer sharedAtoms = rs.getBuilder().newInstance(IAtomContainer.class);
    IAtomContainer primaryAtoms = rs.getBuilder().newInstance(IAtomContainer.class);
    IAtomContainer treatedAtoms = rs.getBuilder().newInstance(IAtomContainer.class);
    Point2d centerOfRingGravity = null;
    for (int j = 0; j < rs.getAtomContainerCount(); j++) {
      ring = (IRing) rs.getAtomContainer(j); /* Get the j-th Ring in RingSet rs */
      for (int k = 0; k < ring.getAtomCount(); k++) {
        unplacedPartners.removeAllElements();
        sharedAtoms.removeAllElements();
        primaryAtoms.removeAllElements();
        atom = ring.getAtom(k);
        rings = rs.getRings(atom);
        centerOfRingGravity = GeometryTools.get2DCenter(rings);
        atomPlacer.partitionPartners(atom, unplacedPartners, sharedAtoms);
        atomPlacer.markNotPlaced(unplacedPartners);
        try {
          for (int f = 0; f < unplacedPartners.getAtomCount(); f++) {
            logger.debug(
                "placeRingSubstituents->unplacedPartners: "
                    + (molecule.getAtomNumber(unplacedPartners.getAtom(f)) + 1));
          }
        } catch (Exception exc) {
        }

        treatedAtoms.add(unplacedPartners);
        if (unplacedPartners.getAtomCount() > 0) {
          atomPlacer.distributePartners(
              atom, sharedAtoms, centerOfRingGravity, unplacedPartners, bondLength);
        }
      }
    }
    logger.debug("RingPlacer.placeRingSubstituents() end");
    return treatedAtoms;
  }
예제 #12
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
  /**
   * Place ring with user provided angles.
   *
   * @param ring the ring to place.
   * @param ringCenter center coordinates of the ring.
   * @param bondLength given bond length.
   * @param startAngles a map with start angles when drawing the ring.
   */
  public void placeRing(
      IRing ring, Point2d ringCenter, double bondLength, Map<Integer, Double> startAngles) {
    double radius = this.getNativeRingRadius(ring, bondLength);
    double addAngle = 2 * Math.PI / ring.getRingSize();

    IAtom startAtom = ring.getFirstAtom();
    Point2d p = new Point2d(ringCenter.x + radius, ringCenter.y);
    startAtom.setPoint2d(p);
    double startAngle = Math.PI * 0.5;

    /* Different ring sizes get different start angles to have
     * visually correct placement */
    int ringSize = ring.getRingSize();
    if (startAngles.get(ringSize) != null) startAngle = startAngles.get(ringSize);

    List<IBond> bonds = ring.getConnectedBondsList(startAtom);
    /*
     * Store all atoms to draw in consecutive order relative to the
     * chosen bond.
     */
    Vector<IAtom> atomsToDraw = new Vector<IAtom>();
    IAtom currentAtom = startAtom;
    IBond currentBond = (IBond) bonds.get(0);
    for (int i = 0; i < ring.getBondCount(); i++) {
      currentBond = ring.getNextBond(currentBond, currentAtom);
      currentAtom = currentBond.getConnectedAtom(currentAtom);
      atomsToDraw.addElement(currentAtom);
    }
    atomPlacer.populatePolygonCorners(atomsToDraw, ringCenter, startAngle, addAngle, radius);
  }
예제 #13
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
 /**
  * Returns the ring radius of a perfect polygons of size ring.getAtomCount() The ring radius is
  * the distance of each atom to the ringcenter.
  *
  * @param ring The ring for which the radius is to calculated
  * @param bondLength The bond length for each bond in the ring
  * @return The radius of the ring.
  */
 public double getNativeRingRadius(IRing ring, double bondLength) {
   int size = ring.getAtomCount();
   double radius = bondLength / (2 * Math.sin((Math.PI) / size));
   return radius;
 }
예제 #14
0
파일: RingPlacer.java 프로젝트: jonalv/cdk
  /**
   * Generated coordinates for a given ring, which is fused to another ring. The rings share exactly
   * one bond.
   *
   * @param ring The ring to be placed
   * @param sharedAtoms The atoms of this ring, also members of another ring, which are already
   *     placed
   * @param sharedAtomsCenter The geometric center of these atoms
   * @param ringCenterVector A vector pointing the the center of the new ring
   * @param bondLength The standard bondlength
   */
  public void placeFusedRing(
      IRing ring,
      IAtomContainer sharedAtoms,
      Point2d sharedAtomsCenter,
      Vector2d ringCenterVector,
      double bondLength) {
    logger.debug("RingPlacer.placeFusedRing() start");
    Point2d ringCenter = new Point2d(sharedAtomsCenter);
    double radius = getNativeRingRadius(ring, bondLength);
    double newRingPerpendicular = Math.sqrt(Math.pow(radius, 2) - Math.pow(bondLength / 2, 2));
    ringCenterVector.normalize();
    logger.debug("placeFusedRing->: ringCenterVector.length()" + ringCenterVector.length());
    ringCenterVector.scale(newRingPerpendicular);
    ringCenter.add(ringCenterVector);

    IAtom bondAtom1 = sharedAtoms.getAtom(0);
    IAtom bondAtom2 = sharedAtoms.getAtom(1);

    Vector2d bondAtom1Vector = new Vector2d(bondAtom1.getPoint2d());
    Vector2d bondAtom2Vector = new Vector2d(bondAtom2.getPoint2d());
    Vector2d originRingCenterVector = new Vector2d(ringCenter);

    bondAtom1Vector.sub(originRingCenterVector);
    bondAtom2Vector.sub(originRingCenterVector);

    double occupiedAngle = bondAtom1Vector.angle(bondAtom2Vector);

    double remainingAngle = (2 * Math.PI) - occupiedAngle;
    double addAngle = remainingAngle / (ring.getRingSize() - 1);

    logger.debug("placeFusedRing->occupiedAngle: " + Math.toDegrees(occupiedAngle));
    logger.debug("placeFusedRing->remainingAngle: " + Math.toDegrees(remainingAngle));
    logger.debug("placeFusedRing->addAngle: " + Math.toDegrees(addAngle));

    IAtom startAtom;

    double centerX = ringCenter.x;
    double centerY = ringCenter.y;

    double xDiff = bondAtom1.getPoint2d().x - bondAtom2.getPoint2d().x;
    double yDiff = bondAtom1.getPoint2d().y - bondAtom2.getPoint2d().y;

    double startAngle;
    ;

    int direction = 1;
    // if bond is vertical
    if (xDiff == 0) {
      logger.debug("placeFusedRing->Bond is vertical");
      // starts with the lower Atom
      if (bondAtom1.getPoint2d().y > bondAtom2.getPoint2d().y) {
        startAtom = bondAtom1;
      } else {
        startAtom = bondAtom2;
      }

      // changes the drawing direction
      if (centerX < bondAtom1.getPoint2d().x) {
        direction = 1;
      } else {
        direction = -1;
      }
    }

    // if bond is not vertical
    else {
      // starts with the left Atom
      if (bondAtom1.getPoint2d().x > bondAtom2.getPoint2d().x) {
        startAtom = bondAtom1;
      } else {
        startAtom = bondAtom2;
      }

      // changes the drawing direction
      if (centerY - bondAtom1.getPoint2d().y
          > (centerX - bondAtom1.getPoint2d().x) * yDiff / xDiff) {
        direction = 1;
      } else {
        direction = -1;
      }
    }
    startAngle =
        GeometryTools.getAngle(
            startAtom.getPoint2d().x - ringCenter.x, startAtom.getPoint2d().y - ringCenter.y);

    IAtom currentAtom = startAtom;
    // determine first bond in Ring
    //        int k = 0;
    //        for (k = 0; k < ring.getElectronContainerCount(); k++) {
    //            if (ring.getElectronContainer(k) instanceof IBond) break;
    //        }
    IBond currentBond = sharedAtoms.getBond(0);
    Vector atomsToDraw = new Vector();
    for (int i = 0; i < ring.getBondCount() - 2; i++) {
      currentBond = ring.getNextBond(currentBond, currentAtom);
      currentAtom = currentBond.getConnectedAtom(currentAtom);
      atomsToDraw.addElement(currentAtom);
    }
    addAngle = addAngle * direction;
    try {
      logger.debug("placeFusedRing->startAngle: " + Math.toDegrees(startAngle));
      logger.debug("placeFusedRing->addAngle: " + Math.toDegrees(addAngle));
      logger.debug("placeFusedRing->startAtom is: " + (molecule.getAtomNumber(startAtom) + 1));
      logger.debug("AtomsToDraw: " + atomPlacer.listNumbers(molecule, atomsToDraw));
    } catch (Exception exc) {
      logger.debug("Caught an exception while logging in RingPlacer");
    }
    atomPlacer.populatePolygonCorners(atomsToDraw, ringCenter, startAngle, addAngle, radius);
  }